OmniAICreator/Qiita-1.07M huggingface dataset:
VOICEVOXへのPOSTリクエストをNGINXで負荷分散＆キャッシュする

## モチベーション
Discord用の自作TTS-Botの音声変換エンジンにVOICEVOXを使っています。
VOICEVOXが合成する音声の品質は素晴らしいのですが、APIサーバーとして多くのリクエスト処理するのには向いているとは言えません。
そこで、次の二つの対策を考えました。

 - VOICEVOXのAPIサーバーを複数用意して負荷分散する
 - リクエストの結果をキャッシュしておき、同じリクエストの場合はキャッシュから結果を返す
 ※長文にはほぼ効果はないですが、定型文の連打とかには効果が見込めるかも？

最初はBot側で実装しようかなって考えていたのですが、「これってリバースプロキシとかロードバランサの仕事じゃない？」と思い直したのでNGINXでやってみることにします

```
TTS-Bot <---> NGINX <-----> VOICE Server 1(192.168.0.101:50021)
                ↕      |--> VOICE Server 2(192.168.0.102:50021)
             (Cache)   |--> VOICE Server 3(192.168.0.103:50021)
```
## NGINXによる負荷分散とヘルスチェックの話
振分については特に解説は必要ないかと思いますが、ヘルスチェックの挙動については下記参考になります！

https://www.konosumi.net/entry/2021/09/12/234543
https://neinvalli.hatenablog.com/entry/2017/10/31/002839
https://recruit.gmo.jp/engineer/jisedai/blog/loadbalancing-nginx/

## マイTTS-BotでつかうVOICEVOXのAPI

/audio_query
/synthesis

どっちもPOSTメゾッドです

https://voicevox.github.io/voicevox_engine/api/

## そもそもPOSTってキャッシュしてもいいの？
キャッシュしてもよいそうです。
ただ「ほとんどの実装では対応してないけどね」という注意書きがつきますが・・・。

APIサーバー側がステートレスで同一のリクエストには同一の結果を返すのを保証するなら問題なさそうです。
※ということで、VOICEVOX側のユーザー辞書機能は封印します。

## 何をもって「同一」のリクエストとするか
 - ホスト名（ポートまで含む）
 - URLパラメータ(URLの末尾の?以降の部分)
 - リクエストBody

今回は、上記一致なら同一リクエストとみなしましょう。
つまり、この３項目をキャッシュを引き当てるキーに使います。

## 一旦出来上がったnginx.conf
RHEL9でインストールできるパッケージのconfファイルがベースです

```nginx
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    
    sendfile        on;
    keepalive_timeout  65;

    # コネクション確立とか送信方向は早めにタイムアウトさせて次のノードにトライさせる
    proxy_connect_timeout 1s;
    proxy_send_timeout 1s;
    proxy_read_timeout 60s;

    # バッファーのサイズが小さくてキャッシュに失敗していたので大きめに設定
    proxy_buffer_size 64k;
    proxy_buffers 100 64k;
    proxy_busy_buffers_size 128k;

    #これを設定しないとリクエストBodyのサイズによっては
    #$request_bodyが空になってキャッシュの引き当てがうまくいかない
    client_body_buffer_size 1m; 

    # POSTのレスポンスコード200の結果のみ、24時間10GBまで保持する。
    # でも再利用されなかったキャッシュは１時間で捨てる。
    proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=vv-cache:10m inactive=1h max_size=10g;
    proxy_cache vv-cache;
    proxy_cache_valid 200 24h;
    proxy_cache_methods POST;

    # キャッシュを引き当てるためのキーの設定
    # $http_host ・・・ホスト名（ポート含む）
    # $request_uri ・・・URIパラメータ
    # $request_body ・・・リクエストBody
    proxy_cache_key $http_host$request_uri$request_body;

    # 負荷分散先
    upstream voicevox {
        server 192.168.0.101:50021;
        server 192.168.0.102:50021;
        server 192.168.0.103:50021;
    }
    
    server {
        listen       50021;

        location / {
            proxy_pass http://voicevox;
            
        }
    }
}
```

同じ単語を連打した場合、キャッシュからレスポンスしてくれるようになった。

## 効果測定
※方法を検討中
- ダミー文章の準備
→面倒なのでキャッシュを無効化して同じクエリをPOSTする方向で（おい）
- 負荷試験用のプログラム作成
→jmeterで試行錯誤中
- レスポンスの遅延が出始める単位時間あたりのリクエスト数を測定すればいい？
→対処不可能なリクエスト数が来た場合、NGINXでキューイング＆ドロップさせる処理が必要だと思い始めた

## 参考
https://danishshakeel.me/how-to-cache-post-requests-in-nginx/
docker build の DEPRECATED をなんとかする

## あらすじ

Docker 触り初めで `docker build` に触れたとき･･･

```sh
docker build -t image-name .

# DEPRECATED: The legacy builder is deprecated and will be removed in a future release.
#             Install the buildx component to build images with BuildKit:
#             https://docs.docker.com/go/buildx/
#
# (以降ビルドのログ)
```

ん？DEPRECATED だって？何か対応しとくか･･･。

調べると代わりに `buildx` を使えと。

```sh
docker buildx
# docker: 'buildx' is not a docker command.
# See 'docker --help'
```

あれ、無いだと？何か導入しろと･･･。

## build/buildx とは

Docker のビルドは、(超雑に言うと) `dockerfile` からイメージを作ってくれるヤツです。

