OmniAICreator/Qiita-1.07M huggingface dataset:
DockerのOpenCVでHaar-like特徴分類器を使うとき

昨日は @kikuchy の [Diverse Podcastを支える技術](https://qiita.com/kikuchy/items/099c9e7c69dbaad941b4) でした。
社内ドキュメントとしても使えるぐらい丁寧にまとめられた内容でしたね、素敵です！

---

さて、Diverseではマッチングアプリを開発しているのですが、やはり「顔は大事だよね！」という認識を皆持っているかと思います。

顔といえばOpenCVを利用した顔認識技術が最もポピュラーですね。
OpenCVの顔認識といえばHaar-like特徴分類器を利用しますが、今回はOpenCVのHaar-like特徴分類器をDockerから利用する際にほんの少しハマるところの解決法を書いてみました。

---

Dockerに公開されているOpenCVのコンテナ[^1]を利用してHaar-like特徴分類器を使いたいとき、カスケードファイルがどこにあるのか悩みますよね？

Haar-like特徴分類器は、`/haarcascades`というディレクトリの下に入っているので、このディレクトリを探してみます。

```sh
docker run --rm jjanzic/docker-python3-opencv find -type d -name haarcascades
```

```:出力
./usr/local/share/OpenCV/haarcascades
```

どうやら`/usr/local/share/OpenCV/haarcascades`にあるようです。
中を確認してみましょう。

```sh
docker run --rm jjanzic/docker-python3-opencv ls -al /usr/local/share/OpenCV/haarcascades
```

```:出力
drwxr-sr-x 2 root staff    4096 Aug 10 19:45 .
drwxr-sr-x 5 root staff    4096 Aug 10 19:45 ..
-rw-r--r-- 1 root staff  341406 Jul  4 11:05 haarcascade_eye.xml
-rw-r--r-- 1 root staff  601661 Jul  4 11:05 haarcascade_eye_tree_eyeglasses.xml
-rw-r--r-- 1 root staff  411388 Jul  4 11:05 haarcascade_frontalcatface.xml
-rw-r--r-- 1 root staff  382918 Jul  4 11:05 haarcascade_frontalcatface_extended.xml
-rw-r--r-- 1 root staff  676709 Jul  4 11:05 haarcascade_frontalface_alt.xml
-rw-r--r-- 1 root staff  540616 Jul  4 11:05 haarcascade_frontalface_alt2.xml
-rw-r--r-- 1 root staff 2689040 Jul  4 11:05 haarcascade_frontalface_alt_tree.xml
-rw-r--r-- 1 root staff  930127 Jul  4 11:05 haarcascade_frontalface_default.xml
-rw-r--r-- 1 root staff  476827 Jul  4 11:05 haarcascade_fullbody.xml
-rw-r--r-- 1 root staff  195369 Jul  4 11:05 haarcascade_lefteye_2splits.xml
-rw-r--r-- 1 root staff   47775 Jul  4 11:05 haarcascade_licence_plate_rus_16stages.xml
-rw-r--r-- 1 root staff  395322 Jul  4 11:05 haarcascade_lowerbody.xml
-rw-r--r-- 1 root staff  828514 Jul  4 11:05 haarcascade_profileface.xml
-rw-r--r-- 1 root staff  196170 Jul  4 11:05 haarcascade_righteye_2splits.xml
-rw-r--r-- 1 root staff   75482 Jul  4 11:05 haarcascade_russian_plate_number.xml
-rw-r--r-- 1 root staff  188506 Jul  4 11:05 haarcascade_smile.xml
-rw-r--r-- 1 root staff  785819 Jul  4 11:05 haarcascade_upperbody.xml
```

しっかり格納されていました。

ということで、DockerからOpenCVを利用するとき、Haar-like特徴分類器は`/usr/local/share/OpenCV/haarcascades`から利用するといいようです。

---

明日も誰かが何かを書いてくれるはず！。

[^1]: [jjanzic/docker-python3-opencv](https://hub.docker.com/r/jjanzic/docker-python3-opencv/)
Android P のAPI (API Level 28) からテスト系パッケージが削除された

# API Level 28 でのテスト系パッケージへの変更点
API Level 28 ではAPI からテスト系のパッケージが削除されています。
そのため例えば、

```java
import junit.framework.Assert
```
のように JUnit3 のアサートメソッドを使うコードを書いていると、
`compileSdkVersion=28` の環境ではコンパイル出来ません。 
（もちろん、別途 JUnit を依存関係に追加している場合は問題ありません。）

なお、API 変更点の詳細は Android オフィシャルページにて公開されています。
https://developer.android.com/sdk/api_diff/28/changes

「SDK のバージョンを28に上げたら、ビルドできなくなった」
という場合は、本変更が原因かもしれません。
gitで以前commitした時の状態に戻したい時

## git log コマンドでcommit id　を調べる
以前のcommitした状態に戻すには、戻したいcommitのidを調べる必要がある。

```
git log
```

commit id　をコピー。


## git reset --hard [commit id]
以下のコマンドを実行。[commit id]は先ほどコピーしたものをペースト。

```
git reset --hard [commit id]
```

ローカルファイルの状態が、選んだcommitの状態に戻っているはず。
8946 Take#38

#問題

http://www.hackerschool.jp/hack/take38.php

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/bcb03d10-181a-f51d-5c6d-d6181d2f78a5.png)

#解いてみた

- 答えが書いてあるのでそのまま入力してみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/01897d39-040d-9b5b-395b-7dbc990abd35.png)

- さすがにダメですね。
- URL直接入力してみてはどうでしょう。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/c38e35ba-944b-04a0-b2d6-f9195d92bc06.png)

- これもダメでした。
- ソースを見てみましょう。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/20895844-92c2-5d8a-9b54-6e050de60042.png)

- ボタンを押したときにtake38_LoadFile()が呼ばれますが、ソースには定義されていません。
- ajax_take38.jsを見てみましょう。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/b0eefd0d-0701-c50b-6c2a-0ee08cfaa471.png)

- ここに定義されていました。
- 中の処理を要約すると入力欄に入力したページにアクセスして、その戻り値を表示する。なかったら、エラーを表示する。といったところでしょうか。
- ということで、ここではあまり参考になりません。
- wiresharkを使って通信を見てみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/b1c31483-07ea-2938-a2cc-114fad05a92f.png)

- 入力したURLにアクセスするわけではなくて、入力した文字はパラメータで送られるようです。
- が、それ以上参考になることはなさそうです。
- いろいろネットで調べた結果、PHPにファイル名をパラメータで送るときにヌルバイト攻撃っていうのに気を付けましょう。というのをいくつか見つけました。
- やってみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/90d3e306-495e-5471-1330-ab085fa6e97b.png)

- やりました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/837abc99-adec-e059-c97d-c348faa8cd94.png)

- 結局渡した引数がどのように使用されているのかはよくわかりませんでしたが、一応解けてよかった。
Pipenvとtoxを組み合わせて、ライブラリのユニットテストを記述する

