OmniAICreator/Qiita-1.07M huggingface dataset:
自分用GPU環境構築メモ(Ubuntu) 2023/12

## 筆者環境
* Ubuntu20.04 or 22.04
* Nvidia gpu

## やること
* 事前準備
* GPUドライバのインストール
* dockerのインストール & 設定
* nvidia dockerのインストール & 設定
* (CUDAのインストール)
* (minicondaのインストール)

## 事前準備
```
sudo apt-get update
sudo apt-get install build-essential
sudo apt-get install openssh-server
ip address
```
OpenSSH Serverは個人的に必須です。
GPUドライバインストールした際、画面オフになる場合がありコンソールにアクセスすることが多いです。IPアドレスは固定しとけばよいのですが、念のための確認用です。

### GPUドライバのインストール
NVIDIAのホームページからドライバダウンロード
https://www.nvidia.com/download/index.aspx

```
sudo chmod +x <ドライバ名>
sudo sh ./<ドライバ名>
sudo reboot
sudo nvidia-smi
```
大抵そのまま上手くいかないので対処法をいくつか。

#### 試行1
nouveauの無効化
```
sudo vi /etc/modprobe.d/blacklist-nouveau.conf
　　blacklist nouveau
　　options nouveau modeset=0
sudo update-initramfs -u
```
#### 試行2
gdmのサービス停止
```
sudo service gdm stop
```

#### 試行3
dkmsが邪魔している場合、オプション付けてドライバをインストール
```
sudo sh ./<ドライバ名> -dkms
```
詰まる点は沢山あるが、大体これでいける

### dockerのインストール&設定
https://docs.docker.com/engine/install/ubuntu/

```
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update

sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
```
sudoなしで実行するための設定
```
sudo groupadd docker
sudo usermod -aG docker $USER
(VMなら一旦ここでリログ)
newgrp docker
# 最後にテスト
docker run hello-world
```

### CUDAのインストール(オプション)
cuda toolkitは個人的にコンテナで使うことが多いが念のため。
GPUドライバとセットでインストールする方法もありますが今回は単独で

nvidia-smiでCUDAの対応Version確認(右上に表示)
```
nvidia-smi
```

下記から指定してダウンロード
https://developer.nvidia.com/cuda-toolkit-archive

runファイルでGPUドライバを含まずにインストールするのがおススメ

※v12.2の場合
```
wget https://developer.download.nvidia.com/compute/cuda/12.2.2/local_installers/cuda_12.2.2_535.104.05_linux.run
sudo sh cuda_12.2.2_535.104.05_linux.run
```
パス設定
```
echo 'export PATH=/usr/local/cuda-12.2/bin${PATH:+:${PATH}}' >> ~/.bashrc
echo 'export LD_LIBRARY_PATH=/usr/local/cuda-12.2/lib64\
                         ${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}' >> ~/.bashrc
```

上手くいかない方はこちらを参考に
https://docs.nvidia.com/cuda/cuda-quick-start-guide/index.html#runfile-installer

### minicondaインストール&設定(オプション)
Python使う人にはおすすめ。
https://docs.conda.io/projects/miniconda/en/latest/index.html

```
mkdir -p ~/miniconda3
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O ~/miniconda3/miniconda.sh
bash ~/miniconda3/miniconda.sh -b -u -p ~/miniconda3
rm -rf ~/miniconda3/miniconda.sh

~/miniconda3/bin/conda init bash
~/miniconda3/bin/conda init zsh
```

### 参考ページ
仕事柄公式HPの情報をソースにしています
https://docs.nvidia.com/datacenter/tesla/tesla-installation-notes/index.html
https://us.download.nvidia.com/XFree86/Linux-x86_64/535.146.02/README/index.html
https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html#runfile-installation
IntelliJ IDEAでReact + TypeScriptのプロジェクトを作成する

# はじめに
[前回](https://qiita.com/YuukiYoshida/items/726a509438081e47a34e)に続き、Webの方の開発を進めています。
実際Webを開発しようとすると、どの開発環境を利用しようか悩むと思いますが、ほとんどの場合がVisual Studioを利用している認識です。
あとはSublime Textだったり、WebStormだったりなど、ちらほら耳にする程度です。
私はサーバーサイドの開発でIntelliJ IDEAを使用しているので、その延長線でIntelliJ IDEAを利用できると便利です。
そこで今回はIntelliJ IDEAを前提として開発を行っていくためのプロジェクト作成手順を備忘録的にまとめておこうと思います。

# プロジェクト作成手順
手順を説明するにあたり、前提としてNode.jsが導入済みであることが前提でお話を進めていきます。
まだ未導入の場合は[こちら](https://qiita.com/YuukiYoshida/items/726a509438081e47a34e)を参考に、Node.jsを導入してから作成手順へ進めるようにしてください。

まずIntelliJ IDEAを開き、New Projectよりプロジェクト作成へ進みます。

![スクリーンショット 2024-01-06 16.16.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/354522/1a74d7ca-b293-c629-b33f-3f94dd7f10d2.png)

すると上記のようなプロジェクトを作成するウィンドウが表示されますので、ウィンドウ左のGeneratorsからReactを選択し、必要な項目を入力していきます。

プロジェクト名、Locationに適切なものを入力し、ProjectTypeはReactを選択します。

使用するNodeは前回のご説明時に導入したNode.jsが選択されていれば問題ありません。

create-react-appはnpx create-react-appを選択します。

最後に、今回はTypeScriptを使用して開発を進めていく想定なのでCreate TypeScript projectにチェックを付けCreateボタンからプロジェクトを作成します。

以上で作成手順は以上になります。

# さいごに
IntelliJ IDEAは、Reactと統合され、lint の設定、編集、実行、デバッグ、アプリケーションの保守を支援します。

とのことなので、IntelliJ IDEAでも十分Webの開発を進められそうです。
今後の使用感なども含め、不便なところや便利なところなどの共有も記事にできたらと思います。
はんだづけの練習のためのLED独楽キットを組み立てよう

中華電子工作キットシリーズです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/ee8ec786-cdbe-0362-7fc1-2428ef9a18ab.png)

回すと光る電子工作キットです。

Tmall で、現地価格で200円ぐらいです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/13906618-6fda-8498-9284-0063430695fa.png)


- 難易度 初級
- 必要な工具
  - はんだごて
  - はんだ
  - ニッパー 
- その他必要なもの
  - CR2032電池 x 2
 
# 部品一覧

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/2a36f4a3-e4d9-f300-1be9-f110f4fe702f.png)

# 組み立てよう

抵抗 x 6 , トランジスタ、コンデンサをはんだづけします。
![image1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/de1953c6-1b72-b388-9e73-9aa5160d8a6f.jpeg)

LED、センサスイッチ、電池ホルダを取り付けます。
LEDは向きに注意!
![image1 (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/1f41f1d6-e6ef-181e-9599-c4f45152ea98.jpeg)


中央にスペーサをネジで取り付け、回してみましょう。センサスイッチが働いてLEDが光ります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/175df480-a9a9-4d10-8e1e-384f6add1e1d.png)

https://twitter.com/nanbuwks/status/1743536058225299958
【備忘録】nodenvでNode.jsのバージョンが切り替わらない

# 経緯
vueでプロジェクトを作成しようとしたら、failedになりました。
```shell
% vue create sample-project
error eslint-plugin-vue@8.7.1: The engine "node" is incompatible with this module. Expected version "^12.22.0 || ^14.17.0 || >=16.0.0". Got "14.16.1"
error Found incompatible module.
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.
 ERROR  Error: command failed: yarn 
Error: command failed: yarn 
    at ChildProcess.<anonymous> (/Users/xxx/.config/yarn/global/node_modules/@vue/cli/lib/util/executeCommand.js:138:16)
    at ChildProcess.emit (events.js:315:20)
    at maybeClose (internal/child_process.js:1048:16)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:288:5)
```

出力結果をみるに、Node.jsのバージョンが合ってなさそうです。
（あれ？16.0.0以上に設定していたような。。）

# Node.jsのバージョンを確認してみる

```shell
$ node -v
v14.16.1
```

確かにバージョンが合ってない。
バージョンを設定します。

```shell
$ nodenv local 16.13.2
$ node -v
v14.16.1
```

あれ？変わらない。。
・
・
・
試行錯誤の結果、Nodebrewが邪魔してました。。
昔、Node.jsを色々触ってた時に入れて、そのまま忘れてしまっていました。

