OmniAICreator/Qiita-1.07M huggingface dataset:
ProcessingでWiiリモコンを使う2020年

＃本記事はProcessingでWiiリモコンを使うためのメモです。

#はじめに
WiiリモコンはBlutoothでパソコンとつなげることが出来ます。2006年発売当時、さっそく使ってみていましたが(win & c++)、2020年になりいろいろと環境が変わってしまったので、あらためて、手順をまとめます。当時としては、加速度センサを手軽に使える環境がなかったので、無線だし画期的でした。

#テスト環境
windows 10及び8
processing 3.5.4
WiiFlash 0.4.5

#ペアリング
最近のノートパソコンならばBlutoothが標準装備なので、アダプタを買わなくてもおそらく大丈夫。
タスクトレイのblutoothからつなげようとすると、PINを必須要求され、うまくいきません。コントロールパネルのデバイスから「Blutoothとその他のデバイス」の下の方の、「関連設定」の下、「デバイスとプリンター」を開きます。
![設定 2020_06_03 10_12_57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/5e701fd0-692c-14e1-6f87-32966eb25c73.png)
ウィンドウが開きますので「デバイスの追加」を押します。
![デバイスとプリンター 2020_06_03 10_14_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/34ad9de6-8d74-9284-dcf5-94fb64c49e6e.png)
Wiiリモコンの電池の横のペアリングボタンを押します。
または、①②ボタンを同時に長押しても行けるかもしれません。
![デバイスを追加します 2020_06_03 10_14_25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/92638440-df8b-a734-744d-e353b1548c8e.png)
PINコードを要求されますが、入力せず「次へ」で大丈夫です。
![デバイスを追加します 2020_06_03 10_14_33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/7f1c43bf-9927-f458-dace-518f3de87aa6.png)
認識完了です。
![デバイスとプリンター 2020_06_03 10_14_54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/73e80129-beaf-60a0-b48a-cdc5054d00ad.png)
Windows8の場合、タスクトレイのblutoothからつなげても、PINの入力は必要ありませんでした。0000とか、1234とか、00000000とか、いろいろ情報が出回っているのはなぜだかよくわかりません。


#WiiFlashの準備
WiiFlash 0.4.5.zipをダウンロードし、解凍します。
https://code.google.com/archive/p/wiiflash/downloads
ペアリング成立した状態で、以下のサーバプログラムを起動します。
WiiFlash 0.4.5/Servers/WiiFlashServer 0.4.5.exe
うまくいけば、青い画面が、だめなら、赤い画面がでます。
赤い画面の場合は何とかして、Blutoothのペアリングを解決する必要がありますが、これが環境に寄るので難しい。
青い画面の場合、Wiiリモコンのアイコンをクリックすると、バイブレーションが動くので、接続チェックできます。
![flash.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/24f9b1c4-4d17-c8b1-23a5-c5b9112cc7fa.png)
Macの場合、WiiFlashServerJ.appを使うのかな？

#Processingのサンプル
「Processing.zip」をダウンロードし、解凍します。
https://code.google.com/archive/p/wiimedia/downloads

Wiimote.pdeの8行目を編集します。
　　"localhost"
を
　　"[::1]"
に変更。


4つあるサンプルのうち、３つが動きました。
Aボタンを押している間だけ、球にライトを当てるサンプル
![light.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/7f08fe46-e429-2eb0-38e1-54b122b227c8.png)

傾きで、左右を認識するサンプル
![mouse.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/c3208381-6315-342f-1eb7-eb3e2c755074.png)

音声波形を傾きで操作するサンプル
![wave.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/2a75bff8-c809-8e4b-fe44-1f397b18e8ec.png)


参考：
動かせませんでしたが、WiiRemoteJはこちらにありました。
https://github.com/micromu/WiiRemoteJ
同じく動かせませんでしたが、wrj4p5はこちら
https://ja.osdn.net/projects/wrj4p5/releases/39784
【GCP】Cloud Storageを触ってみた

# 作成時のポイント

ロケーションタイプを選ぶときに上記の内容を確認しながら作成。
バケット作成後はロケーションの場所を変更できない。
Multi-regionの場合、データ取得サイズはFreeだが、データ転送は有料なので注意。

ロケーション タイプ
Region
単一リージョン内で最低のレイテンシ
Dual-region
2 つのリージョンにわたる高可用性と低レイテンシ
Multi-region
最大の領域にわたる最高の可用性

〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
Archiveが一番安かった。
でも使用用途によって各項目の値段も違うので、注意。
ここは作成後も変更が可能

ストレージクラス
Standard
短期間のストレージや頻繁にアクセスされるデータに最適
Nearline
アクセスが 1 か月に 1 回未満のバックアップとデータに最適
Coldline
災害復旧とデータへのアクセスが四半期に 1 回未満の場合に最適
Archive
アクセス頻度が年 1 回に満たないデータの長期デジタル保存に適しています
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
アクセス制御
・きめ細かい管理
バケットレベルの権限（IAM）に加えて、オブジェクトレベルの権限（ACL）を使用して個々のオブジェクトへのアクセスを指定します。詳細
・均一
バケットレベルの権限（IAM）のみを使用して、バケット内のすべてのオブジェクトに均等にアクセスできるようにします。90 日後に永続的になります。詳細
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
暗号化
・Google が管理する鍵
構成は必要ありません
・顧客管理の暗号鍵
Google Cloud Key Management Service で管理します
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜

# 手順

バケットを作成する
↓
ブラウザで作成したバケットがすべて表示される
↓
任意のバケットを選択し、構成をクリック
↓
アクセス制御できめ細かな管理がされてると公開ができない状態になる
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
権限の操作
権限タブをクリック
↓
allUsersという項目もいれられる
cloud storage という項目に
ストレージ オブジェクト閲覧者
ストレージ オブジェクト管理者
ストレージのオブジェクト作成者
ストレージ管理者
があるので、適宜選択
↓
オブジェクトの公開アクセスの列でURLをコピーできるようになる。



# TIPS
Storageを作成するときに右横で見積を取りながらできる

バケットに対する権限も変更可能
バケット⇛オブジェクト

フォルダを作成した場合、
https://storage.googleapis.com/storage-labs-console-mune/test/
こんな感じで階層ごとに別れる
【GCP】HTTPSロードバランサについて調べた

BCRA設定時につかっているのだが、どうやら以下の縛りがありそう。
・SSL証明書はHTTPS　LBを設定した時点でプロビされるようで、連動している感じ

＝＝＝

HTTPSロードバランサ
https://blog.apar.jp/web/4908/
https://cloud.google.com/load-balancing/docs/https?hl=ja
https://www.slideshare.net/GoogleCloudPlatformJP/google-cloud-72158836

TCP/IPのロードバランサは以下
https://cloud.google.com/load-balancing/docs/internal?hl=ja


Cloud Armor
https://cloud.google.com/blog/ja/products/gcp/getting-to-know-cloud-armor-defense-at-scale-for-internet-facing-services
https://cloud.google.com/armor?hl=ja
https://cloud.google.com/armor/docs?hl=ja
https://medium.com/google-cloud-jp/%E6%96%B0%E3%81%97%E3%81%8F%E5%87%BA%E3%81%9F-cloud-armor-%E3%82%92%E8%A9%A6%E3%81%97%E3%81%A6%E3%81%BF%E3%81%9F-29885a9432b5
https://qiita.com/pyuta/items/64a2654a0e6e17a71c2e
【GCP】node.js python 違い

https://jp.quora.com/Node-js%E3%81%A8Python%E3%82%92%E6%AF%94%E8%BC%83%E3%81%97%E3%81%9F%E5%A0%B4%E5%90%88-%E3%81%9D%E3%82%8C%E3%81%9E%E3%82%8C%E3%81%A7%E9%96%8B%E7%99%BA%E3%81%99%E3%82%8B%E3%83%A1%E3%83%AA%E3%83%83%E3%83%88%E3%81%AF
【GCP】cloud shellのTIPS

# 参考URL
https://medium.com/google-cloud-jp/start-cloud-shell-bb0905e9593d


# 制限事項
HOME 領域が 5GB 割り当てられてます


# ブーストモード
有効にしても問題ない。速度が早くなる

# TIPS
・clearを入力すると一番上に戻る。
・cloudshelの追加機能はダウンロードする必要がある。


# READMEについて
cat README-cloudshell.txt
でドキュメントをみると以下のような記載がある。
the VM is ephemeral
最初に起動するVMは一時的なものとのこと。

ドキュメントの翻訳
＝＝＝
Google Cloud Platformでホストされているリソースを管理するためのツールであるGoogle Cloud Shellへようこそ。
このマシンには、Google Cloud SDKとその他の一般的な開発者ツールがプリインストールされています。

5 GBのホームディレクトリはセッション間で保持されますが、VMは一時的なものであり、リセットされます
セッションが終了してから約20分。それ以降、システム全体の変更は持続しません。

Cloud SDKの使用に関するヘルプを表示するには、「gcloud help」と入力してください。その他の例については、次をご覧ください。
https://cloud.google.com/shell/docs/quickstartおよびhttps://cloud.google.com/shell/docs/examples

