OmniAICreator/Qiita-1.07M huggingface dataset:
Raspberry Pi Pico W のWi-Fi設定をBLE経由で手軽に行う方法

ESP32やNordicのnRFシリーズなど主要なマイコンプラットフォームでは公式のBLE経由のWi-Fi設定（Provisioning）ツールが提供されています。しかしRaspberry Pi Pico Wには同様の設定ツールは提供されていません。本記事では、BLE経由でPico WおよびPico 2 WのWi-Fi設定（SSIDやパスワード）を行うシンプルな実装を紹介します。つまり、ついカッとなって書いた。


実装には、pico-sdkを利用しています。次のリポジトリでコードを公開しています。

https://github.com/oyama/pico-ble-wifi-provisioning


## 実装した機能

- BLEを使用してWi-FiのSSIDとパスワードを設定できます
- DHCPで割り当てられたIPアドレスをBLEで取得できます
- Just Worksでペアリングします(暗号通信しますが、認証はしていません)
- 専用アプリではなく、汎用の[LightBlue](https://punchthrough.com/lightblue/)などの一般的なBLEデバッグアプリで設定できます

## 使い方

- リポジトリのファームウェアを書き込んだPico Wを起動します
- 汎用BLEデバッグアプリでPico Wに接続します
- 専用のGATT Characteristicを通じてSSIDとパスワードを送信します
- 接続に成功するとオンボードLEDを点灯します
- DHCPで取得したIPアドレスはBLE経由で確認できます

| Characteristic Name | UUID                                   | Description                    |
|---------------------|----------------------------------------|-----------------------------------|
| SSID                | `BE3D7601-0EA0-4E96-82E0-89AA6A3DC19F` | Wi-Fi SSID (read/write)           |
| Password            | `BE3D7602-0EA0-4E96-82E0-89AA6A3DC19F` | Wi-Fi password (write only)       |
| IP Address          | `BE3D7603-0EA0-4E96-82E0-89AA6A3DC19F` | Acquired IP address (read/notify) |

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108691/9b851e79-7e11-4414-8478-cc2c31b9529c.png" width=600/>

こういうツールは公式が用意してくれていればみんな幸せなんですけどね。
Webpackについてまとめる

TypeScript、React、Nextを使ったWebアプリケーションに関して、
本番環境でWebpack周りのエラーが発生したので、これを機にWebpackについて勉強してみる

2025/3/29
メモ程度に作ったやつなので、参考にならない可能性高いです。
[他の方が作成してくれた参考になる記事はこちら](#参考)。

## Webpackって何？(ざっくり)
- 複数のJavaScriptファイルを一つのファイルにまとめる**ツール**のこと
- バンドル
    - 一つのファイルにまとめること
- モジュールハンドラ
    - モジュールを一つのファイルにまとめて出力する**ツール**のこと

## Webpackがあると何が嬉しい？
複数のJavaScriptを一つにまとめることで、ブラウザからのリクエスト数を減らし、ファイル転送の最適化が可能となる
つまり、Webpackがあると、以下のことができる
- 開発時は機能をファイルごとに分割することができる
- 実行時は一つのファイルとしてブラウザに提供することができる

## TypeScriptを使ってバンドルしてみる
1 必要なパッケージをインストールする
```shell
npm install --save-dev babel-loader @babel/core @babel/preset-env @babel/preset-react @babel/preset-typescript
```

2 webpack.config.jsの設定をする
```javascript: webpack.config.js
const path = require('path');

module.exports = {
  mode: 'development', // または 'production'
  entry: './src/index.tsx', // 適切なエントリーファイルを設定してください
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },
  resolve: {
    extensions: ['.ts', '.tsx', '.js', '.jsx'],
    alias: {
      '@': path.resolve(__dirname, 'src'),  // 適切なエイリアスを設定してください
    },
  },
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        exclude: /node_modules/,
        use: 'ts-loader',
      },
    ],
  },
};
```
3 バンドルしてみる
```shell
npx webpack
```

4. バンドルすると、以下のファイルが出来上がる
```
├── dist
│   └── bundle.js
├── node_modules
├── package.json
├── src
│   ├── app
|        ├── page.tsx
```

## 参考
https://dev.to/bruno8moura/why-am-i-using-the-webpack-tool-4h14

https://zenn.dev/oreo2990/articles/8581ad93276f0c

https://qiita.com/chihiro/items/ca1529f9b3d016af53ec
📝 【AI活用】PHPerKaigi 2025 レポート - PHP開発者の祭典を詳細にまとめました

## 📋 はじめに

PHPを使っているエンジニアなら一度は参加してみたい「PHPerKaigi」。
しかしわたくし参加できませんでした。
少しでも実際の雰囲気や内容を感じ取るため、AIをフル活用して効率的に情報収集・レイアウトして
2025年の開催内容をまとめた記事です。
今回は最新の複数AI技術を活用して情報をまとめました。

:::note info
**✨ 本記事のナレッジ作成方法**  
- **ChatGPT GPT4o & DeepSearch**：情報収集・一次ソース確認
- **Claude 3.7 Sonnet**：収集情報をHTML形式でレイアウト・まとめ
 - **Cursor**：情報精査・最終チェック
:::

PHPerKaigi 2025の会場の様子、注目セッション、ライトニングトーク、交流企画など、
実際に参加した方々の情報をもとに構成しています。

---

## 🖥️ PHPerKaigi 2025 レポート (CodePen埋め込み)
▼ 直接フルスクリーンで表示したい方はこちら  
https://codepen.io/yu-tama/full/KwKBwWK

<p class="codepen" data-height="1200" data-default-tab="result" data-slug-hash="KwKBwWK" data-pen-title="PHPerKaigi 2025 レポート" data-user="yu-tama" style="height: 1200px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/yu-tama/pen/KwKBwWK">
  PHPerKaigi 2025 レポート</a> by yu tama (<a href="https://codepen.io/yu-tama">@yu-tama</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://public.codepenassets.com/embed/index.js"></script>

---

## 📊 PHPerKaigi 2025の概要

<details>
<summary>📅 イベント基本情報（クリックで展開）</summary>

PHPerKaigi（ペチパーカイギ）とは、PHPが好きで現在使っている人はもちろん、過去に使っていた人やこれから使いたい人まで、PHPエンジニア同士が技術ノウハウと「PHP愛」を共有する年次イベントです。

- **開催日**: 2025年3月21日(金)〜23日(日)
- **会場**: 中野セントラルパークカンファレンス & ニコニコ生放送
- **形式**: オフライン・オンラインハイブリッド開催
- **参加者**: PHP開発者、エンジニア、技術者など多数

</details>

### 🌟 イベントの特徴

```mermaid
graph TD
    A[PHPerKaigi 2025] --> B[技術セッション]
    A --> C[ライトニングトーク]
    A --> D[コードバトル]
    A --> E[交流企画]
    B --> F[レガシーリプレイス]
    B --> G[PHPアーキテクチャ]
    B --> H[金額計算処理]
    B --> I[FrankenPHP]
    C --> J[5分間の濃密トーク]
    D --> K[競技プログラミング]
    E --> L[ノベルティ交換]
    E --> M[スポンサーブース]
    E --> N[PHPerチャレンジ]
```

---

*本記事のコンテンツはAIを活用した情報収集・整理によって作成されています。正確性には努めていますが、最新の情報は公式サイトをご確認ください。*
自分用メモ（React）

※自分用メモですが、「これからはじめるReact実践入門」を参考に勉強中のメモなので、この本に掲載されているサンプルコード等を引用してる場合があります。
※細かい用語については、特に自分にしか通じない言葉もあるので、つっこまないで…

webpacks
Babel：JSXを読み込むやつ

# JS

# React Developer Tool
Chromeとかのプラグイン。あると便利。

# React Sample
#### 繰り返し処理
``` index.js
  // ForListは自作のクラス。src=の{}はJSXにJavascript構文を埋め込むためのやつ。
  // booksはbooks.jsで定義してここでインポートしたオブジェクト。
  // src={books}と書くことで、Babelさんが{src: books}というオブジェクトに変換してるらしい。
  root.render(
    <ForList src={books} />  
  );
  ```
``` ForList.js
// ここで、srcはArray。
// Babelさんが引数を{src: books}という形で渡してくるので、そのうちsrcを直に受け取るためにForList({src})とする。
export default function ForList({src}) {
    // このreturnの後の()はJSXをひとまとめにするための()。
    // なのでJavascriptの構文ではない。1行で書くなら省略できるけど、複数行書きたければ()でくくるのだと。
    return(
        <dl>
        {
            src.map(elem => (
                <>
                    <dt>
                        <a href={`https://wings.msn.to/book/${elem.isbn}/${elem.isbn}.jpg`}>
                        {elem.title} ({elem.price}円)
                        </a>
                    </dt>
                </>
            ))
        }
        </dl>
    )
}
```

# PropsとState
コンポーネントを支える基礎となる概念らしい。
どこ用語？？（AI曰く、React用語だそうな）

コンポーネントは画面を構成する部品という理解でいいかな。

Propは値を渡すためのもので、Stateは状態を記述するためのもの。

以下のコードのsrc={books}がProps。
伝統的にこのオブジェクトの名前をpropsというけど、実際は名前はないでもよい？？見たい。
``` index.js
  // ForListは自作のクラス。src=の{}はJSXにJavascript構文を埋め込むためのやつ。
  // booksはbooks.jsで定義してここでインポートしたオブジェクト。
  // src={books}と書くことで、Babelさんが{src: books}というオブジェクトに変換してるらしい。
  root.render(
    <ForList src={books} />  
  );
  ```

### props.childrenプロパティ
呼び出し側の子要素を取得できる。
Reactでは複数のchildrenを渡せないから、渡したいなら工夫が必要？？？

### RenderProps
描画のための関数を表す総称としてこう呼ぶみたい。
一旦以下は儀式だと思おう。
```const [count, setCount] = useState(0);```


### 情報伝達
親コンポーネントから子コンポーネントへの情報伝達はPropsで行い、逆はStateで行うのだそうな


# コメント
```.jsx
const tag = (
  // コメント。ここはまだJavascriptの世界かな？
  // 次の行からJSXの世界が始まる。
  <ul>
    {/* コメント。JSXの世界なので、一旦Javascriptの世界に戻してあげてコメント */}
    <li // だけれど、タグのなかならコメントできるんだって。
      >React</li>
    <li /*
       複数行コメントもいけるみたい。
    */>Vue.js</li>
  </ul>
);
```
django のエラーハンドリング

django のエラーハンドリングのメモ。

# やりたいこと
- エラー発生時にエラーをログに出力
- エラー発生時に独自のレスポンスを返却

# 準備
app1 というアプリケーションで 'api/' で json を返却する API を作成します。
```bash:
django-admin startproject app1
cd app1
python manage.py startapp api
```

# プログラム例
## urls.py
urls.py 内に handlerXXX に独自のエラーハンドラを設定します。
```python:app1/urls.py
from api.views import hello, error
from .views import error_handler400, error_handler404, error_handler500

