OmniAICreator/Qiita-1.07M huggingface dataset:
S3オブジェクトの変更を確認してダウンロードする

AWS SDK for JAVA を使用し、S3オブジェクトをアップロード、ダウンロードするScalaプログラムを書いた。依存するプログラムですでにV1が使用されていたのでV1を使用した。
ダウンロード処理ではS3オブジェクトの内容が変更されたときのみダウンロードを実行する。

https://aws.amazon.com/jp/sdk-for-java/
https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/

ハマった箇所が２つあったのでまとめる。

# 基本的なアップロードとダウンロード

まず、S3オブジェクトのアップロードとダウンロードをサンプルを見ながら基本的な動作を実装した。

https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/upload-objects.html
https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/download-objects.html

アップロード処理については常に実行し、ダウンロードするときに前回のハッシュ値と見比べる方法で実装することにした。

# ハッシュ値

オブジェクトのハッシュ値を取得する方法を調べる。

## Content-MD5

とりあえずシステム定義のメタデータ一覧を確認する。

https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/UsingMetadata.html

`Content-MD5` がオブジェクトのハッシュ値のようだ。

しかし、いざAWS SDKで取得してみると空になっていた。アップロード時の整合性を確認するためにローカルで生成したハッシュ値を送信し、さらにオプションで保存してメタデータとして返せるようになると言うもののようだ。

https://aws.amazon.com/jp/premiumsupport/knowledge-center/data-integrity-s3/

## ETag

厳密にはコンテンツのハッシュ値とは限らないのだが、今回の用途では `ETag` が使用できる。Consoleでもこの値は確認できる。メタデータの一覧には記載されていないが、しっかりメタデータとして取得できるので利用する。


# ネットワーク接続のクローズ

SDKでは `getObject` によりオブジェクトを取得し、コンテンツは `getContent` で `InputStream` が、 メタデータは `getObjectMetadata` で取得できるようだ。 `getContent` のストリームは使い終わったら閉じろとあるのでそのように書いた。

> ネットワーク接続は、すべてのデータを読み取るか、入力ストリームを閉じるまで開いたままになります。ストリーミングのコンテンツは可能な限り迅速に読み取ることをお勧めします。

しかし、すぐに接続数が多いとエラーになってしまった。`getObject`の時点でネットワーク接続が開始され、ストリームを使い終わるか`getObject`で返された`S3Object`の`close`を呼び出すまで切断されないようだ。`getObject` 以外でメタデータを取得したいところだが、調べると `getObjectMetadata` があったので使用する。

https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/AmazonS3.html#getObjectMetadata-com.amazonaws.services.s3.model.GetObjectMetadataRequest-

V2のドキュメントではこのメソッドはClientには見当たらなかったので、もしかするとV2では `getObject` の挙動が違うかもしれない。

この `AmazonS3`の`getObjectMetadata`を使うことで問題は解決した。
【GO言語】Twitterで自動いいねbotの作り方

久しぶりに投稿します。
今回はタイムラインに流れてくるツイートに対して、
自動いいねできるコードを作成したので、そのご紹介です。
1ヶ月くらいやるとフォローが減ったりします。

####やったこと
・Go言語で自動いいねbotの作成

####環境
・Go (version 1.158.8)
・WindowsServer2019
　※実行方法はタスクスケジューラで定期実行してました。

####実装
#####Twiter認証

```Twiter認証.go
import (
     "github.com/ChimeraCoder/anaconda"
)
//Twitterの認証を行うメソッド
func GetTwitterApi() *anaconda.TwitterApi {
     anaconda.SetConsumerKey("XXXXXX")
     anaconda.SetConsumerSecret("XXXXXXXX")
     api := anaconda.NewTwitterApi("XXXXXX", "XXXXXXXX")
     return api
 }
```
まず、これをやらないとはじまらない！
Twitter認証を行います。今回もanacondaを利用しました。
Twitterであれば基本的にanacondaで実装できるのでおすすめです。
https://pkg.go.dev/github.com/ChimeraCoder/anaconda


#####タイムライン取得
```タイムライン取得.go
import (
     "net/url"
)
---中略---
//Twitterの認証情報を取得
api := GetTwitterApi()

//タイムライン取得用の引数を設定
v := url.Values{}
v.Set("count", "10")

//タイムラインを10件取得する
tweets, err := api.GetHomeTimeline(v)
if err != nil {
     panic(err) //error時の処理
 }
```
先程のAPIを呼び出して、タイムラインを取得します。
vはhttps://pkg.go.dev/net/urlの型になります。
タイムラインを取得するAPIの引数に必要なため、宣言してます。
api.GetHomeTimeline(v)でtweetsに最新10件のツイートをリスト型で格納します。

#####いいね処理
```いいね処理.go
//取得したツイート分繰り返し
for _, tweet := range tweets {
     //ツイートがいいねされているかで条件分岐
     if tweet.Favorited {
          //いいねされていれば何もしない
          fmt.Println("いいね済みでした")
     
     //いいねされていない場合
     } else {
     _, err := api.Favorite(tweet.Id) //いいね処理
     if err != nil {
          panic(err) //error時の処理
     }
}        
```

取得したツイート(リスト型)に対して、いいねされているかどうかで条件分岐し、
いいねされていない場合にFavorite(Id)でいいね処理を行います。
tweet.Idはツイートに対して一意に割り当てられているIDになります。

#####全処理
まとめると以下の通りです。

```いいねbot.go
import (
        "fmt"
        "net/url"
        
        "github.com/ChimeraCoder/anaconda"
        )
func main() {
     //Twitterの認証情報を取得
     api := GetTwitterApi()

     //タイムライン取得用の引数を設定
     v := url.Values{}
     v.Set("count", "10")

     //タイムラインを10件取得する
     tweets, err := api.GetHomeTimeline(v)
     if err != nil {
          panic(err) //error時の処理
     }

     //取得したツイート分繰り返し
     for _, tweet := range tweets {
          //ツイートがいいねされているかで条件分岐
          if tweet.Favorited {
               //いいねされていれば何もしない
               fmt.Println("いいね済みでした")
     
          //いいねされていない場合
          } else {
          _, err := api.Favorite(tweet.Id) //いいね処理
          if err != nil {
               panic(err) //error時の処理
          }
     }        
}

//Twitterの認証を行うメソッド
func GetTwitterApi() *anaconda.TwitterApi {
     anaconda.SetConsumerKey("XXXXXX")
     anaconda.SetConsumerSecret("XXXXXXXX")
     api := anaconda.NewTwitterApi("XXXXXX", "XXXXXXXX")
     return api
 }

```

以上です。ありがとうございました。
楽しいTwitter生活を送ってください。
Reactでcreate-react-appを使わずにwebpackでGAEにデプロイ【忘備録】