これについて、[`build` はレガシーとなっていて廃止予定](https://docs.docker.com/reference/cli/docker/build-legacy/)、対し [`buildx` という新しいの](https://docs.docker.com/reference/cli/docker/buildx/)に切り替えられる様子。

[BuildKit](https://github.com/moby/buildkit) というものを使って、ビルドをとても良い感じにグレードアップしてくれるらしい (よくわかっていない)。

## 早速 `buildx` を導入

`buildx` を導入しましょう。GitHub の [README.md にインストールの説明](https://github.com/docker/buildx?tab=readme-ov-file#installing)があります。

どれどれ、Windows と MacOS なら Docker desktop に組み込まれていると。Linux は `docker-buildx-plugin` パッケージをインストールせよと。

Linux Mint だけど、Rootless で入れてるからパッケージマネージャで入れても反映されないような･･･。その下にある Manual download でやってみます。

:::note warn
マニュアルダウンロードの場合、自動アップデートされないため、テスト用途ならいいけど、プロダクション用途には推奨されない様子
:::

GitHub リポジトリの Releases からバイナリを入手します。

https://github.com/docker/buildx/releases

一般的な PC ならだいたい `buildx-vx.x.x.linux-amd64` で良いはず。

あとはこれを所定の場所に配置 (ファイル名は `docker-buildx` に)。これも README.md にある通り。実行権限の付与もお忘れなく。

```sh
mv <ダウンロードしたファイル> ~/.docker/cli-plugins/docker-buildx
chmod +x .docker/cli-plugins/docker-buildx
```

これで `docker buildx` が使えるようになるはず。

```sh
docker buildx

# Extended build capabilities with BuildKit
#
# Usage:  docker buildx [OPTIONS] COMMAND
#
# (以降オプション詳細など)
```

## おまけ: ビルドキャッシュの効能がわかりやすい

`buildx` で、適当な dockerfile をビルドしてみることにします。[自分の記事](https://qiita.com/aKuad/items/6f278607972463ee9c4f)で作った、Git インストール済み Debian の `dockerfile` で試します。

カレントに以下のような `dockerfile` を作成。

```dockerfile
FROM debian

RUN apt update
RUN apt install -y git
```

一旦ビルド。

```sh
docker build -t image-name .
```

イメージを削除し、ビルドし直してみてください。

```sh
docker rmi image-name
docker build -t image-name .
```

レガシーのビルドだと最初から律儀にビルドしてくれますが、`buildx` ではキャッシュのおかげで 2度目はすぐに完了します (するハズ)。
nginxでlocationディレクティブからのproxy_passが通らない


# 概要

おそらく基礎中の基礎なんだろうけどガッツリハマったので書く。
もともと`location /`のみ記載していたが特別な処理を行うためlocationディレクティブを追加した。`location /hoge/`
書き出した状態で`http://backend/hoge/`にアクセスすると404エラーになってしまった。
設定を全く同じにしても発生し`location /`のみに戻すとアクセスできるようになる。
原因がわからず数時間頭を抱えて色々試していたが分かれば単純な原因だった。

# 結論

実際は他にも色々設定を書いているが要点だけ絞って書く。

```nginx:通らない

    location /hoge/ {
        proxy_pass        http://backend/;
    }


    location / {
        proxy_pass        http://backend/;
    }

```

```nginx:通る

    location /hoge/ {
        proxy_pass        http://backend/hoge/;
    }


    location / {
        proxy_pass        http://backend/;
    }

```

proxy_passはlocationのパスを含めた値にしないといけないのね。
覚えておこう。
【プログラミング初心者】0から始めるReact学習 #8 ~Web開発の基本編~

# 1-3. 課題1
## 9月10日
本日からVScodeを使って課題に取り組もうと思っていたのですが、
StackBlitzを利用することにしました。

学習開始してから小一時間ほどVScodeを使ってコーディングしていたのですが、
ファイルを保存して「index.html」をリロードしても内容が全く更新されませんでした。
上記エラーがなぜ起きているのかChatGPTやReactの講義を見直して試行錯誤していたのですが、
結局解決しなかったためStackBlitzで課題に取り組むことにしました。
同じコードをStackBlitzに書いたところ、正常に反映されました。

考えられる原因として以下の2つを思いついたのですが、
~~~
・コードのどこかが間違っていてレンダリングが上手くいっていない
・Viteの使い方が分かっておらず、コードを実行できていない
~~~
今の私のレベルでは解決するに至らず、、
悔しいですが、進捗を優先したいのでVScodeでの開発は諦めることにします。

## まとめ

エラーを解決するために時間を掛けてしまったため、
見た目を作るところまでで本日は終了。

![mitame.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3877233/e5bd4736-4562-9643-40da-060860a62827.png)

明日からは、機能追加をしてみようと思います。
プログラミング言語 Sather

# はじめに
Eiffelについて調べるとよく見掛けるのがSatherという言葉です。 カリフォルニア州バークレイにある[ICSI(the International Computer Science Institute)](https://www.icsi.berkeley.edu/)でEiffelにならって作られたオブジェクト指向言語のようです。
ちなみにSatherというのはカリフォルニア大学バークレー校にある塔の名前です。Eiffelもエッフェル塔だからということだと思いますが、Eiffelの由来は実は塔ではなくて、エッフェル塔の設計者の名前[^Eiffel]だったと思います。

[^Eiffel]: 同一人物なんだから問題ないだろ、と言われれば、はい、その通りです。

# Sather（本家）
Eiffelに遅れること5年の1990年に誕生しました。Eiffelにならって作られたし、 Satherのページ[^page]には「CやC++やFortranのように効率がよく、Eiffelのように優雅で、Eiffelよりも 安全な言語を目指す」と書いてあったりするので、Eiffelよりも優れた言語なのかもしれません。

[^page]: https://www.icsi.berkeley.edu/~sather/ なのですが、2024年3月までは存在したようです。ですが、2024年5月の時点で"Not Found"になってます。

しかし、「Sather の将来」によると、1999年2月2日時点で「ICSIでのSatherプロジェクトはもう動いていない」そうです。またcomp.lang.satherというニュースグループもありますが、記事はほとんど見掛けません。

# Sather-K
ドイツのカールスルーエ大学[^kit]でSather-K[^K]というSatherの方言がつくられ、こちらの方が長生きしたようです。 ただし、Former Projectsに分類されているので、こちらも本家と同じくもう終わったのでしょう[^kpages]。

[^kit]: カールスルーエ大学は現在カールスルーエ工科大学になっています。
[^K]: -KのKはカールスルーエ大学（Universität Karlsruhe）のKなのでしょうね。
[^kpages]: 大学の改組の影響を受けて、ここで言及しているページは見つからなくなっています。カールスルーエ工科大学のページを検索してみたら、Sather-Kを作った教授の追悼文が見つかりました。この教授はICSIに参加していたようですから、ICSIで自分の関わっていたSatherをカールスルーエ大学に持ってきたということなのでしょうね。

# GNU Sather
https://www.gnu.org/software/sather/

少なくとも1999年の5月までは上のような状況だったのですが、最近Satherのページを見たら「1.2のベータ版をGPL/LGPLに基づいて配布する」と書いてあって、さらに、[GNU Satherへのリンク](https://www.gnu.org/software/sather/)が ありました。「ICSI ではもう発展させるつもりはないが、興味のある方は自由に いじってください」ということなのでしょう。 そういうことなのでSatherに興味のある方は[GNU Sather のページ](https://www.gnu.org/software/sather/)を見てください。 GNU Sather の最新版は 1.2.3 です(2007年7月7日に更新されています)。 また、1.3のβ7というのもあるようですが、こちらは最終更新が2001年の3月14日です。

# おことわり
この文章の内容は、筆者が所属している会社・団体とは一切関わりがありません。いわゆる「自主的な研究の成果の発表」というものです。
あと、文中に「『最近』とかあるのに全然最近ではない」というのは[Eiffelについて書いた記事](https://qiita.com/koizumistr/items/29d1bb574bce8627c796)と同じように10年近く以前に自分のページに書いていたものを引っ張り出してきたからです。さらに、Eiffelと違って、そこまで必死になる理由もないので、引っ張り出したものほぼそのままです。

# おまけ
こんな記事を書いておきながら何なのですが、私はSather・Sather-K・GNU Satherを使ったことがありません。最初に書いた通り、「Eiffelについて調べるとよく見掛けるのがSatherという言葉で」気になったから調べてまとめてみた、と言うだけです。
Eiffelよりも後発で、「Eiffelには足りない部分があるから自分で新しい言語を作った」ということらしいので、Eiffelよりも優れているかもしれません。ただ、上に書いた中で一番新しい[GNU Sather](#gnu-sather)ですら、盛り上がっているとはちょっと言えない状況[^pgeif]ですので、「Satherを使ってみましょう」とは言えません。仕事で周囲が使っているのなら、選択肢はないと思いますけど、そもそも「仕事で周囲が使っている」という状況もねぇ、、、[^qiita]

[^pgeif]: 大学や研究機関に由来し、その後紆余曲折があったという点では、PostgreSQLやLiberty Eiffelも似たような感じのものです。が、Satherの状況を見ると、Liberty Eiffelは大したものだし、PostgreSQLなんてもの凄く大したものなのだな、と思います。
[^qiita]: QiitaでSatherを検索してみてください。検索で見つかる数は（決して多いとは言えない）Eiffelよりも少ないです。
Windowsにおけるクラッシュダンプの解析

<!-- Windowsにおけるクラッシュダンプの解析 -->

Windowsを使っていると、突然ブルースクリーンになってしまうことがあります。

画面が青くなり、エラーメッセージが表示され、再起動を求められるのですが、時には再起動をしてもどうにもならず、何度もブルースクリーンが表示されることもあります。

こういうとき、エラーメッセージにある停止コードを調べたりして原因を調査することができます。以下のようなサイトが参考になります。

[【Windows 11/10】停止コード（STOPコード）の一覧と対処法](https://jp.minitool.com/backup-tips/windows-stopcode.html)

しかし、それだけでは抽象的で、具体的な原因がわからないことがあります。そういうとき、具体的にどこが原因でクラッシュしてしまったのかを調査する手段として、クラッシュダンプを解析するという方法があります。

## クラッシュダンプとは

簡単に言うと、Windowsがクラッシュしたときに作成されるログファイルです。クラッシュしたときの状況や、原因となったプロセスやドライバなどの情報が記録されています。

というわけで、このダンプファイルを解析していくこととします。

## 想定環境

- Windows 10-11

## WinDbg

まずは解析ツールとしてWinDbgをインストールします。

[Windows SDK - Windows アプリ開発 | Microsoft Developer](https://developer.microsoft.com/ja-jp/windows/downloads/windows-sdk/)

このサイトからWindows SDKのインストーラをダウンロードしてインストールします。

インストーラを起動すると、たくさんの機能が表示されますが、今回はデバッグツールが欲しいので、「Debugging Tools for Windows」だけチェックを入れればOKです。

インストーラを続行させると、インストールが完了します。

## 具体的な使い方

ここからは、実際にWinDbgを使っていきます。

クラッシュダンプを見るには管理者権限が必要なので、WinDbgを管理者権限で起動します。

X86とX64がありますが、PCが64bitなら後者を使ったほうが良いとされています。

また、以下のサイトにもありますが、今回はARMではなくX64を使うほうがよいでしょう。

[ARMとx86の違い #ARM - Qiita](https://qiita.com/mamaru/items/2fccdc8ddfa01481c04a)

WinDbgを起動し、左上のほうにある「File」から「Open Crash Dump」を選択します。

すると、クラッシュダンプファイルを選択するダイアログが表示されるので、クラッシュダンプファイルを選択します。名前は「MEMORY.DMP」などが一般的です。場所は「C:/Windows/」です。

選択すると、クラッシュダンプファイルが読み込まれ、解析が始まります。

```
Loading Dump File [C:\Windows\MEMORY.DMP]
(中略)
Loading User Symbols

Loading unloaded module list
......
For analysis of this file, run !analyze -v
```

読み込めたら、青色に表示されている```! analyze -v```をクリックします。そうすると、詳細な解析が行われ、さらにさまざまな情報が表示されます。

```
4: kd> !analyze -v
*******************************************************************************
*                                                                             *
*                        Bugcheck Analysis                                    *
*                                                                             *
*******************************************************************************

DPC_WATCHDOG_VIOLATION (133)
(中略)
SYMBOL_NAME:  rtwlanu+395790

MODULE_NAME: rtwlanu

IMAGE_NAME:  rtwlanu.sys
(後略)
```

このように、クラッシュダンプファイルの解析が行われ、どのようなエラーガ発生したのか、また原因となったモジュールの名前はなんなのか、ということなどが表示されます。

今回はrtwlanu.sysというモジュールが原因でクラッシュしていることがわかりました。これは外付けWi-Fi接続子機のドライバでした。該当する機器のドライバをアップデートしたことによって、クラッシュは解消されました。

## まとめ

これで、クラッシュダンプの解析ができるようになりました。Windowsがクラッシュし、原因がわからない時はこうした手法を使ってみることが有効な解決策となりえます。

特に、原因となったモジュール名がわかると、それを検索にかけることで有効な情報を得ることができるかもしれないです。

Windowsがクラッシュしてしまったとき、こういった手法を使ってみることをおすすめします。

## 参考

[WinDbg をインストールしてとりあえず使えるところまで設定する方法 #Windows - Qiita](https://qiita.com/tokawa-ms/items/62625c7acc263185f530)
YAMAHAルータのカスタムGUIを利用して、独自設定の初期化を行う

<img src="https://img.shields.io/badge/YAMAHA-RTX-blue">

## はじめに

特定の設定を入れてヤマハルータを提供することを想定しています。このような納品の場合、以下のようなニーズが生じることがあります：

- カスタマイズされた納品時の設定に戻したい
- 1週間前のデータに戻したい

これらの操作をコマンドラインが不得手な人でも簡単に行えるよう、CustomGUIを使用して実現する方法を紹介します。


## 検証環境

- 機種: RTX1300
- ファームウェア: Rev.23.00.13


## 通常の方法での制限

CustomGUIからは以下のコマンドを直接実行することができません。

- `copy config` コマンド
- `load` コマンド
- `execute batch` コマンド
- Luaの`rt.command`を使用した上記コマンドの実行


## 解決方法

初期化用のコンフィグを用意し、そこで全ての操作を行う方法を採用します。

### 処理フロー

```mermaid
graph TB
  Start[初期化ボタン押下]
  -->B1[初期化専用設定で再起動]
  -->B2[スタートアップで初期化]
  -->B3[復元された設定で起動]
```


### コンフィグの構成
以下の3つのコンフィグを用意します。

- 0番: 通常利用のコンフィグ
- 3番: 初期値とするコンフィグ
- 4番: 初期化処理のコンフィグ

### 0番コンフィグで初期化開始

CustomGUIで初期化ボタンを作成し、以下のコマンドを実行するように設定します。

```
restart 0 4
```

### 4番コンフィグの内容

```
schedule at 1 startup * copy config 3 0
schedule at 2 startup * restart 0 0
```
この設定により、起動時に3番のコンフィグを0番にコピーし、その後0番で再起動します。



CustomGUIについてはこちらもどうぞ。

https://qiita.com/yshimizu/items/6071ee2f20f1f03c7143

## まとめ

この方法を使用することで、コマンドラインに不慣れなユーザーでも簡単に設定を基準点に戻すことができるようになります。

## 参考
カスタムGUI: [http://www.rtpro.yamaha.co.jp/RT/docs/custom-gui/](http://www.rtpro.yamaha.co.jp/RT/docs/custom-gui/)
Luaスクリプト機能: [http://www.rtpro.yamaha.co.jp/RT/docs/lua/tutorial/](http://www.rtpro.yamaha.co.jp/RT/docs/lua/tutorial/)
HPLT Bert for Japaneseは「酸素ボンベを充[MASK]する。」の[MASK]に何を埋めてくるのか

[昨日の記事](https://qiita.com/KoichiYasuoka/items/885e79090cf52dee012c)の続きだが、日本語LTG-BERTモデル「[HPLT Bert for Japanese](https://huggingface.co/HPLT/hplt_bert_base_ja)」で「酸素ボンベを充[MASK]する。」の[MASK]に穴埋めさせてみた。Google Colaboratoryだと、こんな感じ。

```
!pip install 'transformers<4.40'
import torch
from transformers import AutoTokenizer,AutoModelForMaskedLM
tokenizer=AutoTokenizer.from_pretrained("HPLT/hplt_bert_base_ja")
model=AutoModelForMaskedLM.from_pretrained("HPLT/hplt_bert_base_ja",trust_remote_code=True)
ids=tokenizer("酸素ボンベを充[MASK]する。")["input_ids"]
print([tokenizer.decode(t) for t in ids])
mask=ids.index(tokenizer.mask_token_id)
with torch.no_grad():
  outputs=model(torch.tensor([ids]))
  pred=outputs[0][0,mask].topk(5)
for i,t in enumerate(pred.indices):
  ids[mask]=t
  print(i+1,[tokenizer.decode(t) for t in ids])
```

私(安岡孝一)の手元では、以下の結果が得られた。

> ['[CLS]', '酸', '素', 'ボン', 'ベ', 'を', '充', '[MASK]', 'する', '。', '[SEP]']
> 1 ['[CLS]', '酸', '素', 'ボン', 'ベ', 'を', '充', '填', 'する', '。', '[SEP]']
> 2 ['[CLS]', '酸', '素', 'ボン', 'ベ', 'を', '充', '電', 'する', '。', '[SEP]']
> 3 ['[CLS]', '酸', '素', 'ボン', 'ベ', 'を', '充', '実', 'する', '。', '[SEP]']
> 4 ['[CLS]', '酸', '素', 'ボン', 'ベ', 'を', '充', '充', 'する', '。', '[SEP]']
> 5 ['[CLS]', '酸', '素', 'ボン', 'ベ', 'を', '充', '続', 'する', '。', '[SEP]']

一発目に「填」を埋めてきているのは、かなり強い。そこそこ高い精度が期待できるのだけど、さて、ファインチューニングがうまくいくかな。
AtCoder 勉強記録[C++] その63

AtCoderで入茶を目指して勉強しています。
勉強を継続するために投稿を始めました。
もともとアカウントを作成していましたが、今年の4月から本格的に勉強を始めました。
一応自分用に解法を書いていますが雑です、自分で読み返して困ったら修正します。
[私のアカウント](https://atcoder.jp/users/nanami_brother)
[解いた問題](https://kenkoooo.com/atcoder/#/table/nanami_brother)
# 本日解いた問題
## C - Ladder Takahashi
[C - Ladder Takahashi](https://atcoder.jp/contests/abc277/tasks/abc277_c)
解答
```c++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using vec = vector<ll>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define mod 998244353

map<int, vector<int>> g;
set<int> seen;
void dfs(int v){
  seen.insert(v);
  for(auto nex:g[v]){
    if(seen.count(nex)) continue;
    dfs(nex);
  }
  
}

int main() {
  int n;
  cin >> n;
  for(int i = 0; i < n; i++){
    int a, b;
    cin >> a >> b;
    g[a].push_back(b);
    g[b].push_back(a);
  }
  dfs(1);
  cout << *seen.rbegin() << endl;
}
```
### 解法
問題のビルが`10^9`階建てであるため、全てを考えると計算量をオーバーしてしまう。ここで、はしごの数は`2*10^5`個であるため、はしごのかかった階のみを考えることで計算量を減らす。今回は`Map`型を用いることではしごのかかった階のみを考える。さらにDFSを用いることで結果がもとまる。
## C - FF
[C - FF](https://atcoder.jp/contests/abc278/tasks/abc278_c)
解答
```c++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using vec = vector<ll>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define mod 998244353

int main() {
  int n, q;
  cin >> n >> q;
  set<pair<int, int>> f;
  for(int i = 0; i < q; i++){
    int a, b, t;
    cin >> t >> a >> b;
    if(t == 1){
      f.emplace(a,b);
    } else if(t == 2) {
      f.erase({a,b});
    } else {
      if(f.count({a,b}) && f.count({b,a})) cout << "Yes" << endl;
      else cout << "No" << endl;
    }
  }
}
```
### 解法
AがBをフォローしている関係をpair型配列を用いて`(A,B)`と表す。この関係を管理するset型を用意しておき、`T=1`の場合は`(A,B)`を追加、`T=2`の場合は`(A,B)`を削除、`T=3`の場合は`(A,B)`、`(B,A)`ともに存在する場合`Yes`を、存在しない場合`No`を出力する。
気がつくとHuggingFaceスペースがエラー

今回はPydantic-core bugとgradioが原因みたい。

gradioを最新にしたら落ち着いた。後で、requiresをバージョン指定しておこう。

```
pydantic.errors.PydanticSchemaGenerationError: Unable to generate pydantic-core schema for <class 'starlette.requests.Request'>. Set `arbitrary_types_allowed=True` in the model_config to ignore this error or implement `__get_pydantic_core_schema__` on your type to fully support it.

If you got this error by calling handler(<some type>) within `__get_pydantic_core_schema__` then you likely need to call `handler.generate_schema(<some type>)` since we do not call `__get_pydantic_core_schema__` on `<some type>` otherwise to avoid infinite recursion.
```
進数変換を使って数学パズルを解く


## はじめに
基本情報技術者試験でよく登場する進数変換があります。「プログラマ脳を鍛える数学パズル」という本より自分の復習も合わせて、10進数、2進数、8進数全てで回文数となる最小の数を探すという問題に挑戦をしてみたいと思います。基本情報技術者試験で求められる進数に触れつつ、具体的な問題解決手法をJavaScriptで実装しながら詳しく解説していきます。

## 進数の基本
- **10進数**：日常生活で最も使用される数制で、0から9までの数字を使用します
- **2進数**：コンピュータの基本言語として用いられ、0と1のみで数を表現します
- **8進数**：主にコンピュータの権限設定などに使用され、0から7までの数字を用います

## 問題の理解とアプローチ
**Q:** 10進数、2進数、8進数いずれで表現しても回文数となる数のうち10進数の10以上で最小の値を求めてください。
まず回文数とは、「トマト」のように、どちらから読んでも同じになる特性を持つ言葉や数字のことです。たとえば、10進数では「101」がそれに該当します。今回は10進数、2進数、そして8進数すべてで回文数となる共通の最小数を見つけることが目標です。では具体的なステップを考えてみたのでこの通りに進めて行こうと思います。

### ステップ1: 初期値の設定
数の探索を始める最初の値を設定します。10進数で「11」から始めようと考えました。これは、10進数で最初の二桁の回文数であること、2進数の場合1番右の値が0になると「010」のように存在しない数となってしまうことより、問題文は10以上でとなっていますが、「10」を抜いて考えることにします。

### ステップ2: 進数変換
選定した数を異なる進数に変換します。
- **10進数**：数をそのまま使用。
- **2進数**：数を2の基底で表現（`num.toString(2)`を使用）。
- **8進数**：数を8の基底で表現（`num.toString(8)`を使用）。

### ステップ3: 回文チェック
変換した各進数の数が回文であるかどうかをチェックします。回文チェックには、変換された数を文字列にし、その文字列を反転させて元の文字列と比較します（JavaScriptを使用するので`str === str.split('').reverse().join('')`を使用）。

### ステップ4: 条件の評価
全ての進数で数が回文であるかを確認します。一つでも条件を満たさない場合は、次の数に戻り、再びステップ2から開始します。

### ステップ5: 繰り返しと結果の出力
条件を満たす数が見つかるまで、ステップ2から4を繰り返します。条件を満たす最初の数が見つかったら、その数を結果として出力します。

## アルゴリズムの説明
数の生成：11からスタートし、各数について検証を行います。
回文チェック関数：与えられた数を10進数、2進数、8進数に変換し、それぞれが回文であるかをチェックします。
全条件の確認：すべての進数で回文であることを確認した最初の数が答えです。

## JavaScriptコード
```javascript
const isPalindrome = str => str === str.split('').reverse().join('');

const findSmallestPalindrome = () => {
    let num = 11;
    while (true) {
        const decimal = num.toString();
        const binary = num.toString(2);
        const octal = num.toString(8);

        if (isPalindrome(decimal) && isPalindrome(binary) && isPalindrome(octal)) {
            return num;
        }
        num++;
    }
};

console.log(findSmallestPalindrome());
```

## まとめ
進数変換をプログラムする機会はあまりないですよね。数学パズルを通して私自身も進数変換の考え方を復習できたかなと思います。JavaScriptを今回は使用しましたが、他の言語で考えてみることも問題を解決する方法を学ぶという意味で効果的です。進数変換の考え方は基本情報技術者試験に役立つかと思います。プログラミングスキルも向上させるためにも考え方を学んでいきたいです。
## 参考文献および推薦サイト
MDN Web Docs（toStringメソッド）
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/toString
プログラマ脳を鍛える数学パズル シンプルで高速なコードが書けるようになる70問/著者　増井 敏克

## 採用拡大中！
アシストエンジニアリングでは一緒に働くフロントエンド、バックエンドのエンジニア仲間を大募集しています！
少しでも興味ある方は、カジュアル面談からでもぜひお気軽にお話ししましょう！
お問い合わせはこちらから↓
[https://official.assisteng.co.jp/contact/](https://official.assisteng.co.jp/contact/)
複数ファイルをコード修正プロンプトに入れるのを少し楽する小技

# 前提

複数ファイルを同時編集できるAIエディタが登場しています。しかし、有償プロダクトの利用を増やしたくない方もいるでしょう。ChatGPTやLLM既に契約・所有しており、それらを有効活用したいと考えている方向けの話です。複数ファイルを同時に修正するには、以下のように複数のファイルを含んだプロンプト作成することが求められます。このプロンプト作りを少し楽にする小技です。

**プロンプトのイメージ**

![スクリーンショット 2024-09-13 21.07.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110482/96425bd2-91a7-f7ed-1704-9e2cb2b8ba77.png)

# 結論:ファイルパスを渡せばファイルの中身を転記してくれるスニペットを持っておくと楽

ファイルパスの部分を変更し、zsh (インタラクティブシェル)で実行すれば、プロンプトがクリップボードにコピーされます。


**スニペット:**

```zsh
python3 - <<'EOF' | pbcopy
print("""
<既存のコード> に対して以下の変更を加えた結果を出力してください。
出力する際に省略しないことを心がけてください。
- hogeな機能を追加する
- fugaな機能を追加する
""")
dist_file_paths : str = """
path/to/file1 path/to/file2
path/to/file3
"""
def get_language_from_extension(file_path):
    extension_to_language = {
        ".py": "python",
        ".ts": "typescript",
        ".tsx": "tsx",
        # 他の拡張子と言語のマッピングが必要な場合、ここに追加
    }
    for ext, lang in extension_to_language.items():
        if file_path.endswith(ext):
            return lang
    return None
def print_file_contents(file_paths):
    sorted_file_paths = sorted(file_paths)
    print("<既存のコード>")
    for path in sorted_file_paths:
        try:
            with open(path, 'r') as file:
                content = file.read()
            language = get_language_from_extension(path)
            print(f"\n# {path}\n")
            if language:
                print(f"```{language}")  # コードブロックの言語を指定
            else:
                print("```")  # 言語指定がない場合のデフォルト
            print(f"{content}\n")
            print("```\n")
        except Exception:
            print(f"Error reading {path} \n")
    print("</既存のコード>")
print_file_contents(dist_file_paths.split())
EOF
```

zsh、pbcopy、python、プロンプトはお好みの環境に合わせてください。
コマンド化までせずスニペットとして、取り出しやすいところに持っておくのが丁度良いです。
Python3 エンジニア認定基礎試験 合格体験記

# 初めに
Python3 エンジニア認定基礎試験に受かりました。
前回のAWS SAAを受験してから大体10日ほどでの合格になります。
受験経緯としてはPythonを触れてみたいなと思ったときに、せっかくなら資格でも取ってみようかなと思ったのがきっかけになります。ついでに資格手当ももらえるからですね。資格手当はとても偉大です。

# 試験の概要
受験料金：1万円（税別）　学割5千円（税別）
問題数：40問（すべて選択問題）
合格ライン：正答率70%
試験の詳細は下記になります。
[Python3エンジニア認定基礎試験](https://www.pythonic-exam.com/exam)

# 使用教材
* <b>ExamApp</b>
→知識の確認に使いました。初級、中級、上級とありますが中級まででも合格自体はできるかも。記録を見たら各5回ずつくらい解いてました。
<br>

* <b>DIVE INTO CODE</b>
→1週間無料体験があったので使いました。無料期間でやりきった感じがあったので無料期間中に解約しました。ｺﾞﾒﾝﾈ 
<br>

* <b>公式ドキュメント</b>
→一応2周くらい読みました。試験直前に覚えたことが間違っていないかを確認しました。
[公式ドキュメント](https://docs.python.org/ja/3.9/tutorial/)
<br>

* <b>PRIME STUDY</b>
→第3回まで1回ずつ解きました。試験の2日前頃にやりました。
<br>

* <b>Youtube</b>
→ [Python入門完全攻略](https://www.youtube.com/watch?si=Y99Q6ReNlcMpXNpX&v=W1cnEb8LwVU&feature=youtu.be)
一番最初にやりました。文だけ読んでも頭に入らないって人にはおすすめです。

# 試験に向けて行った勉強法
1.Youtubeでハンズオン学習

2.DIVE INTO CODEの資料を一通り読む

3.ExamAppを初級~中級解いていく

4.PRIME STUDY/ExamApp上級を一通り解いていく

といった流れでやりました。ひとまず手を動かしながら概要を頭に入れてから少しずつ詳細を詰めていくといった風に進めたのですが結局これが一番正解な気がします。
3.4に関しては問題が出た瞬間に答えがわかるところまでやった記憶があります。
分からないところはとにかく調べる。
コード問題も理解できなかったら実際に動かす方が理解できると思います。

# 試験結果
朝一で試験を受けました。結果というと合格しました。
点数は875点でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3863216/36fc73ec-1545-a3f6-dc82-a929a9ec9560.png)

# 受けてみての感想
試験の難易度自体は前述の通りExamAppの中級レベルくらいでした。時間も半分以上余ったので焦らずにしっかり問題を読むことが大事だと思います。この資格を取ったからと言ってPythonが自在に扱えるようになるというものではありませんが、自分の基礎力の向上には良いと思います。

# おわりに
ここまで読んでいただきありがとうございました。

試験自体の難易度が高くないので初めての試験でも挑戦しやすいかなと思いました。前回AWS SAAの資格を取ったので次はAWS SAPの資格にチャレンジしたいなと密かに思っています。
Web アプリに役立つ API

Webアプリケーションの開発において、API（Application Programming Interface）は非常に重要な役割を果たしています。APIを使用することで、開発者は他のサービスやデータと簡単に連携し、アプリの機能を大幅に強化することができます。本記事では、Webアプリケーションで役立つAPIについて紹介します。
![webp file api.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3885422/3bc4f63d-486f-1fda-2740-5833f32bcbe7.jpeg)

APIとは？
APIとは、異なるソフトウェア間でのデータのやり取りや機能の利用を可能にするインターフェースです。Webアプリケーションでは、例えば、外部サービスと連携するためにAPIがよく使用されます。これにより、開発者は自前で全ての機能を作る必要がなく、効率的な開発が可能になります。

APIの利点
APIを使用する利点は以下の通りです：

効率的な開発
他のサービスの機能を活用することで、コードの量を減らし、開発時間を短縮できます。

柔軟な機能追加
必要に応じてAPIを利用して新しい機能をアプリケーションに追加できます。

データのリアルタイムアクセス
APIを使えば、リアルタイムで外部データを取得することができ、アプリに常に最新の情報を提供できます。

よく使われるWebアプリ向けのAPI
Webアプリ開発で頻繁に使用されるAPIには、さまざまな種類があります。以下にそのいくつかを紹介します。

1. Google Maps API
Google Maps APIは、地図機能をWebアプリケーションに組み込むためのAPIです。ユーザーが地図上で場所を検索したり、道順を確認したり、カスタマイズした地図を表示することができます。

使用例
ruby:google_maps.rb
Copy code
# Google Maps APIの呼び出し例
puts '地図を表示します。'
Google Maps APIを使用することで、例えば、位置情報を使ったサービスやナビゲーション機能を持つアプリケーションを簡単に開発できます。

2. OpenWeatherMap API
天気情報を取得したい場合、OpenWeatherMap APIが便利です。このAPIを使うと、現在の天気、予報、その他の気象データを簡単に取得できます。

使用例
ruby:weather_api.rb
Copy code
# OpenWeatherMap APIの呼び出し例
puts '現在の天気を取得します。'
Webアプリで、天気情報を表示するダッシュボードや、天候に関連したサービスを提供することができます。

3. Firebase API
FirebaseはGoogleが提供するバックエンドサービスで、データベース、認証、クラウドメッセージングなどの機能をAPIを通じて提供します。これにより、リアルタイムデータベースを使ったチャットアプリや、ユーザー管理が簡単に行えます。

使用例
ruby:firebase_api.rb
Copy code
# Firebase APIの使用例
puts 'リアルタイムデータを保存します。'
Firebase APIを利用すると、リアルタイムでデータをやり取りするアプリケーションや、ユーザーの認証機能を持つWebアプリを簡単に構築できます。

4. Stripe API
オンライン決済機能が必要な場合、Stripe APIが役立ちます。Stripeは、シンプルで安全なオンライン決済サービスを提供しており、このAPIを利用することで、クレジットカード決済や定期支払いを簡単に導入することができます。

使用例
ruby:stripe_api.rb
Copy code
# Stripe APIの使用例
puts '支払い処理を開始します。'
Stripe APIを活用することで、安全かつスムーズなオンライン決済機能を備えたWebアプリケーションを構築できます。

APIの使い方
APIを使う際には、以下のポイントを押さえておくことが重要です。

APIキーの取得
多くのAPIは、使用するためにAPIキーを必要とします。これは開発者がAPIを正しく使用するために必要な識別情報です。API提供元のサイトで登録を行い、キーを取得します。

APIのドキュメントを読む
APIを利用する前に、提供されているドキュメントをしっかりと確認しましょう。APIごとに異なる仕様があり、エンドポイントやパラメーターの使い方などが記載されています。ドキュメントを読んで、APIの使い方や制限事項を理解しておくことが大切です。

リクエストの送信
APIを使うには、HTTPリクエストを送信します。リクエストには、エンドポイント、パラメーター、認証情報（APIキー）が含まれます。一般的に、GETリクエストでデータを取得し、POSTリクエストでデータを送信します。

リクエストの例
ruby:api_request.rb
Copy code
# APIリクエストの例
puts 'APIリクエストを送信します。'
APIからのレスポンスは、通常JSON形式で返されるため、適切にパースしてデータを扱います。

おすすめのAPIリソース
以下は、APIを学ぶのに役立つリソースです。

RapidAPI
多くのAPIを集めたプラットフォームで、さまざまなAPIを簡単に探索、使用できます。

Postman
APIをテストするためのツールです。APIのリクエストやレスポンスを簡単に確認できます。



め
APIを使うことで
、Webアプリケーションの機能を大幅に強化し、ユーザーに豊かな体験を提供できます。Google Maps APIやOpenWeatherMap API、Firebase API、Stripe APIなどは、その代表的な例です。APIの使い方や選び方を理解し、適切なAPIを活用することで、効率的な開発が可能となります。[Vocso](https://www.vocso.com/blog/essential-apis-for-enhancing-application-functionality/ "Vocso")  にア    クセスして、Web アプリ用の 50 以上の API を確認してください。

APIの利用は、現代のWeb開発において必須とも言えるスキルです。次回のプロジェクトで、ぜひAPIを活用してみてください。
アプリ開発時に英語のドキュメントはちゃんと読んだ方がよい話

最近、あるスマートフォン用アプリの案件を担当するようになりましたが、プッシュ通知が動かなくなるトラブルに遭遇しました。
この案件ではプッシュ通知の仕組みにGoogleのFirebase Cloud Messagingを使っています。

https://firebase.google.com/docs/cloud-messaging

プッシュ通知を送信する場合、Firebase Cloud MessagingのAPIを使いますが、このAPIは新しいAPIに移行し、2023年に古いAPIはサポート対象外となりました。
サポート対象外になったことはFirebaseのドキュメントを見ればわかるのですが、これは2024年8月時点で**英語版には掲載されていて、日本語版には掲載されていないです。**

問題のページはこちらです。
https://firebase.google.com/support/faq

このページのCloud Messagingの箇所について、英語版と日本語版で比べてみました。
英語版
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92424/bcdb3c1d-5e05-d835-978c-f97a419224f8.png)

日本語版
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92424/41cee87b-700b-070d-2db6-345c5fc4bbd4.png)

英語版には **FCM features deprecated in June 2023** の項目があり、サポート終了となるAPIを使っている開発者向けに今後どうすればよいかが記載されています。ところが日本語版にはFCM features deprecated in June 2023に相当する項目はありません。

また、APIの移行についての説明も違いがあります。
https://firebase.google.com/docs/cloud-messaging/migrate-v1

英語版
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92424/c1b212c0-b50c-f570-27a5-f270ac53cb16.png)

日本語版
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92424/078dedf3-39b3-9cdb-bc19-f7dd4019ef4f.png)

英語版には古いAPIは2024年7月22日に停止すると記載がありますが、日本語版にはそういった記載はありません。
以下の記述が日本語版にはありません。
>  Sending messages (including upstream messages) with those APIs was deprecated on June 20, 2023, and shutdown begins on July 22, 2024.

つまり、**日本語版のドキュメントだけ読んでいると古いAPIのサポートが終了となる重大な事実に気づけないのです。**

そして、スマートフォンアプリの開発担当者は日本語版のドキュメントしか見ておらず、APIがサポート切れになっていることに気づけず、プッシュ通知が送信されてないというトラブルを引き起こしてしまいました・・・
このトラブルを解消するにはプッシュ通知の実装を新しいAPIに変える必要があります。すぐには変えられないので障害の長期化、顧客への謝罪、再発防止策の検討など大変なことになりました。

:::note warn
個人的な感覚ですが、海外ベンダーのドキュメントは英語版が最新だと思っております。**安易に日本語版のドキュメントに頼るのではなく英語版のドキュメントを読んで開発した方がよいということです。**
:::
Macのおすすめセットアップ

## 背景
会社から支給されたPCをセットアップする必要があり、今後も同様の操作を行うことが想定されるため、私のMacの設定を紹介します。


## 本記事の対象
- Macのセットアップ予定の人
- 現在Macを使用しているが、もっと生産性を上げたい人


## アプリのインストール

アプリケーションの管理のためにHomeBrewを導入します

### Homebrewのインストール
- ターミナルで以下のコマンドを実行

コマンド
`/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"`

参考URL: 
- https://brew.sh/ja/


## ツール系

### Raycast
アプリケーションの起動やファイルの検索、Windowの位置の設定などをキーボードのみで実行出来るツール

コマンド
`brew install --cask raycast`

参考URL: 
- https://formulae.brew.sh/cask/raycast

### Karabiner-elements
オリジナルのコマンドを設定出来るツール


例: `cmd+y`を押したら`cmd+shift+z`を実行する
以前Windowsを使用しておりctrl+yを多用していたため、このようなコマンドを設定出来るのは非常に便利です。

コマンド
`brew install --cask karabiner-elements`

参考URL:
- https://formulae.brew.sh/cask/karabiner-elements


### AltTab
Macの標準の機能でcmd+Tabを実行すると、Windowを切り替えることが出来ますが、同一のアプリケーションでWindowが複数ある場合には1つにまとめられてしまいます。Chrome等のブラウザを複数Windowで作業している際に非常に便利です。

コマンド:
`brew install --cask alt-tab`

参考URL:
- https://formulae.brew.sh/cask/alt-tab


## 細かい設定

### Google日本語変換

Macの標準の変換だと勝手に変換をされたり、思うような変換にならないということが多々あり、非常にストレスでした。Googleの変換を導入してからこういったストレスから開放されました

コマンド:
`brew install --cask google-japanese-ime`

参考URL:
- https://formulae.brew.sh/cask/google-japanese-ime

注): Google日本語変換の設定で日本語に設定する際、詰まったところがあります。以下の文献を参考にしたら解決出来ると思います。

- https://www.karakaram.com/deleting-alphanumeric-input-sources-on-macos-bigsur/


### バッテリー

私が普段使用しているディスプレイが給電と映像の同時出力であるため、常に給電されてしまっています。
Batteryを使用すれば、80%以上になったら給電しないという設定が出来ます。
注)Macでは内部で給電を自動で管理しているためこのようなアプリを使用することでバッテリーが長持ちするかどうかはわからないです。


**2024/09/13時点でのバッテリーの状態**
![スクリーンショット 2024-09-14 13.30.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3767231/3d523d2f-b35e-bb9b-b200-5bd54aff7ff8.png)

半年間日常的に使用しても、バッテリーの最大容量は100%のままです。
こちらについてはまた時が経ったときに確認してみたいと思います。

コマンド
`brew install --cask battery`

参考URL:
- https://formulae.brew.sh/cask/battery


### おわりに
Macのセットアップには時間が毎回かかるので、今後自分でも見返すために本記事を書かせていただきました。エンジニアの方でなくても、生産性が非常に上がると思います。良かったら参考にしてみてください!
AWSアカウントへのスイッチロール（初心者向け）

AWSアカウントへのスイッチロールについてまとめてみたので紹介したいと思います。

対象者：初心者
書いてある内容：基本的な概要と考え方
書いていない内容：具体的なロールの実装方法

## そもそもスイッチロールとは
スイッチロールはIAM機能の一部であり、ユーザーが一時的に別のAWSアカウントの権限を引き受けることを可能にする仕組みです。この機能を使用すると、ユーザーは自身のIAMユーザーまたはロールの権限を維持したまま、異なるAWSアカウント内で定義された別のIAMロールに切り替え、スイッチロール先のアカウントの操作をすることができます。

## IAMRoleの重要な考え方
1. ユーザーに必要最小限の権限のみを付与する。スイッチロールはロールごとに細かく権限を定義することが可能です。ユーザーは必要な時に必要な権限を持つロールに切り替えることで、常に必要最小限の権限でのみ操作を行うことができます。これにより、誤操作や不正アクセスのリスクを大幅に低減させることができます。
1. 長期的な認証情報の使用を避け、短期的で失効する認証情報を使用します。スイッチロールを使用すると、ユーザーは一時的な認証情報を取得します。この認証情報は通常、設定された時間が経過すると自動的に失効します。
1. アカウント間で信頼関係を確立し、特定の操作を委任することで、中央集権的な管理と分散的な運用を両立させています。この原則により、組織全体のセキュリティポリシーを維持しながら、各部門や環境に必要な柔軟性を提供することが可能になります。
1. スイッチロールの使用は全て記録され、後から監査することができます。これにより、誰がいつどのようなアクセスを行ったかを追跡し、セキュリティインシデントの調査や法令順守の確認に役立てることができます。

## 仕組み
スイッチロールのプロセスでは、ユーザーは一時的な認証情報を取得し、それを使用して特定の期間、別のアカウントのリソースにアクセスします。この一時的な認証情報は、ロールに関連付けられたポリシーによって定義された権限を持ち、通常、設定された時間が経過すると自動的に失効します。重要なのは、スイッチロールによって付与される権限が、そのロールに明示的に定義された権限に厳密に制限されることです。


## 実装
スイッチロールを実装するには、アクセス元のアカウント（信頼するアカウント）とアクセス先のアカウント（信頼されるアカウント）の間に信頼関係を確立する必要があります。この信頼関係は、どのIAMユーザーまたはロールがスイッチロールを実行できるかを指定し、セキュリティを確保します。また、多要素認証（MFA）を要求するなど、追加のセキュリティ層を実装することも可能です。
スイッチロールは、大規模な組織、マルチ環境開発シナリオ、クラウドサービスプロバイダー、セキュリティ監査、コスト管理、災害復旧計画など、様々な状況で有用です。この機能により、組織は必要最小限の権限の原則を適用しつつ、効率的なアクセス管理を実現し、セキュリティとコンプライアンスを強化することができます。


## ユースケース
大規模な企業では、開発、テスト、本番という複数の環境を別々のAWSアカウントで管理していると想定します。本番環境へのアクセスは特に厳重に管理するのが通常です。従業員は開発環境で作業していますが、本番環境でのトラブルシューティングや緊急のデプロイメントが必要になります。ここでスイッチロールが活躍します。
Aさんには、本番環境のAWSアカウントに「緊急対応ロール」が設定されています。このロールには、特定のEC2インスタンスへのアクセス、ログの閲覧、特定のS3バケットへの読み取り権限が付与されていますが、新しいリソースの作成や既存リソースの削除権限は与えられていません。
本番環境で重大な問題が発生したとします。Aさんは自身の開発環境のIAMユーザーアカウントを使用してAWSコンソールにログインし、そこからスイッチロール機能を使って本番環境の「緊急対応ロール」に切り替えます。この操作には多要素認証（MFA）が要求され、追加のセキュリティ層が確保されます。
ロールを切り替えた後、Aさんは本番環境の特定のEC2インスタンスにアクセスし、ログを確認し、問題の原因を特定します。しかし、このロールではインスタンスの停止や再起動はできないよう制限されているため、必要に応じて別の承認プロセスを経る必要があります。
また、このスイッチロールの使用は全て記録され、後で監査チームが確認できるようになっています。さらに、このロールの認証情報は2時間後に自動的に失効するよう設定されており、長時間のアクセスによるリスクを軽減しています。
このユースケースでは、スイッチロールを使用することで、Aさんは必要な時に必要な権限だけを持って本番環境にアクセスし、問題の対応が可能となります。
【AtCoder】setやmapを使う際の注意点

## ポイント
- lower_boundについて、vectorに対してはstd::lower_boundを使い、set/mapに対してはstd::set::lower_bound/std:: map::lower_boundを使う
- std::distanceは、vectorに対して使う場合はO(1)であるが、setやmapに対して使う場合はO(N)になってしまうので注意

## 例題
[ABC213C - Reorder Cards](https://atcoder.jp/contests/abc213/tasks/abc213_c)

```C++
#include <bits/stdc++.h>
using namespace std;
using P = pair<int, int>;
#define all(a) (a).begin(), (a).end()

int main() {
  int H, W, N; cin >> H >> W >> N;
  set<int> tmpr, tmpc;
  vector<P> A(N);
  for (int i = 0; i < N; ++i) {
    int x, y; cin >> x >> y;
    x--; y--;
    tmpr.insert(x);
    tmpc.insert(y);
    A[i] = P(x, y);
  }
  
  // setをvectorに変換
  vector<int> row(all(tmpr)), col(all(tmpc));
  for (auto [x, y] : A) {
    int r = distance(row.begin(), lower_bound(all(row), x));
    int c = distance(col.begin(), lower_bound(all(col), y));
    printf("%d %d\n", r+1, c+1);
  }
}
```
「GithubActions」ビルド時に環境変数を渡した際に「Uncaught Error: supabaseUrl is required.」というエラーが発生するときの解決法

## この記事を書こうと考えた背景について
* GithubActionsを使用してfirebaseでデプロイをするときに今までデプロイ時に環境変数を渡していました。
⇒デプロイは成功していました。
しかしビルド時に環境変数を読み込むように変更しようとして画面が表示されなくなり苦戦したため記事にまとめようと考えました。

# 原因
* デプロイ時に環境変数を渡していなかったため
⇒ビルドとデプロイは違う場所で行われている為再度デプロイをするときに環境変数を渡す必要がある
⇒ビルドとデプロイ時の両方で環境変数を読み込む記述をしている必要がある。

# エラーが発生する原因になっている箇所
* ビルド時にしか環境変数を読み込んでいない
```.yml
jobs:
  build:
    name: build
    runs-on: ubuntu-latest
    steps: 
        - name: Checkout code
          uses: actions/checkout@v4
        - name: Setup Node.js
          uses: actions/setup-node@v4
          with:
            node-version: "20"
        - name: Install dependencies
          run: npm install
        - name: Run build
          run: |
            npm run build
          env:
            VITE_SUPABASE_URL: ${{ secrets.VITE_SUPABASE_URL }}
            VITE_SUPABASE_ANON_KEY: ${{ secrets.VITE_SUPABASE_ANON_KEY }}
```
```.yml
- name: Deploy to Firebase Hosting
        run: |
          ./node_modules/.bin/firebase deploy
        env:
          FIREBASE_CLI_EXPERIMENTS: webframeworks
      - name: delete GOOGLE_APPLICATION_CREDENTIAL
        run: export -n $GOOGLE_APPLICATION_CREDENTIAL
        if: ${{ always() }}

```
# 解決方法
* ビルドとデプロイ時の両方に環境変数を読み込む記述をした
```.yml
jobs:
  build:
    name: build
    runs-on: ubuntu-latest
    steps: 
        - name: Checkout code
          uses: actions/checkout@v4
        - name: Setup Node.js
          uses: actions/setup-node@v4
          with:
            node-version: "20"
        - name: Install dependencies
          run: npm install
        - name: Run build
          run: |
            npm run build
          env:
            VITE_SUPABASE_URL: ${{ secrets.VITE_SUPABASE_URL }}
            VITE_SUPABASE_ANON_KEY: ${{ secrets.VITE_SUPABASE_ANON_KEY }}
```
* 下記の.は途中で省略の為記述しました。
```.yml
      - name: Install firebase-tools
        run: npm install --save-dev firebase-tools
      - name: Webframework Enable
        run: ./node_modules/.bin/firebase experiments:enable webframeworks
                ．
                ．
                ．
      - name: Deploy to Firebase Hosting
        run: |
          ./node_modules/.bin/firebase deploy
        env:
            VITE_SUPABASE_URL: ${{ secrets.VITE_SUPABASE_URL }}
            VITE_SUPABASE_ANON_KEY: ${{ secrets.VITE_SUPABASE_ANON_KEY }}
      - name: delete GOOGLE_APPLICATION_CREDENTIAL
        run: export -n $GOOGLE_APPLICATION_CREDENTIAL
        if: ${{ always() }}
```
【GitHub】GitHubログインでの認証を取り消す・organizationsのリポジトリをAPIから読み取る

# はじめに
EnvHub用のドキュメントです。
一度GitHubアカウントでログインした後に認証を取り消す方法について記載しています。

# 認証の取り消し方
**1.** [GitHub OAuth Settings](https://github.com/settings/applications) に**アクセス**する。
**2.** 三点リーダーをクリックし、**Revoke**をクリックする。![github-oauth-revoke.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/af43664c-b905-d9af-71c0-f191689a4880.png)

# organizationsのリポジトリをEnvHubから読み込む方法
・GitHubの認証画面で共有したいorganizationsの`grant`ボタン **(赤枠部分)** をクリックする。
・**共有**されている状態なら、**青枠部分**のチェックが付きます。
![github-oauth-grant.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/6da6116e-ba9d-f1e8-6277-f926c01d820e.png)
エンジニアを説得する技術

# 😍 エンジニア心理学

https://qiita.com/minegishirei_v2/items/49784ea87ba160ef8065

## 対象者

- 同僚のパーソナリティを理解しようとするエンジニア
- 同僚の一時的な感情を理解しようとするエンジニア
- 信頼関係を構築したいエンジニア
- 同僚に動いてもらえる確率を少しでもあげたいエンジニア

## 🏁 目標

この記事はエンジニアを説得し、前向きに動いてもらう方法を模索する試みです。


## 参考

<img src="https://hondana-image.s3.amazonaws.com/book/image/10031203/normal_5d3d658e-9c48-4c6f-978c-50ce962d448d.jpg">

[コミュニケーションの社会心理学](https://www.nakanishiya.co.jp/book/b10031203.html)


# 影響コミュニケーションとは

気軽な頼み事から相手の考えを変えようとする説得まで、他者に働きかけるコミュニケーションを
「影響コミュニケーション」と呼べる。

- 「影響の与え手（influence target）」は「受け手（influence target）」に働きかけるようメッセージの作り方に関心をもつ
- 受け手としては、不当に与え手から影響を受けないような防衛策に関心を持つようになる。

そして、受け手の行動や態度を変化を生じさせることを総称して「影響（influence）」と呼んでいる。

説得研究は 「ホヴランド」 によって始められたと考えられ、説得を受けた受け手の反応に影響を及ぼすと考えられる要因は、
オキーフ（1990）が4つに分類している。
それは、**送り手**、**説得的コミュニケーション**、**状況**、**受け手** で、詳細は以下の通り。

1. 送り手
    - 専門性
    - 信頼性
    - 好感度
2. 説得的コミュニケーション
    - 結論の明治の有無
    - 一面提示と両面提示
    - 論拠の提示順序、フレーミング
    - 恐怖喚起、ユーモア
    - ストーリー仕立て
3. 状況要因
    - メディア（文字、音声、動画など）
    - 妨害要因（騒音、蒸し暑さなど）
    - 説得の予告
4. 受け手
    - 心理的リアクタンス
    - 自尊心、知能、認知要求支援
    - 説得テーマへの字が関与度
    - メッセージ検査への動機づけ・能力
    - 事前・事後感度の確信度
    - （送り手との）対人関係


# 🤔 「結論を明示する」は大きな説得効果はない

結論を明示することの効果量は(r=.12)(範囲は0.00~1.0)という程度であり、
結論を明示しないよりは、明示したほうがやや説得効果が大きくなるという程度であった。

確かに、送り手として、説得の結論（受け手にとって欲しい行動）は明示した方がよいと考えられるが、
これは「相手の心理的リアクタンス」を喚起する可能性も考えられる。

**「結論を明示するかどうか」は状況によると考えて良い。**


# 😀 「両面提示」+「反論を促す」+「それを反芻」は効果がある。

- 送り手の主張を支持する根拠のみを提示することを、一面提示という
    - メリット : 受け手の反論を促す可能性は低い
- 反対に、送り手の主張に不利な要素も合わせて提示することを、両面提示という
    - メリット : 「公平な立場から説得している」と受け手に捉えられやすい

さらに、両面提示の不利な要素に対して反論することを、反芻という。

この「両面提示」+「反論を促す」+「それを反芻する」というセットは
説得的コミュニケーションほんの少し効果があるとされる。(r=.08)

**相手の知識量が自分より少ない** と判断し切れる場合は、一面提示でも問題ない。
例えば、十分な説明を不要とする顧客に対しては一面提示で十分と考えて良い。


# 😎 エンジニアを説得する技術

しかし、**エンジニア心理学** では説得する相手は顧客だけとは限らず、
技術的な決定を覆したいケースでは知識量が対等な相手がほとんどであろう。

私の「十分な知識量がある相手を説得するための戦略」は以下の通り。

1. 結論ファースト（理由は次の章より）
1. 一面提示を行う（メリットのみの説明）
2. 相手の反応をみて、疑念が出ている場合は「質問を誘導する」
3. 「確かに~」から始めて、両面提示に自然に移行させる（この「自然に」がポイント）
4. 反芻する

上記のように質問が出る場合は「自我関与度が高い状態」であるため、こちらも着目しておくこと。


## 準備中...
[翻訳] OpenAI o1-previewのご紹介

[Introducing OpenAI o1 \| OpenAI](https://openai.com/index/introducing-openai-o1-preview/)の翻訳です。

:::note warn
本書は著者が手動で翻訳したものであり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
:::

困難な問題を解決するための理由づけモデルの新たなシリーズ。9/12から利用可能に。

我々は、レスポンスする前により多くの時間を費やすように設計された、新たなAIモデルシリーズを開発しました。これらは、サイエンス、コーディング、数学において、以前のモデルよりも複雑なタスクを通じた理由づけを行い、より困難な問題を解決することができます。

本日、ChatGPTと我々のAPIにおいて、このシリーズの最初のモデルをリリースします。これはプレビューであり、定期的なアップデートと改善を行う予定です。このリリースに伴い、次回のアップデートでは現在開発中の[評価結果](https://openai.com/index/learning-to-reason-with-llms/)を含める予定です。

# 動作原理

我々は、人々が行うのと同じように、これらのモデルがレスポンスをする前に問題を通じて検討することにより時間を費やすようにトレーニングしました。トレーニングを通じて、検討のプロセスを改善するために学習を行い。異なる戦略を試し、自身の間違いを認識します。

我々のテストにおいては、次のモデルアップデートは、物理、化学、生化学における困難なベンチマークタスクにおけるPhD学生と同様のパフォーマンスを示すことになります。International Mathematics Olympiad (IMO)の資格試験において、GPT-4oは問題の13%のみを適切に回答できましたが、この理由づけモデルは83%のスコアを出しました。これらのコーディング能力はコンテストで評価され、Codeforcesのコンペティションで、89thパーセンタイルに到達しました。こちらの[技術的な研究記事](https://openai.com/index/learning-to-reason-with-llms/)でより詳細を読むことができます。

初期のモデルと同様に、このモデルは、ChatGPTを有用なものにした、情報取得のためにWebをブラウジングしたり、ファイルや画像のアップロードののような機能の多くはまだ実装していません。短期的には、多くの一般的なケースにおいては、GPT-4oの方が優れて能力を有していると言えます。

しかし、複雑な理由づけのタスクにおいては、これは大きな進歩であり、AIの能力の新たなレベルを表現しています。これによって、我々はカウントを1にリセットして、このシリーズをOpenAI o1と名付けています。

# 安全性

これらの新たなモデルの開発の一部として、これらの理由づけの能力が安全性、アライメントのガイドラインに準拠するように強化する新たな安全性トレーニングアプローチを発案しました。コンテキストにおいて我々の安全性ルールに関して理由づけできるようにすることで、より効果的にそれらを適用できるようになります。

安全性を計測する手法の一つは、ユーザーが安全性ルールをバイパス(ジェイルブレークと呼ばれるものです)しようとした際においても、どれだけモデルが安全性ルールに準拠しようとし続けるのかをテストするというものです。我々の最も困難なジェイルブレークテストの一つにおいて、GPT-4oは(0-100のスケールで)22のスコアを出しましたが、o1-previewモデルは84のスコアを出しました。こちらの[システムカード](https://openai.com/index/openai-o1-system-card/)や[研究記事](https://openai.com/index/learning-to-reason-with-llms/)でより詳細を確認することができます。

これらのモデルの新たな能力にマッチするように、我々の安全性の取り組み、内部のガバナンス、政府とのコラボレーションを強化しました。これには、我々の安全性&セキュリティコミッティーによって定義された、我々の[準備状況フレームワーク](https://cdn.openai.com/openai-preparedness-framework-beta.pdf)、最高クラスのレッドチーム、経営レベルのレビュープロセスを用いた厳密なテストや評価が含まれています。

AIの安全性に対するコミットメントを推し進めるために、最近ではアメリカとイギリスのAI安全性機関との合意形成を正式なものにしました。このモデルの研究バージョンに対する機関への早期アクセスを含め、これらの合意の正式運用を開始しています。これは、モデルの事前あるいは事後の研究、評価、テストのプロセスの確立の助けとなる、我々のパートナーシップにおける重要な最初のステップとなりました。

# 誰のためのものか

これらの強化された理由づけの能力は、あなたがサイエンス、コーディング、数学、類似の領域に取り組んでいる際には特に有用なものになるかもしれません。例えば、o1はヘルスケアの研究者が細胞のシーケンスデータに注釈を加えたり、物理学者が量子光学に必要な複雑な数式を生成したり、すべての領域の開発者がマルチステップのワークローを構築、実行するために活用することができます。
YAMAHAルーターを無理やりUSB駆動化し修理した話

# ジャンク110円なYAMAHAルータRTX810を購入したのだが、予想以上に動かなかったorz
物理破損もしくはセキュリティクラスで塞がれていない限り、シリアル通信で緊急パスワード"w,lXlma"を突っ込めば"Administrator"権限で"cold start"出来るはずだった…
https://www.rtpro.yamaha.co.jp/RT/manual/rt-common/setup/security_class.html
↑(RTX3510,RTX1300は初期設定から塞がれている、その場合は起動時に別コンフィグを読ませるor作成すれば行ける?)
https://www.rtpro.yamaha.co.jp/RT/manual/rt-common/operation/cold_start.html
![IMG_20240527_173438(1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3884308/c00488e1-795a-ac49-b4ec-ee2dd6665268.jpeg)
# ルンルンで動作確認を始めるもLEDランプすら光らないorz
本体を分解して基板の様子を確認するとなんとこんがりしてしまっていた。
![IMG_20240602_203348(1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3884308/bf98a92e-2f1b-f721-d3c4-bbd638efe553.jpeg)
# そこでとりあえず、動作品のRTX32を引っ張り出し、電源移植を試みた。
https://www.itpower.jp/tech/vpn/rtx32.html
↑これと同じ事をした所、RTX32の電源基板でRTX810の動作確認が取れた。
![FlWajSGaYAAvGY4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3884308/da743578-b90a-8a5a-8ca7-40dca2294030.jpeg)
https://twitter.com/junkismylife/status/1609364284722810881/
ちなみに安直に、黒ケーブルはGND、赤ケーブルは+5Vだった。
# これもしかして、USB駆動出来る?
とりあえずありあわせの部品で仕上げてみる。
![IMG_20220512_064702-EDIT.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3884308/fabd77b5-4eb0-394b-2bb7-f67a0c63d208.jpeg)
# これで(ずさんだが)修理完了
これで、そこら辺のモバイルバッテリーで動かせる。素晴らしい!
![IMG_20240614_171309_1~2(1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3884308/c1a3f61d-79df-491d-459d-97d34ab7f0c7.jpeg)
# あとがき
https://www.rtpro.yamaha.co.jp/RT/docs/mobile-internet/
↑こいつにLTEドングルでポータブルLANが楽しそう。
リモートデスクトップソフトウェア市場の成長に対する地政学的影響

リモート デスクトップ ソフトウェアを使用すると、ユーザーは、まるでそのコンピュータの目の前にいるかのように、インターネット経由でリモート コンピュータにアクセスして制御できるようになり、デスクトップ環境、アプリケーション、システム、ファイル、およびネットワーク リソースにリモート アクセスできるようになり、リモート チームでの作業が可能になります。リモート デスクトップ ソフトウェアは、集中管理、リモート ワーカーのサポートの簡素化、運用コストの削減、従業員の生産性の向上、ビジネス継続性、災害復旧サポートなどの利点を提供します。



世界のリモート デスクトップ ソフトウェア市場は、2024 年に 39 億 8,000 万米ドルと推定され、2024 年から 2031 年の予測期間にわたって 12% の CAGR を示すと予想されています。

 

重要なポイント



リモート デスクトップ ソフトウェア市場企業には、AeroAdmin、AnyDesk Software GmbH、AweRay、BeyondTrust Corporation、Citrix Systems, Inc.、ConnectWise LLC、GoTo、ISL Online、LogMeIn Inc.、Microsoft Corporation、RealVNC Limited、RemotePC、Securden、SolarWinds、TeamViewer SE が含まれます。これらの主要企業は、市場での地位を強化するために革新的な製品の発売と製品ポートフォリオの強化に注力しています。たとえば、Citrix は従業員エクスペリエンスと生産性の向上を目的とした新しいクラウド サービスを開始しました。



パンデミックによる制限によりリモート ワークの傾向が高まっているため、業界全体のさまざまな組織がビジネスの継続性を維持するためにリモート ワーク モデルを部分的または完全に採用しており、これによりリモート デスクトップ ソフトウェアの導入が促進されています。最近の研究によると、パンデミック後の時代でもリモートワークの傾向は続くと予想されており、リモート デスクトップ ツールの需要が高まっています。



リモート デスクトップ ソフトウェア プロバイダーは、チャネル パートナーと戦略的パートナーシップを締結し、ローカライズされたソリューションを導入することで、世界的な展開を拡大しています。たとえば、AnyDesk は、AI 機能を強化し、アジア太平洋や中東などの世界市場に注力するために Anthropic と提携しました。 LogMeIn は、セキュリティ ポートフォリオを強化し、オーストラリアとニュージーランド地域で事業を拡大するために Wombat Security を買収しました。この世界的な拡大により、プレーヤーは新興国での成長機会を活用できるようになりました。



市場の推進力



[リモート デスクトップ ソフトウェア市場の需要(https://www.coherentmarketinsights.com/ja/industry-reports/remote-desktop-software-market)」の主な推進要因の 1 つは、クラウド ベースの職場文化と BYOD のトレンドの高まりであり、従業員が自分のデバイスを使用してどこからでも作業ファイルやアプリケーションにアクセスできるクラウド ベースのシステムをさまざまな業界で採用しています。これにより、安全なリモート アクセスを提供するためのリモート デスクトップ ソフトウェアの関連性が高まり、IT 管理者が従業員のデバイスを一元管理できるようになり、リモート デスクトップ ツールの柔軟性が向上し、その採用が世界的に増加しています。



リモートデスクトップソフトウェア市場の成長に対する地政学的影響



リモートデスクトップソフトウェア市場は、いくつかの地域で地政学的な不確実性と経済の変動が続く中、大幅な成長を遂げているが、パンデミック中にリモートワークの実践が大規模に採用された一方で、ロシアとウクライナの間で進行中の戦争により、多くの企業が拠点の一部を移転することを余儀なくされた。これにより、分散した従業員間の安全なコラボレーションを可能にするリモート アクセスとデスクトップ ソリューションの必要性が加速しています。しかし、ロシアへの制裁により世界のサプライ チェーンが混乱し、インフレ圧力の高まりが影響を受けているいくつかの企業の IT 支出に悪影響を及ぼしています。これは、市場の拡大にとって短期的な課題となる可能性が高く、将来の成長を促進するために、ベンダーは自社製品の多要素認証、すべての通信およびアクティビティ ログの暗号化のサポートを強化することに投資する必要があります。不確実な時代の中でデータプライバシーの懸念に対処するのに役立ち、さまざまなタイムゾーンにまたがる配信とサポートの機能を拡張することで、世界中の拠点で活動する組織に対する価値提案を強化できます。



リモートデスクトップソフトウェア市場における価値が集中する地理的地域



リモート デスクトップ ソフトウェア市場は、金額の点で北米と欧州に非常に集中しており、2024 年には合わせて世界収益の 65% 以上を占めます。これは、IT、通信などの業界の大企業の間でこれらのソリューションが高度に浸透しているためです。 、BFSI、米国、英国、ドイツ、フランスなどの先進国の医療。



著者について:

コンテンツ ライターの Ravina Pandya は、市場調査業界で確固たる地位を築いています。食品や飲料、情報技術、ヘルスケア、化学薬品や材料など、さまざまな業界について綿密に調査された記事を執筆することを専門としています。

(https://www.linkedin.com/in/ravina-pandya-1a3984191)
AWS Lamba関数をテストする際にbodyの書きかた


AWS LambdaとAPI Gatewayを使ってAPIを実装するユースケースは多いと思います。

自分がLambda関数のテスト機能を使う際に、リクエストの「`body`」の書き方で詰まってしまったので、その時の解決法を共有します。


# 問題点

テスト機能を使ってLambda関数を実行しようとした際、以下のような形式でリクエストを送信したところ、エラーが発生しました。

```json
{
 "body": 
     {
         "userId":"test20240822@test.com",
         "displayName":"test20240822",
         "email":"test20240822@test.com"
    }
}

```

この形式で送ると、Lambda関数内で`body`の内容がパースされず、以下のようなエラーメッセージが表示されることがあります：

```
{
    "errorMessage": "Could not parse request body into json: Unexpected character (\"userId\":\"test20240822@test.com\")"
}

```

# 正しい書き方

API Gatewayを通してリクエストを送信する際には、このようにオブジェクト形式でbodyを指定するのではなく、文字列形式で送信する必要があります。


正しいリクエスト形式は以下のようになります。`body`は文字列として送信する必要があります。

```json
{
 "body": "{\"userId\":\"test20240822@test.com\",\"displayName\":\"test20240822\",\"email\":\"test20240822@test.com\"}"
}
```

# まとめ

- `body`は文字列形式で渡す必要がある

- `JSON`オブジェクトをそのまま渡すとエラーが発生するため、エスケープされた文字列に変換する必要がある

以上です！
Openfoamのソルバー追加について

# 背景
・Openfoamで計算を行う中で新たなソルバーを追加したい．
・ソルバーを `/opt/openfoam*/applications/solvers/`に格納.　`/Allwmake`　を走らせたところ、`Permission denied`で弾かれて進まない．
・`sudo ./Allwmake`で実施しようとすると，環境変数が読み込まれず `wmake: not found`で詰む．

# 環境
・Windows 10Pro
・Ubuntu 18.04LTS (WSL経由)
・Openfoam6

# 解決方法
## 1. sudoに環境変数を引き継ぐ
`sudo -E ./Allwmake`
・これだとうまくいかなかった．（よくわからんが）

## 2. root環境でOpenFOAMを読み込む
`sudo su`
`source /opt/openfoam*/etc/bashrc`
`./Allwmake`
・これはOKだった．

## 3. 所有権の変更
`sudo chown -R <ユーザー名>:<グループ名> <OpenFOAMのディレクトリ>`
・2で成功したのでNo challenge .

# 所感
・環境変数の理解は難しい．
・おそらく3をやるべきなのだろう．（以降、計算時にトラブル発生しそうな予感）
正しい形式で入力されるまで再入力させるメソッド

備忘録で書きました。

#### プログラムについて
`inUserName`メソッド：
１．`input`で文字列を受け取り、`checkName`メソッドで判定する。
２．`checkName`メソッドで判定が通ったら`userName`に代入する。
３．`userName`を返す。

`checkName`メソッド：
`input`の値が「大文字１～１０文字以内の文字列」に当てはまらない場合は再入力を要求する。

## だめだったやつ
最初に入力した文字が戻り値になってしまうので、`checkName`メソッドで再入力しても修正されていない不具合が発生します。
###### 筆者の勘違い：`checkName`メソッドの戻り値が自動的に`inUserName`にある`input`の値を上書きすると思っていました

  ```diff_java
public String inUserName(){
System.out.println("ローマ字（大文字のみ）でユーザー名を入力してください…");
String input = new Scanner(System.in).nextLine();
checkName(input);
-this.userName = input //checkNameの戻り値関係なく3行目で入力した文字列になってしまう
return this.userName;
}

//inputが大文字で1~10文字出ない場合は再入力させるメソッド
public static String checkName(String input) {
while(input.matches("[A-Z]{1,10}") == false) {
System.out.println("大文字で、１０文字以内に入力してください。");
input = new Scanner(System.in).nextLine();
}
return input;
}
```

## 修正
`checkName`メソッドの戻り値をそのまま`userName`に代入するようにしました。
```diff_java
public String inUserName(){
System.out.println("ローマ字（大文字のみ）でユーザー名を入力してください…");
String input = new Scanner(System.in).nextLine();
+this.userName = checkName(input); //checkNameメソッドの戻り値がuserNameに代入された
return this.userName;
}

//上記のコードと同じです
public static String checkName(String input) {
while(input.matches("[A-Z]{1,10}") == false) {
System.out.println("大文字で、１０文字以内に入力してください。");
input = new Scanner(System.in).nextLine();
}
return input;
}
 ```
  ## 結論
他メソッドの戻り値をそのまま変数に入れたいときは、右辺にそのメソッドを書く
Firebaseでデプロイ時に発生した「Uncaught Error: supabaseUrl is required.」というエラーの対処法について

## はじめに
GithubActionsを使用してfirebaseでデプロイをした際に画面が真っ白になってしまい苦戦したので、
対処法についてまとめます。

# エラーの原因
* GithubActionsに登録したシークレットの名前と.envで設定した環境変数名が一致していなかったから
⇒環境変数の名前が違うと全く別のものと認識されてうまく渡せない

* envで定義していた環境変数名とymlファイルで環境変数の読み込みを行っているところで使用している環境変数名が一致していないから

# エラーが発生する原因になっている箇所
```.yml
- name: Deploy to Firebase Hosting
        run: |
          ./node_modules/.bin/firebase deploy
        env:
          FIREBASE_CLI_EXPERIMENTS: webframeworks
          VITE_SUPABASE_URL: ${{ secrets.VITE_NEXT_PUBLIC_SUPABASE_URL }}
          VITE_SUPABASE_ANON_KEY: ${{ secrets.VITE_NEXT_PUBLIC_SUPABASE_ANON_KEY }}
      - name: delete GOOGLE_APPLICATION_CREDENTIAL
        run: export -n $GOOGLE_APPLICATION_CREDENTIAL
        if: ${{ always() }}
```
```.env
VITE_NEXT_PUBLIC_SUPABASE_URL=
VITE_NEXT_PUBLIC_SUPABASE_ANON_KEY=
```
# 解決方法
* 環境変数名とシークレット名を一致させた
* 環境変数を定義しているところと環境変数の読み込みを行っているところでの名前を一致させた。

```.yml
 - name: Deploy to Firebase Hosting
        run: |
          ./node_modules/.bin/firebase deploy
        env:
          FIREBASE_CLI_EXPERIMENTS: webframeworks
          VITE_NEXT_PUBLIC_SUPABASE_URL: ${{ secrets.VITE_NEXT_PUBLIC_SUPABASE_URL }}
          VITE_NEXT_PUBLIC_SUPABASE_ANON_KEY: ${{ secrets.VITE_NEXT_PUBLIC_SUPABASE_ANON_KEY }}
      - name: delete GOOGLE_APPLICATION_CREDENTIAL
        run: export -n $GOOGLE_APPLICATION_CREDENTIAL
        if: ${{ always() }}
```
```.env
VITE_NEXT_PUBLIC_SUPABASE_URL=
VITE_NEXT_PUBLIC_SUPABASE_ANON_KEY=
```
おわりに
今回環境変数の定義にNEXT_PUBLICを使用していましたが、next.jsで使用するものなのでreact×ViteではNEXT_PUBLICは不要ということが今回のエラーに対処するときに知りました。
⇒VITE_環境変数名とすれば良いです。