OmniAICreator/Qiita-1.07M huggingface dataset:
mindの研究 その12

#概要

mindが謎なので調べてみた。
vistaに入れた。
ニューラルネットワーク、書いてみた。
ウェイトとバイアスは、tensorflow.jsで学習済み。
xorを推論する。

#サンプルコード


```


tanh関数は　関数　小数入力　小数出力
　aは　小数変数
　bは　小数変数
　vは　小数変数
　vに　入れる
　[exp(v)]を　aに　入れる
　[exp(-1.0f × v)]を　bに　入れる
　[(a - b) / (a + b)]を　返す。

sigmoid関数は　関数　小数入力　小数出力
　vは　小数変数
　vに　入れる
　[exp(-1.0f × v)]に　1.0fを　ｆ加えて　vに　入れる
　1.0fを　vで　f割り　返す。



簡易小数表示とは
　３桁で　小数形式で表示すること。

w1は　構造体
　セル２は　小数変数
　列２は
　　８個の　セル２
　全体は
　　２個の　列２
。
b1は　８個の　小数変数。

w2は　８個の　小数変数。

b2は　小数変数。

xは　２個の　小数変数。

hは　８個の　小数変数。

メインとは
　kは　変数
　lは　変数
　yは　小数変数
　セル２(1, 1)に　-3.4681022fを　入れる
　セル２(1, 2)に　0.379121fを　入れる
　セル２(1, 3)に　-1.4711456fを　入れる
　セル２(1, 4)に　2.2247136fを　入れる
　セル２(1, 5)に　2.3135107fを　入れる
　セル２(1, 6)に　2.7624693fを　入れる
　セル２(1, 7)に　-1.83576fを　入れる
　セル２(1, 8)に　-1.1545312fを　入れる
　セル２(2, 1)に　2.1978209fを　入れる
　セル２(2, 2)に　0.2895245fを　入れる
　セル２(2, 3)に　2.0881913fを　入れる
　セル２(2, 4)に　-1.3450832fを　入れる
　セル２(2, 5)に　-1.4154571fを　入れる
　セル２(2, 6)に　1.9255028fを　入れる
　セル２(2, 7)に　3.2867477fを　入れる
　セル２(2, 8)に　1.956522fを　入れる
　b1(1)に　-0.6591252fを　入れる
　b1(2)に　0.3864409fを　入れる
　b1(3)に　0.4982838fを　入れる
　b1(4)に　0.3707547fを　入れる
　b1(5)に　0.3982254fを　入れる
　b1(6)に　-0.3612466fを　入れる
　b1(7)に　0.4284867fを　入れる
　b1(8)に　0.2701645fを　入れる
　w2(1)に　1.4324994fを　入れる
　w2(2)に　0.7911373fを　入れる
　w2(3)に　-2.3011343fを　入れる
　w2(4)に　-1.7614117fを　入れる
　w2(5)に　-2.4442003fを　入れる
　w2(6)に　3.9701838fを　入れる
　w2(7)に　-1.837263fを　入れる
　w2(8)に　-1.3641325fを　入れる
　b2に　0.9285715fを　入れる
　４を　回数指定して
　　もし　回数が　１と　等しい　ならば
　　　x(1)に　0.0fを　入れ
　　　x(2)に　0.0fを　入れ
　　　「0, 0 =  」を　表示し
　　つぎに
　　もし　回数が　２と　等しい　ならば
　　　x(1)に　0.0fを　入れ
　　　x(2)に　1.0fを　入れ
　　　「0, 1 =  」を　表示し
　　つぎに
　　もし　回数が　３と　等しい　ならば
　　　x(1)に　1.0fを　入れ
　　　x(2)に　0.0fを　入れ
　　　「1, 0 =  」を　表示し
　　つぎに
　　もし　回数が　４と　等しい　ならば
　　　x(1)に　1.0fを　入れ
　　　x(2)に　1.0fを　入れ
　　　「1, 1 =  」を　表示し
　　つぎに
　　hを　クリアし
　　yを　クリアし
　　２を　回数指定して
　　　回数を　kに　入れる
　　　８を　回数指定して
　　　　回数を　lに　入れる
　　　　セル２(k, l)に　x(k)を　f掛けて　h(l)を　f加えて　h(l)に　入れる
　　　繰り返す
　　繰り返す
　　８を　回数指定して
　　　回数を　lに　入れる
　　　h(l)に　b1(l)を　f加えて　h(l)に　入れる
　　　tanh関数(h(l))を　h(l)に　入れる
　　繰り返す
　　８を　回数指定して
　　　回数を　kに　入れる
　　　w2(k)に　h(k)を　f掛けて　yを　f加えて　yに　入れる
　　繰り返す
　　yに　b2を　f加えて　yを　f加えて　yに　入れる
　　sigmoid関数(y)を　yに　入れる
　　yを　簡易小数表示し　改行する
　繰り返す
　「おけ」を　表示する。





```

#実行結果

```


0, 0 =  0.000
0, 1 =  0.999
1, 0 =  0.999
1, 1 =  0.000
おけ

```

以上。
【Ruby on Rails】検索機能（非選択）

# 目標
![search.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700999/6e46f59b-a713-f55d-cb1f-adbce7e40535.gif)

# 開発環境
ruby 2.5.7
Rails 5.2.4.3
OS: macOS Catalina

# 前提
※　▶◯◯　を選択すると、説明等が出てきますので、
　　よくわからない場合の参考にしていただければと思います。

