OmniAICreator/Qiita-1.07M huggingface dataset:
Siv3D のコードを短くする

Siv3D でコードを短く読みやすくするために知っておきたい Tips を紹介します。動作バージョンは OpenSiv3D v0.6.3 です。

# 1. RGB の省略
### グレー

```before.cpp
rect.draw(Color{ 127, 127, 127 });
```

```after.cpp
rect.draw(Color{ 127 });
// または
rect.draw(ColorF{ 0.5 });
```

### 半透明

```before.cpp
texture.draw(Color{ 255, 255, 255, 127 });
```

```after.cpp
texture.draw(Alpha(127));
// または
texture.draw(AlphaF(0.5));
```

# 2. シーンと同じ大きさの Rect

```before.cpp
const Rect rect{ 0, 0, Scene::Width(), Scene::Height() };
```

```after.cpp
const Rect rect = Scene::Rect();
```

# 3. 正方形

```before.cpp
const Rect rect{ 200, 300, 80, 80 };

const Rect rect2{ 0, 0, 80, 80 };
```

```after.cpp
const Rect rect{ 200, 300, 80 };

const Rect rect2{ 80 };
```

# 4. 一回り大きい / 小さい Rect

```before.cpp
const Rect rect2{ (rect.x - 10), (rect.y - 5), (rect.w + 20), (rect.h + 10) };
```

```after.cpp
const Rect rect2 = rect.stretched(10, 5);
```

# 5. 指定した条件を満たす要素の削除

```before.cpp
Array<Vec2> v;

for (auto it = v.begin(); it != v.end();)
{
	if (it->y < 0)
	{
		it = v.erase(it);
	}
	else
	{
		++it;
	}
}
```

```after.cpp
Array<Vec2> v;
v.remove_if([](const Vec2& p) { return (p.y < 0); });
```

# 6. たくさんの数値の文字列化

```before.cpp
font(U"ステージ ", stage, U" 得点: ", score, U" タイム: ", time, U" 評価: ", result).draw(); 
```

```after.cpp
font(U"ステージ {} 得点: {} タイム: {} 評価: {}"_fmt(stage, score, time, result)).draw(); 
```

# 7. ストップウォッチを即座にスタート

```before.cpp
Stopwatch stopwatch;

stopwatch.start();
```

```after.cpp
Stopwatch stopwatch{ StartImmediately::Yes };
```

# 8. emplace_back()

```before.cpp
Array<Vec3> v;
v.push_back(Vec3{ 0.1, 0.2, 0.3 });
```

```after.cpp
Array<Vec3> v;
v.emplace_back(0.1, 0.2, 0.3);
```

# 9. 画像の全ピクセルへのアクセス

```before.cpp
for (int32 y = 0; y < image.height(); ++y)
{
	for (int32 x = 0; x < image.width(); ++x)
	{
		image[y][x].r = 0;
	}
}
```

```after.cpp
for (auto& pixel : image)
{
	pixel.r = 0;
}
```

# 10. 時刻や日付の文字列化

```before.cpp
const Date today = Date::Today();

font(U"{}月{}日"_fmt(today.month, today.day)).draw();
```

```after.cpp
const Date today = Date::Today();

font(today.format(U"M月d日")).draw();
```

# 11. 確率

```before.cpp
if (Random(1.0) < 0.33)
{

}
```

```after.cpp
if (RandomBool(0.33))
{

}
```

# 12. draw の戻り値
```before.cpp
const Rect rect{ 200, 200, 300, 100 };

rect.draw(Palette::Orange);

rect.drawFrame(2, 0, Palette::White);
```

```after.cpp
const Rect rect{ 200, 200, 300, 100 };

rect.draw(Palette::Orange).drawFrame(2, 0, Palette::White);
```

