OmniAICreator/Qiita-1.07M huggingface dataset:
Command Of SQL

※本記事は英語勉強のため、拙い英語も記載されています。
　温かい目で見てください。

#◆Commands of SQL
ProgateでSQLの勉強をしたので、備忘録として記録していきます。

I am learning about SQL in progate.
I write a article to record.

#◆Commands List

* SELECT
* FROM
* WHERE
* ORDER BY
* GROUP BY
* HAVING
* JOIN
* ON

#◆command execution order
コマンドの実行順
1. Specifying a tabel - FROM
2. Join tables - ON/JOIN
3. Acquistion conditions - WHERE
4. Grouping - GROUP BY
5. Function - COUNT SUM AVG MIN MAX
6. HAVING
7. Search - SELECT DISTINCT
8. Sort - ORDER BY
9. Limit - LIMIT

#◆Command to add the data

データベースにデータを追加するためのコマンド。
Command to add the data into a database.

```
INSERT INTO [DB name] ("[column1]", "[column2]") VALUES ("value1", "value2")
```

#◆Command to update the data

データベースのデータを更新するためのコマンド。

Command to update the data in a database.

```
UPDATE [DB name]
SET [column1]="[value]", [column2]="[value]"
WHERE id=[value]
;
```

※注意
+ データは1度更新すると元に戻せない。
+ クエリを実行するときは、WHEREの条件が正しいか確認してから実行する。
+ WHERE句を設定せずに更新すると、すべてのデータが更新されてしまう。

※Note
+ Once the data is updated, it cannot be restored.
+ When executing a query, make sure that the WHERE condition are correct before executing the query.
+ If you update without the setting WHERE, all the date will be update.

#◆Command to delete the data

データベース内のデータを削除するためのコマンド。
Command to delete the data in database.

```
DELETE FROM [DB name]
WHERE id=[value]
;
```

※注意
"UPDATE"と同様。

※Note
Same as "UPDATE".
Rのデータフレーム操作についてのまとめ

# はじめに

機械学習の勉強を始めたVBAユーザです。
備忘録としてRの使い方についてまとめています。

# Rのデータフレーム操作のまとめ
Rのパッケージ`dplyr`, `tidyr`を使ったデータフレーム操作についてまとめました。
Rのサンプルデータ`iris`と`anscombe`を用いて使い方の例を示しています。

