OmniAICreator/Qiita-1.07M huggingface dataset:
「フロントエンド開発のためのテスト入門」 10章での環境構築エラー対応 posgres sql 管理者で入る方法 M1Mac

# はじめに
少しはまったので記事にします。

# 問題
「フロントエンド開発のためのテスト入門」 10章での開発環境構築エラー解消 ( User `root` was denied access on the database `app-db.public` )
https://qiita.com/osa-osa/items/b1e4466b19d7bde896d5

```
// 実際にDockerでたてているpostgresにpostgresユーザでログインする
$ psql -h localhost -p 5432 -U postgres
```
記事を書かれた方と同じように、Dockerでたてているpostgresにpostgresユーザでログインしようとしました。
Mac Book AirのM1のせいか、postgres のroleがないというエラーでした。
```
% psql -h localhost -p 5432 -U postgres

psql (14.13 (Homebrew), server 14.2)
Type "help" for help.

# 現在のデータベースに存在するすべてのロール（ユーザー）とその属性を一覧表示
postgres=> \du


List of roles
   Role name    |                         Attributes                         | Member of 
----------------+------------------------------------------------------------+-----------
 postgres       |                                                            | {}
username | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
```

# 解決方法
「-U username -d postgres」と、コマンドを少し変える必要がありました。
usernameはご自身のものを入力してください。

```
% psql -h localhost -p 5432 -U username -d postgres

psql (14.13 (Homebrew), server 14.2)
Type "help" for help.
```
```
# 既存のpostgresロールにスーパーユーザー権限を付与
postgres=# ALTER ROLE postgres WITH SUPERUSER;

ALTER ROLE
```
```
#  現在のデータベースに存在するすべてのロール（ユーザー）とその属性を一覧表示
postgres=# \du

                                      List of roles
   Role name    |                         Attributes                         | Member of 
----------------+------------------------------------------------------------+-----------
 postgres       | Superuser                                                  | {}
username | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
```
```
# rootという名前の新しいロールを作成し、スーパーユーザー権限を付与
postgres=# create role root with superuser login password 'password';

CREATE ROLE
```
```
#  現在のデータベースに存在するすべてのロール（ユーザー）とその属性を一覧表示
postgres=# \du

                                      List of roles
   Role name    |                         Attributes                         | Member of 
----------------+------------------------------------------------------------+-----------
 postgres       | Superuser                                                  | {}
 root           | Superuser                                                  | {}
 username | Superuser, Create role, Create DB, Replication, Bypass RLS | {}

```
```
postgres=# exit
```

# おわりに
どなたかの参考になれば幸いです。

# 参考
「フロントエンド開発のためのテスト入門」 10章での開発環境構築エラー解消 ( User `root` was denied access on the database `app-db.public` )
https://qiita.com/osa-osa/items/b1e4466b19d7bde896d5

Postgresqlでスーパーユーザー権限をもったユーザーを作成する
https://qiita.com/IzumiSy/items/6879ae9eb181b5e43087
JestでspyOnを使って、データを削除するテストをする(supabase、React.js、TypeScript)

# はじめに
Jestのmockの理解が浅いので、spyOnでもやっみました。

# 問題
Jestでmockを作って、データを削除するテストをする supabase、React.js、TypeScript
https://qiita.com/like-mountain/items/a81df2e95703468d1378
上記を実装しているとき、spyOnを使おうとしてうまくいかなかったので、
改めて試してみました。


# 解決方法
```AppComponent.spec.tsx
// testファイル
// mockを使ったテストは、describeを使わないと、global的な扱いとなり、他のテストに影響する
describe('mockを使ったテスト', () => {

// spyOnの場合、jest.mockは不要(あっても良い)
jest.mock('@/lib/record.ts');
jest.mock('@/lib/record_delete.ts');

  test('削除ができること', async () => {
    const { Record } = jest.requireActual('@/domain/record');
    await waitFor(() => {
      jest
        .spyOn(recordLib, 'GetAllRecords')
        .mockResolvedValueOnce([
          new Record('5', 'Testtest5', 5),
          new Record('10', 'Testtest10', 10),
        ])
        .mockResolvedValueOnce([
          new Record('10', 'Testtest10', 10),
          new Record('11', 'Testtest11', 11),
          new Record('12', 'Testtest12', 12),
        ]);

        // classを使わなくても、以下のように書ける
        // .mockResolvedValueOnce(Promise.resolve([
        //         { id: '5', title: 'Testtest5', time: 5 },
        //         { id: '10', title: 'Testtest10', time: 10 }
        //       ]))
        //       .mockResolvedValueOnce(Promise.resolve([
        //         { id: '10', title: 'Testtest10', time: 10 },
        //         { id: '11', title: 'Testtest11', time: 11 },
        //         { id: '12', title: 'Testtest12', time: 12 }
        //       ]));
    });

    await waitFor(() => {
        // 元の定義がexport async function RecordDelete(id: string): Promise<void>のため、何も返さない（void）プロミスを返す
        jest.spyOn(recordLibDelete, 'RecordDelete')
        .mockResolvedValueOnce(Promise.resolve());
    });

  // renderの前にspyOnを置かないと、データがないことになる
    render(
      <ChakraProvider value={defaultSystem}>
        <App />
      </ChakraProvider>
    );

   // 確認用出力
    // screen.debug();
    await waitFor(() => {
      const dialogTitle = screen.getByText('登録');
      expect(dialogTitle).toBeInTheDocument();
    });

   // 確認用出力
    // screen.debug();

    const deleteButton = await waitFor(() =>
      screen.getByTestId('delete-button-5')
    );
    // console.log("deleteButton", deleteButton)

    await waitFor(() => {
      fireEvent.click(deleteButton);
    });
   // 確認用出力
    // screen.debug();

    await waitFor(() => {
        //  expect(screen.queryByText('Testtest5 5時間')).toBeInTheDocument();
      expect(screen.queryByText('Testtest5 5時間')).not.toBeInTheDocument();
    });
  });
});
```

# おわりに
spyOnでも実装できて良かったです。

# 参考記事
Jestでmockを作って、データを削除するテストをする supabase、React.js、TypeScript
https://qiita.com/like-mountain/items/a81df2e95703468d1378
JDBC周りの備忘録

参考文献；
https://www.neclearning.jp/sample_text/JV945-1.pdf
https://atmarkit.itmedia.co.jp/ait/articles/0106/26/news001.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1618611/db3d1fb3-9f38-8261-854a-9bd45709c6b5.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1618611/a95749f4-5ac6-91ca-34a2-52e7a9675314.png)

:secret:★JDBCドライバはDBベンダが提供するので、各自でダウンロードしてjavaプロジェクト内に含める必要あり

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1618611/b00dc78a-c457-b0d9-83b3-91b987cc781a.png)

ほんとに標準ライブラリに含まれてた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1618611/7a0e84a1-d855-66bb-0023-742711e44c98.png)
量子アニーリング認定(アドバンス)コースを受講し、認定を受けてみた

# 概要
筆者は以前日本量子コンピューティング協会主催の量子エンジニア(エントリー)講座を受講し、認定試験に合格しました。その時、以下の記事を投稿しました。

https://qiita.com/y-vectorfield/items/9fbd04f3d9be76b0fcb9

それから約1ヶ月後に量子エンジニア(アドバンス)講座を受講し、こちらの認定試験も受験し、:cherry_blossom:無事合格:cherry_blossom:しました。あれから3ヶ月程経過していますが、記憶が残っているうちに記事にまとめておこうと思います。

# そもそも量子アニーリング認定(アドバンス)とは？
形式は過去記事で投稿したエントリーの講座とほぼ同じです。全3回の講座を受講し、最終講義で発表される認定試験問題をTytanSDKを用いて解きます。解答はJupyter Notebook形式で保存し、指定の提出方法で提出します。採点後合格点に達していれば、認定となります。但し、提出期間が(当時は)最終講義から約2週間程の期間しかないため、計画的に進めないと提出期限に間に合わない可能性が有ります。

* 参考: 公式ページ

https://www.jqca.org/course.php

* 参考: Tytan SDK @ GitHub

https://github.com/tytansdk/tytan

* 参考: 講座情報 @ Connpass

https://jqca2023.connpass.com/event/326438/

https://jqca2023.connpass.com/event/328873/

https://jqca2023.connpass.com/event/329665/

# 受講料・受験料
筆者が受講した時期(2024年8月〜9月)は講座の受講自体は無料、認定試験も受験だけであれば無料でした。但し、正式な認定証を発行して貰う場合は、手数料として9,800円(これが実質受験料)必要となります。これはエントリーの講座と同様でした。認定講座は非常に分かりやすく面白かったのと、折角認定に合格したので、筆者は手数料を支払い認定証を発行して貰うことにしました。但し、今後は受講料、受験料共に有料化？される様です。但し、発行を依頼するシステムが当時は正常に動作しておらず、別途Discordで連絡をする必要が有ったり、別の認定の認定証が届いたりなど、まだ認定証の発行についてきちんと手順化されていない？のかと思われるトラブルに見舞われました。

