OmniAICreator/Qiita-1.07M huggingface dataset:
AVL木

# 本記事を読むにあたって
本記事では、木構造の基本概念や二分探索木には触れない。木構造については、下記の記事で触れられている。
 >https://qiita.com/tsudaryo1715/items/8fdf4a5f60b938df1ac6

 ## 平衡木
平衡木は以下のような構造が挙げられる。

![balanced-tree.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3269698/4ffcabbe-96a7-c3d9-727e-9611022e1818.png)

- 最悪のツリーの場合、探索に**O(n)** かかる(n:節点数)。現実では、整列した要素を順位挿入するケースは多い。
- バランスドツリーでは探索効率が最も良い。しかし、形の再構成に時間がかかる。
- 平衡木はバランスドツリーに近い形が適度な手間で維持できる探索木で、節点の挿入/削除・探索どれも**O(logN)** で済む。この探索木の代表例としてAVL木とB木が挙げられる。

## AVL木
AVL木とは**すべての節点において** 左部分木と右部分木の高さの差が**1**に収まった二分探索木である。

![20200207183735.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3269698/6b7cfb33-ee9a-0b20-a40e-975fa1af1eb3.png)

### 節点の挿入
例えば、例えば9 の右に10が挿入されたとき、節点8から見た右部分木は2(9,10)だが、左部分木は0(何もない)そのため、差が2になる。AVL木の条件を満たさないため、再構成する必要がある。とある節点から見た時の差が2以上の時、要素が多い方(例では,右)とは逆方向に回転させる。回転させる際に注目した節点の一つ下(今回でいうと9)を中心に回転させる。結果8→9 となり、9の左部分木には節点8。右部分木には節点10という構成になる。7からみた高さの差も1,3から見た高さの差も1以下であるので操作は終了される。
節点が挿入された場合は必ず各節点の高さの差を比較し、高い方の部分木とは逆に回転させ、その際、注目した節点の1つ下の節点(高さが大きい方の部分木の節点)が注目節点と置き換わる。基本はこの操作で完結するが二重回転が必要となるケースが存在する。

### 二重回転
節点3や節点7のような、節点の分岐後に節点の分岐が存在するような点から見た時の高さの差が2以上の時二重回転が必要となる。例えば、節点4の左下に節点3が挿入されたとき節点3からみて右部分木の高さは4(7→5→4→3)、左部分木の高さは2(1→0or2)となり高さの差は2となる。回転は通常と同様に逆に回転させるが、回転させる際置き換える節点が変化する。結論から述べると、
- 右部分木の方が高い場合は、注目点の右部分木の一番上の節点(今回は7)の左の節点(今回は5)に置き換えられる。
- 左部分木の方が高い場合は、注目点の左部分の木の一番上の節点(今回は1)の右の節点(今回は2)に置き換えられる。

つまり今回は、3→5になり左部分木は(5→3→1→0or2, 5→3→4)となり、右部分木は(5→7→8→9, 5→7→6)となる。節点4は節点5より小さいため左部分木に、節点6は節点5より大きいため右部分木に操作されている。

### 節点の削除
節点の挿入と同様の操作となる。節点が削除された親の節点から各節点の高さを比較し高さ2以上であれば、回転させる。その際、部分木の高さが高い方とは逆方向に回転させる。二重回転も同様な操作となる。

## おわりに
大学の講義でアルゴリズム・データ構造を学習しその際AVL木の内容があまり触れられなかったため、自分で学習し、自分なりの理解を記事として残しました。最初は回転の仕組みの理解に時間がかかりますが数をこなせば何とかなります。
リモートリポジトリをcloneする

リモートリポ(GitHubなど)をローカルリポにcloneする際に必要な各種コマンドの備忘録

## ■Cloneまでの流れ
①ローカルにユーザー情報をセット
②設定内容を一覧で確認
③リモートリポをcloneして、ローカルリポを作成
④ローカルリポがリモートリポに紐づいていることを確認
⑤.gitフォルダを確認

## ①ローカルにユーザー情報をセット
gitをインストールすると、gitに関する設定ができる.gitconfigファイルがホームディレクトリ配下格納される

```
$ ls ~/.gitconfig
/c/Users/yuzo/.gitconfig
```
当該ファイルを直接vimで編集可能だが、実際には以下のコマンドでファイル更新するケースが多い

```
git config --global <attribute><value>
例）
git config --global user.name "yuzo-5" //GitHubのアカウント名
git config --global user.email "xxxx@gmail.com"
```
※global有：当該ユーザのシステム全体の設定(~/.gitconfig)
※global無：実行したリポジトリの設定(.git/config)

gitユーザの設定をする理由ですが、リモートリポではGitHubでユーザアカウントを作成済みだが、その情報はローカルリポにはない状態。そのため、ローカルリポをリモートリポで設定したユーザと同じユーザーであると設定するために上記コマンドで設定する。

## ②設定内容を一覧で確認

```
$ git config --global --list
user.name=yuzo-5
user.email=xxxxx@xxxx.com
core.editor=code --wait
alis.co=commit
alis.ci=commit
alias.st=status
alias.br=branch
alias.co=checkout
alias.ci=commit
```

## ③リモートリポをcloneして、ローカルリポを作成

GitHubでcloneしたいリポジトリ開き、リポジトリのURLをコピーし、以下のコマンド実行

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2935967/d0dac8ca-ca96-213b-f66c-3f1bbb2f71af.png)

※クローンはカレントディレクトリで行われるので、クローンしたいフォルダへ移動しておく。
```
$ git clone git@github.com:yuzo-5/sample-repo.git
```
証跡は割愛するが、リポジトリがローカルにクローンされた。

## ④ローカルリポがリモートリポに紐づいていることを確認

この時点で、リモートリポとローカルリポは紐づいている。
紐づき確認コマンド↓

```
$ git remote -v
origin  git@github.com:yuzo-5/sample-repo.git (fetch)
origin  git@github.com:yuzo-5/sample-repo.git (push)
```
※fetchはpull、pushはpush
つまりoriginという名称で当該URLでpull、pushできますよという意味。
pgvector導入メモ

# はじめに
ChatGPTで自前のDB（PostgreSQL16）に保管したドキュメントから自然言語でQAをする仕組みを検証するために、前回導入したPostgreSQL16にpgvectorを導入し、ベクトルデータベースとして利用可能な環境を作成します。
特記事項なき場合は作業用の一般ユーザーでコマンド実行します。

# pgvector導入
公式のGitHubの導入手順に従い、導入していきます。
https://github.com/pgvector/pgvector
```
cd /usr/local/src
git clone --branch v0.5.1 https://github.com/pgvector/pgvector.git
cd pgvector
export PATH=${PATH}:/usr/local/pgsql161/bin
make
sudo su
export PATH=${PATH}:/usr/local/pgsql161/bin
make install
```
※前回導入したPostgreSQLのバイナリディレクトリにパスを通す必要があります。
以上で導入は完了です。

# pgvector初期設定
#### ベクトルデータベース用PostgreSQLユーザーの作成
```shell:postgresql管理ユーザーで実行
createuser -P -e vecdbuser 
Enter password for new role: 
Enter it again: 
Password: 
SELECT pg_catalog.set_config('search_path', '', false);
CREATE ROLE vecdbuser PASSWORD 'xxx####' NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT LOGIN NOREPLICATION NOBYPASSRLS;
```
#### ベクトルデータ用DBとテーブルの作成
まずはCreateDBを行います。この時点では特に特殊な設定はありません。
```
createdb -e -E UTF8 -O vecdbuser gptretdb -T template0
```
次に作成したDBにpgvector拡張を作成します。
前手順で作成したPostgreSQLユーザーではCREATE EXTENSIONできませんので、PostgreSQL管理ユーザーで操作を行います。
```
psql -d gptretdb
psql (16.1)
Type "help" for help.

gptretdb=# CREATE EXTENSION vector;
CREATE EXTENSION
gptretdb=# \dx
                             List of installed extensions
  Name   | Version |   Schema   |                     Description                      
---------+---------+------------+------------------------------------------------------
 plpgsql | 1.0     | pg_catalog | PL/pgSQL procedural language
 vector  | 0.5.1   | public     | vector data type and ivfflat and hnsw access methods
(2 rows)
```
vectorという拡張が作成されていることを確認します。
下記のSQLを実行し、ベクトルデータ用のカラムを持つテーブルを作成します。
#### 動作確認
簡単なデータも登録し、テストを行います。
```
gptretdb=# CREATE TABLE items (id bigserial PRIMARY KEY, embedding vector(3));
CREATE TABLE
gptretdb=# INSERT INTO items (embedding) VALUES ('[1,2,3]'), ('[4,5,6]');
INSERT 0 2
gptretdb=# SELECT * FROM items ORDER BY embedding <-> '[3,1,2]' LIMIT 5;
 id | embedding 
----+-----------
  1 | [1,2,3]
  2 | [4,5,6]
(2 rows)
gptretdb=# \q
```
embedding列にデータが登録されていることが確認出来たら動作確認完了です。
SwiftUIでAdmob広告を実装時の「Sandbox: rsync.samba」エラー解決法