- [データフレームの行の操作について](https://qiita.com/swathci/items/04f4c1bb2c3c380cae94)
- [データフレームの列の操作について](https://qiita.com/swathci/items/9bf403dca7c428fc3e7d)
- [データフレームの集計操作について](https://qiita.com/swathci/items/d13be09a7ed73c1a8d94)
- [データフレームのpivot操作について](https://qiita.com/swathci/items/4ce25faddfeff3a29a5f)
- [データフレームの関数について](https://qiita.com/swathci/items/8d626865638079d13665)
- [R標準パッケージによる集計操作について](https://qiita.com/swathci/items/f6e2f737d9388603bcd7)


# Pythonのpandasとの比較
Pythonと比較したRのデータフレームの使い方についてまとめました。

- [PythonのpandasとRのdplyrの比較](https://qiita.com/swathci/items/4d3469a413fb5a9f2212)
- [PythonのpandasとRとSQLの比較](https://qiita.com/swathci/items/3489b9886799e2f61c4f)



# 参考
- [tidyverse](https://tidyverse.tidyverse.org/)
   - [dplyr](https://dplyr.tidyverse.org/)
   - [tidyr](https://tidyr.tidyverse.org/index.html)
- R for Data Science
   - [5 Data transformation](https://r4ds.had.co.nz/transform.html)
   - [12 Tidy data](https://r4ds.had.co.nz/tidy-data.html)
- Heavy Watal  - R stats
   - [dplyr — 高速data.frame処理](https://heavywatal.github.io/rstats/dplyr.html)
   - [tidyr — シンプルなデータ変形ツール](https://heavywatal.github.io/rstats/tidyr.html)
- Rのデータベースの操作についての自前のまとめ
   - [行の操作について](https://qiita.com/swathci/items/04f4c1bb2c3c380cae94)
   - [列の操作について](https://qiita.com/swathci/items/9bf403dca7c428fc3e7d)
   - [集計操作について](https://qiita.com/swathci/items/d13be09a7ed73c1a8d94)
   - [pivot操作について](https://qiita.com/swathci/items/4ce25faddfeff3a29a5f)
   - [関数について](https://qiita.com/swathci/items/8d626865638079d13665)
   - [R標準パッケージによる集計操作について](https://qiita.com/swathci/items/f6e2f737d9388603bcd7)
   - [PythonのpandasとRのdplyrの比較](https://qiita.com/swathci/items/4d3469a413fb5a9f2212)
   - [PythonのpandasとRとSQLの比較](https://qiita.com/swathci/items/3489b9886799e2f61c4f)
WSL上からWindowsのクリップボードに保存されている画像をpng保存する

## 解答編

以下のコマンドをwsl上のbashで実行すれば、Windows上でコピーした画像がWSL上のカレントディレクトリにファイルとして保存される。

```
$ powershell.exe '(Get-Clipboard -Format Image).Save("image.png")'
```

## 解説編

まず、WSLはWindowsとは別にUbuntuが動いているので、クリップボードは共有されない。したがって、Widows上でのクリップボードにアクセスする仕組みが必要。

RubyにWin32などのライブラリもあるが、それはRubyをWindows上で動かしたときに機能するものであって、WSL上のRubyでwin32のgemを使っても、Lunux上でkernel32.soを探しに行こうとする（当然ない）。

幸い、WSLからはWindowsのexeファイルは実行可能で、PowerShellも実行可能。PowerShellにGet-Clipboardというコマンドがあるので、そいつを使う。

シンプルに

```
$ powershell.exe Get-Clipboard
```

と実行すれば、テキストファイルの場合には、テキストが出力される。Macで言えば、pbpasteを実行したのと同じ結果になる。

クリップボードに画像が入ってる時には、-Format Image の引数を付与する。

```
$ powershell.exe Get-Clipboard -Format Image


Tag                  :
PhysicalDimension    : {Width=909, Height=527}
Size                 : {Width=909, Height=527}
Width                : 909
Height               : 527
HorizontalResolution : 96
VerticalResolution   : 96
Flags                : 335888
RawFormat            : [ImageFormat: b96b3caa-0728-11d3-9d7b-0000f81ef32e]
PixelFormat          : Format32bppRgb
Palette              : System.Drawing.Imaging.ColorPalette
FrameDimensionsList  : {7462dc86-6180-4c7e-8e3f-ee7333a7a483}
PropertyIdList       : {}
PropertyItems        : {}
```

このように、メタ情報のみが出力される。返すのはImageオブジェクトなので、画像形式で保存するには、Saveメソッドをつける必要がある。インスタンス変数にセットすることなく、いきなりメソッドをつけたいときには、カッコでくくることで、メソッドが実行できる。

```
$ powershell.exe '(Get-Clipboard -Format Image).Save("image.png")'
```

## なぜ必要になったか

MarkDownで文書を書いてる時にはスクショもどんどん入れていきたい。MarkDownはVSCodeで書いてる。VSCodeは基本的にはWSLで動かしている（ほとんどがLinux上で動かしたいものばかりなので）。そこでWSL上で実行するだけで、画像のパスを生成し、そのパスにクリップボードの画像を保存し、さらにクリップボードに画像のパス（文字列）を入れるということを一気にやりたいと思った。

と、ここまで書いて思ったけど、MarkDownで文書を書く時だけ、Windows上でVSCodeを開けば、「CTL＋ALT＋Vでクリップボードの画像を保存してなおかつMarkDonw形式で挿入してくれるツール」がそのまま使えるなと思った。こういうツール。
https://marketplace.visualstudio.com/items?itemName=mushan.vscode-paste-image
さよならCocoaPods

`CocoaPods`から`Swift Package Manager`にライブラリの管理を移行するメモ

プロジェクトファイル内のCocoaPods関連の依存を削除する

```
pod deintegrate
```

続いて残ったファイルを削除する

```
git rm -r  Podfile Podfile.lock *.xcworkspace
```

これできれいになったので改めてCocoaPodsで利用していたライブラリをSwift Package Managerを使った形にしていく。
Xcodeのメニューから［File］－［Swift Packages］－［Add Package Dependency］を実行し、githubなどのリポジトリURLを貼り付けていく。

podコマンドがmac OSのバージョンアップで通らなくなっている場合がある。
その場合は以下を実行する。

```
sudo gem install cocoapods -n /usr/local/bin
```
Google AdMob iOS ( Objective-C ) でアダプティブバナーを表示する

# サンプルプログラムを実行してみる

1.手順１

下記のリンクより、 最新バージョンの "Adaptive Banner Example" の ObjC をダウンロードする。
( 記事作成時の最新バージョンは v7.22 )

https://github.com/googleads/googleads-mobile-ios-examples/releases


2.手順２

 ( 1 ) Mobile Ads SDK をインポートします。

 ( 2 ) プロジェクトのビルド設定で、[Other Linker Flags] に -ObjC リンカーフラグを追加します。

具体的な作業内容は、下記のリンクの内容を確認してください。

https://developers.google.com/admob/ios/quick-start


3.手順3

プロビジョニングファイルを登録し、iOS Simulators または、実機により実行する。


4.備考

サンプルプログラムは、 Interface Builder により広告を表示するようになっています。
プログラムで表示する場合は、下記の手順でサンプルプログラムを修正してください。


# メイン画面をプログラムで表示する場合　( Objective-C )


1."Main.storyboard"(メイン画面)を削除します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1189425/e2ec6a97-c0ea-73d5-9c24-e3663be3a948.png)


2.Info.plist の "Launch screen interface file base name" 、 "Main storyboard file base name" を削除します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1189425/1a0ec116-1eef-adb9-f66d-bd32f83e29c9.png)


3.AppDelegate.h を修正し、メイン画面をプログラムで定義します。

```perl:AppDelegate.h&#x20(&#x20Objective-C&#x20)

#import <UIKit/UIKit.h>

/* 下記内容を追加 (メイン画面定義) */
#import "ViewController.h"
@class ViewController;

@interface AppDelegate : UIResponder <UIApplicationDelegate>
{
    /* 下記内容を追加 (メイン画面定義) */
    ViewController *viewController_;
}

@property (strong, nonatomic) UIWindow *window

@end
```


4.AppDelegate.m を修正し、メイン画面をプログラムで表示します。

```perl:AppDelegate.m&#x20(&#x20Objective-C&#x20)

- (BOOL)application:(UIApplication *)application 
     didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

    /* 下記内容を追加 (メイン画面を表示) */
    /* window 作成 */
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    /* メイン画面作成・表示 */
    viewController_ = [[ViewController alloc] init];
    [self.window addSubview:viewController_.view];
    /* rootViewControllerの設定 [ iOS9対応 ] */
    self.window.rootViewController = viewController_;
    /* メイン画面を前面にする */
    [self.window bringSubviewToFront:viewController_.view];


    ( その他の記述... )

}
```

5.ViewController.h のバナー定義を削除する。

```perl:ViewController.h&#x20(&#x20Objective-C&#x20)

#import <UIKit/UIKit.h>

/* 下記を削除 */
/* @class GADBannerView; */

@interface ViewController : UIViewController

/* 下記を削除 */
/* @property(nonatomic, weak) IBOutlet GADBannerView *bannerView; */

@end
```


6.下記のリンクの　「プログラムで行う場合」　の項目内容を参考にして広告を表示してください。

https://developers.google.com/admob/ios/banner?hl=ja



以上
Linuxコマンド

Linuxコマンドを学んでみました。
Linuxコマンドを使えるかどうかでスピードが全然違うらしいので身につけておきたいと思ってます。


## Linux

OSの一種。
幅広い用途で使われており、たくさんのユーザーに検証されてきたので大きく変更する必要がない。
その為、一度習得すればこれから先長く使える。


## コマンド

- cdコマンド(change directory)

ディレクトリを移動する。ディレクトリ名をcdの後に指定する

```
//sampleディレクトリに移動
cd sample
```

- pwdコマンド(print name of working directory)

自分の今いるディレクトリ（カレントディレクトリ)を確認する。

```
//入力すると下にカレントディレクトリが表示される
pwd
```

- lsコマンド(list)

今いるディレクトリ内のファイルやディレクトリの一覧を表示する。

```
//入力すると下に一覧が表示される
ls

//以下のオプションをつけるとファイルの詳細情報も表示できる
ls -l

//以下のオプションをつけると.から始まる隠しファイルも含めて全ファイルが表示できる
ls -a
```

- mkdirコマンド(make directory)

ディレクトリを作成する。後ろにディレクトリ名を指定する。

```
//sampleディレクトリを作成する
mkdir sample
```

- catコマンド(concatenate)

ファイルの中身を表示する。私自身は鍵情報とかを見るときに使う印象。

```
//sampleというファイルの中身を表示する
cat sample
```

- touchコマンド(touch)

新規ファイルを作成する。

```
//README.mdファイルを作成する
touch README.md
```

- rmコマンド(remove)

ファイルやディレクトリを削除する。

```
//sampleというファイルを削除する
rm sample
```

- cpコマンド(copy)

ファルやディレクトリをコピーする。

```
//sampleというファイルをnew_sampleというファイルにコピーする
cp sample new_sample
```

何の略か分かると覚えやすいですね。
AWS CLIからEC2インスタンスを起動/停止してみた。超ざっくりまとめてみた。

EC2オンデマンドインスタンスの場合、利用しない時間は停止し、利用するときだけ起動するように制御をしたいものです。
このため、AWS CLIからEC2インスタンスの起動/停止を行うためのやり方を調べ、自分の備忘録としてまとまました。これを見れば、一目で思い出せるはず！
<img width="200" alt="qiita-square" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038334/654a08e1-5ca5-ac09-8a1d-12df4c9706fc.png">

---

- 作図には [AWS 公式アイコンセット](https://aws.amazon.com/jp/architecture/icons/)を利用してます
- 全般的に概念的な説明のみとしています。
- 以下サイトを参考としました。不明点がある場合は、補足で参照ください。画面キャプチャ付きで細かく説明されてました！
    - [EC2インスタンスをAWS CLIで起動する](https://qiita.com/tri-comma/items/271d3917899dc2993a00)
    - [AWS CLIでEC2インスタンスを停止する](https://qiita.com/makipen_39/items/f968e3cfb4a2129ebe13)
    - [クラスメソッドさんの記事](https://dev.classmethod.jp/articles/awscli-tips-ec2-start-stop/)
 
前提
---
- 説明を極力シンプルにするために、CLI用IAMユーザーの登録、AWS CLIのインストール(＋設定：aws configure)は完了している状態から始めます。
  - IAMユーザーの作り方は[公式サイト](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_users_create.html)を参照してください。
  - 登録したユーザには、アクセス権限のポリシー「AmazonEC2FullAccess」を付けておきます。（今回だけならフルには不要なのですが）

## 起動

```bash:実行コマンド
aws ec2 start-instances --instance-ids "i-xxxxxxxxxxxxxxxxx"
```

```json:処理結果
{
    "StartingInstances": [
        {
            "InstanceId": "i-xxxxxxxxxxxxxxxxx", 
            "CurrentState": {
                "Code": 0, 
                "Name": "pending"
            }, 
            "PreviousState": {
                "Code": 80, 
                "Name": "stopped"
            }
        }
    ]
}
```

## 起動完了待ち

```bash:実行コマンド
aws ec2 wait instance-running --instance-ids "i-xxxxxxxxxxxxxxxxx"
```

## 停止

```bash:実行コマンド
aws ec2 stop-instances --instance-ids "i-xxxxxxxxxxxxxxxxx"
```

```json:処理結果
{
    "StoppingInstances": [
        {
            "InstanceId": "i-xxxxxxxxxxxxxxxxx", 
            "CurrentState": {
                "Code": 64, 
                "Name": "stopping"
            }, 
            "PreviousState": {
                "Code": 16, 
                "Name": "running"
            }
        }
    ]
}
```

## 状態表示（停止中）

停止状態で`describe-instance-status`すると、結果のjsonが空値で返ってきます。

```bash:実行コマンド
aws ec2 describe-instance-status --instance-ids "i-xxxxxxxxxxxxxxxxx"
```

```json:処理結果
{
    "InstanceStatuses": []
}
```


さいごに
---
この記事はAWS初学者を導く体系的な動画学習サービス[「AWS CloudTech」](https://aws-cloud-tech.com/)の課題カリキュラムで作成しました。

このサービスは、テンポの良い/わかりやすい動画説明をもとに、気軽に実践を積み、自分の血肉とできるオンラインスクールです。
コミュニティも存在し、Slackで会員通しの情報交換/質問も気楽にできます。
<img width="100" alt="qiita-square" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038334/8889d9eb-2c72-293d-fda8-73dbd95eb1ab.png">

書籍を購入するような値段で学習ができ、とてもお得です。(個人的な感想です)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038334/1b330d17-6e3f-50ab-d6f1-2a96300cd626.png)

では、また次回お会いしましょう！
イベントリスナーが即時実行されていた

たいしたことないんだけど地味にはまってしたまったのでメモ。

イベントリスナーがクリックの時だけ動いていて欲しいのになぜかロードのタイミングで実行される:confounded:

用意していたイベントリスナーは以下の通り。
クリックしたら動いてね～ってやつ。

```:【修正前】clickEventListener.js
document.addEventListener("click",displayAlert(),false);
```

呼び出している関数displayAlertは以下の通り。
呼び出されたらダイアログ表示しますってやつ。

```displayAlert.js
function displayAlert(){alert("execute function")};
```
なんで思い通りに動いてくれないの？？？思っていたら、
displayAlertがJSが読み込まれた時点で実行されていただけでした。
なのでclickしたタイミングで動くように
displayAlert()の()を外してあげればOK。

```:【修正後】clickEventListener.js
document.addEventListener("click",displayAlert,false);
```
はい。想定通りのタイミングで動きました:relaxed:
JavaScript書き方に自由度があるところが難しい。
【AWS】 S3簡単まとめ

S3 (Simple Storage Serviceの略)
---
AWSのサービスの1つで、クラウド型の``オブジェクトサービス``です。
容量は無制限で、破格の安さと高い耐久性もあり、高可用性を兼ね備えています。

(補足)
※1 ``オブジェクトサービス``
　オブジェクト（ファイル、テキスト、データなど）単位で出し入れが可能な``ストレージ``です。

※2 ``ストレージ``
パソコンのデータを保管しておくための補助記憶装置のことです。
<br>

メリット
---

#####● ストレージ機能
ストレージの容量により自動的に拡張・縮小されます。
大量のデータを取り扱う際にも最適です。

　　
#####● 耐久性と可用性の高さ
全てのオブジェクトに対して99.999999999%の耐久性と、可用性においても、1年間で99.99%になるように設計されています。
可用性の99.99%というのは、1年間でアクセスできない時間が52〜53分程度なので、高可用性であると言えます。障害などにも強いため、データを安全に利用することが可能です。

　　
#####● 低コスト
1GBあたり0.025ドル（日本円で2.72円、3/14時点）と大変安く、ストレージにおいの容量、リクエスト数、データの転送数などで料金が決まるシステムです。
つまり、最低料金や一定額の料金のお支払いがありませんので、使用量に応じた金額になります。

　　
#####● 静的ファイルの配信
静的なコンテンツを配信する場合には、S3から直接公開することができます。
アクセスによる負荷の軽減に繋がります。
<br>

S3のイメージ
---

<img width="500px" alt="[S3(2).png]" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/942338/50eda97f-538f-a8fc-3282-d0c341c99ab6.png">

※ ``バケット``
S3に保存されるあらゆるオブジェクトを入れておく箱のことです。

※ ``キー``
ファイルなどが持つ固有の識別子（名前）のことです。

=> 画像やテキストデータがそれぞれURLを持ち、公開閲覧することができます。
<br>


終わり
---
最後までご覧いただきまして、ありがとうございます。
また、もし内容に誤りなどがございましたら、ご指摘いただけますと幸いです。
黒い画面の非表示 GCCオプション設定


__Windows10 + GCC__でコンパイルした、__Qt__や__GTK__などの画面を実行すると、__黒い画面__(コンソール画面)が表示される。邪魔だ!!

#CMakeの場合
GCCオプションで、__"-mwindows"__を付けると、この__黒い画面__が表示されなくなる。
FLAGでも、この方法だと、うまく動かないケースがある。


GCCのリンカーのオプションで、__-Wl,--subsystem,console__があると、この__console__が優先されるようだ。
この__subsystem__は、__console__と__windows__の選択肢があるので、後者を指定する

追加: __add_executable()__で、__"WIN32"__と指定する__だけ__でも行ける! 

```CMakeList.txt
set(CMAKE_CXX_FLAGS "-mwindows")
set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} "-Wl,--subsystem,windows")

add_executable(プロジェクト名 WIN32 ${PROJECT_SOURCES})
```

#Rust(rustc)の場合
ソースコードの先頭にマクロを指定する。

```main.rs
#![windows_subsystem = "windows"]
```

#Meson Build systemの場合
__gui_app : True__とすると、__ninja__に__"-mwindows"__を設定してくれる。

```meson.build
project('projectName', 'cpp')
executable('program', 'main.cpp', gui_app : True)
```
hostname 変更あれこれ

# はじめに
変更方法はいろいろあるみたい

## /etc/hostnameによる変更

```shell-session
$ hostname
ubuntu20
$ vim hostname

- ubuntu20
+ linux

$ sudo systemctl restart systemd-hostnamed
$ hostname
linux
$ sudo shutdown -r now
 .
 .
 .
$ hostname
linux
```

## hostnameコマンドによる変更（再起動でもとに戻る）

```shell-session
$ hostname
ubuntu20
$ sudo hostname linux
$ hostname
linux
$ cat /etc/hostname
ubuntu20
$ sudo shutdown -r now
 .
 .
 .
$ hostname
ubuntu20
```

## hostnamectlによる変更

```shell-session
$ hostname
ubuntu20
$ sudo hostnamectl set-hostname linux
$ hostname
linux
$ cat /etc/hostname
linux
$ sudo shutdown -r now
 .
 .
 .
$ hostname
linux
```

## nmcliによる変更

```shell-session
$ hostname
ubuntu20
$ sudo nmcli gen hostname linux
$ hostname
linux
$ cat /etc/hostname
linux
$ sudo shutdown -r now
 .
 .
 .
$ hostname
linux
```

## nmtuiによる設定

```shell-session
$ hostname
ubuntu20
$ sudo nmtui
```

"Set system hostname" を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143127/e2e92b22-471d-92c8-ae8f-f5a8b6ebe83a.png)

host名を入力

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143127/c3847372-125d-16f1-b2e0-9856861aa47c.png)

OK

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143127/be29734d-77e3-29ec-ee01-63e3140f1215.png)

```shell-session
$ hostname
linux
$ cat /etc/hostname
linux
$ sudo shutdown -r now
 .
 .
 .
$ hostname
linux
```
便利なset()の使いかた　Python競プロメモ②

使用言語 Python3

ランダムに抽出された6つ数字が、これとは別に無作為に選ばれた6つの数字と、何個同じ数をい持っているか、という問題。

最初はforで無理やり当てはめれば解けると考えていたが、どう考えても効率が悪い
そこでset()というものをみつけた。

ここで具体的な例で考えてみる。

```
#無作為に選ばれた数字6つ
a_1 = [1,2,3,4,5,6]
a_2 = [51,44,76,2,6,12]

ans = set(a_1)&set(a_2)
print(ans)
```
この時の出力結果は以下のようになる。

```
{2,6}
```
なのでansをlenでとってあげることで、要素の個数を取得できる。

ただ、この時、ansの中身がない場合

```
print(len(ans))
=>set()
```
とかえってしまい、0が取得できない。
こういうときは

```
if len(ans) == 0:
    print(0)
else:
   print(len(ans))
```
こう記述することで、同じ要素の個数を取得することができた。

また、set()を用いるときには帰依をつけるべき点が数点あり、
①set型の並びは不規則
②同じ要素は1つにまとまる。
トンネリングツール「Tunnelto」をRaspberry Piで使う

# はじめに
Raspberry Piを使っているとローカルに立てたサーバーやポートをネットワーク外から参照したいと思うことがあるのですが、これまでは**ngrok**などを活用してweb上から参照したりしていました。
**[Tunnlleto](https://github.com/agrinman/tunnelto)**(作者のリポジトリ)はオープンソースソフトウェア(MIT)として開発されているRust製のトンネリングツールです。

(技術的な仕様の違いとして、インストールしたPC自体にサーバを立ててる？)

TCPやhttpでの通信をしているポートを指定して外部に公開できます。


# 環境
- Raspberry Pi 3B+/4B ([Raspbian GNU/Linux 10 (buster) armv7l ](http://ftp.jaist.ac.jp/pub/raspberrypi/raspbian/images/raspbian-2020-02-14/))
- cargo (Rustのビルドツール兼パッケージマネージャー)

```
$ cargo -V
cargo 1.50.0 (f04e7fab7 2021-02-04)
```

# 構築
まずはcargoを入れましょう。
`rustup`のインストールと同時に入ります。([公式](https://rustup.rs/))
大変時間がかかるのでしばらく待ちましょう。

```
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```

入れた後に`~/.bachrc`に

```
export PATH=$PATH:$HOME/.cargo/bin
source "$HOME/.cargo/env"
```
を雑に追記しました。(sourceで変数の保持をするのって本来の用途からするとどうなんだろう...ここ相談乗って欲しい)


次に、

```
$ cargo install tunnelto
```
して`Tunnelto`をインストールします。

```
$ tunnelto --help
```
でオプションの確認ができればインストールできています。


ちなみにLinux向けに[アーカイブファイルがリリース](https://github.com/agrinman/tunnelto/releases)されているのですが、バイナリ版だと動いてくれなかったので(armだから？)、cargoを使ってインストールしました。

[issue](https://github.com/agrinman/tunnelto/issues/16)にもRaspi4にUbuntuを入れて運用しているユーザーからも`rustup`して入れてねと情報が寄せられていました。

# 使用する

`ss`や`netstat`で外部にトンネリングしたいポートを探して、`tunnelto --port 4000`すると、

```
$ tunnelto --port 4000

                              %%%%
                              %%%%
             ,,,,,,,,,,,,,,
   %%     ,,,%%%%%%%%%%%%%,,,
  #%%     ,,%%%%%,,,,,#%%%%,,
            ,,,,,,#%%,,,,,,,   ((
              .%%%#%%%%#%
                 %%%%#
                  %(%
                 (%%%(
        ((     (%%%#%%%%#
            ,,,,,,,,,,,,,,,          %%%
          ,,%%%%%%,,,#%%%%%,,
 %%       ,,,%%%%%%%%%%%%%,,,
 %%%        ,,,,,,,,,,,,,,,


⣷ Success! Remote tunnel created on: https://{yourHost}.tunnelto.dev
=> Forwarding to localhost:4000

Local Inspect Dashboard: http://localhost:XXXXX
```
と出力され、下部にリクエストとレスポンスが記載されていきます。
{yourHost}を含んだURLが外部トンネリング可能なリンクとなります。

Ctrl+Cで停止します。


# 通信の保持について

多くの場合Raspberry Piにはsshでアクセスしていることと思いますが、 **Tonnelto**を動かした状態で`exit`(セッションを終了)すると同時にプロセスが落ちます。
そこで私の場合は`tmux`で立ち上げてデタッチ後`exit`して**Tunnelto**をssh終了後も動かし続けました。

ただしこれは私の理解の浅いところで、しばらくするとセッションが切れてしまうので、Tonneltoとtmuxの仕様の両方の面をもっと勉強してみる必要があります。

通常起動後にバックグラウンドプロセスに送ってみることも試しましたが、こちらは`exit`後すぐにトンネリングが切れてしまいました。


[公式サイト](https://tunnelto.dev/)への登録で先行サービスのngrokのようにwebサービス上でのステータスが確認しやすくなるのかは追って確認していきます。

なお、サブドメインを立てる値段は$2/monthらしいので競合より安いみたいですね。




# その他

- mac版はbrewでも入るそうで、一層かんたんに導入できますね。

- 私の場合はDockerでポート3000に立てたGrafanaを外部公開する目的でTunneltoを使いました。

- ngrokではサーバーの立ち上げ後`curl localhost:80/api/tunnels`でpublicに公開されているURLを取得してこれるのですが、**Tunnelto**にはこの機能はまだありません。
ポートの公開開始時に`Success! Remote tunnel created on: ~~`が表示されるのにコンソール上のプログレス表示を伴うので、`nohup`などで出力すると肝心のURLが標準出力として吐き出されないという困った点があります(これもあって前述のtmuxなどを使った)
これについても何か対応したいとのコメントが[issue](https://github.com/agrinman/tunnelto/issues/25)にありました。

# リンク
[agrinman/tunnelto](https://github.com/agrinman/tunnelto)(Github)
[Tunnel to dev](https://tunnelto.dev/)(サービス版公式サイト)
MkDocs (Markdown Document Framework)

MkDocsはmarkdownでドキュメントを作るためのフレームワークです。
簡単に設定をしたら、[このようなドキュメント](https://squidfunk.github.io/mkdocs-material/getting-started/)が書けます。
markdownで書いてビルドすると、静的htmlサイトが作成されます。

## 動機
WordやExcelなどでドキュメントを書くのが割りと多いと思いますが、ドキュメントの種類によって、markdownの方が向いている場合があると思います。

markdownで個人的に思う便利なところ：

- 軽い
    - ただのテキストファイルなので、重たいソフトを使わなくても編集できる。
- 差分管理
    - gitを使って、簡単にバージョン管理ができる。
- スタイル
    - 単純なテキストをhtmlにコンパイルすると、いい感じのスタイルになる。
- プラグイン
    - プラグインを追加することで、markdownの機能を増やして、もっと便利に使うこともできる。

「手順書・Wiki・API仕様書」などはmarkdownに向いていると思います。

ただ、markdownをそのまま書いてしまうと、毎回`.md`ファイルを更新したり、htmlに変換し直したりするのが面倒だし、忘れがちです。
また、 チームで使う時、ツールやスタイルやプラグインを合わせる必要もあります。

上記の課題を解決するために、markdownのフレームワークを調べてみたいと思いました。
以下のサイトに様々な静的サイトジェネレーターがあります。
https://jamstack.org/generators/

この中いくつか調べて、MkDocsは一番ドキュメント作成にいいと思いました。
（他にもっと良さそうなのがあれば教えてください。）

## MkDocsについて
MkDocsのドキュメント： https://www.mkdocs.org/

MkDocsはpythonでツールをインストールしてから使えます。

プロジェクトを作成すると、1つのyaml設定ファイルと簡単なフォルダー構成が作成されます。
テーマやプラグインをyamlに追加して、いろいろカスタマイズできます。
コマンドを起動し、ブラウザー上で確認できます。

#### MkDocsのいいところ：
- :white_check_mark: 軽くて速い
- :white_check_mark: ローカルブラウザーでサイトのhot-reloadができる
- :white_check_mark: 検索機能がある
- :white_check_mark: 様々なテーマやプラグインを追加できる
- :white_check_mark: カスタムcssとjsで細かいところまでカスタマイズできる

## Material Theme
今のところ、MkDocsの気に入っているテーマは「material」っていうテーマです。
テーマ自体に様々な機能が入っています。

ドキュメント： https://squidfunk.github.io/mkdocs-material/reference/abbreviations/

以下のgifでいくつかの機能を見せます。

![mkdocs-material.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351787/c9089d8b-1ee0-a53b-8931-82a72264583f.gif)


### Mermaid
mermaid対応はまだできていないですが、開発中らしいです。
https://github.com/squidfunk/mkdocs-material/issues/2170
https://squidfunk.github.io/mkdocs-material/reference/diagrams/

mermaid対応が来たら、Flowchart・シーケンス図・ガントチャート・など...をmarkdownで書けるようになります。

例：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351787/e994b197-d337-1d8a-c24b-ce9fe8155b1d.png)


mermaidはいろいろできるので、ぜひ確認してください。（VSCodeのプラグインもあります。）
https://mermaid-js.github.io/mermaid-live-editor


## これから
まだそんなに使ってはいないですが、役に立ちそうなので、機会があれば、実際のプロジェクトに導入して、試してみたいです。

静的サイトなので、S3で簡単にホスティングできて、IP制限も付けたら、プロジェクトの内部資料としても使えそうだと思います。
【お名前ドットコム】独自ドメインをサーバーに紐付ける【さくらのVPS】

XserverからさくらのVPSにレンタルサーバー を変更しました。
それに伴い、さくらのVPSサーバーに独自ドメインを引越しさせました。
かなり時間がかかってしまったので、手順を覚えたくて記事にしました。

もともとXserverはワードプレスでブログを書きたくて契約しましたが、その時は独自ドメイン化を記事見ながらしたので手順など分からなかったです。

## こんな人に向けての記事
- 独自ドメインでブログを書きたい
- 独自ドメインのwebアプリをリリースしたい


## 前提条件
- 独自ドメインの契約が完了している
- 自前サーバーを持っている


## 実現したいこと
- さくらのVPSレンタルサーバーを独自ドメイン化する

## 作業環境
- OS
    - CentOS7
- webサーバー
    - Nginx

## 参考サイト
- [独自ドメインの設定方法](https://www.sakura-vps.net/original-domain-settings-for-sakura-vps/)
- [ドメイン側のネームサーバー設定](https://www.onamae.com/guide/p/67)
- [VPS側のネームサーバー設定](https://help.sakura.ad.jp/206207381/)
- [お名前ドットコム](https://www.onamae.com/)


## 手順
1. 独自ドメインの取得
2. ドメイン側のネームサーバー設定
3. VPS側のネームサーバー設定

### 1. 独自ドメインの取得

独自ドメインはお名前ドットコムで取得できるので、先に取得しておいてください。
[お名前ドットコム](https://www.onamae.com/)

実際の作業に入る前にある程度の知識が必要になったので、図にしました。
独自ドメインをサーバーに紐付けた場合の流れです。

![domain (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679892/e59abca4-55ad-8a6f-a846-a8402c9c635c.jpeg)


1. ブラウザでお名前ドットコムサーバーへドメイン要求
2. お名前ドットコムサーバーがDNSサーバーに問合せ
3. DNSサーバーが登録してある表を元にさくらのVPSサーバーに確認
4. さくらのVPSサーバーからDNSサーバーに応答
5. DNSサーバーからお名前ドットコムサーバーにIPアドレスを送る
6. お名前ドットコムサーバーからブラウザにIPアドレスを送る
7. ブラウザからIPアドレスを元にさくらのVPSサーバーにアクセス
8. さくらのVPSサーバーからデータを取得

![domain (2).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679892/0f5631b4-112e-d118-2794-796e7e9eeb75.jpeg)

このうち２、３が設定されていないので、今から作業を行い設定していきます。

### 2. ドメイン側のネームサーバー設定

[ドメイン側のネームサーバー設定](https://www.sakura-vps.net/original-domain-settings-for-sakura-vps/)を参考にしてください。

さくらのVPSではDNSサーバーを以下にしています。

- ネームサーバー1	ns1.dns.ne.jp
- ネームサーバー2	ns2.dns.ne.jp

これで②をつなげることができました。
![domain (3).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679892/15db9ed3-74e6-117e-9e6c-6d024747f7a2.jpeg)

### 3. VPS側のネームサーバー設定

[VPS側のネームサーバー設定](https://help.sakura.ad.jp/206207381/)を参考に設定してください。
以上でDNS設定は完了になります。
③をつなげることができました。
![domain (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679892/5d99bfc0-4016-6a5a-3e6f-e70c3ea39aca.jpeg)


実際に反映されるまでに24~48時間ほどかかるようです。
すぐ反映されなくても焦らずに待てばいいです。

## 参考サイト
- [独自ドメインの設定方法](https://www.sakura-vps.net/original-domain-settings-for-sakura-vps/)
- [ドメイン側のネームサーバー設定](https://www.onamae.com/guide/p/67)
- [VPS側のネームサーバー設定](https://help.sakura.ad.jp/206207381/)
- [お名前ドットコム](https://www.onamae.com/)

間違いなどありましたら、コメントで教えていただけると助かります。
デプロイの手段について

今回オリジナルアプリを公開するにあたって
Herokuのサービスを利用しデプロイを行いましたが
他にも手段がありその種類を記事にしたいと思います。

デプロイの手段の前に、よくデプロイの工程で用いられる、
仮想サーバーとコンテナについて説明したいと思います。

### 仮想サーバー
仮想サーバーとは1台のサーバーで仮想的に複数のサーバーを稼働させる仕組み。
仮想サーバーを用いない一般的なサーバーであれば、1つのサーバーで1つのOSが稼働する。
しかし、仮想サーバーを用いると、複数のサーバーを仮想的に稼働することができる。
このような仕組みは処理速度の向上や保守コストの削減などさまざまな利点があるがデメリットもある。

■デメリット
・消費するメモリが膨大であること
・高度な技術が必要であること
・設定や管理などの負荷がかかること

### コンテナ
「他のユーザーから隔離された実行環境」のことをコンテナと呼ぶ。
コンテナは、ホストOS上に作成されるもの。
コンテナは、1つのOSで稼働するためメモリの消費は少なく、ストレージの使用もわずかで済む。したがって、仮想サーバーに比べて起動時間が短く、同じ性能のハードウェアであれば、より多くのコンテナを同時に動かすことができる。

### Docker
コンテナ化を用いてアプリケーションを開発・配置・実行するためのオープンソースソフトウェア。
圧倒的なシェアを占めている。

## デプロイの手段

### カナリアリリース
一部のユーザーにのみ新機能の公開を行い、新しいバージョンにバグなどがないかを検証する手法。
もし新しい機能に不具合があったとしても、サービス全体には影響を及ぼさずに済む、
というメリットがある。

### ブルーグリーンデプロイメント
ブルーグリーンデプロイメントとは、仮想サーバーを用い、2つの本番環境を用意する。それぞれバージョンを設定することができる「デプロイの運用方法」。
サーバーAは、新しいバージョンを反映させた環境で「グリーン」とし、サーバーBは、古いバージョンの環境で「ブルー」とする。万が一、サーバーAの環境の「グリーン」に問題が起こった場合は、サーバーBの環境の「ブルー」にリクエストの向きを戻す事で、容易にロールバックを行う事ができる。
デプロイ後、「ブルー」と「グリーン」の位置づけは変わり、同じ工程を行うことで継続的なデプロイができる。
デメリットとして、デプロイを行わない期間は新しいバージョンを反映させる「グリーン」の運用コストが発生する。
しかし、継続的にデプロイを行えるメリットが大きいと考えられる。

### イミュータブルデプロイメント
コンテナ技術を用い、常に変更を行わない環境を構築することで、デプロイ時に新しい環境に切り替える手法。
コンテナの技術を用いることで、環境自体を新しく構築する作業が容易になり、誕生したデプロイ手法。古い環境は削除するため、運用コストを抑えることが出来る。
ブルーグリーンデプロイメントと似ているが、「古い環境は削除する」という点が大きな違いです。
AKS と Azure AD とを統合している途中でクレデンシャルを失ったときのリカバリ手段

# 症状

Azure のチュートリアルどおりにやれば失敗しないはず…なのだが、ちょっと間違えると、こういう羽目に陥る可能性がある。

```
az aks get-credentials -g <AKSのリソースグループ> -n <AKSのクラスタ名>
```

を行い

```
A different object named clusterUser_camino_camino-wus-2 already exists in your kubeconfig file.
Overwrite? (y/n): 
```

に気軽く `y` し

```
Merged "camino-wus-2" as current context in /home/monaka/.kube/config
```

と表示されているにも関わらず危機感なく


```
$ kubectl get po -n kube-system
```

からの

```
To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code S4GMR4BN2 to authenticate.
```

など言われるので、言われたとおりに認証してみると

```
Error from server (Forbidden): pods is forbidden: User "monaka@example.com" cannot list resource "pods" in API group "" in the namespace "kube-system"
```

`default` namespace にある pod も読めない。`kubectl get nodes` も通らない。かなり焦る。

# 解決手段

```
az aks get-credentials -g <AKSのリソースグループ> -n <AKSのクラスタ名> --admin
```

`--admin` がミソ。リソースグループ名は `MC_` が付かないほう。

右も左もわからない状態で `get po` さえ通らない状態になると、割と動転するので、メモ。
Pythonライブラリ Cerberus によるバリデーション処理 メモ


## Cerberusとは

* Pythonのオープンソースバリデーションライブラリ。
* [公式](https://docs.python-cerberus.org/en/stable/index.html)



## 準備

```shell
pip install cerberus
```



## 利用方法

### 基本的な使い方

```python
from cerberus import Validator
# バリデーション対象パラメータのスキーマ定義し、バリデーターにセット
schema = {'name': {'type': 'string'}, 'age': {'type': 'integer', 'min': 10}}
v = Validator(schema)

request_body = {'name': 'Little Joe', 'age': 5}

# バリデーション実行
v.validate(request_body)
>> False

# エラー理由
v.errors
>> {'age': ['min value is 10']}
```

#### 未定義のパラメータを許容する場合

```python
v.allow_unknown = True
```



### 独自ルールでバリデーションを行いたい場合

* リクエストボディに指定されたメールアドレスに対して正規表現でバリデーションを行う場合。
* 独自定義バリデータークラス：`extendedValidator.py`

```python
import re
from cerberus import Validator

class ExtendedValidator(Validator):
    def _validate_email(self, email_address, field, value):
        if (email_address and not re.match('^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$', value)):
            self._error(field, 'invalid_email_address')

```

* バリデータにセットするスキーマ定義クラス:`const.py`
  * メールアドレスの基本バリデーションルールを定義する。

```python
# setter制御用メタクラス
class ConstMeta(type):
    def __setattr__(self, name, value):
        if name in self.__dict__:
            raise self.ConstError()
        self.__dict__[name] = value
# スキーマ定数定義
class ValidatorConstClass(metaclass=ConstMeta):
    req_schema = {
        'email_address': {
            'type':        'string',
            'required':    True,
            'empty':       False,
            'maxlength':   128,
            'valid_email': True
        }
    }
```

* バリデーション処理実行クラス:`test.py`

```python
import const
from extendedValidator import ExtendedValidator
...

# 独自定義したバリデーターをセット
validator = ExtendedValidator(const.ValidatorConstClass.req_schema)

# バリデーション実行
if not validator.validate(req_body):
   return {'result': 'validation_error', 'errors': validator.errors}
```



## 参考情報

* [Cerberus Usage](https://docs.python-cerberus.org/en/stable/usage.html)
* [Pythonのクラス変数を定数(再代入禁止の変数)として扱う - 名前空間を分けたい](https://cream-worker.blog.jp/archives/1077207909.html)
* [Python FlaskでREST APIを作る](https://qiita.com/trustbank_kei/items/c72c57b54332431c67ec)
eclipsを使ったJavaでmain型が含まれているのにもかかわらず、「エディターにはメイン型が含まれていません」と出た時の、対処法。


備忘録

eclipsで、main型が含まれているのにもかかわらず、「エディターにはメイン型が含まれていません」と出た時の、対処法。
　↓
まず、main型が含まれているソースコードをコピーする。
　↓
そして、そのsrc下のソースコードを削除する。
　↓
新しくクラスから作成する。
　↓
新しい画面に出ているものを削除する。
　↓
コピーしていたものを貼り付ける。
　↓
復活する。
【PAD】PADとCOTOHA APIでルー大柴翻訳をトゥギャザーする

# 概要

以前作成したルー大柴BotをPowerAutomateDesktopで作ってみる。
※今回はBotではなく、入力した文章を翻訳して出力するまでの練習

[【GAS】GASとCOTOHA APIでルー大柴Botをトゥギャザーする](https://qiita.com/Mikoshiba_Kyu/items/97a8b9a452e22edbe6d4)

* PowerAutomateDesktop Preview(無料アカウント)
* [COTOHA API](https://api.ce-cotoha.com/contents/index.html)
* [Google翻訳](https://translate.google.co.jp/?hl=ja)

# 動作

フローを実行するとInputダイアログが表示される。
ここに翻訳してもらいたい日本語の文章を入力する。

![input.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219708/c775fbe7-d92b-cde1-4ca4-58171f1fd732.png)

するとこんな感じで、程よく(？)英語翻訳された文章が出力される。

![output.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219708/a78a9052-d4b6-b889-0b9c-969c29f950ab.png)

翻訳にはGoogle翻訳を使用している。
ちなみに普通に翻訳すると結果はこうなる。

![デフォの翻訳.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219708/6fc91f4e-f650-3ae8-beb6-ab6377c41949.png)


# 中身


## 開始処理

まずは **入力ダイアログを表示** のアクションで文章を入力してもらう。
入力値が空白でなかった場合は処理を開始する。

![フロー1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219708/6763d3c1-c22a-9b28-b3dd-721cac5339a7.png)


## COTOHA API で構文解析後のjsonを受け取る

次にCOTOHA APIのトークンの取得と、インプットされた文章の形態素解析を行う。
COTOHAの処理に関してはサブフローにまとめている。
内容については割愛するが、**Web サービスを呼び出します** のアクションでいける。

![フロー2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219708/d6631adc-4c0e-c0f9-ce48-b963ca36662d.png)

### 確認ポイント

* サブフローと変数のスコープ

    当初、元になる文字列を引数として渡し、解析結果のjsonを戻り値として受け取るイメージで
    サブフローに切り分けたが、どうやらサブフローにはそのような仕組みはなさそう (未調査)
    変数はすべてパブリックスコープになっているっぽい。
    とはいえ、個人的にはRPAツールの仕組み上スコープを細かく分けると
    あとから全体を確認するのが大変だと感じている。
    UiPathでフローを作る時も変数スコープは大きな箱と小さな箱の2段程度にしている。

## 構文解析結果をパースする

レスポンスのjsonをカスタムオブジェクトに変換し、
result 内の tokes 内の form と pos の値をそれぞれのリストに格納していく。

![フロー3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219708/6acb7dcb-c7a8-9bd1-b3a3-cc1b3079c4b9.png)

### 確認ポイント

* リスト

    二次元配列の使い方を見つけられなかったので、個別のリストを作成した。

* オブジェクト内要素のカウント

    カウント方法についてはZero Sys(@sys_zero )さんの記事を参考にさせていただいた。
    
    [Power Automate Desktop「俺のデスクトップはきたない」を何とかする](https://qiita.com/sys_zero/items/6e6d14c854f322d586c0)

    オブジェクト要素に対してcount関数を指定することが出来た。
    `%JsonAsCustomObject2['result'].count%`

## Google翻訳を使用してガチャガチャする

最後にChromeからGoogle翻訳のページを開き、
WordListの値をHinshiListの独自ルールに基づいて翻訳し結合する。
詳細は割愛する。

![フロー4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/219708/609ac144-9a0d-8cc9-af88-37622e1e97ca.png)

### 確認ポイント

* 翻訳

    現在のPADにはIBMの **翻訳** のみがある。
    これはWebAPI経由で使用するIBMのサービスのようなので今回は使用しなかった。
    GASの場合はGoogle翻訳が直接使用できて便利だったので、PADにもカジュアルな翻訳アクションが欲しくなる。

* Webレコーダー

    Google翻訳のページはWebレコーダーで取得した。
    検索結果表示のテキストボックスは上位のdivタグが取得されていて、それだけでも十分だったが
    検索結果によっては余計なテキストが含まれてしまうことがあったので、セレクタービルダーから厳密に調整した。

    ※ディスプレイがメイン4kでサブFHDの環境のせいか、サブ側ではWebレコーダーがうまく機能しなかった。(これは仕方がないと思う)

## 所感

という感じで、実際なんの意味もない機能ですが、
PADの練習には申し分ない題材となりました。

**なぜPADをUseのか。ThereにPADがIs Thereからだ。**
【シェルスクリプト】ファイルを1行ずつ読み込んで処理する方法

while read文を使って次のようにするとテキストファイルを1行ずつ読み込んでなんやかんやすることができます。(Solarisではこの書き方はできないようですが、あまり使われていないOSですので考慮しなくても良いと思います。)

```sh
#!/bin/bash

FILE_NAME=/fuga/hoge/fizz.txt
while read LINE
do
# コマンド
done < ${FILE_NAME}

```

while文に\${FILE_NAME}をリダイレクトするとreadコマンドで\${FILE_NAME}の中身を1行ずつ読み込んでLINEという変数に格納します。(変数名はLINEでなくても問題ありません。)

このようなコードを使うと「3カラム目の値がfizzである行を判別してうんたらかんたらする」みたいなことができます。

#### 注意点と回避策

while文の末尾でリダイレクトする都合上「どのファイルを読み込んでいるのか」ということが上からシェルスクリプトを読んでいくと分かりづらいので、while文の上にコメントで「このファイルを読み込みます」ということを書き添えておくと良いと思います。

```sh

FILE=/hoge/fuga.txt

# FILEを読み込んで処理
while read LINE
# コマンド
done < "${FILE}"
```

#### for文ではファイルを1行ずつ読み込めない

私は当初for文で上記の処理を実現しようとして次のようなコードを書いていました。

```sh

FILE=/hoge/fuga.txt
# これは動かない
for LINE in "${FILE}"
do
# コマンド
done
```


結果から言うとこのコードは動きませんでした。
ディレクトリを読み込んでファイルを1つずつ処理することができたので、その延長線上で考えてファイルを1行ずつ処理することもできるやろ、程度に考えてしまいました。

```sh

# ディレクトリ内にあるファイルを1つずつ読み込む
# これは動く
for FILE in /usr/local/hoge/*
do
  echo $FILE
done
```

ファイルを1行ずつ読み込む場合は **「while read line」**と覚えると良いでしょう。
JPQLでQueryにSQL書いたらエラー

## 環境
spring-boot
JPQL

## 経緯
SpringSecurityの勉強でForm認証したかったのでPostgresSQLからデータを引っ張ってきたのだけど、Spring-boot起動時エラー

## エラー内容
[table_name] not mapped

## 対応方法

```
	@Query("select n from [XXX] n where user_id = :value")
	List<Name> findByUserId(@Param("value") String value);
```

[XXX]のところは実際のテーブル名でなく、Entityのクラス名でした。
グーグルフォントの使い方

## グーグルフォントとは？
Googleが提供しているフォントサービスのこと。約１０００種類以上も無料で使えるフォントがあるそうです。ただ、日本語のフォントは少ないので注意が必要です。
今回WEBページ作成で初めて使用したので書き残しておきます。
## フォントを選ぶ
[グーグルフォント](https://fonts.google.com/)
使いたいフォントを選びクリックする。

![](https://gyazo.com/5db63b260e9619569fc7c0e00df86252.p)

クリックしたら使いたい太さ選び、以下の画像のボタンをクリック
![](https://gyazo.com/7d091704ca05c864bebd5a0850a8ac30.p)
右側に以下のLINKコードが出てくるのでそれをHTMLファイルに貼り付けます。
![](https://gyazo.com/aee4e327dff4888d542364be2c4d9802.p)
cccファイルにも適用したいクラスにfont-family:'Cavet',cursive;を貼り付け適用させます。

以上になります。
初心者のため間違いがあればご指摘お願いします。
【Unity】RendererFeatureの値をランタイムで変更したい

URPの場合は以下のようにRendererFeatureにアクセスできます。

```csharp
var pipeline = ((UniversalRenderPipelineAsset)GraphicsSettings.renderPipelineAsset);
var propertyInfo = pipeline.GetType().GetField("m_RendererDataList", BindingFlags.Instance | BindingFlags.NonPublic);
var scriptableRendererData = ((ScriptableRendererData[])propertyInfo.GetValue(pipeline))[0];
var renderObjects = (RenderObjects)scriptableRendererData.rendererFeatures[index];

renderObjects.settings.depthCompareFunction = CompareFunction.Greater;
scriptableRendererData.SetDirty();
```

値を変更した場合、ScriptableRendererData.SetDirty() を呼び出すことで変更が反映されます。

![RendererFeatureChange_gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/905530/b87db707-1943-628b-f3d6-4ea4ffc9c3f2.gif)


自作RendererFeatureを実装している場合は以下のようにアクセスできます。

```csharp

var myRendererFeature = scriptableRendererData.rendererFeatures.OfType<MyRendererFeature>().FirstOrDefault();
```

---
Unity 2020.1.17f1
Universal RP 8.3.1
AWSへの多段接続とconfigエラーの解決

1■AWSへの多段接続
-
aws上で、踏み台サーバとwebサーバを作成したため
踏み台サーバ経由でwebサーバへのsshでのログインを試みました。
![図2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1189399/9b9a682f-d5a1-6d4b-f110-f89a3a71eacb.png)
図1:configファイル(※拡張子を必ず無しにする)
上記のconfigファイルを秘密キーと同じフォルダに作成し、

￥ssh 接続先サーバ名

をcmdで入力するとログインできました。

2■AWSへの多段接続時に発生したエラーについて
-
作業中に、Bad configuration optionが大量発生したため下記対応をしました。
①記述ミス
誤)IdentifyFile
正)IdentityFile

誤)Users
正)User

誤)~/.ssh/■■.pem
正)./.ssh/■■.pem
②スペースの削除
誤)
Host 〇〇
　　　　Hostname ××
　　　　........

Host △△
　　　　Hostname □□
　　　　........
正)
Host 〇〇
Hostname ××
........

Host △△
Hostname □□
........

以上の修正で多段接続ができました。
【学習メモ】AWS SQS  Loose Coupling

#Loose Coupling
疎結合の意味。密結合の反対。
システム上で、各要素が独立し、互いの関連性が弱い。
疎結合の設計によって、一部のシステム要素は故障が起きても、影響が他の要素に及びにくいというメリットがある。また、一つの要素を修正しても、他の要素への影響を考えなくても良いメリットもある。

#SQSとは
SQS（Simple Queue Service）
二つのプログラムが通信する際にポーリング処理を実施するサービス。

本来ならば、直接通信だと、受信側の処理がいっぱい溜まってて、送信側のキューがうまく届かないかもしれない。
SQSは中継所みたいな役割を果たして、送信側が送ってきたキューを溜め込んで、受信側が通信内容を問合せして、SQSの中にキューがあれば送信。

・SQSの中身は Request QueueとResponse　Queueがある。
![SQS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1082021/b19e73ec-e2c7-ec85-f38c-a21cd45a5780.png)

##特徴
・フルマネージド型
・高可用性：複数のサーバー/データセンターにメッセージを保持する。
・高スケーラビリティ：多数の送信者と受信者に対応可能。
・高スループット：メッセージが増加しても高スループットを維持できる。
・低コスト：無料枠あり、従量課金。

◯メッセージサイズ：最大256KB
※Extended Client Libraryを利用すると、2GBまでのメッセージの送受信が可能。

◯保持期限：
デフォルト：4日間保持
※60秒から14日の間で変更可能。

※30日以上、キューに以下のリクエストがない場合、SQSはそのキューを削除する可能性がある。
SendMessage、ReceiveMessage、DeleteMessage、GetQueueAttributes、SetQueueAttributes。

##処理形式
二つの処理形式がある。
◯標準キュー
◯FIFO(First in First out)

###標準キュー
なるべく順番通りに処理するが、順番が前後する場合もある。
少なくとも 1 回のメッセージ配信をサポートする。

###FIFO
順番通りに処理。最初に入ったキューを優先的に処理。

##SQSの追加機能
####Short　Poling
キューが空の場合でも即時にリターンする。

####Long　Poling
キューが空の場合はタイムアウトまで待つ。

※Long　polingとShort PolingはReceive Message Wait Timeで設定する。
0=Short Poling。最大は20まで。


####Visibility　Timeout
®️ref:https://docs.aws.amazon.com/ja_jp/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-visibility-timeout.html

```
コンシューマーがキューからメッセージを受信して処理しても、そのメッセージはキューに残ったままです。
Amazon SQS では、メッセージが自動的に削除されません。
Amazon SQS は分散システムであり、接続の問題やコンシューマーアプリケーションの問題などが原因で、
コンシューマーが実際にメッセージを受信するという保証がないためです。
そのため、コンシューマーはメッセージを受信して処理した後、キューからメッセージを削除する必要があります。

メッセージが受信された直後は、メッセージはキューに残ったままです。
他のコンシューマーが同じメッセージを再処理しないように、Amazon SQS は可視性タイムアウトを設定しています。
Amazon SQS では、この時間内に他のコンシューマーが同じメッセージを受信したり処理したりすることはできません。
メッセージのデフォルトの可視性タイムアウトは 30 秒です。
最小値は 0 秒、最大スケールは 12 時間です。
```
showModalBottomSheetで角が丸いContainerを表示する【Flutter】

#はじめに
showModalBottomSheet()というメソッドを利用することで、「下からニョキっと出てくるウインドウ」のようなものを作ることができる。

今回は、それを使って「角が丸いContainer」を表示する。
以下の画像のような感じ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1109597/4c1a6d77-5ce7-6053-b0ad-89d5d22b5d7a.png)

上辺の両端を見ていただけたらお分かりの通り、角が丸い。
角を丸くするためにはRoundedRectangleBorderウィジェットを利用するのだが、__普通に使うとContainerとの相性が悪いようである。__
それについては、後で解説する。

#コード
では早速、コードを全文載せておく。

```dart:main.dart
import 'package:flutter/material.dart';

void main() => runApp(MaterialApp(
      home: MyApp(),
    ));

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ElevatedButton(
          child: Text('Push'),
          onPressed: () {
            showModalBottomSheet(
                context: context,
                isScrollControlled: true,   //trueにしないと、Containerのheightが反映されない
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.vertical(top: Radius.circular(15)),
                ),
                builder: (BuildContext context) {
                  return Container(
                    height: 540,
                  );
                });
          },
        ),
      ),
    );
  }
}
```

showModalBottomSheetのプロパティとして、isScrollControlledとshapeを指定している。
それ以外は、いたって単純。
__isScrollControlledはtrueに設定しないと、Containerのheight設定が反映されないので、注意。__

これで、ボタンを押すと画像のようなウインドウが表示されるアプリができた。

##難点
Containerの色を変更したいときはどうすればよいのだろうか。
__実はContainer内でcolorプロパティを変更しても、うまくいかない。__

試しにContainerウィジェット内をこう書き変えてみてほしい。

```dart
                  return Container(
                    height: 540,
                    color: Colors.red,
                  );
```
colorプロパティにColors.redを指定して、赤色にしようとしている。
実行すると、こうなる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1109597/a3c2fd35-4055-60ac-17b2-c82ed1cee13c.png)

__角が四角い！！__

これはガッカリした。
どうやら角を丸くしつつ、色を変更するためには、ContainerではなくshowModalBottomSheetそのものの引数に渡さないといけないみたい。

というわけで、showModalBottomSheet内をこう書き変えると、うまくいく。

```dart
            showModalBottomSheet(
                context: context,
                isScrollControlled: true,
                backgroundColor: Colors.red,   //これを追加した
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.vertical(top: Radius.circular(15)),
                ),
                builder: (BuildContext context) {
                  return Container(
                    height: 540,
                  );
                });
```

実行すると、こうなる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1109597/61dceeff-9802-c703-0d08-87f6b9d5f059.png)

これで一件落着！
JavaScriptでクリップボードにコピーする機能を作成

# 概要
JSでクリップボードにコピーする機能を作成する方法を調べた際、navigatorのwriteTextメソッドを使用すると可能とあったのですが、HTTP環境だと使用できないので別の方法を調べました。
またVue.jsで処理している値を取得したかったので、どちらも可能な方法を調べました。
そもそもクリップボードにコピーする機能はライブラリを導入する方法もあったのですが、今回はライブラリを導入しない方法を探しました。

# 環境
PHP：v7.3.11
Vue：v2
# 実装
* クリップボードにコピーするメソッド(ViewModelクラスに記載)

```
public copyClipBoard(str: string) {
    const targetSentence = str;
    let input = document.createElement('input');
    input.readOnly = true;
    document.body.appendChild(input);
    input.value = targetSentence;
    input.select();
    document.execCommand('copy');
    document.body.removeChild(input);
}
```

* 今回はボタンを押した時にコピーできるようにしたかったので、トリガー用のメソッドを記載

```
doCopy() {
    _viewModel.copyBoard("コピーしたいテキスト");
}
```

* HTMLの実装

```
<button class="copy-clipboard" @click="doCopy">クリップボードにコピー</button>
```

# まとめ
* 今回はJSでクリップボードにコピーする方法についてまとめました。  
* 2行くらいでシンプルにかけるかと思っていたのですが、意外と量が多かったため記事にしました。
A New Supervised t-SNE with Dissimilarity Measure for Effective Data Visualization and Classification

[paper link](https://dl.acm.org/doi/pdf/10.1145/3328833.3328853)

<img width="1119" alt="スクリーンショット 2021-03-14 14.10.16.png (158.3 kB)" src="https://img.esa.io/uploads/production/attachments/9763/2021/03/14/69070/d13aaea8-afac-4419-b864-9c1b7724d7fa.png">


# Abstract
- class情報に関した非類似度を用いた新しい教師ありt-SNE (S-tSNE) を提案
- 分類問題用の特徴量抽出として汎用的な手法であり、MNIST / Chest x-ray / SEER Breast Cancer の3データセットで実験
- k-NNを用いて判別問題を解かせた
- t-SNEと比較して、実験のaccuracyが20%以上向上した

# Contribution
- 既存のsupervised t-SNEの一般化
- k-NNで分類問題を解いた際に、t-SNEよりも精度向上

# Method
1. S-Isomapで用いられている重み付けを利用する。このとき、以下の性質が成り立つ。
$D(a_i, a_j | t_i = t_j) \leq D(a_i, a_j | t_i \neq t_j)$
![スクリーンショット 2021-03-14 15.00.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426293/f1622319-66ff-87b5-7205-6ae28375bf04.png)


1. 重み付けしたデータ間距離を用いてt-SNEの条件付き確率を計算

# Experiment
t-SNEと同様に計算時間が大きいのでデータセットの一部をランダムサンプリングして使用。ただし、ラベル毎のデータ分布は保つようにしている。

## Benchmark
![スクリーンショット 2021-03-14 15.01.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426293/2952c42c-3288-75e2-dc3c-638f91440247.png)


## Qualitative Results
![スクリーンショット 2021-03-14 15.03.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426293/4cffc827-911f-f2f3-cb16-d27c0dd88395.png)


# Consideration
2019年時点でも判別問題を解く際にk-NNを用いて低次元空間の評価をしているが、どの程度受けがいいのか気になる。


# misc
- PCAは非線形データに弱い
- IsomapとLLEはデータの分布が局所的である場合しか機能しないが、t-SNEはデータの分布が広範でも機能する
- 教師なしの次元削減では、classification / regressionに適した特徴量抽出が難しい
- 教師ありの次元削減一覧
    1. Euclidean distanceの代わりにデータ間の非類似度を利用
        - WeightedIso (同じラベルのデータ間距離を小さく重み付け)
        - S-Isomap (WeightedIsoよりも複雑な重み付け)
        - Supervised LLE (異なるラベルのデータ間距離に正の値を加える)
        - Supervised Enhanced LLE (同じラベルのデータ間距離は小さくし、異なるラベルのデータ間距離は大きくする)
    1. データ固有の情報を利用
        - supervised t-SNE (同じラベルのデータ間距離にデータ固有の情報を用いた値を乗ずる)
PCのHDDをSSDに換装した

#####2021年3月10現在
#####無料でHDDクローンソフトを使って、ノートPCのHDDをSSDに換装したので記す

＜準備＞
PCのOS　　　　　
windows10
購入　　　　　　
SSD/2.5inch/7mm 256GB　1個3980円　、HDD/SDDケース/2.5inch/7mm　1個800円
ソフトのインストール
AOMI Backupper　試用版　で無償でクローン作成可能

    手順
    SSDをPCにUSB接続
    AOMI Backupper　を立ちあげる
    新規クローンを作成する（元ソースHDDとターゲットSSDを選択し、実行）
    1時間後クローン作成完了
    PCの電源を切り、古いHDDを取り出し、新しいSSDに交換する
    電源を付けて起動を確認
    完了!

＜換装した感想＞
起動が速くなった
実測で起動後30秒でブラウザを立ちあげることができる
アプリケーションの表示がきびきびしている
興味がある人なら是非お薦めします！

see you , GOD BLESS YOU !
Material-UIのLinkコンポーネントとreact-router-linkでページ遷移させる

Reactのmaterial-uiのLinkとreact-router-linkを使ってページ遷移させる書き方が微妙にわからなかったので備忘録がてら。
ルーティングの記述は書いてある前提とします。



```Link.jsx
import { Link } from "@material-ui/core";
import { Link as RouterLink } from "react-router-dom";

const LinkComponent = (props) => {
  return (
    <Link
     component={RouterLink}
     to={props.to} //遷移先
     color="primary"
    >
     {props.text} //表示するテキスト
    </Link> )
}

```

## 解説
ポイントはMaterial-UIのLinkのcompnentにreact-router-domのLinkを渡すことです。
Linkで名前が被ってしまうので、そこはasを使って別名にしてます。

同じような悩みを持っている方のお役に立てれば幸いです。

## 参考
https://material-ui.com/components/links/
https://material-ui.com/guides/composition/#link
ワークシートに並べておいた定数をVBAから取得するときに便利な関数

VBAでプログラムを作るときに、データがあるフォルダへのパスとか、出力ファイル名の形式とか、部署名とかそういったものを、ワークシートに並べておく、ということをよくやる。こうすると、VBAの知識がない人間にもメンテナンスができるし、場合によっては他の用途に流用するのも容易である。
もっともあとで「こーゆー定数を追加したい」ということが（結構）多く、メンテが大変。最初はセルに名前つけてたりしたのだけども、簡単には一覧が出せなかったりするので管理が大変。

そこでわかりやすい方法を考えました。

定数の項目見出しは特定の列にあると仮定したうえで、見出しには何らかの色を塗っておく。それらの数値の入ったシートをアクティブにして、入力されている列を渡してやると、項目見出しをキーにして設定された定数をペアにした連想配列を返す、というもの。

```
Function 項目値の連想配列(列数 As Long) As Collection

'アクティブシートの指定した列で、色がついているものについて、
'その列と、すぐ右に入力された値を連想配列にして返す。

Dim i As Long
Dim 最終行 As Long
Dim ans_col As Collection

Dim セル値 As Variant
Dim 項目値 As Variant

    Set ans_col = New Collection
    
    最終行 = Cells(Rows.Count, 列数).End(xlUp).row
    
    For i = 1 To 最終行
        '色無しセルでない場合に処理
        'Colorプロパティでは色無しと白が区別できないのでColorIndexで判別
        If Cells(i, 列数).Interior.ColorIndex <> xlNone Then
            セル値 = Empty
            項目値 = Empty
            
            '値が空白でない場合に
            セル値 = Cells(i, 列数).Value
            If Len(セル値) > 0 Then
                項目値 = Cells(i, 列数 + Cells(i, 列数).MergeArea.Columns.Count).Value
                DoEvents
                'コレクションに項目を追加する際、キーが重複した場合に備えて
                '結果的に上の行が優先
                On Error Resume Next
                ans_col.Add 項目値, セル値
                On Error GoTo 0
            End If
        End If
        
        DoEvents
        
    Next i

    Set 項目値の連想配列 = ans_col
    
    'ちょっと丁寧にしてみました
    If Not ans_col Is Nothing Then
        Set ans_col = Nothing
    End If

End Function
```
セルのColorプロパティでは「色塗りなし」と「白」を区別できない（両方とも16777215になる）ので、colorindexプロパティで無色かどうかを判別します。どうしてこういうことをするかというと、印刷の都合もあってセルに色を塗るのが嫌われる場合もあるのよ。
よくあるのがセルが結合されていた場合。単純に列数を＋１すると空欄が返ってきますが、それでは実用になる範囲が限られっる。結合されたセルの列数を調べて右隣のセルをちゃんとみつけてくれます。

念の為呼び出し側のコードも書いておきますと
```
Dim 項目一覧 As Collection
    Set 項目一覧 = 項目値の連想配列(項目列)
```
で、連想配列を作ります。
実際に値を使うときは、存在しない項目見出しを指定してしまったときに備えてエラー処理があったほうがいいです。
```
    On Error Resume Next
        項目値 = 項目一覧(項目見出し)
        If Err.Number > 0 Then
            Cells(i, 1).Value = Err.Number
            Err.Clear
        End If
    On Error GoTo 0
```

折角だからと項目値が「チェックボックス」で与えられる場合も対応したいと思いました。
ただし簡単に言うと「挫折」。労多くして処理時間かかって益少なし。
まずワークシート上のチェックボックスの一覧を取得して、その位置と値の配列を作ってみました。位置としてセルのアドレスをとることには成功したのですが現実問題として「チェックボックスが１つのセルに収まることはあまりない」。大きすぎるんです。ワークシート上のピクセルでの位置はとれるのですが、そこからセルのアドレスを出すかあ？ということです。
必要に迫られたらやらなくもないのですが。
消息を断った潜水艦をベイズ推定で見つける

# 背景
1968年にアメリカ海軍の潜水艦[スコーピオン号](https://ja.wikipedia.org/wiki/%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%94%E3%82%AA%E3%83%B3_(%E5%8E%9F%E5%AD%90%E5%8A%9B%E6%BD%9C%E6%B0%B4%E8%89%A6))が消息を経ちました。この時の捜索に使われたのがベイズ推定を用いたベイズ捜索(Bayesian Search)です。飛行機やそのブラックボックスなどの捜索にも使われます。

# 変数定義
まず捜索エリアをセル分け定義します。ここでは簡易的に20x20のエリアとします。これに航路や最終報告された位置などの情報から、そのセルごとのあて推量の発見確率を、事前確率として以下のように確立分布で表現します。私の場合は正規分布で表現しました。赤いXは行方不明の捜索対象です。

![Screenshot from 2021-03-14 12-27-59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485117/03baa4ec-5d10-8320-3ebb-ed5d25f4ad28.png)

ここで、以下のように変数を定義しておきます。

| 変数名 | 意味 |
|:-----------|------------:|
| $i$       | セルのインデックス。上で示した捜索対象の場合$i=(16,10)$と表現する。        |
| $Y_i$     | iに捜索対象があるか否かの真値。ある場合1。ない場合0。|
| $\pi_i$     | 上記のあて推量の事前確率。$P_r(Y_i=1)$|
|$Z_i$|iを捜索した結論。見つかった場合1。ない場合0。**Yi=1であった場合に見つけられなかった場合も0。**|
| $p_i$       | iに捜索対象があった場合の発見確率。$P_r(Z_i=1｜Y_i=1)$。この例ではどのセルも一律で0.1とする。実際には海底までの深さなどでセル毎に変更される。|

$p_i$を定義している通り、この推定のポイントは**そこに捜索対象があったとしても、捜索班の能力不足などにより見つけられない場合**を考慮していることです。　　
さて、実際の捜索に移りましょう。

# 捜索アルゴリズム

1. $\pi_i$が最大となるインデックス$i$の示すセルを捜索セルとする。
2. セル$i$にて捜索対象が見つかった場合終了。見つからなかった場合、以下の通りに$\pi$を更新。  
$\pi_i \leftarrow \frac{(1-p_i)\pi_i}{1-p_i\pi_i} $  
i以外のセルjに対しては：  
$\pi_j \leftarrow \frac{\pi_j}{1-p_i\pi_i}$
3. 私の実装の場合、$\pi$がだんだん飽和し破綻したので、セル全体を合計して1.0になるように正規化しました。
4. 1から繰り返し。

# 事前確率更新の様子
1000ステップを5ステップ飛ばしで描画させています。青い点がそのステップで捜索対象としたセルです。赤いXを捜索しても処理を終えていないのは、$p_i$が0.1だからです。10回に一回に捜索成功の判定となります。
![myimage.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485117/817fdd60-a562-c516-6b38-bf1751c490d5.gif)

見つけられたかどうかはあまり重要としていないので、最後まで示していません。時間が在る時に全探索とのパフォーマンス比較をやってみます。

# 考察
人間が  
　「だいたいここらへんにあるはず」  
という推測情報を使って、そのあたりからなんとなく順繰り捜索する場合も、  
　｢あれ、おかしいな。こんなに推測から外れている場所に在るわけ無いぞ。
　またあのあたりから探すか｣  
という具合に、エリアを全捜索するのでは無く、ある程度捜索し終わったらまた予測地点から捜索をスタートするという動きになると思います。
ですので上記のGIF画像から、
ベイズ捜索はそれをより無駄なく合理的に行う方法なのだと思いました。

上記のGIF結果を見ると、捜索点がセルの位置的にアチラコチラに触れているので、実際に捜索する場合は  
　セル内の捜索時間>>セル間の移動時間  
でなければ、発見までの時間が無駄に長くなりますね。

# コード
以下に上げました。

https://github.com/yosukeueda33/bayesian-search/blob/main/search.py

# 参考文献
http://www2.stat.duke.edu/~banks/130-labs.dir/lab10.dir/Lab10_bayesian_search.pdf

https://towardsdatascience.com/finding-lost-objects-using-bayesian-search-in-javascript-f502e3a1eb8c