OmniAICreator/Qiita-1.07M huggingface dataset:
[Laravel 8] Eloquent Modelのfillableとguarded

It is necessary to specify either a fillable or guarded property on your model class. These properties are required because all Eloquent models are protected against mass assignment vulnerabilities by default.


$fillable

To get started, you should define which model attributes you want to make mass assignable. You may do this using the $fillable property on the model. 


```Models\Student.php
protected $fillable = ['first_name','last_name'];
```

$guarded

If you would like to make all of your attributes mass assignable, you may define your model's $guarded property as an empty array.

```Models\Student.php
protected $guarded = [];
```


Reference:
https://laravel.com/docs/8.x/eloquent#mass-assignment
AWSのVPCとCIDRの事

# はじめに
少し前の事なのですが、AWSのトレーニングを受講する機会をいただきまして、その際、VPCの理解が浅いまま受講したのが災いし、せっかく受講したのにうまく再現できず（トレーニングでは専用のVPCがすでに構築されている状態だったため）
VPCから改めて知る必要があるなと思い、調べてみました

# 目次
1. [AWS VPC概要](#AWS%20VPC概要)
1. [サブネット](#サブネット)
1. [ルーティング](#ルーティング)
1. [ネットワークのアドレスについて](#ネットワークのアドレスについて)
1. [参考文献](#参考文献)

<!-- 各チャプター -->
# AWS VPC概要
Virtual Private Cloudの略語で、仮想プライベートクラウド、開かれているクラウド上に仮想でプライベートなクラウドを構築するための**ネットワーク**を構築できる機能

https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/what-is-amazon-vpc.html

ネットワークの知識が必要だということがわかります
ちなみに、GoogleCloudPlatformの方は、プロジェクト単位で自動でVPCが構築されるとのことで、私みたいなクラウド初心者はGCPの方が良いかもしれないなと思いました
AWSはデフォルトのVPCがアカウント一つに一個自動で作成されますが、一つのアカウントで多数のプロジェクトを管理するのであれば、プロジェクト単位でVPCを作るべきでしょう
そのためAWSで構成を作る際は、まずVPCを構築するところから始める必要があると考えます

# サブネット
ネットワークの中のネットワークのことをサブネットと言います
VPCがあって、その中にサブネットを作成して構成を作っていくという手法になります
サブネット内に仮想マシンやデータベースを構築していきます
サブネットのIPアドレスの範囲をSIDR表記で指定する必要があります

https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/VPC_Subnets.html

# ルーティング
サブネットへの通信や、インターネットやプライベートネットワークから接続したりするのに、ルートテーブルというものを構成する必要があります
VPCを作って、サブネットを作って、ルートテーブルを構成する、基本的には最低限この一連の作業が必要になると思います

https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/VPC_Route_Tables.html

# ネットワークのアドレスについて
上記3つを設定すれば、最低限VPCの構築が出来るのですが、私が引っかかったのが、IPアドレスを何に指定すれば良いのか
という点でしたので、そちらについて追記します

VPCを作成する際、出てくる「IPv4 CIDER ブロック」
![スクリーンショット_2021-08-26_16_06_51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2788/11afb145-a2a1-16bd-a4d4-f27c9f74c67f.png)
コレに何を入れたら良いのかという話です

まず、このアドレスがいったい何かという事なのですが、VPC内で扱うプライベートIPアドレスの範囲を設定するところになります
表記はCIDRという表記になります

https://dev.classmethod.jp/articles/what-is-cidr/

推奨されているのは以下の３つの範囲のいづれかということです
・10.0.0.0/8
　（10.0.0.0 ～ 10.255.255.255）
・172.16.0.0/12
　（172.16.0.0 ～ 172.31.255.255）
・192.168.0.0/16
　（192.168.0.0 ～ 192.168.255.255）

割り当てる範囲についてなのですが、VPCの中で使うサービスの規模によって変更するべきではあるものの、足りなくなった場合はセカンダリーCIDRブロックを追加出来るので、ぶっちゃけ何でも良いらしいというのを調べている上で知りました

ただ、何も決めないのも気持ち悪いので、さらに調べたところ、VPCのCIDRブロックは/16で切り出したアドレス範囲、サブネットは/24で切り出した範囲で設定するのが良さそうです

設定例を元にするのであれば
VPC：10.0.0.0/16
サブネット：10.0.0.0/24〜10.0.255.0/24
が良さそうです（サブネット一つにつき255個のプライベートIPアドレスの指定が可能）


<a id="#reference"></a>
# 参考文献
- [Amazon VPC とは?](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/what-is-amazon-vpc.html)
- [VPC とサブネット](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/VPC_Subnets.html)
- [VPC のルートテーブル](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/VPC_Route_Tables.html)
- [CIDRとは](https://dev.classmethod.jp/articles/what-is-cidr/)
Chrome 拡張機能の CORS エラーを回避（Manifest V3）

# とても嬉しいので記事にする

**CORS = オリジン間リソース共有（Cross-Origin Resource Sharing）**

ざっくり言うと、ページに使用するソースは自分とは異なるオリジン (ドメイン、プロトコル、ポート番号) から参照する事はできませんよ、というもの。
詳細は他に良い記事が沢山あるので割愛します。

参考：[なんとなく CORS がわかる...はもう終わりにする。](https://qiita.com/att55/items/2154a8aad8bf1409db2b)

で、本題。Chrome 拡張機能のマニフェストバージョンを３にすると、以前はできなかった CORS 回避が簡単にできるようになりました。

これの何が嬉しいのかって言うと、**拡張機能の`background.js`などから外部の REST API を叩こうとすると、API 側が`Access-Control-Allow-Origin`ヘッダーを返すようにしていない限り、CORS エラーで取得できなかった**り、**API が JSONP に対応していればそれを使って取得**していたのが解決できる、と。
こりゃ嬉しい。

もしかしたら、私が知らなかっただけで出来ていたのかもしれませんが、散々ググった結果、出来ないとの結論に落ち着いていたので、簡単にできた時は嬉しかったんですね。

あ、Chrome 拡張機能も Javascript も、素人もいいとこなので、勘違いしていたらすみません。
なお、その際は、この記事は自動的に黒歴史となる予定です。

## やり方

`manifest.json`のバージョンを３にした上で、`"host_permissions"`を加えるだけです。

```manifest.json

"manifest_version": 3,
"host_permissions": [
    "https://api-address/"
]
```

あとはお好きにデータを引っ張ってきましょう。
ただし、V3 にすると、`background.js`（`service_worker`で指定した JS）では`xmlHttpRequest`が使用できない為、`fetch`を使いましょう。

```background.js
var url = "https://api-address/query";

fetch(url)
    .then(function (res) {
        return res.json(); // フェッチしたデータを JSON 形式に変換
    })
    .then(function (jsonData) {
            console.log(jsonData); // JSON へ変換されたデータをコンソールに表示
        })
    })
```

これで、CORS 対応していない API でもブッ叩く事が出来るようになります。

[『郵便番号検索 API』](https://zip-cloud.appspot.com/doc/api)あたりが CORS エラーを返してくれると思うので、試してみて下さい。

## まとめ

JSONP とか使わずに API レスポンスが取れて、とても嬉しいです。
ただ、実現する為にはマニフェストバージョンを３にする必要があるため、既存の拡張機能に実装するのは修正が面倒かもしれませんね。
PHP の型宣言は変数の型のチェックではない

タイトルのとおりです。

https://3v4l.org/iObP4

```php
<?php
function add(int $a, int $b): int
{
    return $a + $b;
}

echo add(1, 2.2) . "\n";   // 3
echo add(1, "2") . "\n";   // 3
echo add(1, "1e1") . "\n";   // 11

add(1, "two"); // Fatal error: Uncaught TypeError: add(): Argument #2 ($b) must be of type int, string given
```

https://3v4l.org/8I9TS

```php
<?php
function not(bool $b): bool
{
    return !$b;
}

var_dump(not(0));    // true
var_dump(not(""));   // true

not(null); // Fatal error: Uncaught TypeError: not(): Argument #1 ($b) must be of type bool, null given
```

値の型そのものを見ているわけではなく、値の内容が目的の型に変換できるかどうかが判断基準になっていて、受け入れられると型変換されます。

Web の入力バリデーションで「数字だけで構成されるから数値としてOK」と判断された文字列は、値の型が int にならず文字列のままでも心配ありません。実質 int の string は int 引数の関数に渡せます。DB で integer 型とわかっているものなら、PHP に渡ってくるとき値の型が文字列でも int 引数の関数に安心して渡せます。

PHP は強い型の値を持ちながら、意図的に弱い型のような振る舞いさせる言語です。文字列 IO と親密な関係にあるため、そういう設計方針が適しています。

https://3v4l.org/StRGI

```php
<?php
function number(...$args): int
{
    return implode('', $args);
}

var_dump(number('1', '2', '3'));  // int(123)

number('4', 'five');
// PHP8: Fatal error
// PHP7: Notice
```

戻り値の型チェックもなかなかダイナミックです。型そのものではなく、値の内容がじっさいに変換できるかどうかが問われることがよくわかる例ですね。

変数だけを見て型がわからないので、コンパイル時型推論でガチガチにする言語と PHP の型とはコンセプトがまったく異なる概念だと意識すると、もっと PHP と仲良くできそうです。
Activerecordを操作するCRUD処理

#Activerecordとは
簡単に言うとデータベース(SQL)をRubyを通して人にわかりやすく伝えてくれるものです。
本来ならSQLでないとデータベース操作はできないのですがrailsで用意されている
Activerecordのおかげでデータベースの操作ができます。

#コンソールを使う。
コンソールとはざっくり言うとコンピューターとの意思疎通をするものです。
下のコマンドでデータベースを操作できるようになります。

```
 $ bundle exec rails c #cはコンソールのcです。　rails cでも　rails consoleでもokです。
```
#CRUD処理とは何か。
データベースを操作する時に　Create(生成),Read(読み込む),Update(更新),Delete(削除)
の操作を総称してCRUD処理と言います。
下でCRUD処理の操作を見ていきましょう。

#CRUD処理　（Create)

```rb

staff = Staff.create(name: "taro", email: "taro@example.com", job:"programmer")
#インスタンスを作成しデータベースに保存すること

staff = Staff.new(name: "taro", email: "taro@example.com", job: "programmer")
#モデルのインスタンスを作成

staff = Staff.build(name: "taro", email: "taro@example.com", job: "programmer")
#メモリ上にインスタンスを置いておく時に使う。

staff.save
#データベースに保存する



```
*createとbuildの違い
・buildインスタンスをデータベースに保存の必要がない時に使う。記録用として使われる。
・createインスタンスはデータベース上に保存してずっとデータを置いておきたいときに使います。


#CRUD処理　（Read)

```rb
staffs = Staff.all
#modelのレコード(データ)を全部取得

staff = Staff.first
#最初にレコードを取得　　*secondなら２番目、thirdなら３番目,lastなら最後のレコードを取得　
*first! last!も使えます。

staff = Staff.find(1)
staff = Staff.find([1,2])
#()に入っている引数を取得.  *何もなかったらエラーになります。


staff = Staff.find_by(name: "taro")　　*()は条件文
#()の中の条件文に一致したものを取得　　
*find_by!は存在していなかったらエラーになります。!がないときはnilになります。

staffs = Staff.where　(name: "taro", job: "programmer")　　＊（）の中は条件文
#()の中の条件文に一致したものを取得

```

#CRUD処理　（Update)

```rb
staff = Staff.first
staff.update(name: "ziro")
#レコードを更新できる。　update!も使えます。

staff = Staff.where(name:"taro")
staff = Staff.update_all(name:"ziro")
#nameがtaroがみんなziroになります。

```


#CRUD処理　（Delete)

```rb
staff = Staff.second
staffs.destroy
#レコードを削除する

staff.delete
*deleteは使わない方がいいみたいです。

```

他にも pluck count order reorder  select exist  などいろいろあるので調べて見てください。



⚫︎参考資料
https://qiita.com/ryokky59/items/a1d0b4e86bacbd7ef6e8
https://wa3.i-3-i.info/word12140.html
https://qiita.com/Oka1551/items/42cd09fab957f0512d00
標準の戻るボタンが押されたときにandroidのホーム画面に遷移

##標準の戻るボタンが押されたときにandroidのホーム画面に遷移
###サンプルコード
```kotlin:back_to_home
    override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
        return if (keyCode == KeyEvent.KEYCODE_BACK) {
            val homeIntent = Intent(Intent.ACTION_MAIN)
            homeIntent.addCategory(CATEGORY_HOME)
            homeIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
            this@自分のクラスの名前.startActivity(homeIntent)
            super.onKeyDown(keyCode, event)
        } else {
            super.onKeyDown(keyCode, event)
        }
    }
```

この関数を使いたいクラスに入れることで、戻るボタンが押された時の動作を変えることができます。
自分のクラスの名前のところを変更して使用してください
laravel8 Passport grant_type authorization_code をやってみた。

##はじめに
Laravelでは Passportを使用してGoogle,LINEのようなSNSログインを提供するサーバーとしても作成できるようなので、一度挑戦。
そもそものOAuthの仕組みが最初わからなかったので何度も読みました。
[OAuthの仕組み](https://qiita.com/TakahikoKawasaki/items/200951e5b5929f840a1f)
[英語 Laravel Passport](https://laravel.com/docs/8.x/passport)
[日本語 Laravel Passport](https://readouble.com/laravel/8.x/ja/passport.html)

## 実行環境
docker 
nginx
mysql
php8.0.9
phpmyadmin
node v14.17.5

## 変更点
Laravel7 までのドキュメントには、下記コマンドによりログイン後のダッシュボードで
クライアントを作成画面を追加できるが、Laravel8では実行できません。
`php artisan vendor:publish --tag=passport-components`
> `Unable to locate publishable resources.`
> 公開可能なリソースが見つかりません。

## 手順
### 認可画面が表示される
![スクリーンショット 2021-08-23 17.03.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318237/fc861646-65a4-dbb2-ff27-76f80bc65fb1.png)

今回は、tailwindcssで修正する。
下記コマンドで認証画面をカスタマイズできるファイルが出力される
```php artisan vendor:publish --tag=passport-views```
実行後、 resource/views/vendor/passport/authorize.blade.php が作成される

### 認可画面を修正
![スクリーンショット 2021-08-24 14.21.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318237/dbc1c09b-ad44-7f0a-d823-54ca5abe7f7b.png)

### 許可実行後、アクセストークンが表示される
![スクリーンショット 2021-08-23 17.22.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318237/605a8f21-569f-be29-6fd4-62088de23399.png)

### アクセストークンを使用してユーザー情報を取得する
ルーティングは routes/api.php に記載されている
取得したアクセストークンを Headerに `Bearer [アクセストークン] ` に設定する
#### POSTMAN 
![スクリーンショット 2021-08-26 16.21.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318237/04858a3c-ecd8-c67c-2b54-4bf702c18166.png)
成功すると
![スクリーンショット 2021-08-26 16.24.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318237/83acce85-ba98-260e-fbb2-a9512b2ceaa1.png)

#### コードで実行する場合は GuzzleHttpを使用する

``` php
require 'vendor/autoload.php';
$http = new GuzzleHttp\Client;
//取得したアクセストークン
$accessToken = '**********************'; 
$response = $client->request('GET', 'http://localhost:8080/api/user', [
    'headers' => [
        'Accept' => 'application/json',
        'Authorization' => 'Bearer '.$accessToken,
    ],
]);

var_dump(json_decode((string) $response->getBody(), true));
```

## 疑問点
テストコードでは、client_id,client_Secretを設定しているが、実際は1クライアント毎にユーザーIDを紐付けしているので、実行前に client_id, client_secret, redirect_uri を取得する必要があるのだが、どのようにして取得すればいいのだろう。
サードパーティCookieは今後利用できないだろうし。

海外記事まで見ましたがOuah Codeでの認証は、
アクセストークンからのPostman,コード実行によるユーザー情報の取得まででした。
引き続き調査します。

## その後
SNSログインの実装を勉強することでGoogleログインを実装する際の流れが同じだった。
その為、ユーザーごとに生成する必要はない。

しかし、大手のSNSログイン申請と比較すると初期状態ではclient idには整数(連番)が入ってしまう。
php artisan passport:install --uuid と入力するとchar型のIDが格納できる。

しかし、AuthCode用のクライアントを作成用コマンドを実行するとエラーが発生する。
結局、clientRepository.php  create() 内に idのデフォルト値を設定することで解決したが
これぐらいはデフォルトで対応してほしい。
client_idを数値だけでは安心できない。（Google,Lineなどのclient_idは当たり前だけど英数字混合の文字列でした。）

あと、ルーティング設定が丸ごと読み込まれるので、必要ないルートは除外したい。
(ServiceProvider で 無効化できるメソッドを設置し、 routes/web.phpに追記するイメージで）
【初心者】YOLOv5を使ってみる #1 (AWS上でのインストール、物体検出確認)

# 1. 目的
- 画像/映像分析の勉強のため、簡単に物体検出ができるフレームワークであるYOLOv5を使ってみて基本を理解する。

# 2. やったこと
- AWS上のWindows Server 2019にYOLOv5をインストールする。
- あらかじめ保存した画像ファイル、動画ファイルに対して推論を行い、結果を出力できることを確認する。

# 3. 構成

- 単純にWindows Server 2019のインスタンスを立てる。今回は学習の処理は行わないため、GPUインスタンスではなく普通のCPUのみのインスタンスを使用。

![構成図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/05226d94-1ad2-bb4b-4035-accae7e7d420.png)

# 4. 実施手順

## 4.1 事前準備
- Windows Server 2019の起動
    - 普通にWindows Server 2019を起動する。（RDPして、OSの中でWindowを開いて動画再生したりしたかったため、今回はOSとしてWindowsを選択）
- Gitのインストール
    - YOLOのインストールに必要なため、Git for Windowsをインストールする。
    - ダウンロードサイト：　https://gitforwindows.org/
    - 今回のバージョン：　Git-2.33.0-64-bit

- Python のインストール
    - YOLOの動作に必要なため、Pythonをインストールする。
    - ダウンロードサイト：　https://www.python.org/downloads/
    - 今回のバージョン：　python 3.9.6
    - 注意点：　基本的にデフォルトのままインストールするが、「Add Python 3.9 to PATH」（パスを通す設定）だけチェックを入れる。（下図）

![yolo01a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/5ce0003c-5d7f-24ba-32f7-1f0ee64eb098.png)


## 4.2 YOLOv5のインストール
- YOLOv5のインストール
    - 公式サイトの「[Getting Started](https://docs.ultralytics.com/quick-start/)」の手順通りにインストールする。

```
C:\Users\Administrator>git clone https://github.com/ultralytics/yolov5.git
C:\Users\Administrator>cd yolov5
C:\Users\Administrator\yolov5>pip install -r requirements.txt
```

## 4.3 動作確認

### 画像の物体検出
- サンプルとして用意されている画像を指定して物体検出を行う。

```
C:\Users\Administrator\yolov5>python detect.py --source "C:\Users\Administrator\yolov5\data\images\zidane.jpg"
```

- C:\Users\Administrator\yolov5\runs\detect\expX (expXのサブフォルダは試行毎に作成される)に結果が保存される。

![yolo02a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/c8fb4d10-426e-86c0-db78-abc8d9f1aa6a.png)


### 映像の物体検出
- [「ＮＨＫクリエイティブ･ライブラリー」様のサイト](https://www2.nhk.or.jp/archives/creative/material/view.cgi?m=D0002021378_00000)から、「「冬のソナタ」のメタセコイア並木」の映像ファイルをダウンロードし、検出対象のソースファイルとして指定する。

```
C:\Users\Administrator\yolov5>python detect.py --source "C:\Users\Administrator\yolov5\winter.mp4"
```
- 映像についても画像と同様に物体検出が可能。

![yolo03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/f8e9c3c1-19b5-cf22-673a-d6e627b90875.png)


# 5. 所感
- 超今更ながらYOLO入門できたので、モデルの作成など引き続き深堀していきたい。
LinuxにてX環境のターミナルでコマンドラインからペーストする方法

# やりたいこと
ターミナルから必要部分を抜き取る部分は扱わない
例えば `ipython` をコマンドラインから起動し、`print('test')`を実行するのを1つのbashスクリプトから行いたい場合
```bash
echo "print('test')" | ipython
```
とすると強制終了する

# コピー
```bash
echo "ls" | xsel -bi
```
# ペースト
```bash
xte 'keydown Control_L' 'keydown Shift_L' 'key v' 'keyup Control_L' 'keyup Shift_L'
```

# 備考
"Linux ペーストする方法"と検索すると `xsel -bi` と `xsel -bo` と `ctrl-V` `ctrl-shift-v` しか出てこなくて困った
[Swift]推定されるジェネリック型の制約

※この記事は[Swift by Sundell](https://www.swiftbysundell.com/tips/inferred-generic-type-constraints/)の内容を日本語に翻訳したものです。

ジェネリック型制約を使用して、特定のAPIが使用される具象型に一連の要件を課すことができます。これにより、ジェネリックコード内でそれらの型について特定の仮定を行うことができます。

たとえば、私たちが取り組んでいるアプリが`NetworkRequest`プロトコルを使用して、さまざまなリクエストを、それぞれ`Response`が期待する種類を宣言するさまざまなタイプとして定義できるようにしているとします。

```.swift
protocol NetworkRequest {
    associatedtype Response: Codable

    func makeURLRequest() -> URLRequest
}
```

このようなリクエストを実行するためのAPIを定義すると、次のような結果になる可能性があります。ジェネリック型制約を使用して、その`T`型が実際に上記のプロトコルに準拠していることを確認する関数です。

```.swift
func perform<T: NetworkRequest>(
    _ request: T,
    then handler: @escaping (Result<T.Response, Error>) -> Void
) {
    ...
}
```

ここで、`NetworkRequestQueue`クラスを使用してリクエストをキューに入れるためのサポートも追加したいとします。これも、`NetworkRequest`プロトコルに制約されたジェネリック型を使用します。

```.swift
class NetworkRequestQueue<Request: NetworkRequest> {
    ...
}
```

上記のクラスのインスタンスを`perform`関数に挿入するためのパラメーターを追加する場合、最初は次のようにパラメーターのリストに追加するだけです。

```.swift
func perform<T: NetworkRequest>(
    _ request: T,
    on queue: NetworkRequestQueue<T>,
    then handler: @escaping (Result<T.Response, Error>) -> Void
) {
    ...
}
```

ただし、`NetworkRequestQueue`クラスでは、`NetworkRequest`プロトコルに準拠するために汎用の`Request`タイプがすでに必要であり、コンパイラは、そのクラスを特殊化するために使用されるタイプがリクエストパラメータに使用されるタイプと同じであることを認識しているため、実際には省略できます。次のように、`perform`関数からの型制約を完全に実行します。

```.swift
func perform<T>(
    _ request: T,
    on queue: NetworkRequestQueue<T>,
    then handler: @escaping (Result<T.Response, Error>) -> Void
) {
    ...
}
```

上記は細かいことのように思えるかもしれませんが、おそらくそれは物事の壮大なスキームにあります—しかし、ジェネリックコードは非常に冗長になる傾向があるため、特に型制約を使用する場合、そのような冗長性を減らすためにできることは間違いなく良いことです。

追加のボーナスとして、上記の`handler`パラメーターのクロージャー型も少し単純にしましょう。最初に、`NetworkRequest`プロトコルの拡張機能内で型エイリアスに変換します。

```.swift
extension NetworkRequest {
    typealias ResponseHandler = (Result<Response, Error>) -> Void
}
```

上記を実行すると、`perform`関数のシグネチャをさらに読みやすくすることができます—次のようになります。

```.swift
func perform<T>(
    _ request: T,
    on queue: NetworkRequestQueue<T>,
    then handler: @escaping T.ResponseHandler
) {
    ...
}
```

Swiftの構文は、ジェネリック型と関数の定義に関しては最初はかなり冗長に見えるかもしれませんが、読みやすさを犠牲にすることなく、そのような定義をはるかにコンパクトにするために使用できる特定のトリックとテクニックがよくあります。

### 元の記事

[Inferred generic type constraints](https://www.swiftbysundell.com/tips/inferred-generic-type-constraints/) Swift by Sundell
WindowsでPythonプログラムへ日本語の引数を引き渡すときの文字化けと対策

## 文字化けの問題
久しぶりWindowsでPythonスクリプトを書くことになりました。セキュリティーの規制でコマンドプロンプトが使えなく、Pythonスクリプトを起動するにはWindowsバッチを使う必要があります。パラメーターとして日本語の文字列を渡すのですが、Pythonプログラム内では(`sys.argv`の中身)文字化けになってしまう事象でした。

```bat
%echo off
C:\python.exe hogehoge.py "あいうえお"
set /p confirm="Enter."
```

Pythonプログラムで標準出力に書く。

```Python
# -*- encoding: utf-8 -*-
import sys

def main():
    if len(sys.argv) > 1:
        print(sys.argv[1])

if __name__ == '__main__':
    main()
```

結果はこうなっています。
![moijbake.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95759/672e1728-de7e-6f13-8e8f-2e632e3fc588.png)


## 解決方法

色々検索して、文字列(`sys.argv`)を`encode`したり、`decode`してみたりしたのですが、効果がなくまたはエラーになりました。

バッチファイルのエンコードとPythonスクリプトのエンコードの両方は UTF-8になっていて、なんで引き渡した後文字化けになっているか原因特定できていないのですが、恐らく文字列を引き渡すときに、エンコードに使っているエンコーディングはUTF-8でないのは確実かと思われます。それで、以下のようにバッチを修正して、コマンドプロンプトの環境のエンコーディング（Windowsではアクティブページ）をUTF-8にすると、うまく文字化けを解決しました。

```bat
%echo off
chcp 65001
C:\python.exe hogehoge.py "あいうえお"
set /p confirm="Enter."
```

以上になります。同じ問題にあった人に役に立てばと幸いです。
YAML書くときにちょっと思い出したいこと

yaml書くときの備忘録です。

# 当たり前
**aa**
- aaa
- aa


+ タブ
禁止。
2個スペースでインデント打とう。

+ 配列のネスト

```
- aaa
-
  - b1
  - b2
  -
    - b3.1
    - b3.2
- ccc
```

+ ハッシュ

:のあとに半角スペースを 1 つ以上いれるのを忘れないで。

```
A: aaa
```

+ ハッシュの中のネスト

```
A: aaa
B:
  B1: bbb1
  B2: bbb2
C: 
  - ccc1
  - ccc2
```


+ [---]

---で区切ることで、ひとつのファイルに複数の YAML ドキュメントを含めることができる

```
---
name: a_name
---
name: b_name
---
name: c_name
```


# 忘れがち

+ フロースタイル

 * 配列
```
[aaa, bbb, ccc]
```

 * ハッシュ
```
{ A: aaa, B: bbb, C: ccc }
```

+ 真偽値

真偽値 (true, yes, false, no)
Null値 (null, ~)


+ …

…だけの行があると、それ以降は読み込まれまない。エラーを特定するときなどに利用
【Unity】ゲーム開発記録（Android / 2D / RPG）

21.08.26
<details><summary>BaseMenuのuGUI(ガワ)</summary>![ezgif-4-65993849410b.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1384531/32da4f0c-963e-0dfa-96c7-afb893d092e0.gif)
「Canvas>Panel(Footer)>各Button」操作時に「BaseManager」内のSetUI()関数を呼び出し、画像・パネル・テキストの変更処理を行う。画像素材やUI配置等は仮なので適当。
</details>

21.09.17
<details><summary>錬金メニューの一覧表示のuGUI(ガワ)</summary>![ezgif.com-gif-maker (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1384531/f4ffdbc0-9c40-23b5-ace6-1d08842528c7.gif)
「ScrollView>ViewPort>Content」に錬金アイテムのインデックスノードを動的に追加。ソートボタン押下でActiveの切替を行う。画像素材やUI配置等は仮なので適当。FF15が楽しすぎてサボりがち良くない。
</details>

21.10.13
<details><summary>錬金システムのuGUI(ガワ)</summary>![ezgif.com-gif-maker.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1384531/c71b30f0-94af-f6fa-c811-b7f66007cfa4.gif)
画像素材やUI配置等は仮なので適当。錬金システム周りのガワは大体終わり。
</details>
[swift]frameと文字の間に余白を設けたUILabelのサブクラスを作る


UIlabelのサブクラスを作るにあたって、init()のところで躓いたので軽くまとめてみました。

# やりたいこと

![8a7ck.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534195/18a04398-7190-5d8f-b4ef-135800f9fff2.jpeg)


上記画像のような、文字とframeの間に余白（赤い部分）を設けたUILabelを作成する為のサブクラスを作ります。

labelはTableViewなどで親Viewの大きさによって可変にしたく、そうなると

- 文字のサイズを指定してLabel自体のサイズを変える（ex.`label.frame.size.width += 10`）

という手法が取れない(`label.frame.size`の値が取得できず0となってしまう為)ので、

今回は文字とframeの距離を固定値で設定するサブクラスを作成します。

# 書いたコード

```.swift
class IndentLabel: UILabel {
    let insets: UIEdgeInsets
    
    init(insets: UIEdgeInsets) {
        self.insets = insets
        super.init(frame: .zero)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func drawText(in rect: CGRect) {
        super.drawText(in: rect.inset(by: insets))
    }
    
    override open var intrinsicContentSize: CGSize {
        var intrinsicContentSize = super.intrinsicContentSize
        intrinsicContentSize.width += (insets.left + insets.right)
        intrinsicContentSize.height += (insets.top + insets.bottom)
        return intrinsicContentSize
    }
}
```

使いたい時は

```.swift
let label = IndentLabel(insets: UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 20))
```

とすると、左右に20ずつ余白のあるLabelが作れます。

# 解説
やっていることを簡単に説明します。

###イニシャライザ

```.swift
    init(insets: UIEdgeInsets) {
        self.insets = insets
        super.init(frame: .zero)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
```

`init()`でインスタンス作成時に引数`insets`を持たせます。

`super.init()`ではスーパークラスのイニシャライザの引数は`frame`なので、`insets`や空っぽではだめです。

私はここの理解が浅かったため、空っぽにしてエラーが出て躓いておりました。。。

### drawText

```.swift
    override func drawText(in rect: CGRect) {
        super.drawText(in: rect.inset(by: insets))
    }
```

ここでテキストを書き出している時に、余白を与えています。


### LabelのautoLayout設定をoverride

AutoLayoutを使うと、Labelの大きさを指定しなくてもテキストのサイズに合わせて自動で表示してくれます。

ただしこれで表示されるのは、「テキストを表示するための最低限のサイズ」のため、

先程のように余白を与えてしまったLabelでは正しく機能してくれません。

そのため、**本来の「テキストを表示する為の最低限のサイズ」**に、`insets`を足した値を

**新たな「テキストを表示する為の最低限のサイズ」**として設定し直します。

それが以下の部分です。

```.swift
    override open var intrinsicContentSize: CGSize {
        var intrinsicContentSize = super.intrinsicContentSize
        intrinsicContentSize.width += (insets.left + insets.right)
        intrinsicContentSize.height += (insets.top + insets.bottom)
        return intrinsicContentSize
    }
```

`intrinsicContentSize`が「テキストを表示する為の最低限のサイズ」を示しています。
シェルスクリプトで大量データのcsvファイル作成！！！

##はじめに

テストで大量データのcsvファイルを作る必要があったので調べてみた結果と、shellのforループとawkどっちが早いのって疑問に思ったのでそれらの結果をQiitaに投稿しました。

##結論

awk はやいぃぃぃぃぃーーーーーーーー！！！

###結果

|作成方法|処理時間|
|:--|--:|:--|
|シェルスクリプト|357秒|
|awk|4秒|

##検証した環境

M1 Mac Book Air
CPU : 8 コア
GPU : 7 コア

のモデルです。

##使用したコード

シェルスクリプト

```shell:test.sh

#!/bim/bash

echo "No,hoge1,hogehoge,piyo,normalID,終了日時,開始日時" >> /Users/username/Desktop/test_1M_by_shell.csv

NO="0"
HOGE1="TEST001"
HOGEHOGE="a"
PIYO="AB9999"
TIME_S="20210824180000"
TIME_F="20210824200000"

for i in `seq 1 1000000`;
do
    NORMALID=$(printf "%020d",${i})
    echo "\"${NO}\",\"${HOGE1}\",\"${HOGEHOGE}\",\"${PIYO}\",\"${NORMALID}\",\"${TIME_S}\",\"${TIME_F}\"" >> /Users/username/Desktop/test_1M_by_shell.csv
done

```

```awk:test.awk

BEGIN {
    printf("No,hoge1,hogehoge,piyo,終了日時,開始日時\n");
    for(i=0;i<1000000;i++){
        printf("\"0\",\"TEST01\",\"a\",\"AB9999\",\"20210824180000\",\"20210824200000\"\n");
    }
}

```

 - awk 実行するコマンド

~~~

awk -f test.awk > /Users/username/Desktop/test_1M_by_awk.csv

~~~
【PHP入門】型と変数について

PHP入門！！
ということで今日は<strong>型と変数について</strong>お話します

まずは代表的な<strong>スカラー型</strong>を紹介します

| 型の名前 | 型の表示 | 型の例|
|:-----------:|:------------:|:------------:|
|論理型|boolean|True/False|
|整数型|integer|1,2,46|
|浮動小数点型|float,double|3.14/1.34|
|文字列型|string|AA/aaa/Hello|

別で<strong>NULL（ヌル）</strong>というものを説明します



次に、<strong>変数について</strong>説明していきます
変数とは箱のようなものです。
プログラムではこの箱の中に何が入っているのかを確認して理解します

PHPでは変数を受け取る時に<strong>＄変数名</strong>になります

```index.php
<?php
   $name = "山田太郎";
   echo $name ;
?>
```
```結果
山田太郎
```


次は<strong>結合演算子について</strong>です

結合演算子というのは(.)で結合します
説明するよりプログラムを書いた方がいいと思うのでプログラムを書いてみます

index.phpは変数名のみで出力しています。
ではこの変数に色んなことをつけてみましょう

```index.php
<?php
   $name1 = "山田太郎";
   $name2 = "田中太郎"

   echo "ようこそ". $name1 . "です";
   echo "ようこそ". $name2 . "です";

?>
```

```
ようこそ、山田太郎です
ようこそ、田中太郎です
```

これを簡単にするためには配列やfor文を駆使してコードを書けばいいわけです
【Swift】郵便番号が存在するか確認するコード

入力した郵便番号が存在するか確認するコード。

```swift
    let geocoder = CLGeocoder()
    geocoder.geocodeAddressString("1000012", completionHandler: {(placemarks, error) -> Void in
        if((error) != nil){
            print("error")
        }
        if let placemark = placemarks?.first {
            print("success!")
        }
    })

```
参考：

https://qiita.com/k-yamada-github/items/5ce29b3c30397104461e

## Swiftのお役立ち情報

https://wagtechblog.com/programing/swift-iphone-application-school

https://wagtechblog.com/programing/swift-textbook.html
SpringBootのapplication.ymlの環境別読み込みの方法

<h1>環境変数を使う</h1>
起動オプションで指定する方法もあるみたいだが、現状はIntelliJから起動したり、eclipseから起動したり、VSCodeから起動したりするのでこっちの方が楽な気がした。

application-xxx.ymlという名前の設定ファイルを用意する。
環境変数にSPRING_PROFILES_ACTIVEというKEYを作成し、先に作ったapplication-xxx.ymlのxxxの部分をValueに指定する。
そのまま実行。IntelliJだとIDEを再起動しないと環境変数を読み込んでくれなった。
うまくいかない場合は環境変数のリロードを試すべき。
[Android]Android Gradle Plugin 7+へ更新後にビルドしたアプリを起動して ClassNotFoundException が発生した時の対処法

業務で開発しているプロジェクトで Android Gradle Plugin を 7.0.1 に更新したのですが、ビルドしてアプリを起動するとアプリが強制終了してしまいました。

その際に以下のようなログ（一部抜粋）が出力されていました。

```
E/LoadedApk: Unable to instantiate appComponentFactory
    java.lang.ClassNotFoundException: Didn't find class "androidx.core.app.CoreComponentFactory" on path: DexPathList[...]
```

Google Issue Tracker で検索してみたところ、どうやら [こちら](https://issuetracker.google.com/issues/196406764) が該当の問題のようでした。

どうやら R8 の問題のようで https://issuetracker.google.com/issues/196406764#comment22 のコメントにあるように、以下のように R8 のバージョンを明示的に指定することでアプリが強制終了することがなくなりました。

```groovy:build.gradle
buildscript {

    repositories {
        maven {
            url 'https://storage.googleapis.com/r8-releases/raw'
        }
        ...
    }

    dependencies {
        classpath 'com.android.tools:r8:3.0.68' // Must be before the Gradle Plugin for Android.
        classpath 'com.android.tools.build:gradle:7.0.1' 
     }
}
```

注意点としては R8 のクラスパスは Android Gradle Plugin より前に宣言する必要があります。

暫定的な対応かと思いますが、同じようなエラーで困っている方の手助けになれば幸いです。
windowsにjenkinsをインストールしようとするとstart serviceでエラーになる時の回避方法

jenkinsをwindowsにインストールしようとしたらエラーになった。
jenkinsサービスがスタートできないというダイアログ。

admin権限あってもダメでなぜかなと思って調査。

https://serverfault.com/questions/287729/jenkins-install-service-start-failure

- windowsがサーバー証明書を探しているがサーバーに繋がらない
- ちゃんとサーバーに接続するようにするのが最善
- 設定ファイルで無効にすればいい（インストールしさえすりゃ問題ない）

ということっぽい。おかしいなと思って管理者とかに色々聞いてみたが、ネットワークや権限周りは問題ないとのこと。

もう少し調査していると、jenkinsで利用するjavaは、`jdk11とかじゃないと初期化に失敗する`　という記事を発見。
試しにjdk11インストールしたらそのままサクッとインストールできた。

jdk16でも大丈夫やろ！って、なんとなくインストールするとこうなるという話・・・・w
シェルで標準入力を逆順に出力する

tac コマンドを使う

```bash
$ tac -
hoge
fuga
pien
# ここで Ctrl+D
pien
fuga
hoge
```

tac は cat をひっくり返した文字列だからこうなってるらしい。
こういう遊び心好き。


#### (2021/08/26 17:46追記)

行内でひっくり返すコマンド `rev` もあるらしい

```
$ echo 'hoge
> fuga
> pien' | rev
egoh
aguf
neip
```
rails db:migrateコマンドとmigrateファイルの記述について


マイグレーションの状態を調べるコマンド

```
rails db:migrate:status
```


マイグレーション実行するコマンド

```
rails db:migrate
```

マイグレーションの状態を一つ下げるコマンド（down）

```
rails db:rollback
```

「実際にpostsテーブルを作成する」という仕様がマイグレーションファイルに記載


```
create_table :posts do |t|
```


カラムの形を入力：カラム名、NOT NULL制約

カラム名を指定するとともに、そこにどんなデータが入るのかを示す「型」も指定する必要


```
t.型 :カラム名,　　　　　　　　　　　　　　　　 null: false
```

カラムの型↓
＜integer　＞　　　数値　　　金額、回数など
＜string　　＞　　　文字(短文)ユーザー名、メールアドレスなど
　＜　text　＞　　　　　文字(長文)投稿文、説明文など
　＜boolean＞　　　真か偽か、はい・いいえの選択、合格・不合格のフラグなど
　＜datetime＞　日付と時刻　作成日時、更新日時など

NOT NULL制約は、テーブルの属性値にNULL（空の値）が入らないように制限する制約です。



外部キーの記述

```
t.references :カラム名,  foreign_key: true
```

外部キーとは、関連する他のテーブルのレコードの主キーを値とする項目のことです。
そして、外部キー制約とは、外部キーのデータに対応するレコードが必ず存在することを保証する制約です。
DBのリレーション


#1：多
（会社）ー（社員）の関係
hasMany
#多：多
（社員）ー（サークル）の関係
belongsToMany

→中間（交差）テーブルを使う
#1：1
（社員）ー（個人情報）の関係
hasOne


#参考記事
https://qiita.com/yukachin0414/items/726f3cbf4270f50f6028
Shifterは独自ドメインを適用しないとrobots.txtにDisallow: /が追加される

#Shifterは独自ドメインを適用しないとrobots.txtにDisallow: /が追加される

サポートに質問すると、上記の仕様と回答いただきました。

##WordPress起動中
`Start WordPress` で起動中にrobots.txtを確認すると一般的なWPで生成されるものと同じ
ここで指す `${Preview Shifter Domain}` は、起動中のWP Dashboardのドメイン

```robots.txt
User-agent: *
Disallow: /wp-admin/
Allow: /wp-admin/admin-ajax.php

Sitemap: ${Preview Shifter Domain}/wp-sitemap.xml
```

##Shifter Generate後
WordPressをStopさせて Generate すると下記が生成される
ここで指す `${Public Shifter Domain}` は、Shifter管理画面Site OverviewのURL

```robots.txt
User-agent: *
Disallow: /wp-admin/

Sitemap: ${Public Shifter Domain}/wp-sitemap.xml

Disallow: /
```
東京都の国のステージ判断のための指標のPDFからCSV作成（camelot）

pdfplumber
https://qiita.com/barobaro/items/75d076f4fbe9771a0b3a

Twitterにcamelotだと変換できないと書いてたのでcamelotで作成

latticeだと「process_background=True」で取得はできるが、表になってないので加工が必要　※めんどくさい

streamで変換

+ camelotの範囲指定しても範囲絞り込めない
+ デフォルトの「edge_tol=50」 だと取り込み範囲が表以外も含まれるため+10してみると「edge_tol=60」表の範囲が取得できた
+ 行間が大きいので「row_tol=40」で調整、10から+10していっただけ
+ 「病床のひっ迫具合」が「入院率」と結合されてしまっているのでPython版は修正

# ダウンロード

```
!wget https://www.fukushihoken.metro.tokyo.lg.jp/iryo/kansen/corona_portal/info/kunishihyou.files/kuni0824.pdf -O data.pdf
```

# コマンド
```
camelot -p 1 -o data.csv -f csv stream -e 60 -r 40 data.pdf
```

# Python
```python
import camelot

tables = camelot.read_pdf(
    "data.pdf", flavor="stream", edge_tol=60, row_tol=40, strip_text=" \n"
)

df = tables[0].df

df.iat[6, 0] = "入院率"

df

df.to_csv("data.csv", index=False, header=False)
```
Cannot declare conformance to 'NSObjectProtocol' in Swiftへの対応

#はじめに
mapにピンを立てる際に、カスタムなアノテーションを用意してMKAnnotationを継承させたときに、`「Cannot declare conformance to 'NSObjectProtocol' in Swift」`とエラーが出ました。

```swift
final class CustomAnnotation: MKAnnotation {}
```

#環境
[Swift] Version 5.3.2
[iOS] Version 14.4

#エラーへの対応
`「Cannot declare conformance to 'NSObjectProtocol' in Swift」`
そのままですが、Swiftでは、私たちが`NSObjectProtocol`の継承を直接宣言できないらしいです。
`NSObjectProtocol`は、すべてのObjective-Cオブジェクトの基本となるメソッドのグループです。
>The group of methods that are fundamental to all Objective-C objects.
(https://developer.apple.com/documentation/objectivec/nsobjectprotocol)

Cocoaのルートクラスである`NSObject`は、このNSObjectProtocolを継承しているので全てのメソッドを使用できます。

```swift
open class NSObject : NSObjectProtocol
```
なので、対応としては`NSObjectを継承`すれば大丈夫です。

MKAnnotationがNSObjectを継承したオブジェクトと思い込んでいたのですが、「Jump to Definition」すると実際はNSObjectProtocolに準拠したプロトコルでした。

```swift
public protocol MKAnnotation : NSObjectProtocol 
```

#最後に
思い込みで少しつまづきましたが、まずは素直に「Jump to Definition」、「公式ドキュメントを読む」、「エラーをよく読む」というのが大事ですね。。

#参考文献
この記事は、以下の情報を参考にしました。

- [NSObjectProtocol](https://developer.apple.com/documentation/objectivec/nsobjectprotocol)
- [Type "xxx" does not confirm to protocol 'NSObjectProtocol'エラーが出る場合の対処法](https://qiita.com/hajime-u/items/78b552803a02c76c63dd)
MixedReality-WebRTCをPackagesからAssetsに移動する

# 目的

- MixedReality-WebRTC Unity用ライブラリのソースコードの解析したい
- MixedReality-WebRTCのサンプルシーンを閲覧したい
- Packages以下だと作業しづらい＆シーンが開けないので、Assets以下に移動する

# 環境

- Windows 10
- Unity 2020.3.14f1
- MixedRealityFeatureTool-1.0.2104.4-Beta
- MixedReality-WebRTC 2.0.2


# MRTK WebRTCをインストール

- MixedRealityFeatureToolを使って、MixedReality-WebRTCをインストール
- `manifest.json` に以下の2行が追加される

```js
{
  "dependencies": {
    "com.microsoft.mixedreality.webrtc": "file:MixedReality/com.microsoft.mixedreality.webrtc-2.0.2.tgz",
    "com.microsoft.mixedreality.webrtc.samples": "file:MixedReality/com.microsoft.mixedreality.webrtc.samples-2.0.2.tgz"
  }
}
```

- 以下の2ファイルが作成される

```
%PROJECT_PATH%\Packages\MixedReality

com.microsoft.mixedreality.webrtc-2.0.2.tgz
com.microsoft.mixedreality.webrtc.samples-2.0.2.tgz
```

## 参考

-  MixedRealityFeatureToolの使い方

https://docs.microsoft.com/en-us/windows/mixed-reality/develop/unity/welcome-to-mr-feature-tool



# トラブル「サンプルシーンが開けない」

- Packages以下にサンプルのシーンがあるようだが、
- Unity 2020.xだと、Packages以下のシーンが開けないようだ

https://github.com/microsoft/MixedReality-WebRTC/issues/526

## Packages から Assets に移動

- 2つのtgzファイルを別の場所に保存する
- `manifest.json` の2行を削除する
- 2つのtgzを展開して、Assets 以下に移動（エクスプローラーでファイルを移動せず、Unity Editorにドラッグ＆ドロップして移動）
  - WebRTCライブラリの方もソースコード解析しやすいように、Assets以下に移動
  - サンプルのシーンを開きたいだけならば、WebRTCライブラリはPackages以下（UPM管理）でよい


# トラブル「WebRTCライブラリをPackagesからAssetsに移動するとエラーが発生」

- com.microsoft.mixedreality.webrtc-2.0.2をAssets以下に移動後
- PeerConnectionを付与したゲームオブジェクトをUnity Editorで開くと以下のエラーが発生する

```
NullReferenceException: Object reference not set to an instance of an object
Microsoft.MixedReality.WebRTC.Unity.Editor.PeerConnectionEditor.DrawSpriteIcon (Microsoft.MixedReality.WebRTC.Unity.Editor.PeerConnectionEditor+IconType type, UnityEngine.Rect rect) (at Assets/com.microsoft.mixedreality.webrtc-2.0.2/package/Editor/PeerConnectionEditor.cs:57)
```

## 対応方法

- アイコンファイルの読み込みに失敗しているのでパスを修正する

```csharp:Assets/com.microsoft.mixedreality.webrtc-2.0.2/package/Editor/PeerConnectionEditor.cs(L.74)

var objects = AssetDatabase.LoadAllAssetsAtPath("Assets/com.microsoft.mixedreality.webrtc-2.0.2/package/Editor/Icons/editor_icons.png");
//var objects = AssetDatabase.LoadAllAssetsAtPath("Packages/com.microsoft.mixedreality.webrtc/Editor/Icons/editor_icons.png");

```


# 課題

- MixedReality-WebRTC C/C++側、C#側のライブラリのソースも解析したいが、どのようにするのがよいか現状、把握できていない
PHPの便利な関数一覧

# 概要
PHPが用意している便利な関数について投稿した記事一覧

# 記事一覧
#### [PHPの便利な関数(1)](https://qiita.com/andota05/items/41bbe57d30a1b9fbc4f3)

* ini_set( )
* require( )
* require_once( )
* array( )
* define( )

#### [PHPの便利な関数(2)](https://qiita.com/andota05/items/e9ccf79711775243979e)

* mb_strlen( )
* mb_strtolower( )
* mb_strtoupper( )
* trim( )
* file_exists( )

#### [PHPの便利な関数(3)](https://qiita.com/andota05/items/4488851f39a2b1fcb3fd)

* fopen( )
* fgets( )
* fclose( )
* array_merge( )
* impload( )

#### [PHPの便利な関数(4)](https://qiita.com/andota05/items/8a6cdbeab5a56f442216)

* array_key_exists( )
* sprintf( )
* empty( )
* isset( )
* is_array( )
PHPの便利な関数(3)

# 概要
* PHPが用意している便利な関数について、忘備録として記載していく。
* また、PHP7系を前提とする。
* 右記
[PHPの便利な関数一覧](https://qiita.com/andota05/items/fc80d2210810a36ec156)
に他の関数について記載した一覧を作成しています。

# ラインナップ
* fopen( )
* fgets( )
* fclose( )
* array_merge( )
* impload( )

## fopen( )
* ファイルまたは ファイルが存在するURL をオープンする(開く)
* 第一引数に開きたいファイルの指定、第二引数にオープンモードを指定
* オープンモードは「r (読み込みのみ)」「w (書き込みのみ)」などが存在する

https://www.php.net/manual/ja/function.fopen.php

```read.txt
読み込まれた
```

```test.php
// 例：read.txtを読み込みようとして開く
$read_file = fopen(__DIR__ . '/read.txt', 'r');
echo fgets($read_file);
```

```
php ./test.php
読み込まれた
```

## fgets( )
* ファイルポインタから1行取得する
* 読み込むデータがない場合はfalseを返す
* 複数行ある場合はwhile文などと組み合わせて読み込む

https://www.php.net/manual/ja/function.fgets.php

```read.txt
読み込まれた
ありがとう
```

```test.php
// while文と組み合わせて複数行を読み込む
$read_file = fopen(__DIR__ . '/read.txt', 'r');
while (($line = fgets($read_file))){
    echo $line;
} 
```

```
php ./test.php
読み込まれた
ありがとう
```

## fclose( )
* オープンされたファイル(ファイルポインタ)をクローズする
* fopenで正常にオープンされたファイルポインタでなければならない
* 成功した場合に true を、失敗した場合に false を返す。

https://www.php.net/manual/ja/function.fclose.php

```read.txt
読み込まれた
ありがとう
```

```test.php
// fopenでファイルをオープンし、読み込む
$read_file = fopen(__DIR__ . '/read.txt', 'r');
fgets($read_file);

// fopenしたファイルを閉じる 
echo fclose($read_file);
```

```
php ./test.php
1
```

## array_merge( )
* 配列をマージすることが可能
* 引数で後に指定した配列を前に指定した配列に追加する形になる

https://www.php.net/manual/ja/function.array-merge.php

```test.php
// array1,2を定義
$array1 = array(1, 2, 3);
$array2 = array(4, 5, 6);

// 2つの配列をマージ($array1に$array2を追加するイメージ)
$merge_array = array_merge($array1, $array2);
// 添字も振りなおされる
echo $merge_array[3];
```

```
php ./test.php
4
```

## implode( )
* 配列に指定した区切り文字を付加し、文字列として連結することが可能

https://www.php.net/manual/ja/function.implode.php

```test.php
// array1を定義
$array1 = array(1, 2, 3);

// 第一引数に区切り文字、第二引数に配列を指定
$implode_str = implode(':', $array1);
echo $implode_str;
```

```
php ./test.php
1:2:3
```
PHPの便利な関数(2)

# 概要
* PHPが用意している便利な関数について、忘備録として記載していく。
* また、PHP7系を前提とする。
* 右記
[PHPの便利な関数一覧](https://qiita.com/andota05/items/fc80d2210810a36ec156)
に他の関数について記載した一覧を作成しています。

# ラインナップ
* mb_strlen( )
* mb_strtolower( )
* mb_strtoupper( )
* trim( )
* file_exists( )

## mb_strlen( )
* 文字列の長さを取得可能

https://www.php.net/manual/ja/function.mb-strlen.php

```test.php
// 変数strの長さを取得
$str = "3文字";
echo mb_strlen($str);
```

```
php ./test.php
3
```

## mb_strtolower( )

*   文字列(アルファベット)を全て小文字にする
*   ひらがな、数字、記号はそのまま

https://www.php.net/manual/ja/function.mb-strtolower.php

```test.php
// 変数strを小文字に変換
$str = 'ABCDEFG';
echo mb_strtolower($str);
```

```
php ./test.php
abcdefg
```

## mb_strtoupper( )

*   文字列(アルファベット)を全て大文字にする
*   ひらがな、数字、記号はそのまま

https://www.php.net/manual/ja/function.mb-strtoupper.php

```test.php
// 変数strを大文字に変換
$str = 'abcdefg';
echo mb_strtoupper($str);
```

```
php ./test.php
ABCDEFG
```

## trim( )

* 文字列の前後にある空白(ホワイトスペース)を削除
* 第二引数を指定すると指定文字列を削除(※先頭に空白があると上手く動作しない)

https://www.php.net/manual/ja/function.trim.php

```test.php
// 変数strの文字列前後にある空白(ホワイトスペース)を削除
$str = ' space ';
echo trim($str);
```

```
php ./test.php
space
```

```test.php
// 変数strの文字列から指定文字を削除
$str = 'space';
echo trim($str, 's');
```

```
php ./test.php
pace
```

## file_exists( )

* ファイルまたはディレクトリが存在するかどうか調べる
* 存在した場合は、trueが返される
* 存在しない場合は、falseが返される

https://www.php.net/manual/ja/function.file-exists.php

```test.php
//　実在するtarget/target.txtファイル
$target = __DIR__ . '/target/target.txt';
var_dump(file_exists($target));
```

```
php ./test.php
bool(true)
```

```test.php
//　実在しないtarget/none.txtファイル
$target = __DIR__ . '/target/none.txt';
var_dump(file_exists($target));
```

```
php ./test.php
bool(false)
```

```test.php
//　実在するtargetディレクトリ
$target = __DIR__ . '/target';
var_dump(file_exists($target));
```

```
php ./test.php
bool(true)
```

```test.php
//　実在しないnoneディレクトリ
$target = __DIR__ . '/none';
var_dump(file_exists($target));
```

```
php ./test.php
bool(false)
```
PHPの便利な関数(1)

# 概要
* PHPが用意している便利な関数について、忘備録として記載していく。
* また、PHP7系を前提とする。
* 右記
[PHPの便利な関数一覧](https://qiita.com/andota05/items/fc80d2210810a36ec156)
に他の関数について記載した一覧を作成しています。

# ラインナップ
* ini_set( )
* require( )
* require_once( )
* array( )
* define( )

## ini_set( )
* PHPの設定を設定ファイル(php.iniなど)を触らずに、指定可能
* ini_get( )で設定情報を取得可能

https://www.php.net/manual/ja/function.ini-set.php

```test.php
// 例：PHPのメモリ使用上限を設定
ini_set('memory_limit', '2048M');
echo ini_get('memory_limit'); // 2048M
```

## require( )

* 機能を分割した.phpファイルなど外部ファイルを読み込む
* .phpファイルでなくても読み込み可能

https://www.php.net/manual/ja/function.require.php

```require.php
// 読み込まれる側
$load_file = '読み込まれています';
echo $load_file;
```

```test.php
// 読み込む側(同じ階層にある前提)
require(__DIR__ . '/require.php');

// こんな書き方もできる
require __DIR__ . '/require.php';
```

```
php ./test.php
読み込まれています
```

## require_once( )
* 目的としてはrequireと同じく、外部ファイルを読み込む
* 違いは`すでに読み込まれている場合は、再読み込みしない`

https://www.php.net/manual/ja/function.require-once.php

```require.php
// 読み込まれる側
$load_file = '読み込まれています';
echo $load_file;
```

```test.php
// 同じファイルをrequireした場合
require(__DIR__ . '/require.php');
require(__DIR__ . '/require.php');
```

```
php ./test.php
読み込まれています読み込まれています
```

```test.php
// 同じファイルをrequire_onceした場合
require(__DIR__ . '/require.php');
require_once(__DIR__ . '/require.php');
```

```
php ./test.php
読み込まれています
```

```test.php
// ちなみに同じファイルをrequire_onceの後にrequireした場合
require_once(__DIR__ . '/require.php');
require(__DIR__ . '/require.php');
```

```
php ./test.php
読み込まれています読み込まれています
```

## array( )
* 配列を作成できる

https://www.php.net/manual/ja/function.array.php

```test.php
// 変数arrayに配列を代入
$array = array('Zero', 'One', 'Two');
echo $array[0];
```

```
php ./test.php
Zero
```

## define( )
* 定数を定義可能
* PHP7以降配列でも指定可能

https://www.php.net/manual/ja/function.define.php

```test.php
// 定数STATEを定義
define('STATE', '定義されています');
echo STATE;
```

```
php ./test.php
定義されています
```

```test.php
// 定数STATEを配列で定義
define('STATE', ['STATEの0', 'STATEの1', 'STATEの2']);
echo STATE[0];
```

```
php ./test.php
STATEの0
```
Anaconda インストール後の conda install がエラー (proxy 設定は正しい) → urllib3 1.26 のバグ [2021.8.26] 

Anaconda (miniconda) を proxy環境下で 新規ubuntu PCに導入後にハマったのでメモを投稿

proxy設定は何度確認しても正しいのに、なぜか conda install 等の web経由系のコマンドがエラーになる。
結論、原因は Anaconda に含まれる urllib3 というライブラリの不具合でした。
そのため、このパッケージが含まれない、少し古いAnaconda(Miniconda)をまず導入して全体アップデートで解決。

urllib3 の不具合のせいで conda install が使えなくなるので、代わりにまず conda上のpip を用意して
conda上のpipを用いて urllib3 だけをダウングレードさせるのがポイント

### 導入手順
Step 1) ubuntu bash の proxy を正しく設定 (.profile or .bashrc)
Step 2) Anaconda(Miniconda) の少し古い (urllib3 が 1.26より古いもの) を取ってきてインストール
Step 3) Anaconda の proxy を正しく設定 (.condarc)
Step 4) (Minicondaの場合) まず conda のbase環境上で pip をインストール
Step 5) conda のbase環境をアップデート (このとき urllib3 も 1.26 にアップデートされてしまうので・・・)
Step 6) conda のbase環境上のpipを用いて、urllib3 を 1.25にダウングレード

今後 urllib3 の不具合が改善されればこの問題自体が無くなると思いますが、
私のように今 (2021.8.26時点) 困っている人がいるかもしれないので、念のため投稿しました。
デカルト座標系(Cartesian Coordinate System)あるいは直交座標系(Orthogonal Coordinate System)における基底ベクトルと位置ベクトル

**デカルト座標系**(Cartesian Coordinate System)あるいは**直交座標系**(Orthogonal Coordinate System)における**基底ベクトル**と**位置ベクトル**の設定は以下となります。

#二次元(<font color=blue>xy/rθ座標系</font>)の場合
[2次元極座標系の運動方程式](https://physnotes.jp/mechanics/pol2-coordinate-system/)<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597772/ccf1583f-ac89-6e22-10a8-c225d95b53eb.png)

* xy座標系

```math
e_x=\begin{pmatrix} 1 \\ 0 \end{pmatrix},e_y=\begin{pmatrix} 0 \\ 1 \end{pmatrix}\\
r=\begin{pmatrix} x \\ y \end{pmatrix}=xe^x+ye^y
```
* 対応する**極座標系**(Polor Coordinate System)(r,θ)への変換式

```math
e_r=\sin(θ)e^x+\cos(θ)e^y\\
e_θ=-\sin(θ)e^x+\cos(φ)e^y
```

* デカルト座標系(x,y,z)への逆変換式

```math
e_x=\cos(θ)e^r-\sin(θ)e^θ\\
e_y=\sin(θ)e^r+\cos(θ)e^θ
```

#三次元(<font color=blue>xyz/rθφ座標系</font>)の場合
[極座標系の基底ベクトル](https://risalc.info/src/polar-coordinate-basis.html)<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597772/c233dc4d-8f0a-deb7-2b09-ef1a762d10fe.png)

```math
e_x=\begin{pmatrix} 1 \\ 0 \\ 0 \end{pmatrix},e_y=\begin{pmatrix} 0 \\ 1 \\ 0 \end{pmatrix},e_z=\begin{pmatrix} 0 \\ 0 \\ 1 \end{pmatrix}\\
r=\begin{pmatrix} x \\ y \\ z \end{pmatrix}=xe^x+ye^y+ze^z
```
* 対応する極座標系()(r,θ,φ)への変換式

```math
e_r=\sin(θ)\cos(φ)e^x+\sin(θ)\sin(φ)e^y+\cos(θ)e^z\\
e_θ=/cos(θ)\cos(φ)e^x+\cos(θ)\sin(φ)e^y-\sin(θ)e^z\\
e_φ=　-\sin(φ)e^x+\cos(φ)e^y
```

* デカルト座標系(x,y,z)への逆変換式

```math
e_x=\sin(θ)\cos(φ)e^r+\cos(θ)\cos(φ)e^θ-\sin(θ)e^φ\\
e_y=\sin(θ)\sin(φ)e^r+\cos(θ)\sin(φ)e^θ+\cos(θ)e^φ\\
e_z=　\cos(φ)e^r-\sin(φ)e^θ
```
とりあえず、以下続報…
pythonでExcelを出力するとハイパーリンクが消える問題

#Excelのハイパーリンクが消える
以前から使用していた自家製システムの挙動がおかしくなったのは、一度MACを工場初期化状態に戻して構築し直してから。
下のかんじで、Excel上のURLがハイパーリンクとして認識されない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1927744/e456d277-3e00-2f20-1ecc-9a7494aa951a.png)

###自家製システムについて

取得したデータをソートしてExcelに出力するという単純なもの。
フローは以下。

1. 情報の取得してリスト化
2. openyxlでExcelに追記、cell.hyperlinkでハイパーリンクの設定をしている
3. pandasでソート
4. pandasでデプリケートチェックして重複は削除
5. 出力


###環境差分

|  | 正常挙動する環境 | 今回の不具合環境 |
|:-:|:-:|:-:|
|  OS  |  macOS Big Sur バージョン不明  |  macOS Big Sur v11.5.1  |
|  Excel  |  Excel for Mac サブスク版  |  Excel for Mac サブスク版  |
|  開発ソフト  |  spider  |  pycharm  |
|  python  |  v3.8.3  |  v3.8.6  |
|  pandas  |  v1.0.5  |  v1.3.1  |
|  openyxl  |  v3.0.4  |  v3.0.7  |

差分ありすぎて、これは切り分けめっちゃたいへん・・・


#いざ！切り分け

##pythonを、ターミナルから直実行
変わらずハイパーリンクにならないのでpycharmの問題でもpythonの問題でもなさそう。

##excelのHYPERLINK関数の利用
Excelに直接
=HYPERLINK("https://www.amazon.co.jp/","aaa")
と入力するとハイパーリンクになることを確認。

そして、
フローの[2]cell.hyperlinkを以下に変更。

```Python
sheet.cell(row=rowmax, column=url_column+1).value = '=HYPERLINK("https://www.amazon.co.jp/", "aaa")'
```
結果は、なんと空。関数自体が削除された。
もしかするとExcelの問題かもしれない。。。と念頭におきつつ次の切り分け。

#pandasをコメントアウトしてみる
フローの[3],[4]だけコメントアウトしたところ、ハイパーリンクが表示される！
ということは、これはpandasをいじれば解決できるのか・・・？

フローの[3],[4]の問題のコードは以下。

```Python
    print ('start deplicate　check.')
    #DataFrameにExcelの読み込み
    df = pd.read_excel(file_path, header=None, engine='openpyxl')
    
    #フラグを基準にして降順（False）にソート
    df_flg_sort = df.sort_values(by=[flag_column,next_flag_column], ascending=False)
    
    # 重複行の上を削除して下を残す
    df_deplicate_delete = df_flg_sort.drop_duplicates(subset=url_column, keep='first')

    # 上書き保存
    df_deplicate_delete.to_excel(file_path, index=False, header=False)

```

色々調べてると、 pandasの仕様でURLが255を超過すると文字列として認知されることが判明。
ExcelWriterのオプションでoptions={'strings_to_urls':False}を指定することで、この機能をオフにできるとのこと。
読み込んでるURLは254文字以下のものばかりなのでこれが該当するかはわからんがやってみる。

```Python
    print ('start deplicate　check.')
    #DataFrameにExcelの読み込み
    df = pd.read_excel(file_path, header=None, engine='openpyxl')
    
    # フラグを基準にして降順（False）にソート
    df_flg_sort = df.sort_values(by=[flag_column,next_flag_column], ascending=False)
    
    # 重複行の上を削除して下を残す
    df_deplicate_delete = df_flg_sort.drop_duplicates(subset=url_column, keep='first')

    writer = pd.ExcelWriter(file_path, index=False, header=False, options={'strings_to_urls':False})
    df_deplicate_delete.to_excel(writer)
    writer.close()
```

結果。だめ。ハイパーリンクならず。
どうやら、ただ、Excelを読んで、上書き保存するだけでハイパーリンクが消えてしまうみたい。
ソートや重複削除は一旦考えない。
.
.
.

ここまで考えてきて、ふと思った。
pandasで定義するのって、データフレーム型だから、ハイパーリンクとか定義できなくない？
pandas.DataFrameがもつ値は、value（値）、column（列）、index（行）のみ。

ということは、これまでシステムの力だと思ってたけど、
Excelパワーでhttps://〜〜〜を自動でハイパーリンクにしてくれてただけか！！


#結論
システム側でハイパーリンク化を有効にするには、データフレーム使わずにソートとデプリケートを実施するしかない。
Node.js（axios）からDirectCloud-BOX APIでファイルのDL #linedc


DirectCloud-BOX APIのAPIを触ってみてました。

[前回の記事](https://qiita.com/n0bisuke/items/35659ffdf00f2158da98)までで、トークン取得、ファイルのアップロードができてるのでファイル取得も試してみます。

[ファイルのダウンロードのAPI](https://directcloud.jp/api_reference/detail/%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC/File#%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E3%83%80%E3%82%A6%E3%83%B3%E3%83%AD%E3%83%BC%E3%83%89)を使ってみました。

## downloadのAPIをNode.jsから

基本はアップロードのときと同様ですが、file_seqの値を入れてあげる必要があります。

アップロードしたときのレスポンスに値があるのでそれを使えば大丈夫です。

```js
'use strcit';

const axios = require('axios');
const FormData = require('form-data');

const token = `xxxxxxxxx`;

const BASE_URL = `https://api.directcloud.jp`;
const URL = `${BASE_URL}/openapp/v1/files/download/1?lang=eng`

const main = async () => {

    const bodyFormData = new FormData();

    const file_seq = 000000000; //アップロードしたときにresponseで帰ってくる値です。
    bodyFormData.append('file_seq', file_seq);

    const res = await axios.post(URL, bodyFormData, {
        headers: {
            access_token: token,
            ...bodyFormData.getHeaders()
        }
    });
    console.log(res.data);
};

main();
```

実行してみると、URLが発行されました。

```bash
$ node playground/dl.js 
{
  success: true,
  download_url: 'https://cdn.directcloud.jp/mdmvslth/tvwvmsgt/20210825202948435483?response-con...'
}
```

ブラウザでアクセスすると直接DLしようとしてきます。

> ![スクリーンショット 2021-08-26 12.20.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/c3796d2c-4fb8-7d32-ce74-408e70517250.png "スクリーンショット 2021-08-26 12.20.11.png")

## おまけ LINEで表示する

このURLをLINE Messaging APIの画像メッセージに設定すればLINE上で画像表示もできます。

```js
const url = `API経由で取得した、DirectCloud-BOXのDLリンク`
const messages = [{
    type: 'image',
    originalContentUrl: url,
    previewImageUrl: url
}];
```

> 参考: [Node.jsでLINE BOTの画像送信を試す](https://qiita.com/n0bisuke/items/e2894a6186a9350dc09d)


動かすとこんな感じ。2件目が画像です。1件目はテストでテキストを送ってます。

> ![スクリーンショット 2021-08-26 12.35.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/8943d2ba-19fb-6ff4-2285-e37e0b310aaa.png "スクリーンショット 2021-08-26 12.35.24.png")


### コピペ用

ほぼこちらのコードくらいなので書くほどでもないでが一応コピペ用を置いておきます。

> [友達全員にメッセージを送るシンプルな送信専用LINE BOTを作る【Node.js】 #linedc](https://qiita.com/n0bisuke/items/7c2616068cb918ba31a5)

```js
'use strict';

const line = require('@line/bot-sdk');

const config = {
    channelSecret: 'LINE Botのチャンネルシークレット',
    channelAccessToken: 'LINE Botのチャンネルアクセストークン'
};
const client = new line.Client(config);


const main = async () => {
    const url = `https://cdn.directcloud.jp/mdm~~~~~`
    const messages = [{
        type: 'image',
        originalContentUrl: url,
        previewImageUrl: url
    }];

    try {
        const res = await client.broadcast(messages);
        console.log(res);        
    } catch (error) {
        console.log(`エラー: ${error.statusMessage}`);
        console.log(error.originalError.response.data);
    }
}

main();
```

## 所感など

LINEで見れるのはやはり便利！

↓こんなの作ってます。

> [紙で申請を出す居酒屋店員のシフト希望と管理業務をちょっとスマートにする](https://qiita.com/n0bisuke/items/0c6d6a236b31e3897d41)
> https://protopedia.net/prototype/2384
mqtt.Storeを試す

#前提

IoTで最も多く利用される通信プロトコルといえばMQTTだと思いますが、
- 通信が途切れたときも、データはちゃんと送信して欲しい
- 通信が途切れてデータを内部にキャッシュしている状態でデバイスを再起動しても、データを復元して送ってほしい
と思っていました。そこで、調べてみたら[mqtt.Store()](https://github.com/mqttjs/MQTT.js#mqttstoreoptions)というオプションがあり、デバイス内部にデータをキャッシュしておく事ができるため、その動作を調べてみました。


## 評価環境
送信用クライアントのネットワークを切ったり、電源をオフしたりして、確認用クライアントで受信したデータを確認する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136933/5332398f-f781-be4a-97df-5198c95d4be3.png)


## 結果
送信用クライアントの通信が復活したときにデータが届くこと、通信切れのまま再起動させたあと再起動後に未送信だったデータが正しく届くことが確認できました。

## 使い方

評価に利用したコードはこの様な感じ。

```javascript:
const mqtt = require('mqtt');
const NeDBStore = require('mqtt-nedb-store');
const manager = NeDBStore('./cache',{ outgoing: { autocompactionInterval: 60 }});

let options = {
	clientId: "yourClientId",
	incomingStore: manager.incoming,
	outgoingStore: manager.outgoing
};
const client = mqtt.connect("yourMqttBroker",options);

let pub_id = 0;
setInterval(()=>{
	client.publish("topic",JSON.stringify({message: `packetId=${pub_id}`}),{qos:1});
	pub_id++;

},10000);

```

## 途中で通信を切断した場合

###試験方法
定期的に送信している途中でネットワークを遮断し、しばらくして復帰させてみる

###　結果
すべてのメッセージを受信
ただし、動作確認用端末に表示される順番は送信した順番通りではありませんでした。

## 途中で通信を切断し、更に電源を再起動した場合

### 試験方法
定期的に送信している途中でネットワークを遮断し、しばらくしたら電源を再起動して通信を再開させる

### 結果
再起動して通信が復活してから、電源再起動前のデータもブローカに届いていることが確認できました。