# 教材及び認定試験
新しい講座になってから、教材は一部公開、認定試験は最終回の受講生にのみ公開されるというシステムになりました。

# 試験受験後
解答の提出は講師の方のDiscordのプライベートチャンネルを経由して行ったため、Discord経由で合格通知が来ました。

# まとめ
量子アニーリング認定(アドバンス)コースを受講し、認定試験に合格したので記事を投稿してみました。ゲート式の方も受講したなと思っていましたが、現在開講されていないようですが、書籍などで勉強しようと思います。また、TytanSDKへのコントリビューションなどを通してアニーリングへの更なる理解を深めていきたいと思います。
mysqldumpで一部のテーブルをダンプする方法

mysqldump コマンドを使用して、特定のデータベース内の一部のテーブルだけをダンプすることができます。

### 基本構文

mysqldump -u <ユーザー名> -h <host名> -p <データベース名> <テーブル名1> <テーブル名2> ... > <ダンプファイル名>.sql


たとえば、my_database データベースの中の table1 と table2 だけをダンプする場合:

```
mysqldump -u root -h localhost -p my_database table1 table2 > partial_dump.sql
```

- -u root：MySQLユーザー名（例：root）
- -p：パスワード入力を求めるオプション
- -h: DB host
- my_database：データベース名
- table1, table2：ダンプ対象のテーブル名
- partial_dump.sql：出力ファイル名

複数のテーブルを指定する際の注意点
- テーブル名はスペースで区切ります。
- 存在しないテーブルを指定するとエラーが発生します。

### 特定のテーブルのデータのみダンプする（条件付き）

特定の条件でデータをダンプしたい場合は、--where オプションを利用します。

例: 条件付きデータのダンプ
table1 のうち、id カラムが100未満のデータだけをダンプする:

```
mysqldump -u root -p my_database table1 --where="id < 100" > conditional_dump.sql
```


https://dev.mysql.com/doc/refman/8.0/ja/mysqldump.html
初めてのAnsibleサーバー構築：自宅ラボで実践するAlmaLinuxを使った簡単手順

## はじめに

少し時間ができたので、Ansibleについて改めて学び、自宅のホームラボでAnsibleサーバーを構築してみました。

:::note info
***今回は、プレイブックの作成などの高度な設定は行わず、基本的なサーバー構築と動作確認だけをゴールとします。***
:::

この記事は少しマニアックな内容ですが、興味のある方はぜひ最後までお読みください！

## そもそも、Ansibleとは？

***Ansibleは、ITインフラの自動化を実現するためのオープンソースツールです。***

![スクリーンショット 2024-12-06 20.25.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/6d9f8273-c2fb-dee7-c0fb-4a84c72a8035.png)
引用画像：https://future-architect.github.io/articles/20180209/

   - **言語/ツール**: YAML (Ansible Playbooks)
   - **概要**: サーバー構成管理とアプリケーションデプロイを自動化するツール。エージェントレスで手軽に利用可能。

:::note warn
***サーバー設定やアプリケーションのインストールを簡単に管理したい場合に便利です。***
:::

***Ansibleの基礎については、過去の記事でも簡単に紹介していますので、参考にしてみてください。***

https://qiita.com/free-honda/items/682e29d92e60e2d17681

## 前提条件について

***この記事では、自宅のVirtualBox上で稼働しているAlmaLinuxを対象に、Ansibleサーバーを構築していきます。***

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/5b0b9e4d-03f2-eb73-b297-b2618b47d33e.png)

管理対象となるクライアントサーバーについては、次回の記事で詳しく解説する予定です。

また、VirtualBoxやAlmaLinuxの基本設定については、***以下の過去の記事で解説していますので、興味のある方はぜひご参照ください！***

https://qiita.com/free-honda/items/ca757d6414a8ea344ea1

https://qiita.com/free-honda/items/835300a0a18b206352cc

:::note info
***基礎知識が気になる方は、これらの記事を参考にして準備を進めてみてください！***
:::

## 実際にAnsibleサーバーを構築してみた
ここからは、具体的な手順を交えながらAnsibleサーバーの構築方法を解説していきます。

:::note warn
***構築自体はシンプルな内容ですので、手順に沿って進めてみてください。***
:::

### 1. システムの更新
まず、システムのパッケージを最新の状態に更新します。

```bash
sudo yum update -y
```

***これにより、インストール時のエラーやセキュリティリスクを軽減できます。***

### 2. 必要なパッケージのインストール

AnsibleはEPEL（```Extra Packages for Enterprise Linux```）リポジトリに含まれているため、まずこのリポジトリを追加します。

```bash
sudo yum install -y epel-release
```

### 3. Ansibleのインストール
EPELリポジトリを有効にした状態で、以下のコマンドを実行し、Ansibleをインストールします。

```bash
sudo yum install -y ansible
```

### 4. Ansibleの動作確認

インストールが完了したら、Ansibleが正しくインストールされているか、以下のコマンドで確認します。

```bash
ansible --version
```

***コマンドを実行すると、Ansibleのバージョンや関連情報が表示されます。***

```bash
[honda@HONDA-TEST ansible]$ ansible --version
ansible [core 2.14.17]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/honda/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.9/site-packages/ansible
  ansible collection location = /home/honda/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.9.18 (main, Jan 24 2024, 00:00:00) [GCC 11.4.1 20231218 (Red Hat 11.4.1-3)] (/usr/bin/python3)
  jinja version = 3.1.2
  libyaml = True
```

:::note warn
***これでAnsibleサーバーの基本構築は完了です！***
:::


## まとめ

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

:::note
***Ansibleは、シンプルでありながら強力なツールであり、小規模から大規模なITインフラまで幅広く対応可能です。***
:::


Ansibleサーバーの基本的な構築内容でしたが、***どなたかの技術的な支えになれば幸いです！***

## 参考記事

https://qiita.com/Brutus/items/1894629105d61f4854bc

https://qiita.com/tags/ansible

https://www.redhat.com/ja/topics/automation/learning-ansible-tutorial
C#の修飾子

# はじめに
感想まで書いてますがまだ理解不十分な点や自分で試せてない所もあるので今後新たな発見や気付きなどあれば徐々に更新していく予定です。

# クラスにつけられるアクセスレベル

|修飾子|意味|使いどころ|
|---|---|---|
|public|全公開|どこからでも参照したい時|
|internal|同一アセンブリ内でのみ参照可能|別のプロジェクトからは参照されたくない時|

※キーワードなしのデフォルトのアクセスレベルはinternal

# アクセスレベル以外のクラスにつけられる修飾子

|修飾子|意味|使いどころ または使用した際に生まれる制約|
|---|---|---|
|abstract|クラスを抽象クラスとして定義|直接インスタンス化できなくなる。|
|sealed|クラスが継承できないことを定義|派生を防ぐことが出来る。|
|static|クラスを静的クラスとして定義|インスタンス化できず、すべてのメンバーがstaticでなければならない。また、internal protected, protectedレベルのメンバーも持てなくなる。|
|partial|クラス定義を複数のファイルに分割可能|自動生成コードと手動コードの分離だったり、複数人開発の際にコンフリクトの衝突を避けることが可能になる。一方で分割しすぎると管理が複雑になりやすいので注意|
|unsafe|クラス内でポインタ操作が可能|？？|
|record|クラスを不変データオブジェクトとして定義|主にデータ転送オブジェクトや簡潔なデータ型を定義したい時|

# メンバー(フィールド、メソッド)につけられるアクセスレベル

|修飾子|同じクラス|継承関係なし(同じアセンブリ)|派生クラス(同じアセンブリ)|継承関係なし(異なるアセンブリ)|派生クラス(異なるアセンブリ)|
|---|---|---|---|---|---|
|public|○|○|○|○|○|
|internal protected|○|○|○|×|○|
|internal|○|○|○|×|×|
|protected|○|×|○|×|○|
|private protected|○|×|○|×|×|×|
|private|○|×|×|×|×|×|

※キーワードなしのデフォルトのアクセスレベルはフィールドもメソッドもprivate

# アクセスレベル以外のメンバーにつけられる修飾子

## メソッド

|修飾子|意味|使いどころ または使用した際に生まれる制約|
|---|---|---|
|abstract|抽象メソッドを定義|実装を記述できなくなる。また、継承したクラスのどこかで実装を強制することが出来る。|
|new|継承元のメソッドを非表示|継承先の型でインスタンス化した場合はnewで新しく定義した方のメソッドが呼び出される。一方でポリモーフィズムを使ってインスタンス化した場合は継承元のメソッドが呼ばれる。|
|static|メソッドを静的メソッドとして定義|インスタンスごとの処理ではなく、アプリケーション全体である処理がしたい場合。|


# 感想
Javaも結構細かく制御できて良いと思ってたけどC#はJavaの後発という事もあって、より改良されてる気がしました。
一方でJavaのパッケージプライベートないのかーとは思ったけど
そもそもパッケージプライベートのレベルで制御したいならアセンブリ(プロジェクト)違うよね。ってのがC#の考えなんかな。
パッケージ json を用いて複数の場所にある HDA へ連鎖的にパスを通す

