OmniAICreator/Qiita-1.07M huggingface dataset:
Kaggle超入門 Contributorになる#1

# はじめに

Kaggle超入門シリーズ　第三弾です。
書籍「データサイエンスの森　Kaggleの歩き方」を読みながらメモになります。
過去の記事は以下になります。

* [Kaggleでユーザー登録するまで](https://qiita.com/makaishi2/items/0d9ca522733a6d9b1ca8)
* [Kaggle超入門](https://qiita.com/makaishi2/items/bfb28cd785b0b0863e4a)

(細かいのですが、この書籍、本全体でContributorのスペルをContributerと間違えているようです。。。)

# 必要条件の確認
最初に改めて、Contributorになるための条件を確認しておきましょう。左のメニューから「More」「Progression」

<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/641f28b0-d240-c199-0090-2b9b8e296aec.png' width=800>

少し下にスクロールします。

![スクリーンショット 2022-03-21 10.09.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/dde82159-0fee-79f1-d332-fe6cd9a245b1.png)

どうやら。私の場合、ユーザー登録時に連携したGoogle Acount側でいくつかの設定をしていたため、いくつかの条件は事前にクリアされていたようです。この部分に関しては、多少想像を交えての説明になります。

# プロフィールの完成
私の場合、Googleアカウントの情報で、最初からOKだったので、どこまでが必須入力だったかはわからないのですが、編集するためには下記のホーム画面で右上の自分のリンクをクリック」し

<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/d3249e8c-1894-58ef-d1ad-07484d7649a9.png' width=800>

下の画面で、Edit Public Profileをクリックします。

<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/e355aa8e-7389-0ec0-848c-f701fccf73da.png' width=800>

下の画面になります。私はせっかくなので、GitHub userid, Twitter userid, LinkedIn URLを追加しておきました。

<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/f82100f9-d472-76f0-c628-020584fe8e74.png' width=800>

# engaged with the community
現時点でこれが何を意味するかからわかっていません。今後調査予定です。

# fully explored Kaggle's platform
こちらも現時点で不明。時間のあるときに調べます。

# Run 1 notebook or script
これは因果関係がはっきりしていて、[Kaggle超入門](https://qiita.com/makaishi2/items/bfb28cd785b0b0863e4a)の中で、チュートリアルの問題を解いたからですね。
一番簡単にクリアするためには、この記事で紹介した問題に対して、コピペで解答するといいかもしれないです。


# Make 1 comment

次の"Make 1 competition submission"は手強いのでいったん後回しにします。

フォーラムの議論に何かコメントを入れるということのようです。
この一番上の記事が人気がありそうです。この記事の``comment``のリンクをクリックします。

<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/e0295c5b-5dbd-9674-3491-7f73bf124ee5.png' width=800>

他の人のコメントを見習って、「素晴らしい！」というコメントをあげておきます。

<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/3eb173dc-a7a2-4ef1-357b-931795c7cf71.png' width=800>

こんなふうに最新コメント欄に自分の名前が表示されれば成功です。

<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/d2d1934c-0cd0-72c3-f1da-51f1460d9eee.png' width=800>


# Give 1 upvote
こちらは、フォーラムの議論に投票をすればいいです。
例えば、下記の画面で、右側の上矢印ボタンをクリックすればOKです。


<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/ceb5d211-96d3-fe1d-f488-b438f469c014.png' width=800>

この段階で、ホーム画面右上を確認すると、下の図のように、あと一つの状態になっていると思います。

<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/0d229367-6c2f-7620-7278-9952fe9cd677.png' width=400>

いよいよ最後のステップですが、手順が長いので別記事にします。
リンクは[Kaggle超入門 Contributorになる#2](https://qiita.com/makaishi2/items/0a22ea0299ac1f63b437)です。
WSL2 + Docker + MinGWで、自動でhello worldをWindows用にクロスコンパイルする方法


# 3行で説明

面倒なクロスコンパイル、なんとかしたいですよね。
そこでscriptを書きました。コマンドプロンプトに貼ってENTERで3分放置すればクロスコンパイル完了です。
```bat
curl.exe -L https://raw.githubusercontent.com/cat2151/wsl2-docker-mingw-hello/main/WSL2_docker_mingw_hello.bat --output WSL2_docker_mingw_hello.bat && WSL2_docker_mingw_hello.bat
```

# この記事の対象読者
以下に興味のある方。何かの参考になれば幸いです。
- WSL2, Docker, Docker Hub, MinGW
- C/C++ソースコードをクロスコンパイルしてWindows用exeを作成
- Windowsでgcc
- Dockerなので環境を汚さないし、高速にビルド（10秒）
- GitHubからcurlしたscriptで非対話的にビルドを実行

# このscriptは何を実現するの？
- 以下を自動化します :
  - docker-mingw-w64 を Docker Hubから得る
    - これはgcc系のC/C++ソースからWindows用exeをビルドできる仕組みです
  - docker-mingw-w64 用の build.sh を得る
    - ユーザーが任意に作れる build.sh の参考用に、hello worldを提供します
  - hello worldをクロスコンパイルする
    - これはWindowsで動作するexeです
      - Dockerで動くUbuntu上でmingwによりクロスコンパイルされて出力されます
  - hello worldをWindows上で実行し、結果を得る
  - 上記すべてのログを出力する

- 環境を汚さないため、手軽に扱えます。
- コマンドプロンプトから1行のコマンドを実行するだけで自動ですべてが完了します。面倒な操作は不要です。

# docker-mingw-w64とは？
Linuxコンテナ上でクロスコンパイルしてWindows用exeを作る仕組みです。

[GitHub docker-mingw-w64](https://github.com/mmozeiko/docker-mingw-w64)
[Docker Hub mingw-w64](https://hub.docker.com/r/mmozeiko/mingw-w64)

Windowsで動かすには、コマンドのpwd部分を書き換える必要があります：
- PowerShell用
```bat
docker run --rm -ti -v "$($pwd.Path):/mnt" mmozeiko/mingw-w64 ./build.sh
```
- bat用
```bat
docker run --rm -ti -v %CD%:/mnt mmozeiko/mingw-w64 ./build.sh
```
- MSYS2/Cygwin用
```bat
docker run --rm -ti -v $(cygpath -w $(pwd)):/mnt mmozeiko/mingw-w64 ./build.sh
```

# さらに詳しく
GitHubをご参照ください :
[WSL2 docker mingw hello](https://github.com/cat2151/wsl2-docker-mingw-hello)

# 関連記事
[MSYS2のダウンロードとインストールを自動で行う方法](https://qiita.com/cat2151/items/a93d2243b8eb62465a51)
[Cygwinのダウンロードとインストールを自動で行う方法](https://qiita.com/cat2151/items/38fe897378ef91b584d6)
S3に画像をアップロードしようとしたら、Client error: `PUT https://~~~~~~.s3.ap-northeast-1.amazonaws.com/WHdo4kayM4bV.png` resulted in a `400 Bad Request`というエラーが発生した

## S3に画像がアップロードできない

先日S3に画像をアップロードしようとしたら以下のようなエラーが発生した

``` laravel.log
Client error: `PUT https://~~~~~~.s3.ap-northeast-1.amazonaws.com/WHdo4kayM4bV.png` resulted in a `400 Bad Request` response:
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessControlListNotSupported</Code><Message>The bucket does not all (truncated...)
 AccessControlListNotSupported (client): The bucket does not allow ACLs - <?xml version="1.0" encoding="UTF-8"?>
```

「The bucket does not allow ACLs」とあるので、S3のアクセスコントロール設定を見直してみることにした。

## 解決策

結論、以下の流れで解決できました。

S3 > バケット選択 > アクセス許可 > オブジェクト所有者のACL設定を無効から有効へ変更 > 変更の保存
Chakra UIで平行四辺形を作る方法

## 結論
transform: skew　を使う。

## 実践
実際に書くとこんな感じになる。
   ``` 
<Box width={"50%"} transform={"skewX(-40deg)"} m={10} border="solid">
     <Text fontSize={"20px"}>こんな感じ</Text>
</Box>
 ```
![スクリーンショット 2022-03-21 12.18.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933740/4a98116d-0b17-7e36-dff3-e070f11b2e58.png)

## 中身は傾いてほしくない時
上記の例では、中のテキストまで傾いてしまっている。
これを改善するためには、テキストに逆の傾きを与えてあげれば良い。
```
 <Box width={"50%"} transform={"skewX(-40deg)"} m={10} border="solid">
        <Text fontSize={"20px"} transform={"skewX(40deg)"}>
          まっすぐ表示される〜
        </Text>
 </Box>
```
![スクリーンショット 2022-03-21 12.26.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/933740/abe4b087-d1f2-1269-fc2f-e5e97e8eee2f.png)


## おまけ
サンプルを作ったので置いときます。

https://codesandbox.io/embed/parallelogram-sample-g5kq4p?fontsize=14&hidenavigation=1&theme=dark
Xcode 5でSpriteKitのSKTextureAtlasを使用する

SwiftUI ベースのプロジェクトで SpriteKit の SKTextureAtlas を使用したかったのですが、プロジェクトに ".atlas" サフィックスのフォルダを作成し、コンパイル時にアトラスを生成させる方法ではできなかったので、調査しました。

https://developer.apple.com/documentation/spritekit/sktextureatlas/about_texture_atlases

結論から述べますと、アセットカタログ (Assets.xcassets) に作成したフォルダをアトラスとして使用できます。

具体例を示します。次の通りにアセットカタログに "cat" フォルダを作成し、猫が歩くアニメーションのフレーム画像 (cat-walk.0 〜 3) を保存します。

```text
Assets.xcassets
├─AccentColor
├─AppIcon
└─cat
  ├─cat_walk_0
  ├─cat_walk_1
  └─cat_walk_2
```

ソースコードで、`SKTextureAtlas` の `named` 引数に作成した "cat" フォルダの名前を指定し、インスタンスを生成します。インスタンスの `textureNamed` メソッドを使用すると、同フォルダに保存したフレーム画像をアトラス内の名前付きテクスチャとして参照できます。

```swift
import SpriteKit

let atlas = SKTextureAtlas(named: "cat")
let textures = [
    atlas.textureNamed("cat_walk_0"),
    atlas.textureNamed("cat_walk_1"),
    atlas.textureNamed("cat_walk_2"),
]
```

アトラスの名前はフォルダの名前ですが、半角英数字のみ (?) で指定しなければいけないようです。フォルダの名前に ". (ドット)" を含む場合は、一番最初の "." より手前の文字までをアトラスの名前として認識しました。又、フォルダの名前に "- (ハイフン)" を含む場合は、アプリケーションが異常終了しました。
DynamoDB Global Tables 概要

## 概要

* DynamoDB のリージョンレベルでのレプリカテーブルを作成する機能。

* アプリケーションがあるリージョンのレプリカテーブルにデータを書き込むと、DynamoDB は書き込みを他の AWSリージョンのレプリカテーブルに自動的に伝播する。

  ![dynamodb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586535/4f262589-82f2-6011-0348-c579ff0ed3d5.png)
 

## 利点

* **ローカルの読み取りと書き込みで、グローバルなデータアクセスができる。**

  * あるリージョンで発生した更新が他のリージョンにも伝播し、最終的に全リージョンのデータの一貫性が保たれる。

    ＝世界各地に分散しているアプリケーションそれぞれでローカルにアクセスされるテーブルが最新の状態が保たれる。

* **パフォーマンス**

  * 1 桁ミリ秒のレイテンシーで提供される。

## 新しいレプリカテーブルを追加するための要件

新しいレプリカテーブルをグローバルテーブルに追加するには、以下の全ての条件を満たす必要がある。

- その他すべてのレプリカと同じパーティションキーがテーブルに含まれている。
- テーブルは、同じ指定した書き込みキャパシティー管理設定とする。
- テーブル名が、その他全てのレプリカと同じ名前である。
- 項目の新しいイメージと古いイメージの両方を含むストリーミングで、テーブルの DynamoDB Streams が有効になっている。
- このグローバルテーブルの新規または既存のレプリカテーブルにデータが含まれていない。

## CloudWatchモニタリング

* **`ReplicationLatency`**
  * 更新された項目が1つのレプリカテーブルの DynamoDB ストリームに表示されてから、その項目がグローバルテーブルの別レプリカに表示されるまでの時間。
  * ミリ秒単位で表し、すべての送信元リージョンと送信先リージョンのペアに対して出力される。 
* **`PendingReplicationCount`** 
  * 1 つのレプリカテーブルに書き込まれているが、グローバルテーブル内の別のレプリカにはまだ書き込まれていない項目の更新数。
  * 項目数で表し、全送信元と送信先のリージョンのペアに対して発行される。





## AWS CLIを用いた作成方法

### 作成

1. DynamoDB Streams を有効にして米国東部 (オハイオ)に新規テーブル (`Music`)を作成する。

   ```shell
   aws dynamodb create-table \
       --table-name Music \
       --attribute-definitions \
           AttributeName=Artist,AttributeType=S \
           AttributeName=SongTitle,AttributeType=S \
       --key-schema \
           AttributeName=Artist,KeyType=HASH \
           AttributeName=SongTitle,KeyType=RANGE \
       --billing-mode PAY_PER_REQUEST \
       --stream-specification StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES \
       --region us-east-2
   ```

2. 米国東部 (バージニア北部) に同じ `Music` テーブルを作成する。

   ```shell
   aws dynamodb update-table --table-name Music --cli-input-json  \
   '{
     "ReplicaUpdates":
     [
       {
         "Create": {
           "RegionName": "us-east-1"
         }
       }
     ]
   }'
   ```

3. ステップ 2 を繰り返して、欧州 (アイルランド) (eu-west-1) にテーブルを作成する。

### 動作確認

1. 作成されたレプリカのリストを表示する。

   ```shell
   aws dynamodb describe-table --table-name Music --region us-east-2 
   ```

2. 新しい項目を米国東部 (オハイオ) の `Music` テーブルに追加し、レプリケーションが機能していることを確認する。

   ```shell
   aws dynamodb put-item \
       --table-name Music \
       --item '{"Artist": {"S":"item_1"},"SongTitle": {"S":"Song Value 1"}}' \
       --region us-east-2
   ```

3. 項目が米国東部 (バージニア北部) および欧州 (アイルランド) に正常にレプリケートされたかどうかを確認する。

   ```shell
   aws dynamodb get-item \
       --table-name Music \
       --key '{"Artist": {"S":"item_1"},"SongTitle": {"S":"Song Value 1"}}' \
       --region us-east-1
   ```

   ```shell
   aws dynamodb get-item \
       --table-name Music \
       --key '{"Artist": {"S":"item_1"},"SongTitle": {"S":"Song Value 1"}}' \
       --region eu-west-1
   ```

   

## 参考情報

* [Amazon DynamoDB グローバルテーブル](https://aws.amazon.com/jp/dynamodb/global-tables/)
* [DynamoDBグローバルテーブルを作成して異なるリージョン間での同期を確認してみた](https://dev.classmethod.jp/articles/dynamodb-global-table-creating/)
家庭内ネットワークセグメント間でRDPのみ許可してみた

# はじめに
我が家では家庭内に2つのネットワークセグメントがありますが、これまでセキュリティの観点からセグメント間の通信はできないようにしていました。

そんな中、一部のPC間のみRDPだけ通す必要がでてき、当初ルータの静的ルーティングだけすれば実現できると思っていたのですが、それだけでは実現できず地味にハマったので備忘として実施したことを残しておこうと思います。

※ネットワークについては基礎用語を知っている程度の素人なので、考え方・設定の仕方に誤りがあれば是非ご指摘いただけると幸いです。


# ネットワーク構成
変更前のネットワーク図です。
「有線セグメント」と「WiFiセグメント」を分けています。

この度、
　PC-Note1　→　PC-desktop1 
へRDP接続する必要がでてきたので、それを実現したいというのが要件です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1955406/9e50963b-d363-1824-492d-ebf299347f4a.png)

※補足
　ルータA：TP-link
　ルータB：NEC（Aterm）
　PC：全てWindows


# やったこと
## １．各機器のIPを固定

各セグメント内のIP、ルータの外側IPはDHCP/自動割てでIPが設定されていますが、RDP、静的ルーティングをするために必要最低限の機器のIPは固定しておく必要があるので、以下の機器のIPを固定しました。

- RDPアクセス元PC（Note1）のIP
- RDPアクセス先PC（Desktop1）のIP
- ルータBの外部IP

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1955406/23d6d6d7-2a72-9354-4c9f-ccf12acdda17.png)


## ２．静的ルーティング
「WiFiセグメント」から「有線セグメント」への通信はルータBに飛ばしあげる必要があるので、ルータAに静的ルーティングを設定しました。

＜設定内容＞
192.168.11.0/24  GW 192.168.1.30

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1955406/4b3a8eb0-4944-f6ba-1f14-bf07c9131365.png)


## ３．ルータのIPフィルタ設定
ここがかなりハマったところなのですが、ルータでは外から内の通信は原則遮断されているので、外から内へ通信するためには通信を許可する必要がありました。
設定方法についてはルータによって異なるものだと思いますが、Atermルータでは「IPフィルタ」機能で該当の通信を許可しました。

＜設定内容＞
- 方向：In
- プロトコル：TCP
- 送信元：192.168.1.5
- 送信元ポート：any
- 宛先：192.168.11.5
- 宛先ポート：RDP用ポート

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1955406/bce23926-8a6f-1e52-08d4-b18a9b8950ed.png)

## ４．セキュリティソフトFW設定
ルータBのIPフィルタ設定で通信を許可することで、有線セグメントのGWにPingが通るようになった（※）ので「いけた！！」と思っていたのですが、ここからも長い戦いでした。。
（※）疎通確認時は宛先ポートはanyとして確認した

GWにPingは通るが、Desktop1にはPingは通らない（RDPもダメ）。
考える限りルータ側の設定は問題ないはずなので、問題は有線セグメント内のことだと当たりをつけ考えていたところ閃きました。

「PC側にFWあるやん。。。」と。

まさしくこれが原因で、Desktop1にインストールしているセキュリティソフト（この端末はESET Internet Security）のFWで、Note1からのRPD通信を許可してあげると無事RDP接続できるようになりました。

＜設定内容＞
- 方向：In
- プロトコル：TCP/UDP
- 宛先ポート：RDP用ポート
- 接続元IP：192.168.1.5

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1955406/4a9a8fd5-59d6-d0fa-606b-1f0fdb62d401.png)

## Tips
- 疎通確認には Windows標準コマンドの「tracert」と「Ping」で確認していたのですが、両コマンドともポートを指定できるものではないので、IPフィルタ/FW設定絡みで疎通確認をすることはできません。
ポートを指定して疎通確認をする場合は、PowerShellの「Test-NetConnection」コマンドを使うとポートが指定できるのでとても便利です。
　```Test-NetConnection [ターゲット] -Port [ポート番号]```

# 最後に
無事やりたいことができて良かったですが、自分のネットワーク知識の無さに危機感しか感じない現状を目の当たりにしたので、専門職の方とお話しできる程度には基礎知識をつけていこうと思います。
Codeigniter のPOST処理で独自ルールを活用して文字を全角に変換する

CodeigniterのPOST処理を行う際に
```php
$this->form_validation->set_rules
```
などでルールを定め、バリデーション処理を行うと思うのですが
その際に以前から文字を変換する作業も一緒に行いたいと考えてました。

公式のサイトを読み漁ったのですが、それらしき利用方法は見つからず諦めていた際に
偶然方法を自分で見つけたのでこちらに記載し共有させて頂きます。

# 方法

独自ルール関数のreturnをbool型ではなく、セットしたい内容にするだけ。
以上になります。

# 具体的なやり方

libraries以下に「CI_Form_validation」をextendsした独自クラスを追加
そのクラス内に文字を全角にしてセットしたい場合は下記の関数を追加
```php
function cv_zenkaku($str)
{
  return mb_convert_kana($str, 'RNAKH'); // 全角に変換
}
```


コントローラーでそのクラスを呼び出します。
```php:クラス名は例
$this->load->library(array('my_form_validation'));
```


その後、変換したいPOSTでrule設定を行います
```php
$this->form_validation->set_rules('test1', 'テスト', 'cv_zenkaku');
```


その後、
```php
$this->form_validation->run()
```

を実行するとPOSTの中身が入力の際に半角文字列を入力していても、全角文字に変換されていることが確認できると思います。

# 最後に

この方法を活用すると、全角文字の入力が必須だった場合。ユーザーに再度入力させる手間を減らすことが出来るので便利かと思います。

# 確認したバージョン

```
3.2.0-dev
```
Unity C#のstatic,const,private,public

![SS 192.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/a41cd967-f549-8677-1efa-2e99bf69518d.png) じぶん用のメモ。まちがっているかも。更新中。


# UnityのC#で変数を宣言するときのメモ

## const

・変化しない値を定義する時に使用。
・宣言時に値を代入する必要がある。
・コンパイル時に定数（固定の数値）として扱われる。
・つまりコードの中で書き換えを指定できない。
・static readonly とだいたい同じ。（違いは[こちらの記事](https://qiita.com/ShirakawaMaru/items/97545b40202bb6ba2ca4)を参照。）

## static
・メモリを静的に確保。メモリ領域が静的なだけなので、数値は動的に変更できる。
・Unityではアプリケーションにただ１つだけ生成する変数。（インスタンス単位の生成ではない）
・どこからでも参照できる。
・ゲームのスコアなど、１個しかないパラメータに使う。

## public（アクセス修飾子）
・アクセス制限なし。もっともゆるい。どこからでも参照できる。
・外部から[クラス名].[変数名]で取得できる。
・Unityのインスペクターに表示される。
・public static 〜 とするとインスペクターには表示されなくなる。
　（理由はインスペクターが担当するインスタンスに紐づかなくなるから？）

## private（アクセス修飾子）
・同じ class 内または同じ struct 内のコードからのみアクセスできる。
・private関数にアクセスするときはプロパティを使う。
・[SerializeField] をつけておくとインスペクタ上から操作できる。

## プロパティを利用したprivate変数へのアクセス
```C#:X_sample.cs
using UnityEngine;
using System;

public class X_sample : MonoBehaviour {
private int x = 1;
public int X{
        get{
            return x;
        }
        set{
           x = value;
       }
    }
}
```
のようにすると、外部からprivate int xの値を
a = X_sample.X;
のように取得することができ、

X_sample.X = 10;
のように書き込みができる。

#参考記事
- [【Unity】よく出てくるprivate, public, static,[SerializeField]についてまとめてみた！](https://turedureengineer.hatenablog.com/entry/2018/10/01/124330)
- [C#-constとstatic readonlyの違い](https://qiita.com/ShirakawaMaru/items/97545b40202bb6ba2ca4)
Raspberry Pi 4に外付けSSDにUbuntu Server 入れたときの注意点

# なにがあったか
microSDから起動だと故障のリスクが高いのでSSDからの起動するようにした。
サポートのことを考えて"Ubuntu Server 20.04.4 LTS"を選択したが、外付けSSDからの起動ができなかった。
どうやら、ブートにバグがあるらしくただインストールするだけでは起動できないらしい。

# 解決策
"Ubuntu Server 21.10"を使う。
サポート期間が短いが、ブートのバグが解消されているらしく起動が確認できた。
Rundeckのインストール手順

EC2にrundeckをインストールするため、一度自分の端末で試しに仮想環境を立てrundeckインストールしてみました。
（人生初めての技術記事投稿のため、生温かい目で見ていただけると幸いです！）

# rundeckインストールのコマンドまとめ

```
//rundeckインストールに必要なスクリプトをもってきてそのままbashで実行
//'/dev/null'は出力先として指定すると何も起こらないし、入力元として指定しても何も入ってこない
curl https://raw.githubusercontent.com/rundeck/packaging/main/scripts/rpm-setup.sh 2> /dev/null | sudo bash -s rundeck
//rundeckインストール（※上記のコマンドを実行してもインストールされていなかったため）
sudo yum update rundeck
//rundeck起動
sudo service rundeckd start
//起動しているか確認のため、ログの際終業から数行を出力
//（※もし"Grails application running at ~"という文字が出力されたらrundeckの起動OK）
tail -f /var/log/rundeck/service.log
//java確認
java -version
//（※以下のようにOpenJDKのバージョンが表示されればOK）
//openjdk version "1.8.0_312"
//OpenJDK Runtime Environment (build 1.8.0_312-b07)
//OpenJDK 64-Bit Server VM (build 25.312-b07, mixed mode)
```

# 参考資料

【rundeckの公式ドキュメント】
https://docs.rundeck.com/docs/administration/install/linux-rpm.html#installing-rundeck

【docker-composeで開発環境作成しVSCodeで接続】
https://dev.classmethod.jp/articles/amazon-linux-2-docker-aws-cli-visual-studio-code/
（→本記事とは関連が薄いですが、もしEC2で何かやりたいということがあれば上記記事で仮想環境立てていじってみると良いかもです！）
Nuxt.jsでルーティング

# ルーティング

Nuxt.jsはpagesディレクトリ配下にフォルダ作ってそこにindex.vue設置して上げると自動的にルーティングしてくれます。
便利便利。

### ディレクトリ作成→中にindex.vue配置
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201311/80c7b130-baa9-25d6-bfd4-acdbd808ec6e.png)
こんなかんじで、プロジェクト生成時、デフォルトで生成される`[PROJECT]/.nuxt/pages`配下にnewPageをディレクトリを作成します。（.nuxtは隠しフォルダなので注意）
index.vueを作成します。

```vuejs:./newPage/index.vue
<template>
    <h1>
      NewPage
    </h1>
</template>
```
newPageに作ったindexの中身です。とりあえずタイトルだけ表示させやす。

### 動作確認
`$ npm run dev`
run dev で確認して見ます。
↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201311/958d5dad-d336-c916-09e4-a5192694bac2.png)
できましたね。

### 補足
ルーティングの設定は、`[PROJECT]/.nuxt/router.js`の`routerOptions`にオブジェクトとして格納されいます。この中身もいつか詳しくやりたい。
```javascript:router.jsのrouterOptions抜粋
export const routerOptions = {
  mode: 'history',
  base: '/',
  linkActiveClass: 'nuxt-link-active',
  linkExactActiveClass: 'nuxt-link-exact-active',
  scrollBehavior,

  routes: [{
    path: "/newPage",
    component: _f8688520,
    name: "newPage"
  }, {
    path: "/",
    component: _971975a0,
    name: "index"
  }],

  fallback: false
}
```
本日の基礎練習問題(22/3/21)

**問題**
3桁の正の整数を入力します。その整数の「百の位・十の位・一の位の和」について、
10の倍数（0,10,20,30...）からの差が
・2以内であるときは"True"
・それ以外は"10の倍数との差は○です"
と表示されるようにしましょう。

出力例：
near_ten(117)→True
near_ten(123)→10の倍数との差は4です
near_ten(111)→10の倍数との差は3です
0も10の倍数に含むものとします。

百の位・十の位・一の位の和が6などの時に、「10の倍数との差は6です」と出力せずに、「10の倍数との差は4です」と10の倍数から近い方の差を出力するようにしてください。

# 私の回答
```
def near_ten(num)
 total = (num/100) + (num/10%10) + (num%10)

end
```
# 解説
時間制限で百の位・十の位・一の位の和だけしか記述できなかった。

# 模範回答
```
def near_ten(num)
  total = (num/100) + (num/10 % 10) + (num % 10)
  remainder = total % 10
  if remainder <= 2 || remainder >= 8
    puts "True"
  elsif remainder <= 5
    puts "10の倍数との差は#{remainder}です"
  else 
    puts "10の倍数との差は#{10 - remainder}です"
  end
end
```
# 模範解説
(num/100) + (num/10 % 10) + (num % 10)によって、百の位・十の位・一の位をそれぞれ足し合わせています。

num/100（百の位）
2桁の整数を100で割った値が百の位になります。
num = 117の場合、num/100 つまり117/100は1.17となります。
Rubyでは整数同士（integer型）の計算だと返り値は整数になるので、小数点以下は切り捨てられて「1」になります。
そのため、百の位の取得は、3桁の数字を100で割るだけで可能となります。
よって、百の位は「1」となります。

num/10 % 10（十の位）
2桁の整数を10で割り、その値を10で割った際の余りが十の位になります。
num = 117の場合、117/10は11.7になります。整数同士は小数点以下の計算は行わないので、11になります。
11 % 10 は、11を10で割った際の余りを計算結果として返します。百の位の計算と同様に、小数点以下の計算は行わないので、余りは1となります。
よって、十の位は「1」となります。

num % 10の場合（一の位）
2桁の整数を10で割った際の余りが一の位になります。
num = 117の場合、117 % 10 は、117を10で割った際の余りを計算結果として返します。百の位の計算と同様に、小数点以下の計算は行わないので、余りは7となります。
よって、一の位は「7」になります。

8行目のelseのポイントは、「百の位・十の位・一の位の和が6または7に該当する場合は、10から差し引いて、10の倍数との差分を導出する必要がある」という点です。

# 感じたこと
なんとか各桁の和は記述することができたが、その後の差の部分の記述ができなかった。
またrubyでは整数同士（integer型）の計算だと返り値は整数になり小数点は切り捨てられることは知らなかったので
ここで学べてよかった。
位の計算はよくある計算だと思うのでしっかりと理解し覚えていきたい。

アドバイスやご指摘等ございましたらぜひお願いします！

以上
折れ線グラフの作成（seaborn,matplotlib）

# はじめに
Python、pandas、matplotlib、seabornを使って気象庁からデータを取得し
平均気温、降水量、日照時間の折れ線グラフを作成します。
気象庁のHPから、好きな地域のCSVファイルをダウンロードしておきます。

## 完成形の確認
以下のようなグラフが本記事のゴールです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2544095/97affb80-c3ca-be8c-ab65-2b11b222daf9.png)

最終的なコードは以下の通りです。
```
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib.font_manager

df_weather = pd.read_csv('weather_sample.csv',encoding="SHIFT-JIS", index_col='日付',parse_dates=True)
df_weather = df_weather[['Unnamed: 1','Unnamed: 4','Unnamed: 8']][4:]
df_weather = df_weather.set_axis([ '平均気温(℃)','降水量の合計(mm)', '日照時間(時間)'], axis=1)
df_weather = df_weather.astype('float64').head(30)

sns.set(font='MS Gothic',context='talk')
plt.figure(figsize=(40,10))
plt.xticks(rotation=45)
sns.lineplot(data=df_weather)
```

## ライブラリのインポート
必要なライブラリをインポートします。
```
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib.font_manager
```

## csvファイル読み込み~データ整形
気象庁のHPからダウンロードしたCSVファイルを読み込みます。（ここではweather_sample.csv）
文字コードの指定　→　encoding="SHIFT-JIS"
indexとするcolumn名指定　→　index_col='日付'
indexをdatetime型に変換　→　parse_dates=True


```
df_weather = pd.read_csv('weather_sample.csv',encoding="SHIFT-JIS", index_col='日付',parse_dates=True)
df_weather = df_weather[2:]
df_weather
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2544095/90b6730c-2314-5d43-7213-36eb428e5730.png)
平均気温、降水量、日照時間に該当するcolumn名を抽出した上でcolumn名を変更する（平均気温、降水量、日照時間）
set_axisメソッドで全ての列名、行名を変更
行名　→　axis=0
列名　→　axis=1
object型からfloat型へキャスト　→　df_weather.astype('float64')
```
df_weather = df_weather[['Unnamed: 1','Unnamed: 4','Unnamed: 8']]
df_weather = df_weather.set_axis([ '平均気温(℃)','降水量の合計(mm)', '日照時間(時間)'], axis=1)[2:]
df_weather = df_weather.astype('float64')
```

## グラフ化

```
sns.lineplot(data=df_weather)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2544095/42f688be-5591-8f5c-6908-2e388becfe77.png)

サイズが小さかったり、日本語表示されていないので修正
### フォント修正
自分の環境で使用できるフォントを確認
グラフの文字サイズ変更　→　context='talk'
大きさの順番　→　paper < notebook < talk < poster
デフォルトはnotebook
```
print([f.name for f in matplotlib.font_manager.fontManager.ttflist])
sns.set(font='MS Gothic',context='talk')
sns.lineplot(data=df_weather)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2544095/a652a07b-9e5f-2e0f-94e9-8381dc744a03.png)

### グラフの大きさ、日付の傾き修正
グラフの大きさ変更　→　plt.figure(figsize=(40,10))
日付の傾き変更　→　plt.xticks(rotation=45)
```
plt.figure(figsize=(40,10))
plt.xticks(rotation=45)
sns.lineplot(data=df_weather)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2544095/2a8e75ec-8451-eef6-9096-314d59b2a08a.png)

## 学んだこと
①文字コードを指定しないとエラーが発生する場合があること。
②型の確認。
　グラフ表示はobject型だとできなく、float型等へキャストが必要で、都度型確認をしたほうが良い
AWS Robot Delivery Challenge 2022 に出場できなかった話 : 最適経路

概要を読んでいない方は先にこちらを読んでください！
[目次のページ](https://qiita.com/KyoBashi/items/153aff5ce8af7111b537)

## はじめに
![](https://i.imgur.com/oGCcepZ.png)

今回は上図のcsv_path_dataの部分について説明します．
ロボットの経路生成には最適制御を用いました．様々な制約を考慮しつつ，評価関数を最小化することで設定した目的を達成できるためです．また，得られた最適経路情報はcsvファイルに保存しました．今回は最適制御による経路を事前にオフラインで保存するため，計算時間を考える必要がなかったので，特にモデル化において線形化などを行わず非線形最適制御問題を解きました．

## 最適制御とは
ある連続時間システム $\dot{x}(t) = f(x(t), u(t), t)$ を考えます．
そのとき，最適制御問題は以下のように定式化されます．
$\min \hspace{5pt} 
J = \int^{T}_{0} L\left({x}\left(t\right), {u}\left(t\right), t\right) d\tau$

$\rm{s.t.}$　$\hspace{1pt} \dot{{x}}(t) = f({x}(t), {u}(t), t)$
$\hspace{30pt} g({x}(t), {u}(t), t) = 0$
$\hspace{30pt} h({x}(t), {u}(t), t) \leq 0$

## 車両制御への応用
今回は，コンテストで用いる（予定だった）車両ロボットTURTLEBOT3 Burgerに対して最適制御問題を解きます．
車両の座標を($x$,$y$)，角度を$\theta$，車両への速度入力を$v$，角速度入力を$\omega$とします．すると，車両モデルの状態方程式は，状態ベクトルを $\boldsymbol{x}=\left[x,y,\theta\right]^\top$， 入力ベクトルを$\boldsymbol{u}=\left[v, \omega\right]^\top$とおくと， 
$$
\dot{\boldsymbol{x}}=\frac{d}{d t}\left[\begin{array}{c}x, y, \theta\end{array}\right]^\top =\left[\begin{array}{c}v\cos\theta,v\sin\theta, \omega \\ \end{array}\right]^\top
$$
と表されます．

そして，始点から終点まで最短で移動したいので，移動時間を最小化する問題を考えます．また，角速度の急激な変化は好ましくないため，角速度の分散も評価関数に加えました．
したがって，今回の問題設定において最適制御問題は以下のように定式化されます．
<img width="200" alt="qiita_continual_optimal.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448229/2c4f2158-5440-40bc-ef31-b4ec0daf70dc.png">


これを解くために，十分大きい$N$を用いて以下のように離散化します．

<img width="400" alt="qiita_discretisized_optimal.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448229/ac7ea124-06f9-6169-1846-834fcf4a6b60.png">

また，今回は自動微分・最適化ライブラリCasADiを用いてこの非線形最適制御問題を解きました．

その結果を下に示します．
状態軌道が滑らかで，拘束条件を守りつつ，移動時間と角速度の分散を最小化していることがわかります．

### ロボットの状態軌道
![](https://i.imgur.com/NBh54mb.png)

### ロボットの速度入力と角速度入力の系列
![](https://i.imgur.com/mhHpHpc.png)

## 参考文献
* 大塚敏之，非線形最適制御入門 コロナ社，2011．
* https://web.casadi.org/
AWS Robot Delivery Challenge 2022 に出場できなかった話 : 黄金探索

概要を読んでいない方は先にこちらを読んでください！
[目次のページ](https://qiita.com/KyoBashi/items/153aff5ce8af7111b537)
## 黄金探索とは
ロボットの目標位置を定めるためのアルゴリズムです。
現時点で自分がいる座標（自己位置推定により導いた座標）と、あらかじめ計画された経路を用いてリアルタイムで目標位置を決定します。

## アルゴリズム
この記事を参考にしました。
https://naoyat.hatenablog.jp/entry/2012/01/04/231801

## 全体としての位置付け
![](https://i.imgur.com/IFjlRDp.png)



## 実装
1. ダイクストラ法で導いた経路の情報を受けとる。
2. 経路上の離散化した座標群の中で、ロボットに一番近い点を黄金探索で探索する。
3. 探索で得た点の少し先の経路上の点をロボットの目標位置として金山制御に渡す。
![](https://i.imgur.com/MPd7TFL.png)
JavaScriptが画面をリロードしないと表示できない問題を解決

# はじめに
１月〜プログラミングスクールで学習しています。
これから平日は~3/25まで毎日何かしらアウトプットのため投稿を続ける予定です。
今回はオリジナルアプリ作成時に起きたJavaScriptが画面をリロードしないと表示できない問題について書きます。
※Ruby2.6.5の環境を使用し学習しています。

# 問題
自動計算機能をjavascriptで実装しましたが、何故かリロードしないとうまく機能しません。
![a2cbd6e59b6113689b8c4dd1ca09d2c7.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2515603/41148a66-91f7-13ee-45ca-32444d5c7914.gif)

# 解決方法
どうやら`turbolinks`が原因となっていたようです。
application.jsのturbolinksを読み込んでいる行を削除することで上記の問題は解決しました。
```JavaScript:app/javascript/packs/application.js
require("@rails/ujs").start()
require("turbolinks").start() //この行を削除
require("@rails/activestorage").start()
require("channels")
```

turbolinksによって画面遷移は高速化しますが、次ページのHTML要素だけを読み取って表示するため、JavaScriptファイルが読み込まれず、JavaScriptにて設定したイベントが発火しないケースがあるようです。
Kaggle超入門

# はじめに
[Kaggleでユーザー登録するまで](https://qiita.com/makaishi2/items/0d9ca522733a6d9b1ca8)の続きです。
書籍「データサイエンスの森　Kaggleの歩き方」を読みながらメモをとっていきます。

# Kaggleで機械学習を学ぶ
書籍　p.50から解説があります。初期画面左の「**Coureses**」をクリックして、後はメニュー階層をどんどんたどっていくと、最後はチュートリアルの画面にたどり着きます。

<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/f73b3d7a-d4e2-fb9d-8ef4-8854ba81766f.png' width=800>

<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/1192f2a8-1f2e-97a6-6321-d4ae7457e3d4.png' width=800>

<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/5a13f5d3-ae13-e0e3-4c52-981e5d1f4e27.png' width= 300>

<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/c8f21dda-7850-d53b-510e-2958ea581487.png' width=500>

チュートリアルのコンテンツはJupyter Notebook形式になっているようです。
チュートリアルの一番最後に「**Exerciseをはじめるか？**」みたいな質問が出ます。

<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/d546a21e-1bf6-4026-13cb-69cd929daeda.png' width=800>

「**Start Exercise**」で答えると、下のような問題用のNotebookになります。

<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/9d3f8e0c-237a-84ba-5a28-d63d7cb64fe8.png' width=800>

で、このセルを下のように書き換えて、Shift+Enterをすると、「**Correct**」となるわけです。

<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/fb11cff7-bd73-79e9-73f0-c18877b0a331.png' width=800>

が、 Pythonの文法を一通り知っていて、「あ、このセルは多分裏でassert機能で正解チェックやっているな」と想像が付く私ですら、正直最初、何をしたらいいか戸惑いました。
Pythonが初めて(かつ私のように英語が得意でない標準的日本人)の人は、わけわからなくなりそうなので、あまりこの機能は使わないことがお勧めかなと思います。

# Kaggleのランキングシステムについて
Kaggleでは、すべての登録ユーザーは「**ランク**」を持っています。初期段階では全員``novice``(初心者)です。コミュニティに対してどういう貢献をすると何ポイントという規定が細かくされていて、ポイントをどんどんためると上のランクに移っていく仕組みです。こういう仕組みを与えられると、一生懸命やりたくなってしまう、人間の本能に根ざした、なかなかニクいシステムだなと第一印象思いました。

では、このランクをどうやって確認できるのかというと、初期画面の右上にランク自体はすでに表示されているのですが、自分のIDのところがリンクになっていて、そこをクリックすると、詳細画面に遷移します。

<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/6b5e57d9-3d23-e0d3-4f71-72a5910fe6ea.png' width=800>

こんな画面ですね。

<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/ab835474-bcb2-63c9-d124-4d74242c5231.png' width=800>

ポイントは、Competitions, Datasets, Notebooks, Discussion の４つのジャンルに分かれているようです。ハマってくると、「Notebooksがポイント足りないからもうちょっと頑張るか」みたいになるのだと想像しました。

では、具体的にどんなランクがあって、そのための条件は何なのか、それを知るためのページが下記のとおり、メニューから「More」「Progression」をクリックした先になります。

<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/cc3cadc5-d6e6-945f-00a8-97451809d3a6.png' width=800>

リンク先を少し下にスクロールすると、Novice, Contributorの定義が出てきます。

<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/811e264e-7a8f-27e0-3048-4475e3cc68d1.png' width=600>


更に下にいくと、Expert, Masterの定義が。

<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206130/46fa2c19-fc44-1a5b-c96e-0700cb020c99.png' width=600>

明らかにExpertは簡単に取れないですね。ということで、まずは「**簡単に達成できそうなContributorをめざそう**」というのが、次のステップになるわけです。このあたりの設定もなかなかニクいですね。

いったん、ここで締めて、次のステップは別記事[Kaggle超入門 Contributorになる#1](https://qiita.com/makaishi2/items/81d0363a37a7441e5caf)で記載することにします。
JavaScript の 論理演算子

JavaScript の論理演算子の書き方についておさらいしてみました。

MDNでは [このページ](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators) に詳しく記述があります。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators


## 論理積( AND )

```javascript
// a & b

const a = 0;
const b = 1;

console.log(a　&　b);
// 0が出力される
```

## 論理和( OR )

```javascript
// a | b

const a = 0;
const b = 1;

console.log(a|b);
// 1が出力される
```

## 否定( NOT )

```javascript
// !a

const a = 0;

console.log(!a);
// 0(false) の否定 = 「true」が表示される

console.log(Number(!a));
// 0(false) の否定である「true」を数値変換 = 「1」が表示される
```


## 排他的論理和( XOR )
```javascript
// a^b

const a = 0;
const b = 1;

console.log(a^b);
// 1が表示される

const c = 1;
const d = 1;

console.log(c^d);
//0が表示される
```

## 否定論理積(NAND)

否定論理積は NOT AND

```javascript
// !(a&b)

const a = 0;
const b = 1;

console.log( !(a&b) );
// trueが表示される

const c = 1;
const d = 1;

console.log( !(c&d) );
// NOT c AND NOT d = falseが表示される

console.log( Number(!(c&d)) );
// 0が表示される

```

## 否定論理和 (NOR)

否定論理和は NOT OR

```javascript
// !(a|b)

const a = 0;
const b = 1;

console.log( !(a|b) );
// falseが表示される

const c = 0;
const d = 0;

console.log( !(c|d) );
// NOT c OR NOT d = true が表示される

console.log( Number(!(c|d)) );
// 1が表示される

```

## 否定排他的論理和 または 論理等価 (XNOR)

a === b の結果で良い？

```javascript
// (a === b)

const a = 0;
const b = 1;

console.log( a === b );
// falseが表示される

const c = 0;
const d = 0;

console.log( c === d );
// true が表示される

console.log( Number(c === d) );
// 1が表示される

```
コーディング規約を見てみる！

## 言語ごとのコーディング参考サイトを公開

- [java](https://future-architect.github.io/coding-standards/documents/forJava/Java%E3%82%B3%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0%E8%A6%8F%E7%B4%84.html)
ACアダプタやハーネスにラベルをつけよう

ACアダプタやハーネスはよく確認しないと誤接続することがあります。
このため、テプラなどのラベルを貼ることをお勧めします。
# ラベルの種類
ラベルの事をテプラということがありますが、これはキングジム社の商標になります。
カシオではネームランドというようです。
ほかにもいろいろなメーカーが出していますが、メーカー間での互換性はないと考えるべきで
誤って違うメーカの商品を購入しないように注意しましょう。
# ラベルの幅・サイズ
ラベルは幅・サイズ等はしっかり選定しましょう。
プリンターの購入時にどの幅まで対応するかをきちんと選定しないと、買ったテープが使えないというケースが発生します。
# プリンターの選定
キングジム社の場合
18㎜程度までが対応する廉価版と、24㎜まで対応する上位機種に分かれるようです。
またテープのオートカッターがついていない最廉価版がありました。
__＊注：熱収縮チューブにはこのカッターは使えないようです__
キングジム社に確認したところ幅24㎜まで対応した
### ラベルライター「テプラ」PRO SR370
https://www.kingjim.co.jp/products/tepra/sr370.html
がおすすめとのことです。
# 熱収縮チューブ
ハーネスにラベルを貼るのは難しいです。
このため、熱収縮チューブをおすすします。
- キングジム テープカートリッジ テプラPRO 熱収縮チューブ
- カシオ ラベルライター ネームランド 熱収縮チューブテープ
これをハーネスの先端に付けておくことで誤接続を防ぐことが可能になります。
 __熱収縮チューブの特長と選び方__
https://www.monotaro.com/s/pages/productinfo/heatshrinktube_feature/
# テプラPROとラベルライターのカートリッジ比較
テプラPROとラベルライターの熱収縮チューブを入手したので形状を比較してみました。
![DSC_0111 (2).JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/d3096b64-1607-78c5-36bc-7b7e86f49fd0.jpeg)
意外とカートリッジの大きさが違います
![DSC_0113 (3).JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/d17a1a61-646a-b8aa-a2c9-4e4f09801d24.jpeg)
# 使ってみる
私は、キングジムのテプラを所有しておらずカシオのラベルライターでテストしました。
9㎜の熱収縮チューブはジャンパーワイヤーには大きく、もっと小さいサイズが欲しいところ。
![DSC_0118 (2).JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/6a13e8d6-2c02-4079-428f-9fdbedc9d81a.jpeg)
逆にACアダプターのDCジャック付きには小さくて入りません。
![DSC_0120 (2).JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/306b7979-1c51-91ea-614e-dbab3117a764.jpeg)
この為DCジャックには18㎜のカートリッジが必要となります。
ただし、18㎜タイプは24㎜幅対応のプリンターである必要があるので要注意です。
![DSC_0129 (2).JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/749f1d17-92dc-b345-857e-a466ad255123.jpeg)
収縮させた状態
![DSC_0130 (2).JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/a60072f0-a679-b67e-bf58-ab7ac3dc3136.jpeg)
# 総評
見てくれは少し良くありませんがジャックやコネクタの判別が可能になりました。
ジャックやコネクタを取り付けた後から使用するにはちょっとキツイですが誤接続防止の観点から取り付けてみてはいかがでしょうか？
Elasticsearch: Httpie でアクセス

こちらのサンプルのクライアントを curl から Httpie に変えてみました。
[Elasticsearch へのデータ投入](https://qiita.com/ekzemplaro/items/b6dda109ffe19b3c39c8)

## データを投入 ##

```bash:go_insert.sh
http PUT http://localhost:9200/blog/_doc/t001 < in01.json
http PUT http://localhost:9200/blog/_doc/t002 < in02.json
http PUT http://localhost:9200/blog/_doc/t003 < in03.json
```

```json:in01.json
{
	"name": "山本太郎",
	"title": "My Name Is Yamamoto",
	"content": "I love dog",
	"tags": ["red", "green", "blue"]
}
```

```json:in02.json
{
	"name": "田中康夫",
	"title": "My Name Is Tanaka",
	"content": "I love cat",
	"tags": ["Earth", "Moon", "Mars"]
}
```

```json:in03.json
{
	"name": "渡辺五郎",
	"title": "My Name Is Watanabe",
	"content": "I love fish",
	"tags": ["apple", "orange", "banana"]
}
```

## データ数のカウント ##

```bash
http http://localhost:9200/blog/_count?q=*
```

## 検索 ##

```bash
http http://localhost:9200/blog/_search?q=title:yamamoto
```

```bash
http http://localhost:9200/blog/_search?q=tags:apple,moon
```

## 削除 ##

```bash
http DELETE http://localhost:9200/blog
```
TypeScript 交差 / 共有体 / リテラル / 列挙型

# `intersection型(交差型)`

既存の型を利用して新たな型を作成することができる型となります。

```typescript
type Pitcher1 = {
  throwingSpeed: number;
};
type Batter1 = {
  battingAverage: number;
};

const DaimajinSasaki: Pitcher1 = {
  throwingSpeed: 154,
};
const OchiaiHiromitu: Batter1 = {
  battingAverage: 0.367,
};
```
例として上記に二つの型エイリアスを定義しています。
今回は、球速を示す`throwingSpeed `と 打率を示す`battingAverage`の両方を持つ型を新たに作成したいと思います。

```typescript
type TwoWayPlayer = Pitcher1 & Batter1;

const OtaniShouhei: TwoWayPlayer = {
  throwingSpeed: 165,
  battingAverage: 0.286,
};
```

新たに`TwoWayPlayer`という型エイリアスを定義し、その中で既存の型を`&`で連結することで型を合成することができます。
また、既存の型を流用することでメンテナンス向上にもつながります。

# `union型(共有体型)`

いずれかの型を指定するときに使用する型となります。

```typescript
let value: number | string = 1;
value = 'foo';
value = 100;
```

指定の型をパイプ記号「`|`」で区切って記述することで、今回の場合、`value`が**数値、もしくは文字列**であることを宣言しています。

# `Literal型`

特定の値だけを代入可能にする型となります。

文字列リテラル
```typescript
let dayOfTheWeek: '日' | '月' | '火' | '水' | '木' | '金' | '土' = '日';
dayOfTheWeek = '月';
dayOfTheWeek = '31'; // 型 '"31"' を型 '"日" | "月" | "火" | "水" | "木" | "金" | "土"' に割り当てることはできません。
```
数値リテラル

```typescript
let month: 1|2|3|4|5|6|7|8|9|10|11|12 = 1;
month = 12;
month = 13; // 型 '13' を型 '1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12' に割り当てることはできません。
```
真偽値リテラル

```typescript
let TRUE: true = true;
TRUE = false; // 型 'false' を型 'true' に割り当てることはできません。
```

今回の場合、`true`のみ代入可能にしています。

# `enum型(列挙型)`

複数の定数を一つにまとめて定義して管理することができる型となります。

**数値の列挙**

```typescript
enum Months {
  January = 1,
  February,
  March,
  April,
  May,
  Jun,
  July,
  August,
  September,
  October,
  November,
  December,
}

console.log(Months.January); // 1
console.log(Months.December); // 12
```

`0`から順にインクリメントされるため、先頭の`January`に`1`をオーバーライドして各要素に適切な数値が設定されるようにしています。

**文字列の列挙**

```typescript
enum COLORS {
  RED = '#FF0000',
  WHITE = '#FFFFFF',
  GREEN = '#008000',
  BLUE = '#0000FF',
  BLACK = '#000000',
}

let green = COLORS.GREEN;
console.log({ green }); // { green: '#008000' }
```

## 参考教材

https://www.udemy.com/course/ts-for-js-developers/
Ethereum2.0のPoSについて

## はじめに

ついにEthereumのMergeがテストネットで成功しました🎉

それに伴ってコンセンサスアルゴリズムがPoWからPoSに変更になりました。そこで両者の違いとEthereumのPoSの動きを自分なりにまとめてみました。

## PoW

Proof of Workの略。Bitcoinで使用されていることで有名。

ブロックチェーンの仕組上、取引がなされた際にその取引データは他の人に承認されてブロックに取り込まれる。

その際にブロックの承認を行うために必要な計算(Nonceの計算)があり、それを早く解き切るとマイナーに選ばれ、報酬を受け取ることができる。

しかし、電力消費量が非常に大きくため、環境に負荷がかかる・個人で行うには設備等で莫大な費用がかかる。

## PoS

Proof of Stakeの略。

トークンを一定数以上ステーキング持っているユーザーからランダムに選択し(バリデーターの選出)、そのバリデーターがブロックを承認することによって報酬を得ることができる。

**特徴**

- トークンを一定数有していると一定の信用があるという考え方

- PoWのように高性能のハードウェアを必要としない

- 個人での参入障壁が下がる

Layer2ソリューションのRollup等と組み合わせてスケーラビリティの問題に対処できる

## EthereumにおけるPoSの動き

### バリデーターのやること

選ばれた場合→ブロックの作成

選ばれなかった場合→ブロックの検証を行う

ブロックの検証をattestingといい、「このブロックは良さそうだ」というのを証明しているイメージ。

もし、悪意のブロックに対してattestingした場合にはステークを失う。

### シャードチェーン

シャーディングによってネットワークの混雑を減らし、シャードチェーンを作成することによって、1 秒あたりのトランザクションを増加させる。

64のシャードチェーンが存在し、それぞれがネットワークの状態を共有することになっている。

**シャーディング**

データベースを水平に分割して負荷分散を行うプロセス。

### ビーコンチェーン

シャードチェーンの調整を行うチェーン。

シャードから状態情報を受け取り、他のシャードがそれを利用できるようにすることで、ネットワークの同期を保つことができる。

また、ビーコンチェーンは、バリデータのステーク入金登録から報酬・ペナルティの発行も管理する。

### バリデーションの働き

シャードでトランザクションを送信すると、バリデータがそのトランザクションをシャーブロックに追加する役割を担う。

バリデータはビーコンチェーンのアルゴリズムによって選ばれ、新しいブロックを提案できるようにする。

**Attestation**

上記とか異なりバリデータが新しいシャードブロックを提案するのに選ばれなかった場合、他のバリデータが行ったブロックの提案に対して認証を行う。

ビーコンチェーンには取引自体ではなく、この認証に対して行われている。

各シャードブロックには少なくとも128人のバリデータが必要で、これを 「**committee**」と呼ぶ。

committeeにはシャードブロックを提案し、検証するための時間枠があり、それを「**slot**」と呼ぶ。

1つのslotには1つの有効なブロックを作成する。そのslotが32個まとまったものを「**epoch**」といい、1つのepochの検証が終了したらcommitteeは解散する。

その後、再び異なるランダムな参加者でcommiteeが再結成される。これによって悪質なcommiteeからシャードを保護することができる。

**Crosslink**

新しいシャードブロックの提案に十分な認証が得られると、ビーコンチェーンにブロックと取引が含まれることを確認する「**Crosslink**」が作成される。

このCrosslinkでビーコンチェーンとシャードチェーンがつながり、同期を行っている。

Crosslinkができると、そのブロックを提案したバリデータは報酬を得ることができる。

**Finality**

分散型ネットワークでは、ある取引が変更不可能なブロックの一部となっている場合、その取引は「**Finality**」を持つ。

PoSでこれを実現するために、Finalityのプロトコルである**Casper**が使用される。

これはあるチェックポイントでのブロックの状態についてバリデーターに同意させるもの。

バリデータの2/3が同意すれば、そのブロックはファイナライズされる。

もしバリデータは、ファイナライズされたブロックを51％攻撃によって元に戻そうとすると、すべてのステークを失うことになる。
切断正規分布のパラメータ計算

## 与えられた期待値と分散から切断正規分布のパラメータを求める方法です。

scipyのoptimizeを使います。

準備1 [公式](https://ja.wikipedia.org/wiki/切断正規分布)に従って関数を用意

```
import math
from scipy import stats, optimize
def dist_E(lower, upper, mu, sigma):
  x0 = (lower - mu) / sigma
  x1 = (upper - mu) / sigma
  return mu + (stats.norm.pdf(x0) - stats.norm.pdf(x1)) / (stats.norm.cdf(x1) - stats.norm.cdf(x0)) * sigma

def dist_V(lower, upper, mu, sigma):
  x0 = (lower - mu) / sigma
  x1 = (upper - mu) / sigma
  term1 = (x0 * stats.norm.pdf(x0) - x1 * stats.norm.pdf(x1)) / (stats.norm.cdf(x1) - stats.norm.cdf(x0))
  term2 =  (stats.norm.pdf(x0) - stats.norm.pdf(x1)) / (stats.norm.cdf(x1) - stats.norm.cdf(x0))
  return sigma * sigma * (1.0 + term1 - term2 * term2)
```

準備2
推定条件を準備
```
a= 1 分布の下限
b= 5 分布の上限
E= 4.00 分布の期待値
V= 0.5 分布の分散
```

準備3
目的関数を準備
```
def fun(x):
  return [dist_E(a, b, x[0], x[1]) - E, dist_V(a, b, x[0], x[1]) -V]
```

パラメータ計算
```
sol = optimize.root(fun, x0=[E, math.sqrt(V)])
x = sol.x
mu = x[0]
sigma = x[1]
print(x)
print(dist_E(a, b, mu, sigma))
print(dist_V(a, b, mu, sigma))
```

結果
```
[4.61408088 1.05919093]
4.0
0.4999999999999998
```

グラフ
```
import matplotlib.pyplot as plt
fig, ax = plt.subplots(1, 1)

fix_a = (a - mu) / sigma
fix_b = (b - mu) / sigma
print(stats.truncnorm.mean(fix_a, fix_b, loc=mu, scale=sigma,  moments='mvsk'))
print(stats.truncnorm.var(fix_a, fix_b, loc=mu, scale=sigma,  moments='mvsk'))
x = np.linspace(stats.truncnorm.ppf(0.01, fix_a, fix_b, loc=mu, scale=sigma), stats.truncnorm.ppf(0.99, fix_a, fix_b, loc=mu, scale=sigma), 100)
ax.plot(x, stats.truncnorm.pdf(x, fix_a, fix_b, loc=mu, scale=sigma), 'r-', lw=5, alpha=0.6, label='truncnorm pdf')
plt.show()
```
グラフ結果
```
4.0
0.4999999999999998
```

![Figure_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221397/568725c0-9c95-8559-3cf6-8a45bf74231e.png)
CMake無しでlibtorch + Visual Studioを使う方法



# 概要
Visual Studio + libtorchを利用する方法だと、CMakeを利用してVisual Studioのプロジェクトを生成する方法があるが、もっと簡単に行う方法があった。（できた？）
Visual Studio 2019にエクステンションを追加するだけで利用できるようになる(2017は未検証,2022は存在しない)。なお、このエクステンションはプレビュー版なので不安がある人は利用しないほうがいい。
CPU Only版でしか試していないが、GPUありでもできると思う。（GPU買ったら記事に載せます）
あと、pytorch本家に[インストール方法の動画](https://ossci-windows.s3.us-east-1.amazonaws.com/vsextension/demo.mp4)があるので、そっちを見てもいい。ただし英語。

# エクステンションのインストール
Visual Studio 2019のメニューで"拡張機能(X) > 拡張機能の管理(M)"を選択する。検索でlibtorchと入力すると"LibTorch Project[プレビュー]"が表示されるのでそれをインストールする。画像では、もうインストールしたあとなのでインストールボタンが出ていないが、インストールボタンをクリックするとインストールできる。

![extension.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/161139/97ee35c6-21f1-d220-fcc9-7a6b721ecbef.png)

# libtorchのダウンロード
[pytorchのWebページ](https://pytorch.org/get-started/locally/)からlibtorchをダウンロードする。
Release版とDebug版の２つが必要となるので、必ず２つともダウンロードすること。
![download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/161139/1306e85b-801b-f6b0-6fe2-1e7265bcb2fa.png)

# libtorchの解凍
zipファイルなので解凍する必要がある。注意点としてかならずzipファイルのファイル名のフォルダありで解凍すること。7zipを利用して"ここに展開"を利用するとlibtorchというフォルダができるが、それだと認識しない。
"解凍先のフォルダ\libtorch-win-shared-with-deps-debug-1.11.0+cpu\libtorch"(デバッグ版の場合)となるように解凍する必要がある。

# Visual Studioでサンプルプロジェクトを作成する
1. Visual Studioを起動して新規プロジェクトを作成する。TorchProjectというのが追加されているのでそれを選択する。
![vs1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/161139/c0c3df4e-04ae-51a4-1536-97b26f60df8b.png)
1. プロジェクト名とソリューション名を入力する。ここは通常のVisual Studioのプロジェクトと同じ。
![vs2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/161139/23122d81-57f2-67e9-8455-eafb7e7629f1.png)
1. さきほどダウンロード・解凍したlibtorchのフォルダを指定する。必ず解凍したフォルダ("libtorch-win-shared-with-deps-debug-1.11.0+cpu")を指定すること。"libtorch-win-shared-with-deps-debug-1.11.0+cpu\libtorch"を指定すると動かない。
![vs3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/161139/2e03c24f-a690-6582-7b3a-f93fcb29babc.png)
1. 最初からサンプルが動かせる状態になっているので、コンパイル・実行で動作する。
![vs4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/161139/32aa4460-8553-2861-48f4-bea08bb2807b.png)
曜日を取得する方法

・曜日を取得する方法

コード
```
<?php
$week_name = ['日', '月', '火', '水', '木', '金', '土'];
date_default_timezone_set('Asia/Tokyo');
$week = date('w');
echo "今日は、$week_name[$week]曜日です";
```

`date_default_timezone_set('Asia/Tokyo');`　で日本時間に設定

`date('w')`で曜日の番号を取得(0:日～6:土)

0:日～6:土に応じた配列を用意
【Swift】StoryBoardを使わずに開発

# StoryBoardを使わずに開発
以下の記事を参考に備忘録として残します。
StoryBoardを使用せずに開発する際に、毎回以下の記事をググっているので、あくまで自分用に本記事を投稿します。
そのため、よりわかりやすく詳細に知りたい方は是非以下の記事を閲覧してください。
https://zenn.dev/kazumalab/articles/76ca59f82c189cf33d43

# 方法
### 1. StoryBoardの削除
プロジェクト新規作成した際にできるStoryBoardを削除します。

### 2. Main Interfaceを空白にする
Targets > General > Development InfoのMainInterface を空白にします。

### 3. Info.plistのStoryboard Nameの項目を削除
Into.plistのApplication Scene Manifest > Scene Configuration > Application Session Role > Item 0 > Storyboard Nameの項目を削除します。

### 4. SceneDelegate.swiftを編集(iOS13以降)
SceneDelegateに以下のコードを記述することでrootViewControllerを設定します。
```swift
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    if let windowScene = scene as? UIWindowScene {
        let window = UIWindow(windowScene: windowScene)
        window.rootViewController = ViewController.init()
        self.window = window
        window.makeKeyAndVisible()
    }
}
```

# 参考
https://zenn.dev/kazumalab/articles/76ca59f82c189cf33d43
【備忘録】Nuxtのaliasに注意する

# この記事について
NuxtでTypeScriptを使っているときに、importが上手くいかなくて困ったので、メモを残しておくことにする。

# NuxtのaliasはTypeScriptには効かない
Nuxtにはデフォルトで`~`や`@`などのaliasが設定されている。

https://nuxtjs.org/ja/docs/configuration-glossary/configuration-alias/

しかし、このaliasは、JavaScriptやCSSでは機能するが、TypeScriptでは機能しない。
よって、以下のようなパスの指定はエラーになる。

```index.vue
<template>
...
</template>

<script lang="ts"> // 言語にTypeScriptを指定
import { TestComponent } from '@/components/TestComponent.vue'; // エラー
...
</script>
```

`tsconfig.json`の`paths`に自分でaliasを定義すれば、上記のようなパスの指定が可能になる。
公式にも以下の注意書きがあったが、見落としていた。

> TypeScript を使っていて、自分で定義したエイリアスを TypeScript ファイル内で使用したい場合は、tsconfig.json 内の paths オブジェクトにエイリアスを追加する必要があります。

# serverMiddlewareでは相対パスしか使えない
serverMiddlewareを使用するために、以下のように設定したとする。

```nuxt.config.ts
export default {
  serverMiddleware: ['../server']
}
```

上記のように設定した場合、`server`ディレクトリ配下でのパス指定はすべて相対パスで行われる必要がある。
`tsconfig.json`で`paths`が設定されていれば、エディタ上ではエラーにならないが、起動すると以下のようなエラーが表示される。

> ServerMiddleware Error: Cannot find module '@/server/utils'

これについて、同様の質問がIssuesに上がっていたので確認してみたところ、以下のようなコメントを見つけた。

> @ is a Webpack alias for the project root. Server middleware are loaded by Node, you must use relative paths.

https://github.com/nuxt/nuxt.js/issues/7017

Nuxt3系で解決されるという話もあるみたいだが、現状では相対パスを使うしかなさそう。
ポータブル電源 EcoFlow Delta MiniのAPIで情報取得する

災害対策やキャンプ需要でポータブル電源流行ってますよね。
てことで、数あるポータブル電源の中でも、Wi-Fi対応しているEcoFlow Delta　Miniを購入したので、公開されているAPIを叩いて状態を取得してみました。

https://jp.ecoflow.com/products/delta-mini-portable-power-station

# Keyの取得
まずは、API keyを取得します。
日本語だとそもそもEcoFlow DeltaのAPIについて触れている記事が見つけられなかったのですが、下記サイトによるとどうやらEcoFlowのサポートにメールすると教えてもらえるらしい。

https://community.home-assistant.io/t/trying-to-get-info-from-my-ecoflow-delta-max-battery/359309

早速EcoFlow Japanのサイトに記載されている問い合わせ先にメールをしてみました。なぜか日本語のみと英語のみの２つのアドレスがあったので念のため英語の方にメールしてみました。

問い合わせ内容
> I've heard you provide an API-key to get information from EcoFlow Delta. Could you send me the key?
> Model: Delta mini
> S/N: ABCDEFGHI012345

サポセン返信
>As intellectual property is involved, please ensure that it is only used by you personally and not for other purpose. :)
> The following is the API of your Delta mini (XXXXXXXXXXXXX)
> https://iot1.ecoflow.com/v1/devices/queryDeviceData?sn=ABCDEFGHI012345&appkey=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

URL形式で回答いただきました。

# APIでバッテリー状態を取得
英語のサポセンから送られてきたURLをブラウザでアクセスすると以下のようなJSONが返ってきます。
```
{"code":0,"message":"success","data:{"sn":"ABCDEFGHI012345","data":{"remainTime":24,"socSum":5}}}
```
remainTimeはバッテリーの残り時間で単位は分
socSumはバッテリー残量で単位は％


# 所感
今のところAPI使ってできることは状態取得だけみたいです。EcoFlowのアプリでは、バッテリーへの給電量を制御して充電スピードの調整とか何％まで充電するといったレベル設定ができるので、それらも公開されたら自宅の太陽光パネルの発電状況に応じて充電制御ができて夢が広がるのになー。今後に期待したい。
とりあえずは、スマートプラグを導入して太陽光パネルの発電量とバッテリー残量から充電オンオフを切り替えるを作ってみようかと思います。
Java: 週末に理解したいラムダ式の記事集

今更感あふれるがまとめておきたかったラムダ式にまつわる記事集。これだけ読んでおけとしたかったもの。
[Java8のラムダ式を理解する - Qiita](https://qiita.com/sano1202/items/64593e8e981e8d6439d3)

> ラムダ式とはインターフェースを実装したインスタンスを生成する式

[ラムダ式 - Qiita](https://qiita.com/Yuki_312/items/d14665b53fc6dccf11f4)

```Java:java
// Java7 non-Lambda
Runnable r = new Runnable() {
  public void run() {
    System.out.println("Hello world!");
  }
};
r.run();

// Java8 Lambda
Runnable r2 = () -> System.out.println("Hello world!");
r2.run();
```


## Project Lambda

[OpenJDK: Project Lambda](https://openjdk.java.net/projects/lambda/)

## 記事

https://qiita.com/sivertigo/items/8f61f02f7c84b786697a

https://qiita.com/sano1202/items/64593e8e981e8d6439d3

https://qiita.com/takumi-n/items/369dd3fcb9ccb8fcfa44

https://qiita.com/kuryus/items/820bdf48cc341a6445f0

https://qiita.com/yonetty/items/24d9a075bf630b1b096f

https://enterprisegeeks.hatenablog.com/entry/2014/10/20/085500


## 関連トピック

https://qiita.com/flyaway/items/16b1a54e8f3ecea609a9#%E6%A1%883-guava%E3%81%AEmapstransformvalues%E3%82%92%E4%BD%BF%E3%81%86

https://www.iandprogram.net/entry/2015/02/08/181600#1-%E3%83%A9%E3%83%A0%E3%83%80%E5%BC%8F%E3%82%92%E7%94%A8%E3%81%84%E3%82%8B%E6%96%B9%E6%B3%95Java8%E4%BB%A5%E9%99%8D

https://qiita.com/sparklingbaby/items/f6f3ce92dc13a9d8fc07

本当にこれだけ。以上です～