OmniAICreator/Qiita-1.07M huggingface dataset:
ボンディング設定

■nmcli c
[root@localhost tmp]# nmcli c
NAME              UUID                                  TYPE            DEVICE
ens33             68ea136f-3808-4093-8855-ac32450d7884  802-3-ethernet  --
ens37             f079013a-cf00-409a-8c70-92588a26a89b  802-3-ethernet  --

■ボンディングデバイスの作成
[root@localhost tmp]# nmcli connection add type bond autoconnect no con-name bond0 ifname bond0 mode active-backup
Connection 'bond0' (322bcd2b-5e71-4f15-aae7-acd682bf8d23) successfully added.t no con-name bond0 ifname bond0 mode active-backup 

■slaveの追加
nmcli connection add type bond-slave autoconnect no ifname ens33 master bond0
Connection 'bond-slave-em1' (46e422f5-5a82-4994-9b31-061b838d384f) successfully added.

nmcli connection add type bond-slave autoconnect no ifname ens37 master bond0
Connection 'bond-slave-ens37' (bf84231f-24a1-4eb1-b20e-49e2ea72d13b) successfully added.

■BondingインターフェースにIPアドレスを設定
nmcli c mod bond0 ipv4.method manual ipv4.address "192.168.3.20/24" ipv4.gateway "192.168.3.1" ipv6.method ignore
nmcli c mod bond0 ipv4.dns 192.168.3.1

■自動起動設定の確認
nmcli c m ens33 connection.autoconnect no
nmcli c m ens37 connection.autoconnect no

■再起動後にbond0に接続するようにbond0とslaveのautoconnectの設定をyesに変える。
nmcli c m bond-slave-em1 connection.autoconnect yes
nmcli c m bond-slave-em2 connection.autoconnect yes
nmcli c m bond0 connection.autoconnect yes

■設定の反映とbondingデバイスの有効化
systemctl restart NetworkManager
systemctl restart network.service 
nmcli c up bond-slave-ens33
nmcli c up bond-slave-ens37
nmcli c up bond0