urlpatterns = [
    path('api/hello/', hello),
    path('api/error/', error),
]

handler400 = error_handler400
handler404 = error_handler404
handler500 = error_handler500
```


## エラーハンドラ
上記の urls.py に指定した error_handlerXXX を app1/views.py に定義しました。
stderr とログファイルにログを出力するようにしています。
```python:app1/views.py
import sys
import traceback
from django.http import JsonResponse


def error_handler400(request, exception):
    sys.stderr.write(f"{__name__} error\n")
    sys.stderr.write(f"traceback:\n{traceback.format_exc()}\n")

    return JsonResponse({"status": 400, "message": "bad request"}, status=400)


def error_handler404(request, exception):
    sys.stderr.write(f"{__name__} error\n")
    sys.stderr.write(f"traceback:\n{traceback.format_exc()}\n")

    return JsonResponse({"status": 404, "message": "not found"}, status=404)


def error_handler500(request):
    sys.stderr.write(f"{__name__} error\n")
    sys.stderr.write(f"traceback: {traceback.format_exc()}\n")

    return JsonResponse({"status": 500, "message": "internal server error"}, status=500)
```


## API 例
```python:api/views.py
import sys
from django.http import JsonResponse


def hello(request):
    sys.stderr.write(f"hello()\n")
    return JsonResponse({"message": "Hello"})


def error(request):
    sys.stderr.write(f"error()\n")
    raise Exception('error')
    return JsonResponse({"message": "Hello"})
```

# 実行例
## サーバ起動
```bash:
python manage.py runserver
```

## API へのアクセス (エラーなし)
```bash:リクエスト
curl 'http://127.0.0.1:8000/api/hello/'
```
```text:レスポンス
{"message": "Hello"}
```

```text:stderr
hello()
```


## API へのアクセス (エラー発生)
/api/error/ では raise で例外を発生させていますので、エラーハンドラの error_handler500() でエラーが返却されます。
```bash:リクエスト
curl 'http://127.0.0.1:8000/api/error/'
```
```text:レスポンス
{"status": 500, "message": "internal server error"}
```

エラーハンドラでは stderr にログを出力しています。
```text:stderr
error()
error1.views error
traceback: Traceback (most recent call last):
  File ".../site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File ".../site-packages/django/core/handlers/base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../app1/api/views.py", line 15, in error
    raise Exception('error')
Exception: error
```
【論文流し読み】2024_A Survey on LLM-as-a-Judge

 https://arxiv.org/abs/2411.15594

# LLM as a judgeとはなにか。  
LLMを用いて、
LLMへのインプットとLLMの出力から、出力物の評価を出力するシステム。  
  
# タスクの学習方法  
通常、タスクの定義にはIn context learningが使われる。  

### スコア生成  
何点ですか？と聞く。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3909060/8828d365-747e-4b2f-8b6f-c8de77f72a5e.png)


### Yes / No question    
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3909060/f28c31e5-75b1-4b44-a1e4-6d53485d06f3.png)


### ペアワイズ比較  
どちらがいいですか？と聞く。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3909060/6c550949-7d93-4582-96af-082a4433a18b.png)  
  
### 選択制の問題  
それが当てはまりますか？を聞く。  

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3909060/ddae4678-b3ec-4264-b3af-e055abb04bee.png)

# LLM as a judgeの実践  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3909060/dcc5396f-0d25-4e58-88ea-769de4686d01.png)
  
全体としては、手元にあるground truthへの評価と、新たな事例を得ての再評価を実施することで  
改善を図っていく。  
  
# 改善戦略  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3909060/e1da7bd7-781c-487f-a0e8-93c812dcf3c8.png)

### Optimizing Output Forms  
そのままスコアを出させようとすると、フォーマットに沿わない出力をしたりするので、構造化された出力を要請するなどして出力を安定させる。  

### Integration of multiple Evaluation results  
偶発的なエラーやランダムの影響を軽減するために、複数回出力の結果を集計（平均など）する。  

### DirectOptimizationofLLNPutputs  
出力スコアに後処理を加えることで、指標としてより最適なものにする。  
(スコア平滑化など)  

# 評価器の指標  
## 基本指標  
### アラインメント  
人間の評価と評価器の評価が一致した割合  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3909060/6c0b4ebd-e252-4870-9824-ff11c97f70c3.png)

（ほかには、CohenのKappaやスピアマンの相関係数など。）  

## バイアス  
バイアスの無い評価ができているか？
- ポジションバイアス(特定の位置にある応答を好む傾向)  
- 長さバイアス（長い / 短い応答をより好む）  
- 自己高揚バイアス(自分の作成した文章をより好む)
    - 評価者と同じモデルを用いない、などの工夫が必要 
- そのほかのバイアス  
    - 性別、人種、性的指向
    - （絵文字など）視覚的に魅力的なコンテンツ
    - 具体性バイアス（権威のある情報源、数値をより好む）
        - 権威バイアス、引用バイアスとも。
    - 感情バイアス
        - 怒り、悲しみなど特定の感情を好む傾向  

## 敵対頑健性  
高いスコアを得ることを目的に作られた入力にモデルが耐える能力
dockerメモ

--------------------
dockerメモ
--------------------
イメージとは・・・
コンテナに必要なソフトウェア、環境変数、設定などの情報が入ったコンテナの型となるもの
イメージは、dockerHubからダウンロードすることもあればDockerfileなど自分用にカスタマイズしたイメージを使うこともある。

コンテナとは・・・
イメージから作るもの。
コンテナにはステータス(created、up、exited)があり、作成直後はcreatedになり、起動状態の場合はup、起動してない場合はexitedとなる。
up<---->exitedの関係なのでいつでも起動と終了をすることが可能。
さらには不要なコンテナは破棄することも可能。

フォアグラウンドモード・・・
画面に表示されて起動している状態

デタッチドモード・・・
バックグラウンドで起動している状態

Dockerfileとは・・・
dockerのイメージを作る設計書にあたるもの

.dockerignoreファイルとは
ビルドコンテキストから除外することでCOPYコマンド時からもコピーの対象外となる

----------------------------------------
dockerの基本操作
----------------------------------------
1.初めてのコマンド
　※イメージがない場合はイメージをダウンロードしてコンテナを起動する
```
docker container run hello-world
```
2.イメージをダウンロード
```
docker image pull {イメージ名}
```
3.イメージを一覧表示
```
docker image ls
```
4.イメージを削除
```
docker image rm {イメージ名}
```
5.イメージからコンテナを作成し起動するコマンド
```
docker container run {イメージ名}

例)
docker container run -it ubuntu:20:04
※オプション i: 標準入力を許可
※オプション t: コマンドの見た目をきれいにする
```

6.全てのコンテナ（実行中および停止中）を一覧表示
```
docker container ls -a
```

7.起動中のコンテナを停止
```
docker container stop {コンテナ名}
```

8.コンテナを再起動
```
docker container restart {コンテナ名}
```

9.ログを確認
```
docker container logs {コンテナ名}
```

10.コンテナを破棄(※停止しているコンテナのみコマンドが使える)
```
docker container rm {コンテナ名}
```

11.upしているコンテナを削除(強制削除)
```
docker container rm -f {コンテナ名}
```

12.イメージの詳細を表示
```
docker image inspect {イメージ名}
```

13.コンテナのデフォルトコマンドを任意のコマンドで上書き実行
```
docker container run -it ubuntu:20.04 {コマンド名}

例)
docker container run -it ubuntu:20.04 pwd
```

14.コンテナ名に好きな名前をつけて起動
```
docker container run --name {好きなコンテナ名} -it ubuntu:20.04
```
15.up状態のコンテナに任意のコマンドを実行させる
```
docker container exec {コンテナ名} {コマンド名}
```
16.停止済みのコンテナを一括で削除する(※起動しているコンテナは削除されない)
```
docker container prune
```
17.コンテナに対してコマンドを実行して直ちにコンテナを破棄したい場合
※コンテナとして残らないので便利
```
docker container run --rm {イメージ名} ls

例)
docker container run --rm ubuntu:20.04 ls
```
18.デタッチドモードで起動(オプションでdをつける)
※bashの場合はデタッチドモードを使うことはほぼない
利用する場面はnginxなど常駐させる必要がある用な場合デタッチドモードを利用する

```
docker container run --itd {イメージ名}