Windows で Houdini を起動すると、デフォルトでは
`C:\Users\<user_name>\Documents\houdini<version>` へパスが通り、その中にある `otls` フォルダ直下のHDAと、`packages` フォルダ直下の json ファイルが認識されます。

`packages` フォルダ内の json ファイルを通して他の場所へパスを通す方法はドキュメントの [Houdiniパッケージ](https://www.sidefx.com/ja/docs/houdini/ref/plugins.html) のページへ明記されています。ただ自分の読解力が足らず、読み込まれたパッケージをもとに、連鎖的に様々な場所にあるパッケージや HDA へパスを通す方法がなかなか判りませんでした。

やりたい事のイメージは下図のようになります。黄色がディレクトリ、白い四角がファイル、青い矢印が別の場所へパスを通すことを意味します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3930709/fd2685aa-8b93-4a7f-cff1-8e9d3109348c.png)

判った後でドキュメントを読めば理解できる内容なのですが、ドキュメントを読むだけで今回の結果にたどり着くのは（自分にとっては）困難だったため、方法を記事に残します。


# サンプル

サンプルを [こちら](https://drive.google.com/file/d/1O4AePs8Z7C-GMKlD5_xZxGe6WP_MI9qL/view?usp=sharing) からダウンロードできます。

このサンプルは、
`C:\Users\<user_name>\Documents\houdini<version>`、`D:\location_A`、`D:\location_B`、`D:\location_C` の各 `otls` フォルダ内に HDA があり、それらへ数珠つなぎにパスを通すことを想定しています。（下図参照）

zip内の各フォルダを次の場所へ展開し、Houdini20.5 を起動すると各 SOP HDA を呼び出すことができるようになります。

- **houdini20.5**: `C:\Users\<user_name>\Documents`
- **location_A**, **location_B**, **location_C**: `D:\`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3930709/0ea7a10b-2158-6c2a-4f50-a46bf0ec439f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3930709/2a745602-cfd8-c3fc-34a8-d2ad4cdb9805.png)


# パッケージ JSON の書き方

重要なのは、いずれの json にも HDA を認識させるための `hpath` だけでなく、json を認識させるための `package_path` を指定したことでした。

```json:set_location_A.json
{
    "package_path": "D:/location_A/packages",
    "hpath": "D:/location_A"
}
```
てっきり `D:\location_A` へ HOUDINI_PATH が通っていれば `D:\location_A\packages` 内の json も認識されるかと思っていましたが、そんな事はありませんでした。

なお、上のコードは
```json
{
    "env": [
        {"LOCATION_A": "D:/location_A"}
    ],
    "package_path": "$LOCATION_A/packages",
    "hpath": "$LOCATION_A"
}
```
のように環境変数を利用する形で書いても良いですし、むしろその方がトラブル時のデバッグが容易になります。

# 最後に

パッケージ json は設定がしやすく、環境自体に階層のような概念がある場合にも有効に活用できます。また、今回紹介した内容により、HDA を保存する場所の制限を小さくすることができます。

HDA の置き場所を集約しておかないことによるデメリットもありますが、環境構築方法の一選択肢として参考になれば幸いです。
【Next.js】ReferenceError: window is not defined を解消する方法

# 発生事象

```
ReferenceError: window is not defined
```

というエラーは、サーバー側でwindowオブジェクトが定義されていないために発生します。サーバーがブラウザのwindowオブジェクトにアクセスできないため、windowオブジェクトを直接参照するコードはこのエラーをスローします。

例えば以下のコードで発生します。

```tsx
  const [windowSize, setWindowSize] = useState({
    width: window.innerWidth,
    height: window.innerHeight,
  });
```

# 解消方法

useEffect を使います。useState の初期値は 0 （ブラウザに依存しない値）とし、state の更新をイベントリスナーに登録します。

```tsx
  const [windowSize, setWindowSize] = useState({
    width: 0,
    height: 0,
  });

  useEffect(() => {
    // state を更新する関数を定義
    const handleResize = () => {
      setWindowSize({
        width: window.innerWidth,
        height: window.innerHeight,
      });
    };

    // ブラウザを開いたときのサイズで state を更新
    handleResize();

    // ブラウザのサイズが変わった時に state を更新するようにイベントリスナーを登録
    window.addEventListener("resize", handleResize);

    // コンポーネントがアンマウントされる時にイベントリスナーを削除する
    return () => {
      window.removeEventListener("resize", handleResize);
    };
  }, []);
```

https://ja.react.dev/learn/synchronizing-with-effects
計測モードの分類と用途

最近、太陽エネルギーの有効利用にハマっています。特に冬場の日照時間が短いワーストケースの状況で測定を行うことで、新たな可能性を探りたいと思っています。どうせなら、Raspberry Pi Zero WとArduinoを使ってソーラーパネルの電力で駆動する仕組みを考えています。

また、本職の方法として温度計測や環境データの記録などもしたいことがあり、それぞれの計測方法について整理することにしました。まず、計測モードを種類別に分けて、自分なりの考えをまとめてみます。

## 計測モードについて
私は計測モードを大きく2つに分けて考えることにしました。

1. **常時計測モード**: データを連続的に記録し、リアルタイム性を重視するタイプ。
2. **定期計測モード**: 必要な時だけデータを取得して、省電力で運用するタイプ。

この分類を元に、それぞれどんな場面で活用できるかを整理していきます。

## 計測間隔での名称付け
さらに計測間隔によって名称を分けて整理しました。これで、自分のやりたいことが具体的にイメージしやすくなると思います。

| **名称**              | **計測間隔**               | **特徴**                                   |
|-----------------------|---------------------------|-------------------------------------------|
| **低速計測**          | 10秒～1秒                 | 長期的な環境モニタリングを想定。           |
| **中速計測**          | 1秒～1ms                  | 頻繁に変化するデータを記録。               |
| **高速計測**          | 1ms～100µs                | 高速現象を捉えるためのモード。             |
| **超高速計測**        | 100µs～1µs                | 精密なデータが必要な場合に対応。           |
| **異次元計測**        | 1µs未満                   | 専用回路が必要な領域。                     |

それぞれのモードについて、自分がどんな用途で使えるかをさらに具体的にしていきます。

## 常時計測モード
常時計測は、リアルタイム性が必要な時に使うことを考えています。

| **計測モード**       | **概要**                                      | **用途**                              |
|------------------------|-----------------------------------------------|---------------------------------------|
| **低速常時計測**      | 計測間隔が10秒～1秒。                        | 環境計測やソーラーパネルの長期監視。  |
| **中速常時計測**      | 計測間隔が1秒～1ms。                          | 照度や温度などのリアルタイム監視。    |
| **高速常時計測**      | 計測間隔が1ms～100µs。                        | 振動計測や波形分析に活用。            |
| **超高速計測**        | 計測間隔が100µs～1µs。                        | 精密解析やダイナミック現象の観測。    |
| **異次元計測**        | 計測間隔が1µs未満。                           | 超高速信号やナノ秒レベルの測定。      |

## 定期計測モード
省電力で長期運用を目指す場合には、定期計測が役立つと考えています。

| **計測モード**       | **概要**                                      | **用途**                              |
|------------------------|-----------------------------------------------|---------------------------------------|
| **低速定期計測**      | 計測間隔が10秒～数時間。                      | 環境データの長期監視や省エネ運用。    |

---

これらを元に、自分がやりたい計測システムの設計に取り組んでいこうと思います。目的に合わせたモードを選び、効率よくデータを取得していきたいです。

明日は大みそかなので、大みそかハッカソンを実施して「低速定期計測」の実装を進める予定です。これがどれだけ成果を出せるか、とても楽しみです。
PrismaとSupabaseの統合方法

## Prismaの使い方

:::note

### **結論: 新しいテーブル追加時の流れ**

1.  **Supabaseでテーブルを作成**（SQLまたはダッシュボード）。
2.  **`prisma db pull` を実行**して新しいスキーマを取り込む。
3.  **`npx prisma generate` を実行**して
3.  Prisma Clientを再生成。
4.  **コードで新しいテーブルを操作**。
:::

---

## **これまでの流れと質問のポイント**
1. **PrismaとSupabaseの統合方法**:
   - PrismaをSupabaseに接続して既存のデータベースを扱いたい。
   - Supabaseのデータを削除せずに、Prismaで操作可能にする方法。

2. **既存のテーブルをリセットせずに使いたい**:
   - Prismaのマイグレーション機能を使う際、データやテーブルをリセットせずに既存テーブルを利用する方法を知りたい。

3. **`prisma db pull` を使ったスキーマ生成**:
   - 既存データベースの構造をPrismaスキーマとして取得し、そのままPrismaで活用したい。

4. **やらなくてよいことが知りたい**:
   - 特に既存テーブルがある場合、不要な操作（データやテーブルのリセットなど）を避ける方法。

---

## **既存のテーブルがある場合の基本方針**
Prismaを既存のデータベースと統合する場合、以下を行います：

### **やるべきこと**
1. **Prismaの初期設定**
   ```bash
   npx prisma init
   ```
   - これにより、`prisma/schema.prisma` と `.env` ファイルが生成されます。

2. **Supabaseの接続情報を設定**
   - `.env` ファイルにSupabaseの接続情報を追加します：
     ```env
     DATABASE_URL="postgresql://postgres:<password>@db.<project-ref>.supabase.co:5432/postgres"
     ```

3. **既存のスキーマをPrismaに取り込む**
   ```bash
   npx prisma db pull
   ```
   - 既存のデータベース構造が `prisma/schema.prisma` に反映されます。
   - このステップで既存のデータベースをリセットする必要はありません。

4. **Prisma Clientの生成**
   ```bash
   npx prisma generate
   ```
   - Prisma Clientを生成し、コードからデータベースを操作できるようにします。

5. **Prismaでデータ操作**
   - Prisma Clientを使用して、既存テーブルを操作します。
     ```typescript
     const prisma = new PrismaClient();

     async function fetchQuizResults() {
         const results = await prisma.quizResults.findMany();
         console.log(results);
     }
     fetchQuizResults();
     ```

---

### **やらなくてよいこと**
1. **既存テーブルの削除やリセット**
   - `prisma migrate dev` を実行しないでください。このコマンドはデータベース構造を変更し、競合がある場合にテーブルをリセットする可能性があります。

2. **データの再作成**
   - 既存のデータはそのままで操作可能です。データベースをリセットして再構築する必要はありません。

3. **不要なカラムやテーブルの削除**
   - Prismaスキーマを調整する際、必要のないカラムやテーブルを削除する操作はデータベースに影響を与える可能性があります。
   - 必要に応じて、`prisma db pull` を再実行して最新状態を取得します。

4. **Supabase特有の拡張機能の無効化**
   - Supabaseが提供する `pgcrypto` などのPostgreSQL拡張機能を無効にする必要はありません。Prismaはそれらを無視するため、特別な変更は不要です。

---

## **最終的な流れ（既存テーブルを活用する場合）**
1. **Prismaのセットアップ**:
   ```bash
   npx prisma init
   ```
   - 必要ファイル (`schema.prisma`, `.env`) を生成。

2. **Supabaseの接続設定**:
   - `.env` に `DATABASE_URL` を設定。

3. **既存スキーマをインポート**:
   ```bash
   npx prisma db pull
   ```

4. **Prisma Clientの生成**:
   ```bash
   npx prisma generate
   ```

5. **既存データベースの操作**:
   - Prisma Clientを使い、データを安全に操作。

---

## **具体的にやらなくてよいことまとめ**
- **`prisma migrate dev` を使ってテーブルを上書きまたは削除しない**:
  - 既存テーブルがリセットされる可能性がある。
- **データベースのリセット操作をしない**:
  - `DROP SCHEMA` などの操作は不要。
- **Supabaseの特定の拡張機能を無効化しない**:
  - PrismaスキーマとSupabaseデータベースはそのまま整合できます。

---
rust でオイラープロジェクト２

まずは逐次型で書いた場合。

```rust
fn create_fibonacci_sequence(n: i32) -> Vec<i32> {
    let mut a = 0;
    let mut b = 1;
    let mut fib = a + b;
    let mut sequence = vec![a, b];

    while fib < n {
        a = b;
        b = fib;
        fib = a + b;
        sequence.push(fib);
    }
    sequence
}

pub fn solver(n: i32) -> i32 {
    create_fibonacci_sequence(n)
        .iter()
        .filter(|&x| x % 2 == 0)
        .sum()
}
```

つぎに宣言型で書いた場合。

```rust
struct Fibonacci {
    a: i32,
    b: i32,
}

impl Fibonacci {
    fn new() -> Self {
        Self { a: 0, b: 1 }
    }
}

impl Iterator for Fibonacci {
    type Item = i32;
    fn next(&mut self) -> Option<Self::Item> {
        let next = self.b + self.a;
        self.a = self.b;
        self.b = next;
        Some(next)
    }
}

pub fn solver(n: i32) -> i32 {
    Fibonacci::new()
        .take_while(|&x| x < n)
        .filter(|&x| x % 2 == 0)
        .sum()
}
```
情報処理安全確保支援士　合格体験記とその勉強方法

## はじめに
令和6年度秋期　情報処理安全確保支援士試験に合格しましたので、その時の勉強方法について共有いたします。
応用情報情報技術者試験　合格体験記に引き続き、非IT系人材が合格するためのロードマップとして何かのお役に立てれば幸いです。

## プロフィール
・非IT系企業勤務(自動車部品メーカの生産技術職)
・年齢は26歳(社会人5年目)
・22年に基本情報技術者試験に合格
・23年に応用情報技術者試験に合格
・大学は地方国公立工学部機械系学科を卒業(学部卒)

## 試験結果
・試験結果は、午前Ⅰ免除　午前Ⅱ76点　午後61点
　かなりギリギリの結果ですが、合格でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3621830/e9c459f7-5632-d87d-4bf5-76d845806d6c.png)

## 受験目的
・明確な目的なし。応用情報技術者試験を受けてから1年ほど経ち、午前Ⅰ免除の資格が失われることがもったいないと思い、とりあえず申し込み。(勢いのみ)

## 使用教材について
・基本的には下記3つを使用で合格できました。
1.情報処理安全確保支援士　合格教本
2.過去問道場
3.youtube　まさるの勉強部屋

## 勉強期間

2024年8月初～10/12(試験前日)までの約2か月半

## 勉強方法

勉強期間が短かったため、”合格することだけ”を考え2段階で勉強を進めています。

### 1段階目：ひたすらインプットと過去問道場で午前Ⅱ対策(1か月)

・合格教本を通読する(毎日＋土日)
　→タイマーをセットして、30秒程度で見開き1ページを確認していく。
 　2h程度で300ページ分ぐらい目を通せるので、分厚い参考書でも通読できます。
   どうせ何週もするので、理解できなかった場合でも止まらない。(2周回目の自分がんばれ！という気持ちで)


・まさるの勉強部屋を見る(毎日)
　→サクッと見れるので、通勤中やスキマ時間に見るように心掛けました。
 　要点が非常にきれいに整理されており、初学者でも理解しやすい。
 　量的には、一日10～15本分見ていたと思う。

・過去問道場(毎日)
　→計算問題がほぼないので、応用よりもサクッとできる
 　問題数があまりないのであまり時間をかけずに、ランダム出題でひたすら実施。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3621830/0d521e34-74fa-4a5d-06fd-4f032b929129.png)

### 2段階目：ひたすらインプットと午後試験対策(1か月半)

・午後過去問を解く(毎日)
　→1問解くのがかなりしんどいので、毎日1問～2問解ければいいと考えました。
 　また、解けたときと全然解けない時の差で一喜一憂しないように意識しました。(極論、同じ問題は出ないので)
 
・まさるの勉強部屋
　→午後問題解説動画を見ていました。長いですが、1.5倍速で午後問題の解き方を確認していきました。
   午後問題を自分で解かなくても、解いた気になれる、素晴らしい動画です…

・合格教本を熟読する
　→午後問題や、まさるの勉強部屋を見て、理解が弱い分野に絞って参考書を熟読していきました。
 　※勉強中に理解が弱いな、と思った分野はPC上の復習項目メモに追加し、別途時間を取って確認していく。

## 総勉強時間について
平日：1h30mぐらいを目標
休日：6hぐらいを目標
トータル：150hぐらい？

## 試験を受けてみて思ったこと等
IT系未経験でも合格狙える資格なんだな、と再認識。
ぼやっとした理解でも案外何とかなる。完全に理解することを優先するよりも、試験範囲の全体像を把握して万遍なく勉強していくほうが早く合格できるかも。
(もちろん、完全に理解することが理想ではある)
どうしても勉強したことをノートや紙にまとめたりしたくなるものだが、今回はその欲求を完全に封じ込めて試験勉強に臨んだ。案外これが一番良かったかも。
/usr/bin/editorにSnapパッケージ版のNeovimを指定できるようにする。

## はじめに
私は最初APT版のNeovimを使っていましたが、バージョンが古く、対応していないプラグインが存在したためよりバージョンが新しいSnap版に移行しました。しかし、Snap版のNeovimはAlternativesに選択肢を追加してくれないためデフォルトのテキストエディターをNeovimにすることができません。それを解決した方法をメモがてら書くことにします。

## 環境
- Ubuntu 24.04.1 LTS (Noble Numbat)
- Snap版Neovim

## 結論
以下のコマンドを順に実行します。
```bash
$ sudo snap alias nvim editor
$ sudo update-alternatives --install /usr/bin/editor editor /snap/bin/nvim 10
sudo update-alternatives --config editor
```

## 解説
:::note info
以下の文章では、Snapパッケージに含まれるコマンドをさしてSnapコマンドと表現しています。
:::
Alternativesは、ユーザーの選択に応じてシンボリックリンクを貼り替えることで同じ機能をもつコマンドを切り替えて使うようにする仕組みです。一方で、Snapは、目的のSnapコマンド名のシンボリックリンクから`/usr/bin/snap`を起動させることで、起動するSnapコマンドを決定しています。例えば、Neovimがいる`/snap/bin/nvim`は`/usr/bin/snap`のシンボリックリンクになっています。そのため、単純にAlternativesを使って`/usr/bin/editor -> /usr/bin/nvim`としてしまうと、Snapはeditorコマンドを起動しようとするため、当然のことながらNeovimは起動できません。
途中にNeovimを起動させるシェルスクリプトを噛ませてもいいのですが、都合のいいことにsnapはアプリケーション・エイリアスという機構を持っており、Snapパッケージ内に含まれるコマンドの別名を作ることができます。これを使ってnvimのエイリアスとしてeditorを作れば、無事Neovimを起動することができます。

## 元に戻したいときは
```bash
sudo update-alternatives --remove editor /snap/bin/nvim
sudo snap unalias editor
```
## 注意
他のSnapパッケージをAlternativesで利用する時も同じ方法が使えますが、コマンド名の衝突にはくれぐれも気を付けてください。

## 終わりに
初めての記事なので、至らない点等あれば指摘していただけるとありがたいです。
ここまで読んでいただきありがとうございました。

## 参考
- [linux - How do I add nvim to update-alternatives when using snap under Ubuntu - Stack Overflow](https://stackoverflow.com/questions/65889273/how-do-i-add-nvim-to-update-alternatives-when-using-snap-under-ubuntu)
- [Commands and aliases | Snapcraft documentation](https://snapcraft.io/docs/commands-and-aliases)
Rails APIについて

## はじめに
現在、Rails APIモードを使用した個人開発の設計を実施しているところですが、そもそもRails APIモードと通常モードの違いを整理したく本記事を執筆しました。  
同じような初学者の参考になれば嬉しいです。

## 内容
### 基本的な違い
主な違いは、ビュー層の有無です。
通常モードでは、HTMLテンプレートを使ってビューをレンダリングするため、完全なMVC（Model-View-Controller）を提供します。 
一方、APIモードはビュー層を省略し、データのやり取りにのみ特化しています。  
この違いにより、APIモードは軽量で高速なレスポンスを実現し、フロントエンドフレームワーク（例：React、Vue.js）と簡単に統合できます。

### 通常モードの特徴
そもそも、RailsとはRuby 言語をベースにしたWebアプリ開発フレームワークです。　　
１番の特徴は、「フロントエンドとバックエンドを両方担えるフルスタックなWebアプリ開発フレームワークであること」が挙げられます。
|  | コンセプト | 特徴 |
|:-|:-|:-|
|フロントエンド|ユーザーが直接触れる部分の領域| HTML/CSS/Javascriptによって記述されたソースコードがブラウザによって実行されることによって、フロントエンド部分が表示  |
| バックエンド| ユーザーが直接触れない部分|  フロントエンド側から受け取ったリクエストに応じてデータベースからデータを取得し、フロントエンド側にレスポンスとして返すといった役割 |

Rails がフルスタックなWebアプリ開発フレームワークとして成立できているのは、RailsがMVCアーキテクチャーを採用しているためです。

それぞれのアーキテクチャの違いは下記の通りです。
| アーキテクチャ | 特徴 |
|:-|:-|
|Model   | データベースとのやりとりを管理する要素  |
|View   | HTML/CSS/JavaScriptを生成する要素   |
|Controller   | Model と View の仲介役で、ユーザーからのレスポンスを返す役割  |

https://pikawaka.com/rails/mvc

### APIモードの特徴
上述の通り、APIモードでは、ビュー（HTML）の部分を省略し、データのやり取りに特化した軽量なアプリケーションを構築することができます。 
　　
メリットは、フロントエンドはReactやVue.jsなどのモダンなフレームワークを使用し、バックエンドはRailsAPIでデータを提供する構成が可能です。

というのも、近年ではSPA（Single Page Application） という設計方針が主流になっています。
　
SPAとは、JavascriptでHTMLの一部を差し替えて必要な部分だけを読み込むため、サーバーとの通信量を抑えれ、パフォーマンス向上につながります。

Googleマップで目的地を変更するたびに、毎回ページ全体の読み込みが行われないのは、このSPAによるものです。


## 最後に
Railsは、通常モードとAPIモードのどちらを選択しても、高い生産性を提供するフレームワークです。
目的に応じてこれらのモードを使い分けることで、効率的なアプリケーション開発が可能になります。

通常モードでは、フロントエンドとバックエンドを統合した開発が可能で、比較的小規模なプロジェクトや完全なフルスタックアプリの構築に適しています。
一方で、APIモードはフロントエンドとバックエンドを分離した構造を採用するため、モダンなフロントエンドフレームワークと連携した開発や、大規模なSPAのバックエンドとして適しています。

本記事が、Rails APIモードと通常モードの違いを整理し、今後の開発に役立つ参考資料となれば幸いです。
情報処理安全確保支援士試験に合格しました

こんにちは。

テックリードのTerukiです。

今年最後の記事です。
10月に受験した「令和６年度秋期 情報処理安全確保支援士試験」に合格したので、その感想とかを書こうかなと。

年末ですしゆるい感じでお届けします。

# 結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192685/a18ac0d5-202d-cdf7-e19a-d45ce01d8eb8.png)

なかなかギリギリでした。

情報処理技術者試験自体かなり久しぶりで、前回受けたのが応用情報技術者試験ですがそれも8年くらい前の19歳の時だったので試験会場はなんだか新鮮でした。

業務もだいぶ逼迫していて、正直ほとんど勉強する時間はなかったのですが合格できてよかったです。

午前午後それぞれ備忘も含めて振り返りをしてみようと思います。

試験問題はIPAのサイトから閲覧できます。

https://www.ipa.go.jp/shiken/mondai-kaiotu/2024r06.html#aki

# 午前Ⅰ

前述の通り前回応用情報技術者試験を受けたのは8年前なので当然免除なしです。

正直受験前は午前Ⅰが一番不安でしたが、結果は普通でした。

結構もったいない落とし方をしていて、逆ポーランド記法やダーウィンの海など微妙に忘れているものを間違えているところが多かったです。

一方ゴリゴリのセキュリティ問題についてはある程度取れていました。
DNSキャッシュポイズニングやエクスプロイトコードの話など業務外では比較的身近だったので簡単に解答できました。

BPRの問題はなかなかひどかったです。

人を増やしたり外部委託したりの条件でコスト効率が一番高いものを選ぶ問題ですが、まさかの人は減らす＆外部委託もしないが答えになるとは。。:innocent:

見た瞬間後回しにした判断は正しかったです。

応用情報技術者試験を受験した時とは違い、AI関連の問題が当たり前のように入っているのが少し新鮮でした。8年も経てば変わりますね。



# 午前Ⅱ

受験する前までは一番自信がありました。受験する前までは:sob:

正直慢心がありました。というのも、勉強をやり始める前に一度実力を測るという意味で春期の午前Ⅱを勉強なしで解いたのですが、そこで25問中21問正解というかなり高得点を取れていたのでこれは大丈夫だと思っていた節があります。

IdPやSSOなど、過去に業務で何度も触ったのでこのあたりは簡単に解くことができましたが、IPSやGoFのデザインパターンなど、シンプルに知らない問題が春期の問題よりも多くギリギリになってしまいました。

それでも、量子コンピュータ関係やテスト駆動開発、メール関係の問題は正答できたのでギリセーフ。

# 午後

私は問1と問3を選択しました。

問1はインシデントレスポンスの問題でしたが、記述部分はいまいち何を訊かれているのかしっくりくる答えを書けたわけではなく、なくなく似たようなことを別々の問で書くことになってしまいました。

それでも記述以外の部分はほぼ正解できたのと、記述部分を３つくらいは正解としてくれるようなことを書いていたのでセーフだったのかもしれません。
配点が気になりますね。。

問3は私にとってはかなり簡単で、多少難読化されたJavaScriptくらいは楽に読めるのでこれは40点以上取れたのではと思っています。
iTECの[試験講評](https://www.youtube.com/watch?v=RYliMTi2kWA)で問3はやや難と言われていたのがちょっと意外でした。

画面を図示しろという問題は面食らいましたが、脳内でJavaScriptを実行できればかなり簡単だと思います。
クエリパラメータで送っているのでアクセスログに残るなどもこの手の問題ではあるあるなのかなと。

一番最後の設問3の(2)だけ気がかりだったのですが、本文では「攻撃者のWebサーバに情報を送信してしまった利用者は漏れなく特定したいが、送信していない利用者はできるだけ含めたくない」と言及しておきながら、送信していない利用者が含まれている可能性がある「配送先・支払方法選択画面にアクセスしたアカウント名」が答えなのは解せない感じがあります。

TACの解答例も「支払手続画面にアクセスした利用者のアカウント名」になっているのでぐるぐる目状態です😵‍💫

事前に勉強してた時よりは明らかに出来が悪くなってしまったのですが、それでも一応合格できたのは良かったです。

# おわりに

昨今のサイバー攻撃は日に日に高度になっていて明日は我が身なので来年からはよりいっそうセキュリティ対策を押し進めていきたいと思っています。

毎週月曜日か火曜日にQiitaに記事を書いていましたが、これは来年も続けようと思っているのでよければ今後も見ていっていただけたらなと思います。

来年もOh my teethをよろしくお願いします！

# Oh my teethについて
Oh my teethでは未来の歯科体験を創るために日々活動しています。

Techチームではより良いユーザー体験を提供するべく、Webフロントエンドからバックエンド、スマホアプリに機械学習モデルなど、さまざまなプロダクトを開発しています。

一緒に未来の歯科体験を創りませんか？興味がある方は是非こちらを確認してください。

https://oh.careers/

カジュアル面談も可能なので気軽に応募してみてください！

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192685/0138b492-e02b-852e-61fa-fc065b53d285.png" width="450" />
SIGNATE Cup 2024 備忘録

# 1. はじめに
SIGNATEのコンペに参加して、メダルを獲得することが出来ました。なので、備忘録としてこの記事を書くことにしました。
初めて記事を書くので、拙い部分が沢山あると思いますが、最後までお付き合いしていただけると幸いです:pray:

# 2. 参加したコンペについて
現在、SIGNATEでSOTA ChallengeになっているSIGNATE Cup 2024(URL: https://signate.jp/competitions/1523 )に参加しました。

このコンペのタスクは、旅行会社が保有する顧客データ（属性、志向、営業担当との接触履歴など）を基に、旅行パッケージの成約率を予測するモデルを構築することです。

ちなみに順位は、108位/1,372人でした。
![スクリーンショット 2024-12-30 20.00.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812650/bb083e8b-c882-382e-ffd4-42ee90965dad.png)


# 3. 実装したコードの詳細
以下は、銅メダル獲得時に使用したコードを説明していきます。

## 3.1. 前処理
基本的には、データの形状の統一、外れ値処理、欠損値処理、ダミー変数化を実施しました。
これらに当てはまらない前処理を行ったのは、**customer_info** だけです。
具体的に customer_info に施した前処理は以下のようになります。

- 婚姻状況、車の所有、子どもの人数
- 婚姻状況は、"未婚"・"離婚済み"・"結婚済み"・"独身" に分類し、ラベリング
- 車の所有は、"所持"・"未所持"に分類し、ラベリング
- 子どもの人数は、整数型に変換

以上が施した前処理になります。基本の処理は、データの形状を見ながら、特徴量ごとに行いました。詳細は、リクエストがあったら載せようと思います🙇

## 3.2. モデル選定
私が使用したモデルは、XGBoost単体モデルです。理由は以下になります。
- 高速な学習が可能
- ハイパーパラメータの柔軟な調整が可能
- 欠損値を自然に処理が可能
- LightGBMや、CatBoostよりLBのスコアが高かった（アンサンブルも試したが、XGBoost単体の方がLBのスコアが高かった）← この理由が1番大きいです

## 3.3. クロスバリデーション
精度向上のために、StratifiedKFold を用いてデータを分割しました。以下のような設定で実装しました。

- 分割数は 5 
- データ分布を考慮した層化サンプリングを採用

```qiita.py
# クロスバリデーションの設定
skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
```

## 3.4. ハイパーパラメータチューニング
XGBoost のハイパーパラメータを最適化するため、以下の範囲で**グリッドサーチ**を実行しました。

```qiita.py
# ハイパーパラメータの候補
param_grid = {
    'n_estimators': [100, 200, 500],
    'max_depth': [3, 5, 7],
    'learning_rate': [0.01, 0.05, 0.1],
    'subsample': [0.6, 0.8, 1.0],
    'colsample_bytree': [0.6, 0.8, 1.0],
    'reg_alpha': [0, 0.1, 1],
    'reg_lambda': [0, 0.1, 1]
}

# モデルの定義
xgb_model = XGBClassifier(
    objective='binary:logistic',
    use_label_encoder=False,
    eval_metric='logloss',
    random_state=42
)

# グリッドサーチの実行
grid_search = GridSearchCV(
    estimator=xgb_model,
    param_grid=param_grid,
    scoring='neg_log_loss',
    cv=skf,
    n_jobs=-1,
    verbose=1
)

grid_search.fit(X, y)
```

最適なパラメータは以下になりました。
- n_estimators: 500
- max_depth: 5
- learning_rate: 0.05
- 他のパラメータもチューニング済み


以上が実装したコードの説明になります。

# 4. 学びと反省
- 簡潔なモデルでも十分な成果を出せる
    - XGBoost のみでアンサンブルを使わず、安定したスコアを達成できました
- データの理解が鍵
    - データの欠損値やカテゴリ変数の分布を深く理解することで、前処理が精度に大きな影響を与えることを実感しました
- 終了までの残り2週間は多忙で、コンペに取り組む時間を確保できませんでした
    - 十分な時間が取れるときにコンペに参加しようと思います
- 最終スコアより高いものがあったが、選択していなかった
    - よく提出ファイルを確認しようと思います（今回は、暫定スコアが1番高かったものを選んだんですが、これはどうやって対策すればいいのでしょうか...）
 ![スクリーンショット 2024-12-30 20.31.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812650/f1eb3292-338a-7494-7555-1dd022809eac.png)

# 5. まとめ
今回のコンペでは、XGBoostを用いたシンプルなアプローチで銅メダルを獲得することができました。最適化されたハイパーパラメータと効果的なデータ前処理が成功の要因となりました。本記事が参考になれば幸いです！最後までお付き合いいただきありがとうございました🥲

質問やフィードバックがあればぜひコメントで教えてください！
Powershellスクリプトの開発環境をVSCodeで構築


PowerShellスクリプトのコードエディタとして、PowerShell ISEを活用されている方も多いのではないでしょうか。
しかし、現在のPowerShell 7.X~以降の開発環境としてVisual Studio Code（以降VSCode）の活用が公式から案内されていることから、VSCode上でPowerShellを利用できる環境の構築について解説します。


前提条件
---
・PowerShell 7.x~以降を利用していること
※PowerShellにて `$PSVersionTable` の実行結果から自身が利用している端末の
PowerShellバージョンを確認。

PSVersionの値から自身の利用しているPowerShellのバージョンを確認できます。

・VSCodeがインストール済みであること
※本記事ではVSCodeのインストール方法については割愛します。


VSCodeへPowerShell拡張機能をインストール
---
1.VSCodeを起動
※起動方法については割愛


2.「ctrl」+「P」を押し、Quick Openを起動


3.Quick Openを開き、「ext install powershell」と入力し検索
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3974027/7a00e507-1114-86fd-f59f-7377688c9d6b.png)


4.「拡張機能」ビューが開くので、MicrosoftのPowerShell拡張機能をインストール
※インストール後、「インストール」ボタンが再読み込みに変化した場合は「再読み込み」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3974027/09d3c224-d7f0-8a7d-972a-7f298c19d728.png)


5.編集が可能となる


まとめ
---
今回の解説範囲はあくまで、Powershellスクリプトの開発環境としてVSCodeを利用するという点に焦点を当てた解説となっております。
需要があれば詳細な設定関連についても解説できればと思います。
AI駆動開発(AI-Driven Development)について学ぶ

# はじめに

最近、AIを使用したシステム開発が盛んになってきています。個人的にもGithub Copilotを使っており、コーディングするときはとても便利だなと感じています。

コーディング時の補助的な役割でAIを利用しているのですが、要件定義や設計時など開発のすべてのフェーズにおいて、生成系AIやLLMを使用する開発手法・思想「AI駆動開発」というものが出てきています。

今回は、AI駆動開発について調べた内容をアウトプットしていきたいと思います。

参考サイト

https://www.ai-driven.dev/

# AI-Driven Developmentとは

## 概要

- 開発のすべてのフェーズで生成系AIやLLMを利用
- プロダクトの企画からリリースまでの速度を上げる

# 自律型人工知能ツール

## Devin

- 自律型AIソフトウェアエンジニア
- 機能の実装からバグ修正に至るまで実行できる
- サポート役ではなく、自ら判断して実行する
- GPT-4や他の生成系AIとは一線を隠す機能
- 人間はDevinにチャットのようにプロンプト(指示文)を送るのみ
- 大規模言語モデル（LLM）の微調整も可能
- フリーランス向けの仕事をすることもできるみたい
- 開発効率化、コストダウン、システム提供の速度向上ができる
- Open Devinでオープンソース版もある

Devin

https://www.cognition.ai/blog/introducing-devin

## AutoDev

- Microsoftが開発している自立形AIエージェント
- 自動化された開発フレームワーク
- 自立、汎用性、拡張性
- 開発環境やリソースに直接アクセスして操作する
- 業務知識は必要で、フィードバックを求められる
- 幅広いプログラミング言語に対応
- 特定の環境内で動くのセキュリティとプライバシーを保証する
- 用途
    - コード生成
    - リファクタリング
    - ドキュメンテーションの自動化
    - テスト自動化、品質向上
    - バージョン管理

AutoDev(論文)

https://arxiv.org/html/2403.08299v1

# フェーズごとに使用するツール
## 要件定義

LLMを使用して要件を洗い出す

- ChatGPT
- Bard
- Copilot

## UI設計

AIとの対話によりUIを設計していく

- create.xyz
    - AIにプロンプトで指示するだけでアプリを作れる
    - コードを生成してくれる
- vo
    - 開発元はVercel。(Next.jsの開発元)
    - ウェブサイトのUIのデザインとコード生成を対話しながら行う
    - Reactコードで生成
- uizard
    - UIデザインツールで、経験がなくても美しいデザインを作成できる
    - テキストプロンプトや手書きのワイヤーフレームから作れる
- Visily
    - スクリーンショットやテキスト、スケッチからデザインを作成できる
    - テンプレートもある
- tldraw
    - オープンソースのホワイトボードアプリ(無料)
    - 手書きのラフスケッチや画像からサイトやアプリのデザインが作れる
    - コード生成も可能

## ソフトウェア設計

要件から基本設計や詳細設計をドキュメントで作成する

エンジニアはレビューして、LLMと会話して更新する

- ChatGPT
- Bard
- Phind
    - 開発者向け

## コーディング

LLMがソフトウェア設計、UI設計を元にコードを生成する

言語やフレームワーク、コーディングスタイルを指定する

エンジニアはレビューする

- GitHub Copilot
- Cursor
    - VScodeをもとにしたエディター
    - AI機能を活用できる
- Amazon Q Developer

## テスト

LLMがテストのベースを作成する

エンジニアはレビューしてテスト観点をLLMに伝える

- GitHub Copilot
- Cursor
- ghostest
    - ローカルPCで動くテストコード自動生成LLMエージェントツール

# まとめ

今回はAI駆動設計について簡単に調べてアウトプットしました。
これまであまりAI関連はちゃんと調べていなかったので、調査したり、実際に使用していきたいと思います。
SayoDevice O2L RGB, PID:3, VID:32905

# SayoDevice O2L RGB, PID:3, VID:32905 の簡易メモ

SayoDevice 上での SayoDevice O2L RGB, PID:3, VID:32905 の認識および設定項目を簡易にメモします。

## 外観

### 製品外観

![SD_O2L_RGB_3_32905_91.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105739/820fff01-8436-3078-0d57-0b50dc9c4da1.jpeg)

## SayoDeviceの簡易説明

- [SayoDevice 概要](https://qiita.com/igapyon/items/94a5d4b7baf9fd1cbc6e)

## SayoDevice で設定確認

### sayodevice.com に接続

Chrome で以下のURLに接続します。

- https://app.sayodevice.com/

### USB接続直後のWebブラウザ許可画面

![SD_O2L_RGB_3_32905_00-PermitDevice.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105739/f9339ae3-e396-d4bc-9e99-d3918d600714.png)

### Webブラウザで 該当の SayoDevice対応ハードウェア を選択

- PID:3
- VID:32905

![SD_O2L_RGB_3_32905_01-SelDevice.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105739/50df8eb9-8fff-47d7-3c6a-bc23dd2f24fb.png)

### Buttons タブの内容

![SD_O2L_RGB_3_32905_02-Button.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105739/a813b0ab-6ce9-9f29-4fbb-ea7ae7bbc28d.png)

### Button で選択可能な mode

![SD_O2L_RGB_3_32905_03-Modes.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105739/5ef93385-e99a-fa92-da32-c7f6acf9bdd3.png)

- Default
- tap or hold
- Mouse mode
- num lock virtual multilayer
- Two-step operation
- Multimedia control
- ??? 多媒体
- gamepad controller
- keyboard + LED control
- lock-self mode 
- A+B+C+D
- Cycle input
- custom mode(Do not use)

### Device Options

![SD_O2L_RGB_3_32905_04-DeviceOption.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105739/f4af0b43-0cf6-5245-a04a-7cee3cf5d4a3.png)
Pygameを使って RPGを作る（2. Surface）

# 概要
本記事はSurfaceについて解説する
Surfaceとは、日本語で表面という意味で、GameWindowが舞台だとしたら、舞台の幕のようなものだと思います。

# 使い方の例
公式には、このようなものしかない。
Surface((width, height), flags=0, depth=0, masks=None) -> Surface
Surface((width, height), flags=0, Surface) -> Surface

やはりちょっとわからない
ともかく、サイズ（横、縦）を指定し、定義する
```py
SURFACE_SIZE = (100, 100)
# Surface((width, height), flags=0, depth=0, masks=None) -> Surface
self.test_surface = pg.surface.Surface(SURFACE_SIZE)
```
次に、
Surfaceを表示させる(blitメソッド)（ビルドの略称？）

```py
# blits(((source, dest, area), ...)) -> [Rect, ...]
# self.display_surfaceはメインWindowのSurface
self.display_surface.blit(self.test_surface,(100, 100))
```
これで真っ黒なSurfaceが表示される

もう一つ、fillメソッドを使うとSurfaceに色で塗ることができる
```py
self.test_surface.fill(RED)
```

今回の完成例
（Surface表示するだけだと面白くないので、ピンポンみたいに左右並行移動を繰り返す）
```py
import pygame as pg
from settings import *

class game:
    def __init__(self):
        pg.init()

        # screen
        self.display_surface = pg.display.set_mode((WIDTH, HEIGHT))
        # title
        pg.display.set_caption(TITLE)
        # clock
        self.clock = pg.time.Clock()
        self.running = True

        # surface
        self.test_surface = pg.surface.Surface(SURFACE_POS)
        self.test_surface.fill(RED)

    def run(self):
        """ゲームループ"""
        dt = self.clock.tick(FPS) / 1000

        dx = 0
        direction = 1
        while self.running:
            # イベント処理
            for event in pg.event.get():
                if event.type == pg.QUIT:
                    self.running = False

            # draw
            self.display_surface.fill(BLUE)

            dx = dx + direction*1 
            if dx >= WIDTH:
                direction = -1
            elif dx <= 0:
                direction = 1
            self.display_surface.blit(self.test_surface,(dx, 100))

            pg.display.update()

        pg.quit()

if __name__ == "__main__":
    new_game = game()
    new_game.run()
```
![uploading...0]()


### 補足
1. 今回はメソッドの説明のため、クラス化はしていない。
2. scrollメソッドを使えば、無限スクロールを作れるが、今回は。横スクロールは用いないので、スキップする。
SayoDevice 2x6F RGB, PID:8, VID:32905

# SayoDevice 2x6F RGB, PID:8, VID:32905 の簡易メモ

SayoDevice 上での SayoDevice 2x6F RGB, PID:8, VID:32905 の認識および設定項目を簡易にメモします。

## 外観

### 開封直後の製品外観

![SD_2x6F_RGB_8_32905_91.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105739/4931f9dd-d704-7afe-bed4-1077d1bfb99b.jpeg)

### 色設定後の外観例

![SD_2x6F_RGB_8_32905_92.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105739/7bc29bf2-8b0c-3de3-2a8b-2af49d76c518.jpeg)

## Amazon 上での商品名

- BTXETUEL 12キーメカニカルゲーミングキーボード
    - https://www.amazon.co.jp/dp/B0BBS3D3JV
    - キーボード側のコネクタ種別: USB-C

## SayoDeviceの簡易説明

- [SayoDevice 概要](https://qiita.com/igapyon/items/94a5d4b7baf9fd1cbc6e)

## SayoDevice で設定確認

### sayodevice.com に接続

Chrome で以下のURLに接続します。

- https://app.sayodevice.com/

### Webブラウザで 該当の SayoDevice対応ハードウェア を選択

- PID:8
- VID:32905

![SD_2x6F_RGB_8_32905_01-SelDevice.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105739/efce071d-e35d-4b40-3b24-136669553075.png)

### Buttons タブの内容

![SD_2x6F_RGB_8_32905_02-Buttons.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105739/0c9b3142-3656-0002-2f1e-dd286b71ff9b.png)

### Button で選択可能な mode

![SD_2x6F_RGB_8_32905_03-Modes.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105739/d79adf27-1db0-2b9a-34b7-8ec4bf07dd91.png)

- Default
- Keyboard
- mouse
- Multimedia control
- tap or hold
- tap or hold (Multimedia)
- Two-step keyboard operation
- keyboad + LED control
- gamepad controller
- A+B+C+D
- Cycle input
- One-click password
- one-click webpage
- one-click Write poetry
- FN
- SW
- control_option
- key to axis
- User Script 1 - 64
- Extended script


### Device Options

![SD_2x6F_RGB_8_32905_04-DeviceOptions.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105739/fd6442f6-661f-767f-34c8-b178c1416340.png)
Reactを使ってブログサイトを作る 11 - プロジェクトのビルドと最適化

https://github.com/KyleAndKelly/ArticleHub-React
## プロジェクトのビルド

### 1. プロジェクトのビルド
- ビルドとは、プロジェクト内のソースコードとリソースファイルを処理し、プロダクション環境で実行できる静的ファイルを生成するプロセスです。
- ビルドコマンド：`npm run build`
- `build`ディレクトリが生成されます。

### 2. ローカルプレビュー（ローカルサーバーでプロジェクトを実行）
- ローカルプレビューとは、ローカルで静的サーバーを使ってプロダクションサーバーを模擬し、プロジェクトを実行するプロセスです。
- 1. ローカルサーバーパッケージをインストール： `npm i -g serve`
- 2. ローカルサーバーを実行： `serve -s build`
- 3. ブラウザでアクセス： `http://localhost:3000/`

## ビルドの最適化
### 1. ルートの遅延読み込み（Lazy Loading）の設定
- ルートの遅延読み込みとは？
  - ルートのリソースは、実際にアクセスされたときにのみ動的に取得されるもので、プロジェクトの初回読み込み時間を最適化することが目的です。
- どうやって設定する？
  - 1. ルートをReactが提供する`lazy`関数を使って動的インポートに変更します。
  - 2. React内蔵の`Suspense`コンポーネントで、ルートの`element`オプションに対応するコンポーネントをラップします。
  
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3916068/edb523a4-83ce-bb2b-0117-ff9c0a6fbb03.png)

