OmniAICreator/Qiita-1.07M huggingface dataset:
【WordPress】自動返信メールのあり・なしの条件分岐

エンジニア歴約半年の駆け出しエンジニアです。
今回はWordPressで自動返信メールのあり・なしの条件分岐に結構詰まってしまったので備忘録として残しておきます。

**自動返信メールを"受け取らない"にチェックしても自動返信メールが送信されてしまう**
最初はラジオボタンの中に"受け取る"と"受け取らない"を入れてしまっていたのでそれが原因だと思いチェックボックスにして項目を分けましたがそれでも送信されてしまいました。

## 解決方法
[お客様への自動返信をある/なしを、スイッチで制御したい](https://qiita.com/masaru21/questions/a62694fd2bf75ca0f1b3)
上記の記事を参考に少し変更をしました。

**手順①**
![スクリーンショット 2024-02-01 121425.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3474232/b6d8d2fc-6716-3b14-b94d-ab95df25f29e.png)
メール（2）の「メール（2）を使用」にチェックを入れます。

**手順②**
今回は"受け取らない"のチェックボックスのみ設置し、"受け取らない"を選択されなかったときは自動返信メールを送信するという処理にしました。
以下のコードを**function.php**に貼りつけます↓
~~~
function my_wpcf7_additional_mail($additional_mail,$contact_form) {
	if( isset($_POST['checkNone'])){
		$additional_mail = [ ];
	}else{
		$additional_mail = $additional_mail;
	}
	return $additional_mail;
}

add_filter('wpcf7_additional_mail','my_wpcf7_additional_mail',10,2);
~~~
これにより"受け取らない"を押したときのみ自動返信メールを制御できるようになりました。


**応用**
```
function my_wpcf7_additional_mail($additional_mail,$contact_form) {
	if( isset($_POST['checkForm'])){
		$additional_mail = $additional_mail;
	}else if( isset(($_POST['checkNone']))){
		$additional_mail = [ ];
	}else{
		$additional_mail = $additional_mail;
	}
	return $additional_mail;
}

add_filter('wpcf7_additional_mail','my_wpcf7_additional_mail',10,2);
```
これにより"**受け取る（checkForm）**"を押したら自動返信メールが送信され、"**受け取らない（checkNone）**"を選択したら制御され、どちらも選択されなかった場合は自動返信メールが送信されるようになります。
VC++ MFCでの(List Control)作成方法メモ

すぐに忘れてしまうので、VC++ MFCでの(List Control)作成方法メモ

# 環境
- Windows 10
- Visual Studio 2022 C++

# 準備
1. 最新のvXXXビルドツール用 C++ MFC(x86およびx64)　のインストール
    - MFCは、個別のコンポーネント　でインストールしないといけない
    link:[第一回-02 コンソールアプリケーションとGUIアプリケーション](https://brain.cc.kogakuin.ac.jp/~kanamaru/lecture/prog1/01-intro02.html)

# 作成
1. 新しいプロジェクト　で、MFCアプリを作成
    - アプリケーションの種類を　ダイアログベース　で作成する
    （リソース上でコントロールを追加できる）  
    <br>

1. リソース上のダイアログに、「List Control」を追加
    - プロパティの「ビュー」は、「レポート」を設定、その他属性設定
    - リソース「List Control」で右クリック
        →　変数の追加
        　　→　コントロール変数の追加　に「m_list」で、完了
    - OnInitDialog に初期設定を追記
    ```C++
        // スタイル
        m_list.SetExtendedStyle(m_list.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
    ```
    link:[【C++/MFC】リストビューの基本的な使い方](https://hirokio.jp/programming/cpp-mfc-listview-howtouse/)
    <br>

1. まず、最初の列を設定する
    - 今回は、カラム(項目)数は、初期固定とする
    - Dialog側のClass(OnInitDialog、OnPaint、等のClass)に、最初の列用のstructをprivateで定義する
    ```C++
    class CxxxDlg : public CDialogEx
    {
    ...
    private:
    	struct FirstCol
    	{
    		int cx;				// 幅
    		std::tstring text;	// タイトルテキスト
    
    	};
    ```
    - ついでに、カラムIndexと個数の為、同じ位置にenumも定義する
    ```C++

    ...

	enum class ItemRow : int
	{
		en = 0,
		ja,

		max
	};
    ```
    - OnInitDialog の初期設定記入箇所に戻り、最初の列(カラム)を挿入する
    ```C++
    	const FirstCol init_FirstCol[] =
    	{
    		{200, TEXT("English")},
    		{100, TEXT("日本語") },
    	};
    
    	LVCOLUMN col;
    
    	col.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
    	col.fmt = LVCFMT_LEFT;
    
    	for (int i = 0; i < _countof(init_FirstCol); i++)
    	{
    		col.cx = init_FirstCol[i].cx;
    		col.pszText = (LPTSTR)init_FirstCol[i].text.c_str();
    		col.iSubItem = i;
    		ListView_InsertColumn(m_list, i, &col);
    	}
    ```
    - 以下の通りになります
    ![2024-02-01_114241.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/612873/268f26ad-c0cc-d1e0-8c8f-91ab7971233b.png)
    link:[リストビュー](https://wisdom.sakura.ne.jp/system/winapi/common/common15.html)

# 操作
- 後は追加したいタイミングで、ListView_InsertItemで追加して、ListView_SetItemで残りの項目を変えていく
    ```C++
    	// リスト追加
    	LVITEM item = { 0 };
    	int nCount = ListView_GetItemCount(m_list);
    	std::tstring msg1 = TEXT("English") ;
    
    	item.mask = LVIF_TEXT;
    	item.pszText = (LPTSTR)msg1.c_str();
    	item.iItem = nCount;
    	item.iSubItem = static_cast<int>(ItemRow::en);
    	ListView_InsertItem(m_list, &item);
    
    
    	item = { 0 };
    	std::tstring msg2 = std::format(TEXT("英語 {}"), nCount);
    
    	item.mask = LVIF_TEXT;
    	item.pszText = (LPTSTR)msg2.c_str();
    	item.iItem = nCount;
    	item.iSubItem = static_cast<int>(ItemRow::ja);
    	ListView_SetItem(m_list, &item);
    ```
- 以下の通りになります
![2024-02-01_122731.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/612873/300404c6-f499-3a4b-1a6b-b569a729033e.png)
link:[リストビュー](https://wisdom.sakura.ne.jp/system/winapi/common/common15.html)
Neovimをdockerで運用する

# モチベーション

ネット上には様々なNeovimの設定やおすすめプラグインがありますが、それらが自分にとって便利かどうかは実際に設定したりインストールして試してみるほかありません。

実際に使ってみて合わなかったり不具合が起きたらアンインストールして・・・という風に試行錯誤を重ねながらそれぞれの設定ファイルを作り上げていくと思います。

これがNeovimの醍醐味であるとは感じますが、インストール↔︎アンインストールを繰り返したり、作ったNeovim環境の再現にはホストマシンにいろんなミドルウェア入れたりとすんなりいかなかったりするのを受けていっそ「実行環境ごと用意してしまえば？」と思い、コンテナ内にNeovim実行環境をまるっと閉じ込めることにしました


# 概要図

![スクリーンショット 2024-02-01 12.01.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489761/13b232ca-5e84-c270-8edc-4ada7c2cc5ec.png)

プロジェクト内容だけはコンテナ内に入れるわけにはいかないので、「コンテナにNeovim実行環境だけ用意」して、「プロジェクトファイルはホストからマウント」する方式を取ります。

# 手順

1. ベースとなるイメージを決める
    1. 私は `Ubuntu 22.04`を使用しています
    1. ミドルウェアのインストールで`apt get`系の記事が多いため、こちらを使っています
1. Neovimをインストールします
1. Neovimコンテナ内でプラグインをインストールします
    1. プラグインのインストールや実行に必要なミドルウェアをインストールした場合はDockerfileに書き込んでimageに含めてしまいましょう
1. 3を繰り返して自分好みのNeovimを作る

# 利点

- Docker内で完結するのでローカルPCを汚さない
- プラグインのインストールに失敗してもコンテナ作り直せば環境ごとリセットできる
- NeoVimのバージョンアップも試してダメなら簡単に巻き戻せる
- 他の人のNeoVimを簡単に試すことができる

# 欠点

- ホストマシンでコピーした内容をコンテナ内のNeovimでペーストできるが、その逆のNeovimコンテナ内でコピーした内容がホストマシンでペーストできない
    - ~~clipboardを認識していないようで現在解消方法を模索中~~
    - neovim 0.10.0 からは可能になった！
    - 参考：https://lifelongboy.com/easy-nvim-copy-and-paste-on-docker/
- x64アーキテクチャのubuntuを使用しているので、Apple Silicon系のMacだと遅いかもしれない
    - ソースコードからNeovimをビルドすれば早くなる「かも」
- ミドルウェアを入れまくる必要があるので、コンテナイメージが3GBを超えてしまっている・・・
- そのため、ビルドが遅い

# 実際に作って使ってみて

- ホストPCでNeovim動かしていた時と比べても遅くなった感じはそんなにしない
- Neovimのバージョンアップとかプラグイン追加/削除が前よりもかなり気軽にできるようになった
- 他のPCでの再現がめちゃくちゃ簡単になった

# 私のNeovim環境

https://github.com/krile136/nvim-docker
Node.jsを使ってサーバを起動する際に、React Iconsが原因のエラーが発生

# はじめに
Viteを使って作成していたサイトをSSRに移行しようとしていた時に起きたエラーです。

server.jsなどを使ってサーバを立ち上げようとすると

```bash
SyntaxError: Named export 'BsSoundwave' not found. The requested module 'react-icons/bs/index.esm.js' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from 'react-icons/bs/index.esm.js';
const { BsSoundwave } = pkg;
```

というようなエラーが発生しました。

#### 開発時のバージョン

| 使用技術 | バージョン |
|:-:|:-:|
| Node.js  |  20.10.0 |
|  vite | 4.4.5  |




# 解決法

[こちら](https://github.com/withastro/astro/issues/7629)を参考にすることで解決をすることができました。

具体的には **vite.config.ts**に下記のコードを追加します。

```vite.config.ts
export default defineConfig({

  // この部分を追加
  ssr: {
    noExternal: ["react-icons", ],
  },
});
```

以上でエラーが起きることなくサーバの立ち上げが可能になります。

# おわりに

記事にする程の内容ではないと考えていましたが、react-helmet-asyncを導入した際にも同じようなエラーが発生し、同じ方法で解決できたこともあって、忘備録として残しておきます。

同じエラーに遭遇された方がいれば参考にしてください。
【ChatGPT有＋DALL-E3】描画する際のやり方。メンション機能にも言及。


　どうも、カーブミラーです。

　今回は、描画する際のやり方をいくつか書きたいと思います。これ、人によって、パターンは違います。

:::note info
本記事は、ChatGPT（有料版）
＋DALL-E3で行なっております。
画像はありません。あしからず。
:::

　描画する際のやり方？
　　なんだそれ？
　　　と思われるかもしれませんね。

　私は、
　　これまでごらんのように、
　　　まず、簡単な文章を与えて
　　　　描画して、多少のやり取りを
　　　　　やって、そこから
　　　　　　プロンプトを出力させて
　　　　　　　修正していく感じです。

　ところが
　　人によっては
　　　簡単な文章を
　　　　いくつも箇条書きにして
　　　　　それで描画指示することも
　　　　　　あります。

　また、別の人は
　　音声入力を使って、
　　　文章を気にせずに
　　　　どんどんと入力していきます。

　ゴールシークプロンプトの
　　シュンスケさんが
　　　このタイプですね。

　シュンスケさんは
　　マインドマップも
　　　お使いになられます。

　You TubeのLIVEに
　　参加したことがありますが、
　　　この二点に驚いたものです。

　まぁ、
　　そのLIVEの時点では
　　　ChatGPTアプリがなかったので
　　　　音声入力もプラグインでした。

　ほかには、
　　というよりは
　　　最近は、GPTsを使っての
　　　　描画をする人も
　　　　　多くなってきた
　　　　　　気がします。

　DALL-E3での描画が目的でも
　　なんのための描画なのかは
　　　人によって、変わります。

　だから、自分に合ったGPTsを
　　使うことになるわけです。

　しかし、
　　そのGPTsを探すのは
　　　かなりの手間が掛かります。

　だって、
　　GPTsは、もう何百万と
　　　登録されていて、
　　　　検索機能があっても
　　　　　画像関連はとても多い。

　できれば
　　どこかのコミュニティに
　　　入って、教えてもらうのが
　　　　いいかもしれません。
***
　さて、
　　“@”の入力で
　　　メンション機能が
　　　　起動するようになりました。

　まだ、
　　開放されておられない方も
　　　おいでかもしれませんね。

　私は、
　　昨日、開放されました。

　でも、スマホユーザーなので、
　　機能しないのが、残念です(泣)

　まぁ、私のことは置いといて、
　　このメンション機能は
　　　面白いもので
　　　　自分で単機能のGPTsを
　　　　　作って、それらを
　　　　　　組み合わせる、という
　　　　　　　形が取れるように
　　　　　　　　なるわけです。

　単機能とは？
　　それなりのプロンプトを
　　　内包したものですね。

　例えば、
　　自分のスタイルで
　　　描画をしてもらいたい。

　そのためには
　　プロンプトを
　　　作って使ってきました。

　それが
　　GPTsを
　　　使うことで、
　　　　ちょっとした単語や文章を
　　　　　入力すれば、
　　　　　　自分のスタイルで
　　　　　　　描画されます。

　目的のプロンプトを
　　管理するのは
　　　意外と大変。

　それが
　　GPTsになれば、
　　　メンション機能で
　　　　簡単に呼び出せます。
***
　このメンション機能の
　　素敵な機能は
　　　同じセッションで
　　　　いくつものGPTsを
　　　　　呼び出せることです。

　だから
　　単機能のGPTsを
　　　組み合わせて、
　　　　最終的な成果物を
　　　　　作成できるわけです。

　例えれば、
　　単機能のソフトを
　　　いくつも使って
　　　　プレゼン資料を作る。

　それらの
　　ソフト切り替えを
　　　ChatGPT上で行なえる
　　　　感じでしょうか。
***
　この記事が
　　みなさんの
　　　作品制作の糧に
　　　　なれば、幸いです。

　今回は、ここまで。
パルワールドwindows鯖のアップデート方法(SteamCMDでインストールした場合)

# windows鯖のアップデート方法
windows鯖のSteamCMDで、インストールした場合のアップデート方法 を記載します

「参加しようとしている対戦は互換性のないゲームバージョンで実行中です。ゲームバージョンを更新してください。」画面が出た場合、鯖のバージョンを更新する必要があります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/771936/315d36b6-7e60-d435-db2a-9cd90d733f32.png)

## 起動中の鯖停止
起動している下記の画面を×ボタンをクリックして閉じます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/771936/6b9f12fd-a8e9-062b-0771-5510670f68c1.png)

## Steamcmdを起動
インストールした場所の下記のexeを起動します
C:\～インストールした場所～\steamcmd\steamcmd.exe

## ログイン
起動した画面で下記を入力してログイン
```
login anonymous
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/771936/b9d2630e-2916-eba4-88ee-5c9800668576.png)


## アップデートを行う
```
app_update 2394010 validate
```

2,3分ほど掛かります。端末の性能や前回のアップデートから間隔があくと長くなる場合があります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/771936/79e322ac-3c98-475f-f129-05b9808a26d6.png)

## 鯖を起動
インストールした場所のPalServer.exe を起動し接続できることを確認してください
C:\～インストールした場所～\steamcmd\steamapps\common\PalServer\PalServer.exe

# まとめ
現在は不具合が多く頻繁にアップデートが入ります
アップデートの前にはバックアップすることをお勧め致します。
バックアップと復旧の方法については、別途纏めたいと思います
Fortigate で異なるAS間でのBGPルーティングを行いたい

現在は、検証中で同一AS内でのピアは確立できることを確認しました。
でも、異なるAS間でのピアが確立できません。

AS間(異なるAS間)でBGPでルーティングする場合、ピア確立時にBGP Openメッセージで自分のAS番号を通知しますが、ピア同士が異なるAS番号の場合、自動的にEBGPでピア確立されるのが普通、という理解でよろしいのでしょうか？
下記のようなメッセージが表示され、TCPセッションが終了し、ピアが確立できませんでした。
AS100と200間でのピア確立時にFortigateに表示されたエラーメッセージ
メッセージ：
BGP: 10.1.0.2-Outgoing[DECODE] Open: Bad RemoteAS(200), expected 100

ちなみに、ルータ同士は直結です。(したがってTTLの変更の必要はないと思います。)
Fortigateの設定上でEBGP/IBGPを明示的に設定する必要があるのでしょうか？

よろしくお願いいたします。
Amazon Linux 2023の初期設定

# Amazon Linux 2023 初期設定

Amazon Linux 2023 をAMIから起動した後に必要そうな初期設定を記載します。
初期設定後、停止してAMIを取得しておきマスターイメージとして使い回すことを想定しています。

### アップデート

```
$ sudo dnf update
```

### ホスト名設定

```
$ sudo hostnamectl set-hostname <hostname>
```

### タイムゾーン変更

```
$ sudo timedatectl set-timezone Asia/Tokyo
```

### SELinux無効化 
デフォルトはPermissiveです。
無効化が必要な場合は実施してください。

```
$ sudo rpm -q grubby
grubby-version

$ sudo getenforce
Permissive

$ sudo grubby --update-kernel ALL --args selinux=0

$ sudo reboot

$ sudo getenforce
Disabled
```

### ログローテーション設定
値は環境に合わせて設定してください。

```
$ sudo cp -p /etc/logrotate.conf /etc/logrotate.conf.org
$ vi /etc/logrotate.conf
```

```logrotate.conf
# see "man logrotate" for details

# global options do not affect preceding include directives

# rotate log files weekly
weekly

# keep 4 weeks worth of backlogs
rotate 12

# create new (empty) log files after rotating old ones
create

# use date as a suffix of the rotated file
dateext

# uncomment this if you want your log files compressed
compress

# packages drop log rotation information into this directory
include /etc/logrotate.d

# system-specific logs may also be configured here.
```

## ここからは環境に沿って、必要あればインストールを検討してください。

### rsyslogインストール
Amazon Linux 2023ではrsyslogがインストールされていないので、必要があればインストールしてください。
※デフォルトではjounalに保存されていてjounalctlを使ってログを確認します。

```
$ sudo dnf install rsyslog
$ sudo vi /etc/logrotate.d/rsyslog
```

#### rsyslogログローテーション設定
値は環境に合わせて設定してください。

```md:rsyslog
/var/log/cron
/var/log/maillog
/var/log/messages
/var/log/secure
/var/log/spooler
{
    rotate 12
    weekly
    missingok
    compress
    notifempty
    dateext
    sharedscripts
    postrotate
        /usr/bin/systemctl kill -s HUP rsyslog.service >/dev/null 2>&1 || true
    endscript
}
```

#### rsyslog起動
```
$ sudo systemctl enable rsyslog
$ sudo systemctl start rsyslog
```

### telnetインストール
いざという時の疎通確認のためインストールしています。

```
$ sudo dnf install telnet
```

### cronieインストール
Amazon Linux 2023ではcronがインストールされていないので、必要があればインストールしてください。
cronieをインストールするとcronが使えるようになります。

```
$ sudo dnf　install cronie
$ sudo systemctl enable crond
$ sudo systemctl restart crond
```

### CloudWatch Agentインストール
カスタムメトリクスを取得したいのであればcollectdもインストールします。

```
$ sudo dnf install amazon-cloudwatch-agent
$ sudo dnf install collectd
```

以上となります。
少しでも皆さんの参考になれば幸いです。
【JavaScript】コールバック関数とは

## はじめに
JavaScriptのコールバック関数についての理解を深めるために、少しまとめてみたいと思います。

## コールバック関数とは
* 引数に入っている関数のことを「コールバック関数」と呼びます

```javascript: 例
const numbers = [1, 2, 3, 4, 5];

const squaredNumbers = numbers.map((num) => num * num);
console.log(squaredNumbers); // [1, 4, 9, 16, 25]
```

mapメソッドは配列内の全ての要素に処理を行い、その戻り値から新しい配列を作成するメソッドです。

上記の例では配列numbersの全ての要素を2乗した要素を持つ、新しい配列を作成しています。

## コールバック関数を使う意義
* コールバック関数を使うことで、mapやfilterなどの関数を活用できるようになります
* コールバック関数を使わない場合、手動でループを書く必要があります

```javascript: コールバック関数を使わずに書き換えると・・・
const numbers = [1, 2, 3, 4, 5];
const squaredNumbers = [];

for (let i = 0; i < numbers.length; i++) {
    const squared = numbers[i] * numbers[i];
    squaredNumbers.push(squared);
}

console.log(squaredNumbers); // [1, 4, 9, 16, 25]
```

コールバック関数を使わない場合、このようにforループを使って一つずつnumbersの要素を取り出し、処理を行うコードを記述しなければいけません。
メディア プレーヤー（!=Windows Media Player Legacy）の履歴を表示しないようにする方法

とりいそぎ備忘録。ここに再生履歴が表示されて困る方向け。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2522426/7e5e0ea9-7e0c-88b2-9a5a-fbaf06e4a663.png)

1. メディア プレーヤーを開く
1. ホームの画面に表示された再生履歴を消す
1. メディア プレーヤーを閉じる
1. `%localappdata%\Packages\Microsoft.ZuneMusic_8wekyb3d8bbwe\LocalState`
にアクセス
1. `MediaPlayer.db-wal`のプロパティを開く
1. 読み取り専用にチェックを入れる
1. 以降再生履歴が保存されなくなる
保存したい場合は読み取り専用のチェックを外す

なんでプレーヤーの設定に履歴保存可否の項目ないんですかね。。

----

追伸: 25/03/28
プレーヤーで再生しようとしたら何も言わずにコケたので、多分上記設定のせいだと思いました。回避策を以下に記します。
※もしかしたら`MediaPlayer.db-wal`の読み取り専用を外して起動すればよかっただけだったのかも。すでに直してしまったので試せず。

1. スタート→ファイル名を指定して実行を選択
1. `ms-settings:appsfeatures`をフォームに入力しOKボタンを選択
1. 一覧から「メディア プレーヤー」の…アイコンを選択→詳細オプションを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2522426/7d4daa40-3114-4108-9ed3-81f32192671b.png)
1. リセットを選択(残念ながら修復では直りませんでした)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2522426/0bb81b21-c561-4a05-8378-fcb2d6b1ad89.png)
1. 出てきたポップアップでリセットを選択
1. 再度プレーヤーを起動すると正常再生できるはず。
設定リセットされているので、履歴取られたくない方は最初の手順に従い`MediaPlayer.db-wal`を読み取り専用にしてください。

以上。大変恐縮ですが、諸々自己責任でよろしくお願いいたしますm(__)m
二重ループ：活用編 三角形の探索

https://paiza.jp/works/mondai/double_roop_problems/double_roop_problems__triangle

今までの例からしてこれでいけると思ったんですけどね。。。
だめでしたね。おそらくループが多すぎるのだと思います。


```py
N = int(input())
Ans = "NO"
for a in range(1,N):
    for b in range(1,N-a + 1):
        for c in range(1,N-a-b + 1):
            if a ** 2 == b ** 2 + c ** 2:
                Ans = "YES"
                
print(Ans)
```
でもよく考えたら、ですね。
2辺が決まったら、あともう1つって自動で決まるんですよね。
だからforを一つ減らせます。
ただ、aが０にならないようにしないとですが、
結局Falseになるので関係ないか。

```py
N = int(input())
flag = False
for B in range(1,N):
    for C in range(1,N-B):
        A = N - B - C 
        if A ** 2 == B ** 2 + C ** 2:
            flag = True
if flag:
    print('YES')
else:
    print('NO')
```

ふむ、なかなかおもしろい。
AWS Certified Solutions Architect - Professional(SAP-C02) 合格体験記

# はじめに
数か月前に「AWS Certified DevOps Engineer - Professional」(DOP-C02)を取得したので、次にProfessionalで残っていた「AWS Certified Solutions Architect - Professional」(SAP-C02)を受験しました。

# スコア
**836/1000**

無事に合格できました。
各問題の文章量がDOPと比較して多いように感じました。
難易度については合格した方たちの体験記を見たり、会社の人に色々聞いたりはしていましたが、その内容を実感できました。
DOP受験時と比較して計画的には学習できていたと思いますが、そのせいか学習期間が長くなり、間延びしてしまった感もあります。

# 受験対策

### 書籍
- AWS認定資格試験テキスト＆問題集 AWS認定ソリューションアーキテクト[プロフェッショナル]
何周か読んだりはしてましたが、正直あまり活用したとは言い切れないと思います。
早々にWeb問題集の実施に切り替えました。

### Web問題集
https://kws-cloud-tech.com/

3～4周くらい実施しました。

https://cloud-license.com/

#15～#83まで4周位実施しました。
間違えた問題はお気に入りに入れて、空いている時間などに繰り返し学習するようにしました。

### 本を読む
SAPは文章量がかなり多いと聞いていたので、日頃から読書することを意識して行いました。
長い文章を読むスピードを上げたかったのと短時間で文章の内容を理解する能力を上げたかったのですが、どれくらい読解力が上がったのわからず、効果は不明だったりもします。。。

# 受験方法
テストセンターで受験しました。
試験に集中したいというものあり、テストセンターでの受験を個人的におすすめしています。

# 対策と受験の心構え
これはおそらく受験した方が皆言っていることだと思いますが、文章量が多いように感じました。
そのような問題でも1問あたり2分弱位しか時間を使えません。(見直しの時間も必要ですので。)
しかも試験時間が180分近くあり、体力と集中力がごっそり持ってかれる結構しんどい試験だなと思います。

あまり、長く問題文や選択肢の文章を見ていると目が痛くなるので、回答悩みそうなものわからない問題については問題文と選択肢をざっとみて回答し、なるべく読む文章量を少なくし、長丁場の試験で集中力を切らさないようにすることを優先しました。
ありえなさそうな選択肢をあらかじめ除外するようにし、読む文章量を減らすよう心がけて挑みました。

とにかく、未回答の問題があった状態で試験時間終了とならないことを目標にまずはすべての回答を埋めるところを意識しました。
全問回答後、改めてフラグを立てた問題を見直し、回答を修正したりしました。

# おわりに
まず、合格できてよかったです。
あと目標にしていた今年度中の6冠達成できて素直にうれしいです。
これで全AWS認定試験のうちまだ半分なので、残りの専門知識の方も挑戦していきたいと思います。

# AWSの相談・お困りごとありましたら、、、

AWSの活用方法や、お困りごとの相談、随時、お仕事の受付しております。

https://www.cs-cloud-aid.com/
【Rails】標準ライブラリ「objspace」って何者？

どうもこんにちは。

今回はアプリケーションのソースコード理解を進めている中で知らないライブラリがあったので調べてみました。

# 標準ライブラリって何？

標準ライブラリとは、Gemfileを通じてインストールする必要がないRubyにすでにインストールされているライブラリのことを指します。

わかりやすいものでは、`CSV`ライブラリがRubyの標準ライブラリとして使用されます。これは、使用したいコントローラーやモデルのファイルの中で`require`するだけです。

```ruby
# これを記述すると
require 'csv'

class Sample
    def format_export
        respond_to do |format|
            format.csv do
                bom = "\uFEFF"
                # CSVクラスを使用してコードを書くことができます。
                csv_data = CSV.generate(bom) do |csv|
                    csv << ['タイトル', 'コメント']
                end
                send_data(csv_data, filename: "title_and_comment.csv")
            end
        end
    end
end
```

一方で、`aws-sdk`などの外部で用意されたライブラリはGemfileを使用してインストールする必要があります。

## 追記

@tanakam 様からの助言をいただきましたので追記します。

> `csv`はdefault gemと呼ばれる立ち位置のライブラリなのですが、Ruby 3.4からはbundled gemというものに変更されるので、Gemfileへの記載が必須になります。
Ruby 3.3でもGemfileに書いていないと警告が出るようです。

Ruby3.4へアップグレードする場合には忘れずにGemfileへ記述する必要がありそうですね。

# objspaceって何者？

`objspace`はオブジェクトスペースに関する詳細な情報を提供してくれるそうです。

このライブラリが提供しているメソッドを使用すると、メモリ使用量やオブジェクトの内部構造がわかるようです。

実際に使用しているアプリケーションのRailsコンソールで試してみました。

## count_objectsメソッド

Railsアプリケーションで使用しているオブジェクトの数を出力してくれるようです。

```ruby
pry(main)> ObjectSpace.count_objects
=> 
{
    :TOTAL=>1278918,  # プロセス内の全オブジェクトの総数
    :FREE=>2999,      # 利用可能な（未使用の）オブジェクトスロットの数
    :T_OBJECT=>82998, # 汎用オブジェクトの数
    :T_CLASS=>28282,  # クラスオブジェクトの数
    :T_MODULE=>2729,  # モジュールオブジェクトの数
    :T_FLOAT=>13,　　　　　　　　　　# 浮動小数オブジェクトの数
    :T_STRING=>313107,# 文字列オブジェクトの数
    :T_REGEXP=>3944,  # 正規表現オブジェクトの数
    :T_ARRAY=>240731, # 配列オブジェクトの数
    :T_HASH=>75570,　　　　　　# ハッシュオブジェクトの数
    :T_STRUCT=>3177,　　　　# 構造体オブジェクトの数
    :T_BIGNUM=>254,   # BIGNUMオブジェクト（大きい数値を扱うオブジェクト）の数
    :T_FILE=>8,       # ファイルオブジェクトの数
    :T_DATA=>55545,   # データオブジェクトの数
    :T_MATCH=>1473,   # マッチデータオブジェクトの数
    :T_COMPLEX=>1,    # 複素数オブジェクトの数
    :T_RATIONAL=>629, # 有理数オブジェクトの数
    :T_SYMBOL=>8288,  # シンボルオブジェクトの数
    :T_IMEMO=>451172, # 内部メモリオブジェクトの数
    :T_ICLASS=>7998   # 内部クラスのオブジェクトの数
 }
 ```

## memsize_of_allメソッド

Railsアプリケーションで使用している全てのオブジェクトのメモリ使用量を出力してくれているようです。

```ruby
pry(main)> ObjectSpace.memsize_of_all
=> 88991854
```

## memsize_ofメソッド

特定のオブジェクトのメモリ使用量も出力してくれています。

```ruby
# 数字の格納された配列オブジェクト
pry(main)> ObjectSpace.memsize_of([1,2,3])
=> 40

# 数字と文字列が格納された配列オブジェクト
pry(main)> ObjectSpace.memsize_of([1,2,3,4, "AAA"])
=> 80

# Railsアプリケーションで使用しているUserオブジェクト
pry(main)> ObjectSpace.memsize_of(User)
=> 6320
```

## オブジェクトが定義された場所を取得する

以下のようにコードを記述するとオブジェクトの定義箇所を出力できる模様です。

```ruby
require 'objspace'

ObjectSpace.trace_object_allocations_start
o = Object.new # 調べたいやつ
ObjectSpace.trace_object_allocations_stop

puts ObjectSpace.allocation_sourcefile(o) # ファイル名
puts ObjectSpace.allocation_sourceline(o) # 行数
ObjectSpace.trace_object_allocations_clear
```

うまく使いこなせれば、アプリケーション開発でコスト最適化ができそう...？

以上
(注意)STM32C011(SOP8)でPA14をOUTPUTに設定して書き込み失敗?して遊ぶ。

前

↓ここをクリック↓

https://qiita.com/caa45040/items/62917ae9fe9dd134edbd

↑ここをクリック↑

x 自己責任の意味がわかる人だけ読んでください。

x ターゲットリセット信号の出る書き込み器を必ず用意してください。
x 必ず、全体のはじめの先頭に3秒のウエートを入れてください。
x 3秒ルールは、絶対に消さないでください
x てへ3じゃなくて3000で3秒

------------------

ちょっとお遊び風で時間稼ぎ。


夜も深まって来たので、そろそろ、ゲームを始めましょう。
その名は、「無限ループ脱出ゲーム」


では、各自、指定の席についてください。

x いらすとや　公共の福祉に反せず、反社会的、犯罪的目的で使用しません。

![o_cop917.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/63f9ab8b-ada5-2811-47b2-f82f82d6afdc.jpeg)



ルールを説明します。
わざと、無限ループを掛けて早く脱出し者を勝ちとします。

中華ST-LINKターゲットリセット改造ずみをお持ちでない方は、
この、ゲームには、参加できません。
お席を立っていただきます。

事前にターゲットリセット信号をターゲットに接続しておきます。

こちらから指定したプログラムを書き込んでいただきます。

![o_cop916.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/91dd9049-6c1e-0c6b-0681-8f6de6c53330.jpeg)



書き込むプログラム

```c++



//PA14のモードチェンジの実験です
//必ずターゲットリセットを接続してください。
//再書き込み手段として「3秒ルール」があり、3秒以内に接続してください。
//GPIO_PA14_OUTPUT_C011_1


//初期化
void setup() {

  delay(3000);//i don't. Not delete. (しらない、消しちゃダメ)(不要删除文档)

  //ピンの初期化 PA14 SWD
  pinMode(PA14, OUTPUT);

  //ピンの初期化 PA8
  pinMode(PA8, OUTPUT);

} //setup


//無限ループ
void loop() {

  //PA8をオン
  digitalWrite(PA8, HIGH);

  delay(1000); //1秒待つ

  //PA8をオフ
  digitalWrite(PA8, LOW);

  delay(1000); //1秒待つ

} //loop



```

x失敗したら永遠にLチカ専用機の置物になります。電池を接続して部屋に飾りましょう。

むむ、ないも起きないて?

再度、おなじ、プログラムを書き込んでいただきます。

えー、あっさり書き込めたて!!!!

それが「脱出」成功なんです。

詐欺だ、詐欺だ、インチキだ、こんな、ことは、ない。

なにを言っているんですか?お客さん、あなたは、ゲームに「勝った」んですよ。
事前に言ったでしょこれは、ゲームなんですよ。
「STM32系」の書き込みゲーム

---------------------------

非常、脱出も用意してあります。
その名は、「3秒ルール」

今回は、簡単に説明しょう。


(1)STM32CubeProgを起動
(2)STM32C011が繋がった書き込み器をUSBに挿す。
(3)3秒以内にコネクト(接続)。失敗したら繰り返す。
(4)イレース
(5)デスコネクト
(6)USBを外す
AWS RDS証明書の有効期限のフォローアップ通知に惑わされる

Amazon RDS証明書が切れるというお知らせがきました。
そして、証明書を変更しました。

![スクリーンショット 2024-02-01 9.51.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17764/515f861b-ac1a-20cf-d90b-35805b108dee.png)
インスタンスの認証期間と認証期間の日付が更新されていることを確認。

数日後・・・
しかし、次のような通知メールが届きました。


>〜省略
これは、SSL/TLS CA 証明書の有効期限に関するフォローアップ通知です。もしこの対応を完了しているにも関わらず、本通知を受け取っている場合は、2019 CA を使用して新しいインスタンスを作成したことが原因と考えられます。新しく作成されたインスタンスで、別の CA を明示的に指定していないものはすべて、デフォルトが rds-ca-rsa2048-g1 に切り替えられる 2024 年 1 月 25 日まで 2019 CA を使用します。アカウントレベルの CA のオーバーライドの設定については、modify-certificates API ドキュメント [1] を参照してください。

文面から

:::note warn
2024/1/25までは古い証明書がデフォルトで使われるよ。
それまでにデフォルトを切り替えたい場合はmodify-certificates APIで更新してね。
:::

ということ？

つまりは、2024/1/26以降はデフォルトがrds-ca-rsa2048-g1に切り替わっているということと解釈。

https://aws.amazon.com/jp/blogs/news/rotate-your-ssl-tls-certificates-now-amazon-rds-and-amazon-aurora-expire-in-2024/

>現在から 2024 年 1 月 25 日まで – 新しい RDS DB インスタンスには、create-db-instance API の ca-certificate-identifier オプションで別の CA を指定しない限り、デフォルトで rds-ca-2919 証明書が含まれます。または、上記のセクションで言及したように、アカウントのためにデフォルトの CA オーバーライドを指定します。
2024 年 1 月 26 日以降 – 新しいデータベースインスタンスは、rds-ca-rsa2048-g1 証明書を使用するようデフォルト設定されます。新しいインスタンスのために別の証明書を使用することを希望する場合は、AWS コンソールまたは AWS CLI を使用して、どの証明書を使用するかを指定できます。詳細については、create-db-instance API ドキュメントを参照してください。

データベースインスタンスを作成する予定もないですし、急いで変更しなくていいかな。
デフォルトが勝手に切り替わってくれるならそれでいいな。


### そして、迎えた2024/1/26
この記事を書いているのは2/1
いまだにデフォルトはrds-ca-2019のまま

データベース新規作成から

![スクリーンショット 2024-01-30 9.46.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17764/c6951a60-5226-bbea-d1c0-c2b304311239.png)

時差なのか、明示的に更新をしないといけないのか。

### 結局、手動でデフォルトの認証機関を更新することに

https://dev.classmethod.jp/articles/rds-modify-default-certificates/
こちらの記事を参考にさせていただきました。

AWS　CLIでデフォルトの設定を確認

```
aws rds describe-certificates --region <region name>
```

```
〜省略
    ],
    "DefaultCertificateForNewLaunches": "rds-ca-2019"
}
```

（AWS CLIの結果から抜ける場合は「q」を入力します。）

デフォルトはやはりrds-ca-2019となっています。

仕方ないので更新してみます。
デフォルトをrds-ca-rsa2048-g1に変えたいので、

```
aws rds modify-certificates \  
    --certificate-identifier rds-ca-rsa2048-g1 \  
    --region <region name>
```

もう一度、AWS　CLIで確認

```
aws rds describe-certificates --region <region name>
```

```
],
    "DefaultCertificateForNewLaunches": "rds-ca-rsa2048-g1"
}
```

先ほどと表記が変わっていました。

念の為、データベース新規作成時の認証機関を確認。

![スクリーンショット 2024-02-01 10.19.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17764/31b20bb6-19d0-fccf-a71e-e7335ae5025c.png)

無事にデフォルトが変わっていました。


そのうちデフォルトも切り替わっているのかもしれませんが、デフォルトが古い認証機関のままインスタンスが作成されてしまうことを避けたい場合は忘れる前に手動で更新しておいたほうが良いですね。
2024年02月未解決の質問

[2024年02月の質問の中から整理します](https://qiita.com/Keiji_otsubo/items/d4781c3b3e21984e8f7a)

+ [We can't find a role named 'Chief Sales Officer', or it doesn't report to the correct role.](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000IQmRo)
+ [ step 10. Where's the Sektion Properties Window?](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007XA8NX)
+ [[デザイナーにクリップ] をクリックしていますが、新しいウィンドウが開いてもクエリが見つかりません。](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007YvYVT)
+ [How to prevent deletion of sandbox?](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007XGSnO)
+ [Visualforce JavaScript Remoting API の JsonAccess アノテーション検証を有効にします。](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007XIaCS)

+ [Could not find a properly routed case. Ensure that you've setup Omni-Channel correctly by following the requirements.](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007Yvb1d)

+ [Set Up Case Escalation and Entitlements > Create an Entitlement Process](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007XISG3)

+ [Command failed: cordova platform add android@12.0.1 ](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007YvVmC)



+ [Error (1): No default environment found. Use -o or --target-org to specify an environment.](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007ZACS9)



+ [The Quote Template is stating "Page not found" and not showing up in Quick Find search - help?](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007YvvSA)



+ [Googleシートにはさまざまな州、電話番号、住所などの情報がありますが、IDコードはありません。データローダーを使用する場合、重複や問題を発生させずにこれらのファイルをインポートするにはどうすればよいですか。](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007ZBSWl)

# 障害みたい

+ [Platform session cache is the same when using "Log In As Experience User" and Experience Builder Preview](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007XIRx6)


# メールの設定

+ [MS Exchange of the messages that did not come through, it displays Drop with this Detail:  Reason: [{LED=250 2.1.5 RESOLVER.GRP.Expanded; distribution list expanded};{MSG=};{FQDN=};{IP=};{LRT=}] ](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007XIYzz)


# Einstein GPT 

+ [No recommendations available](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007ZBRBs)



# よくわからない

+ [My Test Class is not showing up to Run Test](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007X8E5I)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/d7c997e7-72af-6cae-ae9e-d1cf56dc4f2e.png)
【初心者】jQueryで超簡単なクイズゲーム作ってみた！

## ♰はじめに♰　🦔
初投稿である。
JS初心者がクイズゲームを作ってみた。(製作時間20分)

最初はバニラJSだけで書こうと思ったが、古よりの技術「<strong>jQuery</strong>」を取り入れようと思う。
まずは<strong>HTML。
```index.html
<html>
    <head>
        <title>asobi</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <script src="https://code.jquery.com/jquery-3.7.1.js"></script>
        <style>
            h1{
                text-align: center;
            }
            #content{
                margin-left: 40%;
            }
        </style>
    </head>
    <body>
            <h1>四択クイズ</h1>
        <button id="start">スタート</button>
        <div id="content" hidden>
            <div id="q_num"></div>
        <div id="text"></div>
        <div id="buttons">
            <button id="button1"></button>
            <button id="button2"></button>
            <button id="button3"></button>
            <button id="button4"></button>
        </div>
        </div>
        <script src="main.js"></script>
    </body>