#### SwiftUIでAdmobを使おうとしたら…エラー発生!

YouTubeの[この動画](https://www.youtube.com/watch?v=OLs5dVRdN3c)を見てAdmob広告をSwiftUIに導入しようとしたけど、2024年に入ってからはうまくいかない。エラーが出て実装できなくなっちゃったんです。でも、大丈夫！原因も解決策も見つけました。

#### エラーの原因って?

エラー「Sandbox: rsync.samba」は、Xcode15から出る新しい問題。原因はXcodeの「Build Settings」で「User Script Sandboxing」が「Yes」になってること。これでサンドボックス内のファイル書き込みがブロックされてしまってるんです。

#### じゃあ、どうすればいいの？

解決策は簡単！「User Script Sandboxing」を「No」に切り替えるだけ。これでXcodeがサンドボックス内でスクリプトを実行してくれるようになって、エラー解消！

#### まとめ

SwiftUIでAdmob広告を実装するときのこのエラー、開発者なら知っておきたい重要ポイントです。もっと詳しく知りたい方は、[tech.amefure.comの記事](https://tech.amefure.com/swift-xcode-build-error-sandbox)をチェックしてみてくださいね！

---
個人でアプリを開発しています。ベビーカーや車椅子利用の方に便利な、駅のエレベーター出入口を探せるアプリを開発しました。ぜひご利用ください。
​
https://apps.apple.com/jp/app/%E9%A7%85%E3%81%AE%E3%82%A8%E3%83%AC%E3%83%99%E3%83%BC%E3%82%BF%E3%83%BC%E3%83%9E%E3%83%83%E3%83%97/id6472233345
​
​
競技プログラミング関係の 記事のリンクをまとめてみました

# 今回の概要

今まで書いてきた記事のリンクをまとめてみました。

随時更新していくつもりです。

## アルゴリズム解説


初心者向けのアルゴリズムの解説です。
結構頑張って書きました。


https://qiita.com/karaju/items/bb722574a01c837e1a71

### テーマを絞った解説

素因数分解を用いた約数の個数の求め方について解説しました。

https://qiita.com/karaju/items/c8ee5302a3e897475435


ソートについて解説しました。

https://qiita.com/karaju/items/ee24231f44de3ffbffa0


## まとめ記事

AtCoderの解説記事をまとめてみました。

https://qiita.com/karaju/items/eebb5f142d4a5a09480e


自分が良いと思った問題を残しておくための記事です。


https://qiita.com/karaju/items/136846db0e3b3b0d8b0b



---

随時更新予定です。
高解像度(3440x1440)出力したいときの注意点

MacBook Air 2017からUG34Wに出力する際にかなり紆余曲折あったので。。

# 結論
出力解像度の上限はいろいろな要素で決まるので考慮すべきことが多い...
* 規格
* バージョン
* リフレッシュレート
* ケーブル
* 端子
* グラフィックスチップ
* etc...?

以下の情報はだいたいWikipediaです。

# 規格
一般向けではHDMIが主流。主に超高画質向けにDisplayPortがある。

# バージョン
HDMIは2.0か1.4かという印象。1.4でも4K解像度に対応するが、リフレッシュレートが24Hzのみとなる。
Displayportは初期バージョンでも4K出力できる。ただしリフレッシュレートは30Hz。

# リフレッシュレート
同じ解像度でも、このリフレッシュレートまでしか対応していない。ということがあるので注意。

# ケーブル
対応解像度だけでなく対応リフレッシュレートもある。
4K対応でも4Kではリフレッシュレートが30Hzしか出ないとかあるとハマる。

# 端子
PCの端子に規格とバージョンの対応があります。
新しいケーブルやモニター、PCを使っていても端子のバージョンが古いということもありえるはず。

# グラフィックスチップ
ケーブルと同様に対応解像度と対応リフレッシュレートがある。

# 紆余曲折の中身
MacBook Air 2017のスペックを見ると、「60Hzの外部ディスプレイで最大3,840 x 2,160ピクセル解像度を同時サポート」とあります。
https://support.apple.com/kb/SP753?locale=ja_JP

「最大」という言葉が気になりましたが、ちゃんと対応したケーブルを使えばよいのだろうと思い、まずは手元にあったminiDP-HDMIケーブルで接続したが、FullHDまでしか出ない。

このケーブルが高解像度に対応していないのだと思い、手元にあったminiDP-HDMI変換アダプタとHDMIケーブルを使って接続したが、やはりFullHDまでしか出ない。

ケーブルが問題ないことは確認できていたので、変換アダプタが悪いのだと思い、miniDP-HDMI変換アダプタを新しく買って接続したが、それでもFullHDまでしか出ない。。

ここで諦めて新しいノートPCを購入したが、そのPCもFullHDまでしか出ず。。メーカーに問い合わせて高解像度に対応していないという回答を得た。おそらくPCのHDMI端子が1.4だったからだと思っている。

そしてMBAに戻ってきて色々考えた結果、グラフィックスチップが対応していないのではないかという仮説に行き着いた。
そしてIntelのページでCPU検索すると・・・
![スクリーンショット 2024-01-23 23.21.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3678430/34ab4bb4-6722-2b87-20d9-97f2d0ad5ee6.png)
・・・ということで、1,000円のminiDP-DPケーブルを購入してやっと最大解像度で出力できるようになったとさ。
npx create-react-appコマンドエラー・対処の記録（ENOENT: no such file or directory, lstat 'C:\Users\ユーザー名\AppData\Roaming\npm'）

# はじめに
React学習開始時，`npx create-react-app`コマンドが通らなくて苦労したので，エラー・対処内容を記録しておきます．

# 発生したエラー文：`ENOENT: no such file or directory, lstat 'C:\Users\ユーザー名\AppData\Roaming\npm'`

![エラー文](https://lh3.googleusercontent.com/pw/ABLVV87YQNONzcQpNi8WLXAu__q1psXd2M7_pMsiv85GrgXH3UtYy3Qdv1YKNvJ2n-kwoY1aqJodRvo93q1x8rYwAeHV5tvBNV2nb3zmBIewqjViBPRpziWHVgk7bjceQcaQRPsLItrIDcEji1loq9S5fwzR=w1247-h218-s-no-gm?authuser=0,エラー文)

結論として，「C:\Users\ユーザー名\AppData\Roaming」配下に「npm」フォルダが無いためにエラーが発生していた．
自分の場合は，「Node.js」をインストールしただけでは，「C:\Users\ユーザー名\AppData\Roaming」配下の 「npm」フォルダは作成されていなかった．

# 対処
「C:\Users\ユーザー名\AppData\Roaming」配下に 「npm」フォルダを作成する．中身は空でもよい．

https://zenn.dev/ogmer/articles/151d11294642d3

自分の場合は，色々試行錯誤していて「yarn」をインストールした時に，npmフォルダが自動で生成されていた．
test

![スクリーンショット 2024-01-23 22.57.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682780/ac2b099c-8ffa-5218-4cd4-885b032bd88a.png)
![スクリーンショット 2024-01-23 22.57.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682780/98b9fc3b-9d60-5c8d-51d2-af2321c24962.png)
![スクリーンショット 2024-01-23 22.57.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682780/1e71e359-f264-963c-8e61-b49fe5b9e789.png)
![スクリーンショット 2024-01-23 22.57.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682780/ca467fec-220d-fcf1-fa80-3d4590db757b.png)
![スクリーンショット 2024-01-23 22.57.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682780/1a6f8442-d16b-806b-d2b5-c428a10b3c2d.png)
![スクリーンショット 2024-01-23 22.57.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682780/e5cc15b8-6064-2cae-833a-08e971d65095.png)
![スクリーンショット 2024-01-23 22.57.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682780/b6379ee6-fae3-6fd2-5d7c-af4760b6b640.png)
UnityのVSCodeで入力支援が効かない問題の対応

# 問題と経緯
UnityのC#エディタとしてVSCodeを導入してエラー等もなく動作していましたが
気が付くと入力支援（インテリセンス）が無効になっていました。

過去のバージョンでの対処例はいくつか見つかりましたが、現在（2023/08 時点）のバージョンで有効な情報にはたどり着けませんでした。
自力で試行錯誤した結果、一応解決することができたので対処法を記しておきます。


# 環境
・Windows 11 pro 22H2
・Unity 2022.3.7f1
・Visual Studio Code 1.81.1

VSCodeの導入方法などは省略
# 対応方法

C#拡張機能の Dotnet Server:Use Omnisharpのチェックが確認時はチェックが外れていましたが、これを有効にしました。

また、拡張機能の詳細欄にC#Dev Kitを無効にする必要があると書かれていたのでこれを無効にしました。

確か上記機能については使用を推奨される記載があったのでこの対応で問題ないか少し懸念はありますが、当環境ではこの対応で入力支援が有効になりました。

# 備考

アップデート履歴等を確認しているとC#の拡張機能でMonoを使わないようになったようで、これに関連するomnisharp.useGlobalMono　が悪さをしているようで入力支援を有効にする手法としてよくチェックをはずすように指定されていました。

しかし、当環境ではomnisharpは導入されていなかったにも関わらず問題が発生していました。


## 参考にさせていただいたサイト

https://blog.montone-works.com/2021/09/madewithunityonsteam-preparing-006.html

https://qiita.com/oliverx3/items/ac6e90280eca16d215a6

https://www.lisz-works.com/entry/setup-use-unity-with-vscode

https://zenn.dev/leaf/articles/98f02a61440893
tWAS9.0 , Keycloak 構成自動化での備忘録

# はじめに

tWAS, Keycloak でSAML構成をするのに苦労したところを同じことを調べなくて良いように残しておきます。

以下のページを更新しました。

https://qiita.com/keniooi/items/050b5ae0d8f50bf63c84

https://qiita.com/keniooi/items/cfe2b8ef692b23500a15

# spMetadata.xml をJSON形式に変換

https://stackoverflow.com/questions/53662807/configuring-keycloak-saml-from-the-command-line

を参考に試しましたが、なぜか実行できませんでした。各コマンドを手動で1行づつ実行してたのが原因でした。まとめてはりつけて実行することで実行できました。わかってしまうとどうってことないのですが、気づくのに時間がかかったりします。

ポイント：TOKENは有効期限があるのですぐに使えるようにしましょう。

貼り付け用メモ
```
export ACCESS_HOST=`hostname`
export TOKEN_URL=http://$ACCESS_HOST:8080/auth/realms/master/protocol/openid-connect/token
export AUTH="Authorization: bearer $(curl -s -d client_id=admin-cli -d username=admin -d password=password -d grant_type=password ${TOKEN_URL} | jq -r '.access_token')"
export CONVERTER_URL="http://$ACCESS_HOST:8080/auth/admin/realms/pdprof/client-description-converter"
export CLIENT_JSON=$(curl -X POST -H "${AUTH}"  -H 'content-type: application/json' ${CONVERTER_URL} --data-binary @spMetadata-was90.xml)
echo $CLIENT_JSON
```

# kcadm でのクライアント登録

https://kazuhira-r.hatenablog.com/entry/2020/07/30/000946

を参考にCLIで情報を確認します。以下のような情報を用意して作業しやすくします。

CLI使うシェルを開始
```
podman exec -it kc bash
```

環境変数などを設定
```
KEYCLOAK_USER=admin
KEYCLOAK_PASSWORD=password
KCADM=/opt/jboss/keycloak/bin/kcadm.sh
alias kcadm=/opt/jboss/keycloak/bin/kcadm.sh
```

実行するコマンドの元（引数を変えたりして試す）更新したい attribute名などを確認します。手動で作成して出来上がったデータになるようにコマンドを準備します。
```
kcadm get clients -r pdprof --server http://localhost:8080/auth --realm master --user $KEYCLOAK_USER --password $KEYCLOAK_PASSWORD
```

分かったら引数を変えつつうまく作成（更新）できるか試します。
```
kcadm create clients -r pdprof -f /tmp/client_was90.json -s "attributes={\"saml.client.signature\":\"false\"}" -i --server http://localhost:8080/auth --realm master --user $KEYCLOAK_USER --password $KEYCLOAK_PASSWORD
```

# wsadmin の AdminConfig を使った更新

wsadminを実行してコマンドラインに入ります。

```
/opt/IBM/WebSphere/AppServer/bin/wsadmin.sh
```

qiita で紹介しているWASの場合、管理ユーザーは以下のようにしています。

```
wsadmin
passw0rd
```

security.xml などのWAS構成ファイルで大まかなObject名を確認するか全部のlistをしてオブジェクト名を確認します。

更新したいオブジェクトがみつけるのに、listの戻り値を一つにしてattributeから更新するものをみつけます。
```
print AdminConfig.list('Security')
# (cells/DefaultCell01|security.xml#Security_1)
security = AdminConfig.list('Security')
print AdminConfig.show(security)
print AdminConfig.showall(security)
```

みつけた attribute を更新します。
```
AdminConfig.modify(security, [['appEnabled', 'true']])
AdminConfig.save()
```

# tWAS9.0 docker イメージの key.p12 パスワード

tWASの key.p12 デフォルトパスワードは　WebAS ですが、dockerイメージでは変更されていました。文書にはありませんでしたが、スクリプトで更新しているのを見つけました。開けなくなってあせりました。

https://github.com/WASdev/ci.docker.websphere-traditional/blob/main/docker-build/9.0.5.18/scripts/set_keystore_password.sh

現時点（2024/1/23) では KEYSTORE_PASSWORDファイルは使用できていないようなので /tmp/keystorepasswordupdated を見る必要があります。

```
cat /tmp/keystorepasswordupdated
```

私の用意しているgithubのスクリプトも動作のすべては説明できていないので、必要なら実行ファイルをみてみるのは有効です。


# まとめ

同じような苦労をしないように、今回知る事のできた内容をまとめました。
【UE5】今さらUnrealC++で「コピペ機能」を作ってみる　2日目

# 0. 最初
今回は「コピー」 & 「ペースト」を実装します
BPのノードでは公開されていないのでC++を使用しないといけません
 
# 1. 準備

`プロジェクト名.Buid.cs` を開き `AddRange` の引数に `ApplicationCore` を追加します


```cs
using UnrealBuildTool;

public class BlogProject : ModuleRules
{
	public BlogProject(ReadOnlyTargetRules Target) : base(Target)
	{
		PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
		PublicDependencyModuleNames.AddRange(new string[]
         {
                 "Core", "CoreUObject", "Engine", "InputCore", "ApplicationCore" 
          });
	}
}
```

# 2. 実装 

`UBlueprintFunctionLibrary`を継承させ`public`の下に`static void`で関数を宣言する

```cpp
#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "ClipboardUtility.generated.h"

UCLASS()
class BLOGPROJECT_API UClipboardUtility : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()

public:
	UFUNCTION(BlueprintCallable)
	static void Copy(const FString& Str);

	UFUNCTION(BlueprintCallable)
	static void Paste(FString& Dest);
};
```

cppに`#include "HAL/PlatformApplicationMisc.h"`を定義する
```cpp
#include "ClipboardUtility.h"
#include "HAL/PlatformApplicationMisc.h"

void UClipboardUtility::Copy(const FString& str)
{
	FPlatformApplicationMisc::ClipboardCopy(*str);
}

void UClipboardUtility::Paste(FString& Dest)
{
	FPlatformApplicationMisc::ClipboardPaste(Dest);
}
```

# 3. 動作

BPに移り、「Copy」と「Paste」と入力する


![スクリーンショット 2024-01-23 224436.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1918199/714e8c5c-91e7-2965-ab2d-34aa22d9f635.png)


実際の動作が以下
![無題の動画-‐-Clipchampで作成-_5_.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1918199/c30c530e-c5dd-b289-1f54-37face02f231.gif)

# 4. 参考

[UE4/C++: 4.18 以降発生するクリップボードのAPI仕様変更に伴う警告と必要な修正](https://usagi.hatenablog.jp/entry/2018/04/09/150203)

[【UE4】クリップボードから文字列を取得、設定　Copy&Paste](https://shuntaendo.hatenablog.com/entry/2020/09/21/230000)

[UE5/UE4 C++でクリップボードに文字列をコピー（Copy）したり、クリップボードから文字列をペースト（Paste）する](http://kagring.blog.fc2.com/blog-entry-785.html)
UE5.3でSequencerTools.hのリンクエラー

SequencerTools.hをインクルードさせてると、ずっとエラーが発生し続ける…何故？


# 確認環境

Windows 11 Pro
UnrealEngine 5.3.2
Visual Studio 2022

# 起きた問題

```
#include "SequencerTools.h"
```

『SequencerTools.h』をインクルードしているファイルで、ずっと、以下のエラーが発生する。

![LevelSequencehが開けない.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153021/299a9491-30dc-6e0d-f30c-af8d16326f3a.png)


SequencerTools.hを(**一番下を**)よくよく見ると…

```:SequencerTools.h

#if UE_ENABLE_INCLUDE_ORDER_DEPRECATED_IN_5_2
#include "Channels/MovieSceneEvent.h"
#include "CoreMinimal.h"
#include "LevelSequence.h"
#include "SequencerScriptingRange.h"
#endif

```

おま...インクルードしとるやないかーい。


# 対応した事

という事で、『Build.cs』のPrivateDependencyModuleNamesに、『**LevelSequenceを追加**』して終わり。

```XXXX.Build.cs
	
 PrivateDependencyModuleNames.AddRange(new string[] {"LevelSequence"});

```
ITパスポート アルゴリズムとプログラム

# アルゴリズムとは
目的を達成する、決まった処理のまとまりのこと
※「有限時間内に終了することも必要

# 流れ図
アルゴリズム(処理の流れ)を視覚的に捉える図
角丸が開始・終了
条件分岐するところは菱形
など図のルールがある

# プログラムとは
人間にも機械にもわかりやすい言語

# 変数
■変数の型
型の例
・整数型:整数が入る
・実数型:実数(数直線上にあるすべての数)が入れられる
・文字列型:ひらがなやアルファベットを入れられる
・論理型:True,Falseが入れられる

# 条件分岐
■選択処理
条件によって処理を変えたいときはどうするか
if (条件式1)
   処理1
endif

例)テストの点数が60点より上のときに合格と出力したい
　　　　60より下で50点以上のときは惜しい！と出力したい
  それ以外の場合は不合格と出力したい
if (score > 60)
   合格と出力する
elseif (score > 50)
   惜しい！と出力する
else
   不合格と出力する
endif

# 繰り返し処理
■前判定繰返し処理(while/for)
同じ処理を指定した回数繰返したいときはどうするか

while(条件式)
条件が成り立つ間、繰り返す処理
endwhile

例)1から5まで表示したいとき
i←1
while(iが5以下)
 iを表示する
 i←i+1
endwhile

または
for(iを1から5まで1つずつ増やす)
 iを表示する
endfor

# 配列
同じような変数をまとめたい

整数型の配列:nums
nums ← {5,7,9,3}

配列の中身(要素)を取り出す方法
nums ← {5,7,9,3}
nums[2]

5,7,9,3にそれぞれ要素番号1,2,3,4がつく
2は取り出したい要素の番号

# 関数
■関数・引数・戻り値
例)より広く、「n個の値の平均値を求める」ためには
①すべてを合計して
②nで割る
↓
まとめて「平均値を求める」という処理

引数→平均値を求める関数→戻り値
5,7,9,3 → ①すべてを合計して ②nで割る → 6

いくつかの処理をまとめた処理の塊を「関数」または「手続」という

○戻り値の型:関数名(関数に渡す値)
関数内の処理
return最後に返す値

渡す値を「引数」
返す値を「戻り値」という

■手続
ITパスポート試験の擬似言語で、関数と手続という2つが定義されている
厳密に違いはあるが、関数と同じと考えて良い

○手続名(引数)
手続きの処理

# 流れ図とプログラムの対応
![スクリーンショット 2024-01-23 22.35.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2518994/cc3003b2-ef77-6e62-6ba8-b3ea9bf11e6f.png)

# 後判定繰返し処理
繰返し処理の種類はもう1種類ある
while(条件式)
条件が成り立つ間、繰り返す処理
endwhile

do
初めに一回+条件が成り立つ間、繰り返す処理
while(条件式)
FANUCのPMCラダーでバイナリデータをビットにデコードする方法

# 概要
FANUCのPMCラダーで、バイナリ入力をビットに変換する手法を2つ紹介する。

# バイナリ→ビット変換の方法
- EQBでひたすら比較する
- DECBでまとめてビットにデコードする

## EQBでひたすら比較する
機能命令200 EQB(バイナリ比較)を使用して、入力データと定数を比較し一致をビットに出力させる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682717/96dc25b1-d68f-6cf4-3c0c-18492a93972f.png)

入力データの範囲が小さい場合や、特定の値だけを取得したいときは、こちらの方で十分。
使用するアドレスが少なくて済むため、メモリ容量が小さくなる。

## DECBでまとめてビットにデコードする
機能命令25 DECB(バイナリデコード処理)を使用して、まとめてビットデータに出力する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682717/ddd1f539-878b-3570-ebd5-185a7969ee1b.png)