### 2. ビルドサイズ分析
#### ビジネスの背景
- ビルドサイズを分析することで、プロジェクト内のどの部分がサイズが大きいかを把握し、最適化すべきパッケージを特定することができます。

#### 使用手順
- ビルドサイズを分析するパッケージをインストール： `npm i source-map-explorer`
- `package.json`の`scripts`タグに、ビルドサイズ分析コマンドを追加します。
  - プロジェクトをビルド： `npm run build`（すでにビルド済みの場合は省略可）
- 分析コマンドを実行： `npm run analyze`
- ブラウザで開いたページで、グラフ内のパッケージのサイズを分析します。

### 3. CDNの設定

#### CDNとは？
- CDN（Content Delivery Network）は、コンテンツ配信ネットワークサービスで、ユーザーがウェブサイトのコンテンツをリクエストしたとき、最寄りのサーバーからキャッシュされたリソースをユーザーに提供します。

#### どのリソースをCDNサーバーに置くか？
- サイズが大きい、業務外のファイル（例：react、react-dom）
  - 1. サイズが大きく、CDNのブラウザキャッシュ機能を利用して読み込み時間を短縮できるファイル。
  - 2. 業務外のファイルで、頻繁に変更されないもの。CDNは頻繁にキャッシュを更新しなくてよいため。