この記事は[LIFULLその2 Advent Calendar 2018](https://qiita.com/advent-calendar/2018/lifull2)の1日目の記事です。

普段からPipenvを使ってPythonでアプリケーション開発をしているのですが、Pythonパッケージを社内用に提供する必要があり、その際に以下のような疑問が生まれていました。

* Pipenvはバージョン固定するためのツールで、テストは複数のPythonバージョンで行いたい
* 依存ライブラリの記述にsetup.pyとPipfileって結局どう使い分ければいいの？開発時だけに必要なライブラリもPipenv（Pipfile）で記述したいんだけど…

結論からいうと、[公式ドキュメントで紹介されている手順](https://pipenv-ja.readthedocs.io/ja/translate-ja/advanced.html#tox-automation-project)に従って、以下のように行うと良いようです。

* 開発用ライブラリはPipenvを使って管理しよう
* toxを使って複数バージョンのテストを管理しよう(また、もう一つ紹介されているTravis CIも紹介されています)

## 実際にプロジェクトを作ってテストする

実際に、Python2.7とPython3.6でテストしてみました。この2バージョンを利用したのは、私の環境で既に動いているからで、実際には複数バージョンのインストールと指定が必要です。

また、今回使用したコードは以下に置いてあります。

https://github.com/takeshi0406/tox-sample

[この前の記事](https://qiita.com/ninomiyt/items/8db897c42c551e926c0f)は"test"以下にテストコードを置きましたが、今回はpipenvのドキュメントに合わせて"tests"の下に置きました。Pythonではプロジェクトの標準的なディレクトリ構成が厳密には決められていないようです。


```bash
$ tree
.
├── MANIFEST
├── Pipfile
├── Pipfile.lock
├── README.md
├── setup.py
├── src
│   ├── __init__.py
│   └── script.py
├── tests
│   ├── __init__.py
│   └── test_script.py
└── tox.ini
```

toxは、実際にそれぞれのバージョンで仮想環境を作って、その中でpytestのコードを実行してくれます。

```python:setup.py
# !/usr/bin/env python

from distutils.core import setup


setup(name='sample',
      version='0.1',
      description='sample',
      author='sample',
      author_email='sample@sample.sample',
      url='',
      packages=['src'],
      )
```

.tox以下のディレクトリに大量のライブラリができるので、テスト実行前に```.gitignore```には.toxを記述しておきましょう。VS Codeのgit機能が悲鳴を挙げてました。

tox.iniは[pipenvの公式](https://pipenv-ja.readthedocs.io/ja/translate-ja/advanced.html#tox-automation-project)のサンプルを元に記述しています。ついでにflake8で規約チェックもします。

```ini
[tox]
envlist = flake8-py3, py27, py36

[testenv]
deps = pipenv
commands=
    pipenv install --dev
    pipenv run py.test tests

[testenv:flake8-py3]
basepython = python3.6
commands =
    pipenv install --dev
    pipenv run flake8 --version
    pipenv run flake8 setup.py docs project test
```

これでtoxコマンドでテストを実行することができます。

```bash
$ tox
（中略）
_______________________________________________________________________ summary _______________________________________________________________________
  flake8-py3: commands succeeded
  py27: commands succeeded
  py36: commands succeeded
  congratulations :)
```

## まとめ

今後は、以下のようにPythonによる開発とユニットテストを行っていこうと思います。

* アプリケーション開発ではpipenvで管理して、一つのPythonバージョンでテストを実行
* ライブラリ開発では更にtoxを利用して複数バージョンのテストを回す

今回の例では存在しないのですが、実際にライブラリの開発では依存ライブラリをsetup.pyとPipfileの両方に記述することになります。今後、より良いライブラリの依存関係の管理方法が現れることを期待したいです。

## 参考記事

**Pipenv公式ドキュメント Pipfile vs setup.py**

https://pipenv.readthedocs.io/en/latest/advanced/#pipfile-vs-setup-py

※日本語訳

https://pipenv-ja.readthedocs.io/ja/translate-ja/advanced.html#pipfile-vs-setup-py


**PipenvでPythonの依存関係の管理は楽になったか？**

https://techblog.zozo.com/entry/pipenv-make-it-easy-to-manage-dependencies-in-python
AutoHotkey で MacBook Pro ライクなキーバインドにする

ウィンドウズで MacBook みたいなきーばいどにしたくて AutoHotkey のマクロ書きました。

スペースキーの左右にある [無変換] [変換] を [英数] [かな] にして
Emacs ライクなキーバインド (Macな感じ) に変更します。

is_disable() に追加されたアプリケーションは対象外になります。
わたしのばあい Blender はもともとのキーバインドで使いたいので無効にしています。

みなさん　おたのしんでね！

AutoHotkey はこちらから
https://www.autohotkey.com/


```[like_jpmac.ask]
﻿#InstallKeybdHook
#UseHook

ime_set(SetSts, WinTitle="A")
{

    ControlGet,hwnd,HWND,,,%WinTitle%
    if(WinActive(WinTitle))
    {
        ptrSize := !A_PtrSize ? 4 : A_PtrSize
        VarSetCapacity(stGTI, cbSize:=4+4+(PtrSize*6)+16, 0)
        NumPut(cbSize, stGTI,  0, "UInt")   ;    DWORD   cbSize;
        hwnd := DllCall("GetGUIThreadInfo", Uint,0, Uint,&stGTI)
                 ? NumGet(stGTI,8+PtrSize,"UInt") : hwnd
    }

    return DllCall("SendMessage"
          , UInt, DllCall("imm32\ImmGetDefaultIMEWnd", Uint,hwnd)
          , UInt, 0x0283  ;Message : WM_IME_CONTROL
          ,  Int, 0x006   ;wParam  : IMC_SETOPENSTATUS
          ,  Int, SetSts) ;lParam  : 0 or 1

}

is_disable()
{
    ;vim
    if WInActive("ahk_class Vim")
    {
        return 1
    }

    ;tera term
    if WInActive("ahk_class VTWin32")
    {
        return 1
    }

    ;blender
    if WInActive("ahk_exe blender.exe")
    {
        return 1
    }

    return 0
}

send_key(original_key,replace_key)
{
    if(is_disable() == 1)
    {
        Send,%original_key%

        return
    }
    else if(is_disable() == 2)
    {

        Send,%replace_key%

        return

    }
    Send,%replace_key%

    return
}

;<^a::send_key("^a","{Home}")
;<^+a::send_key("^+a","+{Home}")
;<^e::send_key("^e","{End}")
;<^+e::send_key("^+e","+{End}")
;<^d::send_key("^d","{Del}")
;<^+d::send_key("^+d","+{Del}")
;<^k::send_key("^k","+{End}{Del}")

<MButton::send_key("MButton","+{Alt}{Ctrl}")


vk1Dsc07B::ime_set(0)
vk1Csc079::ime_set(1)
```
OpenShiftのコンテナセキュリティ

# 対象読者

この記事はOpenShiftやPodといった用語を理解できている方向けに書いています。

# SCCとは？

SCC(Security Context Constraints)とはPodのパーミッションを制御する機能です。
OpenShiftのデフォルト状態では`restricted`というSCCが設定されています。

SCCはPodに対して付与するロールです。  
どのSCCが付与されるか、はユーザーやグループに設定することができ、Podを起動したユーザー、もしくはグループに設定されているSCCを適用します。

# デフォルトSCC

デフォルトでは以下のようなSCCが設定されています。

```bash
$ oc get scc

NAME               PRIV      CAPS      SELINUX     RUNASUSER          FSGROUP     SUPGROUP    PRIORITY   READONLYROOTFS   VOLUMES
anyuid             false     []        MustRunAs   RunAsAny           RunAsAny    RunAsAny    10         false            [configMap downwardAPI emptyDir persistentVolumeClaim secret]
hostaccess         false     []        MustRunAs   MustRunAsRange     MustRunAs   RunAsAny    <none>     false            [configMap downwardAPI emptyDir hostPath persistentVolumeClaim secret]
hostmount-anyuid   false     []        MustRunAs   RunAsAny           RunAsAny    RunAsAny    <none>     false            [configMap downwardAPI emptyDir hostPath nfs persistentVolumeClaim secret]
hostnetwork        false     []        MustRunAs   MustRunAsRange     MustRunAs   MustRunAs   <none>     false            [configMap downwardAPI emptyDir persistentVolumeClaim secret]
nonroot            false     []        MustRunAs   MustRunAsNonRoot   RunAsAny    RunAsAny    <none>     false            [configMap downwardAPI emptyDir persistentVolumeClaim secret]
privileged         true      [*]       RunAsAny    RunAsAny           RunAsAny    RunAsAny    <none>     false            [*]
restricted         false     []        MustRunAs   MustRunAsRange     MustRunAs   RunAsAny    <none>     false            [configMap downwardAPI emptyDir persistentVolumeClaim secret]
```

デフォルトSCCは変更すべきではないと公式ドキュメントには記載されています。
もし変更してしまうとインプレイスアップグレードの時等に問題になる可能性があるそうです。

# SCCの簡単な見方

`RUNASUSER`カラムだけ抜粋します。

`restricted`SCCでは`MustRunAsRange`が設定されています。これはある一定の数値範囲の中にUIDが自動設定されるような動きになります。Rootグループで実行されるのでコンテナ内で権限設定する場合はグループに権限を付与しておく必要があります。

`nonroot`SCCに設定されている`MustRunAsNonRoot`というのはRoot以外であれば何のユーザーで実行してもよいという意味になります。  
ただし、ユーザー指定は1000等UID指定でなければなりません。  
ユーザー指定はDockerfileのUSERを設定するか、DeploymentConfigやStatefulSetのyamlにて`runAsUser: 1000`等と設定します。

`anyuid`に設定されている`RunAsAny`はrootも含めて「どのユーザーでも良い」を意味します。

# デフォルト状態で`restricted`が付与される仕組み

OpenShiftにログインする全てのユーザーは`system:authenticated`という特殊なシステムグループに所属します。OpenShiftではデフォルト状態で`system:authenticated`グループに`restricted`SCCが付与されています。

もしログインしたすべてのユーザーがPodを起動するときに`nonroot`SCCを使用したい場合は`system:authenticated`グループに`nonroot`SCCを追加します。

```bash
$ oc adm add-scc-to-group nonroot system:authenticated
```

# 特例として一部のPodがanyuidで動作するようにしたい

SCCは当然サービスアカウントにも追加できます。

```bash
$ oc adm add-scc-to-user anyuid -z default
```

logging機能のためのElasticSearchやモニタリングのためのPrometheusはRootユーザーで動作します。であるにも関わらずデフォルトSCCを変更してしまった場合、これらのPodが動作しなくなります。よってそれらのPodには適用されているサービスアカウントに`anyuid`SCCを付与してRoot起動を許可します。

# 参考履歴

[公式ドキュメント(3.9)](https://access.redhat.com/documentation/ja-jp/openshift_container_platform/3.9/html/cluster_administration/admin-guide-manage-scc)
[nekop's blog](https://nekop.hatenablog.com/?page=1513919840)
Microsoft Flowの私的逆引きリファレンス

# はじめに

Microsoft Flowの事例が少なく、公式ドキュメントに記載されていないことが多いため、過去に調べたことを逆引きリファレンスとしてまとめます。

# リファレンス

## 配列を絞り込む

［アクション - データ処理 - 配列のフィルター処理］を使用します。

出力される値は配列形式です。

## 配列から最初の要素を取得する

ここでは以下の流れで説明します。

1. 変数を作成する
1. 1の変数に配列の最初の要素を設定する

まず、［アクション - 変数 - 変数を初期化する］を選択し、1の変数を作成します。

次に、［アクション - 変数 - 変数の設定］を選択します。変数には1の変数、値には`first(collection: array|string)`の関数を設定します。`collection`に配列を設定すれば、最初の要素を1の変数へ設定できます。

## 繰り返し処理を抜ける

繰り返し処理を抜けるためのアクションは存在しません。また、処理内では終了アクションを設定することもできません。

この場合には、Do Untilアクションを用いて、指定の条件の場合に抜けるようにします。

# 参考

- [データ操作を理解する | Microsoft Docs](https://docs.microsoft.com/ja-jp/flow/data-operations#use-the-filter-array-action)
- [Solved: How to filter the array to get single item ? - Power platform Community](https://powerusers.microsoft.com/t5/General-Flow-Discussion/How-to-filter-the-array-to-get-single-item/td-p/14981)
- [How do I break a for-each loop? - Power platform Community](https://powerusers.microsoft.com/t5/Building-Flows/How-do-I-break-a-for-each-loop/td-p/16011)
jsdoでchip8　その11


#概要

jsdoでchip8やってみた。
アセンブラ練習問題、解いてみた。
お題は、hello world

#写真

![image](https://qiita-image-store.s3.amazonaws.com/0/18104/11e93d1e-9cc4-f7ca-0451-49f89c151edf.png)


#フォントを作る。


```

1001 0x90 144
1001 0x90 144
1111 0xf0 240
1001 0x90 144
1001 0x90 144

1111 0xf0 240
1000 0x80 128
1111 0xf0 240
1000 0x80 128
1111 0xf0 240

1000 0x80 128
1000 0x80 128
1000 0x80 128
1000 0x80 128
1111 0xf0 240

1000 0x80 128
1000 0x80 128
1000 0x80 128
1000 0x80 128
1111 0xf0 240

1111 0xF0 240
1001 0x90 144
1001 0x90 144
1001 0x90 144
1111 0xF0 240

0000 0x00 0
0000 0x00 0
0000 0x00 0
0000 0x00 0
0000 0x00 0

1001 0x90 144
1001 0x90 144
0000 0x00 0
0110 0x60 96
0110 0x60 96

1111 0xf0 240
1001 0x90 144
1001 0x90 144
1001 0x90 144
1111 0xF0 240

1111 0xf0 240
1001 0x90 144
1110 0xE0 224
1001 0x90 144
1001 0x90 144

1000 0x80 128
1000 0x80 128
1000 0x80 128
1000 0x80 128
1111 0xf0 240

1110 0xE0 224
1001 0x90 144
1001 0x90 144
1001 0x90 144
1110 0xE0 224

```

#解答例


```
  load  v3  5
  load  v4  5
  load  v5  5
  load  v6  10
  load  v7  1
  load  v8  6  
  load  I  540
loop2  disp  v3  v4  5
  add  v3  v5
  sub  v6  v8
  add  I  v5
  eq  v6  0
  goto  loop2
loop  goto  loop
msg  data  144
  data  144
  data  240
  data  144
  data  144
  data  240
  data  128
  data  240
  data  128
  data  240
  data  128
  data  128
  data  128
  data  128
  data  240
  data  128
  data  128
  data  128
  data  128
  data  240
  data  0
  data  240
  data  144
  data  144
  data  240
  data  0
  data  0
  data  0
  data  0
  data  0
  data  144
  data  144
  data  0
  data  96
  data  96
  data  0
  data  240
  data  144
  data  144
  data  240
  data  240
  data  144
  data  224
  data  144
  data  144
  data  128
  data  128
  data  128
  data  128
  data  240
  data  224
  data  144
  data  144
  data  144
  data  224
```

#成果物

http://jsdo.it/ohisama1/MV2j/

以上。
Macで音楽CDイメージ(bin+cue)をwavに抽出する(Mojave)

昔に音楽CDをイメージ化して保存していた。
それをマウントさせて中身を見れるようにしたいと思ったが、コケたのでメモ。

## 結論
マウントさせるのはうまくいかなかったので、wavファイルで抽出することで解決。
`bchunk`のマニュアル見たらちゃんと書いてあった。
ISOで書き出すのではなく`-w`オプションでwavファイルを抽出できる。

## やったこと
調べてたら`bchunk`を使って、ISO形式ではないイメージファイルをISO形式にできる事が分かった。

##### インストール
homebrewにて。
`$ brew install bchunk`

##### 実行（失敗）
`$ cd <directory>`
`$ bchunk ./Disc1.bin ./Disc1.cue Disc1`
とすると、`.cdr`ファイルで書き出されて拡張子をwavに変えてもダメだった。

マニュアルをちゃんと読んで、`-w`でwavで抽出できることが判明。
##### 実行（成功）
`$ bchunk -w ./Disc1.bin ./Disc1.cue Disc1`
見事、wavファイルが書き出されました。
Blinkと<blink>

HTML 4.01が出る前には、HTMLには独自要素が満ち満ちている状態でした。今回はその1つである、`<blink>`要素について取り上げてみます。

## まずは紹介から

知らない人もいるかと思いますので一応紹介しておきますと、`<blink>`は中身のテキストを点滅させるための要素です。

### 成立の経緯

[関係者が書いたもの](http://www.montulli.org/theoriginofthe%3Cblink%3Etag)が転がっていたのですが、発祥としては「Lynx（テキストブラウザ）でも使えるような装飾として、点滅はどうだろう」と言い出した飲みの席での会話で、それを聞いた誰かが一晩でやってしまった、とのことです。当の本人曰く、`<blink>`が溢れまわるのは全く想定外だった、とのことです。

## 廃止の経緯

ポケモンショックを例に引くまでもありませんが、点滅したものは目に付きすぎるなどUX的にもうれしいものではなく、FirefoxとOperaだけに実装されていました。

そして時は2013年、GoogleとAppleが呉越同舟で開発していたWebKitから、Googleがフォークすることを宣言したのですが、その背後でOperaも独自エンジンを放棄してWebKit系への合流を行うこととなりました。

結果、`<blink>`をサポートしているブラウザがFirefoxだけになってしまうこと、さらにCSS3のAnimationを使えば再現できることもあって、`<blink>`はFirefoxでも[廃止されました](https://hyper-text.org/archives/2013/04/goodbye_blink.shtml)。

事態が落ち着いてみれば、ChromeとOperaが使うエンジンがBlinkという名前となっていたのも、運命の皮肉かもしれません。
PHPでOCR（Google Cloud Vision APIを使って）

画像から文字列を読み取る、OCRの処理をアプリに実装させたいというニーズは、よくあるでしょうが、割と手っ取り早いのはGoogleのCloud Vision APIを使うやり方かな、と思います。
PHPでの例を紹介します。
# Cloud Vision APIとは？　使うには？　注意事項は？
こちらに大変よくまとめてくださっているので、ご覧ください。
Cloud Vision APIをPHPから使ってみた。その① | TECH Projin
https://tech.pjin.jp/blog/2017/07/31/cloud-vision-api-from-php-1/
# PHPでcURLを使えるようにする
環境によって様々のようなので、ここでは詳細は割愛。
Ubuntu 16.04の場合、
`$ sudo apt-get update`
`$ sudo apt-get install php-curl`
のみでOKでした。
# PHPでの実装
こちらから大部分を借用させていただきました。

コピペで動くGoogle Cloud Vision API！！サンプルコード有！ | ただの備忘録ブログですよ
http://bibouroku.blog/2018/01/04/api_google_cloud_vision_api/

```php:ocr.php
<?PHP

// APIキー
$api_key = "あなたのAPIキーを入力ください。" ;

//画像のPATHを入力してください（URLでいいですよ）
$image_path = "画像のURL";

// リクエスト用のJSONを作成
$json = json_encode( array(
        "requests" => array(
                array(
                        "image" => array(
                                "content" => base64_encode( file_get_contents( $image_path ) ) ,
                        ) ,
                        "features" => array(
                                array(
                                        "type" => "TEXT_DETECTION" ,
                                        "maxResults" => 10 ,
                                ) ,
                        ) ,
                ) ,
        ) ,
) ) ;

// リクエストを実行
$curl = curl_init() ;
curl_setopt( $curl, CURLOPT_URL, "https://vision.googleapis.com/v1/images:annotate?key=" . $api_key ) ;
curl_setopt( $curl, CURLOPT_HEADER, true ) ;
curl_setopt( $curl, CURLOPT_CUSTOMREQUEST, "POST" ) ;
curl_setopt( $curl, CURLOPT_HTTPHEADER, array( "Content-Type: application/json" ) ) ;
curl_setopt( $curl, CURLOPT_SSL_VERIFYPEER, false ) ;
curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true ) ;
if( isset($referer) && !empty($referer) ) curl_setopt( $curl, CURLOPT_REFERER, $referer ) ;
curl_setopt( $curl, CURLOPT_TIMEOUT, 15 ) ;
curl_setopt( $curl, CURLOPT_POSTFIELDS, $json ) ;
$res1 = curl_exec( $curl ) ;
$res2 = curl_getinfo( $curl ) ;
curl_close( $curl ) ;

// 取得したデータ
$json = substr( $res1, $res2["header_size"] ) ;
$array_json=json_decode($json, true);

$text=$array_json["responses"]["0"]["textAnnotations"]["0"]["description"];

echo $text;
?>
```
# 実行
`php -f ocr.php`
さすがはGoogle、という精度。
# 注意点
生のAPIキーを記述したソースコードを、リモートリポジトリに直接pushしないように！
特にGitHubの公開リポジトリに上げてしまったりしようものなら、途端にAPIキーを不正利用される危険があります。

例えばPythonの場合、dotenv等を使って、APIキーを環境変数に持たせて、実際にAPIを叩くコードでは、環境変数からAPIキーの値を取得するようにするやり方があります。
PHPは不勉強にして事情を存じ上げないのですが、たぶん同じようなことができると思います。
# 他のやり方
Googleに限らず、APIを利用する場合は課金が発生したり、仕様が変わったり、サービスが終了したりする可能性があります。
（Clould Vision APIの利用料金は、2018年12月現在、月あたり1,000ユニットまでであれば無料のようですが）
他のやり方としては、Tesseract OCRというオープンソースのOCRライブラリがあるそうですが、未確認です。
micro:bitとWeb Bluetoothをパスキー有りのペアリングで接続する

# はじめに

　micro:bitとWeb Bluetoothの接続については、以下のQiitaの記事を参考にしてください。

[micro:bitとWebBluetoothで通信してみました - Qiita](https://qiita.com/yokmama/items/5522fabfb5b9623278e2)

　ここでは、パスキー有りのペアリングで安全に接続する方法を説明します。

# 手順

　まずは、micro:bitを準備します。プロジェクトの設定で「Passkey paring: Pairing requires 6 digit key to pair.」を選択し保存します。

　次に、micro:bitと端末によるBluetooth接続を行います。今回は検証用として端末としてMacを利用しています。この接続の方法については、以下のサイトを参考にしてください。

[micro:bitとmacのBLE接続について（備忘） | micro:bit | kosakalab](https://make.kosakalab.com/microbit/microbit_mac_ble/)

　接続の際にはパスキーが求められます。micro:bitのAボタンを押下することで、6桁のパスキーが次々に表示されます。この数字を入力してください。警告メッセージが表示されず、Bluethoothが接続済みであることが確認できれば成功です。なお、Bluetooth接続は都度ブラウザーから行う必要があるので、成功を確認できたらいったん切断してください。

　最後に、ブラウザーからBluetooth接続ができるかどうか確認してください。警告メッセージが表示されず、Web Bluetoothが正しく動作すれば成功です。警告メッセージが表示されたら、端末側の接続を切断してからもう一度試してください。
はじめよう Galaxy！（2018年版）

今年も Galaxy Advent Calendar 2018 が始まりました。今年のカレンダーへの期待は、昨年よりも内容が整理されて見やすい ＋ 今年のアップデートが盛りだくさん ＋ 個々のネタが少しだけ深くなる、といったところでしょうか。楽しみです。

* 昨年のカレンダーは[こちら](https://qiita.com/advent-calendar/2017/galaxy)

それでは**「Galaxy」とは何か** から話します。スマホではありません。スマホより昔からあります。

データを分析するとき、多くの人は 3つの選択肢を考えます。Excel を使うか、プログラムを書くか、誰かにやってもらうかです。でも、最近多いのは「Excel にはデータが大きすぎるけど、プログラムは書きたくない、そもそも書けない、誰も書いてくれない」という状況です。

そこで登場するのが **データ分析プラットフォーム「Galaxy」** です。

Galaxy は誰でもウェブ上で使えて、サイズの大きなデータを他のユーザーとシェアできて、いろいろなデータ分析のツールを実行することができます。GUI なのでプログラムが書けなくても使えます。下図のようなイメージです。

<img width="663" alt="スクリーンショット 2017-11-30 21.21.05.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/191970/8a6c14b0-c41b-05ba-b72b-d66f08810a1c.jpeg">

これらの分析ツールには、例えば「CSV ファイルを 1つ目のカラムでソートする（= sort コマンド）」といったシンプルなものから、R のパッケージまでいろいろあります。Galaxy はそういったコマンドを GUI で実行できるウェブ上のプラットフォームというわけです。

[https://usegalaxy.org/](https://usegalaxy.org/) からアクセスしてください。実際には、次のような画面で操作します。

![スクリーンショット 2017-11-30 20.55.07.jpg](https://qiita-image-store.s3.amazonaws.com/0/191970/f2d6f83f-fea4-7561-6044-58aefaf3365f.jpeg)

左に並んでいるのがツールたち。真ん中のパネルでツールを操作すると、、、右側に結果が出てきます。簡単ですね！

初心者向けに書かれた昨年の記事をここにまとめておきます。この順番で試してみるのがおすすめです。

* [Galaxyでファイルをアップロードしてみよう](https://qiita.com/percipere/items/8c4a04f4209394c5fee5)
* [Galaxyでファイルをダウンロードしてみよう](https://qiita.com/percipere/items/af59c7559c44141828d1)
* [Galaxyでカンマ区切りをタブ区切りに変換してみよう](https://qiita.com/percipere/items/a34b2797b72f67ffcab8)
* [他のユーザーとデータを共有してみよう](https://qiita.com/oraryotas/items/a0b8e527c60844c76d56)

それでは今年の Galaxy Advent Calendar のはじまりはじまり :grinning:
Rでデータ設定と出力、関数での操作まとめ

# はじめに
エンジニア？アナリスト？サイエンティスト？歴5ヶ月めの新卒社員が最近学んだことをちょっとずつまとめてみたもの。気づいたら最近Advent Calendarに向けて何も準備していない！！となって相当焦りました。思い立つのも早いのですが、飽きたり挫折したりするのもいかんせん早いもので、そんな性分を少しずつ治したいなぁなんて思う今日この頃です。

これまでに書いた記事の最新3回分はこちら↓
[第6弾](https://qiita.com/icchy_sh33p/items/03e09a14f0c0bad9c823)
[第7弾](https://qiita.com/icchy_sh33p/items/7454f6e062c03489eca2)
[第8弾](https://qiita.com/icchy_sh33p/items/82f2bc7d789b74110f7b)

今日は初のRについてです！！

# 変数の設定の仕方

> 変数名 <- 数値

## 変数を設定するときの注意
- 変数名は数字から始めてはいけない
- 数値については、ひとつでも複数でもよい
- 数値が連続しているものについては以下のいずれかに右辺を入力
    
```
seq(a, b)　または　a : b　
```
- 数値を倍数ごとで取得する場合は、以下のように右辺を入力することで、fの倍数ごとになる

```
(a : b) * f
```

- 反対にfの倍数をのぞいた状態で取得したい場合は、以下のように右辺を入力

```
seq(a, b, by = f)
```
- 規則性のないものについては、以下のように入力

```
c(a, b, e) 
※頭文字のcは、combine（結合する）のc。
```

## ベクトル
- ベクトル・・・変数において、複数の数値をひとつのデータとしてまとめたもの

# データフレーム
- データフレーム・・・表に近い形でデータをまとめたもの

## データフレームの作り方
- データフレームの作り方→data.frame関数を使用

  ```
 (フレーム名 <- data.frame(カラム名1 = ベクトル名1, カラム名2　= ベクトル名2, ・・・　, カラム名n = ベクトル名n))
  ```

   以上により、カラムの中身を入れたいベクトルの要素にしたデータフレームが作成可能

## 添字
- 添字・・・データの順番をあらわす概念
- データフレームから特定のデータを指定したいときに使用
- 指定したデータの取り出し方

```
フレーム名 $ 取り出したいカラム名　[ n（取り出したいデータが何番目のものか） ]
```

- カラム名を指定せず、nのみを指定→n行目の全カラムが抽出
- nを指定せず、カラム名のみを指定→すべての行の該当カラムのデータが抽出
- 指定したデータの置換（更新）方法

```
フレーム名 [ n（置換したいデータが何番目のものか） ] <- 置換するデータ（数値、名前など）
フレーム名　#データフレームの置換したところが正しく変わっているか確認
```

# 関数
## 引数
- 引数・・・分析や計算の際に関数で指定するデータ（要素）

## 関数の書き方
```
関数名(引数)
```

# 感想
久しぶりにRを触るってなって、正直最後に触ったのが自分の卒論のときに2要因分散分析（データ分析についてもまた改めてまとめたい）をするってなったとき以来だったっていうのもあってかなり知識が抜けているなぁって再認識しました。少しずつ、練習がてら使わないと。

最近、基本的なことをまとめることが多くなってきていますが、まぁこれも頑張っているんだなぁ、いっちーと暖かい目で見守っていただけると幸いです

ではでは^^
AWS re:Invent 2018でGameDayに参加した話

こんにちは、 @mshibuya です。
このたび、[オプトテクノロジーズ](https://opt-technologies.jp/)初めての海外研修として、先日ラスベガスで開催されたAWS re:Invent 2018に総勢5名で参加してきました。イベント全体は非常に規模が大きく、あらゆる面でよい刺激を受けることができたのですが、中でも自分にとって最も印象的なものとなったハッカソンイベント「AWS GameDay: 2018 Edition 1」について振り返りたいと思います！

なおこの記事は[オプトテクノロジーズアドベントカレンダー](https://qiita.com/advent-calendar/2018/opt-technologies)2日目のエントリーです。

# GameDayとは
AWSの各サービスを題材に、実際にシステムを動かし問題を解決することを通してサービスに親しんでもらう…という趣旨のチーム対抗ハッカソン形式のイベントです。オフィシャルな説明はこちら。
https://aws.amazon.com/jp/gameday/

# やったこと
上記の通りチーム単位で争うわけですが、事前にチームを作って参加することも、その場で支援を受けつつ同様の方々とチームを組むこともできます。自分としてはせっかく参加する以上は、英語の壁は大きいものの絶対現地のエンジニアと組んでやってみたい！と強く思っていたので、単独で向かってチームとなることにしました。結果集まったのは

- アーキテクトの方（大変AWSに強く、チームの成果の大半はこの方のおかげかも）
- セキュリティ関係の方（お仕事関係の連絡を途中でしていて大変そうでした）
- 写真共有サービスを開発している方（日本の方で、最悪日本語でも話せたりして心強かった）
- 自分

といった形で、こういう機会でもなければまったく会うことのないような方々と一緒のチームで戦うことができました。

今回の題材はマイクロサービスということでいくつかのサービスを立ち上げ、それをいかに試練を乗り越え動かし続けるか…というミッションが課せられました。
それぞれ、多様なAWSサービスから構成されていて、それらの前提知識があるとより有利になる形です。

ルールの作りが絶妙で、自チームのみでは完結できないよううまく構成されており、よりゲーム性が高められていました。

今回4時間のイベント枠のなかで、まずはサービスの立ち上げから始まるわけですが一度上げてしまえばそのまま安泰…というわけではありません。謎のチャレンジがどんどん発生して、対応しないとスコアがマイナスになっていく慌ただしさがあります。

やったことについて詳細を書くことは控えるのですが、なるべく失点がないよう工夫して取り組めたのではないかな…と思っています。

# 結果

チームとしてはおのおの担当のサービスのトラブルに対処したりを繰り返した結果、最終的な成績としては（正確なところは失念してしまったのですが）10位台前半くらいだったでしょうか？50チーム程度が参加していたと思うので、寄せ集めチームとしてはそれなりによいところまでいけたのではないかと思っています。

英語の壁についてはもちろんあるにはあったのですが、思ったよりもなんとかなるな？という感想です。やりたいことの細かい説明に詰まるようなことはあったものの、最悪AWSコンソールやコードを指さしてあれこれ言えばだいたいは伝わってくれるので、こういう共通の基盤がある同士なら英語だろうとわりとコミュニケーションできるんじゃないかと思えるようになったのが収穫ですね。

# お知らせ

さて、そんな刺激にあふれたre:Inventについて、AWS Japan様・Voyageグループ様もお迎えして内容を振り返っちゃおう！というイベントが12/20に「市ヶ谷Geek★Night #20 post:Invent」として開催されます。
https://ichigayageek.connpass.com/event/111436/
まだまだお席に余裕がありますので、re:Inventに参加された方もされていない方も、年の瀬でお忙しいとは思いますがぜひいらしてください。自分もLT枠にて登壇しますよ！！
githubへのアップロード

githubの使い方についてメモ。

#流れ
1. githubのマイページへログイン
2. repositoryを新規作成
3. ローカルで編集

# 1.マイページログイン
割愛

#2.repositoryを新規作成
新しいプロジェクトを作成します。
Start a Projectを選択
<img width="898" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280244/8f9d374d-140e-8e7e-43b6-78222fbde576.png">

プロジェクト名を入力。ここではtest_2019とする。
<img width="757" alt="スクリーンショット 2019-04-25 23.30.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280244/df3538ca-d243-8cd8-e4ac-0a442d824852.png">
create repository をクリック。

するとレポジトリができます。
<img width="998" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280244/3c3c7c8e-4a64-bdb1-8371-9e502c3ea7dd.png">


# ローカルで編集
ローカルにGitHub用のディレクトリを作る。デスクトップ下にtest
この段階ではこのレポジトリは空。
ローカル環境を入れてあげる。

```bash
# githubに入れたい環境のルートディレクトリにまず移動しておく
# これは最初(github内の指定するレポジトリが空だった時のみ書かないといけない)
$ git remote add origin https://github.com/user_name/project名.git
# この1行は毎回。pushで変更を参照させる
$ git push -u origin master
```

これでマイページのレポジトリに行けば、先ほどターミナルで作業した場所と同じ環境が入っているはず
入力値のバリデーション

Webシステムを組む上で、データの入出力をする際には特有の注意をする必要があります。今回は、入力側について触れてみます。

## 入力値のバリデーション

外部からの入力の特徴として、**何を送りつけられるかわからない**ということがあります[^1]。整数だと思っていたら文字列が来たり、スカラーを想定している箇所に配列が与えられる、というような事態も考えられます。

ということで、そんな「何が来るかわからない値」を「プログラム内で有効な値」として使えるのか検証する必要が出てきます。これが**バリデーション**です。

一口に「バリデーション」といっても、いろいろな切り口があります。

* データ型のバリデーション…整数、文字列、日付などデータ型が想定のものと一致するか
* データ形式のバリデーション…郵便番号のように書式が決まった文字列や、値の範囲が決まった数値などで、その範囲に入っているかのバリデーション
* ロジックのバリデーション…商談日より契約日のほうがあとになる、というような、ビジネスロジックに基づいたバリデーション

そして、「バリデーションで弾くべき異常値」としても、2通りが考えられます。

* ミスで来うる入力値
* ミスでも起きないような入力値

この分類に関しては、入力の受け付け方をどのようにしているかに依存します。

HTMLフォームで入力させる場合、状況によっては種類も違う値が`<input>`に入力可能なこともありうるので、数値 - 文字列の違いも入力ミスと判断せざるを得ないかもしれません。このような状況で「ミスでも起きないような入力値」は、スカラーであるべきところに配列やファイルが来た、あるいは文字エンコードがおかしい、`<select>`や`<input type="checked">`で用意してあるフォームなのに適切でない値が来た、などごく限られます。

一方で、APIとして入力を受け付ける場合は、明らかに型が異なるようなものは`400 Bad Request`で終わらせてしまって構わないでしょう。一方で、「そこは予約がいっぱい」のようにAPIを呼ぶ側でチェックしきれない[^2]制約条件については、いったん受け付けてきちんと状況を示すレスポンスを戻す必要があります。

あと、バリデーションの重要なポイントとして、「何重にかけても（バリデーターの実行速度の問題を除けば）全く問題ない」ということがあります。コントローラーでパラメーターの名前と型など、簡単なチェックをするバリデーターを入れて、ロジックや値の範囲の検証はモデルで行う、というような分業も可能です。

### バリデーションでやってはいけないこと

バリデーションを組む上で、不適切なこともあります。

#### 値を変更してしまうこと

バリデーションの役割はあくまで値の検証であって、値を変更するのはシステムロジックの都合となります。ロジック側で値を変更する場合は、変更後の値に対してもバリデーションを通す、あるいは通る値なのか確認する必要があります[^3]。

#### ブラックリストによる検証

特定のキーワードを禁止した掲示板がどうなるのかを見れば火を見るより明らかですが、ブラックリストでバリデーションしても、よくて対症療法にしかなりません。HTMLなど、機能の多い言語を一般ユーザーからの[^4]入力として受け付ける場合、受け付けるタグと属性をホワイトリストで洗い出して、残りは全部アウト、というような形にすることが必要でしょう。

[^1]: ユーザーが入力する際にフォームを用意して、特定の形で入力させることはできますが、フォームを無視してリクエストを投げることも可能なので、「HTMLフォームやJavaScriptで行うバリデーション」は、悪意のある攻撃者に対してはまったく無力です。
[^2]: 事前にチェックしておいても、APIを送信するまでにいっぱいになっている危険性もあります。
[^3]: エンコードレベルで壊れた文字列（通して有意になることもほぼないので、事前に弾いてしまうほうがいいでしょうが）やHTMLの断片などを無理やり変換してしまうと、状況によってはバリデーションで弾いたはずの文字列が生成してしまうことがありえます。
[^4]: システム管理側のフォームであれば、「何を入力してもいい」が許される場面もあるかと思います。
Azure DevOps について

# Azure DevOps

MS(Microsoft) が VSTS(Visual Studio Team Services) をリブランドして、Azure DevOps というサービスにしたそうです。
DevOps まわりのツールがひとまとめになっていて結構便利そうな感じですので、ちょっと見ていきたいと思います。

## そもそも VSTS って何だったのか

VSTS は Visual Studio Team Services といい、元々 Visual Studio という MS の開発ツール群をチームで使っていくためのプラットホームでした。
おおまかには Azure DevOps と変わらない機能を提供していましたが、MS が Github を買収したことによりどう統合していくかが話題になるようなものでした。
で、その結果が Azure DevOps というところなのだと思います。

[VSTS](https://visualstudio.microsoft.com/ja/team-services/)

今は、VSTS のページに行くと、Azure DevOps に刷新されましたとなっていて、VSTS はもう使えません。

## Azure DevOps の概要

ということで、Azure DevOps の概要です。

### 1.Azure Boards

「かんばんボード、バックログ、チームのダッシュボード、カスタム レポートを使用した強力な作業追跡。」が実装されてるらしいです。
[Trello](https://trello.com/) っぽい機能プラスアルファを提供しています。
かんばんボードで見える化ですね。

### 2.Azure Pipelines

「あらゆる言語、プラットフォーム、クラウドで機能する CI/CD。GitHub や任意の Git リポジトリに接続し、継続的にデプロイすることができます。」とのこと。
あらゆる言語？？？
`Node.js、Python、Java、PHP、Ruby、C/C++、.NET、Android、および iOS アプリ`
こんな言語らしいです。なんか、あらゆる言語というには・・・ごほごほ・・・
golang は意図してない感じですかね。。。
OSS用だと10並列までの並列ジョブが時間制限なしに使えるって、何その大盤振る舞いって感じですが、通常でも１つのジョブで1か月あたり 1,800 分まではビルド時間が無料のようです。[circleci](https://circleci.com/) では、1,000 分までビルド時間が無料なので、このあたりは対抗してる時間設定のようですね。

### 3.Azure Repos

「クラウドでホストされたプライベート Git リポジトリを無制限にプロジェクトで使用。共同のプル要求、高度なファイル管理、その他。」ってことですが、ここは買収した github とかが裏側で使われてたりするんですかね。無制限のプライベートレポジトリというところが github の客を食ってしまわないか心配なとこですが、いい感じです。無制限のプライベートレポジトリという意味では、[Bitbucket](https://bitbucket.org/) もそうですね。あちらは自社の開発ツールと連動で使ってもらうために提供してる感じ・・・あれ？同じ？

### 4.Azure Test Plans

「オールインワンの計画された探索的テスト ソリューション。」ということで、ワークフローの実行時にテストできる機能が提供されてますね。「探索的テスト」というのがあって、「最新のソフトウェア開発プロセスで探索的テスト セッションを使用することにより、テストの設計と実行を同時に行って、品質を最大限に高めることが可能です。」と書かれてるのですが、ほんまに自動ならそれはいいなと思いますね。ちょっとそのうち試してみたいと思います。

### 5.Azure Artifacts

「パブリックおよびプライベートのソースからの、Maven、npm、NuGet パッケージのフィード。」ということで、コードの再利用をするための共有ってとこでしょうかね。同じ機能をあちこちで作ってるとかないといいですね。git からひっぱってくるのではなく、パッケージ化された状態で使えるという話みたいですが、このあたり再利用を考えてコード書かないとダメなんだろうなとか思いますね。

## まとめ

無料版でもかなりのことができるので、候補の一つとしてお試ししてみてもいいかもしれません。

## 参照

・[Azure DevOps の概要](https://azure.microsoft.com/ja-jp/blog/introducing-azure-devops/)
・[Azure DevOps](https://azure.microsoft.com/ja-jp/services/devops/)
Lineで自動でメッセージを返すbotを作成してみた

# 本稿について
lineのbotを作りたくてネットで調べながらやってみた。こんにちはといったらこんにちはと返すまでできて、ここでひとまずメモっとこうと思った。
自分用なので分かりづらいです。一般の方は他のページを参考にしたほうがいいです。

# 環境
MacBook Pro 
Mojave

# あらかじめやっておくこと
* Line Developerへ自身のlineIDアカウントでログイン
* HEROKUアカウントを作成しておく
* npmのインストール


# npm のインストール

```bash
# homebrewのインストール
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
# nodebrewを入れる
$ brew install nodebrew
# このディレクトリを作っておく
$ mkdir -p ~/.nodebrew/src
# 最新バージョンをインストール
$ nodebrew install-binary latest
# 確認
$ nodebrew list
# 確認したバージョンを使うと宣言
$ nodebrew use  vxx.xx.xx
$ echo 'export PATH=$PATH:/Users/user_name/.nodebrew/current/bin' >> ~/.bashrc
# bash_profileに書き込み(内容はサイト参照)
$ vi -b ~/.bash_profile

# バージョンの確認。ターミナルの再起動がいるかも。ちゃんとバージョンがでればオーケー
$ node -v
$ npm -v
```
サイトでは通すPATHがわかりづらかった。ホームディレクトリ直下の.nodebrew〜を通せば行けた。


## 
実際の実行コマンドは以下。

```bash
$ mkdir line-bot
$ cd line-bot
$ npm init --yes
$ npm install --save express @line/bot-sdk
$ vi -b index.js
$ vi -b .gitignore
$ vi -b Procfile
$ heroku login
$ heroku apps:create アプリ名
# 以下3つはline developerのマイページのアプリケーションのところを参照
$ heroku config:set LINE_CHANNEL_ID=hoge
$ heroku config:set LINE_CHANNEL_SECRET=hoge
$ heroku config:set LINE_ACCESS_TOKEN=hogehoge
```

あとはindex.jsをいじるだけ。
Python で FPGA/ これが Lチカだ

#これが "Lチカ" だ
LED チカチカ。通称 Lチカ。Polyphony で書くとこんな感じになります。

```python:blink.py
from polyphony import testbench, module, is_worker_running
from polyphony.io import Port
from polyphony.typing import bit

@module
class Blink:
    def __init__(self, interval):
        self.led = Port(bit, 'out')
        self.interval = interval
        self.append_worker(self.main)

    def main(self):
        led_bit:bit = 1
        while is_worker_running():
            self.led(led_bit)
            led_bit= 1 - led_bit
            self._wait()

    def _wait(self):
        for i in range(self.interval // 2):
            pass

blink = Blink(10000)
```

ひとつひとつ説明していきましょう。

## 習うより慣れろ
いやいや説明なんてよいという場合はもうコンパイルして使ってください。使い方は次の記事に書くことにする予定です。

書いてみて Lチカは Polyphony では最初の一歩ではないことが分かってしまいました（がそのまま続行しましょう）。もうちょい初歩の初歩としては足し算を用意する予定なので、Python ビギナーや FPGA ビギナーで初歩の初歩からやりたいひとは、そちら(まだ書いてない)を見てほしいと思います。

## `@module` と class Blink
いきなり `@module` という Python のデコレータ機能が出てきてしまい面食らうかもしれません。ここが初歩の初歩としてはむずかしいところです。Polyphony では  `@module` というデコレータ用のキーワード(?)が用意されていてハードウェアの module (Verilog-HDL のmodule) に対応していることを明示します。

細かいことは気にせずに、Lチカの場合はそういうものだと思って進めましょう。

### \_\_init__
\_\_init__ 関数は Python で class を定義する際の初期化関数(コンストラクタ)です。

```python:__init__
    def __init__(self, interval):
        self.led = Port(bit, 'out')
        self.interval = interval
        self.append_worker(self.main)
```

LED をチカチカさせるためには、なんらかのハードウェア的な出力が必要で、それを Port(bit, 'out') で作っています。interval は点滅の間隔です。そして、worker という無限ループをする実体を append_worker という関数で定義します。

### main
初期化関数 \_\_init__ で worker として登録された main 関数が実際に動作する本体です。
Port の led に 1 を書くことで LED が点灯、0 を書くことで LED が消灯としましょう。led_bit は初期値が 1 です。led_bit = 1 - led_bit で値が反転してもとが 1 なら 0 になります。self.led(led_bit) で LED の点灯/消灯がコントロールできます。その後、毎回 _wait 関数を呼びます。

```python:main
    def main(self):
        led_bit:bit = 1
        while is_worker_running():
            self.led(led_bit)
            led_bit= 1 - led_bit
            self._wait()
```

### _wait
_wait は点灯および消灯時間の調整です。for 文で interval の回数だけまわります。

```python:_wait
    def _wait(self):
        for i in range(self.interval // 2):
            pass
```
Float

#フロートとは
・隙あらば入り込んでやるぜ!!!ぐらいの意気込みを持った熱い連中
・英語で浮くという意味
・左に寄せていくか「 **left** 」と右に寄せていくか「 **right** 」のみ
・適用したいものに的確に指示
・適用したくないものには「 **clear** 」を適用させる
・困ったら「 **overflow{:hidden;}** 」「 **clearfix** 」を使用してあげる
・高さがなくなるので背景指定しているものが消えてしまう
・「 **float** 」と「 **clear** 」はワンセットである

cleatfixにおいては別ページにて詳しく解説する予定です

```css:css
.class{
float:left;
}
```

上記の意味は「class」というクラス名がついている要素に対して左にフロートしてくださいの意味
SimpleApiBundleを作っている話

[Symfony Advent Calendar 2018](https://qiita.com/advent-calendar/2018/symfony) 3日目の記事です。
昨日は@77webさんの[Symfony4のautowiringで狙ったinterfaceを確実に注入させる方法](https://tech.quartetcom.co.jp/2018/12/02/symfony4-autowiring-interface/)でした。

## はじめに
一人でそこまで大規模ではないアプリケーションを作る事がおおいのですが、Symfonyで簡単なAPIを実装したくなる場合にどう実装したらいいのか？
結構悩むことが多いです。

要件的には以下のような感じです。

- JSONでレスポンスする
- POST時のrequestのbodyに`{"name":"xxx","description":"yyy"}`な形で入ってきたものを受け取る(bodyParser的なものが必要)
- ControllerでAnnotationを使いAPIかどうかを指定したい


## ２つの方法
SymfonyでAPIな実装(jsonをレスポンスするような実装)をする場合に僕が思いつく方法が２つあります。

1. JsonResponse()オブジェクトを返す
2. FOSRestBundleを使う方法

### JsonResponse()オブジェクトを返す
これは非常にシンプルな方法でコントローラで以下のように書くだけです。<br>

```php5

<?php
class MainController
{
  public function index() 
  {
     return new JsonResponse(['message' => 'hello, world');
  }
}
```

確かにResponseをJSONで返すだけならこの方法で十分です。
しかし、POST時のデータの受取まで考えると、ちょっと微妙ですね。


### FOSRestBundleを使う
SymfonyにはFOSRestBundleという素晴らしいBundleがあります。
[https://github.com/FriendsOfSymfony/FOSRestBundle](https://github.com/FriendsOfSymfony/FOSRestBundle)

ただ、今回の簡単なAPI実装ではちょっと機能が多すぎるのとAnnotationを活用出来ないのであまり積極的に使う気になれません。<br>

## SimpleApiBundle
[polidog/SimpleApiBundle](https://github.com/polidog/SimpleApiBundle)

最初に提示した3つの要件を満たすために作ったBundleです。

一番最初に求めたものは「`@API`アノテーションを付けたら、jsonレスポンスする」ということでした。
`@API`を外して`@Template`に付け替えたら簡単にjsonからhtmlに切り替えられるみたいな。
すべてjsonで返すわけではなくて、一部はTwig使ってHTMLを返したいという要件がよくあって、それを簡単に実現したいのです。

### 使い方

[README.md](https://github.com/polidog/SimpleApiBundle#usage)を見ていただければすぐに分かると思いますが、単純にjsonのレスポンスを返すだけなら以下のとおりです。

```php
// UserController.php

    /**
     * @Route("/user/{id}")
     * @Api()
     */
    public function me($id): array
    {
        $user = $this->userRepository->find($id);
        return [
            'id' => $user->getId(),
            'name' => $user->getUsername(),
            'avatar' => $user->getAvatar(),
        ];
    }
```

#### 201レスポンス

annotationの引数`statusCode`にステータスコードを指定するだけです。

```php5

    /**
     * @Route("/user/post", methods={"POST"})
     * @Api(statusCode=201)
     */
    public function post(Request $request): array
    {
        // TODO save logic.
        return [
            'status' => 'ok',
        ];
    }
```

## ステータスコードの問題点

現状のSimpleApiBundleではannotationで宣言的に書かれている`statusCode`ですが、動的に変化させたいケースもあります。
例えばバリデーションのチェックで失敗した場合は400でレスポンスコード返したいとか、実行時に決まるステータスコードのどう扱うべきか。

現状ではStatusCodeを変更する方法は一つしかなくてExceptionを発生させることです。
Exceptionのcodeが0以外は、ResponseオブジェクトのstatusCodeに反映するように実装しています。
POSTやGETを同じコントローラのアクションに記述するのは、アクションに複数の責務をもたせており、分離したほうがいいわけで、そう考えると、StatusCodeを変更するというのは、基本的にエラーが発生する場合のみであるべきなのではないでしょうか？

ということで現状は宣言的にStatusCodeを設定できるぐらいで十分な気もしてきました。


##　最後に
Bundleを自分で作ると、Symfonyをより深く学ぶ事が出来ます。
SimpleApiBundleはかなりFOSRestBundleを参考にしていますし、僕はFOSRestBundleから多くのことを学びました。
年末年始にお時間のある方は小さなBundle作ってみてはいかがでしょか？
格子を描画するための数式を実装する

# 1. 概要
データ可視化などの際に格子状の模様を描画したくなる場合がある。自明な方法としては

- 縦横に等間隔の直線を描画
- 格子点に点をプロット

などが考えられるが、もう少しだけ工夫を要する手法を紹介する。

なお、以下で紹介するのは
**「平面上の座標 $(x, y)$ が与えられたとき、その地点はどのような色で塗られるべきか」という情報を与える関数 $f(x, y)$**
であることに注意。形状ベースではなくピクセル塗り潰しベースの考え方であり、このような $f(x, y)$ から実際に描画をする際には

- Pythonであれば[matplotlib.pyplot.imshow()](https://matplotlib.org/api/_as_gen/matplotlib.pyplot.imshow.html)
- JavaScriptであれば[Canvasのピクセル値を指定する方法](https://qiita.com/sw1227/items/f08cd25364fbaea07792)

などを利用すれば良い。

# 2. 2色のチェッカーボード
まずは単純なチェッカーボード（市松模様）を描画するための関数を考える。

<img width="400" src="https://qiita-image-store.s3.amazonaws.com/0/58850/196b9c3e-1a1b-2648-43ff-b0b8512be90a.jpeg"/>

各正方形の長さはいったん「１」とし、任意の地点 $(x, y)$ に対して0または1の値を返す $f(x, y)$ を用意したい。
この場合、$(x, y)$ の整数部分$\lfloor x \rfloor, \lfloor y \rfloor$ について

- $\lfloor x \rfloor, \lfloor y \rfloor$ が(偶数,偶数)なら0
- $\lfloor x \rfloor, \lfloor y \rfloor$ が(偶数,奇数)なら1
- $\lfloor x \rfloor, \lfloor y \rfloor$ が(奇数,偶数)なら1
- $\lfloor x \rfloor, \lfloor y \rfloor$ が(奇数,奇数)なら0

とすれば良い。例えば2で割った余りの差の絶対値をとる。
JavaScriptなら以下のように実装する。

```javascript:JavaScript
function checkerBoard(x, y) {
    return Math.abs(Math.abs(Math.floor(x) % 2) - Math.abs(Math.floor(y) % 2));
}
```

これを利用し、各ピクセルについて「`checkerBoard(x, y)`が0なら白, 1なら黒」のような描画を行えばチェッカーボードが描画できる。
※ 正方形の大きさを1以外にしたい場合は $x, y$ のスケール変換を行う。

# 3. 格子からの距離でグラデーション
続いて、以下のようにグラデーションで描画を行う方法を考える。
<img width="400" src="https://qiita-image-store.s3.amazonaws.com/0/58850/ecdd1597-d745-439d-9489-d7260d8a931b.jpeg"/>

ここでも正方形の大きさは1とする。

**考え方**
点$(x, y)$と近くの格子との距離を計算し、0-1の範囲で格子との距離が近いほど大きな値をとるような関数を作り出す。

**ひとつの方法**

- $x$ 方向、$y$方向それぞれについて、最寄りの格子からの距離$dx, dy$を計算する
    - => 四捨五入した値との差の絶対値を利用
- この距離をそのまま使うのではなく、**格子から離れるにつれて急激に減少するようにしたい**ので、対数を取った上で-1倍（符号を+に）する。そのままだと距離=0の格子上で無限大になるため、小さな数$\alpha$ を使って$-log(\alpha + dx)$のようにする
    - => $\alpha$が小さな値になるほどシャープなグラデーションになる
- 値の範囲を0-1に正規化する。正規化の係数は$\alpha$に依存している。

JavaScriptなら以下のように実装できる

```javascript:JavaScript
function latticeProximity(x, y, alpha=0.01) {
    // alpha: prevent divergence of log - the smaller the sharper
    const dx = - Math.log(alpha + Math.abs(x - Math.round(x)));
    const dy = - Math.log(alpha + Math.abs(y - Math.round(y)));
    // Normalize
    const minVal = - 2 * Math.log(alpha + 0.5);
    const maxVal = - 2 * Math.log(alpha);
    // range of return value: [0, 1]
    return (dx + dy - minVal) / (maxVal - minVal);
}
```
`latticeProximity(x, y)`は点$(x, y)$ について格子からの距離に依存する0-1の値を返してくれる。各ピクセルについてこの返り値を[カラースケール関数](https://github.com/d3/d3-scale-chromatic)に渡して色を決めていけば良い。

# 4. 活用例
複素関数$f(z)$による写像 $f(x + iy) = u + iv$ は、正則ならば等角写像になることが知られている。
上述の`latticeProximity()`を使って、ピクセル$(x, y)$ の色を`latticeProximity(u, v)`に基づいて決めていくと、以下のような図（ここでは$f(z) = sin(z)$）を描くことができる。

<img width="500px" src="https://qiita-image-store.s3.amazonaws.com/0/58850/85828f3b-c1df-c5d6-a215-7e418e42ea25.jpeg"/>

格子を等角写像で変換しているため、線と線の交わる部分が直角になっていることがわかると思う。
また、プログラム中で`latticeProximity()`を`checkerBoard()`に書き換えるだけで、以下のようにも描画できる。
<img width="500px" src="https://qiita-image-store.s3.amazonaws.com/0/58850/2f7af54e-22c4-7a37-388e-ca751922f56f.png"/>
シクシク素数列 Advent Calendar 2018 Julia編

この記事は[「シクシク素数列 Advent Calendar 2018」](https://qiita.com/advent-calendar/2018/4949prime-series)4日目になります。

言語は Julia を使って解いたのですが、素数関連の関数を使用する関係上バージョン 0.4 を使っています。
お題の詳細は[ココ](https://qiita.com/advent-calendar/2018/4949prime-series)に譲るとして、早速解答と解説を見ていきましょう！

### 解答

```julia
print(join(filter(x->ismatch(r"4|9","$x")&&isprime(x),(1:1319).')[1:parse(readline())],","))
```

[オンライン実行環境で見る](https://tio.run/##DcvBCoMwDADQfynDJdBJw7zowR8ZHsrMWKRWSSv04L9X7@8tRxBf664SMyybRPhJyKxQXqOk1efvH9R0Z2@seRSDTSPpxitDQQs00Jt6bJ/4oWH3mhiU/RwkMiBO9k6ItZJzFw)

### 解説

1. `(1:1319).'` で1から1319までの配列をつくる。
2. その配列の中から `filter` で「素数 かつ 4か9が含まれる 数字 - ☆」を抽出する。「素数」の判定には `isprime` 関数、「4か9が含まれる」の判定には `ismatch` 関数を使う。与えられた数字が☆を満たすかどうか判定する際に「素数」の判定を後回しにしているのは、「4か9が含まれる」の判定のほうが「素数」の判定より早く判定でき、「4か9が含まれる」を満たさない場合は「素数」の判定のために無駄な計算をしなくて済むからである。
3. ☆を満たす数字の配列の先頭から標準入力で与えられた数字（`parse(readline())`）分取り出す。
4. 3. で取り出した配列を `join` 関数でカンマ区切りで結合する。
5. 結果を `print` 関数で標準出力する。
Unityが開かなくなった時の解決方法

Unity、PCやプログラムの書き方によっては、たびたび強制終了が必要になる場面が存在します。
その際に、Unityのプロジェクトを開ききるところまでいかなくなった人等はいるんじゃないでしょうか？

#環境
Unity5.6.5f
VisualStudio2015Pro

#対象の人

・以下の記事の内容を行ったけど、それでも起動しなかった人
[Unityのプロジェクトが開かない！繰り返し起こるトラブルの解決方法](http://corevale.com/unity/2837)


今回の対象者メイン
・Gitなどのバージョン管理を使用して、ブランチを切り替えた後にUnityが起動しなくなった人


#症状
・Unityでプロジェクトを起動しても、最後まで画面が表示されず、気づいたら、タスクキルされている状態になる。
・UnityBagレポートの画面が表示される


等の症状がでて、そのプロジェクトを開くことができなくなります。




#行うこと

１．起動できなくなったの　プロジェクト/Library　の中にある、ScriptAssembliesのフォルダを消す

２．Unityを起動する。



以上。
Rubyのバージョンアップしたときに躓いたところ

## はじめに
[ユアマイスターアドベントカレンダー2018](https://qiita.com/advent-calendar/2018/yourmystar) の2日目の記事です。

ちょうど1年前にRubyの開発をしていて、それからまったくアップデートしていなかったのですが、年を越す前に、負の遺産となる前に、最新バージョンにしました。
現在のバージョンはRuby 2.5.0だったので、バージョンを[2.5.3](https://www.ruby-lang.org/ja/news/2018/10/18/ruby-2-5-3-released/)にします。
そこで躓いたところを書きつつ、最後的な手順を書きました。

## 躓いたところ

### Ruby2.5.3が出てこない

```bash
$ rbenv install -l
  ...
  2.5.0-rc1
  2.5.0
  2.5.1
  ...
```

rbenvでインストールできるRubyに2.5.3がない。。。
ruby-buildが古いままだったので、更新をしたらちゃんと出ました。

```bash
$ brew upgrade rbenv ruby-build
```

### Rubyを切り替えて、終わりかと思いきやエラー

```bash
$ rbenv exec bundle exec rails s
rbenv: bundle: command not found

The `bundle' command exists in these Ruby versions:
  2.5.0
```

エラーに書いてある通り、Ruby 2.5.3のbundlerが入っていないからでした。
BundlerもRubyのバージョンに依存しているのかー。
bundlerをインストールし直すればOK。

```bash
$ rbenv exec gem install bundler
$ rbenv rehash
```

### Railsテスト実行時にエラー

```bash
$ rbenv exec bundle exec rails t
Could not find nokogiri-1.8.2 in any of the sources
Run `bundle install` to install missing gems.
```

nokogiri-1.8.2がないらしい。
Bundlerの再インストールをすれば解決。

## 最終的な手順はこうなった

### Homebrewを更新

```bash
$ brew update
```

### rbenv、ruby-buildを更新

```bash
$ brew upgrade rbenv ruby-build
```

### インストール済みのrbenvを確認

```bash
$ rbenv versions
  system
* 2.5.0 (set by /projectDir/.ruby-version)
```

### rbenvでインストールできるRubyのバージョンを確認

```bash
$ rbenv install -l
```

### 最新のRubyをインストール

```bash
$ rbenv install 2.5.3
```

### インストールできているか確認

```bash
$ rbenv versions
  system
* 2.5.0 (set by /projectDir/.ruby-version)
  2.5.3
```

### インストールしたバージョンに変更

```bash
$ cd ~/projectDir
$ rbenv local 2.5.3
```

### バージョンが切り替わっていることを確認

```bash
$ rbenv versions
  system
  2.5.0
* 2.5.3 (set by /projectDir/.ruby-version)
```

### bundlerをインストール

```bash
$ rbenv exec gem install bundler
$ rbenv rehash
```

### Gemを再インストール

```bash
$ rbenv exec bundle install --path vendor/bundle
```
機械学習論文読みメモ_144

[Deep Neural Networks with Data Dependent Implicit Activation Function](https://arxiv.org/abs/1802.00168)
Deepnetはその深さが増すほど、訓練データが少ない場合における
汎化性能が下がっていってしまう。
本論で提案するネットワークは、既存のネットワーク構造の継承で
ありながら、この問題を解決する。
提案手法は、訓練データに関する情報を実際の訓練の前に
事前知識として利用する。
そのためにまずResNetと偏微分制御問題との関連性を示す。
この関連性とは、ResNetのResidual Connection部分が
移流方程式の制御問題として表現できる事である。
この表現に基づき求めた、データに依存した活性化関数を用いる事で
少ないデータに対する汎化性能を向上させる。

[Clustering and Unsupervised Anomaly Detection with l2 Normalized Deep Auto-Encoder Representations](https://arxiv.org/abs/1802.00187)
最近の研究において、unsupervisedなautoencoderのencoderを用いた特徴空間上に
おいてcluster analysisを行う手法が増えてきた。
本論ではこの特徴空間上の表現に対してL2 normalizationの制約を掛ける事で
cluster analysisの分離性能を向上させる事が出来る事を示す。

[Regularized Evolution for Image Classifier Architecture Search](https://arxiv.org/abs/1802.01548)
強化学習やevolutionary algorithmに基づく画像分類器の構造探索問題は
最近において信頼のおけるものとなってきた。
本論では著名な非同期のevolutionary algorithmに関して
それを正則化した手法を提案する。
この手法を用いる事で一貫して探索性能を強化学習や非正則化型の手法に対して
向上させる事が出来る。
evolutionary algorithmではtournament methodを用いる。
その上で、性能の最も低いサンプルを除去していく非正則化型の手法ではなく、
新たに提案する古いサンプルから除去していく正則化型の手法を用いる。
CryptZombiesレッスン１(チャプター11~14)の自分なりのまとめ


# 最初に
この記事は私がCryptZombiesを進めていく上で自分なりにまとめたものです。
前回の記事
https://qiita.com/daichi77/items/3ae60fab23634f340e6e
参考にしたサイト
サイト名: イーサリアム上のDApp開発をゲームを作って学びましょう
URL: https://cryptozombies.io/jp/　
この記事の問題文と答えについては上の参考にしたサイトから引用しています。
# チャプター11 Keccak256と型キャスト
## 用語・新しく出てきた便利なやつ
**便利なやつ**

```
keccak256("文字列");
```
これでかっこの中にある文字列をランダムな256ビットの16進数にマッピングしてくれる。
ただブロックチェーン上で使うにはこれは安全とは言い切れない。
**型キャスト**

```
uint a = 5;
uint8 b = uint8(a) 
```
このようにaをuint8で囲むとuint8に型を変更できる。
型キャストについては他の言語と似ている。
## チャプター１１のテスト
**問題文**
_generateRandomDna関数の中身を書いてみよ！以下の点に従って書くように

1. コードの最初の行は _strのkeccak256ハッシュを取得し、擬似乱数の16進数を生成し、それをuintに型キャストして、 randというuintに格納せよ。

2. DNAは16桁になるようにしたい（dnaModulusを覚えているか？）。そこで次の行では上で求めた値のdnaModulusによる剰余(%)を returnするようにせよ。

**答え**

```
function _generateRandomDna(string _str) private view returns (uint) {
        uint rand = uint(keccak256(_str));
        return rand % dnaModulus;
   }
```
## まとめ
テストの２番目でdnaModulusで割ることでなぜ16桁になるのか分からないが、それ以外はとくに難しいことはない。

# チャプター12 統合
今回は演習のみ
**問題文**

1. createRandomZombieという名前の public 関数を作成せよ。そこに_name (string)というパラメーターを設定せよ。 (注: public 関数を宣言する方法は、 private関数を宣言したのと同じです)
2. 関数の最初の行で_nameで_generateRandomDnaを実行させ、それをrandDnaという名前で uintに格納せよ。
3. 次の行で、 _createZombie 関数を実行し、_nameとrandDnaを引数として渡せ。
4. ソリューションは4行以内とする（関数を閉じる}を含む）。

**答え**

```
function createRandomZombie(string _name) public {
        uint randDna = _generateRandomDna(_name);
        _createZombie(_name,randDna);
    }
```
## まとめ
今回の演習で今まで作ってきた関数をcreateRandomZombie関数の中で呼び出した。
これでゾンビを作れるようになった。

# チャプター13 イベント
## 用語
**イベント**
Events は、ブロックチェーンで何かが生じたときに、コントラクトがアプリのフロントエンドに伝えることができるもの。特定のイベントを'listening'状態にして、何かあった時にアクションを起こすこともできる。

## テストのまとめ(答えは省略)
今回のテストでは
1. eventの定義
2. createZombieが呼ばれるたびにイベントが呼ばれるようにする
といったことをやった。

# チャプター１４ Web3.js
ここでまさかのjavascriptライブラリweb3.jsの解説。
ただし解説はcryptZombiesの方に載っているので割愛します。
チャプター１４はのまとめは特になし。web3.jsは後のチャプターで説明されるらしい。
# レッスン１終わっての感想
すごく分かりやすく、基本的な文の書き方が一通りわかるサイトでした。
初心者にはおすすめです。
記事に間違いなどありましたらコメントください。
# 次の記事
https://qiita.com/daichi77/items/edf41bdf2b9953a71fd7
カスタムバリデートでバリデーション前編　初心者→中級者へのSTEP3/25

#カスタムバリデートでバリデーション前編
**はじめに**
[前回の記事](https://qiita.com/kamohicokamo/private/d2ea4d71f86d99261b1a)ではControllerでのバリデーションの具体例としてフォームオブジェクトを紹介しました。今回はモデルでのバリデーションとして、ロジックな検証をカスタムバリデートを用いてしていきます。

##カスタムバリデートとは
Railsに組み込まれているバリデーションだけでは足りない時、プロジェクト仕様のバリデーションルールを追加することになりますが、それを全てmodelに書くと可読性が悪くなります。管理も大変です。てな訳でバリデートクラスなるものを作って独自のルールをそこにまとめようということです。

##個別のEachValidator
カスタムバリデータを追加するには二つのアプローチがあります。
まずは個別の属性にバリデートをかける`EachValidator`について説明します。
今回はemailのバリデーションを例にします。emailがちゃんとemailの形式を取っているかのバリデーションです。

`app/validtors/`階層に、カスタムバリデータクラスとして`email_validator.rb`を作成します。

```email_validator.rb
class EmailValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    unless value =~ /\A[a-zA-Z0-9_\#!$%&`'*+\-{|}~^\/=?\.]+@[a-zA-Z0-9][a-zA-Z0-9\.-]+\z/
      record.errors[attribute] << (options[:message] || "はメールアドレスではありません")
    end
  end
end
```
個別の属性にバリデートをかけるカスタムバリデートを作成する場合、`validate_each`を定義する必要があります。
`validate_each`の引数、`record`に呼び出し元のモデルインスタンスが入り、`attribute`に属性、`value`に値が入ります。このメソッド内で呼び出し元のモデルインスタンスの属性値がemailとして正しい形式か検証しています。
ちなみに正規表現にて検証してますが、これにマッチしないと`errors[]`にメッセージが格納されます。**実はここの記述がないとエラー時に`false`を返してくれません。**`erros[]`にエラーメッセージがあることで、そのデータは正しくないデータと判定します。


クラス名も重要です。`~~Validator`とクラスを名付ければ,モデルにて`:~~`で呼び出せます。
つまり、下記のようになります。

```User.rb
class User < ApplicationRecord
  validates :email, presence: true, email: true
end
```
これでemail属性にだけ先ほどカスタムバリデートクラスに記述した正規表現で検証できます。

##まとめ
カスタムバリデートによる個別の属性の検証はこんな感じです。今回はルールがemailとして正しいかだけの検証だったのであまり差を感じませんが、もっと複雑なルールの場合、モデルにそれを書くよりこのカスタムバリデートクラスにまとめた方が、スッキリしていいですよね。
次回はもう一つのアプローチ、レコード一つ対象にバリデートをかけるものを説明してみます。

##参考にしたの
Active Record バリデーション
https://railsguides.jp/active_record_validations.html#%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%A0%E3%83%90%E3%83%AA%E3%83%87%E3%83%BC%E3%82%BF

【パーフェクトRails】バリデーションをクラスに分離する
https://waterlow2013.hatenablog.com/entry/2016/10/11/011312

メールアドレスの妥当性を正規表現でチェックする
http://rubytips86.hatenablog.com/entry/2014/03/28/135838