</html>
```
bodyタグ上から、タイトル、スタートボタン、問題番号、問題文、回答ボタン４つ。
後はお情け程度の<strong>css</strong>。
そして<strong>JS</strong>。
```main.js
(function ($) {
    const q_array = [
        {
            question: "愛媛県の県庁所在地は？",
            ans1: "松江市",
            ans2: "高松市",
            ans3: "松山市",
            ans4: "浜松市",
            correct: 3
        },
        {
            question: "さらば青春の光「森田哲矢」の相方は？",
            ans1: "北ぶくろ",
            ans2: "西ぶくろ",
            ans3: "南ぶくろ",
            ans4: "東ぶくろ",
            correct: 4
        },
        {
            question: "海豚の読みは？",
            ans1: "なまず",
            ans2: "いるか",
            ans3: "しゃち",
            ans4: "くらげ",
            correct: 2
        },
        {
            question: "豚に？",
            ans1: "真珠",
            ans2: "念仏",
            ans3: "小判",
            ans4: "金棒",
            correct: 1
        }
    ];
    //現在の要素番号
    let i = 0;
    //playerが選択したボタン番号
    let p_num = 0;
    //初期ロード時
    $(function () {
        createText();
    });
    //問題生成
    function createText() {
        $("#q_num").html("第"+(i+1)+"問");
        $("#text").html(q_array[i].question);
        $("#button1").html(q_array[i].ans1);
        $("#button2").html(q_array[i].ans2);
        $("#button3").html(q_array[i].ans3);
        $("#button4").html(q_array[i].ans4);
    }
    //正解時
    function seikai(){
        if (i===q_array.length-1) {
            $("#content").hide();
            $("h1").html("クリア");
        }
        i++;
        createText();
    }
    //不正解時
    function huseikai() {
        alert("不正解");
    }
    ;
    //ボタンクリック時
    for (let j = 1; j < 5; j++) {
        $("#button" + j).click(function () {
            p_num = j;
            if (q_array[i].correct === p_num) {
                seikai();
            } else {
                huseikai();
            }
        });
    }
    //スタートクリック時
    $("#start").click(function () {
        $("#start").hide();
        $("#content").show();
    });
})(jQuery);
```
これが初学者のコードです。こんな程度です。
次はもう少し時間かけて何か作ります。
G検定 勉強はじめてみた

# G（ジェネラリスト）検定の勉強を開始しました。

Python3 エンジニア認定データ分析試験と同時に、機械学習について学びたいと思ったため、G検定の勉強を開始しました。

## 参考資料
１．深層学習教科書 ディープラーニング G検定(ジェネラリスト)公式テキスト
２．徹底攻略ディープラーニングG検定ジェネラリスト問題集
３．最短突破 ディープラーニングG検定(ジェネラリスト) 問題集

## 学習スケジュール
試験予定日：2024年5月11日

1．2024年1月30日 ~ 2024年2月10日
　深層学習教科書 ディープラーニング G検定(ジェネラリスト)公式テキスト 1週目

2．2024年2月11日 ~ 2024年2月20日
　深層学習教科書 ディープラーニング G検定(ジェネラリスト)公式テキスト 2週目

======================まだ予定======================
3．2024年2月21日 ~ 2024年3月1日
　徹底攻略ディープラーニングG検定ジェネラリスト問題集 第2版 1週目

4．2024年3月2日 ~ 2024年3月12日
　徹底攻略ディープラーニングG検定ジェネラリスト問題集 第2版 2週目

5．2024年3月13日 ~ 2024年3月23日
　最短突破 ディープラーニングG検定(ジェネラリスト) 問題集 1週目

6．2024年3月24日 ~ 2024年4月4日
　最短突破 ディープラーニングG検定(ジェネラリスト) 問題集 2週目

7．2024年4月5日 ~
　深層学習教科書 ディープラーニング G検定(ジェネラリスト)公式テキスト 3週目
　AI白書　２０２２ (単行本)

## G検定とは
JDLA Deep Learning for GENERALは、一般社団法人日本ディープラーニング協会が実施するAIに関する検定試験および民間資格である。 特にディープラーニングの基礎知識を有し、適切な活用方針を決定して事業応用する能力を持つ人材の輩出を目的として実施されている。

###### 出題範囲
1.人工知能（AI）
2.機械学習
3.ディープラーニングの基礎概念と応用技術
4.ディープラーニングの研究分野
5.ディープラーニングの応用に伴う社会的課題
Google Chrome拡張機能開発における文字列置換問題の解決

Google Chromeの拡張機能を開発する過程で、ページ上に表示される特定の文字列を変更する機能の実装を試していました。しかし、この機能は期待通りには動作せず、特定の文字列を置換後、短時間で元の文字列に戻ってしまう問題に直面しました。この記事では、この問題の解決過程を共有します。忘れないようにこちらでもメモします。

# 【発生した問題】
試しに、開発したChrome拡張機能は、文字置換の動作を確認するために、ブラウザ上に表示される「ます」を「でござるよ」に置換するシンプルなものでした。content_script.jsとmanifest.jsonを使用して、ページロード時にテキスト置換を実行しますが、置換後すぐに元のテキストに戻ってしまうという問題が発生しました。

# 【作成したスクリプト】
content_script.js
```javascript
// content_script.js
function replaceText(node) {
  if (node.nodeType === Node.TEXT_NODE) {
    node.textContent = node.textContent.replace(/ます/g, "でござるよ");
  } else {
    node.childNodes.forEach(replaceText);
  }
}