#### プロジェクトでの実装方法
- 1. CDNでキャッシュする必要のあるファイル（例：react、react-dom）をビルドから除外します。
- 2. CDNの方法で、リソース（例：react、react-dom）を再度インポートします。
タスク管理がしっくりこなかった私が、NotionでKPI管理ダッシュボードを作ってみた話

## はじめに

タスク管理ツールって、使いこなせている人を見るとすごく憧れるんですよね。
でも実際に導入してみると、かえって負担になってしまって長続きしない...

TODOアプリやObsidianなど渡ってきましたが、
結局最近はこんな感じでやっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3945028/ab735b13-1216-85cd-ef33-01c2a1d801be.png)


特に会社のKPI管理となると、全社共通のGoogleスプレッドシートのテンプレートで管理していて、日々の記録や振り返りがしづらいと感じています。（個人の浅い階層の意見です…）

そんな中で、あるNotionのタスク管理テンプレートと出会い、これをベースに自分専用のKPI管理ダッシュボードを作ってみることにしました。

## なぜNotionを選んだのか

- :point_up_tone2:見た目が好き＆気分が乗りそう　←　１番大事
- :tools: KPIや目標管理系の公開テンプレートが豊富
- :tools: モバイルからもアクセスしやすい
- :tools: ブロックやデータベース機能が柔軟
- :tools: なんだか会社で導入されそうな香りがする

