OmniAICreator/Qiita-1.07M huggingface dataset:
FizzBuzz毎回書くのめんどくさいのでGoパッケージにした

# はじめに
めんどくさいですよね。Goパッケージ化しました。
面接試験などでFizzBuzz課題が出た時などに使ってみてください。

# リポジトリ
https://github.com/junpayment/fizzbuzz

使い方はREADME参照ください

# 同期/非同期モード

常々、FizzBuzzって非同期にしたらええんじゃないの？と思ってたので非同期のメソッドも作りました。

こんな感じで呼び出します。

```golang
fizzbuzz.DoAsync(100, 10)
```

処理はこちらです。
https://github.com/junpayment/fizzbuzz/blob/master/fizzbuzz.go#L38

数字をFizzBuzz化して、結果を別goroutineに渡してソートしているんですね。

ベンチマークはこちらです。

```sh
goos: darwin
goarch: amd64
pkg: fizzbuzz
BenchmarkDo/num_10000/do_sync-8 	    2000	    707744 ns/op
BenchmarkDo/num_10000/do_async/goroutine_1-8         	     200	   8040204 ns/op
BenchmarkDo/num_10000/do_async/goroutine_5-8         	     200	   6065541 ns/op
BenchmarkDo/num_10000/do_async/goroutine_10-8        	     200	   5985554 ns/op
BenchmarkDo/num_10000/do_async/goroutine_20-8        	     300	   5787948 ns/op
BenchmarkDo/num_10000/do_async/goroutine_100-8       	     300	   5782902 ns/op
BenchmarkDo/num_10000/do_async/goroutine_1000-8      	     200	   6126495 ns/op
```

はい、非同期の方がスコア悪いですね。

FizzBuzzの処理は入力待ちとか応答待ちとか皆無なので、並列化した際のチャネルスイッチのコストの方がぜんぜん高いということだと思います。

おそらく、こちらの関数に`time.Sleep(10 * time.Millisecond)`など入れるとスコアが逆転すると思います。

https://github.com/junpayment/fizzbuzz/blob/master/fizzbuzz.go#L13

以上
TTGO ESP-32 OLED USBコネクタ修理