.zprofileにもPATH追加されていました。
[nodenvのgithub](https://github.com/nodenv/nodenv?tab=readme-ov-file#understanding-shims)を読み直してPATH設定をやり直します。

.zprofileに記載しているPATH追加をnodenvに書き換えます。

```.zprofile
export PATH=$HOME/.nodebrew/current/bin:$PATH
↓
export PATH=$HOME/.nodenv/shims:$PATH
```

最後に.zprofileを読み直します。

```shell
$ source $HOME/.zprofile
```

# 治ったことを確認

```shell
$ node -v
v16.13.2
```

設定が反映されました！
よかったー

使っていないnodebrewも削除しておきます。
ユーザーディレクトリ直下の.nodebrewを消すだけで良いようです。

# 参考文献
https://github.com/nodenv/nodenv
【Vitest書き方】describe, it, test, beforeAll...って何？

Vitestは、JavaScriptおよびTypeScriptのためのモダンなテストランナーおよびアサーションライブラリです。VitestはJestにインスパイアされているため、`describe`, `it`, `beforeAll`などの関数の使い方はJestと非常に似ています。これらの関数を使用してテストスイートを構成し、個々のテストケースを定義し、テストの実行前に必要な準備を行います。

### 基本的な構造

- **`describe`**: テストスイートをグループ化するために使用されます。関連するテストケースを一つのブロック内にまとめることができます。
- **`it`/`test`**: 個々のテストケースを定義します。テストしたい具体的な動作や機能に対して記述します。一般的に、it と test は同じ目的で使用されますが、テストケースを記述する際の文脈によって選択します。
- **`beforeAll`**: すべてのテストケースが実行される前に一度だけ実行される関数です。テストに必要な初期化処理などを行います。
- **`afterAll`**: すべてのテストケースの実行が完了した後に一度だけ実行される関数です。テストの後片付けなどを行います。
- **`beforeEach`/`afterEach`**: それぞれのテストケースが実行される前後に毎回実行される関数です。

### サンプルコード

以下にVitestを使用したテストコードの例を示します。

```javascript
import { describe, it, expect, beforeAll, afterAll } from 'vitest';

describe('数値のテスト', () => {

  beforeAll(() => {
    // すべてのテストケースの前に実行される処理
    console.log('テスト開始前の初期化');
  });

  afterAll(() => {
    // すべてのテストケースの後に実行される処理
    console.log('テスト完了後の後片付け');
  });

  it('数値の等価性テスト', () => {
    expect(2 + 2).toBe(4);
  });

  it('数値の不等価性テスト', () => {
    expect(2 + 2).not.toBe(5);
  });

});
```

この例では、`describe`ブロックを使用して、数値に関するテストケースをグループ化しています。`it`関数は個々のテストケースを定義し、`expect`とアサーションメソッド（例えば`toBe`や`not.toBe`）を使用して期待される結果を検証します。`beforeAll`と`afterAll`は、テストスイートの開始前後に実行される処理を定義しています。
その3 仮説を立てる〜T2チップを備えない古いIntel MacをNerves化しようとする日々

「T2チップを備えない古いIntel MacをNerves化しよう」という構想の実現に邁進する駄文シリーズの第3弾です．前回までで，素のx86_64のbuildrootを構築してSSDにインストールし，Mac Pro (Mid 2010)で実行してみたところ，起動画面は出たのですが，ブートが途中で止まってしまう結果になりました．今回は，その対策を考えてみるという回です．

## シリーズ

1. [Nerves化構想を思い立つ](https://qiita.com/zacky1972/items/d1da49dedfaafae57cbb)
1. [buildrootをビルドして起動する](https://qiita.com/zacky1972/items/4ce0032514978a7d2f1f)
1. 仮説を立てる(本記事)

## 閑話休題

buildrootの問題は放置して，2023年のうちに購入していたものの諸問題があって今まで読めていなかった，[牛尾剛さん著の「世界一流エンジニアの思考法」](https://books.bunshun.jp/ud/book/num/9784163917689)の冒頭から第1章の途中までを読みました．

小見出しをつまむと，「試行錯誤は悪である」「理解に時間をかける」「複雑な技術をコントロール」みたいな感じでした．

この部分を読むだけでも，示唆に富んでいて，読んだ甲斐がありました．

## buildrootにおいて「理解に時間をかける」「複雑な技術をコントロール」そして仮説を立てる

さて，ここで，buildrootのことについて，いろいろ考えます．

まず幸いなのが，Linux自体は起動していて，ブートログを画面に出すことはできています．これもできていなかったら，本当に途方に暮れるところでした．

したがって，少なくともLinuxカーネルと，おそらくVGAの画面を出力に関係するデバイスドライバは，正常に動作しています．

しかし，問題なのは，起動シーケンスが早すぎて，ブートログがスクロールアウトして，読めないということでした．しかも，現状では`dmesg`コマンドを発行することもできないので，スクロールアウトしたブートログを読むことはできませんし，他のPCに転送することもできません．

こんな時，シリアル通信でログを取れているといいのになあと思いました．組込みシステムボードであれば，大抵はシリアル通信がついていて，PCで記録することができます．なので，組込みシステムボードを新規で設計するのであれば，まずシリアル通信を死守すべきと思います．FPGAボードであっても，シリアル通信の確立が最優先と思い知りました．

また，Arch Linuxや Ubuntu は Mac Pro (Mid 2010) で何の問題もなく起動できています．したがって，これらの `dmesg` の出力するログを読めば，現状のLinux一式で，Mac Pro (Mid 2010) 向けにどんなデバイスドライバを必要としているかが明らかになることでしょう．

しかし，残念なことに，現状のArch Linuxのインストール状況では， `dmesg` の出力結果を他のPCに転送することができていません．それをするには，USBメモリを使うか，SSH接続を確立するか，何かしないといけません．

しかも運の悪いことに，どういうわけか，USBメモリからの起動ができなくなりました．USBメモリを挿してオプションキーを押しながらの再起動をしても，起動可能なUSBメモリとして認識してくれません．何度上書きしても，ダメなのです．これについては，USBメモリが壊れたものとして，他のUSBメモリでやってみたら良いのかもしれません．

待てよ，Arch Linuxにこだわりすぎているのかもしれません．`dmesg`のログを読むのが目的であれば，別にUbuntuでも良いのではないでしょうか．そうだ，ここで，Ubuntuに切り替えよう．

仮にUbuntuに切り替えて`dmesg`を解析できたとします．依然として，buildrootのブートログを全て読めません．

一旦，まっさらから始めて，まずは画面表示に最低限必要なデバイスドライバのみを組み込んだbuildrootを構築して，ブートログと`dmesg`のログ出力を照合しながら，進めたらどうだろうか？

うん，これでいけそうな気がします．


## 追記

この仮説は全面的に間違っていました．

buildrootを設定してみたら，すぐわかることでした．

つづく

https://qiita.com/zacky1972/items/4e150e1f80e31ac69be7
OpenCVを用いたエッジ検出

OpenCVを使用したエッジ検出は、画像のエッジや輪郭を識別するプロセスで、画像処理や画像認識の分野で広く利用されています。エッジ検出の一般的な手法には、Cannyエッジ検出、Sobelエッジ検出、Laplacianエッジ検出などがあります。本記事では、これらの方法を使った基本的なエッジ検出の例をいくつか紹介します。

必要なもの
Python: プログラミング言語として使用。
OpenCV: 画像処理を行うためのオープンソースライブラリ。
OpenCVをインストールしてください。
```
pip install opencv-python
```
## Cannyエッジ検出
Cannyエッジ検出は、画像のエッジを検出するための多段階アルゴリズムです。

```
import cv2

# 画像を読み込む
img = cv2.imread('image.jpg', 0)

# Cannyエッジ検出を適用
edges = cv2.Canny(img, 100, 200)

# 結果を表示
cv2.imshow('Canny Edge Detection', edges)
cv2.waitKey(0)
cv2.destroyAllWindows()
```

## Sobelエッジ検出

Sobelオペレータは、水平方向と垂直方向の空間勾配を計算することでエッジを検出します。

```
import cv2
import numpy as np

# 画像を読み込む
img = cv2.imread('image.jpg', 0)

# Sobelエッジ検出を適用
sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=5)  # x方向のSobel
sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=5)  # y方向のSobel

# 結果を表示
cv2.imshow('Sobel X', sobelx)
cv2.imshow('Sobel Y', sobely)
cv2.waitKey(0)
cv2.destroyAllWindows()
```

## Laplacianエッジ検出
Laplacianエッジ検出は、画像の二次微分を使用してエッジを検出します。

```
import cv2

# 画像を読み込む
img = cv2.imread('image.jpg', 0)

# Laplacianエッジ検出を適用
laplacian = cv2.Laplacian(img, cv2.CV_64F)

# 結果を表示
cv2.imshow('Laplacian Edge Detection', laplacian)
cv2.waitKey(0)
cv2.destroyAllWindows()
```

OpenCVは、Canny、Sobel、Laplacianなど、さまざまなエッジ検出アルゴリズムを提供しています。これらは、画像から重要な特徴を抽出するための強力なツールです。
Next.js requires react >= 18.2.0 to be installed.

# 問題点
Next.js14で作成したアプリをVercelにデプロイする際に「Next.js requires react >= 18.2.0 to be installed.」と出力され、失敗してしまいました。


# 対応
package.json ファイルを更新するだけでした。
Next.js13以降はReactの最小バージョンは18.2.0になっているようです。

```
"react": "^18",
"react-dom": "^18"
```
【プラクティス紹介】1分でさらっと分かる「スプリント0」

## プラクティス名（別名）
スプリント0　（イテレーションゼロ）

## プラクティスの目的・狙い
* アジャイル開発のマインドセットを浸透させる（**重要!**）
* チームメンバーと関係者の前提認識を揃え、開発方針と体制を定める
* スプリントを開始できるよう環境を整える

## どんな時に使うか
* 新規開発などで前提/目的/経緯といった文脈が共有できていない時
* チームや顧客の中に新メンバーやアジャイル未経験者がいる時

## 実施手順
1. スプリント1に入る前に一定期間を設けて実施する
1. 方針検討は原則チーム全員参加で行う（ステークホルダーは必要に応じて）
1. 前提条件や開発方針は明文化し、いつでも参照できる場所に掲載する（適宜更新）
1. 環境整備やツール設定を含め、スプリント開始に向けて必要な準備を済ませる
（内容は相互に関連するため、上から順にというより重要なものから検討する）

| 実施事項 | 具体的な検討内容・確認内容（例） |
|:-:|:--|
| チームビルディング  | 要員アサイン、自己紹介、スキル可視化、ロール確定、体制図、チームのミッション共有  |
| プロダクト定義 | ビジョンの共有、市場環境分析、プロダクトゴール決定  |
| マインドセット | アジャイル宣言＆スクラムガイドの理解  |
| 基礎教育 | 業務知識共有/技術知識共有/プラクティス説明/PO教育/DEV教育  |
| 開発方針  | 何を優先するか？（トレードオフ）、価値基準、判断基準 |
| 開発スコープ  | どこまでを開発範囲とするか？ （何をする/しない） |
| ステークホルダー  | 誰とどの程度コミュケーションをとるか？ |
| チーム運営方針  | スプリント期間、定例会議と参加者、連絡方法、報告形式、使用ツール、採用プラクティス、ワーキングアグリーメント作成、Wiki作成  |
| ユーザ要求一覧化  | PBLの第一版作成、ユーザヒアリング、優先順位付け  |
| 作業量見積もり  | SP見積＆集計、必要な期間とリソース  |
| 大まかなリリース計画  | いつ頃、何をリリースできそうか？、マイルストーン  |
| リスクの洗い出し  | 想定される主なリスクとその影響・対策　|
| 品質基準  | 完成の定義、非機能要件、作成対象ドキュメント、測定メトリクス、コーディング規約、関連法規|
| 技術検証  | アーキテクチャ策定、技術調査、PoC、ツール選定 |
| 環境準備・ツール設定  | 開発環境等の構築、設定、申請、ID提供、タスクボード準備、自動テストツール、CI/CDツール  |
| ブランチ戦略  | リポジトリ運用ルール |
| 関係者合意  | ステークホルダーと上記方針を共有＆合意 |

## アレンジ例
* 開発方針を明確化するためインセプションデッキをチームで作成する
* PBL第一版作成のためユーザーストーリーマッピングを実施する
* メンバーにも他にやるべきタスクがないか挙げてもらう

## アンチパターン
* POが検討に参加していない（チームが文書化したものを後でレビューするなど）
* スプリント0を完璧にやり遂げようとして、なかなかスプリント1に入れない（本末転倒）

## 参考情報

スプリント0でやるべきことはryuzeeさんが以下の記事で全て言い尽くしてくれています。より詳細に知りたい方にオススメです。

https://www.ryuzee.com/contents/blog/7147

## こぼれ話（私的コメント）
「スプリント0にどの程度の期間が必要か？」
よく聞かれる質問です。案件規模や難易度、メンバーの習熟度、顧客との関係性などによっても変わってくるため一概には答えられないのですが、目安として「スプリント1で走り出すのに困らない程度」に準備ができていればOKと伝えています。正直、時間はいくらあっても足らないので、個人的には最大限の日程確保をオススメしたいところですが、期間中に7割消化できればいいかな、ぐらいの感覚で次に進めています。

スプリント0の所要期間を正確に見積もろうとするより、確保できた期間の中で優先度の高いものからできるだけ消化する、という考え方に切り替えた方がいいかもしれません。
チーム全員参加の合宿形式で集中的にやれたら理想的なんだけどなぁ、といつも思いますが、大抵、POが忙しくて実現しません・・・。

---
　[アジャイルプラクティス一覧へ戻る](https://qiita.com/kakashi_h5/items/20584998c5ca4594b9ea)
状態管理ライブラリ Jotai の使い方

要点だけ端的に説明します。

## インストール
```
yarn add jotai
```
## stateの宣言
state管理するには`atom()`関数を呼び出します。
型は`atom<string>(initialValue: string)`となります。

`atomWithStorage`はlocalStorageを使用して保存します。そのため、ブラウザがリロードしても前の値の状態を保ちます。

型は`atomWithStorage<string>(key: string, initialValue: string)`です。keyはlocalStorageに保存されるKeyの名前になります。

```ts:src/jotai/state.ts
import { atom } from "jotai";
import { atomWithStorage } from "jotai/utils";

export const state = atom<string>("");
export const stateWithStorage = atomWithStorage("storageKey", "");
```

## 保存と呼び出し
あとはuseStateのように使用できます。
厳密には誤りがあると思いますが、以下のように考えてもらえれば大丈夫です。
```ts
const [呼び出し名, 保存関数] = useAtom(state名);
```

よってサンプルコードは以下のようになります。

```tsx:src/pages/index.tsx
import { state, stateWithStorage } from "@/jotai/state";
import { useAtom } from "jotai";

const Home = () => {
  const [exampleState, setExampleState] = useAtom(state);
  const [storageState, setStorageState] = useAtom(stateWithStorage);

  return <>Hello World</>;
};

export default Home;
```

保存と呼び出しは以下のようになります。

#### 保存
```ts
setExampleState("value");
setStorageState("value"); // localStorageに保存される
```

#### 呼び出し(例)
```ts
console.log(exampleState, storageState);
```

サンプルコード :
```tsx:src/pages/index.tsx
import { state, stateWithStorage } from "@/jotai/state";
import { useAtom } from "jotai";

const Home = () => {
  const [exampleState, setExampleState] = useAtom(state);
  const [storageState, setStorageState] = useAtom(stateWithStorage);

  return (
      <center className="mt-[30vh] text-3xl">
        <h1>Jotai Testing</h1>
        <div>
          <p>Example state: {exampleState}</p>
          <input
            className="border"
            type="text"
            onChange={(e) => setExampleState(e.target.value)}
          />
          <p>Storage state: {storageState}</p>
          <input
            className="border"
            type="text"
            onChange={(e) => setStorageState(e.target.value)}
          />
        </div>
      </center>
  );
};

export default Home;
```
値を入力して出力するだけです。

![jotai.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729508/ca867bec-736d-24a1-40a7-06fc5ae359de.gif)

サンプルコードを置いておくのでもしよかったら確認してください。
https://github.com/H-goto16/jotai-test
Microsoft Copilot Studio の生成AI機能でファイルを上手く読み込まない場合の対応(英語環境下)

## はじめに
昨年の12月に、Microsoft Copilot Studioが発表されました。

https://qiita.com/Takashi_Masumori/items/77c3f1bcce188f0df869

既存のPower Virtual Agentsに生成ai機能(旧チャットボット)が追加されたもので、**Webサイト**や**独自にアップロードしたファイル**を参照して回答を行えるbotを作成できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3310860/dabcb058-bb6e-9c43-ff1f-f893736aa4c6.png)

※記事執筆時時点では、日本語環境で生成ai機能を利用したbotの作成ができませんでした。
⇒ Power Platform経由で環境設定を変更すれば可能みたいです。

https://qiita.com/Takashi_Masumori/items/74fac18e0ce57216c10a

## 現状理解

Copilotの生成AIにPDFファイルをアップロードしてみたところ、ファイルの中身を参照できるケースとできないケースがあることがわかりました。

具体的には「**ファイル名が日本語であると読み込めない**」ようで、同じ問題に直面する方もいらっしゃるかと思いますので、忘備録として残します。

「**ファイル名を英語に変更**」で解決でき、ファイルの中身を変更する必要はありません。
以下に実際のテストケースを記述します。

## 検証

デジタル庁が公開している「[ChatGPTを業務に組み込むためのハンズオン](https://www.digital.go.jp/assets/contents/node/information/field_ref_resources/5896883b-cc5a-4c5a-b610-eb32b0f4c175/82ccd074/20230725_resources_ai_outline.pdf)」のPDF教材をbotに読み込ませてみます。

読み込ませるファイル自体は同じですが、**ファイル名のみ変更**を行いテストします。

- 日本語名のPDF
- 英語名のPDF

ハンズオンの資料の2Pで
>アイデアの価値は「検証」してみないとわからない

という記載があるため、こちらを学習して回答が行われるかをテストします。

### 1.ファイル名が日本語の場合

チャットGPT.pdfでファイルを格納しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3310860/bf16b284-857d-9b73-0b5c-39d76d7406f2.png)

「ファイルのアップロードが完了しました。ファイルを Dataverse に正常にアップロードしました。その内容は生成型の回答にまもなく反映されます」の文言が表示されましたが、
**3分ほど経過しても特に画面変化は見られません**。

この状態でbotに質問を投げかけますが、アップロードしたファイルの内容は反映されていないみたいです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3310860/07c97c25-dd33-f3f4-a222-5940dd6c93be.png)

### 2.ファイル名を英語に変換

次に、全く同じ中身のファイルを名前だけ変換しました。
ChatGPT.pdfでアップロードを行ってみます。

![スクリーンショット 2024-01-06 154351.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3310860/38530829-b87a-b25a-ca99-b50fdccdbd9f.png)

英語の時と異なり、アップロード完了の下にファイル名が表示されるようになりました。
ここで、先ほどbotに送ったメッセージを再度送信してみます。

すると、読み込ませたPDFにある情報を元に回答が返ってくるようになりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3310860/aa8b19c1-0f02-ee9b-7949-ddc243ed88f9.png)

## 所感

幾つかPDFファイルを読み込ませて回答を受け取ってみましたが、回答の精度はまずまずといったところでした。メッセージを適当に送ると上手く探してくれなかったりします。

参照元のファイルを明記してくれる点や、chatGPT3.5のように嘘の回答を平然とすることがなさそうな点を考慮すると、有効活用することで業務効率化にも繋げられそうに思います。

今後のアップデートに期待ですね。
JavaでXMLをファイルに出力したい

JavaでXMLをファイルに出力したい場合はTransformerを利用します。

https://docs.oracle.com/javase/jp/8/docs/api/javax/xml/transform/Transformer.html

例: メモリ上で構築したXMLをfruits.xmlに出力する。

```java
// XMLをメモリ上で構築する。
Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();

Element e1 = document.createElement("element1");
e1.setAttribute("name", "ELEMENT1");
document.appendChild(e1);

Element e2 = document.createElement("element2");
e2.setAttribute("name", "ELEMENT2");
e1.appendChild(e2);

Element e3 = document.createElement("element3");
e3.setTextContent("ELEMENT3");
e2.appendChild(e3);

Element e4 = document.createElement("element4");
e4.setTextContent("ELEMENT4");
e1.appendChild(e4);


// XMLをファイルに出力する。
Transformer transformer = TransformerFactory.newDefaultInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.transform(new DOMSource(document), new StreamResult(new File("output.xml")));
```

これを実行すると、以下のようなoutput.xmlが作成されるはずです。

```output.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<element1 name="ELEMENT1">
    <element2 name="ELEMENT2">
        <element3>ELEMENT3</element3>
    </element2>
    <element4>ELEMENT4</element4>
</element1>
```

出力時のオプションはTransformer.setOutputPropertyで指定します。今回はINDENT=yesとすることで、Pretty Printしています。なお、このメソッドで指定できるプロパティはOutputKeysクラスに定数定義されています。

https://docs.oracle.com/javase/jp/8/docs/api/javax/xml/transform/OutputKeys.html

**環境情報**

```
C:\>javac -version
javac 17.0.3

C:\>java -version
openjdk version "17.0.3" 2022-04-19
OpenJDK Runtime Environment Temurin-17.0.3+7 (build 17.0.3+7)
OpenJDK 64-Bit Server VM Temurin-17.0.3+7 (build 17.0.3+7, mixed mode, sharing)
```
'--jsx'フラグが指定されていないと、JSXを使用できません。

# JSXの設定箇所についての理解
JSXの設定箇所を誤りタイトル通りの問題が発生したので、忘れないように記録しておく。

### tsconfig.jsonのオプション(修正前)

```json:tsconfig.json
{
  "compilerOptions": {
    "target": "es2020", 
    "module": "esnext",
    "moduleResolution": "node",
    "allowJs": true,
    "outDir": "./dist", 
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true, 
    "strict": true, 
    "noImplicitAny": false,  
    "noImplicitThis": false, 
    "skipLibCheck": true 
  },
  "jsx": "react-jsx", 
  "ts-node": {
    "esm": true,
  },
  "include": [
    "./src/**/*.ts",
    "./src/**/*.tsx"
  ]
}
```

### tsconfig.jsonのオプション(修正後)

```json:tsconfig.json
{
  "compilerOptions": {
    "jsx": "react-jsx", 
    "target": "es2020", 
    "module": "esnext",
    "moduleResolution": "node",
    "allowJs": true,
    "outDir": "./dist", 
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true, 
    "strict": true, 
    "noImplicitAny": false,  
    "noImplicitThis": false, 
    "skipLibCheck": true 
  },
  "ts-node": {
    "esm": true,
  },
  "include": [
    "./src/**/*.ts",
    "./src/**/*.tsx"
  ]
}
```

### JSXについて学んだこと
JSXはXMLとJavaScriptの混在した構文なので、TypeScriptに変換する為にはプロパティについて定義されている**compilerOptions**内に設定を記載する必要があるそうです。
SQLの基本を学ぶ

# SQLの基本

SQL文を知ならばまずは「データベース」について学びましょう。

## データベースとは

データベースとは一言で言えば**一定の形式で整理されたデータの集まり** を指します。

## SQLとは

大量のデータを保持しているデータベースに対して、情報を取り出したり、データを追加、更新、削除ができる言語になります。

データベースを操作するためにSQL文があります。

最近では、非常に大量のデータを扱うことが普通になっています。

どんなサービスでもデータベースを使用しており、SQL文を使うと、簡単にデータの取得などができます。

ぜひとも学びしょう。

## SQL基本命令文

SQLは基本の命令は**4つ** の命令文になります。

- SELECT・・・データを取得する命令
- INSERT・・・データを追加する命令
- UPDATE・・・データを更新する命令
- DELETE・・・データを削除する命令

### SELECT

SELECTはデータベースからデータを取得する命令になります。

データを取得するコマンドになります。

SELECTを使用することでデータベースに登録されている情報を閲覧できます。

> SELECT [要素] FROM [テーブル名];

### INSERT

INSERTは、データを追加する命令になります。

データを追加するコマンドになります。


> INSERT INTO [テーブル名] (要素1,要素名2) VALUES(要素1に入れるデータ,要素2に入れるデータ);

### UPDATE

UPDATEは既存データの更新を行います。

データを更新するコマンドになります。

> UPDATE [テーブル名] SET = [更新処理];

### DELETE

DELETEはデータを削除します。

データを削除するコマンドになります。

> DELETE FROM [テーブル名];
はんだづけの練習のための金属探知機キット(Ⅰ)を組み立てよう

中華電子工作キットシリーズです。

小さな金属探知機のキットです。
このタイプはボタン電池1個で動作、検出したら音が鳴ります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/9bb1ce82-1897-5ed2-e6c6-b20105c0b74e.png)

Tmall で、現地価格で200円ぐらいです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/a7ac89fd-4776-737f-c6ea-39f82ca1be43.png)