入力データが大きい場合や、複数の値をインタロック等の条件に使用したいときはこちらを使う。
バイト単位でしかアドレス範囲を指定できないので、メモリ容量が大きくなりがちです。

# まとめ
基本的にはDECBでデコードしてあげるのが簡単です。
わざわざEQBで一つひとつビットに起こすのはナンセンスだと思います。

## 参考
[電装制御屋の備忘録](https://taroimo-lifestyle.com/)
p5.js で WEBGLモードの3次元空間にランダムに球を配置する（＋ クラスフィールド・プライベートプロパティを使う）

## 今回の内容
今回の内容は、タイトルのとおりです。

以下のような見た目の描画を行ってみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/38b1eb6c-2d33-7f8e-2496-11b081f74476.png)

上記は WEBGLモードを使って描画していますが、フラットな色を使っているので、3次元的な配置での見た目の立体感はないです。今回、Z軸方向の奥行きは、個々の球の描画サイズに影響を及ぼすだけのものとなっていますが、以下のような動きをつける時には、奥行き方向を使った位置の処理が活きてくると思います。

https://twitter.com/youtoy/status/1749422288498557104

## 作ったもの
### プログラム
今回作ったプログラムの内容は、以下のとおりです。

```javascript
const balls = [];
const count = 100;

function setup() {
  createCanvas(550, 400, WEBGL);
  colorMode(HSB, 360, 100, 100, 100);

  for (let i = 0; i < count; i++) {
    balls.push(new Ball());
  }

  background(0);

  for (const b of balls) {
    b.display();
  }
}

class Ball {
  #factor = random(0, 3, 0.5);
  #position = createVector(
    random(-width / 2, width / 2),
    random(-height / 2, height / 2),
    random(-width * this.#factor, width * this.#factor)
  );
  #color = [random(100, 300), random(60, 90), 100];
  #size = random(10, 15);

  display() {
    noStroke();
    fill(this.#color);
    push();
    translate(this.#position.x, this.#position.y, this.#position.z);
    sphere(this.#size);
    pop();
  }
}
```