　Reactで作ったアプリをGAEにデプロイするまでを忘備録として残します。
　create-react-appで作らずに「作りながら学ぶ React 入門」(吉田裕美,https://github.com/yuumi3/react_book)を参考に環境を作りました。



構成
---
```
├── public
│   └── index.html
├── src
│   └── index.js
├── .babelrc
├── .eslintrc.json
├── app.yaml
├── package-lock.json
├── package.json
└── webpack.config.js
```
GAEにデプロイ
---
 「ハンズオンNode.js」(今村謙士,p355〜360)を参考にGoogle Cloud SDKをインストールする。プロジェクトを作成する。
package.jsonのscriptsにbuildを追記する。

```React:package.json
  "scripts": {
    "start": "webpack serve",
    "webpack": "webpack -d",
    "build": "webpack build"  //buildを追記
```
　app.yamlに「create-react-appを使わない構成でGAEにデプロイする」(@yjiro0403,https://qiita.com/yjiro0403/items/e0c743eb1f230c404fb0)
をから引用させていただいたコードを記述する。
　また、「ReactをGCPのGAEにデプロイする方法」
(@ozora,https://qiita.com/ozora/items/5808046b10cef887804a)
よりnodejsのバージョンを自分のバージョンに変更して記述する。
 
```React:app.yaml
runtime: nodejs14 //数字は使っているバージョンにする。

handlers:
- url: /
  static_files: public/index.html
  upload: public/index.html
  secure: always
- url: /
  static_dir: public
```
下記のコマンドを実行する。

```React:
$ gcloud init //SDKのインストールの時に使ったのでここでは使わない可能性あり。
$ npm run build
$ gcloud app deploy
```
下記のコマンドでデプロイができているか確認する。

```React:
$ gcloud app browse
```

参考
----
1.作りながら学ぶ React 入門 (吉田裕美,https://github.com/yuumi3/react_book)
2.ハンズオンNode.js(今村謙士,p355〜360)
3.「create-react-appを使わない構成でGAEにデプロイする」
(@yjiro0403,https://qiita.com/yjiro0403/items/e0c743eb1f230c404fb0)
4.「ReactをGCPのGAEにデプロイする方法」
(@ozora,https://qiita.com/ozora/items/5808046b10cef887804a)
Messari, 2021Q2 DeFi市場レポートを読む

こんにちは、[@nobumei](https://twitter.com/nobu_mei)です。SubstackとNotionで毎日メルマガを書いてますが、HIDEへの転載は中々骨が折れるので経の内容を画像でベタ貼り付けてみました。

見にくいかね？すまんね。
元記事を見たい方は[こちら](https://nobumei.substack.com/p/messari-2021q2-defi)をご参照くださいませ

Youtubeの切り抜きみたく、代わりにコピペしてくれる人いないだろうか。悩ましいです。

![](https://firebasestorage.googleapis.com/v0/b/hideaki-97c59.appspot.com/o/images%2FlHn2Bn5im1Zex0k1pQyMp0W8eJn2%2FO6Ys3fi8K.png?alt=media)
目次: TeamsとPower Automateを組み合わせて便利に使う！

## Microsoft Teamsの可能性を広げよう！

Microsoft 365はよく知られているWordやExcel以外にも、多くのアプリやサービスを用意しています。中には定型的な処理を自動化することで日々の業務負担を軽減するものも。
そこでMicrosoft Teams(以下、Teams)と定型的なワークフローを自動化するMicrosoft Power Automate(以下、Power Automate)を組み合わせた業務効率向上と業務負担を軽減する方法をシリーズ化して、ご紹介していきます！

出来るだけエンドユーザの皆様に分かりやすく、日々の業務で利用しやすいシナリオを想定してみました。
まずはお試し頂いて、慣れてきたらカスタマイズに挑戦されてみて下さい。

Teamsの既存機能だけでなく、様々なMicrosoft 365のツールとの連携で、もっと便利に働き方を変えてみませんか。

### 第一回 あとで読みたいメッセージをリマインドさせる
Teamsの投稿を見た際、「これ、後でもう一回見直したい」「じっくり考えて解答しよう」と思うような事はありませんか？
そのような投稿を、Power Automateに送る事で、一定時間が経過すると自分のチャットにリマインダーが通知される仕組みをご紹介します。
https://qiita.com/Asuka_Nagamine/items/2abb18db8b7c66eea05f
### 第二回 Formsに回答が来たらTeamsに知らせる
アンケートや集計に利用できるMicrosoft Formsをご存知ですか？Formsへの解答がいつあったのか、定期的にチェックしにくのは面倒ですよね。Formsへの解答があった事をチームに連絡する仕組みをご紹介します。
https://qiita.com/Asuka_Nagamine/items/396b36db27a05b78beb7

### 第三回 参加登録した人に、事前課題をチャットで自動通知
イベントの参加登録をMicrosoft Formsで実施出来る事は、第二回でもご紹介しました。今回は、Formsでイベントの参加登録してくれた人に、Teamsのチャットで事前課題を送る仕組みをご紹介します。
https://qiita.com/Asuka_Nagamine/private/0610b5937332ea00f1e8

### 第四回 Formsで参加登録した人に会議通知を送る（満席になったらキャンセル待ち通知も）
前回に引き続き、今度は会議通知を参加者に送る方法です。会議通知を送る事で、他の人に同時間に会議を入れられる事を防いだり、参加者にリマインダーが通知されるようになり、イベントの出席忘れが無くなります。
https://qiita.com/Asuka_Nagamine/private/24c2fb0aca0c8854cd82

### 第五回 皆の勤務状況をカレンダー形式で見たい
コロナ禍とその長期化により、勤務形態も多様化しています。あの人の勤務状況ってどうなってるんだっけ？チームメンバーの勤怠状況がパッと分かると便利ですよね。テンプレートを利用してササッと試せる仕組みをご紹介します。
https://qiita.com/Asuka_Nagamine/private/ca84afaa061bd08b7b49

### 第六回 Excelファイルのメールアドレスから人をチームに追加する
「4月に入社してくるメンバー200人のメールアドレスが入ったExcelファイルはこれ。部署のチームに追加しておいてくれる？」
こんな面倒な処理も、Power Automateを使えば楽勝です！
https://qiita.com/Asuka_Nagamine/private/a68c9e33baa3dc4ff482

### 第七回 Teamsのチームに入っているメンバーをExcelに書き出す
知らない間にメンバーが増えているチーム。そういえば一体誰がメンバーになっているんだろう？今いるメンバーをExcelファイルに一覧出力出来たら便利ですよね。第六回では、Excelファイルからメンバーをチームに追加する方法をご紹介しましたが、第七回ではチームのメンバーをファイルに書き出す方法をご紹介します。
https://qiita.com/Asuka_Nagamine/items/5626bba2e35f48f56bfb
2.5(難) モーメントの処理 (方針2で凸関数，Jensenの不等式を解説)

## 方針1

「k次モーメントが存在」とは，「E[|X|^k]が有限である」と言い換えることができる．答案1を思いつくのは難しいが結果は重要．

## 答案1

0<h<kの時，任意のxに対して

```math
|x|^h\leq 1+|x|^k
```

が成り立つ(|x|<1ならば|x|^h<1より不等式は成立．1<|x|ならば|x|^h<|x|^kより不等式は成立．)．ゆえに，両辺の期待値を取ることで，k次モーメントが有限であることを用いて，

```math
\begin{align}
\mathbb{E}_{X\sim f_X}[|X|^h]&\leq \mathbb{E}_{X\sim f_X}[1+|X|^k]\\
&= 1+\mathbb{E}_{X\sim f_X}[|X|^k]<\infty
\end{align}
```

となるため，

```math
\mathbb{E}_{X\sim f_X}[|X|^h]<\infty
```

よりXはh次のモーメントを持つ．

## 方針2
### 凸関数の定義
---
区間Iにおいて関数phi(x)が凸であるとは，I内の任意のx,yと0<gamma<1に対し

```math
\phi(\gamma x+(1-\gamma)y)\leq \gamma\phi(x)+(1-\gamma(y))
```

が成り立つ，ということである．

---

phiが凸関数である時，phi内の任意の点は，phi上の任意の接線よりも上にある(y=x^2を想像するとわかる)．つまり，任意のzについて，phiの接線は

```math
y=\phi'(z)(x-z)+\phi(z)
```

であって，全てのxについて

```math
\phi(x)\geq \phi'(z)(x-z)+\phi(z)
```

が成り立つ．このことは後のJensenの不等式の証明に用いる．

### 凸関数の判定方法

---

phiが凸であることと，定義域内の全てのxについて

```math
\phi''(x)\geq 0
```

が成り立つことは同値である．

---

例：

```math
\phi(x)=-\log(x)
```

に対し，

```math
\phi''(x)=\frac{1}{x^2}>0,\ \forall x>0
```

なので，phiは凸関数．

### Jensenの不等式

---
確率変数Xについて，Xは一次モーメントが存在するとする．phiを確率空間上で凸な関数とすると，

```math
\phi(\mathbb{E}_{X\sim f_X}[X])\leq \mathbb{E}_{X\sim f_X}[\phi(X)]
```

が成り立つ．(等号成立条件はXが定数か，phiが直線であること．)

---

(証明)

```math
\mu=\mathbb{E}_{X\sim f_X}[X]
```

と置く．x=muにおけるphiの接線は，

```math
y=\phi'(\mu)(x-\mu)+\phi(\mu)
```

である．この時，全てのxで

```math
\phi(x)\geq \phi'(\mu)(X-\mu)+\phi(\mu)
```

が成り立つ．両辺の期待値を取ることで，

```math
\mathbb{E}_{X\sim f_X}[\phi(X)]\geq \phi'(\mu)\mathbb{E}_{X\sim f_X}[X-\mu]+\phi(\mu)=\phi(\mu)=\phi(\mathbb{E}_{X\sim f_X})
```

## 答案2

関数phiを

```math
\phi(x)=x^k
```

と置く．これは

```math
\phi''(x)=k(k-1)x^{(k-1)(k-2)}>0, \forall x>0
```

より凸関数である．Jensenの不等式により

```math
(\mathbb{E}_{X\sim f_X}[X^h])^{k/h}\leq \mathbb{E}_{X\sim f_X}[X^{h\times k/h}]=\mathbb{E}_{X\sim f_X}[X^k]
```

が成り立つ．今，k次モーメントは存在するので

```math
\mathbb{E}[X^h]<\infty
```



## 参考文献

- 『[現代数理統計学の基礎](https://www.kyoritsu-pub.co.jp/bookdetail/9784320111660)』(久保川達也　著)
ライトユーザーのためのpowershell入門

powershellはWindowsにデフォルトで備わっているシェル環境です。もともとコマンドプロンプトがありましたが、powershellはより機能が強化されたものとなっています。

私はpowershellを使ってサーバー管理など大層なことをしているわけでなく、日頃の作業を少し便利にしています。本記事ではそんなライトユーザーのためのpowershellの使い方・設定方法を解説します。

LinuxでCUIに慣れた人を想定していますが、初心者の方も頑張れば習得できると思います。

#環境
Windows10

#立ち上げ
Windowsキーを押して、「powershell」と入力し、エンターを押すとpowershellのコンソールが立ち上がります。

#基本コマンド

Linuxの基本的なコマンドと同じコマンドが使えることがあります。ただし、オプションまでは一致していないことが多いので気をつけてください。

* ls : 現在のディレクトリにあるファイルを表示する
* cd : ディレクトリを変更する
* md : ディレクトリを作成する
* pwd : 現在のディレクトリのパスを表示する
* rm : ファイルを削除する
* rm -r : ディレクトリごと削除する
* cp : ファイルをコピーする
* cp -r : ディレクトリごとコピーする
* ii : ファイルを拡張子に関連付けられたソフトで開く

iiは便利なコマンドです。txtファイルに使えばメモ帳で、jpgファイルはビューアーで、ディレクトリはエクスプローラーで、というように対応したソフトで開いてくれます。クリックするのと同じ感覚ですね。

ちなみに現在のディレクトリを示す「.」や、ひとつ上の階層を示す「..」はpowershellでも使えて、

```powershell
cp ../hoge.txt .
```

のようにLinuxと同じ感覚でつかます。

ワイルドカードも使えます。

```powershell
rm *.jpg
```

#パスが通っていれば実行可能

メモ帳の実行ファイル「notepad.exe」はパスが通っていますから

```
notepad hoge.txt
```

みたいなことも可能です。

#初期設定ファイル

bashだと.bashrcに対応する初期設定ファイルですが、下記の場所に作成します。（ユーザー名は各自のもので）

```powershell
C:\Users\tacoma\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
```

ちなみにこの設定ファイルのパスは変数$profileに入っていますので、

```
notepad $profille
```

などで編集可能です。


#初期設定ファイルに書くこと

エイリアスや関数を設定します。

```powershell
#エイリアスの設定
Set-Alias   np   "C:\Program Files (x86)\Notepad++\notepad++.exe"

#Linuxの "ls -lrt" 　のような関数を設定
function lrt {Get-ChildItem | Sort-Object LastWriteTime}

#パスの追加
$ENV:Path+="C:\Users\tacoma\bin;"
```

上記設定をしていれば、例えばNotepad++でhote.txtを開く場合

```
np hoge.txt
```

で実行可能ですね。

#その他

その他おすすめの設定は下記リンクに記載されています。

https://suponcho.com/blog/windows-powershell-%E3%81%AE%E3%83%97%E3%83%AD%E3%83%B3%E3%83%97%E3%83%88%E3%81%AB%E8%89%B2%E3%82%92%E4%BB%98%E3%81%91%E3%82%8B/

https://qiita.com/BOACK/items/5b16ebb4b9820d17ebf6


是非試してみてください。
【tmux】smugを利用したワークフロー管理及び自動化

- 普段tmuxを利用して複数端末を起動した状態で作業することが多い。
- 非常に便利だが、以下の点を解消するべく調査。
    - 定型作業の自動化
        - 同様のサーバー接続や複数画面分割等の定型的なtmuxワークフローの手間。
    - プロジェクトや作業単位での管理
        - 日々行なっている複数作業の内容の把握が難航。
- 調査の結果、複数の類似プロジェクトがあるが比較的導入が容易であろうsmugというツールがあったため、今回は利用方法を記録する。

## 概要
- Go製のtmuxワークフロー管理ツール
- ウィンドウやペイン分割数、起動コマンド等の単一のファイル(yaml)で管理可能。
- 同様のツールにRuby製の[tmuxinator](https://github.com/tmuxinator/tmuxinator)がある。
- [Github](https://github.com/ivaaaan/smug)

## 結果
- 以下のように単一の構成ファイルを作成して、単一のコマンドでペインの分割や起動時のコマンドを管理することが可能。

![sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336499/63274b6b-6eb2-d58e-d7e0-e1327d22bced.png)

![test.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336499/4e2b09c2-744e-7a5e-b04c-9b5ae290ee9b.png)

## 環境
- Mac OS X 10.15.6
- tmux 3.2

## 手順

### インストール

#### Mac

```bash
mkdir -p /tmp/work; cd $_
# GithubのReleaseから任意のバージョンを選択。wgetがなければcurlで代替。
wget https://github.com/ivaaaan/smug/releases/download/v0.2/smug_0.2_Darwin_x86_64.tar.gz
tar -xzf smug_0.2_Darwin_x86_64.tar.gz
mv smug /usr/local/bin
rm -rf /tmp/work; cd /tmp
```

#### その他
- その他のインストールは[こちら](https://github.com/ivaaaan/smug)を参照。

### ワークフローの定義
- 普段の作業を要件として定義する必要があるため、今回利用する簡単な例は以下。
    1. Dockerを開発環境とするsampleプロジェクトが対象
    2. 4画面に分割。
        - 1画面 : コンテナ接続画面。接続している状態である。
        - 2画面 : ソースファイル編集画面
        - 3画面 : ローカルの通常ターミナル
        - 4画面 : Dockerfile編集画面
    3. 起動時にプロセス起動、終了時に終了

- **※対象プロジェクトではDockerを利用しているため、先に`docker-compose build`を済ましておく。**

### 構成ファイルの作成
- ワークフロー定義後、それに従い以下の構成ファイルに記述。
    - `~/.config/smug`ディレクトがない場合は新たに作成
        - **※このディレクト内に作成することで、実行時は`smug start session名`だけで良い。**
    - **※configディレクトリの作成が難しい場合、単一のyamlファイルを作成して実行時に`smug start -f ***.yml`として直接パスを指定すれば良い。**

```yaml:~/.config/smug/sample.yml
# セッション名
session: sample

# 対象ルートパス
root: ~/work/sample

# 起動前のコマンド指定
before_start:
  - docker-compose up -d

# 終了時のコマンド指定
stop:
  - docker-compose down

# ウィンドウ情報
windows:
  - name: sample
    layout: tiled  # レイアウト情報(https://github.com/tmux/tmux/blob/2.7/layout-set.c)
    commands:  # 起動時のコマンド指定
      - docker-compose exec sample bash
    panes:     # ペイン情報
      - type: tiled  # レイアウト情報
        commands:
          - vim Dockerfile
      - type: tiled
        commands:
          - vim README.md
      - type: tiled
        commands:
          - vim bin/ncname
```

### 実行
- 構成ファイル作成後、以下で開始。

```bash
smug start sample
```

- 停止するには以下のコマンドで実行

```bash
smug stop sample
```

## 結果
- 以下のようになっていれば完了。

![test.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336499/4e2b09c2-744e-7a5e-b04c-9b5ae290ee9b.png)


## まとめ
- 日々利用している定型作業を管理及び自動化できたため安心。
- こうしたわずかな地味な効率化が重要と実感。
- ただ日の浅いツールのため、様子を見ながらの利用を継続。

## 参考
- https://github.com/ivaaaan/smug
TwitterAPI研究

##APIとは

APIとは、ソフトウェアやアプリケーションなどの一部を外部に向けて公開することにより、第三者が開発したソフトウェア機能を共有できるものです。

上記だとまだ難しいと思うので、下記サイトをご覧ください。APIとはなにかを例を交えて、イメージしやすいようにまとめてあり、とてもわかりやすいです。
__※参考__
https://wa3.i-3-i.info/word12428.html

##Twitter APIとは

ツイートやタイムラインの取得、リツイートやいいねといったTwitterサービスを、公式のウェブサイトを経由せずに直接利用できるサービスです。

例えば、ツイートやリツイート、タイムラインの取得などウェブサイトにログインしてから行うと思います。しかし、TwitterAPIを用いることで、ウェブサイトを経由しなくても、ツイートなどを取得することができます。

ここで「Twitterアプリを使っているからウェブサイトは経由しない」という方がほとんどだと思います。しかし、そのアプリこそがAPIの活用例の一つなのです。

##Twitter APIの機能

TwitterのAPIは大きく5つのAPI機能に分かれています。

・キーワード検索できる__「サーチAPI」__
・アカウントプロフィールを扱う__「アカウントAPI」__
・今現在のツイートを扱う__「リアルタイムAPI」__
・DM機能の__「ダイレクトメッセージAPI」__
・広告機能と連携できる__「広告API」__

##TwitterAPI制限とは

TwitterAPlと合わせてよく聞くのが__「API制限」__という言葉です。

ツイートなどのサービスを利用するとき、どうしてもTwitterのサーバーに接続必要があります。APIを使わない場合はウェブサイトからサーバーに投稿を反映させますが、APIを使う場合はプログラムを用いて直接サーバーにツイートを反映させます。

APIを使うと、ウェブサイトとは違って大量にツイートを投稿するなど「悪意ある攻撃」が簡単にできてしまいます。これをしてしまうと、Twitterのサーバーの負荷が高くなり、サービスの提供が不安定になってしまいます。

そこで一定時間あたりにサーバーがリクエスト（投稿などを反映させること）を受け付ける数に上限を設けています。例えば、フォロワーの取得であれば、「1分に1リクエストまで」といった制限があります。これを超えてAPIリクエストを送ってしまうと、アカウントが「有害なもの」をして一時的に制限されてしまいます。これがいわゆる「API制限」を食らった状態です。

##Twitter APIでできること

####①タイムラインの取得
自分のタイムラインはもちろん、特定ユーザーのつぶやき一覧や、世界中からランダムに取得、地域のツイートなどの取得ができます。

####②ツイートの投稿
APIを用いると、Pythonなどのプログラミング言語などを用いてツイートの投稿ができるようになります。そのため、外部サービスを使わずとも自分で定期的にツイートを行うbotを作ることができます。

####③リツイートやいいねの実行
ツイートだけではなく、リツイートやいいねの実行や取り消しを行うことができます。
これを用いると、自分のツイートを定期的にRTしたり、フォローしているユーザーのツイートをいいねしたりすることができます。

####④フォローやアンフォローの実行
フォロー、アンフォローなどの操作もAPIから行うことができます。
フォロー・アンフォローの操作はAPI制限がツイートに比べて厳しいため、気をつける必要がある。

####⑤ツイートの検索
ツイートの検索は、ユーザーのトレンド予測などに大変役立ちます。ツイート数やツイート内容を分析することもできます。

※TwitterAPIを使うには申請が必要です。
####申請は下記を参考

https://developer.twitter.com/en

####TwitterAPI一覧

https://developer.twitter.com/en/docs/api-reference-index

##TwitterAPI ✕ PHP Twitter機能のコード集

【PHP】Twitter API（ツイート検索・ツイートする・いいねする・トレンド検索する・APIの制限数を確認する）

https://qiita.com/kuzira_vimmer/items/eb19865061b0a7023f5e

#####【PHP】TwitterのトレンドをAPIから取得する＆HTML出力

https://qiita.com/tomox0115/items/9aa06241a9442487469a

#####LaravelでTwitter認証を実装する

https://qiita.com/tamakiiii/items/cd027580e1d86e2652d7

##TwitterAPIを使った面白い機能

#####就寝中であることをtwitterの名前欄でお知らせ
https://qiita.com/matsuri0828/items/df96ff51f5a4ea00d130

#####Twitterで抽出したツイートをTL形式にしてサイトに埋め込む
https://qiita.com/dan-go/items/f29101ffd7da5510fde1

#####Twitterプロフィール画像が自動更新される「うたた寝bot」
https://qiita.com/monohalu/items/ee7b37d8db7dd1949143

#####TwitterのTLを見せ合えるミニサービス
https://qiita.com/dala00/items/c0fe71afc7a0c57ce0e6

#####ツイートの性格分析による本のマッチングシステム
https://qiita.com/Mocchaso/items/ebccd2a98ceb50cfee20

#####Twitter 誹謗中傷撃退マシン
https://qiita.com/pigretyasushi/items/e9900708463b5c4bc36a

#####Twitterのつぶやきをテキストマイニングによって可視化する
https://qiita.com/shibata0523/items/8227131dd938ee012af3
【Go】fmt.Printfには改行を入れよう

##概要
先日、db周りの変数を調べるためにfmt.Printfを使って確認していたらfmt.Printfの中身が出力されなくなったので、自分の解決方法を書いておきます。
##解決方法

```go:main.go
fmt.Printf("hoge変数の中身=%v",hoge)//これを
fmt.Printf("hoge変数の中身=%v\n",hoge)//こうする(\nを付ける)
```

初歩的な事だとは思いますが改行とともに何の変数かがわかる文字列も一緒に出力すると分かりやすくていいと思います。
C#  PowerPointで文書内の文字を置換

<p><strong>今日はSpire.Presentationという無料のライブラリを使って、パワーポイントで文書内の文字を置換する方法を紹介します。</strong></p>
<h4><strong>下準備</strong></h4>
<p><strong>1.E-iceblueの公式サイトから<a href="https://www.e-iceblue.com/Download/download-presentation-for-net-free.html">Free Spire.Presentation</a></strong><strong>無料版をダウンロードしてください。</strong></p>
<p><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/l/lendoris/20210715/20210715111011.png" alt="f:id:lendoris:20210715111011p:plain" width="554" height="205" loading="lazy" title="" class="hatena-fotolife" itemprop="image" /></p>
<p><strong>2.Visual Studioを起動して新規プロジェクトを作成してから、インストールされたファイルにあった相応しいSpire. Presentation.dllを参照に追加してください。</strong></p>
<p><strong>（Net 4.0を例としたら、デフォルトパスは“Bin→NET4.0→Presentation.dll”というようになります。）</strong></p>
<p><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/l/lendoris/20210715/20210715111020.png" alt="f:id:lendoris:20210715111020p:plain" width="250" height="216" loading="lazy" title="" class="hatena-fotolife" itemprop="image" /></p>
<h4><strong>元のファイル</strong></h4>
<p><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/l/lendoris/20210715/20210715111105.png" alt="f:id:lendoris:20210715111105p:plain" width="554" height="393" loading="lazy" title="" class="hatena-fotolife" itemprop="image" /></p>
```c#
public ReplaceText()
{
   {
        //Dictionary オブジェクトを作成し、itemを追加します。
        Dictionary TagValues = new Dictionary();
        TagValues.Add("日本語", "韓国語");
        //PowerPointファイルをロードします。
        Presentation presentation = new Presentation();
        presentation.LoadFromFile("Sample.pptx", FileFormat.Pptx2010);

        //ReplaceTagsメソッドで文字を置換します。
        ReplaceTags(presentation.Slides[0], TagValues);

        //保存します。
        presentation.SaveToFile("Result.pptx", FileFormat.Pptx2010);
        System.Diagnostics.Process.Start("Result.pptx");
    }
}
public void ReplaceTags(Spire.Presentation.ISlide pSlide, Dictionary TagValues)
{
    foreach (IShape curShape in pSlide.Shapes)
    {
        if (curShape is IAutoShape)
        {
            foreach (TextParagraph tp in (curShape as IAutoShape).TextFrame.Paragraphs)
            {
                foreach (var curKey in TagValues.Keys)
                {
                    if (tp.Text.Contains(curKey))
                    {
                        tp.Text = tp.Text.Replace(curKey, TagValues[curKey]);
                    }
                }
            }
        }
    }
}
```
<h4><strong>実行結果</strong></h4>
<p><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/l/lendoris/20210715/20210715111114.png" alt="f:id:lendoris:20210715111114p:plain" width="554" height="333" loading="lazy" title="" class="hatena-fotolife" itemprop="image" /></p>
<p><strong> </strong></p>
universal-sentence-encoderマルチリンガル版の項目レベル比較

## universal-sentence-encoder
[Universal Sentence Encoderのマルチリンガル版](https://tfhub.dev/google/universal-sentence-encoder-multilingual/3)を試用した際の備忘です。  

Universal Sentence Encoderを使用したのは
- 多言語対応
- 分かち書き処理不要
- TensorFlow Hubに繋がれば使える
- 軽い
というとにかくお手軽に出来ることを目指したためです。  

## 多言語対応
多くの方が使うのは日英の2つと思いますが 2021/7 時点で16言語に対応しています。　　

## 分かち書き処理対応
文書分散ですのでmecabなど分かち書きのインストールは不要です。  

## TensorFlow Hubに繋がれば使える
以下のimport文と使用するモデルのurlを指定するだけです。

```
import tensorflow_hub as hub

```

## 軽い
一番うれしかった点  
Universal Sentence Encoderの多言語モデルは通常版とラージ版の2つがあるのですが両方ともとても軽いです。
- [通常モデル](https://tfhub.dev/google/universal-sentence-encoder-multilingual/3)：245MB
- [ラージモデル](https://tfhub.dev/google/universal-sentence-encoder-multilingual-large/3)：303MB

## 比較
簡潔な分かりやすさを優先し、文書ではなくkaggleからタイタニックの日英項目を選択しました。  
英語名と日本語名を正しくマッピングできるか(多言語を同じベクトル上に表現できているか)を見てみます。
[sibsp][parch]のような略語や[boat][body]は意訳に近いので当たらない想定です。

| # | 英語名 | 日本語名(正解) 
|:--|------------:|:------------:|
| 1 | PassengerId | 乗客番号 |
| 2 | pclass | 旅客クラス |
| 3 | name | 名前 |
| 4 | sex | 性別 |
| 5 | age | 年齢 |
| 6 | sibsp | 兄弟、配偶者数 |
| 7 | parch | 両親、子供数 |
| 8 | ticket | チケット番号 |
| 9 | fare | 旅客運賃 |
| 10 | cabin | 客室番号 |
| 11 | embarked | 出港地 |
| 12 | boat | 救命ボート番号 |
| 13 | body | 識別番号 |
| 14 | home.dest | 自宅または目的地 |
| 15 | survived | 生存状況 |

## 結果
- 通常モデルのヒートマップ
![model1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1509592/322ac798-2888-ac08-f2de-e04475bf88ed.jpeg)


- ラージモデルのヒートマップ
![model2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1509592/b632bf17-c55a-994c-5664-85b88f143b70.jpeg)


cos類似度での比較ですが略語は想定通り外れ、一般的な項目は流石に当たってますね。ラージモデルでfareが外れてるのは意外ですが、その他の正解項目ですとcos類似度はラージモデルの方が高いですね。

個人的にはお手軽に単語類似度を多言語でかけられるというのが確認取れたので満足です。
翻訳だけではなく色々な使い道がありそうです。
シークレットモードでの対応が必要なトレイルヘッド

解答例
Have you tried your browser's incognito mode?
Clearing the cache may also help.


何の拡張機能が原因かなのかは分かっていませんが、取りあえずの回避策で実績があったもの

# Unable to Add permission sets to the permission set group

[Unable to Add permission sets to the permission set group](https://trailhead.salesforce.com/en/trailblazer-community/feed/0D54S00000BdCS8SAN)

[Create a Permission Set Group Error](https://trailhead.salesforce.com/en/trailblazer-community/feed/0D54S00000BrM2r)

# パッケージのインストール
[I cannot install Agile Accelerator on my Trailhead Playground.](https://trailhead.salesforce.com/en/trailblazer-community/feed/0D54S00000Bqbn1)


# Disconnected From Omni Channel
[Trailhead Issue - Disconnected From Omni Channel](https://trailhead.salesforce.com/en/trailblazer-community/feed/0D54S00000A8nfZSAR)

This problem was resolved by disabling security software that protects personal information. If you're having the same problem try disabling all browser extensions and security software while completing this badge. 

# Email preview is not displaying within SFMC (Chrome)

逆にシークレットモードになってしまっているのを、元に戻す
[Email preview is not displaying within SFMC (Chrome)](https://trailhead.salesforce.com/en/trailblazer-community/feed/0D54S00000Cf6El)

#  Safariでは動かない

[Internal Error when attempting to add Permission Sets to a Permission Set Group in Trailhead Challenge](https://trailhead.salesforce.com/en/trailblazer-community/feed/0D54S00000Dxyme)

# Aura Components challenges. 

[Challenge not yet complete in My Trailhead Playground 1 Whoops, looks like there was a problem. Please try again.](https://trailhead.salesforce.com/en/trailblazer-community/feed/0D54S00000A8vqHSAR)

# Build a Custom Record Page for Lightning Experience and the Salesforce Mobile App 

[In the challenge of Build a Custom Record Page for Lightning Experience and the Salesforce MobileApp - I encounter an error](https://trailhead.salesforce.com/en/trailblazer-community/feed/0D54S00000HDZXuSAP)

# Create and Train the Dataset not working

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/90b5b032-d14f-24a5-9d55-01b1e29f5871.png)

[Create and Train the Dataset not working](https://trailhead.salesforce.com/en/trailblazer-community/feed/0D54S00000HnLLL)

# This page has an error. You might just need to refresh it. Error in $A.getCallback() [Cannot read properties of undefined (reading 'length')] Failing descriptor: {markup://communitySetup:navigationBarEditorPropertiesPanelV2}

[Hello, I am having an issue with Add pages to Your Site](https://trailhead.salesforce.com/en/trailblazer-community/feed/0D54S00000J5wzP)

#  Data Classification Upload tool from csv

+ [Data Classification Upload tool](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000JelbF)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/69633187-d0e5-52c2-f3c5-75eddddbadcd.png)
ラズパイ４でサーボモータを動かすpigpio

ラズパイ４　カーネル5.1.0（2021.5.7版　32bitおすすめ全部入り）を使用しています
ラズパイの紹介記事でよく見かけるGPIOライブラリ RPi.GPIO でサーボモーターをPWMで制御するとパルス幅などに揺らぎがあるためにサーボモーターが止まるはずなのに、ジッ、ジッ、と動いてしまいます。

GPIOにアクセスするライブラリはいくつかあるようですが、 pigpioを使ってみることにしました。
interface2021.6月号でも紹介しています。https://interface.cqpub.co.jp/wp-content/uploads/if2106_148.pdf
##pigpioのインストール
公式ページのダウンロードリンクhttp://abyz.me.uk/rpi/pigpio/download.html
ここに、以下の２つのコマンドを打つとあるので端末から実行します。
sudo apt-get update
sudo apt-get install pigpio python-pigpio python3-pigpio
今回は、実行時に既に最新板があるよ！と表示されたので、32bitおすすめ全部入り版はインストール不要でした。
使用前にデーモンを起動します。
sudo pigpiod　　　pigpioではなくｄが付いています。
pigpiod -v　でバージョン確認できます。
インストールしたときは１．７９と出ましたが、バージョン確認では７９と表示されました。

##動作テスト
コードは参考HP
https://www.fabshop.jp/%E3%80%90-%E7%AC%AC38%E5%9B%9E-%E3%80%91gpio%E5%88%B6%E5%BE%A1%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E3%81%AE%E3%81%BE%E3%81%A8%E3%82%81/
からコピペしました。windows上だとコード部分をテキストエディタに貼り付けて、PWM.pyなど適当に名前を付けます。
USBメモリにコードを移して、ラズパイに刺しました。その後、ファイルマネージャを使ってホームディレクトリにコピーしています。
pyファイルをダブルクリックするとラズパイのpython開発環境であるThonnyが立ち上がります。
実行ボタンを押すとサーボモーターが動きました。
いくつかの制御関数があるようですが、.hardware_PWMがノイズが少なくて良さそうです。

```py
import pigpio
from time import sleep
# 実行前にsudo pigpiodを忘れずに
pig = pigpio.pi()
pig.set_mode(12, pigpio.ALT0) #OUTPUTの他にALT0-5のモードがある

counter = 0
while (counter < 3):
    pig.hardware_PWM(12, 50, 120000) #サーボは50Hzで制御する
    sleep(1)
    pig.hardware_PWM(12, 50, 72500) #7.25%のdutycycle
    sleep(1)
    pig.hardware_PWM(12, 50, 25000)
    sleep(1)
    pig.hardware_PWM(12, 50, 72500)
    sleep(1)
    counter = counter + 1

pig.hardware_PWM(12, 50, 0)
pig.set_mode(12, pigpio.INPUT)
pig.stop()
```

ラズパイ４でのALTモードの紹介
https://elinux.org/RPi_BCM2711_GPIOs#PCM_CLK
set_modeでOUTPUTやALT1-5を試してみたけど、ALT0と同様にサーボが動きました。18番GPIOでも同様でした。
interfaceの記事では18番でOUTPUTを使っていました。

##サーボモーターの接続
秋月で購入したSG-92Rを使いました。動作電圧：4.8V、配線：茶=GND、赤=電源[+]、橙=制御信号 [JRタイプ]とあるので、
電源ラインは５Vとして(3.3Vでも動きます)、オレンジは参考HPのコードから１２番のGPIOピンと接続しました。
PWMサイクルが20msなので、50Hzで制御します。制御パルス0.5msの時dutyは2.5％、2.4msの時は12％なので、2.5-12%の間でdutyをかけてやります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1520250/ea01f7f1-a07b-d374-3a3e-6969a81c21f0.png)
C#  ExcelをSVGに変換

<p><strong>今回はC#ではSpire.XLSという無料のライブラリを活用して、Excel文書をSVGに変換する方法を紹介してさしあげましょう。</strong></p>
<h4><strong>下準備</strong></h4>
<p><strong>1.E-iceblueの公式サイトから<a href="https://www.e-iceblue.com/Download/download-excel-for-net-free.html">Free Spire.XLS</a>無料版をダウンロードしてください。</strong></p>
<p><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/l/lendoris/20210715/20210715110247.png" alt="f:id:lendoris:20210715110247p:plain" width="523" height="249" loading="lazy" title="" class="hatena-fotolife" itemprop="image" /><br /><strong>2.Visual Studioを起動して新規プロジェクトを作成してから、インストールされたファイルにあった相応しいSpire.XLS.dllを参照に追加してください。</strong></p>
<p><strong>（Net 4.0を例としたら、デフォルトパスは“Bin→NET4.0→XLS.dll”というようです。）</strong></p>
<p><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/l/lendoris/20210715/20210715110259.png" alt="f:id:lendoris:20210715110259p:plain" width="297" height="223" loading="lazy" title="" class="hatena-fotolife" itemprop="image" /></p>
<p><strong> </strong></p>
<p><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/l/lendoris/20210715/20210715110319.png" alt="f:id:lendoris:20210715110319p:plain" width="511" height="526" loading="lazy" title="" class="hatena-fotolife" itemprop="image" /></p>
```c#
using System.Drawing.Imaging;
using System.IO;
namespace Convert
{
    class Program
    {
        static void Main(string[] args)
        {
            //ファイルをロードします。
            Workbook workbook = new Workbook();
            workbook.LoadFromFile("Sample.xlsx");

            //ToSVGStream(Stream stream)メソッドでシートを別々にSVGで保存   
         for (int i = 0; i < workbook.Chartsheets.Count; i++)
            {
                FileStream fs = new FileStream(string.Format("chartsheet-{0}.svg", i), FileMode.Create);
                workbook.Chartsheets[i].ToSVGStream(fs);
                fs.Flush();
                fs.Close();
            }


        }
    }
}
```
<h4><strong> 実行結果</strong></h4>
<p><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/l/lendoris/20210715/20210715110328.png" alt="f:id:lendoris:20210715110328p:plain" width="522" height="561" loading="lazy" title="" class="hatena-fotolife" itemprop="image" /></p>
<p> </p>
sshログインやファイル転送とか

*ファイル権限を変えないとうまくいかない場合がるので

```
chmod 600 /path/to/pemfile/file.pem //例
```

*ssh接続

```
ssh -i /path/to/pemfile/file.pem user@host
```

*ファイル転送 要鍵のとき scpね

```
scp -i /path/to/pemfile/file.pem /path/of/uploadtarget/file.zip user@host:/path/to/you/wantsend
```
動画で学ぶJHipster (4) （Cypressテスト）

# 参考動画

https://www.youtube.com/watch?v=6lf64CctDAQ

# テスト (Cypress)
参考動画の3:25辺りから～

Web UI の自動テストツール [Cypress](https://www.cypress.io/) を使った自動テスト、end to end test が実行できるようです。
まず、サーバーをコマンド`mvnw`で立ち上げておきます。
その後、別のコンソールを開いて、`npm run e2e`を実行します。

自動でブラウザが立ち上がり、テストが実行されます。
画面が高速で目まぐるしく動いて、見てたら疲れます（笑）
![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284134/ad0dffaf-ca6b-8e3b-6e9b-ec1d8a4d96f2.png)
![3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284134/c872e7e3-0e4a-55c1-ef1e-f0d09c5e6813.png)

結果がコンソールに表示されます。
![0.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284134/b41d74e0-ddcb-4a30-d939-482eb888a4ec.png)
![1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1284134/1c4e7135-796a-b9fd-573c-3dd161574c63.png)

`src\test\javascript\cypress\integration`以下のフォルダに入っている`*.spec.ts`ファイルがテストで実行される対象となっています。

## エラーになる場合
動画では`npm run e2e`を実行すると、特にエラーもなく、すんなりうまくいっているみたいですが、私がやるとエラーになりました（笑）

>You passed the --record flag but this project has not been setup to record.
>This project is missing the 'projectId' inside of 'cypress.json'.
>We cannot uniquely identify this project without this id.
>You need to setup this project to record. This will generate a unique 'projectId'.
>Alternatively if you omit the --record flag this project will run without recording.

調べると、同じエラーに遭遇している人がいるみたいで汗・・・

https://github.com/jhipster/generator-jhipster/issues/14309

ファイル`package.json` の中を以下のように変えると、動作しました。

変更前

```
"e2e:cypress": "cypress run --browser chrome --record ${CYPRESS_ENABLE_RECORD:-false}",
```
変更後

```
"e2e:cypress": "cypress run --browser chrome --record false",
```

# 今回のコード

https://github.com/sayuu-tf/learning_jhipster_3/commit/08d11e2f2bc43f7e3dd2b821d68a5b0cf921b09d
libmkl_intel_thread.so: undefined symbol: omp_get_num_procs

MKLを使用するにはOpenMPランタイムのインストールがほぼ必須であるが、Debianでlibomp-devをインストールしても認識されない(表題のエラーが出る)。
libmkl_rt.so内の文字列を探ると、libiomp5.soと見える。aptでインストールされるのはlibomp.so.5であるため、異なっているから認識されないと推測される。
https://xcalablemp.org/download/workshop/7th/kaneko.pdf によると、libompはlibiompをベースにしているため、symlinkを生やせばよかろう。

以下で通すことが可能である。

```
sudo ln -s libomp.so.5 /usr/lib/x86_64-linux-gnu/libiomp5.so
```

## 210906

本件。おそらくBullseyeでは不要です。誤報でした。すみません。

Bullseyeのファイル構造を見ると以下のようになっていた。

/usr/lib/x86_64-linux-gnu/libiomp5.so -> ../llvm-11/lib/libomp.so

どういう理由でこの記事を書いたのか忘れたが、Stretchで https://salsa.debian.org/cielavenir/intel-mkl/-/tree/stretch-bpo を使って入れた場合に必要になるのかも。

## 210906_2

もしかしたら弊社のdev_package-stripperを通すと/usr/lib/x86_64-linux-gnu/libiomp5.so symlinkが消えるのかもしれない。^^;;;
react-adminでSupabaseのユーザー認証を使う方法

Supabaseにはユーザー認証のAPIがあり、その認証システムをreact-adminで使う方法です。

## authProviderを実装する

react-adminには認証の仕組みがあり、これは好きな認証システムを使えます。自前の認証システムを使うには、Auth Providerを実装します。

なので、Supabaseの認証システムをreact-adminに組み込みたいときは、Supabaseの認証APIを使ったAuth Providerを作ることになります。

その実装は次のようになります:

```authProvider.ts
import { AuthProvider } from "ra-core";
import { UserIdentity } from "react-admin";
import { supabase } from "./supabaseClient";

const authProvider: AuthProvider = {
  async login({ username, password }): Promise<void> {
    const { error } = await supabase.auth.signIn({ email: username, password });
    if (error) throw error;
  },
  async logout(): Promise<void | false | string> {
    const { error } = await supabase.auth.signOut();
    if (error) throw error;
  },
  async checkError(): Promise<void> {},
  async checkAuth(): Promise<void> {
    const user = supabase.auth.user();
    if (!user) throw undefined;
  },
  async getPermissions(): Promise<any> {},
  async getIdentity(): Promise<UserIdentity> {
    const user = supabase.auth.user();
    if (!user) throw new Error("Failed to get user identity");
    return { id: user.id, fullName: user.email };
  },
};

export default authProvider;
```

## react-adminにAuth Providerを組み込む

Auth Providerが実装できたら、あとはreact-adminの`<Admin>`コンポーネントの`authProvider`パラメーターにそれを指定するだけです:

```tsx
import authProvider from './authProvider'

<Admin dataProvider={dataProvider} authProvider={authProvider}>
```
【vscode】Markdownにおける目次(TOC)の作成に、Markdown All in Oneが便利だった件

## はじめに

vscode にて、見出し (Heading) の内容に基づく目次(TOC, Table Of Contents)の作成方法を紹介します。

目次の作成には、[Markdown All in One](https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one)という拡張機能の[Table of contents](https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one#table-of-contents)を使います。
この目次は、見出しの変更に伴い自動で更新されます。

## デモ

- コマンドパレットで`Markdown All in One: Create Table of Contents`を実行すると、見出しの内容から目次が作成される
- 見出し更新後に`ctrl+s`で保存すると、目次も更新される

![vscode_toc_01.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110860/e170db4a-4ec8-5c45-80fd-ba1f2758a1b0.gif)

## インストール

1. `ctrl+p` -> `ext install Markdown All in One`
2. `Markdown All in One`をインストール

## 機能

### 目次の作成

`ctrl+shift+p` -> `Markdown All in One: Create Table of Contents`

### 目次の更新

- `ctrl+S`で保存
  - `markdown.extension.toc.updateOnSave`設定を切ることで、無効化も可能
- `ctrl+shift+p` -> `Markdown All in One: Update Table of Contents`

### 特定の見出しを目次から除外する

`<!-- omit in toc -->`を使います。
以下の場合、`## Table of Contents`が目次から除外されます。

```md
# Introduction

## Table of Contents <!-- omit in toc -->

- [Introduction](#introduction)
  - [Section 1](#section-1)

## Section 1
```

`markdown.extension.toc.omittedFromToc`設定を使い、User/Workspace 全体で一部の見出しを除外できます。

> ```json
> // In your settings.json
> "markdown.extension.toc.omittedFromToc": {
>   // Use a path relative to your workspace.
>   "README.md": [
>       "# Introduction",
>       "## Also omitted",
>   ],
>   // Or an absolute path for standalone files.
>   "/home/foo/Documents/todo-list.md": [
>     "## Shame list (I'll never do these)",
>   ]
> }
> ```

### セクション番号の追加/削除

目次を作成する際、見出しは一意である必要があります。
その際、セクション番号を使用すると、簡単に一意の見出しを用意できます。

`ctrl+shift+p` -> `Markdown All in One: Add/Update section numbers`

> ![section-numbers.gif](https://github.com/yzhang-gh/vscode-markdown/raw/master/images/gifs/section-numbers.gif)

見出しを追加した際も、上記のコマンドを実行することにより自動でセクション番号が更新されます。

## 参考

[Markdown All in One - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one#table-of-contents)
作業中ブランチで間違ってpullしてしまった場合の対応

## はじめに

ローカルで機能開発中に、最新のリモートブランチの動作確認をしようと、`git pull` をしました。
しかし、develop ブランチに切り替えるのを忘れており、作業中のブランチにpullしてしまったため、pullを取り消す方法についての備忘録です。
## 前提

- branchAで作業中
- まだコミットしていないファイルがある状態でpullしてしまった

## 対応方法

`git pull` は`git fetch` でリモートの最新状態のブランチを持ってきて、ローカルの現在いるブランチにマージするコマンドなので、pull してきたリモートブランチのマージを取り消しすればよいだけです。

つまりマージする前の位置にHEADを移動させればいいことになります。
### 1. HEADの移動履歴を確認

まずは、現在のHEADの位置を確認しましょう。

```zsh
% git reflog

# 現在のHEADの位置
e6ec135b (HEAD -> feature/branchA) HEAD@{0}: pull origin HEAD: Merge made by the 'recursive' strategy.

# ここに戻したい
eea24d80 HEAD@{1}: commit: branchA での作業内容
d4352211 (develop) HEAD@{2}: checkout: moving from develop to branchA
```

これでマージ前のHEADの位置が`HEAD@{1}` で有ることがわかりました。

後は`git reset --hard` を利用して、強制的にHEADを移動するだけです。
`git reset --hard` は、HEAD，作業ツリー、インデックスのすべてを指定したコミットに書き換えるコマンドになります。
### 注意点
ここで１つ注意しておくことは、現在のブランチで作業中の場合は、変更をコミットするか退避させておかないと、現在の作業内容が消えてしまうことです。

今回は`git stash` を使って退避させる方法を取ります。

### 2. 作業中ブランチの変更を退避

現在branchAで作業中の内容を退避させます。
※今回はまだ修正中でコミットしたくないため、この方法を適用

`git stash save "コメント" -u`

### 3. git pullの取り消し

`git reset --hard HEAD@{1}`

これで上手くHEADの位置が元に戻っていれば完了です。

## さいごに
間違えてしまっても焦らずに対処できるように、これからもどんどん気づいたことをかいていきます。
残念なチェックボックスの使い方

はじめてQiitaに投稿した時に、残念な気持ちになってしまったので記しておきます。
投稿前にこんな画面でますよね。
![Screen Shot 2021-07-15 at 9.33.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1214128/267ab87d-e54e-8eac-1db2-34199ce42d03.png)
このチェックボックスの使い方、ユーザーエクスペリエンス的に残念な点があります。それは、例えば「利用規約に同意する」にチェックを付ける場合、ピンポイントで□をクリックする必要があるということ。本来であれば、この文章のどこをクリックしても、チェックポックスにチェックがはいるべきなんですよね（諸説あり）。
輪をかけて残念なのは、チェックを付けたいのに、少々ポイントしたところがずれてしまうと、ハイパーリンクになっている利用規約やプライバシーポリシーがひらいてしまう。つまり、利用者側の意図しない作業が発生する確率を高めていると思います。
# わたしなら、こうデサインする
利用規約やプライバシーポリシーを読んでもらう必要があるのは当然です。ですので、直前の太字に書いてある部分の「利用規約」や「プライバシーポリシー」をハイパーリンクにして、チェックボックスの文字列は、クリックするとチェックボックスが付くエリアにします。押し間違いさせないために「利用規約とプライバシーポリシー」とチェックボックスの間はもう少しあけてもよいと思います。
SwiftのUserdefaultsに関して

UserDefaults
--
一言でいえばJavascriptのLocalStorageと同じもの。
起動した際にアプリ内にデータを保存してくれるキーバリュー型のDB。

なんのためのUserDefaults
--
データベースを保存しておきたいけど、DBにわざわざ渡す程でもないデータを送るため。
アプリを削除すると同時に消えるため重要なデータは保存できないが設定などの簡単なデータは入れられる。

書き方

```swift:UserDefaults.swift
//データを追加or更新
UserDefaults.standard.set({値}, forKey: {キー})
//データを取り出す
UserDefaults.standard.データ型(forKey:{キー名})
//データ型はobject int string double float　dictionally　data 等

//データを削除する
UserDefaults.standard.removeObject(forKey:{キー名})
//専用データ型がない限りは下の文字をつけて型キャストしてあげる
  as? Date
```


構造体も保存できる

```swift:kozotai.swift
//構造体の宣言
struct Person: Codable {
    let name: String
    let age: Int
}
/// 保存
let saveData = Person(name: "bokuboku", age: 23)//インスタンス化して変数へ
let encoder = JSONEncoder()//JSONエンコーダーをインスタンス化
if let encodedData = try? encoder.encode(saveData) {
    UserDefaults.standard.set(encodedData, forKey: "person")
}
 
/// 読み込み
if let savedValue = UserDefaults.standard.data(forKey: "person") {
    let decoder = JSONDecoder()//Jsonデコードをインスタンス化
    if let value = try? decoder.decode(Person.self, from: savedValue) {
        print(value)    // Person(name: "bokuboku", age: 23)
    }
} else {
    /// 値がない場合の処理
print("無いよ")
}
 
```
ググるの禁止で思いついた□Xと意味|を列挙する

（最初の投稿がこんなので良いのか不安ですが。。。）
ほんと、ただ、それだけです。思いつきいた□Xで年齢ばれそうですねー。こんなの列挙しようと思ったのは、とあるプレゼンテーションをきいていて、意味のわからない略語がたくさんでてきて、私自身思考停止。自分の知識の無さも問題かもしれませんが、話し手側にも問題があるのは間違い無いとおもいますので、その反面教師として。
とにかくリャクゴでてくるとクルシイ。

|略語|意味|解説|
|:--|:------|:--|
|AX|AX規格|IBM PCにJEGAカードを追加して日本語を表示できるようにしたパソコン|
|BX|PC-9801BX|NECがDOS/V機対抗で作った廉価版PC-9801シリーズ|
|CX|フジテレビの略語　|なんでCXなのかは知らない|
|DX|最近だとデジタルトランスフォーメーション|普通の人にはデラックスだよね|
|EX|エクストラ？|個人的には、コンタクトレンズメニコンEX|
|FX|為替で儲ける仕組み|カローラFX、好きだった|
|GX|グラボチップのなんか||
|HX|AXIAカセットテープのグレードにありそう||
|IX|Internet eXchange||
|JX|IBM PC-JX|森進一が宣伝キャラクター??|
|KX|思いつかない||
|LX|ルクス??||
|MX|グラボのチップのなんか|ゲーマーならよくわかるのかな？|
|NX|Lexusの車種|SUVだったと思う|
|OX|小田急系のスーパーマーケットの名前|小田急線沿線住民しかしらない|
|PX|ピクセル||
|RX|PC-9801RX|RX78系とか、Lexusの車もあり|
|SX|386SX、486SX|どちらもコスパ高かったCPU。仮想86モード最高|
|TX|筑波エクスプレス||
|UX|まぁ、ユーザーエクスペリエンスなんでしょう|PC-9801UXもあり|
|VX|毒ガス|PC-9801VXもあり|
|WX|ソニーのコンデジの型番？||
|XX|セリカXX|トヨタカップでジーコがもらってた|
|YX|思いつかない||
|ZX|仮面ライダー||
ReactでTodo App 作ってみた2

<h1>今日はチェックボックスの選択とtodoの削除！</h1>

<h4>学んだこと</h4>
Todoアプリの作成
・Todoの完了状態を変更できるようにする　チェックボックス
・全て完了にするボタンが動作できるようにする　チェックボックス
・全て完了にするボタンの一括操作をできるようにする　チェックボックス
・完了済みのTodoを削除できるようにする
　
■用語
**every**　
配列のメソッド
配列全てがtrueならtrue
配列全てがtrueじゃなければfalse

**filter**
配列のメソッド
配列に対してfilterをかける
filterの中で呼ばれた関数がtrueを返したやつだけ返す
ZennでGoogleアナリティクスを設定してPVを計測する


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33823/0680c29e-9e55-029d-e6d1-d02719373e26.png)

こんな感じでZennのPVを計測できるようにします。

大まかな手順は以下の3ステップです。

* 1. GoogleアナリティクスでトラッキングIDを取得する
* 2. ZennでトラッキングIDを設定する
* 3. トラッキングできていることを確認する

## 1. GoogleアナリティクスでトラッキングIDを取得する

アカウントがない場合は以下から作成しましょう。

https://support.google.com/accounts/answer/27441?hl=ja

はじめて[Googleアナリティクス](https://analytics.google.com/analytics/web)を使う場合は「測定を開始」をクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33823/75604963-78e1-512f-0841-901921afbde6.png)

アカウント名とデータ共有設定を選択して「次へ」をクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33823/90e47335-a653-a11a-63f8-605cc5eca913.png)

次はプロパティ名を記入してタイムゾーンと通貨を日本に設定したら「詳細オプションを表示」をクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33823/f4c02731-069f-14a7-9a09-b1e3ba3bc9af.png)

最新のGooogleアナリティクスではデフォルトだと「UA-」で始まるトラッキングIDが発行されないのでユニバーサルアナリティクスを有効にします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33823/974d1d0c-51a5-a768-b30d-e539c11b0fd6.png)

適当なビジネス情報を選択して「作成」をクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33823/c47d56f2-8ebb-7cfc-ae53-6112e601fc82.png)

作成が完了したら、UA-で始まるトラッキングIDをコピーしておきましょう。

## 2. ZennでトラッキングIDを設定する

[設定画面](https://zenn.dev/settings/account)にアクセスして「トラッキングIDを設定」をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33823/dfeb1a63-517a-e02e-90ec-34096c2e0dfd.png)

先ほどコピーしたトラッキングIDを入力して「保存する」をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33823/17f5dcfb-0412-2e0f-5063-d59aa3d020aa.png)

## 3. トラッキングできていることを確認する

最後にアクセス状況がトラッキング出来ていることを確認します。プロフィールページと記事ページ両方とも解析対象になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33823/0680c29e-9e55-029d-e6d1-d02719373e26.png)

また自分のGoogle Analyticsのアクセスを除外するアドオンが入っていると動作確認できないので、もし何も表示されない場合はチェックしておきましょう。
Wiki(の募金)をぶっ壊す党

## はじめに

みなさん、Wikipediaは利用してますでしょうか？
私はよく利用させていただいています。

サイトを利用している方なら下記のような、募金を促すお知らせをみたことがありますよね？ ↓↓↓

![スクリーンショット 2021-07-15 8.26.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682611/df99e5fc-a80f-b2d7-9ece-201dcd86962a.png)

募金の有無に関わらず、定期的に表示され邪魔に感じているのではないでしょうか？
今回はUserJSを利用してパージしてみようと思います！

## 準備

UserJSというサイト表示時にJavascriptを挿入してくれるChrome拡張機能を使用します！

- User Javascript and CSS  
https://chrome.google.com/webstore/detail/user-javascript-and-css/nbhcbdghjpllgmfilhnhkllmkecfmpld

## 実装

### まず、DOMを調べる
このメッセージの箇所を調べます。
![スクリーンショット 2021-07-15 8.29.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682611/31b31b17-25b7-e2a8-db16-5c84d5abe749.png)


```html
<div id="siteNotice">
```

`id="siteNotice"`というのがサイト全体のお知らせになっているようですね。
その中の、`id="centralNotice"`や`class="cn-fundraising"`, `class="frb-xxx"`辺りが
募金系のメッセージのようです
(fundraising=募金)

### JSでDOMを削除する
今回は、サイトのお知らせ自体削除してしまいます。
(記事が見れれば問題ないですしね)

- UserJS

```javascript
window.addEventListener('load', () => {
  const siteNotice = document.getElementById('siteNotice')
  if (siteNotice) {
    siteNotice.remove()
  }
})
```

![スクリーンショット 2021-07-15 8.39.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682611/d942114b-d60f-fc52-10ae-8c47f4988d9e.png)

※ UserJSはheadタグ内に追加されるコードを記述できます

### いざ、実行

![スクリーンショット 2021-07-15 8.39.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682611/f57e51b8-67f5-3580-b3e8-2c3055213889.png)

$\color{red}{\rm {Now\ it's\ clean!\ 🎉}}$

## さいごに

今回は、UserJSを利用してWikiの募金メッセージを削除してみました。
DOMが変わると対応できなくはなりますが、広告削除などにも応用が効きますので
よく利用するサイトであれば、UserJSなどでパージしておくと便利になるかなと思います！

ではでは　✈️
論文まとめ：Robust Lightweight Facial Expression Recognition Network with Label Distribution Training

# はじめに
AAAI 2021より以下の論文のまとめ
[1] Z. Zhao, et. al. Robust Lightweight Facial Expression Recognition Network with Label Distribution Training

- 論文
https://ojs.aaai.org/index.php/AAAI/article/view/16465

- 公式コード
https://github.com/zengqunzhao/EfficientFace
 -> pytorch
 -> 完全な学習済みモデルは提供されてないので、再学習させる必要あり

# 概要
- 1枚の画像から感情を読み取る系のモデル
- 既存の精度を上回りながら、高い推論速度・低パラメータ数を実現した
- localの特徴量をよりいかすため、local feature extractorを導入した
- 明確に分類し難い表情タスクに対応するため、labelの確率分布を目標値とするlabel distribution lossを導入した


# 手法

## 全体のアーキテクチャ
全体のアーキテクチャは以下。

![EfficientFace_img02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/f98b6ddc-8c66-473b-b297-ed637ae0bfad.png)

まず全体的に見ると、層も深くなく、かつ随所にdepth-wise conv, point-wise convが使われているため、簡素で高速な作り。

下部のlabel distribution generatorは事前に学習しておき、本学習時はパラメータを固定してラベルのdistributionを生み出す役割。

## local-feature extractor
このモジュールはよりlocalな特徴量を披露ためのもの。

上図左上において、input Feature Mapsを空間的に縦２つ、横２つと４等分し、それぞれに対してdepth-wiseで畳み込む。

以下の図は既存モデルとCAMでsalient mapを比較したもの。

![EfficientFace_img00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/9ecbef70-7880-5c3c-80a2-7a9459bdb1e6.png)


## Channel-spatial Modulator
ここではよりglobalな特徴量を取得するが、既存の表情読み取りモデルにおいてはglobalな畳み込みは冗長であるとし、２系統のシンプルなモジュールとしている。

１系統目はGAPして完全にglobalなものとし、fc２回を行う。

２系統目は3x3畳み込みとpoint-wize convを２回ずつ行う。

## Label distribution generator
先に挙げたように、label distribution generatorはtargetとなる確率分布を生み出す。

従来の分類的な手法だと、「neutral, happiness, sadness, surprise, fear, disgust, angry」に無理やり分類して学習するが、実際の表情はそれらの組み合わせであったり、中間で合ったりするらしい。

例えば「満足げに恐れ慄く」みたいな表情は happiness=0.5, surprise=0.1, fear=0.4 などとした方がよいだろうか。

具体的には、このモジュールから出たlogitにsoftmaxをかけて確立分布とし

```math
d_i = \frac{exp(v_i)}{\sum^{c-1}_{j=0} exp(v_j)}

```
この i クラスの確立とmainのモデルから出力される確立 $\tilde{d\_j^i}$ とで

```math
\mathcal{L} = -\frac{1}{N \times c} \sum^{N-1}_{i=0} \sum^{c-1}_{j=0} d^i_j log (\tilde{d_j^i})
```

と交差エントロピーを求める。

以下は各表情画像とそのラベルとなる確立分布。

![EfficientFace_img01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/18d590fe-d955-5eab-3ced-d9b25d2010fa.png)


# 実験と結果

## RAF-DB による精度、パラメータ数、速度の定量的評価
以下が結果。

![EfficientFace_img05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/579ccbaa-5d93-eb4b-632b-9c7dbf302a83.png)

パラメータ数、速度で既存手法を大きく上回りながら精度も若干上回っている。

## ablation study
以下が各モジュールを加えていったときの精度等の変化。

正直言って、各モジュールはあまり寄与してない。

![EfficientFace_img03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/1a01233b-a019-11fb-070c-3e82ebdc4c8a.png)
RDS Proxyとは？

## 勉強前イメージ

RDSに接続する際のプロキシ？

## 調査

### RDS Proxyとは？

接続元と接続先のRDSの間に設置し、アクセスを中継するサービスになります。
フルマネージド型のデータベースプロキシになります。

設定はRDSのProxiesから設定が出来ます。

![1RDS Management Console - Google Chrome 2021-07-13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/c13c59ba-3315-f773-b1b1-b271faa6f4ef.png)


ユースケースとしてはlambdaでサーバレスなシステムを構築する際に
lambda + RDSだと同時接続数を超えてしまいアクセスできない状態になります。
このときに lambda + RDS proxy + RDS構成でコネクションのプーリングなどを行います。

### RDS Proxyを特徴

- 接続プーリング

RDSの接続プールを管理し、アプリケーションからのアクセスと頻度を効率化します。
また、RDSに接続する際のリソースも上記によって軽減します。

- シームレス フェイルオーバー

RDS proxyは複数のAZにデプロイでき、
フェイルオーバーの際は新しいデータベースインスタンスに直接ルーティングすることで、
アプリケーションの再接続は不要で、ダウンタイムを短縮することが出来ます。

- アプリケーション セキュリティの向上

データベースがユーザ名/パスワードしか対応していない場合でも
RDS proxyの接続はiam認証が可能です。
また、Secrets Managerによる認証情報の一元管理も行います。

## 勉強後イメージ

max_connectionとかでエラーになってたらこれが良いって感じなんかな？
ただ、読み取りだけの話だったらリードレプリカでも・・？って思ったけど
RDS proxyは他にもフェイルオーバーとかセキュリティ面でのメリットもあるし
そもそもRDS proxyとリードレプリカはやり方が違うね。

## 参考

- [Amazon RDS プロキシ](https://aws.amazon.com/jp/rds/proxy/)
- [Amazon RDS Proxy のご紹介](https://pages.awscloud.com/rs/112-TZM-766/images/EV_amazon-rds-aws-lambda-update_Jul28-2020_RDS_Proxy.pdf)
- [RDS Proxyを使った実験](https://designare.jp/blog/noda/rds-proxy%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%9F%E5%AE%9F%E9%A8%93.html)