TTGOのESP-32ボードを使用していたら・・・
![TTGO-ESP-check-1.jpg](https://qiita-image-store.s3.amazonaws.com/0/285344/b1dcec66-cecc-9317-f021-a877e2446018.jpeg)
MicroUSBコネクタがボロッと剥がれました。

PCが時々ソフトウェア的に外れる音がしていたので何かな？と思っていた矢先の事。

仕方がないので修理しました。
![TTGO-ESP-check-2.jpg](https://qiita-image-store.s3.amazonaws.com/0/285344/a2ebea66-925e-835d-f9c3-10f8f4f1c168.jpeg)

修理は、当然ハンダゴテです。
今回は、周辺にもハンダを盛って剥がれ防止をします。

最後にUSBコネクタとの導通とショートをチェック。

ちなみに、これはM5StackのUSB Tyoe-CのCC1,CC2が繋がっていない為の検証の為に用意した物です。
![USB-C-check.jpg](https://qiita-image-store.s3.amazonaws.com/0/285344/2a7c0680-094e-1ae7-0387-d296655d6ee5.jpeg)
iOSアプリからInstagramストーリーズシェアを行う方法

自身のiOSアプリからURL SchemeとUIPasteboardを介して、簡単にInstagramのストーリーズへシェアする機能が公式で提供されているので紹介します。

##共有可能なデータと対応するキー
|データ|型|キー|
|:--|:--|:--|
|画像 [^1]|NSData|com.instagram.sharedSticker.backgroundImage|
|動画 [^2]|NSData|com.instagram.sharedSticker.backgroundVideo|
|スタンプ|NSData|com.instagram.sharedSticker.stickerImage|
|背景色上部|NSString|com.instagram.sharedSticker.backgroundTopColor|
|背景色下部|NSString|com.instagram.sharedSticker.backgroundTopColor|

[^1]: サポートされているフォーマットはJPG、PNG。最大サイズ720x1280。推奨画像比9：16または9:18。
[^2]: サポートされているフォーマットはH.264、H.265、WebM。動画は1080pで最長20秒まで対応。50MB以下を推奨。

##実装の流れ
1. Info.plistのLSApplicationQueriesSchemesキーへinstagram-storiesを追加。
2. UIPasteboardへストーリーズでシェアしたいデータを設定する処理を追加。
3. URL Scheme(instagram-stories://share)でInstagramアプリを起動する処理を追加。

Instagramアプリは、UIPasteboardに追加したデータが設定された状態のストーリーズ編集画面で起動します。

##具体的な実装例

**スタンプと背景色を指定**

```swift
func shareStickerImage() {
    let url = URL(string: "instagram-stories://share")
    let pngImageData = UIImage(named: "fish.jpeg")?.pngData()
    let items: NSArray = [["com.instagram.sharedSticker.stickerImage": pngImageData！,
                           "com.instagram.sharedSticker.backgroundTopColor": "#00ff00",
                           "com.instagram.sharedSticker.backgroundBottomColor": "#ff00ff"]]
    UIPasteboard.general.setItems(options as! [[String : Any]], options: [:])
    UIApplication.shared.open(url!, options: [:], completionHandler: nil)
}
```

実行結果
![IMG_0157.PNG](https://qiita-image-store.s3.amazonaws.com/0/368129/266b9fdd-38d9-89cd-e539-1c8526cbb51c.png)

背景色を指定しない場合、自動で`#222222`の単色に背景が設定される。
単色の場合は、グラデーションが適用されない。

実行結果(背景色の指定なし)

![IMG_0162.PNG](https://qiita-image-store.s3.amazonaws.com/0/368129/f42600ba-4c13-d8d3-db39-a8e26254e2e2.png)


**背景・スタンプ画像と背景色を指定**

```swift
func shareBackgroundAndStickerImage() {
        let url = URL(string: "instagram-stories://share")
        let pngImageData = UIImage(named: "blurfish.jpeg")?.pngData()
        let pngStickerData = UIImage(named: "fish.jpeg")?.pngData()
        let items: NSArray = [["com.instagram.sharedSticker.backgroundImage": pngImageData!,
                               "com.instagram.sharedSticker.stickerImage": pngStickerData!,
                               "com.instagram.sharedSticker.backgroundTopColor": "#00ff00",
                               "com.instagram.sharedSticker.backgroundBottomColor": "#ff00ff"]]
        UIPasteboard.general.setItems(options as! [[String : Any]], options: [:])
        UIApplication.shared.open(url!, options: [:], completionHandler: nil)
}
```

実行結果
![IMG_0161.PNG](https://qiita-image-store.s3.amazonaws.com/0/368129/43f20df5-0ed2-f05a-45c4-0627ee0e7d44.png)

背景色と背景画像の両方を設定すると背景画像が優先されて表示される為、
`"com.instagram.sharedSticker.backgroundTopColor": "#00ff00"`
            `"com.instagram.sharedSticker.backgroundBottomColor": "#ff00ff"`
の部分の背景色の設定は不要となる。
背景画像へスタンプをぼかした画像を指定することで、実行結果のような投稿が可能。
AWS API Gatewayでモックを作ってみよう

#きっかけ
マネージャー「テストで必要だから外部APIのモックを作って。API Gatewayを使えば簡単だから。」
確かにAPI Gatewayの統合リクエストの統合タイプに`Mock`って項目がある。
これならば簡単にできそうだ :blush:
#API Gatewayでモックを作成
1. [Amazon API Gatewayコンソール](https://console.aws.amazon.com/apigateway)で`APIの作成`ボタンから新しいAPIを作成する
2. API Gatewayが作られるので`アクション`ボタン > `リソースの作成`からAPIエンドポイントを設定する（必要に応じてCORSを有効にする）
3. エンドポイントが作られるので`アクション`ボタン > `メソッドの作成`からメソッドを作成する
4. メソッドのセットアップ画面で`統合タイプ`を`Mock`にする

##ステータス200で返したい場合
* 統合リクエストのマッピングテンプレート（Content-Type application/json)を下記にする（初期値のまま）

```
{"statusCode": 200}
```

* 統合レスポンスのメソッドレスポンスのステータスが200のマッピングテンプレートに返したい値を設定する

##ステータス400で返したい場合
* 統合リクエストのマッピングテンプレート（Content-Type application/json)を下記にする

```
{"statusCode": 400}
```

* メソッドレスポンスの`レスポンスの追加`から400を追加する
* 統合レスポンスの`統合レスポンスの追加`から以下の設定をする
  * HTTPステータスの正規表現：400（統合リクエストの値を正規表現で指定できる）
  * メソッドレスポンスのステータス：400（メソッドレスポンスで追加したステータス）
* ステータスが400のマッピングテンプレートに返したい値を設定する

#テストとデプロイ
設定が終わったらメソッドの実行画面のテストからメソッドのテストをしてみましょう。
テスト画面でURLクエリパラメータやPOSTのリクエスト本文の設定も可能です。
テストで問題がなければ、`アクション`ボタン > `APIのデプロイ`からデプロイしましょう。
デプロイをするとステージエディター画面に遷移し、呼び出しのURLが表示されます。
`呼び出しのURL + 設定したリソース`でAPIにアクセスできるようになります。
APIの設定を変えた時もAPIのデプロイを忘れずに！
（何度かデプロイを忘れて、おかしい..動かない...となりました :confounded:）

#クエリパラメータを取得
`$input.params("パラメータ名")`でクエリパラメータを取得できます。
統合リクエストのマッピングテンプレートで以下のように設定するとクエリパラメータでステータスコードを分岐させられます。

```
#if($input.params("debug") == "200")
  {"statusCode": 200}
#elseif($input.params("debug") == "400")
  {"statusCode": 400}
#else
  {"statusCode": 500}
#end

##コメントを書く場合は先頭に「#」を2個
```

#まとめ
これでモックはバッチリ！:laughing:

と思ったら、あれれ・・・POSTのリクエストデータが取れない！？
色々調べてみると、`統合タイプ：Mock`ではデータ取得ができないらしい...:scream:
（参考：[teratail　AWS API GatewayでHTTPリクエストのjsonを取得したい](https://teratail.com/questions/172025)）
・・・・仕方ないのでMockはやめて、Lambda関数で作ることにします。
が、長くなるのでLambdaの話は[次回](https://qiita.com/takeh/items/3915e47f58939a6fab88)に。

#プチ連載
1回目　AWS API Gatewayでモックを作ってみよう（本記事）
[2回目　AWS API Gateway + Lambda (Python) でモックを作ってみよう](https://qiita.com/takeh/items/3915e47f58939a6fab88)
[3回目　Slack + Lambda (Python) でAWS API Gatewayモックを作ってみよう](https://qiita.com/takeh/items/9941f78449ff907c1e76)

#We're hiring!
AIチャットボットを開発しています。
ご興味ある方は [Wantedlyページ](https://www.wantedly.com/projects/266837) からお気軽にご連絡ください！

#参考記事
[teratail　AWS API GatewayでHTTPリクエストのjsonを取得したい](https://teratail.com/questions/172025)
ログ設計について

![image.png](https://qiita-image-store.s3.amazonaws.com/0/257568/bd547d1d-a97c-e59e-b7b3-550b1eff4097.png)

ログの設計についてどのように考えるべきなのかを知りたかったため読んだ。
結果、ログを考えることは運用をどう考えるかとイコールであり、前提として必要なのは運用設計であることが分かった。

## ログとは
システムを運用していく上で、必ず必要となるデータ

## ログの役割
大きく分けて2つ

### 障害調査
  - 障害発生箇所や影響度の調査などで必要とする役割
  - 比較的直近のデータで一定日時を過ぎると削除する傾向のあるデータ

### 監査対応 
  - 情報流出や不正アクセスなど、セキュリティ的な側面で必要とする役割
  - 比較的長期保管が必要なデータ

## ログ管理サーバー
ログを稼働システム上に長期保管してしまうと下記のような問題がある

- ディスク容量の圧迫
- 冗長化構成だった場合、ログの調査を横断的に行う必要がある  

これらの問題を解決するために必要なログを1箇所に集めるのがログ管理サーバーになる
以下、ログ管理サーバーがもつ主な機能といえる

### ログの一元管理  
管理対象のログを一か所に集めることで稼働システムのサーバーで長期保管する必要がなくなる

### ログの分析・レポート  
集めたログの内容を分析し、レポートとして表示することができる。今システムに何が起きているのか、過去にシステムで何が起きていたかを確認できる

### ログの圧縮
ログの長期間保存は膨大なディスク容量が必要になるのでデータ圧縮機能を持っているソフトが多い。

### ログのモニタリング
リアルタイムにログを監視し、問題があればメールなどでアラートを上げる機能。
監視とのすみ分けをしないと、二重監視の可能性があるので注意する必要がある。

### ログの原本管理、改ざん防止機能
基本的にはログはテキストベースのデータなので、改ざんすることが容易。
ログが改ざんされてしまうと、障害調査も監査対応も無意味になるので改ざんを検知し、原本を正しく管理する機能があることが多い

### ログ管理サーバーといえるようなサービス主なサービス例
- S3
- GCS
- IDCF  

など


## 書籍情報
JBS Technology Inc, 近藤誠司(監修), みんなが知っておくべき運用設計のノウハウ
https://amzn.to/2VU8olW

## 雑感
今関わっているETLツールやDMPないしCDPなどは、この「ログ」がシステムが扱うメインの情報となるのでその辺り理解をする為にもとても適していた。
#Zapier 活用事例 -  #Slack のチャンネルに bot ではなく自分のユーザーとして投稿できる

# アクション設定

Send as Bot を no にする

![image](https://user-images.githubusercontent.com/13635059/54238564-25808c00-455c-11e9-83a3-eef631d012af.png)

# ユーザーの場合

![image](https://user-images.githubusercontent.com/13635059/54238721-958f1200-455c-11e9-8ba3-6feedf99715f.png)

# bot の場合

![image](https://user-images.githubusercontent.com/13635059/54238751-ab043c00-455c-11e9-806d-ca5656d137f0.png)




# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/759








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
【OpenSiv3D】OpenSiv3Dで独自で定義したクラスや構造体のシリアライズ・デシリアライズを行う

# 【はじめに】
Militumです。

今回は[OpenSiv3D](https://github.com/Siv3D/OpenSiv3D)を使用して、
独自で定義したクラスのシリアライズ・デシリアライズする方法を紹介したいと思います。

# 【OpenSiv3Dのバージョン】
Windows Desktop 0.3.1

# 【サンプルコード】

```c++
#include <Siv3D.hpp>

namespace
{
	struct Character
	{
		uint32 id_;    // 識別用ID
		String name_;  // 名前
		int32 hp_;     // 体力
		int32 attack_; // 攻撃力

		template <class Archive>
		void SIV3D_SERIALIZE(Archive& archive)
		{
			archive(
				id_,
				name_,
				hp_,
				attack_
			);
		}
	};
}

void Main()
{
	// バイナリファイルへ書き込み①
	{
		const Character character{ 1000, U"Siv3Dくん", 100, 20 };
		Serializer<BinaryWriter> writer(U"OpenSiv3D-Character.bin");
		writer(character);
		writer.getWriter().close();
	}

	// バイナリファイルへ書き込み②
	{
		const Character character{ 1001, U"Siv3Dくん", 200, 10 };
		Serializer<BinaryWriter> writer(U"OpenSiv3D-Character2.bin");
		writer(character.id_);
		writer(character.name_);
		writer(character.hp_);
		writer(character.attack_);
		writer.getWriter().close();
	}

	// バイナリファイルの読み込み①
	{
		Character character;
		Deserializer<BinaryReader> reader(U"OpenSiv3D-Character.bin");
		reader(character);
		reader.getReader().close();

		Print(character.id_);
		Print(character.name_);
		Print(character.hp_);
		Print(character.attack_);
	}

	Print(U"-----"); // 仕切り線

	// バイナリファイルの読み込み② 変数別に格納
	{
		Character character;
		Deserializer<BinaryReader> reader(U"OpenSiv3D-Character2.bin");
		reader(character.id_);
		reader(character.name_);
		reader(character.hp_);
		reader(character.attack_);
		reader.getReader().close();

		Print(character.id_);
		Print(character.name_);
		Print(character.hp_);
		Print(character.attack_);
	}

	// 旧Siv3DのWaitKeyに当たる関数が見当たらなかったので終了イベントを任意のキーに指定
	System::SetExitEvent(WindowEvent::AnyKey);
	while (System::Update())
	{
	}
}
```

# 実行結果
![20190312-225515-858.png](https://qiita-image-store.s3.amazonaws.com/0/283952/ea344f0d-9338-b313-c9ea-297b4dff880a.png)

# 補足
独自で定義したクラスのシリアライズ/デシリアライズを行う場合、
サンプルで構造体内に実装した下記の関数が肝となります。
`SIV3D_SERIALIZE` は、OpenSiv3Dで用意されたマクロで、Serializer経由で呼び出せばシリアライズ、
Deserializer経由で呼び出せばデシリアライズ用の関数として機能します。

```c++
template <class Archive>
void SIV3D_SERIALIZE(Archive& archive)
{
	archive(
		id_,
		name_,
		hp_,
		attack_
	);
}
```

# 組み合わせられる
サンプルコードでは、構造体のシリアライズ関数を通してシリアライズしたデータ、
個々のパラメータを別々にシリアライズしたデータを書き込む際と読み込む際にペアとしていますが、
これらは組み合わせを変えても問題ありません。(書き込みは①で出力し、読み込みは②を使用するなど)
※<b>この挙動は、Windows Desktop 0.3.1時点のOpenSiv3Dの仕様の可能性もあるので、
今後のバージョンでは使えなくなるかもしれません。</b>

---

次回は、今回紹介した処理を応用しつつ、
規定フォーマットのCSVファイルを使用して、ツールでシリアライズしたデータを出力し、
OpenSiv3Dのアプリケーションでデシリアライズする処理を紹介予定です。

# 参考
* [Siv3D/Reference-JP - バイナリファイル]
(https://github.com/Reputeless/Siv3D-Reference/blob/master/Tutorials/Binary.md)
* [シリアライズを使って自作アプリにUndo/Redoを実装する](https://qiita.com/agehama_/items/58ae9e712b0a352f3f0d)
GitHubで使っていないPrivateリポジトリのメンテ

# 状況
終わったプロジェクトや、諸事情により別のリポジトリーに移行して使っていないリポジトリーが増えてくると可視性が低くなる

# 対応

1. リポジトリーを「Settings」からリネームして、接頭辞「xxx-」を名前につける
2. リポジトリーを「Settings」から Archiveする

# リポジトリを一覧表示する際に

検索条件 `archived:false`をつけて検索する
PowerAppsのペン入力コントールをSharePointリストの添付ファイルとしてアップロードする

いろいろ試行錯誤していたら偶然できました。
検索しても全然記事がなかったので投稿します。
(手元にPowerAppsをいじれる環境がないため、テキストのみの説明になります)

以下の感じで実現できました。

1. コレクションを作成
2. ペン入力コントロールを配置
3. SharePointリストにひもづいたフォーム(添付ファイル)を作成
4. 添付ファイルフォームをコレクションとひもづける
5. Submitボタンを配置

##1. コレクションを作成
コレクションを準備します。
以下の要素が必要になります。
　・**Id**：添付ファイルとして登録する際に必要な模様。
　・**DisplayName**：ファイル名になる。拡張子は.pngにする。
　・**image**：ペン入力コントロールのImage属性をセットする。

画面のOnVisibleあたりに以下のような感じで記載します。

```
Clear(LocalImages)
```

##2. ペン入力コントロールを配置
ペン入力コントロールを画面上に配置します。
コントロールの名前をPenInputとします。

##3. アップロード先のSharePointリストにひもづいたフォーム(添付ファイル)を作成
フォームを配置し、データソースをアップロード先のSharePointリストにします。
フォーム名をFormとし、属性は"新規"にします。
添付ファイルのフォーム(Attachmentsコントロール)を表示するようにします。
その他必須のカラムとかがある場合は、適宜入力フォームを追加する等します。

##4. 添付ファイルフォームをコレクションとひもづける
添付ファイルフォームのItemsに、1.で作成したコレクションを指定します。

##5. Submitボタンを配置
ボタンを配置し、OnSelectに以下のコードを記載します。

```
Collect(LocalImages,{Id:1,DisplayName:"image.png",image:PenInput.Image});
SubmitForm(Form);
ResetForm(Form);
Clear(LocalImages)
```

---
ボタンを押下すればSharePointリストに新規レコードが挿入され、ペン入力コントロールに書いたものが添付ファイル(画像)としてアップロードされます。
【Rails】よく使うMYSQLコマンド

Railsで開発をする際によく使用するmysqlのコマンドをまとめました。

##パスワードを指定してログインする

```
mysql -u root -p PASSWORD;
```

##データベースを確認する
```
show databases;
```

##使用するデータベースを指定する
```
use databases;
```

##テーブルを確認する
```
show tables;
```

##テーブル内のデータを確認する
```
select * from table_name;
```

##テーブル内のカラムを確認
```
destribute table_name;
```
Create User and Database

# MySQL MariaDB

### ユーザ作成
#### 専用データベースの場合
```sql
CREATE DATABASE salse CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
GRANT ALL PRIVILEGES ON *.* TO 'davide'@'%' IDENTIFIED BY 'jw8s0F4';
FLUSH PRIVILEGES;
```
#### 共用データベースの場合
```sql
CREATE DATABASE salse CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
GRANT ALL PRIVILEGES ON sales.* TO 'davide'@'172.24.0.0/12' IDENTIFIED BY 'jw8s0F4';
FLUSH PRIVILEGES;
```
### クエリをエディタで編集
```sql
\e
```
macOS は￥と＼が別

### ログイン
```
docker run --rm -it mariadb mysql -h host -u davide -p'jw8s0F4' sales
```

# PostgreSQL

### ユーザ作成
```
CREATE USER davide WITH PASSWORD 'jw8s0F4';
```

### データベース作成
```
CREATE DATABASE sales OWNER davide;
```

### ログイン
```
docker run --rm -it postgres psql -h host -U davide sales
```
とあるエンジニアの問題意識 2019-03-12


# 物事の理解を深めるのに、よく目を閉じて考える。沈思黙考。なかば仮眠状態。

頭の中だけで、ひとつの問題について考える。意図的に考えて、次に空白を作り、脳に任せて自動思考させる感覚。

人生の課題にとどまらず、プログラミングの設計について考えるときもよくやる。

エンジニア <https://t.co/BlbQrZ1mOv>

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/758








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
はじめてのC++【16日目】

#はじめに
時間ないのですこしだけ


###std::arrayと配列って何が違うのか検索してみた。

まず、std::arrayを使う理由は、size()やback()などの機能を使いたいから。
通常の配列（```int a[]```）はこのような便利の機能を使えない。std::arrayは要素数が固定のため余分なメモリを取らなくて済むため、std::vectorよりも効率はいい。

>パフォーマンス
最適化をかければstd::arrayは生配列と全く同じアセンブリを吐き出す事が知られています。
つまり、パフォーマンスに差はありません。

つまり、使い得ってことか。

#終わりに
明日はかなり時間取れそうなので遅れた文をいっきに取り戻す。
以上！おやすみなさい。
swiftで配列のユニーク

rubyなどの最近の言語は標準でユニークメソッドを持ってますが、なぜかswiftって地味にユニークメソッドないですよね？色々な方法があるかと思いますが、ユニークメソッドを書くことなんて最近なかったし、今回色々試したので備忘録として残しておきたいと思います。

## よく見かける方法

`reduce` を使ってシンプルに書く方法。要素が`Equatable`を実装している必要があります。欠点としては`reduce`の上にさらに`contains`で探索するので要素が多くなると辛いかも。そんなに大きい配列を扱わない場合はこれで十分だと思います。（余談ですが、ランダムな値の配列を適当に考えるって難しくないですか？w）

```swift
let array = [1, 2, 1, 3, 4, 3, 4, 2, 5]
let result = array.reduce([], { $0.contains($1) ? $0 : $0 + [$1] })
print(result) // [1, 2, 3, 4, 5]
```

## 順番を気にしない方法

ただただ重複を排除したいだけでしたらこの方法が最も良さそう。ですが配列で値を持つからには順番を考慮したい場合が多いと思うのであまり使い道は多くなさそう？

```swift
let array = [1, 2, 1, 3, 4, 3, 4, 2, 5]
let result = Array(Set(array))
print(result) // [5, 4, 1, 2, 3]
```

## 少し速さを気にする方法

`Bool`でなくても何でも良いと思います。配列の要素をキーにして辞書に既存の値をどんどん溜め込めむことで重複する値を排除する方法。この方法は要素が`Hashable`を実装している必要がありますね。しかしもっとカッコ良い方法ありませんかね？

```swift
let array = [1, 2, 1, 3, 4, 3, 4, 2, 5]
var dict = [Int : Bool]()
let result = array.reduce([], { (tmp, element) in
    if dict[element] != nil { return tmp }
    dict[element] = true
    return tmp + [element]
})
print(result) // [1, 2, 3, 4, 5]
```

〜 2019/03/14 追記 〜

コメント欄にて`Set`を使った方法を教えていただきました！
わざわざ`Dictionary`で余計な`Bool`を使用しない分ムダもなくシンプルでカッコいいです！

## 拡張しておく

全く関係ない命名規則についてですが、破壊的な場合は`sort()`、非破壊的な場合は`sorted()`または`sorting()`みたいにするようですね。でも`unique`って形容詞なので`unique()`で良いんでしょうか？（正直、この手の命名規則は苦手です・・・）

```swift
extension Array where Element: Hashable {

    func unique() -> Array {
        var hash = [Element : Bool]()
        return reduce([], { (array, element) in
            if hash[element] != nil { return array }
            hash[element] = true
            return array + [element]
        })
    }
}

let array = [1, 2, 1, 3, 4, 3, 4, 2, 5]
print(array.unique()) // [1, 2, 3, 4, 5]
```

## 追加の場合も考える

元の配列がユニークかつ追加する配列もユニークな場合は以下のようなメソッドを書けば良さそうです。辞書大好きですね！

```swift
extension Array where Element: Hashable {

    func addUnique(array: Array) -> Array {
        let dict = Dictionary(map{ ($0, 1) }, uniquingKeysWith: +)
        return self + array.filter{ dict[$0] == nil }
    }
}

let array1 = [1, 2, 3]
let array2 = [2, 3, 4, 1, 5]
print(array1.addUnique(array: array2)) // [1, 2, 3, 4, 5]
```

あとは、組み合わせれば何とかなりそうですね。

```swift
// 元の配列はユニークだけど追加する配列はユニークか分からない場合
let array1 = [1, 2, 3]
let array2 = [2, 4, 2, 5]
print(array1.addUnique(array: array2.unique()))

// 元の配列も追加する配列もユニークか分からない場合
let array3 = [1, 2, 1, 3, 2]
let array4 = [4, 3, 2, 5, 1]
print(array1.unique().addUnique(array: array2.unique())) // [1, 2, 3, 4, 5]
print((array1 + array2).unique()) // [1, 2, 3, 4, 5]
```

## 感想

ユニークなんて久しぶりに書いたのでちょっと楽しかったですw
水上ドローン作りたい10、L-02C組み込み

# L-02C
寸法は  90 × 35 × 12.9 mm 。ボート内部に収めるのは無理でした。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/359316/401d3fe2-2348-7488-15c7-525e6ca00f04.png)

船外に貼り付けておくしかないのですが、防水も考慮する必要が有ります。その結果こうなりました
![image.png](https://qiita-image-store.s3.amazonaws.com/0/359316/db19d481-a72e-ab13-c61f-2ff8ce2f369a.png)
タッパーです。無理矢理な感は否めませんねぇ、、、

# パテ盛り
蓋の部分にタッパーを乗せるのですが、凸凹が有るのでパテで埋めました。
紙やすりで塗装を剥がし、その上にパテ盛りしました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/359316/9b6927c0-426c-5986-e5bc-00839736a25a.png)
パテは以下の物を使用。粘土のようにこねくり回して、凸凹面に貼り付け乾くのを待つだけです。
[LOCTITE(ロックタイト) 多用途補修パテ 48g DHP-481](https://www.amazon.co.jp/dp/B002YMNJQY)
乾いた後、接着に備えてさらにヤスリがけを行いました。
# 接着
[隆成コミュニティ J-Bウエルド オートウェルド 超強力接着剤 AW-20Z 26.8g×2](https://www.amazon.co.jp/dp/B0011WAV9G/)
アマゾンのレビューで絶賛されていたので購入。タッパーと蓋の部分がかっちり接着されました。
# 穴開け
## タッパーの穴開け
タッパー無いに配線を通すため、穴を開ける必要が有ります。専用の穴あけ工具を持っていない場合はアイロンで開ける手があるそうです。以下のサイトで紹介されていました。
[たまトラ タッパーに穴をあける。アイロンで](https://tamatora.36nyan.com/?p=1382)
私もこの方法を使わせてもらいました。只開けた後のバリ取りが面倒ですね。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/359316/12677e67-429c-10b7-3887-35d4ed11ba04.png)
## 船外と船内の穴開け
これも無理矢理ですが、はんだゴテで穴を開けて通しました。※防水処理は後でする予定。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/359316/8a61975b-1a1c-4e42-4d73-97bc24976c5f.png)

これでL-02Cも組み込めました。ただボート内部の配線が収拾つかない状態になっており、作り直さないと駄目だろうなぁと思っています。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/359316/8d2b89ab-1558-8b62-158d-1ce30472472f.png)
3．ブロックチェーンの記帳原理について

この記事は
[https://learnblockchain.cn](https://learnblockchain.cn)を元に編集したものです。
翻訳者のTwitter Account：[taro03293](https://twitter.com/taro03293)

##記帳原理について
ブロックチェーン（1.0）は、暗号理論に基づいた安全な分散元帳で、送金証明が簡単、且つ改ざんされない元帳のことです。
一般的に、スマートコントラクトと組み合わせたブロックチェーンはブロックチェーン2.0であると考えられています。
例えば、Ethereumは典型的なブロックチェーン2.0です。

多くの人はビットコインの存在を知っていますが、その背景のブロックチェーン技術までを理解していません。
実はビットコインは、ブロックチェーン技術を使用しているアプリケーションの一つです。
また同時に大抵の人はビットコインの価格上下だけに夢中で（最近はパッとしませんが、まだワンチャンあるかもしれません）、ブロックチェーン技術が持つ可能性にはあまり注目していません。
ブロックチェーンとは未来のことです。
もしあなたが未来に賭けたいと思うのなら、今後はコインの価格より、技術について目を向けたほうがいいでしょう。
この記事では、ブロックチェーン1.0テクノロジの実装方法について説明します。

##ハッシュ関数
ブロックチェーンへの記帳について説明する前に、ハッシュ関数について説明しましょう。
ハッシュ関数は`Hash(元の値)（←この式をハッシュ化と呼ぶ）`のことで、“元の値”には任意の値を設定できます。
ハッシュ化すると、元の値を短いコードに変換（ハッシュ値、と呼ぶ）できます。

**ハッシュ化の特徴**
・どこの誰がいつ何時、同じ“元の値”をハッシュ化しても、得られる答えは常に同じ
・逆に“元の値”に少しでも変更があると、得られる答えは変わる
・ハッシュ値から“元の値”を予測する方法はない

例えば、
“張さんは李さんに100万を貸し、1％の利子、1年後に元金および利子を貸します”という文章をハッシュ化しましょう。
`Hash（張さんは李さんに100万を1％の利子で貸し、李さんは1年後に元金および利子を返します）= AC4635D34DEF`（ハッシュ化された情報。これはあくまで例で、実際の答えとは異なります）。
このハッシュ値がブロックチェーン上に記帳されます。

**ハッシュ関数の3つの機能**
1．情報を単純化する : ハッシュ化すると、元の値が小さくなります
2．情報を識別する : 元の値が正しいか否かをAC4635D34DEFを使用して識別できます（AC4635D34DEFは元の値のIDとも呼ばれます）
3．情報を隠す : 通帳に記帳される情報はAC4635D34DEFのようなレコードであり、元の情報は匿名性が保たれます

例えば李さんが返済時にが詐欺的行為をした場合、両者は元の情報を確認するためにハッシュ関数とハッシュ値AC4635D34DEFを使用して、契約の真偽を検証することができます。
ハッシュ関数のこれら3つの機能は、ブロックチェーン技術で広く使用されています。

##ブロックチェーン上に記帳する方法
例えば、下記の取引記録書のページ番号0があるとしましょう

| 口座|入金|出金|残高|メモ|
|:-----------------|------------------:|:------------------:|:------------------:|:------------------:|
| 王さん|100 ||190|報酬を受け取りました|
| 趙さん||100|30|ガス代の支払い|
| 李さん|120|90|170|給料の受け取り＆ローンの支払い|
記帳時間：2018-10-22 10:22:02

ブロックチェーンでは、この記録(ページ番号、記帳時間、取引記録)を元のデータとして、Hash化を行い、1つのHash値を求めます。
例 : `Hash(ページ番号0、記帳時間、取引記録) = 787635ACD`

ページ情報とHash値が組み合わさり、一つのブロックを作ります。
ビットコインシステムでは10分間に1度、ページに記録します。
すなわち10分に1つブロックが作成されています。

2枚目のページに記録する時には、前のブロックで求めたHash値＋ページ番号2の情報をごっちゃにした情報を基にHashを作成します。
例 : `Hash(前のブロックで求めたHash值、ページ番号1、記帳時間、取引記録) = 456635BCD`

こうすることで、2つ目のブロックは、2つ目のブロックの記録と1つ目のブロックの記録両方を含むことができます。
これを繰り返すことで、新しいブロックは過去に起こった取引全ての記録を持っていることになります。
とても簡単に言うと、あなたが持っている通帳の最新ページに、そのページの取引記録＋過去全ての取引が記録されているということです。

このような方法で作られたブロックチェーンは、過去の取引を検証するにあたり非常に便利であり（最後のブロックのHash値のみを検証すれば、それまでの過去の取引記録の真偽がわかる）、また過去の取引記録を変えることが非常に困難になる（過去のどれかのブロックのHash値を変えれば、それ以降のブロックのHash値も変化するので、どこで変わったのかすぐわかる）ので、ブロックチェーン上に記帳された情報を変更することは不可能です。

そして最後に、ブロックチェーン上に記帳するにはコストがかかります。
これはまた次に説明します。

4へ続く
2．ビットコインとは

この記事は
[https://learnblockchain.cn](https://learnblockchain.cn)を元に編集したものです。
翻訳者のTwitter Account：[taro03293](https://twitter.com/taro03293)

##ビットコインとは
もし1000人に“ビットコインについて教えて？”と聞いたら、1000通りの答えが返ってくるかもしれません。
この章ではの入門編として、できるだけ簡単にビットコインについて説明したいと思います(ビットコインについて理解している方は、この章をスキップして頂いて構いません)。
ビットコインとは一体何でしょうか？どのように機能しているのでしょうか？

>ビットコインとは
ビットコインとは分散ネットワークに基づくデジタル通貨のことです。
ビットコインシステム（広義のビットコイン）は、このようなデジタル通貨を構築するために使用されるネットワークシステムであり、分散型のP2P(Peer to Peer)ネットワークシステムです。

もう少し、詳しく見てみましょう。

デジタル通貨とは
ケインズ氏は「貨幣理論」の中で、**“お金とは、何かの価値の代わりになるものであり、一般的に物の価格は、その物の価値に比例する”**と述べています。
お金の本質的役割とは、**物の価値に変わるものになる**ことであり、物はいかなる物（一枚の紙、一つの数字、など人がそれに“価値”を認識できるもの）を指します。
日本円、人民元、米ドルなど、国が発行している信用通貨の価値は、国家の主権によって定められています。
一方でデジタル貨幣は、信用や物に頼らない新しいタイプの通貨であり、その価値は、全員の合意によって決定されます。例えば、ビットコインはデジタル通貨の一つです。 （オンラインバンキングやアプリ間送金は、デジタル通貨と同じように見えますが、それらは正確にいうとデジタル通貨ではなく信用通貨のデジタル化です。）

##動作原理
皆さんがご存知の通り、銀行は我々の身分証明に基づいて作られた銀行口座とリンクして財産を管理しています。
例えば、銀行の通帳は、
張さんが10月1日に1万円を入金しました。残高は10万円です。
のようになります。

ビットコインシステムにもそのような通帳があります。ビットコインの場合、通帳への記録は、ビットコインシステムを実行している全ての人（ノードと言います）によってなされます。
それぞれのノードに完全な通帳を保存（同期）します。
そしてビットコインシステムには、通帳の一貫性を守るために、記録するときの多数の原則があります。
例えば、誰かが自分のパソコン上の通帳の残高を10万から1000万に変えたとしましょう。
この場合、彼の通帳は、他のノードに記録された通帳の残高と一致しないため、ビットコインシステムは彼の操作を無効とみなします。

こうして、ビットコインはシステム全体の運用をサポートするためにブロックチェーン技術を使用しています。

3に続く
1. Blockchainを勉強するには

この記事は
[https://learnblockchain.cn](https://learnblockchain.cn)を元に編集したものです。
翻訳者のTwitter Account：[taro03293](https://twitter.com/taro03293)

##前書き
ブロックチェーン（以下BC）は今後1~3年以内に急速に発展し、近い将来、BC技術関連の需要は急速に増えるでしょう。
特にプログラマーの方は、このチャンスを必ずつかむべきです。
BCに関連する技術、知識は多岐にわたり、多くの開発者は、BC関連の資料を見た後にわかったような、わからなかったような感覚を頂くと思います。
特にBC開発をしたい方が一番多く抱く疑問は、BC技術をどのように体系的に勉強するか、ということではないでしょうか。
ここでは、BC技術を何章かにわけて説明します。私の説明が、皆さまのBC技術を理解する助けになればとてもうれしいです。

##ジャンルを定める
BC技術の開発業務に携わる、といっても、様々なジャンルがあります。
例：BCアプリケーション開発者、BCシステム構築者、BC技術のコア核心部の開発者、BCの数学研究者、などなど

ジャンルが違えば、勉強する方法も異なります。
もしあなたがBCアプリケーション開発をしたいと考えているなら
・次のプログラミング言語のいずれかを理解していること(nodejs, Go, Python, C++ など)
・BC技術の原理を理解していること（奥深いレベルまで理解する必要はありません）
・アプリ開発経験は必須ではないですが、あるに越したことはないでしょう。
が必要です。

また、どんなジャンルにも関わらず時間をかけてしっかり勉強し、実際に自分でコードを書いて実践することが大切です。
BC技術は多岐に渡るため、それぞれの技術について概念を知り、そして一歩踏み込んだ原理を理解する必要があります。

あなたがBC技術の概念を理解している間、頭の中に沢山の疑問が浮かぶでしょう。
例えばBitcoinの概念でよく見かける説明の一つに
**“Bitcoinの認証方式は、仕事量の証明（POW）によって実現される。”**
とありますが、
**“POWとは？”**という疑問が生まれるでしょう。
POWとは、仮想通貨の取引が正しいかを検証する手続き（コンセンサスアルゴリズム）の一種ですが（よくわからなくても大丈夫です。簡単にいうと、張さんがテストを受けて100点を取った時、張さんがよく勉強したということを確認する方法のことです。）、
上記から **“Bitcoinはどのように手続きを検証をしているのでしょうか？”**　という新たな疑問が浮かぶかもしれません。（この疑問を解決するには、BCの暗号理論とHashを勉強する必要があります。）


BCを一歩踏み込んだレベルまで理解するためにはGoogleをよく使って、時には英語文献から答えを見つける必要があります。
もし既に概念や原理を理解したと思えるなら、実際にコードを書いてみましょう。
例えばマイニングについて理解したなら、マイニングのためのコードを書いてマイニングの過程を理解しても良いでしょう。

学習とは一つの長い旅のようなものです。残念ながら、そこには近道はありません。
**本を沢山読み、コードを読み、コードを書く**
これが最も早く、簡単にBC技術を使いこなすための方法です。

2に続く
TypeScriptで型のキーの名前だけを入れ替える

## やりたいこと

```ts
type Person = {
  name: string;
  age: number;
  job?: string;
}
 
type EnhancedPerson = Swap<Person, 'name', 'fullname'>

/*
EnhancedPerson = {
  fullname: string;
  age: number;
  job?: string;
}
*/
```

## やったこと

- (`recompose`とかからOmitをインポート。)
- 引数はもとの型`T`と、`T`の任意のキー名`A`と、`A`と入れ替えたい任意のキー名`B`の３つ。
- `Omit<T, A>`でもとの型の任意のプロパティ`A`を省く。
- `{ [P in B]: T[A] }`で`B`のキーに対して`A`が持っていたバリューを割り当てた型を作ってそれをインターセクション

```ts
type Swap<T, A extends keyof T, B extends string> = Omit<T, A> & { [P in B]: T[A] }
```

## 結果

多分できた。他に誰かもっと効率よいやつを作っていそう。
u-blox NEO-M8シリーズで使用されているUBXプロトコルについて

巷にはいくつものGNSSモジュールが販売されていて、そのなかでもu-blox製品が特にお気に入り。

小型デバイス向けのNEO-M8シリーズではUBXプロトコルというu-blox独自のプロトコルが採用されているので、知っている範囲、調べた範囲のメモ。

## 特徴

* バイナリプロトコル
* コマンドはチェックサムで検証
* クラスとメッセージIDで機能を分解


## メッセージ

メッセージは可変長データで、メタデータが同期キャラ2バイト、クラスとメッセージIDで2バイト、データ帳2バイト、チェックサム2バイト、これにペイロードが1バイト以上ついて最低9バイトとなる。


| SYNC CHAR 1 | SYNC CHAR 2| CLASS | ID | LENGTH | PAYLOAD | OK_A | OK_B |
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
| 1byte, 0xb5固定 | `byte, 0x62固定 | 1byte | 1byte | 2bytes, Little Endian | Nbytes |  1byte | 1byte |


## チェックサム

`CLASS` から `PAYLOAD` 全体がチェックサム計算の対象となる。

| SYNC CHAR 1 | SYNC CHAR 2| CLASS | ID | LENGTH | PAYLOAD | OK_A | OK_B |
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
| 1byte, 0xb5固定 | `byte, 0x62固定 | 1byte | 1byte | 2bytes, Little Endian | Nbytes |  1byte | 1byte |
| | | ここから || | ここまで |  |  |

次のように計算する。なんとなく練習でPythonで書いてみる。

```python
def calc_checksum(data):
    ck_a = 0
    ck_b = 0
    i = 0

    while i < len(data):
        ck_a = (ck_a + data[i]) & 0xff
        ck_b = (ck_b + ck_a) & 0xff
        i += 1

    return ck_a, ck_b
```


## 例: Low Power Modeを書き込む

Low Power Mode=Continuous Modeを書き込む。UBXプロトコルのメッセージをバイナリで組み立てる。
※サンプルが雑でごめんなさい。

```python
# 同期ヘッダ、クラス、ID、ペイロード長さを指定
header = struct.pack('BBBBH', 0xb5, 0x62, 0x06, 0x11, 2)

# ペイロードは2バイト分
payload = b'\x00' + struct.pack('B', 0)

# チェックサムの計算
ck_a, ck_b = calc_checksum(struct.pack('<BBH', 0x06, 0x11, 2) + payload)

# 送信データを組み立てて書き込み
data = header + payload + struct.pack('BB', ck_a, ck_b)
gps_s.write(data)
```

GNSSモジュールから次のような応答が得られれば成功。
※実際にはバイナリ文字列

```
b5 62 05 01 02 00 06 11 1f 48
```

応答の意味は次のようになる。

| SYNC CHAR 1 | SYNC CHAR 2| CLASS | ID | LENGTH | PAYLOAD | OK_A | OK_B |
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
| 1byte, 0xb5固定 | `byte, 0x62固定 | 1byte | 1byte | 2bytes, Little Endian | Nbytes |  1byte | 1byte |
| b5| 62| 05 | 01| 02 00 | 06 11 | 1f | 48 |


## 参考

* https://www.u-blox.com/en/product/neo-m8-series#tab-documentation-resources
【JavaScript】【初心者】純JavaScriptでToDoリストを作ってみた

## 完成イメージ
![todo1.gif](https://qiita-image-store.s3.amazonaws.com/0/247053/87dbbd47-12df-9093-7478-d457b0c5a77d.gif)

## 動作仕様
- テキストボックスに文字を入れて、追加ボタンを押すと入力した文字が下に表示される
- 追加ボタンを押すと、テキストボックスが空になる
- 追加した文字は、ゴミ箱ボタンを押すと、該当の文字が削除される
- バリデーションチェックはしていない（空文字も入力されるし何文字でも入力される）
- リロードしたら全部リセットされる

## 簡単に作ったポイント

### JavaScript部分全体
```html
<script>

 function show(){
       var html = '';
       for (var i=0; i<todos.length; i++) {
           html += '<a class="panel-block"><span class="panel-icon remove" id="' + i + '"><i class="fas fa-trash-alt" aria-hidden="true"></i></span>' + todos[i] + '</a>';
         }
       // ここでタスクを表示する
       target.innerHTML = html;


       // 追加したタスクのclass名(remove)から取得する
       buttons = document.getElementsByClassName('remove');
       for (var i=0; i < buttons.length; i++) {
           buttons[i].addEventListener('click', remove);
       };
 }

// 削除ボタンが押されたら発動
 function remove(){
      var id = this.getAttribute('id');
      todos.splice(id, 1);
      show();
 }

// タスク追加ボタンが押されたら発動
 btn.addEventListener('click', function() {
       todos.push(document.getElementById('task').value);
       document.getElementById('task').value = '';
       show();
 },false);
</script>
```

### 追加ボタンが押された時の動作

```javascript

// タスク追加ボタンが押されたら発動
 btn.addEventListener('click', function() {
       todos.push(document.getElementById('task').value);
       document.getElementById('task').value = '';
       show();
 },false);
```
- クリックされたら、テキストボックスのvalueをtodosという配列につっこむ
- テキストボックスのvalueを空にする
- show関数を呼び出す

### show( )が呼び出された時の動作

```javascript

 function show(){
       var html = '';
       for (var i=0; i<todos.length; i++) {
           html += '<a class="panel-block"><span class="panel-icon remove" id="' + i + '"><i class="fas fa-trash-alt" aria-hidden="true"></i></span>' + todos[i] + '</a>';
         }
       // ここでタスクを表示する
       target.innerHTML = html;


       // 追加したタスクのclass名(remove)から取得する
       buttons = document.getElementsByClassName('remove');
       for (var i=0; i < buttons.length; i++) {
           buttons[i].addEventListener('click', remove);
       };
 }

```
- todos配列の長さ分ループしながら、「`<a>`〜」を追加していく
- target.innerHTMLに↑のhtmlを入れる
- button配列に「remove」クラスのDOMを格納する
- button配列の長さ分、ループして、buttonごとのaddEventListenerのクリックをセットする
- コールバック関数としてremoveをセットする


### remove( )が呼び出された時の動作

```javascript

// 削除ボタンが押されたら発動
 function remove(){
      var id = this.getAttribute('id');
      todos.splice(id, 1);
      show();
 }
```
- `this.getAttribute('id');`でDOMのIDを取得することができる
- target.innerHTMLに↑のhtmlを入れる
- todos配列に格納されているKey（順番）を「id」で指定して「１」個ずつ削除する
- show( )メソッドを呼び出して、タスクを表示する


## 書いてみた感想
- 初のJavaScript作品で、苦労した。
- 絶対もっと簡単に書けるんだろうなと思いながらの実装だった
- これだけでは足りないので、、もっと作りたいです。
#MicrosoftFlow で 新しい承認フロー Approval v2を試してみた

# 備忘録的な記事です。

承認のApprovalコネクタにv2が出たので試してみました。

# v2になって何ができるの？

## 応答のカスタマイズ

前までは、承認 or 否認のみでしたが
自分で応答を設定できるようになりました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/269159/360235c0-04c7-07e3-1632-a852af7ab029.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/269159/4a1c5f1a-19e7-4779-6a0b-2ed9fe313e37.png)

結果

```
[
  {
    "responder": {
      "id": "1a35b8d4-c102-4b4b-bb47-17cb43c29b3e",
      "displayName": "XXXXXX",
      "email": "XXXX@XXXXXX.com",
      "tenantId": "XXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXX",
      "userPrincipalName": "XXXX@XXXXXX.com"
    },
    "requestDate": "2019-03-12T17:00:55Z",
    "responseDate": "2019-03-12T17:07:29Z",
    "approverResponse": "test",
    "comments": "あー　つくれるのか！"
  }
]
```

## 承認の種類が増えた

### Start and Wait for an approval

前回の承認と同じように、応答が来るまで待機します。

### Create an approval

承認が飛びますが、応答を待たずに次に進みます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/269159/88f61847-f17c-198a-810b-b39e68605146.png)

### Wait for an approval

指定した Approval ID の応答を待ちます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/269159/4d153bea-1de4-7c77-2269-7b7ce27cb79a.png)


というわけで、とりあえず簡単に纏めてみましたが
確かに柔軟な承認フローができるようになっている気がしますね！
numpy.argsort を Ruby で

[numpy.argsort()](https://docs.scipy.org/doc/numpy/reference/generated/numpy.argsort.html) は配列のソート後の値の代わりに、ソート前のインデックスを返す。

```py
>>> import numpy as np
>>> ary = np.array([30, 10, 20])
>>> ary.argsort()
array([1, 2, 0])
```

これと同様のことを Ruby で行うと

```rb
[30, 10, 20].each_with_index.sort_by { |n, _i| n }.map { |_n, i| i }
#=> [1, 2, 0]

# シンプルに書きたいなら
[30, 10, 20].each_with_index.sort.map(&:last)
#=> [1, 2, 0]
```

ちなみに numpy.argsort() を 2 回繰り返すと、配列内の値の小ささのランキングを取得できる。

```py
>>> ary = np.array([30, 10, 20])
>>> ary.argsort().argsort()
array([2, 0, 1])
```

これと同様のことを Ruby で行うと

```rb
[30, 10, 20]
  .each_with_index.sort_by { |n, _i| n }
  .each_with_index.sort_by { |(_n, i), _rank| i }
  .map { |(_n, _i), rank| rank }
#=> [2, 0, 1]

# シンプルに書きたいなら
ary = [30, 10, 20]
sorted = ary.sort
ary.map { |n| sorted.index(n) }
#=> [2, 0, 1]
```
TokenPocketでIOSTの財布を作る(Android編)

IOSTのメインネットが稼働しましたが、さっそくいくつかのスマートフォンウォレットアプリが提携し始めています。

TokenPocket — Your Universal Wallet
https://play.google.com/store/apps/details?id=vip.mytokenpocket&hl=ja

ちなみにこのアプリ、同名アプリがあってややこしいんですが、間違えないように注意です（青いアイコンの方です）

tokenPocket - 仮想通貨Etheruem Wallet&Dappブラウザ
https://play.google.com/store/apps/details?id=com.tokenpocket

では、さっそくはじめましょう

##アプリのダウンロード
下記URLからダウンロードしてください（容量は50MBほど）
https://play.google.com/store/apps/details?id=vip.mytokenpocket&hl=ja
ダウンロード終わったら

起動したらこんな画面が出てきます。最初はEOSモードになってます。
![qta01.png](https://qiita-image-store.s3.amazonaws.com/0/39453/d66ddffa-5945-67bc-33bb-4c0d40ef3945.png)
かわいい顔した兄ちゃんの頭の上をタップして、IOSTを選びましょう。
![qta02.png](https://qiita-image-store.s3.amazonaws.com/0/39453/ba507c5f-8a1a-3b16-1b17-6dbae070bf3b.png)
するとIOSTモードに変わります。初回作成なので「アカウントなし」を選んでください。
![qta03.png](https://qiita-image-store.s3.amazonaws.com/0/39453/f62240c1-7374-f112-6024-fa0261e15b53.png)
「アクティベーションコードの作成」を選択。色々細かいことが書いてありますが、アカウント作成には直接関係ないので無視してOKです。
![qta04.png](https://qiita-image-store.s3.amazonaws.com/0/39453/a27ef9da-9933-922d-1c79-0b136fd9890b.png)
ここから先はフォームに値を入力していきます。
![qta05.png](https://qiita-image-store.s3.amazonaws.com/0/39453/ec4301c4-ad60-e8ca-d307-3cad7980e3c8.png)

|項目名|内容|
|---|---|
|アカウント名|5-11文字の好きな文字列で設定してください|
|パスワード|8文字以上で大文字小文字混在がお勧めとのこと|
|パスワード確認|パスワードをもう一度入力|
|アクティベーションコード|キャンペーン中はここに値を入力するとIOSTが無料でもらえたり？|
|プロンプト|何も入力しない|

##アクティベーションコードはどうやって入手すればいいのさ
2019年3月12日現在、こんなキャンペーンやってました。

TokenPocket Partner with IOST | Free Account Giveaway
https://medium.com/@tokenpocket.gm/tokenpocket-partner-with-iost-free-account-giveaway-57d54a6a1d82
英語で色々書いていますが、
・TokenPocketのTelegram（https://t.me/tokenPocket_en）に入って
・管理者の@MartinKongさんに個別メッセージでメールアドレスを送る
とアクティベーションコードもらえます。アクティベーションコード入れるとFREE IOSTアカウントが作成できるらしいです。メールアドレスは捨てアドサービスで生成したものでもいいみたいです（いいのかよ）
期限は『14 March 11:59 AM (UTC+8)』まで、とのことです。
※FREE IOSTアカウントがiGASとiRAMを最初に少しだけもらえてるアカウントと私は理解しているのですが、違うかも…？

![qta06.png](https://qiita-image-store.s3.amazonaws.com/0/39453/9e0ce060-3210-c1ab-67b1-18988c878e98.png)
くれぐれも全体チャットに投下するのはやめましょう。また、こういうキャンペーンに使うメールアドレスは絶対に普段使いのものは避けましょう。

さて、@MartinKongさんに個別投稿したら数分後にアクティベーションコードもらえますので、そのまま先ほどの画面に戻って入力をすると、

![Screenshot_2019-03-12-21-24-55-705_vip.mytokenpocket.png](https://qiita-image-store.s3.amazonaws.com/0/39453/5b522597-3e64-14ee-b845-61d8fb0e3f63.png)

ウォレットの復元に必要な秘密鍵が表示されますが、その前に注意事項が。
かならずローカルに保存して他人に知られないでね、というお作法になります。
この画面の後、秘密鍵が表示され、さらに進むと「秘密鍵を入力してください」と出てくるので確認のために入力することでようやく完了です。
![Screenshot_2019-03-12-21-26-41-617_vip.mytokenpocket.png](https://qiita-image-store.s3.amazonaws.com/0/39453/95ceddf7-a855-9b29-3968-d51d637b80a9.png)
次の画面では入力した先ほど入力したアクティベーションコードが表示されています。
問題無ければ「使用を開始する」をタップ。
![qta07.png](https://qiita-image-store.s3.amazonaws.com/0/39453/d2168264-ca47-4522-4788-266d97304278.png)
さらに「私は知っている」をタップ。
これで作成完了です。お疲れさまでした。

![Screenshot_2019-03-12-21-29-21-935_vip.mytokenpocket.png](https://qiita-image-store.s3.amazonaws.com/0/39453/af46f383-e9a2-6e45-940b-6a0fde2866a8.png)

TokenPocket自体にはいろいろと便利な機能があるのですが、いかんせん多すぎてここでは紹介できないです。あと全体的に怪しい日本語ですがちゃんと使えます。

参考になった！という方はryohoに投げ銭してみてください。
（IOSTのウォレットアドレスの概念がイマイチまだわからないのですが、TokenPocket上はryohoでいけるはず…（"＾ω＾））

###私は知っている
そもそもプログラミングとは何か

# プログラミングとは何か？

プログラミングを学習する上で、
<br>そもそもプログラミングって何なのか</br>
を理解することは重要です。

今回の記事ではプログラミングとは何かを解説していきます。

- [目次]
	- [言葉の意味]
	- [コンピュータは人間の言葉を理解できない]
	- [プログラミング言語]
		- [1.言語にはルールがある]
		- [2.曖昧な表現は伝わらない]
		- [3.便利な辞書がある]
	- [プログラミング学習とは何か？]
		- [1.文法を学ぶ]
		- [2.論理的に指示を出す方法を身に着ける]
		- [3.ライブラリの使い方を知る]


## 言葉の意味
[Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0_(%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF)
<br>によると</br>

>コンピュータのプログラミング（英: programming）とは、コンピュータプログラムを作成することにより、人間の意図した処理を行うようにコンピュータに指示を与える行為である。

ということです。

ざっくり言うと<br>
**『コンピュータにして欲しいことを、順番に書き出していく作業』**</br>

では、どのようにしてコンピュータに指示を出すのでしょうか？

## コンピュータは人間の言葉を理解できない
コンピュータに日本語で『ホームページを作って』
と言っても何もしてくれません。
<br>コンピュータには人間の言葉が通じないからです。</br>

そのため、コンピュータにも分かるように指示を書かなければいけません。
<br>そこで必要になるのが**プログラミング言語**です</br>

## プログラミング言語
一口にプログラミング言語と言っても色々な種類があります。
- ホームページの見た目を作る言葉
- ショッピングサイトなどのシステムを作る言葉
- ゲームを作る言葉
- スマホアプリを作る言葉

プログラミングを始めるときは、まずどの言語が自分の目的に合っているのか調べてみましょう。

次に、プログラミング言語の特徴を3点述べていきます。

### 1.言語にはルールがある
言葉には文法というルールがあります。
<br>プログラミング言語も同じです。</br>
ルールに基づいてコンピュータに指示を出します。

### 2.曖昧な表現は伝わらない
日本語って曖昧なグレーな表現がありますよね？
<br>でも、プログラミング言語に曖昧さはありません。</br>
行って欲しい内容を、明確に、順番通り指示していかなければなりません。

### 3.便利な辞書がある
プログラミング言語には便利な辞書（**=ライブラリ**）があります。
<br>ライブラリには単語の意味だけでなく**コンピュータにやってもらいたい一連の指示**が記載されています。</br>
つまり、その辞書を上手く使う事で、効率よくコンピュータに指示を出すことが可能です。

## プログラミング学習とは何か？
以上の特徴を踏まえてプログラミング学習で学ぶべきことを3つ
### 1.文法を学ぶ
言語の基本となる文法を知らなければ指示を出せません。
<br>言葉は話さなければ身につかない。</br>
プログラミングをどんどん自分で書くことで文法を学んでいきます。
### 2.論理的に指示を出す方法を身に着ける
コンピュータに曖昧な表現は通じません。
<br>そこで必要となるのが客観的に誰がみても納得のいく論理的な記述。</br>
これを**アルゴリズム**と言います。
<br>アルゴリズムの勉強は全ての言語に通じます。</br>
### 3.ライブラリの使い方を知る
ライブラリを使いこなすことで、コンピュータに無駄のない素早い指示を伝えることができるようになります。
Bootstrap

```html:qiita.rb

<table class="table">
    <thead>
        <tr>
            <th>#</th>
            <th>First Name</th>
            <th>Last Name</th>
            <th>Username</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <th>1</th>
            <td>Hanako</td>
            <td>Qiita</td>
            <td>@Hanaq</td>
        </tr>
        <tr>
            <th>2</th>
            <td>Taro</td>
            <td>Qiita</td>
            <td>@TaroQ</td>
        </tr>
    </tbody>
</table>
```

https://webnetamemo.com/coding/bootstrap/2015062126
SQLで部分一致検索

# SQLで部分一致検索

Userテーブルから`name` の中に ゆうすけ、たろう、さき　のどれかが含まれるレコードを取り出すSQL
`LIKE`　を使い、部分一致なので、前後に`%` を入れれば完成

```sql
SELECT user.*
FROM user
WHERE user.name LIKE '%ゆうすけ%'
OR user.name LIKE '%たろう%'
OR user.name LIKE '%さき%';
```

部分一致なので、`こうたろう` や `みさき` も引っかかる
【[独学]で合格】IoT検定 レベル1 プロフェッショナル・コーディネータ

1年以上前ですが、G検定受験前にIoT検定制度委員会が主催する
IoT Professional Coordinatorを受験して合格できました。（2017年）

更にそれがきっかけでIoT検定制度委員会のキーマンの方とお知り合いになったことで
IoT検定ユーザー試験開発WGメンバー
として活動させていただいたり、
福岡市IoTコンソーシアムさんと一緒になって、
IoTの活動を広げる活動を福岡で行なっています。
http://www.iotcert.org/association/
https://fitco.connpass.com/event/107177/

仕事も多忙ではありますが、非常に充実した日々を送っています。

また、私は副業禁止ですので、お金をいただいての講師活動は行っていませんが(今後は副業するかもしれませんが・・) 、他の合格者様は、有償での活動も行われてコミュニティを広げる活動をされているようです。

他の資格と組み合わせて独立して活動されているケースもあるようです。

毎月福岡でIoT検定に特化した勉強会を開催していますので、
IoT検定に特化した記事を書きたいと思います。


##●スケジュール
2017/11/6
* IoT検定 レベル1 プロフェッショナル・コーディネータ
⇒合格


##●投稿の趣旨
QiitaではIoT検定試験の記事は記載されていなかったように思います。
検索してみましたが、G検定は多かったですが、、IoT検定は・・？！

また、AIばかり先に言ってるように思われますが、AIとIoTは切っても切り離せないと思っています。また、BD（ビッグデータ）も。

という背景もあり、是非どんな方にもとっつきやすい
* IoT検定 パワーユーザー
* IoT検定 レベル1 プロフェッショナル・コーディネータ
受験していただきたく、投稿しました。


##●IoT検定を受験した理由
もともとSIerでデジタルトランスフォーメーション（DX)を主とした部署に所属していた点と、仕事柄何か形に残したいと考えたためとなります。

また、データ分析の章がありますが、結構コンパクトにまとまっていて、
その後のJDLAのG検定の足がかりにもなったので、これはいいかもと思ったのがきっかけとなります。

##●試験について
試験概要は以下のようになってます。

【ユーザー試験】
正式名称	IoT検定ユーザー試験パワー・ユーザー
試験方法	CBT　三肢択一
試験時間	４０分＋アンケート
出題総数	４８問（８分野＊６問）
評価方法	グレード制
・グレードA＝正答率８６〜１００％
・グレードB＝正答率７６〜８５％
・グレードC＝正答率６６〜７５％
　（グレードなし）
認定方法	試験終了後証明書（スコアレポート形式）が発行されます。
開催時期	通年受験可能
受験料金	8,640円(消費税込)
★この試験は、昨年末に出来たばかりの試験で私もお手伝いさせていただきました！！
http://www.iotcert.org/association/


【レベル１試験】
正式名称	IoT検定レベル１試験プロフェッショナル・コーディネータ
試験方法	CBT　四肢択一
試験時間	60分
出題総数	70問
評価方法	合否（60％以上の正解で合格）
認定方法	合格者にはプロフェッショナル・コーディネータ認定証を発行
開催時期	通年受験可能
受験料金	10,800円(消費税込)

##●試験への戦略

・参考図書
→日経BP社のIoTの教科書
https://www.amazon.co.jp/IoT%E3%81%AE%E5%85%A8%E3%81%A6%E3%82%92%E7%B6%B2%E7%BE%85%E3%81%97%E3%81%9F%E6%B1%BA%E5%AE%9A%E7%89%88-IoT%E3%81%AE%E6%95%99%E7%A7%91%E6%9B%B8-%E4%BC%8A%E6%9C%AC-%E8%B2%B4%E5%A3%AB-ebook/dp/B074MQLQGZ

に絞りました。
※2019/3/12 現在　Kindle Unlimitedで0円

前半の章は正直、内容が偏りすぎているような気もしますが、全体を通して読むことで
理解力は深まります。また、他の資格に合格していることもあり、セキュリティ、データ分析の箇所のみ集中してやっていれば合格できましたが、

・セキュリティ
・データ分析

IoT機器にあまり触ったことのない方は
・ネットワーク
・IoTデバイス

といった分野は確実に押さえておかないと、足元をすくわれる可能性があります。



・問題集
→日経BP社のIoTの問題集
https://www.amazon.co.jp/%E5%95%8F%E9%A1%8C%E3%82%92%E8%A7%A3%E3%81%84%E3%81%A6%E5%AE%9F%E5%8A%9B%E3%82%92%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF-IoT%E3%81%AE%E5%95%8F%E9%A1%8C%E9%9B%86-%E4%BC%8A%E6%9C%AC-%E8%B2%B4%E5%A3%AB-ebook/dp/B07DK81RGP/ref=sr_1_1?s=digital-text&ie=UTF8&qid=1552406152&sr=1-1&keywords=IoT%E3%81%AE%E5%95%8F%E9%A1%8C%E9%9B%86
に絞りました。
※2019/3/12 現在　Kindle Unlimitedで0円

正直、この問題集だけでは合格は難しいと思います。
この問題集を解きつつ、
― MCPC「IoTシステム技術検定　中級　第2版」対応 ―
（モバイルコンピューティング推進コンソーシアム監修）

なども参考にしながら、知識を深めていく必要があると考えています。

##●最後に

とにかく、
・福岡市IoTコンソーシアム
http://www.fitco.jp/
https://fitco.connpass.com/

・IoT検定制度委員会
http://www.iotcert.org

さんと連携して、様々始められるきっかけとなった資格です。



以下、記事です。

（IoT検定制度委員会公認）「IoTプロ・コミュニティ福岡」を発足しました
http://jinsight.hatenablog.com/entry/20180603/1528034377

「IoTプロ・コミュニティ福岡」の[福岡市IoT推進ラボ]への参加が決定しました！！！（2018年10月～）
http://jinsight.hatenablog.com/entry/20180928/1538131349

IoT検定・IoTリテラシーWG　第一回　戦略とマネジメント　開催（福岡IoTコンソーシアム）
http://jinsight.hatenablog.com/entry/20181102/1541119138


福岡の皆さんがもしいらっしゃいましたら、
是非この輪を広げていきたいと思っていますのでお声掛けください！

まずは、IoT検定試験をきっかけに！

もし目指す方がいらっしゃれば、勉強会にも足を運んでください！

ご覧いただきありがとうございました。

※誤り問題等ございましたら、コメントなどでご指摘いただけますと助かります。
Railsのflashをhelperとboostrapで加工する

##### なぜ？？
RailsのViewをひさしぶりに触り(ほぼ初めてじゃない？？)作成したが、
毎回書くのがめんどくさいのと、とりあえずhelperを触りたかったから。

以前

```sample.erb
<% if.present? %>
  <div class="alert alert-success" role="alert">
    更新を完了しました。
  </div>
<% end %>
```
長い。。。ってか毎回これかくのがだるい。
しかもfailとか用途別にかくのだるい。毎回書くメリットがわからん。ってことで、

- helper
- bootstrap
で対応することにした。

そもそもHeplerって？？[helper](https://railstutorial.jp/chapters/rails_flavored_ruby?version=5.1#sec-custom_helpers)
単純にいうと、viewを簡単に書くmoduleの印象です。
scaffoldにもはいっており、

```terminal
$ rails g helper XXX(helper name)
```

でhelperの作成ができます。


## 本題

flash_message用のhelperを作成して、erbに取り込む。

### 1. flash_message用のhelperを作成する

```
$ rails g helper flash_message
```

```
.
|- app
    |- helper
    |     |- flash_message_helper.rb
```

上記のようにhelperがflash_message_helper.rbが作成されます。

### 2. flash_message_helperの編集

参考
- [stackoverflow](https://stackoverflow.com/questions/12345065/rails-flash-message-helper)

```app.controller.rb
def show
end
def update
   redirect_to show_user_path, :flash => {:success => "更新しました" }
end
```

```flash_message_helper.rb
module FlashMessageHelper
  def flash_message
    flash.map do | k, m |
      # k => success
      # m => 更新しました。
      content_tag :div, m, :id => k, :class => [:alert, "alert-#{k}"]
    end.join
  end
end

```

```show.erb
<%= flash_message %>
```
完成しません。Stringではきだされて期待値通りにはいきません。
Stringをsafe_htmlでrenderingする必要があります。ので、最後に

```show.erb
<%== flash_message %>
```

で完成。多分期待値通りに実装できます。
【Vue/Nuxt】-テスト編（ストア）- 天気APIを使って一通りフロントを実装してみる

## 前提条件
[【Vue/Nuxt】-Vuex編- 天気APIを使って一通りフロントを実装してみる](https://qiita.com/kawa64372358/items/02348536eea1881676e8)
上記記事にて天気APIのデータを取得済み
[【Vue/Nuxt】-コンポーネント編- 天気APIを使って一通りフロントを実装してみる](https://qiita.com/kawa64372358/items/fd7d2cf4234470dc94a5)
上記記事にてコンポーネント、画面完成
[【Vue/Nuxt】-テスト編（コンポーネント）- 天気APIを使って一通りフロントを実装してみる](https://qiita.com/kawa64372358/items/eca77ea3cc72d53c4e9a)
上記記事にてコンポーネントのテスト完成

## ストアのテストを書いてみる

前回 [コンポーネントテストを書いた時](https://qiita.com/kawa64372358/items/eca77ea3cc72d53c4e9a) にprops-template.jsを用意したように
`payloadStub` にモックのJSONを書いてあげます。

```weather-app.test.js
import { createLocalVue } from '@vue/test-utils';
import Vuex from 'vuex';
import { cloneDeep } from 'lodash';
import weatherAppStore from '../../src/store/modules/weather-app';

const localVue = createLocalVue();

localVue.use(Vuex);

describe('WeatherAppストアのテスト', () => {
  let store;

  beforeEach(() => {
    store = new Vuex.Store(cloneDeep(weatherAppStore));
  });

  it('天気を取得', () => {
    const payloadStub = {
      forecast: {
        dateLabel: `今日`,
        telop: `晴のち曇`,
        image: {
          url: `http://weather.livedoor.com/img/icon/5.gif`,
          title: `晴のち曇`
        }
      }
    };

    store.commit('updateWeather', {
      weather: payloadStub
    });

    const actual = store.state.weather;
    expect(actual.forecast).toBeInstanceOf(Object);
    expect(actual.forecast).toHaveProperty('dateLabel');
    expect(actual.forecast).toHaveProperty('telop');
    expect(actual.forecast).toHaveProperty('image');
  });
});
```

`expect` の部分でテストを行なっています。
１行目：実際のデータの型はObjectか
2行目：実際のデータに`dateLabel`というプロパティが含まれているか
3.4行目：同上

<img width="373" alt="スクリーンショット 2019-03-13 1.01.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/239038/15069423-7e17-6891-d9ce-19a1f56d0dce.png">
**無事に通った**🎉

jestについては、この記事がわかりやすいです。
[Facebook製のJavaScriptテストツール「Jest」の逆引き使用例](https://qiita.com/chimame/items/e97883fd46b67529d59f)

## テスト編まとめ

- 今回書いたように簡単にVueコンポーネント・ストアのテストが書ける。
- コンポーネントが指定された状態で正しく動く保証になる。
- 今後、修正や保守が発生した場合に備えることができる。

間違った記述などあればご指摘いただけると助かります。
【Vue/Nuxt】-テスト編（コンポーネント）- 天気APIを使って一通りフロントを実装してみる

## 前提条件
[【Vue/Nuxt】-Vuex編- 天気APIを使って一通りフロントを実装してみる](https://qiita.com/kawa64372358/items/02348536eea1881676e8)
上記記事にて天気APIのデータを取得済み
[【Vue/Nuxt】-コンポーネント編- 天気APIを使って一通りフロントを実装してみる](https://qiita.com/kawa64372358/items/fd7d2cf4234470dc94a5)
上記記事にてコンポーネント、画面完成

## テストを書いていく！
### その前に、テストのツール（Jest/ vue-test-utils）
#### jest
JavaScriptのテストフレームワーク（Facebook製）
[Jest · 🃏快適なJavaScriptのテスト](https://jestjs.io/ja/)
#### vue-test-utils
Vue.js向けの公式単体テストライブラリ
コンポーネントだけのテストなどもできる
[ガイド | Vue Test Utils](https://vue-test-utils.vuejs.org/ja/guides/)

#### ちょっとまって、テストなんて書いたことないよって方
この記事がわかりやすいのでぜひ見てみて！
[フロントエンドにテストを導入](https://qiita.com/howdy39/items/cdd5b252096f5a2fa438)

### コンポーネントテストを書いてみる
前回の記事で作成した`ForcastCard` コンポーネントのテストをします。
本体のコードはこちら→[【Vue/Nuxt】-コンポーネント編- 天気APIを使って一通りフロントを実装してみる](https://qiita.com/kawa64372358/items/fd7d2cf4234470dc94a5)

ディレクトリ構成は下記のとおり

- ForcastCard
    - index.vue
    - style.scss
    - props-template.js
    - index.test.js

### propsのテンプレートファイル作成

```props-template.js
export default {
  forecast: {
    dateLabel: `今日`,
    telop: `晴のち曇`,
    image: {
      url: `http://weather.livedoor.com/img/icon/5.gif`,
      title: `晴のち曇`
    }
  }
};
```

```index.test.js
import { shallowMount } from '@vue/test-utils';
import { getMountTemplate } from '~/utils/test/component-test-util';
import propsTemplate from './props-template';
import TargetComponent from './index';

describe('コンポーネント', () => {
  test('props', () => {
    const wrapper = shallowMount(TargetComponent, getMountTemplate(propsTemplate));

    expect(wrapper.find('.forcast-list__title').text()).toBe(propsTemplate.forecast.dateLabel);
    expect(wrapper.find('.forcast-list__telop').text()).toBe(propsTemplate.forecast.telop);
    expect(wrapper.find('.forcast-list__image').attributes().src).toBe(propsTemplate.forecast.image.url);
  });
});
```

実際にテストしている部分は`expect` のところです。
今回は３件のテストを書いています。

### 言語化するとこんな感じ

①forcast-list_titleクラスを持つDOMエレメントを指定
`(wrapper.find('.forcast-list__title')`

②テストする要素のテキストはpropsTemplate.forecast.dateLabel
`.text()).toBe(propsTemplate.forecast.dateLabel);`

propsTemplate.forecastは、props-template.jsに書いてある `dateLabel: '今日'` の部分です。

つまり、**forcast-list_titleクラスを持つ要素の中身は'今日'である** ということをテストしています
<img width="420" alt="スクリーンショット 2019-03-13 0.39.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/239038/8d2a9f17-608a-2ee1-8f0a-ca5aaeac632c.png">
**無事に通った**🎉

これが分かれば、あと２件もわかる！属性をテストしたいときは `.attributes()` を使います。

他にもテストしたい項目によって都度Jestの公式を確認してみてください〜
最初が分かれば、次回からググり力がつくはず💪

次回はVuexのストアテストの記事を書きます
[【Vue/Nuxt】-テスト編（ストア）- 天気APIを使って一通りフロントを実装してみる](https://qiita.com/kawa64372358/items/23405caa573f6fbdf81b)
【Vue/Nuxt】-コンポーネント編- 天気APIを使って一通りフロントを実装してみる

## 前提条件
[【Vue/Nuxt】-Vuex編- 天気APIを使って一通りフロントを実装してみる](https://qiita.com/kawa64372358/items/02348536eea1881676e8)
上記記事にて天気APIのデータを取得済み

## 見える側を作っていく！

### 前回の続き

`ForcastCard` というコンポーネントを作ってみました。
イメージはこんな感じ。
![IMG_0017.jpg](https://qiita-image-store.s3.amazonaws.com/0/239038/658d0747-9255-77c8-6ac7-b8fa28837e0a.jpeg)


```index.vue
<template>
  <section class="weather">
    <h1 class="weather__title">{{ weather.title }}</h1>
    <ForcastCard
      v-for="(forecast, i) in weather.forecasts"
      :forecast="forecast"
      :key="`weather__forcasts-key-${i}`"/>
  </section>
</template>

<script>
import ForcastCard from '~/components/Pages/ForcastCard';
import { mapFields } from 'vuex-map-fields';

export default {
  components: {
    ForcastCard
  },
  computed: {
    ...mapFields('weatherApp', ['weather'])
  },
  async asyncData({ store, params }) {
    await store.dispatch('weatherApp/fetchWeather');
  }
};
</script>
```

`< ForcastCard :forecast="forecast"` のところでmapFieldsした
weather.forecastsの配列をv-forして一つずつpropsとして渡してあげます。


### ForcastCardコンポーネントを作る

```index.vue
<template>
  <div class="forcast-list">
    <h2 class="forcast-list__title">{{ forecast.dateLabel }}</h2>
    <dl>
      <dt class="forcast-list__telop">{{ forecast.telop }}</dt>
      <dt>
        <img
          v-show="forecast.image.url"
          :src="forecast.image.url"
          class="forcast-list__image"
          alt="forcast.image.title">
      </dt>
    </dl>
  </div>
</template>

<script>
export default {
  props: {
    forecast: {
      type: Object,
      required: true
    }
  }
};
</script>
```

親から受け取ったprops `forecast` を使って画面を構成していきます！

**ここまでの記述で画面は完成！**
完成画像では、少しcss書いたので横並びになっていたりします。

次の記事ではコンポーネントのテストを書いていく！
[【Vue/Nuxt】-テスト編（コンポーネント）- 天気APIを使って一通りフロントを実装してみる](https://qiita.com/kawa64372358/items/eca77ea3cc72d53c4e9a)