## ピンときたテンプレート
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3945028/cc975e0d-465c-193f-896c-65760ea9ff98.png)

https://youtu.be/DATxyiyNqvU?si=ImwgCSOrBhtmeI9o

特に気に入ったポイントは、動画内で解説されている「GTD手法」なるものでタスクステータスを直感的に操作できる点。（カンバン形式に変更しました）
これだけだとよくある話のように聞こえるけど、「手軽に雑多にメモできる」＆「ちゃんと管理できてレビューしやすい」のセットはあまりないと思います。

## :thinking:カスタマイズのアプローチ
### 目的の整理
まずは目的を整理しなければ。

【実現したいこと】
- 今やるべきタスクが見える
- タスクになる前の雑多なメモをストックできる
- 週次、月次のレビューがしやすい
    - （前提）評価はKPIの達成度と行動指針への貢献度が主役
        - タスクはKPI指標と紐づける
        - タスクは行動指針と紐づける
    - レビューための実績整理の負荷を少なくしたい
    - タスク実行結果の累積がそのままレビュー時にデータとしてまとまっていると良い

構築が複雑な部分はすでにテンプレートがやってくれていたので
私の場合、以下の方針でカスタマイズを進めることにしました。

:bulb:
1. **基本構造の維持**：テンプレートの基本的な構造は活かす
2. **KPI指標の追加**：会社の目標に合わせた指標を追加
3. **振り返りの強化**：週次・月次での振り返りがしやすいよう、データの可視化を工夫

