OmniAICreator/Qiita-1.07M huggingface dataset:
Gravioで温度データの平均値をファイルに出力する

【2018/11/30追記】
Gravioの新しいバージョンの公開に伴い、新しい記事を作成しました。
そちらをご参照いただければと存じます。

###[Gravioホームページ](https://www.gravio.com/jp/gpromo/1810-start-edgeware)

###[Gravioとは？](https://www.gravio.com/jp-blog-article/2018-11-02-about-gravio)

###[Gravioのインストール方法](https://qiita.com/mikawan/items/56aaecc05db56723523a)

###[温度センサーのデータをエクセルで簡単に表示](https://qiita.com/mikawan/items/3d93543566680afda868)

###[Slackとボタンスイッチセンサーで「呼び出しシステム」を作ってみた！](https://qiita.com/mikawan/items/ac196bbb5506a3251c55)




---

Gravioで温度データを収集した後、平均値を演算して、ファイルに出力しました。

#準備するものと今回試した環境
■PC
・Bluetooth内蔵
・Windows 10 バージョン 1803
■Gravio
・Studio version　1.5.1167.0
■CC2650STK SimpleLink SensorTag
・FW rev.　：1.40

#手順
##1.	温度データの収集設定
こちらをご参照ください。↓↓
[温度データをGravioで収集してみた] (https://qiita.com/mikawan/items/fc30cbe78b920c4cc2cf)

##2.	フローパッケージの作成
(1)左のメインメニュー一覧からGravioフローを選択し、フロー作成メニュー画面を開きます。
![フロー作成メニューへ](https://qiita-image-store.s3.amazonaws.com/0/247209/d1460f59-57f5-a3c3-7399-b2b929509bd7.png)
(2)フローパッケージを作成します。
![フローパッケージを作成](https://qiita-image-store.s3.amazonaws.com/0/247209/60463a0f-fe3b-2d82-f515-b5757f8ff4ea.png)
(3)フローパッケージ編集画面を開きます。
![フローパッケージ編集画面を開く](https://qiita-image-store.s3.amazonaws.com/0/247209/7e93db5b-a9cb-88de-40a5-e6e4a75bc9cc.png)
##3.	センサーDBコンポーネントの設定
(1)センサーDBコンポーネントを配置します。
![コンポーネントの配置1](https://qiita-image-store.s3.amazonaws.com/0/247209/d3e5a48a-fcd5-35e5-2816-030a1fe45201.png)
(2)コンポーネントのプロパティで、温度データを収集しているレイヤーを指定します。
![センサーDBコンポーネントのプロパティ設定](https://qiita-image-store.s3.amazonaws.com/0/247209/f759f211-ab57-e749-e5e6-de684fb87144.png)
(3)出力フィールドで、次のコンポーネントへ出力する項目を指定します。
項目は出力フィールドの＋ボタンをクリックすることで増やすことができます。
![センサーDBコンポーネントの出力データ設定](https://qiita-image-store.s3.amazonaws.com/0/247209/979de315-6a22-9683-0168-ca31d9f9d17a.png)
##4.	ファイル出力コンポーネントの設定
(1)ファイル出力コンポーネントを配置します。
![ファイル出力コンポーネントの配置](https://qiita-image-store.s3.amazonaws.com/0/247209/42fb4962-697c-102a-c73c-9cbd570b1124.png)
(2)ファイルに出力するデータを設定します。
収集している温度データ（Attribute）の平均値は、Ave関数を使用します。
関数は、Sum（合計値）、Count（データ取得動作回数のカウント）、Left（文字列処理）などといった様々な関数を使用することができます。
出力フィールドには、Ave(cin.Attribute)と設定することで計算できます。
![ファイルへ出力するデータ設定](https://qiita-image-store.s3.amazonaws.com/0/247209/3a5655f1-b6d4-9261-af9a-fc3d5f3737d5.png)
(3)ファイル出力コンポーネントのプロパティで、出力するファイル名を指定します。
![ファイル名の指定](https://qiita-image-store.s3.amazonaws.com/0/247209/da0cf267-fc8c-0d78-9fb4-8e876db51788.png)
##5.	実行結果
(1)右上の実行ボタンをクリックするとコンソール画面が開き、実行状態を確認できます。コンソール画面でエラーなく実行が完了していることが確認できます。
![フロー実行結果](https://qiita-image-store.s3.amazonaws.com/0/247209/2f7b365f-2933-5d93-6f16-e52c24feaa05.png)
(2)出力ファイルは、C:\ProgramData\Infoteria\GravioService\dataに出力されます。
ファイルを開くと、平均値、測定温度、日付データが出力されていることが確認できます。
![出力結果](https://qiita-image-store.s3.amazonaws.com/0/247209/d690b688-c5e8-d268-1131-c2450c3bbbcd.png)
ルートパス読み込みされているファイルを本番環境の絶対パスに変更して読み込む方法（開発環境から本番環境のファイルを読み込むため）

Webページ制作の受託案件などで既存ページを改修して欲しいという場合で、サイト共通で使用される`cssファイル`や`jsファイル`などがルートパスで読み込まれているケースがあったりしますが、サイト共通のファイルは書き換えないので本番環境のファイルを**コード自体は変えずに**そのまま読み込みたいということがあると思います。そんな時にルートパスのままで開発環境から本番環境のファイルを読み込む方法を備忘録的に書いていきたいと思います。**（.htaccessを利用するので、WebサーバはApacheを想定しています）**

## ルートパスで読み込まれているhoge.js

```html:hoge.html
<script type="text/javascript" src="/hogedir/common/js/hoge.js"></script>
```
通常、ルートパスで読み込んでいるので、自身の開発環境のドキュメントルートの階層から`/hogedir/common/js/hoge.js`を読み込みにいってしまいます。なので、本番環境のファイルを読み込ませるためには、読み込みファイルを書き換える必要があります。

## .htaccessを使ってRewrite（リライト）

ルートパスで書かれているパスを.htaccessを使って書き換えることで本番環境のファイルを読み込ませることができます。ドキュメントルートに.htaccessファイルを作成して処理を書いていきます。

### ルートパスで読み込まれるファイル全てを書き換えたい場合

```.htaccess:読み込みファイルのパスにhogedirが含まれている各ファイルを本番環境へ
RewriteEngine on
RewriteRule ^(hogedir.*)\.((gif|png|jpe?g|css|ico|js|svg))$ https://{本番環境のドメイン}/$1.$2
```
上記コードで、パスにhogedirが含まれているgif,png,jpg,jpeg,css,ico,js,svgのファイル全てを本番環境へ読み込みにいくように変更させることができます。

### 特定のファイルは除外して開発環境のファイルを読み込ませたい場合

```html:除外して開発環境から読み込ませるファイル
<!-- ファイルのパスは/var/www/html/devdir/hogedir/hogehoge.js -->
<script type="text/javascript" src="/hogedir/hogehoge.js"></script>
```
特定のファイルを除外したい場合は、RewriteCondディレクティブを使ってリライトのルール条件を追加させます。

```.htaccess:/hogedir/hogehoge.jsを除外する場合
RewriteEngine on
#hogehoge.jsの除外をして、それ以外を本番環境のファイル読み込みにする
RewriteCond %{REQUEST_URI} !hogehoge.js$
RewriteRule ^(hogedir.*)\.((gif|png|jpe?g|css|ico|js|svg))$ https://{本番環境のドメイン}/$1.$2

#hogehoge.jsを/var/www/html/devdir/hogedir/から読み込むように書き換え
RewriteCond %{REQUEST_URI} hogehoge.js$
RewriteRule ^(hogedir.*)\.((gif|png|jpe?g|css|ico|js|svg))$ /var/www/html/devdir/$1.$2
```

## 参考

- [.htaccess の書き方（リダイレクト編） - Qiita](https://qiita.com/shotets/items/1f8f308e008dcb96bf43)
requirements.txtを動的に作成して、lambda用のZIPを作成する

## 課題
lambda(python)用のZIPファイルを作成するときに、pythonパッケージも一緒にZIPに固める必要がある。
コードの改修やfunctionを作成するたびに、requirements.txtを修正するのは大変。

## 対処
lambda functionを一つのディレクトリにまとめて、pipreqsでrequirements.txtを動的に作成する。
amazonlinuxのDockerイメージを使い、requirements.txtからPythonパッケージを作成しZIPにする。

## 詳細

```ディレクトリ構成.
# `function/`にlambda function用のディレクトリをそれぞれ作成
.
├── Dockerfile
├── function
│   ├── lambdaFunction1
│   │   └── function1.py
│   └── lambdaFunction2
│       └── function2.py
└── deploy.sh
```

```Dockerfile.
# For install library for python of lambda
FROM amazonlinux:2017.03
RUN yum install -y python36 python36-pip zip
COPY requirements.txt /tmp/
RUN python36 -m pip install -r /tmp/requirements.txt -t /tmp/library
RUN cd /tmp/library && zip -r /tmp/library.zip *

```

```deploy.sh
PROJECT_ROOT_DIR=$(cd $(dirname $0); pwd)
DEPLOY_WORK_DIR="${PROJECT_ROOT_DIR}/.deploy"
DOCKERFILE_DIR="${PROJECT_ROOT_DIR}"

if [ -e ${DEPLOY_WORK_DIR} ] ; then
    rm -rf ${DEPLOY_WORK_DIR}
fi
mkdir ${DEPLOY_WORK_DIR}

download_python_library() {
    cd ${DOCKERFILE_DIR}
    # requirements.txtはpipreqsを使って動的に作成します
    pip install pipreqs
    pipreqs --force ${FUNCTION_CODE_DIR}
    # lambdaでインストールせずに使えるパッケージは除外します
    sed -i '' -e "/boto3/d" ${FUNCTION_CODE_DIR}/requirements.txt
    mv ${FUNCTION_CODE_DIR}/requirements.txt .
    docker build . -t amazonlinux
    docker run --name amazon amazonlinux /bin/true
    docker cp amazon:/tmp/library.zip ${DEPLOY_WORK_DIR}/${FUNCTION}.zip
    docker stop amazon
    docker rm amazon
    rm requirements.txt
}

create_zip() {
    cd ${DEPLOY_WORK_DIR}
    echo $'Zip \e[33m'$(ls ${FUNCTION_CODE_DIR})$'\e[0m into '${FUNCTION}'.zip'
    zip -j ${FUNCTION}.zip ${FUNCTION_CODE_DIR}/*
}

zip_function() {
    download_python_library
    create_zip
}

# Create ZIP with python package
FUNCTIONS=($(ls ${FUNCTION_DIR}))
for _FUNCTIONS in "${FUNCTIONS[@]}"; do
    FUNCTION=${_FUNCTIONS}
    FUNCTION_CODE_DIR="${FUNCTION_DIR}/${FUNCTION}"
    echo $'Zip \e[33m'${_FUNCTIONS}$'\e[0m'
    zip_function
done

```
Chainerで画像の一部をメモリにキャッシュして高速化を図るDatasetを作った

# はじめに
モデルを訓練する際に，MNIST程度の画像サイズと枚数のデータセットであれば最初にすべてメモリに読み込むことができるので高速にイテレーションを回すことができます。

しかし，自前のそれなりに大きいサイズと枚数の画像データセットでモデルを訓練しようとすると，データがすべてメモリに乗り切らなくなってしまうことがよくあります。

# ChainerのImageDataset
Chainerには自前の画像データセットを扱うために[ImageDataset](https://docs.chainer.org/en/stable/reference/generated/chainer.datasets.ImageDataset.html?highlight=imagedataset), [LabeledImageDataset](https://docs.chainer.org/en/stable/reference/generated/chainer.datasets.LabeledImageDataset.html?highlight=labeledimagedataset)などのクラスが用意されています。
これらのクラスは画像のパスやラベルだけを保持しており，画像データ自体はイテレータなどから`get_example()`が呼び出されるたびにその都度読み込まれます。
そのため，メモリに乗り切らないような大規模なデータセットも扱うことができますが，画像を参照するたびに読み込みのオーバーヘッドが発生します。

画像一枚一枚を読み込むのにかかる時間は微々たるものです。
しかし，ミニバッチ学習を行う場合，たいてい数十枚の画像を毎イテレーション読み込むことになるので，その時間は無視できなくなってきます。

# 作ったもの
画像データセットの一部だけをメモリにキャッシュしておくことで，読み込みにかかる時間を短縮するデータセットのクラスを作りました。

以下にコードを示します。

```python
# -*- coding: utf-8 -*-

import numpy as np
import os
from PIL import Image

from chainer.datasets.image_dataset import _read_image_as_array, _postprocess_image

class CacheImageDataset(chainer.datasets.ImageDataset):
	def __init__(self, paths, root=".", dtype=np.float32, cache_num=0):
		super().__init__(paths, root, dtype)
		
		self.cache_images = [None]*len(self)
		for i in range(min(len(self), cache_num)):
			self.cache_images[i] = super().get_example(i)
		
	def get_example(self, i):
		if self.cache_images[i] is None:
			img = super().get_example(i)
		else:
			img = self.cache_images[i]
		
		return img
```

# 使い方
基本的にはChainerの[ImageDatasetクラス](https://docs.chainer.org/en/stable/reference/generated/chainer.datasets.ImageDataset.html)と同じように使えます。
コンストラクタの引数`cache_num`にメモリにキャッシュしておきたい枚数を指定することで，インスタンス生成時にその枚数分だけ読み込みます。
`chainer.datasets.ImageDataset`クラスを継承しているので，Chainer標準のデータセットクラスと同じようにイテレータに渡したり，`TransformDataset`に渡してData augmentationを行ったりできます。
`LabeledImageDataset`のようにラベル付きで使いたい場合は`TupleDataset`を活用してください。

# おわりに
メモリが許す限り多くキャッシュするほど，回すエポック数が多いほど学習ループ中の画像読み込み処理が減るので高速化が期待されます。
上記ではキャッシュ保存時の`dtype`を`float32`にしてしまっていますが，`uint8`にするなどの工夫をすればさらにキャッシュ枚数を増やせるのではないかと思います。
JIS安全色で色指定したスタイルシート

2018年4月20日に、JIS安全色が改正されました。塗装用、印刷用、画面表示用、のそれぞれについて、好ましい色が改正されました。

色の見え方は人により様々です。色弱の人、ロービジョンの人、白内障になっている人、などです。どのような人でも、なるべく見分けやすいように、調査して改正されました。

## JIS安全色
赤、黄赤、黄、緑、青、赤紫の6色に、白と黒を加えた8色です。

### スタイルシート
[JIS Z 9103 色の指定値](http://safetycolor.jp/shiteichi/)の推奨値を、スタイルシートの形式にしました。

```css
.text-red {
    color: #ff4b00 ;
}
.text-yellowred {
    color: #f6aa00 ;
}
.text-yellow {
    color: #f2e700 ;
}
.text-green {
    color: #00b06b ;
}
.text-blue {
    color: #1971ff ;
}
.text-redpurple {
    color: #990099 ;
}
.text-white {
    color: #ffffff ;
}
.text-black {
    color: #000000 ;
}
.background-red {
     background-color: #ff4b00 ;
 }
.background-yellowred {
    background-color: #f6aa00 ;
}
.background-yellow {
    background-color: #f2e700 ;
}
.background-green {
    background-color: #00b06b ;
}
.background-blue {
    background-color: #1971ff ;
}
.background-redpurple {
    background-color: #990099 ;
}
.background-white {
    background-color: #ffffff ;
}
.background-black {
    background-color: #000000 ;
}
```

### 注意点
上記リンク先にもありますが、正確に色あいを表現するには、表示機器の設定を「sRGB, ガンマ 2.2, 6500 K」にする必要がありますのでご注意ください。

### 色のコントラスト比計算サイト
[色のコントラスト比計算](https://calculator.jp/science/contrast/)
PHPでファンファンのファン問題を考えてみた

#ファンファンのファン問題とは
@yamamoto_hiroya さんの [今更FizzBuzz問題？ファンファンのファン問題やろうぜ](https://qiita.com/yamamoto_hiroya/items/2633491dd4c7f6550c1d)
や、
@MAMEO さんの [ファンファンのファン問題やろうぜという記事をみたのでC#で実践してみた。](https://qiita.com/MAMEO/items/e181985c9813592915d1)
という記事に触発されたのでPHPでこの問題を考えてみました。
特に回数については言及されていませんでしたが、@MAMEO さんの記事に沿って私も10回表示するものとします。
（改行は&lt;br&gt;で行うことにしてみました）

#まず普通に考える
```php
<?php
for ($i = 0; $i < 10; $i++) {
    echo 'ファンファンファン ファンファンのファン<br>';
}
```

面白くもなんともありません。

#「ファン」を重複して書かないようにしてみる
```php
<?php
for($i = 0; $i < 10; $i++) {
    for ($j = 0; $j < 8; $j++) {
        switch ($j) {
            case 3:
                echo ' ';
                break;

            case 6:
                echo 'の';
                break;

            default:
                echo 'ファン';
        }
    }
    echo '<br>';
}
```

長くなりましたし3とか6とかマジックナンバーが書かれていてダサいことこの上ないです。

# ここからはネタ
## 二重三項演算子を使ってワンライナーで書いてみる
```php
<?php for($i=0;$i<10;$i++){for($j=0;$j<8;$j++){echo $j==3?' ':($j==6?'の':'ファン');}echo '<br>';}
```

PHPの三項演算子は普通にネストして使おうとすると期待通りに動かない（ [PHPで三項演算子を二重にするとどうなるか？](https://qiita.com/clown0082/items/ce0eb19cdda9379858ca)参照）ため右辺の三項演算子を()で括ることによりネストして使えるようにしています。
ただしバグの温床になりやすいので実務では使用厳禁です。

## 「ファン」の後ろの文字をサフィックスと捉えてみる
```php
<?php for($i=0;$i<10;$i++){foreach(['','',' ','','の','<br>'] as $s){echo 'ファン'.$s;}}
```
[こちらのコメント](https://qiita.com/yamamoto_hiroya/items/2633491dd4c7f6550c1d#comment-468d9d20953f110b2341)をヒントに、サフィックスを配列にしてforeachでループさせてみました。
空の要素が3つもありますが考え方は凄く好きです。

## 「ファン」を別文字にして置換してみる
```php
<?php for($i=0;$i<10;$i++){echo str_replace('*','ファン','*** **の*<br>');}
```
汎用性がなさすぎてアレですが一気に短くなりました。

##さらに短くする
```php
<?php while(@$i++<10){echo str_replace('*','ファン','*** **の*<br>');}
```
forをwhileにし、条件自体にインクリメント処理を加えることで5バイト減らすことに成功しました。
@でエラー制御もしてるしここまで来るともう実用性皆無です。

## （追記）さらにさらに短くする
```php
<? while(@$i++<10)echo str_replace('*','ファン','*** **の*<br>');
```
whileブロックが1行なので{}が省略できるとフォロワーさんにアドバイス頂いたのと、ショートタグを有効にすれば<?phpも省略できると気付いたので結果更に5バイト減らすことに成功しました。

## （さらに追記）ショートタグとdisplay_errors=offの複合技
```php
<?=str_repeat(str_replace(a,ファン,'aaa aaのa<br>'),10);
```
@rana_kualu さんのコメントをヒントに、str_repeat()を使用して合わせ技を考えてみました。
56バイト（日本語を2バイトでカウント、文字数だと52文字）まで減らすことができました。

# 終わりに
初心者の皆様におかれましては短さにこだわらずぜひ読みやすいコードを心がけて頂ければと思います。
CronJob をその場で Job を作って実行する方法

CronJob を書いた時に、一回実行したいときや、また CronJob で失敗したときなどで、もう一回実行したい時がたまにある。
その時に、わざわざ `kind: Job` を作らずに、 Cronjob を指定して Job を作成することができる。

- `kubectl create job -h`

```bash
$ kubectl create job -h
Create a job with the specified name.

Examples:
  # Create a job from a CronJob named "a-cronjob"
  kubectl create job test-job --from=cronjob/a-cronjob

Options:
      --allow-missing-template-keys=true: If true, ignore any errors in templates when a field or map key is missing in
the template. Only applies to golang and jsonpath output formats.
      --dry-run=false: If true, only print the object that would be sent, without sending it.
      --from='': The name of the resource to create a Job from (only cronjob is supported).
  -o, --output='': Output format. One of:
json|yaml|name|go-template-file|templatefile|template|go-template|jsonpath-file|jsonpath.
      --save-config=false: If true, the configuration of current object will be saved in its annotation. Otherwise, the
annotation will be unchanged. This flag is useful when you want to perform kubectl apply on this object in the future.
      --template='': Template string or path to template file to use when -o=go-template, -o=go-template-file. The
template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
      --validate=true: If true, use a schema to validate the input before sending it

Usage:
  kubectl create job NAME [--from=CRONJOB] [flags] [options]

Use "kubectl options" for a list of global command-line options (applies to all commands).
```

help にある以下を使うことで実現できる。

```bash
      --from='': The name of the resource to create a Job from (only cronjob is supported).
```

- 実行方法

```bash
$ kubectl create job <任意の名前> --from=cronjob/<CronJob の名前> -n <ネームスペース>
```

- 実行例

```bash
$ kubectl create job backup-db-2018-09-06 --from=cronjob/backup-db -n koudaiii
```
FitzHugh-Nagumo方程式をオイラー法で数値計算する

# FitzHugh-Nagumo方程式とは
wikiより
>フィッツフュー-南雲モデル(FitzHugh-Nagumo model)は、神経細胞などの電気的興奮性細胞の活動電位を表現したモデルであり、リチャード・フィッツフューと南雲仁一の名にちなんでいる。このモデルは、神経細胞の活動電位発火(スパイク)における活性化と不活性化をモデル化したホジキン-ハクスリーモデル の微分方程式を簡略化したものである。フィッツフュー-南雲モデルは以下のように僅か2つの微分方程式で表される。
https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A3%E3%83%83%E3%83%84%E3%83%95%E3%83%A5%E3%83%BC-%E5%8D%97%E9%9B%B2%E3%83%A2%E3%83%87%E3%83%AB

```math:
\frac{dX}{dt}=c(X-X^3-Y)
\\
\frac{dY}{dt}=X-bY+a
```

オイラー法で近似

```math:
X(t+Δt)= X(t)+\frac{dX}{dt}Δt
\\
Y(t+Δt)=Y(t)+\frac{dY}{dt}Δt
```

結果は以下の画像のようになります。初期値(X,Y)=(0,0)をスタートして楕円形のアトラクターに引き込まれているのが確認できますね。
(ただし、a=0.01, b=0.5, c=1.0)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/214036/a26ad500-c56c-9cba-08ab-1c0364ac35c7.png)


# コード全文(jupyter推奨)

```python
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sbn
from numpy.random import *
N = 10000
dt = 0.01

def calc(a,b,c, X, Y):
    x.clear()
    y.clear()
    for i in range(N):
        X += (c*(X-X**3-Y))*dt
        Y += (X-b*Y + a)*dt
        x.append(X)
        y.append(Y)
    return x, y

#ここのパラメータをいじって遊ぶ
calc(0.1, 0.3, 0.5, 10*(rand()-0.5), 10*(rand()-0.5))
plt.plot(x,y)
plt.show()
plt.plot(x)
plt.plot(y)
```

#初期値を変化させて収束性を確認
![image.png](https://qiita-image-store.s3.amazonaws.com/0/214036/e04d597a-a903-5b44-aac3-b1dbbb27a4d7.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/214036/80abc897-b134-ece7-fb98-340e80f09d1a.png)
マイグレーションの基礎

# これは何？
[Railsガイドのマイグレーション](https://railsguides.jp/active_record_migrations.html)を後で扱いやすいようにまとめました。

# コマンドで生成するマイグレーション
`bundle exec rails generate migration hogehoge`
の`hogehoge`の部分を変えることで色々作成できるようなのでまとめます。

- AddXXXToYYY カラム名:型 カラム名:型 ・・・
- RemoveXXXFromYYY カラム名:型 カラム名:型 ・・・
- CreateYYY カラム名:型 カラム名:型 ・・・

`YYY`：テーブル名（複数形）
`XXX`：カラム名（複数カラム追加する場合は適当で良い）

上記はよく使うやつですが、[こちら](https://edgeapi.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#method-i-add_reference)を参照するといかにいろんなコマンドが用意されてるかがわかるので必要に応じて使ってください。

僕の場合は、上記だけ最低限押さえた上で、あとはマイグレーションファイルを自作して行く形でいいのかなーと思ってます。

### 注意点
ちなみに、上記ではテーブル名を指定するために複数形で`YYY`を記載してましたが、
モデルを生成する時にはテーブル名ではなくてモデルのクラス名を指定するので単数形となる点を注意してください。

`bundle exec rails generate model User name:string`
`bundle exec rails generate migration CreateUsers name:string`

# 自作するマイグレーション
## まずは基礎
下記は、usersにnameカラムがあるテーブルを作成するファイルです。

```
create_table :users do |t|
 t.string :name
end
```

なお、これだけでも主キーの`id`が追加されるので安心して下さい。

よく使うオプションを付け加えると下記のようになります。

```
create_table :users do |t|
 t.string :name
 t.string :email, null: false
 t.boolean :dev, null: false, default: false
end
```

## テーブル変更
```
change_table :users do |t|
 t.remove :email, :password
 t.string :name
 t.index :name
 t.rename :latitude, :lat
end
```

## カラム変更
コマンドでカラム変更をする方法がなかったですが、簡単です。
すでに、
`add_column :users, :name, :string`
でカラムが作成されてるものの型を変更したいときは下記のようにします。
`change_column :users, :name, :text`

後で、よくNullを禁止したいとかDefault値を入れたくなることが多いので、その参考を記載しておきます。

`change_column :users, :email, :string, null: false, default: "test@gmail.com"`

## ロールバック
直前に行ったマイグレーションが間違っていて、訂正したい場合は下記のコマンドを入力すれば元に戻ります。

`bundle exec rails db:rollback`

これは直前のマイグレーションのロールバックとなりますが、
マイグレーションを複数ロールバックしたい場合はSTEPパラメータを含めれば一気に元に戻すことができます。

`bundle exec rails db:rollback STEP=4`

これで最後に行った4つのマイグレーションがロールバックされます。

## その他
- DB削除
    - `bundle exec rails db:drop`
- 別環境でのマイグレーション実行
    - `bundle exec rails db:migrate RAILS_ENV=test`
IntelliJ IDEA でソースコード管理するときに changelist を使うのが便利

# 動機
今まで SourceTree を使ってソースコードを管理していましたが、以下の理由でやめることにしました。

* SourceTree は重い
* IntelliJ でコーディングしているのに別アプリと往復するのは手間
* IntelliJ にはせっかく様々な機能があるので使い倒していきたい

そこで IntelliJ の changelist を使って上手くソースコード管理すべく、SourceTree はいったん封印しました。結論からいうと、changelist は使いやすいと思います。changelist を活用するようにしてからずっと SourceTree を起動していません。

# 環境
IntelliJ IDEA 2018.1.6 (Ultimate Edition)

# changelist とは

* 名前の通り、変更を管理するリストのこと
* 最初は Default と Unversioned Files のみ存在する
* 名前をつけることによって何のための変更なのかを管理することができる

# ここがいいんだよ changelist
* changelist ごとコミットできる
    * コミットメッセージがデフォルトで changelist の名前
    * あらかじめ行う予定のコミットごとに changelist を作成し、ソースコードを変更したら、変更内容に該当する changelist に入れていくだけで、ソースコードと一緒にコミットも管理できる
        * コミットログがきれいになってソースコードレビューしてもらいやすくなる
        * 大きい開発をするときに、明示的にやることを区切りながら開発できる
* 同じファイル内の異なる変更を異なる changelist で管理できる
    * 以下のようにしてコミットメッセージと変更内容の相違を防止できる
        * User.java でユーザを作成する処理の追加を changelist1 で管理
        * User.java でユーザを削除する処理の追加を changelist2 で管理
    * 以下のスクリーンショットのように、緑色の `[` で表現されている範囲単位で管理できる
        * 緑色の `[` をクリックすれば、変更箇所の revert や別 changelist への移動も可能
            * 新しい changelist を作り、そこに移動させることもできる
        
※ 別個に管理したい変更が同じ緑色の `[` 範囲内だと 1 つの changelist にせざるを得ず辛い

![image.png](https://qiita-image-store.s3.amazonaws.com/0/218706/96b845a9-e534-0a02-48b6-5e4754796724.png)

## changelist を作る
* 作業ブランチを切る
* Command+9 を押して Version Control を開く
* Local Changes タブをクリックする
* 左側メニューの + をクリックして新しい changelist をつくる
    * 名前は開発ルールに沿ったり自分の使いやすいようにしたりするのが一番だと思います
    * 私は「チケット名」＋「コミット内容を一言で表したもの」にしています

![image.png](https://qiita-image-store.s3.amazonaws.com/0/218706/bd758ec6-cda5-bb70-400b-df446ba51edf.png)
Proxy環境下でFirebaseのログインにハマった

初心者が軽い気持ちでFirebaseを使おうとしたら、
Proxyに阻まれ、何時間も無駄にしたのでメモしました。


# とりあえず結論

環境変数にProxyの設定を書けばいい

|変数名|変数値|
|:--:|:--:|
|http_proxy|http://ユーザ名:パスワード@proxy.example.com:8080|
|https_proxy|http://ユーザ名:パスワード@proxy.example.com:8080|
※ユーザ名やパスワードに記号（@とか\とか）があるときは[URLエンコード](https://qiita.com/nshinya/items/08db9be2c5255c91e6a0)する必要がある


# 環境

- Windows (Version 6.1.7601)
- Firebase (Version 4.2.1)
- npm (Version 6.2.0)


# 手順

###1. Firebaseのインストール
```
npm -g install firebase-tools
```
ちなみにnpmのProxyは下記コマンドで設定できる

```
npm config set proxy http://ユーザ名:パスワード@proxy.example.com:8080
npm config set https-proxy http://ユーザ名:パスワード@proxy.example.com:8080
```

###2. Firebaseにログイン
```
firebase login
```

コマンドを実行すると何か聞かれるのでとりあえずyesを選択　("y"と入力)

```
? Allow Firebase to collect anonymous CLI usage and error reporting information? (Y/n)
```

すると認証用の長いURLが表示されて、勝手にブラウザが立ち上がる

```
Visit this URL on any device to log in:

https://accounts.google.com/o/oauth2/...(長いので省略)

Waiting for authentication...
```

Firebaseにログインするアカウントを選択して
![googlelogin.PNG](https://qiita-image-store.s3.amazonaws.com/0/287213/67dd778f-36cf-cc50-70a8-b5799bc0b61a.png)
Firebase CLIのアクセスを許可する
![googlepermission.PNG](https://qiita-image-store.s3.amazonaws.com/0/287213/c0f58cd3-ac2f-a68d-298d-d01686d29fa1.png)
だがしかし...ログインに失敗する
![Oops.PNG](https://qiita-image-store.s3.amazonaws.com/0/287213/94676b06-bf88-fa3a-bd49-2deb786262e5.png)
>**Firebase CLI Login Failed**
The Firebase CLI login request was rejected or an error occurred.
Please run firebase login again or contact support if you continue to have difficulty logging in.

なぜならProxyに阻まれているから...
ということで、Proxyを設定する

###3. Proxyの設定
『コントロールパネル』>『システムとセキュリティ』>『システム』>「システムの詳細設定」
『システムのプロパティ』>「環境変数」>「ユーザー環境変数」>「新規」からそれぞれ以下を設定する

|変数名|変数値|
|:--:|:--:|
|http_proxy|http://ユーザ名:パスワード@proxy.example.com:8080|
|https_proxy|http://ユーザ名:パスワード@proxy.example.com:8080|

「OK」をクリックして設定完了

###4. Firebaseにログイン（再挑戦）
コンソールを立ち上げ直して、再度Firebaseへログインを実行

```
firebase login
```

さっきと同じ手順でFirebase CLIのアクセスを許可すると
![Woohoo.PNG](https://qiita-image-store.s3.amazonaws.com/0/287213/aaafbd04-ddd0-7219-a3b0-0e15c2008c11.png)
無事ログイン成功!!

```
+  Success! Logged in as [googleアカウント名]
```
こんなことに何時間も浪費したことが悔しいです


#参考にしたページ
- **FirebaseのProxyのこと**
 [Unable to deploy behind a proxy #155](https://github.com/firebase/firebase-tools/issues/155)

- **WindowsのProxyのこと**
 [Proxy配下での環境設定について　Guide&Memo](http://taisun.github.io/other-page/base.html)

- **URLエンコードのこと**
  [認証情報に記号があるときのproxy設定](https://qiita.com/nshinya/items/08db9be2c5255c91e6a0)
【バッチ】時刻を比較して処理を終了させる

こんにちはtsuttieです(*'▽')
今回はバッチファイルで時刻の比較をしたときにハマったポイントを記載します。

#1. なにをしたのか

バッチファイルは手軽で好きなのですが、如何せん癖が強くてあんまり得意ではありません・・・
今回、時間が来たら処理を終了するバッチファイルを作成するときにも少しハマりましたので書いていきたいと思います。

#2. サンプルコード

結論から書いてしまいます。
私は以下のサンプルコードを作成しました。

■処理の流れ
for文で何らかの処理を実行 (今回は適当に15秒待機にしています)
↓
所定の時間(12時)を過ぎているか比較
↓
過ぎている場合には処理を終了 (そうでない場合は繰り返し)

```
@echo off
rem 終了時刻
set STOPTIME="12:00:00.00"

rem 実行
setlocal ENABLEDELAYEDEXPANSION
for /L %%a in (1,1,100) do (
	echo %%a
	timeout /T 15
	echo !TIME!
	echo %STOPTIME%
	rem 時刻が過ぎていれば処理終了(下記に追記)
	if "!TIME!" gtr %STOPTIME% (
		echo timeover
		exit
	)
)
endlocal
pause
```

一見簡単そうなのですが(いや、簡単でした)ちょっとしたハマりポイントがありましたので
下に記載しておきます。

#3. ハマったポイント

ハマったポイントは2点です。

**■ 遅延環境変数**
はじめ、現在時刻を取得するために`%TIME%`を使っていたのですが、
更新がされない、という問題が発生しました。
ちょっと調べたところ**遅延環境変数の展開**をしないといけないとか。

変数を反映させて処理を実行していくには何かしらの処理を実施しなければならないということですね。
この対応にあたるのが以下の部分になります。

引用：`for文の中で値を変化させたい場合はfor文全体を、「setlocal enabledelayedexpansion」と「endlocal」で挟みます。また、for文内で使用する変数は「%」ではなく「!」で囲みます。`

つまりサンプルコードではfor文を囲んでTIMEを処理時の時刻として扱いたい場合には以下のように記載します。

```
setlocal ENABLEDELAYEDEXPANSION
for {繰り返し処理内容} (
--------------------------------
この間でTIMEを使用する場合には
%TIME%
ではなく
!TIME!
と表記する。
--------------------------------
)
endlocal
```

解説は以下です。
引用：`「enabledelayedexpansion」は「遅延環境変数の展開」であり、「変数に値が代入されるのが遅延させる（遅らせる）」という意味でした。すなわち、同時に変数を代入するのではなく、変数の代入をコマンドを一行ずつ読み込んでいく時に遅らせるのです。`

参考：[知識ゼロからのwindowsバッチファイル超入門：forループの中で値を変化させる](https://jj-blues.com/cms/wantto-changevalueinfor/)

これで環境変数の問題は解決しました(^^♪

**■ 時刻の比較**
ひとまず、時刻を処理時の時刻にすることは出来ましたが、今度はif文で時刻の正しい比較ができない。という問題が出てきました。
終了設定時刻を過ぎていたらバッチ処理を終了。なので以下のように記載していましたがうまく動きません。

```if !TIME! gtr 12:00:00.00 {処理}```

うーむ・・・
色々悩みましたが、↓の記事を見つけました。
参考：[バッチファイル内で時刻の大小を比較する](http://d.hatena.ne.jp/kitasi/20130915/1379254779)

_バッチファイル内では時刻は文字列として大小を比較しないときちんと比較してくれないとのこと_

つまり↓のように書けばいいんですね。

```
if "!TIME!" gtr "12:00:00.00" {処理}
```

こんな感じです。これで時刻の比較もばっちり出来ました(^^)/

#4. まとめ

ということで、今回はバッチファイル作成時にハマったポイントについて忘備録的な意味も込めて書いてみました。やっぱり癖が強いように思いますね。そしてデバックが難しい・・・でも、手軽に使えて、便利なので使っちゃってます。
今後も使う機会がありそうなので、なにかハマったことがあったら記載したいと思います。

何かご指摘等ありましたら、コメントいただければ幸いです。
よろしくお願いします。('◇')ゞ
画面によってstatus barの色を変える方法(Android JetPack / Navigation)


## はじめに
画面によってstatus barの色を変える方法です。
Android JetPackのNavigationを使っている場合にフォーカスして記載します。
Navigationは`1.0.0-alpha05`を使用しています。
イメージはこんな感じです。
![sample.gif](https://qiita-image-store.s3.amazonaws.com/0/202533/dde60091-1d32-a492-fe0c-f64e9e3c478f.gif)

サンプルに使用した元のアプリはNavigationのcodelabのものを使わせていただきました。
https://github.com/googlecodelabs/android-navigation

## 対応方法
順を追って説明しますが、対応手順は３つです。

### 1.ステータスバーの色定義
やり方は色々あるかと思いますが、整理しやすいようにここではステータスバーの色をenumで定義しました。

```kotlin:StatusBarColor.kt
enum class StatusBarColor(private val key: String, val color: Int) {
    BLUE("blue", android.R.color.holo_blue_dark),
    RED("red", android.R.color.holo_red_dark),
    BLACK("black", android.R.color.black);

    companion object {
        fun findByKey(key: String?): StatusBarColor =
                StatusBarColor.values().find { it.key == key } ?: BLACK
    }
}
```

`findByKey`は、引数はnullableで、戻り値はnon-nullにした方が後々便利です。

### 2.各Fragmentにステータスバーの色を定義
Navigationのxmlにおいて、各Fragmentのargumentにステータスバーの色情報を与えます。コード上でこれを参照して、ステータスバーの色を変えます。

```xml:mobile_navigation.xml
<navigation ...>
    <fragment ...>
        <argument
            android:name="statusBarColor"
            android:defaultValue="blue"
            app:argType="string" />
        ...
    </fragment>
    <fragment ...>
        <argument
            android:name="statusBarColor"
            android:defaultValue="red"
            app:argType="string" />
        ...
    </fragment>
    ...
</navigation>
```

- `android:name` : コード上でargumentから値を取り出すときに使います
- `android:defaultValue` : 先ほど定義した`StatusBarColor`の`key`を指定します
- `app:argType` : 文字列（`string`）として定義します。先頭の「s」は小文字なのでご注意を。


### 3.NavControllerにリスナー設定

```kotlin:MainActivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    ...(略)
    findNavController(R.id.my_nav_host_fragment).addOnNavigatedListener { _, destination ->
        // argumentからstatus barの色情報を取得する
        val statusBarColor = StatusBarColor.findByKey(destination.defaultArguments.getString("statusBarColor"))
        // status barの色を変更
        window.statusBarColor = ContextCompat.getColor(this, statusBarColor.color)
    }
}
```
`NavController`に対して`OnNavigatedListener`を設定します。これにより、Navigationでの画面遷移完了時に通知を受け取ることができます。その際、引数で`NavDestination`が受け取れます。この`NavDestination`は画面遷移したFragmentの情報を持っており、ここに上で定義した`argument`も含まれています。

よって、この`destination`から`defaultArguments.getString`でString値を取り出し、`StatusBarColor`へと変換します。
このとき、string値がnullだったり、argumentに定義がなかったりした場合でも、`StatusBarColor.findByKey`の引数がnullableで戻り値がnonnullだと、便利に使えます。

あとは、`StatusBarColor`のcolorResIdを使って実際にステータスバーの色を変えるだけで完了です。


### 関連リンク
[Navigationでバックキーをハンドリングする](https://qiita.com/mkosuke/items/999fdad16a38ad74e345)
php-master-changes 2018-09-05

朝にやるかなー、と思ってたけど時間が取れず今更新。北海道（本社がある）の地震大変みたい。

# 2018-09-05
## TysonAndre: Fix typos in UPGRADING.INTERNALS
- https://github.com/php/php-src/commit/86c930e268759172d41f89a4f0148991dec27865
- UPGRADING.INTERNALS の typo を修正

## petk: Remove HAVE_STDDEF_H
- https://github.com/php/php-src/commit/6c1ff61a368a26c8f2cbf383aa8a26fc30cf59ef
- autoconf の古いシステム向けマクロ HAVE_STDDEF_H を削除
- \<stddef.h> があるかをチェックする用だが、C89 で入ってるヘッダだし、すでにコードの色んなとこで無条件に include もしてるので

## dstogov: Get rid of ZEND_ACC_CTOR, ZEND_ACC_DTOR and ZEND_ACC_IMPLEMENTED_ABSTRACT
- https://github.com/php/php-src/commit/8939c4d96b8382abe84f35e69f4f6ebd6f0f749d
- メソッドがコンストラクタ/デストラクタかどうかを判定する用のフラグ ZEND_ACC_CTOR / END_ACC_DTOR を削除し、継承処理で内部的に使われていた abstract メソッドの実装かどうかを判定する用のフラグ ZEND_ACC_IMPLEMENTED_ABSTRACT を削除

## cmb69: Fix [#74454](https://bugs.php.net/bug.php?id=74454): Wrong exception being thrown when using ReflectionMethod
- https://github.com/php/php-src/commit/c0a389a9277070f5ef53c230f34aa5072a9f0985
- あるクラス A がパースエラーとなるファイルに定義され、オートローダ経由で ReflectionMethod() から呼ばれる際、ParseError ではなく ReflectionException が例外として投げられていたのを修正
UIImageViewにAspectFitで画像を入れた時の実際の表示サイズを取得する方法

縦横の比率を見て計算してもできるけどもっと簡単な方法があった。

AVFoundationのAVMakeRectメソッドを使う。

```swift:AVUtilities
public func AVMakeRect(aspectRatio: CGSize, insideRect boundingRect: CGRect) -> CGRect
```

#使い方
```swift
// インポートする
import AVFoundation

func calculateImageSize() -> CGSize {
	let image = UIImage(named: "yourImage")!
    let imageSize = AVMakeRect(aspectRatio: image.size, insideRect: self.imageView.bounds).size
    return imageSize
}
```

AspectFitで画像を入れた後、UIImageViewのサイズを変えたりすれば上寄せとかできるから地味に便利。
メモ: Firebase

## 参考

* https://devchallenges-blogs.web.app/Top-5-free-HOSTING-site/
* https://firebase.google.com/

## 準備

```
npm install -g firebase-tools
firebase login
firebase init
```

![スクリーンショット_2018-09-06_13-13-06.png](https://qiita-image-store.s3.amazonaws.com/0/25728/584d21b2-8dc6-b0c7-77d7-43c2cb02644c.png)

* Hosting にカーソルを合わせて Spaceキーで選択
    * 後は全てEnterキー

## ローカルでの動作確認

```
# プロジェクト一覧を確認
firebase list

# localhost:5000 にLISTEN
firebase serve --project プロジェクト名
```

http://localhost:5000 にアクセスすると以下のような画面になる

![5000.png](https://qiita-image-store.s3.amazonaws.com/0/25728/3837ac00-03e6-8685-fbff-e14d54b2295f.png)

![スクリーンショット_2018-09-06_13-35-51.png](https://qiita-image-store.s3.amazonaws.com/0/25728/fde5e866-e4ac-04b8-ba34-ca8e566f99da.png)

* `<script>`タグをhtml中に貼り付ける。


## デプロイ

* ./public/ 以下がUPされる。

```sh:
# デプロイ
firebase deploy
もしくは
firebase deploy --project プロジェクト名

# 画面確認
firebase open hosting:site --project プロジェクト名
```

## Realtime Databaseのサンプル

* 初期段階だと Cloud Firestore が選択されているので、Realtime Databaseに切り替える。

![スクリーンショット_2018-09-09_10-39-39.png](https://qiita-image-store.s3.amazonaws.com/0/25728/639cccb6-256b-0162-0730-104ab14b8c05.png)


以下投稿画面を作ってみる。

![2.png.png](https://qiita-image-store.s3.amazonaws.com/0/25728/9ef1df04-ffba-a666-8f6c-623cdb1bb53a.png)

* 以下どこかのホームページに載ってあったサンプルを元にしました。

```html:sample.html
<script src="https://www.gstatic.com/firebasejs/5.0.1/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/5.0.1/firebase-database.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-alpha1/jquery.min.js"></script>
<script>
  // Initialize Firebase
  var config = {
  (略)
  };
  firebase.initializeApp(config);
</script>

<div>
    <input id="name" placeholder="名前">
    <input id="message" placeholder="メッセージ">
    <button id="send">投稿</button>
</div>
<ul id="messages"></ul>

<script>
    // データベースの参照を準備
    var messagesRef = firebase.database().ref().child('messages')

    // 既存メッセージを表示
    messagesRef.on('child_added', function(snapshot) {
        var msg = snapshot.val();
        $('<li>').text(msg.name + ': ' + msg.body).prependTo('#messages');
    });

    $('#send').click(function() {
        // 新規メッセージを投稿
        messagesRef.push({
            name: $('#name').val(),
            body: $('#message').val()
        });
    });
</script>
```
ERC721について調べてみる

# ERC721について調べてみる

## ERC721とは
ERC20，ERC223などと同じくイーサリアムトークンの規格の一つ
既存のERC20，ERC223、あるいは他の一般的な暗号通貨とは異なり
Non-Fungible Token（代替不可能なトークン）という特徴を持つ。

## 代替不可能なトークンとは
一般的なトークンはどの1トークンも別の1トークンと同じ価値を持ちますが
代替不可能なトークンの1トークンは別の1トークンとは別物として扱われます。
つまり、一般的なトークン（代替可能なトークン）は通貨のような考えを持っているのに対し
代替不可能なトークンは物や権利など、それぞれ価値が異なる可能性がある性質を持ちます。
また、この性質上1トークンが最低単位となりそれ以上の分割は行なえません。

## ERC721が使用された例
**CryptoKitties**
ERC721を使用した例では最も有名な猫のゲームです
1トークンをそれぞれ猫1匹として扱い、猫2匹を交配させることにより新しい猫（トークン）が誕生します
**Chain Monsters**
ポケットのモンスターみたいなゲームのようです
iOS、Android版のアプリが公開されています。

## おわりに
次回は実際にERC721トークンの作成をしてみようと思います
8/16講義内容

#名前空間

- クラスの名前が被っていても呼び出せる
- namespace 名前空間の名前;　で指定できる
    - 一つのファイルに複数つけることが可能
    - サブの名前空間をつけることが可能
    - 名前空間が長すぎる場合
        - use you/me/her/him as him;　こうするとhimで　you-himを名前空間に指定できる


#オブジェクト指向
- メリット：変更が予想されるところをクラスとして別にまとめておくことで変更に対応しやすくなる
- クラス：主要な設計図
- インスタンス：設計図となるクラスを実際に利用したもの
- カプセル化：外部から見て簡単に見えるもの。クラス内での変更をそのクラス内で止めることができる
- ポリモーフィズム：異なる動作を同じ命令で実現すること
- メソッド：クラスの中で使われる関数
- プロパティ：クラスの中で使われる変数
【備忘録】Windows 10 で Elixir をインストールするコマンド

# 今回は備忘録です

# 参考サイト
@alucky0707 さんのこちらの記事
https://qiita.com/alucky0707/items/e80383d57dee5fe26e64

# さて本題
上記サイトは2014年のもので
今現在は2018年です。
今じゃコマンドプロントはかなり影を潜めています。
かつ、ここに書かれているコマンドではうまくいかなくなっているようです。

# なので新しいWindows10でもできるようにちょっと工夫してみました。

※PowerShellの管理者実行が必要です。

```
powershell.exe -NoProfile -ExecutionPolicy unrestricted -Command "iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))" && SET PATH=%PATH%;%systemdrive%\chocolatey\bin
choco feature enable -n useFipsCompliantChecksums
cinst elixir
```

こんな感じ。

# 3行になったけど・・・

```
choco feature enable -n useFipsCompliantChecksums
```
これを追加しています。
どうも、Chocolateyの仕様で、Elixirを入れる際は、このチェックサムチェックを受けるようにしないとこんなエラーがでて入れられないようになっているようです。

```
FIPS Mode detected - run 'choco feature enable -n useFipsCompliantChecksums'
 to use Chocolatey.
When FIPS Mode is enabled, Chocolatey requires useFipsCompliantChecksums feature also be enabled.
```

というわけでただいま絶賛インストール中でございます。
時間がかかるらしいのでまったり待ちましょう。

あ・・・終わったｗ
![image.png](https://qiita-image-store.s3.amazonaws.com/0/269159/e7cceab2-7d8a-cfae-3206-0dd992b98e2d.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/269159/0e48fe87-38ca-69b4-05d3-7e9d2cfd309a.png)
rspecでrake taskのテストをする

[rake_shared_context](https://github.com/willnet/rake_shared_context) このgem使います！

```ruby:Gemfile
gem 'rake_shared_context'
```
詳しくはgithub見ればわかりやすいです。(　´∀｀)つ ミ

丸投げ感半端ないので、ポイントとしては...

```ruby
describe "reports:generate" do
end
```

describeにtask名を書く事です。
そうすればsubjectで拾ってくれます。
GASトリガーでちょっと便利な裏技

# はじめに
Google Apps Script（GAS）でトリガーを設定する際に正確な時間単位での設定が出来なったので
その際に役立ったやり方を紹介します。

# 背景
毎時30分とか40分とか「分」を指定して1時間単位でプログラムを実行させたい。
<img width="792" alt="qiita_gas.png" src="https://qiita-image-store.s3.amazonaws.com/0/61433/9dea45b3-810c-d40d-2249-3e032bc78e01.png">

上記画像のように画面上で設定出来るが、多少のタイムラグがあるため「分」までは正確に指定出来ません。

# 解決方法
Scriptで下記のように制御させます。

```sample_trigger.gs
function myFunction() {
  // トリガー全削除
  var triggers = ScriptApp.getProjectTriggers()
  for(var i=0; i < triggers.length; i++) {
    ScriptApp.deleteTrigger(triggers[i]);
  }
  
  // 1時間後の40分に起動されるようトリガーを設定
  var trigger_setTime = new Date();
  trigger_setTime.setHours(trigger_setTime.getHours() + 1);
  trigger_setTime.setMinutes(40); 
  ScriptApp.newTrigger("myFunction").timeBased().at(trigger_setTime).create()
}
```
コーディングする前に決めて置きたいルール

```
そろそろ見直し必須。
```

## 最低限の統一したい項目
* 文字コード
  * 基本は utf-8
    * 統一しないと文字化ける
* 改行コード
  * 基本は lf（エンジニアさんに確認するのがベター）
    * cr, crlf, lf が混在するとシステムエラーが出てエンジニアさんが苦労する（らしい）
* インデントの種類
  * 基本は space（tabは環境によって見た目が異なる…らしい）
    * tabとspaceが混在するとインデントがガタガタになってエディタの素敵な機能が使えなくなる
    * 混在してなくてもガタガタだとエディタの素敵な機能が使えなくなる
* インデントのサイズ
  * 基本は 2字
    * 理由は「インデントの種類」と同じ
    * 追加理由で、space 4字など文字数が増える=ファイルサイズが大きくなる

※改行コード、インデント文字（tabやspace）は違いに気づけるように、常に表示させるのがおすすめ。<br>
表示方法は「不可視文字 表示 エディタ名（atom、sublime…など）」で検索。

上記を手軽に統一するために**EditorConfig**がおすすめ。<br>
※エディタがdreamweaverの人は…手動で設定。

## EditorConfigについて
公式サイト： [EditorConfig](http://editorconfig.org/)

* メジャーなエディタに対応している（dreamweaverは対応してない）
* 導入も設定も楽
  * 導入=プラグインをインストールしてプロジェクトのルートディレクトリに「 .editorconfig 」ファイルを置く
  * 設定=「 .editorconfig 」に設定内容を記述する（下記サンプルソース）


  ※ただし、charset = shift_jis を指定する場合は要注意！<br>
  （下記リンクの「コラム：サポート外の文字コードを指定した場合の挙動」）<br>
  [チーム開発に効く環境構築術　第1回 EditorConfigのススメ](https://app.codegrid.net/entry/editorconfig)

```
# コメント書きたい時は#で始める（※1行コメントです）

root = true

[*.{html,scss,css,js}]
end_of_line = lf
insert_final_newline = true
charset = utf-8
indent_style = space
indent_size = 2
```

※scssコンパイルするからcssいらないかも。

書き方の参考： [.editorconfig の書き方](http://qiita.com/inabe49/items/d81fed3cf58ad751d915)<br>
EditorConfig全般の参考： [チーム開発に効く環境構築術　第1回 EditorConfigのススメ](https://app.codegrid.net/entry/editorconfig)<br>

## コーディング規約
ルールやベースなどを作っておいた方が良いもの。

### ディレクトリ構成
規模によって適宜どこにどのファイルを格納するか決めておく。<br>
[便利な記号](http://qiita.com/paty-fakename/items/c82ed27b4070feeceff6)<br>

### 対象ブラウザへの対応
前もって確認して、使用できるかできないかある程度検討しとく。<br>

### 命名規則
* 命名規則が必要なもの
    * ディレクトリ名
    * ソースファイル名
    * 画像やその他pdf、zip…etcのファイル名
    * ID、クラス名


* 基本的な共通ルール
    * 半角英数字のみを使用。
    * 機種依存文字の使用禁止。
    * 必ずアルファベットからはじめる。数字からはじめてはいけない。
    * 全角スペース、半角スペース（Space）の使用禁止。
    * 「\」,「/」,「\*」,「:」,「?」,「<」,「>」,「|」,「＄」これらの文字の使用禁止。


* その他ルールが必要そうなもの
    * 大文字、小文字の使用ルール（小文字のみ使用とし、キャメルケース使用禁止など）
    * キャメル、スネーク、チェインケースの使いどころ
    * js用のID、クラスの接頭辞に「js-」をつけ、そのクラス名にスタイルは指定しないなど。


#### 命名規則 - もっと詳しく - ID、クラス名
* 概ねこれでOK→（[BEMの考え方を基にしたHTML / CSSのid・classの命名規則](http://qiita.com/kitaro729/items/3189ded5647475bc2ae7)）
* 上記だと名前が長くなりすぎるので、文字省略のルール（省略する場合は単語の先頭の子音3文字にする）など...他もろもろ

#### 細かい記述のルールなど
* ここ一通り読めばOK→ [ガイドライン・スタイルガイドのまとめ](http://coliss.com/articles/build-websites/operation/work/css-guidelines-for-developers-2015-summer.html)


##### その他参考になりそうなもの
* [表記ルール: 企業サイトで使用する「ひらく漢字」「ひらかない漢字」](http://coliss.com/articles/build-websites/operations/notational-convention-for-writing.html)
* [Google Design](https://design.google.com/)
* [Material Design（Google）の日本語解説](http://dev.classmethod.jp/smartphone/android/google-material-design/)
* そのうち導入できればいいな → [スタイルガイドジェネレータを比べてみた](http://qiita.com/shwld/items/d41ba36e9fd2e636c723)
SQS使ってみたよ

# はじめに
クローラーを構築する際にLambdaと組み合わせてみたらとても便利だったので知見も合わせて記録しておきます。


# SQSとは
Simple Queue Service (SQS)の通りメッセージキューイングサービス
メッセージキューイングとは？？？
> 一般にメッセージキューイングでは、送信側のクライアントはメッセージを受信側に直接送るのではなく、キューと呼ぶメッセージの入れ物に渡す。キューは多数のメッセージをためておくことができる。受信側のクライアントは、キューからメッセージを受け取り、処理する。これが基本的な仕組みだ。

# 気になる料金
[AWS料金表](https://aws.amazon.com/jp/sqs/pricing/)

- 受信：無料
- 送信：ほぼ無料
    - 最初の 1 GB/月 | 無料
    - 10 TB まで/月 | $0.140 GB あたり
    - ...以下省略

# キュー作成画面
<img width="754" alt="qiita_sqs.png" src="https://qiita-image-store.s3.amazonaws.com/0/61433/84bc5306-2b48-f0b0-dc8d-1749e907393c.png">


### 各項目説明
- キュー属性
    - デフォルト可視性タイムアウト
        - 受信(配信)したメッセージが他のサービスから取得出来ない時間（排他制御的なイメージ）
    - メッセージ保持期間
        - 受信したメッセージの保持期間
    - 最大メッセージサイズ
    - 配信遅延
        - 受信したメッセージの配信を意図的に遅延させることが出来る。
    - メッセージ受信待機時間
- デッドレターキュー設定（一定回数送受信を繰り返した場合にデッドレターキューとして別のキューへ送信してくれる仕組み）
    - デッドレターキュー
        - 作成したキュー名
    - 最大受信数
        - リトライ回数

# まとめ
個人的にはデッドレターキューがとても便利でリトライ処理書かなくていいし、エラーとなったキューも保持期間設定して勝手に削除されるので運用も楽ちんになりました:v_tone1:
スコープ演算子　::　現場でよく発生する事

# スコープ演算子とは
奥が先に実行するようにする

```
folder: 
  a.rb
    class A
      self.test = 3

  A.test -> 3
  module
    a.rb
      class A
        self.test = 4

    b.rb
      A.test => 4
      ::A.test => 3


DB
 core
    class Order


 backend
  services
    class Ordera

    gem ../core


  jobs
    class Job
      ::Order.
```
# 周辺知識
rails engine
→複数のファイルに分ける
→外部のアプリ（gem）で実装した機能が取り込まれる
https://railsguides.jp/engines.html
キュー
https://wa3.i-3-i.info/word14716.html
job
→キー操作を行うもの
https://railsguides.jp/active_job_basics.html
非同期
→jobで非同期を扱う事がおおい

# 現場で起こる事象
不定期に起こる事象。（ooが表示されないなど）

# スコープ演算子による影響

rails engineの場合
DB　のapp と　　フロントのappを分けていたりする。

その場合、

フロントとDB側で、同じモデルが存在した場合、
不定期なエラーを起こす可能性がある。

# 発生原因

ローカル環境では発生しないらしい。

そのため、pullrequestでレビー者が見落とす事が発生する。
Line botの入門の際に参考にしたサイト (Node.js / Heroku)

##目的
今更ながらですが、Node.jsとHerokuを使って、オウム返しのLine botを作成してみる。

##Node.jsをHerokuにデプロイ
Herokuをろくに触ったことがないので、
会員登録後、下記の記事を一通りなぞってみる。
参考: https://qiita.com/yfujii01/items/d675f654f1fcce3b9098
 

##Line botを作成
参考: https://qiita.com/n0bisuke/items/ceaa09ef8898bee8369d
SSL証明書の有効期限や内容を確認する方法一覧

コマンドラインでSSL証明書の有効期限や内容を確認するコマンドを収集した。

## SSL証明書の有効期限の確認

### ローカルファイルの確認
```bash
openssl x509 -noout -dates -in /etc/pki/tls/certs/example.com.crt
```

### サーバー側の確認

#### https
```bash
echo | openssl s_client -connect example.com:443 2> /dev/null | openssl x509 -noout -enddate | cut -d= -f2
```

#### smtp
```bash
openssl s_client -connect example.com:25 -starttls smtp | openssl x509 -noout -dates
openssl s_client -connect example.com:587 -starttls smtp | openssl x509 -noout -dates
```
25番ポートや587番ポートを指定する際は `-starttls smtp` を指定しないと以下のようなエラーが出力される。

```bash
139641776269136:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:s23_clnt.c:794:
unable to load certificate
140160526772048:error:0906D06C:PEM routines:PEM_read_bio:no start line:pem_lib.c:707:Expecting: TRUSTED CERTIFICATE
```

## SSL証明書のディスティングイッシュネームの確認
```bash
openssl x509 -noout -subject -in example.com.crt
```

## .
```bash
openssl x509 -noout -issuer -in example.com.crt
```

## 証明書ファイルの確認
```bash
openssl x509 -noout -text -in example.com.crt
```
```bash
openssl asn1parse -in example.com.crt
```

## 秘密鍵ファイルの確認
```bash
openssl rsa -noout -text -in example.com.key
```

## CSRファイルの確認
```bash
openssl req -noout -text -in example.com.csr
```

## サーバーのSSL証明書の確認
```bash
openssl s_client -showcerts -connect example.org:443
```
HTTPS　　443
POP over SSL　 995
SMTP over SSL　 465
IMAPS　　993

## SSL証明書の動作確認
```bash
openssl s_server -accept 10443 -cert example.com.crt -key example.com.key -CAfile example.com.ica -WWW
openssl s_client -connect localhost:10433
```
https://bacchi.me/linux/openssl-tips/
プログラミングパラダイム

#プログラミングパラダイム
- プログラミングパラダイムとはプログラミングの方法・スタイル
- 言語ではなく概念
- 悪い結合
    - 片方を修正するともう片方も修正する必要がある結合や予想外の動作を強いられる結合
- 良い結合
    - 内部構造に依存せず、明示的なもの
- 悪い凝集
    - アトランダムに処理を集めたものや倫理的に似ている処理を集めたもの
- 良い凝集
    - あるデータに触れる処理をまとめること（通信的凝集）や、概念とデータ構造などをひとまとめにすること（情報的凝集）、一つのうまく定義されたタスクをこなせるように集めること（機能的凝集）
- 状態と副作用の支配
    - 副作用のない関数はテストしやすくバグが入る隙間がない
    - 良いモジュール化のポイントはこれを隠すこととデータとアルゴリズムをひとまとめにすること
    - EX)クラスとインスタンス化
    - 抽象化されたデータを取り扱う層は、そうでない層（抽象化されていない層）に触れることがない階層化の概念
docker for mac + angular(ng serve) + virtualbox経由でアクセス

docker-compose で起動した node 内から
ng serve で起動した angular アプリに
virtualbox(IE11検証用）からアクセスしたかったができなかった。

mac からは ng serve するときの host を 0.0.0.0 とすることでアクセスは可能。
virtualboxでmac側のip (10.0.2.2)を見に行った時にも見えるようにしたかった。

```
--disableHostCheck true

#または angular.jsonないで

{
    ...
    "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "browserTarget": "mock:build",
            "host": "0.0.0.0",
            "port": 4200,
            "disableHostCheck": true
          },
    ...
}

```

で無事見えるようになった
http://10.0.2.2:4200
[対応済]Ubuntu18.04でIntel Parallel Studio XE2018のicc, icpcが使えない件


表題の件について，日本語で検索しても該当するページが見つかりませんでした（見落としていたらすみません）。
下記サイトに対応方法が書いてありますが、備忘録代わりに要点を書いておきます。
https://software.intel.com/en-us/forums/intel-c-compiler/topic/760979

#エラー
iccもしくはicpcでコンパイルしようとすると、下記のエラーが出ます。
/opt/user/intel/compilers_and_libraries_2018.2.199/linux/compiler/include/math.h(1230)): error: identifier "_LIB_VERSION_TYPE" is undefined
  _LIBIMF_EXTERN_C _LIB_VERSIONIMF_TYPE _LIBIMF_PUBVAR _LIB_VERSIONIMF;

#対応
対処方法としては、指示されているmath.hを開いて、該当する行をコメントアウトし、代わりに下記の内容を追記します。

```c++:math.h
//_LIBIMF_EXTERN_C _LIB_VERSIONIMF_TYPE _LIBIMF_PUBVAR _LIB_VERSIONIMF;
_LIBIMF_EXTERN_C  _LIBIMF_PUBVAR _LIB_VERSIONIMF;
```

自分の環境ではこれで問題なく動きました。
vimをlua付きで再インストールする際にエラーが出た時の対処


vimプラグインの一つであるneocomplete.vimを入れるにはvimがluaが有効になっている必要がある。ということで
こちらの記事
https://qiita.com/umi/items/23a84d9ae2e05c266f7e
を参考にして

```
$ brew reinstall vim --with-lua
```
vimを再インストールしようとするもエラーでうまく行かない。

## 現状の確認
vim —versionで確認すると、今インストールされているものは

```
$ vim --version
(略) -lua (略)  
```
となっていてluaが有効になっていない。（+になってたら有効)。
これはいいとして、

```
$ brew info vim
```
で情報がかえってくるのに

```
$ brew list
```
を確認すると、vimがない。

以前homebrewでvimを入れたような気がするが、、、

vimの場所を確認すると

```
$ which vim
/usr/bin/vim
```
ここにあるvimはmacにデフォで入っているものらしい。
(homebrewでインストールしたvimは/usr/local/bin/vimに入る。)


##原因
OSのアップデートなどで、それまで問題なく動いていたhomebrewがErrorやWarningを吐くことはよくあるみたいなので、今回もそれかも。と思い、とりあえず

```
$ brew doctor
```
して出てきたWarning類を見ると、

1.xcode-select --installをせよ
2.linkの通ってないパッケージがある

と出てきた。

1.について、Command Line Toolsは入っているはずなのになぜこのエラーが出たのかは不明だが、とりあえず指示に従ってやるとWarningは消えた。
2.について、指示通り

```
$brew link 〇〇
```
でlinkを通してやると、Warningは解消。

Warningが解消されたところで、再度

```
$ brew reinstall vim --with-lua
```
をすると通った。

```
$which vim
/usr/local/bin/vim
```
ちゃんとhomebrewでインストールしたvimが動くようになっている。


##補足

と苦労してやったものの、neocompleteは開発は終了していて今後はdeopleteというものに移行していくようです。
https://rcmdnk.com/blog/2017/11/16/computer-vim/
こちらはluaではなくpython3で動くもの。



.vimrcに書くneocomplete個別の設定は例えばこちらなどが参考になった。
http://pocke.hatenablog.com/entry/2015/10/01/222216

##参考
[neocomlpete.vimのインストール方法]
https://qiita.com/umi/items/23a84d9ae2e05c266f7e
[deoplete]
https://rcmdnk.com/blog/2017/11/16/computer-vim/
[neocomplete個別の設定]
http://pocke.hatenablog.com/entry/2015/10/01/222216
カラム削除後にロールバック(rollback)すると型がなくてエラーになる


railsでカラムを削除する時には`remove_column`を使って削除します。

```ruby
class RemoveEmailFromUsers < ActiveRecord::Migration
  def change
    remove_column :users, :email
  end
end
```

しかし、この変更を取り消したく、`rake db:rollback`でロールバックを行いました。

次の瞬間。。

```
ActiveRecord::IrreversibleMigration: 

remove_column is only reversible if given a type.
```

型が無いよと怒られてしまいました。

なので、ロールバックを行いたい場合は、型を追加して、


```ruby
class RemoveEmailFromUsers < ActiveRecord::Migration
  def change
    remove_column :users, :email, :string #型を追加
  end
end
```

再度, `rake db:rollback`を実行してあげれば無事カラムが復活します。

また、マイグレーションファイルを作る際に、
`rails g migration RemoveEmailFromUsers`ではなく、
`rails g migration RemoveEmailFromUsers email`というように最後にしっかりとカラムを指定してあげると、自動的に変更したいカラムと型が設定されるので幸せになれます。


参考: https://qiita.com/HiromiKai_Green/items/7cedfdabbf7db750fc8c
EchoSpotのビデオ通話認証で違う携帯番号を設定する

2018年9月5日にAmazon Echo Spotの[ビデオ通話機能](https://www.amazon.co.jp/gp/help/customer/display.html/ref=tsm_1_tw_s_aejp_wqtwbj?nodeId=202136140)が解禁されました。
早速意気揚々と設定を試みました。携帯番号認証が必要です。
1アカウント毎に携帯番号が紐付いています。

会社のアカウントに自分の携帯番号を登録してしまい、本来設定したい自分アカウントで登録するとエラーが返ってきて設定できない状態になったので、その対処方法です。

ビデオ通話設定はコチラの方が詳しく手順を解説しています。
https://alexa.wp-kyoto.net/getting-start/setup-alexa-call-by-app/

# ビデオ通話設定
認証の時点で気がつけば良かったのですが、早くビデオ通話を試したい一心で
自分の携帯番号で登録しました。問題なくEcho Spotでビデオ通話ができました。

![s100.JPG](https://qiita-image-store.s3.amazonaws.com/0/154355/53b34baa-949c-77ae-b4bc-5e0233a59ab0.jpeg)

# 別アカウントで認証するとエラーになる
今度は自宅に設定してあるEcho Spotにも繋がるかどうか確認するために、自分のアカウントでログインし直して設定しましたが、携帯番号認証でエラーがでました。

![Screenshot_20180906-110927.png](https://qiita-image-store.s3.amazonaws.com/0/154355/d371ed08-66f6-9050-e4a2-3017562c1397.png)

# カスタマーサービスに連絡
直ぐにカスタマーサービスに問い合わせしました。
https://www.amazon.co.jp/gp/help/customer/contact-us/ref=hp_ss_qs_v3_dv_cu_t2&initialIssue=asin-order/ref=hp_ss_qs_v3_dv_cu_t1

チャット形式で直ぐにレスが返ってくるので、とても対応が良かったです。
カスタマーサービスによると、アカウント毎に携帯番号が紐付いているため一度登録すると解除ができないとのこと。。。

対応策は２つ。アカウント削除するわけにはいかないため、違う携帯番号で登録し直すことにしました。

* アカウントを削除する
* 違う携帯番号で登録し直す

# 違う携帯番号で登録する
https://www.amazon.co.jp/ にアクセスして、アカウントサービスにあるログインとセキュリティをクリックします。

<img width="1016" alt="a100.png" src="https://qiita-image-store.s3.amazonaws.com/0/154355/5770bc6d-c1cb-392f-da5d-0e0079892c74.png">

携帯番号が登録されており、この番号をAlexaアプリは見に行っているようです。
編集ボタンをクリックします。
<img width="616" alt="a101.png" src="https://qiita-image-store.s3.amazonaws.com/0/154355/0e20d587-e339-ed4a-8edf-4c393d987861.png">

今度こそ会社で使用している携帯番号を設定します。
入力した携帯番号に認証コードが送られてくるので、コードを入力します。
<img width="613" alt="a102.png" src="https://qiita-image-store.s3.amazonaws.com/0/154355/5e4e53da-0341-188b-4aef-728626f0add4.png">

# 無事に番号が切り替わる
無事に番号を切り替えることができ、今度はエラー無く本来設定したい自分のアカウントにも正しく設定することができました。
何事も慎重に設定しないといけませんね！

![Screenshot_20180906-113808.png](https://qiita-image-store.s3.amazonaws.com/0/154355/8b52c08b-04b9-6293-34d3-d901b7d9c776.png)
コマンドライン引数でメタ文字を扱うとき

ほんとうに初歩的なんですが、見事にハマったので戒めのために記事にします。

安全のためにCLIの引数ではメタ文字をエスケープ処理するのは当たり前なんですが、Printデバッグなんてしていると"\\n"が標準出力では"\n"になるため内部でエスケープされていることを見落とすことがあります。
(そもそも標準出力にメタ文字がある時点でエスケープ処理されていることに気づけよ…)
たまにエスケープを破壊したくなるときがあるのですが、そういうとき私はエスケープ破壊の関数で任意のメタ文字だけ置換して処理しています。


下記はRustで引数を文字列とバイト列で表示するサンプルコードです。
コマンドラインパーサにはclap("2.20.3")を利用しています。
ビルドした実行ファイルに引数として"hoge\nhuga"を渡すとエスケープされているのがわかりやすいと思います。

./main.rs

```
#[macro_use]
extern crate clap;

use clap::{Arg};

fn run(message: &str){
    let t = "hoge\nhuga";
    let tb = t.as_bytes();
    let mut mb = message.as_bytes();
    println!("literal<{}>:{:?}", t, &tb);
    println!("clapString<{}>:{:?}", message, &mb);
    //エスケープ破壊の関数で対処
    println!("unescape:{}", unescape(&message));
}

fn unescape(message: &str) -> String{
    let rs = message
        .replace("\\n", "\n");
    rs
}

fn main() {
    let _args = app_from_crate!()
        .arg(Arg::with_name("message")
            .help("send Message.")
            .required(true)
        )
        .get_matches();

    if let Some(o) = _args.value_of("message"){
        println!("input value: {}", o);
        run(o);
    }
}

```