OmniAICreator/Qiita-1.07M huggingface dataset:
【fukuoka.ex】学生エンジニアがElixirに興味を持ったきっかけと初心者にオススメの勉強法

## Elixir（エリクサー）って何？
> Elixirは並行処理の機能や関数型といった特徴を持つ、Erlangの仮想マシン (BEAM) 上で動作するコンピュータプログラミング言語 by Wiki

ググれば色々と詳しく出てくるので、ザックリとメリットを述べると

* 関数型言語のメリットを享受できる一方でスクリプト言語のようなシンプルな言語仕様
* 「膨大なデータやアクセスの高速処理」と「高い開発効率」を両立できる
* Railsの開発者が作ったWebフレームワークPhoenix（フェニックス）が優秀
* ハードウェアの性能に比例した高速化が実現できる！

Discordなどの大規模サービスでも実際に使われているとか！

もうちょっと専門的に知りたい人はこちらとかオススメ
[Elixir for Rubyists | カヤックエンジニアブログ](https://techblog.kayac.com/elixir_for_rubyists)

## なんで興味を持ったか

### 1. これから台頭しそう
2020年以降SI案件が激減することが予想され、特に地方ではIT企業の取り巻く環境は厳しくなると考えられます。
そうでなくとも、エンジニアが足りない現状の割には取得データ量はどんどん増えていきます。
そうなると既存の水平/垂直スケールアップでは追い付かず、もっと根本的な効率化が必須となっていきます。
その一つの解決策として上記のようなメリットを持ったElixirが注目されています。

学生エンジニア目線からすると、Ruby(Rails)やPythonのような既に発展した言語だけだと先輩エンジニアに勝てないので、「若い（しかも時間がある）」という優位性を活かしてこれから発展していく言語を触っておくのも重要と思います。

もっと詳しく知りたい方はこちらとかオススメ
[【part.1】福岡のElixirコミュニティ fukuoka.exをどんな人がやってるか聞いてきた](https://dame.engineer/archives/391)

### 2. fukuoka.exコミュニティの優しさ
私が住んでいる福岡では fukuoka.ex というElixirコミュニティが最近盛り上がっています！
[fukuoka.ex ～福岡Elixirコミュニティ～](https://fukuokaex.connpass.com/)

これに加えて、piacereさんというfukuoka.exのドンがいて、その方がとても優しくて素敵なのも魅力です！
[fukuoka.ex公式サイト](https://fukuokaex.fun/)


### 3. 入門記事が面白かった
僕がとりあえず触ったのは「Excelから関数型言語マスター」シリーズ（全5回）
[Excelから関数型言語マスター1回目：行の「並べ替え」と「絞り込み」](https://qiita.com/piacere_ex/items/6714e1440e3f25fb46a1)

まずはこれを触ってみることをオススメします！
シェルスクリプト好きな人はパイプ記法にハマると思います笑

私はこれでElixir楽しい！となりました笑

## とりあえず何やればいい？
「へぇ面白そうじゃんElixir。やってやんよ・・・（ニヤリ）」という人は以下をオススメ笑

### 入門記事やってみる

* [Excelから関数型言語マスター1回目：行の「並べ替え」と「絞り込み」](https://qiita.com/piacere_ex/items/6714e1440e3f25fb46a1)
* [関数型でデータサイエンス#1：様々なデータをインプットする](https://qiita.com/piacere_ex/items/f7077f0ff1b1a6c7a959)
* [Elixir 基礎文法最速マスター](https://qiita.com/niku/items/729ece76d78057b58271)

### Twitterでつぶやく
まずはpiacereさんフォローしてみると面白いと思います！
[@piacere | twitter](https://twitter.com/piacere_ex)

\#fukuokaexのハッシュタグをつけてElixirに関することをつぶやくと、どこからともなくアルケミスト（Elixirエンジニア）がやってきてリプしてくれるという噂が・・・？（実体験ｗ）

### もくもく会への参加（福岡など）
fukuoka.exでは月1回程度もくもく会が開催されています。「Elixir触ったことない、なんならプログラミング初心者なんだけど・・・」って人でも優しく受け入れてくれるらしいです！ｗ
[もくもく会](https://fukuokaex.connpass.com/event/96725/)

開催日を知るには[fukuoka.ex公式サイト](https://fukuokaex.fun/)や[fukuoka.ex connpass公式ページ](https://fukuokaex.connpass.com/)をチェックしておくといいかと！

##### コメントがあったので追記
[fukuoka.ex connpass公式ページ](https://fukuokaex.connpass.com/)に登録しておくと、告知と同時に案内メールが送信されるようです

## ちょっと面白い勉強法
個人的に面白いかなと思う勉強
### HackerRankやってみる
[HackerRank](https://www.hackerrank.com/domains/fp)というプログラミングの問題を解いてオンラインジャッジしてくれるサイトがあります。
色々ジャンルがあるのですが[Functional Programming](https://www.hackerrank.com/domains/fp)というジャンルで関数型に特化した問題がたくさんあります。なんとElixir使えます！「とりあえず文法覚えたし手を動かしてみるか！」って人にオススメ

標準入出力意外と見つからなかったので置いときますね（もっといい書き方ありそう）

```elixir:aとbを標準入力から受け取って和を返す

defmodule Solution do
  a = IO.gets("") |> String.trim() |> String.to_integer
  b = IO.gets("") |> String.trim() |> String.to_integer
  IO.puts(a+b)
end
```

## Elixirやろうぜ！
コミュニティの温かさもあって、単純にエンジニアコミュニティとしてもオススメです！
僕もちまちまElixir書いていこうかなと思います！

**目指せ上級アルケミスト！**

※アルケミスト＝Elixirエンジニアの通称
Django(2系) 覚え書き

# はじめに

Djangoを勉強したので流れをまとめておく。
Djangogirls tutorialで勉強したところDjango2系では少し異なる部分もあった。

筆者はプログラミング初級者のため、間違いがあればご教授いただけると嬉しいです。

## 仮想環境を作成
```
python3 -m venv [env_name]
source [env_name]/bin/activate
```

## pipで下準備
```
pip install --upgrade pip
pip install django gunicorn whitenoise
```

## Djangoでプロジェクト・アプリを作成
```
django-admin startproject mysite .

python manage.py startapp [app_name]

python manage.py migrate

python manage.py createsuperuser
```

## mysite/setting.pyに追加
```py:mysite/setting.py
INSTALLED_APPS = '[app_name]'を追加

MIDDLEWARE = 'whitenoise.middleware.WhiteNoiseMiddleware'を追加

LANGUAGE_CODE = 'ja-JP'

TIME_ZONE = 'Asia/Tokyo'

USE_TZ = False

STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATICFILES_DIRS = (os.path.join(BASE_DIR, "static"),)
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
```

## 'model.py'を作成したら、アプリの登録
```py:model.py
python manage.py makemigrations [app_name]

python manage.py migrate
```

### `[app_name]/admin.py`を編集
```
from .models import [Class_name]

admin.site.register([Class_name])
```

## CSSを読み込む

[BASE_DIR]直下にstatic/css/[app_name].cssを作成

```html:
{% load static %}
<link ref="stylesheet" href="{% static 'css/[app_name].css'}">
```

## templateを使う
[app_name]/[templates]/[app_name]/にhtmlを作る。

```html:
{% extends '[app_name]/base.html' %}

{% block content %}

{% endblock %}
```
"E: Unable to locate package" debianにaptでインストールしたらエラーが起きた問題

これは学習日記をつらつら書いてるだけのものです。
結果を先に書くと、aptをアップデートすることで解消しました。

## Debianにvimをインストール

```
#docker exec -it コンテナ名 実行コマンド
docker exec -it container1 bash
```
で起動したコンテナ（debian）にアクセス。

debian に apt install vim を行おうとすると

```
root@cdf97162355a:~# apt install vim
Reading package lists... Done
Building dependency tree
Reading state information... Done
E: Unable to locate package vim
```
とエラーが出てしまった。

調べてみるとアップデートが必要とのこと。

```
$ apt update
```
でアップデートした後、再度インストールに挑戦したらうまくvimが入った。

というかアップデートしないでいるとインストールしたいコマンドによっては apt
search の結果もでなかたったり。

## おまけ
debianをいじることになったのでそれに伴ってaptを使用したが、
調べてみると、aptには大きく３種類分かれているようだ。
apt / apt-get / aptitudo
他にもaptなんちゃらはあるようだが、これらの違いについてざっくりと調べてみた。

apt-getは最初のapt関連のcuiコマンドだったらしい。
が、今はapt-getでインストールするより、aptでインストールすることの方が推奨されているらしい。

aptitudoはGUI操作も加わって使いやすさを求められたものだとか。
ただ、CUIの扱いとともにGUIの扱い方も学ばないと行けないからダルとかなんとか。

ざっとみた感じ、aptコマンドだけ使っておけば当分は良さそうだ。
Mastodonの連合に見えちゃってるNSFW（R18）な画像を監視してレポートするbotをGCP無料枠で運用する

これで完璧とは言えないが、無いよりマシな連合のNSFW(R18)監視botをGCPの無料枠で運用します。

# Google Cloud Platformの無料インスタンスの構築

[この辺のページ](https://qiita.com/FukuharaYohei/items/0614354d6a4eda32d521)を参考に無料インスタンスを構築します。IPの固定化やポートの開放などは必要ありません。

- 無料枠にする
- デイスクサイズを30GBにする

そしてインスタンス内でdockerを利用するので、

![image.png](https://qiita-image-store.s3.amazonaws.com/0/177194/6b89eefb-fdbe-a570-40ca-a5dc6bc308b8.png)

「このVMインスタンスに〜」にチェックを入れておきます。コンテナイメージには[Docker Hub上のリポジトリ](https://hub.docker.com/r/wakin/nsfw_reporter/)を利用するので

`docker.io/wakin/nsfw_reporter`

を入力します。

# nsfw_reporterの起動

後は[nsfw_reporterの使い方](https://github.com/wakin-/nsfw_reporter#%E4%BD%BF%E3%81%84%E6%96%B9)に従ってください。初回起動は多分dockerコンテナが落ちてると思うんで、`envfile`を追加して`--enf-file envfile`で環境変数ファイルを指定してdockerコンテナを新たに起動します（古い方は消していいです）。ちなみにインスタンス内にブラウザでSSH接続しての作業は非常に辛いものがあるので、envfileの追加はローカルで作成したファイルを右上の歯車マークから「ファイルをアップロード」するのがいいです。
minicondaでスマートに環境構築 for Mac

## 概要
さあ、機械学習をはじめよう！といった場合に、まずはじめにつまづきやすいポイントは開発環境の構築でしょう。
pyenvとanacondaをインストールして環境構築する記事が目立ちますが、正直なところあまりお勧めできません。
・pyenvでPython2系と3系を使い分ける必要は皆無（２系は２０２０年にサポート終了するので、さっさと３系に移行しましょう）
・Anacondaは機械学習では使わないライブラリが多いわりに、必要とするライブラリは結局pipでインストールするので、理にかなってない。

...と、pyenv+Anacondaのデメリット書き出すとキリがありません。
てか、機械学習の開発現場からいらないライブラリが多すぎる！という不満が多くて、
必要最小限の機能だけ詰め込んだMinicondaを作ったんだろうねってことは容易に想像できちゃいます。。

というわけで、Minicondaでシンプルに開発環境を構築していきましょう^^

## マニュアルを読んでインストールしてみよう！
かなり当たり前のことですが、公式マニュアルをしっかり読んでから、インストールしましょう。
Minicondaに限らず、なんでもそうですが、他のブログや記事の通りに作業する前に、出典元である公式ドキュメントを理解してから作業に取り掛かりましょう。基本です。
マニュアルは英語なので、毛嫌いする人もいますが、機械学習の分野で活躍していくためには、英語は必須スキルです。
英語苦手な方もこれを機にトライしましょう。専門用語さえ理解できていれば、英語は難しくありません。

[Installation — Conda documentation](https://conda.io/docs/user-guide/install/index.html)

要点を書きながら、マニュアル通りにインストールします。

>System requirements
32- or 64-bit computer.
For Miniconda—400 MB disk space.
For Anaconda—Minimum 3 GB disk space to download and install.
Windows, macOS or Linux.
Python 2.7, 3.4, 3.5 or 3.6.
pycosat.
PyYaml.
Requests.

システム要件では、Anacondaは3GB必要としますが、Minicondaは400MBのディスク容量で事足りるみたいですね。

> Installing conda on a system that has other Python installations or packages

>You do not need to uninstall other Python installations or packages in order to use conda. Even if you already have a system Python, another Python installation from a source such as the macOS Homebrew package manager and globally installed packages from pip such as pandas and NumPy, you do not need to uninstall, remove, or change any of them before using conda.

>Install Anaconda or Miniconda normally, and let the installer add the conda installation of Python to your PATH environment variable. There is no need to set the PYTHONPATH environment variable.

もうすでにインストールしたPythonパッケージをアンインストールする必要はありません。PYTHONPATHを通す必要もなし。

お次は、Minicondaインストーラのページ
[Miniconda — Conda](https://conda.io/miniconda.html)

自分はMacOSなので、MacOSのインストーラをダウンロードします。もちろんPython3系。
ターミナルを開いて、作業領域でインストーラを実行。早速インストールします。

    $ bash Miniconda3-latest-MacOSX-x86_64.sh

> Do you accept the license terms? [yes|no]

途中で、ライセンス許可が求められるので、yesを選択します。

> Do you wish the installer to prepend the Miniconda3 install location
to PATH in your /Users/hamamac/.bash_profile ? [yes|no]

.bash_profileにMiniconda3のパスを通してもいいか聞かれます。
yesを選択してOKです。既存のbash_profileはバックアップされます。

> For this change to become active, you have to open a new terminal.
> Thank you for installing Miniconda3!

新しく、ターミナルを開いて、確認してみましょう。

    $ conda -V
    conda 4.5.4

とっても簡単でしたね。
記事にする必要がないぐらいシンプルでしたが、
Pythonの開発環境構築系の記事は複雑なやり方している人が多いと思って書きました。
環境構築はシンプルであるべきです。シンプルイズベスト。
では、良きAIライフを！
Adafruit_nRF52_Arduinoを使ってみる（作業途中）

Adafruit_nRF52_Arduinoを使ってみる
https://github.com/adafruit/Adafruit_nRF52_Arduino

これは、Adafruit の 「Adafruit Feather nRF52 Bluefruit LE」
https://www.adafruit.com/product/3406
 用のもの

今までオリジナルのBLEモジュール「アオノドン」
https://qiita.com/nanbuwks/items/1df921fc1f9b832b38a5
を Sandeep Mistry の arduino-nRF5 
https://github.com/sandeepmistry/arduino-nRF5
で使っていた。

今回、「アオノドン」をこちらで使ってみる。

# 「アオノドン」と「Adafruit Feather nRF52 Bluefruit LE」の比較。


アオノドン
- BLEモジュール MDBT42
- SoC nRF52832
- Flash 512K
- 書込デバイス 外部ST-LinkV2モジュール
- USBシリアルモジュール オプション装着 (CP2102)
- 外形 44.5mmx14mm

Adafruit Feather nRF52 Bluefruit LE
- BLEモジュール MDBT42Q
- SoC nRF52832
- Flash 512K 
- 書込デバイス 内蔵USBシリアルモジュール
- USBシリアルモジュール 内蔵　(CP2104)
- 外形 51mmx23mm

# Arduino 開発環境の基本的なセットアップ

https://www.arduino.cc/

から、

ARDUINO 1.8.6をダウンロード。
今回、Linuxの64bit版を使用。


Windowsの場合は、ポータブル環境にすることを考え、「Windows ZIP file for non admin install」を使います。

MACの場合は、「Mac OS X 10.7 Lion or newer」を使います。

ダウンロードしたら、「portable」というフォルダを作ります（Windows,Linuxの場合）
![image](https://qiita-image-store.s3.amazonaws.com/0/139524/228cf18a-b938-67b6-9e5f-f14e8bd33337.png)

## デスクトップにショートカットを作る
（Linuxの場合）
install.sh というファイルを実行すると、デスクトップにショートカットができます
(Windowsの場合)
ショートカットをデスクトップに手動で作成して下さい

## 設定

ArduinoIDEを起動して、
「ファイル」-「環境設定」で、「追加のボードマネージャのURL:」に「 https://www.adafruit.com/package_adafruit_index.json 」と入力して「OK」。
ArduinoIDEを再起動して、「ツール」-「ボード:・・・」-「ボードマネージャ...」で「Adafruit nRF52」で検索して「Adafruit nRF52 by Adafruit」をインストール。
インストールには時間がかかります。

「ツール」-「ボード:・・・」-「Adafruit Bluefruit nRF52 Feather」を選択

さて、書込装置をST-Linkにしようとしましたが、それらしきものが見つかりません。
どうしようかな・・・とりあえず先にコンパイルを試してみます。


## エラー！　

blink を呼び出して、コンパイルしようとしましたが・・・

![image](https://qiita-image-store.s3.amazonaws.com/0/139524/4e482264-5c2d-b895-aa3e-758b5f45104f.png)

```

exec: "adafruit-nrfutil": executable file not found in $PATH
ボードAdafruit Bluefruit nRF52 Featherに対するコンパイル時にエラーが発生しました。

```

となりました。まだまだ精進が足りません。
Laravelの開発環境をDockerで構築する

Dockerの導入~DokHubにイメージ公開まではこちらを参考させてもらいました。
参考：[docker-hands-on](https://github.com/kakakakakku/docker-hands-on/blob/master/README.md)

準備が終わったら、Laradock導入でハマっちゃったこと。

###port is already allocated！！

ポートが使用されていて起動できない！確かにlocalhostにはなんか違うもの表示されてるし…

ポートが使用されていないか確認

```
sudo lsof -i:3306
```
MAMPをSTOPしてDockerをRestartしたのち、
ポート接続を遮断

```
sudo apachectl stop
```

しかしLISTEN状態は解消せず。
最終的にMac再起動で解決しました！
TensorFlow 処理によってCPUとGPUを切り替える方法

# 背景
* TensorFlow GPU版の評価環境において、tf.truncated_normal()を用いて、大量の乱数データ生成を試みるとエラーになることがわかった。
* 他の処理においても、GPU環境でのみエラーが多発し、ハードウェア的な制約が原因の可能性も考えられ、すぐに解決することが難しいと感じた。
* 気軽にGPU資源を活用するために、処理によってCPUとGPUを使い分ける必要があると感じ、その方法を調査した。

# 環境
* iMac14,2
* Intel Core i7
* 3.5 GHz
* プロセッサー数: 1
* コア数:  4
* システムメモリ:    8 GB
* NVIDIA GeForce GTX 775M
* VRAM: 2048 MB
* TensorFlow 1.10.0 (GPUを利用設定でソースからコンパイル)

# データ処理の設計について
ドライブ、システムメモリ、VRAMで容量が異なり、各デバイスの長所を活かして処理するためには、各デバイスの性能を理解して、設計を工夫する必要があると考える。

# 処理の流れ
以下のような構成のサンプルを作成した。データ生成処理については、ドライブからデータ読み込む処理に、置き換える予定だ。

* tf.truncated_normal()で複数のデータを生成(CPU)
  * このデータがVRAMの容量を越えてもエラーにならないことを期待する
* VRAMで処理できる容量にスライスする（CPU）
* スライスされたデータをtf.multiply()する（GPU）

# TensorFlow の実装方法
## 処理デバイスの切り替え
* 以下のメソッドの引数でデバイス名を指定する

```python
Graph.device()

# 以下のラッパーを使い実装することも可能
with tf.device(DEVICE_NAME):
    pass
```

## デバイス名の一覧の取得

```python
from tensorflow.python.client import device_lib
device_lib.list_local_devices()
```


# 処理されるデバイスを確認するためのログの出力
## 設定方法
* 以下の設定で、コンソールログに出力される

```python
tf.Session(config=tf.ConfigProto(log_device_placement=True))
```

## ログ出力の例
* TruncatedNormalはCPU、multiply_operatorはGPUに設定されたことが確認できる

```python
image_generator/TruncatedNormal: (TruncatedNormal): /job:localhost/replica:0/task:0/device:CPU:0
multiply_operator: (Mul): /job:localhost/replica:0/task:0/device:GPU:0
```

# 実行結果
## CPU と GPUで処理を切り替えたときのアプリケーションログ
* 乱数の生成:CPU 
  * この処理をGPUに指定するとエラーになることを確認
* 乱数の生成の処理時間
* multiply演算:GPU
* multiply演算の処理時間

```python
start: generate images. /device:CPU:0
finished: generate images. 36.227976999999996 sec
start: multiply operations.  /device:GPU:0
finished: multiply operations. 35.92272199999999 sec
```

## GPU版で、デバイス指定を全てCPUにしたときのアプリケーションログ
* multiplyの演算において、GPUを指定したときよりも時間がかかるという結果が得られた

```python
start: generate images. /device:CPU:0
finished: generate images. 38.002104 sec
start: multiply operations.  /device:CPU:0
finished: multiply operations. 108.50434299999999 sec
```

# macOS のGPU使用率のスクリーンショット
* macOSのGPU使用率のモニターツールでGPUの使用を確認した
* デバイスの指定をGPUに設定したときのみ、モニターが大きく反応した
* デバイスの指定が正常にされていることが期待できる結果となった

![ss.png](https://qiita-image-store.s3.amazonaws.com/0/198185/44ede00e-bbe6-ec30-324d-f2d72036b652.png)


# 考察
* GPUとCPUで処理を切り替えることで、GPU資源を有効活用しやすくなると感じた。
* 実現可能なのかは、別途、調査が必要だが、CPUでのファイルのロードを分割し、ロードが完了したデータから先にGPUに演算させるような構成を取ることで、効率を上げることができるのではないかと考えた。
* システムメモリ、VRAMへのデータの割り当て状況についての確認方法を模索したい。
Alexa スキルアワード2018　申請編

前回、[申請するためのスキルは作ってみた](https://qiita.com/ryo_naka/items/c8d00abb283c29c278cb)ので今回は申請してみる。

## 条件
<img width="519" alt="01.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/106639/f1b2ad45-665f-c937-41a8-48e6d407c522.png">

わかってはいたが動画のURLが必須。
動画をどこかにアップロードする必要があるのがめんどくさいが仕方ない。

幸い？2年ぐらい前に作ったYouTubeの投稿用のアカウントがあるのでそれを使おうかと思ったが、
名前がもろに出るので別のチャンネルを作ることにする。

といっても、Googleのアカウント紐づくので、サインインしている状態でYoutubeを開いてアップロードのところでブランド名を設定したら出来上がり。

## 申請
ということでこんな感じで申請してみた。

    [作品名]
    SkillToWunderList

    [作品概要（50文字以内）]
    IFTTT経由だと文字化けするので、Skill経由から直接別アプリの家族用の買い物リストへ連携させた

    [動画URL]
    https://youtu.be/QL7ffFIYZdY

<img width="481" alt="02.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/106639/2ac9075e-3087-57be-0151-177d92a9cd51.png">


正直、これだけの情報でどうやって審査するのかは不明。
たぶんにぎやかしとしてだけなのかなーという気もするが、Tシャツくれるんならそれでもいいかな。
「日本での初回のSkillアワードに参加した」という証拠にはなるだろうし。


申請のレスで以下が書いてあったので拡散もしておく。
※というかこのタグ、全然見かけないのだが参加者ってどれくらいいるんだろう？
<img width="417" alt="03.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/106639/f8761b36-5e49-2b85-ce2f-fb821ebfc569.png">

## イベント
ついでに、本アワードのイベントが[Alexa スキルアワード2018 ファイナルステージイベント](https://amazonalexaskillawardsfinal.splashthat.com/)として開催するみたいなのでこっちにも参加登録しておく。
【Mac】右クリックにショートカットキーを割り当てる方法

Macに関するTipsです。

基本的な操作はなるべくキーボードだけで行うようにしているのですが、『右クリック』だけはいつもトラックパッド(or マウス)を併用していました。

公式サイトにも以下のように記述されております。

[Mac で右クリックする方法](https://support.apple.com/ja-jp/HT207700)
> Mac コンピュータでは、右クリックは「副ボタンのクリック」や「『control』キーを押しながらクリック」

Macだと右クリックのショートカットがないのかなと思っていたのですが、Better Touch Toolを使えばショートカットキーの割り当てができます。

Better Touch Toolとはウィンドウ操作をはじめとする様々な操作に対して独自のショートカットキーを割り当てられる便利なアプリで、Macユーザーに広く利用されているものです。Better Touch Toolについてご存知でない方は[こちら](https://nishinatoshiharu.com/window-efficient-app/)をご覧ください。

Better Touch Toolの設定画面をひらき、以下のような手順で進むと右クリックにショートカットキーを割り当てられます。
![スクリーンショット_2018-08-25_11_12_27.png](https://qiita-image-store.s3.amazonaws.com/0/140792/5c0f3edb-51d9-10b7-ea97-ae2c22bed42a.png)

もちろん、Better Touch Toolを使わなくても右クリックのショートカットキーを作成する方法は他にもあると思いますが、方法の一つとして知っていただければなと思います。

もし同じようなことに悩んでいる方がいましたら参考にしていただければと思います。

by <a href="https://twitter.com/nishina555" target="_blank" rel="noopener">@nishina555</a>
【Unity】～SIerからゲーム業界へ～ 第5回 GitHub導入

ソースの公開用にGitHubを導入してみます。

[第一回](https://qiita.com/straycatz/items/2bbadf169f2fde5371f1)で書きましたが
Microsoft Team Foundation Server を使っていたので躓く部分なく導入終わりました。

用語名が違ったりツールの使い方が違うだけなので
・Visual Studio使用者
・TFS または何かしらのソース管理システムを使った事がある人
を前提としたメモになります。

##GitHubに登録
[GitHub](https://github.com/)にて登録作業
詳しいサイトがたくさんあるのでそちらを参考に


##Visual Studio にて拡張機能をインストール

[ツール]-[拡張機能と更新プログラム]にて
GitHub Extensions for Visual Studio をインストール

![image.png](https://qiita-image-store.s3.amazonaws.com/0/267737/cc6870c5-cbff-427f-8e07-b07c7254b8c4.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/267737/dbcf1797-28a7-d83d-f06e-c102a6113dd7.png)


もう作業したあとなので画像が作業後になってしまっていますが
[チームエクスプローラ]の中にGitHub関係の項目が追加されています。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/267737/04c5d9f4-518b-678b-81e9-a52616e3d644.png)

これから徐々に公開していきます。
https://github.com/straycatz

##追記
VisualStudioから初のUnityのファイルをアップロードしたところ
ローカルレポジトリへのアップでエラー多発…。

改行コードの自動変換が行われていることが原因のようです。

C:\Users\ユーザ名\.gitconfig

こちらのファイルにて下記を追記

```.gitconfig
[core]	autoCRLF = false
```
GitHubのREADMEに画像を投稿するイチバン簡単な方法

1, issueに「readme投稿用画像置き場」を作る

2, 上記issueに画像を投稿する

3, 画像リンクをコピー

4, 以下のように埋め込む

```
![画像タイトル](画像アドレス)
```
Item 44: Favor the use of standard functional interfaces

# 44.標準の関数型インターフェースを使うべし
* 標準で用意されているものを使うことによって、使いやすさが増し、すでに組み込まれている様々なメソッドの恩恵にあずかれる。
* java.util.functionに含まれる関数型インターフェースは43個ある。
  * 中心的なのは```UnaryOperator<T>```、```BinaryOperator<T>```、```Predicate<T>```,```Function<T>```,```Consumer<T>```,```Supplier<T>```の6つ。(6)
  * 上の6つそれぞれに```int```、```long```、```double```のプリミティブ型を扱うための関数型インターフェースがある。（18）
  * FunctionにはSrcToResultFunction(```LongToIntFunction```とか)で6つ。SrcToObjFunction（```DoubleToObjFunction```とか）で3つある。(9)
  * 引数を2つ取るものが9つある。(9)
  * BooleanSupplierなるものがある。(1)
* プリミティブ型に対応していない関数型インターフェースでプリミティブ型をボクシングしたオブジェクトを使ってはならない。性能が悪くなる。
* 自身で関数型インターフェースを書く必要があるのは以下の場合。
  * 引数を3つ取る関数型インターフェースなど標準で用意されていないものが必要となる場合。
  * 一般的に使われていて記述から恩恵を受けれらる、強い関連性をもった契約がある（**よくわからん**）、defaultメソッドから恩恵が受けられる、といった特徴がある場合。(```Comparator<T>```が例に挙げられている)
* 関数型インターフェースを書く際には、必ず@FunctionalInterfaceをつける。これがあれば、誤った書き方をしていた場合にコンパイルエラーにしてくれる。
* 関数型インターフェースを引数に取るメソッドはオーバーライドすべきでない。（Item52）
Item 43: Prefer method references to lambdas

# 43.ラムダ式よりメソッド参照を使うべし

* 基本的にラムダ式よりメソッド参照の方が簡潔に書けるため、メソッド参照を選択するべき。
* ラムダ式の方が簡潔に書ける場合もある。よくあるのは、同クラスにあるメソッドを用いる場合。

```java
// メソッド参照
service.execute(GoshThisClassNameIsHumongous::action);
// ラムダ式
service.execute(() -> action());
```

* 多くのメソッド参照はstaticメソッドの参照であるが、他にも4つのパターンがある。
  * Bound 参照（訳が分からない。。）はメソッド参照において、受け取るオブジェクトが特定される。
  * UnBound 参照（訳が分からない。。）は関数オブジェクトを適用するときに、受け取るオブジェクトが特定される（**意味がよくわからない**）。streamのmapやfilterでよく使われる。
  * クラス、配列のコンストラクタについては以下の表のようにできる。


| Method Ref Type | Example | Lambda Equivalent |
|:-------|:-------|:-------|
| Static       | Integer::parseInt | str -> Integer.parseInt(str)
| Bound |Instant.now()::isAfter | Instant then = Instant.now(); t -> then.isAfter(t) |
| Unbound | String::toLowerCase | str -> str.toLowerCase() |
| Class Constructor | TreeMap<K,V>::new | () -> new TreeMap<K,V> |
| Array Constructor | int[]::new | len -> new int[len]
Item 42: Prefer lambdas to anonymous classes

# 42.匿名クラスより、ラムダ式を選択すべし

* より簡潔明瞭に書けるという理由から、匿名クラスよりもラムダ式を用いるべき。

```java
package tryAny.effectiveJava;

import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class AnonymouseVsLambda {
    public static void main(String[] args) {
        List<String> words1 = Arrays.asList("apple", "pen", "pineapple");
        // 匿名クラスで書く。
        Collections.sort(words1, new Comparator<String>() {
            public int compare(String s1, String s2) {
                return Integer.compare(s1.length(), s2.length());
            }
        });
        System.out.println(words1);

        // 型をRawにするとコンパイルエラーとなる。
        List<String> words2 = Arrays.asList("banana", "grape", "melon");
        // ラムダ式で書く。
        Collections.sort(words2, (s1, s2) -> Integer.compare(s1.length(), s2.length()));
        System.out.println(words2);
    }
}
```

* ラムダ式での型は、書くことによってコードが綺麗にならない限り、省略してよい。
* クラスやメソッドと違って、ラムダ式には名前もドキュメントもないので、自明な処理でなかったり、4行以上となる処理はラムダ式で記述すべきでない。
* 匿名クラスが必要となる場面は以下。
  * ラムダ式は関数型インターフェースの型にしか代入できないので、複数のメソッドを持つインターフェースや、抽象クラスのインスタンスが必要となる場合は匿名クラスを使う
  * ラムダ式でのthisはエンクロージングクラス（外側のクラス）を指すが、匿名クラスでは匿名クラス自身を指すので、関数オブジェクト自身へのアクセスが必要な場合には、匿名クラスを使う
Nuxt.jsでサーバサイドとクライアントの仮想DOMの構造が違うというエラーの対処法

あまりにも情報少なかったのでとりあえずメモ残しときます。
nuxt使った時にサーバサイドとクライアントサイドの仮想DOMの構造違うじゃないかとエラーが出て直すのに苦戦しました。
エラーログではpタグとかtbodyタグを見直してと言われてますが自分の場合はレンダリングした時に実行する関数のライフタイムサイクルを
created→mounted
に変更したらエラー消えました。
どうやらvueの仕様で仮想domの操作はmounted以降で行わなければいけないようでした。
意外と初歩的な問題でしたが情報少なかったので記事書きました。
Item 41: Use marker interfaces to define types

# 41.型定義のためにマーカーインターフェースを使うべし

[マーカーインターフェース](https://ja.wikipedia.org/wiki/%E3%83%9E%E3%83%BC%E3%82%AB%E3%83%BC%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%95%E3%82%A7%E3%83%BC%E3%82%B9)とは、メソッド定義を含まず、単にそのインターフェースを実装したクラスが特定の属性を持っていることを示すためのものである。
例として、```Serializable```インターフェースがあげられる（12章）。このインターフェースを実装することで、そのクラスのインスタンスは```ObjectOutputStream```に書き込み可能であることが示される。

マーカーアノテーション（Item39）の登場で、マーカーインターフェースは時代遅れになったように思えるかもしれないが、それは誤りである。
マーカーインターフェースはマーカーアノテーションに比べて、2つの点でアドバンテージがある。
1つ目は**マーカーインターフェースは型を定義するが、マーカーアノテーションはしない**ことである。これによって、マーカーアノテーションでは実行時まで捕捉できないエラーがコンパイル時に捕捉できることとなる。
Javaのシリアライゼーション機能では、型がシリアライザブルであることを示すために、```Serializable```マーカーインターフェースを使用している。```ObjectOutputStream.writeObject```メソッドでは、渡されたオブジェクトをシリアライズするが、その引数はシリアライザブルであることを求める。このメソッドの引数が```Serializable```であれば（実際にはObjectをとる）、不適切な型の引数が来た場合にコンパイルで検知できる。
2つ目は**マーカーインターフェースの方がより簡潔に対象を絞れる**ことにある。
マーカーアノテーションのターゲットが```ElementType.TYPE```である場合は全てのクラスとインターフェースが対象となるが、マーカーインターフェースの場合はそれを実装しているクラスに限られる。
```Set``` インターフェースは、そのような制限するマーカーインターフェースである。
SetはCollectionのサブタイプにのみ実装されるが、Collectionで定義されたメソッドに何も付け加えていない。SetはCollectionのメソッドの一部を再定義しているので、一般にマーカーインターフェースとはみなされていない。
しかし、特定のインターフェースのサブタイプにのみ適用され、インターフェースのメソッドを再定義しないマーカーインターフェースは想像しやすい。そのようなマーカーインターフェースは、オブジェクト全体のある不変値（?）を記述したり、そのインスタンスは他の特定のクラスのメソッドによって処理されるように適合していることを指し示す（この意味では、```Serializable```インターフェースは、そのインスタンスが```ObjectOutputStream```に処理されることに適合していることを指し示している）。

**マーカーアノテーションの利点は、大きなアノテーション機能の一部であるという点にある。**それゆえ、マーカーアノテーションはアノテーションベースのフレームワークで一貫性が考慮されている。

## マーカーアノテーション、マーカーインターフェースをどう使い分けるか？
まず、クラスとインターフェース以外の要素にマーカーをつけるには、マーカーアノテーションを使用するしかない。
クラス、インターフェースへのマーカーに関しては、
***このマーキングをしたオブジェクトのみを対象としたメソッドを1つ以上書くことがあるか？***
を考えてみる。
もし書くことがあるなら、マーカーインターフェースを利用するべき。これによって、メソッドの引数の型チェックをコンパイル時に行うことができる。
もし書かないのであれば、マーカーアノテーションを利用すべき。
アノテーションをたくさん使うフレームワークにおけるマーキングであれば、マーカーアノテーションを選ぶべき。
Google Cloud Functions(The Python Runtime)のHTTP Functionsのテストを書く

## 経緯

Python RuntimeのGoogle Cloud Functions(beta)で画像処理するAPI作ってたのだが、Pythonの場合、[Cloud Functions Node.js Emulator](https://cloud.google.com/functions/docs/emulator)のようなものがまだないので毎回デプロイしないと動作確認できないのが辛かったので、テスト書く方法を模索してみた。

## テスト対象コード

[公式チュートリアル](https://cloud.google.com/functions/docs/writing/http)から拝借。

```main.py
def hello_http(request):
    request_json = request.get_json()
    if request_json and 'message' in request_json:
        name = request_json['message']
    else:
        name = 'World'
    return 'Hello, {}!'.format(name)
```

## テストコード

今回は[Testing Flask Applications](http://flask.pocoo.org/docs/1.0/testing/)を参考にpytestで作成。

テストコード内でflaskのアプリケーション作って、cloud functionsのメソッドを間接的に呼び出すルーティングをして、テストでそれを呼び出すことでflaskっぽい感じのテストをかけるようにした。

```test_main.py
import os
import pytest
from flask import Flask
from flask import request
from main import hello_http


@pytest.fixture(scope='session', autouse=True)
def client():
    # setup
    app = Flask(__name__)

    # 間接的にhello_httpを呼び出す
    @app.route("/")
    def _hello_http():
        return hello_http(request)

    client = app.test_client()

    yield client

    # teardown

def test_hello_world(client):
    rv = client.get('/')
    assert b'Hello, World!' in rv.data

def test_hello_yamada(client):
    rv = client.get('/', json={
        'message': 'yamada'
    })
    assert b'Hello, yamada!' in rv.data

```

## 参考

- [HTTP Functions  |  Cloud Functions Documentation  |  Google Cloud](https://cloud.google.com/functions/docs/writing/http)
- [Testing Flask Applications — Flask 1.0.2 documentation](http://flask.pocoo.org/docs/1.0/testing/)

## 雑記

node.js貧民であるのでcloud functionsの処理が書きづらいなーと思ってたところにpython対応(beta)が入ったので、だいぶ書きやすくなって嬉しい。

今の所、大きなバグには遭遇してないので簡単なAPI作るにはとても良さそう。

ただ、flaskベースだけどflaskのルーティングとかのやり方がそのまま使えないのが結構混乱する。
Databricks cloudでsecret機能を使う

## この記事について

databricks上にAWSのアクセスキーなどの情報をセキュアに扱うための機能、Databricks Secret機能の利用方法についてのメモ。
基本的には[公式ドキュメント](https://docs.databricks.com/user-guide/secrets/index.html)どおりに進めました。

まず、databricks secret機能を利用するためにdatabricksのCLIをインストールし、そこから情報を登録していきましょう。

## Databricks CLIを利用可能にする
インストールはpipで一発。

```.sh
$ pip install databricks-cli 
```

そこから、設定を進めます。
まずは、ご利用のdatabricksにログインし, アカウント設定画面からAccess Tokenを発行(generate)しましょう。
そのtokenをクリップボードにコピーした状態で、引き続きターミナルから下記実行しましょう(実行するのは一番上の行のみ)。
Hostとtokenを聞かれるので、それぞれ入力してください。

```.sh
$ databricks configure --token
>>Databricks Host (should begin with https://): https://<your-host>.cloud.databricks.com/ # アクセスしているhost名
>>Token:  # tokenを貼る
```

これで設定は完了です。

## Databricks Secrets機能を利用する

databricks CLIからSecret機能を設定しましょう。
流れとしては、secret scope(セキュリティ情報をまとめる単位)を作成し、そこにkey-valueのペアを作成していくことになります。まずscopeを作成しましょう。

```.sh
$ databricks secrets create-scope --scope <your_scope> # scope名は任意に設定すること
```

次に、作成したscopeに情報を入れていきす。
CLIからはkeyを入力し、valueはコマンド実行後立ち上がるエディタの一番上の行に入力してください。

```.sh
$ databricks secrets put --scope <your_scope> --key <your_key> # your_keyは任意に設定可
```

secret情報をDatabricks notebook上で取り出す場合には、下記のような形で呼び出せます。

```.sh
# databricks secretsからAWSアクセスキーとシークレットアクセスキーを呼ぶ
key = dbutils.secrets.get(scope="<your_scope>", key="<your_key1>")
secret = dbutils.secrets.get(scope="<your_scope>", key="<your_key2>")
```
CEK 開発用 Clova シミュレーターで開発スピードを上げる

CEK の開発は楽しいのですが、開発効率を下げる要因として実機の使用があります。　　　

- デバッグ中に毎回クローバーに話しかけないといけない
- 結果を音声で聞くしかない
- 分岐を覚えられない
- デバッグすると毎回タイムアウトするので進まない

ということで今回もシミュレーターを作りました。

# Clova シミュレーター

[詳細はこちら](https://github.com/kenakamu/clova-simulator/blob/master/README_JA.md) を参照してください。
![simulator](https://raw.githubusercontent.com/kenakamu/clova-simulator/master/Readme_Images/raw.PNG)

## 機能
- Launch, Intent および SessionEnded リクエストメッセージをサポート。
- セッション情報を自動保存し、サーバーに返す。
- Session Id は自動生成。
## 制限
- SignatureCEK ヘッダーは作成しないため、サーバー側で検証している場合はバイパスが必要。
- Event リクエストメッセージはサポートしていない。
- スロットは 1 つだけサポート。必要に応じて追加。

# 参照
[GitHub: Clova-Simulator](https://github.com/kenakamu/clova-simulator)
[C# で Clova スキルを開発する](https://qiita.com/kenakamu/items/ecb33bacf2d244d9126c)
[ボット開発用 LINE クライアントシミュレーターで開発スピードを上げる](https://qiita.com/kenakamu/items/70555a055bdae99867b5)
Pythonでのファイル読み書きおべんきょう

組み込み屋で、Pythonの勉強をちゃんとやっていなかったので、いちからお勉強。
環境はthinkpad x41 + xubuntu 18.04 + python3.6.5

目標はネットワーク上のログのスクレイピング＆CSV出力→機械学習へのインプットがしたい。

Pythonは超初心者なので、入力をCSVにするサンプルを参考書片手に。。。新人の頃を思い出す。。。

最近の言語はみんなそうだけど、C/C++と比較すると型のうっとおしさがなくて集中できますね。

```file_read.py
import csv

#テスト
def test01():
    #書き込み用途として開く
    with open("answer.csv", "w") as f:
        # CSVファイル書き込み用に
        w = csv.writer(f, delimiter=",")
        
        #CSVの行保存
        rowdata = []

        #文字入力
        while True:
            print("qで抜けるよ")
            s = input("何か書いてちょ。wで一行書き込むよ:")
            if s == "q":
                #ループ抜ける
                break
            if s == "w":
                #CSV一行書き込み、空に
                w.writerow(rowdata)
                rowdata = []
            else:
                #CSVの行データを作成
                rowdata.append(s)
        
        endstr = "終っただよ！"
        #ターミナルに表示
        print(endstr)
        #CSVファイルに最後っ屁書き込み
        f.write(endstr)

#関数実行
test01()

```
Glueの使い方的な㉑(セキュリティ設定 ＆ データカタログ暗号化)

最近ちょっとしたアップデートの紹介記事ばかり書いててよくないなと思いつつ、、書きます><

Glueにセキュリティ関連の設定が"セキュリティ設定"として切り出されました。

<img width="1246" alt="スクリーンショット 0030-08-25 9.57.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/27932/bc87e675-34c6-3b92-8b4e-29784efe63d0.png">

### セキュリティ設定の内容

こんな感じです。Bookmarkも暗号化できるようです。

![スクリーンショット 0030-08-25 10.01.31.png](https://qiita-image-store.s3.amazonaws.com/0/27932/9563585e-8cb5-4b72-4ec2-99b999cfb569.png)

![スクリーンショット 0030-08-25 10.03.48.png](https://qiita-image-store.s3.amazonaws.com/0/27932/4e5197ed-022c-18c3-5f82-a8f1331a9e30.png)

### ジョブやクローラーに適用

#### クローラー作成画面

![スクリーンショット 0030-08-25 10.04.33.png](https://qiita-image-store.s3.amazonaws.com/0/27932/22f75838-b973-f024-e881-b48cbba02c89.png)

#### ジョブ作成画面

![スクリーンショット 0030-08-25 10.05.15.png](https://qiita-image-store.s3.amazonaws.com/0/27932/6c203183-4ee1-d6cc-4c08-0d635ab1bc16.png)

### あと、データカタログの暗号化設定がここに

なぜ"セキュリティ設定"と同じ箇所ではないのか？と思ったけどメタデータの暗号化なのでジョブやクローラーごとの設定ではない為仕方ないですね。

![スクリーンショット 0030-08-25 10.11.31.png](https://qiita-image-store.s3.amazonaws.com/0/27932/da9af627-af4d-c482-56f4-b02a2cb3594f.png)

## まとめ

今は暗号化関連のみの項目ですが、今後さらにセキュリティに関する項目は増えていくかと思います。

## こちらも是非

Glueの使い方まとめ
https://qiita.com/pioho07/items/32f76a16cbf49f9f712f
Franchise で mbtiles を見る

## ベクトルタイルツールチェーンの開発
ベクトルタイルツールチェーンの開発を進めているところ、現在の時点でこういったような要素の組み合わせになっています。赤丸は、まだ開発が到達していないところです。
![](http://g.gravizo.com/g?digraph graphname {
  rp [label="reverse proxy", color=red]
  "Franchise" -> "PostGIS"
  "Franchise" -> "mbtiles"
  "Maputnik" -> "style.json"
  "GeoJSON tile" -> mbtiles
  "Shapefile" -> NDJSON 
  "PostGIS" -> NDJSON
  "NDJSON" -> mbtiles
  mbtiles -> pbf [ label = "tileserver-gl-light" ]
  mbtiles -> pbf [ label = "tile-block" ]
  what3numbers -> mbtiles
  pbf -> "style.json"
  mbtiles -> qmatrix
  "style.json" -> "Mapbox GL JS"
  "style.json" -> OpenLayers
  "style.json" -> rp
  rp -> "ArcGIS API for JavaScript"
})

## Franchise で mbtiles の中身を見る
上の図の一番上にある [Franchise](https://franchise.cloud) は、Node.js で組まれたブラウザベースの SQL ノートブックで、PostGIS データベースの調査をするのに導入して見たのですが、同じツールが SQLite のファイルも触れるので、小規模な mbtiles ファイルの調査にも使えるような気がしました。実際に使ってみると、こんな感じです。この図では、8.6MB 程度の mbtiles ファイルを使っています。9万タイル弱のデータが入っていることが分かりますね。

<img width="896" alt="スクリーンショット 2018-08-24 20.47.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/102082/3f4e2b5a-3fea-eb79-fb3d-edb9b7b94d19.png">

Franchise が Node.js で組まれているので、Franchise にものすごく詳しくなれば、ベクトルタイルの中身をちょっと調べてみるようなところも作れる可能性はゼロではないのだろうな、など思ったりしています。
Excelでエビデンスを取るときに邪魔になるハイパーリンク補正を発生させない

試験結果のエビデンスをExcelで残してね！っていう現場ありますよね。
Excelにログ貼ってると「@」や「html://」を含む行がクリックしたタイミングでハイパーリンク化する機能うざいので、機能を停止する方法を共有します。
機能名は「入力オートフォーマット」なのでしょうか？よくわかりません。

## Excel2008で入力オートフォーマットの変更
1. Excelを起動する
2. 左上のメニューボタンを押下する
3. 「Excelのオプション」ボタンを押下する
4. 「文章校正」タグを選択する
5. 「コートコレクトのオプション」ボタンを押下する
6. 「入力オートフォーマット」タグを選択する
7. 「入力中に自動で変更する項目」→「インターネットとネットワークのアドレスをヘイパーリンクに変更する」のチェックを外す

Excel2013でも似たような感じで行けたと思います。
では、よいエビデンス貼り付けライフを！！
過去に接続したことがあるWi-Fiのパスワードをターミナルで表示させる。

#接続済みのwifiパスワードを忘れた。
先日、自宅に友人がやってきたので、彼のスマホを我が家のwifiに接続してあげようと親機に印字された
wifiパスワードを見ながら入力してあげました。

ただ、この入力の仕方は個人的にイケてなかったのでターミナルでwifiパスワードを表示する方法を
調べました。

##参考
[How to Find the Wi-Fi Password of your Current Network / digital inspiration](https://www.labnol.org/software/find-wi-fi-network-password/28949/)
ここに、各OSの調べ方が書いてあります。
このサイトでは現在接続しているwifiのSSIDの表示方法が記述されています。

以下では、それに補足して過去に接続したことがあるwifiのパスワードを表示させる方法を紹介します。

##Mac OSXのやり方
私のパソコンがMac なので、OSXでのやり方を紹介します。

###1. 過去に接続したWifi SSID を調べる。

```
$ networksetup -listpreferredwirelessnetworks en0
```
をタイプしてください。ここで任意のSSIDをコピーします。あとで使うので。

※もしこんなのが出たら

```
en0 is not a Wi-Fi interface.
** Error: Error obtaining wireless information.
```

以下をタイプして

```
$ networksetup -listallhardwareports
Hardware Port: Wi-Fi
Device: en1
Ethernet Address
```
wifiのDeviceを上記のコマンドのDviceに上書きして書き換えてください。en0のとこですね。

###2. パスワード表示

これをタイプすると（mySSID　を任意のSSIDに置き換えると）UserName と passwordが求められるので
入力すると、WiFiのパスワードがでます。いえい。

```
$ security find-generic-password -wa mySSID
```


###おまけ security ってなに

>[Your Mac OS X uses Keychain to store the configuration details of the WiFi network and we can use the BSD command “security” to query anything stored inside Keychain, including the Wi-Fi password.](https://www.labnol.org/software/find-wi-fi-network-password/28949/)

Keychain から Wifi　パスワードを取り出すためのBSDコマンドのようですね。
Google Compute EngineインスタンスにcPanelを導入する方法（ポイント）

　cPanelは最も多く使われているGUIサーバー管理ツールです。欧米では非常に人気がある唯一無二のサービスなのですが、日本ではあまり多用されていないようです。サービス名称としては「WHM/cPanel」という書き方をしますが、「WHM（Web Host Manager）」はそのサーバーにて運用される個々のホスト達を作成したり設定可能範囲を管理する親ツールです。これに対し、「cPanel」はWHMで管理された個々のホストを管理する子ツールです。すなわち、「WHM」が「ホスティングサービス運営管理者」、「cPanel」が「店子としての各ホストの管理者」という位置付けになります。30日間のお試し期間があり、月額15ドルから（ホストの種類や管理状況により異なる）の費用で使えます。

　cPanelウェブサイト： https://cpanel.com/

　私は理系院卒で学生時代に大学のネットワーク管理者をしていたり、社会人になってもシステム構築やコーディングを一応してきましたが、立ち位置が経営企画・ビジネス設計にシフトしてきている昨今、ターミナルウィンドウでサーバー設定をするのが非常に面倒で効率的に行いたい状況にあります。加えて、ビジネスの拡大縮小に合わせてアプリケーションサーバーのクラスタリング台数を柔軟に変えて運用コストを最適化したいという願いもあり、「GCPでシステムを運用するが、WHM/cPanelを使って構築・管理をしたい」という状況です。

　色々と見ていましたが、あまりGCP（正確にはGCE）にcPanelを導入している事例が多くないようなので、私のような「技術もやる経営者」のために、GCEのインスタンスにcPanelを導入する際のポイントを記載します。

#1. インスタンスを作成する

* OSはRHEL, CentOS, CloudLinuxのいずれかであること
* CentOSの場合、versionは6.5以上であること
* メモリーは3GB以上であること
* HDD/SSDは20GB以上であること
* 何もインストールされていないフレッシュな状態であること
* 外からDNSを引けるようにhostnameが設定されていること

#2. cPanelのインストール

* rootのパスワードを設定する

```shell:command
[root@hostname]$ sudo passwd
```

* root権限を得てyumのアップデートとインストールをする

```shell:command
[root@hostname]# yum update -y
[root@hostname]# yum install -y perl
[root@hostname]# yum install -y wget
```

* Network Managerをdisableもしくはdeleteしておくこと

```shell:command
[root@hostname]# systemctl stop NetworkManager
[root@hostname]# systemctl disable NetworkManager
```

Network ManagerがenabledだとcPanelのインストーラーがインストールを中止しますのであらかじめdisableしておきます。

* ホスト名を設定

```shell:command
[root@hostname]# hostname hogehoge.fugafuga.com
```

* 最新のcPanelを取得してインストール

```shell:command
[root@hostname]# cd /home && curl -o latest -L https://securedownloads.cpanel.net/latest && sh latest
```

#3. インストール後の設定
###3.1. GCPでの設定
* /scripts/configure_firewall_for_cpanel を実行すること

```bash:command
[root@hostname]# /scripts/configure_firewall_for_cpanel
```

* GCPのVPC Network設定でport2087（WHM用）およびport2083（cPanel用）を開けておくこと

![default-allow-cpanel.jpg](https://qiita-image-store.s3.amazonaws.com/0/104422/d6ee15cd-9424-f20e-2fe6-d6148fb7e1dc.jpeg)


###3.2. 管理画面ログイン（WHM）

立てた親ホストのExternal IPが192.168.0.1 だとすると、ブラウザで https://192.168.0.1:2087/ にアクセスすると、下記の画面が開きます。

![2018-11-27_10-49-15.png](https://qiita-image-store.s3.amazonaws.com/0/104422/1a14e9b0-3846-3e0a-cd77-42fc7fd08ad1.png)

* ログインUID/PWDは、立てたホスト（GCEインスタンス）のrootのUID/PWDと同じ

###3.3. 管理画面ログイン（cPanel）

立てた子ホストの登録名が host1.fugafuga.com だとすると、ブラウザで https://host1.fugafuga.com:2083/ にアクセスすると、下記の画面が開きます。

![2018-11-27_10-51-39.png](https://qiita-image-store.s3.amazonaws.com/0/104422/a259351e-1652-6b85-7875-48e4c51f310c.png)

#4. Server Certificate (SSL/TLS)

 WHM/cPanelを導入することによってオトクなのは、運用するホスト（サブドメイン）のサーバー証明書がAutoSSLという機能によって無料で生成されるところです。所有ドメインのサーバ証明書がワイルドカードであればそれで無料ですが、個別にサーバー証明書を有料で発行してもらっている人には嬉しい機能です。

#6. 料金

cPanelは月ごとのサブスクリプション料金を支払う仕組みです。GCEインスタンスはVPSなので 20 USD/Mth で、１年分を払うと 200 USD です。GCPはAmazon AWSよりも割安だったり、細かく設定を行える分、少し敷居が高いように思えますが、cPanelを導入すればサーバー管理もラクラクです。時給換算で毎月１時間の時間の節約ができれば元を取れますのでオススメします（宣伝ではないです）。
Ubuntu18.04をインストールしたとき、まずやること

```bash
# とりあえずアップデート
sudo apt update && sudo apt upgrade

# ドキュメントなどのディレクトリを英語にする
LANG=C xdg-user-dirs-gtk-update

# chromeインスコ
echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" | sudo tee -a /etc/apt/sources.list && wget https://dl.google.com/linux/linux_signing_key.pub && sudo apt-key add linux_signing_key.pub && sudo apt-get update && sudo apt install google-chrome-stable

# いらないパッケージ削除
sudo apt autoremove
```

参考サイト
[aptコマンドチートシート]
(https://qiita.com/SUZUKI_Masaya/items/1fd9489e631c78e5b007)
[Linux Mintのホーム以下のディレクトリ名を英語に変更する方法]
(http://viva-linux.jp/linux-mint-home-english-407)
[Linux Mint 19: インストール後やっておくべき 25 選]
(http://baker-street.jugem.jp/?eid=107)
ReactNative: Firebase + GoogleMapsを使ったアプリ開発でのエラー for Android

以下ReactNativeの開発環境構築中に起こったエラーとその解決方法の一つをメモしておきます。

## 依存
- Firebase: `react-native-firebase`
- GoogleMaps: `react-native-maps`

インストールの手順としては以下

1. `react-native-maps` をインストール & [諸々言われるがままに設定](https://github.com/react-community/react-native-maps/blob/master/docs/installation.md)
2. `react-native-firebase` をインストール
3. `react-native link react-native-firebase` を実行
4. [Firebase公式のAndroidインストール](https://firebase.google.com/docs/android/setup?hl=ja)について参考にAndroidStudioで `android/app/build.grade` と `android/build.gradle` の記述をチェック＆変更
5. Syncする **<= ここでエラー**

## エラー
> The library com.google.android.gms:play-services-base is being requested by various other libraries at [[10.2.4,10.2.4]], but resolves to 15.0.1...

## 解決方法
まず最初にエラーに記載のある `com.google.android.gms:play-services-base` の依存関係でコンフリクトしている部分を直接解決しようと試みました。
とにかく `15.0.1` に統一してほしいようなので以下追記しました。

ちなみに、試しに `android/app/build.gradle` の `implementation project(':react-native-maps')` をコメントアウトしてみるとSyncもBuildも通ったので、おそらくはFirebaseとGoogleMapsのライブラリでコンフリクトを起こしているようです。


### 変更前
```
ext {
    buildToolsVersion = "26.0.3"
    minSdkVersion = 16
    compileSdkVersion = 26
    targetSdkVersion = 26
    supportLibVersion = "26.1.0"
}
```

### 変更後
```
ext {
    buildToolsVersion = "26.0.3"
    minSdkVersion = 16
    compileSdkVersion = 26
    targetSdkVersion = 26
    supportLibVersion = "26.1.0"
    googlePlayServicesVersion = "15.0.1" //<-- here!
}
```

これで解決。

## おまけ
ちなみにこの後も違うエラーが出ました。そちらの方は `google-services.json` のパッケージ名（packagename）とpackage.jsonの名前が異なっていたためのものでしたので、 `google-services.json` の以下の部分を修正しました。

```
"project_info": {
    ...
  },
  "client": [
    {
      "client_info": {
        ...
        "android_client_info": {
          "package_name": "com.hoge_app" //<= here!
        }
      },
...
```
php-master-changes 2018-08-24

最近 Dmitry が元気。
会社の Qiita の organization 見つけたので、混ぜてーと言ったら混ぜてくれた。

# 2018-08-24
## dktapps: mkdist.php: recursively check dll dependencies
- https://github.com/php/php-src/commit/b9bf9ddce6b0813df60b346fca7919735f158cd5
- Windows 用でバイナリ配布物を用意するスクリプトの修正
- PR は[これ](https://github.com/php/php-src/pull/3453)
- intl を入れなくても ICU が無条件で配布物へ含められていたのを、標準の DLL 依存検査処理を再帰的に行うようにすることでその枠内で ICU も取り扱えるようにし、ICU を除外できるようにした
- libenchant や libsasl2 のような一部 DLL は、プラグインとして他の DLL をロードしており、DLL へリンクされているわけではなく、無条件のコピーが必要だった
- ICU もかつては同様だったが、現在は再帰的なリンクチェックで解決できるようになっている

## dstogov: Keep information about unresolved parent class in zend_class_entry->parent_name
- https://github.com/php/php-src/commit/8050f4a334ca43cc95a977413252fa45d3f3bdc3
- クラス定義のコンパイル時、親クラスの名前をクラスエントリへ保存するよう修正

## dstogov: Perform "early-binding" directly during compilation
- https://github.com/php/php-src/commit/b36dbdd1dd431d1a21fdb6f2508c7c41b682466c
- コンパイル時に直接[早期バインド](http://tech.respect-pal.jp/php-helloworld/#zend_declare_function)を行うよう修正
- 元々、zend_compile() より呼ばれる zend_compile_top_stmt() から AST をたどり、関数/クラス定義をコンパイルする際は ZEND_DECLARE_FUNCTION や ZEND_DECLARE_CLASS などのオペコードを生成、その最後に後処理として zend_do_early_binding() でトップレベルのみ関数/クラス定義をバインド（実際に処理系内へスクリプトから利用できる形でクラス定義を構築）するような作りだった
- 今回の修正で、トップレベルのものについては直接関数やクラス定義のコンパイル時にバインドを行うようになった
- これにより、早期バインドの残骸である ZEND_NOP はコンパイル後の op_array に残らなくなった

## dstogov: ZEND_DECLARE_CLASS, ZEND_DECLARE_INHERITED_CLASS and ZEND_DECLARE_INHERITED_CLASS_DELAYED don't need return value anymore.
- https://github.com/php/php-src/commit/6136a20544a3f8a116bb38e404dadd500006b134
- クラス定義系のオペコードで元々定義されたクラスの zend_class_entry を返していたが、不要になったので返さないよう修正された
- いつの何の修正でどうして不要となったのか、そもそも何のために返していたのか、は追えてない
phpのautoloadでclassの読み込みができないとき

#phpのautoloadでclassが読み込めない
新しいプロジェクトにアサインして、環境構築を行っていたとき、以下のようなエラーが出現。
<pre>
Callable Myapp\Controller\Hogehoge does not exist
</pre>
クラスがないというエラーと思いコンソールでもphpを直接実行。
<pre>
PHP Fatal error:  Uncaught Error: Class 'Myapp\Controller\Hogehoge' not found in var/www/html/index.php:4
</pre>
やはりクラスが認識出来ずにエラーになっている。

エラーになっているクラスは、autoloadをcomposerで設定しているためcomposerのアップデートをかける。
<pre>
// composer.json すべてのアップデート
$ composer update
// autoload 関連ファイルの更新のみ
$ composer dumpautoload
</pre>
しかし状況は改善せず・・・

#composerの設定を確認
以下のコマンドでcomposerのロード先フォルダをダンプする。
<pre>
$autoloader = require "vendor/autoload.php";
echo json_encode($autoloader->getPrefixesPsr4(), JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
exit;
</pre>
実行すると以下のような結果となる。
<pre>
{
    "Myapp\\": [
        "/var/www/html/vendor/composer/../../src/myapp"
    ]
}
</pre>
上記が表示されていたら、composerの設定の更新は出来てそうだ。
スペルミス等の凡ミスは要チェック。

composerの設定は出来ていそうなので、autoloader側からクラスを使えるか確認。
<pre>
$autoloader = require "vendor/autoload.php";
$result = $autoloader->findFile('Myapp\Controller\Hogehoge');
echo json_encode($result);
exit;
</pre>
実行結果は<code>false</code> 
本来は以下のような結果で取得できる。
<pre>
\/var\/www\/html\/vendor\/composer\/..\/..\/src\/Myapp\/Controller\/Hogehoge.php"
</pre>

# 最適化をcomposerに行って貰う
ここまで問題を切り分けたが解決できなかった場合は、composerに最適化を行ってもらう。(最終手段)
<pre>
$ composer dump-autoload --optimize
</pre>

とりあえず動作を確認できました。

# 参考サイト！!
<a href='https://nextat.co.jp/staff/archives/183'>Composerのautoloaderの最適化の仕様について - 開発ブログ</a>
<a href='https://akamist.com/blog/archives/6'>[PHP]ComposerでAutoload出来ない時の確認方法 - akamist blog</a>
<a href='https://qiita.com/suin/items/752f3721c4b9084fef4e'>｢Fatal error: Class ‘…’ not found｣に陥ったときのチェック5項目 - Qiita</a>
【Windows】爆速ショートカット　最強のAltキー

どーも。はじめまして。
Windowsをお使いの方向けの記事です。
ちなみに、はじめて投稿します。
qiitaはよく使っているので、今までは読む派でしたが、
これからは、たまーに色んな記事を投稿していけたらと思います。


# Altキーで生産性を上げよう！

Windowsをお使いの方！
Altキーは魔法のキーです。
Altキーがあれば、もう何もいりません。


## どうやって使うのって？


簡単です。
Altキーを押した後に、画面にTooltipで表示されたキーを押してみてください！


## 使用方法
### アプリケーションを閉じる
Alt --> F --> X







以上です。
素晴らしいWindowsライフを！
mavrosのIMUデータをクォータニオンからオイラー角に変換してCSVに出力する


#やりたいこと
pixhawkとKinectV2を積んだロボットで、画像を解析する際に姿勢も知りたい。

##方法
pixhawkから出力されるIMUデータをmavrosを介してサブスクライブしクォータニオンからオイラー角に変換してCSVに出力する。

##なぜわざわざ変換してCSVに出力するのか
rosbagでKinectv2の画像とpixhawkからのIMUデータを記録したのだが、このbagファイルを解析しようとした時に、Kinectとpixhawkが吐くデータの周波数が異なっていたため、一旦CSVに出力してタイムスタンプが近いデータだけ抜き取って扱いたかった。

IMUの姿勢はクォータニオンで表されているので、扱いやすくするためオイラー角に変換したかった。

ubuntuの表計ソフト上（LibreOffice Calc）でクォータニオンからオイラー角に変換するのが面倒だったので、pythonで変換とCSVへの出力を同時に行うROSのノードを書いた訳です。

##準備
※既にmavros環境が整っている前提で進めます。

適当にパッケージを作成します。

```bash:コマンド
cd catkin_ws/src
catkin_create_pkg transform
cd transform/src
mkdir scripts
```
scripts以下にeuler_from_quaternion.pyをおいてやってください。
以下コードです。

```python:euler_from_quaternion.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import rospy
import math
import csv
from sensor_msgs.msg import Imu
from tf.transformations import euler_from_quaternion

header = ["seq", "secs", "nsecs", "roll_rad", "pitch_rad", "yaw_rad"]

def callback(data):
    quaternion = (data.orientation.x, data.orientation.y, data.orientation.z, data.orientation.w)
    seq = data.header.seq
    secs = data.header.stamp.secs
    nsecs = data.header.stamp.nsecs

    euler = euler_from_quaternion(quaternion)
    roll_rad = euler[0]
    pitch_rad = euler[1]
    yaw_rad = euler[2]

    roll =  math.degrees(roll_rad)
    pitch = math.degrees(pitch_rad)
    yaw = math.degrees(yaw_rad)

    rospy.loginfo(rospy.get_caller_id() + "\nqhd_color_time:\nseq: [{}]\nsecs: [{}]\nnsecs: [{}]"
    .format(data.header.seq, data.header.stamp.secs, data.header.stamp.nsecs))

    print "roll: %f" %(roll)
    print "pitch: %f" %(pitch)
    print "yaw: %f" %(yaw)

    body = [seq, secs, nsecs, roll_rad, pitch_rad, yaw_rad]
    f = open('euler.csv', 'a')
    writer = csv.writer(f)
    writer.writerow(body)
    f.close()

def listener():
    rospy.init_node('listener', anonymous=True)
    rospy.Subscriber("/mavros/imu/data", Imu, callback)
    rospy.spin()

if __name__ == '__main__':
    f = open('euler.csv', 'a')
    writer = csv.writer(f)
    writer.writerow(header)
    f.close()
    listener()
```

なんか冗長的ですが多分使えます。print文とかrospy.loginfoの部分は正直いらないです。

権限を与え忘れないように、私は今でも忘れます

```bash:コマンド
chmod +x euler_from_quaternion.py
source ~/.bashrc
```
準備は以上です。

##実際にやってみます
ターミナル3つほど開いて、次の順にコマンドを実行してください。

```bash:コマンド
 roscore
```

```bash:コマンド
 rosrun transform euler_from_quaternion.py
```
```bash:コマンド
 rosbag play -r 30 *.bag
```
rosbagの再生時にオプションとして
-r 30　
をつけているのは30倍速で再生という意味です。ここは任意の数字で構いません。

おそらくホームディレクトリにeuler.csvとかいうファイルができてます。
以上です。
自分のGistを全部別のアカウントに移動

## やりたいこと

* 自分のGistをまとめてダウンロードする
* それらをまとめて別のアカウントにアップロードする

このGist用のコマンドラインツールを使用する。https://github.com/defunkt/gist
インストール方法:

```bash
$ gem install gist  # あるいは `sudo gem install gist`
```

## まとめてダウンロード

まず自分のアカウントにログインする。

```bash
$ gist --login
```

Gistの一覧を出してすべてクローンする。

```bash
$ for url in `gist -l | cut -d " " -f 1`; do git clone $url; done
```

## まとめてアップロード

GistのIDとdescriptionをテキストファイルに書き出しておく。

```bash
$ gist -l | sed 's#https://gist.github.com/##g' > gist-list.txt
```

別アカウントにログインする。

```bash
$ gist --login
```

ここでshellコマンドがわからなくなってpythonに逃げる。

```python
import os
import subprocess

with open('gist-list.txt') as f:
    x = f.read().split('\n')

for line in x:
    if line.strip()=='':
        continue
    line = line.split(' ')
    directory = line[0]
    desc = ' '.join(line[1:]).strip()
    
    files = [os.path.join(directory, f) for f in os.listdir(directory)]
    files = [f for f in files if os.path.isfile(f)]
    
    command = ['gist', '-d', desc] + files
    print(command)
    subprocess.call(command)
```

以上、無事移動できました。

# 後日

たくさん一気に挙げたのが問題だったのか、一時的にGithubアカウントを停止されてしまいました・・・。
seabornでプロットサイズの変更 

タイトルの通り、seabornを使っててプロットサイズを変更したくなった時のためのメモ。
やり方を把握するのに少し戸惑ったので、誰かの役に立てばと思いここにまとめておく。

そういえばQiita初投稿！

自分の環境はこちら:
Windows10
Python 3.6.6
matplotlib 2.2.3
seaborn 0.9.0

以下では、おなじみのやり方でimportしていることにする。

```python
import matplotlib.pyplot as plt
import seaborn as sns
```

# seabornでプロットのサイズを変えるには

最初にまとめておくと、どのplot関数を使うかによって大きく2種類の方法があるみたい。

## 一つ目の方法

ググってみるとmatplotlibを使った下のどれかでできるって説明が多いし、これでだいたい上手くいく。

```python
# その1
plt.figure(figsize=(20, 10))
sns.scatterplot(...) # scatterplotを例に

# その2
plt.rcParams["figure.figsize"] = (20, 10)
sns.scatterplot(...)

# その3
fig, ax = plt.subplots(figsize=(20, 10))
sns.scatterplot(..., ax=ax)
```

ただし、seabornのplot関数によっては上の方法が効かない。例えばsns.lmplotなどがそのような例。
というわけでもう一つのやり方。

## 二つ目の方法

sns.lmplotのサイズ変えられないんだけど！って思いながら検索しているとよい回答があった。

- [stackoverflow: How to change a figure's size in Python Seaborn package
](https://stackoverflow.com/questions/33446029/how-to-change-a-figures-size-in-python-seaborn-package/46346780)

ここの回答にあるようにpairplot、relplot、catplot、lmplot、PairGrid、FacetGridについては次のようにサイズを指定する必要があるらしい。

```python
# その1
sns.lmplot(..., height=10, aspect=2)
# heightで高さを指定して、aspectで縦横の比を指定する
# sns.pairplotなど複数の図がプロットされるやつでは、heightは一つの図の高さ

# 上の回答によると、seabornのバージョン<=0.8.1ならheightじゃなくてsizeらしい
# (バージョンが0.8.1以下の時は自分では試していません)

# その2
g = sns.lmplot(...)
g.fig.set_figheight(10)
g.fig.set_figwidth(20)
```

なんでこんな風に分かれてるのかは、公式ドキュメントとか実装を眺めれば掴めそうだったけどもういいやーってなったので考えるのをやめた。

# まとめ

- 使いたいplot関数によっては、matplotlibを使うのではなくてseaborn側からいじる
プロジェクトごとに異なるバージョンのElmを使い分けるTips

先日 [Elm 0.19 がついにリリース](https://elm-lang.org/blog/small-assets-without-the-headache)されました！
でも、まだ `elm-test` が対応してなかったりして、全てのプロジェクトをいきなり Elm 0.19 にアップデートするっていうわけにはいかないですよね...

そこで、プロジェクトごとにElmのバージョンを切り替える、とってもシンプルなTipsをご紹介します。

## グローバルインストールしない

タイトルのとおりです。以上です。

もうちょっとだけ補足します。
通常は以下のように `-g` オプションをつけてグローバルインストールします。

```bash
# 0.18の場合
$ npm i -g elm@0.18

# 0.19の場合
$ npm i -g elm@0.19.0-bugfix2
```

代わりに以下のように `-g` オプションをつけないでローカルにインストールするだけです。

```bash
# 0.18の場合
$ npm i elm@0.18

# 0.19の場合
$ npm i elm@0.19.0-bugfix2
```

これで、たとえば以下のように `npx` コマンドを使ってそのプロジェクト用の Elm コンパイラを使い分けられます。

```bash
# 0.18の場合
$ npx elm-make --help

# 0.19の場合
$ npx elm --help
```

## 関連コマンドもローカルにインストールする

同じように、[`elm-format`](https://github.com/avh4/elm-format) とか [`elm-analyse`](https://github.com/stil4m/elm-analyse)、[`elm-verify-examples`](https://github.com/stoeffel/elm-verify-examples)、[`elm-test`](https://github.com/elm-community/elm-test)もローカルインストールしてしまいます。

```bash
$ npm i elm-format elm-analyse elm-verify-examples elm-test
$ # Elm 0.19 の場合は `elm-tst@beta` でインストールします。
```

通常、`elm-test` コマンドをグローバルインストールした場合は

```bash
$ elm-test --compiler=$(npm bin)/elm-make
```

のようにローカルインストールした Elm コンパイラの場所を教えてやる必要があります。

`elm-test` などの周辺コマンドもインストールしてしまうことで、`npx` が勝手にローカルの `elm` を実行パスに含めてくれるため、 `--compiler` オプションが不要になります。

```bash
$ npx elm-test
```

## 0.19へのアップグレードもらくらく

ローカル環境に Elm コンパイラや周辺ツールをインストールしておくと、0.19へのアップグレードも簡単に行えます。

まず、`npm-check-updates` コマンドを使えるようにしておきます。
(`npm-check-updates` はグローバルインストールしておきましょう)

```bash
$ npm i -g npm-check-updates
```

このコマンドを使うと、`package.json` で管理されている依存パッケージのバージョンをアップグレードすることができます。

```bash
$ ncu
elm                       ^0.18.0  →  ^0.19.0-bugfix2
elm-analyse               ^0.14.2  →          ^0.15.0
elm-format           ^0.6.1-alpha  →           ^0.8.0
elm-verify-examples        ^2.3.1  →           ^3.0.0
```

`-u` オプションをつけると `package.json` も更新してくれます。
実際にアップグレードしましょう。

```bash
$ ncu -u
$ npm i
$ npm i elm-test@beta
$ # elm-test は beta を指定しないと `elm-test init` などが使えません
```

(もちろん、宗教上の理由で `ncu` を使えない方は手作業で各パッケージのバージョンをアップグレードしても大丈夫です）

あとは `elm-upgrade` もローカルインストールして

```bash
$ npm i elm-upgrade
```

`npx` コマンドで実行するだけです。

```bash
$ npx elm-upgrade
```

もちろん、すでに Elm コンパイラなどもバージョンアップされているので、

```bash
$ npx elm make --output=/dev/null src/Foo.elm
```

みたいにコンパイルして試しながら `elm-upgrade` で対応しきれなかった部分を修正していきます。

[![sakura.jpg](https://qiita-image-store.s3.amazonaws.com/0/16345/a87eeaa3-8d29-fe9e-9cda-5985320626e0.jpeg)](https://twitter.com/hashtag/%E3%81%95%E3%81%8F%E3%82%89%E3%81%A1%E3%82%83%E3%82%93%E6%97%A5%E8%A8%98?src=hash)
[さくらちゃんにご飯をあげる](https://www.amazon.co.jp/gp/registry/wishlist/20ZV2VC57615B/ref=nav_wishlist_lists_1)