## :pushpin:KPI指標の追加
タスクはKPI指標を達成するために発生するケースが多い？
そうであれば、タスクを作成するときに見えていたほうがいいのかな。

→タスク（雑多メモ）作成はモバイルからウィジェット経由で作成するから
思いついたことをどんどん登録していくよ。

なら、やるやらないの振り分けの際に紐づける流れがいいね。

## :gem:振り返りの強化
レビューための実績整理時間をできるだけ削減し、
タスク実行結果の累積がそのままレビュー時にデータとして閲覧できる状態を目指し
振り返りDBに月次レビューテンプレートを追加しました。

### 内容
目標/指針・進捗状況・実績を表示することで、
「何を目指して、何をしてきたか。今どれだけの距離にいるか」
を視覚的に把握しやすくしたい。
#### 目標/指針
- **表示する内容**：自身の中長期キャリアビジョン、組織としての目標
    - タスクとは別で、指針となるものをまとめるDBに入れるのがおすすめ。（KPI指標DBなど）

#### 進捗状況
- **表示するDB**：KPI指標DB
- **フィルタ**：今期のKPI
- **表示カラム**：進捗率、関連タスク
- **その他**：進捗率は関連タスクのステータスで測定する

:::note info
Notionのチャート機能を効果的に使っていきたい。
:::