「cloudshell help」と入力すると、「cloudshell」ユーティリティの使用に関するヘルプが表示されます。共通の機能は
シェルの短いコマンドにエイリアスされています。たとえば、Bashプロンプトで「dl <filename>」と入力すると、
ファイルをダウンロードします。これらのコマンドを表示するには、「cloudshell aliases」と入力してください。
「help」と入力すると、このメッセージがいつでも表示されます。 「builtin help」と入力すると、Bashインタープリターのヘルプが表示されます。
＝＝＝


# 簡易的に環境を構築した
udemyの動画からダウンロードしたgitのプログラムをつかった。
最初に表示されるcloud shel上にファイルを設定したとき、
直接ローカルIPをうってもみれないが、ウェブでプレビューを押せば見れる。
https://8080-dot-12511641-dot-devshell.appspot.com/?authuser=0

urlが上記のようになっている。

このソースコードを見ると以下の記載がある。

const hostname = '127.0.0.1';
const port = 8080;

nodeコマンドを使った
nodemonコマンドを使った
https://qiita.com/kazuhiro1128/items/bb003bbc5747f55938a2
https://maku77.github.io/nodejs/env/nodemon.html

# cloud shellの仕組みに関するサイト
https://www.apps-gcp.com/handson%E7%92%B0%E5%A2%83%E8%BF%B7%E5%AD%90%E3%81%AB%E8%B4%88%E3%82%8Bcloud-shell/

〜〜〜
ワンクリックでアカウントに対して仮想マシンが１台割り当てられます。
ターミナルも提供されているので既にHandsOnの環境が手に入っています！！
Cloud Shellを利用する為にはGmailアカウント、GsuiteアカウントもしくはCloud Identityで作成したアカウントが必要になりますが、これさえあればすぐに使う事が出来るんです。
〜〜〜

https://books.google.co.jp/books?id=xy-3CwAAQBAJ&pg=PA98&lpg=PA98&dq=cloud+shell+%E4%BB%95%E7%B5%84%E3%81%BF+%E3%82%8F%E3%81%8B%E3%82%89%E3%81%AA%E3%81%84&source=bl&ots=ciMregCTql&sig=ACfU3U0Mgb94jKh9p5arXewNzw9jFS80hg&hl=ja&sa=X&ved=2ahUKEwiG28KH_d7pAhWTAYgKHUnEAmgQ6AEwBXoECAoQAQ#v=onepage&q=cloud%20shell%20%E4%BB%95%E7%B5%84%E3%81%BF%20%E3%82%8F%E3%81%8B%E3%82%89%E3%81%AA%E3%81%84&f=false


https://books.google.co.jp/books?id=yQCnCwAAQBAJ&pg=PT30&lpg=PT30&dq=cloud+shell+%E4%BB%95%E7%B5%84%E3%81%BF+%E3%82%8F%E3%81%8B%E3%82%89%E3%81%AA%E3%81%84&source=bl&ots=fJHA_Q8kTL&sig=ACfU3U05Y0HLLkphHPDOA4uUpuCTunxB2w&hl=ja&sa=X&ved=2ahUKEwiG28KH_d7pAhWTAYgKHUnEAmgQ6AEwB3oECAgQAQ#v=onepage&q=cloud%20shell%20%E4%BB%95%E7%B5%84%E3%81%BF%20%E3%82%8F%E3%81%8B%E3%82%89%E3%81%AA%E3%81%84&f=false
【GCP】料金計算について

参考になるサイトをまとめ

料金計算
https://www.youtube.com/watch?v=n-UwMMvQHYQ
https://medium.com/google-cloud-jp/gcp-pricing-calculator%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9-gce-%E7%B7%A8-bbd5416bebc9

作成した内容
https://cloud.google.com/products/calculator/#id=35c55688-a669-4efa-afe7-120079cb2ef6

BigQueryの料金
https://www.dsk-cloud.com/blog/bigquery-pricing-and-points

GCPの料金体系
https://cloud-ja.googleblog.com/2015/02/gcp.html
https://qiita.com/rache/items/796a65a446cc2788144a
https://www.acrovision.jp/service/gcp/?p=438
https://business.ntt-east.co.jp/content/cloudsolution/column-36.html

AWSと料金体系の比較
https://www.keywalker.co.jp/blog/aws-gcp-price-comparison-2018.html
https://style.potepan.com/articles/20181.html

見積の方法
https://dev.classmethod.jp/articles/systemdevelopment-precondition/

AWSをいろんな料金と比較　CPUの性能がわかりやすい
https://www.youtube.com/watch?v=H1-4vYEY3ZA
https://www.youtube.com/watch?v=9xoqcK2XBKc
【GCP】GKE上にnginxを構築

#関連ブログ
【GCP】GKEを触ってみたも参考に

#手順
nginxもすぐに作れるということでやっていく。

kubectl expose deployment nginx --type=LoadBalancer
これを打った時に以下のエラー

error: couldn't find port via --port flag or introspection
See 'kubectl expose -h' for help and examples
確かに、コンソール上もロードバランサができてない。

https://stackoverflow.com/questions/46228628/exposing-the-hello-minikube-service-fails-to-find-a-port
ここにあるが、要はポート指定してないよねということみたい（上記は英語）

http://tjtjtj.hatenablog.com/entry/2019/01/30/230000
ここの指定の仕方でやったらいけた。
kubectl expose deployment nginx --port 80 --type LoadBalancer
これをやるとロードバランサがコンソール上もできあがってた。

ここまでやってできた。

削除して終了。
プロジェクトでの行動指針（メンバーとして）

プロジェクト参画時に実施してきたことを記載しておきます。

##プロジェクト参画時
出来る事と出来ない事をはっきりさせる。また、どのレベルまで習熟しているのかを提示する。

##スケジュール策定時
与えられたタスク・期限と自己のスキルとを照合して、スケジュールが守れるかを明確にする。

##日々の開発
報連相。日々、作業記録を残し、進捗状況を報告する。遅延した作業とその原因を記録する。また、解決案を検討、相談する。

##作業遅延時
作業遅延は直ちに報告する。報告内容は、下記。
・作業遅延の原因
・自力解決の可否と目処
・支援が必要な場合、要望する支援内容の提案。

##弱点強化
プロジェクトで不足しているスキルで間に合うものは、余暇に強化を行う。書籍、ネット等。
JetsonNanoでいろいろするのに調べた内容をメモ＠202006

調べていて必要でピックアップした内容をまとめ

* Commandで任意フォルダをVSCodeで起動
* 起動時の自動ログイン
* スクリーンショット撮影
* IPアドレス固定
* 起動時にプログラム実行
* USBメモリの認識


## Commandで任意フォルダをVSCodeで起動

### Documentsを新規VSCodeで開く
``` editorOpen.sh
#!/bin/bash

code-oss -n ./Documents
```

### DocumentsにあるeditorOpen.shを実行

``` openVSCode.desktop
[Desktop Entry]
Encoding=UTF-8
Name=openVSCode
Exec=gnome-terminal -e "/home/visionpose/Documents/editorOpen.sh"
Type=Application
```

##起動時の自動ログイン

System Setting > User Account 
右上の Unlock を行い
Automatic Login　をON
![Screenshot from 2020-06-03 13-57-27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48015/3ff3595e-2edf-0990-870e-0e08851ede5f.png)

##スクリーンショット撮影

ウィンドウ指定で5秒後に撮影

```command
gnome-screenshot --window --delay=5
```

すぐに画面全体を撮影

```command
gnome-screenshot
```

##IPアドレス固定

タスクバーからネットワーク編集を開き
IPv4 SettingsタブでAddから新規追加し
赤枠の箇所を追加で固定できました
![Screenshot from 2020-06-03 12-13-23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48015/6332ea2f-3f6e-4e22-5eb6-4c8ec11ce94d.png)


##起動時にプログラム実行
下記のディレクトリに.desktopを追加

```
~/.config/autostart
```

非表示のファイルを表示する設定をONにするとGUIでも参照ができました
![Screenshot from 2020-06-03 13-58-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48015/b9d1a3de-1e89-9e7b-fbe3-4f2fcfcb18d7.png)
![Screenshot from 2020-06-03 13-58-40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48015/f8df7de4-a9c2-bdd8-1e67-9ef36300de74.png)

##USBメモリの認識

コンソールで下記を実行しアプリケーションを追加

```
sudo apt-get install exfat-fuse exfat-utils
```

##参考サイト

コマンドラインからVS Codeでファイルやフォルダを開く
https://qiita.com/1natsu172/items/b951aa33451dad36bd7c
ターミナルからVisual Studio Codeを起動する方法【公式の方法】
https://qiita.com/naru0504/items/c2ed8869ffbf7682cf5c
Jetson NanoでRealSense D435iとT265を使ったプログラムを自動起動させる方法
https://cvl-robot.hateblo.jp/entry/2019/08/26/113311
Jetson Nano関係のTIPSまとめ
https://qiita.com/karaage0703/items/b14c249aa33112669ee4
Linux（Ubuntu）にリムーバブルディスク（exFAT）を認識させた
https://qiita.com/KHashimura/items/be39b76a86dbabfae96f
NVIDIA Jetson Nano を使ってみる（起動と設定編）
https://wisteriahill.sakura.ne.jp/CMS/WordPress/2019/07/07/nvidia-jetson-nano-set-up-configration/
UNIX時間(UNIX TIMESTAMP / タイムスタンプ)を普通の日付と時間に変換しながらランダムな日時を自動生成する