### 補足
#### 3次元的な配置
今回行った球の配置で、3次元的にランダムに配置する際には、createVector() で位置を決めています。具体的には、x・y・z の 3つの軸に対してランダムな座標を生成しています。

#### クラスを作成する部分
クラスを作成する部分は、ES2022 から使えるようになったクラスフィールド・プライベートフィールドを使ってみています。今回のシンプルな例だと、これらを使う意味はあまりないのですが、後々の追加実装で役立つかも知れないという想定で、これらを使ってみました。

●パブリッククラスフィールド - JavaScript | MDN
　https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Classes/Public_class_fields

●プライベートプロパティ - JavaScript | MDN
　https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Classes/Private_properties
ProxmoxでVMを一括で別のディスクへ移すBash

実際に使う際にはご自身でご確認の上ご利用ください。
何があっても責任は負えません。
```
#!/bin/bash

new_storage="hdd" #ここに移動先のストレージ名を入れる

for vmid in $(qm list | awk '{if(NR>1) print $1}')
do
    echo "Processing VM $vmid"

    qm config $vmid | grep "virtio[0-9]:\|scsi[0-9]:\|ide[0-9]:\|sata[0-9]:\|tpmstate[0-9]:\|efidisk[0-9]:" | cut -d ':' -f1 | while read -r disk
    do
        current_storage=$(qm config $vmid | grep "$disk:" | cut -d ':' -f2 | sed 's/ //g')
        if [[ ${current_storage} != ${new_storage} && ! ${current_storage} =~ cdrom ]];then
            echo "Moving disk $disk of VM $vmid from $current_storage to $new_storage"
            #qm move-disk $vmid $disk $new_storage --delete
            #実際に実行する際は↑の行のコメントを外してね
        fi
    done
done
```
- VirtIO Block
- SCSI
- IDE
- SATA
上記4種に加え
- TPMの状態
- EFIディスク
の一括移動に対応しています。

移動させたくないディスクは一時的にディスクをデタッチしてunusedにすることで、移行対象から外す事ができます。
Docker学習　1日目

Dockerの学習を始めました。
まだ全体の流れがイメージできていない、メモのような内容です。
間違っているところがあるかもしれませんし、
読みづらい記事になっているかと思います。。。
理解が深まり次第、その都度、更新・訂正します！
(間違いのご指摘や、アドバイスいただければとても嬉しいです！)

# 《目的》
1. Dockerの理解
1. docker-composeの理解
1. コンテナオーケストレーションツール（AWS ECS）の理解



## 1-1 Dockerの構成要素
以下は、Docker hubからcentosのイメージをダウンロードして、さらにcurlの機能を搭載してカスタムしたDockerimageをDocker hubにプッシュする際の図。

![スクリーンショット 2024-01-23 19.34.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3570384/816f0ab9-99ab-9c5b-3168-6becf74c9a28.png)

* Docker Client：Docker Daemonに命令を出す。それぞれは通常同じサーバーにあるが、違うところにある場合もあり。
* Docker Daemon：コンテナに変更を加えたり、変更後のDocker imageを保存したり、Docker imageを管理している。DockerFileを元にビルドする。Dockerhub等のDocker imageの保管場所であるレジストリと通信してPUSHやPULLをする。