[【Ruby on Rails】検索機能（モデル、方法選択式）](https://qiita.com/japwork/items/e6ee225970b50ea5d796)
こちらを実装した上で編集を加えていきます。

# 流れ
1 controllerの編集
2 viewの編集

# controllerの編集
今回は曖昧検索に絞っています。
完全一致にしたい場合は、
where(name: @content)
となります。

```rb:app/controllers/searchs_controller.rb
class SearchsController < ApplicationController
  def search
    @content = params["content"]
    @users = User.where('name LIKE ?', '%'+@content+'%')
    @posts = Post.where('title LIKE ?', '%'+@content+'%')
  end
end
```

# viewの編集
```erb:app/views/search.html.erb
<% if @users.present? && @posts.present? %>
  <h3>【Users,Postsモデルの検索結果】検索ワード：<%= @content %></h3>
  <h4>・ユーザー名</h4>
  <%= render 'users/index', users: @users %>
  <h4>・投稿内容</h4>
  <%= render 'posts/index', posts: @posts %>
<% elsif @users.present? && @posts.empty? %>
  <h3>【Usersモデルの検索結果】検索ワード：<%= @content %></h3>
  <h4>・ユーザー名</h4>
  <%= render 'users/index', users: @users %>
<% elsif @users.empty? && @posts.present? %>
  <h3>【Postsモデルの検索結果】検索ワード：<%= @content %></h3>
  <h4>・投稿内容</h4>
  <%= render 'posts/index', posts: @posts %>
<% else %>
  <h3>検索ワード：<%= @content %>に該当はありません</h3>
<% end %>
```
<details><summary>補足【エラー時】</summary>
routingや部分テンプレートは
[【Ruby on Rails】検索機能（モデル、方法選択式）](https://qiita.com/japwork/items/e6ee225970b50ea5d796)
こちらを参考にしてください。</details>

<details><summary>補足【present、emptyについて】</summary>
[nil? empty? blank? present? exists? メソッドを状況に応じて使い分けよう[Rails]](https://qiita.com/takuyanin/items/aa8c1d82ab14f1827a6a)
こちらでわかりやすく解説されていました。</details>

<details><summary>補足【&&について】</summary>
[Rubyのand,&&とor,||の違いと注意点](https://qiita.com/riku-shiru/items/533a01bdf18e2e3eef46)
こちらでわかりやすく解説されていました。</details>
Pythonの文字列

Pythonの文字列

Pythonではcodecsという仕組を使用して、マルチバイト文字をさまざまなエンコードに変換しています。
日本語だけでなく、韓国語、中国語にも対応しているようです。

* マルチバイト文字

2バイト以上のデータで表現する。
1バイトでは表現できない文字のこと

[a]　1バイトで表現できる
[あ]　1バイトで表現できない

* 文字コード

代表的なものを調べて以下にまとめました

ASCII
アルファベットや数字、記号などをまとめた文字コード。最も基本的な文字コードとして世界的に普及しており、他の多くの文字コードがASCIIの拡張になるよう実装されていて、
文字を7ビットの値（0～127）で表し、128文字が収録されている。
「A」はASCIIでは0x41(0xは16進数を表す)。

イメージしづらかったので以下に小文字を英字部分を抜粋しました。

| 16進 | 文字 |
|:-:|:-:|
|0x61|	a|
|0x62|	b|
|0x63|	c|
|0x64|	d|
|0x65|	e|
|0x66|	f|
|0x67|	g|
|0x68|	h|
|0x69|	i|
|0x6a|	j|
|0x6b|	k|
|0x6c|	l|
|0x6d|	m|
|0x6e|	n|
|0x6f|	o|
|0x70|	p|
|0x71|	q|
|0x72|	r|
|0x73|	s|
|0x74|	t|
|0x75|	u|
|0x76|	v|
|0x77|	w|
|0x78|	x|
|0x79|	y|
|0x7a|	z|
 
Shift_JIS
日本工業標準調査会で標準化された日本語を含む様々な文字をまとめている、日本語を表すために多く用いられていた文字コードです。
全ての文字を2バイトで表します。
「あ」はShift_JISでは0x82E0です。
 
UTF-8
現在最も広く使われている標準的な文字コードです。全ての文字を1〜4バイトで表します。世界中の文字を扱えるため、標準的に使われるようになりました。
ASCIIと同じ部分は1バイトで表現し、そのほかの部分を2〜6バイトで表現する可変長の符号化方式となっています。
UTF-8は、ASCIIコードとの互換性が高く、世界中の多くのソフトウェアが使用しています。
「あ」はUTF-8では0xe38182です。
Pythonのバージョン2.xでは、標準の文字コードは ASCII でした。
Python のバージョン3.xでは、標準の文字コードはUTF-8となったため、文字コードを宣言することなく、日本語を扱えるようになっています。


ユニコード
国際標準化機構(ISO)でISO/IEC 10646の一部として標準化された文字コードです
目的としては、すべての国で、共通して利用できるエンコード目指して作られたそうです。


文字列をバイト型に変換するには

encode()
記載方法
 '文字列'.encode('文字コード名’)　　　※文字コード＝「utf-8」など

decode()
記載方法
b'バイト列'.decode('文字コード名')
Slackにリマインドを通知する方法 5選

社内でよく聞かれる「Slackに定期的にリマインドを送りたいんだけど」に回答しているうちに知見が溜まってきたのでアウトプットしていきます。

## 方法１ ショートカット
### ショートカットからリマインドを設定する
1. ショートカットメニューから「自分自身にリマインダーを設定する」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206219/002db272-a7d7-e24e-5bf3-bffde5ef23a3.png)

2. いつ、時間、説明を入力して作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206219/ae5d47c7-854d-1503-8996-158293f9bfbf.png)

## 方法2 /remind
詳細は[公式](https://slack.com/intl/ja-jp/help/articles/208423427-%E3%83%AA%E3%83%9E%E3%82%A4%E3%83%B3%E3%83%80%E3%83%BC%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B)に詳しく書いていますが、「いつ」の部分を省略して投稿すると時間設定のダイアログが表示されるので便利です。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206219/6192abc7-4a80-a189-3627-8ba2c796559e.png)

## 方法3 Microsoft Power Automate
Office365を使っていれば契約形態にもよりますが[Microsoft Power Automate](https://docs.microsoft.com/ja-jp/power-automate/)が利用できます。  
Power Automateには様々なアプリケーションとのコネクタが用意されており、ノンプログラミングでシステム間の連携処理を行うことができます。
今回は単純なSlackへの通知だけですが、他システムの変更を受取ってSlackに通知するなどが簡単に実装できます。  
※もちろんAzure LogicAppsでも同様の処理を実装できます。  
1. 「予定フローを作成」で繰り返し頻度や通知時間を設定して作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206219/24346e6f-6bb0-262b-8c6a-52d92f4e9e62.png)
2. 「新しいステップ」でSlackを検索して「投稿メッセージ」アクションを選択
3. 投稿するチャンネルとメッセージを入力  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206219/e3fd56db-bf24-e5af-4e17-56d4a256deb4.png)
※プライベートチャンネルは候補に出てこないのでカスタム値から入力する必要があります。
4. 保存を押せば完了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206219/1c5adb05-cab2-adde-b8cd-c860a6adc20d.png)

## 方法4 Slackワークフロービルダー
[ワークフロービルダー](https://slack.com/intl/ja-jp/help/articles/360035692513-%E3%83%AF%E3%83%BC%E3%82%AF%E3%83%95%E3%83%AD%E3%83%BC%E3%83%93%E3%83%AB%E3%83%80%E3%83%BC%E3%82%AC%E3%82%A4%E3%83%89)を用いることで定期的なリマインドも可能です。  
1. 「スケジュールされた日付と時間」トリガーで作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206219/3e55b143-d859-2125-b95b-359282af8e90.png)
2. 細かく頻度と時間を設定できます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206219/65c2e235-9f0d-d7a6-7c21-083b996ad152.png)
3. 「ステップを追加」で「メッセージを送信」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206219/27e536f6-52ef-9676-7898-44c8dbc843a6.png)
※ボタンを含めることで完了確認なども可能

## 方法5 Botを作成する
BotやSlack APIを駆使して作りこめば独自のリマインダーが作成できます。
例えば：https://qiita.com/tasmania/items/e4a6103ddee1e876ad13

方法は無限にあると思うのでご自身の業務に合った形で実装してみてください！

### おわりに
快適なSlackライフを！
Laravelでログインユーザーメールアドレスを暗号化して保存する

Laravelのユーザー登録に関してですが、
パスワードはハッシュ化して保存されますが、メールアドレスはプレーンテキストで保存されるため、
セキュリティ強化で暗号化して保存させます。


まずはユーザーモデルのメールアドレスを取り出すときに自動で暗号化/復号化されるように設定します。



```app/Models/User.php
    public function getEmailAttribute($value)
    {
        return openssl_decrypt($value, 'AES-128-ECB', '暗号化キー');
       }
    public function setEmailAttribute($value)
    {

        $this->attributes['email'] = openssl_encrypt($value, 'AES-128-ECB', '暗号化キー'));
    }
```

次にログイン時のメールアドレスのチェックに関してですが、そのままだと暗号化前のメールアドレスと、暗号化された文字列でログインチェックがなされるのでログインできません。
そこで、ログインチェックの前にメールアドレスを暗号化してあげます。
※追記（credentialsをオーバーライドすると回数チェックのキャッシュファイル名が変わってしまうので、loginをオーバーライドしたほうがいいです。）

```app/Http/Controllers/Auth/LoginController.php

    public function login(Request $request)
    {
        $this->validateLogin($request);
        $request->merge(['email' => openssl_encrypt($request->input('email'), 'AES-128-ECB', \Config::get('kakecco.encryption.key'))]);
        // If the class is using the ThrottlesLogins trait, we can automatically throttle
        // the login attempts for this application. We'll key this by the username and
        // the IP address of the client making these requests into this application.
        if ($this->hasTooManyLoginAttempts($request)) {
            $this->fireLockoutEvent($request);

            return $this->sendLockoutResponse($request);
        }

        if ($this->attemptLogin($request)) {
            return $this->sendLoginResponse($request);
        }

        // If the login attempt was unsuccessful we will increment the number of attempts
        // to login and redirect the user back to the login form. Of course, when this
        // user surpasses their maximum number of attempts they will get locked out.
        $this->incrementLoginAttempts($request);

        return $this->sendFailedLoginResponse($request);
    }
/*
    protected function credentials(Request $request)
    {
        $request->merge(['email' => openssl_encrypt($request->input('email'), 'AES-128-ECB', '暗号化キー')]);
        
        return $request->only($this->username(), 'password');
    }
*/
```

これでログインまでできるはずです。
デフォルトのままだと、ログイン失敗した後、暗号化されたメールアドレスが表示されてしまいますので適当に修正してください。

暗号化で毎回同じ文字列が作成されるためセキュリティ的にはそんなに大丈夫なわけではありませんが、平文で保存するよりはましかと思います。
また暗号化のアルゴリズムに関してですが、可逆式で毎回同じ結果で暗号化する必要があります。
Crypt::encryptStringは毎回異なる結果になるのでログイン時の処理にもうひと手間かける必要があります。


おわり。
Sunaba講座 #2　複数行の実行 ＆ メモリメップド I / O について