#### ランダムな日付だけでなくランダムな時刻も同時に生成

こんにちは。2038年問題まであと18年ですね。
今回は適当な日付と時間をランダムに作るPHPのコードサンプルです。
一応2038年問題も考慮して、date関数などは使わずにやりたいと思います。

[2038年問題の詳しい解説はこちら](https://pisuke-code.com/php-way-to-avoid-2038-promblem/)

DateTimeクラスを使えばいいじゃない...という意見もありますが、フレームワークやライブラリが使えるなら「むしろCarbonでいいじゃない」ということでCarbonを使っております。

Laravelとかではお馴染みですね。CarbonはDateTimeクラスをオーバーラップした日付操作ライブラリなので、DateTimeクラスの上位互換と言えそうです。

仮に、何かしらのテスト用データを大量に挿入しつつ、更新日時をランダムに生成したいとします。Laravelのseedsにそういったコードを書いてみます。

```php:ProductsTableSeeder.php
<?php

use Illuminate\Database\Seeder;
// Carbonを使うための宣言
use Carbon\Carbon;

// Products(商品)テーブルというものがあるとする
class ProductsTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        // ランダムに生成したい日時の期間を決める
        // 仮に 2001-01-01 00:00:00 から 2020-05-01 23:59:59 とする
        // 日付と時刻を format('U') でUNIXタイムスタンプへ変換しておく
        $start = new Carbon('2001-01-01 00:00:00');
        $startUnix = $start->format('U'); // 978274800 に変換される
        $end = new Carbon('2020-05-01 23:59:59');
        $endUnix = $end->format('U'); // 1588345199 に変換される

        // ループで id=1 から id=1000 までの商品を自動で登録
        for($i=1;$i<=1000;$i++){
            // 用意しておいた開始・終了日時のUNIXタイムスタンプを使用してランダムな数値を生成
            $randDate = mt_rand($startUnix, $endUnix);
            // ランダムなUNIXタイムスタンプを引数にしてインスタンスを作成
            $date = new Carbon($randDate);
            DB::table('products')->insert([
                'id' => $i,
                'name' => '商品名_'.$i,
                'created_at' => '2001-01-01 00:00:00',
                // 日付＆時刻は必要に応じてフォーマットを変更可
                'updated_at' => $date->format('Y-m-d H:i:s'),
            ]);
        }
    }
}
```

日付や時間のフォーマットは基本的に ```date()``` の関数と同じパラメータが使えます。
[date() -> パラメータ format](https://www.php.net/manual/ja/function.date.php)

なお乱数を発生させるときは ```rand()``` ではなく ```mt_rand()``` を使う方が実行速度も速くて良いそうです。（randの4倍以上）
暗号化に使うのはいずれも推奨されませんが、文字通りランダムな値を得るためだけであれば問題ありません。

#### 参考URL：
[rand — 乱数を生成する](https://www.php.net/manual/ja/function.rand.php)
[mt_rand — メルセンヌ・ツイスター乱数生成器を介して乱数値を生成する](https://www.php.net/manual/ja/function.mt-rand.php)
[【PHP入門】ランダムな数値・文字列を生成する（rand、mt_rand）](https://www.sejuku.net/blog/24159)
[date — ローカルの日付/時刻を書式化する](https://www.php.net/manual/ja/function.date.php)
[DateTime クラス](https://www.php.net/manual/ja/class.datetime.php)
[テストデータ用にランダムな日付文字列をn個生成する](https://qiita.com/shinderuman@github/items/ea4c877faa0906d931b1)
[特定の2つの日付の間から、ランダムに1日を取得](https://qiita.com/shosho/items/6ce1cfbbfe00047e28cf)
[【PHP】DateTimeでの日時取得とフォーマット方法まとめ](https://www.sejuku.net/blog/21772)
[PHPで2038年問題を回避するには？すぐできる対策とコード例](https://pisuke-code.com/php-way-to-avoid-2038-promblem/)
[「2038年問題」を華麗に解決！～エンジニアの仕事～](https://www.zenken.co.jp/blog/engineer/26593)
[DateTimeクラスで日付文字列とUNIX時間(タイムスタンプ)を相互変換するときのまとめ](https://qiita.com/sounisi5011/items/d6df76798d2e23c83e14)
[DateTime クラスのまとめメモ](https://qiita.com/re-24/items/c3ed814f2e1ee0f8e811)
[PHPで日付時刻処理を書くならCarbonを使うべき](https://qiita.com/yudsuzuk/items/ff894bd0b76d4657741d)
Schoo Java入門コースで残したノート

BufferedReaderクラスはテキストファイルを読み込むためのファイル（ファイルを一行ずつ読み込む）
テキストファイルを読み込む（InputStreamReader）

#### Java入門 -Javaクラスの継承①-
インスタンス化したときにコンストラクタ内に処理があれば実行されるよ！

インスタンス化するとインスタンス化した中身にアクセスできるようになる

オーバーライド：中身を書き換えちゃうよ！
条件はメソッド名、戻り値、引数が同じであること

コンストラクタは「クラス」の処理を実行するために「インスタンス」を生成するときに実行される機能をさします。

#### Java入門 -Javaクラスの継承②- 
インターフェイス宣言時はclassではなくてinterfaceとかく

#### Java入門 -フォワードとリダイレクト-

|   |リダイレクト|フォワード|
|:-----------------|------------------:|:------------------:|
|リクエスト/レスポンスの回数|２回|1回|
|リクエストの情報| 引き継げない|引き継げる|
|外部サイトへの移動|できる|できない|
|処理速度|遅い|早い|

#### Java入門 -MVCモデル-

c　コントローラ：制御
m　モデル：処理
v　ビュー：表示

####Java入門 -スコープの概念-

JavaBean　データを納める倉庫のような役割のクラス
プロパティへのgetter/setterメソッドをもつ
引数のないコンストラクタを持つ
java.io.serializableを実装している

ServletException postのためのリクエストが処理できなかったとき。
IOException もしサーブレットがリクエストを操作するときに入力あるいは出力エラーが検出されるとき。

####Java入門 -Beanクラス-

メンバ変数とは、
クラス定義をしている{ }内に記述され、そして！メソッドの外に記述されてなければならない

スコープの書き方
//セッショスコープの保存領域
HttpSession session = request.getSession();

//セッションスコープに保存
//Session.setAttribute("属性名", 保存したいインスタンス)

//セッションスコープからインスタンスを取得
(型)　名前 = (型) session.getAttribute("属性名");

メソッド内で保持されている変数はローカル変数という。

####Java入門 -ログイン機能の作成-

getter:「get+プロパティ名」、プロパティの値を取得する
setter:「set + プロパティ名」、プロパティの値を設定する
[Rails]フォームのすべての値をワンクリックで初期化する(helperメソッド定義+JavaScript)

#追記（2020/06/10）
この記事の方法だと、実現できる動作はフォームの初期化(リセット)です。
完全にクリア(ブランク)にする方法はこちらの記事で紹介しています。

[[Rails]ransackで詳細検索フォームを作成したメモ書き](https://qiita.com/masato-teshita/items/bc819895921480e03c6e)

#はじめに
様々な検索条件を付けられる検索フォームを実装している中で、検索条件をワンクリックでリセットできる方法がないかと試行錯誤しました。

結果、下記の方法で実装できたのでまとめます。

#環境
- Ruby2.5.1
- Rails5.2.4

#手順
概要を簡単に説明すると、
**1. ヘルパーメソッドにリセットボタンタグを生成するメソッドを定義**
**2. ビューでそれを呼び出す**
**3. チェックボックスをjsでクリアする処理を書く**
という3本でお送りする感じです

##1. ヘルパーメソッドの定義
どのファイルでもいいですが、今回は`helpers/application.rb`に定義します。

```ruby:helpers/application.rb
module ApplicationHelper
  def reset_tag(value = "Reset form", options = {})
    options = options.stringify_keys
    tag :input, { type: "reset", value: value }.update(options)
  end
end
```

##2. ビューファイルで呼び出し

```ruby:search.html.haml
%div
  = reset_tag 'クリア', id: 'js_clear_btn'
%div
  = f.submit '完了'
```
本来Railsに`reset_tag`はありませんが、ヘルパーメソッドで定義したので、この書き方で呼び出せます。

CSSもで調整してこんな感じに↓
<img width="321" alt="スクリーンショット 2020-06-03 13.53.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602794/54645ee0-e4fa-f49b-deef-0c2392c2c176.png">

##3. チェックボックスをJavaScriptでクリアする記述
私の場合は、リセットボタンだとチェックボックスをクリア（チェックを外す）ことができなかったので、そこはJavaScript書きました。

コードは環境に大きく依存してしまうので、割愛します。

#結果
![f923d6ccbb11ae2bb0c6d320371bc226.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602794/c498773f-dcab-2df0-1b1c-52c16df2464e.gif)
こんな感じで、text_fieldもnumber_fieldも、selectもcheckboxもすべて初期化するボタンを作成できました！

#参考
[フォームを初期化するボタンをRailsで使う](https://qiita.com/umanoda/items/629a5d37dd762528f2b4)
React Nativeバージョンアップ作業 (v0.60.5 -> v0.62.2)

モジュールのリファクタリングの影響？などがあり、Podfile周りにエラーが出たので追加・修正を行いました。大きな変更は必要なくてよかったよかった。以下は発生したエラー群です。

```
[!] No podspec found for `React-Core` in `../node_modules/react-native/React`
[!] No podspec found for `React-DevSupport` in `../node_modules/react-native/React`
[!] No podspec found for `React-RCTWebSocket` in `../node_modules/react-native/Libraries/WebSocket`
[!] Unable to find a specification for `FBReactNativeSpec (= 0.62.2)` depended upon by `React-RCTVibration`
[!] Unable to find a specification for `React-RCTVibration (= 0.62.2)` depended upon by `React`
[!] Unable to find a specification for `FBReactNativeSpec (= 0.62.2)` depended upon by `React-RCTVibration`
[!] Unable to find a specification for `ReactCommon/turbomodule/core (= 0.62.2)` depended upon by `React-RCTVibration`
[!] The name of the given podspec `Yoga` doesn't match the expected one `yoga`
[!] CocoaPods could not find compatible versions for pod "ReactCommon/jscallinvoker":
```

修正した行。

```
pod 'React-Core', :path => '../node_modules/react-native/React'
pod 'React-DevSupport', :path => '../node_modules/react-native/React'
pod 'React-RCTWebSocket', :path => '../node_modules/react-native/Libraries/WebSocket'
pod 'yoga', :path => '../node_modules/react-native/ReactCommon/yoga'
```

修正後の行。

```
pod 'React-Core', :path => '../node_modules/react-native'
pod 'React-Core/DevSupport', :path => '../node_modules/react-native'
pod 'React-Core/RCTWebSocket', :path => '../node_modules/react-native'
pod 'Yoga', :path => '../node_modules/react-native/ReactCommon/yoga'
```

新しく追加した行。

```
pod 'React-CoreModules', :path => '../node_modules/react-native/React/CoreModules'
pod 'FBLazyVector', :path => "../node_modules/react-native/Libraries/FBLazyVector"
pod 'FBReactNativeSpec', :path => "../node_modules/react-native/Libraries/FBReactNativeSpec"
pod 'RCTRequired', :path => "../node_modules/react-native/Libraries/RCTRequired"
pod 'RCTTypeSafety', :path => "../node_modules/react-native/Libraries/TypeSafety"
pod 'ReactCommon/callinvoker', :path => "../node_modules/react-native/ReactCommon"
pod 'ReactCommon/turbomodule/core', :path => "../node_modules/react-native/ReactCommon"
```

参考にしたのは以下のページ。

https://github.com/facebook/react-native/issues/26505
https://github.com/facebook/react-native/issues/26753
https://github.com/facebook/react-native/issues/25553
https://stackoverflow.com/questions/61290827/pod-install-error-the-name-of-the-given-podspec-yoga-doesnt-match-the-expect
https://stackoverflow.com/questions/56917963/react-native-ios-podfile-issue-with-use-native-modules
https://stackoverflow.com/questions/60888440/react-rctdevsettings-h-file-not-found
https://stackoverflow.com/questions/60880105/cocoapods-could-not-find-compatible-versions-for-pod-reactcommon-jscallinvoker

あと、React Navigationがv5になっていましたが、だいぶ変更が大きいみたいなのでそっと置いておくことにしました。
UWSC: Gmailでメール送信

[参考サイト](https://air1p1.com/2019/01/06/uwsc-gmail/)をほぼそのまま使用させてもらってます。
ありがとうございます。


Gmailで送信しようとするとセキュリティを緩める必要が出てきます。
本メールアドレスではなく送信専用のgoogleアカウントを取ったほうがいいでしょう。

- アプリパスワードの設定

　SMTP認証で使用する{password}が必要です。
　Googleアカウント内で設定します。

[参考サイト：アプリパスワード](https://jpn.faq.panasonic.com/app/answers/detail/a_id/2155/~/google%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E3%81%AE%E3%82%A2%E3%83%97%E3%83%AA%E3%83%91%E3%82%B9%E3%83%AF%E3%83%BC%E3%83%89%E8%A8%AD%E5%AE%9A%E6%89%8B%E9%A0%86%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6)

```shell:Gmailから送信
sendMail("{送信メールアドレス}", "{受信メールアドレス}", "{タイトル}", "{本文}")

PROCEDURE SendMail(mailfrom, mailto, subject, body)
	smtpserver = "smtp.gmail.com"	//SMTP Server設定
	smtpserverport = 465

	Dim objEmail = CreateOleObj("CDO.Message")
	objEmail.From = mailfrom
	objEmail.To = mailto
	objEmail.Subject = subject
	objEmail.Textbody = body

	schemas = "http://schemas.microsoft.com/cdo/configuration/"
	objEmail.Configuration.Fields.Item(schemas + "sendusing") = 2
	objEmail.Configuration.Fields.Item(schemas + "smtpserver") =  smtpserver
	objEmail.Configuration.Fields.Item(schemas + "smtpserverport") = smtpserverport

	//SMTP認証。
	objEmail.Configuration.Fields.Item(schemas + "smtpauthenticate") = true
	objEmail.Configuration.Fields.Item(schemas + "sendusername") = mailfrom
	objEmail.Configuration.Fields.Item(schemas + "sendpassword") = "{password}"

	//SSL接続。
	objEmail.Configuration.Fields.Item(schemas + "smtpusessl") = true
	objEmail.Configuration.Fields.Update
	COM_ERR_IGN   //ネット回線が切断されている時にメールを送信するとエラーなるのを防止
	objEmail.Send
	COM_ERR_RET
FEND
```
【AWS SAP】AWS SnowballとAWS Snowmobileの違い【頻出】

##AWS SAP取得に向けて勉強する中で覚えてよかったもの 第4弾
以下の違いについて覚えておいて損はありません。

・AWS Snowball
・AWS Snowmobile

##AWS Snowball
オンプレミス環境からAWSにデータを転送する際、ネットワーク経由で転送するのではなく、AWSからsnowballという専用のデータストレージを物理的に借りてそこにデータを入れる。

データを入れたsnowballをAWSへ返送すると、AWSがS3へデータインポートしてくれる。

(以下公式サイトより)
> オンボードのストレージとコンピューティング機能を備えたペタバイト規模のデータ転送

##AWS Snowmobileとは
snowballより、更に大容量のデータを移行することができる。

45フィートコンテナに100PBストレージを搭載。
トラックで直接データ転送元のデータセンターへ移動、データをトラックに搭載したストレージに直接取り込んでAWSに転送します。

もはや、想像の域を超えたデータ移行方法だが、エクサバイト級のデータも楽チンにAWSへ移行できるらしい。

(以下、公式サイトより)
> AWS Snowmobile は、超大容量データを AWS に移動するために使用できるエクサバイト規模のデータ転送サービスです。セミトレーラートラックが牽引する長さ 14 m の丈夫な輸送コンテナで、Snowmobile 1 台あたり 100 PB まで転送できます。Snowmobile を使うと、ビデオライブラリや画像リポジトリ、またはデータセンター全体まで、膨大な量のデータを簡単にクラウドに移動できます。Snowmobile でのデータ転送は、より安全かつ高速で、コスト効率の良い方法です。

##AWS SnowballとAWS Snowmobileの違い
10 PB を超える大規模なデータを一つの場所に移行する場合は、AWS Snowmobile。

10 PB 未満のデータセットの場合、または複数の場所に分散する場合には、Snowball を使用。

バックボーンの帯域によっては、容量が大きくてもSnowballを複数利用した方が効率が良い場合もあります。

参照)
Q: Snowmobile と Snowball のどちらを選択したらよいですか?
https://aws.amazon.com/jp/snowmobile/faqs/
複数のplt.textで重なる文字をなんとかできる。

#複数のplt.textで重なる文字をなんとかしたい。
plt.textをfor文で何個も付けていると文字同士が重なり読めなくなってしまう…

```python
import numpy as np
import matplotlib.pyplot as plt

np.random.seed(0)
x, y = np.random.random((2,30))
fig, ax = plt.subplots()
plt.plot(x, y, 'bo')
texts = [plt.text(x[i], y[i], 'Text%s' %i, ha='center', va='center') for i in range(len(x))]
```
![wiki_example_before.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/330449/f961b7d5-80fe-250f-4803-cc5e62821b3c.png)

**そんなお困りを解決してくれる嬉しいライブラリがあったので共有します**

##adjustTextを入れるだけ
このライブラリはR/ggplot2のggrepel packageに影響を受けて作られたそうです。
（Rの方は知りません）
導入は**pipでできます**。

```
pip install adjustText
```
使い方も簡単で、**adjustTextのadjust_textに整列したいtextsをリストにして入れる**だけ

```python
from adjustText import adjust_text
 
fig, ax = plt.subplots()
plt.plot(x, y, 'bo')
texts = [plt.text(x[i], y[i], 'Text%s' %i, ha='center', va='center') for i in range(len(x))]
adjust_text(texts)
```
![wiki_example_after_no_arrows.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/330449/429f4a8e-547b-3341-f2b8-4efc7f08cb4e.png)

どの点のアノテーションかわかりやすいように**plt.annotateのような矢印**を入れることも可能。

```python
fig, ax = plt.subplots()
plt.plot(x, y, 'bo')
texts = [plt.text(x[i], y[i], 'Text%s' %i, ha='center', va='center') for i in range(len(x))]
adjust_text(texts, arrowprops=dict(arrowstyle='->', color='red'))
```
![wiki_example_after_with_arrows.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/330449/d8eb2529-4b24-2e04-325c-26de95572bf4.png)

ありがてえ！！！
##参考
https://github.com/Phlya/adjustText
NuxtJS（＋Vuetify）にFirebaseを入れたらビルドエラーが出る

# バージョン

```
"firebase": "^7.14.6"
"nuxt": "^2.0.0"
"@nuxtjs/vuetify": "^1.0.0"
```

# エラー

`core-js` 関連でエラーが出ていることが分かります。

```
ERROR in ./node_modules/vuetify/lib/util/helpers.js
Module not found: Error: Can't resolve 'core-js/modules/es6.array.fill' in '/Users/shinozaki/src/github.com/shinoshu/google-analytics-for-firebase/node_modules/vuetify/lib/util'
 @ ./node_modules/vuetify/lib/util/helpers.js 3:0-40
 @ ./node_modules/vuetify/lib/components/VList/index.js
 @ ./layouts/default.vue
 @ ./.nuxt/App.js
 @ ./.nuxt/index.js
 @ ./.nuxt/client.js
 @ multi ./.nuxt/client.js

# 省略

ERROR in ./node_modules/vuetify/lib/util/colorUtils.js
Module not found: Error: Can't resolve 'core-js/modules/web.dom.iterable' in '/Users/shinozaki/src/github.com/shinoshu/google-analytics-for-firebase/node_modules/vuetify/lib/util'
 @ ./node_modules/vuetify/lib/util/colorUtils.js 3:0-42
 @ ./node_modules/vuetify/lib/services/theme/utils.js
 @ ./node_modules/vuetify/lib/services/theme/index.js
 @ ./node_modules/vuetify/lib/services/index.js
 @ ./node_modules/vuetify/lib/framework.js
 @ ./.nuxt/vuetify/plugin.js
 @ ./.nuxt/index.js
 @ ./.nuxt/client.js
 @ multi ./.nuxt/client.js
```

# 原因

> The problem is nuxt/@nuxt/babel-preset-app is not able to locate the right version of core-js when there are multiple versions of core-js in node_modules, which is a common situation in the npm ecosystem. If anything, it is something nuxt should address.

> 問題はnuxt / @ nuxt / babel-preset-appが、node_modulesに複数のバージョンのcore-jsがある場合に正しいバージョンのcore-jsを見つけられないことです。これは、npmエコシステムの一般的な状況です。どちらかと言えば、それはnuxtが対処すべきものです。

https://github.com/firebase/firebase-js-sdk/issues/2968#issuecomment-617975070

# 解決方法

https://nuxtjs.org/guide/release-notes#v2.6.0

## 方法１

core-js ver.2 を使う方法

`$ npm i -D core-js@2`

`$ yarn add -D core-js@2`

## 方法２

core-js ver.3 を使う方法

こちらは公式サイトに詳しくやり方が記載されていますので、ご参照ください。

https://nuxtjs.org/guide/release-notes#v2.6.0
HerokuのビルドインサーバーGit管理


#Herokuとは。
無料でWEBサービスを開発&公開できるサービスで
ApacheやPHP、データベースのインストールが不要(WEBサーバーのデフォルトはApache、DBはpostgres)。
クラウドサービスで初期費用を抑え開発可能になり、環境構築が容易である。

#初期設定

[Heroku](https://signup.heroku.com/jp)で無料アカウントを作成する。

```
$ brew install heroku/brew/heroku
```

Herokuへログインする。

```
$ heroku login
```

編集するディレクトリを作成し移動する。

```
$ mkdir myapp
$ cd myapp //アップロードしたいアプリのディレクトリ
```

gitのリポジトリとアクセスURLを作成する。
`Anyname`は任意のリポジトリ名で入力する。

```
$ heroku create {Any}name //プロジェクトフォルダへアプリの作成
Creating ⬢ eriapptest... done
https://your-app-name.herokuapp.com/ | https://git.heroku.com/{アプリ名}name.git //ドメインとgitのURLが発行される。


```

リポジトリの新規作成し管理するフォルダでgitの初期化を行う。

```
$ git init //リポジトリ作成
$ git remote add heroku https://git.heroku.com/{アプリ名}.git //サーバと紐付けするコマンド
```

PHPファイルを作成。

```
<?php
echo 'Hello, world!!';
```
リポジトリの変更内容を確認。

```
$git status
```

変更したファイルをHerokuのリポジトリにpushする。
`master`はブランチ名。

コミットするファイルの指定。

```
$ git add . //すべてのファイル・ディレクトリ
```

ファイルをコミットする。

```
$ git commit -m"first commit" //mオプションで単一コメントが可
```

Herokuへソースコードの更新。

```
$ git push heroku master
```

pushするとデプロイした画面が表示される。


#heroku　コマンド一覧
[コマンド一覧](https://e-tec-memo.herokuapp.com/article/3/)

#DBの作成

[Heroku postgres](https://vavolab.com/article/2018/05/31/22/16/49/)でDBを作成する。

[Heroku 2](https://vavolab.com/article/2018/06/05/00/02/01/)





#laravelのmigrateファイルを実行
```
$ heroku run php artisan migrate:reset
```

seedファイルの実行

```
$ heroku run php artisan db:seed
```
macにrailsがインストールできない

##この記事について
プログラミングの勉強をしています。
勉強の過程で得た知識を、忘れないようまとめておくのと共に、誰かの助けになればと思います。

##「rails　-v」が上手くいかない！

 ```
(base) hoge@MacBook-Pro ~ % rails -v
Rails is not currently installed on this system. To get the latest version, simply type:

    $ sudo gem install rails

You can then rerun your "rails" command.
```
調べた通りにrailsをインストールしたのに、rails -vを何度実行してもこのエラーが出てしまいます。

##対処法
```
rbenv rehash
```
このコマンドを実行し、再度rails -vを実行すると

```
(base) hoge@MacBook-Pro ~ % rails -v
Rails 6.0.3.1
```
上手くいきました！！

##参考
https://qiita.com/amuyikam/items/313bc89c1de320a4257e
https://github.com/railsgirls-jp/coach.info/issues/32
Bootstrap MaxLengthで警告色表示を実装する



### デモ＆ソースコード

https://codepen.io/qwe001/pen/LYGYxMa

これを見てやりたいことを察してください


### 要件

* 現在の入力値が、入力最大値の75%を超過した時、入力欄と文字数カウンタの色を黄色にする
* 現在の入力値が、入力最大値を超過した時、入力欄と文字数カウンタの色を赤色にし、送信できないようにする

### 必要なもの

* jQuery
* Bootstrap
* Bootstrap MaxLength
* (AdminLTE3) ※デモと同じ見た目を再現する場合

### 知っておくべきこと

* 属性の指定は「data-maxlength」を使用してください。「maxlength」属性ではありません

公式ドキュメントにも書いてましたが一応。

```html

● OK!!

<input type="text" id="name" name="name" class="form-control" value="" data-maxlength="20">

● ダメ～～!!

<input type="text" id="name" name="name" class="form-control" value="" maxlength="20">
```

* 本デモでは、入力最大値ちょうどの時の色を黄色に変更しています

Bootstrap MaxLengthは、入力最大値ちょうどの時、文字数カウンタの色を赤色にします。
ただし、その状態でも送信可能です。

私は入力最大値の時に赤色になるのが気に入らなかったので、強制的に黄色に変更しています。

```javascript

    else if(nowLen === maxLen){ // 現在の入力値が最大値と同じとき
      $(this).addClass('is-warning');
      $(this).removeClass('is-invalid');

      $('.bootstrap-maxlength').removeClass('text-muted');
      $('.bootstrap-maxlength').addClass('text-warning'); // ★★★これ★★★
      $('.bootstrap-maxlength').removeClass('text-danger'); // ★★★これ★★★
    }
```

Bootstrap MaxLengthの本来の挙動ではないのでご注意ください。

### 既知のバグ

* ~~複数の入力欄にdata-maxlengthを設定した場合、それぞれの文字数カウンタの色がバグる(可及的速やかに直します)~~
 * 修正しました
* ~~テキストエリアの改行すると文字数ごとのクラス変更が一致しない(たぶん直します)~~
 * 修正しました

### なぜ作ったか

公式に私がしたいことを実現するオプションがなかったので。。

一応チケット起票しましたが、
古いプラグインですし公式対応してくれるかは望み薄な気がする。

https://github.com/mimo84/bootstrap-maxlength/issues/102

文字数ギリギリで色変更とか結構よくありそうな話だと思うんですが、
皆さんはどうやって実現してるんですか？
もっといいライブラリとかあったら教えてちょ

### おまけ

私が開発中のプロジェクトの場合、
一つの入力フォームの中に、普通のテキストエリア欄と、
HTMLエディタ欄(TinyMCE)が一つずつ、一緒に存在するケースがあります。

TinyMCE側には標準で文字数カウンタがあるので、
テキストエリア欄にだけBootstrap MaxLengthを使っていますが、ここで問題があり。

TinyMCEの読み込みは、ページ読み込み完了よりさらに後になる関係で、
TinyMCEが表示されたらテキストエリア欄の文字数カウンタの位置がずれてしまうのです。

![a.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130352/50bd65cb-d16c-5526-b7d5-b2a2230a1fa6.jpeg)


なので、TinyMCEが読み込まれた後に、文字数カウンタの表示位置調整を行います。
普通のテキストエリア欄やTinyMCEのHTMLエディタ欄が複数あったらどうなるかはしらね。

```javascript
/**
 * TinyMCE configurations
 */
function initTinyMCE(elem)
{
  var myElem = elem !== undefined ? elem : "textarea.html_field";
  var options = {
    selector : myElem,
    setup: function(editor){
      editor.on('init', function(e){ // when tinymce is ready
        // 文字数カウンタの場所がtinyMCEの出現によりずれるので再調整する
        $('textarea[data-maxlength]').trigger('maxlength.reposition');
      });
    }
  };

  tinymce.init(options);
}

initTinyMCE();
```
C# 連番の数値をグループわけする方法

# 概要
連番の数値をグループ化する際に嵌ったので自分用のメモとして残しておく。

以下のような配列形式の数値を連番を整形して
int [] number = { 1,2,3,6,9,10,15,16 }

以下のような形式で取得をしたい
1,2,3
6
9,10
15,16

## 実現方法
以下の方法で実現が可能です。

```cs
var number = { 1,2,3,6,9,10,15,16 };
    
// 配列の要素からインデックスの値を引いた値は同じになることを利用してグルーピングしています
var result = number.Select((x , index) => (x , index))
                   .GroupBy(n => n.x - n.index, n => n.x);
```
MySQL5.7でアプリが動かなくなる原因の１つ

#MySQLのバージョンを5.7にあげたら動かなくなった
MySQL8がリリースされているものの、まだまだMySQL5系をご利用されている場合は多いかと思います。今回はphpのアプリで利用しているMySQLのバージョンを5.6→5.7に入れ替えたときに急にアプリが動かなくなりました。

#原因：sql_modeの設定
原因はMySQLの設定項目であるsql_modeでした。旧環境(5.6)と新環境(5.7)で
この設定が異なっていたため、SQLエラーが頻発していました。
（sql_modeの解説は他に詳しく書いている方が多くいると思うので省略します。）

コマンド実行で変更可能ですが運用的には`/etc/my.cnf`に

```
[mysqld]
...
sql_mode=NO_AUTO_VALUE_ON_ZERO,STRICT_ALL_TABLES
```
みたいに明示的に指定して固定しておいたほうが間違いないかと。

sql_modeのデフォルト設定は5.7以降よく変わっているようです。（[参考](https://econosys-system.com/blog/archives/201)）
Laravelの動的whereを活用する

# 動的whereとは

LaravelのEloquentで条件を指定したい場合、通常は以下のように３つの引数（カラム名、演算子、値）を渡す必要があります。

```php
//名前が「fuga」で、年齢が30歳のレコードを1件取得
Hoge::where('name', '=', 'fuga')->where('age', '=', 30)->first();
```

実はこのクエリ、以下のように書くこともできます。

```php
Hoge::whereName('fuga')->whereAge(30)->first();
```

カラム名がメソッド名に吸収され、演算子も消え、引数は値だけになりました。
`whereXxxx('fuga')`というメソッド名にすることで、`Xxxx`の部分がカラム名に自動変換され、`where('xxxx', '=', 'fuga')`と同等に使うことができます。[^camel]
使える演算子は`=`のみですが、少しだけ行が短くなります。

[^camel]: カラム名が複数語で構成されている場合はキャメルケースに変換して指定してください。

# 応用

`And`でカラム名をつなぎ、同じ数だけ引数に値を渡すことで、一つのメソッドで複数のカラムを対象にすることもできます。
以下のクエリも、冒頭のクエリと等価となります。

```php
Hoge::whereNameAndAge('fuga', 30)->first();
```

`And`ではなく`Or`で繋ぐことで、OR条件にすることもできます。
同じカラム名でも大丈夫です。

```php
Hoge::whereNameOrNameAndAge('fuga', 'piyo', 25)->first();
```

`And`|`Or`で繋いでいけば何個でもカラムを指定できます。
ただし、やりすぎるとむしろわかりにくくなるのでほどほどに。

# 注意点

対象のEloquentモデル、もしくはその祖先のクラスですでに定義済みのメソッドの場合、うまく動作しません。
例えば、`\Illuminate\Database\Eloquent\Builder`には`whereKey`というメソッドが存在するため、`key`というカラムに対して、`whereKey`という動的whereは使用できません。[^1]
その場合は素直に通常の書き方をするか、Eloquentに独自のメソッドを定義してあげるのが良いでしょう。

[^1]: ほかのカラムとの組み合わせなら可能。`whereKeyAndId`みたいな

また、`whereXxxx`というメソッドは当然実際には存在せず、動的に処理を行っているため、そのままだとIDEでエラーになります。
`class Hoge`のPHPDocにちゃんとメソッドを追加してあげましょう。

```php
/**
 * @method static \Illuminate\Database\Eloquent\Builder|\App\Eloquents\Hoge whereXxxx($value)
 */
```
[自分用メモ] Windows 10 on Parallelsでの設定

＃ 英語キーボードを削除
https://blog.divakk.co.jp/entry/parallels-keyboard

# CommandキーをControlキーに割り当てる
<img width="598" alt="スクリーンショット 2020-07-07 13.58.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58650/9a03f368-9ad5-9b11-19f8-7d30d249cf05.png">

# ControlキーをWindowsキーに割り当てる
<img width="598" alt="スクリーンショット 2020-06-03 13.10.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58650/7f88715e-2c73-a29c-160d-81990b6e549c.png">

# IMEオン/オフ
まずIME設定を古いやつに変更する。

https://www.atmarkit.co.jp/ait/articles/2011/13/news012.html

そのあと、設定を変更。

https://sp7pc.com/apple/mac/36198

# Command + →（or ←）
![スクリーンショット 2020-06-03 17.03.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58650/63e68d20-08c0-600f-a49d-69ed7aaa2361.png)

# Windows側でデュアルモニター
![スクリーンショット 2020-07-07 14.00.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58650/4d85be8d-1af2-e1ef-7d02-3c6259ced02e.png)
筑波大学の機械学習講座：課題のPythonスクリプト部分を作りながらsklearnを勉強する (10)

前回
[筑波大学の機械学習講座：課題のPythonスクリプト部分を作りながらsklearnを勉強する (9)](https://qiita.com/legacyworld/items/8da3476d40f9861a38e4)
https://github.com/legacyworld/sklearn-basic

# 課題 5.3 ヒンジ損失と二乗損失
今回は外れ値がある場合
Youtubeの解説は第6回(1)55分30秒あたり

## 外れ値ありのヒンジ損失
プログラムは2行足すだけ

```python
X = np.insert(X,0,[5,-50],axis=0)
y = np.insert(y,0,1)
```
講座では最初の値を入れ替えているようだが、1つ追加してもそこまで変化は無さそうだ。

これが実行結果。
大きく外れた値が一つポツンとあっても、正解であればヒンジ損失では0になるので何ら影響はない。
![5.3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629456/b4c43b49-2dd9-82ed-5731-059087f8a161.png)

## 外れ値ありの二乗損失
これも同じく2行足すのだが、何故か座標が[5,-35]に変わっている。
おそらく二乗損失も[5,-50]でやると外れ方が大きくなりすぎるからだと思われる。
こちらが実行結果
![5.3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629456/c05a212a-9e32-bfb8-d3aa-fecd5632860e.png)

# この問題の意図
大きな外れ値があった場合にヒンジ損失では何の問題も無く分類で来ているが、二乗損失では正解であっても遠く離れたものは大きなペナルティを与えてしまうためおかしくなってしまう。

# 過去の投稿
[筑波大学の機械学習講座：課題のPythonスクリプト部分を作りながらsklearnを勉強する (1)](https://qiita.com/legacyworld/items/a3763760e65774dc0e33)
[筑波大学の機械学習講座：課題のPythonスクリプト部分を作りながらsklearnを勉強する (2)](https://qiita.com/legacyworld/items/5a72c83860c1d0b1d352)
[筑波大学の機械学習講座：課題のPythonスクリプト部分を作りながらsklearnを勉強する (3)](https://qiita.com/legacyworld/items/c9cd7865efb343c42e5e)
[筑波大学の機械学習講座：課題のPythonスクリプト部分を作りながらsklearnを勉強する (4)](https://qiita.com/legacyworld/items/9231c44206c8f0823ff5)
[筑波大学の機械学習講座：課題のPythonスクリプト部分を作りながらsklearnを勉強する (5)](https://qiita.com/legacyworld/items/2d2db10024d7dfb5f89b)
[筑波大学の機械学習講座：課題のPythonスクリプト部分を作りながらsklearnを勉強する (6)](https://qiita.com/legacyworld/items/e54c664fc138b75dd166)
[筑波大学の機械学習講座：課題のPythonスクリプト部分を作りながらsklearnを勉強する (7) 最急降下法を自作](https://qiita.com/legacyworld/items/bdbb0cbdc5b9b33fd1eb)
[筑波大学の機械学習講座：課題のPythonスクリプト部分を作りながらsklearnを勉強する (8) 確率的最急降下法を自作](https://qiita.com/legacyworld/items/663fcd8189f0bdf38f64)
https://github.com/legacyworld/sklearn-basic
https://ocw.tsukuba.ac.jp/course/systeminformation/machine_learning/
【AWS SAA】 曖昧な箇所をまとめてみた③

#背景
`最も本試験の難易度に近い`と言われている[【SAA-C02版】AWS 認定ソリューションアーキテクト アソシエイト模擬試験問題集（6回分390問）](https://www.udemy.com/course/aws-knan/)の中で、<br>自分が解いていてつまづいた箇所をピックアップしました。


#◆ つまづいた用語一覧

|用語 |意味 |
|:-----|:--------|
|NATインスタンス|プライベートサブネットのインターネットアクセスを許可。<br>**送信元/送信先チェックの無効化**
|**NATゲートウェイ**|目的はNATインスタンスと同じ。**Elastic IPアドレスの割り当て**が必須|
|ブロードキャストアドレス|**同じネットワークにいる全ノード**に対して同じデータを散布する|
|**マルチキャスト**|複数のノードに対して**同じパケット(データ)**を送付する|
|ハイパーバイザー|VMWare, Hyper-Vなどの**仮想マシンソフト**|
|インスタンスストアボリューム|インスタンスが**終了・停止**した際に削除される|
|instance-Store-Backed|起動ディスクが**インスタンスストア**|
|**プロキシ**|**内部NWからインターネット接続**を行う際の中継サーバ|
|**ユーザデータ**|**EC2インスタンスの初回起動時**に実行したい処理を設定する<br>※ElasticIPアドレスの紐付けなど|
|メタデータ|**インスタンスID**や**IPアドレス**などEC2インスタンス自身に関するデータ|
|**DHCP**(Dynamic Host Configuration Protocol)|クライアントサーバ方式で、DHCPサーバが**NWアドレスを動的に割り当て**、<br>設定情報と共に、ホストに送信する|
|クライアントサーバシステム|**サーバ/クライアント**に分け、役割分担する|
|トランザクション|**複数の処理を１つ**にまとめたもの|
|**OLTP**(Online Transaction Processing)|**トランザクション処理**を行う**データベース**|
|**OLAP**(Online Analytical Processing)|**分析処理**を行う**データベース**|
|リスナー|**接続リクエストをチェック**するプロセスのこと|
|ALB パスベースルーティング|・明らかな**不正アクセスを上位レイヤーで弾く**役割<br>・任意のアクセスパスを**ターゲットグループに登録**する<br>・**対象リスナー**(https)などの設定|
|**クラスタープレイスメントグループ**|**単一AZ内のインスタンス**を論理的にグループ化<br>**低レイテンシーのネットワーク**に参加する<br>Linuxの**拡張ネットワーキング**合わせて使用される|
|**カスタマーゲートウェイ**|**VPN接続**の際の**作業者側**のアンカー|
|**仮想プライベートゲートウェイ**|**VPN接続**の際の**AWS側**のアンカー|
|**MD5チェックサム**|**S3にアップロード**された**オブジェクトの整合性**を確認する<br>AWS CLIで**整合性**を確認する<br>**MD5チェックサム値**を**HTTPヘッダー**に格納する|
|CIDRブロック|IPアドレスの**ネットワーク部** / **ホスト部**で決められた**ブロック単位**で区切るのが普通<br>**CIDR**は任意の**ブロック単位**で区切ることが出来る|
|**シャーディング**|データを**複数ノードに分割**<br>**リクエスト分散** / **スループット向上**|
|スループット|単位時間あたりに処理できる量のこと|
|**マスター/スレーブ**|**1つが管理** / **残りが制御**という役割方式|
|sequential|シーケンシャル順次的な / 連続的な| 
|**スポットブロック**|**スポットインスタンス**を1〜６時間継続して利用できるようになった機能|
|**スポットフリート**|自動で**最安値のインスタンス**を選択して起動する|
|AWS STS|**アクセスキー**/**シークレットキー**/**セッショントークン**の３つが発行される|
|RDS/DBスナップショット|**DBスナップショット**を取得するためには新しいインスタンスの起動が必要<br>RDSのスケールアップには**停止**が必要|
|ECU(EC2 Compute Unit)|EC2インスタンスの**スペック単位**|
|**Source IP**|**IAMロール**を使用して、特定のIPアドレスからAPI呼び出しを**制限**する|
|WAF(web application Firewall)|**IDS**/**IPS**で防ぐことのできない不正な攻撃からwebアプリケーションを防御する**ファイアーウォール**のこと|
|**eth0**|仮想サーバのNICが**インターネット通信全開**であること|
|インターフェース|機器に関する**外部との接続部分**の総称|
|VPC/サブネットのCIDR範囲|デフォルトVPCのCIDRは172.31.0.0/**16**、<br>デフォルトサブネットはCIDRのうち/**20** CIDRを使用|
|**S3 export/import**|大量の**物理ストレージデバイス**からAWSに転送するのに使用するサービス|
|フェデレーション STS|認証の際に**STS**を使用することでセキュリティが保持される|
|**パッチ**|母体のプログラムに追加することで**プログラムの変更/機能追加**を促せること|
|バッチ|複数の処理を　一括で行えるようにする方法|
|**ラウンドロビン方式**|**ロードバランサー**による**サーバ**/**リクエスト**振り分け方式の一つ|
|**IOPS**(Input OutPut Per Second)|**１秒あたり**に処理出来る**アクセス数**  ※**HDDは低い** / SSDは高い|
|IOPSとスループット|1秒あたりの**最大データ送信料**　※スコープ(範囲)は広い ※**bps** /**kbps**など|
[作業メモ]Firebase Crashlyticsの導入

## 事前準備
- Android Studio

## Firebase SDKの導入
https://firebase.google.com/docs/android/setup

## Crashlyticsの導入
https://firebase.google.com/docs/crashlytics/get-started?platform=android#kotlin+ktx

## 次のステップ

- [強制クラッシュで検証](https://firebase.google.com/docs/crashlytics/test-implementation?platform=android)

- [カスタマイズ](https://firebase.google.com/docs/crashlytics/customize-crash-reports?platform=android)



## ハマりポイント

公式の導入手順ドキュメントは多言語対応していますけど、日本語の場合にAndroid版の導入手順はまだないらしいです。なので言語を英語に切り替えてから、Android版を確認する方が確実に最新版が表示されます。
BigQuery での unix timestamp (micro秒) の JST への変換を何度も忘れるのでメモ

タイトルの通りです

```sql
select 
  FORMAT_TIMESTAMP('%Y-%m-%d %H:%M:%S', TIMESTAMP_MICROS(CAST('1590968103557000' AS INT64)), 'Asia/Tokyo') AS s0, -- STRING
  STRING(TIMESTAMP_MICROS(CAST('1590968103557000' AS INT64)), 'Asia/Tokyo') AS s1, -- STRING
  DATETIME(TIMESTAMP_MICROS(CAST('1590968103557000' AS INT64)), 'Asia/Tokyo') as s2, -- DATETIME
  PARSE_DATE('%Y%m%d',  '20200601')  as  d0 -- DATE
```


|行|s0|s1|s2|d0|
|:-:|:-:|:-:|:-:|:-:|
|1|2020-06-01 08:35:03|2020-06-01 08:35:03.557+09|2020-06-01T08:35:03.557000|2020-06-01|

メモ: `DATETIME` にしておくとその後 EXTRACT 等で操作できるので柔軟。
phpMyAdminでエクスポートしておいたバックアップデータがインポートできない！？

## インポートできない…
削除機能を改修している途中、誤ってデータベースのとあるテーブルのデータががっつり半分以上消えてしまったのでエクスポートしておいたテーブルのデータをインポートして元に戻そうとしました。
・
・
・
できない…
なぜだ…

```sample.sql
1054: Unknown column 'カラム名' in 'field list'

```

とか

```sample.sql
#1062 - Duplicate entry '1' for key 'PRIMARY'
```

とかエラーが出て、何をしてもどっちかのエラーが出て一向にインポートできる気がしない。

## そもそもエクスポートの時点で必要な設定がされていないから！
はい。この問題が発覚してから調べて知りましたが、
エクスポートのオプションで
『DROP TABLE / VIEW / PROCEDURE / FUNCTION / EVENT コマンドを追加する』
にチェックを入れておかないとエラーが出る場合があるみたいですね。
しかもデフォルトではチェックが入っていないときた。
エラー出るならなんでデフォルトでチェック入れといてくれないんだ…なにか理由があるんだろうけど。
結構なサイトでエクスポートの方法見たときこんなこと書いてなかったから要注意ですね。
しかも今までこんな設定知らずにサーバの引越しなんかもしてたのにエラー出たことなかったから忘れそう…

## エクスポート の手順
### 1.『エクスポート方法』で詳細を選択して、エクスポートするテーブルを選択
Macの人はcommandを押しながら複数選択できますよ。
私の場合は管理がややこしくなりそうだからテーブルごとにエクスポートしてます。

<img width="955" alt="スクリーンショット 2020-06-03 11.43.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440512/f84a75fb-46fa-612b-a4ca-349434bcabb4.png">

### 2.『生成オプション』の『DROP TABLE / VIEW / PROCEDURE / FUNCTION / EVENT コマンドを追加する』にチェック
『フォーマット特有のオプション』は『構造とデータ』にチェックですね。
<img width="957" alt="スクリーンショット 2020-06-03 11.49.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440512/a7755a02-685f-41c3-90fa-0f2fa1d63562.png">

※別のテーブルにインポートしようとしても、同名のテーブルにインポートされます。
　→テスト用に複製して名前を変えてそこにインポートしようとしたら複製元のテーブルにインポートされてあせった。（テスト用に作ってあった別のDBでやったから問題なかったけど）

## SQLでインサート
しかし今回はバックアップとしてエクスポートしていたデータ。
当然元のデータはもうミスって消してしまった状態のものしかないのでエクスポートし直すなんてことができない。
なんとかこのバックアップデータをインポートする方法はないかと思ったが、結局ググってもわからなかったのでSQLでインサートすることにしました。

### 1.SQLの画面で『INSERT』をクリックしてINSERT文をセットする
<img width="970" alt="スクリーンショット 2020-06-03 12.51.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440512/201c6adc-79f5-d2d3-8e0c-b8ff7115c572.png">

### 2.先ほど「VALUES」の後にある（…）に、エクスポートしていたデータをコピペして実行
エクスポートしたsqlのデータをテキストエディタで開くとサーバの情報だとかテーブルの構造だとかが入っているが、この部分より下からINSERT文が始まっている。
このINSERT文の「VALUES」以下の(…)をコピペして、1.の同じ箇所にコピペして実行すればOK！（1.で選択されている部分）

```sample.sql
INSERT INTO `sample_table`(`id`, `name`, `color`, `illust`, `position`) VALUES (…)

/*１行分なら最後の「;」は不要っぽい*/
```

複数行インサートする場合は

```sample.sql
INSERT INTO `sample_table`(`id`, `name`, `color`, `illust`, `position`) VALUES (…),(…),(…),(…),(…),(…),(…),(…);

/*複数行の場合は行ごとにカンマ「,」区切って、最後に「;」をつける*/
```

行数が多いとINSERT文が何回かに分けて書かれていると思うので、INSERT文の数だけ上記の手順を繰り返して入れるといいと思います。
INSERT INTOから全部コピペして入れたらいいじゃんと思うかもしれませんが、やってみたら最初のエラー1054が出てできませんでした…。

SQLもphpMyAdminもまだまだよくわかっていないので忘備録的な感じで書きましたが、もっとよく理解できるようになったらわかりやすい記事にしたいと思います。
Windows 10 + Python3 + selenium + chromedriver + headless chrome でファイルをDLしてみる

Windows 10 + Python3 + selenium + chromedriver + headless chrome でファイルをDLしてみる
#目的
サイズの大きなバイナリファイルと画像ファイルをダウンロードしてみる
※urllib.request.urlretrieve で明示的にファイル名を指定すればよいようだ
#サンプルコード
対象とするhtmlの抜粋
<pre>
&lt;a href="./LibreOffice_6.4.4_Win_x64.msi" target="_blank"&gt;LibreOffice_6.4.4_Win_x64.msi&lt;/a&gt;
&lt;img src="./eudv015s.jpg"&gt;
</pre>

```python
# Windows Add env PYTHONIOENCODING = UTF-8 & restart vscode

import os
import time
import urllib.request
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait, Select
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys
import chromedriver_binary # 抜けているとエラー

# ブラウザーを起動
options = Options()
options.binary_location = 'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe'
options.add_argument('--headless')
driver = webdriver.Chrome(options=options)

driver.get('http://localhost:8080/')

try:
    element = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.TAG_NAME, 'a'))
    )

    elm = driver.find_element_by_tag_name("a").get_attribute("href")
    print(elm)

    # DL対象ファイル名
    print(os.path.basename(elm))
    
    # DL先フォルダ名
    print(os.getcwd())

    # DL後のフォルダ＋ファイル名
    print(os.path.join(os.getcwd() + '\\', os.path.basename(elm)))

    # ファイルのダウンロード
    urllib.request.urlretrieve(elm, \
        os.path.join(os.getcwd() + '\\', os.path.basename(elm)))

    img = driver.find_element_by_tag_name("img").get_attribute("src")   
    print(img)

    # ファイルのダウンロード
    urllib.request.urlretrieve(img, \
        os.path.join(os.getcwd() + '\\', os.path.basename(img)))

    # time.sleep(2) # 表示確認用のwait
finally:
    print('done')
    driver.quit()
```

#参考にしたサイトはこちら
[urllib.request --- URL を開くための拡張可能なライブラリ](https://docs.python.org/ja/3/library/urllib.request.html)
[PythonでWeb上のファイルをダウンロードする](https://qiita.com/yuukiclass/items/88e9ac6c5a3b5ab56cc4)
CVE-2019-3799 Spring-Cloud-Config-Server 路径穿越/任意文件读取

## 复现
idea创建一个spring项目，然后pom.xml中加入

```xml
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-server</artifactId>
    <version>2.0.2.RELEASE</version>
</dependency>
```
配置application.properties

```
server.port=8888
spring.cloud.config.server.git.uri=https://github.com/SukaraLin/awesome-cve-poc.git
```

然后访问
`http://127.0.0.1:8888/aaa/bbb/master/..%252F..%252F..%252F..%252F..%252F..%252Fwindows/win.ini`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/63d077bd-2242-7ac4-33b6-1ffe1be43762.png)

## 分析
Spring Cloud Config Server是Spring为了分布式管理的一个组件，在Server端中负责存储配置，Client可以通过http的形式获取配置值。payload对应的路由存在于`org.springframework.cloud.config.server.resource.ResourceController#retrieve()`中，其代码

```java
    @RequestMapping({"/{name}/{profile}/{label}/**"})
    public String retrieve(@PathVariable String name, @PathVariable String profile, @PathVariable String label, HttpServletRequest request, @RequestParam(defaultValue = "true") boolean resolvePlaceholders) throws IOException {
        String path = this.getFilePath(request, name, profile, label);
        return this.retrieve(name, profile, label, path, resolvePlaceholders);
    }
```
`{name}/{profile}/{label}`：name对应仓库名，profile对应配置文件，label为git分支名，一般上都有一个master分支。实际测试中name、profile值无所谓，但是label分支名必须存在。调试跟进getFilePath
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/723d1329-8041-f226-6c40-a5efbe361b0a.png)
这边已经把`%25`urldecode为`%`了，继续跟retrieve()，这边path传入的是我们的payload

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/9e5bf037-6426-97b9-b2fb-5c5ba6fa2c47.png)

继续跟下findOne，位于`org.springframework.cloud.config.server.resource.GenericResourceRepository#findOne`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/5ef84c57-8f82-e5e8-0110-b1c9793c5a4b.png)
locations目录`file:/C:/Users/icu/AppData/Local/Temp/config-repo-6608031716294156148/`是配置文件中git仓库被clone的临时位置，然后拼接`../`造成跨目录文件读取。

## 修复

https://github.com/spring-cloud/spring-cloud-config/commit/3632fc6f64e567286c42c5a2f1b8142bfde505c2

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593424/9bdfae72-4207-1b5d-23cd-189cad33874c.png)

通过判断是否存在`%`来urldecode，然后匹配`../`、`..`、`/`等特殊字符。

## 参考
1. [Spring-Cloud-Config-Server-任意文件读取分析](http://www.lmxspace.com/2019/04/26/Spring-Cloud-Config-Server-%E4%BB%BB%E6%84%8F%E6%96%87%E4%BB%B6%E8%AF%BB%E5%8F%96%E5%88%86%E6%9E%90/)
【AWS】WorkSpacesで月額料金←→時間料金を切り替える

# WorkSpace料金体系
Workspacesの料金体系は、`月額料金`または`時間料金`の課金オプションの選択となっています。
※詳しくはこちら↓
https://aws.amazon.com/jp/workspaces/pricing/

しかし、月額料金/時間料金の切り替えに関する資料がどこにあるか分かりづらい。

# 切り替え方法

マネジメントコンソールWorkSpacesページで設定変更したいWorkSpaceを選択し、
アクションボタンから**実行モードプロパティの変更**をクリックする。
![スクリーンショット 2020-06-03 12.26.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251648/ad2b4e11-6ecc-48d5-98cb-8cb8265f9569.png)

すると以下のようなモーダルが表示され、AlwaysOn/AutoStopの選択ができる。
どうやら**実行モードプロパティ**の切り替えによって、月額料金/時間料金の切り替えが可能なようである。

![スクリーンショット 2020-06-03 12.17.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251648/5ff519d7-71fa-b0eb-fda7-827cf578135e.png)