replaceText(document.body);
```

manifest.json
```json
{
    "name": "text_replace",
    "description": "text_replace",
    "version": "1.0",
    "manifest_version": 3
    },
    "content_scripts": [
        {
          "js": ["content_script.js"],
          "matches": ["https://qiita.com/*"]
        }
    ]
}
```

2つのファイルをフォルダに保存して、chrome://extensions/ にアクセス→右上の [デベロッパー モード] をオン→[パッケージ化されていない拡張機能を読み込む] をクリックして取り込みました。

# 【確認したこと】
サイトを読み込んですぐは、「でござるよ」で変更されますが、
![スクリーンショット 2024-01-31 134629.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3688800/128b6183-b586-4453-1037-97712e72a65f.png)

1秒くらいたつとすぐにもとの「ます」にもどってしまいました。
![スクリーンショット 2024-01-31 134645.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3688800/ad883201-70cb-d9f1-3ea7-63df644bd029.png)

Chromeデベロッパーモードのコンソールで、content_script.jsの中身を打つと、文字列が変更されたまま表示されるので、何かしらの動作で上書きされてしまっているのだろうと推測しました。

# 【解決した方法】
[Qiitaに質問](https://qiita.com/robingho333/questions/deb2fa2352c1ad9b99eb)をしたところ、以下の回答をいただきました。
ご回答いただいた方々ありがとうございました。

「原因までは特定していませんがどこかで更新しているのかと思います。
ページ読み込み後に更新すれば変更はされそうですね。」
```
window.onload = function() {
   replaceText(document.body);
}
```
こちらを反映して、content_script.jsを書き換えました。

content_script.js
```javascript
// content_script.js
function replaceText(node) {
  if (node.nodeType === Node.TEXT_NODE) {
    node.textContent = node.textContent.replace(/ます/g, "でござるよ");
  } else {
    node.childNodes.forEach(replaceText);
  }
}