部品一覧
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/9c4c3635-861c-d535-c097-49ef5fc78053.png)


回路図は、販売している会社のページに掲載されていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/d6a26ed8-8bc1-2ca0-7eef-aab9671bec80.png)

# 作ってみよう!


背の低い部品からはんだづけしていきます。まずは抵抗。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/6bfff6b6-e62b-d555-1201-2f9d106c246f.png)

抵抗とコンデンサを取り付けたところ。
R1が赤赤黃金、R2が赤赤赤金です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/0d3c71b0-e9b7-a363-2ab6-406a67f8b6f1.png)

緑のコンデンサを取り付けます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/a1a06998-9836-468e-5442-bdd7fee77718.png)

トランジスタを取り付けます。数字を待ちがわないように注意!
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/98cc53f8-ac36-7b80-3cd5-00fd34fb811a.png)

電解コンデンサ、スイッチ、ボリューム、ブザーを取り付けます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/af4b127e-fb0f-6b25-788e-5ad5b063b1b0.png)

電池ホルダーをはんだづけします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/4c34ba8e-d4c7-1d3b-5e9a-784486cabaa7.png)
ブザーの保護紙をはがしておきましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/ebc5becd-aef3-a62b-609a-24e5c1fd7353.png)

アンテナコイルを部品の足などを利用して工夫して取り付けます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/df26cc24-207d-a14a-ea71-04b76ac23a51.png)

