OmniAICreator/Qiita-1.07M huggingface dataset:
Prism.Unity で名前をつけて登録する

[前回の記事](https://qiita.com/arahori/items/48acaa5d0c1c01be4ab6)で Prism.Unity を使って DI する基本的な方法を紹介しました。
今回はそこに少しだけ追加で、名前をつけてクラスやインスタンスを登録し、名前を使ってコンテナから取り出す方法を紹介します。

# 登録
```
IAnimal dog1 = new Dog()
{
    Name = "pochi"
};
IAnimal dog2 = new Dog()
{
    Name = "john"
};
container.RegisterInstance<IAnimal>("pochi", dog1);
container.RegisterInstance<IAnimal>("john", dog2);
```
引数に名前を入れます。 RegisterType や RegisterSingleton でも同様です。

# インジェクション
```
    public class MainViewModel
    {
        [Dependency("john")]
        public IAnimal John { get; set; }

        public MainViewModel([Dependency("pochi")]IAnimal animal)
        {
            
        }
    }
```
Dependency アトリビュートの後に登録した名前をつけるだけです。
SQSとmessage queingのメモ書き

# MessageQueueとは
 
端的にいうと異なるソフトウェアでデータの通信を行うため使う機構です。

一般的なRESTAPIの構造だと、requestをしたらresponseが返るまで処理が行えません。そのため非同期の処理を行うことはできません。
なので、ソフトウェア間の通信を一旦 MQに格納して、双方の任意のタイミングで送受信を行えるようにするのがMQの思想です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179800/8179299c-5806-16e9-3651-dcc7f7a09295.png)
(AWSサイトより引用)

# SQS
Amazonが提供しているMessageQueueのサービスで二つのタイプからMQを構築することができます。

## standard
性能を重要視した代わりに、順番の保証を捨てたMQです。

無限に近いスループットを持っていますが、
その代わりに、値を重複して返したり、順番もずれちゃう可能性があるため
冪等性を持った処理などに向いている種類です。


## FIFO
一般的なデータ構造のキューに基づいたMQです。
FIFOに基づいているため、順番は保証されますが、速度に限界があります。

スループットは１秒間に3000程ですが、順番の保証と必ず１度しか値を返さないという保証があるため、処理の順番が大事な場合に向いてます。


# MQが使えるケース
* 画像の加工など非常に重い処理を並列で行いたい場合
    * 画像などを一旦MQに格納して同時にAWSのlambdaなどで加工を噛ませる。
    * 画像が必要になったタイミングでGETで取得してもらう。 
* バッチ処理を数で行いたい場合
    * 処理に必要なデータをMQに書き込んで行き、規定数に到達したらバッチを走らせるという構成。
Rustでテスト（UnitTest）を書く

# 1. はじめに