例)
docker container run -itd ubuntu
```
19.再度フォアグラウンドモードに戻したい場合
```
docker container attach {コンテナID}
```
20.dockerfileからイメージを作成
```
docker image build  -t {コンテナ名:タグ} {dockerfileのディレクトリパス}

例) -tオプション以降にリポジトリ名:TAGを指定することが可能
docker image build -t my-image:v1 .
```
学習記録アプリをアップデート（V3）: TypeScript, Jest Mock, Chakra UI の導入

# はじめに

学習記録アプリをアップデートしました
前回は色々な技術に触れた感動を記事にしましたが
今回はそこからさらに新しい技術を学んだ記録です。

🔽前回記事

https://qiita.com/ccc-chi/items/6a0a561808711c37282d


# 今回のアップデート

- **TypeScript** を導入して型を学ぶ
- **Jest の Mock** を活用してテストの効率化
- **Chakra UI** を採用してデザインの改善
- **React Hook Form** を導入してフォームを管理

を行いました。それぞれの変更点と学びを紹介していきます。


## TypeScript 導入

### なぜ TypeScript を導入したのか？
これまで JavaScript で開発していましたが、

- 型の恩恵を受けたい
- コードの保守性を向上させたい
- エディタの補完機能を活かしたい

という理由で TypeScript を導入しました。

### 実際に使ってみた感想
- **型が難しい！** でもハマるとサジェストがすごく便利
- **エラーが非同期で表示される** ので、JavaScript よりわかりやすい
- **初心者向きかも？** 型の学習コストはあるけど、長期的に見るとメリット大


## Jest と TypeScript 導入

### 導入で起きたトラブルと解決策
まずJestを導入した際にTypeScriptとの組み合わせでエラーが発生しました。
調べたところ、 Jest で TypeScript を使うには Babel の設定が必要でした。

#### **解決策：Babel を導入**
以下のコマンドで `@babel/preset-typescript` をインストールすることで解決しました。
また、テストファイルの拡張子は **.tsx** であることに注意する。
```sh
npm install --save-dev @babel/preset-typescript
```

参考にした記事:
- [Jest 公式ドキュメント](https://jestjs.io/docs/getting-started#using-typescript)
- [Qiita 記事](https://qiita.com/Kei-dev-1213/items/41257b3bd934d213dcad)
テストファイルの拡張子「.tsx」 と 「.ts」に注意する。それぞれ設定が異なる。

## Jest の Mock 導入

### なぜ Mock を導入したのか？
以前は Supabase に直接アクセスしてテストしていましたが、

- **テストの実行が遅くなる**
- **外部サービスの影響を受ける**

という問題がありました。そこで Jest の Mock を使い、API の動作を模擬することで、軽量で安定したテストができるようになりました。

### でも Supabase の関数はテストしなくていいの？
前回は直接supabaseにアクセスするテストでしたが、
今回はmockを使いsupabaseの関数をテストしないことを疑問に思ったので
ChatGPT に質問しました。

- **Jest はユニットテスト向き** → 関数単位の動作確認
- **E2E テスト（エンドツーエンドテスト）** → 実際の API 通信を含めたテスト

という使い分けがあるらしいです。まだまだ学ぶことが多そう！

## Chakra UI 導入

### なぜ Chakra UI を導入したのか？
以前は CSS や JavaScript でスタイルを管理していましたが、

- **コンポーネントベースで開発できる**
- **デザインが統一しやすい**
- **簡単にレスポンシブ対応が可能**

という理由で Chakra UI を採用しました。

### 実際に使ってみた感想
- **ボタンやモーダルが簡単に実装できた！**
- ただし、**細かい微調整の学習コストはありそう…**

### Chakra UI の表示速度は？
cssとjavascriptでモーダルを実装していた過去があるので、
簡単にできるのはいいけど、
chakraUI導入によるパフォーマンスをchatGPTに聞いてみました。

- **Emotion（CSS-in-JS）を使っているため、初回レンダリングは若干遅い傾向がある**
- ただし、**開発効率の向上を考えると許容範囲**

やっぱり使わない手はなさそう。
あとチーム開発での可読性や効率も良さそうだなと思いました。

## React Hook Form 導入

### なぜ React Hook Form を導入したのか？
以前は useState でフォームの状態を管理していましたが、

- **バリデーションを簡単に実装できる**
- **useState を使わなくてもフォームの状態を管理できる**

という理由で React Hook Form を導入しました。

### 実際に使ってみた感想
- **バリデーションが簡単に実装できた！**
- **フォームの状態管理が楽になった**（useState で管理する必要がなくなった）

### 導入で起きたトラブルと解決策

useState を使わなくなることにより
フォームの状態をどのように管理するか分かりませんでした

解決するまでの内容を記事にまとめました

https://qiita.com/ccc-chi/items/c871cd90fcb5632a249f

## まとめ

今回のアップデートで学んだこと

- **TypeScript** はエディタ補完が便利で初心者にもおすすめ！
- **Jest の Mock** でテストが軽くなった
- **Jest + TypeScript** の設定には Babel が必要
- **Chakra UI** で開発スピードが向上。細かいカスタマイズを要学習
- **React Hook Form** でフォーム管理が楽になった！

---

前回の記事と同様に、今回の学びが誰かの参考になれば嬉しいです！

今回のアプリの GitHub

https://github.com/ccc-chi/recordsAppV3

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

https://projisou.jp
個人用備忘録：OpenVPNでハマったので、未来の自分へのメモとしてアウトプットしてみた

## はじめに
OpenVPNは、オープンソースで提供されているVPNソリューションで、安全なトンネルを通じてリモートネットワークに接続できる仕組みを提供します。

:::note info
**個人の備忘録程度の走り書きとなっておりますが、温かい目で見守っていただければ幸いです。**
:::

テレワークや拠点間接続など、様々な場面で活用されているため、ここに基本設定や使用時のポイントを備忘録としてまとめておきます。

---

## 書こうと思ったきっかけ
自宅ネットワークから社内システムへ安全にアクセスする必要があり、OpenVPNを使って接続環境を構築しました。**設定ファイルの記述やポートの開放、証明書管理など、繰り返し確認することが多いため、記録として残しています。**

---

## OpenVPNの基本機能
- 安全なVPNトンネルの構築（SSL/TLS方式）
- クライアント-サーバーモードによる柔軟な構成
- 認証機構のカスタマイズ（証明書、ユーザー認証）
- ポートフォワーディング、ルーティング対応
- クロスプラットフォーム対応（Windows, Linux, macOS など）

**参考文献**

https://www.openvpn.jp/

---

## よく使うコマンド
```bash
# サーバー起動・停止（systemd）
sudo systemctl start openvpn-server@server
sudo systemctl stop openvpn-server@server
sudo systemctl restart openvpn-server@server

# クライアント接続
sudo openvpn --config client.ovpn

# ログ確認
sudo journalctl -u openvpn-server@server
```

**参考文献**

https://zenn.dev/tkrk/articles/d1e08b1331b61f

---

## 基本的な構成ファイル
- `/etc/openvpn/server/server.conf`：サーバー設定ファイル
- `/etc/openvpn/client/client.ovpn`：クライアント設定ファイル

## server.confの例（抜粋）
```conf
port 1194
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key
dh dh.pem
server 10.8.0.0 255.255.255.0
keepalive 10 120
persist-key
persist-tun
status openvpn-status.log
verb 3
```

**参考文献**

https://qiita.com/ghost-dog/items/841ae9418c248ca854de

---

## クライアント設定ファイル（client.ovpn）例
```conf
client
dev tun
proto udp
remote your-server-ip 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
cert client.crt
key client.key
remote-cert-tls server
verb 3
```

**参考文献**

https://qiita.com/SSMU3/items/bf82f76af9534b21da8c

---

## まとめ
OpenVPNはセキュアで柔軟なVPN構築を実現する優れたツールです。**証明書の発行や鍵管理、ネットワーク設定に注意しながら運用することで、安全な通信環境を実現できます。**

今後は、ユーザーごとのアクセス制限やWeb管理UIの導入、異常時の監視強化なども取り入れて、より実用的なVPN環境を整備していきたいと思います！
「因果推論の計量経済学」の書評【レビュー企画用献本御礼】

日本評論社様から「因果推論の計量経済学」を献本いただきましたので、書評を書かせていただきます、大変遅れてしまい申し訳ございません。（隅から隅まで全部は読めていないので、読了したら更新するかもしれません）

# 私について

経済学研究科に所属するM2です。実証で修士論文を書きましたが、因果推論は使いませんでした。因果推論に関する知識は大学・大学院で授業を受けた程度です。4月からデータを扱う職種で企業にて働く予定です。

# 感想

私の思う一般的な因果推論手法は一通りカバーされているなと思いました。特徴的な点は第１部でRCT、第２部で疑似実験的手法を扱い、第２部では回帰不連続デザインと差の差法を章立てて扱っていることでしょうか。他の因果推論に関する本[^1]と違うのは傾向スコアの手法を章立てて扱わず、IPW推定量などについて文中でところどころ触れるにとどめている点でしょうか。[^2]あとは機械学習を用いたCausal Forestのような手法や、企業での実務でよく使われる（らしい）Causal Impact等はカバーされていません。

この本の一番の特徴としては、ビジネスや他分野への応用に重点を置かず、あくまで「経済学訛りの」[^a]因果推論についての本にしようとしている点だと思います。経済学の実証家をターゲットに、因果推論を扱うのであれば必要であろう理論的背景を妥協せずに説明し、また実際の実証論文の例を付することで[^b]、この本を読めば因果推論を用いた実証論文を書く理論的・手法的な基礎が、合成コントロール法のような最新の手法までカバーした形で得られるように思えます。その点でとても貴重な本だと思います。

対してあえて言うのであれば、恐らく経済学に全く興味がない人が読んだとしてもあまり得られるものはないかもしれません。理論的な説明を完全に理解するためにはおそらくコアコースレベルの計量経済学の知識がある程度必要だと思いますし[^3]、例えばちょっと因果推論に触れてみたいなというビジネスマンが最初に読む本におすすめできるかというと、それはさすがに厳しそうです。

逆に言うと、経済学における実証分野の手法に少しでも興味のある方であれば手に取ってみて損はないと思います。特に、実証系の研究者を目指す学生にはとても価値のある本なのではないでしょうか。




[^1]: といっても私が真面目に読んだことがあるのは「効果検証入門」くらいですが
[^2]: 私が見落としているだけだったらごめんなさい。
[^a]: 本文p.8
[^b]: 個人的には「合成マルクス」の話が面白かったです。
[^3]: もしかしたらある程度統計学を学んだ人であれば大丈夫かもしれません。私は計量経済学に触れずに統計学を勉強したことのある方がどういった知識を持っているかがわからないので、、
【SpringBoot】値がない場合を弾くアノテーションチートシート

## 1.  はじめに
　今まで、null判定・undefined判定などの値があるかどうかを判定するロジックに悩むことが多かったので、メモ書きとしてまとめていたもの＋調査したものを公開していきます。
　今回はSpringBoot編です。先のVue2→Vue3へのアップデートでも使っていました。

## 2. SpringBootのアノテーションにおける値存在判定

### ①@NotNull
前回のObjects.isNull()と同様、nullかどうかを判定します。
もしnullであれば、エラーメッセージを返します。　

```java
    // nullの値が渡されると「値はNullです。」のメッセージが返ります
    @NotNull(message =  "値はNullです。")
    private String nullField;
