OmniAICreator/Qiita-1.07M huggingface dataset:
データ ソース を 変更するには

Power BI Desktop や Excel の クエリ エディター で 集計したいデータを加工や変換などできるのですが、データソースのディレクトリやファイル名が変更になったときは [データソース設定] をする必要があります。データモデルにデータがロードされていれば、以前通りにレポートなどを編集することはできますが、[データの更新] ができなくなってしまします。デモデータをお渡しする機会も増えたことですし、基本的な操作手順などを整理しておきます。

# Power BI Desktop
[ホーム]タブ → [クエリを編集] → [データソース設定]
![2017-12-24_12-07-12.png](https://qiita-image-store.s3.amazonaws.com/0/193509/f77aaab5-5a8b-9e17-fc8c-2867d168b4d6.png)

もしくは、クエリ エディター で 
[ホーム]タブ → [データソース設定]
![2017-12-24_12-07-51.png](https://qiita-image-store.s3.amazonaws.com/0/193509/20cf9618-218e-410d-63b3-a1a659c18c9e.png)

[データソース設定] ダイアログ → [ソースの変更]
![2017-12-24_12-09-07.png](https://qiita-image-store.s3.amazonaws.com/0/193509/522272d8-7f58-5963-3173-e17ffe06007e.png)

例えば、Excel ファイルが データソースであるとき
![2017-12-24_12-09-14.png](https://qiita-image-store.s3.amazonaws.com/0/193509/72189127-c3e1-82a6-0121-9d2a4c7e5ff0.png)


# Excel

[データ]タブ → [取得と変換]グループ → [データの取得] → [データソースの設定]
![2017-12-24_12-10-12.png](https://qiita-image-store.s3.amazonaws.com/0/193509/55d61f8f-859f-ac33-90d3-7902e2253905.png)

もしくは、クエリ エディター で
[ホーム]タブ → [データソースの設定]
![2017-12-24_12-10-41.png](https://qiita-image-store.s3.amazonaws.com/0/193509/64649249-e514-d791-4460-7c54bcd61c17.png)

[データソース設定] ダイアログ → [ソースの変更]
![2017-12-24_12-11-41.png](https://qiita-image-store.s3.amazonaws.com/0/193509/3601a572-1df2-ea92-c974-8344f958d27a.png)

例えば、Excel ファイルが データソースであるとき
![2017-12-24_12-11-45.png](https://qiita-image-store.s3.amazonaws.com/0/193509/d0120df8-9c72-31c7-ca0b-0445cd2a3b97.png)

# その他
- [Power BI 勉強会 - connpass](https://powerbi.connpass.com/)
- [Power BI Desktop を使い始めるには](http://qiita.com/PowerBIxyz/items/6c4735cb5b5712e70981)
- [Excel で Power Query を使い始めるには](http://qiita.com/PowerBIxyz/items/52e563037b855a099ca9)
ItemTouchHelperでRecyclerViewの入れ替え

  
この記事は、[株式会社Y's アドベントカレンダー](https://qiita.com/advent-calendar/2017/ysinc) 25日目の記事になります。
KotlinによるAndroid開発の初歩的な内容になります。

　　
RecyclerView内のViewをロングタップで入れ替えたいときの1つのやり方として、ItemTouchHelperを使うと簡単に実装することができるよ！って話をしようと思います。↓みたいなイメージ。

こう並べて
![device-2017-12-24-121236.png](https://qiita-image-store.s3.amazonaws.com/0/224639/4fe2bc8d-d891-7d4f-19a5-ad43cab1f0ce.png)

ドラッグして
![device-2017-12-24-121405.png](https://qiita-image-store.s3.amazonaws.com/0/224639/752584fc-89e8-be41-8f37-99c7f92a6dd5.png)

指を離すと入れ替わる
![device-2017-12-24-121423.png](https://qiita-image-store.s3.amazonaws.com/0/224639/e67fc9bb-bd70-dcd8-8dd6-eeef67f842f9.png)


##Viewの配置
RecyclerViewとGridLayoutManagerを使って並べていきます。

```kotlin
        // 30個のViewを作成
        val data = ArrayList<String>()
        for (number in 1..30) data.add(number.toString())
        
        // GridLayoutManagerで横幅を5に
        val recycler: RecyclerView = findViewById(R.id.recycler)
        val adapter = Adapter(data)
        recycler.adapter = adapter
        recycler.layoutManager = GridLayoutManager(this, 5)
```

ここまでで、
30個のViewが配置できました。
![device-2017-12-24-121236.png](https://qiita-image-store.s3.amazonaws.com/0/224639/16a51de2-6b2d-1a8f-1a1a-e5e719be492b.png)


##ItemTouchHelperでの入れ替え
ロングタップでの並び変え程度であれば、ItemTouchHelper.SimpleCallbackで簡単に実装できます。

```kotlin
        val touchHelper = ItemTouchHelper(object : ItemTouchHelper.SimpleCallback(
                ItemTouchHelper.UP or ItemTouchHelper.DOWN
             or ItemTouchHelper.RIGHT or ItemTouchHelper.LEFT, 0) {
           // ここで指定した方向にのみドラッグ可能

            override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {

                val from = viewHolder.adapterPosition
                val to = target.adapterPosition

                val data = adapter.data.removeAt(from)
                adapter.data.add(to, data)

                adapter.notifyItemMoved(from, to)

                return true
            }

            override fun onSwiped(viewHolder: RecyclerView.ViewHolder?, direction: Int) {
                // スワイプで削除する場合はここ
            }
        })

        touchHelper.attachToRecyclerView(recycler)
        recycler.addItemDecoration(touchHelper)
        // ここを忘れると動かないので注意
```
　　
これを付け加えるだけでドラッグでの移動が簡単にできるようになりました！
![device-2017-12-24-121405.png](https://qiita-image-store.s3.amazonaws.com/0/224639/c7a6454f-d271-645d-0893-5dd30c0e8cca.png)
　　
![device-2017-12-24-121423.png](https://qiita-image-store.s3.amazonaws.com/0/224639/6241983a-3b2c-d1b2-74e0-a0523c4d34ce.png)
コードカバレッジ視点で、Rubyでテストを書くときに気をつけること

### 追記 2017-12-25
Ruby2.5.0で分岐カバレッジのための情報が追加されるみたいなので、それをベースにしたカバレッジツールが出てきそうですね。書いて数日ですが、この記事の内容も古くなりそうなので気をつけてください。

Add branch coverage https://bugs.ruby-lang.org/issues/13901

----

[トレタ Advent Calendar 2017](https://qiita.com/advent-calendar/2017/toreta)の21日目記事です。

トレタでは、SimpleCov(https://github.com/colszowka/simplecov) を使って、
Railsアプのコードカバレッジを計測しています。
そのときに気をつけていることを、いくつかつか紹介したいと思います。

## 行単位でしか判断できない
コードカバレッジにはいくつか種類がありますが、SimpleCovで計測できるのは、命令網羅(C0)と呼ばれる
行単位でコードが実行されたかを確認するものです。(これはRubyVMから実行行を取得し、それをもとに作られているためです)
C0カバレッジは比較的網羅率を上げやすいかんたんなものですが、逆にそれだけでは問題に気づけないケースがでてきます。


## 3項演算子

```rb
def div(x)
  1 / (x ? 1 : 0)
end
```

xがtrueな値のテストだけが書いてあるとして、カバレッジを計測すると100%になります。

<img width="393" alt="スクリーンショット 2017-12-24 12.11.59.png" src="https://qiita-image-store.s3.amazonaws.com/0/26103/110a22db-cfc6-eea6-6337-03ff205b51fc.png">

このケースでfalseを入れると例外が起きてしまいます。あえてifで書いてみると、そのパスが通らないことがはっきりわかります。

<img width="390" alt="スクリーンショット 2017-12-24 12.15.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/26103/d2bac8f2-3774-6b49-37cd-b47d50eea24f.png">



## 後置きのif/unless

```rb
a = 1
a = 2 if x == true
```

これも3項演算子と同じで、xがどういう値であれ、この行を通ってしまうので、xがtrueのケースを書かなくても、この行が通ったことになります。a = 2の部分を通っていないケースに気をつけましょう。

## ブロック
```rb
sum = some_arr.select { |i| i > 0 }.reduce { |r, i| p i ; r + i }
```

このケースでは、some_arrに0以下の値しかない場合に、selectで空配列になってしまうので、そのあとのreduceはなにもしません。reduceに限らず、ブロックを使っているときに、実はそれが実行されないケースのテストしか書いていないというのに気をつけましょう。

たとえばsum([-1, 0])みたいなテストだけしても100%になります。

<img width="574" alt="スクリーンショット 2017-12-24 12.18.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/26103/045f0e94-64a4-7178-7a7b-23d725f7d81b.png">

改行をいれても変わりません。行単位といっても、物理的な改行ではなくてRubyのプログラムとして一行単位なためです。

<img width="390" alt="スクリーンショット 2017-12-24 12.25.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/26103/ef57f337-c704-2be9-fc20-97c27b8706e2.png">

doブロックにしてみると、行が変わるのでテストが通っていないことがわかります。

<img width="376" alt="スクリーンショット 2017-12-24 12.26.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/26103/ce12ee7f-cb9c-085a-cb33-a27a7992db7f.png">

## メタプログラミング
メタプログラミングを使ってメソッドやクラスを動的に生成していると、
その部分に対してテストが通っているかをカバレッジで判断できないケースがが多くあります。

```rb
[0, 1, 2].each do |i|
  define_method "m#{i}" do
    1 / i
  end
end
```

m0, m1, m2が定義されますが、どれか一つでも通せはこの行を通ったことになります。

<img width="435" alt="スクリーンショット 2017-12-24 12.32.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/26103/f40215c0-05aa-d919-6929-c51ea03c3a8a.png">

また文字列からevalするケースではカバレッジは無力です。

参考 [SimpleCovのカバレッジ(網羅率)](https://qiita.com/yui-knk/items/acc8319ecb1ee82f4acc)

## まとめ
思いついたケースをまとめただけなので、まあまだ他にも気をつけるケースはあると思います。

それから、カバレッジのために3項演算子や後置ifやメタプログラミング使うな、という話ではなくて、
使っているカバレッジの性質を理解して、そういう部分にはテストを書くときに注意するとか、
より危なそうなケースでは、あえて冗長にしてもいいし、そのへんは各自で判断してやっていくのがいいと思っています。

もっと強力なカバレッジツールがあれば、こういうことに気をつけなくてもいいようになる可能性もありますが、現状は見当たらないので(あればおしえてください)、テストが意図通りに動作を確認できているかの一つの道具/指標として、SimpleCov使っていきましょう。
Raspberry Piでntpdがない

Raspberry Piで時計がずれているのでntpの設定をしようとしたら、/etc/ntp.confがないしntpqコマンドも使えない。

最新のRaspbianでは[ntpdが入ってない](https://www.raspberrypi.org/forums/viewtopic.php?t=192020)ようなので、インストールが必要らしい。

```
$ sudo apt-get update && sudo apt-get -y install ntp
```

これでntpqが使えるようになった。

```
$ ntpq
ntpq>
```
Google Home miniで、入退出管理を作ってみた

こんにちは、issyxissyです。

先日、"Google Home mini" を 半額で買って、ちょいちょい、いじってます。
プライベートで使いこなすというのもありですが、業務の中で改善できる部分ないかなーと。。。

社内で、まだ紙で管理しているところがあったりするので、そこを何かできないかなーと思って。
とある部屋の入退出を音声で管理してみようと思います。

## やりたいこと
- とある部屋の入退出を音声で管理をしたい

## 必要なもの
- Goole Home mini (Google Home でもOK)
- [IFTTT](https://ifttt.com/)
- Google Spreadsheet & Google App Script

## 概要
- Google Home mini → [IFTTT](https://ifttt.com/) → Google Assistant → 入室時と退室時に、Google Sheetsに記録するようにします

## Google Home miniのセットアップ
- Google Home mini をセットアップします
  - ![IMG_7213.png](https://qiita-image-store.s3.amazonaws.com/0/221028/2d79463a-7b18-0bbe-a4cb-bbf8bfa2018d.png)
  - 完全にマカロンですね、、、
  - セットアップは、説明書どおり。。。
- ちなみに
  - 初期化の方法は、裏側のポッチを長押しするらしいです。

## IFTTTの設定
- **"何をしたとき"** に **"何をする"** を設定します。
- 今回でいうと、Google Assistantで、**入退室の音声を認識したら**、**Google Sheetsに記録** という感じになります。
- なので、入室時と、退室時の2つのAppletを新規作成します。

### "this" の設定
- "何をしたとき"の、"何"を設定します
- "Google Assistant" を選択します
  - Google Home で利用している Google アカウントで連携設定を行います
- "Say a phrase with a text ingredient" を選択します
  - 下記のように設定します
  - <img width="562" alt="" src="https://qiita-image-store.s3.amazonaws.com/0/221028/bc68a5d9-c3a4-3402-db36-e62d4acbe229.png">

### "that" の設定
- "何をする"の"何"を設定します。
- "Google Sheets" を選択します
  - Google Home で利用している Google アカウントで連携設定を行います
- "Add row to spreadsheet" を選択します
  - 下記のように設定します
  - <img width="467" alt="Screen Shot 2017-12-24 at 12.04.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/221028/735731ea-957b-7075-e3fa-78bc3dc85b49.png">

- 現在、{{CreatedAt}}が挿入できないようなので、SpreadSheet側で行が追加されたら、日付と時刻を自動で入力するようにします
  - 参考: [https://www.youtube.com/watch?v=ufujOWXsq40](https://www.youtube.com/watch?v=ufujOWXsq40)

- これと同様に、退室版を作ります。

## Google Sheets の設定
- 新規で、Sheetを作成
  - "入退出管理" で作成
  - カラムは、日付・日時・入室/退室・氏名
- Google App Scriptで、カラムが挿入されたら、自動で日時を挿入
  - トリガーで、値が変更されたら、 AddUpdatedAt が実行されるように設定

```
var sheet = SpreadsheetApp.getActiveSheet(); 

function AddUpdatedAt() {
  var lastRow = sheet.getLastRow();
  sheet.getRange(lastRow, 1).setValue(formatDate(new Date(), 'yyyy/M/d'));
  sheet.getRange(lastRow, 2).setValue(formatDate(new Date(), 'H:m:s'));
}

function formatDate(date, format) {
  return Utilities.formatDate(date, 'Asia/Tokyo', format)
}
```

## 実際やってみる
- 入室するとき
  - issyxissy: 「OK、Google」「作業始めます 石田」
  - マカロン:「石田 さん、慎重に作業しましょう！」

- 退室するとき
  - issyxissy: 「OK、Google」「作業 終わりました 石田」
  - マカロン:「石田 さん、お疲れ様でした！」

- Google Sheetsに記録されます
  - <img width="462" alt="Screen Shot 2017-12-24 at 12.40.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/221028/75f6f488-e724-6115-a7c0-181f316cf413.png">


## もし、認識しない場合、
- スマホ「Google Home」アプリの、マイアクティビティで、どんな音声をキャッチして、どう認識したか、確認できます。
  - しかも、音声を再生できる・・・。
- **区切りを意識して話しかけると、認識率高いです**

## まとめ
- Google Home mini + iftttの組み合わせは、カンタン！
- でも、音声認識が悪い部分もあったりので、iftttの設定は要確認
- ちょっとしたことが、日常のコンテキストに組み込むことができるので、将来性を感じた
- 部屋の入退室の管理は、認識率など考えると、felicaカードが無難かなー。
  - やっぱりネタにしかならない・・・(´・ω・｀;
- Web上で確認したり、業務改善できないか、集計・分析してみたいですね
DesignDoc

ドキュメント作成時に便利なフォーマットメモ。

よく目的とゴールがごちゃごちゃになったりするので、目的、ゴールなどがはっきり伝わります。
経緯もわかるため、なぜ、実行するのかが、伝わりやすいです。

```
## 経緯
## 目的
## ゴール
## 概要・ハイレベルアーキテクチャー
## 詳細
## 効果
## 影響範囲
## 検討事項
## 懸念・課題
## スケジュール
```
CoffeeScriptはやっぱり駄目だった。

## 俺達の戦いは終わった…

[人気上昇中のJavaScriptライブラリを調べてみた【2016年版】](http://www.buildinsider.net/web/popularjslib/2016)

> 2013～2014年の間、この分野は混戦状況だったが、2015年でついに決着がついたようだ。「TypeScript」が飛び抜け、他をさらに引き離し続けている。

[JavaScript ベスト・オブ・ザ・イヤー 2016](https://risingstars2016.js.org/ja/)

> Python と Ruby のシンタックスにインスパイアされた CoffeeScript はここ数年最も人気なコンパイラでしたが、2016年では下火となり大半の開発者は CoffeeScript から Babel を使って ES6 を書くスタイルへと移行していきました。

[AltJS(Alternative JavaScript)をまとめて一覧で比較 人気はTypeScript](https://urashita.com/archives/13524)

> 2015年の初頭までは、どれが本命かわからない混戦状態でしたが、2015年後半にかけてTypeScriptが伸びてきました。
>
> そして、2016年には更に引き続き伸びて、もはや圧勝と言ってよいでしょう。

ついには[嫌いな言語ランキング](https://stackoverflow.blog/2017/10/31/disliked-programming-languages/)6位入賞という不名誉な烙印まで押されてしまった。

もう、CoffeeScript には未来は無いのか？このまま廃れていくのか？我々にはもう絶望しか残されていないのだろうか…

## 遅すぎたCoffeeScript 2

2017年9月18日、CoffeeScript のメジャーバージョンアップである 2.0.0 が正式リリースされた。2015年6月に ECMAScript 2015[^1] がリリースされてから実に2年以上もかかってしまった。その間、ES2015+[^2] を採用を検討する場合が多く発生した。検討の結果、ES2015+ と文法的な互換性が高く、静的型付けである TypeScript を採用するようになったのは自然の流れであった。React の流行により、Babel による ES2015+ のトランスパイルであれば JSX 記法がそのまま使える事や TypeScript での JSX 記法のサポート等も少なくない影響を与えたであろう。

CoffeeScript は ES2015+ に対して何をやっていたかというと、ジェネレーター対応のための`yield`の追加ぐらいである。それ以外にも細々とした対応をしていたが、コンパイル先のターゲットは ES5 であり、ES2015+ にコンパイルするような仕組みでは無かった。Node.js や Electron での使用では ES5 にする必要は全くなく、また、現代的なブラウザでも ES2015+ 対応が進んだこともあり、ES5 へのコンパイルはやや冗長になる場合も出てきた。かといって、ジェネレーターは IE 等の ES5 までのブラウザでは全く対応していないため、ES5 をターゲットをしているのに、ES5 ではないコードになってしまうと言う中途半端な状態になっていた。

そういう中、やっと出てきたのが CoffeeScript 2 である。ES2015+ 文法へのコンパイルに対応したばかり、JSX 記法のサポートや、型付けのために Flow の型コメントにもサポートするなど、TypeScript にも十分対応しうる機能を盛り込んできている。しかし、如何せん遅すぎた。もし、2年前に CoffeeScript 2 が出ていれば、TypeScript の台頭を許さなかった可能性は十分にあり得ただろうが、仮定の話を仕方が無い。

## JavaScriptの未来も暗い

現在、JavaScript の次として注目されているのが WebAssembly だ。WebAssembly が各ブラウザでサポートされ、環境も整ったとき、もはや JavaScript 自体が不要になる。既存のライブラリのために何年かは残るかも知れないが、そのまま消えていく可能性もある。

JavaSCript つまりは ECMAScript 自体は文法的に優れている言語とは言えない。今までは JavaScript しか無かったという独占状態であったため、JavaScript を使わざるを得なかったと言うだけに過ぎない。別のより優れた言語を用いて WebAssembly にできるのであれば、JavaScript を使う理由は無くなってしまうだろう。

JavaScript が消えるとき、それは CoffeeScript が消える時を意味する。TypeScript も同様であろう。TypeScript を WebAssembly で使えるようにするぐらいなら、Microsoft にとっては C# を WebAssembly で使えるようにした方が得だと考えるだろう。有象無象の多くの altJS が同時に消えていく事になる。

## 来るべき言語

未来は誰にもわからない。もしかしたら、来年には CoffeeScript のブームが起きるかも知れないし、誰にも知られずひっそりと終焉するかも知れない。

CoffeeScript は本当に終わったのだろうか？まだ終わってなかったとしても、そのうち終わる言語なのだろうか？どんなものでもいつかは終わりは来るものであっても、それが今か来年か数年先かそれともずっと後なのかはよくわからないものだ。第一、何を持って終わると言えるのだろうか？

CoffeeScript は様々な点で JavaScript よりも優れていると私は信じていた。しかし、ES2015以降はその信念に揺らぎを感じていた。一時的に ES2015+ や TypeScript へ移っていたことを否定はしない。だが、CoffeeScript 2 が出た事によって、ES2015+ や TypeScript へ移る理由は失われた。そうであれば、私達は、もう一度 CoffeeScript を見つめ直すべきなのでは無いだろうか？

[^1]: ES2015とも。バージョンとしては6となるため、ES6と表記される場合が多い。それ以前のECMAScript 5.1までをES5と表記する場合が多い。
[^2]: ECMAScript 2015以上、つまり、ECMAScript 2016、ECMAScript 2017等を含めたES2015以上の機能を示す。
XCTAssertの非同期Assertion(XCTAssertEventually)作ってみた

# はじめに
こんにちは。
突然ですがiOSのユニットテストで、XCTestを使って非同期のテスト書くのって結構めんどくさいですよね。
最近色々あってQuick/NimbleからXCTestに戻したんですが、NimbleにあったtoEventuallyが結構魅力で、XCTestでXCTExpectationやwait(for: [expectation], timeout: 1.0)とか毎回書くの面倒だなと思っていました。
そこで、XCTestでもNimbleのtoEventuallyのように簡単に非同期のAssertionが書けるExtensionを作ってみました。

***XCTestExtensions***
https://github.com/shindyu/XCTestExtensions

# 使い方
非同期処理の値を確認するときの例.

```swift
    func test_XCTAssertTrueEventually() {
        var value = false
        
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
            value = true
        }

        XCTAssertTrueEventually(value) // success
    }
```

UI関連のテストに適用した例.
(ViewControllerAのボタンをタップするとViewControllerBが表示される)

```swift
    func test_tappedButton() {
        var viewControllerA = ViewControllerA()
        
        viewControllerA.button.sendActions(for: .touchUpInside)

        XCTAssertTrueEventually(viewControllerA.presentedViewController is ViewControllerB) // success
    }
```

# 実装

```swift
    public func XCTAssertTrueEventually(_ expression: @escaping @autoclosure () throws -> Bool, timeout: TimeInterval = 1.0, pollInterval: TimeInterval = 0.1, file: StaticString = #file, line: UInt = #line) {
        let expectation = XCTestExpectation()
        for i in 0..<Int(timeout/pollInterval) {
            DispatchQueue.main.asyncAfter(deadline: .now() + pollInterval * Double(i)) {
                if (try! expression()) {
                    expectation.fulfill()
                }
            }
        }

        switchProcess(
            by: XCTWaiter.wait(for: [expectation], timeout: timeout),
            timedOutMessage: "XCTAssertNotNilEventually failed",
            file: file,
            line: line
        )
    }

    private func switchProcess(by result: XCTWaiter.Result, timedOutMessage: String, file: StaticString = #file, line: UInt = #line) {
        switch result {
        case .completed:
            break
        case .timedOut:
            XCTFail(timedOutMessage, file: file, line: line)
        default:
            XCTFail("resultに応じたmessageをいれると良い", file: file, line: line)
        }
    }
```

# 簡単な解説
実装自体はXCTestExpectationとXCTWaiterを使った非同期の処理にDispatchQueueのasyncAfterを組み合わせたものです。
timeoutとpollIntervalを元に一定間隔でexpressionを実行した結果からfulfill()が実行され、XCTWaiter.waitで得られる値から最終的な処理が決まるようになっています。
timeoutとpollIntervalは呼び出し時に設定できるのでテストごとに調節することも可能です。

インターフェースはXCTAssertを参考にしつつ、既存のメソッドを使うときに気づけるように末尾にEventuallyをつけるようにしました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/130686/7484e8aa-7f82-b9ab-b9ad-c410e79ecbdf.png)

ただのwrapperといえばそうなんですが、使う時に毎回お作法のようにXCTestExpectationなどのコードを書かなくて良くなるので気に入ってます。

# 最後に
ちなみに今回書いたコードは、会社で「普段の案件業務と直接関係ないことしましょ〜」という日があったので思い立って書いたコードです。
ついでに何種類かAssertionをまとめてOSSにして公開してみました。
宜しければ使ってみていただいて、StarやPullRequestお待ちしてますmm
MongooseOS + mjs で I2C 気温センサを読み取る

Mongoose js の I2C ライブラリの使い方で手間取ったのでメモを残しておきます。
**SHT31** というセンサーを使い、気温と湿度を取ります。

[Mongoose OS \+ mjs の git 管理開発環境構築 \- Qiita](https://qiita.com/elzup/items/fd2617b7e86ff2357c6b) で作った環境を使います。


```js:fs/init.js

load("api_config.js");
load("api_mqtt.js");
load("api_net.js");
load("api_sys.js");
load("api_timer.js");
load("api_i2c.js");

let address = 0x44;
let bus = I2C.get_default();

let get_temps = function() {
	let d = "\x2C\x06";
	I2C.write(bus, address, d, d.length, true);
	Sys.usleep(1000);

	let data = I2C.read(bus, address, 6, true);

	print(data);

	let temp = data.at(0) * 256 + data.at(1);
	let cTemp = -45 + 175 * temp / 65535.0;
	let fTemp = -49 + 315 * temp / 65535.0;
	let humidity = 100 * (data.at(3) * 256 + data.at(4)) / 65535.0;

	return [temp, cTemp, fTemp, humidity];
};

Timer.set(
	1000 * 5,
	true /* repeat */,
	function() {
		let res = get_temps();
		print("t:");
		print(res[1]);
		print("h:");
		print(res[3]);
		// MQTT.pub('home/livingroom/brightness', JSON.stringify(lux), 0);
	},
	null
);
```


SHT31 のデータシートはこれです。http://akizukidenshi.com/download/ds/sensirion/Sensirion_Humidity_Sensors_SHT3x_DIS_Datasheet_V3_J.pdf


# つまづいた所
[公式ライブラリの api_i2c.js のドキュメント](https://mongoose-os.com/docs/api/api_i2c.js.html)
コード: https://github.com/mongoose-os-libs/i2c/blob/master/mjs_fs/api_i2c.js

1. I2C.write の使い方
2. sleep が必要
3. I2C.read の使い方

```js
I2C.write(bus, address, "\x2C\x06", 2, true);
Sys.usleep(1000);
let data = I2C.read(bus, address, 6, true);
```

Python と比較

```py
bus.write_i2c_block_data(address, 0x2C, [0x06])
time.sleep(0.5)
data = bus.read_i2c_block_data(address, 0x00, 6)
```

address は 0x44 です。
buf はデータシートにあるように指定します。
6byte 読めます。

 ![暫定版.png](https://qiita-image-store.s3.amazonaws.com/0/40717/98de3061-61d9-b360-f7ad-6e036b8c1b1e.png)

# 参考
[ControlEverythingCommunity/SHT31: Humidity and Temperature Sensor](https://github.com/ControlEverythingCommunity/SHT31)
Python や Arduino での実装サンプルなど↑
Rails：renderでmodelの内容を部分テンプレ表示

renderを使い、データベースの内容を表示する方法のメモです。

#ここの例でやりたいこと：talkモデルに入っているcontentを表示する

talkモデルのcontentはブログのコメント（text形式）のようなものです。
コメント機能を実装しようとしていると考えていただければと思います。

#今の状態
```ruby:talks_controller.rb

def index
 @talks = Talk.all
end
```

```talks/index.html.erb

#<table>などは省略

    <% @talks.each do |talk| %>

<tr>
    <td><%= talk.id %></td>
    <td><%= talk.content %></td>
    <td><%= talk.created_at %></td>
</tr>    

    <% end %>
```

このようにして、talkモデルのid、content、created_atを表示していました。

これをrenderで書き出す設定にしたいと思います。

#部分テンプレートの作成
まず初めに、部分テンプレートを作成します。
talkモデルの表示を行いたいので "_talk.html.erb" を作成しました。
その中に、出したいhtmlを書きます。

```_talk.html.erb
<tr>
    <td><%= talk.id %></td>
    <td><%= talk.content %></td>
    <td><%= talk.created_at %></td>
</tr>
```    

そしたら、先ほどの"talks/index.html.erb"に書いてあったhtmlと<%= %>を削除。

その場所に
`<%= render :partial => "talk", :collection => @talks %>`
を書きます。

ここで":partial"の意味は、talks配下の部分テンプレート"_talk.html.erb"を挿入することを指定しています。
collectionにて、talkモデルのすべて（@talks = Talk.all のため）を書くことを指定しています。

このタイミングで、表示が失敗していないか確認してください。

最後に、先ほどの<%= render ....%>を
`<%= render @talks %>`
に書き換えておしまいです。

#注意点
<%= render @talks %>を使うためにはまず、部分テンプレート名が「アンダーバー + ＠以下の単数形」になっている必要があります。

今回の場合では、talksの単数形はtalkなので"_talk.html.erb"としています。

次に、:collectionは@talksなどのように、モデルの複数形で指定する必要があります。
複数形にして、その中に「モデル名.all」（今回は"Talk.all"）とすることで、eachを使ったときと同様に、モデルの全てのレコードを表示するまで自動で繰り返すようになります。

また、@talksのように複数形にすることで、<%= render @talks %>と書いた場合、自動的にtalksの単数形、"talk"が使われている部分テンプレートファイル「_talk.html.erb」を探しにいってくれます。

さらに、自動的に"talk"が部分テンプレートファイル内（今回の場合では"_talk.html.erb"）で、@talksを順番に代入する変数として定義されるため、例えば"talk.id"などのように書くことができています。

renderで使うためのすべてのファイルは同じフォルダ（今回では"views/talks"の中）に入れる必要があり、まだフォルダ名は@以下の文字（今回では"@talks"なので"talks"）と同じにする必要があります。

#結論

結論としては、@talksにTalk.allが代入されている場合、<%= render @talks %>の意味は、
・部分テンプレートファイル「_talk.html.erb」をレンダリングする
・「_talk.html.erb」内の変数、"talk"に@talksの内容を一つずつ代入する

また、viewsの配下のフォルダ名がtalksで、その同じフォルダに部分テンプレとそれを使用するファイルを入れる必要がある、ということも注意点です。
C++とPthreadでJavaライクなスレッドライブラリを作る~その4 - Writeスレッド追加

前回，lock変数とpthreadのmutexを使ってロック/通知の仕組みを実装し，ReadThreadが正しく動作することを確認したので，今回はWriteThreadを追加して，この仕組がうまく動くことを確認する．そこで，以下のクラスを実装する．

- Data：ロックする`read/write`メソッド，ロックしない`unlockRead/unlockWrite`メソッドを持ち，read系のメソッドはある変数(`num`)を100回デクリメント，write系のメソッドは300回インクリメントするメソッド，doReadTest/doWriteTestを内部で呼び出す．
- WriteThread: write系のメソッドを呼び出す．
- ReadThread:  read系のメソッドを呼び出す．


```c++:rw.hpp
class Data {
private:
    int num;
    int bufSize;
    RWLock *lock;

    void slowly();

    /* for test */
    int doReadTest();
    int doWriteTest();


public:
    Data();
    Data(int size, RWLock *lock);
    ~Data();

    int getBufSize();

    /* for test */
    int read(int id);
    int unlockRead(int id);
    int write(int id);
    int unlockWrite(int id);
};
```


```c++:main.cpp
int main(void) {
    std::string s;
    RWLock lock;
    Data d(&lock);
    ReadThread rt1(&d), rt2(&d), rt3(&d);  // ReadThreadを3つ生成
    WriteThread wt1(&d);                   // WriteThreadを1つ生成
    rt1.start(NULL);
    rt2.start(NULL);
    rt3.start(NULL);
    wt1.start(NULL);

    while(true) {
        sleep(1);
//        printf("sleep...\n");
    }
    return 0;
}

```

まず，Read/Writeスレッドともに，ロックしないメソッドを呼び出すようにして実行してみる．

```c++
void* ReadThread::run(void* arg) {
    printf("run Thread %d\n", this->id);
    int num = this->pData->unlockRead(this->id);   --> ここ
    printf("ReadThread%d num = %d\n", this->id, num);
    return NULL;
}

void* WriteThread::run(void* arg) {
    printf("run WriteThread %d\n", this->id);
    int num = this->pData->unlockWrite(this->id);　--> ここ
    printf("WriteThread%d num = %d\n", this->id, num);
    return NULL;
}
```

すると，以下の結果を得る．

```
run Thread 1
run Thread 2
run Thread 3
run WriteThread 4
ReadThread2 num = -183
ReadThread3 num = -186
ReadThread1 num = -182
WriteThread4 num = 2
```
ロックしないことによって，最終的にnumが0にならない

次に，ロックするread/writeに変更する

```c++
void* ReadThread::run(void* arg) {
    printf("run Thread %d\n", this->id);
    int num = this->pData->read(this->id);   --> ここ
    printf("ReadThread%d num = %d\n", this->id, num);
    return NULL;
}

void* WriteThread::run(void* arg) {
    printf("run WriteThread %d\n", this->id);
    int num = this->pData->write(this->id);　--> ここ
    printf("WriteThread%d num = %d\n", this->id, num);
    return NULL;
}
```
すると，

```
run Thread 1
run Thread 2
run Thread 3
run WriteThread 4
read lock by 1
get lock by 1
read lock by 2
lock failed wait by 2
read lock by 3
lock failed wait by 3
write lock by 4
lock failed wait by 4
read unlock by 1
ReadThread1 num = -100
finish wait by 2
get lock by 2
finish wait by 3
lock failed wait by 3
finish wait by 4
lock failed wait by 4
read unlock by 2
ReadThread2 num = -200
finish wait by 3
get lock by 3
finish wait by 4
lock failed wait by 4
read unlock by 3
ReadThread3 num = -300
finish wait by 4
get lock by 4
write unlock by 4
WriteThread4 num = 0  -> ここ
```
最終的にnumは0になる．
つまり，うまく動いていることがわかる．

全部のソースコードは[こちら](https://github.com/hiro4669/thread_cpp/tree/master/4th)

[次回](https://qiita.com/hiro4669/items/de7f8033c63f55a6f8e5)に続く．
装備　♪あなたな～らどうする～　私は・・・。

こだわらなくとも、ある程度のことはできるけど
自分に合ったものを使うと、日々の生活もパフォーマンスも全然異なる。
色々試して、自分に合うものを選択するのがベスト。

#　プライベート
PCはMacBook Airと昔自作したWindowsマシンを使ってます。
モニターはブラビア32インチ（テレビと併用しています）

## Macbook Air

- キーボード　HHKB Lite2 For Mac
- マウス　ELECOM製無線のやつと有線マウスを併用


## Windowsデスクトップ（昔作成した自作機）

- キーボード 茶軸　日本語配列　テンキーレス　（FKBN91M/JB2）
- マウス 有線のコンパクトサイズ

## コーヒー（飲み物）

ネスカフェ、ゴールドブレンド 

# 現在の職場　

-　キーボード　ピンク軸 日本語配列（FKBN91MPS/JB2）
-　マウス　ロジクール M100r（有線のやつ。会社支給品）

PCはThinkPad T440p（堅そうなやつ）で、Windowsの中でVirtualBox使って作業してます。
(iOS向けアプリだとMac使ってますが、サーバサイド担当なので）
BtoB向けクラウドサービスの開発に携わっています。

## コーヒー（飲み物）

- コンビニにある、セルフサービスのやつ。
- クラフトボスのブラック。
- ペットボトルのお茶。

社内にはオフィスグリコのお菓子（100円入れて引き出し開けるやつ）はあるけれど、社内に自販やドリンクサーバ類があると便利かな･･･なんて思う今日この頃。

# 過去の記録

## 数年前（非Web系企業で自社サービス開発）

- キーボードHHKB Lite2 For Mac
- マウス　ELECOM製の無線のやつ
- コーヒー　オフィスグリコなどで補給

PCは、MacBook Pro。中でVirtualBox動かしたりしてやっていました。


## 5年くらい前（客先常駐）

- キーボード　客先に準ずる
- マウス　客先に準ずる
- コーヒー　構内の自販機など

下にメモが挟めるマウスパッドが必需品でした。


# 総括

**キーボードやマウスもコーヒーも、シーンごとに自分に合ったものを使うのがベスト。**
**シーンごとに**というのがポイントで、決まった机での作業が多いケース、フリーアドレス、外出が多いケースなどでだいぶ変わってきます。

## 私の場合

今みたいな固定的な机を使う場合だったらメカニカルキーボードを使いたい。だって…押し心地が違うもの。
できれば、HHKBの宣伝文句の「カウボーイは馬を替えても、鞍は持ち歩く」みたいな感じで、外出時もメカニカルキーボードを使いたいくらい。

会社で使っているピンク軸をに慣れてきたら、茶軸は音が大きく感じました。
押し心地も考えると、ピンク軸の方が良いかな・・・とも思います。

マウスは・・・感度にもよるけど有線式のほうが良いかなと思いました。
ThinkPadの赤いトラックボールはどうも苦手です。
大きさは･･･手が大きいので、余りにも小さいのはどうもダメです。

コーヒーですが、薄めのやつのほうが快適かなと感じています。

#余談

モニターや椅子も重要です。

個人的には、モニターは2台で、1台は作業用、もう1台は参照情報用。って使い方がやりやすいかなと思います。

椅子の座り心地や高さも重要。
高さ調節は大事です。
C++とPthreadでJavaライクなスレッドライブラリを作る~その2 - ロックの導入


前回に引き続き，今回はスレッド感の同期をとるロックの仕組みを導入する．
pthreadを動悸するには，以下の関数を使う必要がある．

```c
int  pthread_mutex_lock(pthread_mutex_t *mutex);
int  pthread_mutex_unlock(pthread_mutex_t *mutex);
```
そして，この関数を実行する前に初期化，そして使い終わったら削除するクリアする必要がある．

```c
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
int pthread_mutex_destroy(pthread_mutex_t *mutex);
```

そこで，これらを導入したRWLockクラスを導入する．このクラスの`invoke`は，スレッドを同期して重い処理をさせ，`invoke_without_lock`は，同期せずにスレッドに処理を実行させる．


```c++:rw.hpp
class RWLock {
private:
    pthread_mutex_t mutex; // ロックのための構造体

public:
    RWLock();
    ~RWLock();
    void invoke(int id); // dummy
	void invoke_without_lock(int id);
};
```


```c++:RWLock.cpp
RWLock::RWLock() {
    pthread_mutex_init(&this->mutex, NULL); // コンストラクタで構造体の初期化
}

RWLock::~RWLock() {
    pthread_mutex_destroy(&this->mutex);    // デストラクタで構造体のクリア
}

/* lock test */
void RWLock::invoke(int id) {
    pthread_mutex_lock(&this->mutex);                // ロック
    for (int i = 0; i < 5; ++i) {
        printf("invoked by thread %d(%d)\n", id, i);
        sleep(1);
    }
    pthread_mutex_unlock(&this->mutex);              // アンロック
}

void RWLock::invoke_without_lock(int id) {
   for (int i = 0; i < 5; ++i) {
        printf("invoked by thread %d(%d)\n", id, i);
        sleep(1);
    } 	
}
```

これらの関数を，ReadThreadから使う．

```c++
void* ReadThread::run(void* arg) {
    printf("run Thread %d\n", this->id);
	//lock->invoke(this->id);
	lock->invoke_without_lock(this->id);
    return NULL;
}
```

この例のように，スレッドから``invoke_without_lock``を実行するようにしてmainを実行すると，


```c++:main.cpp
int main(void) {
    RWLock lock;
    ReadThread rt1(&lock), rt2(&lock);

    rt1.start(NULL);
    usleep(500000); // 0.5sec wait
    rt2.start(NULL);


    while(true) {
        sleep(1);
    }  
    return 0;
```

実行結果は以下のようになる．

```
>./main
run Thread 1
invoked by thread 1(0)
run Thread 2
invoked by thread 2(0)
invoked by thread 1(1)
invoked by thread 2(1)
invoked by thread 1(2)
invoked by thread 2(2)
invoked by thread 1(3)
invoked by thread 2(3)
invoked by thread 1(4)
invoked by thread 2(4)
```
このように，thread1とthread2の出力結果が混在する．
一方，　``invoke``を呼び出すように変更すると，

```c++
void* ReadThread::run(void* arg) {
    printf("run Thread %d\n", this->id);
	lock->invoke(this->id);
	//lock->invoke_without_lock(this->id);
    return NULL;
}
```

実行結果は，

```
run Thread 1
invoked by thread 1(0)
run Thread 2
invoked by thread 1(1) // スレッド1が先にロックを取得
invoked by thread 1(2)
invoked by thread 1(3)
invoked by thread 1(4)
invoked by thread 2(0) // スレッド2は待たされて，個々から実行
invoked by thread 2(1)
invoked by thread 2(2)
invoked by thread 2(3)
invoked by thread 2(4)
```

このように，先にスレッド1がロックを取得し，それをアンロックしてからスレッド2がロックを取得して処理を実行するため，スレッド1の処理が完了した後スレッド2の処理が始まることがわかる．

全部のソースコードは[こちら](https://github.com/hiro4669/thread_cpp/tree/master/2nd)
[次回](https://qiita.com/hiro4669/items/700a7bafc74b9b6b7857)に続く．
C++とPthreadでJavaライクなスレッドライブラリを作る~その１ - Threadクラス

ここでは，C++でRead/Write Lockデザインパターンを実装すべく，Javaのスレッドライブラリ風なAPIを作っていく．Threadクラスを継承して使う設計にする．

まず，pthread_createの定義は

```c
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
         void *(*start_routine)(void *), void *arg);
```

であり，第3引数にvoid*を引数で受取，void*を返す関数ポインタを指定する必要がある．そして，第4引数は
第3引数の関数へ与える引数のためのvoidポインタを指定することになっている．
今回，Javaのスレッドライブラリのように，`new Thread().start()`でThreadを継承するクラスのrunを実行する．
ところが，この第3引数に与える関数ポインタは，スタティックじゃなければいけないので，そのまま`run`をわたす訳にはいかない．そこで，`Thread`にstaticな`wrap`メソッドを用意し，これ経由でインスタンスメソッドである`run`を実行するようにした．

```c++:Thread.hpp
class Thread {
private:
    pthread_t thread;   // pthreadのための構造体
    void *args;         // runの引数のためのポインタ

protected:
    static int tcount;

public:
    Thread(){tcount++; /*printf("thread\n");*/}
    virtual ~Thread() {}
    virtual void* run(void *arg) = 0;

    static void* wrap(void *arg) {
        Thread* pt = (Thread*)arg;  // 第4引数で自分自身(this)が渡されるので，キャストしてrunを実行
        return pt->run(pt->args);
    }
    void start(void *arg) {
        this->args = arg;
        if (pthread_create(&this->thread, NULL, wrap, this)) {  // スレッドの生成. 第4引数にthisを指定
            printf("thread create error\n");
            abort();
        }
    }

    void wait() {
        if (pthread_join(this->thread, NULL)) {
            printf("join error");
            abort();
        }
    }
```

続いて，Threadを継承する`ReadThread`．これは単に，スレッドIDとともに1秒ごとに"work by Thread ..."と表示するだけ．
なお，スレッドIDとして利用している`tcount`はクラス変数であるため，どこかで実体を定義する必要がある．


```c++:rw.hpp
#include "Thread.hpp"

class ReadThread : public Thread {
private:
    int id;

public:

    ReadThread();
    ~ReadThread();
    void* run(void *arg);
};
```

```c++:ReadWrite.cpp
ReadThread::ReadThread() {
	this->id = tcount;
}

ReadThread::~ReadThread() {    
}
void* ReadThread::run(void* arg) {
    printf("run Thread %d\n", this->id);
	for (int i = 0; i < 5; ++i) {
		printf("work by Thread %d\n", this->id);
		sleep(1);
	}
    return NULL;
}
```
次は，これを利用するmain.cpp


```c++:main.cpp
int main(void) {
    ReadThread rt1, rt2;

	rt1.start(NULL);
	usleep(500000);
	rt2.start(NULL);

	rt1.wait();
	rt2.wait();

    printf("end of mein thread\n");

    return 0;
}
```

実行結果

```
> ./main
run Thread 1
work by Thread 1
run Thread 2
work by Thread 2
work by Thread 1
work by Thread 2
work by Thread 1
work by Thread 2
work by Thread 1
work by Thread 2
work by Thread 1
work by Thread 2
end of mein thread
```
個々のスレッドか交互ログが出力されていることわかる．

全部のソースコードは[こちら](https://github.com/hiro4669/thread_cpp/tree/master/1st)

[次回](https://qiita.com/hiro4669/items/23c6681bbe8efd0df4d5)に続く
C言語で学ぶ台形公式による積分の近似

#台形公式とは
下の絵の青い線がが積分したい関数のグラフ、aからbまでを積分したい範囲(左の茶色の線から右茶色の線）だと思ってください。台形公式とは緑と黄色の部分の面積を積分した値だと考えることです。その値は

```math
 \frac{(f(a) + f(b)) (b - a)}{2} 
```
になりますね
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f3130383731362f66613335663735312d356335352d663361642d313138322d6632366236306266373732332e706e67.png](https://qiita-image-store.s3.amazonaws.com/0/108716/f4eaa448-2c86-bc9c-8fe1-f1ce2c54d069.png)


しかし、図で見て分かる通り緑の部分が明らかに余計です。なので、$ a $と$ b $の間に$ c = \frac{a + b}{2} $という点を設けましょう。緑色と黄色の部分の面積の合計は

```math
\frac{(f(a) + f(c)) (c - a) + (f(c) + f(b)) (b - c)}{ 2 }
```
になりますね。するとついさっきの図より緑色の部分が減っているのがわかります。これが台形公式です。$ a $と$ b $の間に点があればあるほど、その値は正確になります。
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f3130383731362f33303762303434352d636133352d306663622d386137362d3030663866383337303136392e706e67.png](https://qiita-image-store.s3.amazonaws.com/0/108716/d97ce9d8-e0f9-cac4-9174-b7e21810ce84.png)!　![Untitled.png](https://qiita-image-store.s3.amazonaws.com/0/108716/781a4ccd-db20-6ba9-a81b-a109c5015a8b.png)



#ソースコード
```integral.c
#include <stdio.h>
#include <math.h>

#define EPS (1.0e-6)
#define f(x) ((x)*(x))

int main(){
    double a = 0, b = 2, sum = 0;
    for(double x = a; x < b; x += EPS){
        sum += (f(x) + f(x+EPS));
    }
    sum *= (EPS / 2);

    printf("%f\n", sum);
}
```
LightSailでWindows Server立ち上げて日本語化してみた


# はじめに
kintoneでSAML認証を使用したSSOを実現するのWindows Server部分の設定です。

ちょっと検証用にサーバー使いたいってなった時に、EC2もラクはラクなんですがもっと手軽なものあるやんけ！ということでLightSail使ってみたのでメモ。

リージョンもいろいろ選べるようになっているのと、うまく使えばEC2よりコスト抑えられるのと、単体でぽこっと立てるだけならこれで十分やんって感じ。

EC2は一応これで1ヶ月あたりのランニング費用を試算。
<a href="http://calculator.s3.amazonaws.com/index.html?lng=ja_JP" target=_blank rel="noopener noreferrer">AWS Simple Monthly Calculator(簡易見積ツール)</a>

# LightSailの価格体系
うん。わかりやすい。今回はADとADFS入れるだけで他に何かバックエンドでゴリゴリ動かすわけでもないので、LightSailの1番安いプランにする。
![lightsail_plan.png](https://qiita-image-store.s3.amazonaws.com/0/73604/ee062e33-cf0c-83c3-1a58-6debab5a09d2.png)


しかもStaticIP(AWSでいういわゆるEIP)ひとつ付けられるみたいなのでなんだかお得感。
セキュリティグループとか細かく設定したいならEC2のほうがいいかもしれないけど、個人ユースでテスト用って考えるとこれくらいで十分。


# 構築のプロセス 〜 LightSail起動
マネコンからプランとリージョン選択してぽちぽちするだけでインスタンスが立ち上がる。
東京リージョンも選択できます。
![lightsail2.png](https://qiita-image-store.s3.amazonaws.com/0/73604/191b09c7-5b25-7231-2cee-d016af8eab27.png)

インスタンスの名前をつけて・・・
![lightsail3.png](https://qiita-image-store.s3.amazonaws.com/0/73604/3540748f-2d14-aef3-9a07-e92a21f38a96.png)

WindowsはWS2K16と2K12R2のどちらか選択可能。
特に支障ないのでWS2K16にしたよ。
![lightsail4.png](https://qiita-image-store.s3.amazonaws.com/0/73604/3436c285-24d3-fb0b-80dd-d550a9771b8f.png)


# 構築のプロセス 〜 立ち上げたLightSailにStaticIPアタッチ
起動までは数分もかからない。この時点でもPublicIPは振られるんだけど、これがおそらくrebootとかかけるとIPが変わっちゃう。なのでIPを固定化するためにStaticIPをアタッチする。
![lightsail5.png](https://qiita-image-store.s3.amazonaws.com/0/73604/9b8a6a57-4b9e-fdd7-2cd4-ad20e008c776.png)

アタッチする時も画面に沿って設定するだけ。
![lightsail6.png](https://qiita-image-store.s3.amazonaws.com/0/73604/1349dccc-59e8-6071-21a2-b15a0a5d46ae.png)

StaticIPがアタッチされた。
![lightsail7.png](https://qiita-image-store.s3.amazonaws.com/0/73604/377ab0d7-7bd4-cfb6-1956-2d5775d1c1d1.png)

アタッチした後はIP表示のところにピンマークが付きます。
![lightsail8.png](https://qiita-image-store.s3.amazonaws.com/0/73604/80663bcb-7caa-6e88-2d0d-a94a01561ddf.png)


# Windows Server 〜 ログイン
ここまでできたらいよいよログインです。ラクなのがなんとRDP用のターミナルがあるんだよ。セルフで自分のRDP Clientを利用することも可能だけど、特に問題なかったらこれで十分かも。
![lightsail10.png](https://qiita-image-store.s3.amazonaws.com/0/73604/a5cf9f1a-a5b2-6f40-1927-90a79eef9fd7.png)


# Windows Server 〜 ロケール設定
デフォルトのロケールが英語なので、そのままでも良いんだが今回はわかりやすいように日本語に変更する。
ロケールの設定は普通のWindowsと同じ。
Add a languageで言語を追加してOptionsからLanguage Packをダウンロードする。
![lightsail11-1.png](https://qiita-image-store.s3.amazonaws.com/0/73604/33276626-3a6a-fc7b-1db4-5887576f5077.png)

その後Set as defaultでデフォルト設定にする。
![lightsail14-1.png](https://qiita-image-store.s3.amazonaws.com/0/73604/41227a81-efd1-b201-485c-60c5d806dcb6.png)

サインインし直すと言語変わるよーと出ているのでログインし直す。
![lightsail12.png](https://qiita-image-store.s3.amazonaws.com/0/73604/dd149fcb-7516-9870-ea96-beb018800b6f.png)

ちゃんと日本語になってることを確認。
![lightsail13.png](https://qiita-image-store.s3.amazonaws.com/0/73604/2466bc2e-e405-8a5d-3f37-6774efe1b094.png)


このあとWindows Updateとかかけたけど時間帯のせいなのかレスポンスが重かった。。。
午前中とかだとRDPのターミナルとかもさくさく快適だし、試す時間帯は考えたほうがよさげ。
C言語 AdventCalendar 2017に寄せて（＋1次元セルオートマトン・ツリー）

12/25くらいは [1次元セルオートマトン][ca]/[ルール30(Rule 30)][rule30] でクリスマスツリーを飾りましょう:christmas_tree:

[ca]: https://ja.wikipedia.org/wiki/%E3%82%BB%E3%83%AB%E3%83%BB%E3%82%AA%E3%83%BC%E3%83%88%E3%83%9E%E3%83%88%E3%83%B3
[rule30]: https://ja.wikipedia.org/wiki/ルール30

```c:rule30.c
#include <stdio.h>

#define RULE 30
#define N 33
int cell[2][N];

int main()
{
  int s, i, j;

  cell[0][N/2] = 1;
  for (i = 0; i < N/2; i++) {
    for (j = 1; j < N-1; j++) {
      putchar(cell[i&1][j] ? '*' : ' ');
      s = (cell[i&1][j-1] << 2) | (cell[i&1][j] << 1) | cell[i&1][j+1];
      cell[~i&1][j] = !!(RULE & (1 << s));
    }
    putchar('\n');
  }
  return 0;
}
```

```text:(出力)
               *               
              ***              
             **  *             
            ** ****            
           **  *   *           
          ** **** ***          
         **  *    *  *         
        ** ****  ******        
       **  *   ***     *       
      ** **** **  *   ***      
     **  *    * **** **  *     
    ** ****  ** *    * ****    
   **  *   ***  **  ** *   *   
  ** **** **  *** ***  ** ***  
 **  *    * ***   *  ***  *  * 
** ****  ** *  * *****  *******
```

さてQiitaへの禊も済ませたので、あとは技術論とは無関係な雑談です。


# C言語 AdventCalendar 2017に寄せて

> [くぅ～疲れましたw これにてAdventCalendar完走です！][ku-tuka]
> 実は、ネタ投稿<sup>[12/1分]</sup>したら代行の話を持ちかけられた<sup>[これは嘘]</sup>のが始まりでした
> 本当は話のネタなかったのですが<sup>[これは真実]</sup>←
> ご厚意<sup>[誰の？]</sup>を無駄にするわけには行かないので流行り<sup>[どこで？]</sup>のネタで挑んでみた所存ですw
> 以下、まどか達<sup>[誰？]</sup>のみんなへのメッセジをどぞ 

[ku-tuka]: https://dic.pixiv.net/a/%E3%81%8F%E3%81%85%EF%BD%9E%E7%96%B2%E3%82%8C%E3%81%BE%E3%81%97%E3%81%9Fw

...続きません。

自分で立てた訳でもない [C言語 AdventCalendar 2017][adc] ですが、最終的には 18記事 を投稿する結果となりました。参加された 7名（自分含む） の皆様もお疲れ様でした。~~25日全部埋めるハメにならなくて良かった。~~

[adc]: https://qiita.com/advent-calendar/2017/c_lang

## ありそうな質問とその答え

> Q: なんでそんなに投稿してんの？

A: さあ？別に義理も義務もなかったのですが、なんとなく。あえて言うなら、うっかり[目標設定][selfgoal](於12/4)したせい。
[selfgoal]: https://twitter.com/yohhoy/status/937645862271950848

> Q: 暇なの？

A: いいえ。事前にネタを準備していた訳ではないので、「ほぼ毎日締め切り的なものが存在する」という状況は想像以上に **精神的負担** になります。特に期日厳守していないにもかかわらず、です。改めて、**一人AdventCalendarを完遂させている方々を尊敬** いたします。

> Q: C言語好きなの？

A: 大嫌いじゃないけど、大好きでもない、そんな感じ。外部要因がなければ、C++言語を使う方がマシです。

> Q: いまどきC言語の需要なくない？

A: せやな。今年のC言語 AdventCalendarも[12月直前まで参加者**ゼロ**][cuckoo](於11/27)だったようですし。人が想像する範囲よりも現実世界は多様ですから、どこに需要あるのかはわかりません。あるところにはあるんでしょう。
[cuckoo]: https://twitter.com/ignis_fatuus/status/934820259369910272

> Q: 来年もまたやるの？

A: こんなにはもうやんねえよ ヽ(｀Д´)ﾉ ウワァァァン 

俺は参加はしない多分しないと思う
しないんじゃないかな
ま ちょっと覚悟はしておけ
テスト駆動開発による組み込みプログラミングをgoogletestでやる8章

[前回](https://qiita.com/tomoyuki-nakabayashi/items/816e35f2099b021992dd)の続きです。

# 前置き

[Amazon.co.jp: テスト駆動開発による組み込みプログラミング ―C言語とオブジェクト指向で学ぶアジャイルな設計](https://www.amazon.co.jp/%E3%83%86%E3%82%B9%E3%83%88%E9%A7%86%E5%8B%95%E9%96%8B%E7%99%BA%E3%81%AB%E3%82%88%E3%82%8B%E7%B5%84%E3%81%BF%E8%BE%BC%E3%81%BF%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-%E2%80%95C%E8%A8%80%E8%AA%9E%E3%81%A8%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91%E3%81%A7%E5%AD%A6%E3%81%B6%E3%82%A2%E3%82%B8%E3%83%A3%E3%82%A4%E3%83%AB%E3%81%AA%E8%A8%AD%E8%A8%88-James-W-Grenning/dp/4873116147)

*James W. Grenning*の名著です。
組込み界隈でテスト駆動開発をしたい人のバイブルだと思っています。

ただし、写経して勉強しようとすると、環境で躓いたり、本に書かれているコードを打ち込むだけでは動作しなくて、困ったりします。
完成されたコードは、オライリーの公式ページで配布されていますが、道中で度々迷ってしまいます。
特に、8章『プロダクトコードをスパイする』からは、テストコード、プロダクトコード、共に省略される場合があるため、余計迷子になりやすいです。

同書籍で勉強を始める人が、サクッとテストを開始できるように、迷子になったときのリファレンスとして使えるように、私の写経を公開します。

# レポジトリ

https://github.com/tomoyuki-nakabayashi/TDDforEmbeddedC_Chapter8

cloneして1分でテスト実行可能です。
8章をはじめからやりたい方は、タグのstartlineかp133をご利用下さい。
startlineはファイルを用意しただけ、p133は最初のテストがパスした状態になっています。

本の写経をしていて、迷子になったら、コミットログを参照して下さい。
できるだけこまめにコミットするように心がけています。
書籍内のテスト名や、ページ番号を含めてコミットしていますので、差分を確認しながら読み進めて頂くと良いかと思います。

![TDDforEmbeddedC_Chapter8.PNG](https://qiita-image-store.s3.amazonaws.com/0/204676/86f4122a-b2ae-b700-9748-3168969b8956.png)
自然非言語処理第１８日目：環境から自律的に機械が学ぶ強化学習

![AF425586-E13A-439A-AE63-719069CD14D0.jpeg](https://qiita-image-store.s3.amazonaws.com/0/78052/b4888119-5ce9-095f-b915-79313d2173d1.jpeg)

人生は試行錯誤しながら生きていくものです。

右の道がダメだったら左の道ヘいき、
左の道がダメだったら右の道ヘいく。

生きていれば、たまには嬉しいこともあったり悲しいこともあるでしょう。

人生だけではなく、人とのコミュニケーションにも距離感が大切です。
ヤマアラシのジレンマを知っていますか。
２匹のヤマアラシが近づきすぎても、相手を傷つけてしまうし、
遠すぎても寂しい気持ちになってしまいます。

そんなこと感じなことを機械学習に活かしたのが強化学習です。

今回は人間が行う試行錯誤による学習のメカニズムと
それをモデル化した強化学習という手法をあわせて説明します。

その後、強化学習を使ったシンプルな問題を問いてみましょう。

# 試行錯誤による人間の学習のメカニズム
人間は試行錯誤をするときには何かを目標として行動することが多いでしょう。
目標に達成できればうれしいですし、快感も得られますがが、
不思議な事に目標を達成しようと夢中になっているときも快感も得られるようになっています。
たとえば、あなたがゲームをしているとしましょう。
さらに言えば、テトリスをやっているとしましょう。
テトリスをうまく積んで積んで積んで、とやっている最中も夢中になると思いますが、4つの縦棒が来た時の感動は誰しもが感じたことがあるでしょう。

この試行錯誤のメカニズムは行動主義心理学ではオペラント条件づけとして説明されます。オペラント条件づけとは報酬と罰を与えることで自立的な学習を生物に行わせる実験手法のことです。主にスキナー箱という特殊な環境でマウスに対して実験は行われます。人間にも適用可能です。たとえば、先ほどのテトリスの場合、オペラント条件づけで説明すると表のようになります。

| 用語 | 用語の説明 | テトリスでの具体例 |
|:-:|:-:|:-:|
| オペラント行動  | 反射ではない研究対象とする行動  | ゲームをプレイする  |
| **強化**  |  オペラント行動の自発頻度が高まること | ゲームをより夢中にプレイしている状態  |
|  弱化 | オペラント行動の自発頻度が低くなること  | ゲームをやらなくなること  |
| 強化子  | オペラント行動の自発頻度を高める刺激  | スコアの上昇  |
| 弱化子  | オペラント行動の自発頻度を低くする刺激  | ゲームオーバーになること  |

表を見ると、テトリスをプレイすること、ハマる要因、つまり強化子となるのはスコアの上昇なのがわかります。


また、神経科学では、この試行錯誤の仕組みは大脳基底核が関わっているとされています。たとえば、覚せい剤を一回使うと永遠に使ってしまうのは、覚せい剤により大脳基底核が放出するドーパミンが快感をひきおこすためです。覚せい剤が非常に強い強化子になっているわけです。

# 生物の学習過程を応用した学習アルゴリズム、強化学習
強化学習とは、このオペラント条件づけをモチーフにした機械学習アルゴリズムです。強化学習の強化はオペラント条件づけの強化から取られています。

まず、強化学習の世界観を図1に示します。
![3EB26564-F90B-436E-8464-976E61033520.png](https://qiita-image-store.s3.amazonaws.com/0/78052/77f2da86-b5ee-b556-23bd-1f88c9a70f8f.png)
図1 強化学習の世界観。sは状態、rは報酬、aは行動を表す変数である。([1]より引用)

強化学習では研究対象となる生物をエージェントモデルで説明できると仮定します。また、そのエージェントモデルで説明されるエージェント(以下、エージェント)は環境の中にいると仮定します。エージェントはセンサなどを通じて、環境に関する情報や自身に関する情報を状態sとして記憶します。エージェントは状態sに応じて、報酬rが得られるように行動aを実行し、自分を含む環境に影響を与えます。つまり、強化学習とは報酬を最大化するように自立的に環境に応じて行動する存在を作り出す技術になります。具体的なアルゴリズムとしてQ学習が挙げられます。

強化学習は作る側の価値観が大きく関わって来ます。エージェントの報酬、つまり、欲求を何にするかを人間側が決めなければならないからです。ゲームのスコアが報酬となら穏やかですが、たとえば、人を⚪︎した数にしてしまうと、⚪︎人機械が生まれます。作り手の倫理観が試されます。


# 実装： ゲームを学習する
今回はアタリの~~クソゲー~~ゲームを元にゲームを強化学習するプログラムを作りましょう。

**(今回は時間の都合上、割愛します。)**

# 感想
今回はゲームを機械に学ばせることを中心に教えました。
こうやって学んだ機械と人間はいい勝負をするでしょう。
**ゲームという遊びを通じて、コミュニケーションを行うこともまた、非言語コミュニケーションの1つと言えます。**

# 応用例
ゲームに対する強化学習といえば、Google のAlphaGoがあります。
人で例えると1000年分の試行錯誤を繰り返して、人を超える棋力を得ました。

# まとめ
今回は試行錯誤を学習方法とした強化学習の仕組みを整理しました。
次回はヤマアラシのジレンマで出てくる距離感ってなんでしょうという話をします。

# 参考文献
[1] https://qiita.com/Hironsan/items/56f6c0b2f4cfd28dd906
[2] これからの強化学習
Chefのrecipe内でgemを追加してロードする

#目的
Chefのrecipe内でgemを追加してロードする方法を紹介します。
ここでは、recipeのリソース"ruby_block"で'deep_merge'をロードする例を紹介します。
一応、インターネット接続がないChef clientでも動くように考慮します。

#構成
OSはRHEL7.3,ChefはServer Client方式。
利用したChef Clientは13.4.24-1.el7, Chef Serverは12.16.14-1.el7

#手順
deep_merge-1.2.1.gemをダウンロードして、cookbookのfiles/default以下に配置しておきます。

以下recipeのサンプルです。

```
cookbook_file "/tmp/deep_merge-1.2.1.gem" do
  source "deep_merge-1.2.1.gem"
end

execute "deep_merge install" do
  command "/opt/chef/embedded/bin/gem install --local /tmp/deep_merge-1.2.1.gem"
  notifies :run, "ruby_block[sample ruby block]"
end

ruby_block 'sample ruby block' do
  block do
    require 'json'
    $LOAD_PATH << '/opt/chef/embedded/lib/ruby/gems/2.4.0/gems/deep_merge-1.2.1/lib'
    require 'deep_merge'

    ~~deep_mergeを利用した処理~~

  end
  action :nothing
end
```



以上
Macターミナルのデフォルト背景色を変更する

ターミナルを起動した時のデフォルト背景色を変えたいと思っていたけど、すぐに方法に気付けなかったのでメモ。

デフォルトプロファイルを指定する。
下記はAppleサポートサイトの引用。

1. 「ターミナル」＞「環境設定」と選択してから、「プロファイル」をクリックします。
1. デフォルトプロファイルとして使用したいプロファイルを選択します。
1. プロファイルリストの下部にある「デフォルト」をクリックします。
1. 選択したプロファイルの名前の下に「デフォルト」と表示されます。

![スクリーンショット 2017-12-24 9.png](https://qiita-image-store.s3.amazonaws.com/0/33974/148f2b3a-e1b4-b9ac-38ac-31c0f510b90f.png)

[Apple - デフォルトおよび起動プロファイルを指定する](https://support.apple.com/ja-jp/guide/terminal/trml5856b1f2/mac)
今年はくりぼっちが少ないらしい

12/9から、\#彼氏欲しい \#彼女欲しい ツイートを強制マッチングするというサービスを稼働させ、クリぼっち撲滅作戦を極秘で行いました。
我々の大活躍で、今年はクリぼっちが少ないはずですが、その結果報告をまとめます。
<img width="592" alt="Screen Shot 2017-12-10 at 0.08.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/62822/e15412bd-cead-9a73-97ed-b751e3bb939a.png">

## 概要
[MashupAwards](http://mashupaward.jp/) 2017関東予選にて、**「[kamatte(かまって)](https://kamatte.cc)」**というサービスを発表しました。
このサービスは、*「\#彼氏欲しい」*や*「\#彼女欲しい」*などのツイートを強制マッチングしお店の用意までするサービスです。
惜しくも予選3位でしたが、需要の高まる**クリスマス前から運用してみたい**という私たちの独断から、炎上覚悟で開発をすすめリリースしたのでその結果をまとめます。

## 12/09から運用を開始

### 早速最初のマッチングが行われる
- 2017年12月9日 22:30 ~ 本番運営開始！！

- マッチングワードは**「#彼氏募集中」** と**「#彼女募集中」**

<img width="592" alt="Screen Shot 2017-12-10 at 0.08.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/62822/e15412bd-cead-9a73-97ed-b751e3bb939a.png">

### リンクを踏むと詳細ページに遷移する
- **「行きたい」**ボタンを押すと相手に更にメンションが飛び、行きたいことをアピールできます
- **「予約する」**ボタンを押すと、ホットペッパーの予約確定手前の画面まで飛びます

<img width="403" alt="Screen Shot 2017-12-10 at 0.32.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/62822/dc9a4ef9-a028-9223-d302-6c0d5a163c5c.png">


### その後も継続的にマッチングが進む
- 意外と男が「#彼氏欲しい」などハッシュタグを載せており、**男性同士でのマッチングも目立つ**
- インプレッションは**1時間で3000ほど**まで上がる
- １時間以内では「行きたい」「予約する」ボタンは押されなかった

<img width="297" alt="Screen Shot 2017-12-10 at 0.16.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/62822/d0590336-994c-b5f1-d56e-d2c8e6f32f0e.png">


### 90分で凍結されていた
- 1時間30分を過ぎたところで、いきなり**マッチングができなくなった**
- どうやら**凍結された**ようです。飲み放題の時間よりも早いです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/62822/a8689498-a8c0-886d-ad92-690b966114b5.png)

#### 原因
- マッチングしてツイートを10分に1回にしてて頻度が高いと予想

### 次の日、めげずにマッチングしてみる
- 頻度は1時間に1回
- 朝7:30から再びマッチング開始
- 12:00頃凍結確認。。。

##### 原因
- 1時間に１回の頻度でも、自動スパム扱いされている模様。。
- それとも、通報が相次いでいるのか


### また次の日、めげずにマッチングしてみる
- 頻度は3時間に1回


#### なんとこれが成功する
- 12/23日現在twitter社に止められることなく、運用が進んでいます。

## 実際のTLでの反応
### 押し売りにもほどがあるだろ
- この反応を待っていました

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f36323832322f63613533666134382d656635632d333233362d653032622d3065666331316265326364652e706e67.png](https://qiita-image-store.s3.amazonaws.com/0/62822/72bd5a75-80ff-a734-81d3-560749f2fe47.png)


## わかったこと
- **かまってちゃんは、意外とおおい**
  - 市場調査すると、かまってちゃんは思ったよりもおおく驚きました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/62822/fbcab932-ddaf-52fd-1556-711f38c0884c.png)


## まとめ
- 意外とみんな通報とかしていない模様
    - 通報されまくって、バンされると思っていましたが、意外と運用ができていました
    - ボットをマッチングしないよう努力（NG文言/ユーザーブラックリスト）はしていますが、それでもボットとマッチングしている感じがある
- 実際に予約はされていない模様
    - 北海道ー沖縄でマッチングしても、お店は関東が選ばれるのでそこらへんも解決したい。
- いきたいボタンも押されていない
    - おそらく押すのがこわいとかそういう問題だと思うのでデザインでカバーできないかと思っています

### **　　　　　\\\\くりぼっちは救えなかった//**


## 参考URL
-  kamatte | かまって (https://kamatte.cc)
-  関東予選の様子 https://twitter.com/mashupaward/status/930786789945573376/video/1
-  MashupAwards 2017関東予選まとめ　https://togetter.com/li/1171830?page=5
Google Cloud Platformのサーバレスサービスを使用して、自宅の環境データを見える化したので振り返る。

#やった事
今回、自宅にあるラズパイから環境データを飛ばし見える化するまでを、Google Cloud Platformのサーバレスサービスを使用して実装してみました。一通り出来たので、料金含めて振り返りたいと思います。

イメージ図と使用したサービスは以下の通りです。
![イメージ図](https://qiita-image-store.s3.amazonaws.com/0/168941/0c5e6fd7-16eb-1bba-ee85-cbc10c9d88ed.png)

IoT Coreのアイコンは公式から提供がなかったので青い六角形で代用しています。

なお、当投稿は2017年12月時点の情報のものになります。
#振り返り
##ラズパイからIoT Coreまで
ラスパイにBosch社制BME280を繋ぎ、Pythonを使用してデータを取得しています。同じくPythonを使用してIoT Coreへデータを飛ばしています。
ほぼ[公式のQuickStart](https://cloud.google.com/iot/docs/quickstart)と同じ手順で実装しました。

IoT Core自体は単なるデバイスの管理ができるサービスなのでデータが飛んできているか否かしか確認することができません。実際に使用するには他のサービスと連携する必要があります。

##IoT CoreからPubsubまで
非常に簡単でした。IoT CoreでPubsubのトピックを指定するだけ。具体的にはIoT Coreの端末レジストリに指定するだけでした。そうすることでデバイスから飛んできたデータをPubsubへ飛ばしてくれます。
IoT CoreはPubsubが前提のサービス、Pubsubがハブの役割をして他のサービスへデータを流していきます。
PubsubからはGoogle Cloud Platformのサービスだけでなく、別のサービスへデータを流すことも可能です。

##PubsubからDataflow経由でBigQueryまで
[Google 提供のテンプレート](https://cloud.google.com/dataflow/docs/templates/provided-templates?hl=ja)を使用して実装しました。DataflowのコンソールにてPubsubのトピック名・BigQueryのテーブル名を入力するだけで実装可能です。送信するデータ形式はJSONで以下のように飛ばすと自動的にBigQueryのカラムに格納されます。

```json
{"COLUMN_NAME":"DATA_VALUE"}
```


##BigQueryからData Studioまで
データソースとしてBigqueryのテーブルを選択し、集計カラム、期間の入ったカラムを指定してレポートを作成するだけで実装可能です。一般的なグラフは既に機能として実装されているので簡単に見せる化することができました。BI系の経験がある方は割とすんなり使うことが可能かと思います。
![イメージ](https://qiita-image-store.s3.amazonaws.com/0/168941/40465e68-665d-758b-2863-57bfd31e2189.png)


#料金
ラズパイからのデータ送信間隔は30秒に1度、約二日半くらい使い続けた
![料金一覧](https://qiita-image-store.s3.amazonaws.com/0/168941/f5bf82d5-93ab-cb8b-d070-a4f1b788f22a.jpeg)


#まとめ・考察
非常に簡単に見える化できました。IoT CoreとData Studioはベータ版ですが機能としては十分に感じました。

が、料金は結構高い印象です。特にDataflowが。
Google提供のテンプレートですとストリーミングの取り込みになるので結構なコンピューティングリソースを使ってしまいます。
今回のようにデバイスが少ないしリアルタイムなデータを必要としない場合は無駄にリソースを消費していることになります。
Pubsubにデータが飛んできた場合にDataflowを起動するような仕組みや、定期的に起動する仕組みを用意すれば的確にリソースを使用することができそうです。工夫の余地はあります。