https://www.notion.com/ja/help/guides/charts-visualize-data-track-progress-in-notion

#### 実績
- **表示するDB**：タスクDB
- **フィルタ**：実行日が今月のタスク
- **その他**　：行動指針との紐づけもここで表現したい

#### NEXTアクション
今月の結果をふまえ、来月どうするか。
ここはデータをもとに来月のアクションを決めるとこなので整理時間が必要になるセクション。
ただ、生成AIと議論して決めるのもとてもアリだと思います。

## まとめ
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3945028/c83674c4-1cee-cbfe-6c95-116377085468.png" width=20%>

せっかく頑張るなら、「効果的に」「モチベ上げて」自身が今やっていることの背景や目的を理解したうえで頑張っていきたい。
そのための１つのアプローチとしてタスク管理をNotionでチャレンジしてみます。
という２０２５年に向けた準備でした。

Notionオートメーション機能もかなり有能そうなので有料契約を検討中…

https://www.notion.com/ja/help/guides/category/automations
Reactを使ってブログサイトを作る 09 - 画像のアップロード

https://github.com/KyleAndKelly/ArticleHub-React
## 画像アップロードの静的構造
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3916068/4d2a66d2-9a94-936c-cac5-0bb3ea1f36d8.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3916068/f75ee5f3-4ead-c2a0-6c42-3e487ff17603.png)


## 画像アップロード機能の実装
- Uploadコンポーネントに`action`属性を追加し、カバー画像のアップロードインターフェースのURLを設定
- Uploadコンポーネントに`name`属性を追加し、インターフェースが要求するフィールド名を指定
- Uploadに`onChange`属性を追加し、イベント内で現在の画像データを取得してReactの状態に保存
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3916068/821eb420-3f7e-c07b-4985-3d51055ba826.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3916068/2b99161c-a6dd-db27-d2e1-7bdfed5564ee.png)

## アップロードアイコンの表示・非表示の制御
- ユーザーが選択したカバー画像の数に応じてアップロードコンポーネントの表示を制御
- つまり、ユーザーが「No pic」を選択した場合、アップロードアイコンは表示されず、それ以外の場合には表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3916068/3692048c-60f3-4f79-4dad-579a0be355d4.png)

## 最大アップロード画像数の制御
- `maxCount`属性を使用して、画像のアップロード可能な数を制限
- 例えば、ユーザーが「1 pic」を選択した場合、最大で1枚の画像しかアップロードできず、「3 pic」を選択した場合、最大で3枚の画像のみアップロードできるように制限
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3916068/08c0ad57-c953-383b-db04-b926b1cae0bb.png)

## 画像付きの記事を投稿
- まず、画像の種類と数量が一致するかを検証
- 次に、画像リストをインターフェース形式に変換

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3916068/cba52d6a-6d3e-9520-e51e-d60bab31327a.png)