OmniAICreator/Qiita-1.07M huggingface dataset:
go1.11のModulesを使って依存パッケージを管理する

今まで `glide` や `dep` を使って依存パッケージを管理していたが、go1.11からModulesがお試し版で使えるようになったので試してみる。

まず、プロジェクトクトの配下で以下のコマンドを実行すると、go.modというファイルが作成される。

```
$ GO111MODULE=on go mod init
```

go.modの中身はこんな感じ。

```:go.mod
module github.com/fuku2014/sample

require (
        github.com/go-sql-driver/mysql v1.4.0
        github.com/jessevdk/go-flags v1.4.0
)
```

この状態で go buildを実行すると、自動的に依存ライブラリをダウンロードしてきてくれてビルドされる

```
$ GO111MODULE=on go build pkg/main.go
```

いろいろな依存パッケージ管理ライブラリが乱立している中、標準のgoコマンドで管理できるようになったのはうれしい。
go1.12から正式にリリースされる予定になっている。
[iOS] デバイスの向きとアプリの向き

短いメモ。

今更気づいたんですが、デバイスの向きとアプリUIの向きは必ずしも一致しないんですね。
たとえばナビゲーションを導入してiPhoneを逆さまにしたとき、`NavigationController`が`portraitUpsideDown`をサポートしてないせいで、

```
デバイスの物理的な向き → up side down
アプリの向き　→ landscape Left のまま
```

となったりします。

そういうときは `UIDevice.current.orientation`を使わず、`statusBarOrientation`を使うと良いです。


```avCapture.swift
/* キャプチャ処理での例。 */
/* キャプチャしたCGImageを、現在のアプリの向きを検知して、UIImageを返すところ */

// ステータスバーの向き(アプリの向き)を取得
let interfaceOrientation = UIApplication.shared.statusBarOrientation

// landscape leftの場合
if(interfaceOrientation == UIInterfaceOrientation.landscapeLeft) {
    return  UIImage(cgImage: imageRef, scale: 1.0, orientation: UIImageOrientation.down)
}
// landscape rightの場合
if(interfaceOrientation == UIInterfaceOrientation.landscapeRight) {
    return  UIImage(cgImage: imageRef) //そのままUIImageに変換
}
// portrate の場合 （デフォルト）
return  UIImage(cgImage: imageRef, scale: 1.0, orientation: UIImageOrientation.right)
```

Swift4での例が少なかったので共有。
GPSの研究　その47

#概要
gpsを理解したかった。
アグリナビで遊んでみた。
usb-serialで、gpsをつないでみた。

#写真

![CIMG2690.JPG](https://qiita-image-store.s3.amazonaws.com/0/18104/ef8fdcec-26d4-b024-cb29-abbe8d0bebf9.jpeg)



以上。
PycharmとAnacondaの連携＠Windows10

# 問題
Anacondaで導入済みのライブラリをimportして
Pycharmでコードを走らせたときに読み込みエラーが発生。
```（ライブラリの読み込みエラー）
ModuleNotFoundError: No Module named six
```

# 解決策
pycharmの設定で外部インタープリタにanaconda3->python.exeを指定

## インタープリタの設定（既存のプロジェクトの場合）
File->Settings->Project->Project Interpreter

## インタープリタの場所
私の環境では以下の場所：
C:->Anaconda3->python.exe

## 設定の反映
OKボタンを押して設定を終えるとpycharmで内部処理が実行された。
ステータスバーで内部処理が終わったことを確認して
pycharmを再起動する。

## 確認
pycharmのコンソールウィンドウにanaconda3と表示されるようになった。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/88641/e2939b22-9c3e-be60-a696-f2d9ec398b98.png)

# 参考資料
以下の投稿を参考にしました
https://qiita.com/suJiJi/items/c0fe298969b4cdf569d9
Docker上のGUI出力をMacで表示

機械学習では多種多様な環境をDockerで使い分けるユースケースがありますが
サンプルコードなんかでよく見かける`matplotlib`なんかのGUIへの出力機能は
Docker上だと動きまへん
そこでDockerからホスト上のGUIへ直接出力する設定方法を備忘録として残す


### 前提
ubuntuです
今回のコンテナはこんな感じです

```
uname -a
Linux 9809f8c3404d 4.9.93-linuxkit-aufs #1 SMP Wed Jun 6 16:55:56 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
```

### 設定
**ホスト側**（Mac上）

```sh
# xquartzをセットアップ
brew cask install xquartz
# xquartzを起動しておきます
open -a XQuartz
```

XQuartzが起動したらセキュリティ設定（環境設定>セキュリティ）を変更しておきます
1. 「接続の認証」をOFF
2. 「ネットワーク・クライアントからの接続」をON


**ゲスト側**（Dockerコンテナ内）