```

### ②@NotEmpty
前回のStringUtils.isEmpty()と同様、nullと""（空文字）の時かどうかを判定します。
もしnullか空文字であれば、エラーメッセージを返します。
StringUtils.isEmpty()と同じく半角スペースのみの場合は検知されません。


```java
    // nullか空文字が渡されると「値はnullか空文字です。」のメッセージが返ります
    @NotEmpty(message =  "値はnullか空文字です。")
    private String emptyField;
```

### ③@NotBlank
前回のStringUtils.isBlank()と同様、nullと""（空文字）、半角スペースかどうかを判定します。
もしnullか空文字、半角スペースであれば、エラーメッセージを返します。

```java
    // nullか空文字、半角スペースのみの値が渡されると「値がblankです。」のメッセージが返ります
    @NotBlank(message =  "値がblankです。")
    private String emptyField;
```

但しこれらに関しては全角スペースはすり抜けます。

| 引数 | 引数(コード) | @NotNull | @NotEmpty | @NotBlank | 
|----|----|----|----|----|
| null | null | **true** | **true** | **true** |
| 空文字 | ''  | false | false | **true** |
| 半角スペース | ' ' | false | false |  **true** |
| 半角スペース | ' ' | false | false |  false  |

## 3.さいごに
今回の記事は以上です。
DTOなどに含めて入れると便利だったので、紹介しました。
次回以降少しペースが落ちるかもしれませんが、気ままに更新していきますので、見ていただけたら嬉しいです。

## 4.参考資料
①[@NotBlank、@NotEmpty、@NotNullの挙動の違いをSpring Boot + Thymeleafで整理する](https://qiita.com/NagaokaKenichi/items/67a63c91a7db8717fc7d)
TauriでWindows向け日本語インストーラーをビルドするw/NSIS

セットアップも終わってウキウキで`npm tauri build`を実行したら「light.exeが実行できなかった」と言われてしまいました。
情報共有記事です。「こうすれば解決できたのに...」という手段があれば是非教えて頂きたいです。
## 解決
wixではなく、NSISを使うことで解決

:::note warn
NSISでのビルドはTauriの方では**Experimental(実験段階)として提供されています**。予めご確認をお願いします。
:::
### 1. `tauri.config.json`を修正
```jsonc:tauri.config.json
{
  // 省略
  "bundle": {
    "active": true,
    "targets": ["nsis"], // +-修正
    // 省略
    "windows": {
      "nsis": {
        "languages": ["Japanese"]
      }
    }
  }
}
```
### 2. LLD(LLVM)をインストール
https://releases.llvm.org/
### 3. Rustの方の設定
シェルの方で実行してください。
```sh
rustup target add x86_64-pc-windows-msvc
cargo install --locked cargo-xwin
```
### 4. ビルドスクリプトを追記
```jsonc:package.json
{
  // 省略
  "scripts": {
    // 省略
    "tauri:build": "tauri build --runner cargo-xwin --target x86_64-pc-windows-msvc",
  },
  // 省略
}
```
あとは`npm run tauri:build`を実行していただくだけです。お疲れ様でした。
Elmer / MMGを用いたAdaptive Mesh Refinement

# MMGについて
メッシュモジュールやSolverにライブラリMMGを組み込み、メッシュ分割の最適化を行うことが可能です。
２次元三角、３次元四面体、表面メッシュに適応しています。

## MMGを使用しているプロジェクト
以下Mmgのページにリストがあります。
FreeCADに標準装備されているソフトということでピックアップすると、ElmerとGmshになります。
[Projects using Mmg](https://www.mmgtools.org/projects-using-mmg)

Elmerでは、Adaptive Mesh RefinementをSolverに利用することができますので、導入方法～試用方法までを説明します、

## MMGが動作するElmerの導入
Mmgはリポジトリになく、コンパイルに必要なライブラリが多いので、あらかじめ作成された環境を使用することをお勧めします。以下の二通りがあります。
### Elmer Virtual Machine (VirtualBox用のovaファイルで提供されています)
- 公式サイトからダウンロードする
https://www.nic.funet.fi/pub/sci/physics/elmer/bin/VirtualMachines/
- ストレージが20GBの設定であり、空き容量に余裕がないので拡張する
https://www.howtogeek.com/124622/how-to-enlarge-a-virtual-machines-disk-in-virtualbox-or-vmware/
- Virtual Machineを起動して、キーボード、言語、パスワードなどの変更する

### 私が作成したWSL2のディストリビューションを使用する
- 以前の投稿に詳しく記載しています
[Elmerをコンパイルするシェルスクリプト...設定済ですぐに使えるWSLディストリビューションを準備](https://qiita.com/HD_mount_Music/items/2695e7480c9585aaf632)

## 解析結果のアニメーション
elmerfem/fem/testsのgitで公開されているものを実行した結果を添付します。但し、コマ数が増えるように設定を一部変更しています。
- adaptivity1-mmg2d
[adaptivity1-mmg2d](https://github.com/ElmerCSC/elmerfem/tree/devel/fem/tests/adaptivity1-mmg2d)
[mp4アニメーション](https://1drv.ms/v/c/ca3fad7a4b4217c1/EbDVoKqShepDtjG0xjC74usBi6tTdgiIPHOWQ-UeJ4sK9Q?e=SPRaH1)
- RotatingBlockRemeshMMG2Dtransient
[RotatingBlockRemeshMMG2Dtransient](https://github.com/ElmerCSC/elmerfem/tree/devel/fem/tests/RotatingBlockRemeshMMG2Dtransient)
[mp4アニメーション](https://1drv.ms/v/c/ca3fad7a4b4217c1/EVwUOM7dVlRAhQYKMqvmM1gB1QzLJq4wofo-9V9yQE_lCA?e=ekVeRf)
- RotatingBlockRemeshMMG3D
[RotatingBlockRemeshMMG3D](https://github.com/ElmerCSC/elmerfem/tree/devel/fem/tests/RotatingBlockRemeshMMG3D)
[mp4アニメーション](https://1drv.ms/v/c/ca3fad7a4b4217c1/ESCzQV9HuiBMgpaVGhvATpgB3MbdMB_X6BYoz3CyZmNXGA?e=oaO1nW)
- StatElecSolveVecMMG3D
[StatElecSolveMMG3D](https://github.com/ElmerCSC/elmerfem/tree/devel/fem/tests/StatElecSolveMMG3D)
[mp4アニメーション](https://1drv.ms/v/c/ca3fad7a4b4217c1/EcIBM74wv8RHtKhaf3gnRf8BxBm84JCI_sjGstiAnrWgKg?e=zVFey8)
新人エンジニアが世界一流エンジニアの考え方や仕事の取り組み方を学ぶ

## はじめに
私がエンジニアのアルバイトを退職する際に、先輩から『世界一流エンジニアの思考法』という本をいただきました。
そこから約1年半放置していて、最近いただいたことを思い出したので読んでみました。
読み進めるとエンジニアとして働くうえで重要な考え方を学ぶことができました。
そこで、自分がこの習慣を実践する戒めのつもりで、記事にまとめようと思います。

## 『世界一流エンジニアの思考法』の概要
**『世界一流エンジニアの思考法』 牛尾剛著**

![世界一流エンジニアの思考法.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4037639/1efac6e2-48a9-460d-8d37-27d96f13ccee.jpeg)
> https://www.google.co.jp/books/edition/%E4%B8%96%E7%95%8C%E4%B8%80%E6%B5%81%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%AE%E6%80%9D%E8%80%83%E6%B3%95/eX_eEAAAQBAJ?hl=ja&gbpv=1

著者である牛尾剛氏は、米マイクロソフトの現役エンジニアです。
世界一流エンジニアとは、米マイクロソフトで著者と一緒に働く仲間たちのことです。
世界一流エンジニアが、生産性高く仕事できる思考法や仕事の取り組み方について知ることができる内容となっています。

## 実践してみたい項目
さて、私が『世界一流エンジニアの思考法』を読んでみて、実践してみたいと感じた****世界一流エンジニア****の習慣や思考法についてまとめます。
3つのセクションに分けてまとめていきます。

### 1. 世界一流エンジニアの仕事の取り組み方
#### エラーの解決やデバッグなどはむやみに手を動かすのではなく、仮説を立てて検証しろ
開発をしていく中でエラーが起こることは避けられません。
エラーが起こった際に私は、とりあえずエラーの内容を調べたあとにすぐに手を動かして修正しようとしてしまいがちでした。
ですが、エラーが起きたら内容を把握し、仮説を立てて検証するほうが効率が良いようです。
また、むやみに手を動かしてエラーが修正されたとしても、根本原因がわかっていないので、学びになりません。
エラー内容を整理し仮説を立てて検証することで、より深い理解に繋がります。

#### 理解は時間がかかるものととらえ、徹底的に理解する習慣をつける
目先の時間だけにとらわれず、理解するまでは時間をかけることで、プロダクトやプログラミング自体の理解ができ、長期的に見て生産性を向上します。

#### 基礎を習得すると、コピペエンジニアや検索エンジニアを卒業できる
基礎を習得することは時間がかかりますが、根本の理解が深まることで応用がきくようになります。
著者もエンジニアとして多くの経験を積んでいましたが、再度一から基礎を学び直し、開発効率が上がることを実感したようです。

#### 記憶力が良いのはしっかり理解をしているから
私は自分が実装した箇所のコードを1ヶ月後ぐらいに確認するとどのような内容だったのか忘れてしまうことが多いです。
ですが、忘れてしまうのは、理解して実装していないからのようです。
自分が行ったことをクリアに説明できるよう時間をかけて言語化することで、時間が経っても、すぐに思い出すことができます。
実装が完了して終わりではなく、「説明できるか」というセルフチェックを入れて理解を高めていくのが良いです。
人に説明するという訓練の手段として、最良の手段はブログや技術記事を書くことです。

最終的には、頭の中で整理できるようになれば、記憶力がさらに良くなります。

#### 自分だけが理解できるようなメモを取るのはNG
第三者が理解できるようにメモを取る癖をつけると人にわかりやすく説明する訓練にもなります。
さらに、人に質問された際にそのままメモを渡すことができるので仕事の効率化にも繋がります。

### 2. 世界一流エンジニアのマインドセット
#### より少ない時間で価値を最大化する
いわゆるパレートの法則のような考え方のことです。
(パレートの法則とは、重要な2割の仕事が終われば、全体の8割が完了しているという法則です。)
いかにやることを減らし、重要なことだけをやるかを見極めることが重要です。
これを実行するためには、普段から最も重要なものを1つだけピックアップする癖をつけると良いです。

#### リスクや間違いを快く受け入れる
検討ばかりするのではなく、検証してミスしたほうが効率的です。
やってみないとわからないことが多いので、検証をすぐに行うと良いです。
そして、早く失敗して方向修正を行うことで効率的に結果を出すことができます。

### 3. 世界一流エンジニアの生活習慣術
#### 定時上がりが効率が良い
生産性を上げるためには定時上がりが良いようです。
生産性を上げるためには学習が必要であり、仕事を定時で切り上げた後に自分の興味のあるトピックを勉強することで、仕事の効率化にも繋がります。
切りのいいところまでやるのではなく、時間で節目を迎える「タイムボックス制」を採用すると良いです。

#### 毎日30分は運動する
物理的なエネルギー不足にならないように、運動を習慣づけると良いです。

## まとめ
実践したいことで記載したものは、あくまで個人的に実践したいと思ったものです。
まずは実践してみて、良さそうであれば続けて、合わなければやめようと思います。

また、この本を読むまでは、仕事の方法が煮詰まってしまった効率的に働きたいシニアエンジニア向けの本なのかと思っていました。
(本をくれた先輩も熟練のエンジニアだったのもあるかもしれません。)
ですが、新人エンジニアでもどのように働けば効率的になるかを早い段階から学ぶことできるので、ぜひ自分のような新人エンジニアに読んで欲しい本だと思います。

最後に、他にも様々な思考法や取り組み方が載っていましたので、気になる方はぜひ読んでみてください。
マイクロソフトのエンジニアの働き方には日本との違いが多く、新たな発見や価値観を得ることができると思います。
株式とは

## 株式

### 株式とは
　株式とは、一般的には株式会社が資金を調達するために発行する有価証券のことである。株式を発行して得た資金は、銀行からの借入金や社債発行で得た資金とは違い、企業には返済の義務はない。その代わり、株式を購入して資金を出してくれた**株主**に対して、様々な還元をする。

### 主な株主の権利
**・経営参加権**
　株主総会で議決権を行使出来る権利。

**・剰余金配当請求権**
　会社の剰余金（利益）から、配当を受け取ることが出来る権利。

**・残余財産分配請求権**
　会社が解散する際、負債を返済した後、財産が残る場合、株主はその持ち株数に応じて残った財産の分配を受けることが出来る権利。


### 株式の売買単位
　通常の株取引で売買される売買単位のことを、「**単元株**」という。単元株の株数は、100株である。実際の取引は、単元株の整数倍で行われ、売買は100株、200株、300株・・・・・・となる。

・**「株式累積投資」と「株式ミニ投資」**
　証券会社が個人向けに提供している「**株式累積投資**」と「**株式ミニ投資**」は、単元株未満で株式の売買が出来るサービスである。

 **株式累積投資** ・・・毎月、一定額ずつ積み立て方式で購入する。
 **株式ミニ投資**・・・1単元の10分の1の単位で売買する。

 ### 証券取引所
 　株式は、通常、証券取引所を通じて売買される。東京証券取引所（東証）以外にも、名古屋・札幌・福岡に証券取引所がある。東証は主に「**プライム**」「**スタンダード**」「**グロース**」の3市場に区分される。

### 株価の仕組み
　株の価格（株価）には、4つの種類がある。
**始値（はじめね）**・・・最初に取引された価格
**終値（おわりね）**・・・最後に取引された価格
**高値（たかね）**　・・・最も高く取引された価格
**安値（やすね）**　・・・最も安く取引された価格
4つの株価を「**四本値（よんほんね）**」という。

### 「ローソク足」とは
　ローソク足とは、株価の動きを時間の経過に沿って図で表したものである。形がローソクに似ていることから、ローソク足と呼ばれており、四本値を表している。
 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387980/4248102e-8026-43b1-a24b-cf6483c87337.png)

　ローソク足を並べてグラフにしたものを「**株価チャート**」と呼ぶ。



## おわりに
ここまで読んでいただきありがとうございます！

## 参考文献
・【CBT模試付/動画付】FP3級合格のトリセツ 速習テキスト 2024-25年版【CBT対応/オールカラー/無料講義動画/完全リンク問題集有/法改正対応】(YouTubeほんださん／東大式FPチャンネルとコラボ中！) (ファイナンシャルプランナー) (ＦＰ合格のトリセツシリーズ) 単行本 – 2024/5/18
東京リーガルマインド LEC FP試験対策研究会 (著, 編集)
p.202-204
無料で住所の情報から郵便番号を検索するGAS

## 初めに
受けている案件で、住所から郵便番号を検索きないか相談されたので、
スプレッドシートで簡単に、かつ無料で郵便番号を検索できるコードを作りました〜。

## 実際のコード

```javascript
function searchZip() {
  var sheetName = '修正後'; // 対象のシート名を指定
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
  if (!sheet) {
    console.error('指定されたシートが見つかりません: ' + sheetName);
    return;
  }
  var lastRow = sheet.getLastRow();
  if (lastRow < 2) {
    console.error('データが存在しません。');
    return;
  }
  var addresses = sheet.getRange('J2:J' + lastRow).getValues();
  var existingZipCodes = sheet.getRange('L2:L' + lastRow).getValues();
  var zipCodes = [];
  var batchSize = 100; // 一度に処理する行数
  var count = 0;
  for (var i = 0; i < addresses.length; i++) {
    var address = addresses[i][0];
    var existingZip = existingZipCodes[i][0];
    if (existingZip) {
      zipCodes.push([existingZip]); // 既存の郵便番号を保持
      continue; // 次の行へ
    }
    if (address) {
      try {
        var response = UrlFetchApp.fetch('https://postcode.teraren.com/postcodes.json?s=' + encodeURIComponent(address) + '&per=3', 
        {muteHttpExceptions: true});
        Logger.log(response.getContentText());
        var json = JSON.parse(response.getContentText());
        Logger.log(json)
        if (json && json.length > 0) {
          var rawZip = json[0].new.toString(); // 数値を文字列に変換
          var formattedZip = rawZip.slice(0, 3) + '-' + rawZip.slice(3); // ハイフンを挿入
          zipCodes.push([formattedZip]);
        } else {
          zipCodes.push(['該当なし']);
        }
      } catch (e) {
        console.error('エラーが発生しました: ' + e.toString());
        zipCodes.push(['エラー']);
      }
    } else {
      zipCodes.push(['']);
    }
    count++;
    // 100件処理するごとにスプレッドシートに書き込む
    if (count >= batchSize) {
      sheet.getRange('L' + (i - count + 3) + ':L' + (i + 2)).setValues(zipCodes.slice(i - count + 1, i + 1));
      count = 0;
    }
  }
  // 残りのデータを書き込む
  if (count > 0) {
    sheet.getRange('L' + (lastRow - count + 2) + ':L' + lastRow).setValues(zipCodes.slice(-count));
  }
}

