OmniAICreator/Qiita-1.07M huggingface dataset:
Firebaseで失敗した

FirebaseのRealtimeDatabaseを使ったときに失敗したことがあったので書きます。
なお、この体験は**ハッカソン等での個人の体験であり、 実サービスとは関係ありません。**
また、関わったエンジニアの方々を馬鹿にしたいわけでなく、同じ失敗を繰り返さないために自分用のメモとしても載せております。

## わかること
- Firebaseを利用するときの失敗例から導入すべきかどうか
- 責任問題やできることできないこと
- 工数は本当に下がるのか

## 要件
- **即反映したい**、システムを作るという要件があった
    - 投稿 -> (何かしら操作) -> (何かしら操作2) -> 反映   といういろいろ経由するけどなる早がいいとのこと  
- 件数は数1000万件?ほど予想であり、webのpub/subやwebSocketでも良かったが、「サーバーサイドの負荷が楽になる＋フロントエンドも実装が楽になる+かっこいい」という見込みを立てて、FirebaseのRealtimeDatabaseを選択
- 実装するための期間も非常に短かった

## 実装作戦
- 匿名ログイン周りは、FirebaseFunctionでTokenなどを発行して処理(サーバー)
- あとは、フロントでデータを突っ込んでもらったり、出してもらったりする想定で進める

#### サーバー担当
- ログイン周り
- Firebaseのルール

#### フロント担当
- DB設計
- データ管理
- 該当のシステムの画面
- 何かしら操作の画面

という感じで、普段サーバーサイドがやっているDB設計などもフロントに投げてしまった（助言程度） <= ここが良くなかった。

## 失敗したこと
- マークアップエンジニアに、データ管理や設計を任せてしまったことにより、データの取扱のところでミスが出てしまい、 **大規模な障害とバグにつながってしまった**
- データをサブスクライブしておけばデータが来ると思っていたらしく、 **実装待ちになって進んでいなかったときがあった**
- データの取扱の工数感がサーバーに比べてないため、**工数を軽視されていた**
- DB設計やソート、カウント、limitを取るという知見がないため、スロークエリになりがちな実装も見られた
- NoSQLはサーバーサイドエンジニアであればDynamoDBなどでもよく使っていたが、マークアップを専門に行なっているフロントエンジニアにとっては少しハードルが高かった
- フロントのViewのソースコードとデータ周りのプルリクが同じなので、サーバーでのプルリク確認がし辛い

## まとめ
- FirebaseのRealtimeDatabaseはとても便利で、実装も早くなるし、**サーバーサイドの実装工数が減る** が、フロントエンドに責任を押し付けてしまう事になり、実サービスや重要案件の場合は気をつけたほうがいい
- 責任分散がやりづらい
- 大規模なサービスになると、実は工数はあまり変わらない
- ログが残りづらいのでたどりにくい(意外と重要)