## はじめに
sunabaの導入については「[Sunaba講座 #0 導入編](https://qiita.com/gmasa/items/62ae871d1f017d4cc682)」をご覧ください。各講座へのリンクも貼ってあります

## 課題01　画面に点をたくさん表示
タイトル通り、**画面に点をたくさん表示させてみましょう。**どこにいくつ点を描くかはおまかせします。
1. 作業フォルダ内でファイル新規作成。ファイル名はkadai01.txtです。
2. 前回の課題は１行書いて点１つ。たくさん書くには、その分だけ行を増やせばいいはずです。
3. 点を描く位置と点の色は、Sunaba早見.pdf で確認しましょう。
4. 思う存分書けたら、実行しましょう。

---
課題は早々に終わってしまったかと思います。
以下は**C言語学習の先取り**になります。関係ないぜ、という人は次の課題に進んでください。

### メモリマップド I / O
Sunabaのメモリと画面の仕組みは、**メモリマップド I / O（アイオー）** と呼ばれる形式です。
メモリマップド I / O とはコンピュータ内部の形式の一種で、I / Oとは input/output、つまり入出力のことを指します。コンピュータにおける入出力は、**何を中心として見た入力/出力なのか**によって変わります。
パソコンとマイコン（機器に組み込む小さなコンピュータ）を比較すると以下のようになります。

|  | 入力 | 出力 |
|:-----------|:------------:|:------------:|
| パソコン | キーボード、マウス、Webカメラ 等 | ディスプレイ、スピーカー 等 |
| マイコン | スイッチ、可変抵抗器、光センサ 等 | LED、液晶表示器、モーター 等 |

SunabaはPC上で動かすアプリケーションなので、上の表でいうとパソコンの方に該当します。（Sunabaでカメラ情報は入手できませんが。。。）

メモリマップド I / O をもう少し詳しく表現すると、**メモリの読み書きと同じ方法で、コンピュータ（CPU）と入出力機器を通信させる仕組み** と言えます。  

### メモリってそんなに大事？
ここまで「メモリ、メモリ」と言われると、「メモリを理解していないとプログラミングできないの？」と不安になる人がいるかもしれません。**大丈夫ですよ**と言いたいですが、**ダメな場合**もあります。デスクトップアプリやWebアプリを作る場合、メモリを意識する機会は少ないかもしれませんね。

- 日記アプリや店舗管理システムを作る時に細かなメモリ管理はきっといらないでしょう。膨大なデータの扱いではメモリ操作よりデータベース設計の良し悪しが求められそうです。
- Webアプリ開発ではデータ通信量の対処の方が大変そうです。（専門外なのでちゃんとは分かりません:bow_tone1:）

ただ、データサイズ縮小やスピードUPを要求する場合はその限りではないでしょう。

色々書きましたが、機器類のコンピュータ制御を代表に、C言語で開発するものについてはメモリの理解が必須です。この講座では後日、C言語を使ってマイコンのメモリやI/Oを直接操作することを想定しています。

- <details><summary>研修では．．．</summary>
  もうやるしかないです。Sunabaでメモリ操作に慣れておきましょう。
  </details>

---
次回は、[Sunaba講座 #3　線の描画、while、式の種類 について](https://qiita.com/gmasa/items/1d3b96703622da551a3d)です。
簡単なアプリ　複数計算機　＋

簡単な計算機をつくて見ました。

使用言語はHTMLと、Javascriptです、

HTMLのコードです。


 


  <h1>計算プログラム</h1> 


      <h2>足し算</h2>

      <div>
      	 1つ目の値<input type="text" id="atai1">       <br>

      	 2つ目の値<input type="text" id="atai2">       <br>

      	 3つ目の値<input type="text" id="atai3">       <br>

      	 4つ目の値<input type="text" id="atai4">       <br>

      	 5つ目の値<input type="text" id="atai5">       <br>

      	 　　　　　　　
      	 <button onclick="tashizan()">
      	 	足し算
      	 </button>        <br>                           


      	 結果<br>

      	 <div id="kekka">

      	 	
      	 </div>　

      </div>


次にJSのコードです。




　<script type="text/javascript">
            
      　//足し算の式


            function tashizan(){

        

         text01 = document.getElementById('atai1');
         text02 = document.getElementById('atai2');
         text03 = document.getElementById('atai3');
         text04 = document.getElementById('atai4');
         text05 = document.getElementById('atai5');

         


         x = parseInt(0 + text01.value);
         y = parseInt(0 + text02.value);
         u = parseInt(0 + text03.value);
         k = parseInt(0 + text04.value);
         t = parseInt(0 + text05.value);





         z = x + y + u + k + t;

         kekka = document.getElementById('kekka');

         kekka.innerHTML = z; 

            }




     
完成形はこんな感じです。


![足し算.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/724497/6a84bf75-dfa8-5478-f1cd-9882418becd4.jpeg)
[javascript] Auth0でManagement APIをより簡単に使う

# 通常ルート

[Auth0 Management APIドキュメント][1]

1. Machine-to-Machine Applicationを[まず作る][3]([参考][2])
2. デフォルトで存在するAuth0 Management APIを選択しpermissions(scopes)を選ぶ
3. 出来たMachine-to-Machine Applicationの`client_id`、`client_secret`でManagement APIの[tokenを取る][4]
4. authorization: `Bearer ${token}`みたいな形でManagement APIを呼ぶ

REST APIなので通信ができれば言語は問わないが、Javascript(node)でAPIを呼ぶ前提なら、かなり簡素にかける。


# [node-auth0][5] npmパッケージを使う

```js:readmeにあるサンプルコード
var ManagementClient = require('auth0').ManagementClient;
var auth0 = new ManagementClient({
  domain: '{YOUR_ACCOUNT}.auth0.com',
  clientId: '{YOUR_NON_INTERACTIVE_CLIENT_ID}',
  clientSecret: '{YOUR_NON_INTERACTIVE_CLIENT_SECRET}',
  scope: 'read:users update:users'
});
```

ManagementClientを使って、clientId、clientSecretを渡せば裏でManagement APIのtokenを取ってきてくれるので、コードがスッキリする。

[githubのリポジトリ][6]を見るとわかるが、`ManagementClient`には26個のプロパティがあって、


```js
// https://auth0.com/docs/api/management/v2#!/Users_By_Email/get_users_by_email
auth0.users.getByEmail("email@address.local", (err, users) => console.log(users))
```

みたいにAPIの呼び出しが全てラップされている。

現状Typescriptは用意されていないようなので、ソースを読まないといけないのが難点。
現状[これがドキュメント][7]っぽい。

# 躓き点

![Application_Details.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16757/3e1f2a54-2265-d40e-6a76-536be564e564.png)

domainとかが`domain: '{YOUR_ACCOUNT}.auth0.com'`になっているけど、最近作ったアカウントのApplicationのdomainは`.us`が間に入ってて、気づかず`dev-tm15fv0o.auth0.com`みたいな形でテストしてた。
これでずっと`access_denied: {"error":"access_denied","error_description":"Unauthorized"}`のエラーで悩まされてた。

![ubuntu_❐_0_●_2_docker.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16757/670d47e1-65e0-08c6-5f36-89b4200857b1.png)

（accountとも言うし、tenantとも言うし、他にも色々同じ箇所を別の言い方で説明しているのでとにかくドキュメントが読みづらい...）



[1]: https://auth0.com/docs/api/management/v2
[2]: https://auth0.com/docs/tokens/management-api-access-tokens
[3]: https://auth0.com/docs/tokens/management-api-access-tokens/create-and-authorize-a-machine-to-machine-application
[4]: https://auth0.com/docs/tokens/management-api-access-tokens/get-management-api-access-tokens-for-production
[5]: https://www.npmjs.com/package/auth0
[6]: https://github.com/auth0/node-auth0/blob/master/src/management/index.js
[7]: https://auth0.github.io/node-auth0/index.html
StartCoroutine での切り替わりのタイミング

# 環境 
Unity2017.4.1f1

コルーチン呼び出しで、関数が切り替わるタイミングのメモ。

```
	void Start () {
		int twork = 0;
		Debug.Log("Start1 twork="+twork);
		StartCoroutine( Test00( (T) => { twork = T; } ) );
		Debug.Log("Start2 twork="+twork);
	}

	public IEnumerator Test00(Action<int> func)
	{
		func(99);
		yield return null;
		func(88);
		Debug.Log("Start3 ");
	}

```
上記のようなコードを作成して実行してみた。
なんとなく、コルーチン処理は登録後、即座に実行はされていないと思っていた。
つまり、
Start2 twork=0
となるのではないか？

## 結果

Start1 twork=0
Start2 twork=99
Start3

となった。
なるほど、StartCoroutineが呼ばれた後は、その関数に遷移し、yield return が呼ばれるまで処理を行い
呼ばれた後に呼び先の関数の処理が継続されるのね。

個人的な備忘録です。
WordPressをSQLで色々変換するクエリ

めったにないのですが、たまにあるのが投稿タイプの変更だったり、一括でカテゴリーをつけたりする事がありますね。
豆腐を買い忘れたくらいの感じでそういうオーダーが来ますよね。

そんな時にsqlから一括更新すると楽なので、いくつかメモしておきます。
自分はphpMyAdminのSQLに貼り付けて更新してます。（変更前にバックアップ必須です）

# カスタム投稿タイプの変更

[Use SQL Query In phpMyAdmin To Change Custom Post Types in WordPress](https://wpsites.net/wordpress-admin/use-sql-query-in-phpmyadmin-to-change-custom-post-types/)

```
UPDATE `wp_posts` SET `post_type` = 'photos' WHERE `post_type` = 'members';
```
投稿タイプ「members」を「photos」へ変更します。通常投稿から変更する場合は、whereのところを「post」ですね。

# taxonomy名の変更
[https://wordpress.stackexchange.com/questions/1037/renaming-custom-post-types-and-taxonomies](https://wordpress.stackexchange.com/questions/1037/renaming-custom-post-types-and-taxonomies)

```
UPDATE  `wp_term_taxonomy` SET  `taxonomy` =  'new_taxonomy_name' WHERE  `taxonomy` = 'old_taxonomy_name';
```
こちらはタクソノミーの変更です。通常投稿のカテゴリーからカスタムタクソノミーへ変更する時に使います。カスタム投稿タイプの変更とセットでよく利用しますね。

# 特定のカテゴリーに属する投稿を任意のカスタム投稿タイプに変換する SQL

[https://gist.github.com/wokamoto/4159068](https://gist.github.com/wokamoto/4159068)

```
update wp_posts
set post_type = 'faq'
where post_type = 'post'
and exists
(select object_id
from wp_term_taxonomy as t
inner join wp_term_relationships as r on t.term_taxonomy_id = r.term_taxonomy_id
where t.term_id = 2
and r.object_id = wp_posts.ID);
```
上記例は、カテゴリーID「2」に属する通常投稿を、カスタム投稿タイプ「faq」へ変更します。
この後、term_id 2のtaxonomyをcategoryからfaq_categoryとかに変更します。

#上記の反対（任意のカスタム投稿タイプを通常投稿、特定のカテゴリーに変換）
```
INSERT INTO wp_term_relationships SELECT id,7,0 FROM wp_posts WHERE `post_type` = 'announcement';
UPDATE `wp_posts` SET `post_type` = 'post' WHERE `post_type` = 'announcement';
```
最初にカテゴリーをセットして、そこから変換します。
カテゴリーをセットしてある場合は、先ほどのを利用出来ます。
VSCodeの幸せになる設定と拡張機能

## はじめに

「これもおすすめっ！！」ってものがあったら教えて下さい！！

## 設定

### 1. ミニマップをカラーブロックに

false

```text
editor.minimap.renderCharacters
```

![プレゼンテーション1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416136/a1d85149-2736-7fa4-f6e0-d0e9f22b2977.png)

### 2. なめらかなカーソルアニメーション

true

```text
editor.cursorSmoothCaretAnimation
```

![プレゼンテーション4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416136/a9d75259-af21-feb4-778b-f56b30f19e49.png)


### 3. 保存時、ファイル末尾に空白行を挿入

true

```text
files.insertFinalNewline
```

![プレゼンテーション3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416136/193c94f7-f154-321c-f8c3-26cdb0bb5253.png)

### 4. ツリーのインデントサイズ

30が丁度いい

```text
workbench.tree.indent
```

![プレゼンテーション2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416136/25c02558-48ee-bab6-4cc1-dbcaa2943f0d.png)

## 拡張機能

### 1. Python docstringを手軽に書く

[Python Docstring Generator](https://marketplace.visualstudio.com/items?itemName=njpwerner.autodocstring)

> ![demo](https://github.com/NilsJPWerner/autoDocstring/raw/master/images/demo.gif)

### 2. 日本語のミスを見つける

[テキスト校正くん](https://marketplace.visualstudio.com/items?itemName=ICS.japanese-proofreading)

> ![demo](https://github.com/ics-creative/project-japanese-proofreading/raw/master/images/demo.gif)

### 3. コード内のコメントにカーソルをあわせると翻訳してくれる

[Comment Translate](https://marketplace.visualstudio.com/items?itemName=intellsmi.comment-translate)

> ![demo](https://github.com/intellism/vscode-comment-translate/blob/master/doc/image/ja/Introduction.gif?raw=true)

### 4. スペルミスを見つける

[Code Spell Checker](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker)

> ![demo](https://raw.githubusercontent.com/streetsidesoftware/vscode-spell-checker/master/packages/client/images/example.gif)
【VBA】ActiveWorkBookは抽象的な参照で危険

# はじめに
ExcelVBAを書くとき、`ActiveWorkBook`を多用されているのをよく見かけます。
しかし、マクロ実行中に別のExcelブックを開らいたことで、そっちに処理を実行されてぶっ壊わされた事は無いでしょうか？
マクロ実行中は、別のExcelブックを開かないようにアナウンスされたりしますが、処理が長かったりすると使う人は、不便を感じており、根本的な`問題が解決していません`。
時々、お客様から何とかならないかという相談を受けます。

そんなときは、`ThisWorkBook`に置き換える事で、解消できます。
そうすることで、`マクロを実行しているExcelブック`にだけ、マクロの処理が実行されます。

筆者はActiveWorkBookは使いません。
ググると例が`ActiveWorkBook.ホゲホゲ`で書いてあるものが多数派であるせいもあるのかなぁ・・。


# ActiveWorkBookってなあに？

ActiveWorkBookとは、`現在表示しているExcelブック`のことです。`抽象的な参照方法`のため、マクロ実行中に別のExcelブックを開くと、そちらが`現在表示しているExcelブック`になってしまいます。


# ActiveWorkBookとThisWorkBookの違い

```
ActiveWorkBook：現在表示しているExcelブック（という抽象的な参照方法）
ThisWorkBook　：マクロを実行しているExcelブック（という限定的な参照方法）
```

# 置き換えても大丈夫？
`ActiveWorkBook`を`ThisWorkBook`に置き換えても大丈夫かという事ですが、
どちらもWorkbookクラスの派生なのでWorkbookでできる事は、継承しているので大丈夫です。
※細かいところで固有メソッドがあるかも知れませんが、今のところそういうのに当たった事はありません。

# まとめ
`ThisWorkBook`を使った方が安全ですよって話でした。
Auth0 + Webサイトで設定しておいたほうがいいこと

Auth0
https://auth0.com/jp/

WordPressとの連携はプラグインがある。
https://ja.wordpress.org/plugins/auth0/

Auth0は無料プランから開始できるけど、ここは覚えておいたほうがいいよというポイントのメモ。

最初にざっくりまとめるとAuth0では

- カスタムドメイン設定しておいた方が面倒は少ない：Auth0 の有料プラン必要
- カスタムメールプロバイダ：配信されるメールを日本語にしたり文面をカスタマイズにしたければメールサーバーの設定が必須

です

# ユニバーサルログイン
ログイン（認証）ページをAuth0のユニバーサルログインページにリダイレクトさせる場合は問題ありません。
ただし、**ログイン（認証）のフォームをアプリケーション（Webサイト側に）埋め込みたい時はテナントでカスタムドメインの設定が必要**（Auth0でのカスタムドメインの利用は有償です）。
「Cross-Origin Authentication」の設定もありますが、ここに手間や時間をかけるくらいならカスタムドメインの設定をした方が良いです。

https://auth0.com/docs/login/embedded-login/cross-origin-authentication

# SNSアカウントでのログイン
SNS側でアプリの作成が必要

## Google Auth
> This connection is using Auth0 development keys. Auth0 development keys are intended for testing and are not recommended for Production environments. This connection should be configured with your own keys to enable SSO, federated logout, and other features. More information about Social Connection developer keys.

すぐに使えるけど開発用のキーだから**本番環境では自分で諸々取得してね**。と言う説明。
https://auth0.com/docs/connections/social/devkeys

![スクリーンショット 2020-09-15 20.28.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18348/cd7cab80-0f2a-6ec1-f7b6-e95afd41b5a0.png)

ちょっと罠っぽいのがGoogle Authの赤い枠の部分。FacebooやTwitterの場合はアプリケーション名になるのに、Googleは認証情報で設定した**リダイレクト先のURLのドメイン**になる。利用者に対してドメイン違うことで惑わせたくない場合はAuth0でのカスタムドメイン設定しておきましょうと言う話。

## Facebook アプリ
- メールアドレス・名前の取得になるので、アプリにプライバシーポリシーやWebサイトのURLを設定する必要あり。
- アプリをライブモードにしておかないとAuth0からエラーが返されます

## Twitter アプリ
https://auth0.com/docs/connections/social/twitter

1. TwitterアカウントでTwitterのデベロッパーの申請
2. 1のアカウントのメールアドレスに申請の確認のメールが配信されるので認証（申請の完了）
3. Twitterがアプリを承認するのを待つ
4. 3の承認がされたらアプリとAuth0との連携

Twitter アプリの作り方は以下を参照
https://dev.classmethod.jp/articles/auth0-twitter/

### Twitterからメールアドレスを取得したい場合
Auth0のドキュメント
https://auth0.com/rules/get-twitter-email

- Twitterアプリで Privacy Policy URL と Terms of Service URL を埋めてからPermissionsでメールアドレス取得にチェックを入れる
- Auth0のRulesで「Get email address from Twitter」を作成し、メールアドレスを取得するルールを追加。
    - この時TwitterのコンシューマーキーとコンシューマーシークレットをRulesに変数で設定しておく
    - ところがプリセットされているGet email address from Twitterのルールではメールアドレスが取得できないという罠がある。
    - なので、を少し書き換えて`app_metadata`というフィールドを追加して格納するよう変更する必要あり。具体的なコードはうちのチームのエンジニアが書いてくれるはず。。。
        - もしかしたらAuth0側でこのRulesのプリセットのコードが改修されている可能性があるので、最新ドキュメントは必ず読んでテストしてください。

# メールのカスタマイズ
> Warning! You are using the Auth0 Email Provider which is only intended for development/trial use. Any customizations made to this email template will NOT take effect until a Custom Email Provider is configured. All emails sent will use the default Auth0 templates, even if customized. Please enable a Custom Email Provider for production use of custom templates.

デフォルトでもメールは配信されるけど、**本番環境ではCustom Email Providerの設定をしてね**。と言う説明。またメールのサブジェクトや文面をカスタマイズしたい場合もCustom Email Providerの事前設定が必要。
https://auth0.com/docs/auth0-email-services/configure-external-smtp-email-providers

# [番外] Webサイト側でCloudFrontなどCDNを通す場合
WebサイトとAuth0間の認証はCookieでやりとりします。
CDNや強固なキャッシュ対策を行っている場合はWebサイト側で

- コールバックURLはキャッシュしないようにしておく 例：`/auth0-callback*` をキャッシュしない
- キーが `auth0_*`のCookieをホワイトリストを追加

としておく必要があります。

- - - -

無料からスタートできるのはあくまで開発までなので、本運用にあたってはちゃんと課金しましょうってことで現場からは以上です。
VSCodeのポップアップ解説を非表示にする


# 久しぶりに…キレちまったよ…
VSCodeでコーディングしてる時に、マウスカーソルがコードの上にホバーすると出てくる解説がクッッッッッッッソ邪魔なので非表示にします

# How to 非表示
`Settings > Editor > Hover:Enabled` のチェックを外すだけ
![スクリーンショット 2020-09-17 16.47.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/690270/de462344-d1e2-c543-4a84-f2adbd0c1445.png)

# できました
これでコードにマウスカーソルが合っても、ポップアップで解説がでてきません！
**やった〜🎉 超快適〜🥳**
Java Stringクラスについて

勘違いしていたので整理するために投稿しています。


String name = "田中君";
String name = new String("田中君");
これら2つは同じ意味であり、文字列は多く使う事があるため特別に
**String name = "田中君";**での入力が可能である。

つまり文字列オブジェクトとなり変数nameに田中君が代入されている訳ではなくnameには参照データが格納されている。
Pythonで特定の条件を満たす要素だけ抽出

忘れがちなのでメモ

## コード
```python
import pandas as pd

data = [
  {"name": "Taro Tanaka",   "organization": "Example1", "age": 18},
  {"name": "Hanako Yamada", "organization": "Example1", "age": 20},
  {"name": "Ichiro Suzuki", "organization": "Example2", "age": 33},
  {"name": "Michiko Sato",  "organization": "Example2", "age": 50},
  ...
]

# オーソドックスな方法
arr = [
  r for r in data
  if r["organization"] == "Example1" and r["age"] > 18
]
## sort
sorted_arr = sorted(arr, key=lambda x: x["age"])


# pandasを利用
df = pd.DataFrame(data)
arr2 = df[(df["organization"] == "Example2") & (df["age"] > 18)]
## sort
sorted_arr = df[(df["organization"] == "Example2") & (df["age"] > 18)].sort_values('age')
```
CloudflareでWebPとそれ以外を別々にキャッシュさせる

# 前提
本来はブラウザのVaryヘッダーを見て `hogehoge.png` とリクエストが来ても
WebPに対応してる＆WebP画像があれば `hogehoge.png.webp` を返してくれますが
執筆現在、CloudflareはサーバーからのVaryヘッダーを無視してしまい
ブラウザのacceptによってwebpかpng|jpegかをハンドリングすることができません。
そのため、半ば無理やりフロントエンドでそれを実現しようと思います。
ちなみに使う技術はnuxt（webpack+vue+scss）です。
※ サーバー側でWebPを内部リダイレクトで返す処理は割愛させていただきます。

# 結論
画像のリクエストにWebP非対応のときだけクエリをつけることで
Cloudflare上で別リクエスト扱いさせ、WebPとそれ以外を別々にキャッシュさせます。

# JS

```javascript

const CAN_USE_WEBP = (() => {
  const elem = document.createElement('canvas')
  if (elem.getContext && elem.getContext('2d')) {
    return elem.toDataURL('image/webp').indexOf('data:image/webp') === 0
  }

  return false
})()

if (!CAN_USE_WEBP) {
  // webp非対応ならクラス付与
  document.body.classList.add('no-webp')
}
```

# Component
画像を表示するものはすべて共通のコンポーネントで表示するようにする。
あくまで下記は一例。ようするに通常のtypeとWebP用のtype二種類を用意してあげる。

```vue
<template>
  <picture>
    <source
      v-for="(source, i) in sources"
      :key="`image-def-${_uid}-${i}`"
      :media="source.media || false"
      :srcset="source.srcset"
      type="image/webp"
    />
    <source
      v-for="(source, i) in sources"
      :key="`image-webp-${_uid}-${i}`"
      :media="source.media || false"
      :srcset="source.srcset + '?nowebp'"
      :type="defaultMIME"
    />
    <img :src="defaultSrc + '?nowebp'" :alt="alt" :type="defaultMIME" loading="lazy" />
  </picture>
</template>

<script lang="ts">
import { Component, Prop, Vue } from 'nuxt-property-decorator'
const MIME_REGX = /\.([a-z]+)$/

@Component
export default class extends Vue {
  @Prop({ default: '' })
  sources!: {
    srcset: string
    media?: string
  }[]

  @Prop({ default: '' })
  alt!: string

  get defaultSrc() {
    return this.sources[this.sources.length - 1].srcset
  }

  get defaultMIME() {
    const src = this.defaultSrc
    const match = src && src.match(MIME_REGX)

    switch (match && match[1]) {
      case 'png':
        return 'image/png'
      case 'jpg':
      case 'jpeg':
        return 'image/jpeg'
      case 'gif':
        return 'image/gif'
      default:
        console.warn(`invalid extname [${src}]`)
        return ''
    }
  }
}
</script>
```

# SCSS
```scss

// mixin定義
@mixin webp-bgimage($url) {
  background-image: url($url);

  @at-root .no-webp & {
    background-image: url($url+'?nowebp');
  }
}

// 背景画像を指定するところで
.class {
  @include webp-bgimage('hogehoge.jpg');
}

// そうすると下記のように2種類が指定される（.no-webpは上記JSで設定）
.class {
  background-image: url('hogehoge.jpg');
}
.no-webp .class {
  background-image: url('hogehoge.jpg?nowebp');
}
```

# Nuxt（nuxt.config）
画像のパスに `[query]` が付与されるようにする

```javascript

export default {
  build: {
    filenames: {
      img: ({ isDev }) => isDev ? '[path][name].[ext][query]' : 'images/[hash:7].[ext][query]'
    }
  }
}
```

以上です。
JSでbackground-imageなどを動的に実装するときは上で判定した `CAN_USE_WEBP` を取得して
画像パスに同じように `?nowebp` をつけてあげるだけです。
Pythonanywhere で簡単デプロイ！！　python 初心者向け（2020年9月）

[ python anywhere とは、👉(part1へ)  https://qiita.com/iwasaki-hub/items/73054cea8f0c32fc90d3  ]

まず、アカウントを作成します！

PythonAnywhereのDashboardから操作を進めます！

![2020-09-17_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/faf0c215-ad72-afb0-4ea4-0edac6f725e0.jpeg)

👆
右上にある［Web］をクリックしましょう！

![2020-09-17 (1)_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/dc149a8c-cb73-827f-8b54-364e67395284.jpeg)

👆👆
［add a new web app］ をクリックした後、［Next>>］ をクリックします！

![2020-09-17 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/1b1d815f-8034-8d0a-2b26-e4de3978fe71.png)

👆👆👆
［Django]を選択します！これらは、Python Web framework の一覧です！
　学習済み📚のものがあれば、そちらを選択してもかまいません！

![2020-09-17 (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/1e9557c5-0fe0-6e2d-6faf-2c032dd358ba.png)

👆👆👆👆
［Python 3.8]を選択します！これらは、Python version の一覧です！

![2020-09-17 (4)_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/d0cf50eb-bcdd-2ec4-62a6-83b68ded41ac.jpeg)

👆👆👆👆👆
プロジェクト名を入力します！
お好みのプロジェクト名で大丈夫😺

これでDjangoのプロジェクトの作成が完了🎉🎉🎉

![2020-09-17 (5)_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/ee5d4207-4cdc-4a1a-cbf3-05138478cf60.jpeg)

👆👆👆👆👆👆
Configuraton for の下の行のリンク（URL）をクリックしてみましょう！

![2020-09-17 (6)_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/4e0ba529-c4a4-3aa6-32b4-979d55f4caac.jpeg)

🌈🌈🌈　完成　🌈🌈🌈

「保護されていない通信」の解決方は、pythonanywhere に戻って

１、Force HTTPS　をEnabledに変更する。（ページの下の方にあります。）
![2020-09-17 (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/049363c5-d09a-4907-699a-b30962962bc4.png)

２、Reloadをクリックする。

３、URLをクリックすれば、解決🔓

ディレクトリ（ファイル）構成などは、[file] から見れます🔍

次回、Djangoのディレクトリ構造を覗いてみます👀　
👉（part3へ）　https://qiita.com/iwasaki-hub/items/5237c1d9639b47c013e3
[python] 日付から文字列に変換

# やりたいこと
- 日付を取得して文字列に変換
- ファイル名などによく使うため整理

## ライブラリ
`datetime`

## 日付から文字列に変換してみる
#### 実行日付
- 現在の日付を出力

```python:実行日付
# yyyymmdd
yyyymmdd = datetime.date.today().strftime('%Y%m%d')
print(yyyymmdd)

# yyyy/mm/dd
yyyymmdd = datetime.date.today().strftime('%Y/%m/%d')
print(yyyymmdd)

# yyyy-mm-dd
yyyymmdd = datetime.date.today().strftime('%Y-%m-%d')
print(yyyymmdd)
```
```python:結果
20200917
2020/09/17
2020-09-17
```

#### 実行日時
- 実行日時に時間を追加して出力
- 表示形式は`yyyymmddhhmmss`

```python:実行日付
yyyymmdd_hms = datetime.date.now().strftime('%Y%m%d%H%M%S')
print(yyyymmdd_hms)
```
```python:結果
20200917155026
```

## 日付フォーマット
`strftime()`を使う
書式コードはこちら　[strftime() と strptime() の書式コード]
(https://docs.python.org/ja/3/library/datetime.html#strftime-and-strptime-format-codes)
Javaのプリミティブ型、参照型、Immutable、Mutable

#Javaのプリミティブ型、参照型、Immutable、Mutableをまとめて理解する
Java Silverの勉強をしていますが、この辺りがバラバラに出てきて混乱したので、自分自身の理解をまとめてみました。

#プリミティブ型

| Type | Value | Bit |
|:-----------|------------:|:------------:|
| boolean       | 真偽値　        | 1         |
| byte     | 整数      | 8       |
| short       | 整数        | 16         |
| char       | 文字        | 16         |
| int       | 整数         | 32       |
| float    | 浮動小数点     | 32      |
| long    | 整数     | 64      |
| double    | 浮動小数点     | 64      |

#参照型
こちらは主にクラスやString、StringBuilderが含まれます。

#Let's try
では実際に確認してみましょう。

```Java:Main.java
class Codechef
{
	public static void main (String[] args) throws java.lang.Exception
	{
		StringBuilder sb = new StringBuilder("apple");
		sample(sb);
		System.out.println(sb); // "apple orange"
		
		StringBuilder ssb = new StringBuilder("apple");
		sample5(ssb);
		System.out.println(ssb); // "apple"
		
		String s = "apple";
		String t = sample2(s);
		System.out.println(s); // "apple"
		System.out.println(t); // "apple orange"
		
		int i = 1;
		sample3(i);
		System.out.println(i); //1

		
	}	
		public static StringBuilder sample(StringBuilder sb) {
		    return sb.append(" orange");
		}
		
		public static String sample2(String s) {
		    return s+" orange";
		}
		
		public static int sample3(int i) {
		    return i+10;
		}
	    
	    public static StringBuilder sample5(StringBuilder sb) {
	        return new StringBuilder(sb+" orange");
	    }
}
```

#Immutable vs Mutable
ここで確認しておきたいのは、同じ参照型でもImmutableなStringとMutableなStringBuilderの違いです。

以下のコードでは、"apple orange"がsbに対して入っており、つまりは引数に渡されたStringBuilderはその値である"apple"ではなく、sbのアドレスが参照として渡されているため、参照先であるsbの値そのものが変わっています。

```Java
        StringBuilder sb = new StringBuilder("apple");
        sample(sb);
        System.out.println(sb); // "apple orange"

　　　　public static String sample2(String s) {
            return s+" orange";
        }
```

対してStringの方はこちらも参照型ですが、引数に渡されたStringの値そのものは変わっていません。なぜか。これはStringBuilderがMutableでStringがImmutableだからです。Stringの方は一度初期化時に割り当てた値はその後変更できない為、 `+` などでStringの元の値を変更しようとした場合は内部では新しいインスタンスが返されており、最初に割り当てた参照先の値は変わりません。変更後の値を使用したい場合は、以下のように新たにString変数を作成して、そちらに割り当てるしかありません。

```Java
        String s = "apple";
        String t = sample2(s);
        System.out.println(s); // "apple"
        System.out.println(t); // "apple orange"

        public static String sample2(String s) {
            return s+" orange";
        }
```

intの方は先に書いたとおりプリミティブ型なのでいわずもがなですね。引数に渡されているのは参照先のアドレスではなく、実値なので引数に渡された値に対して値が返ってきているだけですので、元の値が変わることはありません。
Pytorchで日経平均の予測~幕間~

どうもお久しぶりです。

下宿先が火事になったり、バイト先を首になったり、コロナの影響で麻雀にびっくりするぐらいハマってしまったりでやる気が出ずまったく触っていなかったですが備忘録として、久々に更新することにしました。

まず色々触っていた上で前回の記事[Pytorchで日経平均の予測](https://qiita.com/hoolly728/items/c398afd5a21669b8ce0f)で書いたコードではあまりよろしくないのではないかという結論に至ったので記事にしてみました。

#参考、引用した記事

大体前回記事とおなじです。
追加で以下のものを参考にしました。

[LSTMを使ってFX予測を行ってみた](https://premium.aidemy.net/magazine/entry/2019/02/02/182210)

[【Python】LSTMによる株価予測【Chainer】](https://www.simulationroom999.com/blog/stock-forecast-lstm/)

[データが足りないなら増やせば良いじゃない。](https://qiita.com/cvusk/items/aa628e84e72cdf0a6e77)

[Using Deep Learning Neural Networks and Candlestick Chart Representation to Predict Stock Market](https://arxiv.org/pdf/1903.12258.pdf)

[Affinity LossをCIFAR-10で精度を求めてひたすら頑張った話](https://blog.shikoan.com/affinity-loss-cifar/)


#問題点、考察
上記の記事からLSTMでの予想というのはかなり精度が悪そうということです。
予想と実際の株価の予想から外れている図がプロットされています。

ネットを調べているとこういった記事が散見されますが、いまいちパッとしないことが多いです。根拠は全くないです。感覚的にです。本当に理系なのでしょうか。



そして、前回の記事[Pytorchで日経平均の予測](https://qiita.com/hoolly728/items/c398afd5a21669b8ce0f)で目標にしていた３％上がる時を予想する。といったものですが、これにはデータの不均衡により、厳しいと感じました。

#＋3%の壁

データ数が約４３００（20年分）の日経平均のデータを扱っていたのですが上下だけでいうなら１：１の比率でデータに偏りがありませんでした。しかし、騰落率＋３％という条件をつけると、上昇：下落の比率が１：１０ほどの偏りになります。この場合では全て下落と予想するモデルが出来てしまい、予想もへったくれもありません。

これは、[精度６７％のディープラーニング株価予測モデル_1](https://qiita.com/shiroino11111/items/f812938fbbba7123fbcc)の記事でも言及されていることです。この問題をDataAugmentation(こちらの記事、[データが足りないなら増やせば良いじゃない。](https://qiita.com/cvusk/items/aa628e84e72cdf0a6e77)
を参考にしました)によってクリアしている旨が書かれていました。

#DataAugmentation

なので。データ数が４３００しかないので、アップサンプリングを行いました。
つまりデータを増やしたということです。
時系列データなので画像のようにcsvファイルで管理をしていました。ここからLSTMで20日分（２０行）を読み込ませて学習させるという流れです。
![スクリーンショット 2020-09-07 6.39.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350453/fe765167-6052-5958-e836-4bc3dba8d393.png)

アップサンプリングをすると、データが追加される時、少ない方（この場合上昇するというデータとラベル）がまとめて追加されます。なので、データ数を１：１にするため上昇するという予想されたものが連続で４０００行近く追加されるわけです。

こうなってしまうと２０行ごとに学習していたので後半４０００行でまったく信頼性のないデータになってしまうと考えました（実際予想がまともにできていなかった）。ここで時系列データへのDataAugmentationは問題がありそうと考え使うことは諦めました。


#画像を用いた予想
そういった時に、ディープラーニングが注目され始めたのはAlexNet使用された画像分類コンペであることを思い出しました。なので画像を使った予想について考えてみました。

実際、上昇下落の２値分類を当てるだけであるならば画像での予想は高い精度を誇っているっぽいです。[Using Deep Learning Neural Networks and Candlestick Chart Representation to Predict Stock Market](https://arxiv.org/pdf/1903.12258.pdf)こちらの論文では株価をチャート上から読み取ることで、accuracy97%でSOTA。とのことです。

こちらの記事のコードがgit hubに落ちていたので、使って予想することにしました。

#データ不均衡の問題解決

画像データであるならばデータ不均衡はDataAugmentationによって解決できるかもしれないと考えました。さらに最近では、深層距離学習というのも取り入れることでよりデータの不均衡につよい学習を行えるみたいです。

[Affinity LossをCIFAR-10で精度を求めてひたすら頑張った話](https://blog.shikoan.com/affinity-loss-cifar/)

上記記事が時系列データを使ったLSTMに適応できるかがわからなかったため、画像での学習を行おうと考えました。

#次回の記事

こういったことを踏まえて、現在コーディング中です。乞うご期待。
次回の記事
[Pytorchで日経平均の予測2](https://qiita.com/hoolly728/items/9454e2b349a48aee6b18)
CentOS8.2(x86_64)+ruby2.5+Rails5.2+MariaDB(10.3.17)環境構築

# 環境構築手順メモ

```
yum update -y
yum install -y git
yum install -y bzip2 gcc openssl-devel readline-devel zlib-devel
```

```
dnf module list ruby
dnf module -y install ruby:2.5
ruby -v
```

```
dnf -y install ruby-devel rpm-build make gcc gcc-c++ gcc-gdb-plugin libxml2 libxml2-devel mariadb-devel zlib-devel libxslt-devel nodejs
gem install bundler
gem install nokogiri -- --use-system-libraries
gem install rails --version="~>5.0" --no-ri --no-rdoc
rails -v
gem install mysql2 --no-ri --no-rdoc -- --with-mysql-config=/usr/bin/mysql_config
rails new SampleApp -d mysql
```

```
cd SampleApp
vi config/database.yml
```

```
default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: password   # MariaDB 接続パスワード
  socket: /var/lib/mysql/mysql.sock
```

```
dnf info mariadb-server mariadb mariadb-devel
dnf install -y mariadb-server mariadb mariadb-devel
systemctl start mariadb
systemctl enable mariadb
systemctl status mariadb
mysql_secure_installation
```

```
rails db:create
rails generate scaffold testapp name:string title:string body:text
rails db:migrate
rails server --binding=0.0.0.0
```

```

setenforce 0
firewall-cmd --zone=public --add-port=3000/tcp --permanent
firewall-cmd --reload


http://172.16.1.xxx:3000/
ドロップダウンメニューを実装してeventオブジェクトに非同期でアクセスする際にエラーが出た。

今回、Reactでドロップダウンメニューを実装していて、詰まってしまった部分になります。

#何が起こったか

![824086e9e727e490924dcec88ceb2d42.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670446/54417a68-552d-5028-d3ca-9d55eee6e39d.gif)

上記のように、ドロップダウンメニューを作成して、テストするか！というときにエラーが起きました。

1回目は選択できるのですが、2回目の選択でエラーになってしまう・・・。

# 書いたコード


今回、以下のような形で実装していました。

```react

//ドロップダウンメニューの選択値によって値を変化させるためにuseStateを使う
//今回はドロップダウンメニューが複数あり、一つのuseState内でおさめたかったのでこんな感じで書いた
  const [selects, setSelects] = useState({
    name_id: 0,
    key_id: 0,
  })

//ドロップダウンメニュークリック時のイベントオプションを定義
  const handleDropdownChange = (event: any) => {
    const name = event.target.name
    setSelects(() => {
      return { ...selects, [name]: event.target.value }
    })
  }

//今回は配列からドロップダウンメニューを作成したかったので以下のように書く
//key_idも同じ用に書いてるので今回は省略
  List = names.map((a, index) => (
    <option value={`${a.name_id}`} key={index}>
      {a.name_id}
    </option>
  ))

//表示したい部分で下記のようにして表示
  <select name="name_id" onChange={handleDropdownChange}>
    {List}
  </select>
```

# 解決策
[公式](https://reactjs.org/docs/events.html#event-pooling)に書いてました。

参照できない理由
>The SyntheticEvent is pooled. This means that the SyntheticEvent object will be reused and all properties will be nullified after the event callback has been invoked. This is for performance reasons. As such, you cannot access the event in an asynchronous way.

つまり、パフォーマンスの向上のために一度読み込まれたイベントオブジェクトは再利用されて、すべてのプロパティがnull化されてしまうので、非同期的にイベントにアクセスすることはできないということですね。

私が上記で一回目は問題なくドロップダウンメニューで選択できていたのは、イベントコールバックが一回目の呼び出しだったからで、二回目以降は最初に呼び出されたイベントオブジェクトが再利用されてしまうので、そのときに違う値が選択されているとエラーが発生する（=非同期的にアクセスできない）という理由だったみたいです。

というわけで解決策。解決策も公式に書いてました。

>Note:
>If you want to access the event properties in an asynchronous way, you should call event.persist() on the event, which will remove the synthetic event from the pool and allow references to the event to be retained by user code.

つまり、非同期でアクセスさせるためには`event.persist()`を使ってくれということです。

# 解決

```react
//ドロップダウンメニュークリック時のイベントオプションを定義
  const handleDropdownChange = (event: any) => {
    event.persist(); //これを追加
    const name = event.target.name
    setSelects(() => {
      return { ...selects, [name]: event.target.value }
    })
  }
```

上記で解決！
Railsのlinkd_toタグ

#はじめに
railsのlink_toメソッドの書き方をまとめました。
#目次
1. link_toメソッドとは
2. 基本的な書き方

#1. link_toメソッドとは
link_toメソッドとはビューで使用するhelperメソッドです。 リンクを表示させたい時に使用し、htmlのaタグを生成してくれます。
link_toメソッドにリンクとして表示する文字列とリンク先を引数として渡すことで、リンクを表示させることができます。
以下にlink_toメソッドの基本的なソースコードの書き方の紹介をしていきます。
#2. 基本的な書き方
- 第一引数にリンクのテキスト
- 第二引数にパス、URLの指定

これらを引数として渡すことでリンクを作成することができます。
###URLやパスを使用する方法
- URLを用いる場合

```ruby
<%= link_to 'Yahoo', 'http://www.yahoo.co.jp/' %>
```
- パスを用いる場合

```ruby
<%= link_to ‘ユーザー一覧’, ‘/users/index’ %>
```
###ルーティングを使用する方法
同じアプリケーション内へのリンクを作成する場合は以下を使います。
「config/routes.rb」で設定しているルーティングの名前に「_path」をつけたものをリンク先として指定します。
ルーティングの名前を確認するときは以下のコマンドを使います。作成したアプリケーションで実行します。

#####ターミナル

```
rails routes
```

```
   Prefix        Verb       URI Pattern                  Controller#Action
   incomes       POST       /incomes(.:format)            incomes#create
   new_income    GET        /incomes/new(.:format)        incomes#new
   edit_income   GET        /incomes/:id/edit(.:format)   incomes#edit
   income        PATCH      /incomes/:id(.:format)        incomes#update
                 PUT        /incomes/:id(.:format)        incomes#update
                 DELETE     /incomes/:id(.:format)        incomes#destroy
``` 

例えば、incomes_controllerのnewアクション（新規作成画面）にリンクを貼りたいときは以下のように書きます。

- Prefixを用いる場合

```ruby
<%= link_to '新規作成’, new_income_path %>
```
- URI Patternを用いる場合

```ruby
<%= link_to '新規作成’, ‘/incomes/new’ %>
```
###idを指定する必要があるとき
上記のURI Patternにidを含むものがありますが、これは**どの「income」についての編集画面にリンクを設定するのか**というのを表しています。
「edit_income_path」にincomeのidを引数としてわたすことで、インカムデータのidを元にリンク先を設定してくれます。
###methodオプションを使用する方法
link_toメソッドの引数にはHTTPメソッドを指定することができます。**何も指定しなければGET**となります。書き方は以下の通りです。

```ruby
<%= link_to ‘削除’, income_path(params[:id]), method: :delete %>
```
また、id属性やclass属性を設定することもできます。
###do~endを使用する方法
link_toメソッドは以下のようにdo~endのブロックを使って記述することもできます。

```ruby
<%= link_to income_path, class: 'hoge' do %>
　　<div>a</div>
      <h4>b</h4>
       <p>c</p>
<% end %>
```
link_to do ~ end の中の要素は同時にリンクできるようになります。
#参考リンク
https://udemy.benesse.co.jp/development/web/link-to.html
Nuxt.js + TypeScriptのプロジェクトを作る

## Nuxt.jsのプロジェクトを作る

まず、`create-nuxt-app`を利用して、Nuxt.jsのプロジェクトを作成します。
TypeScriptを利用するので`Programming language`は`TypeScript`を選択しますが、それ以外はお好みに設定してください。

```shell-session
$ yarn create nuxt-app hoge
...
create-nuxt-app v3.2.0
✨  Generating Nuxt.js project in hoge
? Project name: hoge
? Programming language: TypeScript
? Package manager: Yarn
? UI framework: Vuetify.js
? Nuxt.js modules: (Press <space> to select, <a> to toggle all, <i> to invert selection)
? Linting tools: ESLint, Prettier, Lint staged files, StyleLint
? Testing framework: Jest
? Rendering mode: Single Page App
? Deployment target: Static (Static/JAMStack hosting)
? Development tools: (Press <space> to select, <a> to toggle all, <i> to invert selection)
```

作成したプロジェクトのルートに移動して、確認します。

```shell
cd hoge
yarn dev
```

## TypeScriptで動くようにする

### 追記
この記事を書いた後でv3.3.0がリリースされて、以下の対応は必要なくなりました。
https://github.com/nuxt/create-nuxt-app/blob/master/CHANGELOG.md

`pages/index.vue`などの`scripts`に`lang="ts"`を付けてTypeScriptを適応してみます。
すると、ビルドがエラーになり、

```
Module not found: Error: Can't resolve 'ts-loader' in 
```

のようなエラーメッセージが表示されるので、`ts-loader`を追加します。

```shell
yarn add --dev ts-loader
```

追加できたら、もう一度`yarn dev`を実行してページが表示されることを確認します。

これでNuxtプロジェクトのTypeScript対応は完了です。

必要であれば、[nuxt-property-decorator](https://github.com/nuxt-community/nuxt-property-decorator)などを導入してTypeScriptを使って開発していきましょう！

## まとめ

`create-nuxt-app`を使って、TypeScript対応のプロジェクトを作るのに、コマンドを叩くだけではできなかったので書きました。
他の設定では確認していないので、ある設定の時だけの特定の問題かもしれないですが、自分の環境で起こったので同じ問題に当たった人は参考にしてください。
最後まで読んでいただきありがとうございました。
Macで処理中だけVPNに繋ぐコマンドを作りました

リモート作業が増えて、何かと「あーVPN繋がなきゃ」とかなるんですよね。
そして作業が終わってからVPNの接続を切り忘れる...

処理中だけVPNに繋がってくれてればいいのに...
そんなシェルを作りました

```bash:vpn
#!/bin/bash -eu

if [ $# == 0 ]
then
  echo 'vpn [on|off|pass "command"]'
  exit 1
fi

NETWORK_NAME=$(networksetup -listallnetworkservices | grep VPN)

off () {
  networksetup -disconnectpppoeservice $NETWORK_NAME
}
on () {
  networksetup -connectpppoeservice $NETWORK_NAME
}

case $1 in
  'off' )
    off
    ;;

  'on' )
    on
    ;;

  'pass' )
    on
    trap off exit
    eval $2
esac
```

# 使い方
※ 名前に「VPN」と入っているネットワークが1つしかない想定で、そのネットワークに接続するシェルになっています

1. 上記のシェルを `vpn` と名付けて、
2. `chmod 744 vpn`（実行権限を付与）
3. PATHが通っている場所においてください<br>
   （私は自作シェル置き場(`$HOME/bin`など)を作って、<br>
   `.bash_profile`や`.zshrc`に`export PATH=PATH:$HOME/bin`と書いてあります）

例えば、Web開発をしていて、フロントはローカルで起動するけど、APIはVPNを繋いだ先にある場合。
`$ yarn server` でローカルサーバーが起動するときは、

```bash
$ vpn pass "yarn server"
```

これで、サーバー終了時にVPNも自動的に切れます。

# trap
シェルの `trap ~ exit` という行でこれを実現しています。
`exit` のところは `err` なども指定できるので、任意の終了シグナルに応じて処理を設定できるはずです。（やってみてない）

ただ、強制終了(9)は受け取れないようで、例えば、サーバーを起動しているvscodeのウインドウをそのまま閉じると、設定した処理は実行されません...

# きもち
本当は、文字列としてコマンドを渡すなんてしたくない...
何か良い方法があったら教えて下さい...
【その1】wicked_pdfで履歴書を作成するまで

#wicked_pdf とは何か？
HTMLをPDFに変換しダウンロードまで実現することのできるgemです。
Wicked PDFはRubyバージョン2.2〜2.6、Rails4から6.1で動作することが確認されているみたいです。

## 手順1 wicked_pdfのgemをインストールする
wicked_pdfをwkhtmltopdfというHTMLをPDFに変換するオープンソースのラッパーなので、wkhtmltopdfとそのgemのwkhtmltopdf-binaryもインストールする必要があります。

```ruby:Gemfile
gem 'wicked_pdf'
gem 'wkhtmltopdf-binary'
```

```
$ bundle install
```

## 手順2 Initializerを作成
`wkhtmltopdf`の実行可能ファイルのパスがWebサーバー上にない場合は、initializerに記述する必要があります。
より詳しい情報は`wkhtmltopdf`の[ホームページ](https://wkhtmltopdf.org/)をご覧ください。

```ruby:config/initializers/wicked_pdf.rb
# これを追記
WickedPdf.config = {
  :exe_path => "#{Gem.loaded_specs['wkhtmltopdf-binary'].full_gem_path}/bin/wkhtmltopdf"
}
```

## 手順3 実際にwicked_pdfを使ってみる 

```ruby:routes.rb
Rails.application.routes.draw do
 get 'resumes/show', to: 'resumes#show'
end
```

templateはファイルの拡張子まで指定しないと、テンプレートがないというエラーになるのでご注意を。

```ruby:resumes_controller.rb
 def show
   respond_to do |format|
     format.html
      format.pdf do
        render pdf: 'filename',   # PDF名
               template: 'resumes/pdf.html.haml' # viewを対象にする
      end
    end
  end
```

`app/views/layouts/pdf_template.html.haml`にはpdfにしたい内容を記載します。

```app/views/layouts/pdf_template.html.haml

%html
  %head
    %meta{:charset => "utf-8"}
    %meta{ name: 'viewport', content: 'width=device-width, initial-scale=1.0' }
    %meta{ name: 'x-apple-disable-message-reformatting' }
  %body
    = yield
```

```haml:app/views/resumes/show.html.haml

%div{style: 'background: #fff;'}
  %h1 履歴書
  %table{:border => "1"}
    %tr
      %th{:width => "500", :height => "50", :align => "left"} ふりがな
    %tr
      %th{:width => "500", :height => "50", :align => "left"} 氏名
    %tr
      %th{:width => "200", :rowspan => "2", :height => "50", :align => "left"} 現住所

```


![スクリーンショット 2020-09-16 15.44.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/623708/b444c504-a926-1ef9-04de-fb1c7921d9e1.png)

URLに .pdf をつけるとPDFが表示されるはずです。
![スクリーンショット 2020-09-17 15.23.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/623708/dcc1fdce-0a41-ca0e-10ee-b0c3e24771e9.png)
今更きく…Vue3とは？


# まえがき
最近、社内でVue2で作られているアプリケーションのUIを刷新する計画をしており、Vue3を導入するかの議論がされました。
2018年後半からVue3の開発が開始されてから約二年。
Vue3もRCとなり、リリースに向けて動きはじめました。
Vue3のComposition API等具体的な実装部分に触れている記事はよくみますが
大枠に触れている記事が少ないので書いてみます。

EvanYou氏がある記事の中で、「なぜ書き換えたか？」について語っているので、私なりにまとめました。

# なぜ書き換えたか？

### 新しい言語機能の活用
ES2015の最新版への対応が各ブラウザで行われており、Vueも対応する必要がありました
その中でも、Proxyが一番注目しており、VueでもProxyを活用することで、パフォーマンス改善を行うことができます。

### アーキテクチャの問題へ対応
Vueではコードが暗黙的な結合という形で、技術負債を積み上げてきました。
それにより、コントリビューターが変更を加えることが困難になっていました。
これらを解決し、コードを変更をしやすくする必要がありました。

# 改善点

### Typescriptのサポート
Vue2はもともとプレーンESで作成されていましたが、TypeScriptをサポートしました。

### 内部パケージの分離
monorepo（一つのリポジトリでパッケージを管理すること）で、内部パッケージ化を行い、それぞれが独自のAPI、タイプ定義、およびテストを実装しています。
それにより、モジュール間の依存関係をより明確にし、開発者がすべてを読み、理解し、変更しやすくし、プロジェクトの貢献の障壁を下げ、長期的な保守性を改善しました。

### RFCプロセスの設定
ユーザーが重大な変更についてフィードバックを提供できるよう、RFC（Request for Comments）プロセスを採用しました。
議論はGitHubリポジトリで行われ、提案はプルリクエストとして送信されるため、コメントで有機的に議論が展開されます。

Vueはもともと、軽量のフロントエンドフレームワークですが、更に軽量化を行っています。

### 仮想DOMのボトルネックの改善
Vue 3では、適切な[AST](https://ja.wikipedia.org/wiki/%E6%8A%BD%E8%B1%A1%E6%A7%8B%E6%96%87%E6%9C%A8)変換パイプラインを使用してコンパイラーを書き直しました。
これにより、コンパイル時の最適化を行っています。

- ブロック内のノード更新の際、ツリーのトラバースの最適化を行いました。
    - この最適化は、実行する必要のあるツリートラバーサルの量を1桁減らすことで、仮想DOMのオーバーヘッドの多くを回避します。
- メモリ使用率軽減が大幅に向上し、ガベージコレクションの頻度が減少します。
- 要素レベルでは、コンパイル段階で実行計画の作成を行い、ランタイムがそれをヒントに実行を行うことで高速化を実現しています。

これらの手法を組み合わせると、レンダリング更新のベンチマークが大幅に改善されています。
Vue3がVue2のCPU時間（Javascript計算の実行に費やされた時間）の10分の1未満になることもあります。


### バンドルサイズの最小化
フロントエンドフレームワークは、サイズそのものがパフォーマンスに影響しています。
Vueはもともと軽量（圧縮しても約23KB）でしたが、２つの問題に気がつきました。

- 利用していない機能まで、ダウンロードと解析のコストが発生している。
- 機能を追加するにつれ、容量は無限に増え続ける。

この問題を解決するにはツリーシェイキングを行い、不要なコードを削除することでした。
Vue3では、ほとんどのグローバルなAPI、内部ヘルパーをESモジュールにすることで、これを実現しました。
多くの新機能の追加にも関わらず、Vue2の半分以下の容量を実現しています。

# まとめ
ここでは触れていませんが多くの機能が追加されています。

- Composition APIの導入
- multi-v-model機能追加
- Teleport機能追加
- Fragment機能追加
- Suspense機能追加
- フィルターの廃止

等々…

上記に加え、パフォーマンスの向上を考えると、導入しない手はないかなと個人的に考えており
下位互換性もあるとのことなので、正式版がでたら対応を考えたいと思います。
Composition APIの導入で、少しReact側によったことからReactでもいいのでは？という賛否両論の意見が出ていますが
軽量や学習コストの低さという部分では、Vueが依然として変わらないと思うので、棲み分けとしては十分できているのかと思ってたりします。

今回は、ブログをもとに私が解釈した内容で書いているので、認識の齟齬等あれば教えて頂きたいです。

元ネタ：https://increment.com/frontend/making-vue-3/?ref=madewithvuejs.com#why-rewrite