```

一応、100件検索したら、それを先にスプシに書き込むようにしてます。
郵便番号の記載形式は[000-0000]にしてます。

## 終わりに
一部エラーが出ますが、書き込み自体に問題はないので勘弁してください笑
Python-docxとの出会い

## はじめに
これは書いてる人がPython-docxに出会ったときのことを記したものです。
書いてる人はpython初心者です。何か誤った情報の記載があれば悪しからず。

### 環境
- OS: macOS Sequoia 15.3.1
- エディタ: VScode
- Pythonのバージョン: 3.9.6
pythonのバージョンは3.7以降が好ましいそうです。

## 初対面
python-docxとの出会いは今年の2月下旬。
word上の文章を抽出したいな〜となって記事を読み漁ったところ、「それ、pythonで解決できるぜ」と天からの思し召しがあったので早速突撃。

```python: install.py
pip install python-docx
```
お出迎え完了。

## 試してみる
まずはインポートから

```python: import.py
from docx import Document
```

これでインポート完了。てなわけで早速テキストを表示してみましょう

``` python: sample.py
doc = Document("sample.docx") #wordファイルの読み取り

num = 1
for para in doc.paragraphs:
    print(num, para.text) #テキストを段落番号と一緒に表示
    num = num + 1

print("段落数: ", len(doc.paragraphs)) #段落数を表示
```

sample.docxには以下のような文章を書いてみたり引用したりしました。

![スクリーンショット 2025-03-29 17.05.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3950211/21863dc1-62ee-4b35-a78e-988a9389166f.png)


宮沢賢治「ポラーノの広場」より

実行ほいさっさ

```
$ sample.py
1 サンプルだぞ
2 
3 あのイーハトーヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森
4 で飾られたモリーオ市、郊外のぎらぎらひかる草の波。 　またそのなかでいっしょになっ
5 たたくさんのひとたち、ファゼーロとロザーロ、羊飼のミーロや、顔の赤いこどもたち、
6 地主のテーモ、山猫博士のボーガント・デストゥパーゴなど、いまこの暗い巨きな石の建
7 物のなかで考えていると、みんなむかし風のなつかしい青い幻燈のように思われます。で
8 は、わたくしはいつかの小さなみだしをつけながら、しずかにあの年のイーハトーヴォの
9 五月から十月までを書きつけましょう。
10 
段落数:  10
```

できました。やった〜
他にも画像や表も表示できたりするので色々試してみてください

## 参照元

python-docx公式
https://python-docx.readthedocs.io/en/latest/

python-docxの備忘録
https://qiita.com/dkclimb/items/6ce4896d755f7ad4acde
統計検定1級　2022　統計数理　問4　解説

![img20250328_11515861.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/6bc76f53-1c61-48fe-9efa-10960296d93a.jpeg)
![img20250328_11522968.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/da426b1b-785d-433c-b1ca-3c8294581f39.jpeg)
![img20250328_11525540.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/ce89add0-15a3-4a75-bea5-c7abdecd8301.jpeg)
Ubuntu トラブル（認証ダイアログが頻繁に出る）

::: note warn
本記事の後日談はこちら。
　[[後日談] ミニPCでUbuntu環境を構築](https://qiita.com/b-wind/items/6518901e51d032d52862)
:::

とりあえず解決したので、またまた備忘録メモ。

## 現象
ubuntu インストール後、電源ONのまま一週間ほど放置していました。
久しぶりに Windows リモートデスクトップからログインしてみると、「認証が必要です」というダイアログがログイン直後から頻繁に表示される状況になっていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90456/e050166b-cc18-4d1e-94af-4ace3c04cf2d.png)

<font color="red"><b>注）画像の英文は、実際に表示されていたものとは異なります。</b></font>

## 対処方法
いろいろと調べてみましたが、どうやら xrdp とGNOME Keyring 付近が怪しそうです。
そこで、以下のことを実施してみたところ、頻繁に表示される現象はなくなりました。
（ログイン直後は必ず表示されていた現象も解消しました）

　① xrdpユーザーを「ssl-cert」に追加
　② polkit の認証許可を変更
　③ GNOME Keyring の認証動作を変更
　④ （オマケ）X セッション開始時のDaemon起動など

### ① xrdpユーザーを「ssl-cert」に追加
xrdp が秘密鍵情報へアクセスする際に問題が発生している可能性があるとのこと。
グループ「ssl-cert」へユーザー「xrdp」を追加して、xrdp を再起動します。
```bash
sudo adduser xrdp ssl-cert
sudo systemctl restart xrdp
```

### ② polkit の認証許可を変更
xrdpからのリモート接続セッションが「非アクティブ」とみなされ、認証が許可されなかった可能性もあるとのこと。
エントリ「Allow Colord for XRDP Users」を追加し、polkit を再起動しておきます。

まず、次のファイルの**先頭**にエントリを追加します。
**```/etc/polkit-1/localauthority.conf.d/45-allow-colord.conf```**
```conf
[Allow Colord for XRDP Users]
Identity=unix-group:xrdp  # xrdp グループのユーザーのみに適用
Action=org.freedesktop.color-manager.*
ResultAny=yes
ResultInactive=yes
ResultActive=yes
```

続けて、polkit を再起動します。
```bash
$ sudo systemctl daemon-reload
$ sudo systemctl restart polkit
```

### ③ GNOME Keyring の認証動作を変更
以下のことを実現すれば解決するかも、ということでした。
* ロックを自動解除する設定を有効化
* アプリやxrdpセッションが認証情報を自動的に取得可能にする

まず、次のファイルの**最後尾**にエントリを追加します。
**```/etc/pam.d/xrdp-sesman```**
```conf
auth optional pam_gnome_keyring.so
session optional pam_gnome_keyring.so auto_start
```

続けて、polkit を再起動します。
```bash
$ sudo systemctl daemon-reload
$ sudo systemctl restart polkit
```

### ④（オマケ）X セッション開始時のDaemon起動など
①～③ の対処で解決すると思うのですが、念のため X セッションを開始した時に 次の動作を実施するようにしておきます。

* GNOME Keyring Daemon の起動
* SSH_AUTH_SOCK の設定
* GNOME セッションの起動　<-- 本当に記述する意味があるのだろうか…

次のファイルの内容を変更しておきます。
**```~/.xsession```**
```conf
#!/bin/bash