完成!

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/7f686c2c-1988-5750-eabb-54b8daa19232.png)

# 調整

半固定抵抗を回して、音がならないギリギリのところに設定しておきます。
10円玉などをアンテナコイルに近づけると音が鳴ることを確認します。
Q#でプロジェクト作成メモ

# まえがき

プロジェクト構成についてメモを記載。

# ディレクトリ構成:

```bash
/src
 ┝ /libs               # このプロジェクトの共通機能などのQ#ファイルを管理
 │   ┝ Library.qs
 │   ...
 │   └ libs.csproj
 ┝ /example            # EntryPointになるプロジェクト
 │   ┝ Program.qs
 │   ...
 │   └ example.csproj
 ┝ /exampletests        # 単体テスト用プロジェクト
 │   ┝ Tests.qs
 │   ...
 │   └ exampletests.csproj
```

# 作成方法:

各プロジェクトの作成手順と参照手順を以下のコマンドで行う
```bash
# step 1. ライブラリ用のプロジェクトを作成(libsは適当な名前）
 dotnet new classlib -lang Q# -o libs

# step 2. プロダクト用プロジェクトを作成(xampleは適当な名前)
 dotnet new console -lang Q# -o xample

# step 3. 単体テスト用プロジェクトを作成(xampletestsは適当な名前)
 dotnet new xunit -lang Q# -o xampletests

# step 4. プロダクトプロジェクトと単体テストプロジェクトからライブラリ用プロジェクトの参照できるようにする。
 dotnet add xample reference libs
 dotnet add xampletests reference libs

# プロダクトプロジェクトの単体テストしたい場合は以下のように追加する
 dotnet add xampletests reference xample
```
【JavaScript】TypeError: Cannot read properties of undefined (reading 'JsonRpcProvider')

