OmniAICreator/Qiita-1.07M huggingface dataset:
kaminariでpaginationを実装

##pagination(ページネーション)とは？

例えば、Google検索をした時に一番下に出るページ番号のこと。
長いビューを複数のページに分割して、各ページへのリンクを並べて見やすくする。

##kaminariでpaginationを実装！

**kaminari**とはrubyのgemの一種。

Gemgfileにkaminariを追加。

```ruby:Gemfile
gem 'kaminari'
```

bundle installを実行。

```ruby:ターミナル
$ bundle install
```

（ローカル）サーバーの再起動

```ruby:ターミナル
$ rails s
```

##コントローラーの編集
kaminariを導入後は、コントローラーを編集して、1ページあたりに表示したい件数を指定する
。

```ruby:hoge_controller.rb
変数名 = クラスを利用して取得したレコードのインスタンス.page(params[:page]).per(1ページに表示したい件数)
```

例えば、

```ruby:tweets_controller.rb
@tweets = Tweet.all.order('id DESC').page(params[:page]).per(5)
```

##ビューの編集

コントローラーの編集後、ビューを編集してページネーションのリンクを作成する。

リンクを作成したい場所に、

```ruby:hoge.html.erb
<%= paginate(@tweets) %>
```
を記述する。例えば、

```ruby:index.html.erb
<div class="contents row" >
  <% @tweets.each do |tweet| %>
    <div class="content_post" style="background-image: url(<%= tweet.image %>);">
      <%= simple_format(tweet.text) %>
      <span class="name"><%= tweet.name %></span>
    </div>
  <% end %>
  <%= paginate(@tweets) %>
</div>
```
UE4でVRMをインポートできるようにしたけど、まだ先は長そうです

「UE4」と「VRM」で検索して情報が出てくるようQiitaに書いてみます。