## 1-2 EC2(Amazon Linux2023)にセットアップ
EC2上にDockerをインストールし、
Docker Compose(アプリケーションの構成や複数のコンテナを管理するためのツール)もセットアップ、
最終的には、gitで取得したアプリケーションをDockerを使用して起動するスクリプト。
各コマンドの説明。
```sh
# Dockerに関するセットアップ
sudo yum update -y && \
#Dockerのパッケージをダウンロードしてくる
sudo yum install -y docker && \
#　ec2-userを-G docker に所属させる
sudo usermod -a -G docker ec2-user && \
# Dockerを起動する、起動しているかどうかのステータスも表示する
sudo systemctl start docker.service && \
# EC2再起動後もDockerを再起動して
sudo systemctl enable docker.service && \
# 以下はDocker composeに関するセットアップ
# githubのリポジトリからdockercomposeのパッケージをEC2のbinにダウンロード
sudo curl -L https://github.com/docker/compose/releases/download/1.21.0/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose && \
sudo chmod +x /usr/local/bin/docker-compose && \
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose && \
# 以下、EC2のセットアップ＆アプリの起動
sudo yum install -y  python3-devel gcc jq tree git && \
git clone https://github.com/AWSCLOUDTECH/tutorial.git && \
cd tutorial/todobackend && \
cd src && \
sudo yum install -y pip
pip3 install wheel uwsgi && \
#　-rでrequirements.txtに書かれた内容を一括で実行できる 
pip3 install -r requirements.txt --user && \
# migrateはデータベースを使用可能にするコマンド
python3 manage.py migrate && \
python3 manage.py runserver 0.0.0.0:8000
```

上記のコマンド実行にてEC2に直接インストールし、
アプリをEC2上で実行し確認済み。

### 補足：Docker FileとDocker imageの関係
![スクリーンショット 2024-01-23 21.10.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3570384/1712f8c9-61aa-dc43-b662-418e52c064ed.png)
緯度、経度から対応する地理院タイルを取得する

## はじめに
緯度・経度がわかっている時、その地点の対応する地理院タイルを取得したい。その座標の変換方法を調べる

