OmniAICreator/Qiita-1.07M huggingface dataset:
Neovimに反抗させて使いにくくする

:::note info
これは[Vim駅伝](https://vim-jp.org/ekiden/)の295本目の記事です。
:::

こんにちは、苔コッコーです。
今回は、Vimが邪魔してくるようにしました。なんでこんなことをしたのかはよくわかりません。
もちろんオンオフはできますが、邪魔でしか無いので導入することは推奨しません。

https://github.com/Kokecoco/interference.nvim

## 邪魔モードの概要

「邪魔モード」は、Neovimを意図的に邪魔をさせるネタプラグインです。実行すると、以下のような予測不能な動作がランダムで発生します。

1. **ランダムな色の変更**
2. **ランダムなスクロール**
3. **意味不明なエラーメッセージの表示**
4. **行の非表示（折りたたみ）**
5. **ランダムなファイルのオープン**
6. **1分ごとの休憩メッセージ**

## プラグインの設定

プラグインには柔軟な設定オプションが用意されています。デフォルトの設定は以下の通りです：

```lua
interference.config = {
  enable_colors = true,  -- ランダムな色の変更を有効化
  enable_scroll = true,  -- ランダムスクロールを有効化
  enable_errors = true,  -- エラーメッセージの表示を有効化
  enable_files = true,   -- ランダムなファイルを開く機能を有効化
  enable_break = true,   -- 休憩メッセージを有効化
  start_shortcut_key = "<leader>rb",  -- 開始のショートカットキー
  stop_shortcut_key = "<leader>rq"   -- 停止のショートカットキー
}
```

この設定は、`setup()`関数を使ってカスタマイズできます。


## 主な機能

以下は、プラグインが提供する主な邪魔機能の詳細です。
ちゃんと動かないのもありますが、それも含めて邪魔です。

### 1. ランダムな色の変更
背景色と文字色をランダムに変更し、視認性を意図的に損ないます。色が変わるたびに「こっちのほうが見やすいでしょ？」というメッセージが表示されます。

### 2. ランダムなスクロール
カーソル位置をランダムな行に移動させ、「ここが見たかったんだよね」というメッセージを表示します。

### 3. 意味不明なエラーメッセージの表示
リストからランダムに選ばれたユーモラスなエラーメッセージを表示します。

### 4. 行の非表示（折りたたみ）
ランダムな範囲の行を折りたたんで非表示にします。「その行、邪魔だったでしょ？」というメッセージが添えられます。

### 5. ランダムなファイルのオープン
現在のディレクトリからランダムなファイルを開きます。「気分転換にこっちを編集しよう！」というメッセージが表示されます。

### 6. 1分ごとの休憩メッセージ
1分ごとに「1分たったよ！そろそろ休憩しよう！」というメッセージを表示します。モーダル形式で作業をブロックすることで、強制的に休憩を促します。

## 実行と停止

プラグインを起動および停止するためのショートカットキーとコマンドが用意されています。

### ショートカットキー
- **開始**: `<leader>rb`
- **停止**: `<leader>rq`

### コマンド
- **`InterferenceStart`**: プラグインを開始。
- **`InterferenceStop`**: プラグインを停止。

## まとめ

「邪魔モード」は、Neovimのカスタマイズ性を活用したジョークプラグインであり、日常の編集作業にちょっとしたユーモアを加えるものです。興味がある方は、ぜひ試してみてください！

最後までお読みいただきありがとうございました。
Oculinkについて調べた

# はじめに

近日発表のNVIDIAのGPU、RTX5090は600Wクラスの消費電力となると言われ、PC本体の電源に対する要求も従来に比べ、非常に高くなることが予測されています。

また、グラボのサイズもRTX4090から巨大になっており、ケースも大きなサイズのものが必要とされています。

そこでグラボをPCケースから出して、外付けするという考えに至るのですが、Thunderboltは十分な性能が出ない、お高いという課題がありました。

この状況がなんとかならないものかと、調べていく過程で、Oculinkに出会いました。

https://tech-gadget.reinforz.co.jp/4678


# Oculinkとは

こちらに詳しいです。

https://monobook.org/wiki/OCuLink

PCI Express（PCIe）4レーンを延長するのが主流のようです。

PCIe １６レーンのスロットから延長するタイプや
M2スロット（PCIe４レーン）から延長するタイプのカードが販売されている。

ミニPC（小型PC）ではOculink端子を搭載した製品が多く発売されてきている

増設はDIY（自作）で、外付けGPU等ができ、非常に安価。
以前流行ったマイニングの１レーン延長のものよりもパフォーマンスが出ており、ゲームでは１割程度のフレームレートの低下で済んでいる様子。
StableDiffusionなど、AIはロード時間を除けば、パフォーマンスの低下はほとんどない。
ビデオエンコードでは半分程度までパフォーマンスが落ちている。
CPUーGPU間のデータ転送が多いビデオエンコード以外であれば、実用になる。

ホットスワップはできない。PC全体にダメージを与える可能性があるので、要注意。

# 今後

実際に購入して試してみる予定。

後継規格

https://news.mynavi.jp/techplus/article/20240506-2940215/
JavaScriptで元の値と変換方法を引数に取り、変換結果を返す関数

関数定義
```js
function mapObject(obj = null, mapper = function(obj){return obj}){
    return mapper(obj)
};
```

関数呼び出し例
```js
const x = mapObject(100, v => v * v);
console.log(x);
```
表示結果
```text
10000
```
Word, Excel を使った年賀状宛名作成

後から良いテンプレートも見つけた
https://qiita.com/takenawa/items/4e4cce3aa16eff0d00dd

一応シンプルな作り方の一例として載せる（主に Windows 向け）

### 住所録の xlsx と対応する docx の作成
- Word で適当な文書を開く or 新規文書
- 差し込み文書 > はがき印刷 > 宛名面の印刷
	- 「差し込み印刷を指定します」で「標準の住所録ファイル」を指定することで、住所録のフォーマットを作成
	- その後の設定はお好みで

### 住所録の xlsx の入力
- 郵便番号入力時に住所を自動入力
	- 日本郵便のサイトから CSV をダウンロード
		- https://www.post.japanpost.jp/zipcode/dl/utf-zip.html
		- Windows の場合、解凍後に UTF16 LE に変換する
	- CSV の必要な列をコピーし、追加したSheet（名前を ken_all に変更）にコピー
    	- C,H,I 列 を A,B,C 列にペースト
	- 入力したい場所に以下のような関数を記入
		- `=VLOOKUP($B2,ken_all!$A:$C,2,FALSE)`
		- 検索＆抽出範囲、範囲内で何列目か、FALSE（完全一致）
- ひたすら住所を打ち込む

### Word で印刷
- 差し込み文書 > 結果のプレビュー を押すことで、xlsx に基づくプレビューと設定を行き来できる
- 差し込み文書 > 差し込みフィールドの挿入 で、xlsx 内の列を変数として入力できる
- フォントや内容を綺麗に整えたら、差し込み文書 > 完了と差し込み > 文書の印刷 にて印刷する

### 参考
https://forest.watch.impress.co.jp/docs/serial/offitech/1375884.html
https://dime.jp/genre/1887292/
DeepSeek V3でbrowser-use-webuiを使ってみよう！

前回の記事「browser-use-webuiでブラウザ操作を自動化しよう！」の続編として、今回はDeepSeek V3を使用した実践的な方法を解説します。

https://hamaruki.com/automate-browser-with-browser-use-webui/

## DeepSeek V3の特徴

DeepSeek V3は、以下のような特徴を持つ強力な言語モデルです：

- 高性能なタスク遂行能力
- 日本語を含む多言語対応
- コスト効率の良い料金体系
- browser-useとの優れた相性

## セットアップ方法

### 2.1 環境変数の設定

.envファイルに以下の設定を追加します：

```bash
DEEPSEEK_ENDPOINT=https://api.deepseek.com
DEEPSEEK_API_KEY=your_api_key_here
```

### 2.2 APIキーの取得

1. DeepSeekの公式サイトでアカウントを作成
2. API設定ページからAPIキーを生成
3. 生成したキーを.envファイルに設定

## DeepSeek V3での実行方法

### 3.1 WebUI設定

1. LLM Providerで「deepseek」を選択
2. LLM Model Nameを「deepseek-chat」に設定
3. LLM Temperatureは0.7程度を推奨
4. 【重要】use visionのチェックは外す

<blockquote class="twitter-tweet" data-media-max-width="560"><p lang="ja" dir="ltr">browser-use-webui を DeepSeek V3で動かしてみた！<br>この安さなら普通に使えそう！！<br>＊Roo-clineに比べればめちゃ安い！！ <a href="https://t.co/GVK447A37e">https://t.co/GVK447A37e</a> <a href="https://t.co/JAHPsy4NXr">pic.twitter.com/JAHPsy4NXr</a></p>&mdash; Maki@Sunwood AI Labs. (@hAru_mAki_ch) <a href="https://twitter.com/hAru_mAki_ch/status/1875473888337150436?ref_src=twsrc%5Etfw">January 4, 2025</a></blockquote> 

### 3.2 実行時の注意点

DeepSeek V3使用時の重要な注意点：

1. **ビジョン機能の制限**
   - use visionをオンにするとJSONデシリアライズエラーが発生
   - 画像認識が必要な場合は他のモデルを使用

2. **プロンプトの最適化**
   - 日本語での指示は具体的かつ簡潔に
   - 複雑なタスクは段階的に分割して実行

## 実行例：Google検索タスク

実際にDeepSeek V3で以下のタスクを実行してみました：

```
Task: google.com にアクセスして「OpenAI」と入力し、検索をクリックして最初のページにアクセスして内容を教えてください
```

### 実行ステップの詳細

1. **Step 1: Google.comへの移動**
   - アクション: `go_to_url` を使用してGoogle.comに移動
   - 結果: 正常に移動完了

2. **Step 2: 検索クエリの入力**
   - アクション: `input_text` でインデックス10に「OpenAI」を入力
   - 結果: 検索バーに「OpenAI」が入力され、サジェストが表示

3. **Step 3: 検索の実行**
   - アクション: インデックス25の「Google 検索」ボタンをクリック
   - 結果: 検索結果ページに遷移

4. **Step 4: 最初の結果へのアクセス**
   - アクション: インデックス18（最初の検索結果）をクリック
   - 結果: OpenAIのChatGPTページに遷移

5. **Step 5: コンテンツの抽出**
   - アクション: `extract_content` でページ内容を取得
   - 結果: ChatGPTの概要ページの内容を取得

### 実行結果の分析

エージェントは以下の内容を抽出しました：
- ChatGPTの主な機能と特徴
- 無料版とPlus版の違い
- 様々なユースケース例

### 実装のポイント
- インデックスの適切な特定が重要
- 動的コンテンツの待機時間の考慮
- エラーハンドリングの実装

## まとめ

DeepSeek V3は、browser-use-webuiで効果的に利用できる強力なモデルです。適切な設定と最適化により、多くのタスクを効率的に自動化できます。特にビジョン機能以外の用途では、コスト効率の良い選択肢となっています。

## 参考文献

- browser-use公式ドキュメント
- DeepSeek API Documentation
- 前回の記事：「browser-use-webuiでブラウザ操作を自動化しよう！」

<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
local環境でdocker cognitoの環境を作成する

# local環境でdocker Cognitoの環境を作成する

## Motivation

local stackのProを利用すればCognitoの環境は容易に手に入るが、とりあえずサクッと開発環境を手に入れたいなと思い[moto](https://docs.getmoto.org/en/latest/index.html)とterraformの環境を作成する。

## TL;DR

[moto server mode](https://docs.getmoto.org/en/latest/docs/server_mode.html)を利用した環境を作成して、terraformのendpoint urlをmoto server向けにする。

## Directory Architecture

```terminal
% tree .
.
├── Makefile
├── README.md
├── local-dev
│   ├── compose.yaml
│   ├── tmp.cognito.dockerfile
│   └── tmp.terraform.dockerfile
└── terraform
    ├── LICENSE.txt
    ├── main.tf
    └── terraform.tfstate

3 directories, 8 files
```

composeファイルは以下の通りです。
terraformとaws cliもdocker containerで作成しています。
host computer側を利用する場合は、terraform以下は不要です。

```local-dev/compose.yaml
services:
  cognito:
    container_name: cognito_container
    build:
      context: .
      dockerfile: tmp.cognito.dockerfile
      args:
        VERSION: "5.0.25"
    ports:
      - 3001:3000
    restart: on-failure
    networks:
      - internal
  terraform:
    container_name: terraform_container
    build:
      context: .
      dockerfile: tmp.terraform.dockerfile
      target: development
      args:
        TERRAFORM_VERSION: "1.10.3"
        AWS_CLI_VERSION: "2.22.27"
    tty: true
    environment:
      AWS_ACCESS_KEY_ID: AWS_ACCESS_KEY_ID
      AWS_SECRET_ACCESS_KEY: AWS_SECRET_ACCESS_KEY
      AWS_DEFAULT_REGION: ap-northeast-1
    volumes:
      - ../terraform:/usr/terraform
    networks:
      - internal

networks:
  internal: {}

```

motoserverは何と言う設定はしてません。

```local-dev/tmp.congnito.dockerfile
ARG VERSION

FROM motoserver/moto:${VERSION}

ENV MOTO_PORT=3000
```

terraformには、endpointsでdockerのnetwork内をみるようにしています。


```terraform/main.tf
provider "aws" {
    region                      = "ap-northeast-1"
    skip_credentials_validation = true
    skip_metadata_api_check     = true
    skip_requesting_account_id  = true

    endpoints {
        cognitoidentity = "http://cognito:3000"
        cognitoidp = "http://cognito:3000"
    }
}

resource "aws_cognito_user_pool" "pool" {
  name = "my-user-pool"
}
```

aws-cli, terraform環境は以下になります。

```local-dev/tmp.terraform.dockerfile
ARG AWS_CLI_VERSION

FROM amazon/aws-cli:${AWS_CLI_VERSION} as development

ARG TERRAFORM_VERSION

WORKDIR /usr/terraform

RUN yum install unzip -y

RUN curl https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip -o terraform_${TERRAFORM_VERSION}_linux_amd64.zip &&\
    unzip terraform_${TERRAFORM_VERSION}_linux_amd64.zip && rm terraform_${TERRAFORM_VERSION}_linux_amd64.zip &&\
    mv terraform /usr/bin/terraform

ENTRYPOINT [ "/bin/bash" ]

```
PythonでT検定を実施する。

「日本統計学会公式認定 統計検定データサイエンス基礎対応　データアナリティクス基礎」のレビューを読んでいたら「そもそもPythonでよくね？」みたいなコメントがちらほらと見受けられた。よって冬休みの宿題よろしく、「例題7 異なる授業形態による成績データ」をPythonで解いてみる。

### パッケージとライブラリをインポートする
まずは必要なライブラリと拡張機能をすべてインポートする。
```python
import numpy as np
import pandas as pd
from scipy import stats
from decimal import Decimal, ROUND_HALF_UP, ROUND_HALF_EVEN
```
### データを読み込み、中身を確認しておく
```python
sample_data = pd.read_csv("例題7_異なる授業形態による成績データ.csv", encoding="shift-jis")
sample_data = sample_data.dropna()
print(sample_data.head(10))
print(sample_data.shape)
print(sample_data.info())

# オンラインと対面でデータを分けておく。
cf_online = sample_data[sample_data['授業形態'] == "オンライン"]
cf_face = sample_data[sample_data['授業形態'] == "対面"]
```

### 7-1：オンライン授業の受講者の成績に関して、母平均の推定値
```python
cf_online_mean = cf_online['成績（点）'].mean()
print(Decimal(cf_online_mean).quantize(Decimal('0.1'), ROUND_HALF_UP))
```
```markdown:出力例
58.9
```

### 7-2：母標準偏差の推定値を不偏分散に基づいて求める
```python
estimated_standard_deviation = np.std(cf_online['成績（点）'], ddof=1)
print(Decimal(estimated_standard_deviation).quantize(Decimal('0.01'), ROUND_HALF_UP))
```
```markdown:出力例
3.16
```

### 7-3：オンライン授業の受講者の成績に関して、標本平均の標準誤差
```python
estimated_standard_error = estimated_standard_deviation / np.sqrt(len(cf_online))
print(Decimal(estimated_standard_error).quantize(Decimal('0.1'), ROUND_HALF_UP))
```
```markdown:出力例
0.5
```

### 7-4：オンライン授業の受講者の成績に関して、母平均のt分布に基づく信頼度95％の信頼区間の上限
```python
bottom, up = stats.t.interval(0.95,loc=cf_online_mean,
                 scale=estimated_standard_error,
                 df=len(cf_online))
print(Decimal(up).quantize(Decimal('0.1'), ROUND_HALF_UP))
```
```markdown:出力例
59.9
```

### 7-5：仮説検定
P値が0.05よりはるかに小さいので帰無仮説が棄却され、対立仮説が採用される。
```python
print(stats.ttest_ind(a=cf_online['成績（点）'],
                 b=cf_face['成績（点）'],
                 equal_var=False))
```
```markdown:出力例
TtestResult(statistic=6.078296850332994, pvalue=4.235040588884201e-08, df=77.72447906876936)
```

以上。
データリンクプロトコルの仮定

# プロセスが独立することによって三つの層を通信する
>独立プロセス：まず、物理層、データ・リンク層、ネットワーク層は独立したプロセスであって、メッセージをやり取りして通信を行なっている。良くある実装を図3-10に示す。

### 物理層、データリンク層の一部はNICで動作
>物理層プロセスおよびデータ・リンク層プロセスの一部はNIC(Network Interface Card:ネットワーク・インターフェース・カード)と呼ばれる専用ハードウェア上で動作する。

### データリンク層、ネットワーク層はOSの一部で動作
>残りのデータ・リンク層プロセスとネットワーク層プロセスはオペレーティング・システムの一部として主にCPU上で動作し、データ・リンク層プロセスのためのソフトウェアはしばしばデバイス・ドライバ(device driver)の形をとっている。

### 時とともに構成は変化するが三つのプロセスの独立性か変化しない
>三つプロセスともネットワーク・アクセラレータ(network accelerator)と呼ばれるハードウェアに降ろされる、あるいはまた三つのプロセスともソフトウェア無線では主にCPU上で動作するなど)。実際には、望ましい実装法は技術的トレードオフにより年と共に変わる。どのような場合でも、三つの層を独立したプロセスとして扱うことは、議論を概念的にスッキリさせ、層の独立性を強調するのに役に立つ。

### データリンク層からの依頼はすぐにネットワーク層は応じる
>一方向性通信：もう一つの重要な仮定は、マシンAがマシンBに向かって高信頼コネクション指向サービスを用いていデータの長いストリームを送ろうとしていることである。Aには送るべきデータの無限供給があり、データの生成のために待たされることはないものとする。その代わり、Aのデータ・リンク層がデータを求めたときにはネットワーク層は直ちに応じる。

### コンピュータのクラッシュを取り扱わない
>信頼できるマシンとプロセス:またマシンはクラッシュしないと想定する。すなわち、これらのプロトコルは通信誤りには対処するが、コンピュータがクラッシュし、リブートすることで引き起こされる問題は扱わない。

### データリンク層はパケットのヘッダーを認識しない
>データ・リンク層に関する限り、ネットワーク層からのインターフェースを通して渡されるパケットは純粋なデータであり、そのすべてのビットを宛先のネットワーク層に届けなければいけない。宛先のネットワーク層がパケットの一部をヘッダーとして解釈するという事実は、データ・リンク層の感知しないところである。

https://bookplus.nikkei.com/atcl/catalog/23/03/16/00728/
コンテナをワンライナーで消す

## TL;DR

```
docker ps -a | awk '{print $1}' | xargs docker rm
```

## grepなどと合わせて使う場合

実際はこんな感じで、フィルターかけることが多いよね。

```
docker ps -a | grep HOGE_FUGA | awk '{print $1}' | xargs docker rm
```

## 概要

下記のコマンドを使ってできます！

* docker
* awk
* xargs
Pythonで文字列を繰り返し*演算子

Pythonでコンソールやログに出力を装飾したいとき、文字列の繰り返し機能を活用すると便利です。

### Pythonでの文字列の繰り返し
Pythonでは、文字列に対して*演算子を使うことで簡単に繰り返し文字列を生成できます。

```python
# 基本的な例
line = "=" * 20
print(line)
```

```text
====================
```

### タイトルを装飾して見やすくする
文字列の繰り返しと文字列の結合（+）を組み合わせることで、簡単にタイトルを装飾できます。

- 基本的なタイトル装飾
以下の例では、左右に「=」を20回繰り返してタイトルを囲んでいます。

```python
title = "Python"
print("=" * 20 + " " + title + " " + "=" * 20)
```

```text
==================== Python ====================
```

- f-stringを使った例
Python 3.6以降で利用可能なf-stringを使うと、さらにコードが簡潔になります。

```python
title = "Learn Python"
print(f"{'=' * 20} {title} {'=' * 20}")

```

```text
==================== Learn Python ====================
```

### 応用例：実際のシナリオでの利用

- コマンドラインアプリケーション

```python
def display_section(title):
    print("\n" + "=" * 40)
    print(f"{title.center(40)}")
    print("=" * 40)

display_section("User Information")

```

```text
========================================
           User Information             
========================================
```

- ログファイル

```python
def log_header(title):
    header = "=" * 50
    with open("log.txt", "a") as log_file:
        log_file.write(f"\n{header}\n")
        log_file.write(f"{title.center(50)}\n")
        log_file.write(f"{header}\n")

log_header("Application Started")

```

```text
==================================================
                Application Started               
==================================================
```

Pythonの文字列の繰り返し機能を活用すると、簡単に見栄えの良い出力を作成できます。CLIツールやログファイルの整形、デバッグ時の視認性向上など、多くの場面で役立ちます。ぜひ試してみてください！
[C#] 巨大数の計算用プログラムを作成してみた

# はじめに
- 巨大数の近似値を計算するプログラムを作成しました
- $10↑↑n$のような数まで計算できます
- githubでは、JavaScriptに直したものを「バイバインシミュレーター」に使っています

# 制約
- 正の数のみ

# ダウンロード
https://github.com/leekmikan/leekmikan.github.io/blob/main/pg/Exp.cs

2025/2/13再び修正(クヌースの矢印表記を小数に拡張した際の計算ミス)
# 変数
num(double)...指数部
e(int)...指数タワーの長さ(10がe+1個つく)

cl(static int)...小数点以下の桁数
# 例
$10^{5}$ ($1e5$)
~~~C#
Exp x = new Exp(5,0)
~~~
$7$
~~~C#
Exp x = new Exp(Math.Log10(7),0)
~~~
$10^{10^{10^{100}}}$ ($eee100$)
~~~C#
Exp x = new Exp(100,2)
~~~
$10↑↑100$
~~~C#
Exp x = new Exp(10,98)
~~~
$2^{1024}≒1.8e308$ (一般的な放置ゲームのInfinity)
~~~C#
Exp x = new Exp(1024 * Math.Log10(2),0);
~~~
# 計算例

$123+345$
~~~C#
Exp x = new Exp(Math.Log10(123), 0);
Exp y = new Exp(Math.Log10(345), 0);
Console.WriteLine((x + y).Textn()); //Textfで小数まで表示(誤差が出る)
Console.Read();
~~~
~~~
468
~~~

$345-123$
~~~C#
Exp x = new Exp(Math.Log10(123), 0);
Exp y = new Exp(Math.Log10(345), 0);
Console.WriteLine((y - x).Textn());
Console.Read();
~~~
~~~
222
~~~

$(1.5*10^{18}) * (9.0 * 10^{55})$
~~~C#
Exp x = new Exp(18 + Math.Log10(1.5), 0);
Exp y = new Exp(55 + Math.Log10(9), 0);
Console.WriteLine((x * y).Textn());
Console.Read();
~~~
~~~
1.35e74
~~~

$(9.0 * 10^{55}) ÷ (1.5*10^{18})$
~~~C#
Exp x = new Exp(18 + Math.Log10(1.5), 0);
Exp y = new Exp(55 + Math.Log10(9), 0);
Console.WriteLine((x * y).Textn());
Console.Read();
~~~
~~~
6e37
~~~

$7^{7^{7}}$
~~~C#
Exp x = new Exp(Math.Log10(7), 0);
Console.WriteLine(x.Pow(x.Pow(x)).Textn());
Console.Read();
~~~
~~~
3.759e695974
~~~

$(1.0*10^{90})^{\frac{1}{100}}$
~~~C#
Exp x = new Exp(90, 0);
Exp y = new Exp(2, 0);
Console.WriteLine(x.Sqr(y).Textf()); //Textfで小数点以下も表示
Console.Read();
~~~
~~~
7.94328234724282
~~~

$123456789!$

※スターリングの近似
$n!≒\sqrt{2\pi n}(\frac{n}{e})^{n}$
~~~C#
Exp x = new Exp(Math.Log10(123456789), 0);
Console.WriteLine(x.Stirling().Textf());
Console.Read();
~~~
~~~
2.853e945335859
~~~

$log_{10^{1234}}(10^{10^{123}})$
~~~C#
Exp x = new Exp(123, 1);
Exp y = new Exp(1234, 0);
Console.WriteLine(x.Log(y).Textf());
Console.Read();
~~~
~~~
8.103e119
~~~
ImportError: DLL load failed while importing cv2で困ったので忘れないように備忘録()しておく

# [解決策](#how-to-solve)

# why happened
c++でopencvを使おうとcuda対応のopencvをビルドしたらなぜかpythonのopencvが使えなくなった。

```error
Traceback (most recent call last):
  File "<>", line 1, in <module>
    import cv2
  File "<>/Lib/site-packages/cv2/__init__.py", line 181, in <module>
    bootstrap()
  File "<>/Lib/site-packages/cv2/__init__.py", line 153, in bootstrap
    native_module = importlib.import_module("cv2")
  File "<>/lib/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
ImportError: DLL load failed while importing cv2: 指定されたモジュールが見つかりません。
```

## whats happening
import cv2をすると`__init__.py`内で`bootstrap()`(一番最後の行にある)が呼び出されてopencvのdllとかを探して読み込む処理が走るのだろうがうまくdllが読み込まれない。


`def load_first_config(fnames, required=True):`あたりで`/Lib/site-packages/cv2/`にある`config.py`から`BINARIES_PATHS`を読み込み
```python3
for p in l_vars['BINARIES_PATHS']:
    try:
        os.add_dll_directory(p)
```
でdllの検索パスに追加する。
ここでdllのあるディレクトリが検索パスに追加されていないからモジュールが見つからないとなったのだ！つまりは`config.py`に環境変数のPATHを追加したり直接パスを書き込めばうまく読み込んでくれるという

# how to solve
`/Lib/site-packages/cv2/config.py`を
```python3
import os

BINARIES_PATHS = [
    *os.environ["PATH"].split(";") # <-これ
] + BINARIES_PATHS
```
こういう風に書き換える。**ちゃんと必要なdllが環境変数のパスのフォルダにあればこれで解決するはず**

## 足りないdllの見つけ方
足りていないdllは[ここ](https://learn.microsoft.com/ja-jp/sysinternals/downloads/procmon)からprocess monitorをダウンロードして
画面上部のメニュー`Filter ->Filter`をクリックし、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3634486/b14ce177-1c44-a0db-483e-cbbfbfe8c0b1.png)

以下のフィルターを追加する
- `Process Name contains Python then Include`
- `Path Contains .dll then Include`
- `Result is SUCCESS then Exclude` <-optional
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3634486/693fe1f6-ef76-343c-8063-39d12bb66aea.png)
Applyで適用して
`python -c "import cv2;"`とかでopencvをインポートするだけのコードを実行する。
出てきたResultがNAME NOT FOUNDになってるのが見つからなかったdllであるから、それが含まれるディレクトリをパスに追加する。
私の場合はcudnn、cuda、opencvのdllが不足してた。

# ほかの解決策

- [vc redist](https://learn.microsoft.com/ja-jp/cpp/windows/latest-supported-vc-redist)

- `pip install opencv-contrib-python`

https://stackoverflow.com/questions/43184887/dll-load-failed-error-when-importing-cv2
- windows N/KNではWindows Media Feature Packがないから実行できないとかがあるらしい[link](https://support.microsoft.com/en-us/help/3145500/media-feature-pack-list-for-windows-n-editions)

https://github.com/opencv/opencv-python/issues/856#issuecomment-1722082014

# 参考
https://www.jamesbowley.co.uk/nbs/ImportError_dll_load_failed_while_importing_cv2.html
DDNS nowとLetsEncrypt使ってnginxで無料のHTTPS通信を実現する

# 無料でHTTPS通信をしようと思った時の方法です。

お金ないけど、証明書ほしいなーとか思って使ってみた方法です。
**きちんとしたサービスを運用するならお金をかけてきちんとやってください。**
無料で運用できるならそっちのほうがいいですが、お金をかけるとかけないとでは気持ちの入り方や信頼が違うので。
あくまで、勉強に使いたいとか、個人開発のテスト用なのど人向けです。

## 前提と目標
GCP (Google Cloud Platform)上にUbuntuの仮想マシンインスタンスを作成しました。
そのUbuntuサーバー上にウェブサーバーとしてnginxをインストールしてあります。
nginxはインストール済みかつUbuntuサーバー利用として話は進めていきます。
今回の目標はそのnginxで証明書を使用してHTTPS通信ができるようにすることです。

## ドメイン取得

まずは**DDNSNow**でドメインを取得します。  
以下のリンクからアクセスしてください:  
[DDNSNow公式サイト](https://ddns.kuku.lu/)

DDNS nowについての説明は省略します。詳細はリンク先に記載されているので、そちらを参照してください。

### 新規登録手順
1. 希望するサブドメインとパスワードを入力します
2. 登録ボタンを押すと、ドメインの取得が完了します

パスワードやドメインは後で使うので忘れないでください。
取得時点では、取得の際に使用していたIPアドレスに対してドメインが紐づけられています。  
ただし、この設定は後で変更することが可能です。


## ドメイン設定の変更方法

### 1. Linuxサーバーに移動
取得したドメインをサーバーで利用できるように設定します。  
TeraTerm等でサーバーに接続してください。
ここからは、**DDNSnowのマニュアル**に従って進めていきます。

### 2. cronの設定

以下のコマンドを実行します
```bash
crontab -e
```

### 3. 設定ファイルの追記
設定ファイルの最後に次のコードを追記します
```bash
0-59 * * * * wget -O DDNSNow_update.log "https://f5.si/update.php?domain=ユーザ名&password=パスワードもしくはAPIトークン"
```
この設定では、毎分wgetコマンドが実行され、DDNSの更新を行います。その結果はDDNSNow_update.logというファイルに保存されます。

**wgetのインストール**
もし、wgetがインストールされていなければ以下のコマンドでインストールしてください。
```bash
apt install wget
```

### LetsEncryptを使って、証明書を取得する

LetsEncryptは、**無料の認証局**っていうイメージです。 
イメージですっていうかそうです。
LetsEncryptについて詳しく知りたい方は、以下のリンクを参考にしてください：
- [LetsEncrypt公式](https://letsencrypt.org/ja/about/)
- [Kagoya - LetsEncrypt](https://www.kagoya.jp/howto/it-glossary/security/lets-encrypt/)

### 1.certbotのインストール

まず、**certbot**をインストールします。Certbotは、無料かつ自動で証明書を発行できるツールです。  
今回はCertbotとそのnginxプラグインをインストールします。

```bash
apt install certbot python3-certbot-nginx
```
インストールがうまくいかない場合は、まず以下のコマンドでパッケージリストを更新してみてください
```bash
apt update
```
### 2.nginxの起動

次にnginxを起動させます
```bash
systemctl restart nginx
```

### 3.証明書の取得

次のコマンドで証明書を取得します
```bash
sudo certbot --nginx -d ドメイン名
```
指定したドメイン名に対して証明書が発行され、その後nginxの設定も自動で行われます。
この際、いくつかの質問が表示されますが、指示に従って回答してください。

以上で設定が完了です。
ドメインをブラウザで検索し、HTTPS通信が有効になっていることを確認してください。
レンタルサーバにGNU GLOBALを入れてEmacs + trampでコードリーディングする

## レンタルサーバでもコードリーディングしたい

実験場として借りているレンタルサーバでコードリーディングしたいと思いまして、以下、やってみました。

今回のレンタルサーバはエックスサーバさんです。

## GNU GLOBALのインストール

レンタルサーバなので、借りているホームディレクトリにインストールします。

`https://ftp.gnu.org/pub/gnu/global/` を確認して、新しいバージョンがあったら、それを`wget`します。
`~/bin`で作業します（なかったら作る）。
`--disable-gtagscscope`として、configureしないと、エラーが出て`make`できませんでした。

```bash
wget https://ftp.gnu.org/pub/gnu/global/global-6.6.14.tar.gz
tar zxf global-6.6.14.tar.gz
cd global-6.6.14
./configure --prefix=${HOME} --disable-gtagscscope
make
make install
```

### 確認

```bash
gtags --version
```

でバージョンが出たら成功です。

作業ディレクトリに行って、

```bash
gtags
```

で走査をして、以下のファイルができることを確認します。

```
GPATH
GRTAGS
GTAGS
```
### globalの場所を確認

Emacsで使うので、`~/bin/global`に実行ファイルがあることを確認します。

コマンドラインで使うなら、`.bashrc`で、`export PATH=$HOME/bin:$PATH`もしておくと便利だと思います。

作業ディレクトリで

```bash
global 関数/クラス名
```

でファイルが返ってくることを確認できたら、インストール成功です。

## Emacsで使う場合

デフォルトのgtagsはtrampでうまくいかないという記事がいくらか見つかるのですが、ぼくの場合はデフォルトのgtagsでtrampでもうまく行きました（Emacsのバージョンは29.4）。

```elisp
(require 'gtags)
(with-eval-after-load 'gtags
  (setq gtags-global-command "/home/YOURDIRNAME/bin/global")
  (setq gtags-auto-update t)
  (define-key gtags-mode-map (kbd "M-.") 'gtags-find-tag)
  (define-key gtags-mode-map (kbd "M-,") 'gtags-pop-stack))
```

## カレントバッファのメソッド一覧を見る

「[コードリーディングにとっても便利な GNU GLOBAL と gtags.el (と anything-gtags.el) をつかおう](https://qiita.com/yewton/items/d9e686d2f2a092321e34)」を拝読し、なるほど、`gtags-parse-file`でカレントバッファを見られると便利と教えてもらいました。

でも、残念ながら記事内で示されているelispではうまくいかなかったので、以下のとおりにしています。

```elisp
(defun gtags-parse-current-file ()
  "Show the list of tags in the current buffer's file."
  (interactive)
  (if (buffer-file-name)
      (let ((current-file (buffer-file-name)))
        (if (file-regular-p current-file)
            (let ((tagname (expand-file-name current-file)))
              (gtags-push-context)
              (gtags-goto-tag tagname "f"))
          (message "Current file is not a regular file.")))
    (message "Current buffer is not visiting a file.")))
```
キーバインドもこんな感じに変更。
```elisp
(with-eval-after-load 'gtags
  (setq gtags-global-command "/home/YOURDIRNAME/bin/global")
  (setq gtags-auto-update t)
  (define-key gtags-mode-map (kbd "M-.") 'gtags-find-tag)
  (define-key gtags-mode-map (kbd "M->") 'gtags-find-rtag) ; M-shift-.
  (define-key gtags-mode-map (kbd "M-s-.") 'gtags-parse-current-file) ; M-super-.
  (define-key gtags-mode-map (kbd "M-,") 'gtags-pop-stack))
```
described_class

`described_class`を使う
>### Using described_class
もしexampleグループへの最初の引数がクラスならば、そのクラスは`described_class`メソッドを経てexampleグループ内のexampleへ晒される。

>If the first argument to an example group is a class, the class is exposed to each example in that example group via the described_class() method.

exampleから記述クラスへアクセスする　described_classでクラスを返す
>### Access the described class from the example

```rb
RSpec.describe Symbol do
  it "is available as described_class" do
    expect(described_class).to eq(Symbol)
  end

  describe 'inner' do #記述されたクラス
    describe String do
      it "is available as described_class" do
        expect(described_class).to eq(String)
      end
    end
  end
end
```
```
Run options: include {:full_description=>/Symbol/}
2 examples, 0 failures, 2 passed
```

#### described_classを確認してみる
```rb
    it "is available as described_class" do
    expect(described_class).to eq(Symbol)
    puts described_class
  end
```
```
Run options: include {:full_description=>/Symbol\ is\ available\ as\ described_class/}
Symbol
1 example, 0 failures, 1 passed
```
```rb
RSpec.describe Symbol do
  it "is available as described_class" do
    expect(described_class).to eq(Symbol)
    puts described_class
  end

  describe 'inner' do
    describe String do
      it "is available as described_class" do
        puts described_class
        expect(described_class).to eq(String)
      end
    end
  end
end
```
```
Run options: include {:full_description=>/Symbol/}
Symbol
String
2 examples, 0 failures, 2 passed
```
https://rspec.info/features/3-13/rspec-core/metadata/described-class/
音声入力と生成AIを使った簡単ブログ記事作成方法

ブログ記事の作成は、Google ドキュメントの音声入力と生成AIを活用すれば無料で簡単に行えます。今回は、その具体的な手順をご紹介します。

※この記事自体、記載した手順で作成したものです。

## 必要なもの

1. **ノートパソコン**: パソコンで作業すると効率的です。
2. **Google アカウント**: Google ドキュメントを利用するために必要です。
3. **ChatGPT アカウント**: 生成AIを使って文章を整理する際に利用します。

これら3つが準備できれば、すぐに始められます。

## 手順

### 1. Google ドキュメントを開く

Google アカウントを使ってGoogle ドキュメントにアクセスします。Google ドキュメントは無料で利用できる便利なツールです。

### 2. 音声入力を使って文字起こし

1. Google ドキュメントの上部メニューから「ツール」をクリックします。
2. 「音声入力」を選択すると、マイクに話しかけるだけでテキストが入力されます。

音声入力の精度は非常に高く、スムーズに文字起こしが可能です。特にPC版では途中で止まることが少なく、長時間の音声入力も安心して行えます。スマートフォンでも音声入力は可能ですが、録音が途中で切れる場合があるため、PCの利用がおすすめです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20427/bc2ac3c6-99b5-18f0-c57d-17988c8c09c1.png)

### 3. 生成AIで文章を整理

Google ドキュメントで文字起こしが完了したら、そのテキストをChatGPTにコピペします。

- ChatGPTに「この文章をブログ記事風に整理してください」と依頼します。
- ChatGPTが自動的に文章を整えてくれるので、完成した文章をそのまま使用できます。

## メリット

- **時間短縮**: 音声入力を活用することでタイピングの手間を省けます。
- **無料で利用可能**: Google ドキュメントとChatGPT（無料版）を活用すれば、コストをかけずに質の高いブログ記事を作成できます。

## まとめ

Google ドキュメントと生成AIを組み合わせることで、簡単かつ効率的にブログ記事を作成することが可能です。必要なのはノートパソコン、Google アカウント、ChatGPT アカウントの3つだけです。

ぜひ、今回の方法を試してみてください！
Google Colaboratory TA-Lib インストール 2025年最新版

## 現象
```
!pip install TA-Lib

Collecting TA-Lib
  Using cached ta_lib-0.6.0.tar.gz (371 kB)
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Installing backend dependencies ... done
  Preparing metadata (pyproject.toml) ... done
Requirement already satisfied: setuptools in /usr/local/lib/python3.10/dist-packages (from TA-Lib) (75.1.0)
Requirement already satisfied: numpy in /usr/local/lib/python3.10/dist-packages (from TA-Lib) (1.26.4)
Building wheels for collected packages: TA-Lib
  error: subprocess-exited-with-error
  
  × Building wheel for TA-Lib (pyproject.toml) did not run successfully.
  │ exit code: 1
  ╰─> See above for output.
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
  Building wheel for TA-Lib (pyproject.toml) ... error
  ERROR: Failed building wheel for TA-Lib
Failed to build TA-Lib
ERROR: ERROR: Failed to build installable wheels for some pyproject.toml based projects (TA-Lib)
```

この時点でエラー

## ライブラリのインストール
ta-libはソースコードからインストール これは以前と同じ
```
!wget http://prdownloads.sourceforge.net/ta-lib/ta-lib-0.4.0-src.tar.gz
!tar -xzf ta-lib-0.4.0-src.tar.gz
%cd ta-lib/
!./configure --prefix=/usr
!make
!sudo make install
```

これが自動的に行われなくなってた

```
!echo "/usr/lib" >> /etc/ld.so.conf
!ldconfig
```

確認

```
!ldconfig -p | grep ta_lib
	libta_lib.so.0 (libc6,x86-64) => /usr/lib/libta_lib.so.0
	libta_lib.so (libc6,x86-64) => /usr/lib/libta_lib.so
```

ここまでできたら次へ

## TA-Libのインストール
バージョンを指定してインストール 0.6.0はだめっぽいから0.5.0をインストール

```
!python -m pip install git+https://github.com/TA-Lib/ta-lib-python.git@TA_Lib-0.5.0

Collecting git+https://github.com/TA-Lib/ta-lib-python.git@TA_Lib-0.5.0
  Cloning https://github.com/TA-Lib/ta-lib-python.git (to revision TA_Lib-0.5.0) to /tmp/pip-req-build-bchzh4y5
  Running command git clone --filter=blob:none --quiet https://github.com/TA-Lib/ta-lib-python.git /tmp/pip-req-build-bchzh4y5
  Running command git checkout -q 1582434101ee5387765c0dee97f5b4a465f78458
  Resolved https://github.com/TA-Lib/ta-lib-python.git to commit 1582434101ee5387765c0dee97f5b4a465f78458
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Preparing metadata (pyproject.toml) ... done
Requirement already satisfied: numpy in /usr/local/lib/python3.10/dist-packages (from ta-lib==0.5.0) (1.26.4)
Building wheels for collected packages: ta-lib
  Building wheel for ta-lib (pyproject.toml) ... done
  Created wheel for ta-lib: filename=ta_lib-0.5.0-cp310-cp310-linux_x86_64.whl size=2385774 sha256=4c11bba56e84977613bb74b48aa31f030e41337237cdceb6921c01a724972d5b
  Stored in directory: /tmp/pip-ephem-wheel-cache-k99eacu8/wheels/2d/f9/54/5b4c39b0b9a0a2482828299331f69df93fc59dadce83e0622a
Successfully built ta-lib
Installing collected packages: ta-lib
  Attempting uninstall: ta-lib
    Found existing installation: TA-Lib 0.4.26
    Uninstalling TA-Lib-0.4.26:
      Successfully uninstalled TA-Lib-0.4.26
Successfully installed ta-lib-0.5.0
```

古いバージョンをインストールするときはこう

```
!python -m pip install git+https://github.com/TA-Lib/ta-lib-python.git@TA_Lib-0.4.26
```
exampleオブジェクトを参照できる

#### 現在のexampleを使う
>### Using the current example

`it`, `subject`, `let`, `the before`, `after`, `around hooks`へ供給されるブロック引数を使ってexampleオブジェクトを参照できる、そしてそのメタデータにもアクセスできる。
>You can reference the example object, and access its metadata, using the block argument provided to: it, subject, let, and the before, after, and around hooks.

#### example中からexampleオブジェクトにアクセスする
>### Access the example object from within an example
```rb
RSpec.describe "example as block arg to it, before, and after" do
  before do |example| # example.descriptionの"is the example object" が参照されている
    expect(example.description).to eq("is the example object")
  end

  after do |example|
    expect(example.description).to eq("is the example object")
  end

  it "is the example object" do |example| 
    expect(example.description).to eq("is the example object")
  end
end
```
```
Run options: include {:full_description=>/example\ as\ block\ arg\ to\ it,\ before,\ and\ after/}
1 example, 0 failures, 1 passed
```
```rb
RSpec.describe "example as block arg to let" do
  let(:the_description) do |example|
    example.description　# exampleが始まる前にletに参照されている
  end

  it "is the example object" do |example|
    expect(the_description).to eq("is the example object")
  end
end
```
```
Run options: include {:full_description=>/example\ as\ block\ arg\ to\ let/}
1 example, 0 failures, 1 passed
```
```rb
RSpec.describe "example as block arg to subject" do
  subject do |example|
    example.description
  end

  it "is the example object" do |example|
    expect(subject).to eq("is the example object")
  end
end
```
```
Run options: include {:full_description=>/example\ as\ block\ arg\ to\ subject/}
1 example, 0 failures, 1 passed
```
```rb
RSpec.describe "example as block arg to subject with a name" do
  subject(:the_subject) do |example| # subjectにも読み込むことができる
    example.description 
  end

  it "is the example object" do |example|
    expect(the_subject).to eq("is the example object")
    expect(subject).to eq("is the example object")
  end
end
```
```
Run options: include {:full_description=>/example\ as\ block\ arg\ to\ subject\ with\ a\ name/}
1 example, 0 failures, 1 passed
```
https://rspec.info/features/3-13/rspec-core/metadata/current-example/
AWS Bedrock と AWS Chatbotを利用して、SlackからBedrockを使うための備忘録

## はじめに
下記の記事を参考に`AWS Bedrock`をSlackで使うための環境構築を行なった際のメモを備忘録として記事に残しておこうと思います。

https://www.cloudbuilders.jp/articles/4822/

https://qiita.com/moritalous/items/b63d976c2c40af1c39e5

## この記事で書いていること

### 設定の流れ
1. Bedrock エージェントの作成
2. IAMポリシー、IAMロールの作成　:pencil: 備忘録：[IAMポリシーの設定](#iamポリシーの設定)
3. AWS Chatbotの作成　:pencil: 備忘録：[Bedrockでモデルを使うための設定](#bedrockでモデルを使うための設定)
4. Slackの設定
5. Slackで質問してみる　:pencil: 備忘録：[スレッドの内容を考慮して質問を返してくれる
](#スレッドの内容を考慮して質問を返してくれる)

設定の流れはだいたいこんな感じ、40分程度あれば設定できるのでSlackで生成AIのChatbotをサクッと試してみたいという方にはオススメです。
この記事で備忘録として書いているものには、『 :pencil: 備忘録 』と記載しています。

## IAMポリシーの設定
上記の記事にも記載はありますが、`Resource`の設定について改めて解説しておきます。
`Resource`の設定は、[`Amazon Bedrock > エージェント > 作成したリソース`](https://ap-northeast-1.console.aws.amazon.com/bedrock/home?region=ap-northeast-1#/agents) の`エージェントの概要`に記載の2つの情報を使って組み立てます。

### `エージェント ARN`
- 例: `arn:aws:bedrock:ap-northeast-1:XXXXX:agent/ABC12345`
![bedrock_agent_arn.tiff](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2316171/2d6dab45-4795-4c0b-3495-75beb3977872.tiff)

### `エイリアス`の`エイリアス ID`
- 例: `DEF12345`
![bedrock_agent_alias.tiff](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2316171/70427e2d-4bd5-22bc-e0ef-51da2a250f50.tiff)


### `Resource`の組み立て
1. `エージェント ARN`の`agent`を`agent-alias`に書き換えて、`arn:aws:bedrock:ap-northeast-1:XXXXX:agent-alias/ABC12345/DEF12345`と、設定してください
2. 次に、`1`で作成したパスの最後にエイリアスIDを繋げて、最終的に`arn:aws:bedrock:ap-northeast-1:XXXXX:agent-alias/ABC12345/DEF12345`とします。これをIAMポリシーの`Resource`に設定すれば良いです



設定したポリシーの全体は下記のようになります
```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowInvokeBedrockAgent",
            "Effect": "Allow",
            "Action": "bedrock:InvokeAgent",
            "Resource": [
                "arn:aws:bedrock:ap-northeast-1:XXXXX:agent-alias/ABC12345/DEF12345"
            ]
        }
    ]
}
```

## Bedrockでモデルを使うための設定
今まで使ったことのない方は、モデルアクセスの設定を行う必要があります。まずは、[`Amazon Bedrock > モデルアクセス`](https://ap-northeast-1.console.aws.amazon.com/bedrock/home?region=ap-northeast-1#/modelaccess) にアクセスして、利用したいモデルを選択して、アクセスを許可してください。

アクセスが許可されると、下記のようにステータスも更新されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2316171/8c7d42bb-2e17-615b-8cdc-9835cfcb3d78.png)

アクセスが許可されると、Bedrockのエージェントの詳細からモデルが選択出来るようになります。
![bedrock_model.tiff](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2316171/533c8343-8133-2a97-ecdf-70585b8980d9.tiff)

## スレッドの内容を考慮して質問を返してくれる
スレッドの内容を考慮して質問を返してくれるようですが、試しにS3に関する質問をしているスレで、全く違う内容を質問をしてみると「元の質問から話題が変わってしまいましたね」と優しく指摘してくれました。エージェントの指示に「同僚に話すような優しい口調で回答して。」など、自分好みに設定しておくと優しい相方を手にいれることが出来るようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2316171/a64acb5f-d782-b129-31f6-948e955e6787.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2316171/d92a0ac5-365d-2e9d-7c85-7dff75051ae8.png)

以上、備忘録でした。

最後までお読みいただき、ありがとうございました。
MacとLinuxでfindコマンドの実行結果が違う件

<2025.1.4 コメントを受け内容修正>
# 概要

Macbookでfindコマンドを使ったが、思うような結果を得ることができなかったので調べてみた。

# findコマンドとは？

findコマンドはディレクトリ内のファイルやフォルダを検索するためのコマンドです。基本的な使い方は以下のとおりです。

```bash
find <探索するディレクトリ> <ファイル名>
```

以下の構成の場合で考えてみる。

```bash
.
├── hoge
│   ├── hoge1.txt
│	  ├── hoge2.txt
│	  ├── hoge3.txt
│   └── sample.txt
└── fuga
    ├── fuga1.txt
    ├── fuga2.txt
    ├── fuga3.txt
    └── fuga4.txt
```

-nameオプションを使って結果を確認します。-nameオプションはファイル名と探索ディレクトリを指定することで、ファイル名が一致するものを探し出します（とはいえ、ファイル名をいちいち覚えていないので、私はワイルドカードの*と一緒に使っています）。

```bash
# 基本的な使い方はfind <探索するディレクトリ> -name <ファイル名>
# 以下は実行したコマンドとその結果

find ./ -name hoge1.txt
# 実行結果 => hoge1.txtが表示される

find ./ -name hoge
# 実行結果 => hogeディレクトリが表示される（配下のファイルは表示されない）

find ./ -name *hoge1.txt
# 実行結果 => no matches found（シェルがワイルドカードを展開しようとするため）

find ./ -name sample.txt
# 実行結果 => sample.txtが表示される

find ./ -name sample*
# 実行結果 => no matches found（シェルがワイルドカードを展開しようとするため）

find ./ -name "sample*"
# 実行結果 => sample.txtが表示される
```

自分の場合、findコマンドを使う場合は名前の一部だけがわかっているファイルを探すことが多いです。よって、-nameオプションにワイルドカードと組み合わせて探索することがほとんどです。

ここに落とし穴があります！

実は上記の結果は全てMacBookでのもの。Linuxでやるとどうなるかというと…

```bash
find ./ -name sample*
# 実行結果 => sample.txtが表示される

find ./ -name "sample*"
# 実行結果 => sample.txtが表示される
```

そう！ダブルクォートがなくてもしっかり探索して表示してくれるのです！

自分がコマンドを使う場合はLinux（仮想環境）がほとんどで、Macはあまり使わない。そのため、Macでfindコマンドを使った時にダブルクォートを使わず意図した結果が出なかったのです。そのせいでかなり時間を無駄にしました。

# なぜこんなことが起きるのか？

Macではデフォルトのシェルがzshであり、ワイルドカード*が展開されないため、find ./ -name sample*を実行すると「sample*」という文字列に一致するファイル名を探すことになります。その結果、一致するファイルがなくno matches foundとなります。

一方、bashではワイルドカードが展開され、findコマンドに渡されるため、sample*が「sample」という文字列に続く全ファイルが検索されます。

# 迷わないための解決策
ワイルドカードを使う時は、ダブルクォートを使うことをお勧めします！私もこれからはダブルクォートを使いますw

# 最後に
bashとzshでワイルドカードの展開に違いがあり、それによりコマンドの実行結果に差が出てしまいます。こんな違いがあるなんて、驚きですね。
aws-cliのimageにterraformコマンドを利用できる環境を作成する

# aws-cliのimageにterraformコマンドを利用できる環境を作成する

## Motivation

awsの簡易的なlocal開発環境を作成したく、可能な限りterraformで管理をしたいと思った。

## TL;DR

[amazon/aws-cliのdocker image](https://hub.docker.com/r/amazon/aws-cli)に、terraformをinstallして利用可能にする。

## Directory構成

```terminal
tree .
.
├── Makefile
├── README.md
├── local-dev
│   ├── compose.yaml
│   └── tmp.terraform.dockerfile
└── terraform
    └── main.tf
```

```compose.yaml
services:
  terraform:
    container_name: terraform_container
    build:
      context: .
      dockerfile: tmp.terraform.dockerfile
      target: development
      args:
        TERRAFORM_VERSION: "1.10.3"
        AWS_CLI_VERSION: "2.22.27"
    tty: true
    volumes:
      - ../terraform:/usr/terraform
    networks:
      - internal

networks:
  internal: {}
```

```tmp.terraform.dockerfile
ARG AWS_CLI_VERSION

FROM amazon/aws-cli:${AWS_CLI_VERSION} as development

ARG TERRAFORM_VERSION

WORKDIR /usr/terraform

RUN yum install unzip -y

RUN curl https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip -o terraform_${TERRAFORM_VERSION}_linux_amd64.zip &&\
    unzip terraform_${TERRAFORM_VERSION}_linux_amd64.zip && rm terraform_${TERRAFORM_VERSION}_linux_amd64.zip &&\
    mv terraform /usr/bin/terraform

ENTRYPOINT [ "/bin/bash" ]
```
【TS】オブジェクト型の配列で要素が存在したら更新、しなかったら新規追加する

# 前提
- 純粋関数であること（元の配列に上書きしない）


```ts
function updateOrAddImmutableOptimized(items: Item[], name: string): Item[] {
    let isUpdated = false;

    // `map` を使用しつつ、一致する要素があればその場で更新
    const updatedItems = items.map(item => {
        if (item.name === name) {
            isUpdated = true;
            return { ...item, count: item.count + 1 };
        }
        return item;
    });

    // 一致する要素がなければ新しい要素を追加
    if (!isUpdated) {
        return [...updatedItems, { name, count: 1 }];
    }

    return updatedItems;
}

// 使用例
let myItems: Item[] = [
    { name: "apple", count: 2 },
    { name: "banana", count: 5 }
];

myItems = updateOrAddImmutableOptimized(myItems, "apple");
myItems = updateOrAddImmutableOptimized(myItems, "cherry");

console.log(myItems);

```
【TS】Arrayの標準メソッドのメモ

## find()
- Arrayの中から「最初に条件に合ったもの」を「１つReturnする」
- 条件に合うものが２つ以上あっても、1つ目だけで探すのやめる。
- 条件に合うものがなかったら`undefined`が返ってくる

## findIndex()
- `find()`の仕様で戻り値がインデックスになる

## some()
- ある条件に対して、Arrayの中に「最低でも１つはTrueになるもの」があれば「True」を返す。
- 条件をクリアするものが一つもなければFalseが返る
:::note warn
Trueとしか返ってこないので、中身は分からない
:::

## includes()
- 「具体的な値など」がArrayの中に含まれていれば「True」を返す

:::note warn
`10 >= n(10以上の数字)`のような検索条件は指定できない
:::


## indexOf()　
- 「具体的な値など」がArrayの中に含まれていれば最初に見つかったのがArrayの何番目にあるかIndexを返す。
- 一つもなければ「−１」が返る。

:::note warn
同じ値が２つ以上含まれているArrayの場合は１つ目の場所しか返ってこない。
:::

# 要素が存在するかどうかを確認する
`find()`か`findIndex()`を使う。find系は要素が存在した時点で処理を止めるため効率が良い。
新卒エンジニアが5か月でAWS資格5個を取得した話

# 概要
この記事では、新卒1年目のエンジニアである私がAWSの認定資格を5つ取得した話と資格を取得したことによって得られたものについて紹介します。
新卒エンジニア向けに、実際に私が資格取得を通して経験したこと、得られたことを伝えることで少しでも影響を与えられたらと思います。（記事の投稿自体が初めてなので、記事の投稿、アウトプットの練習を兼ねて）
私が取得した資格は、CLF、SAA、DVA、SOA、SAPの5つです。
資格取得を通して、資格のほかにもいくつか得られたものがありました。

# 自己紹介
簡単に自己紹介をします。
- 記事投稿現在、新卒1年目
- 都内中規模Sier勤務
- 業務でのAWS経験ほぼなし
- 大学では情報工学を専攻
- 資格取得前のAWS経験はほぼなし（大学時代にアカウントを作ってみた程度）

大学では情報系の学部を専攻し、自身で簡単なWebアプリを作ってみたり、気になる技術を触ってみたりしていました。大学3年生ごろから小規模なIT企業でインターン兼バイトを始め、業務での経験を積みました。学生時代に一度AWSを触ってみましたが、あまりに知識がないまま始めたため、課金されるのが怖いという不安もあり、ほとんどなにもせず終了しました。
社会人になりAWSの研修を受けた際に、講師の方の発表や先輩の発表に影響を受けてAWSについて学んでみようと思ったのがきっかけでAWSの勉強を始めました。

# なぜ資格取得を目指したか
私が資格取得を目指した理由は主に以下の3つです。
- 単純にクラウド系の技術に興味があった
- AWS関連で活躍している2年目の先輩が身近にいた
- 資格取得による社内認知度の向上

特に、AWS関連で活躍している年次の近い先輩が身近にいたことは大きかったように思います。
わかりやすいロールモデルが身近にいることで、より具体的に自身の進む道をイメージできるようになりました。
また、「社内である程度認知されているほうが今後の挑戦や活躍の幅が広がるのでは」という思いも資格取得のモチベーションとなりました。

# 実際に取得した資格について
私が取得した資格は次の5個です。
上から順番に取得していきました。

 **1. CLF**
AWSのサービスの名称や特徴、クラウドの考え方などについて幅広く学ぶことができました。

 **2. SAA**
個人的には一番難しく感じました。
CLFから一歩進んで、AWSでシステムを構築する際のアーキテクチャなどについて学ぶことができました。
また、AWSのみならず、ネットワークやインフラに関連した用語についても学ぶことができ、とてもためになりました。

 **3. DVA**
CI/CDやテストといった内容についての知識もまとめて学ぶことができました。

 **4. SOA**
どのようにシステムや組織を管理するか、自動化するかといったことについて学ぶことができました。

 **5. SAP**
SAPを学習しているあたりから、問題文を読んだときに「どのようなアーキテクチャになっているか」といったことが頭の中でイメージできるようになりました。
また、今まであいまいだったネットワーク関連のサービスやそのつながり方などについての知識が付きました。

個人的な難易度順は、SAA>SAP>SOA>DVA、CLFでした。
SAAを受けた時期は勉強方法がまだ確立できていなかったといったことが大きく関係していそうですが、問題を解いた後のわからなかった問題の多さでいうとSAAが一番多かったです。（実際に点数もSAAが一番低かった）


# 資格を取得して得られたもの
## 1. 資格とAWSに関する知識
当たり前ではありますが、資格とAWSに関する知識を得ることができました。
業務でのAWS使用経験がほとんどないことは個人的にはネックですが、AWSを全く知らない状態から構成図を見たらある程度イメージができる状態になれたことは大きな成長だと思います。

## 2. AWSサービス以外の基本的なインフラやシステム管理に関する知識
AWSの知識だけではなく、インフラの構成やネットワーク、DB、システム管理、CI/CDといった幅広い知識について学ぶことができました。
大学での勉強や基本情報の取得を通して少し知っていたくらいの知識が、AWSの具体的なサービスや構成を学ぶことで、より解像度が上がったように思います。

## 3. 社内の認知度
これは確実にあったと思います。
社内SNSを通して資格取得と勉強方法についての投稿を行った結果、同期、先輩などから知ってもらえていることが増えました。
同期からはAWSのことを聞かれ、先輩からはAWSを頑張っている人として認知されるようになり、ほめていただけることも多々ありました。
このことが今後どのように影響するかはまだわかりませんが、認知が上がったことを活かしていきたいと考えています。

# 最後に
私自身、資格取得を通していろいろなことを経験し、得ることができました。
AWSサービスはもちろんのこと、インフラなど幅広い事柄について学ぶことができたことは個人的に大きかったです。
新卒に限らず若手エンジニアで、AWSに興味のある人やなんとなくインフラ周りの知識はあるけど理解があいまいといった人には、AWSの資格取得はかなりおすすめです。

最後まで記事を読んでいただきありがとうございます。
転職ドラフトで転職してみた

転職活動を始めるにあたり、「どのような方法が効率的なのだろう」と悩む方は多いのではないでしょうか？私もその一人でした。
しかし、「転職ドラフト」を利用したことでスムーズに新しいステップに進むことができ、結果として年収も100万円以上大幅にアップしました。
この記事では、私の転職ドラフト体験談をお伝えします。


※こちらの記事は転職ドラフト体験談投稿キャンペーンに参加しています。
[転職活動を振り返ろう！転職ドラフト体験談投稿キャンペーン](https://job-draft.jp/articles/251)


## 転職活動を始めた理由

私が転職を決意した背景には、成長意欲とキャリアの方向性に対する悩みがありました。
未経験からエンジニアとして入社した会社では約2年間、フロントエンドエンジニアとしてWebアプリケーションの開発に従事していました。
Vue.jsなどを使ったJSの開発経験も積み、技術的には多くの学びがあったものの、社内でのキャリアパスが見えづらいことが課題でした。

また、新しい技術やプロジェクトに挑戦したいという気持ちが強まる中で、自分の市場価値を客観的に把握する手段が欲しいと思うようになりました。
そんな中、友人から紹介されたのが転職ドラフトでした。

## 転職ドラフトを選んだ理由

転職ドラフトの最大の魅力は、企業側からの指名を受ける仕組みです。
自分から応募する従来の方法とは異なり、企業がこちらの経歴やスキルを評価したうえでオファーを出してくれるため、自分の価値を客観的に知ることができます。
また、提示されるオファー額が明示されている点も、安心感につながりました。

## 実際に利用してみた感想

### レジュメの作成

転職ドラフトでは、レジュメの作成が非常に重要です。
審査を通過しないと指名を受けることができないため、私は次のポイントを意識して作成しました。

- 実績を具体的に記載する
    - 担当したプロジェクトの規模や成果、使用した技術スタックを具体的に記述しました。

- 自己PRを明確にする
    - 特に自分が得意とする分野（フロントエンド開発やUI/UXデザインの知見）について強調しました。

- 成果を数値化する
    - たとえば「ページ読み込み速度を30％改善した」や「ユーザーリテンション率を20％向上させた」など、数字を使って説明しました。

結果として、一度の提出で審査を通過することができました。

## 指名を受けたときの印象

審査を通過後、登録したレジュメを基に企業から指名を受けられるようになりました。
最初に指名が届いたときは、「本当にこんなに良い条件で？」と半信半疑でしたが、詳細を確認するにつれて、企業の真剣さが伝わってきました。

特に感動したのは、指名のコメントに「どの部分を評価しているのか」が具体的に記載されていたことです。
これにより、自分がどのように見られているかを理解し、面接時のアピールポイントを明確にすることができました。

## オファー額と選択肢の広がり

私の場合、2ヶ月間で合計12社から指名を受け、そのうち6社と選考を進めました。
中にはスタートアップから大企業まで幅広い選択肢があり、それぞれの企業文化やプロジェクト内容を比較する良い機会となりました。

## 入社先を決めた理由

最終的に選んだのは、最新の技術を活用したプロダクト開発を手掛けるスタートアップ企業でした。
この企業を選んだ理由は以下の通りです。

- 技術的な挑戦ができる環境
    - モダンな技術スタックを活用したプロジェクトが多く、自分のスキルをさらに磨けると感じました

- 裁量の大きさ
    - 小規模なチームで、自分がプロジェクト全体に関与できる点に魅力を感じました

- チームの雰囲気
    - 面接中の会話から、社員同士のコミュニケーションが活発でオープンな文化が伝わり、自分に合っていると確信しました

## 転職活動を通じて学んだこと

転職ドラフトを利用したことで、以下の学びを得ることができました。

- 市場価値を知る大切さ
    - 自分のスキルや経験がどのように評価されるかを知ることは、キャリアを考えるうえで重要

- レジュメの重要性
    - 限られた情報で自分をアピールするためには、具体的かつ簡潔な表現が求められる

- 転職のタイミング
    - 自分のスキルやキャリアの方向性が企業のニーズとマッチするタイミングを見極めること

## 友達紹介キャンペーンについて
もしこの記事を読んで転職ドラフトに興味を持たれた方がいれば、ぜひ友達紹介キャンペーンを活用してみてください。

- 以下からお好きなものを1点もらえます！(2025年1月現在)
    - お好きなO’REILLY JAPANの本1冊（税込5500円以内）
    - ACTUSギフトカタログ Straw（ストロー）
    - Amazonギフト券 3000円分（Eメールタイプ）

紹介コード：「UIAJ」
※登録後28日以内に入力する必要があるのでご注意ください。
※転職ドラフトに参加したあと、運営からメールで連絡がきます！

詳しくは友達紹介キャンペーンをご覧ください。

[転職ドラフト](https://job-draft.jp/)に登録する。

## さいごに

転職ドラフトを利用したことで、効率的かつ充実した転職活動を行うことができました。
特に、企業側からの指名を受ける仕組みは、自分の市場価値を確認しつつ転職活動を進められる点で非常に有用だと感じました。

この記事を通じて、転職活動中の方や転職ドラフトに興味を持っている方に、少しでも参考になれば幸いです。
【docker版】LLMベクトル検索をWebアプリで試す

# nlp4j-web-vectorsearch

The English version of this is here.

https://qiita.com/oyahiroki/items/90b666b4159c3c276728


---

ベクトルDBへの文書の格納、ベクトルDBでの文書検索を試すことができるWebアプリです。

キーワード検索の機能もありますので、ベクトル検索の結果と対比することも可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110265/24d0db3b-f4ba-7618-e35a-1adb607c7487.png)

# 0. 前提

Docker が動作する環境が必要です。

# 1. 導入

# 1-1. Embedding Server の導入と実行

Multilingual-E5-large Embedding Serever (nlp4j-llm-embeddings-e5) の導入をします。

導入

```
docker pull oyahiroki/nlp4j-llm-embeddings-e5:1.0.0.0
```

実行（初回はモデルファイルのダウンロードで起動後の処理に５分ほどかかります）

```
docker run -d --name nlp4j-llm-embeddings-e5 -p 8888:8888 oyahiroki/nlp4j-llm-embeddings-e5:1.0.0.0
```

実行結果例

```
>docker pull oyahiroki/nlp4j-web-vectorsearch:1.0.0.0
1.0.0.0: Pulling from oyahiroki/nlp4j-web-vectorsearch
cb57fedf0fd8: Download complete
80338217a4ab: Download complete
d1eecb43db8a: Download complete
b317c36e5a10: Download complete
1a5fd5c7e184: Download complete
b24483e35971: Download complete
5b1aa583d1ef: Download complete
10970da6d1d3: Download complete
90a925ab929a: Download complete
57bd701990a7: Download complete
7d9a34308537: Download complete
7478e0ac0f23: Download complete
4c7deb2ac32b: Download complete
727d8fc35079: Download complete
4f4fb700ef54: Already exists
edf7dd409191: Download complete
350cf53fd52a: Download complete
Digest: sha256:9640f3cd726ee2c04d9d422727ecafe59e55c253e6778e0948eabbc85845f762
Status: Downloaded newer image for oyahiroki/nlp4j-web-vectorsearch:1.0.0.0
docker.io/oyahiroki/nlp4j-web-vectorsearch:1.0.0.0

>
```


詳しくは以下の記事を参照してください

https://qiita.com/oyahiroki/items/ba01234cbf65e99b6577

# 1-2. Webアプリケーションの導入と実行

導入

```
docker pull oyahiroki/nlp4j-web-vectorsearch:1.0.0.0
```

実行

```
docker run -d --name nlp4j-web-vectorsearch -p 8983:8983 -p 8080:8080 oyahiroki/nlp4j-web-vectorsearch:1.0.0.0
```

ブラウザを開く

```
http://localhost:8080/nlp4j-web-vectorsearch/
```

以下のような画面になればOKです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110265/374a5546-7975-0538-7bc3-0463399dd0e7.png)

イメージについては以下を参照してください

https://hub.docker.com/r/oyahiroki/nlp4j-web-vectorsearch


# 2. 使い方

## ベクトルDBへの文書の投入

テキストボックスに適当なテキストを入力し、「POST」を押すと文書として格納されます。

## ベクトルDBでのベクトル検索

テキストボックスに適当なテキストを入力し、「Vector Search」を押すとベクトル検索が実行されます。

以下の例では「NY」と「ニューヨーク」がうまい具合にヒットしていることが確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110265/822d5690-7c15-2d97-e7ab-acdc9efadc81.png)



# その他

nvidia GPU が動作する環境（ドライバ導入済）での動作を前提としていますが、非nvidia環境での動作も確認済みです。


---

以上.
ログ設計の基本

# はじめに
ログには様々なパターンがあると思いますが、最低限これをやっておけば運用後に困らない、というものをまとめたものとなります。

皆様の参考となれば幸いです。

### 環境
今回ご紹介するサンプルソースは以下の構成となります。
* C#
* Nlog

また、フィールドにはNLogを呼び出すための変数を定義しています。

```C#
private static NLog.Logger _logger = NLog.LogManager.GetCurrentClassLogger();
```

## メソッドの開始、終了

各メソッドの開始、終了にログを出力することで、どのメソッドで停止または異常が起きたかを正確に特定できます。特に、複数の非同期処理や並列処理が絡むプログラムでは、処理の流れを追いやすくなります。

```C#
public void HogeHoge()
{
    _logger.Info("HogeHoge：Start");

    // 処理

    _logger.Info("HogeHoge：End");
}
```

途中で処理を終了したい場合もreturnの前にログを出力するようにします。

```C#
public void HogeHoge()
{
    _logger.Info("HogeHoge：Start");

    // 処理

    if(条件)
    {
        _logger.Info("HogeHoge：End");
        return;
    }

    _logger.Info("HogeHoge：End");
}
```

:::note info
このほか、複雑なビジネスロジックや多層アーキテクチャにおいて、「どのメソッドがどの順番で実行されるか」を確認するのに役立ちます。
:::

### パラメータや変数の出力
パラメーターや変数の値を出力する事で、実際にプログラムがどのような入力を受け取っていたか把握でき、問題の再現が容易になります。

本番環境で問題が発生した際、パラメーターや変数の値を記録しておけば、デバッグ環境を構築せずに原因を特定できます。



```C#
public void HogeHoge(int param_A , int param_B)
{
    _logger.Info("HogeHoge：Start");
    int param_C = 外部APIのパラメーター();

    _logger.Info($"param_A：{param_A}");
    _logger.Info($"param_B：{param_B}");
    _logger.Info($"param_C：{param_C}");

    _logger.Info("HogeHoge：End");
}
```

:::note info
外部APIからパラメーターを取得する場合、想定していないパラメーターが入ってくる場合もあるので、潜在的なバグや不具合を未然に発見することが可能です。
:::

### 条件分岐の動作確認
（この様な大量のネストは避けたいですが）実行時にどの条件が成立してどのコードが実行されたかを正確に把握できます。

```C#
if(条件A)
{
    _logger.Info("条件A");
    if(条件B)
    {
        _logger.Info("条件B");
        if(条件C)
        {
            _logger.Info("条件C");
        }
    }
}
```

今回はif文の条件を「条件A」という簡単な表現にしましたが、複雑な条件式である場合、パラメーターをログで出力していてもどの条件式を通過したのか分かりやすくなります。


また、条件分岐だけでなく、その前後の処理や関連するパラメーター値と合わせてログを出力することで、処理フロー全体を把握しやすくなります。

```C#
_logger.Info($"条件A成立: param_X={param_X}, param_Y={param_Y}");
```

:::note info
テスト環境や本番環境での挙動が設計通りであることを確認する助けになります。
特定の条件が成立しない場合や、予期せぬ分岐が実行された場合に、その箇所を特定しやすくなります。
:::

### 例外処理
最後に、例外処理のメッセージを出力しておくと後の解析に役立ちます。

```C#
try
{
    // 処理
}
catch (Exception e)
{
    _logger.Error(e.Message);
}
```

https://learn.microsoft.com/ja-jp/dotnet/api/system.exception.message?view=net-9.0