window.onload = function() {
   replaceText(document.body);
}
```

すると、無事に変更された文字列のまま表示されてます！やったー:grin:

![スクリーンショット 2024-01-31 134629.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3688800/128b6183-b586-4453-1037-97712e72a65f.png)
[CDGC] カスタムレイアウト(アセット画面のカスタマイズ) : 参考資料編

# はじめに
2023年11月のリリースにおいて、[インフォマティカ](https://www.informatica.com/jp/)が提供する[CDGC](https://www.informatica.com/jp/products/data-governance/cloud-data-governance-and-catalog.html)で、アセット画面レイアウトのカスタマイズができるようになり、ユーザーのニーズに対応しやすくなりました。

本記事では、カスタムレイアウト(アセット画面のカスタマイズ)を理解するに有用な動画、資料等の参考資料を紹介させていただきます。


# 資料群

<strong>Custom layouts for asset views</strong>
- カスタムレイアウトについてのマニュアルのドキュメント群です

https://docs.informatica.com/data-governance-and-quality-cloud/metadata-command-center/current-version/administration/custom-layouts-for-asset-views.html

<BR>

<strong>Asset Layout Customization in CDGC</strong>
- カスタムレイアウトの設定手順を、動画で解説しています。

:::note info
動画については、字幕の翻訳機能を使って、日本語字幕を表示することが出来ます。
:::
https://www.youtube.com/watch?v=tKBBsbjbV3c

<BR>

<strong>HOW TO: Create a custom layout in CDGC</strong>
- KB(ナレッジベース)で、カスタムレイアウトの設定手順を紹介しています。

https://knowledge.informatica.com/s/article/HOW-TO-Create-a-custom-layout-in-CDGC?language=en_US

<BR>

<strong>FAQ: Why the Asset Customization tab is not visible in MCC?</strong>
- KB(ナレッジベース)で、カスタムレイアウトがメタデータ・コマンドセンターで設定画面が出てこない場合のトラブルシューティングです。ユーザーが適切なロールを持っている必要があります。

https://knowledge.informatica.com/s/article/FAQ-Why-we-are-not-able-to-see-Asset-Customization-tab-in-MCC?language=en_US
SAA合格への道 - Week1 Day2 - コンテナサービス

# この記事について

AWS-SAAに今年合格しようというメンバーで勉強会を立ち上げました。

私はping-tで1日10問解く、という進め方でやっていますが、コンテナ関係は表層的な理解で終わらせない方がいいと思い、こちらにまとめてみます。

# 教材

こちらの Udemy の section18 を参照しつつ、ポイントをまとめ。

https://www.udemy.com/course/aws-certified-solutions-architect-associate-saa-c03/

# 学んだこと

## コンテナ関係のサービス

| サービス名 | 内容 |
|:-|:-|
|ECS|AWSが提供するコンテナのプラットフォーム|
|EKS|AWSが管理する Kubernetes|
|AWS Fargate|サーバレスのコンテナプラットフォームで、ECSやEKSと共に動く|
|ECR|AWSが提供するコンテナのリポジトリ|

:::note warn
Fargate が一番わからん。。。
サーバレスなのにコンテナ…だと…？！
:::

## ECSの起動タイプ

ECSには、いくつかの起動タイプがあるらしい。」

### EC2 起動タイプ

EC2起動タイプでは以下のように、EC2クラスタの配下にEC2の実体を立ち上げる。
各 EC2はECS Agent を持っている。
Dockerコンテナは、ECSクラスタ配下のどれかのEC2インスタンスの中に立ち上がる。

![Screen Shot 2024-02-01 at 8.49.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/99aabe33-b87c-a22b-f9b8-590c271ca6e6.png)

:::note warn
こっ…これはお金がかかりそうだ…
:::

### Fargate 起動タイプ

そこで Fargate 起動タイプ。

Fargate 起動タイプでは、上記のようにクラスタの中にEC2を立てる必要がない。
（もちろんバックエンドでサーバーは動いているわけだが、そこの管理はAWSがやっていて、利用者はタッチしない）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/a5ee47f6-49e8-0e13-c5eb-5e2387c3365d.png)

利用者はただ、タスクの定義を作るだけ。
AWSはそのタスクを、必要なCPU/RAMを割り当てて動かします。

:::note
なるほど、だからサーバレスなのか。
:::

## IAM Role の割り当て方

### 起動タイプ共通で必要な IAM Role

タスクごとに、タスクを実行する用のロールを割り当てる必要がある。

プロフィールの中身はタスクの内容による。
（S3に書き込むタスクならS3への書き込み権限、DynamoDBにアクセスするならDynamoDBへのアクセス権限など）

### EC2 起動タイプのみで必要な IAM Role

上記に加え、ECSエージェントが使う用のEC2インスタンスプロフィールを作成・割り当てる必要あり。

必要な権限は以下。

- ECSサービスへのAPI発行
- Cloud Watch にコンテナのログを送る
- ECRから Docker イメージを pull する
- Secret Manager や SSM Parameter Store から、センシティブ情報を参照する

:::note
Q. Secret Manager と SSM Parameter Store ってなんですか

A. [Secret Manager](https://aws.amazon.com/jp/secrets-manager/)は、APIキーや認証情報などのライフサイクルを管理するサービス。[SSM Parameter Store](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/systems-manager-parameter-store.html)は、パスワードなどの機密情報を管理するための階層型ストレージ。
:::

## LB の利用

以下のLBが使えます

### ALB (Application Load Balancer)

だいたいのユースケースでこれが推奨

### NLB (Network Load Balancer)

すごく高いスループットやパフォーマンスが必要なときはこれが選択肢なります

### Classic Load Balancer

EC2起動タイプの場合は、使えるけど推奨はされていない。
Fargate では使えない。

:::note warn
LBの勉強ちゃんとやろ。。。
:::


## データの保持期間について

どちらの起動タイプでも、EFSをマウントすることができる。

S3はマウントできないぜ！

Fargate + EFS を使えば、完全なサーバレスアーキテクチャのできあがりさ！

:::note warn
EFSの勉強ちゃんとやろ。。。
:::

# 本日は以上です

さらに学んだことがあれば、こちらに追記するか、別の記事に記載します。
[MySQL - ODBC - Access] #Deleted #Deleted #Deleted #Deleted #Deleted

結論から。Accessのバグです。2022年に報告が挙がっていますが現在（2023年12月）依然Fixされていないので、自力で何とかするしかありません。バグが出ないバージョンのODBCドライバ探しも無駄な時間となるでしょう。ドライバのデベロッパーを変えても同様。MySQL ODBC 8.2, MariaDB ODBC 3.1 にて確認済み。SQLServer のODBCドライバでも発生しているようで、原因はAccessのようです。

## その１　主キーに全角

ODBC経由のリンクテーブルで、主キーに全角があると、全カラム #Deleted #Deleted #Deleted… となるようです。

### 解決策

フロントにAccessを使うのをやめる

主キーに全角を使わないテーブル構造にリファクタリングする

## その２　テキストボックスにNULLを代入した

```
Me.txtCode.Value = rs("code") 'NULLの場合
```

NULL を設定すると発生するようです。

### 解決策

NULLを代入しないようにする。

```
If Not IsNull(rs("code")) Then
    Me.txtCode.Value = rs("code")
