OmniAICreator/Qiita-1.07M huggingface dataset:
Module not found: Can't resolve 'fs' の解消法 🎑

## はじめに
React学習中に出会った以下エラーについて、原因と解消方法の共有です。
```
Module not found: Can't resolve 'fs'
```
![スクリーンショット 2025-03-29 23.48.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3427082/2f5c2202-64aa-4af2-bcc0-c896fd053ef1.png)

## 目次
1. [原因と解消方法](#-原因と解消方法)
2. [参考文献](#-参考文献)

## 🧷 原因と解消方法

### 原因

上記エラーは、通常、**Node.jsのファイルシステムモジュールである `fs` を、ブラウザ環境などNode.jsのAPIが利用できない環境で使用しようとした場合**に発生するそうだ。

Next.jsはサーバーサイドとクライアントサイドの両方で動作するため、コードの実行環境によって利用できるAPIが異なる。
<br>

そのため対策としては、

　👉 **クライアントサイドの JS コンテキストで`fs`モジュールが参照されないようにする必要がある**とのこと。

### 解消方法
`next.config.mjs` へ以下(**ここから〜ここまで**の部分)を追加
```js
import { withSentryConfig } from '@sentry/nextjs';
/** @type {import('next').NextConfig} */
const nextConfig = {
  /** ここから */
  reactStrictMode: true,
  swcMinify: true,
  webpack: (config, { webpack }) => {
    config.experiments = { ...config.experiments, topLevelAwait: true };
    config.externals['node:fs'] = 'commonjs node:fs';
    config.resolve.fallback = {
      ...config.resolve.fallback,
      fs: false,
      'stream/web': false,
      async_hooks: false,
      net: false,
      tls: false,
      'util/types': false,
      worker_threads: false,
      perf_hooks: false,
      console: false,
      diagnostics_channel: false,
    };
    config.plugins.push(
      new webpack.NormalModuleReplacementPlugin(
        /^node:(crypto|events|stream|util)/,
        (resource) => {
          resource.request = resource.request.replace(/^node:/, '');
        }
      )
    );

    return config;
  },
  /** ここまで */
};
```
### config.externals["node:fs"] = "commonjs node:fs";
この設定は、`node:fs` モジュールをWebpackのバンドルの外部にあるものとして扱う。
これにより、クライアントサイドのJavaScriptバンドルに `fs` モジュールが含まれなくなり、本エラーの発生を防ぐことができる。
### config.resolve.fallback = { ...config.resolve.fallback, fs: false, };
`resolve.fallback` は、Webpackがモジュールを解決できなかった場合に試みる代替パスを指定する設定。
ここで `fs: false` と設定することで、Webpackが `fs` モジュールを見つけられなかった場合に、フォールバックを試みることなく、そのモジュールが存在しないものとして扱う。
これは、クライアントサイドのコードで誤って `fs` を参照しようとした場合に、ビルドエラーを抑制する効果があると考えられる。
### config.plugins.push(new webpack.NormalModuleReplacementPlugin(/^node:/, (resource) => { resource.request = resource.request.replace(/^node:/, ''); }, ));
この設定は、node: プレフィックスで始まるモジュールIDを、プレフィックスなしの同じIDに置き換えるWebpackプラグインを追加している。
Node.jsの新しいAPIは node: スキームでインポートすることが推奨されていますが、一部の環境やライブラリではまだこの形式に対応していない場合がある。
この設定により、例えば `require('node:fs')` という記述が `require('fs')` として扱われるようになり、互換性の問題を解消する可能性がある。

#### 💡上記の設定を組み合わせることで、Next.jsアプリケーションにおいて、クライアントサイドのバンドルに `fs` モジュールが誤って含まれるのを防ぎ、本エラーの発生を抑制していると考えられます。

## 💫 参考文献
* [[Urgent] Module build failed: UnhandledSchemeError: Reading from "node:fs/promises" is not handled by plugins (Unhandled scheme).](https://github.com/langchain-ai/langchain/issues/4491#issuecomment-1935274842)
自宅のmacで42Tokyoの課題に取り組みたい

macで[42Tokyo](https://42tokyo.jp/)のUbuntu環境を再現する過程でありがたいな〜と感じた記事やコマンドを紹介していきます

### 記事執筆時の環境
M4 Mac mini
maOS Sequoia 15.3.2

### UTMでUbuntuをインストール
[UTMを用いたUbuntuの仮想環境](https://qiita.com/ASONE0923/items/0a897bd5446e26524a24)

### VSCodeのインストール
[LinuxにVSCodeをインストールする](https://higmasan.com/linux/install-vscode/)

:::note warn
この記事ではamdを使用しているが、[UTMを用いたUbuntuの仮想環境](https://qiita.com/ASONE0923/items/0a897bd5446e26524a24)
でarmアーキテクチャに対応したUbuntuのisoファイルをインストールしているため、ここではarm64 の.debをインストールしないといけないことに注意。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4048484/e2e28341-93e7-48d7-9880-26a92cec9a5b.png)
:::

<details><summary>GitHub連携の際、ブラウザが開かない</summary>
VSCodeからブラウザに飛べない時は、"Ctrl+Shift+P"→"settings"を開き、"browser"で検索
External Browserに任意のブラウザを記載する

![スクリーンショット 2025-03-29 23.53.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4048484/d2fbd935-9a34-4d98-b9ed-1161543c2182.png)
</details>

<details><summary>GitHubにSSHキーを設定したい</summary>

[GitHubに新しくSSHキーを追加](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/adding-a-new-ssh-key-to-your-github-account)  
</details>

### makeやccのインストール
```
sudo apt install build-essential
```
[build-essentialとはなんぞや](https://kazuhira-r.hatenablog.com/entry/2020/11/30/204027)

### norminetteのインストール
[Official 42 norminette](https://github.com/42School/norminette/)

README.mdに記載されている`Install using pipx.`でいけました
```
sudo apt update
sudo apt install python3-setuptools
sudo apt install pipx
pipx install norminette
pipx ensurepath
```

### valgrindのインストール
```
sudo apt-get install valgrind
```

### 操作感をmacに似せたい
[42Tokyo Ubuntuのショートカット操作をMacっぽくする](https://qiita.com/kztakada116/items/c842f188316f8df41875)

:::note warn
Ubuntu仮想環境にTweaksはデフォルト装備されていないため、インストールする必要あり
 ```
sudo apt install gnome-tweaks
 ```
:::

### コードの動作検証は校舎で行うのが一番
以上の設定で、自分のコードをUbuntu環境で検証するために必要なものは揃えられるかと思いますが、バージョンが違うこともある（というか十中八九違うことでしょう）と思うので、必ず校舎PCでnormやコンパイルやメモリリークのエラーが出ないかを確認してから提出しましょうね。

理想を言うならば、ちゃんと校舎に足を運んで、他の学生と交流を深めながら課題に取り組みたいところですが、自分のような社会人にはなかなか厳しい面があります。移動に時間、かけてらんない、、！

レビューとか本当に勉強になることが多いので、できる限り対面で行きたいとは思っているのですが。せっかく入った42。BHにならないように、課題だけでも進めていきたいところですね。。
チーム作業で気をつけたいこと   ― リーダー／メンバー ポジション両方を通して得た経験 ―

## はじめに

本記事は、筆者の実体験をもとにした自身の思考整理を主な目的とし、
報・連・相にも関わる「認識共有」の観点から、
チーム作業における認識齟齬の発生要因とその防止策についてまとめたものです。

---

## 結論：認識共有は、定期的かつ適切なタイミングで行うことが重要

チームで作業を進める上で、最も避けたい事象の一つが **認識齟齬（すれ違い）** です。  
どれだけ優秀なメンバーが揃っていても、認識が揃っていなければ、期待される成果を得ることはできません。

認識齟齬を未然に防ぐには、**認識合わせ（認識共有）を定期的に行うことが不可欠** です。  
ただし、頻度が高すぎても効率を損なうため、**適切なタイミングでバランスよく実施することが重要** です。

---

## なぜ認識合わせが重要なのか

プロジェクトや日々の業務において、メンバー間での認識のズレは珍しいことではありません。  
その背景には、以下のような要因があります：

- メンバーの経験・職種・考え方の違い  
- 用語や表現に対する解釈のズレ  
- タスクの目的やスコープに対する認識の差異  

例えば、ある機能改修に「案A-a」「案A-b」の2案があり、リーダーはA-aで進めたいと考えていたにも関わらず、作業者がA-bを選択して実装を進めてしまった場合、  
**工数の無駄・品質の低下・信頼関係の損失** といった問題が発生する恐れがあります。

このような事態を避けるためにも、**作業開始前の認識合わせは必須** です。

---

## 認識合わせを行うべき主なタイミング

### 1. 作業開始時（最優先）

新しいタスクやプロジェクトに取り組む際には、必ず関係者間で認識を揃える必要があります。  
以下のような項目を明確にしましょう：

- 目的と背景  
- ゴールとアウトプットの定義  
- 担当範囲と責任分担  
- スケジュールとマイルストーン  

初期のズレがそのままプロジェクト全体に影響を及ぼすリスクは非常に高いため、**最初の認識合わせが最も重要** です。

### 2. スケジュールや仕様の変更時

計画の変更や仕様の追加・削除などがあった場合は、その都度認識を更新する必要があります。  
共有されないまま進行してしまうと、作業の方向性がズレてしまう恐れがあります。

### 3. 作業中に疑問や例外が発生した際

実際の作業中には、仕様上の曖昧な点や想定外の問題に直面することがよくあります。  
このような場面では、**自己判断で進めずに一度立ち止まって認識を再確認する** ことが重要です。

---

## 頻度と効率のバランスを考慮する

認識合わせの重要性は明らかですが、**頻度が高すぎると業務の効率を下げる原因にもなります**。  
そのため、中庸を取ることが必要です。  
「コミュニケーションコスト」の観点から以下のようなバランスが求められます：

- 最低限必要なタイミングでは確実に実施  
- 不明点や違和感があれば、早期に確認  
- 文書化やツールの活用により、口頭コミュニケーションを効率化  

「会話ベース」だけでなく、「見返せる情報」があると、無駄なやり取りを削減できます。

---

## 認識齟齬を防ぐための具体的な手段

### 1. ドキュメントによる共通理解の可視化

- タスクの背景・目的・方針・決定事項をドキュメント化  
- 全員がアクセス可能な状態にし、都度更新する  

### 2. 認識の可視化

- タスク管理ツール、チャットなど文字として共有し、見返せるようにする  
- 一説によるとヒトの記憶は1日で70%以上忘却すると言われています  
- ※ヒトの記憶するプロセス、シナプス構造などの脳科学関連に関しては専門家ではないので触れません。ある程度把握しておく事は推奨します。  

### 3. 心理的安全性の醸成

- 「確認してもよい」「質問してもよい」という空気感を持つことが、認識齟齬の早期発見につながる  
- 特に心理的安全性含めたメンタルヘルスは日本において軽視されがちですが非常に重要です  
- メンバーのメンタルヘルスは当事者の作業効率に影響するだけでなく、そこからプロジェクト全体へと派生します  

---

## おわりに

現場やチームによって最適な方法は異なるとは思いますが、  
**認識齟齬を軽視しない姿勢こそが、チーム全体の品質や生産性を大きく左右する** と考えています。

もし他にも有効な取り組みや考え方があれば、ぜひコメントやフィードバックをいただけると嬉しいです。
JetBrains IDEのダークテーマ「Darcula」はドラキュラ「Dracula」と「Dark」の言葉遊びらしい

JetBrains IDEのテーマ、「Darcula」の話。

次の画像は、各種JetBrains IDEのSettings > Appearance & Behavior > Appearance > Themeで、テーマを選択するポップアップです。

![スクリーンショット 2025-03-30 1.48.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4125/6006b015-47b4-4995-9a1a-04c7a1f0542a.png)

この中に「Darcula」というテーマがありますね。この「Darcula」という名前、公式フォーラムにおけるJetBrainsの中の人によると「Dracula」（ドラキュラ）と「Dark」を組み合わせた言葉遊びだそうです。

https://intellij-support.jetbrains.com/hc/en-us/community/posts/10439311838098-Why-was-the-Darcula-theme-named-Darcula


へ〜👍

個人的には、結構好きな言葉遊びです。

---

[公式ドキュメント](https://www.jetbrains.com/help/idea/user-interface-themes.html)によると、「Darcula」は「alternative dark theme」だそうです。

実はかつてデフォルトのダークテーマだった、「Darcula」。Darkとの違いは次の様な感じです。

|Dark|Darcula|
|:---:|:---:|
|![スクリーンショット 2025-03-30 2.05.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4125/fe04efe3-f6e5-4d36-83d1-6d8c4f96f598.png)|![スクリーンショット 2025-03-30 2.05.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4125/cd5f1b16-e073-4f59-86a3-82cb15cba308.png)|




https://blog.jetbrains.com/webstorm/2022/12/best-webstorm-themes/#one_dark_theme

より。


> The Dark theme replaces Darcula, which used to be the default theme pre-installed in WebStorm. 

https://blog.jetbrains.com/platform/2021/10/themes-in-intellij-based-ides/

より。

> IntelliJ Light and Darcula are well-known UI themes provided by default within IntelliJ-based IDEs. 

きっと今も、根強い「Darcula」ファンがたくさんいそうです。

---

みなさんはどんなテーマが好きですか？
普通郵便が届かない国・ベトナムで、サイト信頼性を想う

## 文通

2023年、東京でエンジニアとして就職してから、めっきり文字を書く機会がなくなってしまった。
漢字を忘れないようにしようと思って、[JPPFC](https://www.pfc.post.japanpost.jp/) に登録して文通をはじめた。

日本の各地にペンパルができて、仕事の話や旅行先の話や最近行った展覧会の話をしている。
ラウンドトリップタイムは短いもので2週間。仕事が早く終わった日や週末にまとめて手紙を書くのが、ささやかな楽しみだった。

## 出向

2025年1月、ベトナム・ホーチミンシティに出向することとなった。
ペンパルとは年賀状だけ交換して、その後はベトナムから書く手紙を待っていてもらうように伝えていた。
この時点ではまだベトナムでの住所が決まっていなかったからである。

1月下旬、無事ホーチミン市内のアパートメントに入居。
1月末の1週間は旧正月で仕事が休みになるので、その間にまとめて手紙を書き、正月休み明けに一気に送信した。

数人いるペンパルのうちひとりだけ Twitter を交換している方がいる。その方には手紙が届いたら一報入れていただくようにお願いした。

一般にベトナムから日本への航空便は2週間あれば届く。
しかし、このときは正月休み明けで郵便局が混乱していたようで、普通より時間がかかったらしい。

送信からおよそ4週間後、手紙が届いたとの連絡があった。

これで一安心。

お相手に国際郵便の送り方をお伝えして、返信の宛名書きも問題ないことを確認した。

あとは待つだけ……と思っていた。

## 届かない郵便

ところが待てど暮せど手紙が届かない。

投函したと知らせてもらった日から、1ヶ月。

実はこの方より早く、祖母からもはがきが送られてきているはずだった。
これも2ヶ月待っても届かない。

これはともども紛失されたか？と思って、ようやく色々調べてみたのだった。

## ベトナムの郵便事情

ベトナムの家には郵便ポストがないものも多い。
郵便局員は、配達のとき郵便物に書いてある電話番号に電話をかけて、住人に鍵を開けてもらうらしい。
対面での配達が原則だ。

つまり一人暮らしの私は、仕事のある日中に郵便が自宅に届くと、受け取れないということになる。
再配達ももちろんない。

大家さんに相談すると、大家さんの電話番号を書けばかわりに開けてくれるとのこと。

しかしそんなことは露知らず、住所だけを書いた手紙を方方に送ってしまったのである。
電話番号がないと、そもそも配達すらしてくれないらしい。

せめてアパートメントの塀の中に投げ込んでくれれば……と思うのだがそれはこちらの勝手。
途上国の国営郵便のサービスレベルをなめてかかっていた。

確実に届けたければ、10倍以上の費用をかけて EMS を使うか、民営の国際配送サービスを使うかしかないようである。

## ベトナム人と文通

ベトナムに来てから、社外のコミュニティにもいくつか参加させてもらっている。

もちろん趣味の話もするので、文通のことを言うのだが、そのたび traditional とか、romantic とか、色々な感想をもらう。
どうもイマドキのベトナム人は、まったく文通をやらないらしい。

その理由のひとつに、郵便サービスへの信頼性の低さ、があるのではないかという気がしてきた。

社会主義国だけあって検閲が入り、その分配達が遅れる。
そもそも届かないようでは話にならない。

サービスの信頼性の低さによって、そのサービス自体が選択肢から抜け落ちてしまうのだなあ、と話していて思った。

## SRE

ベトナム IT 業界には、SRE のプラクティスはまだ浸透していない。
エンジニアとしての SRE 求人もほとんどない。

情報通信業に携わる人間として、もっともプリミティヴな情報通信であるところの郵便があたりまえに送れる社会を知らないエンジニアたちの間に、サイト信頼性を制御するマインドをどう醸成するか、苦悩の日々を過ごしている。

製品に期待する品質レベルの違いを感じる日々である。日本品質の何たるかを、丁寧に言葉にしていかなくてはいけないのだろう
まっさらなPCとまっさらなあなたをFluttererにしちゃいたい

PCを買ってからFlutterアプリを作るまで、参考になったサイトを紹介していきます。
足掛かり的ロードマップみたいなものだと思ってもらえれば嬉しいです。

紹介しているツールは全てmacOS、Windowsに対応したものがあるはず。。

## 1. PC環境を整える
### VSCodeとGitをインストールし、連携させる
[開発環境を整える(VSCode + Git)](https://zenn.dev/ameyo/articles/1b58281341771f)

<details open><summary>AIエディタのススメ</summary>
AIにコーディングを書いてもらう感動をぜひ味わってみてほしい

**Copilot(VSCode)**
[GitHub Copilotの使い方まとめ｜VSCodeの基本機能や活用のコツを紹介](https://notepm.jp/blog/30499)

**Cursor**
[サクッと始めるAIコードエディタ【Cursor / VS Code / ChatGPT】](https://zenn.dev/umi_mori/books/ai-code-editor-cursor)

**Cline**
[AIによる開発を体験してみよう（Clineを使った開発）](https://zenn.dev/chameleonmeme/articles/1c09e8f856c36b)

それぞれ無料プランがあるから、色々試してみるといいかも。
</details>

### おすすめツール
#### Clibor
個人的最推しツールClibor。
クリップボードの履歴管理をしてくれる。
何回もページを行き来したり、コピー元を忘れて慌てたりすることがなくなってマジ便利。
[Clibor for Windows](https://chigusa-web.com/clibor/)
[Clibor for Mac](https://chigusa-web.com/clibor-for-mac/)

#### Warp
AIターミナル[Warp]((https://www.warp.dev/))。ターミナルで出現するエラーって原因にたどり着くまでめちゃ時間かかるもんね。環境変数とかどこ見たらいいか分からないこと多いし。AIに原因究明から解決まで任せてしまいましょう。

特に環境構築の時には重宝します。
[Warpとはなんぞや](https://qiita.com/shun_sakamoto/items/a0c79083c97064a361f2)

### 【macの人向け】おすすめ設定サイト
[新たなMacをGetした際のおすすめ設定](https://dev.classmethod.jp/articles/mac-recommended-initial-settings/)
↑非常に網羅的でありがたい


## 2. Flutterの環境を作る
### Flutterをインストールする
[Flutter公式インストール](https://docs.flutter.dev/get-started/install)
これ見て分からない時は日本語の記事を見ようね

Windowsの人におすすめ
[Flutter を VSCode で環境構築してみた！＜Windows編＞](https://qiita.com/shimizu-m1127/items/d8dfc2179bc01baaef6b)

macOSの人におすすめ
[【Dart】 Flutter × VSCode で、環境構築 から HelloWorld まで（Mac）](https://tech-lab.sios.jp/archives/42192)

<details><summary>Flutterの拡張機能（最初はいらないかも）</summary>

必要に応じて取捨選択って感じ。Flutterの書き方が分からないうちは、拡張機能ってうるさいだけに感じることが多いから、最初はいらないかも
[【VSCode】2025年度版 Flutterエンジニアにおすすめの拡張機能17選](https://zenn.dev/harx/articles/d0bdb7e04c81db)
</details>

## 3. Flutterに慣れる
Flutterが何かを知る前に、いきなりコードを書き始めるのも大変でしょう。

### Flutterを知る
[Flutterとは？始める前に押さえておきたい必須知識を解説](https://www.sejuku.net/blog/124242)

### Flutterハンズオンに取り組む
一回手を動かしてみましょう
[Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)

一個ハンズオンに取り組んだら、もう少しレベルの高いハンズオンに取り組んでみてもいいですね
[「Flutterでアプリを作りたい」と思っているあなたへ](https://www.flutter-study.dev/)


# 以上！
ここまで来れば、まっさらなPCにはFlutterアプリを作るためのツールが、まっさらなあなたにはFlutterアプリを作るための知識がインストールされたはず。

あとは好きにアプリを作ってみよう！
市場の効率性と即時約定性の関係についての考察

本記事では、ある市場を **ゼロサムゲーム** と仮定した場合の、市場の効率性と即時約定性（トレードの即時執行）がどのように関係するかについて、背理法（証明 by contradiction）を用いて議論します。なお、ここではスプレッドや手数料などの取引コストは存在しないものと仮定します。

## 前提条件

以下の前提条件を置きます。

- **市場はゼロサムゲームである**  
  各参加者の利益と損失の合計がゼロとなる。取引コストがないため、ある参加者が得をすれば必ず他の参加者が同額の損をする状況です。

- **「何の戦略も持たない参加者」の存在**  
  ここでいう「何の戦略も持たない参加者」とは、市場から特に情報や優位性を活用せず、ランダムに取引を行うような参加者を指します。

## 証明の概要

背理法を用いて、次の論理展開を行います。

1. **ゼロサムゲームにおける期待値の性質**  
   ゼロサムゲームでは、すべての参加者の期待値の合計が 0 であるため、もしある参加者がプラスの期待値を持つならば、必ず他の参加者がマイナスの期待値を持たなければならない（自明）。

2. **戦略を持たない参加者の期待値はプラスになりえない**  
   戦略を持たない参加者は、市場の情報や変動を利用することができず、プラスの期待値を得ることは不可能であると考えられます。（①）  
   → つまり、何の戦略も持たない参加者は、理論上、プラスの期待値を得る可能性はゼロである。

3. **戦略を持たない参加者がマイナスの期待値であると仮定**  
   仮に、戦略を持たない参加者の期待値がマイナスであると仮定します。

4. **逆の取引戦略の存在**  
   もし、マイナスの期待値を生み出す戦略が存在するならば、その戦略の「逆の取引」を行えば、同じくゼロサムの性質により、プラスの期待値の戦略を容易に構築できるはずです。（②）  
   → しかし、これは先述の（①）と矛盾します。

5. **矛盾からの結論**  
   （①）と（②）の矛盾から、戦略を持たない参加者の期待値は、プラスでもマイナスでもなく、ゼロでなければならないと結論付けられます。  
   さらに、ゼロサムゲームの性質上、プラスの期待値の参加者が存在しない場合、市場は効率的であると解釈できます。

## 議論のまとめ

以上の議論から、以下の結論を導くことができます。

- 戦略を持たず、即時約定が行われる市場においては、情報や取引コストが存在しない理想的なゼロサム環境では、どの参加者も長期的にプラスの期待値を得ることは不可能である。
- この性質は、市場が効率的であり、特定の参加者が一方的に優位に立つことができないことを示唆しています。

## 結論

今回の背理法による議論は、**市場の効率性**と**即時約定性**の関係性を、理論的な枠組みの中で理解する一助となります。実際の市場ではスプレッドや手数料、情報の非対称性などが存在するため、単純なゼロサムゲームの仮定は成り立たない部分もありますが、理論モデルとして市場の効率性を考察する際の基本的な視点として有用です。
ClineでBedrockのLlamaを使う

# はじめに

最近話題のClineですが、Bedrockも使用できるものの、使用できるモデルがClaude,Nova,DeepSeekになっています。(2025/3時点)
コストが安いLllamaも使いたいため、LiteLLM Proxyを介して使えるようにしました。

# LiteLLM Proxyとは

LiteLLM Proxyは、Bedrockなどの様々なLLMを同じインターフェースで使用可能にしてくれるツールです。100種類以上のLLMに対応しています。

https://qiita.com/moritalous/items/005a5a2fa3783ba5df54

ClineはLiteLLMに対応しているため、ClineのAPI Providerの選択肢にないLLMを使いたい場合はLiteLLMでラップして使うことができます。

# LiteLLMの準備

pipでLiteLLM[proxy]をインストールします。
```bash
pip install LiteLLM[proxy]
```

つぎに、config.yamlを作成します。model_nameは任意の名前です。
```yaml
model_list:
  - model_name: llama3-1-70b
    litellm_params:
      model: bedrock/us.meta.llama3-3-70b-instruct-v1:0
      aws_region_name: {region}
      aws_access_key_id: {access_key_id}
      aws_secret_access_key: {access_key}
      aws_session_token: {session_token}
      input_cost_per_token: 0.00000072
      output_cost_per_token: 0.00000072
```

LiteLLM proxyを起動します
```bash
litellm --config ./config.yaml
```

これでhttp\://0.0.0.0:4000にサーバーが立ちます。準備完了です。

# Clineの設定

API ProviderにはLiteLLMを選択します。
BaseURLには起動したサーバーのアドレス、ModelIDにはconfig.yamlで設定した任意の名前を設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1223968/c3296019-751b-4132-a874-35f3d9081f46.png)

# 完了

これでBedrockのLlamaを使えるようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1223968/c3a78eaf-7834-44c9-9732-fe5eed0c916f.png)

API Costはずっと$0.000のままになっています。おそらく不具合です。
WSL2のファイル変更監視問題とfspollを作った話

[arelo](https://github.com/makiuchi-d/arelo)ではファイルの更新検知に[fsnotify](https://pkg.go.dev/github.com/fsnotify/fsnotify)を利用していますが、WSL2で利用している時にWindows側ファイルシステムのイベントが受け取れない問題がありました。[この問題はWSL2の制限として知られています](https://github.com/microsoft/WSL/issues/4739)。

そこで、このような環境でも動作するようにするために、ファイルの更新日時などを定期的にチェックして変更を検知するポーリング機能を追加することにしました。

この記事では、ポーリング機能実装時に気をつけていたgoroutineの扱い方について紹介します。

...

https://makiuchi-d.github.io/2025/03/30/arelo-fspoll.ja.html
抽象化という技術と思考法：プログラマにとっての核心スキル

## 🔍 抽象化とは？

> **複雑なものから本質だけを取り出して、シンプルにする技術**

抽象化は、プログラミング・設計・仕事術すべてに関わる**基礎力**です。  
この記事では、抽象化の本質や実践例、そして関連概念（正規化・圧縮）との関係をわかりやすく解説します。

---

## 🛠 プログラミングにおける抽象化の実例

### ✅ 関数化は「意味の単位」で分ける

```swift
// 抽象化前
func doStuff() {
    // いろいろな処理
}

// 抽象化後
func validateInput() -> Bool
func fetchUser() -> User
func sendToServer(user: User)
```

→ 「やることの意味」が明確だから関数名もスッと決まる！

---

### ✅ 変数名も抽象化で決まる

```swift
let a = getData()
let b = process(a)
```

❌ 意味が見えない

```swift
let user = fetchUser()
let posts = fetchPosts(for: user)
```

✅ 抽象化された処理単位なら、自然と名前も明確に

---

## 🧱 抽象化と正規化の関係

正規化（特にデータベース設計）も、実はただの圧縮じゃなく「抽象化」が関わっている。

### 例：

```sql
-- 抽象化前
| user_id | name  | department |
|--------|-------|------------|
| 1      | Alice | Sales      |
| 2      | Bob   | Sales      |

-- 抽象化後（＝正規化）
Departments:
| id | name  |
|----|-------|
| 1  | Sales |

Users:
| id | name  | department_id |
|----|-------|----------------|
| 1  | Alice | 1              |
| 2  | Bob   | 1              |
```

→ **「Sales部門」という意味を抜き出し、独立した“概念”にした**のがポイント！

---

## 🤖 抽象化とAI、自動化の関係

### ✅ 抽象化・具体化が人間の仕事の本質

- 抽象化：複雑な事象の背後にあるパターンを見つける  
- 具体化：アイデアを現実の行動・コードに落とし込む  

> 人間の生産性 = 抽象度を自在に上げ下げする力

---

### ❗ でもAIもそれを始めている

- ChatGPT：文章から構成を抽象化、アイデアを具体化  
- LLM：膨大な情報から共通パターンを抽出（＝抽象化）

→ 今後、人間が価値を出せるのは「**より質の高い抽象化**」ができるかどうか。

---

## 📌 まとめ

- 抽象化は、**情報・構造・思考**をシンプルにする技術  
- 正しい関数名や変数名、設計の背後には「抽象の単位」がある  
- 正規化はただの圧縮でなく「概念の整理」＝抽象化を伴う  
- 抽象化と具体化を操る力は、仕事の生産性に直結する  
- AI時代においても、**“考える力”の核は抽象化**

---

必要なら、記事タイトル・タグ・サムネ用アイデアも提案します！
[Python] Anaconda における，base環境と仮想環境の違い



## In a nutshell
Anacondaのインストール時にPythonも自動的にインストールされる．仮想環境では独立したPythonが利用され，baseのPythonは使い回されない．開発や分析は仮想環境で行い，baseは管理用途に限定するのが安全．


## はじめに
Anacondaを利用して仮想環境を作成する際には，必ずPythonを個別にインストールする必要がある．しかし，Anacondaをインストールした際には標準でPythonもインストールされていた事に気が付いた．仮想環境を作成する際にPythonのインストールをするのであれば，Anacondaのセットアップ時にPythonをインストールする事に対して疑問を感じた．そこで，以下の記事を記述した．


## 予想される読み手
 - Anaconda及びPythonを利用しているが，環境の作成はチュートリアル通りで，理解している訳ではない．
 - 複数の仮想環境とbase環境の違いについて，よく分からない．
 - Anacondaをインストールすると，別のツールでもPythonが利用できるようになるが，なぜか説明できない．


## Anacondaのインストール時
Anacondaをインストール際にはPython本体も自動的にインストールされる．一般には最新の安定版のPythonがインストールされる．NumPy，Pandas，Jupyter等の汎用性の高いライブラリも初期にインストールされる．この初期のPythonは，base環境(base)で使用される．各仮想環境のPythonとbase環境は独立している．このPython本体は，Anacondaをインストールしたディレクトリ(例：`C:\Users\ユーザー名\anaconda3`)内に保存されている．その中の，`python.exe` がbase環境専用のPythonである．


## 新規の仮想環境の作成時
バージョンを指定しなければ，その時点での最新のバージョン(Anacondaが管理するデフォルトバージョン)のPythonがインストールされる．`conda create -n 環境名 python=3.9` のようにバージョンの指定が可能．


## base環境のPythonは他で使わないのか？
基本的には，base環境専用である．仮に，base環境に多くのライブラリをインストールすると，依存関係の衝突や不具合の原因になりやすい．その為，baseは極力クリーンに保ち，プロジェクトごとに仮想環境を使い分けるのが望ましい．

### base環境の主な用途
- 仮想環境の作成や管理(`conda create` や `conda install` など)
- 軽いスクリプトや一時的な動作確認
- Anaconda Navigator や Jupyter Notebook の起動

### 推奨される管理方針
- 不要なライブラリは入れない(ライブラリのテストは仮想環境で行う)
- conda本体やconda-buildなど，Anacondaの中核ツールのアップデートは慎重に行う
- トラブルが起きたら `conda update conda` や `conda clean` で復旧できることもある

### トラブル時の対処法
- `conda list` でインストール状況確認
- `conda info --envs` で環境一覧を確認
- `conda deactivate` → `conda activate base` で戻す



## base環境と外部ツールとの連携で注意すべき点
外部ツール(VSCode，PyCharm，Jupyter Notebook，CLIツールなど)とAnacondaのPython環境を連携させる際，以下の点に注意が必要である．

### パスの指定と環境の誤認識
多くの外部ツールは，最初に `PATH` に登録された `python.exe` を自動検出する．
Anacondaをインストールした際，base環境のPythonがシステムに登録されるため，意図せずbase環境を使ってしまうことがある．

#### 対策
- VSCodeなどでは，仮想環境を明示的に選択する必要がある(例：コマンドパレット -> `Python: Select Interpreter`)．
- ターミナル起動時には `conda activate 環境名` を忘れずに実行する．
- `.condarc` や `.bashrc` に自動アクティベート設定を追加するのも一つの手．

### Jupyter Notebookのカーネルに仮想環境を追加する方法
仮想環境でJupyterを使いたい場合，仮想環境にカーネルを登録する必要がある．登録後にJupyter上で「Python (myenv)」を選べば仮想環境を使う事が出来る．

```bash
conda activate myenv
python -m ipykernel install --user --name myenv --display-name "Python (myenv)"
```


## 使われ方のまとめ

| 用途                     | 推奨環境         |
|--------------------------|------------------|
| condaのコマンド実行        | base             |
| データ解析・開発プロジェクト | 専用の仮想環境    |
| 複数プロジェクト管理       | 仮想環境ごとに分ける |


## Summary
- Anacondaインストール時にPython本体と主要ライブラリが含まれる  
- 仮想環境はPythonごと独立しており，baseとは切り離されている  
- base環境は仮想環境の管理やJupyter起動用に利用するのが望ましい  
- 外部ツールと連携する際は仮想環境を明示的に選択する必要がある  
- Jupyterで仮想環境を使うにはカーネルの登録が必要  
- base環境はクリーンに保ち，依存関係の衝突を避ける



## References
 - [Conda  User guide > Tasks > Managing environments — Official Docs](https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html)
 - [Anaconda  Getting Started > Distribution Installing Anaconda Distribution - Installation Guide](https://www.anaconda.com/docs/getting-started/anaconda/install)
ツイートの自動投稿アプリを作成する

## はじめに
KG-7thの槙島です。

Typescript(javascriptでもほぼ同じ)のnode.jsを使って
X(旧Twitter)の自動投稿アプリを作成する方法について、記事に起こしてみます。

XのAPIはお金がかかるイメージをお持ちの方もいるかもしれませんが、
投稿するだけなら無料でできます。
悪質なBot目的でなければ積極的に活用してよいと思います

## 事前準備
XのAPIを利用するためには、Twitter Developer Portalでアプリを作成し、APIキーを取得する必要があります。
以下のページにアクセス＞右上の「開発者ポータル」のリンクを開いて投稿したいアカウントでログインして
必要事項を入力すればOKです。
https://developer.x.com/ja
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4042336/a2c56cf2-9f89-4798-a80f-91f689b2081f.png)

## トークンを作成する

デフォルトで作成されているプロジェクトを開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4042336/d0dec5d0-86b3-4178-8631-954060027061.png)

読み取りと書き込みを選択する
他の必要事項は使わないので適当に。。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4042336/a7a75dcb-8e9f-45bb-bfff-2bab1ebca611.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4042336/fe1ef5ce-cda7-4d08-84a8-fb46a8429c7d.png)

Client IDとClient Secretが生成されるのでコピーして保管する（使い道は正直知らない・・）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4042336/171b21c1-fd05-4e59-8e91-d4cccf5ab4af.png)

APIキーとシークレットキーを生成する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4042336/6e89804c-5761-45f5-945e-3428f20ca51d.png)

コピーして保管しておく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4042336/f1d7b218-59e0-4248-bd66-15ee99183deb.png)

Access Token と Access Token Secretを生成する
（初めて生成するときはGenerate表記になっている）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4042336/b68e83d2-72ec-419c-90df-3964d3bf8221.png)

コピーして保管しておく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4042336/195d4eab-1352-4414-9713-46f1a6ca8cb5.png)

## 実装編

### 前提

今回はtwitter-api-v2ライブラリを使用します
https://www.npmjs.com/package/twitter-api-v2

バージョンは1.22.0を使いました。
もしうまくいかなければ、バージョンを上記に合わせてみてください。
それでもうまくいかない場合はTwitterの仕様変更ですね。。。

なお、npm initでプロジェクト作成するとかの手順は省略してます。コードだけ載せます。

### 認証情報を設定したインスタンスの作成
環境変数じゃなくて直接文字列を入れても動きます。
```typescript
    // Twitter APIキーインスタンスを生成
    const twitterInstance = new TwitterApi({
      // APUキーを環境変数から取得
      appKey: process.env.APP_KEY!,
      // APIシークレットを環境変数から取得
      appSecret: process.env.APP_SECRET!,
      // access tokenを環境変数から取得
      accessToken: process.env.ACCESS_TOKEN!,
      // access token secretを環境変数から取得
      accessSecret: process.env.ACCESS_TOKEN_SECRET!,
    });
    // 権限はread/writeを指定
    const client = twitterInstance.readWrite;
```

### ツイートの投稿

```typescript
await client.v2.tweet("テストの投稿です！！");
```

### 画像付きツイートの投稿
```typescript
    // 画像をアップロードしてメディアIDを取得
    const imageId = await this.client.v1.uploadMedia("<画像のファイルパスを指定>");
    // ツイートを行う
    await client.v2.tweet("画像付きツイートです！！", { media: { media_ids: [imageId] } });
```

上記を使ったプロジェクトは以下で公開してます。

https://github.com/undo-works/sns-automate

以上！

参考になったらうれしいです。
節度を守ってBot運用していきましょう
Supabaseの戻り値で起きた"reduce is not a function"エラーの解決方法

# はじめに
Supabaseの戻り値の指定を間違えてエラーが起きてしまい、解決に時間がかかってしまったので記事にします。

# 問題
console.logにはsupabaseに登録しているデータを取得しているのが確認できるが、画面ではコンポーネントのエラーが発生している。

```App.js
  useEffect(() => {
    const getRecords = async () => {
      try {
        setIsLoading(true);
        const allRecords = await getAllRecords();
        console.log("supabase", allRecords);
        setRecords(allRecords);

        const initialTotalTime = allRecords.reduce(
          (accumulator, currentValue) => accumulator + currentValue.time,
          0
        );
        setTotalTime(initialTotalTime);
      } catch (error) {
        console.log("エラー", error);
        setError("エラー発生");
      } finally {
        setIsLoading(false);
      }
    };
    getRecords();
  }, []);
```
```supabaseFunction.js
import { supabase } from "./supabase";

export const getAllRecords = async () => {
  const records = await supabase.from("study-record").select("*");
  return records;
};

```
実際のエラーメッセージ:
```
TypeError: allRecords.reduce is not a function
```



# 解決方法
supabaseFunction.jsのreturn recordのところにdataプロパティを明示的に指定する必要があった。
```supabaseFunction.js
import { supabase } from "./supabase";

export const getAllRecords = async () => {
  const records = await supabase.from("study-record").select("*");
  return records.data;
};
```
<br />

Supabaseのレスポンスでは以下の構造のオブジェクトを返します。
```
{
  data: [...], // 実際のデータ配列
  error: null,  // エラーがあればエラーオブジェクト、なければnull
  count: null,  // カウントクエリの結果
  status: 200,  // HTTPステータスコード
  statusText: "" // HTTPステータステキスト
}
```
return records; にすると、オブジェクト全体を返しているのに、React側でそれを配列として扱おうとしてエラーが起きていた。具体的には、allRecords.reduceを実行しようとしたが、allRecordsはオブジェクトであり、reduceメソッドを持っていないためエラーになった。


# おわりに
戻り値が配列なのか、オブジェクトなのか、オブジェクトならどのキーの情報が欲しいのか考える癖をつけるようにする。また、APIからのレスポンスデータは、console.logでその構造を確認してから処理を進めていきたい。
# 参考
https://supabase.com/docs/reference/javascript/select
[忘備録]Ubuntu基本コマンド



# はじめに

UbuntuをはじめとするLinux環境では、ターミナル（コマンドライン）を使った操作が非常に重要です。ここでは、初心者がまず覚えておきたい「基本コマンド」を用途別にまとめて紹介します。コマンドの使い方を知っておくと、ファイル操作やシステム管理が格段に効率化します。


---
# ディレクトリ・ファイル操作

| コマンド | 用途 | 主なオプション例・備考 |
|----------|------|----------------------|
| `pwd`    | 現在のディレクトリ（パス）を表示 | `-L`（リンク名表示）, `-P`（参照先表示） |
| `ls`     | ディレクトリ内のファイル・ディレクトリを一覧表示 | `-l`（詳細表示）, `-a`（隠しファイル含む） |
| `ll`     | `ls -l`と同じ（詳細表示） |  |
| `cd ディレクトリ名` | ディレクトリの移動 | 例: `cd /home/username` |
| `mkdir ディレクトリ名` | 新しいディレクトリを作成 | `-p`（親ディレクトリも同時作成） |
| `rmdir ディレクトリ名` | 空のディレクトリを削除 | `-p`（上位ディレクトリも削除） |
| `touch ファイル名` | 新規ファイル作成/タイムスタンプ更新 |  |
| `cp コピー元 コピー先` | ファイルやディレクトリをコピー | `-r`（ディレクトリごと）, `-a`（属性ごと） |
| `mv 移動元 移動先` | ファイルやディレクトリの移動・名前変更 |  |
| `rm ファイル名` | ファイルを削除 | `-i`（確認あり）, `-r`（ディレクトリごと）, `-f`（強制削除） |

---

# ファイル内容の表示・検索

| コマンド | 用途 | 主なオプション例・備考 |
|----------|------|----------------------|
| `cat ファイル名` | ファイルの内容を表示 |  |
| `less ファイル名` | ファイル内容をページ送りで表示 |  |
| `head ファイル名` | 先頭10行を表示 | `-n`で行数指定 |
| `tail ファイル名` | 末尾10行を表示 | `-n`で行数指定 |
| `grep キーワード ファイル名` | キーワードを含む行を検索 | `-r`（再帰的）, `-i`（大文字小文字無視） |
| `find ディレクトリ -name 'パターン'` | ファイルやディレクトリを検索 | 例: `find . -name '*.py'` |

---

# システム・ネットワーク操作

| コマンド | 用途 | 主なオプション例・備考 |
|----------|------|----------------------|
| `history` | コマンド履歴を表示 |  |
| `chmod 権限 ファイル名` | ファイルやディレクトリの権限変更 | 例: `chmod 755 script.sh` |
| `ip a`    | IPアドレスを確認 |  |
| `ping ホスト名/IP` | ネットワーク接続確認 | 例: `ping google.com` |
| `ssh ユーザー@ホスト` | リモートサーバーに接続 |  |
| `scp コピー元 コピー先` | ファイルをリモート間でコピー | 例: `scp file.txt user@host:/path/` |

---

# よく使うショートカット

| ショートカットキー | 説明 |
|-------------------|------|
| `Ctrl + Alt + t`  | 新しいターミナルを開く |
| `Ctrl + C`        | 実行中のコマンドを中断 |
| `Tab`             | コマンドやファイル名の補完 |
| `Ctrl + L`        | 画面のクリア（`clear`コマンドと同じ） |

---

## 注意点

- `rm -rf`は非常に強力なコマンドです。誤って重要なファイルやディレクトリを削除しないよう、慎重に使いましょう
- コマンドの詳細は`man コマンド名`でマニュアルを参照できます

---

## まとめ

Ubuntuの基本コマンドは、ファイル操作・検索・システム管理など幅広い用途で活躍します。最初は覚えることが多いですが、よく使うコマンドから少しずつ慣れていきましょう。困ったときは`man`や`--help`オプションでヘルプを確認するのもおすすめです。
【TypeScript】文字列操作の型

## `Uppercase<StringType>`

文字列内の各文字を大文字に変換する。

```typescript
type Greeting = "Hello, world"
type ShoutyGreeting = Uppercase<Greeting>
 
// ShoutyGreeting = "HELLO, WORLD"
```

## `Lowercase<StringType>`

文字列内の各文字を小文字に変換する。

```typescript
type Greeting = "Hello, world"
type QuietGreeting = Lowercase<Greeting>
          
// QuietGreeting = "hello, world"
```

## Capitalize<StringType>

文字列の先頭の文字を大文字に変換する。

```
type LowercaseGreeting = "hello, world";
type Greeting = Capitalize<LowercaseGreeting>;
        
// Greeting = "Hello, world"
```

## Uncapitalize<StringType>

文字列の先頭の文字を小文字に変換する。

```typescript
type UppercaseGreeting = "HELLO WORLD";
type UncomfortableGreeting = Uncapitalize<UppercaseGreeting>;
              
// UncomfortableGreeting = "hELLO WORLD"
```

## 参考

https://www.typescriptlang.org/docs/handbook/2/template-literal-types.html#intrinsic-string-manipulation-types
Astro.js ファビコンの変更方法

ファビコンはブラウザのタブやブックマークに表示される小さなアイコンです。ここではAstroでファビコンを設定する方法を紹介します。

## ファビコン設定の手順

### 1.ファビコンファイルを用意する

* サイトを表す画像ファイルを用意します
* **形式:** 一般的には `.ico` が最も互換性が高いですが、`.png` (透過可) や `.svg` (ベクター形式) もよく使われます
* **サイズ:** `.ico` 形式なら複数のサイズを1ファイルに含められます。`.png` の場合は、`16x16` ピクセルや `32x32` ピクセルなど、いくつかサイズを用意しておくと、様々な環境で綺麗に表示されやすくなります

png画像があればファビコン(.icoファイル)を作ってくれる無料ツールがあるので活用しましょう。

[Faviconジェネレーター](https://favicon-generator.mintsu-dev.com/)

### 2.ファビコンファイルを `public/` ディレクトリに配置する

* 用意したファビコンファイルを、プロジェクトのルートにある **`public/` ディレクトリ** の直下に置きます
* 例えば、ファイル名が `favicon.ico` なら、`プロジェクトフォルダ/public/favicon.ico` という場所に配置します
* `public/` ディレクトリに置いたファイルは、Astroによってビルド時にそのままサイトのルートディレクトリ (`/`) にコピーされます

```
your-project/
├── public/
│   └── favicon.ico  <-- ここに配置！
│   └── favicon.png  <-- PNGを使う場合はこれも配置
│   └── favicon.svg  <-- SVGを使う場合はこれも配置
├── src/
├── astro.config.mjs
└── package.json
```

### 3.レイアウトコンポーネントの `<head>` にリンクを追加する

* サイト全体で共通して使っている **レイアウトコンポーネント** ファイル（例: `src/layouts/BaseLayout.astro` や `src/layouts/Layout.astro` など、`<html>` や `<head>` タグが書かれているファイル）を開きます。
* `<head>` タグの中に、ファビコンファイルを指定するための `<link>` タグを追加します。使用するファイル形式に合わせて記述します。

`.ico` ファイルの場合:
```html
<head>
  {/* ...他のheadタグ... */}
  <link rel="icon" href="/favicon.ico" /> {/* hrefは / から始める */}
  <title>サイトタイトル</title>
</head>
```

`.png` ファイルの場合: (例: 32x32ピクセル)
```html
<head>
  {/* ...他のheadタグ... */}
  <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" /> {/* typeとsizesを指定 */}
  <title>サイトタイトル</title>
</head>
```
*(注意: この場合、`public/favicon-32x32.png` が存在する必要があります)*

`.svg` ファイルの場合:
```html
<head>
  {/* ...他のheadタグ... */}
  <link rel="icon" type="image/svg+xml" href="/favicon.svg" /> {/* typeを指定 */}
  <title>サイトタイトル</title>
</head>
```
(注意: この場合、`public/favicon.svg` が存在する必要があります)

* `rel="icon"`: これがファビコンであることを示します
* `href="/..."`: **重要！** `public/` ディレクトリに置いたファイルへのパスを、必ず `/` から始まる **ルート相対パス** で指定します。`./favicon.ico` や `public/favicon.ico` ではありません
* `type="..."`: `.png` や `.svg` など、`.ico` 以外の形式を使う場合は、適切な MIME タイプを指定することが推奨されます
* `sizes="..."`: `.png` などで特定のサイズのアイコンを指定する場合に使います

### 開発サーバーで確認と注意点

* 開発サーバーを起動 (`npm run dev` など) して、サイトにアクセスします
* ブラウザのタブに設定したファビコンが表示されるか確認してください
* **【重要】キャッシュに注意！** ファビコンはブラウザにキャッシュされやすく、変更してもすぐに反映されないことがよくあります
* **対処法:** ブラウザの **キャッシュを完全に削除** するか、ページを開いた状態で **スーパーリロード** (Windows: `Ctrl + Shift + R`, Mac: `Cmd + Shift + R`) を試してみてください
参照透明性という理想と、JSという現実

はじめまして！！標準体重 65kg 目指して増量中のそうまです！！

今日は参照透明性について疑問に思ったことと、JSで何故副作用が起こるかを個人的に調査したので殴り書きしていきます！！！

## 調査のきっかけとなったある勘違い

関数型言語における参照透明性って、変数が作られるたびにオブジェクトだろうが値だろうが毎回ディープコピーされてメモリに格納されるものだと思っていました。
(シャローコピーという概念が存在し無い) 

だから副作用とは無縁で安全だと。 

でも、それは完全な勘違いでした。

## そもそもシャローコピーとは

シャローコピーとは、変数に“値そのもの”ではなく、“メモリの番地”がコピーされることを指します。

たとえば、次のようなコードがあるとします。
```jsx
const person = { name: "taro", meta : { age: 12, weight: 40 } }
const target = { ...person }
```

このとき、`target` に格納されるのは、`person.name` の値（プリミティブ）のコピーと`person.meta` という **オブジェクトの参照（つまりヒープ上のアドレス）** です。

そのため、見た目上は person をコピーしたように見えても、`meta` のようなネストされたオブジェクトは共有された状態になります。

これが、シャローコピーと呼ばれるものです。

一方で、次のような場合はどうなるでしょう？
```jsx
const person = { name: "taro", age: 12 }
const target = person.name
```

この場合、`target` に格納されるのは "taro" という文字列そのもの（＝値）であり、 `person.name` が参照していたメモリとは無関係なスタック上のコピーになります。

この違いが、シャローコピーと値コピーの本質的な差です。

:::note info
ディープコピー
メモリの番地ではなく、オブジェクトの値そのものをそのままコピーする
:::

## なぜオブジェクトがシャローコピーされるのか？

それは、**可変長のデータ構造**だからです。

オブジェクトの中身は、構造も違えば深さも違う。  
さらに、途中には**再帰的な参照や構造**が含まれることも多く、全体のサイズを静的に割り出すのは現実的ではありません。

もし、メモリ確保時点でオブジェクト構造のすべてを調べてサイズを決めようとしたら、それだけで**膨大な処理**となってしまいます。

だからこそ、オブジェクトは実行時に動的にメモリ確保できる「ヒープ領域」に乗ります。

そして、そんな可変長のオブジェクトを毎回ディープコピーしていたら、メモリ消費も処理時間も爆増してしまいます。

そこで採用されているのが、**シャローコピー** です。つまり、オブジェクトの“メモリ番地（参照）”だけをコピーすることで、メモリ効率を保っているのです。

![頭整理4.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1100170/c91173b0-26a1-4476-ad1c-308444d2458b.png)

一方で、プリミティブ型はシンプルです。 
型さえ決まっていれば、最大で必要なメモリサイズも静的に決める事ができます。

だから、値をそのままコピーして渡しても問題はありません。
そのため、コンパイル時に静的にメモリを確保する領域であるスタック上で完結するようになっています。

## ヒープとスタック領域って何？

まずヒープ領域とは、サイズが一概に決められない可変長データを格納するためのメモリ領域です。
実行時に必要なサイズを判断して、値をメモリ上に格納します。

一方、スタック領域は、**あらかじめサイズが決まっているデータ**を扱います。  
例えばプリミティブ型のように、型さえわかれば最大で必要なサイズが静的に確定するようなものです。

そういったデータは、コンパイル時にメモリの配置を決める事が出来ます。

![頭整理5.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1100170/0b291a14-0a24-4143-bfd8-ccbab1411534.png)

参照透明性のある関数型言語だと、「でも、副作用がないのでコンパイル時に決めれるやん」ってなりますが、遅延評価により実行時に決めているらしいです (※ ここはまだ勉強中です)

## GC(ガベージコレクタ)の重要性

ヒープに割り当てられる値は、大きくなりがちです。  
だから上記で説明したように、毎回コピーするのではなくメモリの番地（参照）を使って効率的に扱っています。

ですが――  
参照をしているが故に、「どこで使用されているか」「いつ使われなくなったか」の判断は簡単ではありません。

参照されていないものを、即座にメモリから解放できなければ**永遠にメモリを蝕み続けるだけ**です。

プリミィティブ型であれば判断出来ます、何故ならスタック領域に格納されており参照されることはないからです。
もし仮にオブジェクトの値として代入されていても、値をそのままコピーして渡すだけでそのまま役目を終えるため、必要なくなったとして自然とメモリ解放の判断が出来ます。

そこで登場するのが、**ガベージコレクタ（GC)** です。

GCは、プログラムの中でまだ使われていそうな変数を起点にそこから関係のあるデータをたどっていきます。
そして、どこからも参照されていないデータを見つけたら「もう使われないな」と判断してヒープからメモリを解放します。

![頭整理.drawio (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1100170/cfb347f6-b539-458a-b80f-42fb5df84275.png)

## 纏め

長くなってしまいましたが、最後に参照透明性とはなんであるかを話すと

参照透明性とは、同じ入力があれば常に同じ出力を返すという性質の事を言います。
裏を返せば、変数の状態や副作用によって結果が変わらないということです。

それは、値が不変（イミュータブル）であり、オブジェクトの中身を破壊的に変更出来ないからこそ実現出来ます。
つまり、ヒープにあっても「壊せない」から**副作用が起こりません**、これが参照透明性の強みです。

一方でJSはどうでしょうか....オブジェクトであるのに好き勝手変更出来てしまいます、つまり副作用の聖地なのです。
なので必要に応じて気を使いバグが起こらないように「参照されてるかもだから、念のためディープコピーしとくか」
と、**余計な思考コスト**を払う羽目になります。

そして、こういう“気遣い”がバグの温床になるんだと考えています。
OpenAI 新モデル早わかりガイド — 2025年4月16日リリース版

_Last updated at 2025-04-18  /  Posted at 2025-04-18_

---

## 1. はじめに  
2025年4月16日にリリースされた **GPT‑4o** や **o3 / o4‑mini** などの新モデル群を一挙に紹介します。  
本記事では、モデルの特徴・価格・ユースケース別のおすすめポイントを整理します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4006596/aef0455e-8504-4b2e-9b46-24fda3819d4e.png)

---

## 2. モデルラインナップ（2025年4月時点）

| カテゴリ           | モデル                | 特徴                                           | コンテキスト長 | 代表価格*                                           |
|-------------------|-----------------------|-----------------------------------------------|---------------|-----------------------------------------------------|
| フラグシップ       | **GPT‑4o**            | テキスト・画像・音声・動画をリアルタイムに処理  | 128k          | 入力: \\$5 / 1M tok<br>出力: \\$20 / 1M tok  |
| 高速廉価           | **GPT‑4o mini**       | GPT‑4o の約¼の価格で高スループット  | 128k          | 入力: \\$0.6 / 1M tok<br>出力: \\$2.4 / 1M tok        |
| 最新推論           | **o3**                | 深い論理思考＋ツール統合。画像を「考える」能力               | 200k          | GPT‑4o 相当                                          |
| 小型推論           | **o3‑mini**           | STEM・コーディング特化、低レイテンシ                      | 200k          | 入力: \\$0.3 / 1M tok<br>出力: \\$1.2 / 1M tok        |
| 長文＋高速         | **GPT‑4.1 / 4.1 mini** | 最大100万トークン対応、GPT‑4o比26%安                    | 1,000k        | 入力: \\$0.8 / 1M tok<br>出力: \\$3.2 / 1M tok        |

\* API公開価格。詳細はOpenAI公式Pricingをご参照ください。

---

## 3. ユースケース別おすすめモデル

### 3.1 高度なマルチモーダル対話  
- **GPT‑4o**  
  画像認識→音声応答、動画解析、リアルタイム翻訳など高度なマルチメディア対応に最適 。

### 3.2 複雑な推論・レポート生成  
- **o3** / **o3‑mini‑high**  
  学術論文ドラフト、データ分析、複雑コードリファクタリングで多段思考を実現 。

### 3.3 大量アクセス対応のFAQボット  
- **GPT‑4o mini** / **o3‑mini**  
  1/10程度のコストで高品質応答を維持。Webサービスのチャットサポートにおすすめ 。

### 3.4 RAG（Retrieval-Augmented Generation）  
- **text‑embedding‑3‑large + GPT‑4o (or o3)**  
  高精度な埋め込み検索と高性能生成の組み合わせで社内ナレッジベースを強化 。

### 3.5 コールセンター音声UI  
- **audio‑large‑2025 + GPT‑4o**  
  232 ms平均応答、ノイズ・方言耐性に優れた音声認識・対話 。

### 3.6 コード補完・数学演習  
- **o3‑mini (medium effort)**  
  STEMベンチマークで高い精度を発揮。IDEプラグイン等に最適 。

---

## 4. モデル選択フローチャート
1. **画像・音声を使いたい？** → Yes: GPT‑4o / GPT‑4o mini  
2. **複雑な推論・ツール連携？** → Yes: o3 / o3‑mini‑high  
3. **大量トラフィック＆低コスト？** → GPT‑4o mini / o3‑mini  
4. **長文/高速？** → GPT‑4.1 / 4.1 mini  

（冒頭の扉絵フローチャート参照）

---

## 5. 価格と利用制限のポイント
- ChatGPT Free は **一定回数でGPT‑4o miniに自動フォールバック**   
- Plus/Pro は Free の約5倍メッセージ上限、Team/Enterprise はさらに拡大   
- 旧 **GPT‑4 / 4 Turbo** は4月末にChatGPTから廃止、APIで継続利用可   

---

## 6. まとめ  
用途に応じたモデル選択で **速度 × コスト × 品質** の最適解を。  
- まず試すなら：GPT‑4o mini / o3‑mini  
- 高付加価値なら：GPT‑4o / o3  
- 長文×高速なら：GPT‑4.1  

ぜひプロジェクトやサービスに合わせて使い分けてみてください！

---

## 参考リンク  
1. GPT‑4o & 無料ユーザー向け解放[OpenAI](https://openai.com/ja-JP/index/gpt-4o-and-more-tools-to-chatgpt-free/)
2. GPT‑4o システムカード [OpenAI](https://openai.com/ja-JP/index/gpt-4o-system-card/)
【JavaScript】ABC401まとめ（A~C）

AtCoder Beginner Contest 401

https://atcoder.jp/contests/abc401

ABCの3完（10分0ペナ）でした。
985perfでレートは1045->1039（-6）となりました。
Cまでの簡単な問題を爆速で解くことによって耐えていますが厳しい状況です。
明日はコンテスト前にそこそこ精進できそうなので、次回はがんばります！
今回はA〜Cをまとめます。

# A - Status Code
https://atcoder.jp/contests/abc401/tasks/abc401_a

$S$を`Number型`で受け取り、$200$以上$299以下$であれば`Success`、それ以外なら`Failure`を出力しましょう。

```js
function Main(input) {
  input = input.split("\n").map((line) => line.trim());
  const S = Number(input[0]);
  if (S >= 200 && S <= 299) console.log("Success");
  else console.log("Failure");
}

Main(require("fs").readFileSync(0, "utf8"));
```

# B - Unauthorized
https://atcoder.jp/contests/abc401/tasks/abc401_b

求める値は、「認証エラーとなる回数」すなわち「ログインしていない状態で非公開ページにアクセスした回数」です。
この問題では、ログインしたかどうかのboolean変数`isLogin`を定義しておいて、入力に応じて以下のように処理内容を分岐させることで解くことができます。
- `login`のとき：`isLogin`を`true`に設定
- `logout`のとき：`isLogin`を`false`に設定
- `public`のとき：なにもしない（ログイン有無によらずページを開けるため）
- `private`のとき：`isLogin`が`false`であれば、認証エラーカウント+1する

```js
function Main(input) {
  input = input.split("\n").map((line) => line.trim());
  const N = Number(input[0]);
  const S = [];
  for (let i = 0; i < N; i++) S[i] = input[i + 1];

  let isLogin = false;
  let ans = 0;
  for (let i = 0; i < N; i++) {
    if (S[i] === "login") isLogin = true;
    else if (S[i] === "logout") isLogin = false;
    else if (S[i] === "private") if (!isLogin) ans++;
  }

  console.log(ans);
}

Main(require("fs").readFileSync(0, "utf8"));
```

# C - K-bonacci
https://atcoder.jp/contests/abc401/tasks/abc401_c

これは、`差分更新`という典型の問題です。
$A_i$〜$A_{K+i}$までの和を$sum$とおくと、$A_{i+1}$〜$A_{K+i+1}$までの和は$sum+A_{K+i+1}-A_i$と表すことができます。そのため、$A_i$をメモ化しながら$A_{K+i+1}$を逐次求めていくことができれば、$O(N)$でこの問題を解くことができそうです。

問題は$A_N$の$10^9$で割ったあまりを求める点ですが、今回は加法と減法しか使わないため、$A_i$が負にならないよう$10^9$を足して調整しつつ、逐一$10^9$の剰余を計算することで結果に整合しつつ$A_i$を求めていくことができます。

```js
function Main(input) {
  input = input.split("\n").map((line) => line.trim());
  const [N, K] = input[0].split(" ").map(Number);
  const A = new Array(N + 1).fill(1);
  let sum = K;
  const mod = 10 ** 9;
  for (let i = K; i <= N; i++) {
    A[i] = sum % mod;
    sum += A[i] - A[i - K] + mod;
    sum %= mod;
  }

  console.log(A[N]);
}

Main(require("fs").readFileSync(0, "utf8"));
```


# まとめ
D問題はコーナーケースに全く気づくことができず、結局7ペナ出して解くことができませんでした。
土曜夜の90分間を無為に過ごすというとても贅沢な時間の使い方をしてしまったことに反省しつつ、次回こそはレート増加目指してがんばります
【CakePHP 5入門】完全初心者がCRUDアプリを作るまで

## はじめに

CakePHPを使って、PHP初心者でも簡単にWebアプリが作れる手順をまとめました。

### 目標

- CakePHP 5.x のインストール
- MySQLとの接続
- CRUD機能を持つ「記事投稿アプリ」の作成

### 対象読者

- PHPはすこし触ったことがある
- フレームワークに初挑戦

---

## 環境構築

### 使用環境

- Windows 10
- XAMPP (PHP 8.2, MySQL)
- Composer
- CakePHP 5.1.x

### CakePHPプロジェクトの作成

```bash
cd C:\xampp\htdocs
composer create-project --prefer-dist cakephp/app cakephp_test
```

### 開発用サーバーの起動

```bash
cd cakephp_test
bin\cake server
```

→ `http://localhost:8765` にアクセスし、ウェルカム画面が表示されれば成功

---

## データベースの準備

### MySQLにデータベース作成

- `http://localhost/phpmyadmin` にアクセス
- `cake_app` という名前のデータベースを作成

### 接続情報の設定

`config/app_local.php`を編集:

```php
'host' => 'localhost',
'username' => 'root',
'password' => '',
'database' => 'cake_app',
```

### articles テーブルの作成

```sql
CREATE TABLE articles (
  id INT AUTO_INCREMENT PRIMARY KEY,
  title VARCHAR(255) NOT NULL,
  body TEXT,
  created DATETIME,
  modified DATETIME
);
```

---

## bakeコマンドでCRUD自動生成

```bash
bin\cake bake all articles
```

生成されるファイル:

- Controller: `src/Controller/ArticlesController.php`
- Model: `src/Model/Table/ArticlesTable.php`
- Entity: `src/Model/Entity/Article.php`
- Views: `templates/Articles/*.php`

### ブラウザで確認

- 一覧: `http://localhost:8765/articles`
- 新規: `http://localhost:8765/articles/add`

---

## おわりに

CakePHPは「bake」コマンドでMVC構造を自動生成できるので、初心者でもすぐにCRUDアプリが作れます。
DJProject_備忘録_9

======
最後、プロジェクト作業終了時、
絶対に｢🌙｣マークを、
作業中だったコード場所に
打ち込んでおくこと。
======

## 2025-02-19〜
[🦌] YoutubeQRsChangeToArray2DModeのクラス変数の受け渡し受け取りの確認と、未実装プレイヤーの実装(
[🔺(まだ分かんないので)] init_YoutubeReaderPlayer
[🔺(YouTubeオブジェクトがまだ仮定義)] YoutubeScreenShotsPlayer // 最大枚数集まるまでスクリーンショットする(既に集まっていればパス)(

QR数は1枚あたり352個とする。
)
[✅] ScreenShootSelectingPlayer // 自分が処理すべきスクリーンショットを選択する
(ScreenShootSelectingPlayerを実装中ですSNSWithWaitressPlayerに、予め352個のQR座標を求めておくメソッドの実装を施した。
今(2025-03-01)はExecuteMainメソッドを作ってる。に、あたって、いま「処理中のスクショ内の全てが正常に読み込まれた場合trueを返すメソッド」を求めているところ
組み込み完了！(2025-03-06)
)
[✅] UpdateIAmWaitressPlayer // 先にウェイトレスの状態を、Updateする。
(じゃないと各プレイヤーでチマチマUpdateする羽目になり、どこでアップデートしたか忘れるだろうから
)る（
[✅] QRcodeSelectingPlayer // 自分が処理すべきQRcode座標を🌙から選択するプレイヤー
[✅] QRPixelExtractorPlayer // 定めたQR座標から、QRピクセルデータ部分の2次元ピクセルデータをクラス変数に取得するプレイヤー
(
今、読み込むスクショの横のピクセル数的な、1QRあたりのピクセル的なピッチ幅を取得するにあたって、
SNSWITHWAITRESSPLAYERを調整してCol,RowPitchの算出メソッドを調整した。
)
[✅] CentralSquareReaderPlayer // 抜き取ったQR含有テクスチャからQR部分を取り出す。(この時点でまだQRの台形歪みは未処理)
[✅] TrapezoidCorrectionPlayer // QR コードの台形歪みを補正し、25x25 の正方形マトリックスにリサイズするプレイヤー。
[✅] PatternDetectionPlayer // QR コードの画像を取得し、それを 25x25 のバイナリマトリックスに変換して、主要なパターン（位置検出パターン、タイミングパターン、ダークモジュール）が正しく存在するかを検出するプレイヤー。
[✅] ReplacePatternPlayer // QR コードの 2D マトリックスにおける主要なパターン（位置検出パターン、タイミングパターン、ダークモジュールを特定の値（-11）で置き換えるプレイヤー。
[✅] ColumnSplitterConcatPlayer // QR コードの 2D マトリックスに対して特定の処理を行い、新しいジャグ配列を作成するプレイヤー。
[✅] RightBottomReaderPlayer // QRコードデータの2Dリストを解析し、右下からデータを抽出して1Dリストとして取得するプレイヤー。
[✅] BitDataProcessorPlayer // QRコードや画像データから取得したビットデータを処理し、8ビットごとに分割する役割を持つプレイヤー。
[✅] ChecksumCheekPlayer // ChecksumCheekPlayer は、QRコードのデータ処理後にチェックサムの整合性を確認するプレイヤー。
[✅] SpiritBitDataPlayer // QRコードのデータ部分を解析し、モードや文字数情報を取得するプレイヤー。
[✅] BitModeDataReconstructorPlayer // QRコードのビットモードデータを復元するプレイヤー。
[✅] WaitressQRDataWritingSchedulerPlayer // 復元したデータをウェイトレスの帳簿に書き込み、次のユーザーに
(
ウェイトレスがいなければ、ウェイトレスが来るまで "Complete" を返さず、待機。さらに、全てのQRの読み込みが終わったことがウェイトレスから告げられたら、"Completed"とし、読み込み完了とする。
)
ウェイトレスを移動させる。
(
この実装過程により、iAmWaitress.ReadData(読んだQRの保存先)の初期化コードの未実装が発覚した。
どこかで、「ウェイトレスが目の前にいてかつ、自身がワールド内で最小のUIDだった場合に、初期化」を、実装してください。→CalculateAllQRXYs実行時で実装しよう(2025-03-28)。
)


[]SettingsOfPredictMode
▷ ParamsLoadModeの次に実行されるものですね。 Aiの推論設定です。
[]ToVecOfXOfPredictMode
[]OnePositionLoopOfPredictMode
[]SNSWithDaijinMode
[]SettingsOfTrainMode
[]ToVecOfXandTMode
[]OnePositionLoopOfTrainMode
[]ParamsSendToHomePCMode
[]プレイヤー同士のクラス変数の渡し合いの実装
[✅] ParamsToBitDataMode
▷パラメータをBit一次元化と、それをQRCodeサイズにスプリットして2次元化
[✅] BitDataTo2DcodeMode
▷2次元Bitパラメータを全てQRcodeテクスチャ化
[]

```
Javaをとりあえず書けるようになるまで #0-2


早速ナンバリングがおかしくなっているんですが、記事とディレクトリのナンバリングを一致させるためなのでご容赦ください。

# 環境構築とは

まず、人間が書いたプログラムを実行するには、PCが理解できるようにプログラムを機械語へ翻訳してあげる必要があります。これを<b>コンパイル</b>といい、翻訳するソフトウェアを<b>コンパイラ</b>と言います。

どのプログラミング言語を扱うにしても、まずコンパイラをインストールする必要があります。このコンパイラをインストールし、コマンド1つでコンパイル出来るようにするための作業を<b>環境構築</b>と言います。

# 環境構築ってまぁまぁめんどくさい。

この環境構築なんですが、初心者にとっては結構ハードル高い可能性があります。理由としては以下の2つ。
- コンパイラの保存先までパスを通す(=PCにコンパイラの場所を教える)必要があり、PCに慣れていないと結構詰まりがち
- 使っているOS (Windows, Mac, Ubuntu, etc...) やエディタ (VSCode, そもそもIDE(Eclipse, etc...) を使ってる) の多様性から、参考にすべき記事を選べず、また教え合いも難しい

興味があれば以下のリンクを参考にして試してみてください。
OpenJDK (Java本体) + VSCode (エディタ)の組み合わせです。

### Windows
JDK: [Javaの環境構築をしよう!(Windows編)](https://qiita.com/git2024/items/101bfb6b40d0c9fcc882)
VSCode: [Windows への Visual Studio Code のインストール方法](https://www602.math.ryukoku.ac.jp/Prog1/vscode-win.html)
### Mac
JDK: [Javaプログラミングのための環境構築手順(Mac版)](https://tech.e3factory.com/programming/java/4287)
VSCode: [macOS への Visual Studio Code のインストール方法](https://www602.math.ryukoku.ac.jp/Prog1/vscode-mac.html)


環境構築、やると確かにPCへの理解は深まるのですが、プログラミングをする前に力尽きては元も子もないです。なのでなるべくここにはリソースを割きたくない......

# コード書くだけならWeb上でできる！

そんな初心者におすすめなのがWeb上で動くIDEの[myCompiler](https://www.mycompiler.io/ja)！環境構築いらずでコードを書けばWeb上で動きます。

まずはサインアップして、その後たくさんあるプログラミング言語の中からJavaを選んでください。そうすると下のような画面になるはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4065456/fc5320d9-9674-4663-ac43-540710884719.png)

左がソースコードを、右がプログラムを実行した際の出力を表しています。

右上の「コードを実行」ボタンを押してみましょう。下のような出力が見られれば正常に動作しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4065456/d6ddac13-9ba3-4a7e-a79e-22bfbaa755dd.png)

次回からガンガンコードを書いていきましょう！
ChatGPT×Excel：表のレイアウトを崩さずにまるごと翻訳するワークフローを試してみた

## :tada: TL;DR

* **ファイル丸投げ→言語選択→ダウンロード**の 3 ステップで Excel を一括翻訳できるクラウドサービス（*Doc2Lang*）が便利だった  
* ChatGPT ベースなので **専門用語・文脈の精度が高い** ＋ **元のセル結合・グラフ・数式をキープ**  
* ブラウザだけで完結、インストールやサインアップ不要  

---

## 背景：[Excel 翻訳](https://doc2lang.com/ja/excel-translate)“あるある”をどう減らすか？

| 困りごと | 従来の解決策 | よくある落とし穴 |
| --- | --- | --- |
| セル単位のコピペ翻訳が面倒 | Excel 内蔵翻訳 / Google 翻訳 | 文脈が切れて意味がブレる |
| レイアウトが崩れる | DeepL ファイル翻訳 | 結合セル・画像でズレる |
| 数式やピボットが壊れる | スクリプトで置換 | 関数名がロケール依存で事故る |

> 週末まるごと *Ctrl+C → Ctrl+V* に消えたこと、ありませんか？

---

## 解決策：Doc2Lang + ChatGPT を使う

**特徴まとめ**

| 機能 | 内容 |
|---|---|
| 100 + 言語対応 | 日本語⇔英語だけでなく、ヒンディー語・スワヒリ語などにも対応 |
| レイアウト保持 | 結合セル、グラフ、数式、ピボット、マクロが壊れにくい |
| セキュリティ | 処理後にファイルを即削除するオプションあり |
| 料金 | 従量課金（サブスク不要） |
| UI | ブラウザだけで完結、アカウント登録も不要 |

---

## ハンズオン：実際の操作手順

1. **Excel ファイルをドラッグ＆ドロップ**  
2. **ターゲット言語を選ぶ**（日本語→英語など）  
3. **翻訳開始ボタンを押す**  
4. **完了通知が来たらダウンロード**  

処理はサーバー側で非同期に走るので、ブラウザを閉じてもあとからダウンロードリンク経由で取得できます。数千行の大型ブックで 2〜3 分、数百行なら十数秒で終わるイメージでした。

---

## 精度チェック

| 評価軸 | Excel 内蔵翻訳 | DeepL ファイル翻訳 | **Doc2Lang** |
| --- | --- | --- | --- |
| 文脈の自然さ | △ | ◯ | **◎** |
| セル結合の維持 | △ | △ | **◎** |
| 数式の整合性 | △ | △ | **◎** |
| 料金形態 | 無料 | サブスク | **従量課金** |

医療ドメイン 500 行シートを社内レビューした結果、Doc2Lang 利用後は **人手修正率 75 % → 18 %** に圧縮されました。

---

## ベストプラクティスまとめ

1. **1 セル 1 概念**：長い文章を詰め込まない  
2. **結合セルを減らす**：重要テキストは未結合セルに置く  
3. **CSV は UTF‑8 で保存**：文字化け防止  
4. **画像ラベルは ALT に追い出す**：翻訳対象にするため  
5. **関数名は元言語を維持**：数式崩れを避ける  

---

### 参考リンク

* [Doc2Lang 公式サイト](https://doc2lang.com/ja/excel-translate)
* [OpenAI GPT-4o 技術ドキュメント](https://openai.com/ja-JP/) 

---

#### Tags  
`#Excel` `#翻訳` `#i18n` `#Doc2Lang`