Siv3D でこのコードをもっと短く書きたい！というリクエストは、[OpenSiv3D の GitHub issue](https://github.com/Siv3D/OpenSiv3D/issues) や Siv3D Slack で受け付けています。
ラズパイでタイムラプス撮影


家で放置されてるラズパイ3を使って何か作ろうと思い、外を撮影したタイムラプス動画の作成に挑戦してみました。
※タイムラプスとは、一定時間毎に撮影した写真をつなぎ合わせてパラパラ漫画のような動画にしたものです。

# 説明しないもの
- ラズパイの初期設定
- Macからラズパイへのssh接続方法


# 環境
- ラズパイ3
- USBカメラ
  - http://amzn.asia/8Lw5gxL
- Mac


# 前提
- ラズパイにUSBカメラを接続して認識済み
- PCからラズパイに-Xでssh接続済み

今回はラズパイ3を使用していますが、ラズパイzeroやzerowでも可能です。


# 実装
## 準備
ラズパイにssh接続した状態で以下のパッケージをインストールします。

```
sudo apt-get install fswebcam feh libav-tools -y
```

- fswebcam : USBカメラ撮影
- feh : 画像確認
- libav-tools : タイムラプス動画への変換

## 撮影スクリプト
今回はシェルスクリプトで実装します。
（といっても1行の簡単なコードですが）

ssh接続したラズパイにcamera.shファイルを作成し、以下のコードを実装します。

```camera.sh
fswebcam -r 1920x1080 --no-banner -D 2 Pictures/`date +%Y%m%d%H%M%S`.jpg

```

ファイル名はyyyyMMddhhmmss.jpgの形式になります。

あと、実行可能ファイルにするのをお忘れなく

```
chmod +x camera.sh
```

### オプション説明
- -r : 撮影解像度サイズを指定
- --no-banner : 撮影情報テキストの表示無効
- -D : ディレイ値、2秒後に撮影

外を撮影する場合、重要なのは`-D 2`オプションの遅延です。
この遅延なしで撮影すると、真っ白な画像になります。
どうやらUSBカメラが起動直後にカメラのピントやホワイトバランス？の自動調整が数秒行われるようで、調整完了を待ってから撮影する必要があります。
今回は2秒の遅延中にカメラの自動調整を待ち、撮影するといい感じの画像になりました。
（遅延値はUSBカメラにより違うと思います）

camera.shを実行すると無事に撮影できました。

![camera_image.jpg](https://qiita-image-store.s3.amazonaws.com/0/52227/13419304-e8a7-693e-5dbf-a691e2e77434.jpeg "camera_image.jpg")

### 撮影画像の確認

以下のコマンドで画像表示できます。

```
feh 画像ファイル名
```

# 連続撮影
## 準備
あとは撮影スクリプトを定期的に実行するだけです。
今回はcronで1分おきにcamera.shを実行して撮影します。

```
crontab -e

```

crontabに以下を追加しました。

```
*/1 * * * * /home/pi/camera.sh
```

撮影されているか確認すると、無事1分間隔で撮影されてました。

```
20171204231001.jpg
20171204231101.jpg
20171204231201.jpg
20171204231301.jpg
20171204231401.jpg
20171204231501.jpg
20171204231601.jpg
20171204231701.jpg
20171204231802.jpg
20171204231901.jpg
20171204232001.jpg
20171204232101.jpg
20171204232201.jpg
```

## 撮影開始
USBカメラとラズパイを外に向けて放置するだけです。
今回は家のベランダからコンセントに接続して撮影しました。

# 動画変換
放置して写真が撮り溜まったところで、タイムラプス動画に変換します。

ですが、タイムラプス動画に変換するためにはファイル名が連番になっている必要があるようです。
yyyyMMddhhmmss形式から変換する方法が分からないため、ファイル名をいったん0埋め5桁の00000からはじまる連番に変更します。

```rename.sh
find . -name '*.jpg' | sort -n | awk 'BEGIN{ a=0 }{ printf "mv \"%s\" %05d.jpg\n", $0,a++}' | bash
```

これでファイル名が

```
00000.jpg
00001.jpg
00002.jpg
00003.jpg
...
```

のように連番になりました。

その後、タイムラプス動画への変換コードを実行します。

```convert.sh
ffmpeg -f image2 -r 15 -i %05d.jpg -r 15 -an -vcodec libx264 -pix_fmt yuv420p output.mp4
```
output.mp4が出力され、タイムラプス動画が作成できました。

# 完成
タイムラプス動画はscpでラズパイから取り出せます。

```
scp pi@raspberrypi.local:/home/pi/Pictures/output.mp4 .
```

動画はこんな感じになりました。

<blockquote class="twitter-video" data-lang="ja"><p lang="ja" dir="ltr">ラズパイ3とUSBカメラで空をタイムラプス撮影した <a href="https://t.co/FHTAD8kSMk">pic.twitter.com/FHTAD8kSMk</a></p>&mdash; イケムラ (@ikemura_jp) <a href="https://twitter.com/ikemura_jp/status/937956347731066880?ref_src=twsrc%5Etfw">2017年12月5日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 作り終えて

安いUSBカメラなので画質もそれなりでした。
キレイに撮影するには

- `fswebcam --list-controls`でカメラをチューニングする
- 画質の良いカメラにする
- 一眼レフを使用する
このどれかが良いと思います。
今回はチューニング無しで撮影しています。

最近はスマフォでタイムラプス撮影が手軽にできますが、
ラズパイ＋カメラ＋モバイルバッテリーなら電池持ちも抜群に長く、撮影も変換も全て自動化できそうです。

撮影後にSNSへ自動投稿してSlackに通知、なんて事もできそうです。
色々カスタマイズして楽しめますね。
ツールやライブラリなどの名前の発音について

[ゆめみ Advent Calendar 2017](https://qiita.com/advent-calendar/2017/yumemi)の9日目です。

各ツールやライブラリの名前について、「この発音間違ってるんだけどなぁ」と思うような読み方をちょこちょこ耳にしますので、ちょっとまとめてみよう！と思い立ちました。が、その前にまず同じような記事を検索したら、やっぱりすでに書かれていました。

[IT業界で横行する恥ずかしい英語発音](https://qiita.com/ryounagaoka/items/290885ee3291b393fe1f)

はい。二番煎じですが、構わず鉄の意志で書いていきます。なるべくこちらの記事内に登場しないものをまとめました。（一部重複あり）

※以下、私が間違っているものがありましたら、コメントで教えて頂けますと幸いです！

# いわゆる母音の読み間違え

|名前|正しい発音|よく聞く間違い|備考|
|:--:|:--|:--|:--|
|AVA|エイヴァ|アヴァ|公式リポジトリに記述あり|
|null|ナル|ヌル|日本人には「ヌル」で定着してしまっている|
|async|エイシンク|アシンク|元々は`asynchronous`からきている|
|radius|レイディアス|ラディアス /<br>ラディウス|「半径」の英単語の発音|
|Elasticsearch|イラスティックサーチ|エラスティックサーチ|日本では「エラスティック」で定着している印象|
|Nuxt.js|ナクスト|ヌクスト|開発者の言より（※）|
|Redux|リダックス /<br>リーダクス|リデュックス|前者が定着している印象|

※ 引用: [issues/355](https://github.com/nuxt/nuxt.js/issues/355)


# 単なる読み間違え

|名前|正しい発音|よく聞く間違い|備考|
|:--:|:--|:--|:--|
|PEAR|ペア /<br>ペアー|ピア /<br>ピアー|公式サイトに「フルーツのように発音」と記述あり|
|Angular（※1）|アンギュラー|アングラー|今までこの間違いは2名しか見たことない|
|Ionic|アイオニック|イオニック|物理の`ion（イオン）`からきている|
|Git|ギット|ジット|意外といる|
|Alt|オルト|アルト|`Alternate`からきている|
|Delphi|デルファイ|デルフィ|ギリシャの町の名前だとデルフォイらしい|
|LaTeX, TeX|ラテフ、テフ|ラテックス、テックス|スペルの大文字小文字の間違いも多い|

※ 余談ですが、`AngularJS（version 1.x）`と`Angular（version 2以降）`と明確に分けられているのでご注意ください。`Angular2（アンギュラーツー）`とか呼ばないように。


# 特殊系

|名前|正しい発音|よく聞く発音|備考|
|:--:|:--|:--|:--|
|eval|イヴァル /<br>イーヴァル|エヴァル|「イ」も伸ばすのか伸ばさないのか曖昧|
|enum（※1）|?|?|`enumerate`から来ている説、`ENUM（E.164 NUmber Mapping）`から来ている説があり、それぞれで発音が異なるため|
|Kubernetes|クーバネィティス|クベルネィティス/<br>クベルネテス|ギリシャ語で「人生の道標」を意味するが、GCPブログで『For the curious, Kubernetes (koo-ber-nay'-tace) is Greek for “helmsman” of a ship.』ともある（※2）|

※1 イーナム、エナム、イニューム…など本当に多様な読み方が存在しますので、正直わかりません。
※2 引用: [An update on container support on Google Cloud Platform](http://googlecloudplatform.blogspot.jp/2014/06/an-update-on-container-support-on-google-cloud-platform.html)


# 余談

[YOMIKATA](http://yomikata.org/index.php)というサイトの回答がかなり面白いです。試しに`php`と`lisp`で検索してみてください。

# 終わりに
正しく読むことは大事ですが、コミュニケーションを取る上で間違った読み方で意味が統一されているのであれば、そのコミュニティではそのままで良いと思っています。実際外国の方も読み方はテキトーなこともよくありますので（笑）
ReactNativeでindex.android.jsをロードできない

# Situation
`react-native run-android`でのデバッグ時に`index.android.js`ではなく、`index.js`をロードしてしまう。

# Problem
```js:android/app/src/main/java/com/projectname/MainApplication.java
@Override
protected String getJSMainModuleName() {
  return "index";
}
```
上記ファイル30行目以降辺りの`getJSMainModuleName()`で`index`を返しているのが原因

# Solution
`return "index.android"`に直して解決
ヽ(･∀･)ﾉ
jQuery-eGenを使ってCSSセレクタ記法でタグ要素作成

JavaScript(Web)でよく使われる`document.querySelector()`やjQueryの`$()`は、CSSセレクタ記法（以下CSSセレクタ）を使って要素マッチングできる。CSSセレクタとは`body .content > section`のようなやつ。
しかし、要素を取ってくる場合はCSSセレクタで指定するのに、作成する場合は面倒な要素作成メソッド群か、jQueryの場合はHTMLタグで指定すると要素作成できることになっている。これでは一貫性がないだろう。
そこでCSSセレクタで要素作成でき、さらにそれなりに高速で簡単に使えるjQueryライブラリ[jQuery-eGen](https://github.com/sabamotto/jquery-egen)を作った。jQuery使っている段階で低速というツッコミは無しだ。

# 対象者
* ウェブページ or Webアプリ開発でjQueryを使っている
* 要素作成が煩わしいが、テンプレートエンジンは大げさだ
* CSSセレクタやSlimテンプレートエンジンが大好きだ
* フレームワークは使いたくない人／プロジェクト

# インストール方法
1. [eGenのReleases](https://github.com/sabamotto/jquery-egen/releases)から最新版の「jquery.egen.min.js」をダウンロードして、HTMLからアクセス可能な場所に設置する
3. jQueryの読み込み後に本ライブラリを読み込む

```html
<html>
  <head>
    <script src="http://code.jquery.com/jquery-1.11.2.min.js"></script>
    <script src="js/jquery.egen.min.js"></script>
    <title>jQuery-eGen Example</title>
  </head>
  <body> ... </body>
</html>
```

# 使い方
次のコードのようなことをしたいとする。

```js:before.js
$('body .content')
  .append( $('<div class="block">新しい要素</div>') )
  .append( $('<strong><a class="link" href="page.html">ハイパーリンク</a></strong>') );
```

jQuery-eGenを使うことで次のようにできる。

```js:after.js
$('body .content')
  .egen('.block', null, '新しい要素')
  .egen('strong a.link', {href: "page.html"}, 'ハイパーリンク');
```

第3引数に文字列を指定すると、CSSセレクタで指定した最後のタグ要素にテキストを埋め込められる。このテキストは`document.createTextNode`を使って生成されるため、XSS対策を考える必要がない。
そんなわけで使ってみてください。

# 最後に
この記事はQiita初投稿なので、何か変な部分とかあったら教えて欲しいです。
C#でEnumの拡張メソッド

Enumを用いてただ定数を得るためだけに色んな場所で同じような条件分岐処理をしている場合に便利な使い方。

#例
以下のようにEnumExtendクラスを作成します。

```csharp
public enum AnimalType {
        Dog,
        Cat,
}

public static partial class EnumExtend {
        public static string GetTypeName(this AnimalType param) {
                string ret = "";
                switch (param) {
                case AnimalType.Dog:
                        ret = "イヌ";
                        break;
                case AnimalType.Cat:
                        ret = "ネコ";
                        break;
                }
                return ret;
        }
}
```

すると

```csharp
AnimalType animalType = AnimalType.Dog;
string animalName = animalType.GetTypeName(); // イヌ
```
というふうに呼び出す事ができるようになります。

上記の例のように日本語化した場合の名称や、Enumを使って画像などのリソースをロードする際のパスを返すメソッドを作成すると便利に使うことができました。記述の分散を防ぐこともできるのでメンテもしやすくなりますね！
Redshift copyの圧縮オプション比較

Redshiftのcopyコマンドは、[データファイルを圧縮します。](http://docs.aws.amazon.com/ja_jp/redshift/latest/dg/c_best-practices-compress-data-files.html) にあるように、3種類の圧縮形式をサポートしています
どれぐらい性能差があるのか検証してみました

|#|lzop|gzip|bzip2|
|:----:|:---:|:---:|:---:|
|1|26.85|26.71|27.76|
|2|25.82|28.14|27.7|
|3|26.32|25.8|27.42|
|4|26.88|26.89|27.59|
|5|27.55|26.59|27.47|
|av|26.68|26.82|27.59|

9000行ぐらいのcsvをそれぞれの圧縮形式で圧縮してcopyにかかった秒数を比較しています

---
lzopとgzipがほぼ同じ、bzip2が1秒ほど遅い結果になっています
bzip2は若干遅くはありますが、すごく安定しています
lzopは、**高速な圧縮・展開動作を主目的に開発されており** となっていたため、1番速い結果を期待していたのですが、思惑とは外れた結果になっています
[lzop](https://ja.wikipedia.org/wiki/Lzop)

圧縮前後のファイル容量は、

|方式|容量|
|:-:|:-:|
|圧縮前|41M|
|lzop|12M|
|gzip|5.7M|
|bzip2|3.8M|

となっていて、bzip2の圧縮率の高さが光っています

---

lzopはそんなに知名度はない認識です
そこそこ早く誰もが知っているgzipか、圧縮率の高さと安定したcopy時間のbzip2かを選ぶ事になりそうです
Windows 10 LTSB 2016でインターネットショートカットを実行しても予期したページでなく空白ページが表示される件の対策

#現象
　Windows10 LTSB 2016でインターネットショートカットを開くと、空白ページが表示されてしまう不具合があるようです。
　Windows10 LTSB 固有というよりは、LTSB 2016のベースになっているWindows 10 Version 1607由来のもので、その後アップデート実施した本家Windows10では解消している模様。
　そして当該不具合がLTSBだけにそのまま残った、という感じのようです。LTSBには不具合のアップデートも実施されないのか、2017/12/05時点でそのままのようです。

##１．原因
　「インターネットショートカット（拡張子.url）」ファイルが関連付けされた「インターネット ブラウザ（ieframe.dll）」でエラーが発生している。正常な動作ではその後既定のブラウザ（Internet Explorer等）で指定されたURLが開くはずだが、空白のページだけが開いている。

##２．対策
　インターネットショートカットファイル（.url）の既定のプログラムをInternet Explorer等に変更し、ブラウザで直接インターネットショートカットを開く。

##３．設定手順
　1.「コントロールパネル」→「既定のプログラム」を開く

　2.「ファイルの種類またはプロトコルのプログラムへの関連付け」を選択

　3.「ファイルの種類またはプロトコルを特定のプログラムに関連付けます」が表示されるので、一覧から「.url」を探す。

　4.「.url」を選択。当該項目について「既定のプログラム」が「インターネット ブラウザ」になっていたら、「プログラムの変更」を選択

　5.「今後の.urlファイルを開く方法を選んでください。」が開く。候補として「インターネット ブラウザ」「ストアでアプリを探す」が表示される。「その他のアプリ↓」を選択

　6.「その他のアプリ↓」欄が展開したら、「Internet Explorer」等、ショートカットを開きたいブラウザを選択し、[OK]を押下

　7.「.url」の既定のプログラムが「Internet Explorer」等、ショートカットを開きたいブラウザに変更されれば完了

##補足
　「ファイルの種類またはプロトコルのプログラムへの関連付け」以外にもアプリと拡張子を関連付けする方法は存在するが、上記手順を実施する理由は以下の通り

- 「設定」→「アプリ」→「既定のアプリ」から更新を試みた場合

　「.url」ファイルにに関連付けるアプリの候補に「インターネット ブラウザ」と「ストアでアプリを探す」のみが表示される。このため、IE等のブラウザを既定のアプリとして選択できない。

- 「コントロールパネル」→「既定のプログラム」→「既定のプログラムを設定」から更新を試みた場合

「すべての項目に対し、既定のプログラムとして設定する」「既定でこのプログラムを開く項目を設定する」いずれを選んだ場合も.urlのみ変更できず、「インターネット ブラウザ」が選択されてしまう

以上

参考：[Anniversary Updateしたらインターネットサイトのショートカット(.urlファイル)が開けない【Ver1607】](https://answers.microsoft.com/ja-jp/ie/forum/ie11-iewindows_10/anniversary/c2680492-92c1-4993-816d-e9de7189613f)
国土地理院GMLのposListまでのパス

Houdini Advent Calender 2017の記事を書いていたら、Payload Too Largeとやらで初投稿2MB制限に引っかかってしまったので解除用にかるーいネタを。
タイトル通り地理院GMLのposListまでのパスがややこしいのでそれのメモです。
area = "./{\*}area/{\*}Surface/{\*}patches/{\*}PolygonPatch/{\*}exterior/{\*}Ring/{\*}curveMember/{\*}Curve/{\*}segments/{\*}LineStringSegment/{\*}posList"
loc = "./{\*}loc/{\*}Curve/{\*}segments/{\*}LineStringSegment/{\*}posList"
pos = "./{\*}pos/{\*}Point/{\*}pos"
Linuxの文字化けファイルを削除する方法

# 問題
Linuxのディレクトリ名が文字化けして削除できなくなった．

例　↓

```
??????????
????c????ＥF
```

2個めのディレクトリなら

```
rm -rf *c*F
```

で削除できるけど，もしかしたら正規表現に当てはまってしまう必要なディレクトリがあるかもしれない．

# 対処
ファイル・ディレクトリごとにつけられるinode番号を使って削除する
※inode 番号・・・inodeによって割り当てられた番号

* まずはinode番号を表示

```
ls -i
```

* inode番号を指定して削除(例:inode番号が11111111)

```
find . -inum 11111111 -ok rm -rf {} ¥;
```
※ -okオプションだとユーザーに問い合わせがくるので，必要ない場合は -execとする．
※ {  } は全ファイルに対してという意味
ElixirとPerl（のuse）

Perl AdventCalendar 2017　5日目の記事です

# ElixirとPerlのrequire,useが見た目の動作がほぼ同じだなーという小ネタ



|           |  Perl |    Elixir    |
|:----------|-------:|:------------------:|
| require   | 読込+評価|  コンパイル+読込＋評価 |
| use       | `require`+`import`関数実行  |  `require`+`__using__/1`マクロ実行       |


useの使い方がすんなり頭に入ってきます。レガシー！と言われるPerlなのに新しい言語で同じような記法を見つけるとなんだか嬉しいやら感慨深いやら不思議な気持ちになりました。
話はこれだけなのですが、小ネタすぎるのでuseに絡めて、import/exportネタでも。
（以下完全にElixirネタ）


# importディレクティブ
Elixirには`import`ディレクティブというのがありまして、指定モジュールのpublic関数にアクセスできるようになります。
`import`は名前どおり、Perl定番の`Exporter`とは真逆のものです。
`Exporter`はライブラリ側が何をexportするのかを指定していましたが、`import`はライブラリを読み込む側が使うものになります。


```ex
defmodule Main do
  import MyModule

  IO.puts module_name() # 表示はMyModule。Mainではない。関数に「アクセス」できるだけ
end

defmodule MyModule do
   def moduel_name do
     __MODULE__ 
   end
end
```

# Elixirでexport
Elixirのexportは`__using__/1`マクロ内で`import`ディレクティブを呼ぶことで実現できます。

```ex

defmacro __using__(_opt) do

  import MyModule only: [...]

end
```

これで `use MyModule` とするだけでライブラリ作者側がonlyに指定した関数だけがimportされます。
ただPerlのuseのように `use MyModule （）` のように利用側でimoprtを抑制したいですし、そうなるとマクロの引数を解析する処理が必要になります。
で、これを毎回書くのが、ライブラリ作る側としてはしんどい、、
というわけで作りました。

https://github.com/tokubass/ex_exporter

Elixirのお作法的にどうなのかは不明ですが、個人的にはとても楽になりました。

# 明日は
songmuさんの「えるしっているか」です。
タイトル通り、あれの話でしょうか。
Pythonで作る簡易英単語学習プログラム

# 概略
　Pythonを使って、英語の単語学習プログラムを作成した。単語の入力は、コマンドラインで行い、答えの英単語を読み上げてもらえるようにした。
　単語の読み上げのライブラリは、[*pyttsx3 - Text-to-speech x-platform*](https://pyttsx3.readthedocs.io/en/latest/)　を用いた。
# ソースコード
```英単語.py
import random
import collections

import pyttsx3

QA = collections.namedtuple("QA", "q, a")

# 音声読み上げの初期設定
engine = pyttsx3.init() # 初期化
voices = engine.getProperty('voices')
# 用いたOSはwindows10
engine.setProperty('voice', voices[1].id) # 合成音声の選択


lis = [QA(q="An infectious disease [   ]there.", a="broke out"),
       QA(q='Box seats are really hard to [   ].', a='come by')]


def speak(word):
    engine.say(word)
    engine.runAndWait()


def main():

    random.shuffle(lis)

    for i in lis:
        print(i.q)
        ans = input()

        if ans == i.a:
            print("正解")
            print(i.a)
        else:
            print("不正解")
            print(i.a)
        speak(i.a)

    print('#########\nFinish')


if __name__ == '__main__':
    main()

```
# 改善点
　このコードだと、単語を読み上げるまで次の問題が表示されない。そのため、並列や平行処理をすると上手くいくのだろうか。
　また、問題をcsvなどで読み込み、pickle などを使ってデータを保存できるようにすると、ソースコードに直接書き込みをしなくて良くなる。

# ※追記　並列処理
```並列処理.py
import random
import collections
import multiprocessing
from multiprocessing import Queue

import pyttsx3

QA = collections.namedtuple("QA", "q, a")

engine = pyttsx3.init()
voices = engine.getProperty('voices')
engine.setProperty('voice', voices[1].id)


lis = [QA(q="An infectious disease [   ]there.", a="broke out"),
       QA(q='Box seats are really hard to [   ].', a='come by'),]


class Speak(multiprocessing.Process):
    def __init__(self, q):
        super(Speak, self).__init__()
        self.q = q

    def run(self):
        while True:
            data = self.q.get() #単語を受け取る。
            engine.say(data)
            engine.runAndWait()


def main():

    random.shuffle(lis)

    q = Queue()
    j = Speak(q)
    j.start()

    for i in lis:
        print(i.q)
        ans = input()

        if ans == i.a:
            print("正解")
        else:
            print("不正解")

        print("答え:", i.a)
        q.put(i.a) # 正解の単語を送る

    print('#########\nFinish')
    j.terminate()


if __name__ == '__main__':
    main()
```
　Queueを使えばうまくやれることが分かった。

# 参考文献
[Pythonの非同期通信（asyncioモジュール）入門を書きました](http://iuk.hateblo.jp/entry/2017/01/27/173449)
[Python 標準ライブラリ探訪 (23) ~ multiprocessing.Pool 編 ~](http://mocobeta-backup.tumblr.com/post/87477506807/python-23-multiprocessing-pool)
[pyttsx always busy](https://github.com/RapidWareTech/pyttsx/issues/54)
[python でコマンド実行。サブプロセスの終了待ち・強制終了・親プロセスと一緒に殺す。](http://takuya-1st.hatenablog.jp/entry/2016/04/11/044313)
[multiprocessingのQueue型変数の使い方](http://www.raspberrypirulo.net/entry/2016/10/26/multiprocessingのQueue型変数の使い方)
node.jsとnpmをアップデート

node.jsとnpmをアップデートしました。
何を思ったかnpmの方からインストールしたら
？？？が多かったのでメモ。


## update前

```terminal:terminal
$npm -v
3.10.9
$node -v
v7.1.0
```



## npmをインストール

```terminal:terminal
$npm install -g npm
```

エラーが出たので、困った時のsudo

```terminal:terminal
$sudo npm install -g npm
```

```terminal:terminal
$npm -v
3.10.9
```
変わってない。

nodeからやるべきだったのかーと思って


## nodebrewでnode.jsインストール

```terminal:terminal
$nodebrew install-binary stable 
```


```terminal:terminal
$nodebrew use latest
```
その最新バージョンを使う

```terminal:terminal
$nodebrew use latest
use v9.2.0
$node -v
v9.2.0
```

node.jsは無事成功しました。


これでnpmもバージョン変わってるかな、、と

```terminal:terminal
$npm -v
5.5.1

┌──────────────────────────────────────────────────────────────────┐
│                     npm update check failed                      │
│               Try running with sudo or get access                │
│               to the local update config store via               │
│ sudo chown -R $USER:$(id -gn $USER) /Users/mymac/.config │
└──────────────────────────────────────────────────────────────────┘
```

バージョンは5.5.1に上がってる！
けどアップデート失敗のお知らせ。

指示通りに


```terminal:terminal
$sudo chown -R mymac /Users/mymac/.config
```

これで無事

```terminal:terminal
$npm -v
5.5.1
```

解決！

先にnpmからやったのが悪かったんでしょうか？
Rails sのプロセスが切れない時

サーバー起動すると以下が出た時の対処を定石どおりにやった。

```console

$ rails s
=> Booting Puma
=> Rails 5.0.4 application starting in development on http://localhost:3000
=> Run `rails server -h` for more startup options
A server is already running. Check プロジェクト名/tmp/pids/server.pid.
Exiting

$ ps ax | grep rails
37580 s001  S+     0:00.01 grep rails

$ kill -9 37580
-bash: kill: (37580) - No such process
```
**No such process**と怒られる。なんでやねん。

### 追記(2019/8/7)

プロセスのgrep時のやり方を変えればプロセスが無いことがわかりますね。

普通にgrepすると検索したプロセスまで表示されちまいます。

```console
$ ps ax | grep [r]ails
```

こうするとプロセスが出てこないのがわかるはず。

## 面倒臭いので `/tmp/pids/server.pid.`を削除してみた

```console

$ rm /tmp/pids/server.pid

$ rails s
=> Booting Puma
=> Rails 5.0.4 application starting in development on http://localhost:3000
=> Run `rails server -h` for more startup options
Puma starting in single mode...
* Version 3.9.1 (ruby 2.3.1-p112), codename: Private Caller
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://0.0.0.0:3000
Exiting
/Users/user/your_project/vendor/bundle/ruby/2.3.0/gems/puma-3.9.1/lib/puma/binder.rb:269:in `initialize': Address already in use - bind(2) for "0.0.0.0" port 3000 (Errno::EADDRINUSE)

以下エラーメッセージ
```
なんでやねん！！！！！！！！


## 追記 (2019/8/7)

プロセスのgrep時に `puma` を指定して出てきたプロセスを切ってしまえば、もしかしたら下で記述している `lsof` コマンドを使わなくてもいけるかもしれません。

```console

$ ps aux | grep [p]uma

$ kill -9 <出てきたプロセス番号>
```

一度お試しくださいー。

## これで解決

```console

$ lsof -wni tcp:3000
COMMAND    PID   USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
Google     409 fndm40  156u  IPv4 0xf4f2b081d54b7cbf      0t0  TCP 127.0.0.1:61388->127.0.0.1:hbci (ESTABLISHED)
ruby      1091 fndm40   20u  IPv4 0xf4f2b081c673bcbf      0t0  TCP *:hbci (LISTEN)
ruby      1091 fndm40   26u  IPv4 0xf4f2b081d574ceaf      0t0  TCP 127.0.0.1:hbci->127.0.0.1:60305 (CLOSE_WAIT)
ruby      1091 fndm40   28u  IPv4 0xf4f2b081d48de3c7      0t0  TCP 127.0.0.1:hbci->127.0.0.1:61388 (ESTABLISHED)

$ kill -9 1091

$ rails s

"_人人人人人人人人人人人_"
"＞     無事起動！     ＜"
"￣Y^Y^Y^Y^Y^Y^Y^Y^Y^Y￣"

```

## 終わりに
Railsのサーバーはよくバグる

（2019/05/17現在： みんなどんだけプロセス切れないんだ。。。）
Wio LTEで質問されたこと（＆開発プラットフォーム）

Seeedで開発を担当している@matsujirushiです。
文章書く機会が増えていて、辛い日々が続いておりますw 最近は.mdのmarkdownが多くて、時々はてなブログ。あとMS-Wordですね(!)。Qiitaは半年ぶり。

10/25に単品、12/1にスターターキットが販売開始されたWio LTEの、初のユーザーイベントが12/5に開催されるいうことで、この場で質問された内容を情報共有しよう！と、[SORACOM Advent Calendar 2017](https://qiita.com/advent-calendar/2017/soracom)にエントリーしました。

> [Wio LTEユーザーイベント](https://soracom.connpass.com/event/68427/)
主催：Seeed株式会社、株式会社ソラコム
会場協賛：株式会社ウフル

# Wio LTEユーザーイベントで質問されたこと

![image.png](https://qiita-image-store.s3.amazonaws.com/0/109634/a9acf751-a9eb-d5ed-52ef-b31c26bbfc0c.png)

---
**Q1. Wio LTEのLTEアンテナって、どれくらい脱着OKですか？**
U.FLコネクターなので、一般的に数十回です。
結構少ないので要注意ですね。

---
**Q2. Microsoft Azureに接続できるサンプルスケッチ（サンプルコード）はありませんか？**
現時点は無いです。
ですが！
現在、[IoT Kitハンズオントレーニング](https://github.com/ms-iotkithol-jp/IoTKitHoLV4)にWio LTEデバイスの追加を進めています。~~来年春までには完成させたい~~

---
**Q3. Groveコネクターの信号に種類（I2Cとか）がありますが、どれだけの種類がありますか？**

Groveコネクターの信号の種類は、下記4つあります。
Wio LTEは4つ全て実装していますので、すべてをお試しいただけます。

* デジタル入出力（Dxx）
* アナログ入力（Axx）
* シリアル通信（UART）
* I2C通信（I2C）

（※ カッコ内は、基板に書かれているコネクタ名称です。）

ただし、Wio LTEのGroveコネクターは3.3Vなので、5V専用のGroveモジュールは接続できません。購入するときに気をつけましょう。

---
**Q4. Groveジャンパーケーブルを購入したいが、どこで売っていますか？**
把握していないです（汗
通販サイトで調べたところ、Grove-オスピンはマルツ、Grove-メスピンはスイッチサイエンス、千石電商、マルツで取り扱っているようです。

---
**Q5. （サンタが配っていた）Grove-ジェスチャセンサーってどういう製品ですか？**
センサーの上で、手や指の動きを検知できるセンサーです。
[こちらの動画](https://youtu.be/e3nf-b4W6TY)が分かりやすいかと思います。

---

見ていただいくと分かりますが、**ほとんど質問されません**でした。（お、おぅ、、、）
まだ単体が発売されて僅か1か月。キットは発売されてから数日。手に取ったばかりで質問ってのも、そりゃ無くて当たり前。完全に企画ミスった...


# Wio LTE開発プラットフォーム

これだけだとちょっと寂しいので、Wio LTEの開発プラットフォームについて考えを書いておきます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/109634/df8c5ada-55c5-bf6c-6f2c-bd257b9980f8.png)

Wio LTEは、Arduino IDE（C言語）とEspruino（JavaScript言語）の2種類のプラットフォームで開発可能です。どっちが優れてるとか便利とかは宗教論争になるので触れませんが、2種類のプラットフォームがあることで、より多くの方々が**気軽にWio LTEを試す**ことができてハッピーと思っています。誰もが、自分が得意とする言語を使いたいですよねっ。
そこで、さらにプラットフォームを2種類追加しようとしています。

1つは、Mbed(C++言語)による開発です。Arduino IDEやEspruinoはエントリー向けに使いやすいライブラリにしているので、本格的なデバイスを作ろうといったときには若干物足りないものになってしまっています。Mbedでは、より本格的な（でもちょっと難しい？）ものを提供しようと考えています。

もう1つは、Visual Studio（C#言語）による開発です。GHI Electronicsが.NET Micro FrameworkをリニューアルしたTiny CLRをWio LTE開発に使えるように進めています。これは完全にわたし個人の趣味でww

|対象者|開発プラットフォーム|言語|リリース|担当|リポジトリ|
|:--|:--|:--|:--|:--|:--|
|初心者|Arduino IDE|C(C++)|済|Seeed日本|[WioLTEforArduino](https://github.com/SeeedJP/WioLTEforArduino)|
|初心者|Espruino|JavaScript|済|Seeed深セン|[Wio LTE Cat.1](http://wiki.seeed.cc/Wio_LTE_Cat.1/)|
|初心者|Visual Studio|C#|まだ|個人（@matsujirushi）|[TinyCLR-WioLTE](https://github.com/matsujirushi/TinyCLR-WioLTE)|
|上級者|Mbed|C++(C)|来年早々|~~Seeed日本~~ 未定|[WioLTEforMbed](https://github.com/SeeedJP/WioLTEforMbed)|

# 最後に

引き続き、ちょいちょいユーザーイベントやれたらと思います。
みなさん、お気軽に質問くださいね。感想とか改善要望とか。
このQiitaコメントとか、twitterの#wiolteでもOKです。あ、[SeeedJP User Group](https://www.facebook.com/groups/SeeedJPUG)でもどうぞ。

Seeedはメイカーを支援する会社です。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/109634/9f66b90a-05ae-23bd-12dc-93f975b10673.png)
standalone jarを実行可能ファイルにするツール

JVM言語は数多く存在しており、それぞれのビルドツールでスタンドアローンのjarにまとめることが可能です。しかし、毎回`java -jar ~.jar`と書いたりシェルスクリプトを作成するのがめんどくさいです。そこで、コマンド一発でjarを実行可能ファイルにするツールを作りました。この記事は[VASILY Advent Calendar 2017](https://qiita.com/advent-calendar/2017/vasily) 6日目の記事です。

# ツールの紹介
## jarexe
jarファイルから実行可能ファイルを生成するツールです。Goで実装しています。

https://github.com/katsuyan/jarexe

# インストール
```shell-session
go get github.com/katsuyan/jarexe
```

をするか、gitcloneをして`go build`をおこなってください。

# 使い方
```shell-session
jarexe ~.jar
```

上記を実行すると、jarファイルの`.jar`を取り除いた名前の実行可能ファイルが生成されます。

## オプション
それぞれのオプションは以下のコマンドで確認することができます。

```shell-session
jarexe -h
```

### 名前の変更
```shell-session
jarexe ~.jar --name ...
```

`name`オプションを付けることで生成する実行可能ファイルの名前を変えることが可能です。

### javaオプションの追加
```shell-session
jarexe ~.jar --jop "-Xmn120m -Xmx480m -Xms480m"
```

上の例の用にjavaのオプションを追加することが可能です。

# 何を行っているか
行っていることは自分自身のファイルを`java -jar`で呼び出すコードとjarファイルの中身を合体させただけです。

↓イメージ

<img width="221" alt="スクリーンショット 2017-12-05 21.21.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/74514/f08868a8-3a77-3dd8-db12-39e0388f965b.png">



# 参考
https://coderwall.com/p/ssuaxa/how-to-make-a-jar-file-linux-executable
Ubuntu16.4でサクッとETHを掘ってみた(秒でできるお)

# GPUサーバーがあったら掘ってみたい
機械学習に使うGPUサーバー。アイドリングしている時には、流行りの暗号通貨マイニングに使えるのでは？ということで、Ubuntu16.4インストールのサーバーでサクッとマイニングして流行りの暗号通貨マイナーになる方法です。
秒速でできます。

## Nvidia Driverのインストール（ドライバセットアップしてない場合）
[Nvidiaのダウンロードサイト](https://www.geforce.com/drivers)から自分のGPUに合ったドライバーをダウンロードします。

何が刺さってたっけ？となる場合はこちらでわかります。

```
lspci -nn | grep '\[03'
```

ダウンロードしたものを走らせます。（バージョン等変わるので注意）

```
chmod +x NVIDIA-Linux-x86_64-384.98.run
sudo ./NVIDIA-Linux-x86_64-384.98.run
```
再起動します

```
sudo reboot
```

ドライバを確認します

```
nvidia-smi
```

で特にエラーがなければ次のステップへ。
GPUの使用状況とかがわかります。

## Ethereumクライアントをダウンロード
```
sudo apt-get install software-properties-common
sudo add-apt-repository ppa:ethereum/ethereum
sudo apt-get update
```

マイニングには簡単にEthminerを使いますのでこちらもインストール

```
sudo apt-get install ethereum ethminer geth
```

ここまでで、Ethereumクライアントのgethが使えるようになっているはずです。マイニングするにはアカウント（というかアドレス）を作る必要があります。

こちらも簡単。

```
geth account new
```

パスワードを入力するわけですが、このパスワード忘れたら掘ったETHは**永遠に**失われます。気をつけましょう。

```
Address: {自分のアドレス}
```

このアドレスが自分のウォレットアドレスです。こちらもメモとって置くといいでしょう。

## マイニングプールに参加して掘る
ソロでマイニングしても、まあ掘れることはありません。
多数のコンピュータが集合しているマイニングプールに参加してマイニングすると計算量に応じてその分け前に預かれます。こちらも一行でできます



```
ethminer -F http://eth1.nanopool.org:8888/0x16ca14300510b0bade1f892e80595a5aba15c3ad/test1/yutaka.kobayashi@todai-dream-net.com -G
```

さて、それぞれの説明です
```
ethminer -F http://eth1.nanopool.org:8888/(0x+WALLET_ID)/(woker_name)/(mail_address) -G
```

- `-G` GPUを使って計算するということ。なければCPUでのマイニングになります
- `-F` Fの後に接続先URLの指定が入ります。
- 自分のwallet_id(アドレス)の先頭に0xを追加したもの
- worker_nameということで複数台マシンを使う時などの命名区別をします。ここではtest1にしました
- mail_address自分のメールアドレスですね。マイニング停止した時に通知を送ってくれます

マイニング状況は
https://eth.nanopool.org/account/0x(wallet_id)
で確認できます。
Git でコミットの歴史を改変したい

Gitの歴史改変で深んだので、歴史の改変方法をメモ。

歴史の改変をしたいリポジトリで、rebaseコマンドを使用する。

```
git rebase -i 編集したいコミットの前のコミットID
```

編集画面が表示されるので、消したいコミットのpickをdへ変更し、上書き保存。

編集前

```
pick 7539d45 toppage update               ←消したいコミット
pick cf4d0e1 ヘッダーフッター共通化しました
```

編集後

```
d 7539d45 toppage update                  ←消したいコミット
pick cf4d0e1 ヘッダーフッター共通化しました
```
gitのlogを見て、編集したコミットが削除されていることを確認し、歴史改変の編集内容を反映させる。

```
git push -f origin ブランチ名
```

###補足
上記の歴史改変作業では、コミットのほか、追加したファイルやディレクトリも削除される。
[上級者向け]Tabsで、NavPushしたPageにURLアクセスできるようにする

この記事は[Ionic Advent Calendar 2017](https://qiita.com/advent-calendar/2017/ionic)の5日目です。また、バージョンアップにより動作しない可能性があります。十分にご注意ください。

挙動確認時点のバージョンは、`ionic-angular 3.9.2`です。

---

Ionicは、PWA宣言をして積極的にURLルーティングのサポートをはじめました。しかしながら、界隈では有名なぐらいに「Tabsのルーティングには弱い」です。フレームワークとしては非サポートなので自分自身でJavaScript書いてね、ぐらいの勢い。

もちろん、Tabを選択するぐらいは容易です。URLをみて、ドキュメントにある通り`select()`でタブを指定してやればすむ話。しかしながら、

1. tabsのページを開いて
2. そこからPush遷移したページを
3. history含めてURLからアクセスする

のはなかなかに難しいです。そこで、その実装について解説します。なお、本ソースコードは

https://github.com/rdlabo/ionic-tabs-route

に上げておりますので、ご参考ください。

## Lazy Loadng

まず、IonicPageを導入してLazy Loadngを実装します。

1. それぞれのファイル名に対応したmoduleファイルを設置（例：home.tsなら、home.module.ts）
2. `@Component`の前に、`@IonicPage()`を追加
3. 別Component呼び出しの時は、文字列で呼び出す

の手順を行ってください。具体的な手順は以下のコミットになります。

https://github.com/rdlabo/ionic-tabs-route/commit/b8f505bbc1714a9192bc341f8aa9026a7f14f70b

Lazy Loadingの副次効果として、それぞれに自動的にURLが振り分けられるようになりました。

## 下層ページとPushボタンを追加
追加します。Ionic CLIをつかって生成すると早いです。今回は`detail`というページ名にしました。

https://github.com/rdlabo/ionic-tabs-route/commit/404f57ec6eeaa442719fb10ddfc1311d82e6210a

## ルーティング
そして、ルーティングの実装をします。IonicのTabsは、何も設定しない状況ではPush遷移によって

http://localhost:8100/#/tabs/home/detail

とURLバーに表示されても、リロードすると自動的にTabsの先頭に戻ってくる仕様となっております。しかし、

1. Tabsのsegmentが別名となっており（https://github.com/rdlabo/ionic-tabs-route/commit/a264f98bdaadd9ff8aefd65921561ec9017b789e#diff-df85d0ee0c185daf453f19cd506b6735L4）
2. Tabの`tabUrlPath`も別名となっている場合（https://github.com/rdlabo/ionic-tabs-route/commit/a264f98bdaadd9ff8aefd65921561ec9017b789e#diff-71b48e585d5efe186d0f1b663dbb3eecL2）

に限っては、リロードすると下層ページにそのままアクセスすることができます。しかしながら、Historyはすべて消えてしまうようで、`navCtrl.pop()`はできません。

そこで、更に、Historyを手動で追加します。

```

    ngOnInit(){
        if(this.navCtrl.getViews().length == 1){
            this.navCtrl.insert(0, 'HomePage', null,{ animate:false }).then(
                ()=>this.navCtrl.push('DetailPage',null, { animate:false }).then(
                    ()=>{
                        this.navCtrl.remove(1)
                    }
                )
            );
        }
    }

```

本来、このページにPush遷移でアクセスしようと思うと、Historyに親ページがあるので、`getViews().length`は2となるはずです。それが1となっている場合、直接アクセスしている状態です。
その場合、まずHistoryに親ページとなる`HomePage`を追加して、そのあと`navCtrl.push`で`DetailPage`へと遷移します。これらは裏側で行うためにアニメーションは表示しません。
そして、最初に表示したHistoryを`remove()`します。

これで、Tabsで、NavPushしたPageにURLアクセスできるようになりました！そして、`navCtrl.pop`で戻ることもできます！

ちなみに、Tabsを使っていなかったら、`@IonicPage`の`defaultHistory`が正常に動くので、こういうことしなくても親子関係を指定したらしっかり動作します。

それではまた。
Project Euler Q35 【巡回素数】

Project Eulerをワンライナーで解いてみる。
間違っていたらコメントください。


## 問題
$197$は巡回素数と呼ばれる. 桁を回転させたときに得られる数 $197$, $971$, $719$ が全て素数だからである.

$100$未満には巡回素数が$13$個ある: $2, 3, 5, 7, 11, 13, 17, 31, 37, 71, 73, 79,$ および$97$である.

$100$万未満の巡回素数はいくつあるか?

## 解答

```bash
seq 2 1000000 |
factor |
awk 'NF==2{print $2}' |
grep -v "[0|4|6|8]" |
grep -v "[2|5]." |
awk '{for(i=1;i<=length;i++){printf substr($1$1,i,length)" "};print ""}' |
while read line;do factor $line;echo "@";done |
tr '\n' ' ' |
tr '@' '\n' |
awk 'NF==(length($1)-1)*2' |
wc -l
55
```

偶数を$1$つでも含めば巡回素数ではないので偶数を除外した。
するとみるみるうちに対象が少なくなっていったので処理時間をグッと短くなった！

## 答え合わせ
こちらのサイト様と一致していればOKとした。
[Project Euler 35  Circular primes below one million in C#](http://www.mathblog.dk/project-euler-35-circular-primes/)
dangerouslySetInnerHTMLの利用に際して

とても悩んだため、備忘録がてらに記述します。

React.jsで親子関係を持つAとB（A<-B)のコンポーネントを作成した。
親(A)のstateを変更することで子(B)のコンポーネントの内容が自動に変更されるようにコーディングを行った。
出力したい内容物がHTMLだったため、dangerouslySetInnerHTMLプロパティを使用した。

```react.js
var QuestionSentence = React.createClass({
　createMarkup :function(){
    return{__html: this.props.sentence}
  },
  render : function(){
    return (
        <p className="exam-panel-text" dangerouslySetInnerHTML={this.createMarkup()}></p>
    )
  }
});
```

上記のコードだと前に出力された内容物が画面上に残ったまま次の内容物が出力されることになった。

```react.js
var QuestionSentence = React.createClass({
　createMarkup :function(){
    return{__html: this.props.sentence}
  },  
　render : function(){
    return (
        <div className="exam-panel-text" dangerouslySetInnerHTML={this.createMarkup()}></div>
    )
  }
});
```

pタグではなく、divタグで使用することで仕様通りの動きになった。
共有ブランチで作業する時に打つ魔法のコマンド

```
git reset --hard HEAD && git clean -fd && git pull
```

チェックアウトしているブランチの状態が、originと同じになる

```
git reset --hard origin/<ブランチ名>
```

上記も最終的な結果は同じだが、ブランチ名でコマンドが変わるので
プログラマー以外に説明するときは、こっちは教えないほうがいいのかも？
(@_@)
postfixadminで特定ドメインだけを移設する

postfixadminを使っているサーバ間で特定ドメインだけを移設したい場合のデータベースのバックアップ/リストア方法。

#移設元
```
mysqldump -p --where 'domain like "example.com"' -t postfix alias mailbox domain > postfixadmin_example.com.sql
```

#移設先
```
mysql -p postfix < postfixadmin_example.com.sql
```
Python2.7+PyQt4でUnicodeEncodeErrorが出た時用の メモ

#コード

```python
    print (self.dia.lineEdit.displayText())
```
#エラーメッセージ

```
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-4: ordinal not in range(128)
```

#対処策

```python
    print (unicode(self.dia.lineEdit.displayText()))
```
インクルーシブなコーディングについて考えてみた

この記事は [株式会社Y's アドベントカレンダー](https://qiita.com/advent-calendar/2017/ysinc) ６日目の記事です。

# はじめに
11月に行われた[『html5j Webプラットフォーム部 第18回勉強会』](https://html5j-webplat.connpass.com/event/71784/)に参加させて頂いた際に色々と、改めて考えなくてはと感じた部分が多いので共有の意味も込めて、この題材にさせて頂きました。
参考書籍を読み深めることがまだ出来ていないため拙い表現とはなりますがご容赦下さい。

# そもそもインクルーシブとはなにか
結構昔から何かと話題に上がっていたインクルーシブという単語。
でも、具体的にどんな意味？ 教えてgoo辞書先輩。
> インクルーシブ【inclusive】
> ［形動］包含しているさま。含んでいるさま。包括的。

つまり...?
包括とは「ひっくるめて一つにまとめること。」(Weblio辞書)

ふむふむ？
まだちょっとわかりづらいので『インクルーシブ』で検索した時に引っかかったワードを調べてみました。

・**インクルーシブ教育**...障害の有無に関わらず、全ての子ども達がその地域の学校に包み込まれ、必要な援助を提供されながら教育を受けること。
・**インクルーシブ社会**...健常者と障害者の垣根のない社会。
・**インクルーシブデザイン**...高齢者、障がい者、外国人など、従来、デザインプロセスから除外されてきた多様な人々を、デザインプロセスの上流から巻き込むデザイン手法。

つまりWebサービスにおける『インクルーシブ』には、どんな条件、状態下であっても全ての方を対象とし、同じサービスを受けてもらえることを前提に考える。と意味に捉えることもできる。

# 対象者ってどんな人？
上記のワードの説明で挙げられた
・高齢の方
・障害をお持ちの方
・こちらの文字が読めない外国の方々。
など。

グローバル化が進み、日本にもたくさんの方が海外からいらっしゃいます。
また、日本では高齢化社会の話題が絶えません。

そして、障害はなにも生まれ持った障害だけじゃありませんよね。
例えば、普段は眼鏡やコンタクトをつけたら問題なく生活できる方々。
でも眼鏡を壊してしまったら？　コンタクトが無くなってしまったら？ そんな事象が起きてしまうと普段と同じことはできません。

また、捻挫や、ちょっとした怪我をしてしまったり、当たり前が当たり前では無くなる事柄が現実にはたくさん存在します。
そういった事例も含めて『全ての方』が対象として考えられます。

# フロントエンドが意識すること
ではフロントエンドエンジニアが、インクルーシブを意識できること。
それはやっぱりコーディング部分ですよね。

## インクルーシブではない実装とは
まずはどういったコンテンツがインクルーシブではないのか。
反対から考えてみましょう。

・目の見えない方が入力できないフォームや読めないコンテンツ
・マウス操作を前提としたコンテンツ
・画像が読み込めていないと意味が伝わらなコンテンツ
・一見で操作方法が伝わないUI
などなど。

## どう実装すればいいのか
上記の内容をピックアップし、一例を挙げたいと思います。
正解はなく、あくまでも一つの考え方、参考例となります。

**目の見えない方が入力できないフォームや読めないコンテンツ**
アクセシビリティの観点からみて外せないのが『WAI-ARIA』という仕様です。
HTML要素の属性として情報を付加し、ブラウザがそのコンテンツの内容を正確に認識してくれるもので、スクリーンリーダー利用者に対してもわかりやすく情報を提供することが出来ます。
※スクリーンリーダーとはパソコンやスマートフォン上に表示されている情報を音声で読み上げてくれるソフトです。

来週記述予定の記事でWAI-ARIAについてお話しようと思っているので、詳細はそちらで記述したいと思っております。

**マウス操作を前提としたコンテンツ**
キーボードから手を離したくないユーザーや、あまり腕を動かせないユーザーから見て、いちいちフォーカスが外れてしまうようなフォームって不便ですよね。
ノートPCであればトラックパッドがありますので、利用してくれますが、デスクトップでは全ての操作をキーボードだけで済ませたいと思うこともあるでしょう。
ビジュアル重視なサイトが多い中、せめてフォームなどのユーザーアクションの多いものにはタブ移動のしやすさを意識したものだと好ましいかと思います。

**画像が読み込めていないと意味が伝わらないコンテンツ**
画像のaltって悩みますよね？
テキスト画像だった場合、altに記述するべきはそのテキスト内容ですし、絶対必須です。

ですが、写真やイラストの場合その言葉に悩むことは多いと思います。

![c6981e22-e9f5-4d0b-bea8-e0877fb60967.png](https://qiita-image-store.s3.amazonaws.com/0/203392/ad0feb12-146d-5093-05be-7a3ce2fc26e4.png)

上記の画像に適するalt属性の内容って何でしょう？
画像を使用する場所にも限られますが、私は"株式会社Y'sの会社ロゴ"が１番適しているかと思います。
アイコンとして使用するならaltの中身は空でも問題ありませんが、それ以外ならなるべくその画像が表現しているものを具体的に記述しましょう。（かと言って、何行ものやりすぎ文になってはいけません）

**一見で操作方法が伝わないUI**
これはコーディングというよりもデザインありきのお話ですが、
どこに導線がありのか、どう操作すればいいのかわからないサイトってたまにありませんか？
hoverやpointerだけに頼らず、視感的にもわかりやすいUIを意識したいですね。
また、リンク導線を色だけで頼ってしまった場合は色彩が判断出来ない方にはどこを押下すれば遷移するのか判断がつきません。

自分がデザイン担当ではなくても、気づいた部分はデザイナーと相談してみてもいいと思います。


# 最後に
情報がまだまだ少ない中、ピンとこない言葉ではありますが、早いうちに意識をした方がいいと思ったため、共有とさせて頂きました。
私もまだまだ勉強中ですので、共に考えてくれると嬉しいです。

# 参考書籍
・[『インクルーシブ HTML + CSS & JavaScript』](https://www.amazon.co.jp/dp/4862463878)(11月４日出版)
↑　具体的なコーディング例がたくさん記載されています。
　　ソースだけでなく、なぜそのようなコードになるのか、どういった理由・根拠に基づいたものなのかという説明がしっかりと記載されています。
　　購入をお願いし、会社にも書籍がありますので興味のある方は是非とも読んで見て下さい。
　　(現在は私が借りてしまっていますが、自分用に買おうと思っているので近いうちに返却します。)


次は 7日目 @The3rd_Ysinc さんの記事です。お楽しみに！
pjaxのときのga、これでいいのか・・？

pjaxをつかって画面遷移させるときは手動でga('send', 'pageview');してあげないといけないんだけど
よくみる参考記事では
```
ga('send', 'pageview', window.location.pathname.replace(/^\/?/, '/') + window.location.search);
```
と書いてある。

これで送信している値をみてみると
dl(ドキュメントの場所の URL)には今みえてるページではなく、最初に開いたページのURLが書いてある。
そして、dp(ドキュメント パス)に今見えてるページのパスが書いてある感じ。

###例)
```
最初に開いたページ：http://aaaaa.com/xxx/
今見てるページ：http://aaaaa.com/yyy/
gaのコード：先述したやつ

↓おくってる値
dl：http://aaaaa.com/xxx/
dp:/yyy/
```

これでいいのか・・？と不安になったので調べてみた
https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters?hl=ja#dl
をみると、dlの部分の説明に

>対象コンテンツが掲載されているページの完全な URL（ドキュメントの場所）を送る際に、このパラメータを使用します。&dh パラメータと &dp パラメータを使用すると、ドキュメントの URL のホスト名とパス + クエリの部分を上書きできます。

とありました。
ということは、さっきの例でいくと、
dlの`http://aaaaa.com/xxx/`の`/xxx/`の部分をdpの`/yyy/`で上書きしている・・のかな？

だったら多分良さそうなきがする

解決したようなしてないような・・
dockerを使ってseleniumを実行

初のアドベントカレンダー投稿です。

業務ではほとんど使用していないですが、seleniumとdokcerを使ってみたくて記事にしました。

# 参考にしたサイト
[URL](https://codezine.jp/article/detail/10471)
ほとんど記事通りにやってみました

# 環境構築
## virtual boxのインストール
[URL](http://vboxmania.net/content/virtualbox%E3%82%92windows%E3%81%AB%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)

## vagrantのインストール
[URL](https://www.vagrantup.com/downloads.html)
ちなみに、dockerを自動インストールできるvagrantファイルを見つけてくると便利です。

----
もろもろ、環境構築完了したら、seleniumの起動準備
# 実行コマンド
```
docker pull selenium/hub:3.6.0-bromine
sudo docker run --rm -d -p 4444:4444 --name selenium-hub selenium/hub:3.6.0-bromine
docker run --rm -d -p 4444:4444 --name selenium-hub selenium/hub:3.6.0-bromine
----
docker pull selenium/node-chrome:3.6.0-bromine
sudo docker run --rm -d --link selenium-hub:hub selenium/node-chrome:3.6.0-bromine
```
# 起動画面
![FireShot Capture 64 - Grid Console - http___192.168.33.10_4444_grid_console#.png](https://qiita-image-store.s3.amazonaws.com/0/91958/2d8f6374-5491-35ec-5870-25f5603d895a.png)

# 結果
起動まではできましたが、webdriver等の使い方がわからず、ボロボロでした…
でも、簡単にここまでくることができたので、あとは、追加していきます。。

## 追記
stand-alone版のほうが色々やりやすいかも…
Golang で URL から charset を取得するのを書いたのですが、他にもっとよい方法があるとおもうのです...

他によい方法がある気がするのですが...わからないので、書いてみました。

URL から、その charset を取得する。


```go:main.go
package main

import (
	"fmt"
	"net/http"
	"regexp"
	"github.com/PuerkitoBio/goquery"
)


func getCharset(url string) (charset string) {
	res, err := http.Get(url)
	if err != nil {
		// handle error
	}
	defer res.Body.Close()

	doc, _ := goquery.NewDocument(url)
	doc.Find("meta").Each(func(_ int, s *goquery.Selection) {

		// <meta charset="utf-8"> の場合
		charsetAttr, _ := s.Attr("charset")
		if charsetAttr != "" {
			charset = charsetAttr
		}

		// <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> の場合
		httpEquiv, _ := s.Attr("http-equiv")
		if httpEquiv == "Content-Type" {
			content, _ := s.Attr("content")
			rep := regexp.MustCompile(`.*charset=(.+)`)
			charsetStr := rep.ReplaceAllString(content, "$1")
			if charsetStr != "" {
				charset = charsetStr
			}
		}
	})
	return charset
}

func main() {
	url := "https://qiita.com/trend"
	a := getCharset(url)
	fmt.Printf("%v", a)
}
```

```bash
$ go run main.go
UTF-8%
```
[フロントエンド css]BEMを参考にした書き方

# BEMを参考にした書き方
今回はcssでのBEMを参考にした書き方をご紹介したいと思います。

## BEMとは
- BEMとはBlock,Element,Modifierの略で、フロントエンド設計方法のひとつです。

## 何がいいのか？
###以下のことが避けられる

- タグ直指定や!important

```.css
p {
  color: #ff0000;
}
.text {
  color: #ff0000 !important;
}
```

- style属性などでの指定も。。。

```.html
<p style="color: red;">テストです</p>
```

- 深すぎる入れ子問題でcssの修正に時間がかかる

```.html
<div class="wrapper">
  <div class="box">
    <div class="text-box">
    <p class="text">テキストです</p>
    </div>
  </div>
</div>
```

```.css
.wrapper .box .text-box .text {
  color: #ff0000;
}
```

- パーツを使い回しすると思わぬ事態に。。(javascriptなど)
- 初見の人がわからないクラス名だったり、探すのが大変だったり。

### 以上のことを踏まえた上でBEMでは...
- コードを再利用できる
- わかりやすいクラス名とBEMの規則のおかげでチーム開発などに向いている。
- 修正が入った時にどこのことなのか探しやすい。

## BEMの構成と説明(独自ルールも入ってます。)
冒頭でBEMはBlock,Element,Modifierの略と言いました。
それぞれをもう少し噛み砕いていくと以下のような感じになります。(コードも合わせて説明します。)
ここでは例として一つの画像、タイトル、説明文の集まりのコンテンツで説明します。

- block...一つのパーツ。例で言うと画像、タイトル、説明文の集まりがblock。
    - webサイトはこのblockが集まり構成される。
    - blockには作成するパーツのわかりやすいクラス名をつけます。

```.html
<div class="contentBox"></div> /*　独自ルールとして単語つなぎはキャメルケースにしています。*/
```

- element...blockを構成する要素
    - elementの集まりでblockが成り立つ。
    - elementに関してはblockのあとにアンダースコア2つで繋げます。

 ```.html
<div class="contentBox"> /*ここはblock*/
  <h2 class="contentBox__title">タイトルです。</h2> /*ここがelement*/
　<p class="contentBox__text">テキストです。</p> /*ここがelement*/
</div>
```

- Modifier...状態が違うもの。
- 作成したblockやelementに似ているが微妙に見た目が違ったり、動きが違ったりする場合、これを新規で作る必要はありません。
- Modifierを使って既存のblockやelementを改造します。
- Modifierはハイフン2つでつなぎます。

 ```.html
<div class="contentBox contentBox--backRed"> /*ここはblockとModifier*/
  <h2 class="contentBox__title contentBox__title--small">タイトルです。</h2> /*ここがelementとModifier*/
　<p class="contentBox__text">テキストです。</p> /*ここがelement*/
</div>
```

- 上記のコードでは例としてcontentBoxの背景が赤色のもの、contentBox__titleのfont-sizeが既存より小さいものを用意しました。
- こうすることで似たような紛らわしいものが増えず、コードも少なく見やすくなります。

### これらをまとめると以下のようになります。

```html

<div class="block block--modifier">
  <p class="block__element">テキスト</p>
</div>
```

##最初の方にやりがちなこと
elementの中にelement。

```html
<div class="block">
  <p class="block__element">
    <span class="block__element__element">テキスト</span>
  </p>
</div>
```
- こうしてしまうとクラス名が長くなりすぎてしまい、作成するものによっては逆に混乱してしまいます。
- こうする場合はパーツパーツを細かくきり、合わせることをオススメします。

```.html
<div class="block">
  <p class="block__element">
    <span class="block2">テキスト</span>
  </p>
</div>
```

## projects
上記ではbemの書き方について説明しましたが、
これに合わせてflocssを取り入れるとより見やすいコードになります。

次の例では
・トップページ
・利用規約
・お問い合わせ
のページが存在するものとしています。

## case
同じパーツを複数箇所(複数ページ)で使う必要がある場合があります。
例えば、トップページでは背景が赤いboxコンポーネント、利用規約では　背景が青いboxコンポーネントなど
ページごとで同じコンポーネントでも、ちょっと違うデザインのコンポーネントを使いたい時があります。
そのような時は、modifierで対応するかと思いますが、
そのページでしか使われないようなデザインだった場合などは、トップレベルにそのページ専用のクラスを用意し、
その配下のコンポーネントは「これ」と設定してあげることで可読性が上がっていきます。

## トップページの場合
トップページでboxコンポーネントを使いたい場合です。

```.html
<div class="top">
  <div class="box">
    <div class="box__title">タイトル</div>
  </div>
</div>
```

```.css
.top .box {
  background: #ff0000;
}
```

## projectsまとめ
上記のような感じで作れます。
とはいえ、基本的にコンポーネントのデザインに関するものは全てmodifierで作成した方が、混乱は少なくなるかと思います。

上記のようにページ単位でstyleを調整するものは「コンポーネントの余白間」に限定したりすると
大きな混乱は生まれないので意識してみてもいいかもしれません。
ネストされたvue routerを別ファイルで管理する

Vue.jsでSPAを作っていると、ルーティングを機能単位で分けたくなります

例えば、ユーザに関する機能があったとして、ユーザの登録、更新、削除、詳細（所謂 **CRUD** ）それぞれにルーティングを設定する必要があり、それを一つの機能としてルーティングもまとめた方が将来的にも見通しがよくなります。


今回はcompanyに対するCRUDを設定していきます。
環境は以前に作成したものを使います。  
詳しくは以下の記事をご覧ください


[Cloud9でvue-cli環境を作る](http://yanagiya.hatenadiary.com/entry/2017/11/30/Cloud9%E3%81%A7vue-cli%E7%92%B0%E5%A2%83%E3%82%92%E4%BD%9C%E3%82%8B:embed:cite)



## ルーティング設定

**src/router/index.js**にComapny-routesファイルを読み込み、そのファイルで設定を書くようにします。


#### src/router/index.js

``` diff
 import Vue from 'vue'
 import Router from 'vue-router'
 import HelloWorld from '@/components/HelloWorld'
+import CompanyRoutes from './company-routes'
 
 Vue.use(Router)
 
 export default new Router({
   routes: [
     {
       path: '/',
       name: 'HelloWorld',
       component: HelloWorld
-    }
+    },
+    { ...CompanyRoutes }
   ]
 })
```

### vue-routerの動作モードをhistoryモードに指定する
vue-routerをhistoryモードで動作するように修正します

historyモードはHTML5のHistory APIを使ったもので、これは/companies/5のようなきれいなURLとなります。

#### src/router/index.js

``` diff
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import CompanyRoutes from './company-routes'

Vue.use(Router)

export default new Router({
+  mode: 'history',
  routes: [
    {
      path: '/',
      name: 'HelloWorld',
      component: HelloWorld
    },
    { ...CompanyRoutes }
  ]
})

```


### company-routes.js作る
**src/router/** に **company-routes.js**を作成し
それに設定を書いていきます

#### src/router/company-routes.js

``` javascript
import Company from '@/components/company/Company'
import Index from '@/components/company/Index'
import Create from '@/components/company/Create'
import Update from '@/components/company/Update'
import Delete from '@/components/company/Delete'

export default {
  path: '/company',
  component: Company,
  children: [
    {
      path: '',
      component: Index
    },
    {
      path: 'create',
      component: Create
    },
    {
      path: 'update/:id',
      component: Update
    },
    {
      path: 'delete',
      component: Delete
    }
  ]
}



```

## コンポーネントを作成する
**src/components/company** に上記で定義したコンポーネント作ります。

さらに **src/components/company** にあるコンポーネントを読み込むために **src/components/company/Company.vue** を作ります。  
このファイルが無いと正常に読み込まれません

#### src/components/company/Company.vue 

``` html
<template>
  <div>
    <router-view></router-view>
  </div>
</template>
```

これで以下のようにルーティングが設定されアクセスできるようになりました。

- ドメイン/company/
- ドメイン/company/create
- ドメイン/company/update/1
- ドメイン/company/delete/1

以上です。
「知る」技術、もしくは比較することについて

こんにちは、@mkataigiです。PLAID Advent Calendar 2017 8日目です。今日はコードは出てこない、データ分析系のお話です。

PLAIDでは[KARTE](https://karte.io/)という「ユーザーを知り、そのユーザーに合わせて接客をする」ためのシステムを作っています。今回はそんな、ユーザーを「知る」技術について深掘りしてみようと思います。

そもそも「知る」ということはどういうことでしょう？僕はユーザーを「知る」とは、あるユーザーが他のユーザーと比較して何が違うか／違わないかがわかること、だと考えています。つまり、ユーザーを「知る」技術とはユーザーを「比較する」技術になります。今日はその「比較する」技術について考えていきます。

「比較する」というと統計などの技術に入りがちですが、今回はその以前の次の２つの観点について説明します。

- 比較対象：何と比べるのか
- 比較方法：どうやって比べるのか

最初に謝っておきますが、今回出てくる例は全て恣意的に作った架空のもので、具体的な事例ではありません。


# 比較対象：何と比べるのか

```
以下の文章を読んで、あなたならどう感じますか？

「今回の全国模試の数学の成績は偏差値55だった。悪い結果で悔しい。」
```

「何か変なの？特に違和感はない」という人が多いんじゃないでしょうか？よく考えてみてください。偏差値55ということは平均より上、ということです。それは悪い結果なのでしょうか？

この文章のキモは「比較対象」です。次のような暗黙的な比較対象があると自然に考えてしまっているのです。

- （レベルの高い学校に在籍していて、周りの人と比較して）悪い
- （普段の試験ではいつも好成績なため、過去の結果と比較して）悪い

比較をする場合は常に「何と比較しているか」を意識するのが大事です。

#### 個人との比較はしない

個人同士を比較する場合は、単純に数字を比較すればいいので簡単じゃんと思われがちですが、実は個人同士を比較するというのはあまりありません。例えば次の文章を見てください。

```
Aさんは試験の結果が95点だった。Bさんは試験の結果が94点だった。
つまりAさんの方がBさんより賢い。
```

たった１点の差で、この結論は正しいのでしょうか？

![201712_truevalue.png](https://qiita-image-store.s3.amazonaws.com/0/103059/b32514cf-0f74-b191-5a83-bd4a37e1a02d.png)

よく知っての通り、実際には「誤差」というものが入って来ます。実際に分析をするときにはこの誤差が入るため、真の値から少しズレた値になっている、ということを意識しておく必要があります。今回のケースだと、以下のような感じになりますね。

```
テストの点数 = 真の頭の良さ（どうやって測るかわからないけど） +- 誤差（体調とかうっかりミスとか勘が当たったりとか）
```

個人同士の比較をしてしまうと、その「真の頭の良さ」がわからないため、賢さの比較することができないのです。

#### 集団と比較する

![201712_group.png](https://qiita-image-store.s3.amazonaws.com/0/103059/83c0bad7-e75b-c9e8-936e-7dc107d3711f.png)

最初の例の「レベルの高い学校に在籍していて、周りの人と比較して悪い」という解釈がこれになりますね。集団には複数の「値」が存在するため、「何の値」をその集団の「代表値」として捉えるかが大事になってきます。この辺りはぜひ統計学を勉強してみてください。

#### 過去と比較する

![201712_timeline.png](https://qiita-image-store.s3.amazonaws.com/0/103059/4041bb38-39f7-29c5-98e3-a9b5d0c32a23.png)

最初の例の「普段の試験ではいつも好成績なため、過去の結果と比較して悪い」という解釈がこれになりますね。過去の比較というのは、同じ状況が続くのであれば未来でも同じ変化が起こると考えられるので、未来予測をするうえで非常に重要です。そのため、長期間データを保持し続けるというのは非常に価値があります。


# 比較方法：どうやって比べるのか

```
あなたはオリンピック監督です。次の100m走のオリンピック代表を次のAさん、Bさんのどちらかにしようと思います。どちらにしますか？

Aさん： 身長180cm、体重80kg
Bさん： 身長160cm、体重60kg
```

そもそも走ってもらって決めろよ、という話ですが、あなたならどちらを代表選手にしますか？その理由は？

どちらにするかすぐには決めきれない人が大半なのではないかと思います。それは人間には次のような性質があるからです。

```
人間は２つ以上のことを同時に比較できない
```

ではその比較できないものをどうやって比較するのかについて２つの方法を見てみます。

#### １つずつ順番に比較する

２つを同時に比較できないならば、「１つずつ順番に２回比較」しよう、というのがこの方法になります。よく４象限にして書かれている図なんかがこれに当たりますね。

![201712_2dimension.png](https://qiita-image-store.s3.amazonaws.com/0/103059/b3488052-a358-d2eb-32e7-803c2419339a.png)

今回のケースでは使えないですが、事業戦略や成長戦略などで、まずは上に上行ってから右へ行こう！みたいな考え方をしてるかと思いますが、まさしくこれです。

#### 別の指標を作って比較する

２つ目の方法は、「新しい別の合成指標を作る」方法です。例えば今回の場合だとBMI（体重÷身長^2）などが良さそうですね。機械学習なども主にこの方法で比較していると思って良いです。

```
新指標 = aX + bY + cZ
```

今回はBMIという指標で比較してみると、次のようになります。

| 名前 | 身長   | 体重 | BMI |
|:----:|:-----:|:----:|:----:|
| Aさん | 180cm | 80kg | 24.7 |
| Bさん | 160cm | 60kg | 23.4 |

どうやらBさんの方が良さそうですね。


# まとめ

ユーザーのことを知るために「比較する」方法について見てみました。データを分析するときには、統計学や機械学習も大事ですが、その以前の「何を比較しているのか」「どうやって比較しているのか」ということを意識してみると、より良い分析ができるようになるかと思いますので試してみてください。