## 合わせて
- 「[DynamoDBを使うサーバーレス設計で失敗した](https://qiita.com/okamu_/items/f8d6064e3179bca27c3f)」という記事も公開しました
iOSDC インタラクティブラウンドテーブルという企画がよかった!!

# iOSDCとは
https://iosdc.jp/2018/
今年で3回目となる、iOSおよび関連技術のエンジニアのためのカンファレンス

# インタラクティブラウンドテーブルとは
* 特定のテーマに沿って相談できる  

| 日程  | 相談テーマ                   |
|:----:|:--------------------------:|
| 1日目 | テスト相談会                  |
| 2日目 | Storyboard/AutoLayout相談会 |
| 3日目 | Firebase相談会              |

* 今年から始まった企画
* 1テーマあたり20分×3回
* 参加者が困っていることを有識者に相談できる

# 参加してきたものと雑多なメモ
以下2つに参加してきた

* テスト相談会
* Storyboard/AutoLayout相談会

## テスト相談会
### 負債のお話
* 意図をコメント残しておくの重要
    * リリース前の忙しいときはコメント残してPR承認とかする
* リファクタの時間をちゃんととってる?
    * とってる
    * 2週間単位で掃除当番というリファクタ役が回ってくる
* 時間とらなかったとしたらいつやるか
    * KPTで振り返り
    * リファクタ時間を施策実装前とって先にやる
    * 経営のやりたいことが実現できないからリファクタをするという話ができる
        * バグがおおいとか(バグの重要度にもよる)
        * アーキテクチャ的に実現できないとか
        * 修正コミット数とかCrashlyticsとかで可視化できる
* コードをきれいに保つことが離職を防ぐことにつながる

### CI
* サービスにJoin時に導入た(参加者で導入してなかったの私だけ…)
* CIでやっていること
    * ビルド
    * テスト
    * デプロイ(DeployGateなど)
    * PR投げる

#### 入れる理由
* OSSを書いているので最初から入れる、入れないとそれしか確認方法がない
* 証明書を別管理にするリスクヘッジ
* 他のマシンでも動く保証
* ビルド手順の可視化

#### 困っていること
* CircleCIが安定しない
* CIの実行が遅い
    * frameworkに切り出してそっちにテスト書くとか

#### 導入していないのが私だけだったので導入に向けてどうしたらいいか相談してみた
* とりあえず社内だれかにCI導入に関する質問を投げてみる
* Saasが無理ならJenkinsでも導入してみること
    * 導入して運用し始めたらそれにかかった工数を記録しておく
* CIがないとリリースできないという文化を作って浸透させていく
* 運用みんな辛いよっていう状況をみんなが理解する
* 運用を外に投げる相談に行く

## Storyboard/AutoLayout相談会
* Storyboard/AutoLayoutで困っていなそうな強い人達が集まっていた
* その方々の運用方針とかが聞けた

### Storyboardとコードのどちらでやるか、それぞれのメリット
#### Storyboard
* ビルドせずに
    * デザインが確認できる
    * 各機種での確認も1度にできる
* 壊れているかを**コンパイラが教えてくれる**
* デザイナーとやりとりしやすい

#### コード
* **自由度が高い**
    * 実行時にデザインの変更ができる
* 人がレビューしやすい
    * XibのXMLより探しやすいしみやすい
    * レイアウトの制約だけでもCSSみたいに別ファイルなら…
* 制約の一覧性
* 再利用性(コピペとかできる)
* **コンフリクトしにくい**
    * Xibで細分化していればコンフリクトは解消できる

# 所感
* その分野に詳しい人達からノウハウを聞く機会がなかなかなかったので、話を聞いているだけでも参考になった
    * **来年もやってほしい!!**
* 自分が質問したいと思っていたことは他の人も気になっていたようで、ちょっと安心?した
* 「理想」と「現実」の落とし所や進め方も具体的に聞けて、自分がやるときのイメージができてよかった
ネットに転がっている問題をJavaScriptを使って解いてみる

プログラミングの問題を色々解けるようになることで、実装のスピードが上がるかも、と言う仮説を元に、問題を解いてみたので、メモとしてあげてみる。

## 問題：数字nの階乗を求めよ
```index.html
<html>

<head>
    <meta charset="UTF-8">
    <script>
        var array = [];
        var number = 5;
        var answer = 1;
        for (var i = 0; i <= number; i++) {
            if (i === 0) {
                continue;
            } else {
                array.push(i);
            }
        }
        array.sort(function (a, b) {
            return (a < b ? 1 : -1);
        });
        for (var j = 0; j < array.length; j++) {
            answer *= array[j];
        }
        console.log(answer);
    </script>
</head>

<body>
</body>

</html>
```
なんとか解けましたけど、参考にさせていただいたサイトをみると、もっと短く書ける。。。
精進が必要です。

### 参考サイト
[JavaScriptで「階乗計算」「FizzBuzz」問題を解く](https://mae.chab.in/archives/2231)
高齢者は保守的というのはどの程度本当か？

# 発端
[この記事](https://qiita.com/nodakoubou/items/1c92d33855cfd09ccc57)を読んだ所、コメントで"古めの技術者"だの"保守的な人々"だのということが書かれていた。
しかもコメントを見ている限り、技術的には「それ決着ついてんじゃん。VB捨てた方が良いんじゃないか？」みたいな感じでもVBを使い続けるらしい。てことは技術の話ではない。
だから”古めの技術者”を理解するためには技術じゃなくて別の方面で理解した方が良いと考えた。

また、あたかも高齢者が保守的だとでも言わんばかりなのだが、それは本当なのか？
どの年齢からそれが始まるのか？理由は？みたいなことが知りたかったので調べた。

尚、ここに書いているのは一般的な話であり、個人には適用しないでください。

# 結果
保守的になるか？　-> なる
何歳から？ -> 40代後半
理由は？

1. 好奇心の減退
2. 情報処理能力の低下  
  新たな知識を獲得するときに、情報処理を節約しはじめる。  
  そのため、単純化、矛盾する情報の無視、強引な類型、を使って「黒か白」といった単純な話として解釈する。  
  古い知識を保存することが新しい知識を得ることよりも重要であるため、考える前に偏見を使って判断する。
3. 親近感  
  保守的だと経験で判断でき、努力が必要ない。  
  一方、変化は努力を必要とし、老齢ではストレスを感じるため。  
  保守的だと -> 親近感を高める　-> より保守的が魅力的に感じるようになる 無限ループに陥る。  
  また、保守的だと経験が活きるため、自尊心を高める。
4. どの世代で生まれても関係なく、歳と共に保守的になっているため、原因は確かに加齢。

# 感想
ここまで見事に説明されると感嘆しか出てこない。
この理由は92の論文のメタアナリシスの結果のようだ。よく調べたもんだ。　
原著は課金されてるので読めなかった。
でも”なぜ老人は保守的か？”のコメント欄では根拠が薄いなど色々書かれているようだ。
大部分の日本語のサイトではcitationを書いていないため根拠がはっきりとしない。

# 古い人々への解決策
基本的には新しい事をさせない方が良い。
老いて新しく事をさせると、不安と自己疑惑を引き起こす可能性がある。
古い人々は知恵、経験、専門知識があるので、それを頼れば良い。
新しい事をさせず、自尊心をうまく満たしてくれるだろうから。

しかし、そうでない場合は、努力の強要を促した方が良いと思う。
努力をするまでのバリアが高くなるため。

# 文献
[なぜ老人は保守的か?](https://www.psychologytoday.com/intl/blog/mr-personality/201410/why-are-older-people-more-conservative)
[我々は本当に加齢と共に保守的になるのか?](https://www.theguardian.com/commentisfree/2015/nov/03/do-we-become-more-conservative-with-age-young-old-politics)
amplify shader editorが使えるまでに必要な知識

アホを晒すというのが、このQiitaでの趣旨なので、ツラツラ書きます。

ようやく、自分が何を理解していないから、
このAssetを使いこなせないのかが分かった。

・Surface shaderの各項目の意味
　→ふつうにAlbedoがなにか知らなかったので、そら意味不明だわ！
　それ以外の項目は、名前と過去のなんとなくの経験で、
　イメージは付く。

・ノードベースUIの使い方
　複雑なノードがどうなってるのかまではまだ良く分かってないんだけど、
　とりあえず、数値で指定したいプロパティの数値を変えるときは、
　floatのウィンドウを作り、それを設定したいやつにつなげる。
　ここまではさすがにアホでも分かりますが、色を変えたいときどうする
　んだろ・・と思ったら、色用のウィンドウがありまして、それを作って、
　その設定項目を適用したいやつにつなげる。
　(なので、色を設定できないプロパティにつなげると？？
　　たぶん無効になってる気がする→要調査)

と、色とか発光とか金属感を変えれるようになった。
[![Screenshot from Gyazo](https://gyazo.com/c8a329c4d1e46dadf1027265e88436e3/raw)](https://gyazo.com/c8a329c4d1e46dadf1027265e88436e3)

そうすると、右のConstants And Propertiesに、
マジ無限の項目があるが、これらがいったい何なのか、
8割以上分からん・・。

千里の道も・・・

以上、アホ投稿でした！
GitHubアカウントを使い分けたいときのSSH_CONFIG

分け合ってGitHubアカウントを色々使い分けているので、簡単に管理したいなぁとは思っていたが、ssh_configで十分できそうだな、ということで。


## ssh_configを用意する

githubであれば、ssh_configはこんな感じに書く。
UserとかPortを変えることはあるけど、趣味でのgithubもお仕事でのgitlabもプライベートでのgitbucketも似たように書いてる。

``` ~/.ssh/config
Host github-foo
  User git
  Port 22
  HostName github.com
  IdentityFile ~/.ssh/github_foo_id_ecdsa
  TCPKeepAlive yes
  IdentitiesOnly yes

Host github-bar
  User git
  Port 22
  HostName github.com
  IdentityFile ~/.ssh/github_bar_id_ecdsa
  TCPKeepAlive yes
  IdentitiesOnly yes
```

公開鍵をサービスのSSH Keysに登録して、アカウントと紐づけることも忘れずに。


## cloneとかremote addするときに少し書き換えて使う

`git clone`とか`git remote add`するときのURLを少し書き換える必要がある。


`git clone git@github.com:USER/REPO.git` を以下のようにhost部分を変えて使う。

```
# Githubユーザfooとしてcloneする
git clone github-foo:USER/REPO.git
```

hostをドメインそのまま(`Host github.com`)にすれば置き換えはいらないのだけど、そうするとアカウントを分けて使えない（はず）なので、こんな感じにしている。

## （おまけ）git configも行う

アカウントを変えてもコミット者の情報がglobalのものを使うと意味がありません。

リポジトリ毎にgit configを設定できるので、git initやgit cloneしたらやっておきましょう。



## 普段使いとしてもSSH_CONFIGは便利

ssh_configは、別にgithubに限らず普段からssh接続を多用する人とかAnsibleを使ったりする際やトンネルの設定も一緒に出来て便利なので覚えて損はないです。
vueで複数の値をwatchする方法

# 現状
vueにはwatchという設定があって、これで値の変化を監視することができます。
しかし、ここでの設定は1つの値しか監視できず、複数の値を監視することができません。

```vue:単一の値しか監視できない
<template lang="pug">
div
  p watch test
  input(type="text", v-model="$data.text1")
  br
  input(type="text", v-model="$data.text2")
</template>

<script>
export default {
  data() {
    return {
      text1: '',
      text2: ''
    };
  },
  // 両方まとめてチェックする方法がない
  watch: {
    text1(value, oldValue) {
      console.log('text1 change:', oldValue, '->', value);
    },
    text2(value, oldValue) {
      console.log('text2 change:', oldValue, '->', value);
    }
  }
};
</script>
```

# 解決方法
複数の値をチェックする方法は僕が知っている限りでは2種類あります。

## watch関数を使う方法
watch関数に評価関数を設定できるので、watchオプションを使わず、直接watch関数を実行する方法です。

```vue:watch関数を使って監視する
<template lang="pug">
div
  p watch test
  input(type="text", v-model="$data.text1")
  br
  input(type="text", v-model="$data.text2")
</template>

<script>
export default {
  data() {
    return {
      text1: '',
      text2: ''
    };
  },
  created() {
    this.$watch(
      // 2つのプロパティを含めた値を評価させる
      () => [this.$data.text1, this.$data.text2],
      // valueやoldValueの型は上で返した配列になる
      (value, oldValue) => {
        console.log('[text1, text2] change:', oldValue, '->', value);
      }
    );
  }
};
</script>
```
この方法はwatchプロパティに含めることが出来ないので、必然的に監視ロジックを他の場所に書かざるを得なくなり、コードを探すのが少し大変になるかもしれません。

## 算出プロパティを監視する方法
computedで算出された値も監視することができるので、監視したい値をcomputedで計算し、それを監視する方法です。

```vue:算出プロパティを使う方法
<template lang="pug">
div
  p watch test
  input(type="text", v-model="$data.text1")
  br
  input(type="text", v-model="$data.text2")
</template>

<script>
export default {
  data() {
    return {
      text1: '',
      text2: ''
    };
  },
  computed: {
    _allTexts() {
      return [this.$data.text1, this.$data.text2];
    }
  },
  watch: {
    // computedで計算されたものを監視できる
    _allTexts(value, oldValue) {
      console.log('allTexts change:', oldValue, '->', value);
    }
  }
};
</script>
```

この方法はwatchプロパティに含めることはできますが、新しい名前を考えないといけない上、value, oldValueの中身はcomputedの方を見ないといけないのでコードが離れてしまう欠点があります。

# まとめ
正直どっちの方法も微妙なところではありますが、computedを使って監視するのはあんまりよくないかなと思っています。
computedは他の用途でも使われると思いますし、複数の値をwatchしたいだけという理由でプロパティを増やしたくないなという気持ちがあります。
また僕の場合はcomputedは_をつけてdataやpropsと差別化してますが、普通はそんなことをしないようなので、もはやどこの属性のものをwatchしているのか分からなくなっちゃんじゃないかなという懸念もあります。
（ちなみにですが、watchは`'$data.text1'(val, oldVal) { ... }`のように`$data`や`$props`をつけて監視することもできます。気持ち悪いですが）

まぁ最終的には使いやすい方を使うでいいと思います。
Node.js で簡単にtcpスキャン(ポート指定存在チェック)する

## tcpスキャン

スキャンといいつつ、空いているポートを見つけ出す用途ではありません。
知っているホスト、ポートに対して、生きているかどうかをチェックする用途です。

## やりたいこと
* Web Serverが生きているのかどうかをcronなどで定期的にチェックする。
* HTTPでアクセスを飛ばすと、アクセスログが残ってしまうのでこれは避けたい。
* とにかく軽く、早いものが良い。
* ワンライナーでチェックしたい。

自分の要望に合うライブラリは存在しませんでした。

## ライブラリがないなら作れば良いじゃない
というわけで、作りました。

**simple-tcpscan**
https://www.npmjs.com/package/simple-tcpscan

## simple-tcpscan
詳しくは上記npmの公式ページに載せていますので、そちらを見ていただければと思います。

```javascript
const tcpscan = require('simple-tcpscan');
tcpscan.run({'host': 'localhost', 'port': 3000}).then(() => console.log('OK'), () => console.log('NG'));
```

良い感じでチェック処理が書けるようになりました。
A language pack isn't availableを回避

## A language pack isn't available

Windows 10をHyper-Vでインストールした時に、なぜか英語表示しかできず、日本語に切り替えようとしてコントロールパネルのLanguage optionsを開いても、「A language pack isn't available」と出て、言語パックのインストールもできない状態でした。

手動で言語パックを落としてきてインストールすることで回避できたのでメモ。

## 言語パックをダウンロード
~~怪しげな~~サイトに、Microsoftサイトにある言語パックの直リンクが載っているので、自分の環境にあったものをダウンロードしてきます。
https://www.itechtics.com/windows-10-version-1709-language-packs-direct-download-links/

## lpksetup.exe でインストール
Win + Rでファイル名を指定して実行ダイアログを開き、下記を起動する。
`lpksetup.exe`

`"C:\Windows\System32\lpksetup.exe"`（言語パック インストーラー）を直接起動しても同じです。

lpksetupを起動したら、「Install display languages」（表示言語のインストール）をクリックし、「Browse...」（参照...）により先ほどダウンロードしておいた言語パックを指定します。
「Next」でインストールが開始されます。
![lang-install.png](https://qiita-image-store.s3.amazonaws.com/0/27443/2d067390-e928-2005-8d41-23667b1926fa.png)

ProgressがCompletedになり、インストールが完了したら「Close」ボタンでlpksetupを終了します。

## 結果

コントロールパネルのLanguage optionsを開くと、「A language pack isn't available」が「Available」に代わり、「Make this the primary language」というリンクが押せるようになっているので、それをクリックします。

サインアウトしろと出るので、サインアウトもしくはWindows再起動を行うと日本語に変わります。
local にインストールした node module package の実行方法

Qiitaでも使ってる人をほとんど見かけないので共有。

# いままで
例えばeslint。

```
node_modules/bin/eslint ./
```

こんなふうに、 `node_modules` に生成されたバイナリを直接叩いていました。
単発ならこれでもいいけど、つなげて実行したい場合めちゃめちゃ冗長。

# これから

```
npx eslint ./
```

`npx` で冗長なコマンドから開放されました！

# 参考記事
１年前の記事でこんなにいいねがついているのにあんまり浸透していない
https://qiita.com/vvakame/items/23b02e950ca307b9e674

最近の記事もありましたが、同じくらいいいねがついています。やっぱり浸透していない。。。
https://qiita.com/tonkotsuboy_com/items/8227f5993769c3df533d

# ちなみに
使えるのはnpm5.2.0以降みたいですね。
最近 `brew install node` したなら多分6.2.0以上がインストールされていますので使えるはずです。
先日も新しいバージョン6.4.1がリリースされていますので、念の為 `npm upgrade -g npm` してみましょう。

<img width="793" alt="スクリーンショット 2018-09-02 11.58.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/236279/76610acd-ac09-c896-6098-6535fdb31865.png">

浸透してない。。。

以上です。
はじめてのamplify shader editor

shader はずっと興味があったのですが、勉強を先送りしてきてしまって、
尊敬する講師の方に
・はじめはノードベースから入ると良いよ！
・いまは(少し高いけど)assetのamplify shader editor一択！

と聞き、さっそく触ってみているのですが、案外ムズイ。。

まず整理として、shaderの入門として有名なサイトや書籍などをまとめると、

■7日間でマスターするUnityシェーダ入門
http://nn-hokuson.hatenablog.com/entry/2018/02/15/140037

■amplify shader editorの解説として日本語では一番丁寧
https://www.slideshare.net/nyaakobayashi/unity-dojo-amplifyshadereditor101jpnjp

■より基礎の書籍
http://amzn.asia/d/hx5dkmS

で、最終的にいきついたのが、英語だけど、公式のチュートリアルです。
■公式チュートリアルyoutube
https://www.youtube.com/watch?v=BjOCAPEtC-c

ちょっと最新版と画面が違うけど、なんやかんや、一番ゼロから説明してくれてる感じ。

なんとなく自分が表現したいshaderを創れるようになるまでにどれくらいかかるか・・。

Qiita自体も初投稿なので、これも三日坊主で終わらぬよう、頑張ろうと思います！
MessageKit 自分のアイコンを消す／フォントサイズを変更する

## よくあるLine風にするために
- MessagesCollectionViewのMessagesCollectionViewFlowLayoutで全体のレイアウトを指定できる
  - アイコン位置調整 
  - TextMessageSizeCalculatorのmessageLabelFontでフォント指定

```swift
import UIKit
import MessageKit
import Rswift

class ChateViewController: MessagesViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
# 略
        // レイアウト指定
        if let layout = self.messagesCollectionView.collectionViewLayout as? MessagesCollectionViewFlowLayout {  
            // 自分のアイコンを非表示
            layout.setMessageOutgoingAvatarSize(.zero)

            // 非表示の分、吹き出しを移動して空白を埋める
            let insets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 10)
            layout.setMessageOutgoingMessageTopLabelAlignment(LabelAlignment(textAlignment: .right, textInsets: insets))
            layout.setMessageOutgoingMessageBottomLabelAlignment(LabelAlignment(textAlignment: .right, textInsets: insets))

            // メッセージのフォント
            layout.textMessageSizeCalculator.messageLabelFont = R.font.notoSansCJKjpSubRegular(size: 12.0)!
        }
    }
```
### テキスト内の詳細はMessagesDisplayDelegateで指定する

```swift 
extension ChatMessageViewController: MessagesDisplayDelegate {

    // URL青色、下線を表示
    func detectorAttributes(for detector: DetectorType, and message: MessageType, at indexPath: IndexPath) -> [NSAttributedStringKey: Any] {

        let detectorAttributes: [NSAttributedStringKey: Any] = {
            [
                NSAttributedStringKey.foregroundColor: UIColor.blue,
                NSAttributedStringKey.underlineStyle: NSUnderlineStyle.styleSingle.rawValue,
                NSAttributedStringKey.underlineColor: UIColor.blue,
                NSAttributedStringKey.font: R.font.notoSansCJKjpSubRegular(size: 12.0)!
            ]
        }()

        MessageLabel.defaultAttributes = detectorAttributes
        return MessageLabel.defaultAttributes
    }

    // メッセージのURLに属性を適用
    func enabledDetectors(for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> [DetectorType] {
        return [.url]
    }
}
```
DetectorTypeの種類はここを参照
https://github.com/MessageKit/MessageKit/blob/master/Sources/Models/DetectorType.swift
Pine Script Tips

PineScriptのよく使うコードをメモっていきます

* パラメータを可変にする  
input関数を使う

```
short_ma_term = input(title = "短期MA期間",defval=9)
middle = input(title = "中期MA",defval=25)
long_ma_term = input(title = "長期MA期間",defval=75)
```

* テスト期間の日時を可変にする  

```
////テスト期間の設定
sYear = input(2018, "テスト開始年") 
sMonth = input(1, "テスト開始月")
sDay = input(1, "テスト開始日")
sHour = input(0, "テスト開始時")
//分も指定したいときは追加する
sPeriod = timestamp("Asia/Tokyo",sYear,sMonth,sDay,sHour,0)
eYear = input(2018, "テスト終了年") 
eMonth = input(1, "テスト終了月")
eDay = input(1, "テスト終了日")
eHour = input(0, "テスト終了時")
//分も指定したいときは追加する
ePeriod = timestamp("Asia/Tokyo",eYear,eMonth,eDay,eHour,0)
testPeriod = (time > sPeriod and time < ePeriod)

////取引時の設定
//方法1 strategyにwhen optionを指定する
strategy.entry("SELL", strategy.short, when=testPeriod)

//方法2 ifで区切る
if timescale
    strategy.entry("SELL", strategy.short)
```

* plotの線を目立つように、太さを変える  
linewidth オプションを使う

```
plot(bb_bottom,linewidth = 2,color = green)
```

* 他の取引所の価格を使う  
これはTradingViewの大きな優位性  
為替も金も株もすぐに参照できる

```
//hlc3の30分足
sub_hlc3=security("BITFLYER:FXBTCJPY","30",hlc3)
//close
sub_close=security("BITFLYER:FXBTCJPY","30",close)
```

* エントリーして、一定時間後にポジションを閉じる  
変数の保持方法がポイント

```
time_limit = input(10, "イグジット時間")
passed_time = 0
if strategy.position_size[1] == 0 and strategy.position_size != 0
    passed_time := 1
if passed_time[1] >= 1
    passed_time := nz(passed_time[1]) + 1
if strategy.position_size[1] != 1 and strategy.position_size == 0
    passed_time := 0
    
if passed_time > time_limit
    strategy.close_all()
```

* for 文の使い方

```
my_sma(price, length) =>
    sum = price
    for i = 1 to length-1
        sum := sum + price[i]
    sum / length

plot(my_sma(close,14))
```

* 下位足で日足の高値、安値を簡単に確認する

```
//@version=3
study("日足の高安値",overlay = true)
//日足のデータを読み込む
dMin = security(ticker, "D", low, lookahead=barmerge.lookahead_on)
dMax = security(ticker, "D", high, lookahead=barmerge.lookahead_on)
//プロットする
plot(dMin, color=yellow,linewidth = 2)
plot(dMax, color=red,linewidth = 2)

//ticker : 現在と同じ銘柄を読み込む
//"D" : 日足のデータを読み込む
//"lookahead=barmerge.lookahead_on" : 未来のデータを使って表示を更新する
```
GR-ROSE GYRO Sensor サンプルプログラム

ルネサス　岡宮さんが9月1日にプレゼンされた内容を元に作ったものです。

コンパイラーはWEBコンパイラー
http://tool-cloud2.renesas.com/

Wire**をWire2**にする。

*Wire.hはインクルードされるヘッダーファイルなのでいじらない事

なお、センサーのソースはこちらからです。
引用：https://playground.arduino.cc/Main/MPU-6050

私だけかもしれませんが、loop2のPrintfが同期すると出力されない
または、センサーデータすら送らない
というケースが多かったです。

```
/* GR-ROSE Sketch template V0.01 */
/* https://playground.arduino.cc/Main/MPU-6050*/
#include <Arduino.h>
extern "C" {
#include "FreeRTOS.h"
#include "task.h"
#include<Wire.h>
}
const int MPU_addr=0x68;  // I2C address of the MPU-6050
int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;

void loop2(void *pvParameters);

void setup() {
	// LEDs
	pinMode(PIN_LED0, OUTPUT);
	pinMode(PIN_LED1, OUTPUT);
	Wire2.begin();
	Wire2.beginTransmission(MPU_addr);
	Wire2.write(0x6B);  // PWR_MGMT_1 register
	Wire2.write(0);     // set to zero (wakes up the MPU-6050)
	Wire2.endTransmission(true);
	Serial.begin(9600);

	// loop task creation for sensing
	xTaskCreate(loop2, "LOOP2", 512, NULL, 2, NULL);
}

void loop() {
	Wire2.beginTransmission(MPU_addr);
	Wire2.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
	Wire2.endTransmission(false);
	Wire2.requestFrom(MPU_addr,14,true);  // request a total of 14 registers
	AcX=Wire2.read()<<8|Wire2.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)    
	AcY=Wire2.read()<<8|Wire2.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
	AcZ=Wire2.read()<<8|Wire2.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
	Tmp=Wire2.read()<<8|Wire2.read();  // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
	GyX=Wire2.read()<<8|Wire2.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
	GyY=Wire2.read()<<8|Wire2.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
	GyZ=Wire2.read()<<8|Wire2.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
	Serial.print("AcX = "); Serial.print(AcX);
	Serial.print(" | AcY = "); Serial.print(AcY);
	Serial.print(" | AcZ = "); Serial.print(AcZ);
	Serial.print(" | Tmp = "); Serial.print(Tmp/340.00+36.53);  //equation for temperature in degrees C from datasheet
	Serial.print(" | GyX = "); Serial.print(GyX);
	Serial.print(" | GyY = "); Serial.print(GyY);
	Serial.print(" | GyZ = "); Serial.println(GyZ);
	vTaskDelay(770);
}

void loop2(void *pvParameters) {
	while (1) {
		digitalWrite(PIN_LED1, !digitalRead(PIN_LED1));
		Serial.println("loop2");
		vTaskDelay(500);
	}
}

```

![GR-ROSE.jpg](https://qiita-image-store.s3.amazonaws.com/0/285344/10382672-e62a-74c3-99f1-2f52e480fbb8.jpeg)
arduino-cli について整理してみた

# arduino-cli って何？

arduino-cli は、8月24日にARDUINO TEAMよりリリースされた開発者のためのコマンドラインツールです。

[Announcing the Arduino Command Line Interface (CLI)](https://blog.arduino.cc/2018/08/24/announcing-the-arduino-command-line-interface-cli/)

ざっと簡単に説明すると、下記のような特徴とのこと。

- プロの開発者コミュニティのニーズをサポートするために開発
- Arduino IDEの機能を高速でクリーンなコマンドラインインターフェイス
- ほとんどのコマンドでJSON出力の対応
- ARMとIntel（x86、x86_64）アーキテクチャで実行可能

# ARM対応はビックニュース？

ARMとIntelの両対応については、Arduino Teamはビックニュースとして扱ってます。

>The other big news is you can run Arduino CLI on both ARM and Intel (x86, x86_64) architectures.This means you can install Arduino CLI on a Raspberry Pi or on your servers, and use it to compile Sketches targeting the board of your choice (Don’t forget you can also remotely manage your Linux device with Arduino Create Device Manager!)

つまり、**arduino-cli を Raspberry Pi やサーバーにインストールして、それを使用して任意のボードをターゲットとするスケッチをコンパイルさせられる** ということです。

（なお、コンパイルだけでなく、アップロードもできます。）

## Create Device Managerってなんですかね？

最後のある **Create Device Manager** は、Linuxデバイスをリモート管理できるようなものみたい？

自分は使ったことがないので、何ができるかはわかってないです。

もし詳しい人がおられたら、教えてください。

# arduino-cli はどう活用されるのか？

arduino-cliは、好きなプラットフォームに組み込んでArduinoをサポートさせることができるツールです。

>We want you to be able to add Arduino support to whatever development flow you prefer. Whether you use Atom, Eclipse, Emacs, Vim, VSCode, or are even building your own tools, Arduino CLI makes this possible. Let us know what you think!

たとえば、Sublime Text 3はarduino-cli以前より提供されていた Arduino IDEの機能を使ってツールを提供している開発者の方がおられます。

こういった感じでプラグインがどんどん開発されるのではないかと思ってます。

[Arduino Build System for Sublime Text 3](https://github.com/jacobrosenthal/arduino-cli)

# 最後に
 
このarduino-cli を使って、IBMが開発したIoT向けのフローベースドプログラミングツール [Node-RED](https://nodered.org/) 向けに [node-red-contlib-arduino-cli](https://www.npmjs.com/package/node-red-contlib-arduino-cli) という カスタムノードを開発しています。

もし良ければ、使ってみてください。
Spring 5 & Spring Boot 2の初心者向け入門ハンズオンを公開しました

> 2018-11-27 Spring 5.1 + Spring Boot 2.1にアップグレードしました！

Javaの経験はあるけどSpringは初めてという方に向けたハンズオンを公開しました。以前から公開はしていて、自社開催イベントや色んなコミュニティ向けに実施済みなのですが、改めて紹介します。


# どんなハンズオン？

TODOにそって実装していき、Webアプリケーションを完成させるというハンズオンです。

TODOはプロジェクト直下の.mdファイルに書いてあります。また、ソースコードの該当箇所にもTODOコメントを書いてあります。

使っている技術は下記の通りです。

| 該当するTODO | 階層 | 技術 |
|:------------------------:|:------------------------:|:------------------------:|
| TODO 01 | データアクセス | Spring Data JDBC |
| TODO 02 | トランザクション | Spring Tx |
| TODO 03 | Webフレームワーク | Spring MVC + Thymeleaf |
| TODO 04 | 認証・認可 | Spring Security |
| TODO 05 | 設定の簡略化 | Spring Boot | 
| TODO 06 | 運用監視 | Spring Boot Actuator | 


# 在り処と進め方

まずは下記の記事を参考に環境準備をしてください。ソースコードの在り処も載せています。

[Spring 5 & Spring Boot 2ハンズオン準備手順](https://qiita.com/suke_masa/items/44463518fdbbc13e0087)

プロジェクトは全部で4つあります。

- 01-spring5
    - ハンズオンで利用する
    - TODO01〜04まで
- 02-spring5-answer
    - 01-spring5の解答例
- 03-boot2
    - ハンズオンで利用する
    - TODO05〜06まで
- 04-boot2-answer
    - 03-boot2の解答例

01-spring5プロジェクトと03-boot2プロジェクトの直下に、TODO-xx.mdというファイルがあるので、その指示に沿って作業を進めてください。


# なぜ初心者向けハンズオンを作ったのか

僕がいつもSpringの市販書籍としてオススメしているのは下記の2冊です。

- [改訂新版Spring入門](https://www.amazon.co.jp/dp/B01H12Z40U/)
    - アーキテクチャをざっくり理解する
- [Spring徹底入門](https://www.amazon.co.jp//dp/B01IEWNLBU/)
    - リファレンスとして手元にあると安心

この2冊は非常に良い本なのですが、まずは作ってみて理解するという感じではないのです。

Springが初めての人が作りながら学べる教材があったらいいなーと思い、じゃあ自分で作るかということで作りはじめました。

このハンズオンを最初にやっていただき、その後に改訂新版Spring入門→Spring徹底入門の順に読んでいただくといいと思います！


# 著作権について

スライド資料やソースコードなどの著作権は、すべて僕の所属企業に属します。

ただ、個人での学習・コミュニティでのイベント・社内での勉強会など、 **無償** の範囲内での利用は自由です。

このコンテンツの一部または全部を有償サービスで利用することはご遠慮ください。

このハンズオンが、Spring学習の一助になれば嬉しいです。
Rails モデル名の i18n のもう一つの方法

# やりたいこと

Ruby on Rails で，モデル名の日本語を表示したいとする。

例えば会員情報を担う `Member` というモデルがあって，これを「会員」と表示させたい。
「会員一覧」「会員の新規追加」「会員を削除しました。」といったように。

# ふつうのやり方

Rails に備わっている i18n（internationalization；国際化）の仕組みでそれは簡単にできる。

モデルの名前は翻訳ファイル（`config/locale/*.yml`）に

```yaml
ja:
  activerecord:
    models:
      member: 会員
```

のように記述しておく。

そして，そうやって定義した「会員」という文字列を得るには，

```rb
t('activerecord.models.member')
```

とやるか，あるいは

```rb
Member.model_name.human
```

とやればよい。

[`model_name`](https://api.rubyonrails.org/classes/ActiveModel/Naming.html#method-i-model_name) というのはモデルの名前に関する情報（クラス名の文字列，単数形／複数形，スネークケース等々）を持った [ActiveModel::Name](https://api.rubyonrails.org/classes/ActiveModel/Name.html) オブジェクトを返すメソッド。

[`ActiveModel::Name#human`](https://api.rubyonrails.org/classes/ActiveModel/Name.html#method-i-human) は，人間に見せるための文字列を作るメソッド。
例えば `BlogPost` モデルの場合，ロケールが英語なら `"Blog post"` という文字列を返す。
ロケールが日本語だったら，翻訳ファイルに従ってたとえば　`"ブログ投稿"` という文字列を返す。

ここまでの話は過去にも Qiita で何度か取り上げられている。

# もう一つの方法

ここから本記事のテーマ。

この `model_name` メソッドは，実はモデルオブジェクトでも使えるし，モデルオブジェクトのコレクションでも使うことができる。

つまり，例えば `MembersController` の `show` アクションで

```rb
@member = Member.find(params[:id])
```

となっていたら，ビューで

```rb
@member.model_name.human
```

などと書ける。
同様に `index` アクションで

```rb
@members = Member.all
```

などとなっていたら，ビューで

```rb
@members.model_name.human
```

と書くことができる。

# 何が嬉しいの

しかし，`Member.model_name` を，あえて `@members.model_name` と書いて何が嬉しいのか。

嬉しい理由を一つだけ挙げてみる。

よく似たモデルがあって，同じような処理・表示を行う場合に，コードが合わせやすい，ということがあるのだ。

例えば法人会員モデル `CorporateMember` と個人会員モデル `IndividualMember` があるとする（英語が苦手なので，名前が適切かどうかは知らん）。
両者に同じような処理を書くのだが，持っているフィールドが違っているなどの理由で，一つのモデルにうまく統合できない，という場合を想定する。

`index` アクションはそれぞれこうなるだろうか？

```rb:corporate_members_controller.rb
def index
  @corporate_members = CorporateMember.all
end
```

```rb:individual_members_controller.rb
def index
  @individual_members = IndividualMember.all
end
```

いやいや，インスタンス変数は `@corporate_members` などではなく単に `@members` としたい。つまり

```rb:corporate_members_controller.rb
def index
  @members = CorporateMember.all
end
```

```rb:individual_members_controller.rb
def index
  @members = IndividualMember.all
end
```

だ。
これにより，ビューのコードが両者で同じように書ける。
こういうとき，①共通部分を部分テンプレートに括り出すか，②別々に書くか，二つの選択肢がある。どちらがいいかはケースバイケースだと思う。

②の場合でも，テンプレートが同じように書けていると，テキスト比較ツールで比較しやすい。
両テンプレートに同じような修正を施すとき，テキスト比較をすることで修正ミスや修正漏れに気付きやすくなる。

ここで本題に戻る。
テンプレートでモデル名を表示したいとき，

```rb
CorporateMember.model_name.human
```

などとせずに

```rb
@members.model_name.human
```

と書けば，この部分も共通化できる，というわけ。
これが嬉しい理由。

# おまけ

ちなみに，`human_attribute_name` もモデルオブジェクトのコレクションに使うことができ，

```rb 
@members.human_attribute_name :name # => "名前"
```

などと書ける。

しかしモデルオブジェクトには使えないので，

```rb 
@member.human_attribute_name :name # => NoMethodError
```

などとは書けない。
家のWindowsで Apache2.4系 を置く練習をしようぜ☆（＾ｑ＾）

以下の記事を読んで、

「Windows版Apacheをインストールする」
http://d.hatena.ne.jp/Kazuhira/20170128/1485621099

Apache Haus から取ってきて Cドライブに置く。

```
C:\Apache24
```

```C:/Apache24/conf/httpd.conf``` 設定ファイルを開き

```
Define SRVROOT "/Apache24"
```

と書いているところを、頭の C: を取って \ を / に変えて

```
Define SRVROOT "/Apache24"
```

と書く。おんなじだ。
[Windows] + [R]、cmd。[Enter]。

```
cd c:/Apache24/bin
httpd
```

ファイアーウォールが出てきたら「アクセスを許可する」

で、

http://localhost/

にアクセス。 Apache Haus のスクリーンショットが見える。
ベンチャーキャピタルで働きながらKaggleをやってみて良かったと思うこと

# ベンチャーキャピタルとは
ベンチャーキャピタルとは主にスタートアップ企業に投資させて頂き、その企業が成長して上場やM&Aの場合に株式を売却して利益を得る職業です。
日々の業務では、新しいビジネスを起業した経営者の方と、ビジネスプランについて議論させて頂くことが多く、AI、ブロックチェーン、AR/VRなどの新しい技術やこれまでに無いビジネスモデルにアンテナを張って情報収集を行っております。

# Kaggle（カグル）とは
### Kaggleの概要
Kaggleとは世界最大規模のデータ分析のコンペティションで、多数のAIエンジニアやデータサイエンティストが会員として登録して、データ分析の腕前を競っています。
詳細は下記の記事などをご参考に。
・[一から始める機械学習（Kaggleで学ぶ機械学習）](https://qiita.com/taki_tflare/items/8850ac5ba8b504a171aa)
Kaggleの始め方などは、下記の記事などで詳しく解説されています。
・[Kaggle事始め](https://qiita.com/taka4sato/items/802c494fdebeaa7f43b7)

### ルール・概要
Kaggleでは、答えが与えられたトレーニングデータを解析して予測モデルを作成し、そのモデルを用いて答えが伏せられたテストデータの答えを予測し、その予測精度を競うというコンペティションです。
モデルで予測して提出した答えと、実際の値とがどれだけ近いか（予測精度）がスコアとして表示され、スコア順に成績が表示されます。コンペティションの終了時点でのスコアが高い順に表彰されます。
有名な入門編の問題として「タイタニックの生存者予測」というものがあり、タイタニック号の乗客の「年齢」「性別」「船室番号」などのデータから、乗客が生き残ったかどうかを予測するモデル作成が求められます。

# やってみた感想
### これまでの成績
Kaggleに本格的に取り組み始めたのは、2017年末〜2018年初めに開催された、メルカリの出品価格を予測するコンペティションからです。
Kaggleでは、一つのコンペティションの参加者の上位●%以上に入ると金、銀、銅メダルが付与される仕組みとなっており、
0.2%以上：金メダル
5%以上：銀メダル
10%以上：銅メダル
という設定になっています。また、取ったメダルの個数に応じてステータスも、一般→エキスパート→マスター→グランドマスターとランクアップする仕組みになっています。
私は2018年度中に銅メダルを2つ以上取得して、「エキスパート」のステータスになることを目標として週末はKaggleに取り組み、2018年8月末に終了した「Home Credit」のコンペティションで2つ目の銅メダルを取得でき、エキスパートになる事が出来ました。([Kaggleプロフィール](https://www.kaggle.com/ishimotoyoshitake))

### ガチ勢の凄さ
私はここ半年は週末に取り組む程度の関わりでしたが、毎日Kaggleに全力をかけて取り組んでいる人は世の中に沢山いらっしゃるようです。Kaggle内のDiscussionと呼ばれる掲示板には、約3ヶ月間のコンペティション終了後にお互いの健闘を讃えるコメントが数多く掲載されます。さながらスポーツのトップアスリートの世界を彷彿とさせます。
下記は直近終了した7000組以上のチーム、個人が参加した「Home Credit」のコンペティション期間終了後の、参加者のスコアボード（得点ランキング）です。
<img width="991" alt="コンテンツ1.png" src="https://qiita-image-store.s3.amazonaws.com/0/191566/a959e650-8b04-1903-639e-f9c6f2a4e5a1.png">
順位が7000組中で上位1桁に入るようなトップレベルの方々は、数名でチームを組んで参加されていることが多いです。これはチームメンバーで色々な検討を分担しながら効率よく得点を上げて行くためです。
解答提出数を見ると、軒並み200以上の値となっており、それだけ多くの試行錯誤、トライアンドエラーを重ねてこのような高いスコアに至っているという証拠かと思います。

### Kaggleをやって良かったと思うこと
Kaggleをやってみて、特にベンチャーキャピタルの業務への貢献という点で良かったと思う点を記載します。

####1.投資検討の際のスタートアップ企業の技術の理解に役立った
ベンチャーキャピタルが投資検討させて頂く際に、最近は「AIを用いて〇〇する」サービスが沢山あります。その中でも競争優位性があるサービスかどうかを判断する際に、そのAIが「どのようなデータ」を入力し、「どのようなアルゴリズム」で解析するか、Kaggleのコンペティションで出てきた類似のモデルをイメージする事で、ある程度理解しやすくなります。
「十分なデータが集まるか」「データの入手は困難か」「Kaggleのコンペティションで扱われないような複雑な問題か」などのポイントも、競争優位性の判断の手助けになると感じています。

####2.「Kaggleやってる」というと初対面での印象付けが出来る気がする
これはその相手がKaggleを少しでも知っているという前提が必要ですが、Kaggleは「世界最高峰のデータサイエンティストが凌ぎを削る」レベルの高いコンペティションというイメージが一般的にあると思います。私は一応理系ですが、情報学を専攻していた訳でもなく、プログラミングやAI、機械学習の専門家でもない中で、「Kaggleやってます」は、一定のAIに関する知識レベルを保有しているという印象を与える事が出来る気がします。特にベンチャーキャピタルでKaggleやっている人は少ないと思いますので、意外性という点でも効果的に感じます。

####3.エンジニア向けのイベントに気兼ねなく参加出来る
イベント、Meetupの募集サイトの中には「エンジニア限定」と銘打っているイベントもあります。これは主催者側が、冷やかしの防止やイベントの盛り上がり、リクルーティングへの連携などを考慮して設定している条件かと思われます。ベンチャーキャピタルで働く人は、世間一般にはエンジニアでは無いので、このような「エンジニア限定」イベントへの参加は躊躇われる事かと思います。しかしこのようなエンジニア限定イベントの方が最新の技術的な情報へのキャッチアップの点では有効な事が多いのも事実かと思います。Kaggleをやっている人は大半はエンジニア、データサイエンティストですので、もし自分がKaggleをやっていれば、マインドセット面でこのようなイベントにも堂々と参加できます（断られる場合は仕方ないですが）。実際に参加して、懇親会でも周りのエンジニアの人の話にもキャッチアップ出来ますし、関係構築も可能です。

# 最後に
約半年間Kaggleに取り組んでみて、得られた経験は大変有益だったと感じています。
興味がある人は、是非タイタニックの生存者予測の問題だけでもやってみる事をオススメします。何かお手伝い出来ることがあれば[twitter](https://twitter.com/ishigen_dl6)までお気軽にコンタクト下さい。
今勢いのある言語 Elm

フロントエンド特化型 フレームワーク内包言語 [Elm](http://elm-lang.org)が先日(2018/8/23) [バージョン0.19](http://elm-lang.org/blog/small-assets-without-the-headache) にアップデートされました。

アップデートの内容ですが、特に衝撃的だったのが、アセットサイズの縮小です。言語とフレームワークを内包しているにも関わらず、今主流のフレームワークたちを差し置いて29kbとかなり軽量になりました。

![](http://elm-lang.org/assets/home/asset-sizes.png)

それだけでなく、 227モジュール、49,315行のコードに対して**2秒を切る**速度でコンパイルできるほどコンパイル速度が改善しています！

今まで実用的とは言えなかったElmの公式ドキュメントがElm Guideとしてアップデートされました。[Elm-JPのコミュニティ](https://discordapp.com/invite/m9Ew6fR)にも今回のアップデートには火が付いて、少数ながらも精鋭部隊で翻訳プロジェクトがとんでもない勢いで動いています！翻訳やElmに関する質問は是非コミュニティへ！

[Elm Guide (日本語訳)](https://guide.elm-lang.jp)

私自身もElmを簡単に始めれるスタータキットであるelm-dev-envを0.19用にアップデートしました！ 1分以内にElmを体験出来ます！

[elm-dev-env 0.19.0対応](https://github.com/ababup1192/elm-dev-env)

Elm入門のためのハンズオンも積極的に開催しています。首都圏近辺(東京・埼玉・千葉・神奈川)であれば、飛んでいきますので是非気軽にTwitter等でお声がけください。9/22に開催のハンズオンは、connpassで募集したところ、わずか数日で枠が埋まってしまいました。嬉しい悲鳴です。もちろん0.19にアップデートした内容で行わせていただきます！

[Elm入門ハンズオン](https://elm-jp.connpass.com/event/98978/)

Elmをよろしくおねがいします！
acts-as-taggable-onをcheckboxで操作する

Railsでタグ作成に重宝するacts-as-taggable-onというGemがあります。
が、基本的には
![Vegewel見てね](https://qiita-image-store.s3.amazonaws.com/0/1593/45e30f4d-047b-4f1d-81e0-7d2470d09dbe.png)
こんなような手で入力するフィールドに打ち込むというシーンを想定して使っていると思います。
これが、
![Vegewel見てね](https://qiita-image-store.s3.amazonaws.com/0/1593/0b02ce91-5eff-021a-cd69-8d9bb09ded37.png)
こんなふうに入力できたら便利ですよね？

あまりネット上に情報がないのと、本家のGemのサイト
https://github.com/mbleigh/acts-as-taggable-on
にも出てなかったのでこちらにやり方を載せておきます。

基本的にGemをBundleしてテーブルを作成し、ModelとController作るところまでは一緒です。
端折ってしまうと不親切かなと思うので念の為書いておくと、

### Gemfileに以下を記載

    gem 'acts-as-taggable-on', '~> 6.0'


### Bundleを実行

    $ bundle

### Tag関連テーブルの作成

    $ rake acts_as_taggable_on_engine:install:migrations
    $ rake db:migrate

### Model

基本的に使う側（今回でいうとRestaurant）のModelにacts_as_taggable_onを記載する。
今回はタグに名前をつけているので以下のような表記になっているがacts_as_taggableだけしか書かないとデフォルトはtagという名称になる。

```ruby:restaurant.rb
    class Restaurant < ActiveRecord::Base
      acts_as_taggable_on :cuisines
```

### Contoroller

ストロングパラメータにも記載。今回cuisineの名称をつけているので変数としてはcuisine_listとなる。
配列で定義するのでパラメータの後ろの方に記述する。コロンの位置にも注意。

```ruby:restaurant_controller.rb

    def restaurant_params
      params.require(:restaurant).permit(
        :id, :other,
        cuisine_list: []
      )
```

### View

ここからがあまり情報が出てないところ。ul, liで作成したリストで出す場合の例となる。
今回はCuisineというモデル全件出してその中でcuisine_listに含まれているものがあればチェックを入れるという作りとなっているのでこのような表記になる。
さらにもう一点重要なポイントだが、 labelタグとその後に続くinputタグのidの名称を合わせないとIE11とFirefoxでチェックボックスが動かないという問題があるのでここを合わせる必要がある。何かおかしいと思ったらinputタグのid属性を確認するのをおすすめする。

```ruby:restaurant/create.rb
          ul.field.option_check
            - Cuisine.all.each do |cuisine|
              li
                label for="restaurant_cuisine_list_#{cuisine.id.to_s}"
                  = r.check_box :cuisine_list, {multiple: true, checked: @restaurant.cuisine_list.include?(cuisine.id.to_s)}, cuisine.id.to_s, ''
                  span.checkbox =  cuisine.cuisine_name
```

ちなみにここはslimで書いた場合の例なので他のテンプレートエンジン使っている場合は適宜読み替えてください。
xubuntu18.04でmecab-ipadic-neologdを使えるようにする

# 必要なパッケージのインストール
まずはapt-getで必要なパッケージのインストール
xubuntu18.04には最初からはcurlが入ってないので先にインストールします。

```
sudo apt install curl
sudo apt install mecab libmecab-dev
```

# mecab-ipadic-neologdのインストール

```
git clone --depth=1 https://github.com/neologd/mecab-ipadic-neologd
cd mecab-ipadic-neologd
./bin/install-mecab-ipadic-neologd -n
```
Sketch 2 Codeのcliを作った話

*sketch2code.azurewebsites.netのサーバーが503を返すため不安定になることがあります。(Cookie関連)*

# tl;dr
以下で、スケッチした画像をhtmlに変換できます。 [sketch2code-cli](https://github.com/GitHub30/sketch2code-cli)

```bash
# sample.htmlが生成されます。
curl s2c.sh | bash -s sample.jpg
```

- 本当は、CodePenでリアルタイムにスケッチしてhtmlを生成したいです。
- **React** や **React Native** や **Vue** のコード生成したい難民もいるようですね。 [Collaboration proposal](https://github.com/Microsoft/ailab/issues/2)
- 個人的には、 **WebComponents** とかも出来たらいいなと思ってます。

# まとめ
- 日本語やコンボボックスの候補などはまだうまく出来ませんが、今後できるといいですね。
- [Sketch2Code](https://github.com/Microsoft/ailab/tree/master/Sketch2Code) から動かせるようなのですが、Windows(Visual Studio)をもってないと難しそうです。動かして見たいですが、、、
ssh接続のfingerprintをきちんと確認しつつ，半自動で認証を通す．

# ssh
初めて接続するサーバーなどではsshでは以下のようなプロンプトが出ることがある．

```
$ ssh git@github.com
`The authenticity of host 'github.com (192.30.255.112)' can't be established.
RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8.
Are you sure you want to continue connecting (yes/no)?
```
このようなプロンプトは自動化を行う上での障害となる．

確認しないのであれば
`ssh -o StrictHostKeyChecking=no`
オプションを使えばよい．
gitなどほかのツールを用いた場合のssh接続であれば，
`ssh-keyscan　{hostname} >> ~/.ssh/known_hosts `

しかしそもそもこのプロンプトは中間者攻撃などを防ぐために，正しいサーバーに接続していることを証明書のハッシュ値を表示することで確認を促すプロンプトだ．確認するのがセキュリティ的には正しいものと思われる．githubなどは確かに[ここ](https://help.github.com/articles/github-s-ssh-key-fingerprints/)でfingerpirntを公開している．これはhttps接続しているページでもあるわけだから，ブラウザが変な公開鍵を信頼していなければ，PKI的に信頼性のある情報となっているはずだ．
これを適当なファイル(ここでは`hashfile`としよう)にコピペしておいて，半自動で確認するようにさせたい．

# コマンド
`ssh-keygen -E md5 -lf <(ssh-keyscan github.com 2>/dev/null)`
によってmd5のハッシュ値を生成できる．上のコマンドの出力は
`2048 MD5:16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48 github.com (RSA)`
のようになる．
真ん中の値`16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48`が事前に取得したものと一致していることを確認してやればよいだろう．
そこでcutコマンドを使って適宜加工し，diffをとってやる
`diff <(ssh-keygen -E md5 -lf <(ssh-keyscan github.com 1>tmp1 2>/dev/null; cat tmp1) | cut -d' ' -f2| cut -d':' -f2-) <(cat hashfile)`
(`diff <(command1) <(command2)`で確認が可能)
そしてこの結果が一致すれば
`tmp1 >> ~/.ssh/known_hosts`
などとすることによって，known_hostsに加えてやればよい．
まとめてワンライナーにするとこのような形だろうか．

```
if diff -q <(ssh-keygen -E md5 -lf <(ssh-keyscan github.com 1>tmp1 2>/dev/null; cat tmp1) | cut -d' ' -f2 | cut -d':' -f2-) hashfile >/dev/null; then cat tmp1 >> ~/.ssh/known_hosts; else echo "different hash
"; fi
```

これをやってから例えば，githubに接続すると，以下のような表示が出て，追加のプロンプトは出てこない．

```
$ ssh git@github.com
Warning: Permanently added the RSA host key for IP address '192.30.255.113' to the list of known hosts.
```

# 感想
普通にオプションでファイルを指定したら，自動で確認してくれるようにできないのだろうか…
Linuxコマンドは素人なので，ミス・改善点などあったらコメント・編集リクエストお願いします．
ARC102「Triangular Relationship]

# ARC102「[Triangular Relationship](https://beta.atcoder.jp/contests/arc102/tasks/arc102_a)」

## コンテスト中の考察（おじさんは解けませんでした^^;にゃおーん！！）

- 愚直にやるとa, b, cを全探索する3重ループになるなー。
- $O(N^3)$から$O(NlogN)$くらいに落とすのかなーと思いつつ考察を進めた
- Snuke Festivalみたいに真ん中(b)のループ回してa, cを二分探索で求められそうとか思う。無理でした。
- いろいろこねくり回して謎の数式たくさん生成した結果解けませんでした！！おしまい！！



## 理想の考察

### 一部分について考える

- $(a+b), (b+c), (c+a)$をいきなり全部考えると頭爆発する

- なので、とりあえずその中の一部分である$a+b$について考えてみる。
- $a+b$が$K$の倍数になる条件は、以下のいずれかが当てはまるときである。
  1. $a \% K + b \% K = 0$
  2. $a\%K+b\%K=K$
- 条件1は、$a, b$がそれぞれ$K$の倍数であるときに成り立つ。
- 条件2は、$a,b$を$K$で割った余りの和が$K$であるときに成り立つ。

### 全体的なことを考える

- 部分的なことはわかったので、全体的なことを考える

- $a,b,c$という3つの数を考慮した場合、条件を満たすのは以下のいずれかが当てはまる時である
  1. $(a\%K, b\%K, c\%K) = (0, 0, 0)$
  2. $(a\%K, b\%K, c\%K) = (\frac{K}{2}, \frac{K}{2}, \frac{K}{2})$
- 条件1は、全ての要素が$K$の倍数であるときに成り立つ。
- 条件2は、$(a+b), (b+c), (c+a)$それぞれの和が$K$となる場合に成り立つ

### 具体的なことを考えていく

- 大体の方針が立ったので、詳細を詰めていく。

#### 偶奇で処理を分ける

- $(a\%K, b\%K, c\%K) = (\frac{K}{2}, \frac{K}{2}, \frac{K}{2})$についてよく考えると、$K$が奇数の場合はこの条件が使えないことが分かる。$K$が奇数のときにこの条件を成り立たせるためには各要素が小数点数である必要がある。だが、制約によりそれは認められないので$K$が奇数の時はこの条件は使わないこととする。
- つまり、偶数の時は条件1, 2を適用し、奇数の時は条件1のみを適用する。

#### 組み合わせ方について

- $(a, b, c)$に条件に当てはまる数字を組み合わせていくだけ。
- 例えば条件を満たす数字が5種類あったら、$(a, b, c)$それぞれに5種類ずつ入れるから$5^3=125$が答えとなる。こんな感じで考える。



- 条件1, 2に当てはまる数字を別々に数える。
- その後、$(条件1に当てはまる数字の個数)^3 + (条件2に当てはまる数字の個数)$をした数値が答えとなる。



## 解法

1. $x(1 \leq x \leq N)$が$K$の倍数である個数を数え上げる。この個数を$a$とする。
2. $x(1 \leq x \leq N)$を$K$で割った余りが$\frac{K}{2}$である個数を数え上げる。この個数を$b$とする。
3. $K$が奇数の場合、答えは$a^3$となる。$K$が偶数の場合、答えは$a^3+b^3$となる。



## [コード](https://beta.atcoder.jp/contests/arc102/submissions/3122915)

```cpp
#include <bits/stdc++.h>
using namespace std;

using int64 = long long;

int N, K;

int main() {
   cin >> N >> K;

   // Kの倍数である数値の個数を数える
   int64 a = 0;
   for (int x = 1; x <=N; x++) {
      if (x % K == 0) {
         a++;
      }
   }

   // 余りがKの半分となる数値の個数を数える
   int64 b = 0;
   for (int x = 1; x <=N; x++) {
      if (x % K == K/2) {
         b++;
      }
   }

   // 全ての要素がKの倍数の場合を足す
   int64 ans = a * a * a;
   // Kが偶数なら余りがK/2の場合も考慮する
   if (K % 2 == 0) {
      // 全ての要素がK/2の場合を足す
      ans += b * b * b;
   }

   cout << ans << endl;

   return 0;
}
```





## 要点

- いきなり全体的なことを考えるのが大変だったら、まずは一部分について考える(これ「友達の友達」でも使った考え方)
- **倍数が出てきたら、modを意識する**
  - modを使うと状態のグループ分けがしやすい
  - $K$で割った余りが$\frac{K}{2}$になる場合とか、modを使ったおかげで考えることも減ったし処理が楽になった。
  - 「a, b,cを$K$で割った余りの和が$K$になるとき、(a+b+c)は$K$の倍数になる」ってのは覚えといて損はない気がする。



## 類題

- ABC096 - D
- ABC077 - D
- この問題と似たような考え方を使うらしい(by takeoさん)
- たぶんどっちも解いたこと無い




## 感想

- なんか数学的な問題が解けない。
- なんで解けないのかすらよく分からない。
- もう解ける気すらしない。
- おなかすいた
- 解説かなり雑になったし、僕も完全に理解しているわけでは無い。
- 僕的にこの問題クソムズいんですが、上位陣が10分以内に通しててつおいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいって思った。なんでそんなにすぐわかるんだよ。僕なんかクッソ長い考察書いてようやく理解したぞこの野郎。
- ちなみに問題タイトルの「Triangular Relationship」は三角関係っていう意味らしいです！！！夏だから恋愛っぽいタイトルにしてみたんでしょうか！！！僕にはまっっったくかんけいないですがね！えーん ><
カジュアルに自動retweetがしたかった

##　過去の投稿を自動でretweetしたい
[bitbears](https://twitter.com/waseda_bitbears)のtwitterのBot化計画のはじめとして、[クラウドファンディング](https://t.co/OpveN40syh)のtweetを期間限定でretweetしてくれる機能を適当に作ってみた。
[schedule](https://docs.python.jp/3/library/sched.html)で等間隔、または、定時の実行を可能にし、
[twython](https://twython.readthedocs.io/en/latest/)でapiを叩きます。

###機能
 IDに基づいて、そのtweetがリツイートされているか確認し、されていれば、それを取り消したのち、retweetをします。
tweepyでも、twythonでも、retweetを取り消すコマンドは実装されていなかったので、unretweetのstatusをpostします。

```.py
import schedule
import time
from twython import Twython

consumer_key = "*"
consumer_secret = "*"
access_key = "*"
access_secret = "*"

ID = num of your tweet id

twitter = Twython(consumer_key, consumer_secret,
                    access_key, access_secret)

def job():
    if twitter.show_status(id=ID)['retweeted']:
        twitter.post('status/unretweet/%s' % ID)

    twitter.retweet(id = ID)
    print("retweeted")

schedule.every().day.at('08:00').do(job)

schedule.every().day.at('12:00').do(job)

schedule.every().day.at('22:00').do(job)

def main():
    while True:
        schedule.run_pending()
        time.sleep(1)

if __name__ == '__main__':
    main()
```
ubuntu上でdocker-composeをsystemdで管理する

# 目標

Dockerをsystemdで簡単に管理する

# 前提

すでに`docker-compose -f <yml> up`は使えるようになっていること(dockerのインストールは、公式ドキュメント参照)

# 手順

## 1. docker-compose用の汎用化されたサービスを作成

`/etc/systemd/system/docker-compose@.service`<- このファイルの名前が重要なので基本変えないこと。変える場合は、`@`や`.`の役割をしっかり理解してから。

```/etc/systemd/system/docker-compose@.service
[Unit]
Description=%i service with docker compose
Requires=docker.service
After=docker.service
 
[Service]
Restart=always
 
WorkingDirectory=/etc/docker/compose/%i
 
# Remove old containers, images and volumes
ExecStartPre=/usr/bin/docker-compose down -v
ExecStartPre=/usr/bin/docker-compose rm -fv
ExecStartPre=-/bin/bash -c 'docker volume ls -qf "name=%i_" | xargs docker volume rm'
ExecStartPre=-/bin/bash -c 'docker network ls -qf "name=%i_" | xargs docker network rm'
ExecStartPre=-/bin/bash -c 'docker ps -aqf "name=%i_*" | xargs docker rm'
 
# Compose up
ExecStart=/usr/bin/docker-compose up
 
# Compose down, remove containers and volumes
ExecStop=/usr/bin/docker-compose down -v
 
[Install]
WantedBy=multi-user.target
```

これだけではなにも起きない。これは、Docker-compose用のサービステンプレートと言う感じ


## 2. 実際のdocker-composeを置くフォルダ作成 & docker-compose.ymlを置く。

ファイルを置くときは、必ず`docker-compose.yml`で置く！

上のServiceからわかるように、複数のdocker-compose.ymlを別のDirctoryに配置＆Working Directoryを変更することで汎用化しているので、`docker-compose.yml`の名前は変更できない。

```
sudo mkdir -p /etc/docker/compose/<自分のservice名>/
sudo cp <自分のdocker-compose.yml> /etc/docker/compose/<自分のservice名>/docker-compose.yml
```

## 3. serviceスタート

```
sudo systemctl start docker-compose@<自分のservice名>
```


# 最後に

エラーが出たら、`sudo journalctl -xe`などでみるが、わかりずらいので、実際にコマンドを確かめてみるのが早い。

1. まずは、`docker-compose -f <自分のyml> up`でちゃんと動くことを確認
1. docker-composeの場所はあっているか(`which docker-compose`で出てくるものとサービス内のPathが等しいか)
2. docker-compose.ymlのおいた位置は正しいか
などｎ
僕が考える最強のPWAボイラープレートを作る（未完成）

# 概要
俺が考える最強のPWAボイラープレートを作る。
俺が考える最強のPWAボイラープレートの構成は以下の通りだ。
next.jsもworkboxもあんまり触ったこと無いので、さぐりさぐりやっていく。


## 構成
以下の2つでアプリケーションを構築する。

## next.js
* https://nextjs.org/
* SSR/SPA用

普段よく触っているのがReactなので、ReactのIsomorphic JavaScriptフレームワークを使う。

## workbox
* https://developers.google.com/web/tools/workbox/
* Service Workerライブラリ

Service Workerを作るライブラリとしてはworkboxが一強っぽいのでworkboxを使ってみる。

## firebase
* https://firebase.google.com/
* 主に使うのは以下の3つ
    * hosting
    * functios
    * FireStore

プラットフォームは一番手軽でタダのfirebaseを使う。

# next.js/firebaseのセットアップ
~~理解するためにもcreate-next-appは使わずに作り込んでいく。~~
→ なんかめんどくさそうなのでcreate-next-app使うことにした。

## create-next-appのインストール

```bash
npm i -g create-next-app
```

## nextjsのproject作成

```bash
create-next-app --example with-firebase-hosting-and-typescript pwa-boilerplate
```

## firebaseのproject作成
https://console.firebase.google.com/
※ 詳しくは https://qiita.com/Miracle-T-Shirt09/items/8ac43ab7a18b3001dda0 とか見て

## .firebasercの編集

```json
{
  "projects": {
    "default": "<firebase projectId>"
  }
}
```

## 動作確認

```bash
yarn run deploy
```

https://{projectId}.firebaseapp.com/
<img width="541" alt="スクリーンショット 2018-09-16 0.37.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/65939/aeb45fa1-76fa-0ef1-b67f-1bf93fab93c0.png">

〜つづく〜
Redigoを使う(1)　基本的な使い方

# はじめに

[Redigo](https://github.com/gomodule/redigo)は、[Redis](https://redis.io/)のGo言語向けクライアントライブラリです。
Redigoの一通りの使い方を見ていきます。

# 環境

* OS: Windows 10
* Redis: [win-3.2.100](https://github.com/MicrosoftArchive/redis/releases/tag/win-3.2.100)
* Go言語: [1.11](https://blog.golang.org/go1.11)

# サーバの起動

マイクロソフトが提供しているRedisのWindows向けmsiパッケージをダウンロードして実行します。
デフォルト設定では、ローカルの6379番ポートでサービス開始します。別PCからアクセスできるようにするには設定ファイルでprotected modeを「no」に変更します。

# redis-cliでの動作確認

インストールディレクトリ（WindowsではC:\Program Files\Redis）にあるredis-cli.exeを実行すると、ローカルホストの6379番ポートに接続します。
以降、キーボードからコマンドを入力できます。

```
127.0.0.1:6379> SET temperature 20
OK
127.0.0.1:6379> GET temperature
"20"
```

temperatureというキーに20という値を書き込み、直後に読み出しています（なおRedisでは数値と文字列は区別されません）。
本記事ではRedisの各コマンドについては説明しません。必要に応じて、[コマンドリファレンス](http://redis.shibu.jp/commandreference/)を適宜参照して下さい。

# 基本的なコード

上記の単純なSET/GETを、Redigoを使って行います。
始めにパッケージを取得します。

```
C:\Dev> go get github.com/gomodule/redigo/redis
```

単純なコードは次のようになります。

```go:main.go
package main

import (
	"fmt"

	"github.com/gomodule/redigo/redis"
)

func main() {
	// 接続
	conn, err := redis.Dial("tcp", "localhost:6379")
	if err != nil {
		panic(err)
	}
	defer conn.Close()

	// 値の書き込み
	r, err := conn.Do("SET", "temperature", "25")
	if err != nil {
		panic(err)
	}
	fmt.Println(r) // OK

	// 値の読み出し
	s, err := redis.String(conn.Do("GET", "temperature"))
	if err != nil {
		panic(err)
	}
	fmt.Println(s) // 25
}
```

始めに、`conn.Dial`でRedisサーバとの間で接続を確立します。
次に`conn.Do`でSETを実行します。第1引数にコマンド名、第2引数以降にパラメータを記述します。
最後に`conn.Do`でGETを行います。ここでは戻り値をさらに`redis.String`へ渡しています。`conn.Do`の結果はinterface{}型です。ここからstringを得るには[]byte型にキャストしさらにstringに変換する必要があります。煩雑なコードになるため、一発でstringを得る関数がイディオム的に用意されています。

実行結果は次の通りです。

```
C:\Dev> go run main.go
OK
25
```

# おわりに

Redisのセットアップと、Redigoでの基本的なSET/GETの行い方を見ました。
以降ではより高度な使い方を見ていきます。

# 参考

* [【Redis】Go言語で高速呼び出しKVS【Redigo】](https://qiita.com/chan-p/items/5c5e7cc1e966f8a90422)
* [GolangとRedisで遊んでみた](https://qiita.com/lightstaff/items/7428a37a24b4ad56f995)
* [Redigoを使う(2)　様々なデータ型を扱う](https://qiita.com/riverplus/items/04aa969d699c78f58598)
* [Redigoを使う(3)　トランザクションを行う](https://qiita.com/riverplus/items/5379111adda57f9ac18a)
* [Redigoを使う(4)　コネクションプールを使う](https://qiita.com/riverplus/items/12f9b37cf1795d9bdbb1)
* [Redigoを使う(5)　ユーティリティ関数](https://qiita.com/riverplus/items/a359ba7e74642a870440)
* [Redigoを使う(6)　パブリッシュ／サブスクライブ](https://qiita.com/riverplus/items/e31c6da6f5af28d3a3f7)
FOOBARキーボードを作る 【基板発注編】2018/9/1

前説
----
そもそもはレツプリを作りたいと思ってて、PCBも作らないとだめっぽいからいろんなサイトを眺めてた。基板屋さんはいろいろあるみたいだけど、いきなりは怖いからお試しの発注ができたらいいななんて安易な考えでネットサーフィン。

PCB発注
----
いろいろサイトを見た結果は、100mm角だったら安価に作ってくれるみたいだった。
でも送料という落とし穴があって、基板が2ドルでも送料が10ドル超えたりしてたんで結局少量の発注ではコストがかかるなーと実感。

たくさん作ったらいいかもしれないけど、個人的に作るんでそんなにいらないと思っていたら、FusionPCBで100mm角のPCBが送料込みで7.9ドルだったので、気絶したふりをして発注した。
スイッチを実装する基板とトッププレートを発注して合計15.8ドル。ボトムプレートはPCBじゃなくていいので発注はしなかった。

![Screenshot 2018-09-02 at 00.24.58.png](https://qiita-image-store.s3.amazonaws.com/0/283328/77d786c8-88a4-6c1b-80a0-19b67625e747.png)
https://www.fusionpcb.jp/prototype-pcb-sale.html

100mm角で収まるキーボードの基板と言ったら[FOOBAR](http://www.40percent.club/2017/09/foobar-10.html)な感じだったし、[ガバーデータ](https://github.com/di0ib/Misc/tree/master/foobar
)もサイトからダウンロードできるのがありがたい。

製造は早いけど何時届くかなぁ…
![Screenshot 2018-09-02 at 01.07.21.png](https://qiita-image-store.s3.amazonaws.com/0/283328/bb1f0bdf-9827-ba7a-0b82-1fc3f002292f.png)

参考にしたサイト
----
http://blog.youchan.org/2018-01-20
https://github.com/di0ib/Misc/tree/master/foobar
巨大な GeoJSON からファイルシステム上のベクトルタイルに落とす方法

GeoJSON からベクトルタイルに変換する Node.js プログラムである geojson2mvt の issues に、巨大な GeoJSON からの変換についての議論がありました。

この　issue では、geojson2mvt ではなくて tippecanoe と mbutil を使えば良いという話になり、具体的な方法も紹介されています。オープンソースらしい素晴らしい情報共有ですね。

https://github.com/NYCPlanning/labs-geojson2mvt/issues/13#issuecomment-417622380

ところで、ベクトルタイルをファイルシステムに展開せず、mbtiles からサーブする方が良い、という場合には、tippecanoe で mbtiles を作った上で、[tile-block](https://github.com/hfu/tile-block)　や　[tileserver-gl-light](https://github.com/klokantech/tileserver-gl)を使えば良いですね。
ChromeでPDFファイルを開いたら真っ白になる現象の解決法 (2018年9月)

# 現象
 - pdfのページを開くと、1,2秒後にページが真っ白になる 

# 解決策
 - 現状バグとして報告されているので、正常に機能するまでは解決待ちかと思いますが、暫定的な対策として**新規タブで開く**とこの現象が起きないことが確認されています。
 - 以下のリンクで報告されています。
 - https://bugs.chromium.org/p/chromium/issues/detail?id=870404
localhostでだけclickが複数回実行される？！

開発環境(localhost)に、Browser-sync使っているなら、この続きを読んでみてください。

```javascript
element.addEventListener('click', (e)=> {
    console.log(e); //コレなんぞ2回連続実行される。。
}, false);
```
なぜか、clickイベントのcallbackが2回走るんだよ！
なんでだよ、全然原因がわかんねーよ！！！

・・・って先日はまったのでメモ残します。

よくよく調べたら、原因はBrowser-syncのclickイベントでした。

Browser-syncのSync Optionsの設定で、ClicksをOFFにしてみましょう。
![image.PNG](https://qiita-image-store.s3.amazonaws.com/0/42905/f2fed666-d84f-ad51-a386-ccbcf42967a6.png)
自分の場合、ClicksをOFFにしたら、複数回clickイベントのコールバックが実行される現象が解消されました。

上記画面（Sync Optionsの設定）へのアクセス方法は、Browser-sync実行時に、
![image2.PNG](https://qiita-image-store.s3.amazonaws.com/0/42905/7fd79946-d8da-f048-2915-56fed149dcd5.png)
こんな情報が表示されますので、この**UI**に記載されたアドレス（上記画像例でいうと localhost:3001）を、ブラウザから開けば表示されます。