■ip a 確認
[root@localhost ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master bond0 state UP qlen 1000
    link/ether 00:0c:29:20:a8:7f brd ff:ff:ff:ff:ff:ff
3: ens37: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master bond0 state UP qlen 1000
    link/ether 00:0c:29:20:a8:7f brd ff:ff:ff:ff:ff:ff
4: bond0: <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000
    link/ether 00:0c:29:20:a8:7f brd ff:ff:ff:ff:ff:ff
    inet 192.168.3.20/24 brd 192.168.3.255 scope global bond0
       valid_lft forever preferred_lft forever
    inet6 2400:2411:11e1:d000:20c:29ff:fe20:a87f/64 scope global mngtmpaddr dynamic
       valid_lft 85979sec preferred_lft 13979sec
    inet6 fe80::20c:29ff:fe20:a87f/64 scope link
       valid_lft forever preferred_lft forever
laravelからchatworkへCommandの実行お知らせ

##◆目的
前回、Commandをやったので、通知をやろうと思う
今回は、実行時間をお知らせする。

##◆Batchとは
Commandクラスを毎日指定した時間に(cronで管理)裏で実行してくれるやつ
今回は手動実行

##◆chatworkのapiトークンの作成
apiトークン = 認証情報のようなもの

[サイト参考に作成](https://saitodev.co/article/PHP%E3%81%A7%E3%83%81%E3%83%A3%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AFAPI%E3%82%92%E4%BB%8B%E3%81%97%E3%81%A6%E3%83%A1%E3%83%83%E3%82%BB%E3%83%BC%E3%82%B8%E3%82%92%E6%8A%95%E7%A8%BF%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B)

##◆Commandクラス作成

```:コマンド
php artisan make:command SampleBatch
```

```
class SampleBatch extends Command
{
    protected $signature = 'sample-batch';

    protected $description = 'チャットワークに通知する';

    private $apiToken  = 'サイトを参考に取得したapiトークン';
    private $myChatUrl = 'https://api.chatwork.com/v2/rooms/サイトを参考に自分のルームID/messages';

    public function __construct()
    {
        parent::__construct();
    }

    public function handle()
    {
        //バッチの実行時間
        $startTime = Carbon::now();
    }
}
```

##◆外部apiにhttps(post)通信したいので、Guzzleを導入する

### Guzzleとは
https://qiita.com/mapyo/items/5307e1b36437600c2c34

```:コマンド
composer require guzzlehttp/guzzle
```

##◆通知を実装

```
public function handle()
{
    //バッチの実行時間
    $startTime = Carbon::now()->toString();

    $client = new Client();

    $client->post($this->myChatUrl, [
        'form_params' => [
            'body' => $startTime
        ],
        'headers' => [
             'X-ChatWorkToken' =>$this->apiToken
        ]
    ]);
}
```

ClientクラスがGuzzleを利用するためのクラスで、post送信メソッド(第一引数でurl指定)第二引数はオプションを指定していく。
<b>・format_paramsの中のbodyの中に送信したい内容を記述する(文字列方じゃないとエラーになる)</b>
<b>・headersにchatworkのapiTokenくっつけて、認証してもらってる。</b>

```:コマンド
php artisan sample-batch
```

通知完了OK

[参考にさせていただいた記事]
https://qiita.com/zaburo/items/13bfdc349e1421421c98
https://qiita.com/komatzz/items/faa8f97efdfc5da84aad
【python3】python3系でurllibのエラーが出た時の対処

pythonでスクレイピングをやろうと思い立った。
そこでurllibを使ったがssl関連でエラーにブチ当たってしまった。

おとなしくurllib3使うべきだろうが、
すぐに解決できたのでその対処法を残す。

エラーにぶち当たったコードはコレ
---

```stringControl.go

package main
import (

)

func main() {
	fmt.Println("Hello, playground")
	s := "Alfa Bravo Charlie Delta Echo Foxtrot Golf"
 	fmt.Println(strings.Index(s, "Delta")) 
	tg := "F"
	fmt.Println(strings.Index(s, tg)) 
	
	strings.Replace(s, "A", "Z", 1)
	fmt.Println(s)
	
	t := "hogehogehogehoge"
	p := strings.Replace(t, "ge", "ji", 1)
	fmt.Println(p)	
	
	at := [18 29 31 37 44 48 55 69 72 78 90]
	
	
}
```

↓
↓
↓

```
＜エラー内容　一部省略＞

urllib.error.URLError:
 <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED]
certificate verify failed:
unable to get local issuer certificate (_ssl.c:1045)>
```

対象方法は下記のどちらかをシェルで実行するだけ。
---

```
pip install --upgrade certifi
```
それでもだめなら、、、

```
open /Applications/Python\ 3.6/Install\ Certificates.command
```
※　Pythonのバージョンを合わせることが必要！　




---

参考サイトは
[Fixing CERTIFICATE_VERIFY_FAILED error when trying requests-html out on Mac](https://timonweb.com/tutorials/fixing-certificate_verify_failed-error-when-trying-requests_html-out-on-mac/)


---
既にデータの入っているBigQueryのスキーマを書き換える方法

BigQueryのスキーマを変更したい場合に、`bq mk` でテーブルを新規作成して元のテーブルから全データ再投入するしかないと思っているBiqQuery初心者[^1]向けの記事。

[^1]: 数ヶ月前の自分がそうでした…

## BigQueryのスキーマは条件つきで後から変更できる

BigQueryでは、既に入っているデータを消すことなくスキーマの変更ができます。ただし、変更内容には次のような制約があります。

- NULLABLE モードの新たな列を追加する (追加した列の値は全てNULLになる）
- 既存の列のモードを REQUIRED から NULLABLE にする

この条件に当てはまらない変更をしたい場合は頑張る必要があります[^2]。

[^2]: [テーブル スキーマの手動変更  \|  BigQuery  \|  Google Cloud](https://cloud.google.com/bigquery/docs/manually-changing-schemas?hl=ja)

詳細は公式の文書に書いてあります。

- [テーブル スキーマの変更  \|  BigQuery  \|  Google Cloud](https://cloud.google.com/bigquery/docs/managing-table-schemas?hl=ja)

## BigQueryのスキーマを後から変更する手順

まず現在のスキーマをJSON形式で取得します。

```
$ bq show --schema --format=prettyjson [GCPプロジェクト名]:[データセット名].[テーブル名] > schema.json
```

このJSONファイルを編集してスキーマを書き換えます。列の追加はファイル末尾でなくとも好きな場所に追加することができます。

ファイル編集後にスキーマ変更を反映します。

```
$ bq update [GCPプロジェクト名]:[データセット名].[テーブル名] schema.json
Table '[GCPプロジェクト名]:[データセット名].[テーブル名]' successfully updated.
```

これで完成です。あとはデータを投入しましょう。
Salesforce ✕ SpringBoot クイックスタート

JavaからSalesforceにSOAP APIを叩くためのツール作成の入門。
最近Salesforceの開発に携わったので、備忘録として。

# Spring Initializrから元コード取得

※　とくにDependenciesは選択しない

![image.png](https://qiita-image-store.s3.amazonaws.com/0/230829/efd674b9-b0be-c53d-19ff-b389a2927529.png)

# Mavenに以下追加

```xml:pom.xml
		<dependency>
		    <groupId>com.force.api</groupId>
		    <artifactId>force-partner-api</artifactId>
		    <version>45.1.0</version>
		</dependency>
```

force-partner-apiのPartnerって何？

※　Partner: Salesforceで汎用に使えるWSDLを使用
※　Enterprise: Salesforceで組織ごと独自で使用するWSDLを使用

# Javaファイルに以下追加

```java

package sfdc.test;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import com.sforce.soap.partner.PartnerConnection;
import com.sforce.ws.ConnectionException;
import com.sforce.ws.ConnectorConfig;

@SpringBootApplication
public class TestApplication {

	public static void main(String[] args) {
		SpringApplication.run(TestApplication.class, args);
		login();
	}

	// Salesforceのログイン処理
    private static boolean login() {
    	PartnerConnection partnerConnection = null;
        boolean success = false;
        String username = "※ログインID※";
        String password = "※パスワード※";
        String authEndPoint = "https://login.salesforce.com/services/Soap/u/45.0/";
        // Sandboxの場合、testに変更する

        try {
          ConnectorConfig config = new ConnectorConfig();
          config.setUsername(username);
          config.setPassword(password);

          config.setAuthEndpoint(authEndPoint);
          config.setTraceMessage(true);
          config.setPrettyPrintXml(true);

          partnerConnection = new PartnerConnection(config);

          success = true;
        } catch (ConnectionException ce) {
          ce.printStackTrace();
        }
        return success;
      }
}

```

# ここから先、InsertやUpdate処理を行うには・・・

以下の公式サイトのサンプルコード参照

https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_partner_examples.htm

https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sample_create_call.htm#topic-title

https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sample_search_call.htm#topic-title

## つまづきポイント

### * 型の違い

```java
        SObject contact = new SObject();
        contact.setType("Contact");
        contact.setField("FirstName", "Otto");

        // 日付は、String ではなく Dateを入れる
        contact.setField("Date__c", "Jespersen");

        // 日時は、String ではなく Calenderを入れる
        contact.setField("DateTime__c", "Professor");
```

### *  外部キーのセット

```java
        SObject contact = new SObject();
        contact.setType("Contact");

        SObject account = new SObject();
        account.setType("Account");
        // 外部キー
        account.setField("Key__c", value);

        contact.setField("FirstName", "Otto");
        contact.setField("Account.Key__c", account);

```
画像や動画を拡大ポップアップして表示するLuminousとLityを使ってみた

# LuminiousとLity
LuminiousとLityはページ内で画像や動画を拡大ポップアップして表示できるjQueryプラグインです。
実際に使ってみました。
WordPressや自作のWebサイトなどに導入してみるのも良いと思います。

##Luminous
クリックすると画像がポップアップして拡大表示するスクリプトです。
画像のポップアップしていくれるjQueryスクリプトではlightboxが有名ですが、
使ってみたところ画像の表示までの時間が長いことが問題でした。
ネット上で他のスクリプトを探してみたところ、**Luminous**というスクリプトは表示までの時間が短めで軽量なので使用しています。
https://github.com/imgix/luminous

##Lity
Luminousは画像のみの対応でしたが、もう一つ紹介するプラグインの**Lity**は以下のようなメディアにも対応しています。
- 画像
- 動画
- Youtube
- Googleマップ
- リンク先ページ
etc...
https://sorgalla.com/lity/

# LuminiousとLityのプラグインダウンロード
##Luminous
[Luminousダウンロード](https://github.com/imgix/luminous/releases)
ダウンロードしたフォルダのdist内にある**luminous-basic.min.css**と**Luminous.min.js**をそれぞれcssとjsフォルダに保存します。
##Lity
[Lityダウンロード](https://github.com/jsor/lity/releases)
ダウンロードしたフォルダのdist内にある**lity.css**と**lity.js**をそれぞれcssとjsフォルダに保存します。

# LuminiousとLityを実装

Lityのcssとjavascriptを`head`内に記載、Luminousのcssとjavascriptを`最後のbodyタグ終わり`に記載します。
`<div class='block'>`でタグを囲むと矢印キーの左右で前後の画像を見ることができます。

```sample.html
<!DOCTYPE html>
<html lang="jp">
  <head>
    <meta charset="utf-8">
    <title>Luminous & Lity</title>
    <link rel="stylesheet" href="./css/styles.css">
    <!-- Lityプラグイン設定 -->
    <link rel="stylesheet" href="./css/lity.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    <script src="./js/lity.js"></script>
  </head>
  <body>
    <h1>Luminous</h1>
    <div class='block'>
      <a href='./media/food1.jpg' class='luminous'>
        <img src='./media/food1.jpg' alt='image'>
      </a>
      <a href='./media/food2.jpg' class='luminous'>
        <img src='./media/food2.jpg' alt='image'>
      </a>
      <a href='./media/food3.jpg' class='luminous'>
        <img src='./media/food3.jpg' alt='image'>
      </a>
    </div>
      <h1>Lity</h1>
      <a href='./media/fcgifu.mp4' data-lity='data-lity'>VIDEO</a>
  </body>
    <!-- Liuminousプラグイン設定 -->
    <script src="./js/Luminous.min.js"></script>
    <script>
      var luminousTrigger = document.querySelectorAll('.luminous');
      new LuminousGallery(luminousTrigger);
    </script>
</html>
```
```styles.css
.luminous img {
    width: 150px;
    display: inline-block;
}
```
各ファイルの配置は以下の通りです。

```
$ tree
.
├── css
│   ├── lity.css
│   ├── luminous-basic.min.css
│   └── styles.css
├── js
│   ├── Luminous.min.js
│   └── lity.js
├── media
│   ├── fcgifu.mp4
│   ├── food1.jpg
│   ├── food2.jpg
│   └── food3.jpg
└── sample.html
```

# LuminiousとLityのデモ

## Luminous

画像をクリックすると拡大ポップアップとして表示されます。
矢印キーの左右で前後の画像を見ることができます。
画像以外のところをクリックすると拡大ポップアップが終わります。


![Apr-08-2019 10-12-41 PM.gif](https://qiita-image-store.s3.amazonaws.com/0/120727/3b4aeb57-e051-7d39-ae3a-5554faa88dca.gif)

## Lity

リンクをクリックすると動画が再生されます。
※いきなり再生するので音量に注意してください

![Apr-08-2019 10-49-11 PM.gif](https://qiita-image-store.s3.amazonaws.com/0/120727/35269bc7-516a-f4fc-81a8-54505bba2892.gif)

# その他

LuminousにはGitHubの「Options / Defaults」から数多くのオプションが存在するので、
使ってみたらもっとカッコよく画像が表示できるかもしれません。(まだ試してない)

# 参考

https://on-ze.com/archives/2556
https://wemo.tech/1169
bashの可変数引数の処理

# bashの可変数引数の処理

ずいぶん昔に書いたコードを今更ながら思い出したのでメモとして記載。

シェルスクリプトを書くときに可変数での引数を処理したい場合がたまにある。
その時に以下のようにコードを書くことで全ての引数を順に処理することができる。

```
#!/bin/bash

while [ -n "$1" ]
do
    echo "$1"
    shift
done
```

$1が第1引数を表している。
$1をechoで出力し、shiftコマンドで引数をずらす。
そうすることで、第2引数が$1に入ってくる。
これを繰り返すことで全ての引数を処理できる。

例えば以下のようになる。

```
$ ./test.sh 5 4 3 2 1

実行結果
5
4
3
2
1
```

これだけではあまり意味がないかもしれないが、
バッチ処理をするとき等に、他のJarなどを呼び出す際に
引数をばらす処理をJava側で書く必要がないため楽かもしれない。
Raspberry pi3でのNTFSマウントについてのメモ

raspberry pi 3 model b+ をsambaでファイルサーバーにしようとした時に軽く3時間ぐらい飛ばした、そんな時に気付いたことのメモ。
NTFSフォーマットの外付けHDDを接続するために、/etc/fstabに

```
UUID="386CCB306CCAE828" /media/data  ntfs defaults,nofail,gid=1000,uid=1000,umask=000,dmask=000,fmask=000 0 2
```

と、していました。最初はマウントするときのユーザーの指定もグループの指定も無かったのですが。
(本当は当たり前ながら有った方が良いですね。この指定のようにpiを所有者にした方がいいので)
すると読み込みは出来ても書き込みが出来ず。。。
試行錯誤しているとき、ふとターミナルから入って書き込みをしようとtouchをしてみるとそれもだめ。piを所有者にしてもrootで入っても、sudoつけてもダメ。書き込みが出来ない。
あれこれググってみたが明確な解はなく。そんな時に皆さんが書いているntfs-3gを素直に入れてみたらどうかと。

```
UUID="386CCB306CCAE828" /media/data  ntfs-3g defaults,nofail,gid=1000,uid=1000,umask=000,dmask=000,fmask=000 0 2
```
ですね。結果、書き込み出来るようになりました。つまり、ラズパイのデフォルトのntfsは読み込みのみで書き込みは出来ない。ntfs-3gで初めてRW双方出来るようになると。

最初にHDD認識してくれたので大丈夫かと思ったのですがntfs-3g入れなくてもいけるかと、、、よもやこのようなものとは。。。明言してくれているところがなかったので僕が書こうかと。

このお陰でsambaの設定やらfstabの書き方やら、勉強にはなったからよしとしましょうかw
Gradleを使ったinteliJの設定


## build.graldeの設定
```
buildscript {
  repositories {
    maven {
      url "https://plugins.gradle.org/m2/"
    }
  }
  dependencies {
    classpath "gradle.plugin.com.avast.gradle:gradle-docker-compose-plugin:0.9.1"
  }
}

apply plugin: "com.avast.gradle.docker-compose"

dockerCompose {
    waitForTcpPorts = false // turns off the waiting for exposed TCP ports opening
}
```

## コンフィグの設定
<img width="1072" alt="スクリーンショット 2019-04-08 22.37.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/138660/b2cd7d2b-5c41-23b2-05c8-55b4b09028aa.png">

## gradleの設定
<img width="675" alt="スクリーンショット 2019-04-08 22.48.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/138660/cf8bf966-5c29-de03-631e-3338f3d2e51f.png">
<img width="699" alt="スクリーンショット 2019-04-08 22.48.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/138660/0e0e0923-0276-a0db-d884-612bf4023896.png">
Excelテスト手順書が幅を利かせるのは「コマンドで実行できて人間向けに変換できるテスト手順書フォーマット」が存在しないから

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">新社会人の皆様へ<br><br>Excelは表計算ソフトです。<br><br>大事なことなのでもう一度言います。<br><br>Excelは表計算ソフトです。</p>&mdash; ぷり (@pu_ri) <a href="https://twitter.com/pu_ri/status/1113953505281073153?ref_src=twsrc%5Etfw">2019年4月4日</a></blockquote>

上記ツイートをみて激しく同意するところがあるので筆をとりました。

（[私のブログ記事](https://blog.aimof.net/test-format)から加筆つき転載です）

## 悪夢の言葉： Excelテスト手順書

注記１：当記事にExcelを悪く言う意図はありません。Excelを表計算ソフト意外の用途で使うことに意を唱えているだけです。わかりやすいからExcelの名前を使っていますがSpreadSheet、ドキュメントツールなど全部同罪です。

昨日勢いで書いた記事を深く考えて纏めました。

### ターゲット

* リポジトリ単位のテスト
* CIを用いて一日に何度も実行するテスト
* フロントエンドのないテスト（今回はAPIの機能テストに限定）

（E2Eテストのようなフロントを含むものはスコープから外します。まずはRESTfulAPIから）

## なぜExcel手順書は忌み嫌われるか

* 手動実行を前提としていることが多いから
* たとえ自動化しても、テスト手順書と実行コードの二重管理が生まれるから
* 実行頻度が低くなりがちだから

### つまり

* __テスト手順書を機械的に実行できればいい__
* __非エンジニアが読みづらいって言ってきたら、人間向けに出力できるようにしておけばいい__

## 表計算ソフトでテスト手順書を書くの辞めましょう

普通の`.xlsx`形式を実行してもテストは走りません。Cleverなスクリプトを書いて自動化している人はいそうですが、レアケースだと思います。

### テスト仕様書からテストデータを作るのではなく、テストデータから仕様書を作る

よく考えれば当たり前のことです。

実運用中のソフトウェアでテスト仕様書とテストに齟齬があり、テストを書き換えると本体が動かなくなるという事件が発生した際に、この原因は二重管理にあります。たぶん片方しか変更しなかったのでしょう。

一元管理しないと問題になります。テスト文書からテストを作るより、テストを元にテスト仕様書を自動生成するのがラクなので後者を選びます。

## 「コマンドで実行できて人間向けに変換できるテスト手順書フォーマット」の要件

* 手順書通りに実行できるソフトウェアが作れる
* そのソフトウェアをCIで実行できる
* エンジニアにとって可読性が高い
* テストの順番を指定できる
* コメントを書ける
* テスト手順からテストドキュメントを作成できる

### テスト手順書の前提

* APIのテストはコンピュータが行うものである。間違ってもキーボードと目視で行うべきではない。
* 日に何度もテストが行われるべきである。
* 要するにCIで使える必要があるので、軽くて速いことが望ましい。
* テストは順序だって行われる。
* テスト手順書から「テスト手順書（非エンジニア向け）」を作成できる必要がある。

## 私が作成中の例

```yaml
version: '0'
config:
  timeout: 120

testcases:
  # test GET
  - name: "Test case 0"
    url: http://api:8080/
    method: GET
    retry: -1
    want:
      statuscode: 200
      bodypath: ./txt/getwant.txt
  # test 400
  - name: "Test case 1"
    url: http://api:8080/api
    method: GET
    want:
      statuscode: 400
      bodypath: ./txt/empty.txt
 # 繰り返し
```

nameの下に、purposeとかdescriptionとか入れる予定です。

## なぜテストフォーマットが必要になるか

* 開発者が開発中にAPIが正しく動いていることを常に確認するため
* 開発の出戻りの発覚を減らすため
* QAエンジニアの負担を減らすため
* QAエンジニアがいなくてもなんとかするため

## まとめ

誰か作ってくれと思ったら自分が作るべきなので自分で作ります。
既存のものはちょっと要件を満たしてくれませんでした。

### 追記

興味が合ったら[私のプロジェクト](https://github.com/aimof/apitest)を見たり、連携している連絡先から連絡をしたりしてください。
まだ、ドキュメント化は未着手ですすみません。
straight.elでEmacsをよりポータブルに！！

Emacsは設定ファイルさえあれば環境移行が楽、
だと思って使っていましたがパッケージのインストールだけは手動でやる部分も多かった。。。
私の力不足なだけですが笑

しかしstraight.elを見つけて本当に自動で自分の環境を再現させることを知って感動しました。

=>=>=>[straight.elのりぽじとり](https://github.com/raxod502/straight.el)

# 私の環境
下記2環境で使えました

- macOS Mojave 10.14.4
    - Emacs 26.1
- Ubuntu 18.10
    -  Emacs 25.2.2

# 導入

何を書けば良いのか、READMEにある通りに書きましょう

```~/.emacs.d/init.el
;; straight.el setting by myself
(let ((bootstrap-file (concat user-emacs-directory "straight/repos/straight.el/bootstrap.el"))
      (bootstrap-version 3))
  (unless (file-exists-p bootstrap-file)
    (with-current-buffer
        (url-retrieve-synchronously
         "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
         'silent 'inhibit-cookies)
      (goto-char (point-max))
      (eval-print-last-sexp)))
  (load bootstrap-file nil 'nomessage))

;; use-package
(straight-use-package 'use-package)

;; use-packageをstraight.elにフォールバックする
(setq straight-use-package-by-default t)

;; init-loader
(use-package init-loader)
;;; ログはエラーが出た時のみ
(custom-set-variables
 '(init-loader-show-log-after-init 'error-only))

;; ~/.emacs.d/init配下のelファイルをすべてロードする
(init-loader-load "~/.emacs.d/init")
```


これだけ書けば終わり、あとは使いたいパッケージの設定をつらつらと書いていきます。


```~/.emacs.d/init/00_volatile-highlights.el
;; volatile-highlights
(use-package volatile-highlights)
(volatile-highlights-mode t)
```

こんな感じで`use-package`で呼んであげて普通に設定していくだけです。
Emacsを起動すると`.emacs.d/straight`配下のパッケージを使って自身構築していき、パッケージがなかった場合はクーロンしてきて配置してくれます。

これで新しい環境に移ってもinit.elとinitだけあれば元の環境を再構築することができます。素晴らしいですね。

# Tips
ただやっぱりいろんなパッケージをロードしていると毎回起動するには少し遅くなってしまいます。
なのでデーモンでバックグラウンドに常駐させといて、クライアントを呼べば高速に起動することができます。

```
;; デーモン起動
$ emacs --daemon
;; クライアント起動
$ emacsclient -t
```

`emacsclient -t`と毎回タイプするのはちょっと長すぎるので私はaliasを貼って使っています。

```
alias e='emacsclient -t'
```

これで

```
;; scratch
$ e

;; [filename] を開く
$ e filename
```

って感じで使えますね。
javacの警告が100個までしか出力されない。

この記事は以下の環境で動作確認を行いました。ただし、ほかのバージョンやほかのベンダーでも通用する内容だとは思います(´・ω・｀)

```
C:\jdk>java -version
openjdk version "12" 2019-03-19
OpenJDK Runtime Environment (build 12+33)
OpenJDK 64-Bit Server VM (build 12+33, mixed mode, sharing)

C:\jdk>javac -version
javac 12
```

たとえば以下のようなコードがあったとします。

```java
import java.util.List;

public class Sample {
    public static void main(String[] args) {
        List list001;
        List list002;
        List list003;
        List list004;
        List list005;

        // 長いので中略

        List list196;
        List list197;
        List list198;
        List list199;
        List list200;
    }
}
```

煩雑なので一部省略していますが、`List`が原型(Raw Type)のまま200個宣言されています。よってこれ`-Xlint`オプション付きでコンパイルしたとき、200個の警告が出力されてほしいのですが、実際は100個しか出力されません。

```
C:\jdk>javac -Xlint Sample.java
Sample.java:5: 警告:[rawtypes] raw型が見つかりました: List
        List list001;
        ^
  汎用クラスList<E>の型引数がありません
  Eが型変数の場合:
    インタフェース Listで宣言されているE extends Object
Sample.java:6: 警告:[rawtypes] raw型が見つかりました: List
        List list002;
        ^
  汎用クラスList<E>の型引数がありません
  Eが型変数の場合:
    インタフェース Listで宣言されているE extends Object
Sample.java:7: 警告:[rawtypes] raw型が見つかりました: List
        List list003;
        ^
  汎用クラスList<E>の型引数がありません
  Eが型変数の場合:
    インタフェース Listで宣言されているE extends Object

(例によって長いので中略)

Sample.java:102: 警告:[rawtypes] raw型が見つかりました: List
        List list098;
        ^
  汎用クラスList<E>の型引数がありません
  Eが型変数の場合:
    インタフェース Listで宣言されているE extends Object
Sample.java:103: 警告:[rawtypes] raw型が見つかりました: List
        List list099;
        ^
  汎用クラスList<E>の型引数がありません
  Eが型変数の場合:
    インタフェース Listで宣言されているE extends Object
Sample.java:104: 警告:[rawtypes] raw型が見つかりました: List
        List list100;
        ^
  汎用クラスList<E>の型引数がありません
  Eが型変数の場合:
    インタフェース Listで宣言されているE extends Object
警告100個
```

コンパイル時警告の最大数は`-Xmaxwarns`オプションにより設定することができます。この値がデフォルトでは100になっているらしく、そのために上記の例では100個しか警告が出力されませんでした。よって「警告を200個出力したい」、もとい「警告を無制限に出力したい」場合は`-Xmaxwarns`オプションに巨大な値を設定すればよいということです。

```

C:\jdk>javac -Xlint -Xmaxwarns 999999 Sample.java
Sample.java:5: 警告:[rawtypes] raw型が見つかりました: List
        List list001;
        ^
  汎用クラスList<E>の型引数がありません
  Eが型変数の場合:
    インタフェース Listで宣言されているE extends Object
Sample.java:6: 警告:[rawtypes] raw型が見つかりました: List
        List list002;
        ^
  汎用クラスList<E>の型引数がありません
  Eが型変数の場合:
    インタフェース Listで宣言されているE extends Object
Sample.java:7: 警告:[rawtypes] raw型が見つかりました: List
        List list003;
        ^
  汎用クラスList<E>の型引数がありません
  Eが型変数の場合:
    インタフェース Listで宣言されているE extends Object

(長いので中略)

Sample.java:202: 警告:[rawtypes] raw型が見つかりました: List
        List list198;
        ^
  汎用クラスList<E>の型引数がありません
  Eが型変数の場合:
    インタフェース Listで宣言されているE extends Object
Sample.java:203: 警告:[rawtypes] raw型が見つかりました: List
        List list199;
        ^
  汎用クラスList<E>の型引数がありません
  Eが型変数の場合:
    インタフェース Listで宣言されているE extends Object
Sample.java:204: 警告:[rawtypes] raw型が見つかりました: List
        List list200;
        ^
  汎用クラスList<E>の型引数がありません
  Eが型変数の場合:
    インタフェース Listで宣言されているE extends Object
警告200個
```

- おまけ1: 警告だけでなく、コンパイルエラーの最大値も`-Xmaxerrs`で指定することができます。
- おまけ2: 「デフォルト100個が最大」 というのは少ないようにも思えますが、基本的には警告が1つでもあれば、即修正すべきです。コンパイルに成功したからといって、警告に目をつぶってはいけません(自戒)
Laravelのテストについてメモ

# 設定ファイル

`./phpunit.xml`

# フォルダ

## Fature

機能テスト。複数の処理の連携やHTTPリクエストに対する応答など。

## Unit

コードの独立した一部、ほとんどの場合はメソッドのテスト。

# テストの生成

Featureディレクトリにテストを生成する。
```php artisan make:test UserTest```

Unitディレクトリにテストを生成する。
```php artisan make:test UserTest --unit```

# DBを使用したテスト用のトレイト

テスト用のトレイト3種。
色々試して、たぶん下記のような動きではないかと思う。

`DatabaseMigrations`
テスト開始時にマイグレーションを実行し、終了時にマイグレーションをロールバックする。
開始時にシーダーは実行されない。

`DatabaseTransactions`
テスト開始時にトランザクションを開始し、終了時にロールバックする。

`RefreshDatabase`
テーブルがない状態でテストを実行すると、テーブルはできていてレコードはない。
テーブルがあってレコードもある状態でテストを実行すると、テーブルはあるがレコードは消えている。テストの中で作成したレコードもない。
→テスト開始時にマイグレーションしてトランザクションを開始し、終了時にトランザクションをロールバックする（マイグレーションのロールバックはしない）。


# テストの実行

`./vendor/bin/phpunit [パス]`

パス指定なしの場合は tests 以下の全テストを実行する。



# 参考ページ
[データベースのテスト 5.7 Laravel](https://readouble.com/laravel/5.7/ja/database-testing.html)
[Laravel 5.5正式版がリリース、新機能をまとめてみた - WPJ](https://www.webprofessional.jp/new-features-laravel-5-5/)
[Laravelとテストについて - SlideShare](https://www.slideshare.net/nodat/laravel-63332189)
ABC - 096- A&B&C

#AtCoder ABC 096 A&B&C
[AtCoder - 096](https://atcoder.jp/contests/abc096)

#A問題

 - 高橋は1月に1回発生する

```java
	private void solveA() {
		Scanner scanner = null;
		int numA = 0;
		int numB = 0;

		try {
			scanner = new Scanner(System.in);
			numA = scanner.nextInt();
			numB = scanner.nextInt();

			//5月だったら4か月は高橋がある・・・1/1 2/2 3/3 4/4
			int res = numA - 1;
			//5月だったら、5日以上であれば高橋
			res += numB >= numA ? 1 : 0;

			System.out.println(res);

		} finally {
			if (scanner != null) {
				scanner.close();
			}
		}
	}

```

#B問題

 - 黒板に書かれている整数の内、一番大きいものを操作するのが一番大きい数字を得られる
 - ソートして一番最後を取りだす

```java
	private void solveB() {
		Scanner scanner = null;
		int[] wk = new int[3];
		int numK = 0;

		try {
			scanner = new Scanner(System.in);
			wk[0] = scanner.nextInt();
			wk[1] = scanner.nextInt();
			wk[2] = scanner.nextInt();
			numK = scanner.nextInt();

			Arrays.sort(wk);

			int res = wk[wk.length - 1];
			for (int i = 0; i < numK; i++) {
				res *= 2;
			}
			wk[wk.length - 1] = res;
			res = 0;
			for (int i = 0; i < 3; i++) {
				res += wk[i];
			}

			System.out.println(res);

		} finally {
			if (scanner != null) {
				scanner.close();
			}
		}
	}
```

#C問題

 - この問題のポイントは以下
    - `同時に二か所塗ることが必須条件であり、同時に二か所濡れない場合はNG`である


```java
	private void solveC() {
		Scanner scanner = null;
		int numH = 0;
		int numW = 0;

		try {
			scanner = new Scanner(System.in);
			numH = scanner.nextInt();
			numW = scanner.nextInt();
			char[][] wk = new char[numH][numW];

			for (int i = 0; i < numH; i++) {
				wk[i] = scanner.next().toCharArray();
			}

			boolean isRepaint = true;
			outside: for (int i = 0; i < numH; i++) {
				for (int j = 0; j < numW; j++) {
					/*
					 * 塗るべき個所を判定
					 */
					if (wk[i][j] == '#') {
						/*
						 * 塗れたかどうか？
						 */
						isRepaint = hasNeighbor(wk, i, j, numH, numW);
						if (!isRepaint) {
							break outside;
						}
					}
				}
			}

			System.out.println(isRepaint ? "Yes" : "No");

		} finally {
			if (scanner != null) {
				scanner.close();
			}
		}
	}


	/*
	 * 上下左右に隣接する黒色で塗る予定のマスがあるか判定
	 * 1つ以上あれば二つ塗れる
	 */
	private boolean hasNeighbor(char[][] wk, int i, int j, int maxH, int muxW) {
		int cnt = 0;

		if (i > 0 && wk[i - 1][j] == '#') {
			cnt++;
		}
		if (j < muxW - 1 && wk[i][j + 1] == '#') {
			cnt++;
		}
		if (i < maxH - 1 && wk[i + 1][j] == '#') {
			cnt++;
		}
		if (j > 0 && wk[i][j - 1] == '#') {
			cnt++;
		}

		return cnt > 0;
	}
```
お絵描きする時に便利なAutoHotKey

#はじめに
お絵描きする時ってタブレットが目の前にあるので、
どうしてもキーボードのショートカットは押しにくいですよね？
かといって色々な割り当て可能なものと言えば、
パッと浮かぶのはWACOMのワイヤレスキーリモート。
その他ゲーミング向けでもいくつかあります…しかし高い！
そういうわけで、私はAutoHotKeyを使って
千円程度で購入可能なテンキーにショートカットを割り当てたのでした。

#コード
```
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
#IfWinActive CLIP ;CLIPを含むウィンドウがアクティブの場合
NumpadDot::MsgBox CLIP PAINT Lab用`nAHKテンキーショートカット一覧`n０→手のひら`n１→アンドゥ`n２→ペン`n３→消しゴム`n４→範囲選択`n５→移動`n６→選択解除`n７→未使用`n８→未使用`n９→全消し`n`n
Numpad0::h ;手のひら
Numpad1::^z ;アンドゥ
Numpad2::p ;ペン
Numpad3::e ;消しゴム
Numpad4::m ;範囲選択
Numpad5::k ;移動
Numpad6::^d ;選択解除
;Numpad7::m ;範囲選択
;Numpad8::k ;移動
Numpad9::
Send,^a ;全体選択
Sleep,100
Send,{Delete} ;全体消去
Sleep,100
Send,^d ;選択解除
return ;サブルーチン終了
NumpadAdd::^NumpadAdd ;拡大
return ;終了
#IfWinActive SAI ;SAIを含むウィンドウがアクティブの場合
NumpadDot::MsgBox SAI用'nAHKテンキーショートカット一覧'n０→手のひら'n１→アンドゥ'n２→ペン'n３→消しゴム'n４→範囲選択'n５→移動'n６→選択解除'n７→未使用'n８→未使用'n９→全消し'n＋→拡大'nー→縮小'n'n
Numpad0::Space ;手のひら
Numpad1::^z ;アンドゥ
Numpad2::n ;ペン
Numpad3::e ;消しゴム
Numpad4::m ;範囲選択
Numpad5::k ;移動
Numpad6::^d ;選択解除
;Numpad7::m ;範囲選択
;Numpad8::k ;移動
Numpad9::d ;全消し
NumpadAdd::^NumpadAdd ;拡大
NumpadSub::WheelUp ;縮小
return ;終了
```

私自身めったにお絵描きする人間ではなかったですし、
まともに完成させず描いてはすぐ消してを繰り返してたので、全消去とかは置き換えても良いでしょうね。
プログラムとかやったことない人でもパッと見ればわかるような内容と思うので、適宜修正して良いと思います。

"."キーのところで、どこのキーに何のショートカットが割り当てられてるか確認できます。
とはいえ、設定した内容を手入力した文字列をメッセージで出してるだけなので
自分用にカスタマイズしたら、そこのところも修正したほうが良いですね。
（というか現状のコードで既に一致してるか怪しいｗ）

ActiveWindowsがSAIかCLIPかのどちらかを含むか、
という判定しかしてないので、他のソフトでも流用可能です。

利用方法はAutoHotKeyをインストール後に、
上記コードをIllust.ahk等、拡張子がahkならなんでもＯＫなので
適当なファイル名にして適当な場所に置き、後は実行するだけ。

2019-08-13追記：SAIのほうだけ対象AHKファイルを「管理者として実行」で起動しないとWindows10では正しく動作しないようです。
単純な実用問題への線形回帰の応用

前回の記事では線形回帰の知識とそれらの数学論拠を説明しました。今回は単純な実用問題への線形回帰の応用について説明させていただきます。
#１．問題
この節では、Pythonで線形回帰問題を解く簡単な例を選びます。 式![Screenshot from 2019-04-08 19-06-49.png](https://qiita-image-store.s3.amazonaws.com/0/344186/d73e5762-98da-5a7a-2d8f-d0ba64fce0af.png)に従って解くときの問題の解答も比較し、Pythonのscikit-learnライブラリを使って解きます。 （これは機械学習ライブラリで、Pythonで広く使われています）。 この例では、入力データは、平面での説明を容易にするために1つの値（一方向）のみを持ちます。

次のような15人の身長と体重に関するデータシートがあります。
![Screenshot from 2019-04-08 19-10-44.png](https://qiita-image-store.s3.amazonaws.com/0/344186/ac5cacc6-9f5e-a208-8a1a-94f60b462aff.png)
問題は、身長に基づいて人の体重を予測できるかどうかということです。 （実際のところ、もちろん重量は、容積のような他の多くの要因に左右されるため）。 このブログは単純な機械学習アルゴリズムに関するものなので、かりに私たちはそれを予測できる。

体重は身長に比例する（重いほど高い）ことがわかりますので、この予測には線形回帰モデルを使用できます。 見つかったモデルの精度を確認するために、155 cmと160 cmの列をテスト用に保持し、残りの列を使用してモデルを訓練します。
#２．グラフにデータを表示する
まず、2つライブラリの線形代数用のnumpyと図形描画用のmatplotlibが必要です。
![Screenshot from 2019-04-08 19-48-33.png](https://qiita-image-store.s3.amazonaws.com/0/344186/36d016a0-70a3-91ef-7454-1fd9ea20552d.png)
次に、データを宣言してグラフに表します。
![Screenshot from 2019-04-08 19-48-53.png](https://qiita-image-store.s3.amazonaws.com/0/344186/4040ac4d-dbfa-b144-c89e-e41966088280.png)
![Screenshot from 2019-04-08 19-50-02.png](https://qiita-image-store.s3.amazonaws.com/0/344186/8dc7d1cb-5e43-991a-bff0-32ca7878a1f5.png)
このグラフから、データが直線上に配置されていることがわかります。そのため、線形回帰のモデルでは良い結果が得られます。
`（重さ）= w_1 *（身長）+ w_0`
#3.式に従って実験する。
次に、式(5)に基づいて係数w_1とw_0を計算します。注：Pythonの行列Aの逆ダミーはnumpy.linalg.pinv（A）で計算されます。pinvは「pseudo inverse」の略語です。
![Screenshot from 2019-04-08 19-54-42.png](https://qiita-image-store.s3.amazonaws.com/0/344186/2e78c5ff-e20e-644a-4268-1fc40cfb298f.png)
![Screenshot from 2019-04-08 19-55-36.png](https://qiita-image-store.s3.amazonaws.com/0/344186/4305db67-4613-3c15-0ab3-a76f5f555f7d.png)
上のグラフから、赤のデータポイントは予測された青い直線に非常に近いことがわかります。 そのため、線形回帰モデルはトレーニングデータセットとうまく連携します。 今度は、このモデルを使用して、トレーニングするときに使用しなかった身長155cmと160cmの2人の体重を予測します。
![Screenshot from 2019-04-08 19-55-47.png](https://qiita-image-store.s3.amazonaws.com/0/344186/609dc21d-fc06-0b32-69eb-377a9b8df989.png)
![Screenshot from 2019-04-08 19-55-58.png](https://qiita-image-store.s3.amazonaws.com/0/344186/3fe7ccbe-9868-c1de-d802-7fcd121434fd.png)
予測結果は実際の数値に非常に近いことがわかります。
#4. scikit-learnライブラリに従ってテストする
次に、私達はPythonのscikit-learnライブラリを使用して解決策を見つけます。
![Screenshot from 2019-04-08 20-00-14.png](https://qiita-image-store.s3.amazonaws.com/0/344186/315d537d-0da1-227b-2c9d-f10d085541dd.png)
![Screenshot from 2019-04-08 20-00-22.png](https://qiita-image-store.s3.amazonaws.com/0/344186/157bbc10-9523-a64e-fca0-58b094937730.png)
2つの結果は同じであることがわかります。（つまり、上記のテストでミスをしなかったことを意味します）
#５．最後
以上で線形回帰の応用する基本的な問題を説明しました。実際はもっと難しい問題を解説しなければならないと思います。そのとき解説するために線形回帰の他にはいろいろな問題と組み合わせなければならないと思います。
私の記事を読んでくれてありがとうございます。
ApacheでPythonを実行する

# 概要
ApacheでPythonを実行できる環境を整えます。

#環境

* Arch Linux 5.0.6
* Apache 2.4
* Python 3.7


# mod_wsgiとは
WSGIとはWeb Server Gateway Interfaceの略で、mod_wsgiは、Graham Dumpletonにより開発されたWebサーバとPythonで作成したコードをつなげるためのインターフェイスです。以前はmod_pythonが主流でしたが、開発が終了したため、現在はmod_wsgiが使われています。

# mod_wsgiのインストール

```
# pacman -S mod_wsgi
```

# Apacheの設定ファイルの変更
/etc/httpd/conf/httpd.confに以下の行を追加します。

```/etc/httpd/conf/httpd.conf
LoadModule wsgi_module modules/mod_wsgi.so
```


# 動作確認
テストファイルを作成し、Apacheの設定ファイルに以下を追加します。

```/srv/http/wsgi_app.py
#-*- coding: utf-8 -*-
def wsgi_app(environ, start_response):
    import sys
    output = sys.version.encode('utf8')
    status = '200 OK'
    headers = [('Content-type', 'text/plain'),
               ('Content-Length', str(len(output)))]
    start_response(status, headers)
    yield output

application = wsgi_app
```


```/etc/httpd/conf/httpd.conf
WSGIScriptAlias /wsgi_app /srv/http/wsgi_app.py
```


Apacheを再起動します。

```
# systemctl restart httpd
```

curlコマンドで確認

```
$ curl http://localhost/wsgi_app
3.7.3 (default, Mar 26 2019, 21:43:19) 
[GCC 8.2.1 20181127]
```
ABC - 095- A&B&C

#AtCoder ABC 095 A&B&C
[AtCoder - 095](https://atcoder.jp/contests/abc095)

#A問題

 - 文字列を1つずつ○×判定

```java
	private void solveA() {
		Scanner scanner = null;
		String topping = "";

		try {
			scanner = new Scanner(System.in);
			topping = scanner.next();

			int res = 700;

			for (int i = 0; i < topping.length(); i++) {
				switch (topping.charAt(i)) {
				case 'o':
					res += 100;
					break;
				case 'x':
					break;

				}
			}

			System.out.println(res);

		} finally {
			if (scanner != null) {
				scanner.close();
			}
		}
	}
```

#B問題

 - `N 種類のドーナツそれぞれを少なくとも 1 個は作る。`という制約よりN種類のドーナツを1つずつ作ることは可能
    - Xから、N種類のドーナツ全て最低1回作成したとして $m_i$ を引く
    -  $m_i$ が一番低いドーナツをたくさん作りたいので、ソートして、Xの残りを全て $m_i$ にあてる

```java
	private void solveB() {
		Scanner scanner = null;
		int numN = 0;
		int numX = 0;

		try {
			scanner = new Scanner(System.in);
			numN = scanner.nextInt();
			numX = scanner.nextInt();

			int[] wk = new int[numN];

			int res = 0;
			for (int i = 0; i < numN; i++) {
				wk[i] = scanner.nextInt();
				res++;
				numX -= wk[i];
			}

			Arrays.sort(wk);

			boolean isExit = false;
			while (!isExit) {
				if (numX >= wk[0]) {
					numX -= wk[0];
					res++;
				} else {
					isExit = true;
				}
			}

			System.out.println(res);

		} finally {
			if (scanner != null) {
				scanner.close();
			}
		}
	}

```

#C問題

 - ピザの枚数は $2×C= A ＋ B$ でも同じものを作れる
 - $2×C$ と $ A ＋ B$ のどちらが安いかを判定
    - $2×C$ と $ A $ のどちらが安いかを判定
    - $2×C$ と $ B $ のどちらが安いかを判定

```java
	private void solveC() {
		Scanner scanner = null;
		int numA = 0;
		int numB = 0;
		int numC = 0;
		int numX = 0;
		int numY = 0;

		try {
			scanner = new Scanner(System.in);
			numA = scanner.nextInt();
			numB = scanner.nextInt();
			numC = scanner.nextInt();
			numX = scanner.nextInt();
			numY = scanner.nextInt();

			int sabun1 = Math.min(numX, numY);

			int res = 0;
			if (numA + numB >= numC * 2) {
				res += sabun1 * (numC * 2);
			} else if (numA + numB < numC * 2) {
				res += sabun1 * (numA + numB);
			}

			if (numX > numY) {
				if (numA <= numC * 2) {
					res += (numX - sabun1) * numA;
				} else {
					res += (numX - sabun1) * (numC * 2);
				}
			} else if (numX < numY) {
				if (numB <= numC * 2) {
					res += (numY - sabun1) * numB;
				} else {
					res += (numY - sabun1) * (numC * 2);
				}
			}

			System.out.println(res);

		} finally {
			if (scanner != null) {
				scanner.close();
			}
		}
	}
```
【Youtubeまとめメモ】Webエンジニアの将来性について雑感＋フリーランスのお仕事アイディア

[![alt](https://i.ytimg.com/vi/WjSvUBR97C8/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIpCGAFwAYABAQ==&rs=AOn4CLBblH6zJs9Dbbm9IamV5UrMEaWgCA)](https://youtu.be/WjSvUBR97C8)
**Webエンジニアの将来性について雑感＋フリーランスのお仕事アイディア**

---

**最後にUtsuさんが言っていたまとめメモ**

- すべてのIT技術は簡単になっていく
- GAFAのサービスにメガベンチャーを含めて侵攻される潮流がある
- GAFAがリリースしてくるインサイトの商売にキャプチャしておく
- 若い人は小規模でも全体をやることを意識
- 深くやるエンジニアになると、それでしか注文が取れなくなるので注意
- コミュ力を鍛えて、チームで一番明るい存在になる
- フリーランスになってからは、セキュリティ診断などのアップセル・クロスセルできるような、
    - 仕事の取り方
    - 顧客との関係の作り方
    - 仕事の進め方
    - 顧客のメンテナンスの仕方　を意識する
- 企業のお抱え（レート高）になるなら、PMPを取得して売り込む。企業としても大したコストではない。

>
アップセル・クロスセルとは顧客単価を上げるための営業手法
より高額なモデルの商品を勧める手法がアップセル、セットとして関連商品を勧める手法がクロスセル
https://www.turbine.co.jp/blog/201710-upselling

**たぶん間違っている本編メモ**

- IT技術は簡単になっている。安くなっている。
- Webの今後　内製化が進む。海外系のサービスが押し寄せてきて、負ける。GAFA等。
- 小さくてもいいから全体をやる。（私は趣味で作りたいものがあって全体をやった。）
- 全体をやることで全体を仕切る。クライアントとのコミュニケーション能力。
- フリーランスを目指すべき。
- どういうフリーランスになるか。一部のコーディングをするくらいならやめた方がいい。実力大事。
- セキュリティ診断。大規模なら他に流す。小規模なら自分でやってフィーをもらう。つながるビジネスになる。
- 基幹システムのフリーランス。プロセスや社内の説得などができる。技術などではない。
- 企業のお抱えで３ヶ月でアドバイザーとして入るようなWebエンジニア。
- その方向性でPMPはあり。



プロが見たらどうかわからないけど、Webエンジニアを目指す素人が見たら参考になると思った動画。
Windows10でWSL＋Railsの開発環境を整える

# はじめに
WSLを利用してWindows上にRails環境構築した時のメモ書きをまとめてみました。
[RailsTutorial](https://railstutorial.jp/)を一通り終えた後、windows上で気軽にRailsを試せるのかーって感じで構築してみました。

## WSL導入
メモをし忘れたので割愛...。
[こちらの記事](https://qiita.com/Aruneko/items/c79810b0b015bebf30bb)を参考に導入しています。

## Rails導入
[こちらの記事](https://qiita.com/stkdev/items/96f507f46276c4e782c0)の流れで導入しています。

最初にrbenv,ruby-buildを導入します。

```
# 事前に必要なパッケージをインストール
$ sudo apt install -y build-essential
$ sudo apt-get install -y libssl-dev libreadline-dev zlib1g-dev libsqlite3-dev

# rbenvをインストール
$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile

# ruby-buildをインストール
$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build

# .bash_profileを再読み込み
$ source ~/.bash_profile
$ rbenv --version
# バージョンが表示されればOK

# NodeJSも最新をインストール
$ curl -sL https://deb.nodesource.com/setup_9.x | sudo -E bash -
$ sudo apt-get install -y nodejs
```

次にRubyを導入します。
依存関係とバージョンを管理するためのbundolerも導入します。

```
$ rbenv install --list	# インストールできるものリスト
$ rbenv install 2.6.1   # バージョンを指定してインストール
$ rbenv versions        # インストール済みバージョン確認
$ rbenv global 2.6.1    # グローバルバージョンを指定

# bundlerもインストール
$ gem install bundler
```

最後にRailsを導入。
Windows管理下で作業できるようにしていきます。

```
# ドキュメントは時間がかかるのでインストールしない
$ gem install rails -v 5.1.6 --no-document

$ cd /mnt/d　      # ubuntuのマウント先ディレクトリに移動
$ mkdir rails_dev  # 開発用のディレクトリ作成
$ cd rails_dev
$ bundle init      # Gemfileを作成
```
Gemfileを作成したらファイルを開いて`# gem "rails"`のコメントアウトを取り除き有効化させます。

```
$ bundle install --path ~/tmp/bendor/bundle
$ bundle exec rails new test_app
$ cd test_app
$ bundle install --path ~/tmp/rails/vendor/bundle
# サーバ立ち上げ
$ bundle exec rails s

# ブラウザで動作確認
# http://localhost:3000/にアクセスできればOK
```
bundle installする先はlinux管理下に置くようにしてあります。
windows管理下だとよくないパッケージがあるかもしれないので。

ここまでやれば、windows10上でRailsを動作させることができます。

ここから先は自分の使いやすさで変更しました。
## その他設定
**buncle exec コマンドにエイリアスを設定**

```
$ vi ~/.bashrc
alias be="bundle exec" を追加

$vi ~/.bash_profile
source = ~/.bashrc　を追加
```
`$bundle exec rails s`と打ち込んでいたものを`$be rails s`みたいに使っていけるように変更。

**開発ディレクトリまでのパスにシンボリックリンクを設定**

```
$ ln -s /mnt/d/rails_dev/ ~/rails_dev
```
$ cd ~/rails_devで開発環境まで行けるように設定。

**vimのコメントアウトの色を変更**

```
$ echo "hi Comment ctermfg=gray" >> ~/.vimrc
```
コメントの内容が見えなかったのでgrayに変更。

**ターミナルのカラーテーマを変更**
Microsoftの[ColorTool](https://github.com/Microsoft/console/releases)を使用しました。
colortool.exeの親ディレクトリを環境変数(ユーザ変数)のPathに追加。
追加後、cmdでコンソールを立ち上げて設定を変更。

```
> colortool -d OneHalfDark
```

自分はデフォルト設定のOneHalfDarkを指定しました。



# まとめ
linuxはそこまで触ったことがなかったので結構苦戦...。
ページ下部にテーブルと連動する横スクロールバーをつくる。

##◆目的
テーブルの中身が多くて、横スクロールバーが出たときに、画面下部にもそれと連動するスクロールバーを作成する。

##◆実装
テーブルと連動するダミーを用意して、目的を達成する。

```html
<div class="dummy-table-frame" style="height:30px; bottom: 0; position: fixed; overflow-x: auto">
    <div class="dummy-table" style="height: 1px"></div>
</div>

<script>
    $(function() {
　　　　 //ダミーテーブル
        const dummyTableFrame = $('.dummy-table-frame');
        const dummyTable      = $('.dummy-table');
        
        //実際のテーブル
        const tableFrame      = $('.table-frame');
        const table           = tableFrame.get(0);

        //dummyのサイズも実際のテーブルサイズに合わせる
        dummyTableFrame.width(tableFrame.width());
        dummyTable.width(table.scrollWidth);

        //ページのサイズが変わったらdummyのサイズも実際のテーブルサイズに合わせる
        $(window).resize(function(){
            const tableFrameSize = tableFrame.width();
            const tableSize      = table.scrollWidth;

            dummyTableFrame.width(tableFrameSize);
            dummyTable.width(tableSize);
        });

        //スクロールバーを連動させる
        dummyTableFrame.get(0).onscroll = () => {
            table.scrollLeft = dummyTableFrame.get(0).scrollLeft;
        };
        table.onscroll = () => {
            dummyTableFrame.get(0).scrollLeft = table.scrollLeft;
        };
    });
</script>
```

テーブルの下に、中身が何もないダミーのフレームと入れ物を作成。styleで画面下部に固定する。あとは連動させるjsかいてOK
Laravelでxdebugしてみた

## 開発環境
docker-toolbox
Windows 10

## xdebug.iniの設定

```
zend_extension=xdebug.so
xdebug.remote_enable=on
xdebug.remote_handler=dbgp
xdebug.remote_mode=req
xdebug.remote_host=192.168.99.1
xdebug.remote_port=9001
xdebug.var_display_max_depth = -1
xdebug.var_display_max_children = -1
xdebug.var_display_max_data = -1
xdebug.idekey = "PHPSTORM2"
xdebug.remote_connect_back=1
xdebug.profiler_output_dir = "/var/log/xdebug/"
xdebug.remote_autostart=on
```

## inteliJ側の設定は下記とします。
![WS001008.JPG](https://qiita-image-store.s3.amazonaws.com/0/138660/10acc1ed-0aaa-54c3-7e1c-2b9ddb21c5ee.jpeg)
![WS001009.JPG](https://qiita-image-store.s3.amazonaws.com/0/138660/5c53f54d-3300-d748-1312-eac7d864e2e5.jpeg)
![WS001010.JPG](https://qiita-image-store.s3.amazonaws.com/0/138660/0109ef85-e272-5b67-08c3-3a01bdef04b3.jpeg)


## 虫眼鏡を押して、挙動を確認
![WS001011.JPG](https://qiita-image-store.s3.amazonaws.com/0/138660/d6a98ca7-df23-b8b9-4db0-1224271df235.jpeg)
![WS001012.JPG](https://qiita-image-store.s3.amazonaws.com/0/138660/52773811-8ad6-a607-a4fb-eb9ba08380bf.jpeg)
USB OTG White Listについて

#USB On-The-Go
周辺機器同士を接続するための規格。
ホストとなるPCに接続したデバイスはUSBデバイスとして動くが、そのデバイスがホストとしても動作するようする。
今までPC-カメラで写真を取り込んで、PC-プリンタでその写真を印刷する、ということで実現していたことを、カメラ-プリンタを直接つなぐことで実現できる。

##OTG White List
driver/usb/core/otg_whitelist.hに用意されている。
CONFIG_USB_OTG_WHITELISTをyにすると、上記のファイルに定義されていないUSBのデバイスはエニュメレーションを拒否される。
使いたいデバイスがある場合にはここに列挙する必要がある。
[メモ] sRGB から リニアRGBに変換

 - C#

式に問題があったので修正しました

```diff
- return Math.Pow((c_srgb + a / 1 + a ), 2.4 );
+ return Math.Pow(((c_srgb + a) / (1 + a) ), 2.4 );
```

```c#

using System;
using System.Collections.Generic;
using System.Linq;


public class App {
    
    public static void Main(string[] args) {
        int[] rgb = { 1, 1, 1};
        double[] linearrgb = Array.ConvertAll(rgb,LinerRgb);
        Array.ForEach(linearrgb, Console.WriteLine);
    }
    
    private static double LinerRgb(int c) {
        double c_srgb = (double)c / 255;
        double a = 0.055;
        
        if ( c_srgb <= 0.04045 ) return  c_srgb / 12.92;
        return Math.Pow(((c_srgb + a) / (1 + a) ), 2.4 );
    }
}
```
 - python

```python
def linearrgbg(c):
	c_srgb = c / 255
	a = 0.0555
	
	if c_srgb <= 0.4045:
		return c_srgb / 12.92
	return math.pow(((c_srgb + a) / (1 + a) ), 2.4 )
	
if __name__ == '__main__':
	rgb = [1,1,1]
	linearrgbg = list(map(linearrgbg, rgb))
	print(linearrgbg)
```

参考: [sRGB - Wikipedia ](https://en.wikipedia.org/wiki/SRGB#The_reverse_transformation)
[備忘録]AngularでTS2305エラー

# AngularでTS2305エラー発生
またデコレーターか・・・

```
ERROR in src/app/app.module.ts(5,10): 
error TS2305: Module '"/Users/makimatsu/dev/src/github.com/makimatsu/ngDragDrop/src/app/
drag-drop/drag-drop.component"' has no exported member 'DragDropComponent'.
```

# 原因
importの仕方が悪いらしい
`DragDropComponent` が見つけられてない

# 解決
コンポーネントのファイル名とクラス名を合わせて`selector`,`templateUrl`,`styleUrls`を存在するパスに変えたら解決した

これを
![image.png](https://qiita-image-store.s3.amazonaws.com/0/331389/43892d3c-5352-6949-9649-5047c4be33eb.png)

こうじゃ
![image.png](https://qiita-image-store.s3.amazonaws.com/0/331389/ce1a8762-913a-2afd-4029-904181a76b25.png)
node.jsのバージョンごとの違い

## node.jsのバージョンがいろいろあってよくわからない
node.jsのバージョンが1.x、io.js、11.x等があり、なぜ分かれているか、どんな差分があるのかわからなかったので簡単に調査。

> 参考 [node.js のバージョンについて。](https://teratail.com/questions/69714)
### 0.12.xって何

>Node.jsは0.xの時代に開発が停滞していたことがあって、一部の開発者が「io.js」と称してフォークを行い、バージョン1から3まで進んでいました。
>その後、Node.jsとio.jsが再統合されることとなったのですが、io.jsでバージョン番号が進んでいてしまって、そちらと同じ番号を使っても混乱するので、統合後のNode.jsは4.0を名乗ることとなりました。

つまり、io.jsを統合せず進んでいるのが 0.12.xで、4.x以降はio.jsの変更を取り込んだバージョンとなる。

## 結局どのバージョンを使えばいいの？
新しい機能試してみたいなら奇数バージョン、安定したシステムを構築したいなら偶数バージョンの最新版を使いましょう。
バージョンの定義は奇数がCURRENT（最新の機能を取り込んでいるけど安定性は保証しない）、偶数がLTS(Long-Term-Support 長期の保守運用に使用することを目的としている）と定義されている。
詳しくはgithubを参照。
　[node.js/release](https://github.com/nodejs/Release)

## まとめ
昨今の開発ではバージョンの位置付けを理解した上で、node.jsのバージョン管理ツール(anyenv,nodenv,nodist等）を使ってうまいこと付き合っていくのがきっと正解。
Androidアプリエンジニアがアプリの設計を見直してみた

Andoridアプリの設計に関して、今一度

- ActivityとFragment
- Activity Lifecycle
- MVVM設計って？

といったあたりを再確認してみました

# ActivityとFragment

Activityは、**アプリの画面を表示するためのコンポーネント**であり、各Activityにはユーザインタフェースを表示するためのウィンドウが与えられます。一般的にはウィンドウは画面と同じ大きさになりますが、画面より小さくしたり、他のウィンドウ上にフローティングさせたりすることもできます
一方で、Fragmentは、**Activityのもつユーザインタフェースや機能の一部を表現するもの**で、1つのActivityに複数のFragmentを組み合わせてビルドしたり、複数のActivityで1つのFragmentを再利用したりもできます。独立したライフサイクルを持ち、Activityの処理によって追加・削除が可能です

### Fragmentの登場

Fragmentはタブレット用に開発されたAndroid3.0から導入されたもので、Fragmentを用いることでタブレットのような大きな画面サイズに対しても、Activityで無理やりユーザインタフェースを変えて複雑な処理を行わずに済むようになりました

### ActivityとFragmentの使い分け

以前は、画面のユーザインタフェースやそれを操作するロジックの多くはActivityに集中してしまい、Activityの肥大化、可読性の低下を引き起こしていました
しかし、Fragmentの登場によって、**画面ごとのロジックやインタフェースはFragmentに記述できるので、ActivityはFragmentを管理するだけで済むようになり**、複数画面の表現も1つのActivityで可能となりました
Fragmentはいわば、Activityを単純化させてくれる優れものだったわけです

# Activity Lifecycle

![image.png](https://qiita-image-store.s3.amazonaws.com/0/304818/bc4b5cdf-0ac3-9d9b-978b-4b1f0b2f0a99.png)

#### onCreate()
Activityが最初に起動されたときに呼ばれます
レイアウトの作成など、最初に1回だけ実行される初期処理などはここで行います

#### onStart()
Activityが表示される直前であることを示しています
onCreate()とは異なり、Activityのライフサイクルの中で繰り返し呼ばれる可能性があります

#### onResume()
Activityがユーザの操作を受け付けるようになる直前で呼ばれます
アプリ内の他のActivityから復帰してきた際にも呼ばれます

#### onPause()
Activityがバックグラウンドに移行する直前で呼ばれます
アプリ内の他のActivityに遷移する際にも呼ばれます
また、onPause()呼び出し後には、メモリ不足によってプロセスが終了してしまう可能性があるため、onPause()では**アプリの永続化データを保存する必要があります**

#### onStop()
Activityがユーザからまったく見えなくなった後に呼ばれます
メモリ不足でプロセスを終了させられた場合には、呼ばれません

#### onRestart()
onStop()の後、Activityが再度表示される場合に呼ばれます
ホームボタンなどでアプリがバックグラウンドタスクになり、再びフォアグラウンドタスクになった際に呼ばれます

#### onDestroy()
Activityが破棄される直前に呼ばれます
メモリ不足でプロセスを終了させられた場合などには、呼ばれない可能性があります

# MVVM設計って？

ご存知の通り、よく知られたMVC(Model-View-Controller)の派生形と言われています

![image.png](https://qiita-image-store.s3.amazonaws.com/0/304818/99b8bb1e-db0c-6ed3-d9e4-b12083aebc78.png)

- View
    - 画面の表示を担い、Activity/Fragmentやxmlが該当します
- ViewModel
    - ViewとModel間の情報の伝達、およびViewのための状態保持を役割とします
    - プレゼンテーションロジックを表現し、ボタンタップ時の処理などをコマンドとして保持します
- Model
    - ドメイン領域を担い、データの操作やビジネスロジックの処理が記述されます
    - UIに依存しないロジックを扱います

### MVCとの違い
MVCではViewがModelを直接参照していたのに対し、MVVMではViewとModelの間にViewModelという中間層が置かれます

![image.png](https://qiita-image-store.s3.amazonaws.com/0/304818/fa37d9de-f0fa-b1b9-6ec0-09e566876482.png)
(引用) https://qiita.com/shinkuFencer/items/f2651073fb71416b6cd7

**双方向DataBinding**
- Viewは常にViewModelの状態を参照し、ViewModelが変更になればViewの表示も変更されます
- また、ViewModelもViewを常に監視し、Viewに何かしらの入力があれば即座にViewModelの状態も変更されます

このようにMVVMは、
DataBindingによってデータそのものを共有して取り扱う考え方なのです
dockerでvue3系環境を作成する

# 手順
1. docker, docker-composeをインストール(他の記事で導入してください)
2. Dockerfileを作成
3. docker-compose.ymlを作成
4. コンテナをbuildし起動する
5. コンテナ内に入り、確認をする
6. vueプロジェクトを作成


## Dockerfileを作成

アプリケーションを作成するディレクトリへ移動する。
カレントディレクトリにvueファイルが展開される。

`Dockerfile`を新規作成し、コンテナの指定などの設定情報を書き込む。

```
$ cd workdir
$ vi Dockerfile
```

```:Docker
FROM node:8.11.3-alpine

WORKDIR /app

RUN apk update && \
    npm install -g npm @vue/cli
```
## docker-compose.ymlを作成
`docker-compose.yml`を新規作成し、コンテナの起動時の設定を書き込む
`vue_app` => 任意のアプリ名
`9000:9000` => ポート指定したい場合

```:docker-compose.yml

version: '3'
services:
  vue_app:
    build: .
    ports:
      - 8080:8080
    volumes:
      - .:/app
    stdin_open: true
    tty: true
    command: /bin/sh
```

## コンテナをbuildし起動する

```
$ docker-compose build
$ docker-compose up -d
```

## コンテナ内に入り、確認をする
コンテナ内部に入りvue.jsのバージョンを確認する
`3.x.x`になっていればOK

```
/app # docker-compose exec vue_app sh
/app # vue --version
3.5.5
```

## vueプロジェクトを作成
プロジェクトを作成する。
`my_app`  =>  任意のプロジェクト名
`npm install`は時間がかかる

```
/app # vue create my_app
/app # cd my_app
/app/my_app # npm install
/app/my_app # npm run serve
```
`localhost:8080`にアクセスしvueの画面が出ればOK
SSLの更新手順の簡単な概要

#SSLの更新をしてもらうから
そんな上司の一声でSSLの更新を任されて、明日実際に更新作業をするので
前もって簡単に概要を調べてみました。

##STEP1:秘密鍵を生成する。
OPENSSLというソフトウェアをインストールしたApacheサーバーで
まずはコマンドを入力して秘密鍵`.key`を生成する

```
openssl genrsa -out esuesueru.domain.key 2048
```
こんな感じで生成する。

秘密鍵には長さがあって、1024bitならば問題は無いらしい。
セキュリティを堅実にするなら2048bitだと安心らしい。
近年のコンピュータの性能が上がってきて1024bit以下の長さだと総当たりで解かれてしまう。

##STEP2:CSRを作成する。
STEP1で生成した`.key`を元にコマンドを入力してCSRファイル`.csr`を作成する

```
openssl req -new -key esuesueru.domain.key -out esuesueru.domain.csr
```

##STEP3:SSL証明書を発行してもらう。
認証局という機関に`.csr`を送り、SSL証明書`.crt`を発行してもらう。
認証局は複数あり、GMOやジオトラスト、デジサートが有名？

##STEP4:インストールして設定する。
秘密鍵、証明書、中間証明書を指定のディレクトリに配置する。
そしてsslの設定ファイル`ssl.conf`を編集する。
秘密鍵、証明書、中間証明書のパスを記述するみたい。

##STEP5:Apacheを再起動し、確認する。
これでSSLの更新は完了！
のハズ…

#編集後記
入社6日目
明日上司と一緒に更新作業する、とはいえ丸腰では不安なので調べてみました。
実際はGUIツールがあって簡単らしいけど
この作業をコマンド叩いてバババってやる人が存在するってだけで、世界は強すぎる…
広告制作時の基準

広告制作時の基準を調べます。


# 法律
景品表示法
知的財産権
医薬品医療機器等法
特定商取引法
健康食品の広告・表示規制

# 業界・自主規制
##化粧品等の適正広告ガイドライン2017年版（第２刷）（2017年9月6日）
https://www.jcia.org/user/common/download/business/advertising/JCIA20170906_ADguide.pdf

## 化粧品等のインターネット上の広告基準
https://www.jcia.org/user/common/download/business/advertising/JCIA20170713_ADguide_internet.pdf

>「広告」とは、厚生労働省通知(平成 10 年 9 月 29 日医薬監第 148 号厚 生省医薬安全局監視指導課長通知)に示される広告の三要件を満たす表 示 と す る 。

##薬事法における医薬品等の広告の該当性について
(平成 10 年 9 月 29 日医薬監第 148 号都道府県衛生主管部(局)長あて 厚生省医薬安全局監視指導課長通知)
https://www.mhlw.go.jp/bunya/iyakuhin/koukokukisei/dl/index_d.pdf

>顧客を誘引する(顧客の購入意欲を昂進させる)意図が明確であること 
>特定医薬品等の商品名が明らかにされていること 
>一般人が認知できる状態であること

上記条件は、潜伏広告(stealth marketing)を含まないことになる。


###医薬品、医療機器等の品質、有効性及び安全性の確保等に関する法律

##インターネットによる医薬品等の広告の該当性に関する質疑応答集(Q&A)について　厚生労働省医薬食品局監視指導・麻薬対策課長
https://www.mhlw.go.jp/file/06-Seisakujouhou-11120000-Iyakushokuhinkyoku/situgiqa.pdf


###薬事法(昭和 35 年法律第 145 号)における医薬品等の広告の該当性について は、「薬事法における医薬品等の広告の該当性について」(平成 10 年9月 29 日 医薬監第 148 号)(以下「通達」という。)


ISO 16128 に基づく化粧品の自然及びオーガニックに係る指数表示に関するガイドライン
https://www.jcia.org/user/business/guideline/organic

「なぜステマがネットで騒動になるのか」の講演資料を公開しました。　徳力 基彦
http://blog.tokuriki.com/2016/07/160704stealth.html

### 最後までおよみいただきありがとうございました。
いいね　💚、フォローをお願いします。
####  Thank you very much for reading to the last sentence.
Please press the like icon 💚　and follow me for your happy life.