### 2018/12/08 追記：最新版は手順が変わっています
導入の際は[VRM4U置き場](https://github.com/ruyo/VRM4U)より、最新の手順をご確認ください。
この記事よりも機能が増えています。



# やったこと

UnrealEngine4のVRMインポーターとして機能する VRM4Uというプラグインを作成しました。
https://github.com/ruyo/VRM4U

利用するには、DownloadZIPをクリックし、MyGame/Plugins/VRM4U/　となるように配置してください。
エディタを起動し、コンテンツブラウザ上にVRMファイルをドラッグ＆ドロップすれば動作します。

| |
|----|
|![image.png](https://qiita-image-store.s3.amazonaws.com/0/36233/0d9a87ac-2d25-5acd-cd3f-1c4aefa4f1a8.png)|


# インポートしてみた例

|VRoidStudio v0.2.13で出力したもの https://vroid.pixiv.net/|
|----|
|![image.png](https://qiita-image-store.s3.amazonaws.com/0/36233/8c7cf10d-0678-7adb-618e-d4d40a13c690.png)|
|MToonはUE4の素のマテリアルになります。MorphTarget読めます|

|ニコニ立体ちゃん (VRM) http://3d.nicovideo.jp/works/td32797|
|----|
|![image.png](https://qiita-image-store.s3.amazonaws.com/0/36233/d94bc145-a23e-e547-dc94-473e35e68641.png)|
|UnlitTextureはUnlitのマテリアルになります。揺れ物設定はPhysicsAssetに展開します|


# 仕組み
VRM読み込みはAssimpのglTF対応をベースにしています。
※現在(2018/10月)のAssimpはglTFのboneと頂点ウェイトの読み込みに未対応です。VRM拡張も未対応です。
　　なので対応しました。VRMには不要なボーンアニメーションも一部対応しました。https://github.com/ruyo/Assimp
　　機会あればソースを整頓して本家にパッチを提供したいです。
　　…しかし今はVRMが優先です。

少し改造すればAssimpで対応している大半のモデルを、UE4にインポートしたり動的に読むことができるでしょう。夢が膨らみます。
…しかし今はVRMが優先です。

仮ながらAssimpはglTFの出力に対応しているので、そこそこ改造すればUE4上で設定したパラメータをVRMファイルに出力することもできるでしょう。
…しかし今はVRM読み込みが優先です。

インポートのメイン処理は、UE4ランタイム側のモジュールで行っています。
これは動的(ゲームビルドで動作する)なモデル読み込みを前提としているからです。

## 今出来ることと制限
- スキンモデル（メッシュと骨）の読み込み
- MorphTargetの読み込み（いわゆるブレンドシェイプ）
    - ※現状では顔の表情を意図通りに制御するのは難しいでしょう。VRMのBlendShapeGroupへの対応が必要そうです。
- テクスチャの読み込み(今のところPNGのみ)
- マスク、半透明マテリアルの作成と割り当て
    - UnlitTextureシェーダ：Unlitのマテリアルになります。
    - MToonシェーダ：UE4の素の物理シェーディングなマテリアルになります。VRMをglTFビューワで見た時とほぼ同じ結果です
- 揺れ物の読み込み
    - コリジョンは正確だと思います
    - ※揺れ方は適当です （パラメータを適当に決め打ちしています）

## 今は出来ないけど将来的に解決したいこと
- 1つのAnimBPを全てのVRMで適用できるようにする
    - UE4の思想と非常に相性が悪い… ようにみえます。しかし、これができて初めて「UE4でVRMを読めた」と言えるのはないかと。
    - ベースの共通Skeletonの姿勢をコピーするよう実装すればいける予感はしています…
- Gameビルドした環境で 動的にモデルを読めるようにする
    - UE4の思想と非常に相性が悪い… ようにみえます。
    - 現在はEditorビルドでしか読めません。MorphTargetを読み込む時に行き詰まったので、一旦Gameビルドを諦めました。
    - ※裏を返すとMorphTargetを諦めれば、Gameビルドで動的に読むことは おそらく可能です。
- 日本語の骨名に対応する
    - 現在はスキニング結果がおかしくなります。最悪エディタが落ちます。
    - 動的に読む限りでは、勝手にリネームしても影響は少ないと考えています。
    - MMDをVRMにコンバートしたファイルでよく見られます。

## 出来ないこと
- Unityでの見た目、挙動を完全再現すること

# 目標
UE4でVRoidHubのようなサービスと連携できるようなところまで行きたい
　　けど挫けてVRMインポーターで終わるかもしれません（弱気
　　別問題として、このプラグインがUE4のバージョンアップに追従できるか、かなり不安が残ります。

VTuberのためのツールとしては…正直オススメしません。応援はします！

要望、参考情報、コメントなどありましたらお知らせください。

# さいごに
（自分語りなので読みたい方だけ）
Webで情報を公開している方へ 勝手ながら感謝の意を述べます。ありがとうございます。
私個人もUE4でVRMを手軽に扱えない状況に、長らく歯がゆい思いをしていました。
ふと思い立って、えいやっと実装し、公開してしまいました。
UE4とVRMが取り巻く環境が今後どう変化するかわかりませんが、なんらかの足しになれば幸いです。

10/13 ちょっと編集
表記を gltf->glTF、assimp->Assimpにした。言葉足らずなのを修正。
[C++]コンパイルしたら全く同じ関数が２つバイナリに埋め込まれた

# はじめに

C++で書かれたソースコードをコンパイルすると、ソースコードに書かれている関数がバイナリに埋め込まれ、呼び出し可能な状態で保存される。

しかし、GCCにおいてはある条件下で全く同名の関数が埋め込まれるということが分かった。

今後同じような状況に遭遇した人が混乱しないように記事を残しておく。

# 実験

## 問題のないケース

```cpp:foo.hpp
int foo();
```

```cpp:foo.cpp
#include "foo.hpp"

int foo() { return 1; }
```

これは全く問題ない。foo関数がバイナリに埋め込まれるのは一度だけである。

```console
$ g++ -c foo.cpp

$ nm --demangle foo.o
0000000000000000 T foo()
```

シンボルが`T`となっているのは、バイナリに実装が埋め込まれていることを示している。

## 問題のケース

ことが起きたのは、コンストラクタやデストラクタを定義した場合である。

```cpp:bar.hpp
struct Bar {
  int var;
  Bar();
  ~Bar();
};
```

```cpp:bar.cpp
#include "bar.hpp"

Bar::Bar() { var = 1; }
Bar::~Bar() { var = 2; }
```

先ほどと同様にコンパイルしてみると、奇妙な現象が起こる。

```console
$ g++ -c bar.cpp

$ nm --demangle bar.o
0000000000000000 T Bar::Bar()
0000000000000000 T Bar::Bar()
0000000000000016 T Bar::~Bar()
0000000000000016 T Bar::~Bar()
```

なんと、全く同名の関数が2つずつ埋め込まれている。しかも、`T`というシンボルは実装が埋め込まれていることを示している。

私が最初これを見た時、多重定義(ODR違反)ではないか？またGCCのバグか？と思ったがそんなことはないようだ。

[Two identical constructors emitted? That's not a bug!](https://www.ibm.com/developerworks/community/blogs/5894415f-be62-4bc0-81c5-3956e82276f3/entry/Two_identical_constructors_emitted_That_s_not_a_bug?lang=en)

&nbsp;

これによると、GCCでは一つのコンストラクタから以下のような関数群を生成する。

<dl>
  <dt>complete object constructor</dt>
  <dd>オブジェクトそのものを生成するための関数</dd>
  &nbsp;
  <dt>base object constructor</dt>
  <dd>基底クラスのコンストラクタとして呼び出した際に使用される関数。ただし、仮想継承を用いていない場合はcomplete object constructorと同じ実装を用いる。</dd>
  &nbsp;
  <dt>complete object allocating constructor</dt>
  <dd>オブジェクトの生成後、<code>operator new(sizeof(class))</code>を呼び出して、メモリを確保するための関数。通常この関数は生成されず、他のコンパイラを併用する場合などに用いられる(参考: <a href="https://stackoverflow.com/questions/17728634/why-are-c3-allocating-constructors-never-used">Why are C3 allocating constructors never used?</a>)。</dd>
</dl>

デストラクタに対しても同様の関数群が生成される。
またこれらの関数はマングリングした後の名前が異なるが、その名前をデマングルするといずれも同じ名前になるため、同一の関数が複数存在するように見える。

先程の`bar.o`の中身を、デマングルせずに表示してみよう。

```console
$ nm bar.o
0000000000000000 T _ZN3BarC1Ev
0000000000000000 T _ZN3BarC2Ev
0000000000000016 T _ZN3BarD1Ev
0000000000000016 T _ZN3BarD2Ev
```

なるほど、確かに、マングリング後の名前は異なっている。

クラス名の後に`C1`と書いてあるものがcomplete object constructorで、`C2`はbase object constructorである。

関数のアドレス(offset)が一致しており、同じ実装を用いていることが分かる。

したがって、これは全くもって正常な動作であり、GCCのバグなどではなかったのだ！

このことはGCCのサイトの[Non-bugs](https://gcc.gnu.org/bugs/#nonbugs_cxx)というセクションにも記載されている。

# まとめ

GCCにおいて、コンストラクタやデストラクタの実装を含むソースコードをコンパイルすると全く同名の関数がバイナリに埋め込まれるが、これはGCC本来の仕様で、正常に動作するために必要なものである。
【DirectX11】C4316エラーへの対処法まとめ (#DirectX11 C4316 error and solution)

VisualStudio2015でDirectX11のプログラミングをしている。DirectXMath.hのXMATRIXを使おうと、このファイルをincludeし、変数宣言した途端、C4316エラーが発生した。このエラーへの原因と対処をまとめておく。

##原因
　DirectXMath.hのXMATRIXクラスを使おうと、変数宣言した途端発生した。XMMATRIXクラスは以下のように16バイト単位のメモリアライメントが定義されている。

```c++
__declspec(align(16)) struct XMMATRIX {
```
　VisualStudioが提供する標準の new/delete は8バイト境界だ。このため、このXMMATRIX使うクラスも16バイト単位のメモリアライメントで生成しなければならない。つまり、new/deleteをオーバーライドする必要がある。

##対処
前述の通り、XMMATRIXを保持・使用するクラスにて、以下のようにnew/delete関数をオーバーライドする。 \_mm_malloc / \_mm_free関数は、内部で \_aligned_malloc / \_aligned_free関数を呼び出している。

```c++:HogeHoge.cpp
class CHogeHoge {
	//16byte memory alignemt.
	DirectX::XMMATRIX m_matrix;

	//override the operator new/delete.
	void* operator new( size_t i ) {
		return _mm_malloc(i,16);
	}
	void operator delete( void* p ) {
		_mm_free(p);
	}
}
```
##より良い対処
以下のような テンプレートを使った AlignedAllocationPolicyクラスを作り、16バイトメモリアライメントが必要なクラスので使うと、同じコードを各クラスに書く手間が省ける。

```C++:AlignedAllocationPolicy.h
#pragma once
template <size_t T>
class AlignedAllocationPolicy {
public:
	static void* operator new( size_t i ) {
		return _mm_malloc(i,T);
	}
	static void operator delete( void* p ) {
		_mm_free(p);
	}
};
```
使い方はこうだ。

```C++:HogeHoge.cpp
class CHogeHoge : public AlignedAllocationPolicy<16> {
	//16byte memory alignemt.
	DirectX::XMMATRIX m_matrix;
};
```

##まとめ
　DirectXMath.hのDirectX::XMMATRIXは、SSE命令を使い行列を高速に処理するために、16バイトメモリアライメントになっている。そのため使う側もそれに応じたコードを書かなければならない。面倒くさいけど仕方ないね。

参考：
[alignemt error(C4316)](http://copynull.tistory.com/241) 韓国語
[warning C4316: object allocated on the heap may not be aligned 16.](https://stackoverflow.com/questions/20104815/warning-c4316-object-allocated-on-the-heap-may-not-be-aligned-16)
React Native Firebase が Carthage を認識してくれない

# 概要

- Carthage を使って firebase-ios-sdk を入れた
- インストールとビルドは成功した
- react-native-firebase で認識してくれなくて、詰んだ

# 解決策

素直に Cocoapods を使う

# 試した手順

https://github.com/firebase/firebase-ios-sdk/blob/master/Carthage.md を参考に、SDKを入れる

- Cartfile に記述

```ruby:Cartfile
binary "https://dl.google.com/dl/firebase/ios/carthage/FirebaseAnalyticsBinary.json"
binary "https://dl.google.com/dl/firebase/ios/carthage/FirebaseAuthBinary.json"
```

- インストール

```
carthage update
```

- `Carthage/Build/iOS/*.framework` ファイルを手動でFrameworksに追加する
- 起動する
- 次のコードを `App.js` などに記載


```js
import firebase from 'react-native-firebase'

firebase
  .auth()
  .signInAnonymously()
  .then(credential => {
    if (credential) {
      console.log('default app user ->', credential.user.toJSON())
    }
  })
```

Native でインストールしてないから、 `pod install` しろと怒られる。

Native にインストールできている証拠としては、 `AppDelegate.m` に Firebase 関連のコードを書いた時は、うまく動いている。

他にも色々なことを試したが、結局うまくいかなかった。 Cocoapods 親切すぎるのであまり使いたくないのだが、特に React Native の場合は Cocoapods から変えないほうが時間の節約になるということを学んだ。
zshの初期設定に詳しいサイトをまとめた。

# はじめに
素のbashの使いにくさに嫌気がさしてきたので、zshに乗り換えることにしました。

最近はfishというzshよりもユーザーフレンドリーで軽量なシェルが出ており、徐々に人気が出ているそうです。
自分もfishにしようか迷いましたが、以下の記事
[たった2つのポイントで！zshでもfish並のインクリメンタル補完を実現する](https://www.pandanoir.info/entry/2018/02/23/193721)
を見てzshに決めました。


# zsh導入に際して知っておくべきこと
自分がzsh導入時にいくつかの記事を読んで「最初にまとめて知りたかったな」と感じたことをまとめておきます。


- 設定ファイル関連
  - bashの設定ファイル(.bashrcや.bash_profile)同様、設定ファイルの書き方には流儀が色々ある。
  - とりあえずはzshの設定ファイルは環境変数も含めて.zshrcに書けばいい。
  - .zshrcは長くなってくると分割して管理した方が良い。
  - .zshrcはコンパイルできる。あまり分割していない場合はこれでいくらか速くなる。
    
- プラグイン関連
  - zshの威力（補完やシンタックスハイライトなど）を発揮するにはpluginを導入する必要がある。
  - oh-my-zshというフレームワークを全部入れるとzshが重くなる。
  - プラグイン管理ツールはAntigen(定番だが遅いらしい), zplug(速くて評価が高く、よくオススメされている。vimのvim-plugライクな仕様。), zgenなどがある。
  - 基本的に.zshrcにpluginに関する記述をするだけ。



# zshの設定に詳しい記事まとめ
- .zshrcファイルの例
  - [少し凝ったzshrc](https://gist.github.com/mollifier/4979906)
- zshの設定ファイルの種類と内容
  - [zshが起動時に読み込むファイルとその内容について](http://vorfee.hatenablog.jp/entry/2015/03/05/211447)
  - [zshの設定ファイルの読み込み順序と使い方Tipsまとめ](https://qiita.com/muran001/items/7b104d33f5ea3f75353f)
- .zshrcのcompile
  - [もっさりしたzshを改善する方法](http://blog.aqutras.com/entry/2016/05/12/210000)
- .zshrcの分割
  - [zshrcを分割する時のベターなファイル名を知りたい。](https://qiita.com/clomsync/items/091e1423bc96e5259b3a)
- zshの右プロンプトにgitの情報を表示する方法
  - [zshのターミナルにリポジトリの情報を表示してみる](http://tkengo.github.io/blog/2013/05/12/zsh-vcs-info/)
  - [【スクショ解説付き】zshでgitのブランチ名をステータスに応じて色付き表示させる簡易設定
](https://qiita.com/nishina555/items/f4f1ddc6ed7b0b296825)
deployerでデプロイしたが、.vueファイルがコンパイルされおらず、以前のapp.jsがまだ残ってる場合

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">手元だと動くのに、本番環境だと動かないのはなぜ <a href="https://t.co/L3BDQ3KMGw">pic.twitter.com/L3BDQ3KMGw</a></p>&mdash; れとるときゃりー🧡 サービス開発で生きていきたい DM開放してます (@retoruto_carry) <a href="https://twitter.com/retoruto_carry/status/1050300374781808640?ref_src=twsrc%5Etfw">2018年10月11日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">deployerでデプロイしたときに、.vueファイルがコンパイルされずに、前のapp.jsがまだ残ってるんだけど、どうすればいいんだろう...</p>&mdash; れとるときゃりー🧡 サービス開発で生きていきたい DM開放してます (@retoruto_carry) <a href="https://twitter.com/retoruto_carry/status/1050445618160709632?ref_src=twsrc%5Etfw">2018年10月11日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet" data-conversation="none" data-lang="ja"><p lang="ja" dir="ltr">cloudflareのキャッシュでした</p>&mdash; れとるときゃりー🧡 サービス開発で生きていきたい DM開放してます (@retoruto_carry) <a href="https://twitter.com/retoruto_carry/status/1050447663198437376?ref_src=twsrc%5Etfw">2018年10月11日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

laravel側のキャッシュを削除しても解決しなかったので、少しハマりました。

cloudflareを通していたので、そっちのキャッシュが問題だったようです。

[Webページの変更が反映されないときはこれが原因かも! CloudFlare のキャッシュを削除する方法](http://phiary.me/web-page-cloudflare-cache-clear-how-to/)
この記事を参考に/js/app.jsのキャッシュを指定して削除したら解決しました。
昔作ったCNNの簡単な(2層)モデルが出てきたので、貼っておく

# はじめに
昔、画像認識での正誤判定にkerasでモデル作成を行ったことがあるが、
その際のソースコードのかけらを発見したので、Qiita上にサルベージしておく。
# CNN

```python:2_layer_cnn.py
from keras.models import Sequential
from keras.layers import Activation, Dense, Dropout
from keras.utils.np_utils import to_categorical
from keras.optimizers import Adagrad
from keras.optimizers import Adam
import numpy as np
from PIL import Image
import os

# 学習用のデータを作る.
image_list = []
label_list = []

for dir in os.listdir("data/dog/ForFinalTrain/"):
    dir1 = "data/dog/ForFinalTrain/" + dir
    label = 0

    if dir == "Normal":
        label = 0
    elif dir == "Tumor":
        label = 1

    for file in os.listdir(dir1):
        if file != "Thumbs.db":
            label_list.append(label)
            filepath = dir1 + "/" + file
            image = np.array(Image.open(filepath).resize((25,25)))
            image = image.transpose(2,0,1)
            image = image.reshape(1, image.shape[0] * image.shape[1] * image.shape[2]).astype("float32")[0]
            image_list.append(image / 255.)

image_list = np.array(image_list)
Y = to_categorical(label_list)

'''
model = Sequential()
model.add(Dense(200, input_dim=1875))
model.add(Activation("relu"))
model.add(Dropout(0.2))

model(Dense(200))
model.add(Activation("relu"))
model.add(Dropout(0.2))

model.add(Dense(2))
model.add(Activation("softmax"))

opt = Adam(Ir=0.001)

model.compile(loss="categorical_crossentropy",optimizer=opt, metrics=["accuracy"])
'''
model = Sequential()
model.add(Dense(32, activation='relu', input_dim=1875))
model.add(Dense(2, activation='sigmoid'))
model.compile(optimizer='rmsprop',
              loss='binary_crossentropy',
              metrics=['accuracy'])

model.fit(image_list, Y,nb_epoch=1500, batch_size=100, validation_split=0.1)

total = 0.
ok_count = 0.

for dir in os.listdir("data/dog/ForFinalTrain/"):
    if dir == "Thumbs.db":
        continue

    dir1 = "data/dog/ForFinalTest/" + dir
    label = 0

    if dir == "Normal":
        label = 0
    elif dir == "Abnormal":
        label = 1

    for file in os.listdir(dir1):
        if file != "Thumbs.db":
            label_list.append(label)
            filepath = dir1 + "/" + file
            image = np.array(Image.open(filepath).resize((25, 25)))
            print(filepath)
            image = image.transpose(2, 0, 1)
            image = image.reshape(1, image.shape[0] * image.shape[1] * image.shape[2]).astype("float32")[0]
            result = model.predict_classes(np.array([image / 255.]))
            print("label:", label, "result:", result[0])

            total += 1.

            if label == result[0]:
                ok_count += 1.

print("seikai: ", ok_count / total * 100, "%")
```
めも：vue.jsでv-model使いつつ親子間でのデータ一意性を取る　vuex？知らんがな(´･ω･`)

実験用フォーム
![tmp01.png](https://qiita-image-store.s3.amazonaws.com/0/20341/7bf35d66-5b42-f45d-57bf-94ace6aeb461.png)

①親コンポーネント内に定義されたdata配列
②親コンポーネント内で①の中身を変更するフォーム
③子コンポーネント内で④の中身を変更するフォーム
④子コンポーネント内にある①からデータを受け取ったフォーム

やりたいこと：
・②から①を変更したら④にも反映される
・③から④を変更したら①にも反映される
・④を直接変更したら①にも反映される
・子コンポーネント内で④監視にcomputedでの下駄と雪駄を使いたい

コード

```html:parent.html
<div id="app">
    <!-- ３と４をつくるよ -->
	<div v-for="(item, index) in message" :key="index">
	<my-textbox v-model="item.text"></my-textbox>
	</div>

    <!-- 2をつくるよ　-->
	<div v-for="(val, index) in vals" :key="index">
		<input v-model="val.text" type="text" :placeholder="'parent '+index" />
		<button type="button" @click="fire(index)">fire</button>
	</div>
    <!-- 1を表示するよ -->
	<p>{{ message }}</p>
</div>
```
```js:parent.vue
new Vue({
	el: "#app",
	data: {
		vals:[
			{ text: "" },
			{ text: "" },
			{ text: "" }
		],
		message: [
			{ text: "form 0" },
			{ text: "form 1" },
			{ text: "form 2" }
		]
	},
	methods: {
		fire: function (i) {
			this.message[i].text = this.vals[i].text;
		}
	}
})
```


```js:child.vue
Vue.component("my-textbox", {
	template: `<div>
		<!-- 4をつくるよ -->
		<input v-model="internalValue" type="text" />
		<!-- 3をつくるよ -->
		<input v-model="hoge" type="text" placeholder="child" />
		<button type="button" @click="apply">apply</button>
	</div>`,
	props: {
		value: String
	},
	data() {
		return {
			val:this.value,
			hoge:null
		}
	},
	computed: {
		internalValue: {
			get() { return this.value },
			set(v) { 
				this.val = this.value;
				this.$emit("input", v);
			}
		}
	},
	methods: {
		apply: function() {
				console.log(this.value);
				this.val = this.hoge;
				this.$emit("input", this.hoge);
		},
	}
})
```
ログデータを正規化するイディオム「sort」「uniq」をよく忘れる自分のための備忘録。ついでにPythonでも同様のこと書いたメモ

# はじめに
シェルでログデータをガチャガチャする場合も時としてありますよね。
そんな時に使う[cat][sort][uniq]の熟語的なスクリプトがありますが、
よく忘れるのでここに置いときます。

それだけでは記事として面白みが薄いので、Pythonで同様のふるまいをするコードも置いときます。
# シェル
```shell:重複削除の正規化
cat log.txt | sort | uniq > uniq.txt
```
# Python
```python:sort_uniq.py
l = [3, 3, 2, 1, 5, 1, 4, 2, 3]
l_unique = list(set(l))
print(l_unique) # [1, 2, 3, 4, 5]
```
思ったこと
sort->uniqやset()では、中身の順序性を保持しないのが欠点。
対象フォルダから特定文字列のみを抽出するスクリプト

# はじめに
自然言語領域で使ったスクリプトの一部です。

用途としては、Wikipediaから抽出された膨大なテキストデータ(9GB...)から特定文字列を含む行のみを抽出して、それをAImodelの学習データに組み込みたかったため、突貫でつくりました。

# 表示するコード
```python:print_words.py
import os
import re

search_dir = "/home/ono/test"
search_pattern = ""

file_name_list = os.listdir(search_dir)
for file_name in file_name_list:
    f = open(os.path.join(search_dir, file_name))
    line = f.readline()
    line_number = 1
    while line:
        m = re.search(search_pattern, line)
        if m:
            print("Pattern found: file:%s, line:%d, data:%s" % (file_name, line_number, line))
        line = f.readline()
        line_number = line_number + 1
    f.close()
```

少しのメモ書き
### os.listdir
ディレクトリとファイルの一覧を取得。
その後for文で一文ずつファイル名のみ取り出す。
### os.path.join(x,y)
ディレクトリ+特定ファイル名で走査ファイルの決定を行う。
### line_number = 1 の理由
number は未定義の場合、0始まりなので、表示用計算ならば1を置いた。
### re.search(x, y)
文章がパターンにマッチするか検索している部分
## 今振り返ると改善点。
- 検索文はsys.args[]などで引数指定にすることも可能
- re.search()よりもre.compile()にすると実行速度が向上する
- open()よりもwith open()のほうがコードが短くなる

# 抽出するコード
```python:get_words.py
import os
from glob import glob

input_dir = "/home/ono/AA"
output_file = "/home/ono/extract.txt"
featuredwords = "dicTechterm_180411.txt"

def main():

    hako = []

    for path in glob(os.path.join(input_dir,'wiki_*')):
        with open(path,"r",encoding="utf-8") as file:
            for contents in iter_docs(file):
                if contents != "":
                    hako.append(contents)
                with open(output_file, "w") as out:
                    out.write('\n'.join(hako))

    print(hako)
    
def iter_docs(file):

    contents = []

    with open(featuredwords, "r",encoding="utf-8") as term:
        #特徴語を格納する
        query = []
        for text in term:
            query.append(text.strip('\n'))

        #格納した特徴語を検索キーとして、
        for w in query:
            breakflg = 0 #初期化フラグ
            for line in file:
                if breakflg == 1:
                    continue
                if line.startswith('<doc '):
                    pass
                elif line.startswith('</doc>'):
                    pass
                else:
                    if line.find(w) > -1:
                        contents.append(line.strip("\n")) 
                        breakflg = 1
                        break
    return contents
                
if __name__ == '__main__':
    main()
```
AndroidでMVNOを判断したい。(確認中)

MVNOの識別って出来ないのか、調べたのでメモ。
実機お試しはしていないので、これを使えば出来るのでは？という段階。
確認したら追記予定です。

# キャリアコードってなんだっけ
スマホの電話回線のキャリアを識別出来る数字。
MCC(Mobile Country Code)＋MNC(Mobile Network Code)

#取得方法
キャリアコードでとる方法と、キャリアコードの名前をとる方法がある。

## キャリアコードを取得
~~~java
TelephonyManager tm = (TelephonyManager)Context.getSystemService(Context.TELEPHONY_SERVICE);
String carrierCode = tm.getSimCarrierId();

~~~

https://developer.android.com/reference/android/telephony/TelephonyManager.html#getSimCarrierId()

## キャリアコード名を取得
~~~java
TelephonyManager tm = (TelephonyManager)Context.getSystemService(Context.TELEPHONY_SERVICE);
CharSequence carrierCodeName = tm.getSimCarrierIdName();

~~~

https://developer.android.com/reference/android/telephony/TelephonyManager.html#getSimCarrierIdName()

## パーミッション設定
TelephonyManagerを使用する場合、AndroidManifest.xmlに権限の宣言が必要です。

~~~
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
~~~

## キャリアコードの一覧
https://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/master/assets/carrier_list.textpb

UQ系がMCC441なのだけど、上記にはなかったので、もうちょっと調べないとダメかも。

---

##プロバイダの取得
おなじくTelephonyManagerで、getSimOperatorというのがあり、
これの説明がズバリ「MCC+MNCを返します」となってる。
こっちを使うのでは？
https://developer.android.com/reference/android/telephony/TelephonyManager#getSimOperator()
フロントエンド初心者がW3C勧告に出会うまで 

こんにちは、フロントエンド初心者のエンジニアです。
RFCやW3C勧告については、今まで何度か耳にしたことはあったのですが、今回初めて生のW3C勧告に辿り着いて(と言っても日本語翻訳ですが)、テンションが上がったので、その経緯についてまとめてみます。
※ フロントエンド初心者が解釈したものなので、間違い等もたくさんあるかと思います。まさかり怖い。

## 経緯
* 仕事で初めてちゃんとjQueryを使う必要が出てきた。
* jQueryは、論理的に「あれがそうだから、こう動く」ではなく、「ああしたらこう動く」という暗記ばかりで面白くなかった。
* そのせいか、使い方を全然覚えれなかった。
* 本格的にjQueryを使うからには、「HTMLがなぜJavaScriptで操作できるのか」などの疑問を解消した上で開発したい。

## 最初の疑問
* ブラウザ上で動くJavaScriptはHTMLドキュメントに対して、なぜgetelementbyidなどの操作が可能なのか？
* そもそもただの文字列であるHTMLをどうして操作することができるのか？

## JavaScriptはDOMを操作している？
とりあえず手当たり次第調べてみた。わかったことは下記のような感じ。

* JavaScriptはDOMというものを操作することでHTMLを操作しているらしい。
* DOMって何？？Document Object Model？？DOM API？？？
* DOMはHTMLをツリー構造に整理したもの。HTMLのタグや値はノードと呼ばれているらしい。意味わからん。
     * 参考：[改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで | 山田 祥寛 |本 | 通販 | Amazon](https://www.amazon.co.jp/%E6%94%B9%E8%A8%82%E6%96%B0%E7%89%88JavaScript%E6%9C%AC%E6%A0%BC%E5%85%A5%E9%96%80-%E3%83%A2%E3%83%80%E3%83%B3%E3%82%B9%E3%82%BF%E3%82%A4%E3%83%AB%E3%81%AB%E3%82%88%E3%82%8B%E5%9F%BA%E7%A4%8E%E3%81%8B%E3%82%89%E7%8F%BE%E5%A0%B4%E3%81%A7%E3%81%AE%E5%BF%9C%E7%94%A8%E3%81%BE%E3%81%A7-%E5%B1%B1%E7%94%B0-%E7%A5%A5%E5%AF%9B/dp/477418411X/ref=zg_bs_14304181_17?_encoding=UTF8&psc=1&refRID=H6BAP91DMMJXBSDQJQHS)

# ブラウザとDOMはどういう関係？
DOMの詳細に入る前に、HTML・ブラウザ・DOMの関係を整理してみた。

* そもそも、HTMLというただのテキストで書かれたものが、Chromeなどのブラウザで綺麗に表示されるのはなぜ？？どうやってるの？？
* HTMLの内容を解析して、ブラウザに描画するものが必要じゃない？

* 調べてみると、その解析・描画機はレンダリングエンジンと言われていて、Chromeなどはそのエンジンを搭載しているらしい。
    * [HTMLレンダリングエンジン - Wikipedia](https://ja.wikipedia.org/wiki/HTML%E3%83%AC%E3%83%B3%E3%83%80%E3%83%AA%E3%83%B3%E3%82%B0%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%B3)
* そもそもブラウザって何だろう？ PCなどからWebページをみるための便利な道具？
* ブラウザって、テキストエディタや地図アプリと同じように、単なる「アプリケーション(ソフトウェア)」じゃない？
* 詳細に言うと、URLを指定してリクエストを投げて、帰ってきたHTMLなどを解析して画面に描画するGUIアプリケーションじゃない？？

# DOMの実装
どうやらDOMは、GUIアプリケーションたるブラウザが、HTMLを操作する為に必要な何からしい。DataBaseにおける、SQLみたいな立場なのかな？

* じゃあそのDOMって何で作られているんだろう？？
* 「DOM 実装」でググってみる。
* MDNのDOM紹介ページにこんなことが書かれていた
    * 「W3C DOM および WHATWG DOM 標準は、現代のブラウザーのほとんどで実装されています」 [DOM の紹介 - DOM | MDN](https://developer.mozilla.org/ja/docs/DOM/DOM_Reference/Introduction)
* 文脈的にDOMは、ブラウザを作る際に必要な一つの仕様のようなもの？？

# DOMの仕様
DOMの実装の詳細はわからなかったが、DOMは仕様のようなものであることはわかった。どう言う仕様なのかを調べる。

* 「DOM 仕様」でググってみる
* WikiPediaのページがヒットしたので、中身を見てみる。(というかどうして最初に見なかったんだ...) [Document Object Model - Wikipedia](https://ja.wikipedia.org/wiki/Document_Object_Model)
* 「仕様」と言う項目の中に、W3C勧告のリンクがあったので飛んでみる [DOM1仕様書](http://www.doraneko.org/misc/dom10/19981001/cover.html)
* DOMを実装する際の仕様がいろいろ書かれている。こ、ここ、これだああああ！！！


## まとめ
以下の最初の疑問に答えてみる。
> * ブラウザ上で動くJavaScriptはHTMLドキュメントに対して、なぜgetelementbyidなどの操作が可能なのか？
> * そもそもただの文字列であるHTMLをどうして操作することができるのか？

* Chromeなどのブラウザから送信されたリクエストの結果として、ローカル端末に帰ってきたHTML文書は、再びブラウザに届けれる。
* 送られてきたHTML文書などを元に、ブラウザのレンダリングエンジンはHTML文書の文字列を解析し、画面に描画する。
* ブラウザは、W3C勧告で規程されたDOMの仕様を実装しており、HTMLを操作する仕組みを備えている。
* そのため、JavaScriptのメソッドなどをブラウザで実行することで、HTML文書に対して、要素の取得や変更・削除などの特定の動作の実行が可能になっている。

## 感想など
* フロントエンドの技術って、丸暗記+絵描きだと思っていたのですごい苦手意識あったけど、ゴリゴリのロジカルな技術の世界のようで少し好きになった。

# 一応
* 素人の仮説なので間違いが多いと思いますが、間違いが酷かった場合は優しくコメントしてもらえると嬉しいです。
PowerShell でフォルダーを一括作成する

[ブログからの転載](https://1bed.allright.life/?p=2788)

## 経緯

先日同僚が、お客様からもらったリストを元に、約 5,000 個程のフォルダーを作成するという話をしていたので、PowerShell でサクッと試してみた

## 環境

* Windows Pro 10
* PowerShell 5.1.17134.228

## 用意したデータ

次の内容で list.txt として用意した

```
ルート
ルート/子１
ルート/子１/孫１－１
ルート/子１/孫１ー１/ひ孫１－１－１
ルート/子１/孫１ー１/ひ孫１－１－２
ルート/子１/孫１－２
ルート/子１/孫１－２/ひ孫１－２－１

ルート/子２
ルート/子２/半角 スペース
ルート/子２/全角　スペース
ルート/子２/重複テスト
ルート/子２/重複テスト
ルート/子２/hoge*異常系テスト
```

* 1-7 行目まで「ルート/子１」の部分が正常系
* 8 行目が空行テスト
* 9 行目以降はデータの異常系テスト

## コード

```powershell
Get-Content list.txt | %{ &({ [void](New-Item ($_.ToString()) -ItemType Directory -Force)}, { Write-Output "is row empty" })[[string]::IsNullOrWhiteSpace($_.ToString())] }
```

何となく無理やりワンライナーで書いてみました

1. list.txt を読み込み
2. ForEach-Object(コードでは省略して % と表記)で行数分繰り返す
  * フォルダ作成処理
     - 空行ではない時行が空じゃないときにフォルダを作成
     - 空行の時「is row empty」と表記する

## 実行例

```powershell

Get-Content list.txt | %{ &({ [void](New-Item ($_.ToString()) -ItemType Directory -Force)}, { })[[string]::IsNullOrWhiteSpace($_.ToString())] }

New-Item : パスに無効な文字が含まれています。
発生場所 行:1 文字:38
+ ...  &({ [void](New-Item ($_.ToString()) -ItemType Directory -Force)}, {  ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (C:\Users\hoge\...\子２\hoge*異常系テスト:String) [New-Item]、ArgumentException
    + FullyQualifiedErrorId : CreateDirectoryArgumentError,Microsoft.PowerShell.Commands.NewItemCommand
```

予定通り、異常系テストの最終行のファイルやフォルダ名で使えない文字でエラーが出た

## 考察

ちゃんと書けば try-catch-finally を入れるんだろうけど、とりあえずエラーが出た箇所の行を修正していけばよさそう
rails5でjQueryを使う

# rails5でjQueryを使う方法
rails5でjQueryを使うためには、<br>
1.gemのインストール,<br>2.application.jsへの記述　<br>3.application.html.erbへの記述

の３つの作業が必要

## 1.gemのインストール
gemfileに gem "jquery-rails"を記述し、bundle install

gemfile
```gem "jquery-rails"
```
## 2.application.jsファイルへの記述
app/assets/javasciript下にある、application.jsにjQueryを読み込ませるコードをかく
（必ずapplication.jsにかくこと。ほかのjsファイルではダメ！）

application.js
```//= require jquery
//= require jquery_ujs
```
## 3.application.html.erb
application.html.erbのhead内に以下の記述をする（すでに書いてあったらそのままにする）
```<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
```

# 最後に
Qiita初投稿です。よろしくお願いします。
【Python】Linkを取得したいときのスクリプト-初歩

# はじめに
昔、自然言語処理領域でのデータ集めのためにスクレイピングのスクリプトを作ってました。
昔のログをあさっていたら、その際のスニペットが発掘されたので、このまま闇に葬るのもあれなので
Qiita上にアップロードします。

かなり初歩的なリンクのみを抜き出すスクリプトで、phantomJSを使用しているのでSPAページからリンクを抜き出したかったのかと思います（すっとぼけ）。

きっとurl が正しく指定されているならば、きっと動くはず。。。
# スクリプト

```python:get_links_by_phantomjs.py
import functools as ft
import lxml.html
from selenium import webdriver
import re

def get_link():
    driver = webdriver.PhantomJS()
    for page in range(1,12+1):
        url = f"http://ssmania.info/category/%E3%83%87%E3%83%AC%E3%83%9E%E3%82%B9?page={page}"
        driver.get(url)
        root = lxml.html.fromstring(driver.page_source)

        link_urls = [link_element.get("href") for link_element in root.cssselect('a.articlelink')]
        print(link_urls)
        yield link_urls

get_link_gen = get_link()

with open("linkes.dat", "w") as f:
    for links in get_link_gen:
        for link in links:
            print(link)
            f.write(link)
```
俺的ベストなPython開発環境構築方法

# 対象読者
プログラミング初心者やエンジニア1年生



# はじめに
結構Pythonの環境構築には迷いポイントが多いと思う。PythonはOSのシステム部分やデータ分析、プラグイン開発にWebアプリ開発と幅広い分野で使われる言語だからだ。その分多様な想定ユーザーがいて、それぞれに適した環境構築方法がある。

この記事で対象とするのは「これからプログラミングを始めたい」という人。

初めてPythonの開発環境を構築する場合、大体次の情報を見つけるんじゃないかと思う。

- なんか2系と3系があってどっちも使われているらしい
- パッケージ管理にpipとcondaというものがあるらしい。しかもそれぞれ用途が違い共存できない
- 不用意にPython3を導入するとローカルのPython2が使えなくなり既存システムが壊れるらしい
- virtualenvとかvenvとかよく分からない単語が次々出てくる

Pythonは素晴らしい言語だと思うので、こんなつまらないことで時間を浪費するのはもったいないし、上記の疑問はしばらくやっていれば自然と解決する。
という訳で私が考える最高にシンプルな環境構築方法を書くことにした。


# 結論
Dockerを使いましょう。
Dockerとは「コンテナ」というプログラムを実行するための環境を作ってくれるツールのこと。ローカルの環境を汚さないので安全です。
コマンドを1発打てばコーヒーを飲んでいる間に環境構築が終わります。

Python開発に限らず、現在(2018年10月)のほとんどの開発現場でDocker使ってるんじゃないかな？ってくらい超絶便利なシロモノなので、入れておいて損にはならない。



# Dockerのインストール
## Windowsユーザーの場合
### Windows 10 Professionalユーザー
Docker Desktopをインストールする(サイト：https://www.docker.com/products/docker-desktop)
### それ以外
Docker toolboxをインストールする(サイト：https://docs.docker.com/toolbox/toolbox_install_windows/)

## Macユーザーの場合
### OS X 10.11 El Capitan以降のユーザー
Docker Desktopをインストールする(サイト：https://www.docker.com/products/docker-desktop)
### OS X 10.10 Yosemite以前の場合
Docker toolboxをインストールする(サイト：https://docs.docker.com/toolbox/toolbox_install_mac/)



# 開発環境を構築する手順

- Docker Quickstart Terminal(インストール時に導入されたはず)を開く
- `docker pull python`と打ち込んでEnter
- ダウンロードが始まるのでしばらく待つ

これで環境構築完了。最新バージョンのPythonが使えるようになる。

# 開発を始める方法

- 適当な場所にプロジェクトフォルダーを作る
    - `mkdir project-folder-name`
- プロジェクトフォルダーに移動
    - `cd project-folder-path`
- コンテナを立ち上げる
    - `docker run -it -w /app -v $(pwd):/app python bash`

試しに`python --version`と打ち込むとpythonのバージョンが表示されるはず。
haskellで一番身近に感じるモナド「getLine」と「putStrLn」

getLineで標準入力から入力した文字を取得、putStrLnで文字を標準出力に表示することができます。
getLineとputStrLnのタイプをghciで見てみます。

```
Prelude> :t getLine
getLine :: IO String
Prelude> :t putStrLn
putStrLn :: String -> IO ()
```

「```IO String```」とは何かというと、「IOというアクションを実行したらStringの値を生成しますよ」という意味です。[haskell公式:IO入門編](https://wiki.haskell.org/IO入門編)
「```String -> IO ()```」はString型を引数に入れてIO ()が返ってくるという意味です。

というわけでgetLineで標準入力から取得したStringをそのままStringで返す関数、つまり```IO String -> String```というような関数があればputStrLnの引数に入れられそうですね。

....
。。
。。。。が、haskellには```IO a -> a```というような関数が基本的に用意されていません。なぜかというとIOは**アクション**と呼ばれ、乱数・時刻の取得・ファイル入力など、実行するたびに異なる結果を返す可能性があるため、関数とは別物として扱っているからです。なのでgetLineはそもそも関数ではなく**IOアクション**と呼ばれます。

じゃあどうすればgetLineで入力した文字列をputStrLnに入れられるかというと、ここでモナドが登場します。IOアクションは「モナド」であるため、モナドから値を取り出す→その値を関数に適用する、という流れとなります。

つまり、

- getLineは```IO String```のIOアクション(モナド)なので、「IO String」からStringの値だけ取り出す
- 取り出した値をputStrLnの引数に入れる

という流れとなります。

IOモナドから値を取り出す一つの方法として「**<-**」演算子を用います。

```main.hs
main :: IO ()
main = do
  line <- getLine
  putStrLn line

```

```IO String```であるgetLineからStringの部分だけをとってきてlineに束縛し、putStrLn関数の引数に入れています。putStrLnはStringを引数にして　IOアクションを返す```String -> IO String```の関数であり、標準出力に表示するIOアクションを返します。

他にも**>>=**を用いる方法もあります。

```
main :: IO ()
main = 
  getLine >>= putStrLn
```
変数への束縛を行わず、getLineのStringをそのままputStrLnの引数に入れることができます。

参考: [Haskell IOモナド 超入門](https://qiita.com/7shi/items/85afd7bbd5d6c4115ad6)
【Python】戻り値の型がわからないメソッドを正しく呼びたい【typing】

冷静に考えれば当たり前の話だけど、ちょっと迷ったのでメモ。

# 要件
`foo()`メソッドを持つオブジェクトを受け取り、そのオブジェクトの`foo()`メソッドを呼んで、その戻り値を返す関数`call_foo()`を定義したい。

```fooables.py
class Fooable1:
    def foo(self) -> int:
        return 42

class Fooable2:
    def foo(self) -> str:
        return 'bar'
```

```call_foo.py
def call_foo(x: '???') -> '???':
    return x.foo()
```

```main.py
from fooables import Fooable1, Fooable2
from call_foo import call_foo

if __name__ == '__main__':
    a = call_foo(Fooable1())  # Expected type for a: int
    b = call_foo(Fooable2())  # Expected type for b: str
    c = call_foo(42)  # Expected to raise error at static type checking
```

`call_foo()`の引数`x`は`foo()`を持つことだけが規定されていて、`x.foo()`の戻り値の型を`call_foo.py`モジュールから見ることはできない。

# 失敗例

```call_foo.py
from typing import Any

def call_foo(x: Any) -> Any:
    return x.foo()
```

`Any`を受け取って、`Any`を返すようにしてみた。

```main.py
from fooables import Fooable1, Fooable2
from call_foo import call_foo

if __name__ == '__main__':
    a = call_foo(Fooable1())  # Inferred type is "Any"
    b = call_foo(Fooable2())  # Inferred type is "Any"
    c = call_foo(42)  # No error and inferred as "Any"
```

全て`Any`になってしまい、何の情報も残らない。失敗。

# 正解例

```call_foo.py
from typing_extensions import Protocol
from typing import Generic, TypeVar
from abc import abstractmethod

T_co = TypeVar('T_co', covariant=True)

class FooableType(Generic[T_co], Protocol):
    @abstractmethod
    def foo(self) -> T_co:
        raise NotImplementedError()

def call_foo(x: FooableType[T_co]) -> T_co:
    return x.foo()
```

これで期待通りの動作になる。

```main.py
from fooables import Fooable1, Fooable2
from call_foo import call_foo

if __name__ == '__main__':
    a = call_foo(Fooable1())  # Inferred type is "int"
    b = call_foo(Fooable2())  # Inferred type is "str"
    c = call_foo(42)  # Error: Argument 1 to "call_foo" has incompatible type "int"; expected "FooableType"
```

## 解説

「`foo()`を持つ任意の型」を表現するためには、`Protocol`を使うのが良い。
`foo()`を持つクラスを作ってそれを継承してもらってもいいが、今回の場合`Fooable`がどのようなクラスなのか`call_foo`モジュールは知らないので、こちらの要求するクラスを継承してもらえるとは考えにくい。
従って、`Protocol`と`abstractmethod`を用いて表現することになる。

「`foo()`の返す型」を返したい場合は、ジェネリッククラス`Generic[]`と型変数`TypeVar`を用いて、 C++ で言うところのテンプレートクラスにしてしまうのが良い。
`Generic[T]`を継承することで、このクラスをジェネリッククラス、すなわち受け取った型によって引数や戻り値などの型を変更できるクラスにすることができる。
この型は今回戻り値の型にしか使わないので、共変であること（例えば、`FooableType[float]`型の変数に`FooableType[int]`型の値を代入できること）を明示すると良い。実際、mypy 0.630 はこの`T_co`を不変にすると「Invariant type variable 'T_co' used in protocol where covariant one is expected」と怒ってくれる。

# おわり

`Protocol`と`Generic`の組み合わせは強力で、かなり任意のお気持ちを表すことができる。
積極的に使っていきたい。
WebRTC Native Client Momo をビルドしてみた

(追記:20190817)
この記事はすでに古いです。以下のページを見て試して下さい。
https://github.com/shiguredo/momo/blob/develop/doc/BUILD_LINUX.md
(追記ここまで)

https://github.com/shiguredo/momo/blob/develop/BUILD.md
を見ながらやってみた。

# ソースコードの入手

```
git clone --recursive git@github.com:shiguredo/momo.git
```
githubにssh keyを登録していないとpermission deniedになる。
以下のようにすればOK

```
git clone --recursive https://github.com/shiguredo/momo.git
```

# docker のインストール

ubuntu 18.04 では以下のようにインストールできる。

```
sudo apt install docker.io
```

自分のユーザ (この場合はkoba) を dockerのグループに追加する。

```
sudo adduser koba docker
```

有効にするために、一度ログアウトして再度ログインする。

インストールできたdockerのバージョンは以下の通り。

```
$ docker version
Client:
 Version:	17.12.1-ce
 API version:	1.35
 Go version:	go1.10.1
 Git commit:	7390fc6
 Built:	Wed Apr 18 01:23:11 2018
 OS/Arch:	linux/amd64

Server:
 Engine:
  Version:	17.12.1-ce
  API version:	1.35 (minimum version 1.12)
  Go version:	go1.10.1
  Git commit:	7390fc6
  Built:	Wed Feb 28 17:46:05 2018
  OS/Arch:	linux/amd64
  Experimental:	false
```

# ビルド

```
cd momo/build/
nohup make armv6 &
tail -f nohup.out 
```

できたファイルはこれ。

```
$ ls -l momo-armv6-m70-20181011152123 
-rwxr-xr-x 1 koba koba 49975560 Oct 11 15:59 momo-armv6-m70-20181011152123
$ file momo-armv6-m70-20181011152123 
momo-armv6-m70-20181011152123: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.2.0, with debug_info, not stripped
```
Alexa開発メモ（音声による応答での適切な表現と情報量について）

# 要旨
先日、はじめてAlexaのスキルを作成して公開しました。
音声応答の内容検討でちょっと困った点＆解決した内容あったので共有します。

# アプリの概要
- 観光イベントの問い合わせアプリ
- 入力の発話：検索条件（イベントのジャンル など）
    - 例）(スキル名)で"アート"のイベントを教えて
    - 音声＋文字（Alexaアプリのカード通知）で応答
    - イベントが複数件該当した場合は、MAX5件目までを回答
- イベント情報は外部APIからJSON形式で取得。JSONを加工して応答データを作成。

# とりあえず作った音声応答
アプリケーション側で作成した応答データのイメージは以下の通りです

> イベント名：山本大と現代美術の肖像
> 開催場所：イベントスペースA.R.T
> アクセス：両国駅B5出口から出て両国公園に向かって徒歩5分
> 開催期間：2018/10/1～2018/12/13
> 開館時間：6:00～23:00
>
> イベント名：フー・バーの華麗なる世界
> 開催場所：日本橋三越本店　美術画廊
> アクセス：銀座線・半蔵門線「三越前」より徒歩１分
> 開催期間：2018/10/13～2018/11/25
> 開館時間：9:00～22:00

上記データは目で見る分には（多少長いですが）問題ないと思います。

が、上記文字データを音声応答データとしてそのまま使ったところ、以下のような読み上げになりました…

> いべんとめい　やまもとだいとげんだいびじゅつのしょうぞう
> かいさいばしょ　いべんとすぺーす　えー　あーる　てぃー
> あくせす　りょうこくえきびーごでぐちからでてりょうこくこうえんにむかってとほごふん
> かいさいきかん　にせんじゅうはちねんじゅうがつついたちからにせんじゅうはちねんじゅうにがつじゅうさんにち
> かいかんじかん　ろくじからにじゅうさんじ
>
> いべんとめい　ふー　ばー　のかれいなるせかい
> かいさいばしょ　にほんばしみつこしほんてん　びじゅつがろう
> あくせす　ぎんざせん　はんぞうもんせん　みつこしまえよりとほいっぷん
> かいさいきかん　にせんじゅうはちねんじゅうがつじゅうさんにちからにせんじゅうはちねんじゅういちがつにじゅうごにち
> かいかんじかん　くじからにじゅうにじ

実際にはAlexaが（割と）流暢に喋ってくれるので上記のようなひらがな書きよりかはマシでしたが、
率直に言って「**長くて聞く気が起きない**」「**何言ってるかよくわからない**」という感じでした。

# 問題点の整理
改良の方針を決めるために、ひとまず問題と感じたポイントをリストアップしました。

- 音声情報は文字情報と違って、「最初に全体像を確認してから個別部分を見る」が難しい
    - 文字情報の「飛ばし読み」は容易だが、音声の「飛ばし聞き」は困難
    - 応答を受け取った側は、応答内容の分量を即座に推し量ることができない
    - 箇条書きによる構造情報は音声では表現されづらい
- アプリが発話を正しく解釈しているのか不安
- 沢山数字が出てくるとしんどい。特にyyyy/mm/ddでFrom～Toを読むと2×8個の数字が出てくる。
- 固有名詞を適切に読んでくれない
    - 人名の「やまもとまさる」が「やまもとだい」と読まれる
    - 東京の地名の「りょうごく」が二つの国を表す「りょうこく」になる など

今回作成したアプリは外部APIから情報を取得している仕様上、固有名詞を適切に読ませるための対応が難しかったので、それ以外についての改良を実施しました。

# 改良内容　★本記事のポイント
改良した点は以下の通りです。

- 音声応答内容は必要最小限にする。補足的な情報は文字応答のみで表示
- 最初に結果件数を返す
- 応答の最初で発話内容を復唱する
- 箇条書きではなく、文章で応答する。スペースや読点で音声にメリハリをつける。
- yyyy/MM/ddのFrom～Toの読み上げを廃止。イベント終了日までの日数のみを読み上げ。

改良後の応答データは以下の通りです。

> あーとのいべんとは　にけん　です
> 
> いっけんめは 　やまもとだいとげんだいびじゅつのしょうぞう　です
> かいさいは　いべんとすぺーす　えー　あーる　てぃー
> しゅうりょうは　ごじゅうはちにちご です
> 
> にけんめは 　ふー　ばー　のかれいなるせかい　です
> かいさいは　にほんばしみつこしほんてん　びじゅつがろう
> しゅうりょうは　さんじゅうににちご です

だいぶスッキリしました！
固有名詞の読み方は相変わらずですが、聞いていてなんとなく意味がわかればそこまで気になりませんでした。

# その他思ったこと
画面ベースのアプリで検索処理を実現する場合は、
「検索結果を最大20件程度画面に表示してユーザに目視で目的の情報探してもらう」
のような作りになっていることが多いかと思いますが、音声応答アプリではこの方法は難しいかと思いました。
　⇒ 20件分の情報を耳で聞きながら目的の情報に到達するのは難しい

音声応答ベースで検索処理を実現する場合は、
「対話的な処理を繰り返しながら１～３件程度になるまで結果絞り込みをする」
のような作りにするのがよいのかなーと思いました。
Table の値取得 jquery (jqueryには、jqueryの立場がある)

**[他の記事を見ていたら](https://qiita.com/kokonotun/items/d5c6555f31bdfbb39e49)**ふとコーディングした。
![getdata.PNG](https://qiita-image-store.s3.amazonaws.com/0/274715/879baa97-0cbf-028a-023a-0d45886646ca.png)
# テーブルに表示したデータの取得

**テストデータ**

``` data.html
   <table id='table' class="table table-sm table-bordered table-striped table-responsive-sm table-hover w-100 h-60">
    <thead><tr>
   <th>ID</th>
   <th>名前</th>
   <th>名前フリガナ</th>
   <th>性別</th>
   <th>血液型</th>
   <th>生年月日</th>
   <th>電話番号</th>
   <th>携帯番号</th>
   <th>メール</th>
    </tr></thead>
    <tr>
   <td>1</td>
   <td>関波子</td>
   <td>セキナミコ</td>
   <td>女</td>
   <td>AB</td>
   <td>1980/07/31</td>
   <td>03-3060-4716</td>
   <td>090-7787-3784</td>
   <td>sk@eaccess.net</td>
   </tr>
    <tr>
   <td>2</td>
   <td>小倉準司</td>
   <td>コクラジュンジ</td>
   <td>男</td>
   <td>A</td>
   <td>1973/10/08</td>
   <td>0166-36-3522</td>
   <td></td>
   <td>junzi-kokura@eaccess.net</td>
   </tr>
    <tr>
   <td>3</td>
   <td>西村有紀子</td>
   <td>ニシムラユキコ</td>
   <td>女</td>
   <td>O</td>
   <td>1972/12/05</td>
   <td>0745-67-2723</td>
   <td>090-5165-2074</td>
   <td>okikuy1972@livedoor.com</td>
   </tr>
    <tr>
...........................................省略
```
## jqueryの立場でコーディングすると

```getdata.js
  function getData(){
		var d=[];$('table tr').each(function(i, e){
		 var dd=[]; if (i===0) $(this).find('th').each(function(j, el){dd.push($(this).text())}); 
					 else $(this).find('td').each(function(j, el){dd.push($(this).text())});
		 d.push(dd);
		});
   return d;
  }
```
ご指摘ありがとうございます。上記のプログラミングは、一般的お作法に従っていません。私のプログラミングフィンガープリントです。
連想記憶術で頭にしまうために上記のようなコーディングになっています。
私は、jsでコーディングするときに改行やタブを使いません。
ご指摘のように見やすくインデントすると

```code.js
function getData(){
var d=[];
$('table tr').each(function(i, e){
var dd=[];
if (i===0)
$(this).find('th').each(function(j, el){dd.push($(this).text())});
else
$(this).find('td').each(function(j, el){dd.push($(this).text())});
d.push(dd);
});
return d;
```
結果は、以下の通りです。

``` .py
[["ID","名前","名前フリガナ","性別","血液型","生年月日","電話番号","携帯番号","メール"],
["1","関波子","セキナミコ","女","AB","1980/07/31","03-3060-4716","090-7787-3784","sk@eaccess.net"],
["2","小倉準司","コクラジュンジ","男","A","1973/10/08","0166-36-3522","","junzi-kokura@eaccess.net"],
["3","西村有紀子","ニシムラユキコ","女","O","1972/12/05","0745-67-2723","090-5165-2074","okikuy1972@livedoor.com"],
```
Codility Lesson1 BinaryGap 2進数整数の1と1の間に連続して存在する0の最大長探索

# Codilityとは？

[Codility](https://www.codility.com/)はアルゴリズム系のプログラミングテストを提供しているサイトです。限られた時間内に問題の解答を提出すると、以下の2つの観点でスコアが評価されます。

- 正確性(Correctness)
- 効率性(Performance)

企業が人を採用する際に実力を確認するためのプログラミングテストとしても使われているようです。プログラミングテストの対応言語はメジャーな言語はほぼ対応しています。

https://app.codility.com/programmers/
上記のリンクにLesson問題が公開されていたのでPythonでLesson1をやってみました。

# Lesson1 BinaryGap 問題説明

https://app.codility.com/programmers/lessons/1-iterations/binary_gap/

> A binary gap within a positive integer N is any maximal sequence of consecutive zeros that is surrounded by ones at both ends in the binary representation of N. For example, number 9 has binary representation 1001 and contains a binary gap of length 2. The number 529 has binary representation 1000010001 and contains two binary gaps

正の整数Nを２進数表現にし、2つの1で囲まれた連続して並んでいる0の最大長をbinary gapとする。binary gapが複数ある場合は、最大のものの値を返す関数を作成する。

例： N = 529 == 10000010001 戻り値の正解： return 5

# 解答コード

以下がスコア100%の解答になります。

### 実行環境

- Python 3.6

```python:binary_gap.py
import time

def solution(N):
    bin_str = bin(N)
    bin_main = bin_str[2:]
    counter, max_gap = 0, 0
    flag = False
    for s in bin_main[::-1]:
        if s == "1":
            if 0 < counter:
                if max_gap < counter:
                    max_gap = counter
            counter = 0
            flag = True
        else:
            if flag:
                counter += 1

    return max_gap

def main():
    print("test1")
    actual1 = solution(9)
    assert actual1 == 2, "actual: {} expected {}".format(actual1, 2)

    print("test2")
    actual2 = solution(529)
    assert actual2 == 4, "actual: {} expected {}".format(actual2, 4)

    print("test3")
    actual3 = solution(20)
    assert actual3 == 1, "actual: {} expected {}".format(actual3, 1)

    print("test4")
    actual4 = solution(15)
    assert actual4 == 0,  "actual: {} expected {}".format(actual4, 0)

    print("test5")
    actual5 = solution(32)
    assert actual5 == 0,  "actual: {} expected {}".format(actual5, 0)

    print("test6")
    actual6 = solution(1041)
    assert actual6 == 5, "actual: {} expected {}".format(actual6, 5)

    print("test7")
    start = time.time()
    actual7 = solution(2147483647)
    print("calculation time: {}".format(time.time() - start))
    assert actual7 == 0, "actual: {} expected {}".format(actual7, 0)


if __name__ == "__main__":
    main()
```

```text:Out
$ python binary_gap.py
test1
test2
test3
test4
test5
test6
test7
calculation time: 4.0531158447265625e-06
```

以下のようなスコア結果が表示されます。

<img width="1440" alt="binary_gap_test_score.png" src="https://qiita-image-store.s3.amazonaws.com/0/156927/5af51f30-4e51-7851-ccaa-20bd8602dda6.png">

> Write an efficient algorithm for the following assumptions: 
N is an integer within the range [1..2,147,483,647].

上のように効率的なアルゴリズムを書けと問題文にはあったのに、今回の問題ではperformanceは評価されないようです。

Lesson2以降もPythonで挑戦したいですね。
Amazon EBS スナップショットライフサイクルが自動化された

こんばんは。

本日はタイトル通りですが、8月16日にEBSスナップショットのライフサイクルの自動化：Amazon データライフサイクルマネージャー (DLM) がリリースされたおりましたので、試してみた所感を残してみようと思います。

# リリース記事
#### Amazon データライフサイクルマネージャーのリージョンでの拡充
##### https://aws.amazon.com/jp/about-aws/whats-new/2018/08/amazon-data-lifecycle-manager-regional-expansion/


ご覧いただければおわかりいただけますが、すでに定期バックアップと世代管理を実装していらっしゃるユーザにおいては、特筆性がなく、あまり実用性のないものとなっていますが、コーディングに戸惑うユーザ様にとってはかなりありがたいサービスとなっています。

今までは CloudWatch Events やスクリプトで実装しなければならなかった仕組みを完全に GUI のみで簡易的に実装できることとなりました。

さて、ではどのように設定するかは以下の通りです。

## 設定項目
#### Description：ライフサイクルポリシーの説明
#### Target volumes with tags：ターゲットボリュームのタグ指定
#### Schedule name：スケジュール名
#### Create snapshots every：スナップショットの取得頻度
#### Snapshot creation start time：スナップショット取得開始時刻
#### Retention rule：保管世代数
#### Tag created snapshots：スナップショットへの付与タグ
#### IAM role：実行権限をデフォルトとカスタムのどちらで実行するか選択
#### Policy status after creation：スナップショット作成後のポリシーの状態を選択

早速設定完了し、実行してみました。
この結果、確かにスナップショットが取得できました。
これはかなり便利ではないかと思います。
しかしながら、タグ付けルールは一元的にしか付けられないので、AWS の機能拡張を待つなり、自身で自動タグ付けの実装をするしかないかなと感じ、
その辺りの実装をできているお客様には現段階では移行の必要はなさそうでした。

また、同時取得スナップショット数についてもEBS側の上限に依存しそうなため、最大１時間の遅延を許容して自動取得を行えるのですが、利用台数の多いユーザは、やはりその辺りの制限には注意しながら運用していく必要がありそうです。

https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/snapshot-lifecycle.html

本日はこれくらいで。
Angular6 で Angular CLI を使ってコンポーネント、サービス、パイプを自動生成する

Angular6 において、 Angular CLI ツールのコマンドで、コンポーネント、サービス、パイプ ファイルを自動で生成するコマンドの備忘録。

## コマンド
- コンポーネント生成

```
ng generate component sample
```

実行すると、sample ディレクトリと、その配下に Component, HTML, CSS, Spec（UTソース）ファイルが出来あがる。

- サービス生成

```
ng generate service sample
```

実行すると、Service, Spec（UTソース）ファイルが出来あがる。ディレクトリはできないので、必要あれば事前に作る

- パイプ生成

```
ng generate pipe sample
```

実行すると、Pipe, Spec（UTソース）ファイルが出来あがる。ディレクトリはできないので、必要あれば事前に作る

## ちょっとした工夫
私の場合は、コンポーネントとかサービスを app.module.ts の declarations や providers とかに直接ぶら下げるやり方はせず、全て Module を用意して、Module を app.module.ts の imports にぶら下げるやり方の方が直感的に見やすいので、そのようにしてます。

コマンドで生成すると、自動的に declarations や providers に直接ぶら下げるように書き込まれてしまうため、事前にフォルダを切ってから生成し、生成後はインポートに記載をし直す事をおすすめします。
Ruby におけるヒアドキュメント（行指向文字列リテラル）の基本的な仕様

# 前提
- ヒアドキュメントという言葉すら知らないケツの青い少年です。

# 環境
- ruby 2.5.0


# TL;DR

```ruby
<<[(-|~)]["'`]識別子["'`]
   ...
識別子
```

# 詳細

ヒアドキュメントをざっくり言うと、複数行にまたがる文字列を出力したいときに使う文法です。よく見るのは、長くなりがちな生 SQL を書く時とか、マークダウンの出力結果をテストする時とかに使うって感じでしょうか。たぶんもっとたくさん使い道あると思います。

```ruby
<<FOO
  <div class="foo">
    <p>Hello World!</p>
  </div>
FOO
# => "  <div class=\"foo\">\n    <p>Hello World!</p>\n  </div>\n"

<<SQL
  select count(*) from users where created_at between '1970-01-01' and '2018-10-11'
SQL
# => "  select count(*) from users where created_at between '1970-01-01' and '2018-10-11'\n"
```


## 各パターンの特徴
TL;DR に書いたように、いくつか書き方のパターンがあるので、それぞれのパターンの特徴を列挙していきたいと思います。

### `<<` と `<<-` と `<<~`

```ruby
<<FOO
FOO
```

- 中身のコードのインデントは省略されず、そのまま出力されます。
- 終端の `FOO` にインデントは許可されていません。必ず行頭にべったりくっついてる必要があります。

---

```ruby
<<-FOO
FOO

# 例)
def foo
  var = <<-FOO
    some_variable
  FOO
  # ↑ インデントしていてもOK！
end
```

- 中身のコードのインデントは省略されず、そのまま出力されます。
- 終端の `FOO` はインデントすることができます。つまり、上記の例のように、ネストしたコードの中に書いてもOKです。

---

```ruby
<<~FOO
FOO

# 例）
foo = <<~FOO
                                    hoge
                                      hoge
                                        hoge
                                          hoge
FOO

puts foo
# ながーいインデントが省略されます。
hoge
  hoge
    hoge
      hoge
=> nil
```

- 一番インデントの短い行を基準として、全ての行のインデントが省略されます。
- 終端の `FOO` はインデントすることができます。つまり、上記の例のように、ネストしたコードの中に書いてもOKです。


---


### `<<"FOO"` と `<<'FOO'` と ``` <<`FOO` ```

```ruby
<<"FOO"
FOO

# 例）
<<"FOO"
  昨日のこの時間は、 #{1.day.ago} です。
FOO
# => "  昨日のこの時間は、 2018-10-11 00:32:59 +0900 です。\n"
```

- 識別子（FOO）で囲まれたコードは `""` で囲まれた文字列と同じ扱いになります。つまり、 `#{}` を使って式展開することができます。
- ちなみに `<<FOO` のように何も囲わなかった場合、ダブルクオートで囲まれたのと同じ扱いになります。

---

```ruby
<<'FOO'
FOO

# 例）
<<'FOO'
  hoge\n  hoge\n    hoge\n      hoge\n
FOO
=> "  hoge\\n  hoge\\n    hoge\\n      hoge\\n\n"
```

- 識別子（FOO）で囲まれたコードは `''` で囲まれた文字列と同じ扱いになります。つまり、書いた文字列がそのまま出力されます。逆にこの場合、 `#{}` による式展開は無視されます。
 
---

```ruby
<<`FOO`
FOO

# 例）
<<`FOO`
  echo #{Time.current}
FOO
# => "2018-10-12 00:08:53 +0900\n"
```

- 識別子（FOO）で囲まれたコードは ``` `` ``` で囲まれた文字列と同じ扱いになります。つまり、中身のコードはコマンドとして実行され、結果の標準出力が文字列として返されます。なお、コマンド実行の前に式展開が行われるので、 `#{}` を使うことができます。


## 引数としてのヒアドキュメント

メソッドの引数に開始ラベルを書くことによって、ヒアドキュメント全体を引数として代入することができます。以下の例の場合、生 SQL を第１引数として `find_by_sql` メソッドに渡しています。

```ruby
users_in_first_quarter = Users.find_by_sql([<<~SQL, { from: '2018-01-01', to: '2018-03-31' }])
  select count(*) as number_of_users from users where created_at between :from and :to
SQL

puts users_in_first_quarter.number_of_users
```

## 複数のヒアドキュメント
（2018/10/12追記）
以下のように、複数のヒアドキュメントを重ねて書くこともできます。仮に変数に代入した場合は、配列として保存されます。

```ruby
foo = <<~FOO, <<~BAR, <<~BAZ
  this is foo
FOO
  this is bar
BAR
  this is baz
BAZ
# => ["this is foo\n", "this is bar\n", "this is baz\n"]
```

# 参考文献
公式ドキュメント is 最高。
https://docs.ruby-lang.org/ja/latest/doc/spec=2fliteral.html
Capistrano で特定の Role の時だけタスクを実行する

複雑な環境下で Capistrano を書いていると様々なシチュエーションに遭遇することがあります。
例えば、特定の Role の時だけタスクを走らせたくて、それも Role `A` と Role `B` の場合は実行したいが、 それ以外の、例えば Role `C` の時は実行したくない！ といったなシチュエーションです。
世の中は複雑ですから、こうした問題に直面することもままあります。

普段我々が書いている cap タスクはこんな感じです。

```lib/capistrano/tasks/test.cap
namespace 'test' do
  desc 'this is test'
  task :foo do
    on roles :A do
      puts 'hello!'
    end
  end
end
```

素直に `roles` に `:A` を渡していますね。
この場合は Role が `A` の場合のみブロック内のタスクを実行してくれます。

ふと素朴な疑問が浮かびます、複数の Role を指定して、それに該当する場合のみタスクを実行することは可能なのでしょうか？

そこでこのような感じで行けるかなーと思いつつ、Role `A` と `B` で実行できそうな cap タスクを、雰囲気で用意しました。

```lib/capistrano/tasks/test.cap
namespace 'test' do
  desc 'this is test'
  task :foo do
    on roles [:A, :B] do
      puts 'hello!'
    end
  end
end
```

`config/deploy.rb` は素朴にやります。

```config/deploy.rb
lock "~> 3.11.0"
```

stage はこんな感じでローカルで完結させつつ、Role は `A` を指定します。

```config/deploy/local.rb
set :deploy_to, '/mypath/sandbox'
set :sshkit_backend, SSHKit::Backend::Local
server(
  'localhost',
  roles: [:A]
)
```

`test:foo` タスクを実行してみましょう。

```shell-session
$ bundle exec cap local test:foo
hello!
```

いいですね！ Role `A` でタスクは想定どおりに処理されているようです。

Role `B` も行きましょう。

```config/deploy/local.rb
set :deploy_to, '/mypath/sandbox'
set :sshkit_backend, SSHKit::Backend::Local
server(
  'localhost',
  roles: [:B]
)
```

```shell-session
$ bundle exec cap local test:foo
hello!
```

何もかもが想定どおりです！

当然、 Role `A` `B` を指定しても実行されます。

```config/deploy/local.rb
set :deploy_to, '/mypath/sandbox'
set :sshkit_backend, SSHKit::Backend::Local
server(
  'localhost',
  roles: [:A, :B]
)
```

```shell-session
$ bundle exec cap local test:foo
hello!
```

そう、これこそが私の求めていたものです！

これで Role `C` で実行されなければすべてが完璧に動いていると言えるでしょう。

```config/deploy/local.rb
set :deploy_to,　'/mypath/sandbox'
set :sshkit_backend, SSHKit::Backend::Local
server(
  'localhost',
  roles: [:C]
)
```

```
$ bundle exec cap local test:foo

$
```

ああ！ 何もかもが完璧です！

どうやら `on roles` にシンボルの配列を渡しても良い感じに解釈してくれるようです！