# gnome-keyring-daemon がすでに起動していない場合のみ起動
if [ -z "$GNOME_KEYRING_CONTROL" ]; then
    eval $(gnome-keyring-daemon --start)
fi

# SSH_AUTH_SOCK が設定されていない場合のみ設定
if [ -z "$SSH_AUTH_SOCK" ]; then
    export SSH_AUTH_SOCK=$(find /run/user/$(id -u)/keyring/ -type s -name "ssh" | head -n 1)
fi

# gnome-session が正しいパスに存在するか確認
if [ -x "$(command -v gnome-session)" ]; then
    # gnome-session が存在する場合のみ実行
    if [ -z "$GNOME_DESKTOP_SESSION_ID" ]; then
        # セッションの開始（デスクトップ環境）
        exec /usr/bin/gnome-session
    else
        echo "gnome-session is already running."
    fi
else
    echo "Error: gnome-session not found."
    exit 1
fi
```
## 結果
今のところは解消されたように見えます。
認証ダイアログも、不必要な時に表示されなくなりました。

そもそも、インストール直後はそんな現象もなく動いていたのですが、この現象が発生し始めた真の原因は不明なままです。
まぁ、とりあえず **これで良し！** という事にしておきます。

実はもう１件、おかしな事象が発生して対処したネタもあり…
それまた次回の記事で。（一応は解決済みです）
個人用備忘録：BINDでハマったので、未来の自分へのメモとしてアウトプットしてみた

## はじめに
BIND（Berkeley Internet Name Domain）は、最も広く使われているDNSサーバーソフトウェアです。ドメイン名とIPアドレスの変換（名前解決）を担い、ネットワーク通信の根幹を支える重要な役割を果たします。

:::note info
**個人の備忘録程度の走り書きとなっておりますが、温かい目で見守っていただければ幸いです。**
:::

本記事では、自分用にBINDの基本や設定のポイントをまとめておきます。

---

## 書こうと思ったきっかけ
社内で内部DNSの構築や、サブドメインの管理を行う場面があり、BINDの設定に触れる機会がありました。**設定ファイルの構成やゾーンファイルの書き方を毎回調べるのは非効率なため、備忘録としてまとめています。**

---

## BINDの基本機能
- ドメイン名とIPアドレスの名前解決
- 正引き・逆引きDNSの提供
- ゾーン転送（マスター／スレーブ構成）
- キャッシュDNSとしての動作
- アクセス制御やACLによるセキュリティ強化

---

## よく使うコマンド
```bash
# サービスの起動・停止
sudo systemctl start named
sudo systemctl stop named
sudo systemctl restart named

# ステータス確認
sudo systemctl status named

# 設定ファイルの文法チェック
named-checkconf

# ゾーンファイルの文法チェック
named-checkzone example.com /etc/namedb/example.com.zone
```

**参考文献**

https://docs.oracle.com/cd/E19253-01/819-0382/dnsref-9/index.html

---

## 基本的な設定ファイル
- `/etc/named.conf`：メイン設定ファイル
- `/var/named/`：ゾーンファイル格納ディレクトリ

## named.confの例
```conf
options {
    directory "/var/named";
    allow-query { any; };
};

zone "example.com" IN {
    type master;
    file "example.com.zone";
};

