OmniAICreator/Qiita-1.07M huggingface dataset:
Deno × GraphQL × Apollo Server でハマった落とし穴とその回避方法

## はじめに

GraphQLを学び始めたばかりで、「DenoでApollo Serverを動かしてみたい！」という方は少ないかもしれません。
でも、そんなちょっと尖った初学者の皆さん（と未来の自分）に向けて、**DenoでGraphQL環境を構築したときにハマった落とし穴**と、その回避方法を共有します。

---

## 🛠 使用環境

以下の環境で検証しました：

- Deno: 2.1.6  
- Node.js: 23.6.0  
- Apollo Server: 3.13  
- GraphQL: 16.10.0  

DenoとNode.jsで**まったく同じコード**を動かしたのに、出力結果が違って困った…というお話です。

---

## 🚀 Apollo Serverの立ち上げコード（共通）

Node.jsとDeno、どちらも使用したコードはこちらです：

```ts
import { ApolloServer } from 'apollo-server';
import { typeDefs, resolvers } from "./schema.ts";

const server = new ApolloServer({
    typeDefs,
    resolvers,
});

server.listen().then(({ url }) => {
    console.log(`🚀 Server ready at ${url}`);
});
```

schema.tsからなんか呼び出してますが、本題とは違うので一旦無視で

---

## 💣 異なる挙動

このコードをそれぞれの環境で実行すると、**出力されるURLが異なっていました**。

### ✅ Deno の実行結果

```
🚀 Server ready at http://0.0.0.0:4000/
```

### ✅ Node.js の実行結果

```
🚀 Server ready at http://localhost:4000/
```

ぱっと見、「ちょっと違うだけじゃん？」と思うかもしれませんが、ここが**かなり厄介な落とし穴**でした。

追記:
このPRを見る限りこの挙動はDeno側の意図した挙動のようです。

https://github.com/denoland/deno/pull/5203

---

### ❗ Apollo Studio に接続できない問題

Denoで表示された `http://0.0.0.0:4000/` を使って、Apollo Studioから接続しようとすると、こんなエラーが発生します：

![スクリーンショット 2025-04-06 20.04.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3655193/f48d53cb-7365-4fc2-b0c8-6d7fbb4d847b.png)

これは、**HTTPSなApollo Studioが、HTTPかつ「0.0.0.0」なURLにアクセスできない**というセキュリティ上の制限が原因です。  
つまり、**Apollo StudioがGraphQLサーバーを認識してくれない＝開発が進められない**！という状態に。

---

## ✅ 回避方法

Apollo Serverの `listen()` に `host` オプションを明示的に指定することで、挙動を統一しつつ、Apollo Studioにも接続できるようにできます。

```ts
server.listen({ host: "localhost", port: 4000 }).then(({ url }) => {
    console.log(`🚀 Server ready at ${url}`);
});
```

これで **DenoでもNode.jsでも、`localhost(127.0.0.1)` で統一して動作**させることができ、Apollo Studioの接続エラーも解消されました 🎉



---

## 🧠 まとめ

- DenoとNode.jsで**同じコードでも、デフォルトのバインド先が異なる**  
- `0.0.0.0` と `localhost` の違いは、実行環境のネットワーク挙動に影響する  
- **Apollo Studioが `0.0.0.0` に接続できず、エラーになる落とし穴がある**  
- **明示的にホスト名を指定することで、落とし穴を回避可能**

Denoでの開発はまだまだマイナーですが、こうした細かい違いに気づけると、トラブルを減らすことができるのかなと思いました。

---

## 📌 最後に

この記事が、DenoでGraphQLにチャレンジする誰か（または未来の自分）のお役に立てば嬉しいです！
もっとスマートな回避策や何か間違っている点があればコメントで教えていただけると助かります〜
ノシ

## 参考
https://qiita.com/Sicut_study/items/13c9f51c1f9683225e2e

https://qiita.com/1ain2/items/194a9372798eaef6c5ab
【Mac】今日ダウンロードしたファイルを見つけるコマンド

## 背景

ファイルをダウンロードしてブラウザのダウンロードした部分？をクリックすればファイルの場所を開けるが、ターミナルから一発で開きたかった。

## コマンド

```bash
$ find ~/Downloads -type f -newermt "$(date +%Y-%m-%d)" ! -newermt "$(date -v+1d +%Y-%m-%d)"
```

## 考察

ダウンロードではなく、更新があったかどうかを見ている。
ちょっと重いので、findの前に何かして対象を絞りたい。
はじめまして

# はじめまして！
皆様、はじめまして！
2025年の4月1日よりデータエンジニア見習いになりました
古川聖馬と言います！
今後、自主学習したことを記録したり新しい試みをしたりなど
キャリアの動きを記事にしていこうと思ってます

# 過去の経歴
### 1社目 : 株式会社コメリ 副店長
新卒で株式会社コメリというホームセンターを展開している会社に就職しました
私が就活をしていた当時、DXグループを自社で持とうという動きがあり
学生時代、DXに興味があった私はそこに飛びつきました！
が、世の中そううまくはいかず、店舗配属になり希望の部署まで10年以上かかる
と言われたものですからそれはもう我慢ならず半年で転職に踏み切りました笑

### 2社目 : 株式会社アルトナー
2社目に選んだのは株式会社アルトナーというSES企業にエンジニアとして入社しました
データ関連の会社に派遣があったため入社しましたがTOEICの点数に興味を持たれ、
なんと外資系の車のパーツだったり、家電などを扱うBOSCHという会社に派遣されました
こちらの会社は仕事に関するところで言えば、楽しいの半分辛いの半分って感じです
まあ、やりたいことでもなかったしデータを扱うことができる企業はほかにいっぱいあるので
こちらも約2年ほどで区切りをつけました

### 3社目 : 株式会社UncoverTruth -> 現職
現在は株式会社UncoverTruth(以下UT)というところでお世話になっています。
絶賛研修中です！現在はSQLをゴリゴリやっている感じです！
なんとか次の金曜までにSQLはマスターしたいところです...
タグにもありますがゆくゆくはpandasを使って業務効率化を図ったり
統計学的視点からお客様の役に立ちたいのでSQLで立ち止まっている場合ではないのです...
自主学習も積極的にやっていこうとこの度Qiitaを始めたわけです

# まとめ
私はこれからUTで様々なデータに関する技術を身に着け、
やがてデータサイエンティストとして活躍していこうと思っておりますので
日々、勉強を重ねていって日本でも指折りのDSになってみせます！
それでは日々の勉強の記録でまたお会いしましょう！
【準1級】統計学実践ワークブック　第8章　例3　モーメント法

統計検定準1級の勉強のための解説記事となります。下記にご了承いただける方のみ、お読みください。

:::note warn
##### 注意
* 著作権の都合により問題文は掲載せず解説のみの記述となります。
* 独自の解釈により、不適切な表現がある可能性があります。
:::

以下の動画でも解説していますので、見やすいほうでご覧ください。
<iframe width="560" height="315" src="https://www.youtube.com/embed/ybnjgwVVyHk?si=dOxPvmRvMsVM9dRl" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

# 学習のポイント

## モーメント法

**パラメータ** $θ = (θ₁, θ₂, ..., θm)$ をもつ確率分布の確率密度関数を$f(x; θ)$ とする。以下を**中心モーメント**といいます。

$μ₁ := ∫xf(x; θ) dx$ （平均または1次中心モーメント）
$μₖ := ∫(x - μ₁)^k f(x; θ) dx,  k = 2, 3, ...$ （k次中心モーメント）

モーメント法は、**母集団分布の理論的な中心モーメントを、標本から計算される標本平均や標本分散のような推定量で置き換え**、**得られた方程式を解くことによって**、 $\hat{θ}_j$ を導出し、母集団パラメータ$θ_j$の**推定量**として用いる推定方法です。



```plantuml
@startuml
title モーメント法によるパラメータ推定

rectangle "母集団パラメータθ1, θ2, ..., θk" as PopulationParameter
rectangle "中心モーメントμ1, μ2, ..., μk" as PopulationMoment
rectangle "標本データ" as SampleData
rectangle "推定量（標本平均、標本分散）" as SampleMoment



PopulationParameter -down-> PopulationMoment : それぞれのモーメントが\n θ1, θ2, ..., θkの関数として表現される

SampleData -down-> SampleMoment : 観測データから算出

SampleMoment .left.> PopulationMoment : 中心モーメントを推定量で置き換え

PopulationMoment -up-> PopulationParameter : 大きな次数Kまでのモーメントを利用して\nそれぞれのパラメータを解ける

@enduml
```



# 解答

ガンマ分布に独立同一に従う標本 $X_1, X_2, ..., X_n$ から、モーメント法を用いてパラメータ $\alpha$ と $\lambda$ を推定する方法を確認します。

## 1. ガンマ分布の平均と分散

まず、ガンマ分布の中心モーメントを確認します。ガンマ分布の確率密度関数は以下の通りです。

$$ f(x;\alpha, \lambda) = \frac{\lambda^\alpha}{\Gamma(\alpha)} x^{\alpha-1} e^{-\lambda x} \quad (x ≥ 0) $$

ここで、

*   $x$: 確率変数
*   $\alpha$: 形状パラメータ 
*   $\lambda$: 尺度パラメータ 
*   $\Gamma(\alpha)$: ガンマ関数

です。

このガンマ分布の中心モーメントは以下のように表現できます。

*   $μ_1=E(X) = \frac{\alpha}{\lambda}$
*   $μ_2 =V(X) = \frac{\alpha}{\lambda^2}$

## 2. 標本平均と標本分散