RustのUnit Testについてクイックスタート的に学んでみようと思います。Rustのドキュメント、[Learn Rust/Unit testing](https://doc.rust-lang.org/stable/rust-by-example/testing/unit_testing.html)を参考にしながらの実践です。Learn Rustにはほかにも、Documentation testingやIntegration testingがありますが、この記事のスコープ外です。

## 環境情報

この記事は以下の環境で試しています。

- Windows ver.1903
- Visual Studio Code 1.49.1
 - 拡張機能①：Rust for Visual Studio Code（0.7.8）
 - 拡張機能②：CodeLLDB（1.5.3）
- Rust 1.46.0

環境の準備はこちらの記事に書きました。
[Visual Studio CodeでRust開発環境を整える](https://qiita.com/84zume/items/377033ab6b6aee2a68d7)

# 2. Unit Test
ではさっそくUnit Testを書いてみます。

## 準備
`cargo` コマンドを利用してクイックスタート用のライブラリパッケージを作成します。

```console
> cargo new adder --lib
     Created library `adder` package
```

`lic.rs` を開いてみると、こんなコードになっていてすぐにテストを試すことができます。

```rust:lib.rs
#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        assert_eq!(2 + 2, 4);
    }
}
```

では試します。コマンドラインでテストを実行させて結果を確認します。`cargo test`です。

```console
> cargo test 
   Compiling adder v0.1.0 (D:\Develop\code-writing\rust\adder)
     Running target\debug\deps\adder-251fa9e510f029d1.exe

running 1 test
test tests::it_works ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

   Doc-tests adder

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

```

実行したところUnit TestとDocumentation Testを2種類のテストが貼りしました。Unit Testは1件`passed`していて成功です。

## 基本的な始め方
テストの基本的な始め方は以下の通り。
- `#[cfg(test)]` アトリビュートを付与した`tests`モジュールを用意する
- テストを実行するファンクションには`#[test]`アトリビュートを付与する

## テスト対象の検証方法
テスト対象の検証方法を簡単なコードでまとめます。

```rust:lib.rs
#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        //値が一致することを検証
        assert_eq!(2 + 2, 4);
    }

    #[test]
    fn it_doesnt_work() {
        //値が一致しないことを検証
        assert_ne!(2 + 2, 5);
    }

    #[test]
    fn it_is_true() {
        //値がtrueであることを検証
        assert!(true);
    }

    // パニックが発生することを検証
    #[test]
    #[should_panic]
    fn test_panic() {
        panic!("hoge-fuga!!");
    }

    // 無視して検証しない
    #[test]
    #[ignore]
    fn ignored_test() {
        //値が一致しないことを検証
        assert_ne!(2 + 2, 5);
    }
}

```

違和感なくテストが書くことができました。

# 3.おわりに
Learn Rustを読みながらRustのUnit Testについてまとめてみました。
TreasureDataのWorkFlowを利用して、テーブル名に日にち(YYYYMMDD)を入れる方法！

#記事内容のユースケース

**TreasureDataのWorkFlowを利用して、新規でテーブルを作成し、
そのテーブル名の末尾に作成した日にち(YYYYMMDD)を入れたい。**

この記事では上記ケースで利用できる、WorkFlowの記述方法をご紹介したいと思います。

#WorkFlow記載例
以下のように記載することで、日本時間の深夜1:30に実行して、
「sample_YYYYMMDD」のようなテーブルを作成することができます。

```sql
timezone: Asia/Tokyo

schedule:
   daily>: 01:30:00 --日本時間の深夜1:30に実行

_export:
  td:
    database: sample_db --対象のデータベース
    date: ${moment(session_time).format("YYYYMMDD")} --集計実施日
    date_1: ${moment(session_time).add(-1, 'days').format("YYYYMMDD")} --集計実施日-1日

+sample_date:
  td>: sample_date.sql
  create_table: sample_${td.date} --集計実施日のYYYYMMDD
  
+sample_date_1:
  td>: sample_date_1.sql
  create_table: sample_${td.date_1} --集計実施日-1日のYYYYMMDD

```

少し解説すると、変数td内の「date」が、集計実施日を宣言しています。

```sql
${moment(session_time).format("YYYYMMDD")}
```

#一言感想
簡単にテーブル名に日にちを入れることができ、非常に便利ですね！
過去データを、スナップショットで保存しておきたい場合に役立ちそうです！

#参考文献
[digdagドキュメント](https://docs.digdag.io/workflow_definition.html)
Users配下のフォルダーをエクスプローラーで開く - Windows Tips

#Users配下のフォルダーを簡単にエクスプローラーで開く
##使用頻度の高いshellコマンド
 [スタート]ボタン→[ファイル名を指定して実行]を選択（またはショートカット [Ctrl]+[R]）で、以下のコマンドを実行する。

|コマンド|開くフォルダー|パス|
|---|---|---|
|shell:Recent|最近使った項目|C:\Users\<ユーザー名>\AppData\Roaming\Microsoft\Windows\Recent|
|shell:SendTo|「送る」メニュー|C:\Users\<ユーザー名>\AppData\Roaming\Microsoft\Windows\SendTo|
|shell:Start Menu|ユーザーのスタートメニュー|C:\Users\<ユーザー名>\AppData\Roaming\Microsoft\Windows\Start Menu|
|shell:Startup|ユーザーのスタートアップ|C:\Users\<ユーザー名>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup|
|shell:Profile|ユーザーのフォルダー|C:\Users\<ユーザー名>|
|shell:Downloads|ユーザーのダウンロード|C:\Users\<ユーザー名>\Downloads|
|shell:My Music|ユーザーのマイ ミュージック|C:\Users\<ユーザー名>\Music|
|shell:My Pictures|ユーザーのマイ ピクチャ|C:\Users\<ユーザー名>\Pictures|
|shell:My Video|ユーザーのマイ ビデオ|C:\Users\<ユーザー名>\Videos|
|shell:Personal|ユーザーのマイ ドキュメント|C:\Users\<ユーザー名>\Documents|
|shell:Desktop|デスクトップ|C:\Users\<ユーザー名>\Desktop|
|shell:Common Desktop|パブリックのデスクトップ|C:\Users\Public\Desktop|
|shell:Common Documents|パブリックのドキュメント|C:\Users\Public\Documents|
|shell:CommonDownloads|パブリックのダウンロード|C:\Users\Public\Downloads|
|shell:CommonMusic|パブリックのミュージック|C:\Users\Public\Music|
|shell:CommonPictures|パブリックのピクチャ|C:\Users\Public\Pictures|
|shell:CommonVideo|パブリックのビデオ|C:\Users\Public\Videos|
|shell:Windows|ウインドウズフォルダ|C:\Windows|
コーディングの命名：１単語でつけるメリット（One Word Naming）

# 文脈・全体を考慮し、同じ言葉を2度使わず、１単語で命名

 JavaやPHPの案件で以下のように冗長なクラスやメソッド名をみることがある。
 （もっと冗長な名前のものがあるのだけど、書くのが鬱陶しいので割愛）

```java:LongerFileReader.java

package com.example.filesytem;

class FileReader {

  public static String readFile(String filePath) {
    //.... 処理
  }
}

````

 上のコードぐらいな特に冗長さを感じないかもしれないけど、これと同じ発想をしていくとそのうち、とてつもない長いコードが生まれる。（Javaの現場いったことある人なら分かると思う）

　これを１単語で名前付けしていく。
　ただ、Javaだと読み込み時にエイリアスが付けられないので、どうしても２単語でせざるを得ないので、PHPで書いてみる。（Javaは本質的に短くかことが困難な文法だなあと実感）

```php:ShortFileReader.php

namespace Example\File;

class Reader {

  public static content($path) {
    //.... 処理
  }
}

````

 - まず、packageで「file」をつける。これで、このパッケージ以下は「ファイル」を扱っているのが分かる。
 - class名で「Reader」をつけるので、このクラスはファイル読み込み処理をしているのが分かる。
 - メソッド名は、読み込む対象にする。動作をつけるのが通例だろうが、そもそも動作はクラスで付けているので分かる。

```java:reading.php

use Example\File\Reader;

$path = "/xx/xxx";
$content = Reader::content($path);

```

 Javaの場合、コーディング規約があるので通例から外れるのが難しいところはあるかもしれないが、他の言語でシンプルに名前付けできるなら、できるだけ単語1つでつけるようにするとコードが見やすくなる。（Javaはエイリアスが付けられないので、最低でも２単語を付けないと名前の衝突が起きやすい。）

　また、単語１つでするということは、そのクラスやパッケージの役割が限定され、コードの独立性が高まってくる。つまり、FatClassなどの回避にも役立つ。

　まさに、**「名は体を表す」でシンプルな命名はシンプルなロジック**を実現する。
 
 クラス名、メソッド名が２単語以上であったり、引数の数が多い場合、それはそのメソッドに役割を担わせすぎているサインであり、単語を１つにしていくように命名し、引数も少なくしていく。
　そうすることで、独立性の高いシンプルなコードになる。（もちろん、テスタブルでもある）
C#のActionは途中でExceptionを起こすと中断される

## 思てたんとちがう！
`C#`の`Action`をコールバックのリスナとして利用していたところ「思てたんとちがう！」という挙動があったので、改めて検証しました。
`Unity`の`.NET 4.x`で実行していますが、`C#`ならどのプラットフォームでも同じことが起こると思います。

### テストコード

```c#:テストコード
// コールバック用のリスナー
public event Action OnSomething;

private void Start()
{
    // コールバックをそれぞれ登録
    OnSomething += OnSomething1;
    OnSomething += OnSomething2;
    OnSomething += OnSomething3;

    // イベントを実行
    OnSomething?.Invoke();
}

private void OnSomething1()
{
    Debug.Log("1");
}

private void OnSomething2()
{
    throw new NotImplementedException();
}

private void OnSomething3()
{
    Debug.Log("3");
}
```

このコードを実行するとこうなります。

```:ログ
1
NotImplementedException: The method or operation is not implemented.
```

本来ならばOnSomething1〜3は独立のため、2で`Exception`が起きても3が実行されてほしいところですが、出力されていません。

こんな感じで`try-catch`してあげると3も実行されます。

```c#:try-catch
private void OnSomething2()
{
    try
    {
        throw new NotImplementedException();
    }
    catch (Exception e)
    {
        Debug.LogException(e);
    }
}
```

```:ログ
1
NotImplementedException: The method or operation is not implemented.
3
```

## 何が怖いか
「コールバック公開しておくから、誰でも好きにイベント登録しといてくれよな！」というのがわりと一般的な使い方と思いますが、この挙動だと「他のところで登録した誰かが`throw`したら自分のところにイベントが来なくなる**(しかもそれを知ることすらできない)**」というなかなか恐ろしいことになります。

`C#`の`Action`は他にもラムダ式でイベント登録すると解除できなかったり、いろいろ「コワ〜」な挙動が多いです。それすらもなかった昔よりはマシになっているだろうと言われればそうなのですが……。

なにはともあれ、良い子はイベント購読側で、イベントを購読しているという状態をインスタンスとして保持・破棄できる`ReactiveExtension`とか`UniRx`使おうね！[^reactive]　という話でした。

おしまい。

[^reactive]: とはいえ`Rx`もまだ人類には早すぎる代物感がある。
windowsでiverilog その74

#概要　

windowsでiverilogやってみた。
俺cpuのテストベンチ書いてみた。

#動作させるアセンブラ

エコーバック

```
mem[12'h000] = 16'hd000;//loop:  in
mem[12'h001] = 16'h3007;//       set  i
mem[12'h002] = 16'h2007;//       get  i
mem[12'h003] = 16'h5000;//       jz  loop
mem[12'h004] = 16'h2007;//       get  i
mem[12'h005] = 16'he000;//       out
mem[12'h006] = 16'h4000;//       jmp  loop
mem[12'h007] = 16'h0000;//i:  0x0000
```

#テストベンチ

```

module ore(input clk, input rst, input [15:0] in);
	wire [15:0] in;
	wire [11:0] abus;
	wire [15:0] irout,
		dbus,
		qtop,
		qnext,
		ramout,
		aluout,
		out,
		pcout;
	wire [7:0] data2;
	wire empty;
	wire get;
	wire rdy;
	wire rd;
	wire push;
	wire pop;
	wire pcinc;
	wire dbus2pc;
	wire dbus2ir;
	wire dbus2qtop;
	wire dbus2ram;
	wire dbus2obuf;
	//agent0 m(.clk(clk), .rst(rst), .rdy(rdy), .rd(rd));
	//rs_rx x(.clk(clk), .rst(rst), .rx(rx), .rx_RD(rd), .out(in), .rx_RDY(rdy));
	//putc p(.clk(clk), .rst(rst), .start(start), .char(data2), .tx(tx));
	//agent2 t(.clk(clk), .rst(rst), .empty(empty), .get(get), .start(start));
	//fifo f(.clk(clk), .rst(rst), .put(dbus2obuf), .get(get), .data(dbus), .data2(data2), .empty(empty));
	irbuf f(.clk(clk), .rst(rst), .load(dbus2obuf), .d(dbus), .q(data2));
	pcount c(.clk(clk), .rst(rst), .load(abus2pc), .inc(pcinc), .d(abus), .q(pcout));
	irbuf b(.clk(clk), .rst(rst), .load(dbus2ir), .d(dbus), .q(irout));
	stack k(.clk(clk), .rst(rst), .load(dbus2qtop), .push(push), .pop(pop), .d(dbus), .qtop(qtop), .qnext(qnext));
	alu a(.a(qtop), .b(qnext), .f(irout[4:0]), .s(aluout));
	ram r(.clk(clk), .load(dbus2ram), .addr(abus[11:0]), .d(dbus), .q(ramout));
	cpu u(.clk(clk), .rst(rst), .irout(irout), .dbus(dbus), .qtop(qtop), .qnext(qnext), .ramout(ramout),
		.aluout(aluout), .out(out), .pcout(pcout), .in(in), .abus(abus), .pcinc(pcinc), .push(push), .pop(pop),
		.abus2pc(abus2pc), .dbus2ir(dbus2ir), .dbus2qtop(dbus2qtop), .dbus2ram(dbus2ram), .dbus2obuf(dbus2obuf));
	initial
	begin
		$monitor("%h %h", in, data2);
	end
endmodule


module test;
	reg clk;
	reg rst;
	reg [7:0] in;
	ore u(.clk(clk), .rst(rst), .in(in));
	initial
	begin
		clk = 0;
		rst = 1;
		#2
			rst = 0;
		#4
			rst = 1;
		#4
			in = 8'h55;
		#36
			in = 8'h56;
		#36
			in = 8'h57;
		#36
			in = 0;
		#200
			$finish;
	end
	always
		#1
			clk = ~clk;
endmodule


```

#実行結果

```

00xx xx
00xx 00
0055 00
0056 00
0056 55
0057 55
0057 56
0000 56
0000 57

```

以上。
極小マイコン LeafonyでWaveshare 2.9inch e-Paper Module動かしてみる

# はじめに
前回、ESP32で電子ペーパーを動かしてみました。

[Aliexpressで購入したWaveshare 2.9inch e-Paper Moduleのサンプルコードを動かすメモ](https://qiita.com/minwinmin/items/09dd0cfe1c660f4bed94)


今回は、ESP32が搭載されている[極小マイコン「Leafony」](https://leafony.com/)から電子ペーパーモジュールであるWaveshare 2.9inch e-Paper Moduleを動かしてみました。
プログラムは前回と同じで、配線だけ回路図を確認して読み解きました。

# つかうもの
- Waveshare 2.9inch e-Paper Module
- Leafony ESP32 Wi-Fi Kit
- ジャンパーワイヤー

# 配線図
前回、ESP32とWaveshare 2.9inch e-Paper Moduleの配線下記のようになっていました。

> USY -> 4, RST -> 16, DC -> 17, CS -> SS(5), CLK -> SCK(18), DIN -> MOSI(23), GND -> GND, 3.3V -> 3.3V

Leafony ESP32 Wi-Fi Kitで、これと同じピンにでつなげることができるようにします。
ちなみにESP32 dev moduleの配線を確認するとかきのようになります（[こちら](https://ht-deko.com/arduino/esp-wroom-32.html)を参考にしました）。
上記に示した番号はIO番号なので、それとLeafony ESP32 Wi-Fi KitのAX08 29pin headerのピンの割り当てを比較しながら接続するピンを考えます。。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212276/b506e94f-1075-a101-14e8-e87278812861.png)





## Leafony ESP32 Wi-Fi Kitの回路図
[Leafony ESP32 Wi-Fi Kit](https://github.com/Leafony/HW-Design-Files/blob/master/AP02A_ESP32_MCU/AP02A_ESP32_MCU_Schematic.pdf)はこちらにあります。

下記のIO番号を探し、比較します。
> USY -> 4, RST -> 16, DC -> 17, CS -> SS(5), CLK -> SCK(18), DIN -> MOSI(23), GND -> GND, 3.3V -> 3.3V

すると、

```
4  -> D2
5  -> D10
16 -> D9
17 -> D8
18 -> D13
23 -> D7
```
とわかります。

![スクリーンショット 2020-09-24 6.09.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212276/5fcfa23e-4382-236f-6990-c511a7b38654.png)

## AX08 29pin headerへの接続
AX08 29pin headerの回路図は[こちら](https://github.com/Leafony/HW-Design-Files/blob/master/AX08_29pin_header/AX08_29pin_header_Schematic.pdf)にあります。

上記調べた割り当て通りに、ピンをつなげます。

```
4  -> D2
5  -> D10
16 -> D9
17 -> D8
18 -> D13
23 -> D7
```


![スクリーンショット 2020-09-24 6.14.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212276/daa8ff19-ed2e-f2d1-9778-38965732bf2b.png)

CN740、CN741、CN742は下記の順番なので、ピンを繋ぎ間違えないようにしましょう。

![スクリーンショット 2020-09-24 6.16.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212276/b4657f61-6792-d0b4-8069-cf6af8cba3c0.png)

# プログラム
使用したプログラムは前回と同じで[github](https://github.com/minwinmin/waveshare_2.9inch_epaper)にあります。

# 動作確認
こんな感じになりました。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">そういえばLeafonyでも電子ペーパー動かせた <a href="https://t.co/WEJu0iuczb">pic.twitter.com/WEJu0iuczb</a></p>&mdash; たくろーどん (@takudooon) <a href="https://twitter.com/takudooon/status/1308757732158181376?ref_src=twsrc%5Etfw">September 23, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
Javascriptにおける配列の操作(要素の取得、検索、追加、削除)

#はじめに
ここではJavascriptの配列に関する操作をまとめました。
主な内容としては、要素の追加、削除、結合、分割になります。


#配列とは？
そもそも配列とは何であるか説明します。 
変数は以下のように、基本的に一つの値しか代入することができません。

```
let word = 'Hello world!'; 

let num = 8;
```

しかし、もっと多くの値を扱いたい場合に、いちいち変数を1つずつ作るのは大変です。
そのような際に、以下のように配列を作成することで大量の値を1つのデータとして扱うことが可能になります。
また、配列を活用することで、値の作成・追加・初期化・削除・検索…などを簡単に行えるようになります。

```
let words = ['a','b','c','d','e'];

let nums = [3,5,8];
```

#要素取得
以下のようにすると配列の各要素を取得することが可能です。

```
let words = ['a','b','c','d','e','f'];

console.log('words[0]:' + words[0]); // words[0]:a
console.log('words[3]:' + words[3]); // words[3]:d
console.log('words[6]:' + words[6]); // words[6]:undefined　//要素なし
```
変数[要素番号]と書くことにより、その要素の中身を取得することができます。

注意点としては要素番号が0から始まることです。

また、要素が存在しない場合は、'undefined'が得られます。

#要素検索(indexOf())
配列内の各要素のデータを検索する方法の一つに「indexOf()」メソッドがあります。
「indexOf()」は、指定した「値」が配列内に存在する場合、その場所を「インデックス番号」で取得することができます。

```
let words = ['a','b','c','d','e','f'];

let res = words.indexOf('e');

console.log(res); // 4
```
#要素の追加
###先頭に追加 - unshift

```
let words = ['b','c','d'];

words.unshift('a');
console.log(words); // ['a','b','c','d']
```
###最後に追加 - push

```
let words = ['a','b','c'];

words.push('d');
console.log(words); // ['a','b','c','d']
```
###指定位置に追加 - splice

```
let words = ['a','e'];

words.splice(1,0,'b'); //一番目(b)の前に要素追加
console.log(words); // ['a','b','e']

words = ['a','b','e'];

words.splice(2,0,'c','d');　//二番目(e)の前に要素追加
console.log(words); // ['a','b','c','d','e']
```


#要素の削除
###先頭を削除 - shift

```
let words = ['a','b','c'];

words.shift();
console.log(words); // ['b','c']
```
###最後を削除 - pop

```
let words = ['a','b','c'];

words.pop();
console.log(words); // ['a','b']
```
###指定位置の要素を削除 - splice

```
let words = ['a','b','c','d','e','f'];

words.splice(1,1); //二番目の要素削除
console.log(words); // ['a','c','d','e','f']

words = ['a','b','c','d','e','f'];

words.splice(1,3); //二番目から３つ分の要素削除
console.log(words); // ['a','e','f'];

words = ['a','b','c','d','e','f'];

words.splice(2);　//二番目以降の要素を削除
console.log(words); // ['a','b']

```

##参考
[【JavaScript入門】配列の使い方と操作まとめ（初期化・追加・結合・検索・削除）](https://www.sejuku.net/blog/22295)
[【MDN】Array.prototype.splice()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/splice)
Web APIとは

##WebAPIとは

`Web APIとは、コンピュータプログラムの提供する機能を外部の別のプログラムから呼び出して利用するための手順・規約（API：Application Programming Interface）の類型の一つで、HTTPなどWebの技術を用いて構築されたもの。`

Webサイトに外部のサイトの提供する機能や情報を組み込んだり、アプリケーションソフトからWeb上で公開されている機能や情報を利用する際などに用いられる。

Web APIで機能を公開しているサーバに対して、インターネットなどを通じて依頼内容をHTTPリクエストの形で送信すると、処理結果がHTTPレスポンスの形で送られてくる。呼び出し側が挙動や入力データを指定する引数はURLパラメータ（クエリ文字列）などの形でURLの一部として指定することが多い。

送受信されるデータの形式はAPIによって様々だが、Webでよく用いられるXMLやHTML、JSON、単純なテキスト形式やCSV形式、各種の画像ファイル形式などが用いられることが多い。
Javaの配列について

## Java 配列
Javaの配列について学習しましたので、配列のメリットや使用例などアウトプットしていきます。

## 変数が持つ不便さと配列のメリット
今回は、点数管理プログラムを用いて変数と配列の使い方の比較をし、配列を使うメリットを解説します。

### 変数を使ったプログラム
```java:test
public class Main {
  public static void main(String[] args) {
    int sansu = 20;
    int kokugo = 30;
    int rika = 40;
    int eigo = 50;
    int syakai = 80;
    int sum = sansu + kokugo + rika + eigo + syakai;
    int avg = sum / 5;
    System.out.println("合計点：" + sum);
    System.out.println("平均点：" + avg); 
  }
}
```
### 実行結果
```
合計点：220
平均点：44
```
これでも、問題はないが不便なことが2点ある。

- 科目が増えると面倒で冗長なコードになる
- まとめて処理できない

### 配列を使ったプログラム
```java:test
public class Main {
  public static void main(String[] args) {
    int[] scores = {20, 30, 40, 50, 80};
    int sum = scores[0] + scores[1] + scores[2] + scores[3] + scores[4];
    int avg = sum / scores.length;
    System.out.println("合計点：" + sum);
    System.out.println("平均点：" + avg);
  }
}
```
### 実行結果
```
合計点：220
平均点：44
```
実行結果はどちらも一緒だが、配列を使った方がコードがスッキリしてるし、手間的にもいくらかマシ。
こんな感じで配列を使うメリットを分かった(?)ところで一つひとつ解説していきます。

## 配列とは
**同一種類**の複数データを**並び順**で格納するデータ。
また、並び順のことを添え字とよび、**0から始まる決まり**になっている。
配列を使ったプログラムで言うと、20点の科目が0番の要素となる。

## 配列の書き方
配列を作成するには2Stepが必要。

### Step1 配列の宣言
`要素の型[] 配列の変数名`

```java
int[] scores;
```
### Step2 要素の作成と代入
```java
scores = new int[5];
```
newはnew演算子と呼ばれ、指定された方の要素を[]内に指定された数だけ作成できる。

### Step1とStep2を同時に行うこともできる
```java
int[] scores = new int[5];
```
## 配列の要素数の取得
```java
int num = scores.length;
```
Raspberry PiのUbuntuにスワップ領域を設定する

# 使用環境
* Raspberry Pi 3 Model B+
* Ubuntu 18.04.5 LTS Server

# スワップが設定されているかどうか確認する
```bash
$ sudo swapon --show
```
設定されてないので何も出ない
設定されていればこんな感じで表示される

```bash
$ sudo swapon --show
NAME      TYPE  SIZE USED PRIO
/swapfile file 1024M   0B   -2
```

# 手順
## スワップファイル作成
とりあえず1GB作ってみる。まぁ、そんなに必要に迫られてもないし、物理メモリも1GBなので同じくらいで。

```bash
$ sudo fallocate -l 1G /swapfile
```

## rootユーザーしか読み書きできないようにパーミッションを変更する

```bash
$ sudo chmod 600 /swapfile
```

## `mkswap`を使ってファイルにスワップ領域を作成する

```bash
$ sudo mkswap /swapfile
Setting up swapspace version 1, size = 1024 MiB (1073737728 bytes)
no label, UUID=44dd3594-5812-473e-839d-d9c7a1af3d6a
```

## スワップを有効にする

```bash
$ sudo swapon /swapfile
```

## 確認してみる
```bash
$ sudo swapon --show
NAME      TYPE  SIZE USED PRIO
/swapfile file 1024M   0B   -2
```

## htopでも見てみる
![htop.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41603/5e0c4fe4-46a9-c97b-c066-a37ee8c19c87.png)

## 起動時に自動マウントされるように`fstab`に追加する
```bash
$ echo '/swapfile swap swap defaults 0 0' | sudo tee -a /etc/fstab
/swapfile swap swap defaults 0 0
```

## 再起動して確認してみる

```bash
$ sudo reboot
```

```bash
$ sudo swapon --show
NAME      TYPE  SIZE USED PRIO
/swapfile file 1024M   0B   -2
```

# 参考にしたサイト
https://linuxize.com/post/how-to-add-swap-space-on-ubuntu-18-04/
https://kazmax.zpp.jp/linux_beginner/mkswap.html
【手動】バーチャル背景が適用された動画から部屋の背景画像を復元する話

## はじめに
最近は物理的なウイルスの影響で、自宅でビデオ通話をする機会が増えています。会議、飲み会、デートまで自宅で出来るので、家から出たくない族にとっては天国のような時間です。しかし、「ヤバイ！部屋がオタクグッズまみれ！！」といった状況も少なくありません。そんな時に使える神機能がバーチャル背景です。キモい背景を、デートに耐えうる爽やかな背景へ変更してくれます。
![bg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549585/c59a2732-a8c2-28b2-bf77-196dde9be8c4.png)[@Zoom](https://zoom.us/)

## 部屋の背景のセキュリティとバーチャル背景
部屋の背景は私たちが思っているよりも多くの情報を提供しているかもしれません。窓から電車が見える場合、線路の形状や電車の速度などから周辺駅はすぐに特定されます。特徴的な看板や建造物などはピンポイントで場所を教えているのと同じです。空が見える場合も危ないです。飛行機の航路はリアルタイムでトラックできます。壁であれば大丈夫。ポスターでアイドルグループのファンであることがバレていませんか？マンションなどは、全部屋の壁紙が一緒である場合もあります。家具や食器は購入場所がわかる場合があります。TVも地域によって放送内容が変わります。以上の事からバーチャル背景を使用することは、自己防衛の一つといえるでしょう。

## 部屋の背景情報を取得する
前述した理由からバーチャル背景をセキュリティ向上を目的として使っている方も多いでしょう。特に女性の方や、芸能活動をしている方には必須といえるかもしれません。しかし、このバーチャル背景から部屋の背景が復元出来るとしたらどうでしょうか？部屋の背景の復元など一見不可能に思えますが、唯一(部屋の)背景の情報が含まれている部分があります。注目する部分は、以下の画像の赤丸です。
![img1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549585/c2355e13-5660-0de7-3261-024183dc25e1.png)
うまく切り抜けていないため境界面に背景の色情報が含まれています。一枚だけでは何もわかりませんが、長時間の動画でかつ人物が動いている場合には背景の情報が蓄積されます。境界が一ピクセルであっても、画面を横切った場合などは車のワイパーのごとく情報が取得される可能性があります。まして、数ピクセルの境界線があった場合(髪の毛などでよく起こる)はさらに容易でしょう。トイレに行くだけ、お茶をくみに行くだけで背景が復元される危険性があります。動きが速いとバーチャル背景が追いつけないこともあります。振った手の指の隙間から背景が見えているケースなどです。うかつにバイバイできません。

## 部屋の背景情報を実際に復元してみる
ここまでは背景が復元できる可能性の話でした。実際に復元できるのでしょうか？今回ターゲットとするのはZoomで、グリーンスクリーンなしのバーチャル背景です。環境はFMVA53XWKS搭載のカメラ、OSはWindows10です。実際に背景を復元してみたのが以下の画像です。
![img2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549585/53bb657c-0b3d-19ea-2689-e5223001001e.png)
45秒ほどの動画を撮影し、手動で切り貼りしました(もっと細かい情報を集めればより鮮明になる)。検証のため少し激しい動きや不自然な動きをしましたが、バーチャル背景オンの状態です。途中カメラを動かしてしまったミスもありましたが、おおむね背景を復元できたといってもよいでしょう。
※カメラの画質も影響します。
※部屋の色が統一されている場合、その色を選択することでバーチャル背景の精度を向上できます。

## おわりに
こうしてバーチャル背景から部屋の背景を復元することに成功しました。この記事は技術的な興味と、誰もセキュリティ面でバーチャル背景に触れていない事から生み出されたので、使えるかは不明です。CTFのフラグを背景に隠しておいて、それを読み取らせる問題とか作成できそうです。とにかくバーチャル背景で安心せず、部屋を片付けてくれるオタクたちが増えることを望みます。ネット上の美少女はだいたいハッカーなので部屋がバレていますよ。
~~ちなみに、自動化してくれる方の出現を待っています。~~
自動化しました。
B埋めの感想

#自己紹介
what_a_messといいます。とりあえず緑を目指して精進中です。投稿時点で灰222ですので、まだまだ浅いと言えると思います。
Qiitaを使い始めたばかりなので、ミスの指摘などどんどんください。

(投稿:2020/9/24)

##はじめに
9月上旬に[ABC-B埋め](https://kenkoooo.com/atcoder/#/contest/show/e0af67fe-160a-43f3-859c-719c8287ba70)というものを見つけて参加した。9/23(9/24未明)に終わった。

順調に全部解けたという訳ではなかったので、備忘録としてここに残しておく。主に、初見では解けず、考え直したりカンニングしたりして解いた問題を挙げる。

###[ABC140-B Buffet](https://atcoder.jp/contests/abc140/tasks/abc140_b)
やるだけ・・・のはずだったのに、考察が必要なものだと勘違いしてしまったっぽい。
まあ配列3つだし場合分けも必要だし、見た目が厳ついのは否めない。実装は正確にやれば素直。

###[ABC030-B 時計盤](https://atcoder.jp/contests/abc030/tasks/abc030_b)
実装方法で-360°〜360°をとることに気がつかず、負の値の場合に360°を足すのを忘れていた。absを取らなかったのはえらい。180°前後での場合分けは忘れていなかったので、えらい。()

###[ABC035-B ドローン](https://atcoder.jp/contests/abc035/tasks/abc035_b)
**苦戦①**。最大値を合わせるのはx軸y軸?3つに分けて管理すればできるとして、最小値が問題。**最小値が0じゃない場合がある**のに気づけない。さらに偶奇場合分け...めんどくさい。何とか通した。


###[ABC026-B N重丸](https://atcoder.jp/contests/abc026/tasks/abc026_b)
cout<<fixed<<setprecisionを忘れてただけ。doubleにintを足すとdoubleで保持してくれるのね、便利。

###[ABC051-B Sum of Three Integers](https://atcoder.jp/contests/abc051/tasks/abc051_b)
$O(N^3)$だと思ってバグらせていたが、XとYが決まればS-X-Yだけ調べればいいので、$O(N^2)$だった。まだまだだね。

###[ABC050-B Contest with Drinks Easy](https://atcoder.jp/contests/abc050/tasks/abc050_b)
添字の問題。TにPを入れてもいいけど、XにPを入れないで。意味的にもずれたものになるし。ここのデバッグだけしたら通った。

###[ABC097-B Exponential](https://atcoder.jp/contests/abc097/tasks/abc097_b)
普通に誤読していて、Xが素数ならそれが答えになると思っていた。問題文の冪乗数をX以下で全探索して、全部priority_queueに突っ込んで終わり。ところで貪欲でよくない？

###[ABC125-B Resale](https://atcoder.jp/contests/abc125/tasks/abc125_b)
入力はN+1行じゃなくて3行だった...正しく実装すれば大丈夫。

###[ABC047-B すぬけ君の塗り絵 2 イージー](https://atcoder.jp/contests/abc047/tasks/abc047_b)
**苦戦②**。縦と横でbool管理して更新、最後に両方白である区間を足していけば答えになると思ったけど、WA2つが取れない。(実装ミスで縦と横を逆にするとWA減るけど、罠です)
他の方の回答コードを参照して、白の長方形の4辺がどこにあるか管理していくようにしてAC。なんでバグるんだ...？


###[ABC060-B Choose Integers](https://atcoder.jp/contests/abc060/tasks/abc060_b)
Aの倍数を全探索して$10^8$個やっても見つからなければ無理、でよくない？→AC。まあたぶんB個でいいんでしょう。
最初はB*(動かしていく)+Cを動かしていて、どういうわけかif文をバグらせていたので罪深い。何を考えていたのか全くわからない。

###[ABC066-B ss](https://atcoder.jp/contests/abc066/tasks/abc066_b)
std::substringを使えば「消す」なんて行動に焦点を当てる必要はない。最大値は脳死でpriority_queue(貪欲でいいじゃん:2回目)


###[ABC075-B Minesweeper](https://atcoder.jp/contests/abc075/tasks/abc075_b)
文字列入力に抵抗を感じていたが、'0'+(int0〜9)で文字列にできるとわかれば何とかなった。端っこはmaxやminをうまく使って、配列エラーが起きないように気をつける。


###[ABC108-B Ruined Square](https://atcoder.jp/contests/abc108/tasks/abc108_b)
ガウス平面で計算すると、直角二等辺三角形の三頂点は、反時計回りに(a,b),(c,d)(直角),(a+c-d,c+d-a)なので、これを2回やって出力すればOK。数学問っぽい。


###[ABC014-B 価格の合計](https://atcoder.jp/contests/abc014/tasks/abc014_2)
いいbit問題。これ灰diffなの？と思って見たら茶diffだった。やっぱり。
[ABC173-C H and V](https://atcoder.jp/contests/abc173/tasks/abc173_c)と合わせて学ぶとちゃんと身につく感じがする。bitというだけで後回しにしてました。ごめんなさい。

###[ABC027-B 島と橋](https://atcoder.jp/contests/abc027/tasks/abc027_b)
最初はキツそうだと思ったが考えすぎで、左から人数を合計していって、均等になる人数×島の数に等しくなった時橋は要らないってだけ。そもそも均等にできないならerror(-1)。

#終わりに
Bを瞬時に解けるといいですよね。まあ最初からできてたらこの記事もないでしょうが。
頑張るぞぉ
Grib fileをmatplotlibで描画してみた

## Grib fileをmatplotlibで描画する方法

ここのサンプルを見ながらやってみた
[https://confluence.ecmwf.int](https://confluence.ecmwf.int/pages/viewpage.action?pageId=57443489)

こんな感じの物ができた。多分使ったデータセットが悪かったからイマイチよくわからん結果になった
![スクリーンショット 2020-09-24 1.15.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/537802/72c78a18-6820-2bd1-6a0f-5e14d27820e0.png)
[Laravel]Gmailを利用したメール送信

自身のLaravel学習の備忘録として。
Laravelにおいてメール送信機能はパスワードリマインダーなどで使用される。
パスワードを忘れてしまい、ログイン出来ないときにemailに再設定のメールを送るやつ。

以下の写真において,画面右上に「LOGIN」と「REGISTER」が表示されているように、すでにアプリケーションに認証機能を実装された状態。

![スクリーンショット 2020-09-24 0.54.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630885/20a76237-26c8-c7f7-7f1a-f61285db177d.png)



#環境
macOS Catalina バージョン10.15.4
Laravel 5.8.38

#Gmail側の設定
以下のURLから設定。
https://myaccount.google.com/security

googleアカウントでは以下の設定を行う。
　　・「2段階認証プロセス」を「オン」にする
　　・「アプリパスワード」を設定する


「2段階認証プロセス」はスマートフォンのGoogleアプリを使うなどしてGoogleアカウントの認証を行う方法。
この設定をしないと次の「アプリパスワード」の設定が出来ない。

![スクリーンショット 2020-09-24 0.08.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630885/ef2024cf-98d9-b674-37cd-bbac26d75825.png)

アプリパスワードの「アプリを選択」のプルダウンで「その他（名前を入力）」を選択し、アプリ名を入力する。
写真では「Laravel」となっているがアプリ名はわかりやすいものがいい。

![スクリーンショット 2020-09-24 0.20.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630885/fe2c7fc3-9266-42ca-cb1a-531c7d9648b1.png)

「生成」ボタンを押すとアプリパスワードが表示される。
このパスワードをLaravelの設定ファイルに書き込む。

![スクリーンショット 2020-09-24 0.28.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630885/77865be1-c1c7-274f-9472-1faf9783bf21.png)

Laravelの.envを開き、以下の部分を修正。

```
MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
```
↓

```
MAIL_DRIVER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=****@gmail.com ← 自分のgmailのメールアドレス
MAIL_PASSWORD=**** ← アプリパスワード
MAIL_ENCRYPTION=tls
```

MAIL_PASSWORDには先ほど生成したアプリパスワードを入力。

ちなみにMAIL_PORTで指定した587という数字はSMTP（TLS/STARTTLS）のポート番号。

>SMTP
SMTP(Simple Mail Transfer Protocol)とは、送信したメールを宛先のメールサーバーまで届ける技術のこと。
ユーザーがメールソフトウェア（例：Gmailなど）を使用してメールを送信すると、設定されているSMTPサーバーがメールを送信先のサーバーに配信します。

>TLS
TLSとはSSLの次世代規格のことで、電子メールを暗号化することでプライバシーを保護するセキュリティプロトコルを指します。

>STARTTLS
STARTTLSとは、メールの送受信を暗号化する方法です。送信サーバーから受信サーバーへのデータ通信を暗号化することにより、メール通信経路上の悪意のあるハッキングからメールを保護できます。

#動作確認
実際に「REGISTER」からアカウントを登録。試しに自身のgmailのアドレスで登録。メールが届き、ログイン状態になればOK。
グラフ理論の問題: 〜を含まないグラフの〜を求めよ

# 問題
**任意の$t\geq 2$に対して、$K_{2,t}$を部分グラフとして含まないグラフの最大辺数が次式以下であることを証明せよ。
$$\frac{1}{2}(\sqrt{t-1}n^{3/2}+n)$$**

## 解法
<details><summary>解法を見る</summary><div>

　問題の条件を満たすグラフを$G=(V,E)$とする。$G$に含まれる以下のような部分グラフを考え、これを順序列$M=(v, \\{u_1, u_2\\})$で表す。$G$に含まれる$M$の数を2通りの方法で数える。

> ![graph2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/739010/69a75891-fed5-ef31-ebb7-b0031150c054.png)


　$\\{u_1, u_2\\}$を固定し、$v$を探すと、最大で$t-1$個の$v$がありえる。なぜなら、$t$個以上の$v$があれば$K_{2,t}$が$G$に含まれることになってしまうためである。よって
$$ |M| \leq (t-1){n \choose 2} $$が成り立つ。
　一方、$v$を固定して$M$を成すような$\\{u_1,u_2\\}$を探す。各頂点の次数$d_i=\deg(v_i)$に注目すると、
$$ |M| = \sum_{i\in [n]} {d_i \choose 2} $$となる。
　これらを組み合わせると、
$$|M| = \sum_{i\in [n]} {d_i \choose 2} \leq (t-1){n \choose 2}$$が成り立つ。 ・・・ (A)
　さらに、コーシーシュヴァルツの不等式と(A)より、

```math
\begin{align}
\sum_{i\in [n]} (d_i - 1) &\leq \sqrt{\sum_{i\in [n]} (d_i-1)^2} \sqrt{\sum_{i∈ [n]} 1}\\
&\leq \sqrt{(t-1)n^2} \times \sqrt{n}
\end{align}
```
下式を変形し、元の式を見ると、

```math
\begin{align}
2|E| - \sum_{i\in [n]} 1 &\leq & (\sqrt{t-1})n^{3/2}\\
|E| &\leq & \frac{1}{2}(\sqrt{t-1}n^{3/2} + n)
\end{align}
```
が得られる。

### まとめ
* コーシーシュヴァルツの不等式を、次数の式に適用するといいことがある。
* 3つの頂点で成るグラフを数える！これより多いと数えにくいので注意が必要。

</div></details>
QRコードを生成するパッケージを使ってみた

# QRコードを生成するパッケージを使ってみた

QRコードをパッケージを利用してサクッと作ってみた。

## 環境
- PHP 7.3.18
- composer 1.10.10
- Windows10 Home
- localhost

## 利用するもの
- [endroid/qr-code](https://packagist.org/packages/endroid/qr-code)

## 作成手順
- 任意のディレクトリに「QRコード」フォルダを作成
- コマンドプロンプトを起動して、「QRコード」内に入る。
- 下記を実行し、パッケージをインストールする。

```
composer require endroid/qr-code
```

- 「QRコード」ディレクトリ直下にindex.phpを作成し、下記のコードを貼り付ける。

```
<?php
require_once __DIR__ . '/vendor/autoload.php';

use Endroid\QrCode\QrCode;

$qrCode = new QrCode('Life is too short to be generating QR codes');

header('Content-Type: '.$qrCode->getContentType());
echo $qrCode->writeString();
```

- 下記を実行し、ローカルサーバーを立ち上げる。

```
php -S localhost:8080
```

- [動作確認](http://localhost:8080/)

## 補足
composerでパッケージをインストールした際、私の環境では下記のエラーが表示された。

```
  Problem 1
    - endroid/qr-code 3.9.1 requires ext-gd * -> the requested PHP extension gd is missing from your system.
    - endroid/qr-code 3.9.0 requires ext-gd * -> the requested PHP extension gd is missing from your system.
                                           ode ^3.9 -> satisfiable by endroid/qr-code[3.9.0, 3.9.1].
  To enable extensions, verify that they are enabled in your .ini files:              e enabled in your .ini files:
    - C:\bin\php\php.ini
  You can also run `php --ini` inside terminal to see which files are used by PHP in CLI mode.nal to see which files are used by PHP in CLI mode.
```

JPEG,PNG,GIFなどの画像処理をする際に利用するgdというextensionが必要とのこと。
php.iniの該当箇所がコメントアウトされていたので有効にしたらインストールができるようになった。

```
extension=gd2　　 ← ';'を消して保存すればOK
```
【GAS】先日AppSheetで作った栞アプリに不具合があったので修正

##概要
先日GoogleAppSheetで、本を何巻まで読んだか管理するアプリ（並べ替え,最近読んだ,書籍検索）が出来たので投稿した・・・ところが、実際に使ってみたら思わぬところで不具合が見つかり、修正したのでご報告。

先日の投稿：[【GAS】AppSheetで本を何巻まで読んだか管理するアプリを作成（並べ替え,最近読んだ,書籍検索）
](https://qiita.com/YasumiYasumi/items/ba0bf5cfe09cfbdb85fa)

##不具合とは
まずこのアプリだけども、新しく読んだ本と既読巻数などを登録すると、その本のGoogle書籍検索URL、読んだ日付を自動で生成し、スプレッドシートの一覧に追加。自動でタイトル順に並べ替えを行う。

AppSheet側には、タイトル順にソートしたビューと、最近読んだ順にソートしたビューがある。

で、不具合と言うのが、読み終わった本を一覧から削除したところ、スプレッドシートの並び替えの際、削除したことによって出来た空欄に移動してきた本に対して、書籍検索URLと読んだ日付が更新されてしまい、AppSheetの読んだ順の並びが間違えた並びになってしまったorz

##原因
そもそもの動作は、セルの変更をトリガーに、変更があった書籍に対して[書籍検索URL生成][更新日時入力][並べ替え]が行われる。

新しい書籍が登録された場合の並べ替えはセルの変更と判定されていないようだが、書籍削除によってできた空欄を詰める並び替えだと、空欄に入った書籍が変更のあった書籍と判定されてしまう模様。

そのため書籍を削除すると、空欄を詰める形で並び変わった書籍に対して[書籍検索URL生成][更新日時入力][並べ替え]が行われてしまった。

##対策
書籍が減った場合だけ不具合が起こる。更に、書籍が減って並び替えが行われる所までは期待通りの動作で、並び変わった後に余計な日付更新があるのが良くない。

スプレッドシート視点で考えると、空欄が詰まった時に余計な日付変更があるので、並べ替え前の最終行より並べ替え後の最終行が少なくなった場合（空欄が詰まった場合）、日付変更を行わないようにしたい。

具体的には、並べ替えが行われる度に最終行を記録し、スクリプトが実行される度に前回の最終行を参照し、最終行が減っていたら動作を終了すればOK！

と言うわけで、最終行を書き出すためのシート「シート2」を作成し、コードを追記。変更後のコードがコチラ！

```javascript
function onChange(e) {

  //更新されたセルを取得
  var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('シート1');
  var fs = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('シート2');
  var ActCell = ss.getActiveCell();

  //今回の最終行と前回の最終行を取得
  var oftimeRow = ss.getLastRow();
  var previousRow = fs.getRange(1, 1).getValue();
  
  //行が減っていたら終了＆最終行を上書き
  var dis = oftimeRow - previousRow;
  if(dis<0){
    fs.getRange(1, 1).setValue(oftimeRow);
    return;
  }

  //セルの行列を取得
  var CellRow = ActCell.getRow();
  var CellCol = ActCell.getColumn();

  //セルの内容を格納
  var Cell = ss.getRange(CellRow, CellCol).getValue();

  //自動実行させたくない処理をif文で回避
  if(Cell){ if(CellRow!=1){ if(CellCol<4){

    //A列の文字列でグーグル書籍検索するURLを生成 E列に入力
    var title = ss.getRange(CellRow, 1).getValue();
    title = title.replace(" ", "%20");
    ss.getRange(CellRow, 5).setValue('https://www.google.com/search?q='+title+'&tbm=bks');

    //F列に更新日時を入力
    var date = new Date();
    var today = Utilities.formatDate(date, 'JST', 'yyyy/MM/dd');
    ss.getRange(CellRow, 6).setValue(today);

  } } }

  //B列で並べ替え 行を削除した時も並べ替えたいのでifの外
  var range = ss.getRange("A2:H");
  range.sort([{column:2, ascending:true}]);

  //実行後の最終行をシート2,A1セルに入力
  var lastRow = ss.getLastRow();
  fs.getRange(1, 1).setValue(lastRow);

}
```

素人が作ったアプリだけあって、こういった不具合はまだありそう^^;

##関連ページ
[【GAS】AppSheetで本を何巻まで読んだか管理するアプリを作成（並べ替え,最近読んだ,書籍検索）
](https://qiita.com/YasumiYasumi/items/ba0bf5cfe09cfbdb85fa)
[【GAS】AppSheetからスプレッドシートを操作するとonEditが動かない問題の対処法](https://qiita.com/YasumiYasumi/items/592ecd87c4ac2035fd0f)」

###おしまい
[メモ] Linuxコマンド & git管理 

##Linuxコマンド
```
　$ mkdir [既存フォルダ名]/[Newフォルダ名]：フォルダを作成(メイクディアー)
　$ touch src/components/[ファイル名]：ファイルを作成
　$ rm [ファイル名]：ファイルを削除
　$ rmdir [フォルダ名]：フォルダを削除
　$ cat [ファイル名]：ファイルの閲覧
　$ git grep：git管理下のファイルを検索
　$ vim [フォルダ名]/[ファイル名]
　$ cdコマンド：ディレクトリを移動
　$ lsコマンド：ディレクトリの内容を表示 (ls -a コマンドで、隠しファイルを含めたディレクトリ全内容を表示)
　$ cpコマンド：ファイルをコピー
　$ mvコマンド：ファイルの移動とファイル名の変更。
```

##git管理

###基本的なGitコマンド
（参考）https://docs.aws.amazon.com/ja_jp/codecommit/latest/userguide/how-to-basic-git.html

① ローカルリポジトリの新規作成(initialize)

```
　cdコマンドで該当ディレクトリに移動 => $ git init
```

② ステージングエリアに追加

```
$ git status  （ステージにAdd前：赤色、Add後：緑色）
$ git add .  or $ git add [ファイル名]
```

③ ローカルリポジトリにコミット

```
　$ git commit -v（$ git commit -m 'メモ'）
　①vimというエディターで開かれる
　②編集：「半角英数字」→「i」
　③メッセージ入力画面（１行目：変更内容の要約、２行目：改行、３行目：変更した理由）
　④「esc」→「:wq」→「Enter」保存
```

④-1 コミットの変更履歴を確認

```
　$ git log
　(変更履歴１行だけ：$ git log --oneline)
　(差分だけ：$ git log -p)
　「j」とすると下に移動
　「k」とすると上に移動
　「q」とすると終了
```

④-2 変更差分を確認

```
　$ git diff（ステージとの差分）
　$ git diff HEAD（ステージとコミットの変更差分）
```

⑤ ローカルリポジトリをリモートリポジトリ(github=origin)にPush

```
　$ git push origin master
＊gitをgithubに登録 $ git remote add origin <Clone名>
　(例)git remote add origin https://github.com/Niyomong/shampooo.git
```

⑥ Git管理から外す.gitignore（パスワード、自動生成されるファイル等）

```
(.gitignoreファイルの書き方)
　・#から始まる行はコメント
　・指定したファイルを除外 (例)index.html
　・ルートディレクトリを指定 (例)/root.html
　・ディレクトリ以下の除外 (例)dir/
git rmコマンド：コミットしたファイルGitの管理から削除(ファイル削除してもGitからは削除されない)
　$ git rm [ファイル名]
　$ git rm -r [ディレクトリ名]
ファイルは残すけど、Gitの管理からは削除
　$ git rm --cashed [ファイル名] ＊.gitingoreに追記が必要
```

⑦ ブランチ（大人数の開発）

```
・ブランチ一覧
　$ git branch
・新しいブランチへの切替
　$ git checkout -b [新しいブランチ名]
・既存のブランチに切替
　$ git checkout [既存ブランチ名]
・直近にコミットしたブランチをPush
　$ git push -u origin HEAD
　$ git push origin [ブランチ名])
・ブランチを削除
　$ git branch -d [ブランチ名]
```

###その他Git

・Gitをクローン

```
$ git clone xxx
(例)git clone git@github.com:Niyomong/shampooo.git
```

・gitのversion確認

```
　$ git version
```

・その他git
```
$ git mv [移動したいファイル] [移動先のフォルダ]/　：ファイルの移動
(例)git mv src/App.js src/components/
$ git mv [変更前のファイル名] [変更後のファイル名]　　：ファイル名の変更
(例)git mv src/components/App.js src/components/stock_index.js
$ git status
変更したファイルを閲覧
$ git diffで修正履歴確認
```
WebSocket のサーバー・クライアントをコマンドラインで簡単に実行する（npx と wscat）

## はじめに
こちらのツイートをきっかけに、ふと思いついて試した内容の第二弾のメモです。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">npxで実行できるMQTTクライアントってないのかなぁ <a href="https://twitter.com/hashtag/iotlt?src=hash&amp;ref_src=twsrc%5Etfw">#iotlt</a></p>&mdash; 菅原のびすけ (@n0bisuke) <a href="https://twitter.com/n0bisuke/status/1308754318124748808?ref_src=twsrc%5Etfw">September 23, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

上記を見て「MQTT.js で実現できそうかも」という話をコメントして、その際に試した内容を以下の記事に書きました。

●MQTTクライアントをコマンドラインで簡単に実行する（npx と MQTT.js） - Qiita
　https://qiita.com/youtoy/items/edeaa9cc316d5f47c0e8

そして、このときもう 1つ思いついていたのが「[wscat](https://github.com/websockets/wscat) も似たような、便利な使い方ができるのでは？」ということでした。

## npx で wscat を実行する
IoTな作品を作ろうとしたときに、デバイス間の通信などで MQTT の他に使っていたものの 1つに WebSocket がありました。そして、その検証時に活用できそうなツールを調べ、見つけて実際に利用していたものの 1つに [wscat](https://github.com/websockets/wscat) があります。

wscat を知ったのは、情報を調べていて以下の記事にたどり着いたことがきっかけでした。

●WebSocket の検証では wscat が便利だった - Qiita
　https://qiita.com/toshihirock/items/4dfaca29058c9e744529

以下のような手順で利用でき、自分はあまり利用してないですが様々なオプションもあるようです。

1. インストール： `npm install -g wscat`
2. サーバーとして実行（ポート番号は 8000 を指定）： `wscat -l 8000`
3. クライアントとして実行： `wscat -c ws://【サーバーのURL】:【ポート番号】`

![websockets_wscat_usage.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/4e482be8-b4f8-920b-70d9-13dc19328efd.jpeg)

通常の利用方法は上記のとおり、グローバルインストール後にコマンドを実行する形ですが、npx を利用することで、インストールのステップを踏むことなく wscatコマンドでのサーバー・クライアントとしての実行を行うことができました。

- サーバーとして実行： `npx wscat -l 【ポート番号】`
- クライアントとして実行： `npx wscat -c ws://【サーバーのURL】:【ポート番号】`

Mac のターミナル上で実行すると、以下のようになります。

・サーバー
![wscat_server.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/9bb57b57-3c45-f69b-a9f8-20ba1bb14bfe.jpeg)

・クライアント
![wscat_client.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/91742e61-5421-cf00-dde3-537848ea3413.jpeg)

あとは、サーバー側でもクライアント側でも、どちらかで文字を入力してみると、他方にその入力された文字が表示される、という挙動が確認できます。

## おわりに
WebSocket を使った開発を行う際、簡単に環境を準備できて便利に使えそうです！
[PlayCanvas]Inspector上に表示し、編集可能なパラメータ

# 概要
Inspector上でパラメーター調整できるようにする方法。 Unityでいう **SerializeField** に該当するもの。
PlayCanvaseでは **Attribute** と呼ばれる。

# 実装例
``` javascript:sample.js
var Sample = pc.createScript('sample');

// 第一引数に変数名、第二引数にその名前に紐づける設定をObjectで指定する
Sample.attributes.add('param', {type: 'number', default: 0});
```

# 第二引数での設定項目
第二引数に様々な設定を記述したObjectを渡すことでAttributeを設定するが、その設定項目は16個もある。
その中でもそこそこ多めに使用するであろう項目だけピックアップする。

## type
実際に使用する型を宣言する項目、全項目は[APIリファレンス](https://developer.playcanvas.com/en/api/pc.ScriptAttributes.html)に記載されているので省略する。

## default
初期値を設定する。typeで設定した型と同じ型でなければならない。

## placeholder
項目内に表示されるテキストを設定できる。
用途としては距離などの単位を設定する事が多い。

## title
Inspector上に表示する名前を設定できる。
デフォルトでは第一引数で設定した名前が表示されるが、それが好ましくない場合に使用する。
日本語は使えない。(2020/9/24)

## description
作成したAttributeにInspector上でフォーカスした時に表示される説明文を記載できる。

## min max
typeで指定した型が**number**の時のみ使用可能な項目。
最小値と最大値を設定が可能で片方だけの設定も可能だが、両方設定すればスライダーが表示される。

## array
項目を配列にするか否かのフラグ。
trueにする事で複数の値を保存できるようになる。

## size
**array**がtrueに場合のみ使用する。
配列の上限数を設定する。

## enum schema
値の入力ではなく、ドロップダウンでパラメータを設定できる様にしたい場合に使用する。
内部の値はtypeで設定した型と同じでなければならない。
schemaはtypeで**json**を指定した場合のみ使用する。
はじめてのWebページ！Githubで公開～☆

超ハイパースペシャル初心者の“ぴおにあ”でーす:v:

今日は初めてのWebページを作ってGithubで公開してみました:clap:
稚拙すぎて笑わないでね~:laughing:


公開したサイト　:　 [はじめてのWebページ](https://paeonia77.github.io/first_step/)


##目標##

 MDN Web Doc の[「JavaScript オブジェクトの基本」](https://developer.mozilla.org/ja/docs/Learn/Getting_started_with_the_web/JavaScript_basics)を参考に
　・CSSを軽く意識しつつ
　・クリックイベントを使ったページを
　・Githubで公開
を目標としました。


##HTML/CSS##

<dl>
  <dt>画像</dt>
  <dd>挿入の仕方やサイズ（画素数）の感覚を覚える</dd><br>
  <dt>装飾はまだあまり学んでいないので、まずは、</dt>
  <dd>・文字の色、フォント、影</dd>
　<dd>・背景色</dd>
　<dd>・width, margin, border, padding</dd>
</dl>
 を使って慣れてゆくことを主題としました。

##JavaScript##

[わろ先生](https://qiita.com/kurosawa_kuro)から「イベント」を学ぶようにご教示いただいたので、今回はMDN にあった、
　・画像をクリックすると絵が変更される
　・アクセスしたときに名前を入れ、それが画面トップに反映される。
　・上記名前がページ内のボタンで変更できる。
という機能を使ってみました。


##Githubでの公開##

これは[わろ先生](https://qiita.com/kurosawa_kuro)が動画で丁寧に解説してくださっているので、それを参考にしました。
参考資料：[GitHub Pagesでのホームページ公開方法(Windows)](https://www.youtube.com/watch?v=xwxsv6RKc0M&feature=youtu.be)

先生の動画ではアップロードが「index.html」ファイルひとつだけでした。
今回は画像が複数あり、.jsや.css ファイルもある場合のアップロードはどうなるのか少々心配でしたが、何事も大雑把な私はフォルダ3つと「index.html」のファイルを纏めてドラッグアンドドロップ！　えいやっ！

Githubは優秀で、無事に読み込みされました。:joy:


##おわりに##

初めてのWebページ、とても楽しみながら作成できました。
この一か月半は、本当に全く意味が分からず、説明の言葉をひとつひとつ調べながら基礎情報を何度も読んでいました。

最近はやっと自分が何をやっているかが分かってきたような？（いや分かっていないような？）そして、もっといろいろな機能を知りたいなぁと思えてきました。

最終ゴールはSmart Contractですので、引き続きWeb App とJavaScriptの勉強を続けたいと思います。
inputFieldのTMP版をスクリプトで使う方法。

最終的にはこんな感じになる。
![ezgif.com-video-to-gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688851/c38eef9b-4efb-5b37-6ed6-e7d0d6c0c942.gif)

テキストメッシュプロで日本語が使える設定などは各自で済ませておいてください。
それについては参考になるようなサイトを貼っておきます↓
[TextMeshProで日本語フォントを使用する【Unity】](https://hi-network.sakura.ne.jp/wp/2020/04/15/post-1407/)


では早速始めにCreate→UI→InputField - TextMeshProを選択。
その後空のゲームオブジェクトを作る。

![“shot” 2020-09-24 0.01.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688851/7e65e274-7c33-13cf-ff11-1c0cd0ca62b3.png)



次に新しくスクリプトを作る。
スクリプトの名前はなんでもよし。
スクリプトを作成したら

```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
```
のusing〜と書いてあるところに

```
using TMPro;
```
を追加する。

その後「TMP_InputField」型の変数を宣言。↓のように書く。
ここでは変数の名前を「_inputField」としている。

```
public class Textscript : MonoBehaviour
{

    TMP_InputField _inputField;

    void Start()
    {
```
その後Startの中でInputField (TMP)のゲームオブジェクトを探し、そこに「TMP_InputField」をGetComponentする。

```

    void Start()
    {
        _inputField = GameObject.Find("InputField (TMP)").GetComponent<TMP_InputField>();


    }
```

その後「public」で「InputName」という関数を作ります。
↓関数の中身も含めこんな感じです。

```
    public void InputName()
    {
        string name = _inputField.text;
        Debug.Log(name);

        _inputField.text = "";
    }
```
中身の説明としてstring型のnameという変数に、先ほど作った「TMP_InputField」型の「_inputField」という変数の中のtextを入れる。
そしてDebug.Log(name)でコンソールに出力。
という感じ。
ここまでのスクリプトの全体を貼っておきます。

```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;

public class Textscript : MonoBehaviour
{
    TMP_InputField _inputField;

    void Start()
    {
        _inputField = GameObject.Find("InputField (TMP)").GetComponent<TMP_InputField>();
    }

    void Update()
    {
        
    }

    public void InputName()
    {
        string name = _inputField.text;
        Debug.Log(name);
    }

}
```

スクリプトはここまでで、作り終わったら先ほど作った空のゲームオブジェクトにこのスクリプトを貼っつける。


そしたら「InputField (TMP)」のインスペクタービューの「On End Edit(String)」の「+」を押し、「None」の部分にスクリプトがついている空のゲームオブジェクトをドラッグ。
右に色々選択できるところがあるので、そこで先ほど作ったスクリプトの名前を探し、その中に先ほど作った関数「InputName」があるのでそれを選択。
そうするとこうなる↓。

![“shot” 2020-09-24 0.05.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/688851/7026ca66-20b6-7b9f-d62a-f963788a3972.png)


以上。
一番上のGIF画像みたいに入力した文字がコンソールに出力されるはず。
BFE.dev解答記録 #2. placeholderをサポートするcurry()を実装する

> https://bfe.dev/ja はFrontEnd版のLeetCode、GAFAの面接を受けるなら練習した方がいいかなと。
> 以下は自分の練習記録です。

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/yirk0xdbyytnlh5yzhjv.png)

第２問 [BFE.dev#2. placeholderをサポートするcurry()を実装する](https://bigfrontend.dev/ja/problem/implement-curry-with-placeholder)

[BFE.dev#1. curry()を実装する](https://bigfrontend.dev/ja/problem/implement-curry)とちょっと違って、今度はplaceholderの対応が必要になる

```js
curriedJoin(1, 2, 3) // '1_2_3'
curriedJoin(_, 2)(1, 3) // '1_2_3'
curriedJoin(_, _, _)(1)(_, 3)(2) // '1_2_3'
```

実装方針は一緒、引数の数が足りるかどうかを確認する他、placeholderの除外が必要、以下のように


```js
const expectedArgLength = func.length
const isArgsEnough = args.length >= expectedArgLength &&
  args.slice(0, expectedArgLength)
    .every(arg => arg !== curry.placeholder)
    
if (isArgsEnough) {
  return func.apply(this, args)
} else {
  // TODO
}
```

引数が足りない場合は、第１問と同じ引数を保存して次回の実行に渡す。

問題は、`Function.prototype.bind`は引数のリストを連結するだけで、欲しいのはplaceholderの入れ替えですね。

なのでこの場合は、`bind()`を使うのでなく、新しいfunctionを返して、古い引数と新しい引数をいい感じにmergeするように。

```js
if (isArgsEnough) {
  return func.apply(this, args)
} else {
  return function(...newArgs) {
    // we need merge two arg list,  newArgs and args
    const finalArgs = []
    let i = 0
    let j = 0
    while (i < args.length && j < newArgs.length) {
      if (args[i] === curry.placeholder) {
        finalArgs.push(newArgs[j])
        i += 1
        j += 1
      } else {
        finalArgs.push(args[i])
        i += 1
      }
    }

    while (i < args.length) {
      finalArgs.push(args[i])
      i += 1
    }

    while (j < newArgs.length) {
      finalArgs.push(newArgs[j])
      j += 1
    }
     
    // then just call the curried function again
    return curried(...finalArgs)
  }
}
```

よし、通った！

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/snfx58o73q2xa2af2pir.jpg)

[BFE.dev#1. curry()を実装する](https://bigfrontend.dev/ja/problem/implement-curry)よりこの問題は難しい。

役に立てると嬉しいです！　次回を楽しみに！
Manjaro に Docker をインストール

# はじめに

Raspberry Pi 4 にインストールした Manjaro に Docker を入れて何かサーバを立てよう。
初めてのArch系で、恥ずかしながら緊張しているよ。

```:確認環境
$ lsb_release -rd
Description:    Manjaro ARM Linux
Release:        20.09
```

# Docker

## インストール

```
$ sudo pacman -S docker
$ docker --version
Docker version 19.03.12-ce, build 48a66213fe
```

## 一般ユーザに実行権限を与える

```
$ sudo usermod -aG docker `whoami`
```

## サービスの有効化

再起動無しで `systemctl start docker` したかったが、全然起動してくれなかった。
`systemctl enable docker` して再起動したらあっさりいけたので、これで良しとする。

```
$ sudo systemctl enable docker
$ sudo reboot
```

※グループが反映されていないからでした。

# Docker Compose

## インストール

```
$ sudo pacman -S docker-compose
$ docker-compose --version
docker-compose version 1.27.3, build unknown
```

# おわりに

結構パッケージ充実してんだね。
グローバルインストールせずにMQTTをCLIで試す


JavaScriptやNode.jsを書いてる人はnpmコマンドなどは通常装備だと思うのでnpxでmqttを利用する方法のメモです。
JSerやNoder向けIoTって感じですね。とはいえMQTTをとりあえず試すってときの話です。

npmが入ってない人は素直にmosquittoをインストールでも良いかも。

## MQTTクライアントライブラリ(MQTT.js)を利用

mqttをcliで利用できるかつnpmにレジストリされてるツール探してました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Sub のほうなら、MQTT.js で「npx mqtt sub -t &#39;トピック&#39; -h &#39;ホスト名&#39;」みたいなの感じでどうでしょう？<br>（意図と異なるかもですが）<br><br>Pubのほう、「npx mqtt pub -t &#39;トピック&#39; -h &#39;ホスト名&#39; -m &#39;from MQTT.js&#39;」とかやったら、メッセージを送るたびにインストールがされて微妙でしたがｗ</p>&mdash; you (@youtoy) <a href="https://twitter.com/youtoy/status/1308775232446971908?ref_src=twsrc%5Etfw">September 23, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

探しても見つからないなぁと思ってたら[mqtt.jsのCLI利用のドキュメント](https://www.npmjs.com/package/mqtt#cli)にありました。 @youtoyさんありがとうございます :) 

### subscribe側

```
$ npx mqtt sub -h ホスト名 \
-t トピック名 \
```

これで待ち受けてくれます。npxは一回だけインストールして実行してくれるのでグローバルインストール(npm i -g ~~)したく無い時に使えます。

### publish側

```
$ npx mqtt pub -h ホスト名 \
-t トピック名 \
-m '{"content":"Hello!!! from MQTT!"}'
```

## PubNubの場合

[PubNubで5分でリアルタイムWebこと初め + MQTTでデバイス連携も](https://qiita.com/n0bisuke/items/36e4b334d17174446df7) など最近PubNub触ってるのでこちらもメモ。mosquittoのCLIとオプションが一緒なのでコピペで大丈夫でした。

### subscribe側

```
$ npx mqtt sub -h mqtt.pndsn.com \
-t pub-c-xxxxxxxxxxxxxxxxxxxx/sub-c-xxxxxxxxxxxxxxxxxxxx/トピック名 \
-i pub-c-xxxxxxxxxxxxxxxxxxxx/sub-c-xxxxxxxxxxxxxxxxxxxx/クライアントID
```

### publish側

```
$ npx mqtt pub -h mqtt.pndsn.com \
-t pub-c-xxxxxxxxxxxxxxxxxxxx/sub-c-xxxxxxxxxxxxxxxxxxxx/トピック名 \
-i pub-c-xxxxxxxxxxxxxxxxxxxx/sub-c-xxxxxxxxxxxxxxxxxxxx/クライアントID \
-m '{"content":"Hello!!! from MQTT!"}'
```

## 所感

subscribe側は一度実行したら実行しっぱなしというのが多いと思うので、npxでも良さそうだけど、publish側は確認で何回も実行すると思うのでnpxでの実行だと毎回インストールされてだるいかもしれませんね。

`npm i -g mqtt`でグルーバルインストールしてしまってもよいかもしれません。

## 追記: 同じタイミングで記事書いてくれてたという笑

@youtoyさんも記事を書かれていたので、リンクを掲載します。

> [MQTTクライアントをコマンドラインで簡単に実行する（npx と MQTT.js）](https://qiita.com/youtoy/items/edeaa9cc316d5f47c0e8)

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">やばい、うける / グローバルインストールせずにMQTTをCLIで試す <a href="https://t.co/DG5KSgqpXD">https://t.co/DG5KSgqpXD</a></p>&mdash; 菅原のびすけ (@n0bisuke) <a href="https://twitter.com/n0bisuke/status/1308784739810115584?ref_src=twsrc%5Etfw">September 23, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

同じタイミングで......わろ
PHP Laravel 6 おすすめ映画投稿サイト作成過程 5:更新機能作成編

#ルーティング

更新ページにはeditを使用します。

```
| GET|HEAD  | recommends/{recommend}/edit | recommends.edit    | App\Http\Controllers\RecommendController@edit                          | web          |

```


更新をDBに登録するにはupdateを使用します。

```
| PUT|PATCH | recommends/{recommend}      | recommends.update  | App\Http\Controllers\RecommendController@update                        | web          |
```


#viewの作成

![Screen Shot 2020-09-23 at 22.54.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/736153/5658ca12-cde3-c0f3-d06a-69c4dc54c8ee.png)

#editに対するコントローラーの作成

```recommend/app/Http/Controllers/RecommendController.php
public function edit(Recommend $recommend)
    {
      return view('recommends.edit');
    }
```

#editへのリンクをindexに追加

```recommend/resources/views/recommends/index.blade.php
<table>
  <thead>
    <tr>
      <th>タイトル</th>
      <th>画像：現在は空</th>
      <th>URL</th>
      <th>操作</th>
    </tr>
  </thead>
  @foreach($recommends as $recommend)
    <tr>
      <td>{{$recommend->title}}</td>
      <td>{{$recommend->image_file_name}}</td>
      <td>{{$recommend->url}}</td>
      <td><a href="{{route('recommends.show', $recommend->id)}}">詳細</a></td>
      <td><a href="{{route('recommends.edit', ['recommend' => $recommend])}}">編集</a></td>
    </tr>
  @endforeach
</table>
```

#editからコントローラーへ更新内容を飛ばす
formタグで更新した内容を飛ばします。
この時、@method('PUT')を忘れずに。

```recommend/resources/views/recommends/edit.blade.php
<table>
  <thead>
    <tr>
      <th>タイトル</th>
      <th>映画URL</th>
      <th>概要</th>
      <th>感想</th>
    </tr>
    <tr>
      <th><input type="text" name='title'></th>
      <th><input type="URL" name='url'></th>
      <th><textarea name="description" id="" cols="30" rows="10"></textarea></th>
      <th><textarea name="Impressions" id="" cols="30" rows="10"></textarea></th>
      </tr>
   </thead>
```







#DBの更新
editから受け取った内容を、Modelのアップデートメソッドを使用して更新します。

```recommend/app/Http/Controllers/RecommendController.php
 public function update(Request $request, Recommend $recommend)
    {
        $recommend->update($request->all());
        return redirect()->route('recommends.show', compact('recommend'));
    }
```