zone "0.168.192.in-addr.arpa" IN {
    type master;
    file "192.168.0.rev";
};
```

**参考文献**

https://qiita.com/ss12345/items/d348bb02c5c85d930db3

---

## ゾーンファイルの例（正引き）
```dns
$TTL 86400
@   IN  SOA ns1.example.com. admin.example.com. (
        2025032301 ; Serial
        3600       ; Refresh
        1800       ; Retry
        1209600    ; Expire
        86400 )    ; Minimum

    IN  NS  ns1.example.com.
ns1 IN  A   192.168.0.1
www IN  A   192.168.0.10
```

**参考文献**

https://atmarkit.itmedia.co.jp/fnetwork/dnstips/031.html

---

## まとめ
BINDはDNSの基本的な仕組みを理解する上で欠かせないツールです。

:::note warn
**設定ファイルやゾーン情報の記述ミスでトラブルが起きやすいため、設定変更の際には必ず文法チェックを行う習慣をつけましょう。**
:::

今後はセカンダリDNSの構成や、DNSSEC、アクセス制限などにも取り組み、より信頼性とセキュリティの高いDNS運用を目指していきます！
個人用備忘録：Squidでハマったので、未来の自分へのメモとしてアウトプットしてみた

## はじめに
Squidは、UNIX系システムで広く使用されているキャッシュ型プロキシサーバーです。Webアクセスの高速化やアクセス制御、ログ収集など、ネットワーク管理において重要な役割を担います。

:::note info
**個人の備忘録程度の走り書きとなっておりますが、温かい目で見守っていただければ幸いです。**
:::

本記事では、自分用にSquidの基礎や設定のポイントをまとめておきます。

---

## 書こうと思ったきっかけ
社内のネットワーク監視やWebアクセス制御の仕組みを構築する中でSquidを導入しました。最初は設定に戸惑うことも多かったため、今後の運用や再設定に備えて備忘録としてまとめています。

---

## Squidの基本機能
- プロキシキャッシュ（Webコンテンツの高速化）
- アクセス制御（ACLによるIP・URL制限）
- ログ記録（アクセスログ、キャッシュヒット率など）
- 認証機能（Basic認証、LDAP認証など）
- フィルタリング機能（広告ブロックや特定サイトの制限）

---

## よく使うコマンド
```bash
# サービスの起動・停止
sudo systemctl start squid
sudo systemctl stop squid
sudo systemctl restart squid

# ステータス確認
sudo systemctl status squid

# ログの確認
sudo tail -f /var/log/squid/access.log
sudo tail -f /var/log/squid/cache.log
```

**参考文献**

https://wiki.archlinux.jp/index.php/Squid

https://tech-mmmm.blogspot.com/2018/01/squid.html

---

## 基本的な設定ファイル
- `/etc/squid/squid.conf`：メイン設定ファイル

## squid.confのよく使う項目
```conf
http_port 3128
visible_hostname proxy.example.com

# アクセス制御
acl localnet src 192.168.0.0/16
http_access allow localnet
http_access deny all

# キャッシュの設定
cache_mem 256 MB
maximum_object_size_in_memory 512 KB
maximum_object_size 10 MB
cache_dir ufs /var/spool/squid 100 16 256
```

**参考文献**

https://www.novell.com/ja-jp/documentation/sles11/book_sle_admin/data/sec_squid_configfile.html

https://blog.serverworks.co.jp/squid

---

## 認証の設定（Basic認証の例）
```conf
auth_param basic program /usr/lib/squid/basic_ncsa_auth /etc/squid/.htpasswd
auth_param basic realm ProxyAuth
acl authenticated proxy_auth REQUIRED
http_access allow authenticated
```
```bash
# 認証ユーザーの作成（htpasswdが必要）
sudo htpasswd -c /etc/squid/.htpasswd username
```

---

## まとめ
Squidはネットワーク管理に欠かせない強力なツールですが、設定項目が多く柔軟な分、最初は戸惑うこともあります。**ログの確認やアクセス制御の仕組みを把握し、少しずつカスタマイズしながら運用していくことが大切です。**

:::note info
**個人の備忘録程度の走り書きとなっておりますが、温かい目で見守っていただければ幸いです。**
:::

今後はログの可視化や、外部認証連携（LDAP等）、HTTPSの中継なども学びながら、よりセキュアで効率的なネットワーク環境の構築を目指していきます。
私のゼロレベルCSS

CSSの勉強初めて見ました。途中でやめようと思いましたでも我慢して前に進みました。いろんな人から聞いたことあって皆んなCSSの勉強辛くてやめるのは結構います。でもこの話も考えて自分で自分にモチベーションをさせていきました。大変とかはなんでも始まってもあります。それに対してこれは義実関係なことなんで絶対頑張らないといけない思っていきました。CSSの中ですごくたくさんのことあるんですけど覚えられないし、ずっと終わらなくなるみたいでyoutubeでどれくらいの出してるのかそれを学んで行ってました。CSS勉強する時 ニードはこちらポイントで書きます。
「1」 Box model
「2」 Margin , Padding 
「3」 Grid
「4」 Flexbox
「5」 Class /Id
「6」 Some knowledge of Some sites cdn link
「7」 Position
「8」 Media query
まだたくさんありますけど全部は終わらないでもできるだけで頑張ったらいいと思います。ゼロからしているみんなに安心してこれくらいゆっくり勉強して練習もして前につづきましょう。
Ubuntu20.04LTSのMBRディスク内容を保持したまま、GPTディスクに変換する

## ついにMBRの読めないRegacyモードのないパソコンについに出会った
どうもUEFIブートしかサポートしていないパソコンが出てきている様子。時代の流れか。
なのでMBRで作成されているHSRのディスクをGPTにして，UEFI用のgrubを新規インストールして解決したので手順を記す。割と真面目に人力で再構築してるので、もう少しGrub-updateの力を借りて楽な手順とかありそう。

## 全体の流れ
1.diskアプリでブート用パーティションを作成
2.MBRからGPTへの変換作業
3.UEFI用のGRUBを書き込み


## 詳細手順
### 1. 変換したいmbrディスクを起動しefibootmgrを入れる
起動できるうちに入れときましょう。最後の再構築の際に、grub installができなくてめんどくさくなります。
```
sudo apt install efibootmgr
```
で入ってればＯＫ。

ここからはuefi環境のLiveUSB or ほかのUbuntu機に変換したいディスクをSATAで接続して作業する。最初は、USB-SATA変換で接続したのだが、うまく機能しなかった。変換器によるのかも。
### ２．disk(gui)で後ろ256MBを切ってフラグboot,espにしておく
作成したパーティションをvfatでフォーマットします。
sudo /sbin/mkfs.vfat -F32 /dev/sdb4

### ３．ターミナルを開き、gdiskでmbr→gpt変換
データが吹き飛ぶ可能性あります。必ずバックアップを取ってから行いましょう。
```
sudo gdisk
/dev/sda
r(revovery and transformation options)
f(load MBR and build GPT)
y(yes)
w(write)
y(yes)
```
 

### ４．UEFI用のgrubを入れ直し
まずgrub-efiが入っているか確認
```
sudo apt install grub-efi
```
次にrootの入っているパーティションをマウントして作業します。
たぶんMBRディスクであれば最初のパーティションだと思う。
私の場合は、sdb1だった。
```
sudo mount /dev/sdb1 /mnt
```
また、先程作成したESPパーティションを/boot/efiにマウントします。
私威の作ったESPパーティションはsdb3だった。
```
sudo mkdir -p /mnt/boot/efi
sudo mount /dev/sdb3 /mnt/boot/efi
```

必要なディレクトリをバインド
バインドは、すでにマウントされているツリーの一部を、別の場所にマウントさせるオプション。
```
sudo mount –bind /dev /mnt/dev
sudo mount –bind /proc /mnt/proc
sudo mount –bind /sys /mnt/sys
sudo mount --bind /usr /mnt/usr 
```
ルートディレクトリを変更して、UWFIGRUBをインストール
```
sudo chroot /mnt
/usr/sbin/grub-install –-target x86_64-efi –-efi-directory /boot/efi /dev/sdb
```
再起動

 
### ５．grubにカーネルの位置を設定して
再起動すると、シェルが出るorGRUBメニューが出るが起動しない状態になるはず。
メニューでeを押すとエディタが起動し、Ctrl+Cでシェルへ入れます。
手動でブートを実施。

bootフォルダを探す。いろいろ探索する。
```
grub> ls
	(hd0)  (hd0,gpt3)  (hd0,gpt2)  (hd0,gpt1)  (fd0)  (fd1)
grub> ls (hd0,gpt2)/ 
	./ ../ boot/ dev/ proc/ run/ sys/ etc/ var/ root/ 