## 計算式
[参考サイト](https://www.trail-note.net/tech/coordinate/) によると、以下のようである


経度λとズームレベルzからピクセル座標xを計算する
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141937/ece5f9f0-00a7-48bb-4aac-fd25ddc7cea3.png" alt="drawing" width="200"/>

緯度φとズームレベルzからピクセル座標yを計算する
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141937/e8442149-ad12-1aec-4f49-ea6ccc37d811.png" alt="drawing" width="500"/>

Kotlinでの実装
```Kotlin
    private fun getPixelCoord(lat: Double, lng: Double, zoom: Double): Pair<Int, Int> {
        val l = 85.05112878

        val x = 2.0.pow(zoom + 7.0) * (lng / 180.0 + 1)
        val y = (2.0.pow(zoom + 7.0) / Math.PI) *
                (-atanh(sin(Math.PI * lat / 180.0)) + atanh(sin(Math.PI * l / 180.0)))

        return x to y
    }
```

## 検証
上記メソッドを使ってズームレベル16の時の東京駅（緯度：`35.680959106959`, 経度：`139.76730676352`）の地理院タイルを求めてみる

```Kotlin
        val pixelCoord = getPixelCoord(35.680959106959, 139.76730676352, 16.0)
        println("pixelCoord: $pixelCoord")
```
計算結果は以下のようになり、
```sh
pixelCoord: (14902236, 6606514)
```
東京駅はズームレベル16の地理院タイル上でX座標: `14902236`, Y座標: `6606514` ということがわかった
タイルは一辺が256ピクセルの正方形であるから、256で割ることで左上から何番目のタイルなのかを求めることができる
```
14902236 / 256 = 58211 番目
6606514 / 256 = 25806 番目
```

これを国土地理院の [標準地図](https://maps.gsi.go.jp/development/ichiran.html#std) の `URL` に当てはめると、、
> https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png

`https://cyberjapandata.gsi.go.jp/xyz/std/16/58211/25806.png`

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141937/de07f597-62a3-e57c-4bc1-20bd735cbc51.png" alt="drawing" width="300"/>

たしかに、東京駅周辺の地理院タイルが取得できている :ok_woman:

## 参考
正方形タイルについては以下が参考になった
https://www.trail-note.net/tech/tile/

:tada:
SSH接続先のフォルダをWindowsのドライブにマウントする

## 目的

SSH接続先（EC2とかさくらのVPSとか）のフォルダをローカルPCのドライブにマウントできるようになります。

dokan と WinSSHFS でやろうと思ったら使える秘密鍵の形式が限られていたため探した対応法の備忘です。

## ざっくり手順

1. [Rclone](https://rclone.org/downloads/) を入れる
1. [WinFsp](https://github.com/winfsp/winfsp/releases/tag/v2.0) も入れる
1. Rclone の設定ファイルを作る
1. マウントする！

## じっくり手順

### [Rclone](https://rclone.org/downloads/) を入れる

1. 環境にあったインストーラを落とす
  GitHubのリンクもついており、そこから落とす方が速いかも知れない。
1. インストール
  任意のフォルダに解凍する。以下このフォルダをカレントディレクトリとして記載します

### [WinFsp](https://github.com/winfsp/winfsp/releases/tag/v2.0) も入れる

これをやらないと、マウントコマンド実行時に `cannot find winfsp` と怒られる。

1. [WinFsp](https://github.com/winfsp/winfsp/releases/tag/v2.0) の「DOWNLOAD WINFSP」をクリックしてダウンロード
1. インストール
  特に難しいことなし

### Rclone の設定ファイルを作る

#### 設定ファイルを手作りする場合

設定ファイルを `%APPDATA%\rclone\rclone.conf` に作成する。
マウントコマンドで設定ファイルパスを指定できるらしいので、気に入らなければ別の場所に作っても良い。
内容は `"C:\Users\anata\.ssh\config` にある情報で足りる。

```
[settei-no-namae]
type = sftp
# ホスト
host = xxx-xxx-xxxxx.vs.sakura.ne.jp
# 秘密鍵のパス
key_file = C:\Users\anata\.ssh\id_ed25519
# ポート
port = xxxx
# ユーザー名
user = xxxxxx
shell_type = unix
md5sum_command = md5sum
sha1sum_command = sha1sum
```

#### いろいろ設定したい場合

ドキュメントを読んで頑張ってもいいけど、GUIのほうがやりやすいかも

1. GUIの起動  
  `rclone.exe rcd --rc-web-gui`
2. 設定の新規作成
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34511/f5942dcb-e990-933f-ef64-cb030f31bf50.png)
1. 名前と接続の種類の指定
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34511/ff5b26a4-c48b-7961-79e5-5e4af64fe302.png)
  名前は自由。マウントコマンド実行時に指定する識別子になる
1. その他の設定
  お好みでどうぞ

### マウント

Mドライブにマウントする例

```bat
rclone.exe mount settei-no-namae: M: --dir-cache-time 1m
```

`--no-console` オプションを付けてもウィンドウが絶対起動し、閉じる（≠最小化）するとマウントが解除されてしまう。GitHubでも議論されているが、うまくいってないらしい。

スタートアップフォルダに `.bat` を置くなり、タスクスケジューラに登録するなりするとよい。コンソールが立ち上がるのが気に入らないけど。

## 参考

+ [Rcloneを用いたファイルシステムのマウント方法](https://zenn.dev/kabec_dev/articles/4199b774f95e76)
    + ほぼここを見れば実現できる
+ [RcloneでGoogleドライブをローカルPCにマウント | DevelopersIO](https://dev.classmethod.jp/articles/mounted-google-drive-using-rclone/)
    + いろんなサービスとか接続方法に対応してて、これからも色んな場面で使えそう。
BetterTouchToolを使って、コピーしたテキストを自動フォーマットする（PDFの改行を消す）

## はじめに
たとえば英語論文を読んでいるとき、PDFの文章をコピーしてDeepLにぶん投げること、ありますよね。しかし普通にコピペすると、それぞれの行が改行扱いになって変な翻訳になってしまうことも多いわけです。
これを解消するために、よくブラウザのURL欄に一度貼り付けたりするわけですが、
「PDFコピー」→「URL欄にペースト」→「全選択」→「コピー」→「DeepLにペースト」
って普通に面倒ですよねっていう。
でもよく考えたらこれってBTTの機能で全自動化できないか？と思ってやってみました。
## 環境
MacBook Pro 15-inch, 2018
macOS Sonoma 14.2.1
BetterTouchTool Version: 4.356
## 実装
BTTの機能を利用して、専用のキーボードショートカットキーを作成します（もちろんショートカットキー以外でもOK）。適当なショートカットをトリガーに設定したら、アクションは
「Text Actions」から「JavaScriptで選択範囲を変換&コピー」
を選択してください。
![スクリーンショット 2024-01-23 20.59.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3661623/078c0774-f009-b196-d552-51ee6f570d6c.png)
クリップボードトランスフォーマー機能のところに、たとえば下記のように入力すると、忌まわしき改行を駆逐してコピーすることができるようになります（ついでに行末のハイフネーションも駆逐しています）。
```JavaScript:
async (clipboardContentString) => {
   return clipboardContentString.replaceAll("-\n","").replaceAll("\n", " ");
}
```
## 結果
こんな感じの途切れてしまった文章を、ショートカット一つでコピーして
>For example, when you want to
translate a sentence with many unnece-
ssary line breaks like this one,
you can paste it into DeepL easily!

こう普通にペーストできます
>For example, when you want to translate a sentence with many unnecessary line breaks like this one, you can paste it into DeepL easily!

これでワンタッチで直接DeepLにコピペできるので、操作が半分以下になって効率爆上がりです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3661623/14f4c3f6-c6a7-3db8-9415-426c551fc6a9.png)


## おわりに
今回は単にハイフネーションと改行を取り除くような変換を行いましたが、他にも使い道はいろいろ見出せそうな気がします。そもそも実装が非常に簡単なので、何か特殊な変換を伴ってコピペしたいとき、手元の文字列から何かを計算したいときに逐一コードを書き換えて使うのもアリかもしれません。

例：なんなら文字数を計算してコピーする機能にする
こうやると、文字列をコピーしてペーストするだけで文字数カウントができます。
```JavaScript:
async (clipboardContentString) => {
   return String(clipboardContentString.length);
}
```
追記：もっと便利な機能として実装してみました。

https://qiita.com/kompeki/items/ae41f4379d30cc5738eb

BTTは本当に思いつくことは大体何でも実装できますね！便利です。
a*bの値が与えられたときにaとbをベイズで推定してみる

基礎代謝から体重の推移のモデリングをしていたときに未知数が多く、どのくらい識別できるのか不安になったので、実験として。

データは単純にa,bを正規分布から生成

```r

library(rstan)

N=1000
a=rnorm(N,mean=100,sd=10)
b=rnorm(N,mean=2,sd=0.2)

lst=list(N=N,y=a*b)
fit=stan(model_code = scode,data=lst,
         warmup=300,iter=1000,chain=1)
```

```stan
data {
  int N;
  real y[N];
}
parameters {
  real<lower=0> a;
  real b;
  real sigma;
}

model {
  sigma~cauchy(0.01,0.01);
  //a~normal(140,30); 
  //b~normal(2.5,0.5);
  a~normal(130,30);
  b~normal(1.5,0.5);
  
  y~normal(a*b,sigma);
}

print(fit)
```




事前分布を色々かえると、a,b同じ方向にずらしたときは比較的うまくいき、上下反対方向にずらすと的外れになっていくっぽい。ただし一応正しい値のほうにズレていく。

なぜ識別できるのか考えてみると、y,bが与えられたときのaの事後分布見ると
$P(a|y,b)∝P(y,b|a)*P(a)$
となるが、
$P(y,b|a)$ の部分は

yが平均付近でbが（真の）平均付近ならaも平均付近の確率が高く
yが平均付近でbが高ければaは低い確率が高く
それにaの事前分布をかけた値が高い所からサンプリングされる確率が高くなる。
どっちにしろ真の確率分布*事前分布が高い所からサンプリングされる確率が高くなり、収束していくのもわかる気がする。
ERROR: UnrealBuildTool.dll not found in なんちゃらかんちゃら…

UEでC++のコードを追加する際に、リンクエラーが結構な頻度で発生してしまい、四苦八苦するエンジニアの姿は、よく見る光景に思います。
その度に、『これ何？』と調べつつ、色々、弄りまわして、『直った』と安心し作業に戻ります。
しかし、調べた過程をどこかに置いておいて、メモしていなかったりして、同じ問題が発生した際に、『これ何したっけ？』とまた、**同じ事を調べ直すのもよくある光景**だと思います。


そんな、負の連鎖に終止符を打つべく、今回は、対処した事を覚えている内にQitaに残しておいて、**未来の自分を助けてあげたい**と思います。


# 確認環境
Windows 11 Pro
UnrealEngine 5.3.2
Visual Studio 2022


# C++を追加した際のルーティン

C++クラスを追加する際の個人的なやっているルーティンです。
エディタからプロジェクトにC++クラスを追加して、**ビルドが一度で通った成功体験**がありません。
その為、以下の事をやるようにしています。

1. エディタを一度落とす
1. DerivedDataCache、Intermediate、Savedを削除する
1. uprojectをダブルクリックしてプロジェクトの起動してみる。2で削除したファイルを復元する為なので、起動できなくてもOK
1. Generate Visual Studio Project Filesを実行しsinファイルを作り直す


# 起きた問題

今回は、発生した問題は、『**Generate Visual Studio Project Files**』を実行した際に画像のようなダイアログが発生し、『エディタも起動しない』『VisualStudioも起動しない』状態になり、困りました。


![sinファイルを作成できない_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153021/4984f429-2189-0bed-339f-0f103db4e1c5.png)

実際のエラー文です。
```
Running E:/Workspace/Engine/UE_5.3/Engine/Build/BatchFiles/Build.bat  -projectfiles -project="E:/Workspace/Test/BakeTrailUE/BakeTrailUE.uproject" -game -rocket -progress -log="E:\Workspace\Test\BakeTrailUE/Saved/Logs/UnrealVersionSelector-2024.01.23-17.26.30.log"
Using bundled DotNet SDK version: 6.0.302
ERROR: UnrealBuildTool.dll not found in "..\..\Engine\Binaries\DotNET\UnrealBuildTool\UnrealBuildTool.dll"

```

# 対応した事

対応した事は、解決してみれば簡単で

```
エンジンのインストール先\Engine\Binaries\DotNET\UnrealBuildTool
```

ここが、UnrealBuildToolのプロジェクトになっており、『**UnrealBuildToolのソリューションを立ち上げてビルドし直した**』だけです。

ビルド後に、無事にプロジェクトのsinファイルが作成されて安心しました。
『UnrealBuildTool.dll』は、PCを検索すると、別のパスに存在していた為、このDLLを移動させるだけでも良かったかもしれません。

それが不安だったので、今回はしていません。
同じケースでハマっている方の手助けになればと思います。
今回は、以上です。
git の設定（改行コードの自動変換をやめる）

# 改行コードの自動変換が有効になっている場合
作業ツリー上のファイルの改行：CRLF
コミット後のリポジトリ上の改行：LF
プル（チェックアウト）後の作業ツリー上：CRLF

# git全体に反映

### 改行を変換しない
作業ツリー上：CRLF
コミット後のリポジトリ上：CRLF
プル（チェックアウト）後の作業ツリー上：CRLF
~~~
git config --system core.autocrlf false
~~~
### 改行を変換する
作業ツリー上：CRLF
コミット後のリポジトリ上：LF
プル（チェックアウト）後の作業ツリー上：CRLF
~~~
git config --system core.autocrlf true
~~~

# ユーザーに反映

### 改行を変換しない
作業ツリー上：CRLF
コミット後のリポジトリ上：CRLF
プル（チェックアウト）後の作業ツリー上：CRLF
~~~
git config --global core.autocrlf false
~~~
### 改行を変換する
作業ツリー上：CRLF
コミット後のリポジトリ上：LF
プル（チェックアウト）後の作業ツリー上：CRLF
~~~
git config --global core.autocrlf true
~~~

# 特定のリポジトリ上のみに反映

### 改行を変換しない
作業ツリー上：CRLF
コミット後のリポジトリ上：CRLF
プル（チェックアウト）後の作業ツリー上：CRLF
~~~
git config core.autocrlf false
もしくは
git config --local core.autocrlf false
~~~
### 改行を変換する
作業ツリー上：CRLF
コミット後のリポジトリ上：LF
プル（チェックアウト）後の作業ツリー上：CRLF
~~~
git config core.autocrlf true
もしくは
git config --local core.autocrlf true
~~~

# 優先度
local（そのリポジトリ）が一番優先度が高い
次にglobal（ユーザーごと）、
次にsystem（全体）という優先度になる

例）
git config --system core.autocrlf true
と設定していても、
git config --local core.autocrlf false
であれば、
そのリポジトリは「false」が有効になる
Kaggle参戦記：手痛い洗礼。1940位で終了。

今日は「[AIが書いた文書か、人間が書いた文書かを当てるコンペ](https://www.kaggle.com/competitions/llm-detect-ai-generated-text/discussion/470154)」の最終日でした。参加者の多くが予想していた通り、大きなShake-up/Shake-downが起こっています。私はというと。。。大きなShake-downの方に入ってしまいましたー！わははは！

結局、1940位で終了。メダルの影も形も見えません。振り返ってみると、結構、序盤で良いモデルができていたのに、それを採用せず、また、後半で悪手を重ねてしまった、という感じでした。下記、私がLBスコアを上げるためにやったことと、その結果を見て内面化していった仮説に対して、PVスコアはどう変化していたか、を照らし合わせながら、答え合わせをしていきます。

仮説(1)：DAIGT v2にDATGT-exのデータを統合すると精度が良くなる
⇒〇正解　
　　LB:0.960 ⇒ 0.961
　　PV:0.893 ⇒ 0.903

仮説(2)：CatBoostに高い重みを与えるのは良くない
⇒×不正解：実はすごいゲインがあった！この時の結果を最終提出していれば・・・
　　LB:0.961 ⇒ 0.951
　　PV:0.893 ⇒ 0.917

仮説(3)：TfIdfVectorizerのmax_featureを減らすのは効果がある
⇒〇正解
　　LB:0.961 ⇒ 0.962
　　PV:0.902 ⇒ 0.906

仮説(4)：人間の文章データの重複は効果がある
⇒〇正解
　　LB:0.961 ⇒ 0.963
　　PV:0.902 ⇒ 0.904

仮説(5)：LightGBMを省いても精度は向上する
⇒×不正解。これはかなり致命的なミスだった。
　　LB:0.961 ⇒ 0.963
　　PV:0.902 ⇒ 0.890

仮説(6)：TfIdfVectorizerのn-gram rangeを長い方に伸ばすのは良いこと
⇒×不正解
　　LB:0.963 ⇒ 0.967
　　PV:0.890 ⇒ 0.886

仮説(7)：再びCatBoostに重みを与えても良くならない
⇒×不正解：実はCatBoostにすごいご利益があった。。。
　　LB:0.967 ⇒ 0.967
　　PV:0.886 ⇒ 0.905

仮説(8)：ノイズデータの重複は効果がある
⇒〇正解：
　　LB:0.972 ⇒ 0.973
　　PV:0.883 ⇒ 0.887

こうして振り返ってみると、序盤でそこそこ優秀なモデルが作れていたのに、そこを素通りしてしまい、後半は悪い仮説に悪い仮説を重ねた結果、PVスコアをどんどん下げていっていた、という感じですね。特に、データ拡張まわりの仮説はだいたい当たっていたのですが、分類器の選択を完全に見誤っていた感じです。こうなった原因としては、「データ拡張で精度が向上できる」⇒データを増やしたい⇒メモリオーバーフローになる⇒重い分類器を軽い分類器に入れ替えてみる⇒LBスコアが上がった（ひと安心）⇒またデータを増やす⇒・・・。という思考ループにはまってしまっていたからでした。

今回の教訓は下記の通りです
- CatBoost、LightGBMは、それなりに性能の裏付けがある。安易に外そうとするな。
- 「最後にたどりついた最高LB、最高AUCは努力の結晶ではない」それは「悪い仮説に悪い仮説を積み重ねただけの代物かもしれない」。最終提出結果には、先入観なく作っていた序盤の単純なベストモデルも入れておけ。

また、PVスコアの上位層の手法を見ていると、みんな結構、データの整備に時間と力をかけていたことが分かりました。やはり、データの質と量が分類器のロバスト性を高めるのだと再認識しています。過学習の可能性を放置せず、しっかり、手元のデータのトピックを分類して、偏りをなくす工夫をしておくべきでした。

このように、今回は残念な結果に終わりましたが、これからは「Kaggleで1900位以上転落した男」として、別のコンペでも引き続き頑張ります。
Python 3 エンジニア認定基礎試験対策8 - エラーと例外

# はじめに
Python3エンジニア認定基礎試験の対策として自分用に執筆しています。

:::note warn
この記事はPython・執筆学びたての初心者が執筆しています。間違いがあるかもしれませんので、ぜひ各項目にある**参考文献**も確認してください。また、誤りがあればコメントで教えていただけると幸いです。
:::

# エラーと例外

## 構文エラー

```Python
>>> while True print('Hello')
SyntaxError: invalid syntax
```

正しい構文で記述されていないとエラーを起こす。
今回だとwhile Trueの後ろに`:`がないのでエラーとなる

## 例外

``` Python
>>> 10 * (1/0)
ZeroDivisionError: division by zero
>>> 4 + spam*3
NameError: name 'spam' is not defined
>>> '2' + 2
TypeError: can only concatenate str (not "int")to str
```
発生した例外の組込み名が表示される。

## 例外処理

``` Python
>>> while True:
...     try:
...         x = int(input())
...         break
...     except:
...         print('Error!')
```

`try`文は以下のように動く。

 1. try節が実行される
 2. 例外が発生しなければそのまま終わる
 3. 例外が発生すればその節の残りはスキップ、except節を実行する。

```Python
except (RuntimeError, TypeError, NameError):
    pass
except ValueError as e:
    print(e)
```

といったように複数の例外をキャッチすることもできる

また、`else`文をつけることもできる。`try`文でなにもエラーが起きなければ実行される節で、全ての`except`節の後ろにつける。

## 例外を投げる

`raise`文を使うと、特定の例外を発生させる。

```Python
>>> raise NameError('Hithere')
NameError: HiThere
```

`raise`文の後ろに例外名を書かなければ例外が再創出させることができる

```Python
>>> try:
...     raise NameError('HiThere')
... except NameError:
...     print('Error!')
...     raise
Error!
NameError: HiThere
```

## クリーンアップ動作を定義

`finally`節を定義すると、どんな状況でも必ず実行される節を加えることができる。

```Python
>>> try:
...     raise KeyboardInterrupt
... finally:
...     print('Goodbye, world!')
GoodBye, world!
KeyboardInterrupt
```

# 参考文献

https://docs.python.org/ja/3.9/tutorial/errors.html
【SwiftUI】Previewを実機で行う

# はじめに
Previewを実機でできるってことは知っていたのですが、やったことがなかったのでやってみました。
やり方を記事にします。

```swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        Circle().frame(width: 100, height: 100)
    }
}

#Preview {
    ContentView()
}
```

今回の例では上記のコードを使用します。

# やりかた
まず、Previewを開きます。
![スクリーンショット 2024-01-23 20.34.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/08eb0be3-e578-cf74-edcc-e30b6dfb01e7.png)

Previewの下に現在のPreview機種が書かれているボタンがあるので選択します。
![スクリーンショット 2024-01-23 20.35.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/86ed6db3-56ac-e97f-f9ac-67adc3271371.png)

「Devices」に書いてあるのが、実機です。
過去に接続したことのある実機が表示されます。
ここで今回使用する実機を選択します。
私はコードで繋げずに接続しているので「〇〇 will connect on demand」と書いてあります。
![スクリーンショット 2024-01-23 20.36.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/f5fec372-abe7-8f55-9f82-6779b3e146e5.png)

実機でのPreviewに成功すると以下のように「Previewing on "〇〇"」となります。
![スクリーンショット 2024-01-23 20.39.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/8f3bc83d-4bed-0e1a-2ca1-b8aff296a63b.png)

では実機の方を見てみましょう。
以下のようなアイコンのアプリが自動で現れました。
![IMG_5096.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/a4236be7-2727-3dd3-b8ca-25699024715a.jpeg)

少し待つと自動で以下の順番で画面が変わっていきます。
|1|2|3|
|-|-|-|
|![IMG_5090.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/1d90b3e6-ad7a-23ee-5d59-586c896e4ee5.png)|![IMG_5095.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/400eca1e-5f94-8cfe-71a9-3a730d773c37.png)|![IMG_5097.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/0d98514d-d635-1af5-ed1f-92c4ec7f533b.png)|

# おわり
もちろんPreviewなので、コードを変えると実機のPreviewの方も勝手に変わります。
commandというコマンドを調べてみた

---
始めに
---
　*『「鏡よ鏡よ鏡さん 世界で一番美しいのは誰？」 「それは白雪姫です。」* 

　 *「は？」*

　*パリンパリンパリーン！*

　*こうして鏡は粉々になりましたとさ。ちゃんちゃん。』<br><br>*


　これは正直者がバカを見るという昔話です。（大嘘）

　社会では正直者は求められますが、正直すぎると得をしないことが多いです。
しかしcommandは違います。

　　<br>&emsp;彼は真実を映す鏡です。
<br>&emsp;真実を映す鏡はあなたに素晴らしい情報を与えるでしょう。
&emsp;たとえそれが、あなたの望まない結果であったとしても......。

# 目次
1. commandというコマンドとは
1. commandの主なオプション
1. 使い方
1. まとめ


# commandというコマンドとは
　皆さんはcommandというコマンドをご存知でしょうか？
<br>&emsp;そもそもコマンドとは、一般的にUNIXやLinuxなどのコマンドライン環境で使われる、
ls、cat、echo のようなコンピュータ操作の指示を指します。

```bash php  
> #!/bin/bash
> echo hello  
> hello(出力)  
```  

 これらはコマンド、と呼ばれますが、実はcommandというコマンドが存在するのです。

 ```bash php  
> #!/bin/bash
> command -v ls
> /bin/ls(出力)  
```  

commandはエイリアスや関数以外の指定したコマンドを実行するコマンドです。
「type(またはzshのwhich)」コマンドと同様、シェルが実際には何を実行するのかを表示することもできます。
|オプション|意味|
|:---|:--|
|-p|コマンドを探すパスを指定する（通常は環境変数PATHを使用|
|-v|「コマンド」を実行せず、実行対象となるコマンドやファイル名、エイリアスの定義を表示する
|-V|「コマンド」を実行せず、実行対象となるコマンドの詳細な情報を表示する（「which コマンド」相当）

# 使い方

引数なし

 ```bash php  
> #!/bin/bash
> alias ls='echo hello'
> ls
> hello(出力)
> command ls
> Desktop		Downloads	Movies		Pictures	goinfre		sgoinfre
Documents	Library		Music(通常のlsの出力と同じ)
```  

command -v

 ```bash php  
> #!/bin/bash
> alias ls='echo hello'
> ls
> hello(出力)
> command -v ls
> alias ls='echo hello'(出力)
```  

command -V(typeと同じ挙動)
 ```bash php  
> #!/bin/bash
> command -V ls
> ls is /bin/ls(出力)  
```  

# まとめ
　いかがだったでしょうか。

&emsp;そんなに役立つ場面はないかもですが、雑学程度にはなったと思います。（願望）

&emsp;真実を映す鏡。
次はあなたの真実を、映すかもしれません......。

 *テレレレレン テレレレレン テレレレテッテー テレレレレン♪*
centos7でスクリーンキャプチャを取得する

gnome-screenshotを使用してスクリーンキャプチャを取得する
3秒後のアクティブウインドウを対象とするなら以下の指定
```
[linuxstudy@xxxx ~]$ gnome-screenshot --delay=3 --window
```
取得した画像はここに格納されていた。設定で変えられるのか不明。
```
[linuxstudy@xxxx ~]$ ls ${HOME}/Pictures/
Screenshot from 2023-07-14 12-16-12.png
Screenshot from 2023-07-14 12-20-19.png
Screenshot from 2023-08-10 20-13-50.png
Screenshot from 2024-01-23 20-12-21.png
Screenshot from 2024-01-23 20-15-23.png
Screenshot from 2024-01-23 20-16-32.png
Screenshot from 2024-01-23 20-16-41.png
Screenshot from 2024-01-23 20-20-05.png
```
マニュアル
```
GNOME-SCREENSHOT(1)                                        GNOME-SCREENSHOT(1)



NAME
       gnome-screenshot  -  capture  the  screen, a window, or an user-defined
       area and save the snapshot image to a file.

SYNOPSIS
       gnome-screenshot [ -c ]  [ -w ]  [ -a ]  [ -b ]  [ -B ]  [ -p ]   [  -d
       SECONDS   ]  [ -e EFFECT  ]  [ -i ]  [ -f FILENAME  ]  [ --display DIS‐
       PLAY  ]

DESCRIPTION
       gnome-screenshot is a GNOME  utility  for  taking  screenshots  of  the
       entire  screen,  a  window  or an user-defined area of the screen, with
       optional beautifying border effects.

OPTIONS
       -c, --clipboard
              Send the grab directly to the clipboard.

       -w, --window
              Grab the current active window instead of the entire screen.

       -a, --area
              Grab an area of the screen instead of the entire screen.

       -b, --include-border
              Include the window border within the screenshot.

       -B, --remove-border
              Remove the window border from the screenshot.

       -p, --include-pointer
              Include the pointer with the screenshot.

       -d, --delay=SECONDS,
              Take the screenshot after the specified delay [in seconds].

       -e, --border-effect=EFFECT,
              Add an effect to the outside of the screenshot  border.   EFFECT
              can  be ``shadow'' (adding drop shadow), ``border'' (adding rec‐
              tangular space around the screenshot), ``vintage'' (desaturating
              the screenshot slightly, tinting it and adding rectangular space
              around it) or ``none'' (no effect).  Default is ``none''.

       -i, --interactive
              Interactively set options in a dialog.

       -f, --file=FILENAME
              Save screenshot directly to this file.

       --display=DISPLAY
              X display to use.

       -?, -h, --help
              Show a summary of the available options.

       In addition, the usual GTK+ command line options apply.  See the output
       of --help for details.

AUTHOR
       This   manual   page   was   written   by  Christian  Marillat  <maril‐
       lat@debian.org> for the Debian GNU/Linux system (but  may  be  used  by
       others).

       Updated  by Theppitak Karoonboonyanan <thep@linux.thai.net>, Tom Feiner
       <feiner.tom@gmail.com>, Cosimo Cecchi <cosimoc@gnome.org> and others.



                                August 10, 2013            GNOME-SCREENSHOT(1)
```
@openzeppelin/contracts/utils/Counters.sol, imported from [filename].sol, not found エラーへの対処法

## はじめに
.solファイルを実行したら、このようなエラーが出ました。

```bash
Error HH404: File @openzeppelin/contracts/utils/Counters.sol, imported from contracts/MyEpicGame.sol, not found.

For more info go to https://hardhat.org/HH404 or run Hardhat with --show-stack-traces
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
error Command failed.
Exit code: 1
Command: /Users/username/.nvm/versions/node/v20.11.0/bin/node
Arguments: /opt/homebrew/Cellar/yarn/1.22.19/libexec/lib/cli.js run:script
Directory: /Users/username/github/ETH-NFT-Game/packages/contract
Output:

info Visit https://yarnpkg.com/en/docs/cli/workspace for documentation about this command.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
```

## 結論

### 原因
OpenZeppelin V5.0では Counters が削除されたため。

他の機能やコントラクトも削除されています。
- Address.isContract
- Counters
- SafeMath
- SignedSafeMath
- GovernorCompatibilityBravo
- GovernorVotesComp
- TokenTimelock (in favor of VestingWallet)
- ERC777
- All cross-chain contracts (including AccessControlCrossChain)
- All presets in favor of [OpenZeppelin Contracts Wizard](https://wizard.openzeppelin.com/)

### 対処法
https://github.com/OpenZeppelin/openzeppelin-contracts/issues/4233

この記事を参考に書き換え、エラーが解消されました。

#### import
```sol:v4
import {Counters} from "@openzeppelin/contracts/utils/Counters.sol";
```
```sol:v5
// 削除
```

#### using Counters for Counters.Counter
```sol:v4
using Counters for Counters.Counter;
Counters.Counter private _tokenIdCounter;
```
```sol:v5
uint256 private _tokenIdCounter;
```
#### .current()
```sol:v4
uint256 tokenId = _tokenIdCounter.current();
```
```sol:v5
uint256 tokenId = _tokenIdCounter;
```

#### .increment()
```sol:v4
_tokenIdCounter.increment();
```
```sol:v5
_tokenIdCounter += 1;
```

#### 全体
```sol:v4
import {Counters} from "@openzeppelin/contracts/utils/Counters.sol";

contract MyToken is ERC721, Pausable, Ownable {
        using Counters for Counters.Counter;
        Counters.Counter private _tokenIdCounter;

        function safeMint(address receiver) public onlyOwner {
            uint256 tokenId = _tokenIdCounter.current();
            _safeMint(_receiver, tokenId);
            _tokenIdCounter.increment();
        }
}
```

```sol:v5
contract MyToken is ERC721, Pausable, Ownable {
        uint256 private _tokenIdCounter;

        function safeMint(address receiver) public onlyOwner {
            uint256 tokenId = _tokenIdCounter;
            _safeMint(_receiver, tokenId);
            _tokenIdCounter += 1;
        }
}
```

## 参考記事
https://blog.openzeppelin.com/introducing-openzeppelin-contracts-5.0#AModernizedContracts5.0

https://note.com/hayattiq/n/n88465fdff232
springのHTTP Interfaceでhttp client実装を切り替え

https://docs.spring.io/spring-framework/reference/integration/rest-clients.html#rest-http-interface に書いてある通り。

# ソースコードなど
```build.gradle
plugins {
	id 'java'
	id 'org.springframework.boot' version '3.2.2'
	id 'io.spring.dependency-management' version '1.1.4'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'

java {
	sourceCompatibility = '17'
}

configurations {
	compileOnly {
		extendsFrom annotationProcessor
	}
}

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-web'
	compileOnly 'org.projectlombok:lombok'
	developmentOnly 'org.springframework.boot:spring-boot-devtools'
	annotationProcessor 'org.projectlombok:lombok'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

tasks.named('test') {
	useJUnitPlatform()
}
```

以下は ```RestTemplate``` の場合。

```java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.client.support.RestTemplateAdapter;
import org.springframework.web.service.invoker.HttpServiceProxyFactory;
import org.springframework.web.util.DefaultUriBuilderFactory;

@Configuration
public class Config {
    @Bean
    public BookApiClientService bookApiClientService(){
    	RestTemplate restTemplate = new RestTemplate();
    	restTemplate.setUriTemplateHandler(new DefaultUriBuilderFactory("http://localhost:8080/"));
    	RestTemplateAdapter adapter = RestTemplateAdapter.create(restTemplate);
    	HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build();
    	
    	BookApiClientService service = factory.createClient(BookApiClientService.class);
    	return service;
    	
    }    
}
```

6.1から新規追加された ```RestClient```  を使用する場合。

```java
    @Bean
    public BookApiClientService bookApiClientService(){
    	RestClient restClient = RestClient.builder().baseUrl("http://localhost:8080/").build();
    	RestClientAdapter adapter = RestClientAdapter.create(restClient);
    	HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build();
    	
    	BookApiClientService service = factory.createClient(BookApiClientService.class);
    	return service;
    	
    }
```

```WebClient``` もデフォルトで用意されているがここでは省略。

もしspringに対応するproxyクラスが無い場合、```HttpExchangeAdapter```の実装クラスを自前で用意するのだと思われる。以下はJDK標準の ```HttpClient``` を使用する場合のイメージ。とはいえ、探せば何かしらライブラリが公開されているとは思うがそこまでは調べていない。

```java
public class Asadf implements HttpExchangeAdapter {
	HttpClient client = ...
 ```