# エラー内容
smart contract を利用したプロジェクト開発の際に、
```
> npx hardhat test
```
と行ったとき、
```
TypeError: Cannot read properties of undefined (reading 'JsonRpcProvider')
```
から始まるエラーが出る。

# 解決策

2024年1月現在、``ether.js``のversion6以降はNodeJS上で正しく動作しない。
これについて議論された2023年2月の[記事](https://ethereum.stackexchange.com/questions/144381/ethersjs-listening-to-events-with-nodejs-strange-errors)があるが、どうやらまだ修正には至っていないようだ。
[``ether.js``のdocs](https://www.npmjs.com/package/ethers?activeTab=versions)を見る限り、最も安定したバージョンは``5.7.2``のようだ。というわけで、
```
> npm install ethers@5.7.2 --save
```
を実行すると、見事にエラーが消えた。
Virtuoso (VOS) にODBCを用いてSPARQLで問い合わせる

トリプルストアの[Virtuoso Open-Source Edition (VOS)](https://vos.openlinksw.com/owiki/wiki/VOS)に対しては多くの場合、SPARQLエンドポイントとしてHTTP(S)を用いてアクセスし、所望のデータを取得する。しかし、検索対象のデータサイズが大きい場合、特に複雑なクエリや大量の結果が得られるクエリの処理に時間がかかり、タイムアウトすることがある。一方でVOSはODBCに対応しているので、これを利用して問い合わせると検索時間が短く、SPARQLエンドポイント経由では取得できないクエリでも結果が得られることが多い。
なお、ODBCを利用してアクセスするまでに必要な作業はOSごとに異なるので、今回はLinuxを対象とし、pythonのpyodbcを利用した手順を記載する。管理者権限は不要。今回動作確認した環境は以下の通り。

* VOS 7.2.6
* CentOS7
* Python 3.9.6
* pyodbc-5.0.1

# 1. VOSのODBCドライバの存在を確認する
VOSをダウンロードして適切に配置すると、`lib/virtodbcu_r.so` が置かれるので、確認する。

# 2. .odbc.ini を設置する
下記の内容と同等の項目を記載したファイル `.odbc.ini` を `${HOME}` 直下に置く。`[`と`]`に囲まれた冒頭部分の文字列は、後にPythonスクリプト内で利用するための識別子になる。また、`Description`の内容は任意。`Driver`に対しては、VOS配置後に置かれる`virtodbcu_r.so`の絶対パスを記載する。`Address`はSPARQLで問合せたいVOSのネット上の所在を記載する。なお、本記事で`21650`としているポート番号は、特に`virtuoso.ini`を編集するなどしない限り、`1111`が初期値である。さらに、プログラムとVOSの間でやり取りする際に用いる文字コードに関する設定として`wideAsUTF16`に対する値を`Y`とする。参考文献として[VOS開発元による記事](https://docs.openlinksw.com/virtuoso/virtmanconfodbcdsnunix/
)がある。
```
[MyVirtuosoDSN]
Description = Virtuoso ODBC Data Source
Driver      = /data/vos726/lib/virtodbcu_r.so
Address     = localhost:21650
wideAsUTF16 = Y
```

# 3. pyodbcをインストールする
[こちら](https://pypi.org/project/pyodbc/)を参照するなどしてインストールする。通常は、`pip install pyodbc`で事足りるが、環境によっては[pyodbcの文書](https://github.com/mkleehammer/pyodbc/wiki/Install#installing-on-linux)に書かれている通り、次のようなエラーが生じることがある。
```
ImportError: libodbc.so.2: cannot open shared object file: No such file or directory
```
その場合は同文書に書いてある通り、下記の要領で`unixodbc`をインストールする。この作業は残念ながら管理者権限が必要になるので、sudoersではないなら適宜権限のある利用者にお願いする。
```
$ sudo apt install unixodbc
```
もしくは
```
$ sudo yum -y install unixODBC unixODBC-devel
```

# 4. プログラムを書いてみる
下記のプログラム(`query_vos.py`)などを参考に、動作確認プログラムを書く。`conn_string`に与える文字列冒頭部分に、`DSN=MyVirtuosoDSN`と書かれているが、これを、上記の`.odbc.ini`冒頭部に書かれている内容と一致させることが重要。また、SPARQLクエリをVOSに認識させるためには、クエリの冒頭に、`SPARQL`と記載する。そうでない場合は、SQLクエリとして認識される。
```python
import pyodbc

# ODBC接続の準備
conn_string = "DSN=MyVirtuosoDSN;UID=dba;PWD=dba"
conn = pyodbc.connect(conn_string)

# やり取りする文字コードの設定 (pyodbc 5では不要)
conn.setdecoding(pyodbc.SQL_CHAR,  encoding="utf-8")
conn.setdecoding(pyodbc.SQL_WCHAR, encoding="utf-8")
conn.setencoding(encoding="utf8")

# カーソル生成
cursor = conn.cursor()

# クエリ実行
query = 'SPARQL select distinct ?class {[] a ?class}'
cursor.execute(query)

# 結果の表示
for row in cursor.fetchall():
    print(row)

# 接続の解除
conn.close()
```
# 5. 起こりがちなエラーとその原因
#### a. `.odbc.ini`が適切に配置されていない場合は以下のエラーメッセージが表示される。
```
Traceback (most recent call last):
  File "query_vos.py", line 7, in <module>
    conn = pyodbc.connect(conn_string)
pyodbc.InterfaceError: ('IM002', '[IM002] [unixODBC][Driver Manager]Data source name not found, and no default driver specified (0) (SQLDriverConnect)')
```
#### b. 文字コード周りの設定が適切になされていない場合は、以下のエラーメッセージが表示される。
```
Traceback (most recent call last):
  File "query_vos.py", line 18, in <module>
    cursor.execute(query)
pyodbc.ProgrammingError: ('42000', '[42000] [OpenLink][Virtuoso ODBC Driver][Virtuoso Server]SQ074: Line 1: Too many closing parentheses (-1) (SQLExecDirectW)')
```
docker-composeでコンテナ作成(redmine)

6年前にCentOS7.6で構築した検証環境をubuntu22.04.3TLSへ移行するのでメモ

### 環境
仮想化：VMware Workstation-playre17またはVMware workstation-pro17
ホスト：Windows10またはWindows11pro（どちらも確認済み）
ゲスト：ubuntu22.04.3TLS
↓環境構築時メモ
[VMでWindowsホストにUbuntuをゲスト起動する](https://qiita.com/38pinn/items/a136ed43457562c8471d)
[dockerコンテナ環境作成](https://qiita.com/38pinn/items/92a65ea162098f7a9859)

### docker-composeでRedmineコンテナ作成
``` sh:Redmine用のディレクトリ作成
$ mkdir docker-redmine
```
``` sh:作成したディレクトリへ移動
$ cd docker-redmine
```
``` sh:$ vi docker-compose.yml（ファイル作成：8081は他のコンテナと重複しないportを適宜指定）
services:
  redmine:
    image: redmine:5.0.4-bullseye
    ports:
      - 8081:3000
    environment:
      REDMINE_DB_POSTGRES: redmine-db
      REDMINE_DB_DATABASE: redmine
      REDMINE_DB_USERNAME: redmine_user
      REDMINE_DB_PASSWORD: redmine_password
      REDMINE_SECRET_KEY_BASE: supersecretkey
      REDMINE_DB_PORT: 5432
    volumes:
      - vol_redmine:/usr/src/redmine/files

  redmine-db:
    image: postgres:15.1-bullseye
    ports:
      - 5432:5432
    environment:
      POSTGRES_DB: redmine
      POSTGRES_USER: redmine_user
      POSTGRES_PASSWORD: redmine_password
    volumes:
      - vol_redmine_db:/var/lib/postgresql/data

volumes:
  vol_redmine:
  vol_redmine_db:
  
``` 
``` sh:Docker Composeを使ってRedmineをバックグラウンドで起動
$ sudo docker-compose up -d
```
``` sh:すべてのDockerコンテナの状態を表示
$ sudo docker ps -a
```
### Remine　WEBUIへアクセス
http://ホストのアドレス:設定したport番号
初期ログインID/PWはadmin/admin
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/340841/889d216b-11cd-071b-36a6-641ae0640c93.png)

``` sh:dockerコンテナの状態確認とログ確認
$ sudo docker ps -a
$ sudo docker logs <container ID>
```

### 参考にしたページ

### 当方の環境での設定log

[redmine_ubuntu_install_log　正常ログ](https://github.com/38pinn/miwa/blob/master/redmine_ubuntu_install_log)
AWS Data Provider for SAPのアクセス許可ポリシーを作成する。SAP on AWS ハンズオン①


### ソース
技術的要件
https://docs.aws.amazon.com/sap/latest/general/data-provider-req.html#data-provider-iam-roles

### PAS試験用まとめ

- 必要な権限
EC2:DescribeInstances→インスタンスのパラメータを一覧表示する
EC2:DescribeVolumes→EBSボリュームのパラメータを一覧表示する
cloudwatch:GetMetricStatistics→CloudWatchメトリクスのデータポイントを取得する
s3:GetObject→対象のS3バケットからオブジェクトを取得する

cloudwatch:GetMetricStatisticsに関しては以下。
https://dev.classmethod.jp/articles/get-data-points-for-cloudwatch-metrics-with-api/

DescribeInstancesは単なるインスタンスの一覧ではなく、インスタンスのパラメーターなど説明要素を返してもらう、だからDescribeなんですね。

公式のレスポンス例がわかりやすいです。
https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeInstances.html#:~:text=eyJOZXh0VG9rZW4iOiBudWxsLCAiYm90b190cnVuY2F0ZV9hbW91bnQiEXAMPLE%3D%0A%26AUTHPARAMS-,%E4%BE%8B%202%3A%20%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9%E3%81%AE%E8%AA%AC%E6%98%8E,-%E3%81%93%E3%81%AE%E4%BE%8B%E3%81%A7%E3%81%AF

### ポリシーの作成

マネジメントコンソール→IAM→ポリシー→ポリシーの作成→JSON

以下貼り付けJSON。

``` json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "EC2:DescribeInstances",
                "cloudwatch:GetMetricStatistics",
                "EC2:DescribeVolumes"
            ],
            "Resource": "*"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": "s3:GetObject",
            "Resource": [
                "arn:aws:s3:::aws-sap-dataprovider-ap-northeast-1/config.properties"
            ]
        }
    ]
}
```

上記を貼り付けして、ポリシーの作成で完了。

### 次にやること

完成したポリシーをIAMロールにアタッチする。
作成したIAMロールをEC2へアタッチする。
実行済みのDockerコンテナに後からポート公開設定を行う

実行済み（docker runした後）のDockerコンテナのポートを直ぐに公開したくなることがたまにある。
Dockerfileを作成するために、ベース（FROMで指定するDockerイメージ）のコンテナをdocker runで起動し、実際にパッケージのインストールなどを行いながら、Dockerfileにコマンド行を追加して行く作業は普通に行われることだと思う。
その途中にコンテナのポートを公開したくなったら、通常は以下の手順を経ることになる。

- 一旦docker commitでDockerイメージとして保存
- 現在のコンテナを停止＆削除
- 保存したDockerイメージをdocker runで起動する際に-pオプションでポート公開を設定

上記手順は1回だったら我慢できるが、それ以上は無駄で時間が掛かる作業が我慢できなくなる。

そこで市井の情報を漁ったところ、「[iptablesでfirewall設定~Dockerのポートフォワードを後から変える方法~](https://momozo.tech/2020/05/16/iptables%E3%81%A7firewall%E8%A8%AD%E5%AE%9Adocker%E3%81%AE%E3%83%9D%E3%83%BC%E3%83%88%E3%83%95%E3%82%A9%E3%83%AF%E3%83%BC%E3%83%89%E3%82%92%E5%BE%8C%E3%81%8B%E3%82%89%E5%A4%89%E3%81%88%E3%82%8B/)」が見つかった。
上記サイトを参考として、実行済みのDockerコンテナのポート公開設定を行うスクリプトを作成したので共有する。

※使い方はスクリプト内の usage: ～ \_\_USAGE\_\_ の間のメッセージを参照

```bash:dkport.sh
#!/bin/bash

# ref: https://momozo.tech/2020/05/16/iptables%E3%81%A7firewall%E8%A8%AD%E5%AE%9Adocker%E3%81%AE%E3%83%9D%E3%83%BC%E3%83%88%E3%83%95%E3%82%A9%E3%83%AF%E3%83%BC%E3%83%89%E3%82%92%E5%BE%8C%E3%81%8B%E3%82%89%E5%A4%89%E3%81%88%E3%82%8B/

if [ "$1" = "-s" ]; then
        echo "*** nat table ***"
        sudo iptables -t nat -S DOCKER | sed "/^-N/d" | sed "/RETURN$/d"
        echo "*** filter table ***"
        sudo iptables -t filter -S DOCKER | sed "/^-N/d"
        exit 0
fi

if [ "$3" = "" ]; then
        cat <<__USAGE__
usage:
  - show tables
    $0 -s
  - expose port
    $0 <running container> <source host port> <destination container port>
  - delete setting
    $0 <running container> <source host port> <destination container port> -d
__USAGE__
        exit 1
fi

option="-A"
optname="expose"
if [ "$4" = "-d" ]; then
        option="-D"
        optname="delete"
fi

set -euo pipefail

container=$1
srcport=$2
destport=$3

ipaddr=`docker inspect --format '{{ .NetworkSettings.IPAddress }}' $container`

sudo iptables -t nat $option DOCKER ! -i docker0 -p tcp -m tcp \
        --dport $srcport -j DNAT --to-destination $ipaddr:$destport
sudo iptables -t filter $option DOCKER -d $ipaddr/32 ! -i docker0 -o docker0 \
        -p tcp -m tcp --dport $srcport -j ACCEPT

echo "$optname: host $srcport -> $container $ipaddr:$destport"

exit 0
```

なお、docker container portでコンテナの公開ポートを表示することはできない。
また、コンテナを停止しても、dkport.shで追加したiptablesの設定は削除されない。

#### Docker Desktop for Windowsの話

Windowsの場合、netshコマンドで同様のことができるだろうと思い調べたところ、以下のドキュメントに記載の通り、ホストからアクセス可能なIPアドレスがLinuxコンテナに割り当てられないことが分かった。
Windowsコンテナには割り当てられるようだが、Windowsコンテナは個人的に使い道がない。

https://docs.docker.jp/docker-for-windows/networking.html

docker inspectでLinuxコンテナの情報を見ると、確かにNetworkSettings.IPAddressが空になっていることが分かる。
mac初心者が覚えたショートカットキーまとめ

## 概要
前職でも個人PCもwindowsを使っていたが、転職を機に仕事でmacbookを使うことになったため、macを操作する中で調べたショートカットキー（設定も含む）をまとめるための備忘録。
※Windowsと操作感が違うと感じたもののみ記載しています。

## キーボード設定（方法は各項目を開いて確認）
###### 1. CapsLockキーにCommand(⌘)を割り当て
|①`システム環境設定`を開く<br>②`キーボード`を選択<br>③`キーボードショートカット`を開く<br>④左メニューの`修飾キー`を選択<br>⑤CapsLockキーの割り当てをCommand(⌘)に変更|
|:-|

###### 2. 文字入力の設定
|①`システム環境設定`を開く<br>②`キーボード`を選択<br>③`入力ソース`を開く<br>④`ライブ変換`のチェックを外す（※）<br>⑤`Windows風のキー操作`にチェック（Enterキーを2回押す手間が省ける）|
|:-|
※「ライブ変換」は文脈を見て自動的に変換してくれるmacの機能

###### 3. F1、F2などのキーの設定変更
|①`システム環境設定`を開く<br>②`キーボード`を選択<br>③`F1、F2などのすべてのキーを標準のファンクションキーとして使用`にチェック|
|:-|

## ショートカットキー
#### 文書系
| 操作 | 動き |
| :---- | :---- |
| fn + ← | 文章の始めにカーソル移動 |
| fn + → | 文章の終わりにカーソル移動 |
| fn + BackSpace<br>Ctrl + D | カーソルの右側の文字を削除<br>（windowsのdeleteキーと同じ動き） |

#### アプリケーション系
| 操作 | 動き |
| :---- | :---- |
| Command(⌘) + Tab | アプリケーションの切り替え（windowsの Alt+Tab） |
| Command(⌘) + @ | 同じアプリケーション内でのウィンドウの切り替え |
| Command(⌘) + N | 新しいウィンドウを開く |
| Command(⌘) + T | 新しいタブを開く |
| Command(⌘) + Shift + N | 新しいシークレットウィンドウを開く |
| Command(⌘) + Q | アプリケーションを終了する |
| Command(⌘) + Ctrl + Q | 画面ロック |
| Command(⌘) + Option + ← | 前のタブに移動 |
| Command(⌘) + Option + → | 次のタブに移動 |

## トラックパッド操作
| 操作 | 動き |
| :---- | :---- |
| 指1本でタップ | 左クリック |
| 指2本でタップ | 右クリック |
| 指2本で上下にスワイプ | 画面を上下にスクロール |
| 指2本で左右にスワイプ | 前/次の画面に移動 |
| 指2本を離す動作（ピンチアウト） | 画面の拡大 |
| 指2本を近づける動作（ピンチイン） | 画面の縮小 |
| 指2本を近づける動作（ピンチイン） | 画面の縮小 |
| 親指と指3本でピンチイン | アプリケーション一覧を表示 |
| 指4本(3本)で上にスワイプ | ミッションコントロール起動<br>※現時点で開いているウィンドウやアプリを表示 |
| 指2本を近づける動作（ピンチイン） | 画面の縮小 |
軽微な修正を一つのCommitにまとめる手順メモ


## プチストレス
以下のように変更し、`git push`してCI/CDを走らせたらエラーになることがよくある。

```bash
git log --online

6d76d86 機能を追加した
2e125f9 first
6d95b84 Initial
```

typoなど本題ではない原因の場合、それを修正して無意味なコミットが残るのが嫌である。
ちょっとした修正コミットをまとめる。

## 手順
軽微な修正をコミットするときに`--fixup`オプションをつける。
```bash
git commit --fixup 6d76d86
````

`fixup!`がコミットメッセージにつく。
```bash
git log --oneline

eb483e5 (HEAD -> main) fixup! 機能を追加した
6d76d86 機能を追加した
2e125f9 first
6d95b84 Initial
```

rebaseを実行(まとめたいコミットたちの直前のコミットを指定)。
```bash
git rebase -i --autosquash 2e125f9
```
`6d76d86`以降のコミットが並んでいるテキストがエディタが開くので`:wq`で保存。
`pick`, `fixup`の行を変更することで複数コミットをまとめることもできそうだが、今回はシンプルに直前のとまとめただけなので特に変更なしで保存。

まとまる。
```bash
git log --oneline
df299c4 (HEAD -> main) 機能を追加した
2e125f9 first
6d95b84 Initial
```
`git push -f` すればリモートにも反映できる。みんなでやっているときはやらない方が良い。
RLogin のカラー設定メモ

自分用のメモです。
ssh クライアントは RLogin を使っているのですが、カラー設定にいつも悩まされるので。

https://kmiya-culti.github.io/RLogin/

# 自分が設定している Windows Terminal と同じ感じにする場合

元ネタは [gist](https://gist.github.com/landwarrior/0003b364ff8251cf21af5e41560b8dad) に用意した Campbell2 だけど、とりあえずぱっと見同じ感じになるように調整。
どこに適用されるのか分からないものがあるので、それはおいおい。

| No | Red | Green | Blue | No | Red | Green | Blue |
|:---|---:|---:|---:|:---|---:|---:|---:|
| 0 | 44 | 44 | 44 | 8 | 117 | 113 | 94 |
| 1 | 249 | 38 | 114 | 9 | 240 | 60 | 78 |
| 2 | 132 | 247 | 125 | 10 | 21 | 196 | 17 |
| 3 | 244 | 191 | 117 | 11 | 240 | 169 | 69 |
| 4 | 55 | 105 | 255 | 12 | 94 | 170 | 227 |
| 5 | 174 | 129 | 255 | 13 | 126 | 51 | 255 |
| 6 | 161 | 239 | 228 | 14 | 95 | 227 | 210 |
| 7 | 161 | 212 | 181 | 15 | 249 | 248 | 245 |

# 文字色を黄色にしたい場合

自分の場合はスタブとして構築した VM に使ってます。
色々変えてたけど、面倒になって文字色だけ変えました。

| No | Red | Green | Blue | No | Red | Green | Blue |
|:---|---:|---:|---:|:---|---:|---:|---:|
| 0 | 44 | 44 | 44 | 8 | 117 | 113 | 94 |
| 1 | 249 | 38 | 114 | 9 | 240 | 60 | 78 |
| 2 | 132 | 247 | 125 | 10 | 21 | 196 | 17 |
| 3 | 244 | 191 | 117 | 11 | 240 | 169 | 69 |
| 4 | 55 | 105 | 255 | 12 | 94 | 170 | 227 |
| 5 | 174 | 129 | 255 | 13 | 126 | 51 | 255 |
| 6 | 161 | 239 | 228 | 14 | 95 | 227 | 210 |
| 7 | 255 | 237 | 106 | 15 | 249 | 248 | 245 |

# Dev 環境用

| No | Red | Green | Blue | No | Red | Green | Blue |
|:---|---:|---:|---:|:---|---:|---:|---:|
| 0 | 40 | 30 | 17 | 8 | 117 | 113 | 94 |
| 1 | 249 | 38 | 114 | 9 | 240 | 60 | 78 |
| 2 | 132 | 247 | 125 | 10 | 21 | 196 | 17 |
| 3 | 244 | 191 | 117 | 11 | 240 | 169 | 69 |
| 4 | 55 | 105 | 255 | 12 | 94 | 170 | 227 |
| 5 | 174 | 129 | 255 | 13 | 126 | 51 | 255 |
| 6 | 161 | 239 | 228 | 14 | 95 | 227 | 210 |
| 7 | 206 | 181 | 156 | 15 | 249 | 248 | 245 |

# Stg 環境用

| No | Red | Green | Blue | No | Red | Green | Blue |
|:---|---:|---:|---:|:---|---:|---:|---:|
| 0 | 17 | 30 | 40 | 8 | 117 | 113 | 94 |
| 1 | 249 | 38 | 114 | 9 | 240 | 60 | 78 |
| 2 | 132 | 247 | 125 | 10 | 21 | 196 | 17 |
| 3 | 244 | 191 | 117 | 11 | 240 | 169 | 69 |
| 4 | 55 | 105 | 255 | 12 | 94 | 170 | 227 |
| 5 | 174 | 129 | 255 | 13 | 126 | 51 | 255 |
| 6 | 161 | 239 | 228 | 14 | 95 | 227 | 210 |
| 7 | 156 | 181 | 206 | 15 | 249 | 248 | 245 |

# 本番環境用

| No | Red | Green | Blue | No | Red | Green | Blue |
|:---|---:|---:|---:|:---|---:|---:|---:|
| 0 | 40 | 17 | 30 | 8 | 117 | 113 | 94 |
| 1 | 249 | 38 | 114 | 9 | 240 | 60 | 78 |
| 2 | 132 | 247 | 125 | 10 | 21 | 196 | 17 |
| 3 | 244 | 191 | 117 | 11 | 240 | 169 | 69 |
| 4 | 55 | 105 | 255 | 12 | 94 | 170 | 227 |
| 5 | 174 | 129 | 255 | 13 | 126 | 51 | 255 |
| 6 | 161 | 239 | 228 | 14 | 95 | 227 | 210 |
| 7 | 206 | 156 | 181 | 15 | 249 | 248 | 245 |
ネットワーク層とリンク層：データ通信の根幹を理解する 🌐✨



## 🚀 リンク層の深掘り: データ通信の基礎 🔍

ネットワークの基本を理解するには、リンク層の役割を詳細に把握することが不可欠です。この層は、ネットワークデバイスの物理的な接続とデータの転送に関わります。

### 1. スイッチングハブの機能と重要性 🔄
スイッチングハブは、ネットワーク内のデバイス間でデータパケットを転送する中心的なデバイスです。各ポートに接続されたデバイス間で、データパケットを効率的に送り届けます。これにより、ネットワークトラフィックの混雑を防ぎ、通信速度を向上させることができます。

### 2. MACアドレスの構造と機能 🏷️
MACアドレスは、ネットワークインターフェースカード（NIC）に割り当てられた一意の識別子であり、通常は6バイト（48ビット）の長さを持っています。このアドレスは、デバイスが製造元によってユニークに割り当てられ、ネットワーク上でデバイスを識別するために使用されます。MACアドレスの構造は、先頭3バイトがOUI（Organizationally Unique Identifier）を表し、残りの3バイトが製造元によって指定されるデバイス固有の番号で構成されています。

このMACアドレスを使用することで、ローカルネットワーク内で異なるデバイスを一意に識別することができます。例えば、次のMACアドレスはこの構造を示しています：

- MACアドレス: 00:1A:2B:3C:4D:5E

この中で、"00:1A:2B"はOUIを表し、"3C:4D:5E"は製造元によって指定されるデバイス固有の番号です。このように、MACアドレスはネットワークデバイスの一意の識別子として重要な役割を果たしています。

## 🌍 インターネット層: 異なるネットワークの接続 🕵️‍♂️

インターネット層は、異なるネットワーク間のデータ伝送を担当し、複雑なネットワーク構造の中での通信を可能にします。

### 1. ルータの役割と動作原理 🌉
ルータは、異なるネットワークセグメントを接続する装置であり、データパケットの送信先を決定します。ルータはデータパケットの宛先IPアドレスを解析し、内部のルーティングテーブルを使用して、そのパケットを最適な経路で送信します。これにより、異なるネットワーク間でのデータ伝送が可能になります。

### 2. IPアドレスの構造と分類 📌
IPアドレスは、インターネット上でのデバイス識別に使用される32ビットの数値です。通常、ドットで区切られた4つの8ビットの数値（例: 192.168.0.1）で表されます。IPアドレスには、ネットワーク部とホスト部があり、それぞれがネットワークの所在地と個別デバイスを識別します。IPv4とIPv6という2種類のIPアドレス体系が存在し、IPv6はより多くのデバイスをサポートするために開発されました。

## 🤝 まとめ: ネットワーク通信の基盤 🌐🤝🌍

リンク層とインターネット層は、ネットワーク通信の2つの重要な構成要素です。リンク層は物理的な接続とローカルなデータ転送を担い、インターネット層は異なるネットワーク間のデータ転送を担います。これらの層がうまく連携することで、インターネットをはじめとする多くのネットワーク通信がスムーズに行われています。
GoによるAPIエラーの返却

## はじめに
GoによるAPIエラーの返却について説明したい。

## そもそも何をエラーとして何を返却するか
参考にさせていただいたAPIエラーの返却内容
https://qiita.com/suin/items/f7ac4de914e9f3f35884

こちらを参考にすると、code,messageは入れておくのが定石みたいですね。エラー内容がわからなくなるので当然かと思います。ほかはサービスによって異なりますね。
個人的にはどこにアクセスしたかを知れるとデバッグで助かるので、urlは欲しいと思います。

## 実際にコードを見てみよう
下記は上の内容を踏まえて作成した、APIエラーを返却する１例です。

```
return func(w http.ResponseWriter, req *http.Request){
    if err != nil {
        apiError, _ := json.Marshal(map[string]interface{}{
            "code":    http.Status...,
            "message": http.StatusText...,
            "url": req.URL.String()
        })
        w.Header().Set("Content-Type", ...)
        w.WriteHeader(http.Status...)
        w.Write(apiError)
    } else { 
    ...
}
```
【zsh】aliasを使ってよく使うコマンドを短くしちゃおう！

## はじめに
ターミナルでよく打つコマンド、「なげぇなぁ...」と思ったことはないでしょうか？
僕は普段iOSをメインに触っているので、`pod install`とかもちょっと長いなとか思っていました。

他にも、よく開くファイル、いちいちGUIでコチコチ開くのもめんどくさい、かといってターミナルから開くのもコマンドが長い。そんなときに、便利なaliasを紹介します。

要するに`特定のコマンドに別名をつけられる`みたいなものです。
ではやっていきましょう。

## できるようになること
例) `pod install`というコマンドを`pi`というコマンドを打つことで発動できる

## この記事で説明すること
- zshを使用したaliasの作成方法

## 説明しないこと
- bashを使用したaliasの作成方法
- bashからzshに切り替える方法

## 環境
- MacBook Air M2
- macOS Sonoma 14.1

## 手順
### ①使ってるシェルの種類を確かめる
ターミナルで以下のコマンドを実行
```
$ echo $SHELL
```
以下のように表示されれば、`zsh`を使用しているのでこのまま手順②へと進んでください。

もし`/bin/bash`と表示されたら`bash`を使用しているので、zshの切り替えを行うか`bash`のalias設定をしてください。これについてはこの記事では説明していません。

### ②設定ファイルの有無を確認
ターミナルで以下のコマンドを実行
- ルートディレクトリへの移動
```
$ cd
```

- 隠しファイルを含めて表示
```
$ ls -a
```

以下のファイルがあるかを確認してください
```
.zshrc
```

すでにあれば手順③に進んでください。

該当ファイルがない場合は以下のコマンドを実行
- .zshrcファイルの作成
```
$ touch .zshrc
```

もう一度`ls -a`コマンドを実行すると、`.zshrc`ファイルが作成されていることを確認できると思います。

### ③aliasの設定
#### `.zshrc`ファイルを開く
```
$ open .zshrc
```

#### aliasの設定をする
以下のように書くことで`pod install`というコマンドを`pi`で実行できるようになります。自身の用途に合わせてアレンジしてください。
```
alias pi='pod install'
```
例えばデスクトップにある特定のファイルを開くコマンドは以下のようにaliasを設定することができます。
{ユーザー名}と{ファイル名}のところは自身の環境に合わせて設定してもらえればOKです

ようは`open { 開きたいファイルの絶対パス }`を設定するってことですね。

```
alias test='open /Users/{ユーザー名}/Desktop/{ファイル名}
```

#### ④ aliasの設定を読み込む
最後にターミナルで以下のコマンドを実行し、書き込んだaliasの設定を読み込むことで設定したaliasのコマンドを使用することができるようになります。何かの設定を`.zshrc`ファイルに書き込んだ後はこのコマンドを実行します。
```
$ source ~/.zshrc
```

#### ⑤alias設定したコマンドを使用する
あとはaliasで設定したコマンドをターミナルで実行すれば終わり。

## おわりに
このコマンドよく打つのに「なげぇな」ってやつにはぜひaliasを設定してみてください
ではでは！
プロトコルの基礎知識：共通ルールの重要性🌐


## はじめに
プロトコルは、コンピューター間の「共通の言語」のようなものです。これがなければ、機器同士のコミュニケーションは不可能になります。例えば、印刷機を使う際、プロトコルがないと、コンピューターから印刷指示を出しても、印刷機がそれを理解できません。🖨️

## プロトコルのレベル分け
プロトコルは、ハードウェアからアプリケーションまで、さまざまなレベルで設定されています。主な層は以下の通りです：

1. **アプリケーション層** - ソフトウェアの通信規約（例：HTTP, FTP）
2. **トランスポート層** - データの分割や再組み立て（例：TCP, UDP）
3. **インターネット層** - パケットの送受信（例：IP）
4. **リンク層** - ネットワーク機器間の物理的な通信（例：Ethernet）
5. **ハードウェア層** - 物理的なデバイスやケーブル（例：NIC, リピーター）

## ハードウェア層の詳細
ハードウェア層では、データを電気信号に変換するルールや、ケーブルの形状など、物理的な接続に関する基準が設定されています。

- **NIC（ネットワークインターフェースカード）**：コンピューターがネットワークに接続するための装置。
- **リピーター**：信号を増幅し、通信距離を延長する装置。
- **ハブ**：複数のデバイスを接続し、データを中継する装置。

ハードウェア層のプロトコルによって、異なるメーカーの機器でもスムーズに通信ができるようになっています。これがなければ、例えば、特定のメーカーのパソコンでしか有線LANを利用できないという状況になるでしょう。

## まとめ
プロトコルは、異なるコンピューターやデバイスが効率的に通信するための基盤を提供します。これにより、世界中のさまざまな技術が互換性を持ち、連携して動作することが可能になります。ハードウェア層からアプリケーション層に至るまで、この階層化されたプロトコルの設計は、現代のデジタルコミュニケーションの基礎を形成しています。🌍💻
bigqueryのwindow関数でNULLを無視する(dense_rank編)

### SQL

```sql
with
target as (
  select 1 as val union all
  select 1 as val union all
  select null as val union all
  select 2 as val union all
  select 3 as val union all
  select null as val union all
  select 4 as val union all
  select 4 as val
)
select
  val,
  case
    when val is null then null
    else dense_rank() over (order by val nulls last)
  end as dense_rank_val,
from
  target
```

### 結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196303/3a60c36a-b319-5793-c191-5d923bcc6985.png)

### ちょっと補足
構文的にはNULLを無視してランクを採番する方法がないので少しハマったのでメモ。
CASEによる人力判定とnulls lastを使えば何とかできる。
もっとスマートな方法がありましたら教えて下さい。
Docker: MongoDB を動かす

Ubuntu 24.04 で確認しました。

## インストール

```bash
docker run -itd \
        -e MONGO_INITDB_ROOT_USERNAME=scott \
        -e MONGO_INITDB_ROOT_PASSWORD=tiger123 \
        -p 27017:27017 \
        --name mongo \
        mongo 
```

動いていることを確認

```text
$ docker ps
CONTAINER ID   IMAGE     COMMAND                   CREATED       STATUS       PORTS                                           NAMES
a10d81c545bf   mongo     "docker-entrypoint.s…"   4 hours ago   Up 4 hours   0.0.0.0:27017->27017/tcp, :::27017->27017/tcp   mongo
```

## 停止

```bash
docker stop mongo
```

停止の確認

```text
$ docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
```


## 起動

```bash
docker start mongo
```

起動の確認

```text
$ docker ps -a
CONTAINER ID   IMAGE     COMMAND                   CREATED       STATUS          PORTS                                           NAMES
a10d81c545bf   mongo     "docker-entrypoint.s…"   4 hours ago   Up 11 seconds   0.0.0.0:27017->27017/tcp, :::27017->27017/tcp   mongo
```

## コンテナにログイン

```bash
docker exec -it mongo bash
```

```text
$ docker exec -it mongo bash
root@a10d81c545bf:/# which mongosh
/usr/bin/mongosh
```

## mongosh を使う

```text
root@cc71b629ee0b:/#  mongosh -u scott -p tiger123
Current Mongosh Log ID:	667a877744a92e9f67a26a12
Connecting to:		mongodb://<credentials>@127.0.0.1:27017/?directConnection=true&serverSelectionTimeoutMS=2000&appName=mongosh+2.2.6
Using MongoDB:		7.0.11
Using Mongosh:		2.2.6

For mongosh info see: https://docs.mongodb.com/mongodb-shell/

------
   The server generated these startup warnings when booting
   2024-06-25T08:59:42.178+00:00: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine. See http://dochub.mongodb.org/core/prodnotes-filesystem
   2024-06-25T08:59:42.788+00:00: Soft rlimits for open file descriptors too low
------

test>
```

バージョンの確認

```text
test> db.version()
7.0.11
```

データベースの表示

```text
test>  show dbs
admin   100.00 KiB
config   12.00 KiB
local    72.00 KiB
```