OmniAICreator/Qiita-1.07M huggingface dataset:
Clineで現役プレイングマネジャーがチケット管理システム「Trak」を作ってみた話

## はじめに

全賭けしろと話題のAIエージェント「Cline」。
実際に賭けてみるにしても、その実力がどの程度か分からないと判断しづらいものです。
「TODOアプリをつくって」や「ECサイトをつくって」といった単純なアプリを作っても、実力が分からない上にXの驚き屋になってしまうため、程よい規模感のアプリを作らせて、その実力を調査してみることにしました。

## チケット管理システム「Trak」制作

実働5日足らずで、以下のようなNext.jsアプリを作成することができました。
![ss-trak.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136165/efd12b46-08fc-4da1-855d-1d477cc1d43b.gif)

(忙しい方は⇒[[エンジニアのためのお仕事問題集 : 11_trak](https://github.com/kaku3/workbooks/tree/main/11_trak)]一式無料公開しています。)


実用レベルを測定するには、ざっくりした要件から細かい画面の要望までを含むアプリを作るのが適切だと考えました。
ということで、以下のコンセプトで制作を進めてみました。

- 要件定義メモを作成
- Cline に外部設計を行わせる
- Cline が作成した外部設計を元に Cline に実装を行わせる
- 程よく実装が進んだところで本システムを利用して障害チケットを起票する
- Cline に障害チケットの対応をさせる

結果、**メンバーやBPに指示出しをするよりだいぶ少ない指示で** ほぼすべてのドキュメントやソースコードを Cline によって作成することができました。

通常であれば休日だけでなく平日の夜などに消えゆくモチベーションと戦いながら数ヶ月かけてどうにかするプロジェクトですが、基本土曜日の作業にてひと月足らずで形にすることができました。

わたしがやったことと言えば、「こうしてほしい」と指示を出して Approve ボタンを押して成果物を確認したこと。
たまに、デバッグしたりリファクタリングの指示をしたりしたぐらいでした。

**プレイングマネジャーの仕事そのものでした。**

## AIエージェントClineを触ってみて

つよいところ、よわいところを書いておきます。

### Cline のつよいところ

- 設計から実装まで簡単な指示でだいぶ汲み取ってやってくれる
    - 通じやすいところ、通じにくいところはあるがやってると分かってくる
    - リーダーやPMなど指示を出しをしていた人には使いやすいと思う
- 人類には不可能な物量・速度
- コードの品質はビジネスプログラマーよりは遥かに高い

### Cline のよわいところ

- 手癖で書く
    - こっそり書き直したところを、豪快に元に戻される
    - こだわりの css が消されるのは悲しい
    - 部分的には Copilot を使った方が、結果が安定する
- 大きなファイルを読むのは苦手 (**これは人間もですね**)
    - すごい速さで rate limit (単位時間あたり利用制限)が近づく恐怖
    - 人類の技術負債は Cline にとっても負債
    - マメにリファクタリングした方がよさそう
- リファクタリングを能動的にしない
    - マメに指示してあげたり手伝って上げたりしないとダメ
    - リファクタリングしておかないと障害が起きた時に原因の特定ができなくなる
    - 指示側が妥当なデザインパターンや設計を知っていた方がよさそう
- 実際のところは画面が見えていない
    - 直っていないのに「直りました」と言われる
    - 画面の微調整は自分でやる方が楽
    - **UI系の指示を日本語で指示するのは高難易度 (これはClineに限らずですね)**
- 人間がやりがちな障害を埋めてくる
  - 例) ドラッグ&ドロップで並べ替え時、下に移動する時だけ挿入先が一つずれる
  - 例) setState が非同期更新と気づかず、無限に間違ったアプローチでバグ修正をしようとする

### 効率的な作業に向けて

- 仕様追加時は、仕様メモを書いて Cline に仕上げをやらせる
    - Cline の理解度を確認
    - Cline 作業時のリファレンス作成
- マメにコミットをしよう
    - 勢いよく書き直される
    - 動いてたところが動かなくなることもしばしばなので元に戻せるように
- マメにソース整理をしよう
    - 新機能追加前にリファクタリング
    - リファクタリングしていると機能追加の成功率が爆上がりする
- ついでにソースを学ぼう
    - やりたいことに対してベストプラクティスなソース
    - 知らない機能が使われていたら積極的に調べよう

## まとめ

Trak アプリプロジェクトは着想からおよそ形になるまでだいたい実働５日でした。
Copilt の rate limit がなければもっと早くできたかもしれません。

これは、**『人類には不可能なレベルの驚異的な結果』** と言えるでしょう。

ただ、当面は、外部設計の妥当性を確認できるだけの外部設計力と、クリーンなコードをキープして技術負債を産まないだけの設計力とリファクタリング力および複雑な障害のトラブルシューティングができるだけの力を持った人間がいなければ、AIはその力のすべてを発揮できないのかなとも感じました。

無限に試行させれば解決するかもしれませんが、期日までに確実にモノをつくりたいのであれば、「まだ」人類がやるべきことはありそうです。

いずれにしても、AIエージェント Cline は **『全賭けと言うのかは分かりませんが、無ければ暮らせないレベルにはつよい』** と感じましたので、そのつよさは実感しておいた方がよいと思いました。

もしよろしければ、本稿で作成したアプリもご利用頂ければ幸いです。

途中でプロンプトの記録やチケット作成を省略しているため、すべてのチケットやプロンプトは含まれていませんが、プロンプトや作成したドキュメント、ソースコードは以下のリポジトリですべて無料公開しています。

[エンジニアのためのお仕事問題集 : 11_trak](https://github.com/kaku3/workbooks/tree/main/11_trak)
Next.jsでOGP画像が表示されない原因とその対応策



## 概要

Next.jsで構築したWebサイトにおいて、OGP画像がSNSで正しく表示されない問題が発生しました。   
調査の結果、SSR（サーバーサイドレンダリング）時にクライアントオブジェクトである `document` を参照していたことが原因であると判明しました。

本記事ではその原因と対応策をまとめます。


## 問題の発生状況

- Next.jsで構築したサイトをFacebookやX（旧Twitter）でシェア  
- OGP画像が表示されない  
- `meta` タグは正しく出力されている  
- OGP画像URLにも直接アクセス可能  



## 調査の流れ

1. **metaタグの確認**  
   以下のように正しく記述されていたため、タグのミスではないと判断。

   ```html
   <meta property="og:image" content="https://example.com/ogp.jpg" />
   <meta property="og:title" content="サイトタイトル" />
   ```

2. **Facebook Sharing Debuggerで確認**  
   [Facebook Sharing Debugger](https://developers.facebook.com/tools/debug/) にてURLを入力したところ、  
   **500 Internal Server Error** が返されていました。

3. **Cloud Runのログ確認**  
   GCP（Google Cloud Run）のログを確認しましたが、`payloadNotSet` と表示されており、スタックトレースなどの詳細情報は取得できませんでした。

4. **関連情報の調査**  
   以下の記事を発見し、類似の問題であると推測しました。  
   [https://blog.toru-takagi.dev/article/44/](https://blog.toru-takagi.dev/article/44/)


## 原因

サーバーサイドレンダリング中に `document.cookie` を参照していたことが原因でした。  
以下のようなコードが存在しており、これがSSR中にも実行されてしまい、  
`ReferenceError: document is not defined` により500エラーが発生していました。

```tsx
const hasCookie = document.cookie.includes('animationPlayed=true')
```

このコードは `"use client"` を記述しているファイル内で使用されていたため、  
**サーバーでは実行されないと思い込んでいました**。

しかし、**Next.jsにおけるクライアントコンポーネントであっても、SSR時には関数本体が一度だけ評価される**ため、  
`document` などのクライアント専用オブジェクトを直接参照するとクラッシュします。



## 対応方法

クライアント側でのみ `document` を参照するよう、`useEffect` 内に処理を移動することで対応しました。

### 修正前（NG）

```tsx
const hasCookie = document.cookie.includes('animationPlayed=true')
```

### 修正後（OK）

```tsx
const [hasCookie, setHasCookie] = useState(false)

useEffect(() => {
  setHasCookie(document.cookie.includes('animationPlayed=true'))
}, [])
```

`useEffect` はクライアント側でのみ実行されるため、SSR中に `document` を参照することがなくなり、500エラーも解消されました。


## なぜ「use client」だけでは不十分なのか

`"use client"` を付けたコンポーネントはクライアントコンポーネントとして扱われますが、  
**Reactが最初にHTMLを生成するためにコンポーネント関数本体を一度実行する**という挙動は変わりません。

そのため、以下のような処理はSSR中にも評価されるため、注意が必要です。

```tsx
// SSR中にも実行される（NG）
const width = window.innerWidth
const cookie = document.cookie
```

このような処理は、必ず `useEffect` または `typeof window !== 'undefined'` 等でガードする必要があります。



## OGPとSSRの関係について補足

OGPは、ページのHTMLに含まれる `<meta>` タグの情報をもとにSNS側で展開されます。  
FacebookなどのクローラーはJavaScriptを実行せず、**SSRによって返されたHTMLのみを解析**します。

つまり、**SSR中にクラッシュしてHTMLが正しく返されない場合、OGP情報も取得できず、画像やタイトルが一切表示されない**という結果になります。


## まとめ

- OGP画像が表示されない場合は、Facebook Debuggerなどでステータスコード（500など）を確認する
- `"use client"` を記述していても、関数本体の評価はSSR中に一度だけ実行される点に注意
- `document`, `window`, `navigator`, `localStorage` などのクライアント専用オブジェクトは、**`useEffect` 内でのみ使用する**



## 最後に

通常のブラウザの開発者ツールでは特に問題ないように見えるので解決に時間がかかりました
同様の現象に悩まれている方の参考になれば幸いです。
windows 11 HomeでHyper-Vをインストールする

## 経緯
私自身はよわよわエンジニアですが、つよつよエンジニアの方たちはLinuxを使いこなしているイメージがあり、ただただLinux環境を構築してみたかったからです。
WSL2を使用する方法もありますが、業務でHyper-Vを使用することがあり、Wslよりも本格的な感じがしたので、Hyper-Vを使用して、Linuxの環境を作成することにしました。(今回はLinux環境構築には触れません。)

## windows 11 HomeにHyper-Vをインストールする手順
注意点として、windows 11 Homeでは、Microsoft learnに記載の方法では、hyper-vをインストールできません。

https://learn.microsoft.com/ja-jp/windows-server/virtualization/hyper-v/get-started/Install-Hyper-V?pivots=windows


## 1. 任意の場所にバッチファイルを作成してください
```shell:バッチファイル作成
pushd "%~dp0"
dir /b %SystemRoot%\servicing\Packages\*Hyper-V*.mum >hyper-v.txt
for /f %%i in ('findstr /i . hyper-v.txt 2^>nul') do dism /online /norestart /add-package:"%SystemRoot%\servicing\Packages\%%i"
del hyper-v.txt
Dism /online /enable-feature /featurename:Microsoft-Hyper-V /All /LimitAccess
pause
```
- メモ帳 > コピペ > 名前を付けて保存 > 任意のフォルダに保存

*注意点はファイルの種類をすべてのファイルにして、拡張子`.bat`までつけること*

![{67ED1EB4-89A5-442C-92FF-40F50DAB10C2}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686561/96ad77e6-a6a7-4372-868d-9aae397c8284.png)

## 2. 作成したバッチファイルを管理者として実行

- 作成したバッチファイルを右クリック > 管理者として実行を選択

![{C2F69745-C480-4323-B2D9-702C138C6514}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686561/74ee21aa-ec00-4553-828f-7b137162e13d.png)

## 3. 「Y」を選択して再起動
しばらく待つと「今すぐコンピューターを再起動しますか？(Y/N)」と表示されるので、「Y」を選択して、PCを再起動します。
![{9D012317-D752-4363-A3CB-2144C9F32902}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686561/4b8ebef5-551d-48ba-aae9-70423a795e38.png)

## 4. Hyper-Vを有効化する
- windowsの機能を開いて、`Hyper-V`と`Windowsハイパーバイザープラットフォーム`にチェックを入れてOKをクリックしてください。

![{B4EB4BC0-A227-46B3-9052-396292C64430}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686561/751b9935-7ec8-446b-9084-e20978b8f814.png)

- 今すぐ再起動でもう一度再起動する。

![{F176E427-E178-4629-92B9-567387DACE50}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686561/109b659a-c738-41ee-a67d-0de025949001.png)

## 5. Hyper-Vマネージャーが起動することを確認する
![{B9A9F266-EAA6-4B8F-B5D4-18DB0E5F5B59}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686561/f0834c4e-3312-42ab-956b-c1f13e5036f0.png)

![{EAE04140-2E96-4F1E-B424-7976BF70AEB3}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686561/c17c6608-e93b-4870-afd2-4d856c4edbf2.png)

## まとめ
これで、Windows上に仮想環境を作成する準備が整いました。
次は、インストールしたHyper-Vを使用して、いよいよLinux環境を作成していこうと思います。
【Chrome拡張機能】ブラウザのタブを整理・保存する拡張機能を作ってみた

## 要約

- Tab Group Ex（Chrome拡張機能)を作成しました。
- この拡張機能には、**タブの自動グループ化、タブグループの開閉、保存、復元**の機能があり、ブラウザの整理整頓が簡単にできます。
- 詳しい使い方を以下で説明します。

## 対象読者

- すぐにブラウザのタブがいっぱいになり、整理したい方
- タブを保存して、いつでも復元できるようにしたい方

## 目次

1. [はじめに](#はじめに)
2. [デモ](#デモ)
3. [拡張機能の紹介](#拡張機能の紹介)
   - [タブの自動グループ化](#機能1-タブの自動グループ化)
   - [タブグループを一覧表示](#機能2-タブグループを一覧表示)
   - [タブグループの保存・復元](#機能3-タブグループの保存・復元)
4. [キーボードショートカット](#キーボードショートカット)
5. [最後に](#最後に)

## はじめに

皆さんは普段、こんな悩みはありませんか？

> 「気づいたらブラウザのタブがいっぱいで、どこに何があるのか分からなくなった…。」  
> 「昨日開いていたあのページをまた開きたいけど、見つからない…。」

私もよくありますが、こうした悩みがあると**作業効率がどんどん下がってしまいます**…。  
そこで、**ブラウザのタブを整理するChrome拡張機能「Tab Group Ex」** を作成しました！  

今回は、この拡張機能について紹介します。

ダウンロードはこちらからできます。
https://chromewebstore.google.com/detail/tab-group-ex/fapofgkidlmimpfamjgmeikgafjjgbpk?hl=ja

## デモ

![tab-group-ex_demo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328838/26f04cb4-efa9-468e-a15d-35ac87f36aaa.gif)


## 拡張機能の紹介

この拡張機能には、大きく分けて**3つの機能**があります。

- **タブの自動グループ化**
- **タブグループを一覧表示**
- **グループ化したタブを保存・復元**

それぞれ詳しく説明していきます。  
また、**キーボードショートカット**も用意しているので、画面操作が面倒な方はぜひ最後までチェックしてください！

### 機能(1) タブの自動グループ化

ブラウザで開いているタブを**自動グループ化**する機能です。

#### 実行方法

1. **拡張機能を開く**
2. 「**GROUPS**」タブの「**Actions**」にある「**Group Tabs**」をクリック
3. 現在開いているタブが、設定されたモードでグループ化される

#### グループ化モード

- **All**：グループ化されていないタブを1つにまとめる（**デフォルト**）
- **Domain**：ドメインごとにグループ化する（サブドメインは無視）
- **Custom Domain**：指定したドメインごとにグループ化（※詳細は後述）

#### Custom Domain 設定方法

1. **拡張機能を開く**
2. 「**RULES**」タブでテキストボックスに対象ドメインを入力
3. 「**SAVE GROUP RULES**」をクリック  
   （追加する場合は「**ADD GROUP RULE**」を押下）

💡 **設定例**  
- `https://qiita.com/` → `qiita`  
- `https://chat.openai.com/` → `openai`  

### 機能(2) タブグループを一覧表示

現在のタブグループを**一覧表示**する機能です。

#### 確認方法

1. **拡張機能を開く**
2. 「**GROUPS**」タブの「**Current TabGroups**」を確認

#### 操作できること

- **タブグループ内のタブを一覧表示**
  - **タブグループ名をクリック**すると、タブの一覧が表示
  - クリックするとそのタブに移動可能
- **タブグループの開閉**
  - **タブグループ名を右クリック**で開閉
- **タブグループの解除・削除**
  - **右側の「設定」アイコンをクリック** → メニューから選択
    - **Close**：タブグループを閉じる
    - **Ungroup**：グループ化を解除する

### 機能(3) タブグループの保存・復元

タブグループを保存すると、**ブラウザを閉じた後でも復元が可能**です。

#### 保存方法

1. **拡張機能を開く**
2. 「**GROUPS**」タブの「**Current TabGroups**」で、各タブグループ名の右側にある「**保存**」アイコンをクリック

#### 復元・削除方法

1. **「SAVED」タブを開く**（保存済みのグループが一覧表示される）
2. **操作を選択**
   - **復元**：タブグループ or タブの「復元」アイコンをクリック
   - **削除**：タブグループの「削除」アイコンをクリック

## キーボードショートカット

| ショートカットキー | 説明 |
|------------------|------|
| `Ctrl + Shift + Z` | 拡張機能を開く |
| `Ctrl + Shift + 1` | 未グループ化のタブを1つのグループにグループ化（All） |
| `Ctrl + Shift + 2` | ドメインごとにタブをグループ化（Domain） |
| `Ctrl + Shift + 3` | 指定したドメインごとにグループ化（Custom Domain） |

💡 **ショートカットの変更方法**  
ブラウザのURLに `chrome://extensions/shortcuts` を入力し、そこで変更可能。

## 最後に

今回は、私が作成した**ブラウザのタブを整理整頓する拡張機能**を紹介しました。  
GitHubのリポジトリも載せているので、もし何かあればコメントいただけると幸いです！

https://github.com/o-kaisan/tab-group-ex
【Udemy学習記録】「ゼロから学ぶネットワーク基礎」通信の流れを整理してみた

## はじめに

ネットワークの基礎を学ぶために、Udemyの「ゼロから学ぶネットワーク基礎」を受講しました。

本記事では、この講座で学んだ「通信の流れ」について、自分なりに整理・解釈しながらまとめていきます。

## 講座概要

- 講座名：ネットワークエンジニアを目指す初心者はここから始めよう！「ゼロから学ぶネットワーク基礎」豊富な図解で徹底解説
- 対象者：ネットワークの基礎を学びたい初学者
- 学べること：IPやEthernetを用いたネットワークの基礎

ネットワークの基礎を一通り学ぶために、動画教材を探していたところ、この講座が多く紹介されていたため受講しました。

通信の仕組みを理解し、メンタルモデルを構築することを目的に受講しました。

そのため、本記事では「通信の流れ」に絞ってまとめていきます。

## 通信の流れ

送信元ホストから宛先ホストにデータを送信する場合を考えます。

送信元ホストが宛先ホストのIPアドレスをすでに知っていると仮定します。

まず、宛先ホストが同じネットワークにいるのか、それとも異なるネットワークにいるのかを、送信元ホストのIPアドレスとサブネットマスク、および宛先ホストのIPアドレスを使って判断します。

### 同じネットワークにいるとき

1. ヘッダに宛先ホストのIPアドレスを付加
    - 前提条件から、宛先ホストのIPアドレスはわかっている
2. ヘッダに宛先ホストのMACアドレスを付加
    - ARPテーブルを参照
    - 記載がなければ、ARPリクエストを送る
3. L2スイッチにデータを送信
4. フォワーディングデータベースを参照して、宛先ホストのポートを確認
    - 記載がなければ、フラッディングを行う
5. 宛先ホストにデータが届く

### 異なるネットワークにいるとき

1. ヘッダに宛先ホストのIPアドレスを付加
    - 前提条件から、宛先ホストのIPアドレスはわかっている
2. ヘッダにデフォルトゲートウェイのMACアドレスを付加
    - ARPテーブルを参照
    - 記載がなければ、ARPリクエストを送る
3. デフォルトゲートウェイにデータを送信
4. L2スイッチがフォワーディングデータベースを参照して、デフォルトゲートウェイのポート番号を確認
    - 記載がなければ、フラッディングを行う
5. デフォルトゲートウェイにデータが届く
6. ルーティングテーブルを参照して、次に送信すべきルータを決定
    - ルーティングテーブルは、手動or自動で作成されている
7. ヘッダに次に送信すべきルータのMACアドレスを付加
    - ARPテーブルを参照
    - 記載がなければ、ARPリクエストを送る
8. データが次のルータに到達
9. ステップ6~8を繰り返し、最終的に宛先ホストのネットワークに到着
10. 宛先ホストのL2スイッチがフォワーディングデータベースを参照して、宛先ホストのポートを確認
    - 記載がなければ、フラッディングを行う
11. 宛先ホストにデータが届く

## 気づいたこと

一見複雑に見えますが、実際には以下のことを繰り返しているだけだと気づきました。

- データベースやテーブルを参照して行き先を決定
- データベースやテーブルに記載がなければ、調べて確認

## 感想

この講座を通じて、IPやEthernetを用いたネットワーク通信の流れについて、自分なりのメンタルモデルを構築することができたと思います。

今後は、さらに細かい知識も学んでいきたいと思います。
Azure プライベートエンドポイント経由でのストレージアカウントへのアクセス

## はじめに
本記事ではazureクラウドでプライベートエンドポイント経由でのストレージアカウントの静的webサイトへのアクセス方法について記載します。

## 構成
構成については、以下の通り。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733779/0f342e4d-98ed-49f3-90a5-515d6a9b1c60.png)

## 手順
前提としてvnetとsubnet,bastion,vm,ストレージアカウントは作成済みとする。

1. プライベートエンドポイントの作成
    注意点としては今回静的webサイトを対象としているため対象サブリソースを「web」とする
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733779/fd1dd4a0-4a0a-4409-a497-02991d278b5b.png)
 またプライベートDNSゾーンも自動で作成される。

1. ストレージアカウントで静的なwebサイトを有効化する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733779/341b97b2-1f8c-43b1-a345-012d81a1a29f.png)

1. コンテナに自動で$webが作成されるのため、index.htmlを格納する
1. vmから静的webサイトにアクセスすると表示されるが、ローカル端末からアクセスすると表示されない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733779/9899195f-c6ba-4165-9e50-19222fe07cdb.png)


## まとめ
ストレージのファイアウォールからip制限もかけることができるが、プライベートエンドポイントを使用したほうがよりセキュアになる。AWSと違いプライベートDNSゾーンが自動で作成されるためコストがかかる。
Screen Flow Distribution Superbadge Unit



https://trailhead.salesforce.com/content/learn/superbadges/superbadge_screen_distribution_sbu

# Hive アプリ ページを更新する

プロバイダーフローを Hive アプリのホームページに追加し、アカウント レイアウトのアクションとして追加します。

何もせずに検証ボタンをクリック

:::note alert
We can't find a flow on the Hive App Home page.
:::

まだ、設定が必要？


:::note alert
The account object doesn't have an action named 'Create New Provider'.


アカウント オブジェクトには、「新しいプロバイダーの作成」というアクションがありません。
:::


# Hive アプリのページをさらに更新

連絡先レイアウト上のカスタム ボタンを使用してプロバイダーフローを配布し、Hive アプリのユーティリティ バーに追加します。


何もせずに検証ボタンをクリック

:::note alert
We can't find the Add New Provider button on the contact.
:::

:::note alert
We can't find any flows on the Hive App Utility bar.
:::



# プロバイダーフローを更新する

プロバイダーフローを Hive サイトに配布し、要件に応じて画面を調整します。

何もせずに検証ボタンをクリック

:::note alert
It appears we can still pause the flow at various times during execution.


実行中にさまざまなタイミングでフローを一時停止できるようです。
:::


:::note alert
We can't find a Provider record created by Jane Grey with the correct Practice Type.


正しい診療タイプで Jane Grey によって作成されたプロバイダー レコードが見つかりません。
:::

:::note alert
We can't find the expected configuration updates relating to Practice Name on the S2 Provider Signup screen.


S2 プロバイダー サインアップ画面で、プラクティス名に関連する予想される構成の更新が見つかりません。
:::
bash の builtin-command をまとめる

## 概要
bash の builtin-command について簡単にまとめておきます。
- echo (-n option)
- cd
- pwd
- export
- unset
- env
- exit
## 🔧 echo コマンドとは？
`echo` は、**指定した文字列を標準出力**する ビルトインコマンドです。
```shell
$echo "Hello World"
Hello World
```
また、`-n` のオプションがあり、これを指定すると**改行が無くなります**。
```shell
$echo -n "Hello World"
Hello World$(次のコマンド)
```
このように、出力した文字の後ろからすぐに次のコマンドを入力することが出来ます。
## 🔧 cd コマンドとは？
`cd` は、**カレントディレクトリを変更する**コマンドです。
```shell
$cd /home/user/Documents
```
このようにパスを指定することで、そのディレクトリへ移動できます。また、**相対パス**や `..`（1階層上）、`~`（**ホームディレクトリ**）なども利用可能です。
```shell
$cd ..
```
現在のディレクトリから**一つ上の階層**に移動します。
```shell
cd ~
```
**ホームディレクトリ**に移動します。

## 🔧 pwd コマンドとは？

`pwd`（print working directory）は、**現在のカレントディレクトリを表示する**ビルトインコマンドです。
```shell
$pwd
/home/user/Documents
```
`pwd`と打つことで、自分が今**どこのディレクトリにいるのか**を確認することが出来ます。
## 🔧 export コマンドとは？
`export` は、**シェル変数を環境変数としてエクスポート**し、子プロセスからも参照できるようにするコマンドです。
```shell
$ export VAR1=hello
$ echo $VAR1
hello
```
このように設定した変数は、他のコマンドやスクリプト内でも**参照可能**になります。
## 🔧 unset コマンドとは？
`unset` は、**変数や環境変数を削除する**コマンドです。これにより、変数の値を無効化できます。では、実際に先ほど設定した`VAR1`を削除してみます。
```shell
$echo $VAR1
hello
$unset VAR1
$echo $VAR1
(何も表示されない)
```
## 🔧 env コマンドとは？
`env`は、**環境変数の表示**や**一時的に環境変数を設定する**際に使用されるコマンドです。
```shell
$env
```
と打つことで、`KEY=VALUE`方式で現在の**全環境変数**を取得することが出来ます。また、以下のように書くことで**一時的に環境変数を設定する**ことが出来ます。
```shell
$env VAR1=test1 printenv VAR1
test1
```
実行後は、今設定したVAR1は消えて元に戻ります。そのことを以下で確認してみます。
```shell
$env VAR1=test1 printenv VAR1
test1
$printenv VAR1
(何も出ない)
```
`env`実行後に、`printenv`単体で`VAR1`を確認すると何も表示されませんでした。
## 🔧 exit コマンドとは？
`exit` は、**シェルやスクリプトの実行を終了する**ためのビルトインコマンドです。
```shell
$exit
```
これにより、現在のシェルセッションが終了します。
数値（終了コード）を指定することで、終了ステータスを明示的に設定することもできます。

## 最後に
これらのコマンドをC言語で実装する記事を執筆中です。完成したら投稿します！！
(投稿URL)
FiiO JM21にMedia Goからプレイリストを転送する（Pythonを使う）

# はじめに
[FiiO JM21](https://www.fiio.jp/products/jm21/) はコストパフォーマンスに優れたDAPですが、内蔵プレーヤーアプリの FiiO MUSIC の使い勝手に難があります。特にプレイリストについては独特な仕様が複数あり、PC の音楽管理ソフトからのプレイリスト転送が困難です。

本記事では、内蔵SDカードに対して、SONY が提供していた音楽管理ソフト Media Go からプレイリストを転送して、Fiio MUSIC で読み込めるように加工する方法を提供します。



# FiiO MUSIC の仕様
先述した通り、FiiO MUSIC には独特な仕様が複数あります。今回関わってくるのは以下の仕様です。

- プレイリストファイルは、 `/storage/emulated/0/Android/data/com.fiio.music/files/playlist` 配下しか読まない
- ファイル名は `{playlist_title}.playlist.m3u(8)` しか読まない
- m3u(8) ファイルで指定するパスは、絶対パスで指定する

それに対して、Media Go からFiiO JM21にプレイリストを転送する際は以下の挙動をします。

- プレイリストファイルは、 `/storage/external_sd/Music` 配下に出力される
- ファイル名は `{playlist_title}.m3u`
- m3u ファイル内で指定されるパスは、相対パス

以上の差異を埋めれば読み込めるということです。一つずつ解決していきます。

# ファイル配置場所
`/storage/emulated/0/Android/data/com.fiio.music/files/playlist` を、 `/storage/external_sd/Music` へのシンボリックリンクにします。

Windows マシンからシンボリックリンクを貼るために、Fiio JM21 を USB デバッグモードにして、Windows マシンにはadbをインストールしておきます。（やり方は各自調べてください）

以下コマンドを実行すればシンボリックリンクになります。

```sh
$ adb shell
$ cd /storage/emulated/0/Android/data/com.fiio.music/files
$ rm -rf playlist
$ ln -s /storage/external_sd/Playlists playlist
```

参考: https://www2.filewo.net/wordpress/2025/02/01/3989/#USB

# ファイル名
ふつうにリネームすればよいです。Windows の .bat を使うのが一番シンプルなはずですが、私は弱いので Python で実装します。

```py
import subprocess

m3u_list = [path.replace(" ", "\\ ") for path in str(subprocess.check_output("adb shell ls /storage/external_sd/Music/*.m3u"))[2:].split("\\r\\n")[:-1]]

for path in m3u_list:
    # すでに .playlist.m3u になっているファイルはスキップする
    if 'playlist' in path:
        continue
    rep_path = path.replace(".m3u", ".playlist.m3u")
    print(f'adb shell cp \"{path}\" \"{rep_path}\"')
    subprocess.check_output(f'adb shell cp \"{path}\" \"{rep_path}\"')
```

# m3u のパス
`.playlist.m3u` ファイルの中身を読み込んで、パス指定部分に `/storage/external_sd/Music/` のプレフィックスを加えます。そのままだと区切り文字がバックスラッシュ `\` になっているので、ついでに置き換えます。

```py
# .playlist.m3u のファイルだけをリストアップ
path_list2 = [path.replace(" ", "\\ ")for path in str(subprocess.check_output("adb shell ls /storage/external_sd/Music/*playlist.m3u"))[2:].split("\\r\\n")[:-1]]

for m3u_path in path_list2:
    # .m3u を Windows 側に adb pull
    m3u_path = m3u_path.replace("\ ", " ")
    local_file = './temp.m3u'
    subprocess.check_output(f"adb pull \"{m3u_path}\" \"{local_file}\"")

    # BOM付きなので utf-8-sig で読む
    with open(local_file, "r", encoding="utf-8-sig") as f:
        content = f.read()
        
    prefix = '/storage/external_sd/Music/'
    modified_lines = [
            # パスが書かれている行は 0 始まりでカウントして 2, 4, 6, ...（偶数インデックス）
            prefix + line.replace('\\', '/') if i % 2 == 0 and not i == 0 else line
            for i, line in enumerate(content.splitlines())
        ]

    # ローカルに出力 → adb push
    output = "\n".join(modified_lines)
    local_output = "temp_output.m3u"
    with open(local_output, "w", encoding="utf-8-sig") as o:
        o.write(output)
    subprocess.check_output(f"adb push \"{local_output}\" \"{m3u_path}\"")
```

# FiiO MUSIC で読み込む
以上を実行して、FiiO MUSIC の「M3Uプレイリストのインポート」を実行すれば無事にインポートできるはずです。python のコードはファイルにまとめといて .bat から呼び出せるようにすると便利だと思います。

# やり残したこと
- ファイル名のエスケープが甘いので、`(` `)` とかがあるとエラーになる。各自で改良されたい。
- たぶん .bat で全部できそう
Hello world

# 初めての投稿
こんにちは！ついにこのブログを始めることができました。これから、自分の学びや日々の気づきを少しずつ発信していきます。初めての試みなので手探りですが、読んでくださる方に何かしらの気づきや共感を届けられたら嬉しいです。どうぞよろしくお願いします！

# Qiita

`tags` が空欄だとGithub Actionsが失敗する
マイクロサービスアーキテクチャの利点と課題

## はじめに
本記事では、書籍「マイクロサービスアーキテクチャ 第2版」で読んだ内容をまとめます。今回はマイクロサービスの利点と課題についてまとめていきます。

https://www.oreilly.co.jp/books/9784814400010/


## マイクロサービスの概要
マイクロサービスとは、ビジネスドメインごとに独立して開発・デプロイが可能な小さなサービス群で構成されたアーキテクチャスタイルです。各サービスはネットワーク越しに通信し合い、全体として一つのアプリケーションを構成します。

このアプローチは「サービス指向アーキテクチャ（SOA）」の一種であり、特定の技術スタックに依存しないのが特徴です。マイクロサービスの目的は、疎結合で柔軟性の高いシステムを構築することにあります。

### コンセプト
🔹 独立デプロイ可能性
マイクロサービスでは、各サービスが独立してデプロイできることが求められます。これは他のサービスと疎結合であることが前提で、共有データベースのような強い結合は避ける必要があります。

🔹 ビジネスドメインに基づくモデル化
ドメイン駆動設計（DDD）に基づき、サービスの境界をビジネスロジックの単位で明確に定義します。これにより、機能の追加や変更が局所的に行えるようになります。

🔹 状態の所有
それぞれのサービスは自分のデータを所有します。データが必要な場合は直接DBにアクセスせず、他サービスのAPI経由で取得することが原則です。

## マイクロサービスの利点
多くの利点が分散サーバーによるものです。しかし、マイクロサービスアーキテクチャでは境界の定義に特定の考え方（ドメイン駆動設計に習うなど）があるため、さらに利点が大きくなります。

**1. 技術の異種性**

マイクロサービスアーキテクチャでは各サービスに異なる言語や技術を選択可能です。
各サービスが独立しているため、**最適な技術スタックを選択可能**です。

**2. 堅牢性**

アプリの堅牢性を向上させる重要な概念は「バルクヘッド（障壁）」です。
バルクヘッドの設計により**一部の障害が全体に波及しない**構造を作れます。

**3. スケーリング**

モノリシックサービスでは大規模に全てをまとめてスケールさせる必要がありますが、マイクロサービスでは必要なコンポーネントのみをスケール可能です。**効率的なコスト最適化**が可能となります。

**4. デプロイの容易性**

モノリシックアプリケーションの場合は１行の変更でも全体（１００万行など）をデプロイする必要がありますが、このような場合、影響が大きく危険性の高いものとなる可能性があります。マイクロサービスの場合は、独立してデプロイ可能なため、迅速にデプロイすることができます。

**5. 組織連携**

１つのコードベースに対して、チームの規模を生産性とのバランスの取れた適切な領域にすることが可能です。

**6. 合成可能性**

マイクロサービスでは、サービスが明確に分離されているため、**再利用や機能の組み合わせ**がしやすくなります。

## マイクロサービスの課題
マイクロサービスの多くの問題は分散システムによるものであり、多くの複雑さがもたらす欠点と利点を比較できるようにすることが重要です。

**1. 開発者体験**

１台の開発者マシンで実行できるマイクロサービス数には制限があります。１台のマシンでシステム全体を構築できない場合にどうすべきかの議論をする必要があります。場合によってはクラウドでの開発も選択肢となりますが、フィードバックサイクルの低下を招く可能性があります。

**2. 技術の過負荷**

マイクロサービスでは異なるランタイム上で動作可能で、異なるデータベースを使うための選択肢を与えてくれます。その一方で使用する技術の幅広さや複雑さ、多様な技術がもたらすコストの間のバランスを慎重に取る必要があります。データ一貫性や遅延、サービスのモデル化といった問題解決のための新しい技術やソフトウェア開発への考え方を理解する必要があり、**学習運用コストが増大**します。

**3. コスト**

短期的にはコストが上昇する可能性が高いです。使用リソースが増えることによるコスト増加となる可能性があります。

**4. レポートと監視**

全体像を把握するための監視・ログ収集・トレーシングは必須であり、専用の仕組み（Prometheus, Grafana, OpenTelemetryなど）が求められます。

**5. セキュリティ**

マイクロサービスではサービス間ネットワークを介して多くの情報が流れるためセキュリティ上の危険性が高まります。

**6. 遅延**

以前は１つのプロセッサ上でローカル実行されていた処理が、複数のマイクロサービスに分割されます。そのため、ネットワークを介したシリアライズ、転送、デシリアライズを行う必要があり、システムの遅延を悪化させる可能性がある。

**7. データ一貫性**

単一のデーターベースで管理していたデータを、複数プロセスが異なるデーターベースで管理することで、データ一貫性の観点で課題が発生する可能性があります。

## まとめ
マイクロサービスは、多様な技術を活用しながら柔軟でスケーラブルなシステムを構築できる一方で、分散アーキテクチャ特有の複雑さや課題も抱えています。マイクロサービスを採用することで享受できる利点と、抱える可能性のある課題を認識しながら、要件や運用設計をトータルで見ながら進めることが重要ですね。
next.js 13 でカスタムカラーを設定しよう！

## 動機
next.jsのアプリ開発でTailwindのデフォルト設定されているカラーパレット以外で、カスタムで用意したいと思った。


Tailwindの設定ファイルtailwind.config.jsのtheme.extend.colorsに設定を記述することでデフォルトのカラーパレットを追加することができる手法を試してみたが、適用することができなかった。

### ちなみに、適用できない件に関して以下のことは試してみた。
・tailwind.config.js がプロジェクトのルートディレクトリに正しく配置されているか確認
・プロジェクトのルートに postcss.config.js ファイルがあることを確認
・CSSファイルのインポート確認
・開発サーバーの完全な再起動
・キャッシュの削除

## 他の手法を模索

app/global.cssにCSS 変数を直接使用して、以下のように定義すると
```css
:root {
  --color-custom-red: #FF5154;
  --color-custom-red-light: #FF6567;
  --color-custom-purple: #B900FF;
}
```
次のようにコンポーネント内で使用できる。
```html
<div style={{ backgroundColor: 'var(--color-custom-red)' }} className="w-20 h-20"></div>
```
##
だがこれだと記述が長くなり、可読性が悪い。
そこで！！
Tailwind の @apply ディレクティブを使ってカスタムクラスを作成すると
使いやすく汎用性アップする(classNameにそのまま指定できる)
```css
/* globals.css */
@tailwind base;
@tailwind components;
@tailwind utilities;

:root {
  --color-custom-red: #FF5154;
  --color-custom-red-light: #FF6567;
  --color-custom-purple: #B900FF;
}

/* ここで、ユーティリティクラスを設定 */
@layer utilities {
  .bg-custom-red {
    background-color: var(--color-custom-red);
  }
  .bg-custom-red-light {
    background-color: var(--color-custom-red-light);
  }
  .bg-custom-purple {
    background-color: var(--color-custom-purple);
  }
}
```

##
この方法なら、通常の Tailwind クラスと同じように使える
```html
<div className="w-20 h-20 bg-custom-red"></div>
```
記述も短くなり、プロジェクト内で汎用がしやすくなった！ハッピー！！！


やったことをまとめると
1. global.css: ルート要素にカスタムカラー変数を定義
2. global.css: @layer utilities を使って Tailwind のユーティリティクラスとしてカスタムカラーを設定
KUMO：大規模言語モデルは本当に推論しているのか？―SATと自然言語で挑む次世代ベンチマーク

# 「本当に推論しているのか？」を問う：KUMOによる大規模言語モデルの論理的推論能力評価

今回は、Haowei Linらによる2025年の論文「Generative Evaluation of Complex Reasoning in Large Language Models」をご紹介します。  
この研究は、大規模言語モデル（LLMs）の推論能力を動的・構造的・論理的に評価するベンチマーク「KUMO」を提案し、LLMがどのような知的過程で結論に到達しているのかを**観察可能な形で評価**することを目的としています。

---

### 論文情報
- **タイトル**: Generative Evaluation of Complex Reasoning in Large Language Models  
- **リンク**: [https://arxiv.org/abs/2504.02810](https://arxiv.org/abs/2504.02810)  
- **発表日**: 2025年4月3日  
- **著者**: Haowei Lin, Xiangyu Wang, Ruilin Yan, 他  
- **DOI**: [10.48550/arXiv.2504.02810](https://doi.org/10.48550/arXiv.2504.02810)

---

## 背景と目的：言語モデルは「推論」しているのか？

多くのLLMは、人間のような自然な文章を生成できる一方で、その出力が**「思考」に基づくものなのか、「記憶」なのか**を判定する方法はこれまで存在しませんでした。

本研究は次の問題意識から出発します：

- ベンチマーク問題の汚染（Contamination）  
- CoT（Chain-of-Thought）における推論の検証不能性  
- 訓練データに含まれた情報と新規性の分離困難  
- 単なる正答率では「どのように考えたか」が見えない

これらに対し、**自然言語による知識提供 + 論理的に整合性ある環境**での動的評価を可能にする「KUMO」が提案されました。

---

## KUMOの設計と理論的フレーム

KUMOは、**形式推論空間における行動選択ゲーム**です。  
形式的には次のように構成されます：

### 構成要素

- $T$：Truth候補集合（例：病気名）
- $A$：Action集合（例：検査項目）
- $K: T \times A \rightarrow O$：知識ベース（Knowledge Book）
- $O$：観測結果（例：陽性／陰性など）

タスクは、SATソルバーによって以下の条件を満たすように構成されます：

- 各 $t \in T$ に対して、複数の $a \in A$ による識別可能性が保証される  
- 一意な真理 $t^*$ が存在し、最適な行動系列によってそれを特定可能  
- 複数の推論パスが存在する（非直列的な論理構造）

---

## LLMの性能と行動分析

### 評価モデル

23モデルが評価対象となり、以下に分類されます：

- **Reasoning-scaled**：推論能力に特化した微調整（DeepSeek-R1等）
- **Instruction-tuned**：RLHFや指示追従チューニング（GPT-4o, Claude 3.5）
- **Base**：プリトレインのみの非微調整モデル（LLaMA-3, Qwen等）

### 評価指標

- **Success Rate**：最終解の正答率
- **Relative Action Count (RAC)**：理想的行動数との差  
  $$
  \text{RAC} = \frac{|\text{LLM Action}| - |\text{Optimal}|}{|\text{Optimal}|}
  $$

### 結果概要

| モデルタイプ | Easy正答率 | Hard正答率 | 平均RAC |
|--------------|------------|------------|---------|
| DeepSeek-R1 | 94.8% | 78.3% | +0.23 |
| GPT-4o       | 96.1% | 71.4% | +0.49 |
| Claude 3.5   | 93.5% | 69.9% | +0.52 |
| LLaMA-3 70B | 83.2% | 51.0% | +1.10 |

---

## 誤答パターンと推論傾向の分類

KUMOは誤答に至るまでの行動をすべて記録可能です。分析の結果、以下の誤答パターンが観測されました：

- **過剰観測型**
- **早期決断型**
- **誤解釈型**
- **構文盲点型**

---

## マルチモーダル評価への拡張性

- 画像（例：レントゲン）
- 表（例：診療フローチャート）
- 音声（例：心音判断）

GPT-4oやGemini 1.5 Proなど、マルチモーダル対応モデルへのKUMO適用も視野に入ります。

---

## 教育・医療など実務応用

- **教育**：推論教材の自動生成・生徒の認知行動分析
- **医療**：診断フロー評価・AI診断の透明性確保

---

## メタ評価とベンチマークとしての信頼性

- 安定性・一貫性スコアによる**ベンチマーク自体の信頼性**評価が可能
- モデル間スコアばらつきの統計的検証が容易

---

## 限界と批判的視点

- **論理完全性 vs 人間的合理性**：ヒューリスティック判断や直感的理解とのギャップ
- **言語構文への脆弱性**：接続詞・否定構文の扱いが誤答を招く

---

## KUMO 2.0構想

- Counterfactual推論対応
- 確率論的知識への対応（e.g., Bayesian推論）
- チーム推論（Human + LLM）

---

## 結論

KUMOは、LLMの「推論能力」を、論理構造に基づいて動的・透明に測定可能にした初のフレームワークです。  
今後の研究・教育・実務において、AIの「思考過程」を可視化・制御する技術の中核となるでしょう。

---

📄 論文PDF：[https://arxiv.org/pdf/2504.02810](https://arxiv.org/pdf/2504.02810)  
💻 GitHub：[https://github.com/linhaowei1/kumo](https://github.com/linhaowei1/kumo)
React hooksとuseState

## React hooksとは
React 16.8で追加された機能
関数コンポーネントで状態管理や副作用処理などのReactの機能を使えるようにする仕組み

## useStateとは
関数コンポーネント内で状態管理するために使うもの

## 基本的な使い方
```react
const [state, setState] = useState(initialValue);
```
- `state`: 現在の状態の値
- `setState`: 状態を更新する関数
- `initialValue`: 状態の初期値（例えば 0, "", false など）

### 具体例
```react
import { useState } from "react";

// +1ボタンを押すごとに、カウントが増える関数
function Counter() {
  // countの初期値を0に設定
  const [count, setCount] = useState(0);

  const increment = () => {
    setCount(count + 1);  // countを1増やす
  };

  return (
    <div>
      <p>カウント: {count}</p>
      <button onClick={increment}>+1</button>
    </div>
  );
}
```
countの値は `setCount(count + 1)` を呼んだ直後にはすぐには更新されません(例えば、0の時に、`+1`ボタンを押しても、見かけは1となっていますが、本当の`count`は0)。
仕組みなどを解説します。

## Reactの画面表示と再レンダリングの仕組み
### 画面表示の動き
1. `setCount(count + 1);`を呼びます
→ しかし`count`の値は すぐには変わらないです
2. Reactは「次のレンダリングが必要」と判断し、仮想DOM(実際のDOMの差分だけ変更したもの)を更新されます
3. 新しい`count`の値を持った新しい仮想DOMを作成します
4. React が「変更点だけ」本物のDOMに適用（効率的に更新）します
5. 画面が更新され、新しい`count`が表示されます

### レンダリングのタイミング
- 初回レンダリング時
  - `Counter`コンポーネントが最初に表示されるとき、レンダリングされます
- `+1`ボタンが押されたとき
  - 前回押されたときの`count`の処理が実行されます

## まとめ
useStateはReactの関数コンポーネント内で状態管理を行うためのフックで、状態を変更すると再レンダリングが発生します。状態の更新は即時反映されず、Reactが次のレンダリングで画面に反映します。
ユーザー問い合わせの不具合が再現できないとき

# 再現できないときの対応について
ユーザーからの不具合の問い合わせで、再現ができないことがあります。

その場合、ユーザーが使用しているブラウザのバージョンが古くないかを確認してみましょう。

一般的なWebサービスではスマホからのアクセスが多く、ユーザーのスマホ利用環境に依存する不具合も起きやすいです。

機種が古いとブラウザのアップデートが出来なくなるので、頻繁にバージョンの更新があるスマホはPCよりも不具合が発生しやすいです。

たとえば、JavaScriptでは ES2023 から Array.prototype.findLast() が導入されましたが、未対応のブラウザでは「findLast is not a function」といった実行時エラーになります。

再現させる方法として、AWS DeviceFarmを使えば、2025年4月時点で iOS 13.6〜、Android 8〜の実機がリモート検証できます（利用可能な端末は随時更新されます）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601978/0ca62ff3-de61-4f32-91b4-a32affb382ea.png)


# 要件定義の段階で確認すべきこと

どのブラウザのバージョンからサポート対象とするかを、要件定義時に確認しておきましょう

高齢のユーザーが多い場合、スマートフォンの買い替え頻度が低いため、古いブラウザバージョンを考慮する必要があります。

この確認をせずに開発を進めると、後から対応ブラウザの範囲を広げるのが難しくなったり、想定外の修正コストが発生したりする可能性があります。

特に、JavaScriptフレームワークやライブラリは、特定のブラウザ機能に依存していることが多く、対応ブラウザによっては正しく動作しないことがあります。導入時は注意が必要です。

# まとめ
- 再現できない場合はブラウザのバージョンを疑う
- 要件定義の段階で、どのブラウザのバージョンからサポート対象とするかを確認する

スマホブラウザ起因の不具合は一見気付きにくいので、これらのことを意識しておくと原因の特定がスムーズになるかと思います。
競プロ典型 90 問 011 - Gravy Jobs（★6）

# 導入
atcoderで精進してますが、  
どこかにアウトプットしたかったので、qiitaに書くことにしました。  
ACしてから載せるようにしてますが、考え方が至っていない点があればご指摘頂けると幸いです。  
また、誰かの参考になると嬉しいです。

# 使用しているアルゴリズム
- 動的計画法（DP）

# 解法のポイント
この問題は「締切と作業時間のあるタスク」を選んで報酬の総和を最大化する典型的なスケジューリング問題です。  
DPテーブル `dp[i][j]` は、タスクを期限順にソートした `i` 番目まで見たとき、`j` 日目までで得られる報酬の最大値を表します。

以下、解法のポイントをざっくりと。

- タスクは `(l, d, a)` という形式で、締切 `l`、所要日数 `d`、報酬 `a`。
- 締切順にタスクを並べることで、DPで「そのタスクをやる/やらない」の選択がしやすくなります。
- 各タスクに対して、可能な日数 `j` を逆順でループすることで、「j - d 日前に終わっているなら実行できる」かどうかを簡単に判定できます。
- `dp[i][j] = max(dp[i-1][j-d] + a, dp[i-1][j])` のように、タスクをこなした場合とスキップした場合の最大を取って更新します。

最終的な答えは、全タスクを見たあとの `dp[-1]` の中で最大の値です。

# 具体的なDPイメージ

問題の入力例2の場合、以下のようなDPになります。

```
3
7 3 200000
3 2 100000
5 3 150000
```

| タスク数 \ 日数 | 0      | 1      | 2      | 3      | 4      | 5      | 6      | 7      |
|------------------|--------|--------|--------|--------|--------|--------|--------|--------|
| 0                | 0      | 0      | 0      | 0      | 0      | 0      | 0      | 0      |
| 1 (標準入力2番目)      | 0      | 0      | 100000 | 100000 | 0      | 0      | 0      | 0      |
| 2 (標準入力3番目)      | 0      | 0      | 100000 | 150000 | 150000 | 250000 | 0      | 0      |
| 3 (標準入力1番目)      | 0      | 0      | 100000 | 200000 | 200000 | 300000 | 350000 | 350000 |


# ACサンプル
```python
# dp[i][j]: iを標準入力で与えられたタスクを期限順にソートしたindex, jをj日目と考える
## つまり、dp[i][j]にはiタスク目のj日目で取れる最大の報酬総額を入れる
## 逆に標準入力で与えられたタスクを期限順にソートしなければdpは使えない

N = int(input())

tasks = [(l,d,a) for l,d,a in (map(int, input().split()) for _ in range(N))]
tasks.sort(key=lambda x: x[0])

# dp[i][j]のjの末端はmax(tasks, key=lambda x: x[0])[0]になる:: あ、tasks[-1][0]でもいけるわ
max_l = max(tasks, key=lambda x: x[0])[0]
dp = [[0] * (max_l + 1) for _ in range(N+1)]

for i in range(1,N+1):
  l,d,a = tasks[i-1]
  # そのタスクの期限から逆順に辿ることで斬化式が単純化できる
  for j in range(l, -1,-1):
    if j - d >= 0:
      # 単純化された斬化式
      dp[i][j] = max(dp[i-1][j - d] + a, dp[i-1][j])
    else:
      dp[i][j] = dp[i-1][j]

# iを標準入力で与えられたタスクを期限順にソートしているのでdp[-1]の最大値が答えになる
print(max(dp[-1]))
```

# リンク
[ACサンプル集(アルゴリズム逆引き)](https://www.notion.so/motonao/1cc8aca4381b80f39713ddb52fa85e8f?v=1cc8aca4381b80519654000c236bb8d6&pvs=4)

[問題へのリンク](https://atcoder.jp/contests/typical90/tasks/typical90_k)
さよなら。unloadイベント

## 概要

今更ながら、unloadイベントがGoogle Chromeで
使えなくなる予定だと知りました。
具体的には、2026年4月1日リリース予定のバージョン147で
全てのサイトで完全に使えなくなるようです。
そして早くも、検索結果が上位50サイトでは、
2025年6月18日予定で使えなくなります。

https://developer.chrome.com/docs/web-platform/deprecating-unload?hl=ja

## タイムライン

##### アンロードのサポート終了のタイムライン

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208928/b0650537-fdca-4b08-abc4-0df224218a56.png)

##### 具体的な日付

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208928/75cdb288-672f-4e7a-875f-a7509c37d675.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208928/0b8523ce-dc58-4e97-8995-d3aebc3e995f.png)

## 対策方法
#### unload イベントがある状態
```JavaScript
window.addEventListener('unload', () => {
    // 何らかの処理
});
```

#### pagehide イベントを使って書き換えた状態
```JavaScript
window.addEventListener('pagehide', (event) => {
    /* event.persistedは、ユーザーが別のページに移動した際、
     * 画面を完全に閉じたのか / 背面化され非表示化されただけなのか
     * を判別できます。
     * true:  非表示化
     * false: 閉じられた
     */
    if (!event.persisted) {
        // 画面が完全に閉じられた場合のみ、何らかの処理を行う
    }
});
```

## Internet Explorer 10以前をサポートする場合

Googleのおすすめは、こちらの方法のようです。
補足するとInternet Explorer 8以前には、addEventListenerが無いため、
Internet Explorer 9/10をサポートするための方法です。

> すべての最新ブラウザでは、unload イベントではなく、pagehide イベントを使用して、ページのアンロード（終了状態）の可能性を常に検出することをおすすめします。Internet Explorer バージョン 10 以前をサポートする必要がある場合は、pagehide イベントを検出し、ブラウザが pagehide をサポートしていない場合にのみ unload を使用する必要があります

```JavaScript
const terminationEvent = 'onpagehide' in self ? 'pagehide' : 'unload';

window.addEventListener(terminationEvent, (event) => {
    // 何らかの処理
});
```

https://developer.chrome.com/docs/web-platform/page-lifecycle-api?hl=ja#the_unload_event

## まとめ
何だかんだでunloadイベントは、重宝されているはずなので
Webサイトの開発者は、注意した方が良いです。
【随時更新】生成AIでよく使うワード集


みなさんはChatGPTを使いますか？
私はしょっちゅう使います。

でもChatGPTは割とサボったり、適当に返すことがありますよね。
ということで、個人的によく使うワードをまとめました。

## 深呼吸してから取り組んでください

これは個人的に効果がありますね。他と何が違うのでしょう？
このワードを出すとなぜか絵文字も出てくるようになります。

## 徹底的に教えてください。徹底的です。

これも割と便利なワードです。
文量が限界レベルになるイメージがあります。

## 限界を超えてください。限界突破です。

特に効果を感じていませんが、一応挙げました。

## 多角的に教えてください。

これは多少いい感じに多角的に教えてくれるのでよく使います。

## ステップバイステップで教えてください

これを書いておくと、説明に段階を入れてくれるので少しわかりやすくなる気がしますが、どうなのでしょう...？

## 今の回答は60点です。原因を分析して100点にしてください。

良い回答になりますね！
1回質問しないと利用できないのが玉にキズですね。

## 最適なフレームワークを選定してから説明してください。

これいいですね。

## ハルシネーションを起こさないでください。

ハルシネーション＝嘘をつくということですが、
実際に嘘をあまりつかなくなるイメージがあります。

## ヤジをなくしてください。

余計なことを言わなくなりました。これはいいですね。



## その他

その他の効くような効くかないような..というワードは以下の通りです。
・そうすれば200ドルをあげます。
・今日は10月の月曜。生産性が最高の日です
・私には指がないので全てのスクリプトを教えてください
・あなたはあらゆる分野の専門家です

## 余談

私は上記のワードをまとめて以下のように送っちゃいますね。
---
なお、以下に注意してください。（復唱や甘えは不要です）
・xxxxx
・xxxxx
・xxxxx
・xxxxx
・xxxxx
【GitHub】Languages割合を修正する

# はじめに
Vite + React + TypeScriptプロジェクトを作成、GitHubに連携したところ、languageの割合のCSSが非常に高いため、修正を試みました。

# 問題
GitHubのプロジェクトが`CSS`プロジェクトとみなされている。Languagesの割合も高い。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3993509/20b2da00-e0a7-417e-925a-402e84831884.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3993509/08cac5e8-eb9f-4dc3-a7da-c833f71f5ae8.png)


# 解決方法
`.gitattributes`を使用して、CSSを言語統計から除外する

* プロジェクトのルート配下で.gitattributesファイルを作成する

```shell
$ touch .gitattributes
```

* CSSを言語統計から除外するよう.gitattributesに記載
```.gitattributes
*.css linguist-documentation
```

* commit、pushする

* 変更が反映されたことを確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3993509/04c061cf-dff8-47c5-9c3d-040464e598d1.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3993509/5e4ff1e7-28f8-4849-be5e-92861a7a02a0.png)


# おわりに
[Linguist](https://github.com/github-linguist/linguist/blob/main/docs/how-linguist-works.md)
を使用して統計を出していることを学びました。

# 参考

https://github.com/github-linguist/linguist/blob/main/docs/overrides.md#using-gitattributes
Flow Administration Superbadge Unit



https://trailhead.salesforce.com/content/learn/superbadges/superbadge_flow_administration_sbu


# 新規ケース作成フローの更新

要件に応じて、新しいケースの作成フローを更新します。

何もしないで検証ボタンをクリックする

:::note alert
The flow does not allow users without access to the Case object to create a case.

このフローでは、ケース オブジェクトへのアクセス権を持たないユーザーがケースを作成することはできません。
:::

意味が分からん。システムモード？

:::note alert
We're unable to find an active flow named 'Create a New Case' with the expected layout. Make sure that an active flow by that name exists and the layout is set as per requirements.


期待されるレイアウトの「新しいケースの作成」という名前のアクティブなフローが見つかりません。その名前のアクティブなフローが存在し、レイアウトが要件に従って設定されていることを確認してください。
:::

英語の意味がわからん。何をしろって言っているんだ？　エラーからすると自動に変える？

:::note alert
The layout for 'Create a New Case' flow is not configured correctly. Make sure the flow's layout is set as per requirements.

「新しいケースの作成」フローのレイアウトが正しく構成されていません。フローのレイアウトが要件に従って設定されていることを確認してください。
:::

あああ、この課題もフローの操作が分からんと言うよりは日本語に訳しても意味が分からん英文にあるな。
ITの英語ってもっと分かりやすいと思うけど、さっぱり意味が掴めない。


# フローの実行順序を更新する

非表示チェックボックスの更新フローを調整し、レコードによってトリガーされるフローの順序を更新します。

何もしないで検証ボタンをクリックする

:::note alert
We can't find the 'Update Hidden Checkbox' flow adjusted as per requirements.


要件に従って調整された「非表示チェックボックスの更新」フローが見つかりません。
:::

はぁ？　まだなんかある？

:::note alert
We can't find the adjustment that ensures 'VIPCheckboxAdd100' flow runs before 'VIP Discount' flow.

「VIPCheckboxAdd100」フローが「VIP Discount」フローの前に実行されるようにする調整が見つかりません。
:::

意味が分からん

Currently, the VIP Discount flow runs before VIP points are awarded from the VIPCheckboxAdd100 flow. 

現在、VIP Discount フローは、VIPCheckboxAdd100 フローから VIP ポイントが付与される前に実行されます。

VIP Discount フロー：VIPという項目がtrueなら起動する？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/5a0d81c2-e714-4ad0-a9eb-cf091cad4c0c.png)

VIPCheckboxAdd100 フロー　：　VIPという項目がtrueなら起動する？ 条件が同じじゃん　あほか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/a60b7793-a8d6-4d16-b02b-61b3a647dffc.png)

VIP Discount フロー　550
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/3affbd1e-3afa-461a-817b-b7c91b0027f7.png)


VIPCheckboxAdd100 フロー　1200

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/d19a003c-e834-4f7a-835d-d7192c9c29f7.png)

あああ、入れ替えろってか？




# フローのメール設定を更新する

すべてのApex 例外メール受信者がプロセスまたはフロー エラー メールを受信できるように設定を更新します。

何もしないで検証ボタンをクリックする

:::note alert
System settings should be adjusted so that all Apex Exception Email Recipients receive any process or flow error emails.


すべての Apex 例外メール受信者がプロセスまたはフロー エラー メールを受信できるように、システム設定を調整する必要があります。
:::


こっち？

https://help.salesforce.com/s/articleView?id=platform.flow_troubleshoot_error_email.htm&type=5


これも？
https://help.salesforce.com/s/articleView?id=000385876&type=1
CursorユーザによるVSCodeのエージェント機能ことはじめ

# 概要
VSCode v1.99（2025年3月）よりエージェント機能がStableになったので試してみます。
# 背景
コーディングにおいてAIエージェントが統合されたエディタは非常に便利です。
筆者も[Cursorのエージェント機能を使い始めてからコード生産性が3倍に](https://qiita.com/shimajiroxyz/items/be02bacd81028d33813b)あがったりしました。

AIエージェント統合エディタとしてよく名前を聞くものとしてCursor，windsurf、clineなどがあります。CursorとwindsurfはVSCodeのフォーク版、clineはVSCodeの拡張機能であり、ビジネス利用を考慮した場合には、VSCode単体に比べてセキュリティ面などで一定のハードルがあります。

そんな中、2025年3月リリースのVSCode v1.99にてエージェント機能がリリースされました。
VSCodeの公式機能ですので、相対的には企業での利用のハードルが低い可能性が高いです。
加えて、MCPのサポートもされており、Cursorなどと比べても大きく遜色ない使いごこちも期待されます。
そこで、今回手元で使い方を試してみたいと思います。

参考: https://code.visualstudio.com/docs/copilot/chat/chat-agent-mode 

# 導入
- GitHub Copilotに加入する。無料プランでもOK。
- VSCodeのバージョンを確認し、1.99未満であれば、更新する。
- 設定エディタからchat.agent.enabledを設定する。よくわからない場合は、リリースページの同文字列のリンクをクリックするとvscodeを開いて設定してくれます。
- 「ヘッダーのCopilotアイコン > Open Chat」でコパイロットの画面を開く。GitHubにサインインしていない場合はここでサインインする。
- Copilotのチャット画面の右下の「質問する（Ask）」をクリックし「エージェント（Agent）」を選択
- 標準以外のモデルを使用したい場合は「model」から追加しAPIキーなどを登録する

なお、企業などorganizationに属するアカウントの場合は、organization設定でプレビュー機能がオフになっていると「エージェント」が選択できないかもしれません。Stableとしてのリリースなので、遠からず使えるようになる可能性もありますが、急ぎの場合は、GitHubのorganizationの設定を確認してください。
使用できるモデルも同様にorganizationによって制限されている可能性があります。

# エージェント機能
試しに適当なフォルダを作って、reactのプロジェクトの初期化をお願いするとやってくれました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259353/a6215178-a7e3-43b8-95b0-1f6f5949fe0a.png)

ターミナルでのコマンド実行、ファイルの読み書きなどよしなにやってくれました。
モデルはClaude 3.7 Sonnetで試しました。
普段はCursorのdefaultモデルを使っているのですが、それと比べると、少し文脈の理解が弱く、2つ前に行ったことを無視して実装されることが何度かありました。モデルのせいなのかエディタ独自のインストラクションのせいなのかは不明です。

# カスタムインストラクション
以降は、エージェント機能と関係なく、Copilotのころからある設定と思いますが、Cursorから乗り換えた手前、基本的な使い方として確認しておきます。

[こちら](https://docs.github.com/ja/copilot/customizing-copilot/adding-repository-custom-instructions-for-github-copilot?tool=vscode)を参考に、リポジトリ固有のカスタムインストラクションを`.github/copilot-instructions.md`に書きます。

試しなので、instructionsはエージェントに書いてもらいました。
最初、上記のリンクを参考に書いてと頼むといい感じに書いてくれなかったので、上記のサイトを読んで、書くときに注意することをまず列挙してから書かせると、いい感じになりました。


`.github`の直下に１つしかおけないのはCursorと比べると不親切に思いました。
Cursorでは`.cursor/rules/`の下に複数のmdcファイルを置くことができます。
workflowsなど`.github`下の他の設定ファイルとゴチャゴチャにならないように、`.github/rules`みたいな場所におけるようになるといいなと思いました。



# コミットメッセージ

エディタのソース管理タブからコミットメッセージを自動生成できます。
デフォルトだと英語で生成されるので、[こちら](https://zenn.dev/prog_hallelujah/articles/b57ddf2c6763ce)を参考にコミットメッセージ用のカスタムインストラクションを設定しました。

settings.jsonに書けるタスクごとのインストラクションは

- Review Selection，
- Code Generation
- Commit Message Generation
- Pull Request Description Generation
- Test Generation

があるようです。

# Memory Bank
clineのメモリバンク的なことをやってみたかったので、[こちら](https://qiita.com/getty104/items/68bfdd8e24ab5afbc676)を参考に実装しました。
上記に記載のmdを、すでに作成したinstructionsに追記し、`init memory`とchatで指示しました。

# 数時間使った感想（主に不満）
## コードハイライトのCopilotチャットへのコピーができない
Cursorだとcmd+Lでコードのハイライト部分をチャットにコピーできます。
これに相当する方法をCopilotで探しましたが見つかりませんでした。
## コードハイライトへの質問ができない
Cursorだとcmd+Kでコードハイライト部分の編集ができるのですが、送信時にoption+Enterとすると、編集ではなく単なる質問があります。
GitHub Copilotではcmd+Iでコードハイライト部分の編集ができますが、Cursorのoption+Engerに相当する、単に質問するだけのやり方はわかりませんでした。
## 遅い
Cursorと比べると出力がかなり遅いです。
生産性に直結します。

# おわりに
とりあえず以上です。
細かい差異はありますが、cursorやclineと遜色ないことができそうな気配があります。
引き続き使い勝手を試していきたいです。
個人的備忘録：HTTP 3xx系ステータスの違いを整理して、迷わなくなるために記事にしてみた

## はじめに
Web開発をしていると、あるURLから別のURLに自動的に移動する「リダイレクト（Redirect）」に出会うことがよくあります。

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

この動きは HTTP の 3xx 系ステータスコードによって制御されており、SEO やユーザー体験にも関わる重要な仕組みです。

## 書こうと思ったきっかけ
個人開発中のウェブサイトでURL構造を変更した際、古いURLにアクセスしたユーザーを新しいページに転送する必要がありました。

***その際、ステータスコードの使い分けに迷ったため、整理する目的でこの備忘録を作成しました。***

## 3xx系ステータスコード一覧
以下は代表的な 3xx 系の HTTP ステータスコードです：

**参考文献**

https://envader.plus/article/31

### 301 Moved Permanently（恒久的な移動）
- 古いURLは今後使われず、新しいURLに恒久的に移動したことを示します。
- ブラウザや検索エンジンは、新しいURLをキャッシュします。
- SEOの観点でもリダイレクト先に評価が引き継がれます。

### 302 Found（一時的な移動）
- リクエストされたリソースが一時的に別の場所にあることを示します。
- 将来的には元のURLが再び使われる前提です。
- 検索エンジンは元のURLをインデックスし続けます。

### 303 See Other（POST → GETのリダイレクト）
- フォーム送信後に他のページへリダイレクトする際によく使用されます。
- POSTメソッドをGETに変換してリダイレクトされます。

### 307 Temporary Redirect（302の厳密版）
- 302と似ていますが、元のリクエストメソッド（GET/POSTなど）を保持します。
- セキュリティが重要なAPIなどでよく利用されます。

### 308 Permanent Redirect（301の厳密版）
- 301と同様に恒久的な移動ですが、元のメソッドを保持したままリダイレクトされます。
- HTTP/1.1 以降の新しい仕様です。

## 実際の使用例（Apacheの.htaccess）
```apacheconf
# 恒久的なリダイレクト（301）
Redirect 301 /old-page.html https://example.com/new-page.html

# 一時的なリダイレクト（302）
Redirect 302 /temporary.html https://example.com/maintenance.html
```

## まとめ
3xx ステータスコードは、ユーザー体験の向上やSEOの最適化に大きく関わる重要な要素です。

:::note warn
**特に301と302の使い分けを意識することで、意図しない評価の分散やキャッシュのトラブルを防ぐことができます。**
:::

今後もURL設計やページ移動時に役立てていきたいです！
【体験談】Must系関数との出会いがGoの考え方を変えた話

## はじめに
Goでテストコードを書いていたときの話だ。  
「なんでわざわざ `MustNewNode` なんて関数を作る必要があるんだ？」  
最初は心の底からそう思っていた。

今回は、自分がその疑問にぶつかってから「なるほど！」と腑に落ちるまでの体験を書いていく。  
これを読んだ人にもあの感動を味わってほしい。

## 1. 最初の疑問「NewNodeで良くない？」

テストコードの中でノードを作ろうとしたとき、こんなコードを見つけた。

```go
mockNode: MustNewNode("node-123", "Q", "A", nil, nil)
```

「いやいや、`MustNewNode`って何？普通に`NewNode`使えば良くない？」

素直にそう思った。そこでこう書いてみた。

```go
mockNode: domain.NewNode("node-123", "Q", "A", nil, nil)
```


## 2. コンパイルエラーで気づく

するとビルドが通らない。  
エラーメッセージはこれ。

```
multiple-value domain.NewNode(...) in single-value context
```

「えっ、何これ？」

少し考えてハッとした。  
`NewNode`は戻り値が `(Node, error)` になっている。  
Goは明示的にエラーを返す文化。  
つまりこう書かないといけない。

```go
node, err := domain.NewNode(...)
if err != nil {
    t.Fatal(err)
}
mockNode: node
```

## 3. いや、これテストに毎回書くのめんどくさすぎる問題

確かにこれが正しい書き方だ。  
でもテストコードでこんな処理を何回も書くのは明らかに冗長だ。  
せっかくテストコードで動作確認したいだけなのに、コード量が無駄に膨れる。  
しかも「このパターンでエラーになるわけがない」って前提も多い。


## 4. なるほどMustNewNodeってそういうことか！

ここでやっと`MustNewNode`の意図に気づいた。  
「もしこの場面でエラーが出るなら、そもそもテストコードの書き方が間違っている」  
だったら `panic` で即座に気づけた方が良い。  
だからこういう実装になっている。

```go
func MustNewNode(...) domain.Node {
    node, err := NewNode(...)
    if err != nil {
        panic(err)
    }
    return node
}
```


## 5. Goらしい合理的な割り切りに感動した

この考え方、めちゃくちゃGoっぽい。  
「本番コードでは安全に」  
「テストコードではスピード優先で」  
その切り分けが潔くて合理的。  
しかも、標準パッケージでもこの思想が貫かれている。  

```go
regexp.MustCompile()
template.Must()
time.MustParse()
```


## まとめ

今回の出来事で、Goの哲学が少し身体に染み込んだ気がした。  
最初は「わざわざMustなんていらない」と思った。  
でも実際に手を動かして、エラーを起こして、初めて腑に落ちた。

こういう「試行錯誤して初めて見える景色」があるのがプログラミングの面白さだと思う。  
この記事が、同じ疑問を持った誰かの助けになれば嬉しい。
家計簿アプリを作る＃２８

![スクリーンショット 2025-04-05 131507.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4012588/ca2aee22-907d-4d7b-a89b-6c0903fd16fa.png)
interfaceを作成します。

![スクリーンショット 2025-04-05 131604.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4012588/4c64b3dc-d050-47ad-a4da-71c495941720.png)
これで、コードがすっきりしました。

![スクリーンショット 2025-04-05 131707.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4012588/76dec33f-669b-498b-9600-89c7e30ffd77.png)
drawerは、サイドバーでのみ使用するので、切り取って、

![スクリーンショット 2025-04-05 131813.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4012588/8d1da475-2d5f-497c-94d5-ebd8de693a0a.png)
return文の上で貼り付けます。
個人的備忘録：クライアントエラー系（4xx）が出たときに、すぐ確認できるようまとめてみた

## はじめに
WebアプリケーションやAPIを開発・運用していると、ユーザーの操作ミスや不正なリクエストによって引き起こされる「4xx」系のステータスコードに頻繁に遭遇します。

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

この記事では、クライアントエラーに特化してその意味や代表的なエラーコードをまとめておきます。

## 書こうと思ったきっかけ
AWSを学び始めの時に、予期しない400 Bad Requestや403 Forbiddenが表示されれることがありました。

そのときに調査した内容を今後も活かせるよう、備忘録として残すことにしました。

## クライアントエラー（4xx）とは？
HTTPステータスコードの「4xx」番台は、クライアント（ユーザーまたはアプリ）からのリクエストに誤りがある場合に返されるエラーです。

**参考文献**

https://www.agent-grow.com/self20percent/2018/07/16/http-status-code-4xx/

例えば、リクエストパラメータの不足、認証情報の不備、アクセス権限の不足などが該当します。

## 代表的な4xxステータスコード一覧

### 400 Bad Request
- サーバーがリクエストの構文を理解できない場合に発生
- 原因例：不正なJSON形式、必須パラメータの欠如

### 401 Unauthorized
- 認証が必要だが、適切な認証情報が提供されていない
- 原因例：アクセストークンの未設定、認証ヘッダーの不足

### 403 Forbidden
- リクエストは理解されたが、権限がなくアクセスが拒否された
- 原因例：管理者のみアクセス可能なページに一般ユーザーがアクセス

### 404 Not Found
- リクエストされたリソースが存在しない
- 原因例：URLのタイプミス、削除されたページ

### 405 Method Not Allowed
- 指定されたHTTPメソッドがサポートされていない
- 原因例：GETしか許可していないエンドポイントにPOSTを送信

### 429 Too Many Requests
- 一定時間内にリクエスト数が制限を超過した
- 原因例：APIへの過剰なアクセス、ボットの連続アクセス

## よくある原因と対策
| ステータスコード | 原因例 | 対処方法 |
|------------------|---------------------------|-------------------------|
| 400 | 不正なリクエスト形式 | 入力値の検証、フォーマット確認 |
| 401 | 認証情報の不足 | トークンの送信、認証処理の実装 |
| 403 | 権限なしアクセス | ロール・アクセス権限の確認 |
| 404 | リソースが存在しない | URLの確認、存在チェックの実装 |
| 429 | リクエスト過多 | レート制限の実装、待機処理 |

## まとめ
4xxエラーはクライアント側の問題であるため、ユーザーや開発者が原因を理解し、適切な対応を行うことが求められます。

:::note warn
***API設計時には、各エラーに対してわかりやすいレスポンスメッセージやエラーコードを返すことで、ユーザー体験の向上にもつながります。***
:::

今後の開発や運用時にも活用できるよう、本記事の内容を都度更新していく予定です！
反比例の積分においてネイピア数が現れる訳

# はじめに
反比例を積分すると自然対数の底であるネイピア数$e$が何故か出現する。これは、高校数学の数学2と数学3で扱う積分の単元においてもっとも違いが現れる点である。しかし、何故ネイピア数$e$が現れるのかといった説明はあまりないようにみえる。そこで、今回は、$x$を被積分変数とおいたとき、$x^{-k}$という関数を積分し、$k$を1に近づけていった場合に、積分値がどのような値に収束するのかを調査することでなぜ、ネイピア数$e$が登場するのかを考察する。

![S_approximation.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686019/40c5fd98-fd85-4419-a033-361697500a6e.png)



# 前提条件

$1\le x\le 2$であるとき、以下の積分を考える。

 
```math
S(k)=\int_{1}^2 x^{-k}=[\frac{1}{-k+1}x^{-k+1}]^2_1=-\frac{1}{k-1}(2^{-(k-1)}-1)
```

ただし、$k\ne 1$である。これは、高校数学2で扱う積分の公式を用いただけなので、何も特別なことではない。

一方で、数学3で扱う、問題の公式を用いて、


```math
S(k=-1)=\int_{1}^2 x^{-1}=[log x]^2_1=log 2


```

となることが知られている。そこで、今回は、

```math
\lim_{k\to 1} S(k)=\lim_{k\to 1} -\frac{1}{k-1}(2^{-(k-1)}-1)=log 2

```

となるかどうかを考察する。

# 考察
自然対数の底つまり、ネイピア数$e$は、以下のように定義される。

```math
\lim_{n\to \infty}(1+\frac{1}{n})^n=e
```

すなわち、

```math
\lim_{h\to 0}(1+h)^{\frac{1}{h}}=e
```

この式の両辺の対数を取ると以下のようになる。


```math
\lim_{h\to 0}\frac{log(1+h)}{h}=1
```

この式の対数の底を$e$から$2$へと変換する。

```math
\lim_{h\to 0}\frac{1}{h}\frac{log_2(1+h)}{log_2 e}=1
```

つまり、


```math
\lim_{h\to 0}\frac{log_2(1+h)}{h}=log_2 e
```


ここで、$h=2^\alpha-1$とおくと、

```math
\lim_{\alpha\to 0}\frac{\alpha}{2^{\alpha}-1}=log_2 e
```

したがって、分子と分母を反転して、


```math
\lim_{\alpha\to 0}\frac{2^{\alpha}-1}{\alpha}=log2 
```

ここで、話を元に戻して、$\alpha=-(k-1)$とすると、


```math
\lim_{k\to 1} S(k)=\lim_{k\to 1} -\frac{1}{k-1}(2^{-(k-1)}-1)=\lim_{\alpha\to 0}\frac{2^{\alpha}-1}{\alpha}=log 2

```
となることから、題意を示すことができた。

# プログラム

さて、上記の関数の極限をプログラムを使って図示してみる。

```python sekibun.py
import numpy as np
import matplotlib.pyplot as plt
import japanize_matplotlib
import math
n=100
delta=1.0e-10
n_ary=np.linspace(delta,1,n)
S_ary=[]
for i in range(n):
    alpha=n_ary[i]
    S=(1/(-(alpha)))*(2**(-(alpha))-1)
    S_ary.append(S)
plt.plot(n_ary, S_ary, label='S', color='blue')
plt.axhline(y=np.log(2), color='red', linestyle='--', label='ln2')
plt.title(' 反比例の積分（区間1から2）の近似')
plt.xlabel('n')
plt.ylabel('S')
plt.legend()
plt.savefig('S_approximation.png')
plt.show()
```


![S_approximation.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686019/40c5fd98-fd85-4419-a033-361697500a6e.png)


このように、$\alpha$を0に近づけていくと、$log2$に収束していくことが分かる。

# まとめ
今回は、反比例の積分において、何故ネイピア数という謎の数が姿を現すのかを調査した。結果、極限を飛ばすという作業においては、どうしてもネイピア数の存在を無視することはできなかった。また、後半では、そのことをPythonを用いて視覚的に図示することを試みた。