次に、標本 $X_1, X_2, ..., X_n$ の標本平均を$\bar{X} $、標本分散を$S$とします。

## 3. モーメント法の適用

母集団のモーメントである$μ_1$を標本平均$\bar{X}$に、 $μ_2$を標本分散$S$で置き換えます。ここで、$\hat{\alpha}$ と $\hat{\lambda}$ はそれぞれ $\alpha$ と $\lambda$ の推定値を表します。



*   $\bar{X}= \frac{\hat{\alpha}}{\hat{\lambda}}$
*   $S= \frac{\hat{\alpha}}{\hat{\lambda}^2}$


上記の連立方程式を $\hat{\alpha}$ と $\hat{\lambda}$ について解くと、モーメント法によるガンマ分布のパラメータ $\alpha$ と $\lambda$ の推定値は以下のようになります。



*   **$\hat{\alpha} = \frac{\bar{X}^2}{S}$**
*   **$\hat{\lambda} = \frac{\bar{X}}{S}$**
GitHub Actionsのデバッグに便利なactの使用方法まとめ

# はじめに
GitHub Actionsを使ったCI/CDフローの開発やデバッグを行う際、GitHubにプッシュするたびにワークフローを実行するのは手間がかかりますよね。 
そんなときに便利なのが、GitHub Actionsをローカルで実行できるツール「[act](https://github.com/nektos/act)」です。  
本記事では、`act`の基本的な使い方をご紹介したいと思います。

# actとは

`act`は、GitHub Actionsのワークフローをローカルで実行できるコマンドラインツールです。  
ローカルで事前にワークフローの動作を検証できるため、開発の効率を大きく向上させることができます。

:::note info
actは仮想環境上にGitHub Actionsの環境を構築する仕組みになっているのでDockerを使用しますが、本記事でのDockerに関するご説明は省いております。
actをインストール前にDocker環境をご準備いただいてからお試しください。
:::

# インストール方法

以下のコマンドでインストール可能です（Homebrewの場合）:

```bash
brew install act
```
その他のインストール方法については、公式リポジトリをご確認ください。
https://github.com/nektos/act

# 基本的な使い方

### 1. ワークフローを定義する

GitHub Actionsの通常の使い方と同様に、`.github/workflows/`配下にYAML形式のワークフロー定義ファイルを作成します。

```yaml
# 例: .github/workflows/test.yml
name: Test

on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Run Tests
        run: echo "Running tests..."
```

### 2. actを実行する
#### 基本の実行例

```bash
act
```

上記コマンドを実行すると、`on`で定義されたイベント（例: `push`）に応じて、該当のジョブが実行されます。

---


#### 特定のイベントを明示的に指定して実行

```bash
act push
```

GitHubに実際にpushしたときと同じ挙動で実行されます。  
他にも以下のように任意のイベント名を指定することができます。

```bash
act pull_request
act workflow_dispatch
```

---

#### 特定のジョブだけを実行

```bash
act -j <ジョブ名>
```

ジョブ名はYAMLファイル内の `jobs` セクションのキーとして定義されている名前（例: build や test など）と一致させる必要があります。

例:

```bash
act -j build
```

---

#### Secretsを読み込んで実行

```bash
act --secret-file .secrets
```

`.secrets`ファイルには、以下のように1行ずつ「KEY=VALUE」形式で記述します。

```text
MY_SECRET=value123
API_KEY=abcdefg
```

---

#### Appleシリコン（M1/M2）環境での実行

Dockerのアーキテクチャを明示的に指定する必要がある場合があります。

```bash
act --container-architecture linux/amd64
```

---

#### ワークフローのイベント一覧を確認

```bash
act -l
```

定義済みのイベントと、それに対応するジョブの一覧を表示します。

# 注意点
- 一部のGitHub公式ActionsがDocker上で動かない場合があります（例: `actions/setup-node`など）。
- `runs-on`の指定に応じたコンテナイメージが自動的に使われますが、必要に応じてカスタムイメージを指定することも可能です。

# さいごに
本記事では、GitHub Actionsのワークフローをローカルで実行できるツール「act」の使い方についてご紹介しました。  
CI/CDの構築やデバッグを効率的に行うための強力なツールなので、ぜひ活用してみてください。

なお、私自身も現在Webアプリ開発の真っ最中で、GitHub Actionsを利用する際にはactを使った検証にかなり助けられています。  
今後もWeb開発に関するTipsをまとめていく予定ですので、興味があればまたご覧ください！
情報処理安全確保支援士になりました

こんにちは。

テックリードのTerukiです。

4月になり情報処理安全確保支援士の登録証が届いたのでその記録です。

https://qiita.com/omt_teruki/items/40252050698c5ebd0941

年末に合格してから割とすぐに登録申請をしています。

登録申請はPDFを印刷して簡易書留で郵送みたいな感じなので結構アナログです。

IPAなら紙は一切使わないみたいなこだわりを持ってほしいなと思わなくはないですが、時間が解決してくれるかなと。

登録されたので名前などが検索できるようになっています。

https://riss.ipa.go.jp/r?r=029815

私は会社名も込みでフルオープンの設定ですが結構柔軟に選択できます。

会社の情報セキュリティを高めるために、日々の開発とは別に動いていきたいと思っています。
二等無人航空機操縦士技能証明について　合格体験記

# はじめに

無人航空機（以降、ドローン）の技能証明制度の開始により、自分の中でもドローンへの関心が高まりまして、「二等無人航空機操縦士技能証明」という資格に合格したのでまとめました。後で見返せるので、こちらに自分用のメモとしても残したいと思います。

# Who am i ?

ドローンは完全に趣味です。アマチュア無線を利用したFPVドローンに関する記事を過去に投稿しています。
ドローンに関する資格ではなく電波に関する資格ですが、第二級アマチュア無線技士や第二級陸上特殊無線技士といった資格も取得しています。

https://qiita.com/forest_moririri/items/46fcbd8ea99e6632336c

# 背景

最近はDJIのドローンのような自動制御装置が搭載されているドローンも安くなってきているようで、性能・操作性だけみても、自作してドローンの構造を理解するよりお金で解決しちゃった方が早かったりするようです。よって、FPVを勉強したい人にとってもアマチュア無線を活用したFPVドローンは必ずしも登竜門的な立ち位置にならない気がしました。結論を言うと、アマチュア無線技士の資格を先に取得した私としては、少々廻り道をしてしまったということです。

ただ、アマチュア無線を活用したドローンは自動制御装置が搭載されていないことが多く、練習用ドローンとして活用することで実際にドローンを操作するスキルは上がると思います。ドローンレース等に活用する以外にもこういった活用方法があるのかと今になって勉強になっているところです。

さて、ドローンの技能証明制度の一つに無人航空機操縦士技能証明というものがあります。今回、私は「二等（基本）」を取得しました。なぜ基本だけなのかというとドローンって勉強してみるとわかるのですが、そもそも一人で飛ばすべきものではなく、複数人で安全を確保しつつ飛ばしていくものだと勝手ながら理解しております。私は今のところビジネスでドローンを活用していこうとは考えておらず、勉強のためということが主だったので別に目視外や夜間といった制限の解除は不要と考えたためです。それに操縦に慣れるのにもある程度時間を要します。アマチュア無線を活用したFPVドローンは100g未満のものがほとんどだと思っており、こちらを操作するにしてもある程度の操作技術の習得は必要ですし、今後趣味でドローンを飛ばすのにも役立てるような資格があったら良いなぁというのが本音です。やはりスティック操作、慣れが要ります。

# 本題

二等無人航空機技能証明（以降、二等）ですが、以下の３つから構成されます。

 - 身体検査
 - 筆記試験
 - 実技試験

最初に技能証明申請者番号を国交省のサイト（DIPS2.0）で申請をする必要があります。
身体検査と筆記試験はClassNKというサイトから個別に申し込む必要があります。
実技試験のみスクールに通うことで免除される仕組みです。

私はスクールに通ったため、実技試験は免除されました。筆記の勉強もある程度並行してやっておくと楽だったりします。二等の場合、身体検査は運転免許証があれば、その結果を使うことができますし、筆記試験については市販の参考書が売っているので、それを使って事前に勉強しておくことが可能です。

実は二等以外に一等無人航空機操縦士技能証明（以降、一等）もあるのですが、スクールに通うことが前提の場合、最初に二等を取得しないと一等の講習を受けることができないように設定されているようです。なので、二等はある種の登竜門的な立ち位置にもなっています。

ちょっとスクールについて簡単に補足させて頂くと、私が通っていたスクールは二等のカリキュラムは５回の講習があり、そのうちの１回はドローンの安全点検に主を置いた学習で、３回がスティック操作の学習、最後の１回は試験のリハーサルといった感じでした。５回目のリハーサルで、ある一定以上の基準を上回ると修了審査をうけることができます。これに合格すると実技試験合格の扱いになるといった感じです。なお、講習が４回目まで進むと学科のオンデマンド講習を受講することができるのですが、学科についてはこれだけで他は各自の自習に委ねるといった感じです。スティック操作の学習や学科の講習いずれにしも、自習が主の体系でしたので、「スクールに行けば何とかしてくれる」といった心構えは避けておいた方が良いと思います。

あとドローンを持っていない場合は、スクールに通う際、購入を検討しても良いかと思います。二等（基本）の講習の費用だけで２０万～３０万近くかかってしまうことが多いとのことなので、ドローンを購入すると最低でも１０万近く上のせされる感じになります。ドローンの種類によっては５０万～６０万近くするものもあるので、ある程度お財布と相談が必要です。ドローンをスクールで購入すると、ヨドバシカメラなどの家電量販店よりも安く購入できる他、スクールの会場を練習用に開放してくれるサービスもあるので、そういった点は良いですね。

すべての試験に合格後は、試験合格証明書というのをClassNKで申請して、講習修了証明書と試験合格証明書をDIPS2.0経由で提出することで、二等のライセンスを取得することができます。申請にお金がかかるので、こちらも覚えておくとよいかもしれません。

# 最後に

一等の範囲については操縦士免許とも言われるくらいで（カテゴリーⅢ飛行等で）必須になってきていますが、二等については任意ですので、今後の法改正なんかにも注目してよいかと思います。
【C#】System.Drawing.Imaging.ImageFormat に WebP 形式を見つけたけど動かなくてもやった話

# はじめに

最近は WebP 画像形式 ([Wikipedia](https://ja.wikipedia.org/wiki/WebP)) をよく目にするようになりました。ファイルサイズが比較的小さく、透過度も持てるため使いやすいです。  
しかしながら比較的新しい画像形式なので、C# 標準ライブラリ [`System.Drawing.Bitmap クラス`](https://learn.microsoft.com/ja-jp/dotnet/api/system.drawing.bitmap?view=windowsdesktop-9.0&viewFallbackFrom=net-10.0)では扱えなかったりします。

[WPF の BitmapImage](https://learn.microsoft.com/ja-jp/dotnet/desktop/wpf/graphics-multimedia/how-to-use-a-bitmapimage?view=netframeworkdesktop-4.8&viewFallbackFrom=netdesktop-9.0) を使ったり、サードパーティのライブラリを使う方法があります。

ImageProcessor.Plugins.WebP の紹介記事  
<https://qiita.com/visyeii/items/9320b0d08e6b132c6541>

先日 [`System.Drawing.Imaging.ImageFormat.Webp プロパティ`](https://learn.microsoft.com/ja-jp/dotnet/api/system.drawing.imaging.imageformat.webp?view=windowsdesktop-9.0#system-drawing-imaging-imageformat-webp) を見つけました。もしかしたら `Bitmap` でいけるんじゃね？ と思ったのですが、いけなかったので備忘録を書こうと思います。

## エラーの詳細

[`System.Drawing.Imaging.ImageFormat.Webp プロパティ`](https://learn.microsoft.com/ja-jp/dotnet/api/system.drawing.imaging.imageformat.webp?view=windowsdesktop-9.0#system-drawing-imaging-imageformat-webp)

> この形式は、Windows 10 1809 以降でサポートされています。  
> Windows Desktop バージョン: 7, 8, 9

```cs
using var bitmap = new System.Drawing.Bitmap(10, 10);
using var stream = new MemoryStream();

// CA1416 警告: この呼び出しサイトは 'Windows' 7.0 以降 で到達可能です。
// 'ImageFormat.Webp' は 'windows' 10.0.17763.0 以降 でのみサポートされています。
bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Webp);
```

```text
System.ArgumentNullException :
    Value cannot be null. (Parameter 'encoder')
スタック トレース:
    at System.Drawing.CoreImageExtensions.Save(
        IImage image,
        Stream stream,
        Guid encoder,
        Guid format,
        EncoderParameters* encoderParameters
    )
    at System.Drawing.Image.Save(
        Stream stream,
        ImageFormat format
    )
```

- 実行環境は Windows11 なので要件を満たしていると思うのですが、動きません
- `エンコーダーがないよ` エラーが出ます
- おま環なのかもしれません。よくわかりません

## おわりに

`Bitmap` 関係は .NET のアセンブリではなく WindowsDesktop のアセンブリに含まれています。  
C# チーム的には画像はサードパーティのライブラリを使ってね、という方針なんでしょう。  
コーデックとかは、ものによってはライセンス的にあれで保守のコストが高い等の事情があるかもしれませんし。
Claude Desktop経由でSlack MCP遊んでみた

# はじめに
昨今話題のMCPサーバーですが、slack MCPがあるとのことで、遊んでみました。
社内のslackに導入できるかは正直怪しいですが、かなり業務効率向上も目指せるので、これからが楽しみです。

# Slack MCPとは
Slack MCP（Model Context Protocol）は、AIアシスタントとSlackワークスペースを連携させるための仕組みです。MCPはAnthropic社が提唱したプロトコルで、AIアプリケーションと外部サービス（SlackやGitHubなど）のAPIを標準化された方法で操作できるようにします。これにより、AIが自然言語で指示を受けて外部サービスを効率的に操作できるようになります

# 何ができるのか
主に下記のようなことができます。
- チャンネル内の会話履歴を参照
- 特定のトピックに関する過去の議論を要約
- メッセージの送信や返信
- チャンネルの作成や管理
- 過去のslackの履歴から、チーム内の知識やノウハウの抽出

私が所属している組織では、サービス規模が大きいため、詳細な仕様書が存在していません。その辺がslackに散らばっているので、ぜひ**過去のslackの履歴から、チーム内の知識やノウハウの抽出**が、非常に魅力的に見えました。

# 設定方法
[こちら](https://github.com/modelcontextprotocol/servers/tree/main/src/slack)の公式ドキュメントか、[【MCPのトリセツ #7】Slack MCPサーバー：チームコミュニケーションを強化](https://zenn.dev/takna/articles/mcp-server-tutorial-07-slack)が非常にわかりやすかったのでぜひ！！

# 実際に遊んでみた
## チャンネルに送信
私宛に「調子はどう？」と聞いてと依頼
![スクリーンショット 2025-04-06 19.05.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699265/fbad0e89-a26f-4735-8a89-78db53911649.png)

1度目の依頼は、チャンネルに参加していないので、別チャンネルに送りますという暴れ具合、、
これ社用のslackでこんな事やられたら、非常に困る。。


参加させて2度目の挑戦は正しく飛んできた！
![スクリーンショット 2025-04-06 19.08.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699265/0f99c4a2-b280-4a26-a7d6-a105d86e9153.png)

## チャンネルの情報を読ませる
私が3週間ほど前に、とあるチャンネルでマネージャーの教科書についてアウトプットしました。
![スクリーンショット 2025-04-06 19.17.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699265/e3e6d6d8-4d3a-4fe1-8eb4-43fbe511d082.png)
詳細な部分まで取得できるのか気になるので、「自己効力感について、アウトプットしていたのは誰ですか？」と聞いてみます。（期待値はyamaki.kaito）
![スクリーンショット 2025-04-06 19.21.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699265/c2f54f10-2686-4b18-beb7-7bb05bdcecfc.png)
見つけられないのかい。。残念。

slackのチャンネルを絞って、なおかつスレッド内にあることも加えて再度聞いてみます。
「もくもくアウトプット」チャンネルで自己効力感について、アウトプットしていたのは誰ですか？スレッド内の可能性もあります。」
![スクリーンショット 2025-04-06 19.24.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699265/d93ee2fb-241e-40a2-82f1-b29c4f87cc45.png)
見つけてくれました！！
なるほど、スレッド内を追う場合は異なる処理（slack_get_thread_replies）が走るので、明示的に伝えてあげないと難しそうですね。

# 使ってみての感想
正直、社内slackへの導入は難しいかも？という所感です。今回試したチャンネルは、今年から始動しているかつ、参加メンバーも少ないので投稿数も多くありません。それでも結構な時間（対話+プロンプト+処理時間）がかかっているので、もう少しタイパ・精度が良くなったら再度使ってみたいなと思いました。
【CSS】CSSだけで作るカルーセル

## はじめに
みなさんはカルーセルを作りたいと思ったことはありますか？

今までは、ライブラリーを使ったりしても、アクセシビリティの担保ができてなかったり、
少し複雑なJSを書かなくちゃいけなかったりと、カルーセルを自作するのは大変でした。

しかし、Chrome 135 以降では、[CSS Overflow Module Level 5](https://drafts.csswg.org/css-overflow-5/) が適応され、CSSだけで、カルーセルが作れるようになりました。

そのため、この記事では、CSSだけでカルーセルを作る方法を紹介しようと思います。

## CSSだけで作るカルーセル

### カルーセルのコンテナを作る
まずは、このようにカルーセルのコンテナをつくります。

```html
<ul class="carousel">
  <li class="carousel-item">1</li>
  <li class="carousel-item">2</li>
  <li class="carousel-item">3</li>
  <li class="carousel-item">4</li>
  <li class="carousel-item">5</li>
</ul>
```

```css
.carousel {
  overflow-x: auto;
  scroll-snap-type: x mandatory;

  /* スタイル調整 */
  display: flex;
  gap: 16px;
  width: 250px;
  margin: 0px;
  padding: 16px 0px;
}

.carousel-item {
  scroll-snap-align: center;

  /* スタイル調整 */
  height: 100px;
  width: 200px;
  flex-shrink: 0;
}
```

コンテナに　`display: flex;` を指定して横並びにします。
そして、`overflow-x: auto;` を指定して、横スクロールできるようにしてます。
スクロールが変な位置で止まらないように、`scroll-snap-type: x mandatory;` を指定します。

また、itemに `flex-shrink: 0;`を指定して、itemが縮まないようにして、
`scroll-snap-align: center;` で、コンテナの中央で止まるように調整しています。


### スクロール用のボタンを追加する

カルーセルをスクロールさせるためのボタンを `::scroll-button()` 疑似要素を使って作成します。

`::scroll-button()` は、　`::scroll-button(方向)` でスクロール方向を指定します。

```css
.carousel {
  /* ... */

  &::scroll-button(left) {
    content: "←" / "Scroll Left";
  }
  
  &::scroll-button(right) {
    content: "→" / "Scroll Right";
  }
}
```

`::scroll-button()` 疑似要素で、`content: "←" / "Scroll Left";`を指定することで、
roleが`button`で、nameが`Scroll Left`が追加されます。

### スクロールマーカーを追加する
次は、カルーセルの下によくあるマーカーを追加していきます。

```css
.carousel {
  /* ... */
  
  scroll-marker-group: after;

  &::scroll-marker-group {
  /* マーカーグループのスタイル　*/
  }
}

.carousel-item {
  /* ... */

  &::scroll-marker {
      /* マーカーのスタイル　*/
  }
  
  &::scroll-marker:target-current {
      /* ターゲットの当たっているマーカーのスタイル　*/
  }
}
```

スクロールマーカーを追加するには、コンテナー要素に`scroll-marker-group`を指定する必要があります。
`scroll-marker-group`は、`before`と`after`の値を指定でき、表示させる位置を指定します。

そして、スクロールマーカーグループにスタイルを当てるには、`&::scroll-marker-group`疑似要素を使うことで指定することができます。

また、個別のマーカーにスタイルを当てるには、`&::scroll-marker` 疑似要素を使うことで指定することができます。

### 完成系
お好みのスタイルに調整したら完成です！

<p class="codepen" data-height="400" data-default-tab="result" data-slug-hash="bNGJVem" data-pen-title="CSS Only Carousel" data-editable="true" data-user="degudegu2510" style="height: 400px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/degudegu2510/pen/bNGJVem">
  CSS Only Carousel</a> by degudegu2510 | Qiita (<a href="https://codepen.io/degudegu2510">@degudegu2510</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://public.codepenassets.com/embed/index.js"></script>

## まとめ

この記事では、CSSで作るカルーセルを作る方法を紹介しました。
ぜひこの記事を参考に、カルーセルを作ってみてください

---
最後まで読んでくださってありがとうございます！

普段はデザインやフロントエンドを中心にQiitaに記事を投稿しているので、ぜひQiitaのフォローとX(Twitter)のフォローをお願いします。

https://twitter.com/degudegu2510
【Tableau】画像埋め込み対応版 Export All のご紹介

## 背景と目的

Tableauユーザーのみなさま
どうもこんにちは٩( ᐛ )و

突然ですが、拡張機能「Export All」をご存じでしょうか？

https://exchange.tableau.com/ja-JP/products/25

この拡張機能を使えば、Excelファイルで複数のシートを一括ダウンロードできるため、大変便利ですよね！

しかし、ダッシュボード内に埋め込んだ画像をそのままExcelへ出力したい場合、既存のExportAllでは [Tableau上で画像化](https://help.tableau.com/current/pro/desktop/ja-jp/image_role.htm) していたとしてもURL文字列のままエクスポートされてしまいます。

もちろん、ダウンロードしたExcelファイル上でIMAGE関数やマクロを用いて画像を表示させることも可能です。
とはいえ、作業工程が増えて運用の手間になることもしばしばです。。

そこで、特定のカラムについて「**Excelに画像を埋め込んだ状態でエクスポートする**」機能を追加したFork版を作成しました🎉

## Fork版リポジトリ

https://github.com/iisyos/Tableau-Extension-ExportAll

これを用いればURL文字列での出力にとどまらず、実際にセルに画像として配置されることで、エクスポート後の編集を省き、よりスムーズなレポート運用を実現できます。


## 導入方法

1. **trexファイルのダウンロード**
Fork版はTableau MarketPlaceには公開していないため、GitHubリポジトリから直接ダウンロードします。
→ [ExportAll.trex](https://github.com/iisyos/Tableau-Extension-ExportAll/blob/main/ExportAll.trex)
    
2. **拡張機能の設定**
Tableauでダッシュボードに拡張機能を追加する際、拡張機能URLに以下を指定します：
`https://bucolic−sundae−b29dc2.netlify.app`
その後、ダッシュボードに 1. でダウンロードした`.trex`を指定します。

:::note info
上記URLは私がNetlifyにホスティングしているものとなります。
ご自身でホスティングすることも可能です。
[2. ホスティング環境](#2-ホスティング環境)
:::

## 使い方

基本的な使い方は本家Export Allと同じですが、「SelectColumns」タブに「Is Image」というチェックボックスを追加しています。

![スクリーンショット 2025-04-06 17.57.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759541/44993520-70d5-4f59-a07d-14374f5491bb.png)

このチェックボックスをオンにすると、該当するカラムはExcel出力時に画像として挿入されます。↓

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759541/4c06ae70-57a5-48a1-acbd-fff191340f21.png" width=300 />

チェックを入れなければ従来通りURL文字列として出力されるため、既存のワークフローを崩すことなく利用できます！

## 技術的な要素

### 1. ExcelJSの導入
    
画像をExcelに直接埋め込むために、Node.js用のライブラリ`ExcelJS`を採用しています。本家で用いられている`xlsx`ライブラリでは画像埋め込みができないため、Fork版では`ExcelJS`に切り替えました。
    
なお、`ExcelJS`には潜在的なバグがあるらしいので、特定のケースで予期せぬ動作をする可能性があります。
その場合はIssueにて報告いただけますと◎

https://qiita.com/nakahara-d/items/2506f90ce8081445b509
    
### 2. ホスティング環境
    
Fork版の拡張機能はNetlify上でホスティングしています。
    
当初は本家同様にVercelを検討しましたが、VercelではNodeのバージョンが`18.x`系以上しか選択出来ず、本家ExportAll（おそらく`14.x`〜`16.x`系）との互換性が問題となった経緯があります。
    
ご自身でホスティングしたい場合は、**リポジトリをForkしたうえで `npm run release` を実行し、生成されるbuildディレクトリを配信してください**

その場合、`.trex`ファイルのurlディレクティブをご自身の配信ドメインに変更することをお忘れなく ;)
    
### 3. **CORSの設定**
    
画像を読み込むためにJavaScriptの `fetch` APIを使用しているので、画像を配信するサーバー側でCORSを行う必要があります。


## まとめ・考察

ExportAllは非常に便利な拡張機能ですが、クロス集計に対応していないのが唯一の難点であり、このFork版でも同様です。

一度自身で実装を試みたのですが、Tableau Extensions APIがクロス集計に向けたAPIを提供していない都合上、自身でセルを取得しそれを整形する必要がありました。
その結果、ワークブック毎に独自実装が多くなり、汎用的にすることはなかなか難しかったです。

https://tableau.github.io/extensions-api/api/globals.html

ま、ま、まぁ実装できなくはなくはないですが、この余白はそれを書くには狭すぎるということで・・・。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759541/31840f79-89c0-4df8-b05a-4897da36310c.png)
Cursorのエラー解決備忘録

# 問題の発生
Cursorで開発を行っていたところ、突然以下のメッセージが表示されるように
```
Our servers are currently overloaded for non-pro users, and you've used your free quota.
Please try again in a few minutes.
if you think this is a mistake, please contact hi@cursor.sh
```
しかし無料アカウントだった為、一旦時間をおいてみることに。
...2日経ったがまだエラーが発生する。

さすがにおかしい。
ということで調べてみる。

# 対処法
https://forum.cursor.com/t/i-get-error-for-servers-overloaded-for-non-pro-users-even-though-i-am-already-pro-user/29977

このフォーラムがヒットした。
フォーラム方はプロユーザーということで、自分とは環境が違うが、上記対応で解決した。

以下手順
1. `cmd + shift + j` で設定を開く
1. 一度ログインしているアカウントをログアウトする
1. 再度ログインし直す

# 最後に
無料だったとしても、何か発生したら、とりあえずフォーラムを調べるのがベスト
GitHub リポジトリと Cloudflare Pages を連携し、Next.js アプリのCI/CDパイプラインを構築

## 記事の経緯
内容はネット上によくありますが、
GitHub経由でホスティングするしない方法と混同してつまづいたので備忘。

## 順番
1. Next.JSでアプリをつくる。
(GitHub Flavored Markdown Specにもとづいてマークダウンチェックしてくれるアプリを作りました。)
2. buildできるような状態にして、
```npm install --save--dev @opennextjs/cloudflare```コマンドする。（ここもしかしたらいらないかも）
3. GitHubでリポジトリにPUSHする。
4. CloudflareのWorkers&Pagesページの新規作成から、GitHubリポジトリを選択して作成。(この辺は内容割愛。）
5. 一回deployして、エラーが出るので、Settingsから
 - Variables and Secretsで実際のプロジェクトのNODE_VERSIONを設定。
 （自分は20でした）
 - Compatibillity flagsを```nodejs_compat```を入力して登録。
 プルダウンで```nodejs_compat_populate_process_env```と
 ```nodejs_compat_do_not_populate_process_env```しか出てこなくてないやん、入力できんやん！で困った。（確かに最初入力できんかった気がするのだが、、）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2724581/fa9e900c-2a83-4d45-b902-d1a144f82303.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2724581/7c2ec5a3-2f08-478e-80ff-beb3017fbe42.png)

## おわりに
公式ドキュメントをだいぶ読んだので、いい経験になった。
markdownの書き方を理解したい。
これで再現性のないAIパワープレイホスティングでなくていろいろホスティングできるぞ。


## 参考にさせていただいた記事
https://uhiyama-lab.com/blog/webdev/nextjs-cloudflare-custom-domain/

### Cloudflare公式ドキュメント
https://developers.cloudflare.com/pages/framework-guides/nextjs/deploy-a-static-nextjs-site/

https://developers.cloudflare.com/workers/runtime-apis/nodejs/

compatibilityのとこ

https://developers.cloudflare.com/workers/configuration/compatibility-flags/
Angular 構造ディレクティブについて

# Angularの構造ディレクティブとは
Angular の**構造ディレクティブ**は、HTML の構造を変更するためのディレクティブである。要素を追加・削除したり、条件に応じて表示を切り替えたりする際に使われる。

構造はHTMLの構造のことで、そのHTMLの構造に対してディレクティブ(命令、変更)するということ。

# 代表的な構造ディレクティブ
| ディレクティブ | 説明 |
|----------------|------|
| `*ngIf`        | 条件が `true` のときだけ要素を表示する |
| `*ngFor`       | リストなどの配列を繰り返して要素を表示する |
| `*ngSwitch`    | 複数のケースに応じて要素を切り替える |

# 使用例

- `*ngIf`
``` html
<div *ngIf="isLoggedIn">ようこそ！</div>
```
`isLoggedIn` が true のときだけ表示される。

- `*ngFor`
``` html
<ul>
  <li *ngFor="let item of items">{{ item }}</li>
</ul>
```
`items` 配列の中身を繰り返してリストにする。
`items = ['りんご', 'バナナ', 'みかん']` の場合、以下のようなコードとなる。
``` html
<ul>
  <li>りんご</li>
  <li>バナナ</li>
  <li>みかん</li>
</ul>
```

- `*ngSwitch`
``` html
<div [ngSwitch]="fruit">
  <p *ngSwitchCase="'apple'">りんごです</p>
  <p *ngSwitchCase="'banana'">バナナです</p>
  <p *ngSwitchDefault>他の果物です</p>
</div>
```
`fruit === 'apple'` のとき "りんごです" が出力される。

# 補足：なぜ * を使うのか
`*` は「構造ディレクティブの糖衣構文(コードを見やすくする構文)」で、Angular が裏で `<ng-template>` に変換して扱っている。

たとえば
``` html
<div *ngIf="isVisible">Hello World!!</div>
```
は、実際にはこう変換される↓
``` html
<ng-template [ngIf]="isVisible">
  <div>Hello World!!</div>
</ng-template>
```

# まとめ
- 構造ディレクティブは HTML 構造を制御する

- `*ngIf`, `*ngFor`, `*ngSwitch` が代表例

- `*`は裏でテンプレート構文を生成している
MCPサーバーを開発環境に導入してみる

# 初めに

https://qiita.com/youtoy/items/adfeedeedf1309f194ce

こちらの記事を見て、筆者は思いました。
これ、VscodeのSettingで設定しているということは、Devcontainerに突っ込めるんじゃね？
→意外と簡単に行けたので、せっかくなので記事にしてみました。


# MCPサーバーとは
筆者の理解では、AIからAPIをたたくためのプロトコルです(間違ってたらすみません)
→MCPを使うことでいろいろなAPIを実行することができます(あら便利)

https://zenn.dev/tomo0108/articles/6b472b4c9cacfa

# VScodeでMCPサーバーを動かす方法
setting.jsonに記載すればよいそうです。詳細は以下の記事をご確認ください。

https://qiita.com/youtoy/items/adfeedeedf1309f194ce

setting.jsonにこんな感じで追記すればよいです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780680/cdab5b5f-cb3f-41d2-a32f-b59d13aa6589.png)

# devcontainerで動かす
setting.jsonにかけるのであれば、devcontainer.jsonのsettingに追記してしまえばよいのです。

```jsonc:devcontainer.json
{
  "name": "mcp",
  "build": {
    "dockerfile": "Dockerfile" // 相対パス表記
  },
  // VScodeの設定
  "customizations": {
    "vscode": {
      // 拡張機能のインストール
      "extensions": [],
      // setting.jsonの設定
      "settings": {
        "mcp": {
          "inputs": [],
          "servers": {
            "file_server": {
              "command": "npx",
              "args": [
                "-y",
                "@modelcontextprotocol/server-filesystem",
                "/workdir",
                "/workspaces/mcp_test"
              ],
              "env": {}
            }
          }
        }
      }
    }
  }
}
```

とはいっても、これだけだと動かないので、dockerfileにnpmと必要なmcpサーバーをインストールします。aptで入れていますが、もう少しいい方法ないかなぁ。
今回はとりあえず、server-filesystemを入れています

```dockerfile:Dockerfile
FROM python
USER root

######################
# MCPサーバーのインストール
WORKDIR /workdir
RUN apt -y update && apt -y upgrade && apt -y install npm
# ファイル操作用のモジュールをインストール
RUN npm install @modelcontextprotocol/server-filesystem
######################
```

# 利用するとき

Copilotでエージェントモードをで利用してください(もしかすると何かしら契約いるかも)。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780680/7132525d-7b0e-443c-bf98-43dd3b2e2830.png)


利用するのサーバーの機能は、右下の工具マークから選択できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780680/5b5aeaff-0f6b-4565-942b-d60ca2713678.png)

使ってみると、こんな感じ。うまくいった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780680/c422ca4b-6146-4cc8-969a-6d11ef450615.png)

# 終わりに
今回は、server-filesystemを使っていますが、ほかにもいろんなMCPサーバーがあるのでいろいろ試してみると面白いかもです。

今回作ったものは、gitにも上げているので興味があれば試してみてください。

https://github.com/togra1997/mcp_devenv
【ROS】fatal error: sdf/sdf.hh: そのようなファイルやディレクトリはありません を解決した話


# はじめに

現在研究で使用しているROSパッケージで，突然ビルドが通らなくなり，以下のようなエラーメッセージが出てしまいました．

```bash
(略)

________________________________________________________________________________________________________________________________________________________
Errors     << seed_r7_gazebo:make /home/[PC名]/catkin_ws/logs/seed_r7_gazebo/build.make.038.log                                                                                                                                                                                                                              
In file included from /usr/lib/x86_64-linux-gnu/pkgconfig/../../../include/gazebo-11/gazebo/common/common.hh:8,
                 from /home/[PC名]/catkin_ws/src/seed-r7-for-ros-noetic/seed_r7_gazebo/src/gazebo_ros_planar_move.h:37,
                 from /home/[PC名]/catkin_ws/src/seed-r7-for-ros-noetic/seed_r7_gazebo/src/gazebo_ros_planar_move.cpp:29:
/usr/lib/x86_64-linux-gnu/pkgconfig/../../../include/gazebo-11/gazebo/common/Battery.hh:25:10: fatal error: sdf/sdf.hh: そのようなファイルやディレクトリはありません
   25 | #include "sdf/sdf.hh"
      |          ^~~~~~~~~~~~

(略)
```

```sdf/sdf.hh: そのようなファイルやディレクトリはありません``` というエラーメッセージが出ていました．

# 環境

- Ubuntu20:04
- ROS1 noetic
- gazebo 11.15.1

今回使用したパッケージはSeed noidというロボットを動かすためのものです

https://github.com/seed-solutions/seed_r7_ros_pkg

# 結論

解決方法を知りたい人向けに，先に結論だけ．
エラーが出たパッケージの```CMakeLists.txt```に以下の文を追加することで解決しました．

```cmake
find_package(PkgConfig REQUIRED)
pkg_check_modules(SDF REQUIRED sdformat11)

include_directories(${SDF_INCLUDE_DIRS})
```

追加した位置は以下の通りです．

```diff
（略）

find_package(catkin REQUIRED COMPONENTS
  gazebo_ros
  gazebo_plugins
)

+ find_package(PkgConfig REQUIRED)
+ pkg_check_modules(SDF REQUIRED sdformat11)

+ include_directories(${SDF_INCLUDE_DIRS})

catkin_package()

（略）
```

# 解決法

Chat GPTに解決方法を聞いたところ，CMakeに ```sdformat``` ライブラリのインクルードパスが正しく設定されていないため，この問題が発生しているとのことなので，CMakeLists.txt にこれを追記することとしました．

まず，そもそもPC内に```sdf.hh```が存在することを確認するために，端末で```loacte```コマンドを使用して確認しました．

```bash
[PC名]:~$ locate sdf.hh
/usr/include/ignition/sdformat11/sdf/sdf.hh
/usr/include/sdformat-9.10/sdf/sdf.hh
```

より，PC内に存在することが確認できました．
そこで，```find_package(sdformat REQUIRED)```を CMakeLists.txt に追記したのですが，うまく行きませんでした．（```sdformatConfig.cmake```が見つからないことによるエラーが出てしまいました．）

そこで，```pkg-config```を使用して追加する方法を利用しました．```locate```コマンドで```sdformat11.pc```が存在することを確認し，CMakeLists.txt に ```pkg_check_modules(SDF REQUIRED sdformat11)``` を追記したところエラーがでなくなりました．

```bash
[PC名]:~$ locate sdformat11.pc
/usr/lib/x86_64-linux-gnu/pkgconfig/sdformat11.pc
```

# おわりに

大した話ではないのですが，ROSの日本語の情報は少ないので，共有することにしました．
しかし，ROS1は2025年内にサポートが終了してしまうので，あまり需要のない話だったかもしれません．
とはいえ，ロボットに組み込まれているシステムである場合，なかなかROS2に乗り換えるのは大変だと思いますので，なんだかんだまだまだROS1を使う人はいるのでしょう ~~（私みたいに）~~ ．
[Power BI]「複製」と「参照」の違いを整理してみた

Power BIでモデリングを行っていると、「ファクトテーブルからディメンションテーブルを作りたい！」という場面、ありますよね。  
そんなとき、**Power Queryで「複製」するべきか「参照」するべきか**、迷ったことはありませんか？

私自身、どちらを選ぶべきか判断に悩んだので、整理してみました。

![複製と参照.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987347/09825290-56bb-4045-8381-be63907c2068.png)

---

## 🧪 今回の検証の前提

- 元になるのはファクトテーブル（たとえば、売上データ）
- そこから、ディメンションテーブル（たとえば、商品一覧）を作成したい
- Power Query上で「複製」または「参照」を使ってテーブルを作成する

---

## 💡 「複製」と「参照」の違い

| 操作 | 内容 |
|------|------|
| **複製** | 元テーブルの**ステップをそのままコピー**する。以降は**別の独立したテーブル**として動く。 |
| **参照** | 元テーブルの**現在の状態を参照**する形で新しいステップが追加される。元テーブルと**つながった関係**になる。 |

---

## 🔍 実際に検証してみた

元のファクトテーブルにあたるコピー元テーブル「特定のカテゴリでフィルターをかける」というステップをあとから追加してみました。  
そのとき、ディメンションテーブルにあたる複製／参照で作ったテーブルがどうなるかを見てみると、以下の結果に。

| 方法 | 結果 |
|------|------|
| **複製** | フィルター処理は**反映されない**。複製元とは**別物**として動く。 |
| **参照** | フィルター処理は**反映される**。参照元と**つながっている**ため。 |

### 元テーブルフィルター前の複製・参照テーブル
![複製_フィルター前.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987347/3715ca0c-633c-41d7-83e4-0ba247606f4a.png)
![参照_フィルター前.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987347/d3df04c6-7651-4694-8404-cf0d5d790b9b.png)

### 元テーブルフィルター操作
![元テーブル_フィルター.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987347/f8f08c7c-9e35-4d5d-afc3-eaaec432be7a.png)

### 元テーブルフィルター後の複製・参照テーブル
![複製_フィルター後.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987347/4a2c866a-70ab-4d94-8701-3c54ef360fb5.png)
![参照_フィルター後.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987347/81701132-76ee-4062-a44c-ae7d35ffa2fc.png)

---

## ✅ まとめ

| 項目 | 複製 | 参照 |
|------|------|------|
| 元テーブルの影響を受けるか | 受けない | 受ける |
| 安定性 | 高い | 低い（依存関係がある） |
| おすすめ | ✅ | △ 要件次第 |

Power BIのモデル設計では、**依存関係を意識する**ことが非常に重要です。  
参照でテーブルを作ると、**元のステップが変わるたびに影響を受ける**ので、管理が煩雑になる可能性もあります。

**特にディメンションテーブルのように「安定した構造」が求められる場合は、複製のほうが無難**です。

---

## ✏️ おわりに

ファクトテーブルからディメンションテーブルを作る方法はさまざまですが、「複製」と「参照」の挙動を理解して使い分けることが大切です。

同じように悩んでいた方の参考になれば嬉しいです！  
よければLGTM＆フォローよろしくお願いします🙌

---
GitにおいてTagを使ってみよう！！

# GitでTagを使ってみよう！！
Gitのコミットはそれぞれハッシュ値を持っていますが、長い英数字の羅列ではどのコミットを示しているのか分かりづらく、コマンドに指定するのも大変です。そこでタグを使うと、コミットに分かりやすい名前（v1.0やRelease1など）を付けられ、重要なポイントを簡単に識別できるようになります。

## タグの種類
Gitのタグには主に3種類あります：

1. **軽量タグ（Lightweight Tag）**
   - 単純にコミットへのポインタ
   - コミットのハッシュ値に名前をつけるだけの簡易なもの
   - 追加情報は保存されない
   - ローカルでの一時的な目印に適している

2. **注釈付きタグ（Annotated Tag）**
   - Git内部に完全なオブジェクトとして保存される
   - タグ作成者の情報、日付、メッセージなどのメタデータを含む
   - リリースバージョンなど公式なマーキングに推奨される

3. **署名付きタグ（Signed Tag）**
   - 注釈付きタグにGPG署名を追加したもの
   - タグの作成者の身元を暗号学的に検証できる
   - タグが改ざんされていないことを保証
   - セキュリティが重要なプロジェクトで使用される

## タグの作成方法

### 軽量タグの作成
```
git tag <タグ名>
```

例：
```
git tag v1.0.0
```

### 注釈付きタグの作成
```
git tag -a <タグ名> -m "<タグのメッセージ>"
```

例：
```
git tag -a v1.0.0 -m "バージョン1.0.0をリリース"
```

### 署名付きタグの作成
```
git tag -s <タグ名> -m "<タグのメッセージ>"
```

例：
```
git tag -s v1.0.0 -m "バージョン1.0.0の署名付きリリース"
```

注意: 署名付きタグを使用するには、事前にGPGキーの設定が必要です。

### 過去のコミットにタグを付ける
```
git tag <タグ名> <コミットのハッシュ値>
```

または注釈付き/署名付きタグの場合：
```
git tag -a/-s <タグ名> <コミットのハッシュ値> -m "<タグのメッセージ>"
```

例：
```
git tag -a v0.9.0 a87f54e -m "バージョン0.9.0"
```

## タグの表示と確認

### タグの一覧表示
```
git tag
```

パターンに一致するタグだけを表示：
```
git tag -l "v1.8.*"
```

### タグの詳細情報を表示
ハッシュ値を用いて`show`コマンドを利用したときと同じ結果が出ます．
```
git show <タグ名>
```

例：
```
git show v1.0.0
```

### 署名付きタグの検証
```
git tag -v <タグ名>
```

例：
```
git tag -v v1.0.0
```

## タグの共有とリモートでの操作

### タグをリモートにプッシュ
特定のタグをプッシュ：
```
git push origin <タグ名>
```

すべてのタグをプッシュ：
```
git push origin --tags
```

### リモートのタグを取得
```
git fetch --tags
```

## タグの削除

### ローカルのタグを削除
```
git tag -d <タグ名>
```

### リモートのタグを削除
```
git push origin --delete <タグ名>
```
または：
```
git push origin :refs/tags/<タグ名>
```

## タグをチェックアウト
特定のタグをチェックアウトして、そのバージョンのコードを見る：
```
git checkout <タグ名>
```

タグからブランチを作成してチェックアウト：
```
git checkout -b <ブランチ名> <タグ名>
```

## 署名付きタグの設定と利用

### GPGキーの設定
署名付きタグを使用するには、まずGPGキーを生成し、Gitに登録する必要があります：

1. GPGキーの生成（まだ持っていない場合）：
```
gpg --gen-key
```

2. キーのリスト表示と確認：
```
gpg --list-secret-keys --keyid-format LONG
```

3. Gitにキーを登録：
```
git config --global user.signingkey <GPGキーID>
```

### 署名の検証
チームメンバーが署名を検証するためには、作成者の公開鍵をインポートする必要があります：

1. 公開鍵をエクスポート（キーの作成者）：
```
gpg --armor --export <メールアドレス> > public-key.asc
```

2. 公開鍵をインポート（検証者）：
```
gpg --import public-key.asc
```

3. タグの検証：
```
git tag -v <タグ名>
```

## タグの利用ケース

- **リリースバージョンのマーキング**：製品の公式リリース（v1.0、v2.0など）を明確に識別
- **マイルストーンの記録**：プロジェクトの重要な段階を記録
- **バグ修正ポイントの識別**：特定のバグが修正されたコミットをマーク
- **セキュリティ更新の保証**：署名付きタグを使って、セキュリティ更新の信頼性を保証
- **ドキュメントのバージョン管理**：ドキュメントの特定バージョンを参照可能に

## タグの種類の選び方

- **軽量タグ**：一時的な作業や個人的な参照用
- **注釈付きタグ**：チーム内での共有や公式リリースに
- **署名付きタグ**：セキュリティが重要な場合や、配布されるコードの信頼性保証に

タグを効果的に活用することで、コミット履歴をより理解しやすく管理でき、プロジェクトの重要なポイントを簡単に識別できるようになります！個人開発や小規模開発において、タグは不要と思われます、オープンソースプロジェクトや大規模チーム開発では、適切なタグ付けがプロジェクト管理の効率を大きく向上させます。
Next.jsとReact Testing LibraryでContextを使用しているコンポーネントのテストコードを書く方法

下記のようなSampleContextというContextと、SampleContextを使用しているSampleというコンポーネントがあるとします。

```SampleContext.tsx
"use client";

import React, { ReactNode, SetStateAction, useState } from "react";
import { Dispatch } from "react";

type Sample = {
  num: number;
  setNum: Dispatch<SetStateAction<number>>;
};

export const SampleContext = React.createContext({} as Sample);

export const SampleProvider = ({ children }: { children: ReactNode }) => {
  const [num, setNum] = useState<number>(0);

  return (
    <SampleContext.Provider value={{ num, setNum }}>
      {children}
    </SampleContext.Provider>
  );
};
```

```Sample.tsx
"use client";

import { SampleContext } from "@/provider/SampleContext";
import { useContext, useState } from "react";

const Sample = () => {
  const { num, setNum } = useContext(SampleContext);
  const [inputNum, setInputNum] = useState<number>(0);

  return (
    <>
      <div>{num === 0 ? "0です" : "0以外です"}</div>
      <div>
        <input
          type="text"
          value={inputNum}
          onChange={(e) => setInputNum(Number(e.target.value))}
        />
      </div>
      <div>
        <button onClick={() => setNum(inputNum)}>更新</button>
      </div>
    </>
  );
};

export default Sample;
```

上記Sampleコンポーネントで「0です」と表示されるケースと「0以外です」と表示されるケースのテストコードをReact Testing Libraryで書こうとして、どうやって書くか悩みましたが下記のようにしたらできました。

```Sample.test.tsx
import "@testing-library/jest-dom";
import Sample from "@/components/Sample";
import { render, screen } from "@testing-library/react";
import { SampleContext } from "@/provider/SampleContext";

describe("Sample", () => {
  it("numが0の場合、「0です」と表示されること", () => {
    render(
      <SampleContext.Provider value={{ num: 0, setNum: jest.fn() }}>
        <Sample />
      </SampleContext.Provider>
    );

    expect(screen.getByText("0です")).toBeInTheDocument();
  });

  it("numが0以外の場合、「0以外です」と表示されること", () => {
    render(
      <SampleContext.Provider value={{ num: 1, setNum: jest.fn() }}>
        <Sample />
      </SampleContext.Provider>
    );

    expect(screen.getByText("0以外です")).toBeInTheDocument();
  });
});
```
shadcn/ui: コピペで使えるReact UIコンポーネント集

`shadcn/ui` は、React向けに開発された、カスタマイズ性の高いUIコンポーネントのコレクションです。

### UI開発の課題とコンポーネントライブラリ

ReactでUIを構築する際、ボタンやフォームなどのコンポーネントをゼロから作るのは手間がかかります。そこで、デザイン済みのコンポーネントを提供する「UIコンポーネントライブラリ」（例: MUI, Chakra UI）がよく利用されます。

### shadcn/uiの特徴：ライブラリではない？

`shadcn/ui` も同様に便利なコンポーネントを提供しますが、**一般的なライブラリとは異なります**。

*   **インストール不要**: `npm install shadcn-ui` のようなコマンドで依存関係として追加するものではありません。
*   **コードを直接コピー**: コマンドを実行すると、コンポーネントの**ソースコードそのもの**があなたのプロジェクト内にコピーされます。

```
// 従来のライブラリ
npm install some-ui-library  // 依存関係として追加

// shadcn/ui
npx shadcn@latest add button // プロジェクトに 'button.tsx' をコピー
```

### shadcn/uiのメリット

*   **高いカスタマイズ性**: コピーされたコードはあなたのプロジェクトの一部なので、自由に編集・拡張できます。ライブラリの制約に縛られません。
*   **依存関係が少ない**: 必要なコンポーネントのコードだけがプロジェクトに含まれます。
*   **最新技術ベース**: Tailwind CSS や Radix UI を活用して構築されています。

### ハンズオン：shadcn/uiを使ってみよう (Next.js)

ここではNext.jsプロジェクトで `shadcn/ui` をセットアップし、Buttonコンポーネントを追加する手順を説明します。

**1. shadcn/ui の初期化**

まず、ターミナルでプロジェクトのルートディレクトリに移動し、以下のコマンドを実行します。

```bash
npx shadcn-ui@latest init
```

*   このコマンドは、プロジェクトに必要な設定ファイル (`components.json` など) を作成し、Tailwind CSSなどの設定を更新します。
*   実行すると、TypeScriptの使用、スタイルの選択（Default / New York）、ベースカラー、CSS Variablesの使用などを対話形式で質問されます。基本的にはデフォルトのままでEnterキーを押していけばOKです。
*   `package.json` がない場合は、先に `npm init -y` を実行するか、`init` コマンドが新しいNext.jsプロジェクトを作成するか聞いてきます。

**2. コンポーネントの追加 (例: Button)**

次に、使いたいコンポーネントを追加します。ここでは `button` を追加してみましょう。

```bash
npx shadcn-ui@latest add button
```

*   このコマンドを実行すると、`components/ui/button.tsx` というファイルがプロジェクト内に作成（コピー）されます。
*   依存するライブラリ（Radix UIなど）があれば、それらもインストールするか聞かれます (`y` を選択）。

**3. コンポーネントの利用**

コピーされたコンポーネントを通常のReactコンポーネントとして利用します。例えば、`app/page.tsx` を以下のように編集します。

```tsx
// app/page.tsx
import { Button } from "@/components/ui/button"; // ★追加されたButtonをインポート

export default function Home() {
  return (
    <main className="flex min-h-screen flex-col items-center justify-center p-24">
      {/* ★Buttonコンポーネントを使用 */}
      <Button>Click me</Button>

      {/* バリアントやサイズも指定可能 */}
      <Button variant="destructive" size="lg" className="mt-4">
        Destructive Large
      </Button>
      <Button variant="outline" className="mt-4">
        Outline
      </Button>
    </main>
  );
}
```

**4. 開発サーバーの起動**

変更を確認するために開発サーバーを起動します。

```bash
npm run dev
```

ブラウザで `http://localhost:3000` を開くと、追加したボタンが表示されているはずです。

### まとめ

`shadcn/ui` を利用することで、以下のメリットがあります。

*   **✅ デザイン済みのUIコンポーネントを簡単に利用できる**
*   **✅ コマンド一つで必要なコンポーネントのコードを追加できる**
*   **✅ プロジェクト内のコードとして、コンポーネントを自由にカスタマイズできる**

これにより、シンプルでカスタマイズしやすいReactのUIを効率的に構築できます。

---
Google Cloud ACE 取ってみた

Google Cloud ACE取りました
それまでを備忘録的にまとめます

# なぜ取ったか
仕事も落ち着いてきたし応用情報でも取るかと思っていたら、締め切り過ぎていて申し込めなかった
じゃあどうしようかなと思っていたところ、会社でGoogle Cloudの3月までのバウチャーあるよとなったので、じゃあいい機会だと思って受けようと
PCAを取ろうと思ってUdemyの模擬問題集やってみたら、案外難しく2度やって5割くらいしか取れず、期限も迫る中これじゃ間に合わんということでACEに変更した

# 前提知識
業務ではPjM的なところが主な担当なので、インフラエンジニアではない
業務時間の2〜3割簡単なコード書くくらいで、Webエンジニアって書いてるけどエンジニアかどうかというと怪しい

Google Cloudのプロダクトは3年運用していて、直近のこプロダクトはAzureで運用

# 対策・勉強
### やった内容
PCAでやろうと思ってた対策をそのままやった
Udemyの問題集買ってひたすらやるだけ
50問 * 3セット問題があるので、それを繰り返すだけ
- 試験と同じように50問やる
    - 解いている最中に自信がないものはマーク
    - 1周目は全問振り返り
    - 2周目以降は間違えた問題とマークつけた問題は振り返り
    - 知識がつながっていないと思うところは、chatGPTにひたすら聞く

特に今回は理解を深めたいというところでの受験だったので、試験の対策をするというよりはそれを通して理解するのを意識した
勉強時間は3セットを2.5回くらいやったので、2時間 * 3セット * 2.5回 で15時間くらいと思われる

### 場所
基本的にカフェでやるようにしてみた
試験時、実際どれくらい時間を割くのかを想定できていなかったので、2時間集中し切る時間を取る意味でも場所を変えた
家だとモニターが複数あったり大きかったりするので、試験時に近づける目的もあった

# 本番
- 試験センターで受験
    - 当日10分前に着くように家を出たら、メールに「必ず15分前に着くように」と記載があったのでめっちゃ走った
        - 別に10分前でなんとかなった、でも15分以上前に着くように行くべきではある
    - 家でだと色々片付けが必要だったので試験センターにしてよかった
    - 後ろの席の人がめっちゃ貧乏ゆすりしていてうるさかった…
- 問題
    - 思ったよりUdemyと似通った問題が少なく、試験中本当にドキドキした
        - 問題集と7割同じみたいな話を聞いていたので本当に焦った
        - 体感は2〜3割くらいだった、買った問題集が古かったかも
    - 理解するというところに意識を割いていたのが良かったのか無事合格できた

# 感想
久しぶりにこういう試験を受けたので楽しかったし、何より曖昧に理解をしていたところが明らかになったので良かった
夏くらいまでにPCAにチャレンジする予定
【Excel】関数で取得データがマスタリストに含まれているかどうかを判別　メモ

# 課題
取得したデータを元にレポートを作成したい。
全てのデータを集計するのではなく、リストに紐づいたデータのみを柔軟に抽出したい。
※調査中

## ①if,index,find関数を組み合わせる
````
=IF(COUNT(INDEX(FIND($F$3:$F$5,[@キャンペーン名]),)),[@キャンペーン名],"対象外")
````
「sample1」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3680755/ec33bdd2-479e-4975-b3b5-8973482996bd.png)



### Count関数
````ruby:数値の個数を数える
=COUNT(値1,値2,値3)
````

### index関数
````ruby:参照中の行と列で指定した位置の値を求める
=INDEX(参照,行番号,列番号)
````

### FIND関数
````ruby:文字列の位置を調べる
=FIND(検索文字列,対象,開始位置)
````
対象で指定した文字が、検索文字列の中の何文字目かを調べる。
結果は整数で返される？
【メモ】displayプロパティの種類と使い分けについて

# display プロパティの役割とは？

HTMLの要素は、「ブロック要素」や「インライン要素」など、表示の性質がある。

display を使うと、それを自由に変更することができ、例えば：

+ 要素を横に並べたい
+ 要素の中に中央揃えをしたい
+ 見えなくする
+ グリッドやフレックスで 柔軟にレイアウト

…といったことが可能になる。

# よく使う display の種類と使い分け
### ① block（ブロック要素）

+ 特徴：幅100%を占めて改行される
+ 例：\<div>, \<p>, \<h1> など

```
display: block;
```
使い所：
+ セクションを区切るとき
+ 要素を縦に並べたいとき

### ② inline（インライン要素）
+ 特徴：文章の中に並ぶように表示される（改行しない）
+ 例：\<span>, \<a>, \<strong> など

```
display: inline;
```

使い所：
+ 文字の一部だけスタイルを変えたいとき（色・太字など）

注意：
+ width, height, margin-top などが効かない

### ③inline-block
+ 特徴：インラインのように横並びになるけど、サイズ指定（width/height）ができる

```
display: inline-block;
```
使い所：
+ ボタンなど「横並び」かつ「サイズ調整」したいとき

### ④ none（非表示）
+ 特徴：要素自体が画面から消える（DOMから除外されるように）

```
display: none;
```
使い所：
+ タブ切り替え・モーダル表示の非表示状態など

ちなみに：
+ visibility: hidden は見えないだけでスペースは残る
+ display: none は完全に消える

### ⑤ flex（フレックスボックス）
+ 特徴：要素を横並び・縦並びに整列できる柔軟な仕組み

```
display: flex;
```

使い所：
+ ヘッダーの横並び
+ コンテンツの**中央揃え（上下左右）**など

よく一緒に使うプロパティ：
```
justify-content: center; /* 横方向の揃え方 */
align-items: center;     /* 縦方向の揃え方 */
flex-direction: row;     /* 横並び */
```

### ⑥ grid（グリッドレイアウト）
特徴：2次元のレイアウトが得意（表のような構成）

```
display: grid;
```
使い所：
+ 複雑なレイアウト（ブログの一覧、カード表示など）

一緒に使うプロパティ：
```
grid-template-columns: 1fr 1fr 1fr; /* 3列レイアウト */
gap: 16px; /* 要素の間隔 */
```

### ⑦ contents（中身だけ表示）
+ 特徴：要素そのものは無視して中の子要素だけを表示

```
display: contents;
```
使い所：
+ セマンティックな構造を残しつつ、見た目は親要素を消したいとき

注意：
+ 一部のブラウザで不安定なこともある

### ⑧ table 関連（テーブル構造用）
+ table, table-row, table-cell などテーブルレイアウトを自分で作りたいときに使う。

```
display: table;
display: table-row;
display: table-cell;
```

使い所：
+ テーブルのような構成を CSS だけで再現したいとき（今はあまり使わない）

# よくある使い分けの具体例

| 目的 | display |
|:-|:-|
|横並びにしたい（レスポンシブ対応）|flex または inline-block|
| 要素を非表示にしたい  | none  |
|要素を上下に並べたい   |block（デフォルト）   |
| ボタンなどのサイズ指定できる横並び  |inline-block   |
|グリッド表示（複数列）にしたい   | grid  |
|テキストの一部だけ強調したい   |inline（または span）   |



# まとめ
+ display は「この要素をどんな形で並べるか」を決めるスタイル。
+ シンプルなレイアウトは block / inline / flex を覚えるだけでも十分。
+ flex は超万能でよく使う。
+ grid は2列以上の複雑レイアウトに便利。
cookieがsetされるAPIを叩いた時に使えるCurlコマンドオプション

## curlでAPIテストするときにcookieを保存して次のリクエストで再利用する方法
### 手順：
保存する：
```bash
curl -i -c cookie.txt http://localhost:8080/api/login
(-c はcookieをファイルに保存するオプション。)
```

再利用する：
```bash
curl -b cookie.txt http://localhost:8080/api/private
(-b はcookieファイルを読み込んで送信するオプション。)
```
🚀 MacにCocoaPodsをインストール

CocoaPodsは、iOSやMac向けのアプリ開発において、ライブラリを管理するためのパッケージマネージャーです。

GitHub などからライブラリを自動で取得・管理できるため、ライブラリの導入・更新が簡単になり、開発効率が向上します。

# 1. CocoaPods がインストールされているか確認

まずは CocoaPods がすでにインストールされているか確認しましょう。

```bash
pod --version
```

バージョンが表示されればインストール済みです。  
表示されない場合は、次の方法でインストールしましょう。


# 2. CocoaPods のインストール方法（2通り）

### ✅ 方法 A：gem（RubyGems）でインストールする場合

RubyGems を使ってインストールします。  
Ruby 環境に慣れている方向けです。

```bash
sudo gem install cocoapods
```

#### 📌 注意：PATHを通す必要があります

`pod` コマンドが `not found` になる場合は、PATH が通っていない可能性があります。

以下のコマンドで確認：

```bash
echo $PATH | grep '.gem/bin'
```

何も表示されなければ、以下を `~/.zshenv`（または `~/.zshrc`）に追記：

```bash
export PATH=$HOME/.gem/bin:$PATH
```

反映するには：

```bash
exec $SHELL -l
```

再確認：

```bash
pod --version
```

### ✅ 方法 B：Homebrew でインストールする（推奨）

特に Flutter を使用する場合や、M1/M2 Mac では Homebrew 経由の方が安定することが多いため、こちらをおすすめします。

```bash
brew install cocoapods
```

インストール完了後に確認：

```bash
pod --version
```

# おまけ：pod repo update

初回や久しぶりに CocoaPods を使うときは、リポジトリの更新をしておくと安心です。

```bash
pod repo update
```

これで CocoaPods のインストールは完了です✨  

Xcode や Flutter のプロジェクトで `pod install` を使って、ライブラリ管理を快適にしましょう！
Gymnasium(旧OpenAI Gym)の環境構築方法

# 概要
　この記事では、Gymnasium(旧Open AI Gym)の環境構築方法を記載しています。

# 1. 初めに
　私は最近、「ゼロから作るDeep Learning 4 強化学習編」を勉強し始め、強化学習の基礎を学んでいます。この本の中で触れられているOpenAI Gymを使った強化学習の実装に挑戦しようとしたところ、現在ではGymがGymnasiumに移管されており、そのままではコードが動かないことが判明しました。
そこで、Gymnasiumの使い方を調べていく中で得た知見を、記録として残すことにしました。この記録が、同じように「ゼロから作るDeep Learning」を学ぶ方や、Gymnasiumの利用を考えている方の参考になれば幸いです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4053577/850a9c55-c0d5-4b12-b3c0-42c7c864fb7c.png" width="150px" height="200px" />

# 2. Gymnasiumとは
　Gymnasiumは、強化学習（Reinforcement Learning, RL）に特化したツールキットで、もともとはOpenAIによって開発されたOpenAI Gymから移管されたプロジェクトです。また強化学習に関する論文では、ベンチマークとしてOpenAI Gymがよく使われます。
 
　Gymnasiumは、基本的にはOpenAI Gymと同様の動作やAPIを提供しているため、Gymで慣れ親しんだユーザーはそのまま移行が容易です。また、従来のコードもほとんど修正せずに利用可能で、これまで培った学習や実験を継続することができます。
 
　以下が公式ドキュメントになります。インストール方法から利用方法まで解説されています。

https://gymnasium.farama.org/#

## 3. Gymnasiumを動かしてみる
 今回まずは、入門編としてよく使われる「Cart Pole」を動かしてみたいと思います。まず始めに、以下のコマンドを実行します：
 ~~~bash
 pip install gymnasium[classic-control]
~~~
gymnasiumのインストールが完了したら、以下を実行します。
~~~python
import gymnasium as gym

# 環境を初期化
env = gym.make("CartPole-v1", render_mode="human")

# 環境をリセットして最初の観測値を生成
observation, info = env.reset()
for _ in range(1000):
    # ここにアクションを挿入する。アクションがランダムに生成される。
    action = env.action_space.sample()

    # アクションを入力し、次のステップに移行
    # 次の観測値、報酬、エピソードが終了したか中断されたかを受け取る
    observation, reward, terminated, truncated, info = env.step(action)

    # エピソードが終了した場合、新しいエピソードを開始するためリセット可能
    if terminated or truncated:
        observation, info = env.reset()

# 環境を終了
env.close()
~~~
うまく動作すると、以下のような結果になると思います。
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4053577/b55940c1-9bff-4fe1-93a0-fc93b1fa3154.gif">


#### 旧OpenAI Gymとの違い
「ゼロから作るDeep Learning 強化学習編」で記述されているOpenAI Gymとの違いですが、
* CartPole-v0ではなくCartPole-v1が使われる。
CartPole-v0は現在ではサポートされておらず、CartPole-v1を使うことになります。
* step()の出力の違い
`step()`で出力されてくるものが、「`observation, reward, terminated, truncated, info` 」となっています。従来は`done`でゲームを終了したかの判定をしていたのですが、`terminated, truncated`と2つになりました。これは終了した理由を明確にするためです。

## 4. 基本的な使い方
* 環境を作成する　`gym.make("CartPole-v1")`
　このコードでCartPole-v1という環境が作成され、エージェントが操作する舞台が設定されます。
* 環境をリセットする`reset()`
 　`reset()`メソッドを使用して、環境を初期状態に戻し、最初の観測値`observation`を取得します。※`observation`と`info`の値が返ってきます。
* 環境でアクションを実行する`observation, reward, terminated, truncated, info = env.step(action)`
　 `step(action)`メソッドを使って、環境内でアクションを実行します。
・`action`: エージェントが実行する操作（例：左に移動、右に移動など）。
・`observation`：環境の状態を示す。
・`reward`: このアクションによって得られる報酬。
・`terminated`: エピソードが終了した（成功または失敗）場合に`True`。
・`truncated`：制約（タイムリミットなど）でエピソードが中断された場合に`True`。
・`info`: 環境に関する追加情報。
* 環境を閉じる`close()`
 作業が終了したら、 `close()`メソッドを使用して環境を閉じます。

 ## 5. おわりに
　今回はGymnasiumの環境構築方法や簡単な使い方など記載しました。Cart-Poleを例に出しましたが、PendulumやAtari、Car-racingなどの環境も実行できます。詳しくは公式ドキュメントを参考にしてください。
　これで強化学習のアルゴリズムのテストを実行できるようになりましたので、様々なアルゴリズムを試してみたいと思います。