OmniAICreator/Qiita-1.07M huggingface dataset:
Vue.js + GoogleMapで地名検索を実装する

# GameWith Advent Calendar 2018

この記事は[GameWith Advent Calendar 2018](https://qiita.com/advent-calendar/2018/gamewith) の3日目になります！

# はじめに

GoogleMapで地名を入力して検索をすると、ピンが立って緯度経度を取得するのをVue.jsを利用し実装しました。

![スクリーンショット 2018-12-01 14.59.46.png](https://qiita-image-store.s3.amazonaws.com/0/81308/df982a51-abbd-af56-66fd-f758e5e58fe3.png)

[こちら](https://www.holy-place-photo.com/photos/create)から挙動を試せます。

# 前提

- Vue version 2.5.7
- Google Maps Apiの登録済み

# 実装

## HTML

地名を入力するためにinputタグと、検索のトリガーになるbuttonタグとGoogleMap用のdivタグです。

```html
<input type="text" v-model="address">
<button type="button" @click="mapSearch">検索</button>
<div id="map"></div>
```

## JavaScript

地名検索は[Geocoding](https://developers.google.com/maps/documentation/geocoding/intro)を利用します。

`google.map.Geocoder()`で`Geocoder Object`を作成し、`geocode()`で検索します。

`geocode`の第一引数には入力された地名を渡します。

渡せる引数は下記オブジェクトで、緯度経度なども渡せます。

```
{
 address: string,
 location: LatLng,
 placeId: string,
 bounds: LatLngBounds,
 componentRestrictions: GeocoderComponentRestrictions,
 region: string
}
```

検索処理が終わると第二引数の関数が実行されます。

`results`に渡るのは下記オブジェクトで、地名などが緯度経度から逆引きで取得ができます。

`results[0].geometry.location`をマーカーオブジェクトに渡すことでピンを立てることができます。

```
results[]: {
 types[]: string,
 formatted_address: string,
 address_components[]: {
   short_name: string,
   long_name: string,
   postcode_localities[]: string,
   types[]: string
 },
 partial_match: boolean,
 place_id: string,
 postcode_localities[]: string,
 geometry: {
   location: LatLng,
   location_type: GeocoderLocationType
   viewport: LatLngBounds,
   bounds: LatLngBounds
 }
}
```
![スクリーンショット 2018-12-01 15.36.38.png](https://qiita-image-store.s3.amazonaws.com/0/81308/cb6373cb-1fce-6573-415c-bb1ffb9ffed6.png)


その他詳しくは[こちら](https://developers.google.com/maps/documentation/javascript/geocoding)。



```javascript
new Vue({
  el: '#wrapper',
  mounted() {
    this.map = new google.maps.Map(document.getElementById('map'));
    this.geocoder = new google.maps.Geocoder();
  },
  data() {
    return {
      map: {},
      marker: null,
      geocoder: {},
      address: ''
    }
  },
  methods: {
    mapSearch() {
      this.geocoder.geocode({
        'address': this.address
      }, (results, status) => {
        if (status === google.maps.GeocoderStatus.OK) {
          this.map.setCenter(results[0].geometry.location);
          // 緯度経度の取得
          // results[0].geometry.location.lat();
          // results[0].geometry.location.lng();
          this.marker = new google.maps.Marker({
            map: this.map,
            position: results[0].geometry.location
          });
        }
      });
    }
  },
});
```

# 終わりに

地名からの検索が勝手に難しいイメージを持ってましたが、さすがGoogleMap！

IngressやポケGOが流行っていますが、端末の性能があがってきたので地図系のアプリが今後どんどん増えそうですね！
とある小規模チームの取り組みの紹介

この記事は[千 Advent Calendar 2018](https://qiita.com/advent-calendar/2018/sen)の3日目の記事です。


千株式会社ではエンジニア組織の中にいくつかチームがあり、私はその中のアプリチームでリーダーを任されています。
この記事ではアプリチームが行っている取り組みをリーダーの視点で紹介します。

チームが3名と小規模なので、そのようなチームのリーダーの方の参考になれば幸いです。

## 体制と担当

- エンジニア: 3名
- 担当プロダクト: 3つ
    - Electronアプリ: 2つ
    - iOSアプリ: 1つ
- 各エンジニアに1つのプロダクトを任せるようにしていますが、完全に分業せずに必要であればサポートするようにしています。

## 取り組み

### 朝会

- 毎朝、昨日やったことと今日やることの共有を行います
- 合わせて、困っていることとモブ作業したいことの相談も行っています
    - 後述しますが、アプリチームではモブ作業を積極的に行っています
- ファシリテーターは日替わりで交代し、誰かがいない時はやらないという状況にならないようにしています

### チームふりかえり

- 週1回ふりかえりのミーティングを行っています
- ミーティングでは以下の内容を話し合います
    - 直近の大きなリリースの認識合わせ
    - チームKPIの確認(月1回)
    - 今週リリースした内容の共有
    - その他に相談したいトピックス
    - KPTによるふりかえりと今週取り組むkaizenタスク
- 相談したいトピックスが多い場合にふりかえりの時間が取れないことがありますが、その場合別の時間を取っています

### 1on1

- リーダーとメンバーで1on1を実施しています
- リーダーは日々、1on1で話したい内容をメモしています
- 初めは月1回1時間で行っていましたが、現在は週1回30分で行っています
- 月1回だと話したい内容を話すタイミングが最大で1ヶ月空いてしまい、思い出すのに時間がかかったり、適切ではないと感じ、頻度を週1回にしました

### メンバーのリーダー評価

- 先月からメンバーのリーダー評価をはじめました
- [一緒に働いているチームメンバーに評価してもらう](http://blog.h13i32maru.jp/entry/2018/01/09/085813) を参考にGoogleスプレッドシートに評価項目を用意し、期待値と評価値を記載してもらっています
- まだ1回しか実施していませんが、普段のコミュニケーションからは得られない情報が得られました
- なお、評価には1~2時間かかっていると聞いています

### （なんちゃって）スクラム

- 担当しているプロダクトのうちの1つでスクラムを実施しています
- スクラムは以下のように行っています
    - 1スプリント1週間
    - スプリント開始時にスプリントプランニングを実施
    - スプリントプランニングでは1週間で取り組むISSUEを決める
    - スプリント終了時にスプリントレビューとレトロスペクティブを実施
    - スプリントレビューとレトロスペクティブでは、スプリントの実績と、プランニングで決めた予定との差異をもとに原因を考え、次のスプリントに活かしていきます
- メンバーから「スケジュールを守れるようになりたい」という意見が上がったのですが、アプリチームの開発では締切がある仕事が多くありません
- そこで、スクラムを導入してスプリントのスケジュールを守れるようになっていければ良いなと考え導入しました

### 困ってること教えてBOT

- チームのSlackチャンネルで `もうお手上げです。あなたが困っていることも教えて下さい。` などと1時間に1度投稿するBotを運用しています
- 1人で困っている時にこの投稿に返信し、それを他のメンバーが見つけ、サポートする運用が行われています
- 分報の文化も少しあったのですがあまり使われておらず、このBotもあまり使われないのではないかと懸念していましたが、結構投稿されていて適度にサポートできるようになったと感じています

### モブ作業

- モブ作業とはモブプロをプログラミング以外の作業にも拡張したものです
- 前述した通り朝会でモブ作業をしたいものを確認し、必要に応じて行っています
- 具体的には、以下の状況でモブ作業を実施しました
    - アプリの不具合が見つかり急いで対応する必要があった作業
    - 修正が難しく、規模が大きくなりそうな作業
    - 開発歴が浅く実装に時間がかかりそうな作業
- モブ作業の詳細は別の記事で書こうと思います

### ランチ

- 少なくとも週に1回は必ずメンバー揃ってランチに行くようにしています

## 最後に

現在のアプリチームではこのような取り組みを行っていますが、状況によって必要な仕組みは変わっていきますし、もっとメンバーが良いと思えるチームにしていきたいと考えています。
11. M5StackでPhilips hueコントローラを作る

下記にサンプルとともにおいてあります。

https://github.com/Hiroshi-Sugimura/M5_hueSwitch

# どんなもの？

このプログラムはPhilips hueをM5StackでON，OFFできます。
ここでは簡単に使い方を紹介します。

**なお，「Philips Hue Dimmer スイッチ」のほうが高機能で，M5Stackよりも安いです。**

- Philips Hue Dimmer スイッチ: 3500円くらい
- M5Stack: 6000円くらい

「じゃあDimmerスイッチ買えばいいじゃん！」ということではなく，ここから先のさらなる連携をするためのパーツとして使っていきましょう。

# 環境・準備

必要に応じてWiFiルータやコントローラ用のPCなども必要です。

- M5Stack
- 開発用ArduinoIDEの動作するPC
 - M5stackを開発できるようにしてあること


# hueブリッジの設定（PCの設定）

- https://discovery.meethue.com/ を開く

例えば下記の情報を手に入れたとする。

```
[
{
id: "001788fffe193883",
internalipaddress: "192.168.2.192"
}
]
```

- このIPを利用して，下記のURLにとぶ。

```
http://192.168.2.192/debug/clip.html
```

- hueブリッジのLink button（物理）を押す。

- すかさず，デバイスタイプを設定する。

```
/api
{"devicetype": "hogehoge"}
[POST]
```

- usernameが手に入る。

```
username = b6wyKuDg-2EhuAG2l25HRO0Sd2yUnxXR-8wTnpbF
```

- これを使ってhueをコントロールできる。たとえばライト1をONするには下記を実行する。

```
/api/b6wyKuDg-2EhuAG2l25HRO0Sd2yUnxXR-8wTnpbF/lights/1/state
{"on":false}
[PUTS]
```


# サンプルの実行手順

簡単ステップで実行できます。

- 下記のURL（Github）からソースをZIPでダウンロードします。
 - https://github.com/Hiroshi-Sugimura/M5_hueSwitch

- 下記の5行目から8行目の定義を自分の環境に書き換えます。

```C++:M5_hueSwitch.ino
5 | #define WIFI_SSID "your wifi ssid"
6 | #define WIFI_PASS "your wifi pass"
7 | #define HUE_IP    "hue bridge IP address"
8 | #define HUE_USENAME "hue username e.g. AjE6JULce16fMDbVrjiGJrt8pYOL6SMCMDlqDFyb"
```

- 実行します。

- ArduinoIDEのシリアルモニタにIPアドレスなどのログが表示されればOK!
Androidで現在のスレッドがUIスレッドか調べる方法

Realmのトランザクションを使っていたところ、書き込み操作はスレッドをブロックするからUIスレッドから呼ぶ時はexecuteTransactionAsyncを使ってねと書いてありました。
わかりやすい部分なら良いのですが外部ライブラリに依存している部分のコールバック内など、ブラックボックス化されているところでUIスレッドか否かを調べる方法が必要でした。
以下のようにUIスレッドか知らべることができます。

```
val isUiThread = Thread.currentThread() == Looper.getMainLooper().thread
info { "IS_UI_TREAD: $isUiThread" }
```
jsx-no-lambda を recompose で回避

# 背景

tslint などには `jsx-no-lambda` というルールがある。
これは、 React の `render` 内で lambda 関数を作成すると、処理によってはメモリを消費して重くなるため、良くないとされているため。


```tsx
// NG
const Component = ({ onChange }) => (
  <input onChange={e => onChange(e.target.value)} />
)

export default Component
```

# 回避方法

Lint を黙らせるだけなら

```tsx
// 回避できてない？
const Component = ({ onChange }) => {
  const _onChange = e => onChange(e.target.value)

  return <input onChange={_onChange} />
}

export default Component
```

で良いが、 re-render の度に関数を作成している点では同じでは？と思ってしまう。

# recompose を使って回避

TypeScript の型定義など含めると、記述量が多くなってしまうが、 recompose を使って回避するのが良いかなと思った。

```typescript
import { withHandlers } from 'recompose'

const Component = ({ _onChange }: Props) => (
  <input onChange={_onChange} />
)

export default withHandlers({
  _onChange: ({ onChange }) => e => onChange(e.target.value),
})(Component)
```

一度定義した関数 ( `_onChange` ) を使いまわしているので、何回 `render` してもメモリ消費量は増えない・・・はず？
CSSができなくても安心！elm-uiで簡単レイアウト！

[elm-ui](https://package.elm-lang.org/packages/mdgriffith/elm-ui/latest/)


- [CSSができなくても安心！elm-uiで簡単レイアウト！](https://qiita.com/miyamo_madoka/items/e29a97102df8770a6375)
- [もう上下左右中央揃えでググらない！elm-uiで簡単レイアウト！](https://qiita.com/miyamo_madoka/items/c423af7b8c4b0f9dc200)
- [要素の検証はもういらない！？elm-uiで簡単UIデバッグ！](https://qiita.com/miyamo_madoka/items/9700a4994daa95934d39)


# 「CSSﾜｶﾝﾅｲ...」「CSSフレームワークでうまくレイアウトできない...」

CSSわかんないですか？CSSフレームワーク使ってみても結局思い通りにレイアウトできなくて辛くないですか？どうですか？

[elm-ui](https://package.elm-lang.org/packages/mdgriffith/elm-ui/latest/)はそんなあなたの救世主、次世代レイアウトシステムです（誇大広告です、適当に言ってます）

AltJS的にJSはバイトコードみたいなもので直接触るものじゃないはずです。elm-uiでは[CSSをバイトコード](https://www.infoq.com/presentations/css-bytecode)として扱うことができます。他人の作った抽象にのっかろう

# 「そのなんとかuiで何ができるの？」

レイアウトできるよ

とりあえず[楽天のこのページ](https://static.id.rakuten.co.jp/static/about_security/jpn/)を見てきてくれ。適当なところで要素の検証をしてdomを覗いてもらえばclassが
`hc bg-247-247-247-255 p-10-22 spacing-10-10 tc s c wf ct cl`
こんな感じで書かれているのが分かると思います。
またstyleタグがちょくちょく書かれています

あと拙作だけど[Biblipola](https://miyamoen.github.io/bibliopola/)もelm-uiだし、[Elm 2048](https://miyamoen.github.io/elm-2048/public/)もelm-uiで作ってます

# 使い心地

一種のCSSフレームワークだと思ってもらっていいかなと思います。`el`, `column`, `row`というレイアウトが組み込まれた基本要素でhtmlを組み立てていきます。
また、styling(要素の装飾、背景色とかボーダーとか)はelm-uiで用意されたものを付けてくことになります

### 「え、じゃあelm-uiで用意されてなかったら？」

自分でcss書け

とはいえレイアウトは全部やってくれるので、そんなに難しいことはないと思います。
Elm 2048だとアニメーションだけ[css](https://github.com/miyamoen/elm-2048/blob/master/public/style.css)で書いてます
あと思いつくのはグラデーションとかですかね。

# まとめ

elm-uiいいぞ

今回はこれくらいにしといて次回（未定です）からelm-uiでどうレイアウトできるか、使い方などを記事にしていこうと思います（未定です）

でも普通にドキュメント読めばいいと思うよ。英語だけど

- [CSSができなくても安心！elm-uiで簡単レイアウト！](https://qiita.com/miyamo_madoka/items/e29a97102df8770a6375)
- [もう上下左右中央揃えでググらない！elm-uiで簡単レイアウト！](https://qiita.com/miyamo_madoka/items/c423af7b8c4b0f9dc200)
- [要素の検証はもういらない！？elm-uiで簡単UIデバッグ！](https://qiita.com/miyamo_madoka/items/9700a4994daa95934d39)
SICP読書録 #18 2.1.2 抽象化の壁-練習問題 2.3

[hiroshi-manabe様の日本語訳](https://github.com/hiroshi-manabe/sicp-pdf)を使わせてもらいます。
練習問題等は[Gauche](http://practical-scheme.net/gauche/index-j.html)で実行。

[前回はこちら](https://qiita.com/shuetsu@github/items/110770aed6d769c61da9)

## 2.1.2 抽象化の壁

前回、有理数を扱うための手続き群を作成したことで、有理数を扱うプログラムと、有理数の実装とを**抽象化の壁**で隔てることができた。

例えば`numer`や`denom`が呼ばれてから有理数を簡約にしたほうがいいじゃないかと思い立って、以下のように書き換えたとしても・・・

``` _.scm
(define (make-rat n d) (cons n d))
(define (numer x)
  (let ((g (gcd (car x) (cdr x))))
    (/ (car x) g)))
(define (denom x)
  (let ((g (gcd (car x) (cdr x))))
    (/ (cdr x) g)))
```

これを使ってたプログラムは変更しなくてすむのだ。

### 練習問題 2.2

平面上の線分を表現できるようにしてみよう。線分は始点と終点という点のペアで表現する。

まずは点を表現できなくてはいけないだろう。コンストラクタとXY座標のセレクタ、そして表示を行う手続きを作る。

``` _.scm
(define (make-point x y)
  (cons x y))
(define (x-point p)
  (car p))
(define (y-point p)
  (cdr p))
(define (print-point p)
  (print "(" (x-point p) "," (y-point p) ")"))
```

これで、線分のコンストラクタ、始点と終点のセレクタを作れる。

``` _.scm
(define (make-segment s e)
  (cons s e))
(define (start-segment sg)
  (car sg))
(define (end-segmeint sg)
  (cdr sg))
```

では、線分の中点を返す手続きを作ろう。

``` _.scm
(define (midpoint-segment sg)
  (define (average a b) (/ (+ a b) 2))
  (let ((s (start-segment sg))
        (e (end-segment sg)))
    (make-point (average (x-point s) (x-point e))
                (average (y-point s) (y-point e)))))
```

実行結果。

```_.scm
gosh> (define sg (make-segment (make-point 10 20) (make-point 110 120)))
gosh> (print-point (midpoint-segment sg))
(60,70)
```

### 練習問題 2.3

線分が表現できたら、次は長方形を表現してみよう。

先ほど作成した、点を表現するための手続き群を用いて、始点と終点のペアを保持することで表現する。

```_.scm
(define (make-rectangle p1 p2)
  (cons p1 p2))
(define (width-rectangle r)
  (abs (- (x-point (car r)) (x-point (cdr r)))))
(define (height-rectangle r)
  (abs (- (y-point (car r)) (y-point (cdr r)))))
```

周囲長と面積を計算する手続きを用意する。

```_.scm
(define (perimeter-rectangle r)
  (* 2 (+ (width-rectangle r) (height-rectangle r))))
(define (area-rectangle r)
  (* (width-rectangle r) (height-rectangle r)))
```

実行結果。

```_.scm
gosh> (define r (make-rectangle (make-point 10 10) (make-point 110 210)))
gosh> (width-rectangle r)
100
gosh> (height-rectangle r)
200
gosh> (perimeter-rectangle r)
600
gosh> (area-rectangle r)
20000
```

さて、内部表現を始点と終点ではなく、幅と高さのペアとするように修正してみよう。

```_.scm
(define (make-rectangle p1 p2)
  (cons (abs (- (x-point p1) (x-point p2)))
        (abs (- (y-point p1) (y-point p2)))))
(define (width-rectangle r)
  (car r))
(define (height-rectangle r)
  (cdr r))
```

こちらのバージョンでも、先ほどの周囲長と面積を求める手続きは修正の必要なく、そのまま使える。
プログラミングを勉強して改めて理解したこと

一週間ほど、プログラミングの勉強を行って改めて理解したことを書いていきます。

#　・はじめに
僕は元々、春頃にPythonの勉強を一通り行っており、プログラミングについての知識はある程度はあるつもりでした。
しかし僕の勉強法が悪く、Pythonを勉強しても「次はどうすれば良いのだろう...?」と途方に暮れ、しばらくプログラミングの独学から身を引いてしまいました。
今にして思えば、春から継続的に続けるとポートフォリオの一つや二つはなんとか作れていたのではないかなと後悔しています。

##　・ここから始まるプログラミング
HTML&CSSの勉強をするにあたって分かったことは、「ああ、これは覚えようとしたらダメだな」ということが直感できたことです。
プロのSEやプログラマでも、日々調べまくっているということを実感。
pやh1などならまだしも、擬似クラスなど覚えようとしても覚えきれないものが多々あります。
しかもプログラミング言語は日進月歩でアップデート、アップグレードを続けており、半年前は使えていたクラスやコマンドが、使えないということがざらにあります。
ですから、プログラムを組むときは「ここをこうすれば、ここがこうなってああなる」といったふうに、論理的思考をもってあたる、ということが肝要だと分かりました。

###・おわりに
プログラミングをしていた経験があるとはいえ、業務レベルにはまだまだほど遠いレベルです。
将来の目標や、自分の現状の打破の鍵となるプログラミング。
モチベーションは十分にあるので、実力がそこに伴うように頑張っていこうと思います。
Windows環境以外でPowerShellを使ってみよう

Ateam Lifestyle x cyma Advent Calendar 2018の4日目は、株式会社エイチームライフスタイルのエンジニア@matsu06が担当します。

突然ですが、皆さんターミナルで作業する際にはどのようなシェルをお使いでしょうか？
最近はfishを使用する方が多いようですね。
今回は、Microsoft謹製のオープンソースのシェルであるPowerShellについて、ご紹介させていただきたいと思います。

# 対象
- これまでbash等のシェルを使用しており、Macや、Linuxを使うにしても、PowerShellはWindowsサーバを管理するような場合以外、特にメリットはないと思っている方

# PowerShellとは
## 歴史
PowerShellは、マイクロソフトが開発したシェルおよびスクリプト言語であり、**オブジェクト指向に基づいて設計**されています。
.NET Frameworkと.NET Coreを基盤としており、2018年1月からは、PowerShell Core 6.0として、クロスプラットフォーム版がリリースされています。
各OSでのインストール方法については、[公式サイト](https://docs.microsoft.com/ja-jp/powershell/scripting/setup/installing-powershell?view=powershell-6)にまとまっているため、ご参考にしてください。

## コマンドレット
PowerShellで実行されるコマンドは、**コマンドレット**と言われています。
そして、コマンドレットには覚えやすいように*動詞-名詞形式の命名規則*がされています。
例えば、ディレクトリを移動するためのコママンドレットは、

```powershell
Set-Location ./hoge
```
のようになっています。
しかし、これでは長いですし、他シェルの経験者ならば、```cd```コマンドが使いたいと思われると思います。
そこで、デフォルトでいくつかのエイリアスが設定されており、```cd```コマンドもエイリアスに登録されていますし、エイリアスを新たに追加するコマンドレットも用意されています(```Get-Alias```)。
コマンドレットの一覧については[公式サイト](https://docs.microsoft.com/ja-jp/powershell/scripting/powershell-scripting?view=powershell-6)にあるので、見てみるのもいいかもしれません。

# オブジェクト指向
PowerShellは、他のシェル同様、パイプで繋いで複雑な処理を簡単にできます。
しかし、他と大きな違いがあり、それは*パイプで渡すのはオブジェクトである*ということです。

例えば、下記のようなCSVファイルのスコアの合計や平均、最大、最小を知りたい場合、どのようにすればよいでしょうか？(~~スプレッドシートを使うのが楽そうですが~~)

```csv:score.csv
team,score
a,45
b,65
c,55
```

bashの場合は、下記のようになると思います。

```bash:合計
$ cat ./score.csv | awk -F "," 'NR>1{sum+=$2} END{print sum;}'
165
```
```bash:平均
$ cat ./score.csv | awk -F "," 'NR>1{sum+=$2} END{print sum/(NR-1);}'
55
```
```bash:最大
$ cat ./score.csv | awk -F "," 'NR>1{if(max<$2) max=$2} END{print max;}'
65
```
```bash:最小
$ cat ./score.csv | awk -F "," 'NR>1BEGIN{min=100}{if(min>$2) min=$2} END{print min;}'
45
```
詳細は省略しますが、読みづらかったり、書きづらいと思ったことはないでしょうか？
これは、従来のシェルがテキストベースで設計されており、パイプで渡すものがテキストであるためことに起因していると考えられます。
同じ処理でも、オブジェクト指向であるPowerShellでは、下記のようになります。

```powershell:集計
PS> Import-Csv ./score.csv | Measure-Object -sum -average -maximum -minimum score

Count             : 3
Average           : 55
Sum               : 165
Maximum           : 65
Minimum           : 45
StandardDeviation :
Property          : score
```
従来のものに比べて、わかりやすくはないでしょうか？
簡単に説明いたしますと、まず、```Import-Csv```というコマンドレットでCSVを読み込み、オブジェクトを生成します。
そのCSVオブジェクトを、パイプで集計用コマンドレットである```Measure-Object```に渡し、オプションで```-sum -average -maximum -minimum```を指定しています。そして、渡したオブジェクトの集計したいプロパティ(今回の場合はCSVオブジェクトのscore)を引数にする、ということを行っています。
これまでのテキストベースのシェルでは、どうしてもawk等用いて、文字列として扱わなければならなかったものが、オブジェクト指向になったことで、大変わかりやすく表現できるようになっていると思います。

# まとめ
PowerShellは、オブジェクト指向を取り入れることで、これまでのシェルに比べて、書きやすく、読みやすいものになっていると思います。
実績が少なく、これまでの資産もあるため、業務に取り入れるのはハードルが高いかもしれませんが、息抜きに触ってみるといろいろ発見があり、楽しいかもしれませんですよ。

---

Ateam Lifestyle x cyma Advent Calendar 2018、明日は凄腕マネージャーの @gonjyu121 に書いてもらう予定です。ぜひお楽しみに！

エイチームグループでは、一緒に働けるチャレンジ精神旺盛な仲間を募集しています。興味を持たれた方はぜひエイチームグループ採用サイトを御覧ください。
https://www.a-tm.co.jp/recruit/
C++ Builder XE4 | Tokyo > IDEインサイト使用前と後の作業効率 > フォームデザイン時の作業効率の向上

```txt:動作環境
C++ Builder XE4
RAD Studio 10.2 Tokyo Update 3
```

## IDEインサイト使ってますか?

C++ Builder XE4やTokyoなどにある「IDEインサイト (IDE Insight search box )」という機能。

これを使う使わないで作業効率は大幅に変わります。


## 例: フォームデザインでプロパティ変更をする手順 (例: Name)

Note: 下記動作例は「C++ Builder XE4」での例ですが、「Tokyo」でも同様の動作になると思われます。

### 暗黒の時代1 (IDEインサイトに気づかなかった時代 > 全てのプロパティリストから探査) > 2016年以前

下記手順で実施する。

1. フォームデザイナ上の任意のコンポーネントをクリック : 定数時間
2. プロパティリストから該当プロパティを探す : 不確定時間

**「スクロール」という旧時代のUIを使うことになります** (例: 平安絵巻)。

### 暗黒の時代2 (IDEインサイトに気づかなかった時代 > カテゴリでなんとかしようとした) > 2018年4月19日以前

「オブジェクトインスペクタの「表示する項目」を指定すれば作業効率があがるかも」
そんなふうに考えていた時期が俺にもありました

1. オブジェクトインスペクタにて「表示する項目」を選択 : 不確定時間
    - 「その他」にする
    - カテゴリが不明の時は「不確定時間」、記憶している時は「定数時間」
2. フォームデザイナ上の任意のコンポーネントをクリック : 定数時間
3. プロパティリストから該当プロパティを探す : ほぼ定数時間 (閲覧数が少ない)
4. オブジェクトインスペクタにて「表示する項目」を元に戻す : 定数時間

Note1: `Nameプロパティは「その他」に含まれる`という知識はRadStudioユーザなら当然持っていますね？

下記のPythonコードに記載のように「全てのプロパティがどのカテゴリに属するか覚え続ける」のは面倒ですね。

```python
for item in getAllProperties():
    print(item + "プロパティは「XXX」に含まれる`という知識はRadStudioユーザなら当然持っていますね？")
```

### 豊穣の時代 (IDEインサイトに気づいた後) > 2018年4月19日以降

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f33323837302f32343437343134362d326264362d393033322d366132322d3433646462623663663830342e706e67.png](https://qiita-image-store.s3.amazonaws.com/0/32870/76162243-49e9-54b1-ada6-cc0fb3d9c908.png)

画像は[C++ Builder XE4 > IDE > IDE Insight search box > TButtonのNameプロパティ(@オブジェクトインスペクタ)にジャンプ](https://qiita.com/7of9/items/8dd5986e4d0ffa4a2b4e)より再掲。

1. オブジェクトインスペクタの「プロパティ」クリック (*1) : 定数時間
    - *1) 「イベント」になっていると、別のところに飛んでいくので注意
2. フォームデザイナ上の任意のコンポーネントをクリック : 定数時間
3. F6 (または<kbd>Ctrl</kbd> + <kbd>.</kbd>) : 定数時間
4. Nameと入力 : 定数時間
    - NameがIDEインサイトでNameが表示される 
        - 前方一致検索のようなので、`Nam`でもリスト表示される
5. Enter入力 : 定数時間


**こちらの操作を行うようになってから、生産性は格段に上がりました。**


### 探すということやめましょう

セネカ「人生の短さについて」
http://www.qmss.jp/interss/03/materials/senvita.htm

> しかし、われわれは短い時間をもっているのではなく、実はその多くを浪費しているのである。

探すのやめませんか？（提案)

### 関連

下記と組合わせると、さらに効率が上がります。

- [C++ Builder XE4 > ショートカットキー > Tool paletteへフォーカスを移す (IDE Insight search boxと組合せて使う) > Ctrl+Alt+P](https://qiita.com/7of9/items/0e22c9ecb2e6c7bc0430)
- [C++ Builder XE4 > IDE Insight search box > TLabel, TEditのCaption, Text編集 > Capで検索すればいい](https://qiita.com/7of9/items/c2fc8dfe42d5e3818d26)


### その他

Embarcadero提供のヘルプのどこかには「IDEインサイト (IDE Insight search box )」が記載しているはず。
**探した**ところ、下記で見つけた。
[操作手順：IDE を使用する](http://docwiki.embarcadero.com/RADStudio/Tokyo/ja/%E6%93%8D%E4%BD%9C%E6%89%8B%E9%A0%86%EF%BC%9AIDE_%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B)
の
[［IDE インサイト］を使用して項目を検索する](http://docwiki.embarcadero.com/RADStudio/Tokyo/ja/%EF%BC%BBIDE_%E3%82%A4%E3%83%B3%E3%82%B5%E3%82%A4%E3%83%88%EF%BC%BD%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%A6_IDE_%E5%86%85%E3%81%A7%E9%A0%85%E7%9B%AE%E3%82%92%E6%A4%9C%E7%B4%A2%E3%81%99%E3%82%8B)

ヘルプには確かに記載はあるが、何故かその記載が目に留まってなかった。
文字だけの記載でなく画像付きの使用例があると、興味を引いていたかもしれませんね。

> F6 キーまたは Ctrl+.（ピリオド）を押します。

<kbd>Ctrl</kbd> + <kbd>.</kbd>でも可能ということを記事を作成中に知りました。
(Tokyoのヘルプですが、XE4でも有効でした）。
仕事する時の必需品

#はじめに
19日目担当の@somu4です。
IDをみて推測される通り総務部に所属しています。
むかーしむかしは開発なんぞもしていました。

そんなちょっと技術をかじった私が総務に移動してびっくりしたことを書いてみます。

#総務部の必需品
技術者の皆さんのPC以外の必需品はなんでしょう？
私の個人的なイメージでは技術者の必需品は、タバコ:smoking:とコーヒー:coffee:とジャンクフード:hamburger:。


私の総務部での必需品は、**指サック**、**ゴム印**、**シャープペン**です。
シャープペンは使ったことがある人は一杯いると思いますが、
指サック、ゴム印は使ったことない人が多いのでは？
では、これらがなぜ総務部の必需品なのかというと・・・・

#どこもかしかも紙だらけ～

あれも紙、これも紙、たぶん紙、きっと紙。
総務部は紙であふれかえっているのです。
なので、上記が必需品になります。

技術者の皆さんは仕事で紙に触れる機会は減ってますよね？？
もしかしたら、今日一日紙を使わなかった、という人もいるのでは？
ではなぜ総務部は紙に溢れているのか？

#提出物が紙！！
行政に提出する資料(e-Govは未対応)も社員から提出してもらう申請書も紙なのです:cry:

行政に提出する資料は本番の紙に記載して間違ったらもう大変。
ダウンロードできない用紙もあるのです。
なので、まずはシャープペンで下書きします。

そして、そういう提出物には必ず会社名/住所/代表者名などなどを記載する箇所があるのですが、
そこに**効率化**という事でゴム印が登場します。
皆様ゴム印使ったことありますか？私はありませんでした。
このゴム印が慣れないとなかなか難しい。
まず曲がる、なぜか手にインクがつく、手が汚れるから紙も汚れる悪循環。

異動して間もないころはボス(上司)に「手真っ黒ね、ぷぷぷぷぷ:joy:」と笑われてました。
いまでは、きっちり、すっきり押せますけどね:v:

最後に指サック。皆さん指サックわかりますか？メリケンサックじゃないですよ。
指にはめるゴム製の袋、紙をめくるときの滑り止めに用いるアレです。
総務部に異動して人生で初めて使いました。
指サックつけるのとつけないのとでは滑りが違う。
指ペロして紙めくる人に断然おすすめです・・:nerd:

#さいごに
私の必需品は紙がベースの仕事だからこそ。
来年度の目標はe-Gov導入して、基幹システム導入してどんどん紙をなくしていって、
脱指サック、ゴム印、シャーペンをめざします！

![1218953.jpg](https://qiita-image-store.s3.amazonaws.com/0/317706/e75ba6e4-47fd-b9b0-c049-7738794e6f73.jpeg)

紙はなくしても髪はなくしません。

さて、本日の記事は箸休め。
明日からは皆様の為になる、かっこよい記事になっていますので、乞うご期待！
最強の勉強法「Retrieval Practice」によるPandasの学習(随時更新)

## はじめに
最も効率が良いと言われる最強の勉強法
それが**Retrieval Practice**です

**Retrieval Practice**とは検索練習と呼ばれており、覚える事に重点を置くのではなく**思い出す事**に重点を置いた学習法です
その手段はフラッシュカード・・・つまり**単語帳**です！

ところで単語帳を作るのは手間がかかりますよね・・・
しかし今の時代は単語帳アプリを使えば簡単に作ったり、どこでもすぐに使ったりで便利になっています
スマホがあればお手軽にいつでもどこでも(通勤電車でもお布団の中でも孤独な飲み会中でも)**Retrieval Practice**ができます！

## 説明

利用するアプリは下記になります
[Quizlet](https://quizlet.com/ja)

サイトの登録が必要ですが、CSVやTSVファイルをデータとしてインポートできるのが選定した理由になります

単語帳に登録する内容は自分のqiitaの記事を利用しました

pandasとエクセルの対応表(随時更新)
https://qiita.com/lunar_sword3/items/f68d9af0f426ccc49817

インポートに使ったTSVファイルが下記になります
https://github.com/lnsw/pandas-tangocho
(csvだと"や,をquizletがうまく認識してくれないのでTSVにしましたが、インデントまで使うならば区切りをカスタムで;とかにするほうがいいかもしれません)

それで作ったのが下記です
https://quizlet.com/343062912/pandas%E3%81%AE%E5%9F%BA%E6%9C%AC-flash-cards/

やり方は単語カードの表を見て裏に書かれている事を**思い出す**
それだけです
とにかく**思い出してください**！

※quizletだと「筆記」もあるので、そちらでもいいかもしれません
※ちなみに単語カードは自分で作ると更に効果があるそうです


## おわりに
実は"最強の学習法「Retrieval Practice」"とうたいましたが本当かどうかはわかりません！:bow_tone1:

ところで「Pandasが使える」というのはどういう事でしょうか？
Pandasで意図した処理をやりたい時に、該当の処理を**思い出せている**ことではないでしょうか？
それならば、覚えることより**思い出す**ことに重点を置いたほうがよいと私は考えます

あと下記より、私がフォローしている脳科学者の池谷裕二さんがおっしゃっているので、きっとそうなんだと信じています

>記憶力を鍛えるのは入力じゃなくて出力です
>池谷裕二（脳科学者）×出口治明（ライフネット生命会長）［第3回］
>http://wedge.ismedia.jp/articles/-/9640

>>池谷：でも、これまでにいかなる勉強法よりもリトリーバルトレーニングが一番点数が高いというのが証明されています。
>>出口：思い出す訓練を一所懸命するんですね。

wikipediaにも「テスト効果」という項目で載っています
https://ja.wikipedia.org/wiki/%E3%83%86%E3%82%B9%E3%83%88%E5%8A%B9%E6%9E%9C


## あとがき
「最強の勉強法「Retrieval Practice」によるPythonの学習」てのを誰か作ってください:pray_tone2:
Spaced Practice のいいアプリも教えてください:pray_tone2:
(ankiはPC版の操作がちょっとわかりづらいです・・・)
[論文メモ] Distributed Representations of Sentences and Documents

# 情報
* [Distributed Representations of Sentences and Documents](https://cs.stanford.edu/~quocle/paragraph_vector.pdf)
* この記事の画像は上記論文からの転載。

# 簡単にまとめると
* doc2vecと呼ばれている手法を提案している(筆者達はParagraph vectorと呼んでいるが)。
* 現在、doc2vecはgensimにも実装されており簡単に使うことができる。
* doc2vecは名前の通りドキュメントのembeddingを得る手法で、word2vecのアルゴリズムを応用している
* アルゴリズムをword2vecとほぼ同じ。inputに常にdocumentのembeddingを入れて単語を予測するようなモデルにしている。

![スクリーンショット 2018-12-03 9.37.05.png](https://qiita-image-store.s3.amazonaws.com/0/199247/14b666cf-7751-e6d7-01a4-ee572a5638a5.png)

* 上記はword2vecのような単語のembeddingを求めるアルゴリズム
* the, cat, satを入力とし、onを予測するようなモデルを作ることによりembeddingを計算している。
* このアイデアを文書に適用したのが下記の図

![スクリーンショット 2018-12-03 9.36.47.png](https://qiita-image-store.s3.amazonaws.com/0/199247/52ce91f6-3689-cdd5-d682-ff5a9c04beea.png)

* the, cat, satの単語のembedding以外にparagraph idのembeddingをインプットに追加している。
PLV8でPostgreSQLのテーブル分割をしてツイートを保存する

# 目的
TwitterのSearchAPIの結果をPostgreSQLに保存します。この時保存するテーブルは1日ごとにテーブル分割を行います。ツイートを保存するコードはplv8で記述しました。

## テーブル分割
PostgreSQL10から入った新しいテーブル分割ですがPostgreSQL11から機能が向上して主キーやインデックスが子テーブルにも反映されるようになりました。ただし分割するキーを主キーにする必要があります。ツイートの場合本来ステータスIDのみが主キーになるはずですが、分割のためにはツイート日時を含める必要があります。

ステータスIDは将来BIGINTの範囲を超えそうなのでNUMERICにしています(BIGINT最大992京に対して現在のステータスIDは106京)。

```sql
CREATE TABLE public.tweets (
  status_twid NUMERIC NOT NULL
  ,tw_created_at TIMESTAMPTZ NOT NULL
  ,data_json JSONB NOT NULL
  ,PRIMARY KEY(status_twid, tw_created_at)
) PARTITION BY RANGE (tw_created_at);
```

## ツイート日時
テーブル名をtweets_20181201のように日付を後ろにつけたいです。日付とフォーマットを与えて文字列を取得する関数を準備しました。

```sql
CREATE OR REPLACE FUNCTION tw_get_data_text_to_ymd (
  p_data TIMESTAMPTZ
  ,p_format TEXT
) RETURNS TEXT AS $FUNCTION$
  return p_format.replace(/yyyy/g, p_data.getUTCFullYear()).
    replace(/MM/g, ('0' + (p_data.getUTCMonth() + 1)).slice(-2)).
    replace(/dd/g, ('0' + p_data.getUTCDate()).slice(-2)).
    replace(/HH/g, ('0' + p_data.getUTCHours()).slice(-2)).
    replace(/mm/g, ('0' + p_data.getUTCMinutes()).slice(-2)).
    replace(/ss/g, ('0' + p_data.getUTCSeconds()).slice(-2)).
    replace(/SSS/g, ('00' + p_data.getUTCMilliseconds()).slice(-3))
$FUNCTION$
LANGUAGE plv8 IMMUTABLE STRICT;
```

## ツイート登録
パラメーターp_jsonはTwitterのSearchAPIのレスポンスそのものが入ります。

子テーブルはあらかじめ用意せずに、とりあえず登録してみてテーブルが無かったらその場で子テーブルを作成するようにしています。エラーコード「23514」はテーブルが存在しなかった時に出るエラーです。このエラーが発生した時にはテーブルを作り再度登録しなおしています。prepare statementのおかげ同じSQLを書かなくて済んでいます。

```sql
CREATE OR REPLACE FUNCTION tw_set_add_tweets (
  p_json JSONB DEFAULT NULL
) RETURNS VOID AS $FUNCTION$
  const statuses = p_json.statuses
  const func = plv8.find_function("tw_get_data_text_to_ymd")
  const insert = plv8.prepare(`
    INSERT INTO public.tweets (
      status_twid
      ,tw_created_at
      ,data_json
    ) VALUES (
      $1
      ,$2
      ,$3
    ) ON CONFLICT (status_twid, tw_created_at)
    DO NOTHING
  `, ['numeric', 'timestamptz', 'jsonb'])
  for (let key in statuses) {
    if (statuses.hasOwnProperty(key)) {
      try {
        insert.execute([statuses[key].id_str, statuses[key].created_at, statuses[key]])
      } catch (error) {
        if (error.sqlerrcode != 23514) {
          throw error
        }
        const tw_created_at = new Date(statuses[key].created_at)
        const ymd = func(tw_created_at, 'yyyyMMdd')
        const from = func(tw_created_at, 'yyyy-MM-dd')
        tw_created_at.setDate(tw_created_at.getDate() + 1)
        const to = func(tw_created_at, 'yyyy-MM-dd')
        plv8.execute(`
          CREATE TABLE IF NOT EXISTS public.tweets_${ymd}
          PARTITION OF public.tweets FOR VALUES 
          FROM ('${from}')
          TO ('${to}')
        `)
        insert.execute([statuses[key].id_str, statuses[key].created_at, statuses[key]])
      }
    }
  }
  insert.free()
$FUNCTION$
LANGUAGE plv8;
```

# まとめ
PLV8を使うことでJSONの取り回しが簡単にできました。レスポンスのほとんどがJSONのTwitterAPIとは相性がよさそうです。

PostgreSQLのテーブル分割で分割キーを主キーに含める必要があるのは、困りものです。今回の例のように主キーでは無いカラムで分割したい要件は色々あると思います。主キーですら論理設計がそのまま使えないのは不便なので将来改善してほしいところです。
Re: シクシク素数アドベントカレンダー Ruby 編

この記事は[Okinawa.rb Advent Calendar 2018](https://qiita.com/advent-calendar/2018/okinawarb)の3日目の記事です。
昨日は @hanachin_ さんの[Re: Ruby で季節のような循環する概念を表したい](https://qiita.com/hanachin_/items/583e7a202667bdf24b7c)でした。
明日は @hanachin_ さんの[TracePointのenable(target: )は戻り値を書き換えるときべんり](https://qiita.com/hanachin_/items/d5e243048900344b2146)です。

シクシク素数のプログラムを見て書きたくなったので書きました
https://qiita.com/tbpgr/items/9f075537b927916f64d5

## 改良版

見ていて改良できそうなので書きました

```rb
require 'prime'

😭prime = Prime.each.lazy.select {|prime|
  digits = prime.digits
  digits.include?(4) || digits.include?(9)
}

puts 😭prime.take(ARGV.first.to_i).to_a.join(",")
```

## ベンチマーク

ちょっと早い

```ruby
require 'benchmark_driver'

Benchmark.driver do |x|
  x.prelude <<~RUBY
    require 'prime'
    😭prime = Enumerator.new do |y|
      a = 1
      loop do
        a += 1
        loop { a.prime? && a.to_s.match(/[49]/) ? break : a += 1 }
        y << a
      end
    end
    😭prime.take(100)
    😭prime2 = Prime.each.lazy.select {|prime|
      digits = prime.digits
      digits.include?(4) || digits.include?(9)
    }
    😭prime2.take(100)
  RUBY
  x.report 'tbpgr', '😭prime.take(100)'
  x.report 'hanachin', '😭prime2.take(100).to_a'
end
```

```console
% ruby -v /tmp/49.rb
ruby 2.5.3p105 (2018-10-18 revision 65156) [x86_64-linux]
Warming up --------------------------------------
               tbpgr     1.871k i/s -      1.880k times in 1.004923s (534.53μs/i)
            hanachin     4.642k i/s -      4.972k times in 1.071051s (215.42μs/i)
Calculating -------------------------------------
               tbpgr     1.958k i/s -      5.612k times in 2.866668s (510.81μs/i)
            hanachin     4.593k i/s -     13.926k times in 3.032325s (217.75μs/i)

Comparison:
            hanachin:      4592.5 i/s
               tbpgr:      1957.7 i/s - 2.35x  slower
```

## 変更点

`Prime.each`を使うとEnumeratorが取れるのでそれをそのまま使いました。
http://rurema.clear-code.com/2.5.0/method/Prime/s/each.html

そのままでは無限に素数を列挙しつづけるので`Enumerable#lazy`を使って遅延評価するようにしました。
http://rurema.clear-code.com/2.5.0/method/Enumerable/i/lazy.html

数値に4か9が含まれているか判定するために`Integer#digits`を利用しています。
http://rurema.clear-code.com/2.5.0/method/Integer/i/digits.html
CO2センサー、空気品質センサーの測定値を比較する


NDIR方式のCO2センサー「MH-Z19B」と「S-300L-V3」、MOXガスセンサー「BME680」と「CCS811」を同じ環境に置いて値を測定し、[IoTデーター可視化サービス「Ambient」](https://ambidata.io)に送信して、比較しました。

![](https://ambidata.io/wp/wp-content/uploads/2018/11/airqualitysensors-768x750.jpg)

NDIR(Non Dispersive Infrared)方式のセンサーはガス分子が特定の波長の光を吸収することを利用して特定のガスの濃度を測定するセンサーです。MH-Z19BとS-300L-V3がこのタイプです。

MOX(Metal Oxide)ガスセンサーは温めたMOX(金属酸化物)が空気中の揮発性有機化合物によって抵抗値が変わることを利用してガス濃度を測定します。ガスの種類は区別できません。BME680とCCS811がこのタイプです。

四つのセンサーの値を比較するために、1台のM5Stackに全部接続してみましたが、突然リセットがかかるなど安定して動きませんでした。ESP32でも試みましたが、同様でした。

各センサーの最大消費電流が次のようだったので、1台のM5StackやESP32では電源電圧が降下し、安定動作しなかったのだと思います。

| センサー | 最大消費電流 |
|:--:|:--:|
| MH-Z19B | 150mA |
| S-300L-V3 | 180mA |
| BME680 | 18mA |
| CCS811 | 30mA |
 

そこで、M5Stackを２台使い、MH-Z19B、BME680、CCS811を1台のM5Stackが、S-300L-V3をもう1台のM5Stackが制御して、同時に測定しました。写真は四つのセンサーが一つのブレッドボードに載っていますが、単に同居しているだけです。５分間隔で4日間データーを測定し、比較しました。

# 「MH-Z19B」と「S-300L-V3」

二つのNDIR方式のCO2センサーの測定値です。絶対値ではS-300L-V3の方が300〜400ppm高い値ですが、同じ傾向を示しています。

![](https://ambidata.io/wp/wp-content/uploads/2018/11/graph1.jpg)

相関は次のようになっており、ほぼ比例関係にあることが確認できます。

![](https://ambidata.io/wp/wp-content/uploads/2018/11/graph2.jpg)

S-300L-V3は電源オンから24時間ごとに自動校正するとのことなので、最後の約24時間のデーターの相関を調べると、ほぼ直線になっています。

![](https://ambidata.io/wp/wp-content/uploads/2018/11/graph3.jpg)

校正によって絶対値は修正されるものの、校正と校正の間はMH-Z19BとS-300L-V3はほぼ比例関係のデーターが得られるようです。

どちらのセンサーも大きく値が変化することがあり、正しい値が測定できているのか不安でしたが、二つのセンサーがほぼ同じ傾向の値を出力することから、絶対値はともかく、正しい傾向のデーターと推測できます。だたし、基準となるデーターがないので、絶対値としてどちらのセンサーの値が正確かは分かりません。

なお、MH-Z19BとS-300L-V3は別のM5Stackで制御し、「[Ambient](https://ambidata.io)」の別々のチャネルにデーターを送信しています。Ambientでは別チャネルのデーター比較ができないので、それぞれのチャネルに保存されたデーターをPythonで読み込み、集計処理しています。

# 「MH-Z19B」と「CCS811のTVOC」

MH-Z19BとCCS811のTVOCの値を比較すると、絶対値は違いますが、似たような傾向で推移しています。

![](https://ambidata.io/wp/wp-content/uploads/2018/11/graph4.jpg)


相関を調べると、それほど強い直線性ではありませんが、プラスの相関はあるようです。MH-Z19BはCO2を測定しているのに対し、CCS811はTVOC(総揮発性有機化合物)を測定しています。違うものを測定しているので、違う値になりますが、個人宅の居間の空気環境で、短時間に変化するのはCO2なので、CO2とプラスの相関になっているものと思われます。

![](http://ambidata.io/wp/wp-content/uploads/2018/11/graph5.jpg)

なお、「[Ambient](https://ambidata.io)」は二つの値の相関を表示することができます。チャート設定でグラフ種類として散布図を選んでください。

# 「CCS811のTVOC」と「CCS811のCO2」

CCS811はTVOC(総揮発性有機化合物)の量とCO2濃度の二つが得られます。この二つを比較しました。ほぼ同じ傾向を示しています。

![](https://ambidata.io/wp/wp-content/uploads/2018/11/graph6.jpg)


相関を見ると、ほぼ直線です。測定値はどちらか一方で、その値を元にもう一方の値に変換して出力しているのではないかと思われます。

![](https://ambidata.io/wp/wp-content/uploads/2018/11/grap7.jpg)

# 「MH-Z19B」と「BME680のガス抵抗値」

BME680はTVOC(総揮発性有機化合物)の量に対応したガス抵抗値という値を出力します。マニュアルによると「空気品質が上がるとガス抵抗値も上がり、空気品質が下がるとガス抵抗値も下がる」と書かれています。CO2などのガス濃度とはマイナスの相関になると思われますが、実際の値はあまり相関がないようです。

![](https://ambidata.io/wp/wp-content/uploads/2018/11/graph8.jpg)
![](https://ambidata.io/wp/wp-content/uploads/2018/11/graph9.jpg)

CCS811のTVOC値とBME680のガス抵抗値を比較しても、あまり相関が見られません。

![](https://ambidata.io/wp/wp-content/uploads/2018/11/graph10.jpg)

BME680の使い方やガス抵抗値の理解が不足しているのかもしれません。

# まとめ

CO2濃度の測定としてはMH-Z19BとS-300L-V3はほぼ同じ傾向のデーターが得られます。基準となるデーターがないので、どちらが正確かは分かりませんが、傾向を見る上ではどちらのセンサーも同様に使えると思われます。

TVOC(総揮発性有機化合物)の測定としてはCCS811の値がMH-Z19BのCO2濃度とプラスの相関があり、それらしい値になっていると思われます。
[macOS]MongoDBのインストールからコンソールに入るまで

##MongoDBのインストール方法
```%brew install mongodb```
で安定版4.0.4がインストールされる

##起動方法
今すぐ起動して、ログイン時に自動で再起動する場合
```%brew services start mongodb```

```Successfully started ‘mongodb’ (label: homebrew.mxcl.mongodb)```
と出たら起動成功

```%mongo ```

でmongodbのインターフェースに入る

##バックグラウンドで起動しない起動方法
バックグラウンドで起動したくない場合は
```%mongod --config /usr/local/etc/mongod.conf```
を入力するとターミナルがサーバを起動した状態になるので、command+tで新しい
ターミナルのタブを開いて, 
```%mongo```
と入力すれば、MongoDBのコンソールに入れる
ESLintエラーの自動修正でデバッグコードが勝手に消されてしまう問題

## :warning: 追記 :warning: 
以下はESLint v5.1.0以前の問題とその対処を記したものです。
v5.1.0以上のバージョンでは `debugger` ステートメントは自動修正されないようになりました。

@mysticatea さんご指摘ありがとうございました :bow: 

## 問題

エディタのプラグインなどで、ESLintエラーの自動修正を有効にしていると、デバッグ時に困ることがあります。

たとえば、 `no-debugger` のルールを有効にすると、コード中に埋め込んだ `debugger` ステートメントが保存時に自動で消されてしまい困るわけです。これではデバッグができません。

とはいえ、 `debugger` の消し忘れをプロダクションに出してしまうリスクがあるので、ルールを削除するわけにはいきません。

## 特定のルールをCI環境でのみ有効にする
そこで、`no-debugger` など、ローカル開発環境では有効にしたくないけど、オフにするわけにはいかないルールはCI環境のみで有効にする方法をオススメします。

そうすれば、デバッグ時に困ることもありませんし、プロダクションにデバッグコードが不用意にデプロイされてしまうことも防げます。


## 環境ごとに特定のルールのon/offを切り替える
環境ごとに特定のルールのon/offを切り替えるには、環境変数を利用できます。

たとえば、このような `.eslintrc` ファイルがあるとします。

```json:.eslintrc
{
    "rules": {
        "no-debugger": "error",
    }
}
```

これを、このように書き換えます。

```js:.eslintrc.js
// 環境変数は文字列として取得されるので注意!!
const ERROR_IN_CI = process.env.CI === "true" ? "error" : "off";

module.exports = {
    rules: {
        "no-debugger": ERROR_IN_CI,
    }
};
```

CIとしてよく使われるCircleCIやTravisCIではデフォルトで `CI` という環境変数に `true` が設定されているので、この値を利用して環境ごとに切り替えることが可能です。

- [CircleCIドキュメント](https://circleci.com/docs/2.0/env-vars/#built-in-environment-variables)
- [TravisCIドキュメント](https://docs.travis-ci.com/user/environment-variables/#default-environment-variables)

その他のCIを使っていて `process.env.CI` で値を取得できない場合は、下のように `npm-scripts` を書いて、環境ごとに呼び分けると良いでしょう。

```json:package.json
{
  "scripts": {
    "eslint:dev": "eslint 'src/**/*.js'",
    "eslint:ci": "CI=true eslint 'src/**/*.js'",
  }
}
```
スクラムガイド・リファレンスカードのサマリ

# はじめに
ガイドをコンパクトにまとめたものが欲しくなったので作ってみた。
だいぶ省略した表現になっているので、この資料を使うときはちゃんと口頭補足する。
※そもそも書いてあることが違うとかの指摘あれば、ぜひお願いします。

# 考え方・ポリシー
ここは省略してはいけないので丁寧に伝える。

個人的な解釈

- [スクラムとは何か？〜Certified ScrumMaster 研修を受けて〜](https://qiita.com/nh321/items/19818f04841474587644)

公式情報

- [アジャイル・マニフェスト](http://agilemanifesto.org/iso/ja/manifesto.html) ：そのまま
- [アジャイル・マニフェストの背後にある原則](http://agilemanifesto.org/iso/ja/principles.html) ：そのまま
- [スクラムガイド(2017)](https://www.scrumguides.org/docs/scrumguide/v2017/2017-Scrum-Guide-Japanese.pdf) ：目的～価値基準くらいまで。
- [スクラムリファレンスカード(v1_3)](http://www.scrumreferencecard.com/ScrumReferenceCard_v1_3_jp.pdf) ：冒頭の「スクラムについて」、後ろの「自己組織化されたチーム」「スクラムが適切な状況とは？」くらい。
- [スクラムマスターチェックリスト](http://scrummasterchecklist.org/) ：スクラムマスター以外にも見てもらえると嬉しい。最新版が近々公開されます。（最新版が公開されたら記事にしようかな。最新版の翻訳を担当したので。）

※追記
良い感じのやつ見つけた。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="en" dir="ltr">I love this Agile Manifesto <a href="https://twitter.com/hashtag/agile?src=hash&amp;ref_src=twsrc%5Etfw">#agile</a> <a href="https://t.co/oidYEuCHFH">pic.twitter.com/oidYEuCHFH</a></p>&mdash; David Marti (@Xsfera) <a href="https://twitter.com/Xsfera/status/1058269514352222208?ref_src=twsrc%5Etfw">2018年11月2日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>



# ロール
Lessのスライドがシンプルでわかりやすい。

![less-role-responsibilities.png](https://qiita-image-store.s3.amazonaws.com/0/214587/5fa14e24-7211-f6d8-8367-e8165eaeb06b.png)

引用元： https://less.works/less/management/role-of-manager.html

※補足的にふんわり翻訳

- Product Owner: プロダクトオーナー
    - ビジョンと方向性を示す
    - PBIの優先順位を決める
    - ユーザーと市場を理解する
    - 組織の戦略的な方向性を支援する
- Developer Team: 開発チーム
    - プロダクトを作る・インクリメントする
    - 自己組織化されている
    - ユーザー、ビジネスドメインなどをチームとして理解する
- Scrum Master: スクラムマスター
    - 組織をコーチングする
    - 継続的な改善を支援する
- Managers: 組織のマネージャー（スクラムの外の役割）
    - システム開発力を向上させる
    - 組織の構造やポリシーを決定する

# ツール
- 改善策を入れるのを忘れがち。
- タスクが消化されてもPBIのゴールに到達してなければ意味がない。
- 見積もりに関しては、「S」か「Sじゃないか」の二択で評価するケースもある。

![scrum_guide_summary_tool.png](https://qiita-image-store.s3.amazonaws.com/0/214587/c81ff3e3-7e5f-65c0-c858-f3b4dd26a0e5.png)


# プロセス
- 時間を守るのは大事。守れないのならちゃんとそれを振り返るべき。
- 何も記載してない時間はSprintBacklogにあるTaskを実施する。

![scrum_guide_summary_process.png](https://qiita-image-store.s3.amazonaws.com/0/214587/59b06b8d-06a6-106a-5996-9edc6b91d7f0.png)

# さいごに

スクラムガイドもリファレンスカードも、読み返すたびに発見があって面白いですね。

以上です
HerokuでNode使っていたらナニモシテナイのに壊れた

linebotづくりでHerokuを使っていた。

## 現象

ある日herokuにpushしたらlinebotが動かなくなった。
`heroku logs --tail`でログを確認すると以下のエラー。

```
internal/modules/cjs/loader.js:582
    throw err;
    ^

Error: Cannot find module 'react-dev-utils/crossSpawn'
...
```

自身のコードを実績あるところまで戻しても同様。ナニモシテナイのに！！

## 原因

`npm install --save-dev "request"`でインストールした`request`モジュールが動かなくなってた。

## 解決

`npm uninstall --save-dev request`
`npm install --save request`

としたら動くようになった。

## 追いログ

herokuのNode.jsトラブルシューティングを見ると、[ヒントになる記事](https://devcenter.heroku.com/articles/troubleshooting-node-deploys#start-with-a-blank-slate)があった。
記事曰く、herokuはpushのたびに以下のコマンドを実施するらしい。

> ```
$ rm -rf node_modules
$ npm install --quiet --production
$ npm start
```

これをローカル環境で実施すると、確かに同じ現象が発生した。
`npm install --quiet --production`
としていて、これだと`devDependencies`(--save-devでインストールしてるほう)のインストールをしてくれないらしい。

## なんである日動かなくなったのか

~~正直謎。~~

~~動作で使うモジュールを`--save-dev`していたのは問題だ。でも最初はそれでも動作していたのに、ある日動かなくなった。~~
~~気づいたのは、ローカルのnodeがversion 8でherokuも同じだったが、herokuのmasterが11月1日にnodeのversion 10に上がってた。（この前後で動く・動かないが変わっていた）~~
~~>Author: Jeremy Morrell <morrell.jeremy@gmail.com>~~
~~>Date:   Thu Nov 1 10:37:28 2018 -0700~~
~~>~~
~~>    Update to the latest LTS version of Node~~

~~これが影響している気もしたのだが、`npm`の`production`オプションは前からある。~~

~~結局**突然動かなくなった原因**はわからなかった。~~
~~ただログから追うことができたので、追い方は分かった。~~

分かった。私のせいだ(当然)。
Herokuのサンプルをそのまま改変して使っていたが、Herokuのサンプルでは`request`が`devDependencies`に入っている。
`npm install`して開発を開始したが、途中`require(request)`する修正を入れた。
ローカル環境では`npm install`してあるのでnode_modules配下に`request`が存在するから何もせず使えていたが、リモート環境は`npm install --quiet --production`でやるから`request`がなくエラーになっていた。
XDオートメーションに関する雑感

XDのプラグインはUXP（Unified Extensibility Platform）と呼ばれるアーキテクチャの上で動作します。このUXPというプラットフォームは他のアプリケーションで組み込まれているCEPの影響を色濃く見ることができます。
まずはこの新しいプラットフォームについておさらいしておきましょう。

##UXPについて
###モダンなJavaScript VM
モダンなヴァーチャル・マシンという事で恐らくV8もしくはV8ベースのカスタムエンジンだと思われます。他のAdobeアプリケーションで主流のExtendScriptのエンジンとは比べ物にならない位高速に動作してくれます。これはJITであることに依る部分が大きいのですが、ノンブロッキングな動作である点も見逃せません。ECMAで言うところのES2015準拠な構成となっていますので標準的なJavaScriptの知識が役に立ちます。また、Webで利用される多くのライブラリやフレームワークを利用することも可能です。注意するところは、XDのDOMに対するアクセスはブロッキング動作で完全に同期処理となっています。この部分の操作を把握していないとややこしくなるので注意が必要です。

###Universal Windows Platformのサポート
これ、会社のMacintoshでXDさわったあとに自宅で手持ちのWindowsでさわって戸惑いました。タッチインターフェース標準になってて見た目が別物になります。慣れると画面触りまくってベタベタにしながら操作するのが楽しくなります。

###簡素なマニフェスト記述とパッケージ処理
Adobe社の他のアプリケーションで採用されているCEPと異なりマニフェストファイルはJSON形式のファイルになっています。現状の構成は設定項目が非常にシンプルで直感的です。将来的には様々な拡張が追加される可能性がありますが、JSON形式での実装はスケーラビリティという点においても利点となるでしょう。
また、I/Oポータルを利用したテンプレートの生成やパッケージ処理に関してもCEPと比較するとかなり簡素化されています。

###サンドボックスの装備とファイル操作
UXPでは基本的にユーザーの同意なしにはサンドボックス外のファイルシステムへのアクセスは出来ない仕様となります。

という具合に春ぐらいに公開された情報ではこの様な特徴が強調されていました。
そしてXDプラグインの実装は次の項目が同時にアナウンスされていました。

##XDプラグインにおける実装
1.ユーザーインタラクションによる自動処理やコンテンツマネジメント等
2.ローカルファイルシステムへのアクセス
3.メニュー項目の追加及びカスタムUI

という事で、おおよそは実装されていますが、まだまだ完全には達成されていません。特にUI関連やユーザーインタラクションに関してはもう少し実装を進めていただきたいと思います。

XD自体はUXP実装第１号という事で、オブジェクトモデルの実装も他のアプリケーションとは全く違った過程で進められました。XDのオブジェクトモデル自体はIllustratorやPhotoshop等と比較するとかなりシンプルですが、構成的にはWeb系のDOMに近く従来のExtendScriptを主とした開発者よりWeb方面のコーダーに対して親和性が高いと言えるでしょう。
また、開発チームも細かいアップデートを繰り返しています。現状、不備なところも多々あるのですが、これから先が楽しみなアプリケーションではないでしょうか。


###プラグインの実装
さて、つまらないことばかり書いてきましたが、今回サンプルに挙げるのがPropertyExplorerのXD版です。
![xdprop.png](https://qiita-image-store.s3.amazonaws.com/0/310121/5c85d529-426d-dc1c-9a94-b36fea4d42f5.png)

こちらが実行画面になるのですが、オブジェクトを選択した状態でこのプラグインを実行すると、そのオブジェクトが持つプロパティとその現在値が表示される様になっています。

```
const {SceneNode,RootNode,Group,GraphicNode,Rectangle,Artboard,Ellipse,Line,Path,BooleanGroup,Text,SymbolInstance,RepeatGrid,LinkedGraphic, Color} = require("scenegraph"); 
const { alert, error } = require("./lib/dialogs.js");

function searchProperty (selection, documentRoot) {
	showAlert(selection.items[0]);
	}

async function showAlert(ob) {
    await alert("Object Info", ob);
}

module.exports = {
	commands: {
		peExe: searchProperty
	}
};
```

この様にコード自体は非常にシンプルです。ExtendScriptから来た人は冒頭のrequireとかconstの定義で戸惑うかも知れません。XDの場合、ドキュメン上のオブジェクトを操作するためには必要なものを自分でrequireしないといけません。また、２行目の様にアラート一つ出すにもライブラリを読み込む必要があるために少し面倒に感じるかもしれません。
しかしながら、各ライブラリには詳細なコメントが書き込まれており、ドキュメンテーションが舌っ足らずなExtendScriptと比較すると親切設計になっていると思います。

これのパッケージ化したものは以下から入手できるようにしてあります。（わたしのgoogle driveからのダウンロードです）
[Property Explorer for XD](https://drive.google.com/file/d/10EeDHshtm6dALj--P4fcbHRC9OE9lx1g/view?usp=sharing)
とりあえず、QR Code Maker for XDもよろしくね(^-^)/

##最後に
このXDとUXPはAdobe社がこれから向かう方向性を指し示す指針とも言うべきものかも知れません。比較的シンプルなオブジェクトモデルと、今風のスクリプトエンジンという学習に最適な組み合わせで世に出されたプラットフォームです。これを勉強しない手はないと思いませんか？

###おまけ
…IllustratorのPropertyPanelのプラグインって、UIがCEPではなくてADMっぽいんだけどマニフェストがJSONなんだよねぇ……
Ubuntu 18.04 LTS にDocker環境をインストールする

この記事は、「[オンプレミス、Kubernetesで、マイクロサービスを意識したWebアプリをデプロイするまでの軌跡](https://qiita.com/soumi/items/2ef65b0d6e3fb562451e)」の一部です。

## はじめに

Kubernetesを使うにしても、まずはコンテナソフトウェアであるDockerを入れないと始まりません。
例のごとくUbuntuの上に、Dockerをインストールする手順を紹介します。

## Dockerのインストール

Ubuntu公式リポジトリにもDockerはあるのですが、ここでは[公式の方法](https://docs.docker.com/install/linux/docker-ce/ubuntu/)に従ってDocker公式がメンテナンスしているDockerCEをインストールします。

まずはおなじみのこのコマンドから。

```shell
$ sudo apt update
```

前提ソフトウェアのインストールという事で以下のパッケージをインストールするのですが、僕の環境ではすでに入っていました。

```shell
$ sudo apt install -y \
    apt-transport-https \
    ca-certificates \
    curl \
    software-properties-common
```

GPG 公開鍵のインストールして、フィンガープリントを確認します。

```shell
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo apt-key fingerprint 0EBFCD88

pub   4096R/0EBFCD88 2017-02-22
      Key fingerprint = 9DC8 5822 9FC7 DD38 854A  E2D8 8D81 803C 0EBF CD88
uid                  Docker Release (CE deb) <docker@docker.com>
sub   4096R/F273FCD8 2017-02-22
```

Docker公式のaptリポジトリを設定します。

```shell
$ sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"
```

そして満を持してDockerCEのインストール。

```shell
$ sudo apt update
$ sudo apt install -y docker-ce
```

これでDockerCEのインストールは完了です。
お疲れ様でした！

### httpなプライベートDockerレジストリからイメージを使う場合

デフォルトだと、dockerはhttps通信でコンテナファイルを取得しに行こうとします。
特にオンプレミスでDockerレジストリを構築してイントラのみで運用している場合、SSLの証明書を最近流行りのLet's encryptで取得することが出来ないので、httpのままになっている事が多いと思います。

以下のように設定ファイルを編集する事で、http通信でのコンテナファイル取得が出来るようになります。

```shell
$ sudo nano /etc/docker/daemon.json

{ "insecure-registries":["<dockerレジストリのip>:<ポート>"] }

$ sudo service docker restart
```

僕の環境では```/etc/docker/daemon.json```は存在しなかったので、新たに作る形になりました。

## docker-composeのインストール

インストールした```docker```コマンドを直接使ってコンテナを起動しても良いのですが、起動の度にオプションを指定したり、いくつも立ち上げたりするのが面倒な事があります。
```docker-compose```はdocker-compose.yamlというファイルに設定を書き込み、そのファイルを元にコンテナを起動してくれるアプリケーションです。ファイルになるので後で使いまわす事も、Git等でバージョン管理する事もでき、とても便利です。

Docker本体とは違って、aptを使ってインストールすることが出来ません。
プログラムを直接DLしてパスの通ったところにインストールします。

```shell
sudo curl -L "https://github.com/docker/compose/releases/download/1.23.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
```

直接DLになるので、最新バージョンナンバーは以下で確認して下さい。

https://github.com/docker/compose/releases

DLしたら、実行権限を付与します。

```shell
sudo chmod +x /usr/local/bin/docker-compose
```

以上です。
お疲れさまでした！

## 参考

[Ubuntuにdockerをインストールする](https://qiita.com/tkyonezu/items/0f6da57eb2d823d2611d)
[Get Docker CE for Ubuntu](https://docs.docker.com/install/linux/docker-ce/ubuntu/)
[Install Docker Compose](https://docs.docker.com/compose/install/#install-compose)
せっかくだから俺は自分のアプリを紹介することにするぜ

「クソアプリ2 Advent Calendar 2018」の記事です。

# 才ジェネ

「さいじぇね」って読みます。
年齢ジェネレータです。
◯才と◯ヶ月が計算できます。
17歳信者も使えますね。

* これはFlutter製

## iOS

https://itunes.apple.com/jp/app/%E6%89%8D%E3%82%B8%E3%82%A7%E3%83%8D/id343162291?mt=8

## Android

https://play.google.com/store/apps/details?id=com.shinriyo.saigene

# iPasser

これは自分で問題を登録して自分で問題を解くことができます。
TOEICだろうがMIT大学の過去問だろうがなんでもできますね。
単一選択、複数選択、記述式に対応。

* これはIonic製

## iOS

https://itunes.apple.com/jp/app/ipasser/id1366737341?mt=8

## Android

https://play.google.com/store/apps/details?id=jp.shinriyo.passer

# かぞエモン

君は、2438437458345486748っていう数字とかを貴方瞬時に言えるだろうか？
数えられない人は猛省してこれをダウンロードだな。

* これはReactNative製

## iOS

https://itunes.apple.com/jp/app/%E3%81%8B%E3%81%9E%E3%82%A8%E3%83%A2%E3%83%B3/id1437424140

## Android

なかった

# BIG NUMBER QUIZ

さっきの「かぞエモン」の英語版にした感じ。
34356466566みたいな数字を瞬時に英語で言えますか？
言えない人はこれで勉強だな。

* これはWeex製

## iOS

https://itunes.apple.com/jp/app/big-number-quiz/id1438479253

## Android

https://play.google.com/store/apps/details?id=jp.shinriyo.bignumber

# カフェマスター

珈琲館やドトールのカード使っている人に便利。

## iOS

なし

## Android

https://play.google.com/store/apps/details?id=com.shinriyo.cafemaster
gccっていったいなんなんだ

linuxで何かインストールしようとすると、その一連で「gcc」という単語がよく出てくるイメージがありました。
gccとはなんぞや？というところをまとめます。


#GCCとは
GNU Compiler Collectionの略。
>GCCとは、GNUプロジェクトが開発および配布している、さまざまなプログラミング言語のコンパイラ集のことである。

https://www.sophia-it.com/content/GCC

このGCCの実行ファイル(コマンド)が`gcc`である。

~~#gccとは~~
~~GNUプロジェクトが開発・公開しているコンパイラ。様々なプログラミング言語のコンパイラを集めたパッケージとなっている。~~　
~~http://e-words.jp/w/gcc.html~~
~~複数言語に対応するコンパイラです。~~
~~(昔は「GNU C Compiler」の略だったそうです)~~

※ご指摘いただき修正しました 2019/1/17




##さっそく使ってみる

公式サイト：http://gcc.gnu.org/
動作確認環境：Docker上のCentOS7 (Windows10上にDockerをインストールしています)

###インストール

```bash
$ yum install gcc
```

※Windowsは`MinGW`、Macは`Xcode`を入れることでgccを使えるようになるようです。


###C言語で書いたソースコードをコンパイルして実行
一番簡単にできそうだったので、C言語で書いたコードをコンパイルして実行してみます。

```c:hello.c
#include <stdio.h>
  main(){
  printf("hello world.\n");
}
```
上記のように`hello.c`というファイルを作成します。

コンパイルしてみます。

```bash
$ gcc hello.c 
$ ls
a.out  hello.c
```

成功すると、`a.out`というファイルができました。
実行してみます。

```bash
$ ./a.out
hello world.
```
実行できました！

###コマンド解説
```bash
$ gcc <ソースコードファイルパス> 
```
上記コマンドで、ソースコードをコンパイルし、実行形式ファイルを出力できます。
実行形式ファイルの名前は`a.out`となります。
この名前はデフォルトです。`-o`オプションを使うことで、実行形式ファイルの名前を指定できます。

```bash
$ gcc -o hello hello.c
#helloという実行形式ファイルが作成される
```

実行形式ファイルにしたあとは、以下のコマンドで実行できます。

```bash
$ ./<実行形式ファイルパス>
```
`./`が必要です。


##でも、`gcc`コマンドは使ったことがない気がする
ワードは何度も聞いたことがありますが、今まで実際にLinux上打ったことはあまりない気がします。
(コピペしてた中に入ってたのかもですが・・・)
実際に打っていたのは`make`とかだったような気が・・・

ということでDockerのCentOSにはいっていなかったvimをインストールしてみます。

https://qiita.com/silverskyvicto/items/386839cc3e2fcfa191fe
の記事を参考にさせていただきます。

```bash
# vimが入っていないことを確認
$ vim --version
bash: vim: command not found

# 必要なライブラリをインストールしておく
$ yum install -y ncurses-devel make gcc git

# vimのソースをダウンロード
$ cd /usr/local/src/
$ git clone https://github.com/vim/vim.git

# コンパイル
$ cd vim/src
$ make
$ make install

# インストール完了
$ vim --version
VIM - Vi IMproved 8.1 (2018 May 18, compiled Nov 10 2018 06:24:47)
```

`make`コマンドを使うことでより簡単にインストールができるようです。
上のサンプルの例でも、「必要なライブラリ」の中に`gcc`が入っています。
`Makefile`を準備し、その中にコンパイルのためのコマンドを書きます。このファイルを準備することで、`make`というコマンドを打つだけでコンパイルができるようです。
`gcc`は直接はつかわなくても、内部的に使われているんですね。
お手軽なDataflow処理をScioの「Type Safe BigQuery」を使って作ってみる

本記事は[Fringe81アドベントカレンダー2018](https://qiita.com/advent-calendar/2018/fringe81)の3日目の投稿です。
[昨年](https://qiita.com/kaz3284/items/990058201f134d5689d6)に続きScioを使ったDataflowの処理について書きます！

# Scio、Dataflowとは？
[Scio](https://github.com/spotify/scio)はApacheBeamおよびDataflowのScala版APIです。
音楽配信サービスで有名なSpotifyが主導で開発しています。
[Dataflow](https://cloud.google.com/dataflow/)はApacheBeamをGoogleCloudPlatform上で実行できるサービスです。
付加機能も充実していて本家のJava版より簡潔に実装、実行できるためオススメです。

# なぜDataflow？？
個人的には、ある程度〜大規模のデータ処理はGCPのBigQueryで処理するのが最強だと思っています。
しかし、SQL一発で欲しいデータを抽出するのが難しい時もあり、SQLで出すため中間テーブルをいくつも経由したり、
一旦中間ファイルに落としてから別の仕組みで処理しする場合があります。
そんな時、Dataflowを活用すると速く、シンプル、低コストで実現できます。

# Type Safe BigQueryとは？
ScioでBigQuery処理を簡潔に実装できる仕組みです。
DataflowでBigQueryを中心としたデータ処理を実装する場合に大変便利です。
cf. https://github.com/spotify/scio/wiki/Type-Safe-BigQuery

# 作るモノ
BigQueryの一般公開データセットとしてアクセスできる
StackOverflowの質問データ(タイトル)に対し、word-countを実行して情報を付加して新規tableへ書き出す処理を書きます
(単純だけど、SQL表現が難しいデータ処理の一例として)

# ScioREPLで実行(ローカルDataflow)
簡単に実行できるScioのREPLで実行します。
(Scioの準備等は[昨年の記事](https://qiita.com/kaz3284/items/990058201f134d5689d6)を参照していだければ(^^))

## 起動
```shell
java -jar scio-repl-0.5.6.jar
```

## サンプル実行
### BigQueryデータを抽出する

```scala
@BigQueryType.fromQuery("SELECT id,title,0 AS wordcount FROM `bigquery-public-data.stackoverflow.posts_questions` limit 100")
class Row
```

- gcpアカウントが適切に設定されてないとエラーで止まってしまう可能性があるので下記を実施します
```
gcloud auth login
gcloud config set project [project-id]
gcloud auth application-default login
```


### タイトルに対してワードカウントを実行して情報を付与、新規BigQueryテーブルへ書き出す

```scala
val questions=bq.getTypedRows[Row]()
val wcquestions=questions.map(r=> Row(r.id, r.title, r.title.map(_.split("[^a-zA-Z']+").length)))
bq.writeTypedRows("[project-id]:sample.wcquestions", wcquestions.toList)
```
([project-id]は各自の設定へ置き換えてください)

### 結果
サクッとtitleに対するwordcount処理が実行され新規tableへ書き出されます。
<img width="831" alt="スクリーンショット 2018-12-03 6.59.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/26997/da4e7124-f224-9ae5-d791-51526c1251ee.png">

コードは下記で全てです！！　
本当にこれだけのコードを書くだけで
__BigQueryからデータ抽出->データ加工->新規BigQueryテーブル作成(スキーマはデータ型から自動作成)__
が実行されて完成です！便利です！

```scala
@BigQueryType.fromQuery("SELECT id,title,0 AS wordcount FROM `bigquery-public-data.stackoverflow.posts_questions` limit 100")
class Row
val questions=bq.getTypedRows[Row]()
val wcquestions=questions.map(r=> Row(r.id, r.title, r.title.map(_.split("[^a-zA-Z']+").length)))
bq.writeTypedRows("[project-id]:sample.wcquestions", wcquestions.toList)
```


## GCPのDataflowで本格実行

```shell
java -jar scio-repl-0.5.6.jar --runner=DataflowRunner
```
「--runner=DataflowRunner」をつけてREPL起動するだけで本格的な分散処理環境であるGCP上のDataflowで実行できます。
ある程度以上のデータ処理を行う場合はDataflowで実行しないと終わらないです(^^;)

# 最後に
データ処理を運用していると、ある程度以上のデータ規模になると急に厳しくなる(インフラ調整、コスト問題)問題がありました。
そこで、使い勝手がよいBigQueryとフルマネージドで分散処理を実現するDataflowを使うと、ほとんどの問題が解消される実感があります。
同じような問題を感じている方は是非使ってみてください〜