```
ブートフォルダを見つけたら、ルートにマウントするファイルシステムを設定。
```
grub> set root=(hd0,gpt2)
```
起動するには、linuxefi でvmlinuzファイルと、root=で/パーテーション指定を行い、initrdedi でinitramfsファイルを指定する必要がある。
```
grub> linuxefi /vmlinuz-3.10.0-514.16.1.el7.x86_64 root=/dev/sda1
grub> initrdefi /initrd-3.10.0-514.16.1.el7.x86_64.img
grub> boot
```

### ６．ブート後、起動したUbuntuで、起動の為の正しい設定を実施
```
sudo apt-get install grub-efi
sudo mount /dev/sda3 /boot/efi
sudo /usr/sbin/grub-install  –-target=x86_64-efi  -–efi-directory /boot/efi /dev/sda
sudo grub-mkconfig -o /boot/grub/grub.cfg
```
 これでUEFI Bootできる。
GithubActionsのCIがpaymentsエラーで動かない

## 現象
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3760274/df2660db-49ab-4243-92f6-46b3110a99d5.png)

```
The job was not started because recent account payments have failed or your spending
limit needs to be increased. Please check the 'Billing & plans' section in your settings
```

## クレカ情報のエラー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3760274/fda295eb-b27e-46d9-97ec-e3e94e3fbfc9.png)

```
Invalid payment method - authorization hold failed.
```

### Paypalに変更
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3760274/cbc6a4b7-c068-4edd-9ddb-be4fd9cf337d.png)

JCBがNG？VISAでも上手くいくかも

### CI通った OK

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3760274/4cf2584e-6c37-4707-b42f-7b07d394156d.png)
FirebaseのDatabase理解していますか？

## 前書き
初投稿！エンジニア界のインスタグラムと聞き、始めてみました。
実務経験も半年になり、ようやくQiitaで記事を投稿してエンジニアの仲間入りをしようと目論んでおります。
今までは情報を得るために使用していましたが、アウトプットも兼ねて現在実務で使用しているFirebaseの曖昧な理解を明確にします。（間違っていたら指摘して下さい）

## 向いてる人
- FirebaseのDBをよく分からず使っている人
- かわいい駆け出しエンジニアの記事を見守りたい人

## FirebaseのDBについて
FirebaseにはFirestoreとRealtime Databaseの二つが提供されており、それぞれ要件に応じて使う必要があります。今回は中でもその使い方の違いに言及します。
使い方は公式ドキュメントを載せておくのでみて下さい。

### Firestore Admin SDK

https://firebase.google.com/docs/firestore/manage-data/add-data?hl=ja

FirestoreはRPC (Remoto Procedure Call)ベースのAPIを提供しているそうです。簡単に言うとprojectIdを基にFirestoreのエンドポイントを呼び出しているそうです。なのでadmin.initializeApp()にprojectIdを書くだけで自動的にデータベース接続をしてくれます。

### Realtime Database Admin SDK

https://firebase.google.com/docs/database/web/start?hl=ja

URLベースを基にアクセスします。いわゆるRest APIです。またFirestoreとは異なり複数のデータベースインスタンスを作成してデータを分割することが可能です。

## まとめ
- FiresotreはRPC
- Realtime DatabaseはREST

これらの違いは「[RPCとRESTの違い](https://aws.amazon.com/jp/compare/the-difference-between-rpc-and-rest)」がわかりやすいです。
個人用備忘録：Postfixでハマったので、未来の自分へのメモとしてアウトプットしてみた

## はじめに
Postfixは、UNIX系システムで広く使用されているメール転送エージェント（MTA）です。メールの送信・中継・受信を担うソフトウェアであり、シンプルながら強力な機能を備えています。

:::note info
**個人の備忘録程度の走り書きとなっておりますが、温かい目で見守っていただければ幸いです。**
:::

本記事では、自分用にPostfixの基礎や設定のポイントをまとめておきます。

---

## 書こうと思ったきっかけ
業務でサーバーから自動通知メールを送信する際にPostfixを使用する機会がありました。設定ミスによってメールが外部に届かなかった経験があり、今後のトラブル防止のためにも備忘録としてまとめています。

---

## Postfixの基本機能
- ローカルからのメール送信
- 他のMTAへのメール転送
- メールキューの管理
- SMTP認証の設定対応
- セキュリティ制御（リレー制限、TLS設定など）

---

## よく使うコマンド
```bash
# サービスの起動・停止
sudo systemctl start postfix
sudo systemctl stop postfix
sudo systemctl restart postfix

# メールキューの確認
mailq

# メールキューの削除
postsuper -d ALL

# メール送信のログ確認
sudo tail -f /var/log/maillog
```

**参考文献**

https://mytracking.hatenablog.com/entry/2016/09/03/042044

https://www.infra-linux.com/menu-lpic6/mail-mailq-cmd/#google_vignette

---

## 基本的な設定ファイル
- `/etc/postfix/main.cf`：メイン設定ファイル
- `/etc/postfix/master.cf`：サービスの定義やポート設定

## main.cfのよく使う項目
```conf
myhostname = mail.example.com
mydomain = example.com
myorigin = $mydomain
inet_interfaces = all
inet_protocols = all
mydestination = $myhostname, localhost.$mydomain, localhost
relayhost = [smtp.provider.com]:587
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_use_tls = yes
```

**参考文献**

https://qiita.com/ss12345/items/97ad32aaefbc01cc25a9

---

## メール認証の設定（例：Gmail経由送信）
```conf
# /etc/postfix/sasl_passwd
[smtp.gmail.com]:587    youraddress@gmail.com:yourpassword

# ハッシュ化
postmap /etc/postfix/sasl_passwd
chmod 600 /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db
```

---

## まとめ
Postfixは一見シンプルに見えて奥が深く、少しの設定ミスでもメールが送れなくなることがあります。**そのため、設定ファイルの書き方やメールログの見方を事前に理解しておくことが重要です。**

今後はTLS証明書の導入やDKIM/SPFなどのメール認証機構との連携も含めて、より安全な運用を目指していきます！
リファクタリング

# リファクタリングとは？
リファクタリングとは、外観を変更せず、内部構造を修正し、コードの可読性の向上や保守性の改善を図ること等を目的としており、コードを管理する手法の一つであります。このように継続的な改善を行うことにより、コードの品質を保ったり、より良いコードにしていくことができます。
まとめますと、以下となります。

## リファクタリング
1.外部から見た動作や設計を改善する
2.保守性の改善(バグ修正がしやすくなる)
3.拡張性の向上(新機能追加が容易になる)
4.長期的なコスト削減

## リファクタリングのメリット
### 1.コードの可読性向上：
　・他の開発者がコードを理解しやすくなる
　・自分自身が後から見返した時にも理解しやすい
 ### 2.バグの発見と修正：
　・複雑な構造を単純化することでバグが見つけやすくなる
　・細かい改善を繰り返すことで潜在的なバグを排除することができる
 ### 3.テストの容易化：
　・小さな単位の関数に分割することでユニットテストが書きやすくなる
　・テスト範囲が明確になり、テストの網羅性が向上する
 ### 4.知識の移転：
　・コードの意図が明確になり、チーム内の知識共有がスムーズになる
　・新しいメンバーの学習曲線が緩やかになる
 ### 5.技術的負債の削減：
　・短期的な解決策で蓄積された「技術的負債」を減らせる
　・将来の開発コストを下げることができる

 ## リファクタリングのデメリット
 ### 1.時間とリソースの消費：
　・短期的には開発リソースを消費する
　・すぐに目に見える機能追加にはつながらない
 ### 2.新たなバグの導入リスク：
　・リファクタリング自体が新しいバグを生む可能性がある
　・適切なテストが無い場合、特にリスクが高まる
 ### 3.過剰リファクタリング：
　・必要以上に「完璧」を求めると、永遠にリファクタリングが終わらない
　・「過剰な抽象化」が逆に可読性を下げることもある
 ### 4.ビジネス価値の説明困難：
　・経営層や非技術者に対して価値の説明が難しい
　・「動いているものを変える理由」の正当化が必要

 ※私も知識・経験が少ないため、もし間違い等ありましたらご教示いただけますと幸いです。
Cursor に Git diff を食わせて開発ブランチの作業内容をざっくりと把握させる方法

### 簡単な説明

開発ブランチの変更内容を効率的に把握するために、Git の差分を Cursor AI に解析させる方法を紹介します。この方法を使えば、コードの変更点を素早く理解し、生産性が上がると共に次の作業に早急に着手出来ます。

### 活用シーン
個人的に思う活用シーンは下記です。
- コードレビュー前の準備：レビュー対象の変更内容を事前に把握
- 作業の引き継ぎ：他の開発者の作業内容を素早く理解
- ドキュメント作成：変更履歴や実装内容のドキュメントを文書化する時

### 本題
開発ブランチにてターミナルで下記のコマンドを実行します。

```bash
% git diff main..開発ブランチ名 > branch_changes.diff
```

`branch_changes.diff`というファイルが生成されます。

```bash
% git status
On branch 開発ブランチ名
Your branch is up to date with 'origin/開発ブランチ名'.

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        branch_changes.diff # これ

nothing added to commit but untracked files present (use "git add" to track)
%
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3282990/cb02a946-dc20-4cc9-96e8-8999e3f1e05a.png)


最後に、作成したファイルの相対パスをコピーして、ファイルメインション機能を使って Cursor AI に食わせます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3282990/8f0911c9-78a2-49ef-9a6d-740b7ef0d5a0.png)


```markdown
例

下記のファイルを確認し、このブランチでどういった変更がされているか説明してください。
@branch_changes.diff
```

:::note warn
注意点

ブランチの作業ボリュームがでかいとかなりの量になるため、そこは使い所を見極める必要がありそうです。その場合、下記の様に特定のディレクトリに限定する方法があります。
:::



## **特定のディレクトリに限定し差分を取得する場合**

例として feature ディレクトリ内の全ての変更を取得したい場合はこのようにやります。

```bash
% git diff main..開発ブランチ名 -- feature/ > feature_changes.diff
```

mainブランチと現在の開発ブランチの間で、feature/ディレクトリ内のファイルに対する変更のみを抽出し、feature_changes.diff ファイルに保存します。

以降の手順は先ほどと同じで、Cursor AI に食わせます。

### まとめ
Git の差分情報と Cursor AI を組み合わせることで開発作業の効率が向上します。
ただ、鵜呑みにするのではなく、ある程度は疑いつつ上手に使う事が大事です。
便利である反面、間違えた回答をする事もそれなりにあります。
要は使いようです。
上手に使い、開発の効率と生産性を向上させていきましょう！