End If
```

#DELETED 覚悟で代入してデータ再取得する

```
Me.txtCode.Value = rs("code")
Me.Requery
```
[MySQL - ODBC - Access] ODBC--呼び出しが失敗しました。

```
Datetime field overflow (#0)
```

MySQL側 date型　Access側テキストボックスに 2023/12/12 12:12:12 なんて、時刻まで入れてませんか？ Accessフォームはそこまで変換してくれないので、2023/12/12 と自身でフィルタすべし。テキストボックスの書式を yyyy/mm/dd なんてしてたら発見が遅れる。
Pythonを使って二人用しりとりゲームを作る

## 初めに
今回は、判定に二分探索を使ってしりとりゲームを作りました。

## コード
```py
import re

wordList = []
#しりとりの初めの文字を初期値で入れる
LastTimeWord = "り"
#ひらがな判定用
p = re.compile('^[ぁ-ゖ]+$')

#しりとりとして成り立っているか判定
def siritoriCheck(inputWord):
    global LastTimeWord
    if inputWord[0] == LastTimeWord[-1]:
        #成り立っていたら言葉を格納
        LastTimeWord = inputWord
        return False
    return True

#言葉が重複していないかをチェック
def wordCheck(inputWord):
    global wordList

    #最後の文字が「ん」だったらTrue
    if inputWord[-1] == "ん":
        return True
    
    #文字列が格納されているリストをソートする
    wordList=sorted(wordList)

    #2分探索で文字が重複していないかを探す
    left = 0
    right = len(wordList) - 1
    while left <= right:
        mid = (left + right) // 2
        if wordList[mid] == inputWord:
            return True
        elif wordList[mid] < inputWord:
            left = mid + 1
        else:
            right = mid - 1
    #リストに文字列を追加
    wordList.append(inputWord)
    return False



while True:
    inputWord = input()
    #ひらがなで入力されているかチェック
    if not p.fullmatch(inputWord):
        print("ひらがなで入力してください")
        continue

    #しりとりとして成り立っているかチェック
    if siritoriCheck(inputWord):
        print("文字が繋がってないよ!")
        continue

    #同じ言葉が入力されていないか、最後の文字が「ん」かチェック
    if wordCheck(inputWord):
        print("ゲームオーバー")
        break

```
SAA合格への道 - Week1 Day1 - サーバレス

# この記事について

AWS-SAAに今年合格しようというメンバーで勉強会を立ち上げました。

合格者の方から、「Lambdaなどのサーバレス関係がよく出る」と聞いたこと＆ふだんの業務ではサーバレスコンピューティングに触る機会がないことから、この分野は重点的に勉強しようと思いました。

# 教材

こちらの Udemy に沿って学んでいく予定です（途中で計画変えるかも）

https://www.udemy.com/course/aws-serverless-a-complete-guide/

講師のお顔からはすぐに見抜けませんでしたが、インド系の方のようで、中程度のインドなまりが入っています。
（重度ではない。本当のインドなまりはこんなもんじゃねえ！）

…ということで、ITと英語、特にインドなまりリスニングを同時に強化したい方にはおすすめかもしれません。

# 学んだこと

## サーバレスの定義

サーバレスというのは、必ずしも「Lambdaのこと」ではない。

以下の要件を満たしていることを、AWSではサーバレスと定義しているらしい。

- サーバーの調達や管理を伴わない
- 使用量にしたがって自動スケールする
- 待ち時間の間にお金を払う必要がない
- 高可用性、フォールトトレラントが組み込まれている

## サーバレスサービスの例

AWSが提供している、代表的なサーバレスサービスのラインナップ。
（全てではないが、代表的なもの）

### コンピュート

- AWS Lambda
- AWS Fargate

### ストレージ

- Aurora Serverless
- DynamoDB
- Amazon S3

:::note warn
S3ってサーバレスだったのか…！
そんなふうに考えたことなかったぜ
:::

### 統合、分析

- Amazon API Gateway
- Amazon Glue
- Amazon SQS
- Amazon SNS
- AWS Step Functions
- AWS AppSync

## とはいえ、サーバレスの代表格はやはり Lamda

Let's talk about the crown jewel of serverless, Lambda.
(サーバレス界の王冠の頂点に輝く宝石、Lamdaの話をしようぜ！)

と講師が言ってました。

### 設定項目

- メモリサイズ - 128MB〜10GBまで

:::note warn
メモリちっちゃ…！
と思ったけど、マシンではなく関数単位に割り当てるメモリだからこんなもんなのか？
（3GBがMaxだった時代もあるらしい）
:::

- CPUとネットワークはメモリサイズに連動して割り当てられる？
- 15分間が稼働のMax
    - ここは試験にもよく出るっぽい
    - 15分を超えるような、大量データの処理とかには向かない

### 柔軟性

- 同期（API）、非同期（SQS,S3）の起動に対応

:::note warn
非同期の起動の例でS3が入ってるのなんで
:::

- AWS の他のサービスが、ビルトイン的に Lambda を起動できるパターンもある

:::note warn
S3もそれができるってことか？！
:::

ここから先は、Lambdaを実際に動かしながら学びを深めていきたいと思います。

# 以上

また何か学んだことがあれば追記します。
WPFでDIからSerilogでのログ出力をやってみた

## 環境
- dotnet6
- C#
## Nugetパッケージ
- Serilog.AspNetCore
- CommunityToolkit.Mvvm
## 内容
- Program.cs
```
namespace SerilogTeest
{
    public partial class App : Application
    {
        private void Application_Startup(object sender, StartupEventArgs e)
        {
            // Serilogの設定
            Log.Logger = new LoggerConfiguration()
                .MinimumLevel.Debug()
                .WriteTo.Debug()
                .WriteTo.File(
                    @"C:\Logs\SerilogTeest\.txt",
                    rollingInterval: RollingInterval.Day)
                .CreateLogger();

            var serviceCollection = new ServiceCollection();

            serviceCollection.AddLogging(loggingBuilder =>
                loggingBuilder.AddSerilog(dispose: true));

            Ioc.Default.ConfigureServices(serviceProvider);
        }
    }
}
```
### 設定説明
```
@"C:\Logs\SerilogTeest\.txt",
```
出力するログのパス。RollingInterval.Dayを設定してあるので、yyyyMMdd.txtの形で出力される。
```
rollingInterval: RollingInterval.Day
```
この設定で、C:\Logs\SerilogTeestにyyyyMMdd日付のログが出力される。
### 感想
あとはILogger<T>を使用するだけで使用可能。
これだけでログ出力の設定が出来るんだから、便利な世の中になったもんだ。
Android StudioでAPI通信の中身をサクッと見よう

![スクリーンショット 2024-02-01 8.02.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/898008/983aa6ab-5b25-0242-c2ba-fc08921885e0.png)


# はじめに
Androidstudioを使っていて、APIを使用するときにレスポンスやリクエスト、ヘッダーなどをサクッと確認するための方法を紹介します。
Log.dで確認している方はぜひこちらの方法を参考にしてみてください。

# Android Studioの標準機能Network Profilerとは？
Android Studioには、標準で[Network Profier](https://developer.android.com/studio/profile/network-profiler?hl=ja)という機能が備わっています。
このNetwork Profiler を使用してAPIのレスポンスやリクエストをjson形式で見ることもできます。またヘッダーにjwtなどを付与している時にも正しく付与できているかを確認するのに重宝します。

# 必須条件
### httpクライアント
公式にも記されているように、 
* HttpURLConnection ライブラリ
* OkHttp

にのみ対応しています。ただし、[Retrofit](https://square.github.io/retrofit/)など、内部的にOkHttpを使うものも対応しています。

一方で、Ktorの場合は標準でCIOエンジンを使っていて動作しませんでしたが、エンジンをCIOからOkHttpに変更することでトラフィックを見られるようになりました。

# 使用方法
## 手順
使用法はとても簡単です。インストールなど特に不要です。
1. Android Studioの下のタブにある "App Inspection" を開く
2. Run "app" でビルドしてデバイスでアプリを起動する。
3. "Select Process" のタブから、対象のデバイスを選択する(ビルド時に普通は自動で選択される)
下図の、 "Pixel6a API 32...." の箇所のことです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/898008/0e3fccdb-8d58-ab91-0ac7-b424d476afb2.png)

4. Network Inspectornのタブを開く

あとは、API通信があると、そこにトラフィック毎に流れてくるので、選択すれば中身を詳細に見ることができます。



## 使用例
Retrofitを使ってAPI通信を行うサンプルです。imgを返す場合は、そのimgも表示してくれます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/898008/33785c76-f870-29b7-579e-936cb735e4b2.png)


![スクリーンショット 2024-02-01 8.02.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/898008/c3964738-6bab-06a2-3fb0-17125d0e8f96.png)

## 注意点
* build.gradleの設定で、次のような設定が入っていると正しく動作しないので、デバッグ時にはコメントアウなどして外しておく必要があります。
 
```kotlin:build.gradle
    ....
    isDebuggable = false
    isMinifyEnabled = true
    isShrinkResources = true
    proguardFiles(
        getDefaultProguardFile("proguard-android-optimize.txt"),
        "proguard-rules.pro"
    )
    ....
```

* Network Profilerをずっとつけっぱなしにすると、動作が重くなることがあるので,気づいたら停止するようにしておきましょう。

# まとめ
Log.dでAPIを見るのはやめて、Network Profilerを使ってデバッグしましょう！

# 参考
なお、Xcodeでも同様な機能として、[Instrument機能](https://qiita.com/hyuga_amazia/items/fe6626b111e974184b02)を使うことでネットワーク通信を見れます。
ReactNativeでも同様で、[フリッパー(Flipper)](https://fbflipper.com/docs/features/react-native/) を使うと簡単にAPI通信が見られます。
Tableauの地理的レイヤー

[Workout Wednesday 2021 Week19](https://workout-wednesday.com/2021w19tab/)では、地理的レイヤーを使うvizでした。
地理的データを複数使うときに便利な機能です。

1つマップを表示させた上で、別の地理的役割をもつディメンションをドラッグ&ドロップすると、地理的レイヤーを追加できます。
レイヤーを複数追加することで、地図上で可視化を細かく制御することが出来ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1859308/fe4e5b3a-162e-5ed7-1246-051f4516c8c9.png)


## WoW 2021 Week19のポイント
### ポイント1
各regionのマークはマップにする。
デフォルトだと円になるので注意してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1859308/f5f1611f-83e6-0b90-e2bd-20ea242c7b97.png)

### ポイント2
色の表示でnullを非表示にする。
除外をしてしまうと、1つのregionしかデータが表示されなくなってしまいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1859308/a39597e1-8d8e-e8cc-9b52-8f3847d4a2fb.png)

## 公式ドキュメント
https://help.tableau.com/current/pro/desktop/ja-jp/maps_marks_layers.htm
同じデータをユニオンすることでできること

[Workout Wednesday week10](https://workout-wednesday.com/week-10/)では同じデータをユニオンして面白いvizの作成をしていました。
vizの作成のポイントを紹介します。

## ポイント1. 同じデータをユニオンする。
一方のデータを始点、もう一方のデータを終点として使うためにユニオンします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1859308/96c53ddc-eb76-8cfa-1c92-e683e4906d02.png)


## ポイント2. 顧客区分の順番を決める
下記のように顧客区分毎に、円の外・真ん中・内側のどこに配置するか決めます。
この場合、大企業・消費者・小規模事業者の順で円の内側から並びます。

*line location*
```
1+
IF [data level]           // Returns TF
THEN CASE [顧客区分]       // For true create start of each line
     WHEN "大企業" THEN 0
     WHEN "消費者" THEN [Corporate Sales / Week]/[Sales / Week] + .15
     WHEN "小規模事業所" THEN ([Corporate Sales / Week] + [Consumer Sales / Week])/[Sales / Week] + .30
     END
ELSE CASE [顧客区分]       // For false create end of each line
     WHEN "大企業" THEN [Corporate Sales / Week]/[Sales / Week]
     WHEN "消費者" THEN ([Corporate Sales / Week] + [Consumer Sales / Week])/[Sales / Week] + .15
     WHEN "小規模事業所" THEN 1 + .30
     END
END
```

## ポイント3. 円の式

```math
x = r\cos\theta \
```
```math
y = r\sin\theta \
```
今回の場合、
```math
r = [Line Location]
```
```math
\theta = 2\pi[Percent of Year]
```
となります。

Percent of Year は 週数 / 年間週数 です。
Tableau 空間関数 紹介

[Workout Wednesday 2020 week10のテーマ](https://workout-wednesday.com/2020w09/)は空間関数を使ったvizの作成でした。
普段空間関数を使う機会がなく、面白いと感じたので共有します。

この記事ではTableauのMAKEPOINT関数、BUFFER関数およびINTERSECTSを紹介します。

## MAKEPOINT関数
MAKEPOINT関数は、
```
MAKEPOINT(緯度,経度)
```
のように記述します。
これをマップで表示させると、該当する緯度経度をプロットできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1859308/69f599fe-7fd8-c96f-839c-588a02dea17d.png)

## BUFFER関数
BUFFER関数は、
```
BUFFER(ジオメトリ(点) , 半径 , 単位)
```
のように記述します。
ジオメトリ(点)はMAKEPOINT関数で作成した点です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1859308/74b0d802-f073-67cb-a5b9-8b71596d10c4.png)

## INTERSECTS
ジオメトリの結合に使用します。
- ポイント-ポリゴン
- ライン-ポリゴン
- ポリゴン-ポリゴン
の組み合わせがサポートされているようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1859308/49b27819-887f-58de-1529-10dfed3c4309.png)

## 公式ドキュメント
https://help.tableau.com/current/pro/desktop/ja-jp/functions_functions_spatial.htm
Pythonで SimpleNamespace を使って辞書の値を属性アクセスできるようにする

# この記事は何？
Pythonで **SimpleNamespace** を使って、辞書の値に属性アクセス（.属性名）できるようにする方法を紹介します。

# Pythonの辞書について
Pythonで辞書の値にアクセスする際には `dict['key']` のように文字列のキーを使用する必要があります。これは時に不便であり、コードの読みやすさを損なうことがあります。
SimpleNamespaceを使うと、辞書の値に属性アクセス `（.属性名）`できるようになります。

# SimpleNamespace とは
SimpleNamespace は、Pythonの標準ライブラリ types に含まれるクラスで、属性へのアクセスを容易にするためのものです。このクラスを使うと、辞書のキーをオブジェクトの属性としてアクセスできるようになります。

# サンプルコード
### 辞書を SimpleNamespace に変換する関数
```python
from types import SimpleNamespace

def convert_nested_dict_to_namespace(data):
    """
    再帰的に辞書を SimpleNamespace に変換する。

    Args:
        data: 辞書またはその他のデータ型

    Returns:
        変換された SimpleNamespace オブジェクトまたは元のデータ
    """
    if isinstance(data, dict):
        for key, value in data.items():
            data[key] = convert_nested_dict_to_namespace(value)
        return SimpleNamespace(**data)
    else:
        return data
```
この関数は、入力されたデータが辞書型であるかどうかをチェックします。辞書であれば、その各キーと値に対して再帰的にこの関数を適用し、最終的に SimpleNamespace オブジェクトを返します。

## YAML形式の設定ファイルを読み込む例

指定されたYAMLファイルを読み込み、辞書に変換する例です。
`convert_nested_dict_to_namespace` 関数を使用して、この辞書を `SimpleNamespace` オブジェクトに変換します。

### YAMLファイル
```yaml
database:
  host: localhost
  port: 5432
```

### コード
```python
import yaml

def load_config(yaml_file_path):
    """
    yaml config読み込み

    Args:
        yaml_file_path (str): ファイルパス

    Returns:
        SimpleNamespace: 設定値が属性としてアクセス可能なオブジェクト。
    """
    with open(yaml_file_path, "r") as file:
        config_dict = yaml.safe_load(file)
    config = convert_nested_dict_to_namespace(config_dict)
    return config

config = load_config('path/to/config.yaml')
print(config.database.host)  # localhost
print(config.database.port)  # 5432

```


# 最後に
もうちょっと複雑なことをしたい時は, OmegaConf を使うといいと思います。
https://github.com/omry/omegaconf