```sh
apt-get update
apt-get install -y libx11-dev
export DISPLAY=host.docker.internal:0.0
```
version18.03から[host.docker.internal](https://docs.docker.com/docker-for-mac/networking/#use-cases-and-workarounds)が利用可能になってたので修正しました
教えてくださった[YOKO-Chance](https://qiita.com/YOKO-Chance)さんに感謝


### 実行

Dockerコンテナ内でmatplotlibへimshowとかするPythonを実行すると
ホスト上で新規Windowが立ち上がり、結果を表示します。
フォークコインを作るときに、ジェネシスブロックのハッシュ値をマイニングする

`以前の記事が自分の勘違いで一切マイニングをしないコードになっていたため、きちんとマイニングするように修正しました。`

genesisのpszTimestampやnTime、を書き換えると、起動時にこんな感じのエラーが出る。

```
coind: chainparams.cpp:152: CMainParams::CMainParams(): Assertion `consensus.hashGenesisBlock == uint256S("00000…0000")' failed
```

原因は`src/chainparams.cpp`のここ

```c++
genesis = CreateGenesisBlock(1231006505, 2083236893, 0x1e0ffff0, 1, 50 * COIN);
consensus.hashGenesisBlock = genesis.GetHash();
assert(consensus.hashGenesisBlock == uint256S("0x0000…f"));
assert(genesis.hashMerkleRoot == uint256S("0x12345…f"));
```

もちろんジェネシスブロックのハッシュが変わってるのでassertで落ちてる。
ファイルの頭あたりにある`CreateGenesisBlock`の中で力技でマイニングさせるようにする。

差分はこんな感じ。

```diff:ヘッダーにarith_uint256.hを追加
  #include "chainparams.h"
  #include "consensus/merkle.h"
+ #include "arith_uint256.h"
 
  #include "tinyformat.h"
  #include "util.h"
```

```diff:マイニングするコードを追加
static CBlock CreateGenesisBlock(const CScript& pszTimestamp, const CScript& genesisOutputScript, …enesisReward)
{
    CMutableTransaction txNew;
    txNew.nVersion = 1;
    txNew.vin.resize(1);
    txNew.vout.resize(1);
    txNew.vin[0].scriptSig = …………
    txNew.vout[0].nValue = genesisReward;
    txNew.vout[0].scriptPubKey = genesisOutputScript;

    CBlock genesis;
    genesis.nTime    = nTime;
    genesis.nBits    = nBits;
    genesis.nNonce   = nNonce;
    genesis.nVersion = nVersion;

    genesis.vtx.push_back(MakeTransactionRef(std::move(txNew)));
    genesis.hashPrevBlock.SetNull();
    genesis.hashMerkleRoot = BlockMerkleRoot(genesis);
+
+    arith_uint256 hashTarget = arith_uint256().SetCompact(genesis.nBits);
+    std::cout << hashTarget.ToString() << '\n';
+    while (UintToArith256(genesis.GetHash()) > hashTarget) ++genesis.nNonce;
+
     return genesis;
 }
```

で、これでマイニングが成功すると、動作が帰ってくる。
そのときにnNonceを表示するため、`genesis = CreateGenesisBlock(1231006505, 2083236893, 0x1e0ffff0, 1, 50 * COIN);`の下に以下のコードを挿入する。

```c++
std::cout << "genesis.nTime = " << genesis.nTime << '\n';
std::cout << "genesis.nBits = " << genesis.nBits << '\n';
std::cout << "genesis.nNonce = " << genesis.nNonce << '\n';
std::cout << "genesis.GetHash = " << genesis.GetHash().ToString() << '\n';
```

これで、coind起動時にマイニングが起動、ジェネシスブロックをマイニングしてそのnNonceを吐き出すようになる。その値をassertに突っ込めば良い。

ちなみに、今回のnBitsである0x1e0ffff0はモナコインから流用した。難易度的にはものすごく簡単なため数秒でマイニングに成功する。
⑦Raspberry Pi3で照射量を取得する（BH1750FVI）

# 準備するもの（周辺機器）
1.Raspberry Pi 3
2.BH1750FVI（デジタル光センサー）
3.はんだごて
4.はんだ
5.オスジャンパー、メスジャンパー（Raspberry Pi初心者キット使用）

# はんだごて


# BH1750FVI+ブレッドボード+Raspberry Piを接続

![スクリーンショット 2018-08-28 12.09.57.png](https://qiita-image-store.s3.amazonaws.com/0/25698/6b1882c8-95b7-7202-d48e-c852b1b9867f.png)

# I2Cの設定
```
# /etc/modules: kernel modules to load at boot time.
#
# This file contains the names of kernel modules that should be loaded
# at boot time, one per line. Lines beginning with "#" are ignored.

snd-bcm2835
i2c-bcm2708 ←追加
i2c-dev ←追加
```

I2Cにつながっている確認するツールをインストール

```
sudo apt-get install i2c-tools
```

IC2デバイスを確認

```
$ sudo i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- 23 -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
```
光センサーのアドレスは0x23



I2Cのデバイスをpythonから使う時は、smbusライブラリを使う

```
sudo apt-get install python-smbus
```



# スクリプト作成

```li.py
#!/usr/bin/python

import smbus

bus = smbus.SMBus(1)
addr = 0x23
luxRead = bus.read_i2c_block_data(addr,0x11)
print("Lux: "+str(luxRead[1]* 10))
```



# スクリプト実行

```
$ sudo python li.py

Lux: 10.00
```
PHPの「Unable to load dynamic library」を解消する方法

# PHPの「Unable to load dynamic library」を解消する方法

とある案件の管理用サーバーの検証環境構築時の出来事。
本番環境の管理サーバーのPHPバージョンなどを確認しながら検証環境構築を進めておりました。
その環境ではPHP5.3を利用しており正常に動作しているものの、実は裏で警告が出てました。
（この時点で「正常」ではないのですが・・・）

※ちなみにPHP7系に後日移行予定です。

似た内容の記事がすでにQiitaに存在するかと思うのですが、僕なりの解消手順、作業ログとして記事にすることにしました。

## 環境
- AWS t2.micro EC2インスタンス
 - Amazon Linux AMI release 2018.03
 - Apache/2.2.34 (Unix)
 - PHP 5.3.29

## 警告内容
```
$ php -v
PHP Warning:  PHP Startup: Unable to load dynamic library '/usr/lib64/php/modules/php_pdo.dll' - /usr/lib64/php/modules/php_pdo.dll: cannot open shared object file: No such file or directory in Unknown on line 0
PHP 5.3.29 (cli) (built: May 12 2015 22:42:19)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2014 Zend Technologies
```
PHP自体は動作しているが、ライブラリをロードできない旨の警告が出ている。

またまた。そんなわけないじゃーん。

```
$  ll /usr/lib64/php/modules/ | grep php_pdo
```


ほんまや(°▽°)
ちゃんとライブラリ無いね笑

## 修正
phpの設定ファイルを確認してみた

```
$ php --ini | head -n5
PHP Warning:  PHP Startup: Unable to load dynamic library '/usr/lib64/php/modules/php_pdo.dll' - /usr/lib64/php/modules/php_pdo.dll: cannot open shared object file: No such file or directory in Unknown on line 0
Configuration File (php.ini) Path: /etc
Loaded Configuration File:         /etc/php.ini
Scan for additional .ini files in: /etc/php.d
Additional .ini files parsed:      /etc/php.d/curl.ini,
/etc/php.d/fileinfo.ini,
```

`/etc/php.ini`を修正するよ

```
$ sudo su
$ vi /etc/php.ini
```

ぺろぺろと修正。。。
以下のようにしました

```
$ cat /etc/php.ini | grep php_pdo -n1
927-; Fix: Unable to load dynamic library error.
928:; extension=php_pdo.dll
929-
```
`extension=php_pdo.dll`の行が不要でした。
恐らく、参考になるサイトを見ながらPHPの導入を行ったので、不必要なライブラリを読み込む設定を追加したのだろう。。。
コメントアウトし、１つ上の行にコメントを入れました。

この後、`exit`コマンドでrootから抜けました。

## 修正完了
httpdプロセス再起動

```
$  sudo service httpd restart
Stopping httpd:                                            [  OK  ]
Starting httpd:                                            [  OK  ]
```
再起動完了！！

PHPの動作を確認してみる。
バージョンの確認コマンドでも`--ini`オプションでもなんでも良いと思います。実行します。

```
$ php -v
PHP 5.3.29 (cli) (built: May 12 2015 22:42:19)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2014 Zend Technologies
```

無事、警告が解消されましたね。

## さいごに
今回、手元の環境では設定の誤りが原因で存在しない`php_pdo.dll`ライブラリを読み込もうとして警告を履いておりましたが、異なるライブラリでもロード時の警告が発生し得ます。
なので、`ls -la [警告に表示されたライブラリへのパス]`などで参照できるか確認後、php.iniの設定に誤りが無いか確認してみてください。

（´-`）.｡oO(早めにPHP７に移行しないとなぁ。。。)
ネトゲのスケジュール共有アプリを作って即終了した話

#はじめに
Rails tutorialを進めながら、なんとなく欲しい物が決まってきたので、
チュートリアルを進めつつオリジナルに手を加えて作っていきました。
作っている時に公式アプリの告知があり、このアプリが完全に不要になることが確定しましたが、勉強のために完成させることに。
結局、8月初旬に公式アプリが公開され当サイトは閉鎖しました。1ヶ月弱の命でした。
今回は供養のための備忘録です。
内容的には「tutorialからの魔改造でこんな物も作れる」という感じです。


#要件定義
と言えるような大層なものではないが、どんなことがしたいか書き出す。

・登録制
・匿名(ゲーム内キャラ名等)でスケジュール管理
・特定多数の人と共有
・スマホでもそれなりに使える
・ぱっと見で参加・不参加がわかる

##細かく考える
###登録
Rails tutorialをほぼそのまま流用する。
項目を変える程度。
メールアドレスの実在確認はしないが、重複はさせない。
ログイン機能も流用できるので、devise等のGemも使わない。
![2d08406fddcb16c3ee36aaf46d50c335fd51623e.png](https://qiita-image-store.s3.amazonaws.com/0/260430/26a98c3c-0410-f2e5-a5c2-367eebfdd330.png)


###特定多数での共有
個人でグループを作成できるように。
作成時にグループ加入用パスワードを設定させて、知っている人だけが入れる。

###スマホ対応
これもtutorialと同様、bootstrapにお願いする。

###ぱっと見でわかる
カレンダーをつける。
匿名性を優先したいのでGoogleカレンダーは使わない。
![d49a22e84633fca73a5f00f5bad23c12f43188de.jpg](https://qiita-image-store.s3.amazonaws.com/0/260430/79f29641-908c-5515-952d-6a8e14aa878c.jpeg)
[詳しい実装は別記事で紹介](https://qiita.com/arekore0/items/099c728b5b7efaf631a5)

###その他のスケジュール確認方法
個人用ページの上部に一覧で表示させる。
1人が複数のグループに所属することも可能なので、グループ毎のタブ表示にした。
ALLタブでは自分の投稿した予定の一覧を出し、各グループのタブではメンバーが投稿した予定の一覧を表示。
![38787acd8bea898bb209c2cde58ec2832c5d9fdf.jpg](https://qiita-image-store.s3.amazonaws.com/0/260430/fb4069d4-f3cd-6906-910b-a59ed9604f9c.jpeg)

###マイページ
登録時に入力したキャラクターIDを用いて、公式サイトからスクレイピングで自キャラ画像とジョブLvを取得し表示。
PCでは全身画像、スマホでは顔画像での表示になる。
反省点として、アクセス毎の取得のため相手サーバーに負荷がかかる可能性があること。
考えられる改善方法として、画像は登録時のアップロードやスクレイピングで固定させ、ジョブLvはタイムスタンプなどで一定の間を設ける。

###その他機能
グループの検索はIDか名前
グループ掲示板(これは他の教本で作った物を流用)

#ソース
初Railsで作った物なので粗いとこしかありませんが参考までに。
https://github.com/arekore/rails.git
⑤Raspberry Pi3と土壌湿度センサーで土壌湿度を取得する（YL69 + MCP3002）

# 準備するもの（周辺機器）
1.Raspberry Pi 3
2.YL-69（土壌湿度センサー）
3.MCP3002（A/D コンバータ）
4.オスジャンパー、メスジャンパー（Raspberry Pi初心者キット使用）

# A/D コンバータとは
Raspberry Piはアナログデータを読み取ることができません。
A/Dコンバータはアナログデータを1と0の2進数に変換し、Raspberry Piに通信で送信するデバイスです。
Raspberry PiとA/Dコンバータの間の通信は、SPI通信を使用します。

# Raspberry PiでSPI通信の設定

SPI通信のドライバをインストール

```
$ sudo apt-get install python-spidev
```

「5.Interfacing Options」を選択
<img width="640" alt="スクリーンショット 2018-08-28 11.57.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/25698/91a27df9-31c7-f173-0cdb-1b63d4d5458f.png">

「P4 SPI」を選択
<img width="640" alt="スクリーンショット 2018-08-28 11.57.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/25698/516af547-8ae9-fad3-c5b0-4887603f48f3.png">

SPIが有効かの確認

```
ls -l /dev/spi*

```

# yl69+MCP3208+ブレッドボード+Raspberry Piを接続

<img width="812" alt="スクリーンショット 2018-08-28 11.53.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/25698/c037bd84-ae1c-53e1-3ac6-89688d24f63b.png">


# スクリプト作成

```yl69.py
# -*- coding: utf-8 -*-
import RPi.GPIO as GPIO
from time import sleep
import spidev

#GPIOのピン番号
pin = 22

# initialize GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.cleanup()

#GPIOの指定したピン番号を出力端子に設定
GPIO.setup(pin, GPIO.OUT)

#出力用関数
def output_fromGPIO(pin, output):
    GPIO.output(pin, output)
    sleep(0.1)

#MCP3002動作用関数
def readadc_spidev(adcnum):
    if ((adcnum > 1) or (adcnum < 0)):
        return -1
    #0x68は1chを使う場合です。2chは0x78を使います。
    ret = spi.xfer2([0x68,0x00])    
    #データは8ビットずつに分かれているので、最初の8ビットを上位データとして8ビットシフトし、下位データと結合する
    #MCP3002は10ビット目までがデータなので、10ビット目までを残して他のデータを消す
    adcout = ((ret[0]<<8) + ret[1])&0x3ff
    return adcout

#SPI通信開始
spi=spidev.SpiDev()
spi.open(0, 0) # bus0, CE0

#データ取得前にYL-69に電圧を印可
output_fromGPIO(pin,True)

try:
    while True:
        #先ほど定義したMCP3002の関数を呼び出す
        getValue = readadc_spidev(0)
        #値がちゃんと取れたらデータを出力。取れるまでトライ
        if getValue != -1:
            print(getValue)
            break;
        sleep(1)

except KeyboardInterrupt:
    pass

#YL-69の印加電圧をとめる
output_fromGPIO(pin,False)
#SPI通信終了
spi.close()
```

# スクリプト実行
```
sudo python yl69.py
>>> 1023
>>> 464
>>> 699
```
成功!!
④Raspberry Pi3と土壌湿度センサーで土壌湿度を取得する（YL69 + MCP3208）

# 準備するもの（周辺機器）
1.Raspberry Pi 3
2.YL-69（土壌湿度センサー）
3.MCP3208（A/D コンバータ）
4.オスジャンパー、メスジャンパー（Raspberry Pi初心者キット使用）

# yl69+MCP3208+ブレッドボード+Raspberry Piを接続

<img width="733" alt="スクリーンショット 2018-08-28 11.42.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/25698/15c2d88a-33f1-9f80-ce5d-799521583397.png">

# スクリプト作成

```yl69.py
# -*- coding: utf-8 -*-
import RPi.GPIO as GPIO
from time import sleep
import spidev

#GPIOのピン番号
pin = 22

# initialize GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.cleanup()

#GPIOの指定したピン番号を出力端子に設定
GPIO.setup(pin, GPIO.OUT)

#出力用関数
def output_fromGPIO(pin, output):
    GPIO.output(pin, output)
    sleep(0.1)

#MCP3002動作用関数
def readadc_spidev(adcnum):
    if ((adcnum > 1) or (adcnum < 0)):
        return -1
    #0x68は1chを使う場合です。2chは0x78を使います。
    ret = spi.xfer2([0x68,0x00])    
    #データは8ビットずつに分かれているので、最初の8ビットを上位データとして8ビットシフトし、下位データと結合する
    #MCP3002は10ビット目までがデータなので、10ビット目までを残して他のデータを消す
    adcout = ((ret[0]<<8) + ret[1])&0x3ff
    return adcout

#SPI通信開始
spi=spidev.SpiDev()
spi.open(0, 0) # bus0, CE0

#データ取得前にYL-69に電圧を印可
output_fromGPIO(pin,True)

try:
    while True:
        #先ほど定義したMCP3002の関数を呼び出す
        getValue = readadc_spidev(0)
        #値がちゃんと取れたらデータを出力。取れるまでトライ
        if getValue != -1:
            print(getValue)
            break;
        sleep(1)

except KeyboardInterrupt:
    pass

#YL-69の印加電圧をとめる
output_fromGPIO(pin,False)
#SPI通信終了
spi.close()
```

# スクリプト実行
```
sudo python yl69.py
>>0
>>0
>>0
```
全て0で土壌湿度がとれない、、
Raspberry Pi3とyl69とMCP3208の組み合わせが悪いのか
原因は謎です。
GitlabCIでsbtのキャッシュファイルをキャッシュする

sbtはオプションの指定等がないと$HOMEにキャッシュを生成する。
このキャッシュがないと毎回依存ライブラリを取得しにいくので、非常に時間がかかってしまう。。。

GitlabCIではそれぞれのJobで共通のキャッシを持つことができるが、
ビルドディレクトリ以外のディレクトリをキャッシュすることはできない。

そこで以下のように sbtとivyのホームディレクトリを指定してあげれば、2回目移行の実行時間を大幅に短縮できる

```.gilab-ci.yml
  script:
    - sbt -Dsbt.global.base=./cache/.sbt/ -Dsbt.ivy.home=./cache/.ivy2/ -Divy.home=./cache/.ivy2 compile
  cache:
    key: "sbt_cache"
    untracked: true
    paths:
      - "cache"
```
Redash でリソースを削除する方法

Redash をチームで使っていて割とすぐに直面する問題として、

- 試しに作ってログインしてみたテストユーザーを削除できない
    - CLI から削除操作はできるけどログインイベントが存在するともう手遅れ
- 試しに作ったダッシュボード・クエリを削除できない
    - アーカイブ化はできるけどデータとしては残る
    - 正直お試しで作ってみたゴミを本番環境とかに残したくはない
- 誰が何やったか履歴とかないのかしらん

とかないでしょうか？

## 結論

- `https://<redash.example.com>/admin` にアクセスするだけ
    - ダッシュボード・クエリ・実行結果・イベントなどは閲覧できるし追加も削除もできる
    - ユーザー削除は **そのユーザーに紐付く情報** を全て消せば CLI から削除できる
        - ただしそのユーザーの全てのイベントを一気に消す方法も検索する方法もないからかなり辛い...
        - (2018-10-23) Redash v5 でユーザーの無効化ができるようになったので削除よりこっちを使うべき

せめてダッシュボード・クエリと同じようにアーカイブ化くらい無いと権限管理に困りもの
Solidityにおけるガス節約のためのチートシート

ガスを節約するためのコードの書き方。
自分、ユーザ、イーサリアムコミュニティという3者のためにもよりよいコードを書いていきましょう。

不等号はより好ましいものを表す

#データ型
##### globalデータ(storage)
※structに限らない

*__型は小さい方が良い__
*__intは同じデータ型で隣り合うようにする(小さい順 or 大きい順で統一)__


```
 struct Campaign {
  uint64 aaa;
  uint64 bbb;
  uint128 ccc;
  uint256 ddd;
  uint256 eee;
}
uint128 xxx;
uint128 yyy;
uint256 zzz;
```

(参考：https://y-nakajo.hatenablog.com/entry/2018/02/15/012023)

以下のご指摘いただき、一部修正しました！

<blockquote class="twitter-tweet" data-conversation="none" data-lang="en"><p lang="ja" dir="ltr">同じデータ型を隣り合うように並べるという箇所なのですが、小さい順or大きい順だと必ずしも最小にはならないのではないでしょうか？例えばbytes20とbytes12の変数がたくさんあるときには交互に並べた方がぴったり32byteにおさまるので効率的になる気がしました。(細かいところですが…。)</p>&mdash; ゆで卵 (@takayukib) <a href="https://twitter.com/takayukib/status/1035075636857950208?ref_src=twsrc%5Etfw">August 30, 2018</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


引数はuint256で渡し、globalデータに追加や変更があるときは、その方に合わせて計算結果をくくる(SafeMath使用時)

```
function test(uint256 lmn) {
    xxx = uint64(lmn);
}
```

##### return
型は小さい方が良い



##### 文字列
string < bytes < bytes32
基本はbytes32、長い文字列（bytes32に収まりきらないものはbytes）

#SafeMath
you should use it when you need to validate the input.
https://ethereum.stackexchange.com/questions/54998/solidity-safemath-library-best-practice-use-cases

ユーザが悪意もっとインプットすることができるものに限りSafeMathを使用すると良い。
payableはユーザが送金する金額を指定できるので、SafeMathを使用

#修飾子
#####view < pure
引数だけを計算するものはpureを使い、ネットワークからデータをとってくるものはviewをつける
(constとconstantは使わない)

##### public < external
外から呼び出すだけと確定しているものはexternal、そのコントラクト内でも使うのはpublic

##### private < internal
Azure Storageで静的ウェブサイトを構築する

# はじめに
Microsoft Azureは今までS3のような静的なウェブサイトを構築するには向いていませんでした。
というのもindex.htmlをデフォルトページにできないといった不便な点があったからです。

しかし、最近のアップデートによってS3のような静的なウェブサイトを構築することができるようになりました。ここではその構築手順について説明します。

# ストレージの作成

Storage Accountからストレージを作成します。
この時、アカウントの種類を**Storage v2(汎用V2)**にする必要があります。
![２スクリーンショット 2018-07-12 17.30.26 (1).png](https://qiita-image-store.s3.amazonaws.com/0/69399/a1d8e437-31bb-296b-4a00-5e3e03d473c5.png)

# 静的ウェブサイト用コンテナーの作成

作成されたストレージを選択し、メニューを表示します。その中にある**静的なWebサイト(プレビュー)**を選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/69399/0529f88d-501a-5b69-7659-7f693c7b7292.png)


**静的なWebサイト**を**オン**にします。すると、`$web`コンテナーが作成され、エンドポイントが表示されます。インデックスドキュメントとエラーページを指定する入力ボックスも表示されます。

このエンドポイントはAmazon S3でいう`****.s3.amazonaws.com`みたいなものであり、Webブラウザから開く場合はこのURLを使います。

# $webコンテナーにファイルを追加

Cyberduckなど好きな方法で`$web`コンテナーにファイルを追加します。設定画面と同じ場所にある`Storage Explorer`であれば手っ取り早くファイルをアップロードできますね。

# ブラウザで確認
<img width="836" alt="スクリーンショット 2018-08-28 2.16.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/69399/06269bcb-b2c2-ae64-be9b-098224846f91.png">
正常に表示されていますね。これで完了です。

静的でも構わないWebサイトが突然必要になった場合に活かせるのではないでしょうか。
CourseraのEmbedded Hardware and Operating Systemをまとめてみた(1)

以下のコースをまとめてみました。授業内容と、自分の考えを忘備録でまとめてます。講義内で出てきたステートメントと、それに対する感想をまとめて行きます。

https://ja.coursera.org/learn/embedded-operating-system

*  組み込みシステムはスマホから宇宙ステーションまで、色々あるよ。
*  まあ、システムの基本だよ。  
*  しかしながら、ハードウェアを正しく選択することが重要だよ   　

組み込みってそうなんですね。

*  一般的なアプローチは、ハードウェアリソースを制御する基本的なタスクを扱うオペレーティングシステムを使い、ユーザーアプリケーションを提供することだ。 

ここではLinuxのことを言ってますね。この講義ではIoTについて触れることが多くて、使われるOSは主にLinuxです。Linuxの上に、全てのアプリケーションが乗っかっている感じですね。
Linuxとは、リーナストーパルズが中心になって開発している、オープンソースのOSソフトウェアのことです。上に書いてある通り、AndroidのスマホもLinuxですし、Webサーバ、スーパーコンピュータなども多くはLinuxです。
個人的には、Linuxカーネルを勉強したくてこの講義を取っています。

*  このコースでは、サイバー物理システムの二つの要素、ハードウェアとオペレーティングシステムを取り上げます。

まさに、僕の求めているものですね。僕はオペレーティングシステムを勉強したいのです。
次の章に行きます。

*  今日、コンピュータはあらゆるところにある。エンジンを走らせ、声をエンコードし、モバイルコミュニケーションのためのラジオシグナルを構築している。マイクロ波さえコントロールするのだ。

まあ、これらは主に組み込みシステムなんですが、いろんなところに使われてますね。

*  デスクトップコンピュータと組み込みシステムの違いは、組み込みシステムは特定のタスクを解決するために使われ、ユーザーから見える限られたI/Oからなる

ユーザーから見える限られたI/Oってどう言う表現なんだかなかなかよくわからないですが、意味していることはわかります。

*  組み込みシステムの例として、航空機を取り上げることができる。航空機は組み込みシステムで満ちている。座席は、ビデオ、オーディオ、ゲーミング機能を持ったエンターテインメントシステムがあり、温度と客室の気圧を制御しているエアコンディショニングシステムがある。他方、飛行制御システムは組み込みシステムが非常に多く実装されている。たくさんのセンサーが、飛行状況をパイロットに知らせている。場所、天気、高度、スピード、角度、これらの値が常時モニターされているのである。
　
なんか、飛行機とか、組み込みシステムの塊っぽい感じしますね。なんか一つでも狂ったら、大変な惨事が起きそうな気がします。技術者の責任は重大ですね。そのあと、オートパイロットの話になって、やっぱり組み込みシステムが重要だみたいな話になります。

*  飛行機に使われる組み込みシステムの主な性質と、制約条件は、それが信頼性が高い必要があると言うことである。センサーは、正しい値を常に報告する必要がある。

あと、色々信頼性が高い必要がある理由が連ねてあって、

*  それらの条件が一つでも満たされないと、簡単に惨事が起こるのである。

と、あります。で、信頼性がどう意味されるか、どう計測されるかは、後の講義で議論するらしいです。非常に楽しみですね。

*  他方、組み込みシステムはセキュアである必要がある

個人的にセキュリティとかの記事を読むことが多いんですが、組み込みシステムはセキュアである必要があるんですよね。で、組み込みシステムのアプリケーションは危険なC言語を使って記述される場合が多いので、ますます重要になってきます。
飛行機がハッキングされて墜落する可能性があるとか言う記事もあるし、恐らくだけど、イージス艦や軍用機なども、組み込みシステムの塊なので、ああ言う戦争が起きた時に使われる前提のものも、実際戦争が起きたら結構攻撃されると思うんですよね。だから恐らく重要だと思います。

*コンピューティングがどこにでもある良い例の一つは、Internet of Thing(IoT）である。ノードとは、センサーとActivator(これ何？）につながった組み込みシステムのことだ。ノードは、色々な種類の情報を集める。ノードは離れたところに設置され、長く動くことを期待される。なので、エネルギー効率はIoTの関心事の一つだ。もう一つの関心事は、意味のあるデータを集めることだ。

Activatorって「活性剤」とか言う意味らしいですが、なんのことかわかりません。個人的には、離れたところに設置されるとしたら、信頼性とかも重要になってくると思いますが。
で、ある程度めちゃくちゃなデータから、意味のあるデータを集めるためには、機械学習や、ビッグデータも重要になってくると言ってます。

* だから、IoTは、人々にたくさんのデータを提供し、プロセスを最適化するのに使われる。

ビッグデータって、業務システムを改善するのに使われたりしますよね。新しい知見を得て、それを応用する。結構直感って間違えるから、統計的な情報を応用するんですね。

*  一般的な組み込みシステムとIoTの違いは、IoTはハードウェアが分散していることと、ノード間で通信することである。

なるほど、個人的には興味深いステートメントだと思います。周りでの使われ方を見ると、IoTと組み込みを混同していることが多いと思うんですが、こう言う区別の仕方があるんですね。ちなみに僕もちょっと混同してます。と言うか、IoT自体がバズワードっぽいところがあるので、こう言う混同は仕方ないですね。

*  組み込みシステムは、顕著に反応的（Reactive)である。これが意味するところは、そのようなシステムは常時環境と相互作用しており、環境が言うことを実行するのである。反応的システムとは、インプットを待ち、コンピューティングを実行し、アウトプットを吐き出し、新しい状態に遷移する。そのようなシステムはオートマトンとしてモデル化できる。

このステートメントは個人的にはよくわからないですね。環境と相互作用すると言う意味では、デスクトップPCも同じだし、単純にコンピュータの性質を記述しているように思います。
この後、一般的なinput→処理→outputなどの、一般的なコンピュータの性質を記述しています。

FPGAについてこの講義では触れるようです。この講義では、組み込みシステムと、FPGAがどのように構築されているかを議論します。センサーとアクチュエータについても触れ、どうインターフェースするかを議論するようです。

最後に、組み込みシステムを学びたいなら、このコースがいい出発点だと言ってました。

これで、Introduction to Embedded Systemを終わるようです。
ちゃんちゃん
G Suiteで取得したドメインと他社サーバーを利用してサイトを公開したい

先日案件でタイトルのような事例があったのですが、設定でハマってしまったので、備忘録も兼ねて書き残します。
本記事では、サーバーはさくらのレンタルサーバーを使用していますが、
Xserverなど、他のサーバーであっても、設定の流れは同様だと思いますので、ご参考までどうぞ。

# したいこと
G Suiteで取得したドメインと、さくらのレンタルサーバーを使ってサイトを公開する。

# 前提
- G Suiteアカウントを持っていて、Google経由でドメイン取得をしている。
（Googleでドメインを申し込むと、実際はGoogleを経由し、他社でドメインを取得します。筆者の場合はGoDaddyでした。）
- さくらのレンタルサーバーを契約している。

# 設定
早速設定方法に入ります。

## さくらレンタルサーバーのIPアドレスの確認する
さくらのサーバコントロールパネルにログインし、左側のメニューから「サーバ情報とパスワード」＞「サーバ情報の表示」をクリックします。
![キャプチャ6.PNG](https://qiita-image-store.s3.amazonaws.com/0/267886/583617d8-7007-b208-174d-3fd75a711e48.png)

サーバに関する情報をクリックします。
![キャプチャ7.PNG](https://qiita-image-store.s3.amazonaws.com/0/267886/14d6da14-be69-4479-f087-da85a220c39f.png)

IPアドレスが確認できました。後ほどこのIPアドレスを使用するので、コピー出来るようにしておいてください。
![キャプチャ8.PNG](https://qiita-image-store.s3.amazonaws.com/0/267886/66fc3bbc-37ec-8a6f-b424-ad4497d447eb.png)

## Google管理コンソールへログインする
Googleにログインし、[https://admin.google.com/](https://admin.google.com/)へアクセスします。

管理コンソールのダッシュボードからドメインをクリックします。
![キャプチャ1.PNG](https://qiita-image-store.s3.amazonaws.com/0/267886/c8436736-606f-5119-e865-b1b169f01f20.png)

ドメインの追加と削除をクリックします。
![キャプチャ2.PNG](https://qiita-image-store.s3.amazonaws.com/0/267886/a9aae058-7174-4287-f699-bf3f1e4bcb86.png)

詳細なDNS設定をクリックすると、アコーディオンで詳細情報が開きます。
ここに記述されているログイン名とパスワードは次の項目で使用するのでコピーしておいてください。
![キャプチャ3.PNG](https://qiita-image-store.s3.amazonaws.com/0/267886/1a679f7a-51b6-65e4-ce99-db81a8f70d57.png)

DNSコンソールにログインをクリックすると、ログイン画面が開くので、先ほど「詳細なDNS設定」で表示されていたログイン名とパスワードを入力します。
![キャプチャ4.PNG](https://qiita-image-store.s3.amazonaws.com/0/267886/27ea719f-025f-86ac-ab54-c8ccbf60dc08.png)

ログインに成功するとG Suiteのドメインマネージャーの画面が開きます。

## ドメインマネージャーからAレコードを設定する

該当のドメイン部分、右上の歯車ボタンをクリックし、DNSを管理をクリックします。
![キャプチャ5.PNG](https://qiita-image-store.s3.amazonaws.com/0/267886/8292bd70-e9e1-a421-f90e-bcf078bc2229.png)

Aレコードが4つデフォルトで設定されていますので、これを全て削除します。
鉛筆ボタンをクリックすると、編集画面になってゴミ箱ボタンが出ますので、そちらから削除できます。

削除した4つのAレコードは、Googleサイトを利用する際に関係する値でデフォルトで設定されているものでした。今回はさくらのサーバーを利用するので、先ほど確認した、さくらのIPアドレスでAレコードを登録し直します。

レコードの右下の追加ボタンをクリックします。下記のように入力し、保存してください。

- [タイプ]リストから[A]を選択します。
- [ホスト]欄に「@」と入力します。
- [ポイント先]にサーバーのIPアドレスを入力します。
- [TTL]は1時間のままにします。
![キャプチャ9.PNG](https://qiita-image-store.s3.amazonaws.com/0/267886/2e78ba9d-e771-2f05-305d-b481a80040e7.png)

## さくらサーバーでドメイン設定をする
さくらのサーバコントロールパネルにログインし、左側のメニューから「ドメイン設定」＞「ドメイン/SSL設定」をクリックします。
![キャプチャ10.PNG](https://qiita-image-store.s3.amazonaws.com/0/267886/d5202ee1-703d-e942-fd51-74daab9f0fa4.png)
![キャプチャ11.PNG](https://qiita-image-store.s3.amazonaws.com/0/267886/3133dea6-2a37-8625-d45d-01f90f13f72c.png)

「新しいドメインの追加」をクリックし、「5. 他社で取得したドメインを移管せずに使う」から「ドメインの追加へ進む」をクリックします。
![キャプチャ12.PNG](https://qiita-image-store.s3.amazonaws.com/0/267886/ae61f671-1ba5-c3d1-371b-fd56b8632a35.png)

他社で取得した独自ドメインの追加に、Google経由で取得したドメインを入力し、送信をクリックします。
設定の反映には少し時間がかかる場合があります。
![キャプチャ13.PNG](https://qiita-image-store.s3.amazonaws.com/0/267886/5374c411-e966-a7da-4f8b-35600761583d.png)



設定は以上になります。
サイトが表示されていることを確認してください。お疲れ様でした。
AmazonLinux2 でswap領域作成

# Attach SWAP area to AmazonLinux2
 自分用のメモです。

## 環境

```
% cat /etc/os-release
NAME="Amazon Linux"
VERSION="2"
ID="amzn"
ID_LIKE="centos rhel fedora"
VERSION_ID="2"
PRETTY_NAME="Amazon Linux 2"
ANSI_COLOR="0;33"
CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2"
HOME_URL="https://amazonlinux.com/"
```

## 手順

1Gバイトのスワップファイルを `/swapfile` において、Linuxのスワップ領域として利用します。

```
% sudo dd if=/dev/zero of=/swapfile bs=1M count=1024
% sudo chmod 600 /swapfile
% sudo mkswap /swapfile
% free
              total        used        free      shared  buff/cache   available
Mem:        1011064       91304       72464        3516      847296      746632
Swap:             0           0           0

# この時点でfreeしてもまだシステムに認識させてないので０ですよ^^;

% sudo swapon /swapfile
% free
              total        used        free      shared  buff/cache   available
Mem:        1011064       92348       70168        3516      848548      745592
Swap:       1048572           0     1048572

# 認識されました！！
```
という感じです。
あとは`/etc/fstab` に書いとけば再起動してもswap割当てられます。

```
/swapfile  swap        swap    defaults        0   0 # 追記
```

以上。
Facebook Audience Network SDK設定のながれ

Facebook Audience Networkで収益化する方法の流れ

収益化を始める5つのステップ

・ビジネスマネージャの新規または既存アカウントを使用して、収益化マネージャを設定します。
→https://business.facebook.com/　（ビジネスマネージャ作成）
→https://business.facebook.com/pub　（収益化マネージャを設定）

・収益化マネージャでプラットフォームを選択し、Audience Network広告の配置を作成します。
![1.jpg](https://qiita-image-store.s3.amazonaws.com/0/275421/facd3c9d-a960-b164-041a-e2f543d86f96.jpeg)

・アプリにAudience Network SDKと配置を統合します。Facebookアプリをインストールした機器から広告リクエストを送信し、配置をテストします。
![2.jpg](https://qiita-image-store.s3.amazonaws.com/0/275421/3333d194-f6b4-6fa9-6c3f-7ce6880ede9d.jpeg)

・支払い情報を追加します。
https://www.facebook.com/help/publisher/103628146695524/
![3.png](https://qiita-image-store.s3.amazonaws.com/0/275421/afd98570-c8b8-661b-ed40-1a1b06846417.png)

・アプリをレビューに送信します。
![4.jpg](https://qiita-image-store.s3.amazonaws.com/0/275421/975ca828-04ec-47b7-f8a0-01b7428fd56e.jpeg)

Audience Networkスタート
https://business.facebook.com/pub/start

モバイルSDKのダウンロード
https://developers.facebook.com/docs/audience-network/download
Autotoolsでのbuildに慣れた人がcmakeでのbuildで???となったメモ

# Autotoolsでのbuildに慣れた人がcmakeでのbuildで???となったメモ

使おうと思ったソフトをビルドしようとおもったらcmakeでのビルドだった。なるべくユーザー領域で完結したいので、インストール先を変えたりそれに対応してリンカオプションを設定したくなる。
autotoolsだったら迷わずにまず ``./configure --help`` だが、cmakeではどうすればいい？となったので、メモ。

## cmakeで``./configure --help``に相当するのは？

autotoolsでは、``./configure --prefix=??? --with-???=???`` といったオプションで指定するが、cmakeでは、``cmake -D(変数)=(値)``と指定することになる。が、どんな変数があるのか？を調べたい。いくつか方法があるようだ。

1. ``cmake --help-variables`` : これはソフトウェアパッケージによらない変数一覧がでる。説明文付きで長い。ページャーにパイプしないと見てられない。 
1. ``cmake -L[A][H] (ソースディレクトリ)``: ``A``をつけないと主要なものだけが表示されるようだ。``H``をつけると、短い変数の説明文がついて表示される。詳細は、``cmake --help-variable (変数名)``で調べることが想定されているのかもしれない。
1. ``ccmake (ソースディレクトリ)``: 独自のUIで変数の表示/指定ができるようになっている。

他にGUIなどあるようだ。

## 実際にどのようにコンパイルされているのか？

cmakeで作成されたMakefileでは、実際に``make``と叩いても、進捗表示しか表示されないので実際にどんなオプションでコンパイルされているのか見えない。見えるようにするには、``make VERBOSE=1``とすればいいらしい。

## 参考
  - [CMakeを使ってみた（1）経緯と簡単なアプリケーション](https://www.wagavulin.jp/entry/2011/11/27/222636)
ViewからControllerへ配列を渡す方法【Rails】



##起こった問題
viewから配列で渡すと、コントローラ側では結合された状態で渡ってしまう。

```slim
form_tag update_users_path, method: "patch" do
  = hidden_field_tag "users", users.ids
  = submit_tag "送信"
```

**view側**

```ruby
> users
> [1, 2, 3, 4]
```

**controller側**

```ruby
> params[:users]
> "1,2,3,4"
```

```ruby

users = params[:users]
Users.where(id: users)

#こうなってしまう
#Users.where(id: "1,2,3,4")
```

これでは、idが1のuserしかとれない。

やりたいこととしては、**viewからcontrollerに、全userのidが入った配列を渡したい。**

```ruby

> params[:users]
> [1, 2, 3, 4]
```

```ruby

users = params[:users]
Users.where(id: users)

#これがしたい
#Users.where(id: ["1", "2", "3", "4"])
```


しかし、paramsで受け取る際、配列としてうまく渡らずにいろいろ試行錯誤したので備忘録として残しておきます。



##joinを使って文字列の配列として渡す

前提知識として、**paramsは文字列として受け取ります**

joinを使って文字列を区切って渡してみましょう。

```view.html.slim
form_tag update_users_path, method: "patch" do
  = hidden_field_tag "users", users.ids.join(",")
  = submit_tag "送信"
```

**view側**

```ruby

> users
> "1,2,3,4"
```

**controller側**

```ruby

> params[:users]
> "1,2,3,4"
> params[:users].split(",")
> ["1", "2", "3", "4"]
```
連結されたのでcontroller側でsplitで配列にしてあげます。
これで配列で渡したidに基づいたuserを取得することができます。

```rb


users = params[:users].split(",")
Users.where(id: users)

#Users.where(id: ["1" ,"2" ,"3" ,4"])
```

##まとめ

**viewでjoin**、**controllerでsplit**でうまくいきました。
殴り書きなので記載ミスがあるかと思いますが、やさしくしてくれるとありがたいです。
2018-08-28 記事の検索性 > (タグを付加することで)ストック検索性を高める考えがありながら(不特定多数の人にそれをお願い)する方法を知らない

> CUDAのドライバーのインストールに躓いた。
> そのエラー回避はこうです。

そういう記事が見つかりストックしたとする。
ストック検索でその記事を後日見つけることができるか?

(下記の件数は自分の状況での例です)
A. CUDAタグ: 1976件
B. CUDAタグ + setupタグ: 2件
C. CUDAタグ + installタグ: 2件
D. CUDAタグ + 環境構築タグ: 8件
E. CUDAタグ + 環境構築(キーワード): 63件
F. CUDAタグ + インストールタグ: 2件
G. CUDAタグ + インストール(キーワード): 212件

上記の状況では「どのキーワード、どのタグで探せばいいか]、考える時間が発生する。
あるいは、CUDAタグのみで1976件を見直すかというと、それはしないだろう。

CUDAインストール時の躓きについての記事は、「CUDAタグ + 一つの追加タグ」で見つかると情報に到達しやすいと考えている。

タグをもっとうまく使えばいいと思うが、それを不特定多数の人にお願いするのはシステム上でサポートしない限り無理だろう。

あるいはStackOverflowのように、ボランティアがより良いタグを編集リクエストし続ける。
そして、記事執筆者がそれに従いリクエストを受付ける。

情報を残す人は増えているかもしれないが、「検索性を考慮して」残している人はまだ少ない気がする。

### タイトル

inspired from スティーブス(うめ、松永肇一)のコラム
「地平線の先まで見る目がありながら行く方法を知らない」
Go1.11に各種環境（HostPC/Goland/circleci）をアップデートする

Go1.11に各種環境（Goland/hostPC/circleci）をアップデートする。（2018/8/28寄稿）

# Host PC

Homebrewで入れてる場合は下記でかんたんに。

```bash
-> % brew upgrade go
-> % go version
go version go1.11 darwin/amd64
```

もし、なにか動かないときはuninstallしてからinstallし直しても1.11が入る。

```bash
-> % brew uninstall go
-> % brew install go
```

# Goland
設定に行きます。

<img width="238" alt="Screen Shot 2018-08-28 at 10.30.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/84126/916315d2-7df4-d1db-9199-6b26b043d6a8.png">

GOROOTを変えるとGolandの設定も更新されます。
<img width="1029" alt="Screen Shot 2018-08-28 at 10.31.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/84126/d082f590-64c6-f12f-8e99-bbf749d6a886.png">

# circleci

circleci公式イメージを使用している場合は、すでに1.11タグで公開されています。使用イメージを更新しましょう。

https://hub.docker.com/r/circleci/golang/tags/

以上
intra-martのワークフローマスタが「編集対象の定義情報が他のユーザによって変更されました」エラーで更新できない時

#状況
IM-Workflow関連のマスタ「コンテンツ定義」「ルート定義」「フロー定義」を編集しようとすると、「編集対象の○○定義情報が他のユーザによって変更されました。」というエラー表示されて更新ができない。

#解決方法
1. テナント管理メニューの「TableMaintenance」または「データベース操作」が可能なユーザでログインします。
「データベース操作」はシステム管理ページでも利用可能。

2. 以下のテーブルの`update_count`フィールドを参照します。
　コンテンツ定義: `imw_m_contents`
　ルート定義: `imw_m_route`
　フロー定義: `imw_m_flow`

3. 更新できない定義情報と同じIDで`locale_id`が異なるレコードの`update_count`を、全て同じに修正します。根拠はないが最大値に合わせるのがいいと思う。

「データベース操作」を使うなら、以下のSQLを流せばOK。

```sql
-- コンテンツ定義
update imw_m_contents a
set update_count = (
   select max(update_count)
   from imw_m_contents b
   where a.contents_id = b.contents_id
)
```

```sql
-- ルート定義
update imw_m_route a
set update_count = (
   select max(update_count)
   from imw_m_route b
   where a.route_id = b.route_id
)
```

```sql
-- フロー定義
update imw_m_flow a
set update_count = (
   select max(update_count)
   from imw_m_flow b
   where a.flow_id = b.flow_id
)
```

#原因
自環境とロケール構成が異なる環境からワークフロー定義をエクスポートして自環境にインポートすると、エクスポート元に存在するロケール情報のみ更新されます。
このため、`update_count`にずれが生じることにより発生する模様。
eslint-plugin-prettier と prettier-eslintの使い分け

[eslist](https://eslint.org/)と[prettier](https://prettier.io/)を併用してるのですが、恥ずかしながら今ごろ知りました。。。

この併用するには
1. prettier-eslintを使う
2. eslint-plugin-prettierを使う

の２つの方法があることを！！

## それぞれの特徴

### [prettier-eslint](https://github.com/prettier/prettier-eslint#prettier-eslint)
> This formats your code via `prettier`, and then passes the result of that to `eslint --fix`

 `prettier`を通してから、その結果をさらに`eslint --fix`に通すんやで。
とのこと。
[prettier-eslint-cli](https://github.com/prettier/prettier-eslint-cli)と一緒に使うことで、コマンドラインから便利に使えるようになるみたい。

### [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier)
> Runs Prettier as an ESLint rule and reports differences as individual ESLint issues.

ESLintのルールでprettierを走らせて、ESLintのエラーをレポートするで。
って感じ？
それよりも重要なのは
> The rule is autofixable -- if you run eslint with the `--fix` flag, your code will be formatted according to `prettier` style.

`eslint --fix`で、`prettier`のスタイルを適用してフォーマットするで。
とのこと。
[eslint-config-prettier](https://github.com/prettier/eslint-config-prettier)で、prettierとeslintのルール間のコンフリクトを解決してくれる。

## prettier-eslint vs eslint-plugin-prettier
じゃ、どっちを使えばええんや:scream::scream::scream:

やっぱり同じ疑問を持った人がいて、prettierのコントリビューターが答えてくれてる。
https://github.com/prettier/prettier-eslint/issues/11

この２つの違いのポイントが、
__prettier-eslint__はprettierの結果を`eslint --fix`に渡す。なのでeslintの設定が優先され、prettierのフォーマットは上書きされてしまう可能性がある。
__eslint-plugin-prettier__は`eslint --fix`と同時に動かすので、prettierのフォーマットは保たれる。

> eslint-plugin-prettier - ESLint plugin. While prettier-eslint uses eslint --fix to change the output of prettier, eslint-plugin-prettier keeps the prettier output as-is and integrates it with the regular ESLint workflow.
>https://github.com/prettier/prettier-eslint#related


なので、どちらを使うのがベストとういわけではなくケースバイケースになるみたい。

## 個人的感想
__eslint-plugin-prettier__を使ってます。自分のプロジェクトではairbnbのスタイルをベースにしているのですが、運用上これで問題になっているところは今の所ありません。
eslintに規約をゴリゴリに書いて、prettierは補助的に使いたいという人などは__prettier-eslint__を使う選択の方がいいのかもしれないと思いました！
Vim — 複数行をカット&ペーストする ( 3行カットするなら 3dd → p )

# 3行カットしたい場合

## カット

```
3dd
```

## ペースト

```
p
```

# 環境

- vim 7.3

# あわせて読みたい

- [Qiitaに記事を書く動機は「ググりにくい記事を、ググりやすく」するためでOK - Qiita](https://qiita.com/YumaInaura/items/e83df9a45836f7b2929b)
- [Vim — 複数行をコピー&ペーストする ( 3行コピーするなら 3yy → p ) - Qiita](https://qiita.com/YumaInaura/items/6334afed820774a28cb1)








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
AWS EC2 上の Windows で再起動時にシステム時刻が狂う問題の対処

どういう前提条件で再現するのかは不明ですが、タイトル通り AWS EC2 上の Windows で再起動時にシステム時刻が数時間単位で狂う問題が再現することがあります。

Windows か EC2 の仮想化ソフトウェアのどちらか以外でシステム時刻を勝手に弄るようなソフトウェアやバグなど他にはそうそうないと考え、最初は Windows の自動時刻調整が悪さしてることも疑っていたのですが、自動時刻調整をOFFにしてても再現し、また自動時刻調整を有効にしてても再起動をかけない分には問題が再現しないので、恐らくは EC2 の仮想化ソフトウェアのタイムゾーン絡みのバグではないかと踏んでいます。

Windows の自動時刻調整を信用する前提でサーバー起動時に自動時刻調整を実施する為の次のコマンドが自動実行されるように設定したところ、その後問題は確認されなくなりました。(と言うか問題が発生してもすぐに修正される)

```cmd
w32tm /resync
```
C# 8 で null 安全が導入されるらしいので、??（null 合体演算子）、?. ?[]（null 条件演算子）を復習する

## C# 8 あたりから導入される `null` 安全について

C# 8 あたりから`null`安全が導入される予定だそうです。

- **参考：[ピックアップRoslyn 4/4 C# 8.0辺りの検討事項](https://ufcpp.net/blog/2018/4/pickuproslyn0404/)**

C# では値型（`int`や`struct`など）は`null`値は取れません。
値型で`null`値をとるには`null`許容値型（`int?`など`?`をつける）を使います。
一方、参照型（`string`や`class`など）はデフォルトで`null`許容型であり、`null`値の許容、非許容が区別されていません。

ですので、以下のコードはコンパイルが通りますが、ユーザーオブジェクトを取得する`TryGetUser`メソッドが実行時に`null`を返した場合、`user.Name`は`null`参照例外をスローします。

```cs
var user = TryGetUser(id);
string name = user.Name; // => user が null なら System.NullReferenceException
```

参照型でも`null`許容、`null`非許容の区別が付くようになった場合、null参照例外が発生するコードはコンパイル時に検出してくれるようになります。
つまり、実行時に`null`参照例外がスローされる心配がなくなります。

`null`安全が導入されると、コード上で`null`かどうかを判断し処理を分岐させる必要が出てきますが、`if`文などの条件分岐を使うと冗長になります。

```cs
var user = TryGetUser(id);
if (user == null)
    return;
string name = user.Name   
```

そこで、既にある`??`（`null`合体演算子）、`?.` `?[]`（`null`条件演算子）を使用すると簡潔に書くことができるようになります、

##### 参考：`null`安全とは、何が嬉しいのかについて

- **[null安全でない言語は、もはやレガシー言語だ](https://qiita.com/koher/items/e4835bd429b88809ab33#null-%E5%AE%89%E5%85%A8%E3%81%A8%E3%81%AF%E4%BD%95%E3%81%8B)**
- **[null安全を誤解している人達へのメッセージ](https://qiita.com/omochimetaru/items/ee29d4c6eb0d78f02b15)**

##### 参考：C# における`null`参照問題について

- **[nullが生まれた背景と現在のnullの問題点 ― null参照問題（前編）](https://www.buildinsider.net/column/iwanaga-nobuyuki/011)**
- **[C#でのnull参照問題への取り組み ― null参照問題（後編）](https://www.buildinsider.net/column/iwanaga-nobuyuki/012)**

## `??`（`null`合体演算子）

`??`は`null`合体演算子や`null`カスケード演算子と呼ばれます。
左辺が`null`でない場合は左辺を返し、`null`である場合は右辺を返します。

下記のコードは、`TryGetUser`が`null`を返した場合、右辺の`DefaultUser`が評価されます。

```cs
User user = TryGetUser(id) ?? DefaultUser();
```

## `?.` `?[]`（`null`条件演算子）

`?.` `?[]`は`null`条件演算子と呼ばれています。
`?.` `?[]`はメンバーやインデックスのアクセスの前に、左辺が`null`かどうかテストし`null`でない場合、アクセスが行われます。
左辺が`null`の場合、`null`が返ります。

下記のコードは`user`が`null`出ない場合、`Name`の値が返り、`null`の場合には`null`を返します。
`user`が`null`でも`NullReferenceException`は発生しません。

```cs:
var name = user?.Name;
```

また下記のコードも`users`（`User`のコレクションを想定）が`null`でも`NullReferenceException`が発生しません。

```cs:
var second = users?[1];
```

`if`文や`?:`（三項演算子）を使った場合に比べて読みやすいと思います。

```cs:
// if 文
string name;
if (user != null) name = user.Name;

// 三項演算子
var name = (user == null) ? null : user.Name;
```

## `?.` `??`の合わせ技

`?.` `??` を組み合わせて使うこともできます。
`user`が`null`の場合、`"名無しの権兵衛"`、`null`でない場合`Name`の値が返ります。

```cs:
var user = TryGetUser();
string name = user?.Name ?? "名無しの権兵衛"
```

## `??=`（`null`合体代入演算子）

2019/05/23追記。

```csharp
string name1 = null;
name1 ??= "NULLのときの名前";
Console.WriteLine(name1); // "NULLのときの名前"

string name2 = "nossa";
name2 ??= "NULLのときの名前";
Console.WriteLine(name1); // "nossa"
```
Winmerge portable にDiffコンテキストがない

##WinMerge Portable
(参考)WinMerge 日本語版＞WinMerge Portable
https://portableapps.com/apps/utilities/winmerge_portable
Version 2.14.0.0 Japanese Unicode
・表示(V)＞Diffコンテキスト(D)がない
・表示(V)＞垂直分割(E)がない

##winmerge
(参考)WinMerge 日本語版
(参考)winmerge-2.14.0-jp-152-x64-exe
Version 2.14.0.152+jp-152 japanese Unicode X64
Facebook Audience NetworkをiOSで実装しようとしたらハマった話

AdMob Mediationを使用してFaceBook Audience Network(FAN)を実装しようとしたけど全然表示されなくて困った話。

結論としては、広告枠をバナーにしてたのに、Viewの高さが50じゃなかったのが原因でした。
200にしてたらリクエストも送信されないしエラーログも出ないし。

同じように困ってる人の助けになれば幸いです。
それでは。
GPSの研究　その46

#概要
gpsを理解したかった。
rtknaviで、ローバーubx,ベースubxでfixするか、実験してみた。

#結果
fixする。

![fix.png](https://qiita-image-store.s3.amazonaws.com/0/18104/e6391d27-965b-9d6b-9f29-ce61c1c9a6b8.png)


以上。
numpyを使ってみる

計算をかんたんにできるという、「numpy」を使ってみた。
3分でできるお手軽さ。

まずはnumpyモジュールをインストール。pipが入ってない場合。(OSはxubuntuです)

>sudo apt install python3-pip
>pip3 install numpy

電気科で死ぬほどやる行列のかけ算。
なんだ、この楽さ。

```test_numpy.py

import numpy

n_array = numpy.array([[1,2,3],[4,5,6],[7,8,9]])
n_array2 = numpy.array([[2,2,2],[3,3,3],[4,4,4]])

print(n_array)
print("*\n")
print(n_array2)
print("=\n")

print(n_array * n_array2)
【初心者の質問】戻り値について

VBAで戻り値を返すにはSubではなく、Functionプロシージャーを使うとあり、

VBA関数は、処理の材料となる値:引数と、結果の値:戻り値が返ります。
とあります。

```vb
Sub sumple()
 Dim i As Integer
 i = Msgbox("今日は晴れですか",vbyesno,"今日の天気は")
End Sub
```

上記で、Msgbox関数の戻り値がiの変数に代入ということですよね。

この場合Subプロシージャで記述するのはどうしてでしょうか？
PythonのWebフレームワークDjangoでバッチ処理（カスタムコマンド）を行うときのPyCharmでのデバッグ方法

社内ツールの開発を効率的に行うことができるPythonのDjangoフレームワークを使用する際に、
Webサイトとは別にバッチを作成したいときはカスタムコマンドを作成します。
カスタムコマンドを実装するときにIDEのPyCharmでデバッグする方法を紹介します。

![スクリーンショット 2018-08-27 15.18.58.png](https://qiita-image-store.s3.amazonaws.com/0/34488/75769f92-3679-a812-8f15-2fdaa8841b77.png)

# Djangoについて
Djangoはニュース系サイトを管理する目的で開発されたPythonのWebフレームワークです。
ユーザー管理やデータ変更画面がデフォルトで用意されているため、
社内ツールなどを開発するときに短時間で作成できます。
![スクリーンショット 2018-08-27 14.29.10.png](https://qiita-image-store.s3.amazonaws.com/0/34488/9ce0e175-f273-d77e-4181-27d8e6bc7967.png)
Djangoの開発を行うにはPyCharmを使用するのが便利です。


# PyCharmについて
JetBrainsが提供するPython用IDEです。
無料版のCommunity Editionと、月額2000円程度の有料版のProfessionalが存在します。
[![スクリーンショット 2018-08-27 14.17.46.png](https://qiita-image-store.s3.amazonaws.com/0/34488/e95a5cdd-5a30-48cb-504a-546bb21ce7e3.png)](https://www.jetbrains.com/pycharm/)

# Djangoカスタムコマンド
Djangoで作成したDB操作のためのクラスを使用してGUIでなくバッチ処理を行うためには、
カスタムコマンドを作成します。
CustomCommandの作成方法は公式ドキュメントが分かりやすく記載されているため、
以下を参考にしてください。
[公式ドキュメント：カスタム django-admin コマンドの実装](https://docs.djangoproject.com/ja/2.1/howto/custom-management-commands/)

# PyCharmでのデバッグ方法
公式のDjangoカスタムコマンドのドキュメントに従って、
mysiteプロジェクト内にpollsアプリケーションのclosepollコマンドがある状態を用意します。
![スクリーンショット 2018-08-27 13.48.21.png](https://qiita-image-store.s3.amazonaws.com/0/34488/2a284fbe-0b44-dd71-f875-b3956b1a4a4d.png)
「Run」→「Edit Configurations」を選択

![スクリーンショット 2018-08-27 13.51.54.png](https://qiita-image-store.s3.amazonaws.com/0/34488/116a3fe7-80b9-89cc-41d4-baec8ba32915.png)

左上の「+」ボタンを選択

![スクリーンショット 2018-08-27 15.18.12.png](https://qiita-image-store.s3.amazonaws.com/0/34488/63addc9a-ffef-1b44-eb3b-7ff41eb5f54f.png)

「Script path」と「Working directory」に実行したいアプリケーションのmanage.pyのパスを設定。
（Working directoryのパスが設定されているので、Script pathはmanage.pyのみでもOKです。）

「Parameters」にコマンド名の「closepoll」を設定し、
右下の「OK」を選択。
![スクリーンショット 2018-08-27 15.18.58.png](https://qiita-image-store.s3.amazonaws.com/0/34488/b82fecbb-3cc6-2ce0-5b1e-75de18d81a34.png)

ブレイクポイント（赤丸）を設定し、右上のデバッグボタンを押下してデバッグ実行すると、ブレイクポイントで止まりデバッグすることができます。



# 参考
https://stackoverflow.com/questions/17141817/how-to-debug-django-commands-in-pycharm
https://docs.djangoproject.com/ja/2.1/howto/custom-management-commands/
https://qiita.com/ytyng/items/a64d474c40587459d52f
pythonでdate, datetime型を含むlistやdictをjson文字列に変換する

# json.dumpsで発生するエラー:sob:

```python
import json
from datetime import datetime

test = [datetime.now()]
json.dumps(test)

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/json/__init__.py", line 244, in dumps
    return _default_encoder.encode(obj)
  File "/usr/lib/python2.7/json/encoder.py", line 207, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python2.7/json/encoder.py", line 270, in iterencode
    return _iterencode(o, 0)
  File "/usr/lib/python2.7/json/encoder.py", line 184, in default
    raise TypeError(repr(o) + " is not JSON serializable")
TypeError: datetime.datetime(2018, 8, 28, 2, 52, 36, 329332) is not JSON serializable
```

何も考えずに実行すると上記のエラーが発生します。
datetime型の項目を含んだ状態でjson.dumpsで文字列に変換しようとすると、シリアライズが出来ないというエラーが！

# シリアライズできない項目を考慮した設定を追加してから実行:stuck_out_tongue_closed_eyes:

```python
import json
from datetime import date, datetime

test = [datetime.now()]

def sugoi_json_dumps(json_obj):
    def json_serial(obj):
        # 日付型の場合には、文字列に変換します
        if isinstance(obj, (datetime, date)):
            return obj.isoformat()
        # 上記以外はサポート対象外
        raise TypeError("Type %s not serializable" % type(obj))
    return json.dumps(json_obj, default=json_serial)

sugoi_json_dumps(test)
'["2018-08-28T02:57:02.747438"]'
```

と、こんな感じで表示されてくれます。
json.dumpsのdefaultに関数を渡してあげればOKです:ok_hand:


# 最後に
[株式会社ネコカリ](https://www.nekokari.co.jp/)では猫の手も借りたい🔥炎上中🔥なお仕事を募集しています！
一緒に働くメンバーも募集していますので、よかったら是非！
Djangoのviewでloginした状態をテストする

#テスト対象のコード

```python:view
from django.shortcuts import render


def home(request):
    if request.user.is_authenticated:
        username = str(request.user)
        context = {'username': username}
        return render(request, 'dashboard.html', context)
    else:
        return render(request, 'welcome.html')
```

上記のviewをテストする。

loginされた状態(`request.user.is_authenticated`が`True`)か否かで正しく処理が分岐できることを確認したい。

#テストツール

viewをテストするには、ダミーのウェブブラウザとして振る舞う`django.test.Client`を使う。loginされた状態をシミュレートするには`Client`のメソッド`force_login`が使える。

公式ドキュメントには、以下の通り記載されている
> force_login(user, backend=None)
>
>    If your site uses Django's authentication system, you can use the force_login() method to simulate the effect of a user logging into the site. Use this method instead of login() when a test requires a user be logged in and the details of how a user logged in aren't important.

ここの`user`をどのように指定すれば良いかパッとは分からず、あれこれ検索した。
その結果、`django.contrib.auth.models.User`の提供する、`User.objects.create_user`を使えば良さそうなことが判明。

また、loginされていない状態をシミュレートするには`Client`のメソッド`logout`が使える。

#テストコード

ここまで調べた結果を用いて作成したテストコードは以下の通り。ここで、viewである`home`はURL`/`は紐付いているものとする。

```python:test
from django.test import TestCase, Client
from django.contrib.auth.models import User


class TestViewsHome(TestCase):

    def test_not_authenticated(self):
        client = Client()
        client.logout()
        response = client.get('/')
        self.assertFalse('username' in response.context)

    def test_authenticated(self):
        client = Client()
        client.force_login(User.objects.create_user('tester'))
        response = client.get('/')
        self.assertTrue('username' in response.context)
        self.assertEqual(response.context['username'], 'tester')
```

1件目がloginされていない状態のテスト。応答にはユーザ名(key: `username`)が含まれていないのが期待。
2件目がloginされた状態のテスト。応答には、loginした時のユーザ名が含まれているのが期待。

#テスト実行

以下の通り。２件とも成功。

```shell
$ python manage.py test
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
..
----------------------------------------------------------------------
Ran 2 tests in 0.143s

OK
Destroying test database for alias 'default'...
```

カバレッジを参照する。viewを実装したファイルが100%になっているので、`request.user.is_authenticated`が`True`と`False`のどちらのケースもテストできている。

```shell
$ coverage run --source='.' manage.py test
$ coverage report
Name                                   Stmts   Miss  Cover
----------------------------------------------------------
...
apps/views/home.py                        7      0   100%
```

#参考にしたサイト

https://docs.djangoproject.com/ja/2.1/topics/testing/tools/
https://docs.djangoproject.com/ja/2.1/topics/auth/default/
Amazon Linux WorkSpaces でシェルのプロンプトを短くする

Amazon WorkSpaces で作った Linux 環境のシェルのプロンプトがとても長いです。

![toolong.png](https://qiita-image-store.s3.amazonaws.com/0/63688/efc56c40-ff1a-73f8-87ac-ac9c30e8aefe.png)

元々のユーザー名とコンピュータ名が長い上に、先頭にドメイン名までくっついています。

あまりに長いので、短くします。

```bash:~/.bashrc
export PS1="\w\[$(tput sgr0)\] $ "
```

ディレクトリ名のみ。デスクトップなのでこれで十分です:relieved:

結果は…。

![sukkiri.png](https://qiita-image-store.s3.amazonaws.com/0/63688/126c7c15-b695-cf94-4b5f-bfbf1b492c63.png)

PS1 の値は [.bashrc PS1 generator]([http://bashrcgenerator.com/]) で作成しました。
Shellのテストフレームワーク bats を使ってみる

## Github

[sstephenson/bats: Bash Automated Testing System](https://github.com/sstephenson/bats)

## ポイント

- 他言語のユニットテスト同じようなフォーマットでテストが書ける
  - `setup` `teardown` `skip` や helper の仕組みがある
  - アウトプットもフォーマルな形式 ( e.g `5 tests, 2 failures, 1 skipped` )
- インストールが簡単、インストール用のシェルスクリプトを叩くだけ
- Star数はかなりのもの、5000近い
- 2018年8月現在でもメインバージョンがゼロ.
  - 最後のバージョンアップが2014年　( `0.4.0 (August 13, 2014)` )
https://github.com/sstephenson/bats/pull/6
- テストの結果表示で変数展開をしてくれない ( e.g `[ "$one" -eq "$two" ]` )
  - テストが何故成功したか、失敗したかの詳細が分かりづらい
- シェルスクリプトのように `-eu` オプションが使えないので、変数未定義に注意する必要がある
- 確かに完璧ではないけれどオレオレテストを書くよりは良いかもしれない
  - 探したら他にも色々フレームワークがありそう (試したい)

## 簡単なスクリプトの例

`./example-test`

```sh
#!/usr/bin/env bats

function setup() {
  one=1
  two=2
}

@test "succeed case" {
  [ 1 -eq 1 ] 
}

@test "succeed case ( use variable )" {
  [ "$one" -eq "$one" ]
}

@test "failure case" {
  [ 1 -eq 2 ] 
}

@test "failure case ( use variable ) " {
  [ "$one" -eq "$two" ]
}

@test "undefined variables but succeeded case" {
  [ "$none" = "$none" ] # Ooops this case succeed
}

@test "skip case" {
  skip
  [ 1 -eq 2 ]
}

```

## 結果の例

```sh
 ✓ succeed case
 ✓ succeed case ( use variable )
 ✗ failure case
   (in test file tmp/bats, line 17)
     `[ 1 -eq 2 ]' failed
 ✗ failure case ( use variable )
   (in test file tmp/bats, line 21)
     `[ "$one" -eq "$two" ]' failed
 ✓ undefined variables but succeeded case
 - skip case (skipped)

6 tests, 2 failures, 1 skipped
```

![image](https://user-images.githubusercontent.com/13635059/44672594-dfeaee80-aa63-11e8-8619-d2a5b5651a4a.png)

## Versions

- Bats 0.4.0

## Lins

- [Gist](https://gist.github.com/YumaInaura/08696625b2a32f48b7cd384f39235ea9)








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->