OmniAICreator/Qiita-1.07M huggingface dataset:
hard-source-webpack-pluginを使ってみた


# 概要

webpackのビルド時間短縮するために[thread-loader](https://github.com/webpack-contrib/thread-loader)や[cache-loader](https://github.com/webpack-contrib/cache-loader)を使ったり、一部のモジュールを[DLLPlugin](https://webpack.js.org/plugins/dll-plugin/)でバンドルに固めたりすると思います。

最近、モジュールの中間キャッシュを利用する[hard-source-webpack-plugin](https://github.com/mzgoddard/hard-source-webpack-plugin)を見つけて気になっていたので使ってみました。

---

# TL;DR

サンプルアプリで使ってみたところ、cache-loaderに比べてビルドは速かった

---

# 準備

cache-loaderを利用した場合とビルド速度を比べてみます。

ビルド時間の測定のために、vue2+vuexで作られた[vue-spa](https://github.com/skyronic/vue-spa)というSPAサンプルアプリを利用します。
もちろん、このプロジェクトにはcache-loaderもhard-source-webpack-pluginも入っていないので、それぞれ以下のバージョンで導入します。

```js:version
cache-loader => 1.2.0
hard-source-webpack-plugin => 0.5.15
```

いずれも5回連続でビルドしてみます。

---

## cache-loader

[README](https://github.com/webpack-contrib/cache-loader/blob/master/README.md)にキャッシュのr/wにオーバーヘッドがあるので重いローダーにのみ使うべきとあります。ただ、イマイチどれが重たいのか分からないのでとりあえずbabel-loader,vue-loader,css-loaderにcache-loaderを適用してみます。


```js:build/webpack.base.conf
{
  test: /\.vue$/,
  use: ['cache-loader',{ loader: 'vue-loader', options: vueLoaderConfig }]
},
{
  test: /\.js$/,
  use: ['cache-loader', 'babel-loader?cacheDirectory'],
  include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
},
```

```js:build/util.js
function generateLoaders (loader, loaderOptions) {
   var loaders = ['cache-loader', cssLoader]
```

---

## hard-source-webpack-plugin

pluginsに追加するだけ。とってもシンプル。

```js:build/webpack.prod.conf
plugins: [
  new HardSourceWebpackPlugin()
]
```

---

# 測定結果(`yarn build`)
## 素の状態

||1回目|2回目|3回目|4回目|5回目|
|---|---|---|---|---|---|
|ビルド速度(s)| 14.38 | 13.75 | 14.09 | 13.80 | 13.84

だいたい14sくらい

---

## cache-loader
||1回目|2回目|3回目|4回目|5回目|
|---|---|---|---|---|---|
|ビルド速度(s)|14.17 | 12.30 | 12.23 | 12.18 | 11.94 |

1回目以降は12sくらいでちょっと速い

---

## hard-source-webpack-plugin

||1回目|2回目|3回目|4回目|5回目|
|---|---|---|---|---|---|
|ビルド速度(s)|15.80 | **8.80** | **8.57** | **8.71** | **8.22** |

初回はconfigHashを作るためか素の状態に比べて少し遅いですが、**2回目以降は9sほどでたしかに速いです**

---

# まとめ

cahce-loaderに比べてビルドが速かったです。

ただ、READMEにも書かれているとおりwebpack-dev-serverを使う際に注意しなければいけない点があったり、他のプロジェクトで導入してみたところビルドが正常に終了しなかったりと不安定さを感じます。

実際にプロジェクトに本導入するまでとはいかないかもしれませんが、cache-loader使ってるけどもっと早くしたいよという場合であれば試験的に導入してみるのもいいかもしれないです。

また、今回は測定だけで中身まで見ていないので機会があれば実装も覗いてみたいと思います。
変数にデフォルト値を設定する


ある変数に値ガセットされていればそのまま。セットされていなければ設定する時のパターン

```fish
set -q hoge; or set -g hoge 100
```

確認

```
$ echo $hoge

$ set -q hoge; or set -g hoge 100

$ echo $hoge
100
$ set -q hoge; or set -g hoge 50

$ echo $hoge
100
```

# 関連

* [シェル変数のデフォルト値を設定する、未初期化時にエラーメッセージを出力してスクリプトを強制終了する](http://doi-t.hatenablog.com/entry/2013/12/08/161929)
Python > if lie is lie is lie: > is 演算子の書き換え(書換えできない) | 三重引用符 | operator chaining | link: Comparisons

https://stackoverflow.com/questions/48270127/can-a-1-a-2-a-3-ever-evaluate-to-true
> answered 14 hours ago
Eric Duminil

Pythonコードにて`=`の書換えをしているようだ。

試してみた。

https://ideone.com/KXo60n

```py3
class A:
    def __is__(self, who_cares):
        return True
	
lie = A()

txt = """no matter how white, how small, 
how incorporating of a smidgeon 
of truth there be in it."""

if lie is lie is lie:
     print(txt)
```

```txt:run
no matter how white, how small, 
how incorporating of a smidgeon 
of truth there be in it.
```

関連: [技術英語 > There is a little truth in what she says. / A lie is a lie is a lie.](https://qiita.com/7of9/items/79b287a462cb79cfcbbf)

### 備考

演算子の書換えは、コードの意図が分からなくなるから、自分は使わないことにしている。

[What are the basic rules and idioms for operator overloading?
](https://stackoverflow.com/questions/4421706/what-are-the-basic-rules-and-idioms-for-operator-overloading)

### 参考

[トリプルクオーテーション](https://www.pythonweb.jp/tutorial/string/index3.html) @ PythonWeb
検索用キーワード: 三重引用符

http://thepythonguru.com/python-operator-overloading/

### is演算子は書換えできない

@LouiS0616 さんの[コメント](https://qiita.com/7of9/items/574da7ae55e543b02679/#comment-08abfe15a8818db33ea0)
によってis演算子は書換えできないことが分かりました。

情報感謝です。

### link

[Stackoverflow](https://stackoverflow.com/questions/48315777/understanding-if-lie-is-lie-is-lie)
での質問で得られた回答について有用な言葉とリンクを整理しておきます。

- operator chaining
- [6.10 Comparisons](https://docs.python.org/3/reference/expressions.html#comparisons)
- [10. Full Grammar specification¶](https://docs.python.org/3/reference/grammar.html)
QiitaにCodePenを埋め込んで遊んでみる

[Qiitaで記事にCodePenが埋め込めるようになりました](https://qiita.com/Qiita/items/edae7417214c8e957f54) との事なので、CodePenを埋め込んでみる。

## 仕様

### プレビュー時

> 現在のところ、エディタのプレビューには貼り付けたCodePenは表示されない仕様となっております。ご了承ください。

確かにプレビュー時は以下のような表示になっている。

> ![image.png](https://qiita-image-store.s3.amazonaws.com/0/220757/6c778968-c973-7787-653f-d084b47e5b68.png)


## `alert()`を表示させるサンプル

<p data-height="265" data-theme-id="0" data-slug-hash="zpMqKM" data-default-tab="js,result" data-user="kikuchi-hiroyuki" data-embed-version="2" data-pen-title="Qiita embed test" class="codepen">See the Pen <a href="https://codepen.io/kikuchi-hiroyuki/pen/zpMqKM/">Qiita embed test</a> by kikuchi hiroyuki (<a href="https://codepen.io/kikuchi-hiroyuki">@kikuchi-hiroyuki</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://production-assets.codepen.io/assets/embed/ei.js"></script>

今日現在(2018/01/18 9:27)、記事を表示するとCodePen内のalertが表示されて鬱陶しい。

## 感想

動作サンプルを見せる時めっちゃ便利なんだけれど、その目的外で遊ばれないか心配。
Serverspecオフラインインストール

インターネットに接続できない環境にてServerSpecをインストールする。

ほぼほぼ以下のサイト参照となります。
※バージョンを上げたためか、必要パッケージは下記サイトより増えています。

Serverspec (2/3) ：スタンドアロン環境へのServerspecインストール
https://qiita.com/pideo/items/1f2c653a980a5a4a858a

## 構成

今回実施したサーバおよびPPは以下の通り。
(2018/1/17時点での最新安定版を使用)


OS:RHEL 7.4.1708(3.10.0-693.el7.x86_64)
Ruby:2.5.0
RubyGems:2.7.4
Serverspec:2.41.3

## 資材のダウンロード

- Rubyのダウンロード
    以下からダウンロード、/tmpに格納
    __Ruby 2.5.0__
    https://www.ruby-lang.org/ja/

- RubyGemsのダウンロード
    以下からダウンロード、/tmpに格納
    __RubyGems v2.7.4__
    http://rubygems.org/pages/download


- Serverspecのダウンロード
    必要パッケージをダウンロード、/tmp/serverspecに格納。
    __serverspec 2.41.3__
    http://rubygems.org/gems/serverspec
    __specinfra 2.73.1__
    http://rubygems.org/gems/specinfra
    __highline 1.7.10__
    http://rubygems.org/gems/highline
    __rspec 3.7.0__
    http://rubygems.org/gems/rspec
    __net-ssh 4.2.0__
    http://rubygems.org/gems/net-ssh
    __rspec-mocks 3.7.0__
    http://rubygems.org/gems/rspec-mocks
    __rspec-expectations 3.7.0__
    http://rubygems.org/gems/rspec-expectations
    __rspec-core 3.7.1__
    http://rubygems.org/gems/rspec-core
    __diff-lcs 1.3__
    http://rubygems.org/gems/diff-lcs
    __multi_json-1.13.1__
    http://rubygems.org/gems/multi_json
    __net-scp-1.2.1__
    http://rubygems.org/gems/net-scp
    __rspec-its-1.2.0__
    http://rubygems.org/gems/rspec-its
    __rspec-support-3.7.0__
    http://rubygems.org/gems/rspec-support
    __sfl-2.3__
    http://rubygems.org/gems/sfl


- gcc関連のインストール※
	※gcc,c++関連がインストールされていない場合、
	rubyのconfigureコマンド発行時にエラーが発生する。
	資材の取得はインストールDVDから実施し、以下パッケージを導入。
	
	gcc,gcc-c++

- zlib,readline,opensslのインストール※
	※zlib,readline,openssl関連をインストールしていないと
	Serverspecのインストール時に
	「no such file to load --zlib | readline | openssl」系のエラーが出る。

	zlib,readline,opensslはcentosのデフォルトで最初からインストールされていたが
	以下はインストールされていなかったため、DVDから入手してインストールしておく。

	zlib-devel,readline-devel,openssl-devel

## Serverspecのインストール

Serverspecのインストール要件であるRubyとRubyGemsをインストールする。

  1. Rubyのインストール
	
	```bash
	cd /tmp
	tar zxvf ruby-2.5.0.tar.gz
	cd ruby-2.5.0
	./configure
	make
	make install
	```

  1. RubyGemsのインストール

    ~~~bash
	cd /tmp
	tar zxvf rubygems-2.7.4.tgz 
	#「tar: 未知の拡張ヘッダキーワード `SCHILY.~' を無視」
	# のメッセージが出るが、無視

	cd rubygems-2.7.4
	ruby setup.rb 

	~~~



  1. Serverspecのインストール

    ~~~bash
	cd /tmp/serverspec
	gem install serverspec --local

	~~~

以上で、インストール完了。
docker swarm でゾンビ化したコンテナを掃除する

先月リリースされたdocker 17.12を使用していますが、docker swarmを使っていると、何かの拍子にserviceに属するコンテナがゾンビ化して削除できない状態に陥るケースがあるようです。(See [Why I cannot stop, kill, rm a zombie container in swarm mode?](https://github.com/moby/moby/issues/35908#issuecomment-354986070))

ゾンビ化したコンテナは`docker service ps` ではtaskとしてリストアップされないのに `docker ps`ではリストアップされ存在を確認できる状態になります。

**何が困るか**

```
nslookup tasks.<service-name>
```
DNSで名前を解決しようとするとゾンビコンテナのIPが含まれており、`service update` で更新を行っても古い状態のコンテナが生き残り続けてしまいます。


そのうち修正されることを期待したいですが、現状では以下のようにすればゾンビコンテナを掃除できるようです。

1. `docker ps --no-trunk`でゾンビコンテナのIDを調べる
1. ゾンビコンテナが存在するホストで、`ps aux | grep <container id>`コマンドで対応するdocker-containerd-shimプロセスのPIDを調べる
1. `kill <PID>`
arduinoでi2c　その5

#概要
arduinoでi2cやってみた。
フルスクラッチでslave書いてみた。


#写真
![CIMG2523.JPG](https://qiita-image-store.s3.amazonaws.com/0/18104/525189a7-625f-1502-b48c-4cba3f0409da.jpeg)



#サンプルコード


```
#include <inttypes.h>
#include <compat/twi.h>

#define TWI_STX_ADR_ACK					0xA8
#define TWI_STX_ADR_ACK_M_ARB_LOST 		0xB0
#define TWI_STX_DATA_ACK		   		0xB8
#define TWI_STX_DATA_NACK		  		0xC0
#define TWI_STX_DATA_ACK_LAST_BYTE 		0xC8
#define TWI_SRX_ADR_ACK					0x60
#define TWI_SRX_ADR_ACK_M_ARB_LOST 		0x68
#define TWI_SRX_GEN_ACK					0x70
#define TWI_SRX_GEN_ACK_M_ARB_LOST 		0x78
#define TWI_SRX_ADR_DATA_ACK	   		0x80
#define TWI_SRX_ADR_DATA_NACK	  		0x88
#define TWI_SRX_GEN_DATA_ACK	   		0x90
#define TWI_SRX_GEN_DATA_NACK	  		0x98
#define TWI_SRX_STOP_RESTART	  		0xA0

uint8_t t = 0;

void i2c_init(uint8_t dat)
{
}
void Rx(uint8_t dat)
{
	t = dat;
}
uint8_t Tx(void)
{
	t++;
	return t;
}
void setup()
{
	uint8_t adrs = 0x55;
	adrs <<= 1;
	TWAR = adrs;
	TWCR = (1 << TWEA) | (1 << TWEN);
}
void loop()
{
	if (!(TWCR & (1 << TWINT))) return;
	switch (TWSR)
	{
	case TWI_SRX_ADR_ACK:
		i2c_init(TWDR);
		TWCR = (1 << TWEA) | (1 << TWEN) | (1 << TWINT);
	break;
	case TWI_SRX_ADR_DATA_ACK:
		Rx(TWDR);
		TWCR = (1 << TWEA) | (1 << TWEN) | (1 << TWINT);
	break;
	case TWI_STX_ADR_ACK:
		i2c_init(TWDR);
		TWDR = Tx();
		TWCR = (1 << TWEA) | (1 << TWEN) | (1 << TWINT);
	break;
	case TWI_STX_DATA_ACK:
		TWDR = Tx();
		TWCR = (1 << TWEA) | (1 << TWEN) | (1 << TWINT);
	break;
	case TWI_STX_DATA_NACK:
	case TWI_SRX_STOP_RESTART:
		TWCR = (1 << TWEA) | (1 << TWEN) | (1 << TWINT);
	break;
	}
}



```


以上
MongoDB 詰まった所メモ


#概要
MongoDBのEmbedded Documentにおいて詰まった所をメモします。


###MongoDBのデータの保存の仕方について。
MongoDBはNoSQLデータベースと分類されており、「ドキュメント」と呼ばれる構造的データをJSONライクな形式で表現し、そのドキュメントの集合を「コレクション」として管理する。
（Wikiより引用)
つまり従来のRDBMSと違い、テーブルにデータを保存していくのではなく、全てを連想配列のような形で保存しています。
※その他のMongoDBについての用語や仕組みは[Wiki](https://ja.wikipedia.org/wiki/MongoDB)を参照

#作成
Node.jsでMongoDBを扱うためにmongooseというライブラリを利用します。

<b>インストール</b>

```
$ npm install mongoose
```


##スキーマ定義
今回はToDoリスト作成し、スキーマを下記の通りに設定。

```javascript:sampleSchema.js
var Schema = mongoose.Schema;
var todoSchema = new Schema({
  tf: {
    type: Boolean,
    default: false
  },
  content: String,
  createdDate: {
    type: Date,
    default: Date.now
  },
  limitDate: Date
});
var todoList = new Schema({
  listName: String,
  createdDate: {
    type: Date,
    default: Date.now
  },
  details: [todoSchema]
});
mongoose.model('Todo', todoList);
```
MongoDB にはドキュメントの中にドキュメントを埋め込む Embedded Document という概念があります。

上のsampleSchema.jsを例に説明すると、
todoListというスキーマを定義する際に、todoSchemaをdetailsというフィールドの値として保存しています。
こうすることでToDoリストのデータ構造は下の状態になります。

- ToDoリスト
    - ToDoリスト名
    - ToDoリスト作成日
    - 詳細
        - ToDo1
            - チェック
            - 内容
            - ToDo作成日
            - 期限
        - ToDo2
            - チェック
            - 内容
            - ToDo作成日
            - 期限

もしここでEmbedded Documentしなかった場合、データベースが第1正規形のようにただのデータの羅列になってしまい、のちにfindする際にクエリが複数必要となってしまうので注意です。

##ドキュメントの追加
mongooseにはsaveというメソッドがあり、

```javascript:sampleMethod.js
var Todo = mongoose.model('Todo');
var todo = new Todo();
todo.listName = 'リスト名';
todo.save();
```
上のsampleMethod.jsのようにmodel新規作成->saveで格納でき、更にIDの割り当ても自動でやってくれます。

では、新たにドキュメント内のドキュメントに追加するにはどうするか？

```javascript:sampleAddTodo.js
var Todo = mongoose.model('Todo');
    Todo.findOne({query}, 
    function (err, todos) {
      var todo = {};
      todo.tf = false;
      todo.content = '内容';
      todo.limitDate = limit;
      todo.createdDate = Date.now();
      todos.details.push(todo);
      todos.save(function (err) {
        // ...
    });
});
```

コレクションを検索
↓
配列作成
↓
作成した配列をドキュメントに追加

この方法で追加できます。このやりかたでもIDの割り当てが自動でされるのでとても便利です。

##検索
正直、検索が一番躓きました。
まずは、クライアントのチェックに応じてtrue/falseを変える場合

```javascript:sampleUpdate.js
Todo.findOneAndUpdate({query}
      $set: {
        'details.$.tf': true/false
      },
      function (err, todos) {
          // ...
});
```
[$]にたどり着くまでが一番時間がかかりました。[参照1](https://docs.mongodb.com/manual/reference/operator/update/set/) [参照2](https://stackoverflow.com/questions/15691224/mongoose-update-values-in-array-of-objects)

そして、ToDo・ToDoリストを検索する場合

```javascript:sampleUpdateTodo.js
Todo.find({
    $or: [{
        listName: new RegExp('.*' + '検索名' + '.*', 'i')
      },
      {
        'details.content': new RegExp('.*' + '検索名' + '.*', 'i')
      }
    ]
  }, function (err, todos) {
    // ...
  });
```
MongoDBの特徴として、検索の際に正規表現検索が使えるのでRegExpを使います。文字列(検索名)を全文検索することができます。
こちらは、[$]は用いません。難しい。

#おわりに
後半適当になってしまい申し訳ありません。NoSQLではMongoDBはライブラリも充実してますし導入にはいいなと思いました。興味ある方は初めてみることをお勧めします。最後までご覧頂きありがとうございました。

##参考サイト
[ node.js から MongoDB にアクセス (Mongoose の紹介) - KrdLab's blog](http://krdlab.hatenablog.com/entry/20110317/1300367785)
React.jsで「こんにちは」を、Qiitaの記事上にcodepenで埋め込みました

# ただ新機能を使ってみたかったんです。
[Qiitaで記事にCodePenが埋め込めるようになりました](https://qiita.com/Qiita/items/edae7417214c8e957f54)
という記事を拝見しましたので、早速埋め込んでみました。

# CodePen便利ですね
すぐにReact.jsを扱えました。LESSとかSCSSとかもちょこちょこ触ってみたいです。

<p data-height="265" data-theme-id="0" data-slug-hash="mpzgWg" data-default-tab="js,result" data-user="ke1ta" data-embed-version="2" data-pen-title="mpzgWg" class="codepen">See the Pen <a href="https://codepen.io/ke1ta/pen/mpzgWg/">mpzgWg</a> by keita (<a href="https://codepen.io/ke1ta">@ke1ta</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://production-assets.codepen.io/assets/embed/ei.js"></script>

# React.jsの書き方が独特というか初見じゃ分からない。
もちろん知識が全然無いという僕のステータスが大前提ではありますが、かなり独特な印象はやっぱり持ちました。
とはいえ、知的好奇心はくすぐられてしまうのでまた遊んでみます。
(まずはSwiftやります。。。）
pyenv+anaconda3+tensorflowの環境構築メモ

学校の授業でTensorFlowを使うことになったので、その際の環境構築メモ。
pyenv導入〜TensorFlowインストールまで、メモしておこうと思います(WSLでも後ほどやってみようかと思います)

## pyenv+anaconda3導入
pyenvとanaconda3の導入は下記サイトを参考にしました
[pyenv + anaconda + python3](https://qiita.com/sk427/items/9f215931c8249ada75cd)
またはpyenvのみの導入はこちらでの方法もあるみたいです
[Pyenvの使い方](https://qiita.com/mogom625/items/b1b673f530a05ec6b423)
どちらもpyenvのディレクトリは変わらない様なのでお好きな方法で導入していただけたらと思います。

```
git clone https://github.com/yyuu/pyenv.git ~/.pyenv
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init -)"' >> ~/.bashrc
source ~/.bashrc
pyenv install -l | grep anaconda3 (anacondaのパッケージ一覧を表示)
pyenv install anaconda3-5.0.1 (最新バージョンのanaconda3をpyenvにインストール)
echo 'export PATH="$PYENV_ROOT/versions/anaconda3-5.0.1/bin/:$PATH"' >> ~/.bashrc
source ~/.bashrc
conda update conda
```

前者のqiita記事を参考に上記コマンドを入力するとpyenv+anaconda3の導入は完了です。(当方はrehashやglobalコマンドは使用していません)
また、anaconda3のインストールに少々時間がかかるようなので、コーヒーでも飲みながら気長に待ちましょう。

## 仮想環境構築〜TensorFlowインストール
上記にてpyenv+anaconda3の導入は完了しましたので、ここからはTensorFlowを使うための仮想環境を作ります。
`conda create -n tensorflow python=3.5`　と打ち込み仮想環境を作ります。
(仮想環境名は好きな名前で構いませんが、今回はtensorflowを使いますので分かりやすくするためこの名前にしております。また、pythonバージョンを3.5にするため **python=3.5** とオプションをつけています)
次に、上記で作った仮想環境をactivateします
`source activate tensorflow`
そうするとこのような画面になります
![Screenshot from 2018-01-18 02-48-03.png](https://qiita-image-store.s3.amazonaws.com/0/230050/873bc63f-699c-cd68-c225-a697d8219d55.png)
()があるか無いかで仮想環境をactivateしたかどうかがわかるかと思います。
activateした状態で以下のコマンドを打ちます。
`pip install --ignore-installed --upgrade tensorflow`
打ち込むと何やらダウンロードのプログレスバー的なのが出てきますので、完了まで待ちましょう。(そこまで時間はかからないと思います)

## 動作検証
ダウンロードが完了し、ターミナルがコマンド入力待ちになりましたら、tensorflowを使えるかどうか検証します。
`python`と打ち、python shell画面になり以下コードを記入します

```
import tensorflow as tf
hello = tf.constant('Hello TensorFlow')
sess = tf.Session()
print(sess.run(hello))
```

すると以下画面になるかと思います
![Screenshot from 2018-01-18 02-54-24.png](https://qiita-image-store.s3.amazonaws.com/0/230050/b5af8258-56ea-132c-7bab-f9b29f1acb6f.png)

`b'Hello TensorFlow'` と出力されれば検証成功です。(Session()代入時のメッセージの意味がイマイチ理解できていませんが、使用自体には問題なさそうなので無視しています)

また仮想環境でIDLEを使用するとき、`idle3`と打ち込まないと3.5で実行できないのでそちらも注意しておきたいです。(activate後、`idle`と打ち込むと3.6になってしまい、授業配布のサンプルが実行できませんでした)

以上メモとなります。記述ミス等ありましたら指摘していただけると助かります。
WSLでも環境構築はできますが、IDLEがGUIで起動するのかがわからないので後ほど検証してみたいと思います。
SwiftでPAY.JPを試してみたけど、10分で決済までできた。

#はじめに
決済系のサービスに今まで触れたことなかったので、試しに触ってみました。
何がきっかけか忘れましたが、PAY.JPというワードが記憶に残ってたのでそれを今回試してみます。


#PAY.JPとは
決済サービスです。Webにもアプリにも簡単に決済システムを組み込めます。
ベンチャー向けのプランでは決済手数料2.59%〜とのことです。安いのかな？
ApplePayにも対応していて専用のSDKが用意されているようです。

#以下ざっくりとした作業内容

https://pay.jp/docs/mobileapp-ios
ここにある通りですが、一応メモがてら自分のやったことを記載しておきます。

##会員登録を済ます
ここから会員登録を済ましておきます。
https://pay.jp/

##ダッシュボードにアクセスし、公開鍵と秘密鍵をメモっておく
ダッシュボード左側メニューの設定を押すと「APIキー情報」というのがあるので、そこに記載のある公開鍵と秘密鍵をメモっておきます。

![スクリーンショット 2018-01-18 2.16.15.png](https://qiita-image-store.s3.amazonaws.com/0/112614/ba3c09b8-baae-8ce6-0cf6-612df6de8631.png)

##サンプルコードを使って試す。
・PAY.JP公式のサンプルコードがあるので落とします。
https://github.com/payjp/payjp-ios

・それをカルタゴでビルドする

```
$ carthage update --platform iOS
```

・サンプルコード内の公開鍵を変更する。

```swift:ViewController.swift
let PAYJPPublicKey = "pk_test_6b..........." // ここをメモっておいたテスト公開鍵に変更。
```


・アプリを起動します

![IMG_9199.PNG](https://qiita-image-store.s3.amazonaws.com/0/112614/bff78fca-50e2-00d2-efc9-26e7ee15241c.png)



・Create Tokenを押すとトークンが生成される。

![IMG_9200.PNG](https://qiita-image-store.s3.amazonaws.com/0/112614/6cde8aef-f934-b229-77d2-ed34aeaac4fd.png)


セキュリティ保護の観点からクレジット情報はそのまま保管せず、トークン化します。
このトークンをサーバーに送り、決済を行います。

##決済までしてみる。
決済処理までやろうとするとサーバー側も組む必要が出てくるので、今回は簡略化のためcurlでやってみます。

```
curl https://api.pay.jp/v1/charges \
-u sk_test_******（メモっておいた秘密鍵）: \
-d "amount=500" \
-d "currency=jpy" \
-d "card=さっき生成したトークン"
```

##ダッシュボードを確認すると売上が計上されている。
![スクリーンショット 2018-01-18 2.24.11.png](https://qiita-image-store.s3.amazonaws.com/0/112614/66e35652-f9ad-761e-cfc7-758c91f4e473.png)




#最後に
非常に簡単に導入できました。個人アプリを考えるときも決済がネックだったのでこれは助かります。
実際はサーバー側も書く必要がありますが、公式のライブラリも充実してそうなので、なんとかなりそうです。

https://pay.jp/docs/library
>公式ライブラリ
Python
Ruby
PHP
Java
Node
Perl
Go
iOS
Android

Python Flaskのサンプル
https://pay.jp/docs/flask-checkout
Ruby Sinatraのサンプル
https://pay.jp/docs/sinatra-checkout


また、公式マニュアルにも書いてある通り、トークンは一回しか使えないのでこれだとユーザーは毎回クレジットカード情報を入れる必要がありとても面倒です。
>トークンは一度しか使用できないので、先ほどの例では、支払いのたびに購入者にカード情報を入力させなければいけません。 これを避けるため、トークンを顧客情報に紐付けておくことで、2回目以降はカード情報を入力せずに何度でも支払いができるようになります。

なので、そのうち顧客情報にトークンを紐づけるパターンもやってみて記事にしようと思います。



参考
https://github.com/payjp/payjp-ios
https://pay.jp/docs/mobileapp-ios
【MAYA】あるファイル名に似た名前のファイル一覧を同じフォルダから探す

同じフォルダから名前が似たファイルを探す処理が必要になったので、difflibモジュールとやらを使って、ざざっとクラスにしてみた。動作確認までして思ったけど、mayaが関係ない処理だった。
とはいえ、MAYA上で動作確認してるし、この後の記事で登場するかもしれないので、mayaの記事と言うことにしておく。

`MAYA 2018` + `MacOS Sierra` および、 `MAYA 2017` + `Windows10 Pro` で動作確認しました。


##作成したクラス

```python
import os
import difflib

class SimilarFilenameFinder(object):
    """
    あるファイル名に似た名前のファイル一覧を同じフォルダから探す
    """

    def __init__(self, threshold=0.0):
        """
        :param threshold: 敷居類似度 ここより低い類似度は結果としない
        :type threshold: float
        """
        super(SimilarFilenameFinder, self).__init__()
        self.threshold = threshold
        self._matcher = difflib.SequenceMatcher()

    def find_in_same_folder(self, base_file_name, folder_path=None):
        """
        あるファイル名に似た名前のファイル一覧を同じフォルダから探す

        :param base_file_name: 対象フォルダ（未指定でファイルと同じ階層)
        :type base_file_name: str
        :param folder_path: 探索ファイルパス(もしくは名前のみ)
        :type folder_path: str
        :return: ファイル一覧 と 類似度一覧 (indexが同じもので紐付けて使う)
        :rtype: lisr of str, and list of float
        """
        similar_files_info = []
        if folder_path is None:
            folder_path = os.path.dirname(base_file_name)
        if not os.path.isdir(folder_path):
            # フォルダが取得できないのでNoneを返す
            return None, None
        if not os.path.isfile(base_file_name):
            # ファイル名ではないのでNoneを返す
            return None, None
        files = os.listdir(folder_path)
        self._matcher.set_seq1(os.path.basename(base_file_name))
        for f in files:
            if os.path.join(folder_path , f) == base_file_name:
                # 自分との比較は省く
                continue
            file_name = os.path.basename(f)
            self._matcher.set_seq2(file_name)
            similar_ratio = self._matcher.ratio()
            if similar_ratio >= self.threshold:
                similar_files_info.append({'name': file_name, 'ratio': similar_ratio})
        similar_files_info.sort(key=lambda x: 1.0 - x['ratio'])
        return [x['name'] for x in similar_files_info], [x['ratio'] for x in similar_files_info]
```


## 使い方の例

類似度が高い順で、周りのファイル名一覧が帰ってきます。

```python
sf = SimilarFilenameFinder(0.1)
found_files, ratios = sf.find_in_same_folder(
        '/git/hogehoge/README.md') # ファイルパスを指定する
if found_files is not None:
    for i, _ in enumerate(found_files):
        print(found_files[i], ratios[i])

# 以下、出力例
#('LICENSE.md', 0.5263157894736842)
#('BUILD.md', 0.47058823529411764)
#('.idea', 0.2857142857142857)
#('img', 0.16666666666666666)
#('.git', 0.15384615384615385)
#('Gemfile', 0.125)
#('Rakefile', 0.11764705882352941)
#('.DS_Store', 0.1111111111111111)
#('.gitignore', 0.10526315789473684)
```
【AWS】Redhat系OSのライセンス確認

# AWSのAPIでライセンス確認

対象のES2インスタンスにログインして、以下のコマンドを実行する

```
curl http://169.254.169.254/latest/dynamic/instance-identity/document |grep billingProducts
```

### ■ 実行結果
```
[ec2-user@ip-10-0-1-218 ~]$ curl http://169.254.169.254/latest/dynamic/instance-identity/document |grep billingProducts
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
115   463  115   463    0     0   334k      0 --:--:-- --:--:-- --:--:--  452k
  "billingProducts" : [ "bp-xxxxxxx" ],

```

**「null」でなければライセンスが付与されている**

**ライセンスが付与されていないインスタンスではyumが実行出来ないなどの問題が発生する**
MongoDBの自動起動設定

## 起動・停止スクリプト

```
vi /etc/init.d/mongodb
```

```
#!/bin/bash
#
# chkconfig: 2345 99 14
# description: mongodb.

CONFIG_PATH="/etc/mongodb/conf/mongodb.conf"
PIDFILE_PATH="/var/run/mongodb"
TYPE="MongoDB of Shard"

case "$1" in
  start)
        echo "$TYPE Start"
        mkdir -p $PIDFILE_PATH
        /usr/bin/mongod -f $CONFIG_PATH
        ;;
  stop)
        echo "$TYPE Stop"
        /usr/bin/mongod --shutdown -f $CONFIG_PATH
        ;;
  restart)
        echo "$TYPE Restart"
        /usr/bin/mongod --shutdown -f $CONFIG_PATH
        /usr/bin/mongod -f $CONFIG_PATH
        ;;

  *)
        echo $"Usage: HOGE {start|stop|restart}"
esac
```

## 自動起動設定

```
chmod u+x /etc/init.d/mongodb
chkconfig --add /etc/init.d/mongodb
chkconfig mongodb on
```
Unityでリリース前に気をつけること For Windows

2018/1/24 編集　黄泉口製薬
本稿ではunityでスタンドアローンとしてリリースする際に気をつけることをまとめるものである。
また、いつの間にか追記で増えることがある。そしてコメント欄にて他にもあればご指摘ください。

筆者環境　unity2017.2.2　 MacOS  high sierra

## 画像について 
unityで使うsprite画像だが、こちらがインポートしたものは縦横ともに2のべき乗か4の倍数でなくてはならない。また、なるべく2のべき乗がよい。
2のべき乗例　1024*1024
４の倍数例 200*200 px

もし2のべき乗か４の倍数でないならメモリを必要以上に大量に使用することになり、メモリ不足で死ぬ。
例（10MBの画像を使用　→　500MBくらいの画像になっている）
スタンドアローンとしてビルドしたときに起こるため、リリースし低スペックPCを使っている顧客のクレームで気づくことになる。
ちなみにwin7 32bit メモリ4G　の環境下だと上記1MBの画像一枚でも死ぬ可能性がある。
さらに補足するなら低スペでも動くようにしたいなら長辺の長さの最大は1024までがいい。

## 音について
BGMのような長めの音楽を扱う際にInportSettingの
Conpression Format（圧縮形式）は Vorbisがいい
もし圧縮形式がPCMでかつ　Decompress Onloadオプションの場合展開時に
10MB -> 30MB　になり
予想よりメモリが足らなくて落ちる場合がある。

## Fontについて
日本語を使っている以上フォント周りのトラブルは絶えない。
ざっくり説明するとそのフォントのInportSettingで
フォント使用時にそれがDynamic設定にしていると一度全てのフォントデータがテクスチャとして開かれる。あと他多数。によってメモリ不足で死ぬ場合がある。
これに関しては説明すると長い上にプラットフォームに寄るため申し訳ないが略します。
公式のリファレンスをみて・・・・・・
https://docs.unity3d.com/ja/540/Manual/class-Font.html

##DirectX
現在最新のWindows updateをかけていればDirectXのバージョンは11(win7,8)か12(win10)だ。
しかし世の中にはあえてDirectXのバージョンを9か10のしている人が一定層いる。
理由としてはやりたいゲームがそれにしか対応してないからというのが多い。で、そのゲームが終わった後もバージョンをそのままにしていて忘れているパターンが多い。とくにwin7などは更新がすでに自動でかからないためそのパターンが多い。
で、unityなのだがいつのまにかDirectX 9,10のサポートを打ち切っている。
その関係上スタンドアローン時に動いたり動かなかったりする。
うちの環境だと動くんだけどユーザーがわでは・・・という場合これを疑って見るといいかもしれない。
対処法は当方では分かりかねるのでユーザーにDirectXのバージョンアップを呼びかけるしかない。
一応その設定はPlayer Setting /Other Setting/Auto Graphics Api　for windows
のチェックを外すことで見ることができる。



##ビルドしたいプラットフォームがない
あれ？android向け、Mac向けに、windous向けにビルドしたいのに・・・ビルドセッティングに表示されない・・？
というとき、もう一度Unityインストーラーを実行して見ると途中でビルドターゲットの欄があるのでそこでいれる。
ただ、色々いれるとビルド時間が若干伸びる。
また、アップデートによりAndoroid　sdkも現行Unityに含まれている。


##圧縮 
これはMac User向けだがMacでZip圧縮したものをWindowsで解凍すると文字コードの違いによってバグることがある。ただWindows8　以降だとこれの解消を担保されている。
そのため、たとえMacでビルドして作ったとしてもWindowsに未圧縮のものを入れて圧縮したほうがいい。
というかこれはunity以外でもだが

##圧縮その２
マルチプラットフォームだからとWindows向けもMac向けもとフォルダに入れ（フォルダは別）圧縮するとバグることがある。
別々に配布するか、Mac用のファイルだけ別で圧縮しよう。

##文字コード 
Macでビルドしてwindowsで起動した時（またはその逆）Macでは動作する部分がwindowsでは動作しない、または文字化けしている時、文字コードが関係している可能性がある。
また、windows7では上記が起こるがそれ以降の8以降のOSでは上記が起きない場合も含まれる。
これはWindows向けにビルドする時Windowsで行えば一応回避できる。

##Update
A機では正常、B機ではバグがでる。この機器二つにスペック差がある場合。
スタンドアロンにおいて例として以下のようなプログラムを持つ場合バグ・・というよりも
それぞれで動作が異なってしまう。
例
update内においてオブジェクトのトランスフォームポジションでまっすぐ移動するようにする。
コルーチンによってオブジェクトはX秒後に消える。

これだと機器スペックによって消えるまでの移動距離が変わる場合がある。
上記はあくまで例であり、その他にも考えられる。
とりあえず上記であればTween系ライブラリを使えば解決する。


とりあえず以上。
雲の上の人になろう！

# 社内LT大会でスピーカーしてきました
- 資料です。


# 最近MacBookPro買いました:stuck_out_tongue_closed_eyes:

<!---
買ったはいいがいままのでWinの環境を移行したい・・・
--->

---

# 一から環境を作るのは面倒:weary:
## そもそも移行できないのもある......
## 試してみたいだけなのに環境構築に時間取られるのは嫌！:rage::rage::rage:

---

# ならローカル環境を捨てよう！
## =>ブラウザだけで開発したい......:thinking:

<!---
Vimmerなら余裕なんでしょうかね？？
--->

---

# [AWS Cloud9](https://aws.amazon.com/jp/cloud9/)

![cloud9.png](https://qiita-image-store.s3.amazonaws.com/0/177957/0a95c189-071d-462a-22c1-fe0ad30cb1f9.png)


<!---
去年の12月にCloud9.ioがAmazonに買収されて結果的にまたAmazonの回し者になってしまいましたｗ
--->

---

# なにができるの？

---

## <font color="Red">**５分で構築完了!**</font>
![lang.png](https://qiita-image-store.s3.amazonaws.com/0/177957/9528a53b-f6a0-3141-ea13-56d56891d282.png)

<!---
他にも40種類の言語・環境が利用可能！
--->

---
## ブラウザ用IDEで、すぐ<font color="Red">**開発!!!**</font>
![Screenshots_tulip_03_1x.8dd9da76bd4975e09f640b73d4fecb9848c03031.png](https://qiita-image-store.s3.amazonaws.com/0/177957/8eb9f59a-3b35-6dd6-0631-88dc5ce34684.png)

<!---
オートコンプリート、リアルタイムデバッキング等基本的なIDEの機能はもちろん！
--->

---

## 複数人でのリアルタイムコーディング
![C9-Collab-Image@3x.e03a65d9488633c154358430540ab363dd1e8f45.png](https://qiita-image-store.s3.amazonaws.com/0/177957/4e5c475e-6e1c-5a8c-c43b-07edc19c46c0.png)

<!---
IDEから直接チャットができるので
ペアプロに良さそう
編集履歴もあってRevertもあるのでGitいらないかも？
--->


---

# [デモ](https://aws.amazon.com/jp/cloud9/)

<!---
じかんかかるかもだから別タブで開いとく
--->


---

# 使ってみた感想 
- 外出先でコーディングすることが多くなった
- <font color="Red">**AndroidでもiOSでもIDEが使える！**</font>  
  =>KindleFire7(3000円)でも動くことを確認
- 絶対これでペアプロ楽しい

<!---

ChormeもしくはFireFoxが使える環境なら端末は選ばないので
AWSのアカウントさえ用意して、人数分IAMユーザー作れば
1人頭10000円以内(端末+無線キーボード)で準備ができます。
構築コストもほぼ0です。
あとはEC2のインスタンス代だけ。
セッション切れたら自動で切ってくれたりもする。

--->

---

# **あれ？MBP買った意味？**:fearful:
Amazon Linux2上にwordpressをインストールした際につまづいたこと＆その対処方法メモ

久々に自分のAWS環境のEC2上にWordpressのインストールしようと思った
かつ
最近出たAmazon Linux2上にインストールした時に
若干ハマったので、その内容と解決方法をメモっておきます。
また作るとき用に残しておきます。

## 自動起動方法

Amazon Linuxで使えた自動起動の設定のコマンドですが、サービスの設定方法が変わっているらしく、

>$ sudo chkconfig httpd on

を実行すると、使えないらしく、以下のようなメッセージを出してくれます。

>Note: Forwarding request to 'systemctl enable httpd.service'.
Created symlink from /etc/systemd/system/multi-user.target.wants/httpd.service to /usr/lib/systemd/system/httpd.service

ということで、

> $ sudo systemctl enable httpd.service

を実行しました。

サービスの起動停止等は以下のコマンドでした。
> $ sudo systemctl [start | stop | restart] httpd.service

## PHP7のインストール
何も考えずにyumでPHPをインストールしたら、5.4だったんですが、
Wordpressのプラグインで、アップロードしたファイルをS3にアップロードする[WP Offload S3 Lite(Amazon S3 Cloud Front)](https://wordpress.org/plugins/amazon-s3-and-cloudfront/)というプラグインがあって、今回これを使いたかったのですが、PHP5.5以上じゃないと使えないことが判明。
じゃあ、どうするよと、色々調べたところ、Extras Library(amazon-linux-extras)でPHP7がインストールできるということで、

> $ sudo amazon-linux-extras install php7.2

でインストール・・・と思ったら、失敗。

> Package php-cli-5.4.16-43.amzn2.0.1.x86_64 already installed and latest version
Error: Package: php-json-7.2.0-3.amzn2.1.x86_64 (amzn2extra-php7.2)
           Requires: php-common(x86-64) = 7.2.0-3.amzn2.1
           Installed: php-common-5.4.16-43.amzn2.0.1.x86_64 (@amzn2-core)
               php-common(x86-64) = 5.4.16-43.amzn2.0.1
           Available: php-common-5.4.16-43.amzn2.x86_64 (amzn2-core)
               php-common(x86-64) = 5.4.16-43.amzn2
 You could try using --skip-broken to work around the problem
 You could try running: rpm -Va --nofiles --nodigest
Installation failed. Check that you have permissions to install.

あん？なんでやねんと関西弁でツッコミを入れたところで、
調べてみると、AWSのフォーラムで同じエラーが出てるというスレッドを発見

[Amazon Linux 2 - Can't install PHP 7.2](https://forums.aws.amazon.com/thread.jspa?messageID=824328&tstart=0)

google翻訳さんの力を借りて読んでみると、
とりあえず、AWSもこの問題は認識していて、アップデートするから待っててね。的なことが書いてあったので、
どーすんだとよ、再度いろいろ調べた結果、代替案としては、yumでバージョン指定してインストールするという以下の方法で対応
>sudo yum install \
>   php-common-7.2.0-3.amzn2.0.1.x86_64 \
>   php-fpm-7.2.0-3.amzn2.0.1.x86_64   \
>   php-cli-7.2.0-3.amzn2.0.1.x86_64 \
>   php-mysqlnd-7.2.0-3.amzn2.0.1.x86_64 \
>   php-pdo-7.2.0-3.amzn2.0.1.x86_64 \
>   -y --disableplugin=priorities

(ただ、このコマンドどこから持ってきたか忘れているので、思い出したら追記)

公開する頃には、Extras Libraryの問題は解決してるかも。と思ったけど、フォーラム見る限りは未解決でした。

週末に続きをやるから、また、何か起きたら、さらに追記します。

---
## 2018.02.18 追記
問題修正されたようです。
コマンド実行前にyum updateが行ってください。以下スレッドの最後のコメント。
[Amazon Linux 2 - Can't install PHP 7.2](https://forums.aws.amazon.com/thread.jspa?messageID=824328&tstart=0)

---

# 参考サイト
## Wordpressのインストール
[AWSにWordPress3.8をインストールしてみた – その1](https://dev.classmethod.jp/cloud/aws/aws-wordpress3-8-part1/)
## サービス自動起動
[systemdでの自動起動設定](https://qiita.com/shosan87/items/f65b43373b895edb2946)
## Extras Library(amazon-linux-extras)
[Amazon Linux 2のExtras Library(amazon-linux-extras)を使ってみた](https://dev.classmethod.jp/cloud/aws/how-to-work-with-amazon-linux2-amazon-linux-extras/)
[Amazon Linux2 の注意点【Zabbixの視点から】](http://blog.serverworks.co.jp/tech/2017/12/24/amazon_linux2/)
New Relic APMで監視するホストの限定方法[Rails]

RailsにNew Relic APMを導入する時に監視対象のホストを限定する方法を紹介します。

## New Relic APMの導入方法と設定
* https://docs.newrelic.com/docs/agents/ruby-agent/installation/install-new-relic-ruby-agent
* https://docs.newrelic.com/docs/agents/ruby-agent/configuration/ruby-agent-configuration

## なんで監視するホストを限定したいのか
New Relic APM のProはホスト課金です。
契約台数の都合上、特定のサーバーだけに限定したいときがあるからです。

## 設定手順
production環境の特定ホストのみ監視させたい場合の例

1. config/custom_new_relic_configuration.rbを読み込む設定を追加します

	``` config/application.rb
	require_relative './custom_new_relic_configuration'
	```

2. 特定ホストか判定するメソッドを作成します。

	```config/custom_new_relic_configuration.rb
	require 'socket'
	
	class CustomNewRelicConfiguration
	  ENABLED_NEWRELIC_HOST = 'host.example.com'

	  def self.enable_on_current_host?
	    ENABLED_NEWRELIC_HOST == Socket.gethostname
	  end
	end
	```
3. デフォルトでは監視させないようにして、productionだけ作成したメソッドで判定させます。

	```config/newrelic.yml
	common: &default_settings
	  monitor_mode: false
	
	production:
	  <<: *default_settings
	  monitor_mode: <%= CustomNewRelicConfiguration.enable_on_current_host? %>
	
	```

## 参考
* [Rails に New Relic をサクッと導入してみた](http://kakakakakku.hatenablog.com/entry/2015/09/11/023231)
* [Enable NewRelic monitoring [for Rails] on specific hosts only](https://makandracards.com/makandra/19145-enable-newrelic-monitoring-for-rails-on-specific-hosts-only)
* [[newrelic][rails] Rails で特定のホストでのみ NewRelic Agent を起動する術](https://www.hsbt.org/diary/20150202.html)
Kotlin コード規約（ Configure style in IDE, Source code organization ）

[公式](http://kotlinlang.org/docs/reference/coding-conventions.html)の和訳（意訳）です．

- IDEでスタイルを設定する, ソースコード構成(この記事)
- [命名規約](https://qiita.com/hmiyado/items/feea2cdd196ef53b1a1a)
- [フォーマット 前半](https://qiita.com/hmiyado/items/2ad86df1d0cb842beee6)
- [フォーマット 後半](https://qiita.com/hmiyado/items/4667994ea71fe4c76484)
- [ドキュメントコメント，冗長な記述を避ける](https://qiita.com/hmiyado/items/05cae7df64d6d0138594)
- [慣用表現の使用](https://qiita.com/hmiyado/items/94792e428e5993bc8fc6)
- [ライブラリのコード規約](https://qiita.com/hmiyado/items/f1e84c7870b8a5864a7b)

# IDE でスタイルを設定する

Kotlin の著名な2つのIDE, IntelliJ IDEA と Android Studio はコーディングスタイルの豊富なサポートをしています.
所望のコードスタイルを利用して自動であなたのコードをフォーマットするように設定できます.

## スタイルガイドを適用する

1. **Settings/Preferences | Editor | Code Style | Kotlin** を開く
1. **Set from...** をクリックする
1. **Kotlin style guide** を選択する

## コードがスタイルガイドに従っていることを検証する

1. **Settings/Preferences | Editor | Inspections | Kotlin** を開く
1. **Kotlin | Style issue** を開く
1. **File is not formatted according to project settings** の設定を有効にする.スタイルガイドに記載されている他の課題（命名規約など）を検証する設定はデフォルトで有効になっている.

# ソースコード構成
## ディレクトリ構造

複数の言語で構成されるプロジェクトの場合， Kotlin ファイルは Java ファイルと同じソースルートに置き，同じディレクトリ構成にする．
（Java と Kotlin それぞれのファイルは，パッケージ名に対応するディレクトリに置く）．

Kotlin のみで構成されるプロジェクトの場合，共通のルートパッケージを省略したパッケージ構造に従ったディレクトリ構造を推奨する．
（たとえば，プロジェクトのすべてのコードが "org.example.kotlin" パッケージ以下にあるとき， "org.example.kotlin" パッケージのファイルはソースルートに置く．
また， "org.example.kotlin.foo.bar" のファイルはルート直下の "foo/bar" ディレクトリに置く）．

[JVM] Java と一緒に利用されるプロジェクトでは, Kotlin ソース・ファイルは Java のソースファイルと同様にソースルートに置いたままにする.
宣言したパッケージと対応するディレクトリにそれぞれのファイルが置かれるようにする.

## ファイル名

Kotlin ファイルに単一のクラス（および，そのクラスに関連するトップレベル宣言）があるとき，ファイル名はクラス名に .kt 拡張子をつけたものになる．
ファイルに複数のクラスがあるか，トップレベル宣言しかないないとき，ファイル名はそのファイルの内容を表す名前にする．
ファイル名には，キャメルケースを用い，最初の文字は大文字にする（ `ProessDeclarations.kt` など。パスカルケースとも）．

ファイル名は，中身のコードの処理を表す．
なので， "Util" のような無意味な単語を使うのは避けるべきである．

## ファイル構造

意味的に強い関連があり，ファイルサイズも妥当である（数百行は続かない）ならば，同じファイル内にクラスやトップレベルの関数・プロパティのような宣言を複数書くことを推奨する．

特に，あるクラスのすべてのクライアントに関連する拡張関数を定義するときは，そのクラス自体が定義されているファイルに書く．
特定のクライアントに対してだけ意味がある拡張関数を定義するときは，そのクライアントの近くに書く．
何かしらのクラスのすべての拡張関数を羅列するためだけのファイルを作らない．

## クラス内のコードの配置

一般に，クラス内のコードは以下の順序で書く．

1. プロパティ宣言と初期化ブロック
2. セカンダリコンストラクタ
3. メソッド宣言
4. コンパニオンオブジェクト

メソッド宣言をアルファベット順や可視性の順にソートしてはならない．
また，通常のメソッドと拡張関数を区別してはならない．
代わりに，関連するものをまとめて書く．
コードを読む人がそのクラスを上から順に読んだときに，何が起こっているかを理解できるようにするためだ．
高レベルのものから順に書くか，低レベルのものから順に書くか，適当に決めて一貫性を持たせる．

ネストされたクラスは，そのクラスを使用する場所の近くに書く．
もし，ネストされたクラスが外部で使用されることを意図したもので，内部からは参照されないのならば，コンパニオンオブジェクトの次，クラスの最後に書く．

## インターフェースの実装の配置

インターフェースを実装するとき，メンバの実装はインターフェースでの宣言と同じ順にする．
（インターフェースの実装に private メソッドが必要な場合は，インターフェースの実装の間に書く）．

## 演算子オーバーロードの配置

演算子オーバーロードは，常にクラス内の隣り合った場所に書く．
【Three.js】複数のブロックを散らしてみる

# はじめに
Qiitaの記事にCodePenが埋め込めるようになりました！
これでhoverの動きやアニメーションが簡単に試せますね！

今回はThree.jsで複数の小さいブロックを散らすアニメーションを作成してみます
最終的にはこんな感じです↓

<p data-height="357" data-theme-id="0" data-slug-hash="EbxeQO" data-default-tab="result" data-user="qwerty8t" data-embed-version="2" data-pen-title="moving blocks" class="codepen">See the Pen <a href="https://codepen.io/qwerty8t/pen/EbxeQO/">moving blocks</a> by qwerty8t (<a href="https://codepen.io/qwerty8t">@qwerty8t</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://production-assets.codepen.io/assets/embed/ei.js"></script>

# コード
全体のコードは[CodePen](https://codepen.io/qwerty8t/pen/EbxeQO/)で確認してください．


# 補足
## グローバルに定数を設定
グローバルに定数として宣言することで
ブロックの大きさや速さを容易に変更できるようにします．

```js
const block_width = 5; // ブロックの横の長さ
const block_height = 5; // ブロックの縦の長さ
const block_num = 300; // ブロックの数
const min_speed = 1; // ブロックの最遅スピード
const max_speed = 10; // ブロックの最速スピード
```

## ブロックの色を乱数にする
Three.jsでは色の指定を"0x"の後の16進数で表現するのが[推奨](https://threejs.org/docs/#api/math/Color)されているようです．

```js
let rect = [];
for (var i = 0; i < block_num; i++) {
  var color = "0x" + Math.floor(Math.random() * 16777215).toString(16);
  // var color = "0xffffff";
  var material = new THREE.MeshBasicMaterial({
    color: Number(color)
  });

  rect.push(new THREE.Mesh(geometry, material));
}

for (var i in rect) scene.add(rect[i]);
```

## ブロックの初期位置と速度を乱数にする
```js
let x = [];
let y = [];
let dx = [];
let dy = [];
const min_pos_x = -(Number(width) / 2);
const max_pos_x = (Number(width) / 2);
const min_pos_y = -(Number(height) / 2);
const max_pos_y = (Number(height) / 2);

for (var i = 0; i < block_num; i++) {
  x.push(Math.floor(Math.random() * (max_pos_x + 1 - min_pos_x)) + min_pos_x);
  y.push(Math.floor(Math.random() * (max_pos_y + 1 - min_pos_y)) + min_pos_y);
  dx.push(Math.floor(Math.random() * (max_speed + 1 - min_speed)) + min_speed);
  dy.push(Math.floor(Math.random() * (max_speed + 1 - min_speed)) + min_speed);
}
```

## 壁との跳ね返り
壁とブロックが当たれば速度の+, -を変更します．

（コメントアウトを外すと壁と接触する度に加速します）

```js
for (var i in rect) {
  x[i] += dx[i];
  y[i] += dy[i];
  if (x[i] > (width / 2) || x[i] < (-width / 2)) {
    dx[i] = -dx[i];
    // if (dx[i] < 0) dx[i] = dx[i] - 1;
    // else dx[i] = dx[i] + 1;
    x[i] += dx[i];
  }
  if (y[i] > (height / 2) || y[i] < (-height / 2)) {
    dy[i] = -dy[i];
    // if (dy[i] < 0) dy[i] = dy[i] - 1;
    // else dy[i] = dy[i] + 1;
    y[i] += dy[i];
  }

  rect[i].position.x = x[i];
  rect[i].position.y = y[i];
}
```

# おわりに
Three.jsの[公式ドキュメント](https://threejs.org/docs/#manual/introduction/Creating-a-scene)は英語ですが，英語が理解できなくてもコードはなんとなく理解できると思います．

[CodePenが埋め込める](https://qiita.com/Qiita/items/edae7417214c8e957f54)のは本当にすばらしいです！
運営の方々ありがとうございます！

 以上
PythonでThreadを使うflaskサンプルを作ってみた

Flaskで時間のかかる処理をするとき、どうするのが良いか実行してみたので、自分用にメモ。

## 主な解法
ちょっと調べてみた感じだと、下記が主なやり方になりそうでした。

- [celery](http://www.celeryproject.org/) でジョブキューを使う
  - redisなど使うため準備が少し必要
  - Pythonではメジャーな実装っぽい
- [Thread](https://docs.python.jp/3/library/threading.html)を使う
  - Javaに近い感じ
  - celeryよりは実装が楽そう
- 単純に実行が終わるまで待つ
  - 実装は単純（というか何もしない）
  - タイムアウトなど起こり得る
  - 待ち時間が長いとクライアント側の使い勝手がよくない

今回は、Threadを試してみました。

## Threadについて
Javaで使ったことがあると親しみやすいかもしれません。
実行する方法が２つあります。

1. Threadを使う
  1. `threading.Thread(target=[job])`でjobを渡してThreadオブジェクトを作る
  2. `start()`で処理を開始する
2. Threadを継承したクラスを使う
  1. 継承したクラス内で `run`メソッドを実装すると、それが処理内容になる
  2. オブジェクトを作り、`start()`で処理を開始する

**Javaと異なる点は**、停止処理などがないことです。
> 現状では、優先度 (priority)やスレッドグループがなく、スレッドの破壊 (destroy)、中断 (stop)、一時停止 (suspend)、復帰 (resume)、割り込み (interrupt) は行えません。

ただ、停止させる方法がないわけではなく、フラグを外から更新してあげることで実現可能です。

今回は停止処理なども試したかったので、継承したクラスを使いました。

### サンプル

``` app.py
from datetime import datetime
from flask import Flask, make_response
from time import sleep
import threading

app = Flask(__name__)

class MyThread(threading.Thread):
    def __init__(self):
        super(MyThread, self).__init__()
        self.stop_event = threading.Event()

    def stop(self):
        self.stop_event.set()

    def run(self):
        try:
            for _ in range(1000):
                print(f'{datetime.now():%H:%M:%S}')
                sleep(1)

                # 定期的にフラグを確認して停止させる
                if self.stop_event.is_set():
                    break
        finally:
            print('時間のかかる処理が終わりました\n')

jobs = {}

@app.route('/start/<id>/')
def root(id):
    t = MyThread()
    t.start()
    jobs[id] = t
    return make_response(f'{id}の処理を受け付けました\n'), 202

@app.route('/stop/<id>/')
def stop(id):
    jobs[id].stop()
    del jobs[id]
    return make_response(f'{id}の中止処理を受け付けました\n'), 202

@app.route('/status/<id>/')
def status(id):
    if id in jobs:
        return make_response(f'{id}は実行中です\n'), 200
    else:
        return make_response(f'{id}は実行していません\n'), 200
```

Flaskを起動します。

``` console:Flaskの起動
$ FLASK_APP=app.py flask run
```

下記のようにリクエストを送ってみると、クライアント側にはレスポンスがすぐ返り、かつ時間のかかる処理が継続していることが確認できました。

``` console:リクエストを送ってみる
$ curl localhost:5000/start/1/
1の処理を受け付けました
$ curl localhost:5000/status/1/
1は実行中です
$ curl localhost:5000/stop/1/
1の中止処理を受け付けました
```

``` console:Flask側の結果
$ FLASK_APP=app.py flask run
 * Serving Flask app "route"
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
127.0.0.1 - - [18/Jan/2018 00:33:04] "GET /start/1/ HTTP/1.1" 202 -
00:33:05
00:33:06
127.0.0.1 - - [18/Jan/2018 00:33:07] "GET /status/1/ HTTP/1.1" 200 -
00:33:07
00:33:08
00:33:09
00:33:10
127.0.0.1 - - [18/Jan/2018 00:33:10] "GET /stop/1/ HTTP/1.1" 202 -
時間のかかる処理が終わりました
```


## まとめ
celeryを使うほどじゃないけど、処理時間がかかる場合などはThreadを使うと良いかなと思いました。（celeryまだ使ったことない。汗）

他にもっと良い方法などありましたらコメントいただけますと幸いです。
gnuplot.pyのインストール(mac)

必要なもの
・gnuplot
・python (2.2 ~)
・numpy (pythonのパッケージ)


以下よりファイルをダウンロードして解凍
http://sourceforge.net/project/showfiles.php?group_id=17434

解凍した後terminalを起動し。cdコマンドで解凍したフォルダ内に移動。
terminalで

```
python setup.py install 
```
をコマンド入力することでインストールができる。
python3ではインストールが出来ないがこちらに落ちていたものを使ったらできた
https://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0ahUKEwjBivCqsN_YAhXBbrwKHVjLC6UQFggrMAA&url=https%3A%2F%2Fgithub.com%2Foblalex%2Fgnuplot.py-py3k&usg=AOvVaw2hE1TElfKmW_ZjJMwxmieL
クラスなどの配列の中で同じ要素のものを固めて整列させる

最初に結論から
# コード
``` swift
extension Array {

    /// 配列を要素が同じ物が並ぶように整列します。(元の配列を変更します)
    ///
    /// - Parameter by: 並べる基準となる要素の配列
    mutating func align<T: Equatable>(by: [T?]){
        var by = by
        guard self.count == by.count, var now : T? = by.first else {
            return
        }
        for index in 0..<self.count{
            if now != by[index]{
                for jndex in index..<self.count{
                    if now == by[jndex]{
                        let temp = (self[jndex], by[jndex])
                        self.remove(at: jndex)
                        by.remove(at: jndex)
                        self.insert(temp.0, at: index)
                        by.insert(temp.1, at: index)
                        break
                    }
                }
            }
            now = by[index]
        }
    }
    
    /// 配列を要素が同じ物に並ぶように整列します。(元の配列は変わりません)
    ///
    /// - Parameter by: 並べる基準となる要素の配列
    /// - Returns: 整列した配列
    func aligned<T: Equatable>(by: [T?])->Array{
        var copied = self
        copied.align(by: by)
        return copied
    }
    
}
```

# 表題が何言ってるか分からんって方に
~~正直自分でもなんて言っていいか分からない。~~
メンバに`String`型とかを持つ自作クラスの配列を，そのメンバが同じ物が並ぶように整列させたいとか思ったことないですか。
私はあります。だから作りました。
こんな感じで使います。

``` swift
class foo{
    var str :String
    init(str: String) {
        self.str = str
    }
}

var bar : [foo] = [foo(str: "a"), foo(str: "b"), foo(str: "c"), foo(str: "b"), foo(str: "a"), foo(str: "b")]

print(bar.aligned(by: bar.map({$0.str})).map({$0.str})) //["a", "a", "b", "b", "b", "c"]
```

# 並べ替えのアルゴリズムについて
多分というか絶対，これ以上に最適なアルゴリズムが存在するので，もしアイデアがあればご教授いただければ幸いです。
MongoDBインストール（CentOS、Amazon Linux）

## yumアップデート  
```
yum update -y
```

## レポジトリ追加

```
vi /etc/yum.repos.d/mongodb-org-3.4.repo
```

### ■ CentOSの場合
```
[mongodb-org-3.4]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/3.4/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-3.4.asc
```

### ■ Amazon Linuxの場合
```
[mongodb-org-3.4]
name=MongoDB Repository
baseurl=http://repo.mongodb.org/yum/amazon/2013.03/mongodb-org/3.4/x86_64/
gpgcheck=0
enabled=1
```

## インストール
```
yum install -y mongodb-org
```

## SELinuxの無効化
※ Amazon Linuxは最初から無効のため必要なし

```
getenforce
setenforce 0
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
```

## 起動
### ■ CentOSの場合
```
systemctl start mongod
systemctl enable mongod
```

### ■ Amazon Linuxの場合
```
/etc/init.d/mongod start
chkconfig mongod on
```

## 起動確認
```
cat /var/log/mongodb/mongod.log
2017-07-25T09:51:17.306+0000 I NETWORK  [thread1] waiting for connections on port 27017
```
bindで接続されたSVAからDUV内部の信号を指定する方法

SVAを検証するターゲットのモジュール(DUV)に接続するとき、bindを使うと簡単ですが、bindでDUVに接続されたSVAの中からターゲット内部の信号を指定する方法もとても簡単です。

SystemVerilogで階層構造の頂点を示す$rootを使ってDUV内部の信号signal_1を参照する例を示します。

property one_pulse(CLK, RST_N, signal);
@(posedge CLK) disable iff !RST_N
  signal |=> !signal;
endproperty

assert_one_pulse:assert property(one_pulse(clock,rst_n,$root.DUV.signal_1));

上記のように$rootを先頭にして、DUV以下の階層構造を指定することで、bindで接続されたSVAから、DUV内部を参照できます。
Emacsは美しい(黄金比編)

Emacsは美しいんです。
と書くとVim信者からTwitterに晒されるんで先に断っておきます！
Vimをディスったりする意図はないです(・ω・)

---
どんなエディタでも画面を分割すると1行に収まる文字の量が減ってしまいます(・ω・)
普段からMacBookProで作業しているとどうしても画面サイズの都合で情報量が減ってしまう結構な悩みだった。
で、さっき見つけたパッケージが素敵だったのでご紹介！

## golden-ratio(黄金比)
[roman/golden-ratio.el](https://github.com/roman/golden-ratio.el)
このパッケージを導入すると画面分割した時編集可能なバッファが1:1.618（黄金比）にしてくれます(・ω・)
![](https://camo.githubusercontent.com/26b1ac5fec67a2c557cfbe87382a0134d3443fd0/68747470733a2f2f7261772e6769746875622e636f6d2f726f6d616e2f676f6c64656e2d726174696f2e656c2f6173736574732f676f6c64656e5f726174696f5f656c2e676966)
これならバッファを3分割しても4分割しても編集したいバッファだけしっかり見ることができます！
黄金比にしてくれるところがにくい！
美しいEmacsには黄金比がふさわしい！
PetaLinuxでディレクトリやPythonスクリプトを、Linuxイメージにインストールする

この記事の内容は正しいかは不明。とりあえず動いた。

# 環境
PetaLinux 2017.4

# ディレクトリごとコピーする
`mydir`というディレクトリを全部コピーしたい場合のYoctoレシピ。ここでは、`/home/root/inst`にインストールされる。
`myinit`というアプリケーションを作り、インストール時にコピーするようにする。(アプリケーション名はなんでもいい)

```sh:PetaLinuxコマンド
petalinux-create -t apps --template install -n myinit --enable
```

`mydir`を`project-spec/meta-user/recipes-apps/myinit/files`にコピーする

```txt:project-spec/meta-user/recipes-apps/myinit/myinit.bb
SUMMARY = "Simple myinit application"
SECTION = "PETALINUX/apps"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"

SRC_URI = "file://mydir"

S = "${WORKDIR}"

do_install() {
	# install a directory
	install -d ${D}/home/root/inst
	cp -r ${S}/mydir ${D}/home/root/inst
}
FILES_${PN} += "/home/root/inst"
```

# Pythonスクリプトをインストールする
Pythonスクリプトをインストールするとき、ファイル先頭に環境設定があるとエラーになった。

_追記(2018/1/20): 単にパスを間違えているだけかも。`#!/usr/bin/env`ならOKかも(未確認)_

```py:NGだった
#!/bin/env python
# coding: utf-8
import os
...
```

```py:OKだった
##!/bin/env python	# ignore
# coding: utf-8
import os
...
```
python3で4つごとに区切る。

#python3で文字列を4つごとに区切る

番号を羅列したときに4つごとに","で区切るプログラムをとにかく書いてみました。
whileを使って書きました。

```python3
#ダメなコード
x=str(input("input"))
y=0
li=[]
while len(x)>= 4:
    li.append(x[y:y+4])
    x=x[4:]
a = ",".join(li)
print(a)
```

# 反省点
pythonのコミュニティでいろいろ評価を得たり、考えたりした結果を書いてく。

 - 色々間違えた点としては`input()`にpython3は`str()`はいらないっぽい。
 - `y`の需要がない。
 - あと、今回は必要じゃなかったからいいけど、`len(x)`が4の倍数じゃないと切り捨てられるから、今回はいいけど致命的でした。

```py3
#少しきれいにした
x=input("input")
li=[]
while len(x)>= 4:

    li.append(x[0:4])
    x=x[4:]

a = ",".join(li)
print(a)
```

そしてなんと、コミュニティのpythonistの先輩の別解は一行。

```py3
x=input();print(','.join([x[i:i+4] for i in range(0,len(x),4)]))
```

これはびっくりでしたね。。
`while`じゃなくて、`for`だったらもっと楽にかけたのかもねぇ、、、

あとは`zip`関数を使ったやり方も教えてくれました〜。

# あとがき
めっちゃ雑でごめんなさい。
今回はいろいろ反省点ありました。
そして、有識者に聞くことは大切ですね。

最後に、まだまだはじめたばかりでpythonも詳しくないので、間違いなどがあったら、コメントください。
Dashlane に U2F オプションがあったので設定してみた

# はじめに

Dashlane が U2F オプションに対応しているらしく、使用感がしりたく設定してみた。
微妙に設定が分かりにくいところがあったので記事に残す。

## 環境

TOTP を読み込める Auhenticator(Google Authenticatorや Authyなど）と SMS 受信できる電話番号が必要。

* Windows10
* Google Chrome
* YubiKey4, YubiKey Neo
* Nexus 5X


とりあえずプレミアアカウントである必要がある。

![2018-01-12_09h44_17.png](https://qiita-image-store.s3.amazonaws.com/0/83984/6590fc1a-a09c-58ad-4e49-39ea90a234ca.png)

ツールバーメニューから設定を開く。
こういう最近のアプリは、なかなかツールバーを操作しないので 2段階認証メニューを探すのに手こずった。

![2018-01-12_09h44_33.png](https://qiita-image-store.s3.amazonaws.com/0/83984/cce79da3-2941-3247-f3db-7d302303e0b8.png)

あとはよくある感じなので、2段階認証を設定した人ならわかるはず。

![2018-01-12_09h44_48.png](https://qiita-image-store.s3.amazonaws.com/0/83984/d56e2376-0a34-75f1-1f33-19d29e4d89db.png)

マスターパスワードを入れて…

![2018-01-12_09h45_12.png](https://qiita-image-store.s3.amazonaws.com/0/83984/615ab34d-a966-2ec4-8261-5c20e10edc80.png)


二要素認証をONに

![2018-01-12_09h45_25.png](https://qiita-image-store.s3.amazonaws.com/0/83984/f7e129ed-e7b7-4d84-8469-26cedcc129da.png)

どのタイミングで二要素認証を有効にするかを設定する。
**新しいデバイスを追加する時のみ** を選択しても、すでにログインしているデバイスには特に認証は追加されない。
Dashlane にログインするたびを選択した場合、ログインするたびに2要素認証が求められるが、そもそもログアウトするタイミングはよくわかってない。
（Webから端末の強制ログアウトはできる）

![2018-01-12_09h45_35.png](https://qiita-image-store.s3.amazonaws.com/0/83984/e61fd0c9-89bd-73bd-301f-23414b78ab75.png)

よく見る Authenticator の QRコードが出てくるので、 Google Authenticator などでスキャンするか、文字列を入力する。

![2018-01-12_09h47_56.png](https://qiita-image-store.s3.amazonaws.com/0/83984/bbda25c6-dd35-58ed-dfa4-4cc3a94d99b7.png)

Authenticator に出てきたコードを入力して次へ

![2018-01-12_09h48_48.png](https://qiita-image-store.s3.amazonaws.com/0/83984/1809b309-c241-9199-6909-7c97d50998c4.png)

電話番号を入力して次へ

よくあるバックアップコード（電話番号、Authenticator とも紛失した際の最終復元コード）がでるので
印刷して金庫にでもぶち込んでおく。

![2018-01-12_09h48_57.png](https://qiita-image-store.s3.amazonaws.com/0/83984/d2978b4a-f40b-d74f-da79-7e5693ce4cf2.png)

2要素認証が有効になったので U2F デバイスを設定していく。

![2018-01-12_09h50_44.png](https://qiita-image-store.s3.amazonaws.com/0/83984/8777f708-eccc-c4f8-8ffb-e1f0df77bf55.png)

U2Fセキュリティーキーを追加

![2018-01-12_09h51_06.png](https://qiita-image-store.s3.amazonaws.com/0/83984/8370e2c6-c66f-6e5c-2162-4ad37df8621a.png)

名前を決めて次へ
YubiKeyであれば タッチボタンをタッチする。

![2018-01-12_09h51_17.png](https://qiita-image-store.s3.amazonaws.com/0/83984/9bbb4ae8-80f6-11fb-6042-3888ad55b09a.png)

登録完了。


わかりづらいが追加のキーを登録するには「編集」を押す。

![2018-01-12_09h51_34.png](https://qiita-image-store.s3.amazonaws.com/0/83984/7da9b68e-8cb4-aa30-1681-a2abc4712e17.png)

キーの削除や編集が行える。

![2018-01-12_09h51_41.png](https://qiita-image-store.s3.amazonaws.com/0/83984/a167fae0-0a2c-5b09-04bc-236c38f08433.png)

ブラウザのプラグインでログインしてみる。

![2018-01-12_09h52_53.png](https://qiita-image-store.s3.amazonaws.com/0/83984/8928590a-0424-5325-db8a-f572a5674cd6.png)

U2F デバイスが求められるのでタッチする。

![2018-01-12_09h55_38.png](https://qiita-image-store.s3.amazonaws.com/0/83984/c0438918-de6c-6392-6460-03f11eb07e31.png)

ログイン完了。

![2018-01-12_09h55_50.png](https://qiita-image-store.s3.amazonaws.com/0/83984/13ae2012-5b3a-8cef-e85b-e4ff38a3787f.png)


## その他

ちなみに Android のアプリにログインするときは、Authenticator のコードでのログインのみの対応だった。