OmniAICreator/Qiita-1.07M huggingface dataset:
windowsアプリケーションをexeファイルとしてビルドする方法（VB.NET）

# 流れ
## ① 前提として、アプリケーションの開発やテストが終えていること
前提条件として、exeファイルとして、ビルドできる状態（エラーなどが発生していない状態）にあることが条件になります。本記事の説明では、[こちら](https://qiita.com/portfoliokns3/items/a11d0d8e330225d34e69)の記事で作成したものを利用しています。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/37431308-5855-e3fb-878c-113bf806e336.png)

## ② DebugからReleaseへ設定を変更する。
開発段階では、Debugが選択されていると思います。これをDebugからReleaseへ変更します。
![無題2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/e677b7b1-82a3-e8f7-4ada-dd36353d2fa2.png)
- Debug
こちらは、開発時に使用するモードで、visual studio上で変数やオブジェクトの値を表示することができるため、デバッガー（開発者）がステップ実行などで、デバッグ情報の確認に使用します。そのため、Debugでビルドされたアプリケーションは、実行速度が遅く、メモリ使用量が多くなるため、通常、exeファイルとして出力する場合は、Releaseを使用します。
- Release
こちらは、完成品として納品する際などに利用します。デバッグ情報を持たないため、実行速度が速く、メモリ使用量も少なくなります。**本番リリース時や納品時には、Releaseに設定しておく必要があります。** またReleaseでビルドしたexeファイルを用いて、テストすることが理想だと思います。 

私は新入社員の時、DebugとReleaseの違いを知らないで、仕事をしていたので、気を付けましょう。

## ③ ビルドを行い、exeファイルを出力する。
「ビルド」タブから「ソリューションのリビルド」または「（プロジェクト名）のリビルド」を選択し、exeファイルをビルドします。
![無題3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/ed9ef695-9020-b79a-988a-7bdedef1634c.png)

少し時間を置くと、リビルドが完了します。リビルドが完了した後の情報は出力画面に表示されています。exeファイルの出力先を確認して、アクセスします。
![無題4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/d3409b50-71d6-5466-eb53-2a7448a8260f.png)
**特に問題がなければ、releaseをdebugへ戻しておきましょう。**

## ④ 試しに実行してみる
エクスプローラーを開き、ビルドをされたexeファイルの場所まで、アクセスしましょう。その後、exeファイルを実行すれば、アプリケーションが起動し、使用できることが確認できる。
![無題5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/1d3531f1-663f-3aa7-f489-7dc172f0ff45.png)
![無題6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/d16eb75f-44b0-3540-f474-9d5519145d1c.png)
![無題7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/f2b4fffe-3498-c040-9879-02df8042a893.png)
![無題8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/aa32c95b-642f-c2e9-5668-2f1740194dbc.png)

# 注意事項
- この記事では、visual studio 2022を使用しているので、試してみたい方は事前に準備が必要です。
- 関連する記事の一覧は[こちら](https://qiita.com/portfoliokns3/items/7c789b7e1ba40500abbb#%E3%81%93%E3%82%8C%E3%81%8B%E3%82%89%E6%89%B1%E3%81%A3%E3%81%A6%E3%81%84%E3%81%8D%E3%81%9F%E3%81%84%E4%BA%BA%E5%90%91%E3%81%91%E3%81%AE%E8%A8%98%E4%BA%8B)。
※参照先のリンクが切れている場合は、[トップページ](https://qiita.com/portfoliokns3)から確認してください。

# この記事は誰向けの記事か？
- アプリケーションのexeファイルの手に入れ方が分からない人
- ビルドの仕方がわからない人
- debugとreleaseの違いを知りたい人

# 環境
- OS：Windows10
- 開発プラットフォーム：[visual studio 2022](https://visualstudio.microsoft.com/ja/vs/)

# 本記事における注意事項
- 本記事は、備忘録としてまとめたものになります。
- 他の方の参考になる可能性も踏まえて、一般公開も行なっております。
- また記載内容はすべて、正しい内容が記載されているとは限りません。
- 誤った内容を見つけた場合は、ご指摘をお願いいたします。
【テックジム無料講座】Ruby on Rails講座 ＜クローラーを作ろう＞の感想

ProgateのRuby on Rails講座を一回終了したので、テックジムが無料で開催している、Ruby on Rails講座 ＜クローラーを作ろう＞をオンラインで受講してみました。何回か復習しないと、理解が出来そうにありませんでした(涙)

<a href ="https://www.youtube.com/watch?v=J4PA4YIHW_w">環境構築編</a>
<a href ="https://www.youtube.com/watch?v=-uWf99V6KJQ&t=1s">解説動画</a>



<a href ="https://github.com/techgymjp/techgym_rails_open/blob/master/RailsCourse02_1.pdf">テキスト</a>
BCDiceをDiscordのダイスボットにして動かす

## 背景
herokuが有料化してからDiscordで無料で常に動かす方法がわからない
調べてみたら方法あるっぽいけど、`/roll`とかの入力が必要だったりして面倒
なによりBCDiceが最強なので使いたい

## やること
GlitchにBCdiceBotをおいてNode.jsで動かす
（Javaを永続的に動かす方法がNode.js使う以外に分からなかったんです！！）

## 前提
https://shunshun94.github.io/discord-bcdicebot/index.html
> 中級者以上向け：heroku を使って動かす手順

↑で詰んだ人とか

https://aimsot.net/discord_dicebot/
>Q.Botを常に起動していたい

↑で詰んだ人はこれで導入できる
トークン取得とか終わってる前提

## ローカルで設定
- [discord-bcdicebot](https://shunshun94.github.io/discord-bcdicebot/index.html)の概要からダウンロード
- `start.sh`の`DISCORD_BOT_TOKEN=`を削除
- `start.sh`の`BCDICE_API_URL=`を設定。[BCDice-API バージョン一覧](https://api-status.bcdice.org/)から好きなURLを選ぶ
- そのほか`start.sh`を好きに設定
- コマンドラインで`$ npm init`を叩く
    - 出てくる選択肢は自由。面倒なら無視してEnter連打でOK
    - npmなんか知らねぇと言われたら[ダウンロードサイト](https://nodejs.org/ja/download)からぶち込みましょう
- 作成された`package.json`を編集。`start`を追加
```json:package.json
{
  "scripts": {
    "start": "sh start.sh"
  },
}
```
- GitHubにpushする
 
## Glitchで動かす
https://glitch.com/
ここにボットを設置する
ここではGitHubを使うが他の方法でも良い
- 画面右上の「New Project」をクリック
- 「import from GitHub」を選択
- URLは自分のリポジトリ
- 環境変数の設定をする
    - ここは[discord-bcdicebot](https://shunshun94.github.io/discord-bcdicebot/index.html#install-editStartFile)を読みつつ`.env`に記述
        - `.env`の`Add a variable`で追加する
        - Glithの`start.sh`に公開しておくとセキュリティ上よくないので`.env`に入れて隠す必要がある
    - `DISCORD_BOT_TOKEN=`を消していたのでここで設定する
    - 参考までに私が設定した環境変数はこんな感じ
        ```
        DISCORD_BOT_TOKEN={token}
        BCDICE_API_URL=https://bcdice.onlinesession.app
        BCDICE_API_SECONDARY=https://bcdice.trpg.net
        BCDICE_MENTION_MODE=1
        ```
-  画面下のターミナルをクリックして開く
-  `$ npm start`する

## GASでGlitchの永続化
Glitchは一定時間アクセスがないと死んでしまう
定期的にGASにアクセスさせて蘇生することにより永遠の命を手にする
[GlitchでBOTを作る手順](https://scrapbox.io/discordjs-japan/Glitch%E3%81%A7BOT%E3%82%92%E4%BD%9C%E3%82%8B%E6%89%8B%E9%A0%86)を参考にした

- Glitchの画面下の「Preview」から「Preview in a new window」を選択
- 開いたウィンドウのURLをコピーしておく
- [Googleドライブ](https://drive.google.com/)を開く
- 画面左の「＋新規」をクリック
- 「その他」→「GoogleAppScript」を選択
- GlitchにPOSTするだけの関数を書く
```js
const retainGlitch = () => {
  const data = {}
  const headers = { 'Content-Type': 'application/json; charset=UTF-8' }
  const params = {
    method: 'post',
    payload: JSON.stringify(data),
    headers: headers,
    muteHttpExceptions: true
  }
  //特に中身のないデータをGlitchへPOST
  response = UrlFetchApp.fetch('/* コピーしておいたURL */', params);
}
```
- 保存
- 左側の時計のアイコンの「トリガー」をクリック
- 「＋トリガーを追加」でこのように設定して保存
    - 実行する関数：retainGlitch
    - 実行するデプロイを選択：Head
    - イベントのソースを選択：時間主導型
    - 時間ベースのトリガーのタイプを選択：分ベースのタイマー
    - 時間の間隔を選択（分）：1分おき

## 完成！！
Discordで動作確認してみよう
ダイスを振るのじゃ

## 困ったことがあったら
chatGPT君に聞くと全部答えてくれるよ。

## 参考文献
- https://github.com/bcdice/BCDice
- [discord-bcdicebot](https://shunshun94.github.io/discord-bcdicebot/index.html)
- [DiscordでDiceBot(BCDice)を使う方法 その1](https://aimsot.net/discord_dicebot/)
- [Glitch](https://glitch.com/)
- [GlitchでBOTを作る手順](https://scrapbox.io/discordjs-japan/Glitch%E3%81%A7BOT%E3%82%92%E4%BD%9C%E3%82%8B%E6%89%8B%E9%A0%86)
list の「値」と「index値」の両方を取得する方法（enumerate()関数）

list の「値」と「index値」両方を取得する方法について、
以下の2パターンで紹介する。

1. `for`文の変数を使って取得する方法 
1. `enumerate()`関数を使って取得する方法
　

**1. `for`文の変数を使って取得する方法**
`for`文の変数を使ってlist内の「値」とその「index値」を求めるには、
以下のようなコードになる。

```python
array = [10, 20, 30]

# for文の変数を使って「index値」と「値」の両方を取得する
for i in range(len(array)):
    print("index値が", i, "の値は", array[i])
```

実行結果は以下の通り。

```python
index値が 0 の値は 10
index値が 1 の値は 20
index値が 2 の値は 30
```

　

**2. `enumerate()`関数を使って取得する方法**
続いて`enumerate()`関数を使って「値」と「index値」を取得する。

```python
array = [10, 20, 30]
    
# enumerate() 関数を使って「index値」と「値」の両方を取得する
for index, value in enumerate(array):
    print("index値が", index, "の値は", value)
```

実行結果は以下の通り。

```python
index値が 0 の値は 10
index値が 1 の値は 20
index値が 2 の値は 30
```

`for`文の変数を使った場合と同じ結果を得ることができたが、
`enumerate()`関数を使った方が「値」と「index値」を別々に管理出来るので
より複雑なコードを書いた場合などには、理解しやすいかもしれない？
Cloud Monitoringのalert設定の、label_extractors問題にハマった

## 背景
GCPの Cloud Monitoringの設定で、ある条件のエラーログが検知されたら、Slack通知される、という仕組みを作成していた。terraform設定の概要は下記のようになる（少し編集してあります）

```terraform
resource "google_monitoring_alert_policy" "alert_policy_api_failure_sample" {
  ...
  conditions {
    ...
    condition_matched_log {
      filter = <<-EOT
        resource.type="cloud_run_revision"
        resource.labels.service_name="sample-endpoint"
        severity=ERROR
      EOT

      label_extractors = {
        message = "EXTRACT(jsonPayload.message)"
        tenant = "EXTRACT(jsonPayload.tenant)"
      }
    }
  }
  ...
  // 条件にマッチしたログをslackに流す
  notification_channels = [
    var.notification_channel
  ]
  ...
  // 通知に追記されるメッセージ
  documentation {
    content = <<-EOT
      *${var.env}環境*
      tenant_id: `$${log.extracted_label.tenant_id}`
    EOT
    mime_type = "text/markdown"
  }
}
```

## 発生した問題
新しくログに載せる項目を増やすために、`label_extractor`に項目を追加した。

```diff
      label_extractors = {
        message = "EXTRACT(jsonPayload.message)"
        tenant = "EXTRACT(jsonPayload.tenant)"
+       target = "EXTRACT(jsonPayload.target)"
      }
      documentation {
        content = <<-EOT
         *${var.env}環境*
         tenant_id: `$${log.extracted_label.tenant_id}`
+        target: `$${log.extracted_label.target}`
        EOT
        mime_type = "text/markdown"
      }
```

これで、`target`という名前の項目がとれるので、ログに出力されるはずだった。
が、出力されなかった。

## 原因
どうやら、jsonPayload.targetのキーあるいは値が存在しないとき、インシデントとして見なされないようで、slackに通知されない。

## 対策
`jsonPayload.target` に **必ず** 値が設定されるようにする！で今回のハマりはとりあえずなんとか乗り越えられた。
キーおよび値が設定されないと通知されない。デフォルト値をいれておくのもいいかもしれない。
（詳細未確認だが、デフォルト値が空文字だともしかしたらダメかもしれない。
android カスタマイボタン

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="#00ACEE"/>
    <corners android:radius="15dp"/>
    <stroke
        android:color="#E69D35"
        android:width="2dp"/>
</shape>
ParallelsDesktopForMacに入れたWindows11から見たMacフォルダの設定まわり

# 何が起きたのか

:::note warn
ParallelsDesktopForMacにセットアップしたWindows11から、MacのユーザーフォルダにCloneしたGitHubのフォルダが見れなかった。
:::

:::note info
**前提条件**
Macのユーザーフォルダの内、以下のフォルダは見えていた。
<ul>
<li>デスクトップ</li>
<li>書類</li>
<li>ピクチャ</li>
<li>ミュージック</li>
<li>ムービー</li>
<li>ダウンロード</li>
</ul>
:::
# 相方はどう考えるか
![スクリーンショット 2023-04-07 221219.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3322151/b498a0f4-2bb5-a006-e3cc-f410c4166c4a.jpeg)
今回はアプローチがちょっと違いますね。
シンボリックリンクでも出来たのかぁ！~~そんな気はしてたんだよ~~
# 実際にやったこと
1. Mac上のWindows11の歯車アイコンから "Windows11"の構成 を開く
1. 「オプション」の「共有」の中にある「Macを共有する」の中にある「Windowsと任意のMacフォルダーを共有する」にチェックを付ける。
1. 「フォルダーを管理」ボタンを押下して、Macのユーザフォルダを指定して、Windowsを再起動
1. Windows11からMacのユーザフォルダーにクローンしたプロジェクトを参照できることを確認

# 所感
今はこんな便利なツールが出来ていたんですね。
VMWareとかVirtualBox使っていたときは、フォルダの共有もう少しだけ面倒だった様な記憶があるようなないような。~~もう十年以上前か~~
Macあれば何でも出来ちゃうじゃん！ってそりゃあなるよぉ～～！
(root 無し, 現環境を汚さず) 取り急ぎで Python の任意バージョン環境を pip 付きで用意したい

# 注意

※ 多分、もうちょっと効率的な方法があると思う (よってタイトルに "取り急ぎ")
※ Linux Mint (21.1 Vera 64bit) 上で動作確認、他環境では動作未検証

# 手順

Python を自力でビルドし、仮想環境を構築し、そこを環境とします。仮想環境を作ることで、環境を汚さない上に、無理やり pip が使える環境を用意する、という算段です。

## 1．必要なバージョンの Python をビルド

とりあえず、手元で動いたコマンドを載せておきます。詳しいビルド手順は、[公式リファレンス](https://devguide.python.org/getting-started/setup-building/index.html)を参照してください。

```sh
# 先にソースをダウンロード・展開し、カレントを移しておく
mkdir build
cd build
../configure --enable-optimization
make -j5
```

※ ここで、`sudo make install` は不要です。

:::note
`make` のオプション `-j5` は、並列タスクの最大数指定です。フルパワーで動かすには、CPU スレッド数+1を指定すると良いとされています。
:::

## 2. 得られた実行ファイルから仮想環境作成

```sh
# ホームに pytest ディレクトリを作り、そこに環境を作るとする
mkdir ~/pytest
./python -m venv ~/pytest/.venv
cd ~/pytest
```

## 3. 必要なパッケージなどをインストール

```sh
./.venv/bin/pip install <required-packages>
```

## 4. あとは任意のコードを実行

```sh
./.venv/bin/python </path/to/any_code.py>
```

# 余談

Python 3.9 以降について･･･

* `list` の要素の型アノテーション `list[int]` がビルトインサポート
* それ以前 (3.8.X) は `typing.List` でサポート
* `typing.List` は 3.9 リリースの 5年後に廃止予定

というような理由があって、3.8 以前と 3.9 以降それぞれの環境で検証したいことがあり、今回の記事作成に至りました。

当初、apt をなんやかんややってと考えていたのですが、頓挫してこの方法に至りました。自力ビルドなのでちょっと手間･･･ではありますが、環境を汚す心配が全くないのが長所です。
【Web基礎】アプリケーションの裏で起きていること

## 概要
今更ですが、Webの基礎について学び直したメモがわりに書きます。

## アプリケーションの裏で動いているもの
まず、ブラウザからのリクエストに対して、裏でに何が動いているかのイメージはこちらです。
このページの画像を使わせてもらいました。
https://hikopro.com/server-domain/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2613586/95ba0737-66a7-4f2c-c6de-b57561117824.png)

## ○Webクライアント
ブラウザと呼ばれるもので、サイトを閲覧するための役割を果たしています。
主に、Webサーバーからのレスポンスを画面に表示します。
#### ◾️よく使われるWebクライアント
・Google Chrome
・Microsoft Edge
・Safari
などがよく使われます。

## ○Webサーバー
Webサーバーはサイトを公開する役割を持ちます。
ブラウザから送られてきたURLに対して、HTMLや画像を返していきます。場合によっては、APサーバーにアプリケーションを動かすように指示を送り、そこから返ってきたデーターなどを返していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2613586/b57a1b41-9a35-14d2-2dae-3f70ebdb80fa.png)

#### ◾️よく使われるWebサーバー
・Apache
・Nginx
こちらが代表的なWebサーバーです。

## ○APサーバー
APサーバーはWebサーバーからのリクエストに対して、アプリケーションの結果を返す役割を持ちます。
APサーバーとWebサーバーの違いは、簡単にまとめると以下のようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2613586/5c50d3df-f341-c101-4ccf-6e4bff0c5d2f.png)

##### ・単体で使うことができるか
静的なコンテンツならWebサーバーのみで動きます。しかし、APサーバーだけでは、アプリケーションは動きません。

##### ・静的コンテンツならWebサーバーだけでも動くが、動的コンテンツはAPサーバーが無いと厳しい
静的コンテンツ(HTMLや画像)を返すだけなら、Webサーバーだけでも動きますが、動的なコンテンツ(PHPやRubyなど)を使ったサイトを作成するためには、APサーバーは必要になります。
しかし、中にはWebサーバーの機能も持ったAPサーバー(TomcatやPumaなど)が存在しますが、オマケのような感覚なので、基本的には分けて使うことがほとんどです。
#### ◾️よく使われるAPサーバー
・Puma
・Unicon
・Tomcat
などがよく使われます。
ほとんどのアプリケーションがWebサーバーとAPサーバーをセットで使っています。

## ○DBサーバー
DBサーバーは、その名前の通り、データベースを管理・運用するサーバーになります。
基本的に、APサーバーからのリクエストを受けて、データベースから取得したデータをAPサーバーに返すという役割を持っています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2613586/39b85a65-c5e0-2201-0bf9-ddcaa3129934.png)

#### ◾️よく使われるDBサーバー
・Oracle
・MySQL
・Postgres
などが一般的です。

## 最後に
今回はWebの基礎について書いていきました。当たり前ですが、アプリケーションの流れを理解することは大事ですね。
以上になります。
【SwiftUI】TCAでSheetを実装する

# はじめに
TCA勉強記録第二弾です。

https://qiita.com/SNQ-2001/items/26035e88e1959f3876fc

今回はSheetを実装してみました。

# 実装
```swift:ContentView
import SwiftUI
import ComposableArchitecture

struct ContentView: View {
    let store: StoreOf<Feature>

    var body: some View {
        WithViewStore(store) { viewStore in
            Button {
                viewStore.send(.sheetPresented)
            } label: {
                Text("表示")
            }
            .sheet(isPresented: viewStore.binding(
                get: \.sheet,
                send: .sheetDismissed
            )) {
                Text("Sheet")
            }
        }
    }
}
```

```swift:Feature
import Foundation
import ComposableArchitecture

struct Feature: ReducerProtocol {
    struct State: Equatable {
        var sheet: Bool = false
    }

    enum Action: Equatable {
        case sheetPresented
        case sheetDismissed
    }

    func reduce(into state: inout State, action: Action) -> EffectPublisher<Action, Never> {
        switch action {
        case .sheetPresented:
            state.sheet = true
            return .none
        case .sheetDismissed:
            state.sheet = false
            return .none
        }
    }
}
```

# 完成
![Simulator Screen Recording - iPhone 14 Pro - 2023-04-07 at 21.37.03.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/30dca397-42be-44e3-6eab-4cdb9ae33271.gif)

# おわり
Sheetを実装することができました。
強化学習の参考資料

# この記事で書くこと
強化学習に関係ありそうな資料をまとめる。
自分が興味ある部分のみまとめておく。資料を見つけ次第、随時更新予定。

# 強化学習の基本的な手法
<iframe src="//www.slideshare.net/slideshow/embed_code/key/d2SbQyyFjaHppr" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe> <div style="margin-bottom:5px"> <strong> <a href="//www.slideshare.net/ShotaImai3/rlssdeepreinforcementlearning" title="強化学習の基礎と深層強化学習（東京大学 松尾研究室 深層強化学習サマースクール講義資料）" target="_blank">強化学習の基礎と深層強化学習（東京大学 松尾研究室 深層強化学習サマースクール講義資料）</a> </strong> from <strong><a href="//www.slideshare.net/ShotaImai3" target="_blank">Shota Imai</a></strong> </div>

# 強化学習とベイズ
<iframe src="//www.slideshare.net/slideshow/embed_code/key/4FfGubszTuoy1G" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe> <div style="margin-bottom:5px"> <strong> <a href="//www.slideshare.net/ShoheiTaniguchi2/ss-238325780" title="Control as Inference (強化学習とベイズ統計)" target="_blank">Control as Inference (強化学習とベイズ統計)</a> </strong> from <strong><a href="//www.slideshare.net/ShoheiTaniguchi2" target="_blank">Shohei Taniguchi</a></strong> </div>

# マルチエージェント強化学習
<iframe src="https://www.slideshare.net/slideshow/embed_code/key/rcEb3uR5HtSab5?startSlide=1" width="597" height="486" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px;max-width: 100%;" allowfullscreen></iframe><div style="margin-bottom:5px"><strong><a href="https://www.slideshare.net/DeepLearningJP2016/dl-254480259" title="【DL輪読会】マルチエージェント強化学習における近年の 協調的方策学習アルゴリズムの発展" target="_blank">【DL輪読会】マルチエージェント強化学習における近年の 協調的方策学習アルゴリズムの発展</a></strong> from <strong><a href="https://www.slideshare.net/DeepLearningJP2016" target="_blank">Deep Learning JP</a></strong></div>

# AlphaZero周辺
https://github.com/opendilab/LightZero にいい感じの図があったのでメモ
![AlphaZero周辺](https://github.com/opendilab/LightZero/raw/main/assets/mcts_rl_evolution_overview.png)
FreeCADでFEMするまで（MacOS Ventura / M1対応）

M1 MacにFreeCAD、CalculiX、gmshをインストールしてFEMを実行可能な環境を構築する方法です。

# Homebrew導入（行っていなければ）
まだ導入を行っていなければ、Homebrewを導入します。MacPortsではCalculiXが存在しないようです。

https://brew.sh/

以下のコマンドでインストールします。
```bash
$ xcode-select --install
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```

指示に従ってインストールしてください。PATHを通すために追加のコマンドを実行するよう指示されるかもしれません。

# FreeCADインストール
FreeCADをインストールします。Homebrewではインストールがうまくいかなかったためパッケージからインストールしました。

https://www.freecad.org/downloads.php

ダウンロードしたら、```.dmg```内の実行ファイル（FreeCAD）をシステムの「アプリケーション」フォルダにコピーします。

貼り付けた実行ファイルを右クリック→実行を選択すると、確認されたのち起動できます。（次回以降はダブルクリックで起動できますが、初回はこの手順が必要です）

# gmshインストール
Homebrewからインストールします。
```bash
$ brew install gmsh
```

実行したら、インストール先を確認しておきましょう。
```bash
$ which gmsh
/opt/homebrew/bin/gmsh
```

# CalculiXインストール
CalculiX（calculix-ccx）をインストールします。様々なbottleが公開されていますが、私の環境ではこのbottle以外ではインストールできませんでした。
```bash
$ brew install costerwi/calculix/calculix-ccx
〜略〜
==> Installing calculix-ccx from costerwi/calculix
==> Patching
==> make -C spooles lib
==> make -C spooles/MT/src makeLib
==> Using Homebrew-provided Fortran compiler
This may be changed by setting the FC environment variable.
==> make -C ccx_2.20/src ccx_2.20 CC=clang FC=/opt/homebrew/bin/gfortran CFLAGS=-O2 -I../../spooles -DARCH=Linux -DSPOOLES -DARPACK -DMATRIXSTORAGE -DUSE
🍺  /opt/homebrew/Cellar/calculix-ccx/2.20: 4,686 files, 98.6MB, built in 1 minute 27 seconds
==> Running `brew cleanup calculix-ccx`...
Disable this behaviour by setting HOMEBREW_NO_INSTALL_CLEANUP.
Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`).
Removing: /Users/xxxx/Library/Caches/Homebrew/calculix-ccx--test--2.13.tar.bz2... (9.0MB)
Removing: /Users/xxxx/Library/Caches/Homebrew/calculix-ccx--2.13.tar.bz2... (1.1MB)
Removing: /Users/xxxx/Library/Caches/Homebrew/calculix-ccx--doc--2.13.tar.bz2... (2MB)
```

インストール先を確認しておきます。上のメッセージにも表示されている通り実体はCellarフォルダにあるのですが（```/opt/homebrew/Cellar/calculix-ccx/2.20```）、Cellarフォルダではなくbinフォルダを探せばよいです。
```bash
$ ls -d /opt/homebrew/bin/* | grep ccx
/opt/homebrew/bin/ccx_2.20
```

# FreeCADにPATHを登録する
FreeCADを開き、FEMワークベンチを開きます。

左上のFreeCAD→Preferences…を開き、FEMの項目を開きます。
![スクリーンショット 2023-04-07 21.13.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1075437/f3d87629-0fca-7517-e479-4b80b471cd67.png)

それぞれ先ほど調べたインストール先PATHを入力します。

![スクリーンショット 2023-04-07 21.14.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1075437/46459ebf-e097-9831-99f5-998c9bf1a686.png)
![スクリーンショット 2023-04-07 21.16.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1075437/437ffe26-17f9-88ae-14d6-7cf58955b4d5.png)

適用→OKで画面を閉じれば、FEMが可能な状態になっているはずです。Startに表示されるサンプルプロジェクト等で確認してください。
Azure NetApp Files でNFSv4.1ボリュームの作成と注意事項

Azure NetApp FilesではNFSプロトコルとSMBプロトコルの両方をサポートし、しかもDualプロトコルのボリューム作成も可能です。
本記事はNFSv4.1ボリュームの作成してからドメインに関連記事になります。

1、Azure NetApp Fileアカウントを作成（AzureのUIにて30秒で完成）
2、Azure NetApp Fileの容量プールを作成（AzureのUIにて30秒で完成）
3、Azure NetApp FileのNFSボリュームを作成
　 各項目の設定はこちらの公式ドキュメントをご確認ください
　 リンク：https://learn.microsoft.com/ja-jp/azure/azure-netapp-files/azure-netapp-files-create-volumes#create-an-nfs-volume
4、NFSv4.1ボリュームをRedhatの仮想マシンへマウント
5、マウントしてからユーザー表示が[nobody]になってます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3230994/a8bbf601-b0a5-2eae-5b52-3b5c116419d1.png)

　これはAzure NetApp FilesのNFSv4ボリュームで認証ドメインの概念が導入されて、Defaultのドメインは「localdomain」為、ルートマッピングもユーザーが「nobody」表示になってます。

ここからは「nobody」表示から「root」ユーザー表示される為の操作を行います。
☑ボリュームをアンマウントする
   -df –h              ボリュームを確認
   -umount  /xxx/xxx   対象ボリュームディレクトリ
　 -df –h              ボリューム無いことを確認
☑　/etc/idmapd.conf ファイルを更新する
参考コマンド：sudo nano /etc/idmapd.conf

　－ボリュームが LDAP に対して有効になっていない場合は、Domain = defaultv4iddomain.com を設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3230994/bf98e025-9585-efa7-263d-50afbebacc99.png)


　－ボリュームで LDAP が有効になっている場合は、Domain を NetApp アカウントの Active Directory 接続で構成されているドメインに設定
　例：Domain = contoso.com
☑ドメイン編集後、「Ctrl+X」で保存、「Ｙ」Yesを入力、Enterキーで通常の画面に戻る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3230994/a5dec79f-7ff9-4d2f-b47f-325b1c53c404.png)

☑ホストで rpcbind サービスを再起動する (service rpcbind restart) か、単にホストを再起動します。
　※Azureポータルでrpcbind サービスを再起動する方法
　　Ubuntuの場合
    -sudo apt-get update                             
    -sudo apt-get install rpcbind                  
　　Redhatの場合
    -sudo yum update 
    -sudo yum install rpcbind
    上記実施してから再起動
    -systemctl restart rpcbind
☑ボリュームを再度にマウントし、ユーザー・グループ表示が変わってることを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3230994/2bf073b3-8220-c865-d493-8c5be3c87007.png)



最後に、おまけ付きの情報です。
NFSv4.1ボリュームではAzure NetApp Files特有の「.snapshot」ディレクトリは非表示されてるけど、アクセスして中身の確認は可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3230994/92a0483f-9d1a-cd89-09c4-d545e01bf520.png)
M1 Mac で 「Package libcrypto was not found in the pkg-config search path.」と言われた場合の対処。


```bash
sudo mkdir -p /usr/local/lib/pkgconfig

sudo ln -s /opt/homebrew/opt/openssl\@1.1/lib/pkgconfig/libcrypto.pc /usr/local/lib/pkgconfig/libcrypto.pc
sudo ln -s /opt/homebrew/opt/openssl\@1.1/lib/pkgconfig/libssl.pc /usr/local/lib/pkgconfig/libssl.pc
```

以上
「定型的なボイラープレートまみれ」はすべてライブラリが存在します

ちょっと過言ですが...

- 複雑で凡ミスしやすい
- 長ったらしくて意味がわからない
- 同じようなことをアチコチで書いている
- あのプロジェクトでもこのプロジェクトでも同じようなことを書いてる

みたいなボイラープレートコードに対しては、だいたい分かりやすく書けるようなライブラリがあります。

- 仕事として書くなら解決するべき問題に集中するべき
- 学習者なら、さっさとスキップして上級に進むべき

という理由で**ライブラリを使うことと、それを見つける努力をすること**をオススメします。

:::note
もちろん、ライブラリ等を導入するときは、同僚への確認や、じゅうぶんな検証が必要です。
:::

# 例: clsx &mdash; React で className を動的に切り替えたい場合

ライブラリの力を借りずに、自力で条件分岐を書こうとするとこうなります。

```tsx
<div
  className={`card ${disabled ? "card--disabled" : ""} card--variant-${variant}`}
/>
```


もしスペースを忘れてしまったら、 disabled が true のときに　`cardcard--disabled` というクラス名になってしまいます。 しかも、出し分けたい条件が増えるたびに文字列テンプレートリテラルがどんどん長くなっていきます。

:::note
特に、条件に応じて配列になにかを追加していく、というコードを JavaScript に含まれる関数型のメソッドだけで正直に書くのは難しいです。ユーティリティを用意するかライブラリに頼りたところ。
:::

どうしましょう？ライブラリを探しましょう。 Google で検索してもいいですし、今どきは ChatGPT も役に立つかもしれません。

このような定型的で面倒くさい処理には、便利なライブラリを考える人が大抵いるものです。 
ほら、 **「React クラス名 動的 ライブラリ」** で探すと出てきました。 [clsx というライブラリ](https://github.com/lukeed/clsx) について書かれた記事です。ドンピシャですね。

https://qiita.com/taqm/items/c38855d8158cdd9d5a3e

```tsx
<div
  className={clsx(
    "card", // これは常に含まれる
    `card--variant-${variant}`, // スペースを気にせずに連結できる
    { // クラス名 : それが追加される条件 (真偽値) の形式のオブジェクトが使える
      "card--disabled": disabled,
    },
  )}
/>
```

ライブラリの使い方を学習しさえすれば、単純な文字列の分割と比べてかなり楽になると思います。



- スペースの入れ忘れを心配する必要がない
- クラス名 / それが追加される条件 とはっきりと意図がわかる
- 改行を自由に含めることができて、意味の区切りがわかりやすい
  - prettier でフォーマットしましょう


学習コストの問題についても、 clsx のような **その特定領域のデファクトスタンダード** であれば、みんなが知っているので、 コストが小さくなります。

:::note warn
ただし、非推奨と宣言されていないか、メンテナンスが止まっていないか。上位互換（さらに洗練されている、さらにパフォーマンスが良い） がないか、など注意が必要です。

とくに、記事の日付に注目したり、ライブラリの GitHub レポジトリを直接見に行けば気づけるかもしれません。まあここは慣れの問題ですね。


今回の場合は、 classNames というライブラリも出てきますが、どうやら clsx のほうがパフォーマンスが良い...らしい？
:::

# ほかの例

|たいへんなこと|解決法|
|---|---|
| 実行時の型エラー | TypeScript |
| コーディング規約 | ESLint / Prettier で強制する |
| ルーティングの設定 | Next.js | 
| UI コンポーネント実装 | Radix UI / Headless UI|
| UI コンポーネント実装<br/>(定型的な見た目でよい場合)| Mantine UI / MUI |
| fetch によるデータ取得 | SWR / TanStack Query |
| 入力フォーム| React Hook Form |
| コンポーネント単体の動作検証 | Storybook |




# まとめ

主語がデカくなりますが、日本人の多くは学生時代を通して「便利な道具に頼るのは甘え」「自力で問題を解かなければならない」という考えを刷り込まれていますが...

学校はあくまで実社会で必要な「頭の筋力」を身につける場所です。能力を鍛えるために**あえて**非効率ことをする場所なのです。

筋力を鍛えたいときには丸腰でモノを持ち上げますが、実生活で重すぎて上がらないものを持ち上げたいときには、ジャッキや重機を使いますよね？



私たちにとって大事なのは

- 製品を期日中に仕上げられるか
- タスクを分担しやすいか
- バグの混入の可能性を減らせるか
- 作業の精神的・肉体的負担を減らせるか
- あとで見返したときに内容を思い出せるか
- 後任者が困らないか

という現実的な問題です。

超一流ではない我々のようなエンジニアに必要なのは、 **同じ問題を解決した人が残した文書や、適切なライブラリ等を見つけてくる能力** だと思います。

学習者についても同じです。大事な問題には取り組まなければいけませんが、 **退屈なだけで身にならない問題はライブラリを使って楽しちゃいましょう。**

<b><font color="red">「楽をせず自力で全部やれ」は全て詐欺です。<font></b>

（ちょっと過言です）
コンテナでsupervisor使用時に「INFO reaped unknown pid XXX (terminated by SIGKILL)」 で困っている場合

```
INFO reaped unknown pid 1702 (terminated by SIGKILL)
```
コンテナ内で supervisor を使用していると、このようなログが大量に出力されていた。

コンテナ実行時に `--init` オプションを付けると解決するかもしれない。
#### Docker ( `--init` )
```docker
docker run --init --name web alpine:latest
```

#### Docker Compose ( `init: true` )
```yaml
version: "3.9"
services:
  web:
    image: alpine:latest
    init: true
```

https://github.com/docker-library/rabbitmq/issues/453#issuecomment-745540846
Stable-diffusion  basil mix   google colabo エラー対処

Stable-diffusionにも種類がある　
Stable-diffusionにも種類があります 今回は basil mix を使用したいと思います
basil mix　は、とても可愛らしいイラストを生成することができるモデルです

https://original-game.com/how-to-use-basil-mix-on-colab/

上記のサイトを参考に実施しました

2023年4月7日現在では上記のサイトだけでは難しく
google colabo の　内部設定を変える必要がありました

PyTorchが1.9.0である場合、適切なtorchvisionのバージョンは1.9.0となります

https://qiita.com/maskot1977/items/1d11d5875054b5a345ad

こちらの記事が非常にわかりやすかったです！

以下のソースコードで実行できました！！
```
!pip install --upgrade Pillow
!echo "Y" | pip uninstall torchvision
!echo "Y" | pip install torchvision==1.9.0

!git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui
%cd /content/stable-diffusion-webui

!wget https://civitai.com/api/download/models/11745 -O /content/stable-diffusion-webui/models/Stable-diffusion/Chilloutmix-Ni-pruned-fp32-fix.safetensors

!python launch.py --share --xformers --enable-insecure-extension-access
```
Pillowとtorchvisionは、コンピュータプログラムで画像を使うために必要なツールです。あなたがやったことは、Pillowを新しいバージョンにアップデートし、torchvisionを一度消してから再びインストールしました。これにより、これらのツールがうまく働くようになりました。これは、壊れたおもちゃを直すようなものです。修理が終わったら、また遊ぶことができます。


## basil mixを使って、すごく可愛いイラストが生成できる

basil mixを使って、すごく可愛いイラストが生成できる
みたいなのでアイドルを生成してみました


![00024-24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629668/88eee836-c9ab-3b11-ae3b-41dfc0196b1d.png)
![00025-27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629668/a9562f71-1df5-4bb8-90a4-aaed605e0bdd.png)
![00026-32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629668/aebcff43-4cee-7857-589e-89899cba238f.png)
![00028-36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629668/c62ebe9d-5f01-c69f-cd2a-8126ec41ba94.png)
![00030-36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629668/3487bde7-395a-2ffe-c1ef-0131dc9322cc.png)

すっごく可愛いイラストが生成できました！！！
「sudo vi の時に .vimrc が適応されない」の対処法

# 概要

これ困ってる人いそうだなと思って記事書きました。

# 問題

僕が直面した問題は以下の通りです。

- ユーザーayatoで`.vimrc`を作った。
- vim開いて設定が適応されていた。
- `sudo vim`したら設定が適応されてない。
   例えば、`sudo vi /etc/hosts`とかで見ずらい！

# 理由

`sudo vim`をしたら、rootの方の設定を読み込むようになっている。

# 対処法1

Kaliなどで一人で使っている、かついつもはrootで作業をしない時に使えます。

```bash
$ sudo ln -s /home/ユーザー名/.vimrc /root/.vimrc
```

rootの`.bashrc`が呼ばれた場合に、現在のユーザーへのリンクを提供してやればOKです！

# 対処法2

rootを他の人が使ってる場合に有効です。

```
sudo -E vi ファイル名
```

sudoコマンドの`-E` オプションを使用して環境変数を引き継ぎます。

# まとめ

役立てていただければ幸いです。
今は Windows Terminal があるので Tera Term がなくても SSH が使える！？

Windows に ssh.exe や Windows Terminal が標準で入るようになりました。「**ゆえに** SSH に Tera Term は必要ない」という発言を見かけますが、その説明が技術的に正しいと言える場合と、そうでない場合を説明してみたいと思います。

## 説明1. ssh.exe が標準搭載された

OpenSSH の Windows バイナリはそれ以前からありましたので、これだけでは技術的に正しい説明とはなりません。

導入しやすくなったのは事実ですが、自分で導入すれば（"OpenSSH for Windows" とか、Cygwin に openssh パッケージを入れるなどで）利用可能でした。

## 説明2. Windows Terminal が標準搭載された

Windows コンソールホスト(conhost.exe) で起動したコマンドプロンプトからでも ssh.exe は使えるので、技術的に正しい説明とはなりません。昔からコマンドプロンプトで telnet.exe が使えたのと同じです。

## 説明3. Microsoft が提供したものだけを使いたい

自由にフリーソフトを入れられない環境もあり、そのような制約がある場合には OS 標準のツールでのみ作業することになります。また、単に導入が楽ということもあります。そのような場合には技術的に正しい説明になると思われます。

ssh.exe が標準搭載されたことは理由になります。しかし前述のとおり「Windows Terminal が搭載されるようになったから」は理由になりません。

また Windows に標準搭載された ssh.exe は、Microsoft が OpenSSH を Windows バイナリとしてコンパイルしたものです。Microsoft が独自に開発した SSH クライアントというわけではありません。Micosoft が OpenSSH を Windows に標準搭載したこと（ある意味で OpenSSH または OpenBSD Project を信用する判断をしたこと）で導入できるのであれば、ssh.exe が OpenSSH であることは問題にならないことでしょう。逆に「Microsoft が開発したものでなければ不安で使えない」のであれば、macOS, 各種 Linux, BSD などで採用されている OpenSSH であっても使えないことになります。


# コンポーネントと担当部分のまとめ

Tera Term や Windows Terminal といった登場人物は、次のような役割を担当しています。

![component.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699223/22a2f730-4392-a1f3-b903-39bf2ac1d81b.png)

「Windows Terminal が、Tera Term や他の端末エミュレータと同様に SSH 接続を行っている」という認識は誤りであり、正しくは以下のようになります。

* Windows Terminal を使う場合
  * Windows Terminal を起動する
    * コマンドプロンプト(cmd.exe) か PowerShell が起動し、コマンド入力を受け付けるようになる
  * ssh.exe コマンドで SSH サーバに接続する
    * SSH サーバがシェルを起動し、サーバ側のコマンド入力を受け付けるようになる

* Tera Term の場合
  * Tera Term を起動する
  * 接続先を指定して接続を開始する
    * SSH プロトコルで接続する場合は内部的に TTSSH が使用される
    * SSH サーバがシェルを起動し、サーバ側のコマンド入力を受け付けるようになる
雑談：最先端の情報を公開する

# はじめに
タイトルにも書いているように、nRF Connect SDKに関する日本語の情報ってのは僕が知る限りではほとんどありません。元々、ハードウェアやファームウェアの情報というのはネット上では出回りにくいものです。その理由は色々とあるのでしょうが、ソフトウェアと比べると絶対数が少ないのと、ネット上で記事にするだけの熱意がある人が少ないのが主な理由ではないかと思っています。また、そのような状況の中では情報そのものに価値が出てくることになるため、ますます書く人も少なくなる、でだいたい説明ができると思っています。
# なんで書いてるの？
そんな状況の中でお前はなんでこんな情報を書いているんだって思いますよね。僕も最初は悩みましたし、実は最初のころに書いたものは一度全部消しました。

::: note
全然反響がなかったので消しましたw
今も別にそんなに大きな反響があるわけではないですけどね。
:::

正直なことをいえば、今もこのレベルの情報なら普通に売れる(お金になる)と思っています。そんなものをあえて無償の場で公開しているのは、少しでも技術者が増えてくれることを願っている、ただそれだけです。モノづくり大国の日本でありたいじゃないですか。すごいものを作って感動させたいじゃないですか。
あとはこういうのを見てこの会社で働いてみたい、と思ってくれる人がいたら最高ですよね。50歳のオッサンがいつまでも前線で最先端のことを調べているのはやっぱりよろしくないですよ、ええ(笑)。
若い人たちにもっとがんばってほしいなといつも思っています。
# ということで
少しでも技術者の役に立つと報われるかな、と思っています。

::: note
別に反響がなくても消しはしませんよ！(笑)
:::
.split(" ").map(Number)について

paizaの問題を解く際によく使うので、まとめました

# .split(" ")
.split(" ")は、文字列を空白文字（スペース、タブ、改行など）で区切って配列に変換するJavaScriptのメソッドです。このメソッドを使用することで、文字列を単語ごとに分割して、配列の要素として格納することができます。

# map()
map()は、配列の各要素に対して、指定された関数を呼び出し、その戻り値を新しい配列として返すJavaScriptのメソッドです。

# Number
Numberは、JavaScriptのビルトインオブジェクトで、数値を表すために使用されます。Numberコンストラクタ関数を呼び出すことで、引数として渡された値を数値に変換します。

したがって、.split(" ").map(Number)は、空白文字で区切られた文字列を配列に分割し、各要素を数値に変換するためのJavaScriptコードになります。


# 使用方法:
`split()`は文字列のメソッドで、引数に区切り文字を渡すことで、文字列を区切って配列に変換します。
`map()`は配列のメソッドで、配列の各要素に対してコールバック関数を実行して、新しい配列を生成します。
`Number()`はJavaScriptのビルトインオブジェクトで、文字列を数値に変換するための関数です。

例えば、以下のような文字列があるとします。

```JavaScript

const str = "1 2 3 4 5";

```

この文字列を空白文字で分割して、各要素を数値に変換するには、以下のようにコードを書くことができます。

```JavaScript

const arr = str.split(" ").map(Number);
console.log(arr); // [1, 2, 3, 4, 5]

```

# 使用理由:
このような処理を行うことで、入力された文字列を数値の配列に変換することができます。例えば、フォームから送信された文字列データを数値データに変換して、計算処理を行う場合などに有用です。

# メリット:
このような方法を使用することで、文字列を簡単に数値配列に変換できます。また、1行でコードを記述できるため、コードが簡潔で読みやすくなります。

# デメリット:
文字列の区切り文字が変わった場合や、数値以外の文字列が混ざっている場合には、うまく処理できない可能性があります。また、コードの読みやすさを優先するため、処理の詳細なエラーハンドリングが行われない場合もあるため、注意が必要です。
WSL2環境からWinSCPを使用してローカルファイルシステムにアクセスする手順

## 概要
Windows環境で、WinSCPを利用してWSL2のUbuntu環境へ接続する手順です。
自身のWindows環境から、WSL2のUbuntuへファイルやフォルダを移動させたい場合に活用できます。
## 手順
#### 1. WSL2環境でSSHサーバーをインストール & 起動

```
sudo apt-get update
sudo apt-get install openssh-server
sudo service ssh start
```

#### 2. WSL2環境のIPアドレスを確認


```
ip addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}'
# IPアドレスが赤字で表示される
```

:::note
コマンドの意味（不必要な方は読み飛ばしてください）
 - **ip addr show eth0**: "eth0" という名前のネットワークインターフェースに関する詳細情報を表示
 - **grep**: 検索コマンド
 - **|(パイプ)** : 直前のコマンドをフィルタリングする 
 - **-o**: マッチした部分だけを表示。
 - **-P**: Perlの正規表現構文を使用。
 - **(?<=inet\s)\d+(\.\d+){3}**: 正規表現
 - **eth0**: Linuxシステムで最初に認識されるイーサネットインターフェース
     - **Ethernet**：ローカルエリアネットワーク（LAN）で最も広く使用されるネットワークプロトコルの1つ
:::

#### 3. WinSCPを起動 & Sessionの設定

>ファイルプロトコル: SFTP
>ホスト名: WSL2環境のIPアドレス
>ポート番号: 22
>ユーザー名: WSL2環境のユーザー名

#### 4.Session設定で保存した情報を選択し、ログイン
毎月のアカウント利用料を通知する機能をCloudFormationで作ってみた！

# はじめに
今回は、「Control Tower環境で、各メンバーアカウントの利用料を特定のチャンネルにSlackで通知する機能」について社内ブログで投稿しましたのでご紹介させていただきます。

CTを使用するユースケースとして、社内のサンドボックス環境が一例として挙げられるかと思いますが、各アカウントの月次の利用料の通知はあると便利な機能なのでぜひご参考にしていただけると幸いです:relaxed:

以下のリンクからご覧いただけます。
https://blog.mmmcorp.co.jp/blog/2023/04/07/notify-monthly-cost/
StackSetsで予算設定・通知機能を作ってみた！

# はじめに
今回は、「ControlTower環境の各アカウントで、予算を管理・通知するための機能をCloudFormation StackSetsを利用して作ってみた！」という内容で社内ブログに投稿させていただきましたのでそちらのご紹介です。

Control Tower内で各アカウントごとに予算を設定することは必要な機能だとは思いますが、中々手動で行うのは大変なので、本記事がどなたかのお役に立てれば幸いです:relaxed:

以下のリンクからご覧いただけます。
https://blog.mmmcorp.co.jp/blog/2023/04/07/create-setting-budget-tool/
AFTでアカウント管理やってみた！

# はじめに
今回は、「AWS Control Tower Account Factory for Terraform（AFT）を利用して、社内のサンドボックス環境のユーザをコード管理する」という内容の記事を、社内ブログにて執筆させていただきました！

Terraformも初心者な私ですが、悪戦苦闘しながら実装しましたのでぜひみていただけると嬉しいです:relaxed:

以下のリンクからご覧いただけます！
https://blog.mmmcorp.co.jp/blog/2023/04/07/manage-account-by-aft/
複数のフォルダ内の文字列を置換する方法

### 困ったこと
以下のような構造のフォルダ内のテキストファイル(text1.txt~tex4.txt)内の文字列を一括で置換したい．

```
├─dir_parent
│  ├─dir_child1
│  |    ├─text1.txt
│  |    └─text2.txt
│  └─dir_child2
│      ├─text3.txt
│      └─text4.txt
```
### 解決策
以下の手順で解決可能
1.``cd``  コマンドを使用して、置換対象のテキストファイルが含まれる親フォルダに移動する．
2.以下のコードを実行．フォルダ内の文字列hageがhogeに置換される．
```shell
find . -type f -name "*.txt" | xargs sed -i '' 's/hage/hoge/g'
```
応用すると複数の文字列も置換可能
```shell
find . -type f -name "*.txt" -exec sed -i '' -e 's/2022\/3\/4/2023\/3\/3/g' -e 's/2022\/4\/6/2024\/4\/5/g' {} +
```

### 少し解説
`` find ``でカウントディレクトリ内の置換対象のテキストファイルのリストを作成する． 
今回であれば全ての``.txt``ファイル．
``` shell
find . -type f -name "*.txt"
```
``xargs``で標準入力から受け取った値を引数に渡す．（らしい）
`` sed -i``で文字列の置換を直接行う．
C++による格子ボルツマン法の平衡分布関数の計算のベンチマーク測定

# はじめに

前回の記事

https://qiita.com/shohirose/items/0b798bf1560be8ef2565

においてVisual Studio 2022のパフォーマンスプロファイラーを使ってコードを分析した結果を示しましたが、今回はホットスポットのひとつである平衡分布関数の計算について、実装方法の違いによる実行速度の比較を行いました。プログラムのベンチマーク測定にはgoogle benchmarkを使用しました。

https://github.com/google/benchmark


## コード

https://github.com/shohirose/lbm-simulator

## 実行環境

OS：Windows 11 Pro
CPU：Intel Core i7-9700K 8C/8T 3.60GHz
コンパイラ：Visual Studio 2022
最適化オプション：`O2`

# 測定結果

D2Q9格子の平衡分布関数を様々な実装方法で計算したプログラムについて、横軸にセル数、縦軸にCPU時間をとってプロットした結果を下図に示します。セル数が$262,144=512^2$の時、実行時間が最も短い`EigenVectorizeTest2`/`EigenVectorizeTest3`と最も長いもののひとつである`NaiveImplTest`の間で約4.5倍の差がついており、実装方法に注意を払う必要があることがわかります。

![benchmark.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130485/e82dbccf-2f8b-46a1-557d-319e1e46db89.png)

ここでは一部のプログラムの詳細のみ紹介するので、その他は[`benchmark/run_feq_benchmark.cpp`](https://github.com/shohirose/lbm-simulator/blob/master/benchmark/run_feq_benchmarks.cpp)を参照してください。まず`NaiveImplTest`はEigenの機能を使って下記の様に素直に実装したプログラムです。

```c++
// u_   : velocity (2 x N)
// c_   : lattice vector (2 X 9)
// w_   : weight coeffs (9 x 1)
// feq_ : equilibrium distribution function (9 x N)
// rho_ : density (N x 1)
// N    : number of cells
const Eigen::Matrix<double, 9, Eigen::Dynamic> cu = c_.transpose() * u_;
const Eigen::Matrix<double, 1, Eigen::Dynamic> u2 =
    u_.colwise().squaredNorm();
feq_ = ((w_ * rho_.transpose()).array() *
        (1.0 + 3.0 * cu.array() + 4.5 * cu.array().square() -
         1.5 * u2.replicate<9, 1>().array())).matrix();
```

一方、`EigenVectorizeTest2`は下記の様にセルごとにforループで計算するようにしたプログラムです。

```c++
const Eigen::VectorXd u2 = u_.colwise().squaredNorm().transpose();
for (int i = 0; i < feq_.cols(); ++i) {
  const Eigen::Matrix<double, 9, 1> cu = c_.transpose() * u_.col(i);
  feq_.col(i) =
      (rho_(i) * w_.array() *
       (1.0 + 3.0 * cu.array() + 4.5 * cu.array().square() - 1.5 * u2(i)))
          .matrix();
}
```

興味深いことに、`EigenVectorizeTest2`の`feq_.col(i) = ...`の部分をforループを使って下記のように実装した`ForLoopTest2`の実行時間は`EigenVectorizeTest2`の1.2倍かかりました。このようにEigenの機能をうまく使うと、コンパイラがコードを最適化してくれる場合があります。

```c++
for (int i = 0; i < feq_.cols(); ++i) {
  const auto u2 = u_.col(i).squaredNorm();
  const Eigen::Matrix<double, 9, 1> cu = c_.transpose() * u_.col(i);
  for (int k = 0; k < 9; ++k) {
    feq_(k, i) = w_(k) * rho_(i) *
                 (1.0 + 3.0 * cu(k) + 4.5 * cu(k) * cu(k) - 1.5 * u2);
  }
}
```

# その他

科学技術計算において実装方法に迷った場合、本記事のように特定の部分のみ切り出してベンチマーク測定し、最も実行速度の速いものを選択するといいでしょう。実行環境によっては、もっと高いパフォーマンスを出せる実装方法があると思うので、色々試してみてください。
Shopify REST APIでデータをID順で取得するコツ

業務でShopify APIを使っています。
ある日、Shopify Article APIでArticleデータをID順に取得したい事がありました。その時に"ID順でデータを取得する技"を見つけたので、備忘録として残しおきます。

## 結論
- パラメーターとして用意されている"since_id"を使って、IDのソートを実現させる。
https://shopify.dev/docs/api/admin-rest/2023-01/resources/article#get-blogs-blog-id-articles

- since_id=1にすると、ID順でデータを取ることができる(注意として、since_ID=0だと"since_ID"の設定が無視されます。おそらくsince_idが設定されていない場合、つまり初期値(0)の場合に、設定を無視する為だと推測してます)
- 今回、この技を使って、ページネーション機能を実装させました(取得したデータの一番最後のIDをsince_IDで設定し、再度APIを実行する事で次のページのリストデータを取得できる。結果的に全データの取得をしました)
- Articles以外でも、Products、Ordersでも同じ方法でIDのソート順でデータを取得できたので、since_idパラメータがある全てAPIに適用されそうです。

実行例
curl
```
curl -X GET "https://your-development-store.myshopify.com/admin/api/2023-01/blogs/241253187/articles.json?since_id=1" \
-H "X-Shopify-Access-Token: {access_token}"

```
NCMBの管理画面をGoogle Chrome機能拡張で便利にする（ファイルストアの一括ダウンロード）

NCMBでは管理画面を提供していますが、時々物足りないことがあります。この機能があったらもっと便利なのに…と思いつつ、使っている方もいることでしょう。

そこで、その足りない機能を補足するGoogle Chrome機能拡張を開発しはじめました。

## 動作について

動作は以下のようになります。機能拡張をインストールしていると、ファイルストアの画面で一括ダウンロードボタンが表示されます。このボタンを押すと、表示されているファイルストアのファイルを順番にダウンロードします。

![画面収録 2023-04-07 19.12.25.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/56c6ca65-2c94-2c71-c724-28a8a3eedf2a.gif)


## インストール

[Chrome機能拡張のページからインストール](https://chrome.google.com/webstore/detail/ncmb-extension/dglkhlplcpmnbgodhbngcmdfpojkbdnc?hl=ja&authuser=0)してください。


## 制限

この機能拡張は [https://console.mbaas.nifcloud.com](https://console.mbaas.nifcloud.com/) 以下でのみ動作します。また、この機能は管理画面のAPIを使っていますので、APIコール数を消費しません。また、ACLは無視して処理されます。

## コードについて

機能拡張のコードは[NCMBMania/chrome-extension](https://github.com/NCMBMania/chrome-extension)にアップロードしてあります。ライセンスはMIT Licenseです。依存ライブラリとして[URL.js](https://github.com/duzun/URL.js)を使っています（こちらもMIT Licenseです）。

## まとめ

機能的にはまだ多くありませんが、徐々に機能を追加していきます。Google ChromeでmBaaSの管理画面を利用されている方はぜひお使いください。
react-calendar-timelineで祝日をハイライトする方法

### 環境
[react-calendar-timeline](https://github.com/namespace-ee/react-calendar-timeline)

### 祝日をハイライトする方法
verticalLineClassNamesForTime　プロパティを使う。
if内のreturnで任意のクラス名を返却してください。今回は祝日を想定していたため、['rct-day-0']を返却しました。
rct-day-0はreact-calendar-timelineのcssで日曜日に当てられているクラス名です。
matchingHolidayが見つからなかった時に空の配列を返すことを忘れずに。

```TypeScript

  const holidays = [
    moment('2023/1/1', 'YYYY/MM/DD'),
    moment('2023/1/2', 'YYYY/MM/DD'),
    moment('2023/1/9', 'YYYY/MM/DD'),
    moment('2023/2/11', 'YYYY/MM/DD'),
    moment('2023/2/23', 'YYYY/MM/DD'),
    moment('2023/3/21', 'YYYY/MM/DD'),
    moment('2023/4/29', 'YYYY/MM/DD'),
    moment('2023/5/3', 'YYYY/MM/DD'),
    moment('2023/5/4', 'YYYY/MM/DD'),
    moment('2023/5/5', 'YYYY/MM/DD'),
    moment('2023/7/17', 'YYYY/MM/DD'),
    moment('2023/8/11', 'YYYY/MM/DD'),
    moment('2023/9/18', 'YYYY/MM/DD'),
    moment('2023/9/23', 'YYYY/MM/DD'),
    moment('2023/10/9', 'YYYY/MM/DD'),
    moment('2023/11/3', 'YYYY/MM/DD'),
    moment('2023/11/23', 'YYYY/MM/DD'),
  ];

<Timeline
        groups={group}
        items={items}
        //他のプロパティは省略
        verticalLineClassNamesForTime={(timeStart, timeEnd) => {
          const currentTimeStart = moment(timeStart);
          const currentTimeEnd = moment(timeEnd);
        
          const matchingHoliday = holidays.find(
            (holiday) =>
              holiday.isSame(currentTimeStart, 'day') && holiday.isSame(currentTimeEnd, 'day')
          );
        
          if (matchingHoliday) {
            return ['rct-day-0'];
          }
          return [];
        }}
</Timeline>
```
GitLab Runner(Helm版)をpodAntiAffinityで冗長化する

HelmでGitLab Runnerを導入する際にレプリカ数は指定できるが、どのノードで上がるかや分散させるかなどの冗長化に関する直接的な設定項目はない。
そのため、同一ノードで起動することも考えられ、冗長化観点からは嬉しくない。
ここでは、`podAntiAffinity`を利用してGitLab Runnerを別々のノードであげるように設定する。
なお、Kubernetesの1.18以降だとPodを分散してあげるには`topologySpreadConstraints`を使うとよいのだが、まだGitLab RunnerのChartには実装されていないため利用できない。
[Add support for topologySpreadConstraints
](https://gitlab.com/gitlab-org/charts/gitlab-runner/-/issues/359)

## 設定と確認
Helmのvaluesで`affinity`の設定項目があるので、こちらを利用して分散させる。
values.yamlに以下を記載する。
```yaml
affinity:
  podAntiAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
    - labelSelector:
        matchExpressions:
        - key: app
          operator: In
          values:
          - gitlab-runner-test
      topologyKey: kubernetes.io/hostname
```

`podAntiAffinity`における各項目の意味は以下となる。
- `requiredDuringSchedulingIgnoredDuringExecution`：ルールを満たさない場合、Podをスケジュールしない。なお、ルールを満たさなくてもPodをスケジュールしたい場合は`preferredDuringSchedulingIgnoredDuringExecution`を指定する。
- `labelSelector`：対象Podのラベル。helmでデプロイする際、helmがapp=<リリース名>というラベルを付与するので、予定しているリリース名を指定する。
- `topologyKey`：対象ノードのラベル。今回はノード間で分散したいため`kubernetes.io/hostname`とした。EKSでAZで分散したいとかなら`topology.kubernetes.io/zone`を指定する

AntiAffinityルールの場合、該当するPodが存在したらデプロイしない。`topologyKey`にノードを指定しているため、これにより同一ノードへのデプロイが行われなくなる。
また、values.yamlにレプリカ数も設定する。現在4ノードで動いているため、ノード数+1で定義して、1Podだけ起動できないことを確認する。
```yaml
replicas: 5
```

これを使ってRunnerをインストールする。
```
helm install -n gitlab gitlab-runner-test gitlab/gitlab-runner -f ./runner-values.yaml
```
インストール後に分散していること、5つ目のPodがAntiAffinityにより起動できないことが分かる。
```
$ kubectl get pod -n gitlab -o wide -l app=gitlab-runner-test
NAME                                  READY   STATUS        RESTARTS   AGE    IP                NODE                             NOMINATED NODE   READINESS GATES
gitlab-runner-test-8bd6cdbb6-7nfsr    1/1     Running       0          102s   192.168.75.200    ip-192-168-77-42.ec2.internal    <none>           <none>
gitlab-runner-test-8bd6cdbb6-95ddb    1/1     Running       0          102s   192.168.69.222    ip-192-168-79-93.ec2.internal    <none>           <none>
gitlab-runner-test-8bd6cdbb6-jxtt8    1/1     Running       0          102s   192.168.108.218   ip-192-168-98-54.ec2.internal    <none>           <none>
gitlab-runner-test-8bd6cdbb6-pcqtr    0/1     Pending       0          102s   <none>            <none>                           <none>           <none>
gitlab-runner-test-8bd6cdbb6-sdlf5    1/1     Running       0          102s   192.168.110.244   ip-192-168-97-139.ec2.internal   <none>           <none>
```
企業リース向けスリムPCの電源換装をした

# はじまり
 ファイルサーバーを作りたい、と思った。手元には Lenovo の ThinkCentre-Edge72 がある。
しかし、製造から割と経っているコイツをずっと稼働させっぱなしにするのは怖い。
知らんうちに電源が爆発したりしてしまわないだろうか。
電源が怖い。
電源が怖い。

-> __それなら、電源を換装すればいいんだ！__

と、いうわけで、スリムPCの電源換装計画　もとい ThinkCentre 改造計画がスタートした。

# 規格を確認する
 計画はスタートしたわけだが、必要なものを購入する前にマザーボードの規格や、電源ピンの仕様について調べなくてはならない。
購入してから「うーん、ねじ止めできないね」という事態に陥ってしまっては嫌なので。

## マザーボード
 [PC 生活](http://tdmsite00.blogspot.com/2014/09/blog-post.html)さんに ATX 規格のマザーボードのネジ位置が掲載されていたので、ThinkCentre の寸法と照らし合わせる。

6つあるネジ穴すべての寸法がぴったり同じようだ。
マザーボードの規格については問題ない。

## 電源
電源を換装するぞー、と軽く言ってしまったがメーカー製PCは電源ピンに独自規格を用いていたり、供給電圧が ATX 規格に準ずるものでないことがあるので、要チェックである。そのどちらか一方にでも独自規格が使用されていた場合には、この計画は即終了である。
 ### 電源ピンの形状
メインの 24 ピンは見比べたところ、すべて同じ形状であった。
また、CPU電源の 4 ピンの形状も同じであった。
その他、SATA 電源やペリフェラル電源についても同様であった。
よってピンの形状には互換性があると判明した。

### 供給電圧

Wikipedia の情報と、AcBel製の電源に記載された情報を基に互換性があるかを調べる。

ThinkCentre
- +5.08 V
- +3.3 V
- +12.0 V
- -12.0 V
- +5.08V (sub)



-5 VDC については SFX 電源では省略されているようであるが、ATX 電源との互換性は保たれているようである。
というわけで、供給電圧についても互換性有りと判明した。

> [Wikipedia ATX電源](https://ja.wikipedia.org/wiki/ATX%E9%9B%BB%E6%BA%90)

# 材料
- ThinkCenter-Edge72
   - CPU : core i3-3220 (2C 4T)
- 新品の電源
  - Thermaltake Smart 500W

- 新品のケース
  - Thermaltake Versa H17


元々 ThinkCentre に搭載されていた電源は、小型PC向けの SFX 規格なのだが、新しく用意した電源は ATX 規格のものである。
ATX 規格の電源を選んだ理由は単純で、SFX 規格の電源と比較して安いからである。
そして、上記の理由から電源のサイズが大きくなったことにより元の筐体のまま電源のみを交換することが出来なくなってしまったため、仕方なくケースも新調したというわけである。

電源、ケース共に Thermaltake 製品を選んだのは、そこそこの大手であり信頼をおけるからである。

電源については 500 W も必要ないのだが、 Thermaltake が Amazon で販売している電源で一番容量が小さいのが 500 W だったためしぶしぶ選択した。

<details><summary>裏話</summary>

(〇人志向などが200 W や 350 W の電源を販売しているが、正直なところいい噂をあまり聞かないので今回は選択しなかった。)
</details>


# 工程
1. ThinkCentre からマザーボードを引っぺがす。
![IMG_1602.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2403016/8d81914a-b1aa-6224-6cf8-b4149a7ccf43.jpeg)

1. 新しいケースに固定する。
![IMG_1603.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2403016/48b40921-d0e7-ee1b-51aa-cc56afd1a987.jpeg)
(グリスの塗り替えも行ったのでCPUクーラーが外れている)

1. 配線する。
![IMG_1606.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2403016/a07f39b9-996f-20b5-74f8-c5401d85385b.jpeg)

1. 完成！
![IMG_1609.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2403016/10cd7267-3ff1-0fce-2530-c75c977d0f27.jpeg)

# 終わりに
 ケースを加工するなどの工作を行ったわけでもないので非常に薄味な記事になってしまった。しかし、こんなこともできるのだと知ってもらえれば、それだけで十分だ。
AWS Fargate, ECSを用いたコンテナ運用設計、構築をしてみた。~DB構築とラスト~

# 前記事
[AWS Fargate, ECSを用いたコンテナ運用設計、構築をしてみた。~Fargate+ECSの構築~](https://qiita.com/bakuchiku/items/33db8d8f218415a6a370 "AWS Fargate, ECSを用いたコンテナ運用設計、構築をしてみた。~Fargate+ECSの構築~")
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3138153/d8804ca3-bee7-dd8f-e56a-019099e44898.png)

# 今回やること
DB立てる！DB接続情報をコンテナで使えるようにする！
完成！！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3138153/e91629cd-4688-3c03-2a2f-b2eedf45911b.png)

今回がラストです、、長かった。

# Auroraの作成
サクッと立てました。
設定はいい感じにお願いします。
セキュリティグループには第二回で作成したDB用セキュリティグループを設定しましょう！！
![39.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3138153/f8f74ac7-642c-a0dc-d5da-351c79a5762c.png)

## DBへの接続確認
Cloud9から以下コマンドを実行するとDBに接続できます！
DBの設定は各自のアプリケーションに合わせてお願いします笑笑
```
$ mysql -h {DBのエンドポイント} -u {DBユーザ名} -p {DBパスワード}
```

# DB接続情報をSecret Managerに登録する
## 新しいシークレットを登録
「Secret Manager」→「新しいシークレットを保存する」から登録していきます。
暗号化キー：aws/secretmanager
データベース：先ほど作成したDB
![41.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3138153/9aeca88e-120c-5d70-cade-ada854ce37ee.png)

## Secret Manager用のポリシー作成
下図のように作成します。
![42.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3138153/1bc35191-f3b9-2278-fc0d-22759f73fe90.png)

作成したポリシーを「ecsTaskExecutionRole」にアタッチします。
![43.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3138153/07cba3d8-0bed-1121-6de0-718045f33a56.png)

## Secret Manager用エンドポイントの作成
ECSからSecret Managerを呼び出すためにはインターフェースエンドポイントが必要になります。
Cloud Watch, ECRと同じサブネットに作成します。
![44.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3138153/8c327541-9759-0809-37ec-c00c4234e7e7.png)

## タスク定義を更新する
「ECS」→「タスク定義」からコンテナ定義画面を開きます。
環境変数を指定し設定します。
![45.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3138153/7aad2591-1e03-f9e8-620f-00a2e3fc02c8.png)

# Brue/Greenデプロイメントによる切り替え！
これですね！
![46.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3138153/41861daa-ed1a-3a4e-5e20-411a76aacce0.png)

# まとめ
おわった～～
コンテナ実行環境の勉強でした〇
正直途中であきらめそうになるくらいエラー出ましたが何とかやり切りました笑笑

次はAzureの検証とかもやってみたいな～なんて、
ありがとうございました。
NCMBの管理画面をGoogle Chrome機能拡張で便利にする（データストアのエクスポート）

NCMBでは管理画面を提供していますが、時々物足りないことがあります。この機能があったらもっと便利なのに…と思いつつ、使っている方もいることでしょう。

そこで、その足りない機能を補足するGoogle Chrome機能拡張を開発しはじめました。

## 動作について

動作は以下のようになります。機能拡張をインストールしていると、任意のデータストアでエクスポートボタンが表示されます。このボタンを押すと、該当するデータストアのデータをJSON形式でエクスポートします。

![extension-1.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/db955fa6-5d17-64bb-4fa0-1f114b1f94b0.gif)


## インストール

[Chrome機能拡張のページからインストール](https://chrome.google.com/webstore/detail/ncmb-extension/dglkhlplcpmnbgodhbngcmdfpojkbdnc?hl=ja&authuser=0)してください。


## 制限

この機能拡張は [https://console.mbaas.nifcloud.com](https://console.mbaas.nifcloud.com/) 以下でのみ動作します。また、この機能は管理画面のAPIを使っていますので、APIコール数を消費しません。また、ACLは無視して処理されます。

## コードについて

機能拡張のコードは[NCMBMania/chrome-extension](https://github.com/NCMBMania/chrome-extension)にアップロードしてあります。ライセンスはMIT Licenseです。依存ライブラリとして[URL.js](https://github.com/duzun/URL.js)を使っています（こちらもMIT Licenseです）。

## まとめ

機能的にはまだ多くありませんが、徐々に機能を追加していきます。Google ChromeでmBaaSの管理画面を利用されている方はぜひお使いください。