OmniAICreator/Qiita-1.07M huggingface dataset:
GitHubの道① アカウント登録編

　若干制限があるものの非公開で使えるプライベートリポジトリがGitHubで無料になった。安定して高速に動作するGitHubは非常に便利である。個人でも企業でもGitHubを使う機会は増えるのではないだろうか。一方、プライベートリポジトリには外部に公開できないデータが含まれるので、その運用にはセキュリティ関連のことを強く意識する必要がある。考え方は色々あると思うが、私の運用方法を何回かに分けて紹介する。今回はアカウント登録・二段階認証設定・SSH公開鍵の登録を説明する。なお、この記事はLinuxを前提にしている。

#アカウントの登録

https://github.com/join よりGitHubに登録する。画面の指示に従えば特に問題ない。

#二要素認証の登録

パスワードだけの認証では不安なので、SMSによる二要素認証を導入する。

1. https://github.com/settings/security より Enable two-factor authentication ボタンをクリックする。(下図赤丸部分)

![1.png](https://qiita-image-store.s3.amazonaws.com/0/171932/88f81da0-18c3-bea5-3da5-ac1edda1fc7b.png)

2.二要素認証にSMS認証を使用する場合はSet up useing SMSをクリックする。(下図赤丸部分)
![2.png](https://qiita-image-store.s3.amazonaws.com/0/171932/e832cc31-c86b-a11b-f092-8d51283122e5.png)

3.次にリカバリーコード画面(下図)が出てくるので、①のdownload/print/copyのいずれかをクリックしコードは保存する(もっとも、私は使ったことがない)。その後②のNextをクリックする。

![3.png](https://qiita-image-store.s3.amazonaws.com/0/171932/50ace8bf-cac2-db84-9ada-11ec1b6ae851.png)


4.Country CodeにJapan +81(下図①)をphone number(下図②)に電話番号の一桁目を削った番号を入力する。(例) 080XXXXXXXXの場合80XXXXXXXX

![4.png](https://qiita-image-store.s3.amazonaws.com/0/171932/7019ac26-109d-8ed2-69a8-ff01fd94fa8e.png)

5.Send authentiocation codeボタンを押す。(上図③)
6.しばらくすると、指定した電話番号にSMSで6桁の数字が送られてくるのでEnter the six-digit code sent to your phone(上図④)に入力し、Enable(上図⑤)をクリックする。

ここまで終了すると、ログイン時にSMSでGitHubから送信される6桁の数字を求められるようになる。

#SSH公開鍵の登録
　SSH鍵を使うとgitコマンドでのパスワードの入力が不要になる。秘密鍵の流失には注意してほしい。
##SSH公開鍵と秘密鍵の作成(作業PC)
　公開鍵の暗号方式には対応ソフトも多く十分に安全なECDSAを使用する。作業するPCで、ssh-keygenコマンドを利用し、~/.ssh以下に鍵ペアを作りcatコマンドで公開鍵を表示させ、クリップボードにコピーする。

```sh:ECDSAの例
$ ssh-keygen -t ecdsa
$ cat ~/.ssh/id_ecdsa.pub
ecdsa-sha2-nistp256 AAA(略)
```

|鍵種|ファイル|
|--- |--- |--- |
|公開鍵 |~/.ssh/id_ecdsa.pub|
|秘密鍵 |~/.ssh/id_ecdsa|

##SSH公開鍵の登録(github)
1.https://github.com/settings/keys よりSSH Keyをクリックする。
![5.png](https://qiita-image-store.s3.amazonaws.com/0/171932/5aab04b7-e8e4-da87-869e-24eb32f76c17.png)
2.公開鍵を下図①にペーストし、②をクリックする。(Titleは何でも良い)
![6.png](https://qiita-image-store.s3.amazonaws.com/0/171932/e7e5953d-e98a-c369-7667-e5c54a09d11c.png)

成功すると前画面に戻り、登録した公開鍵を示すものがリストに表示される。

#まとめ
　GitHubにアカウントができ二要素認証とSSH鍵を用いることで、基本的な部分のセキュリティは担保できたと言えるだろう。なおGitHubではSSH鍵ではなくhttpsとパスワードを使う方法を推奨しているようだが理由はわからない。
 次回はGitの概念を簡単に整理する。
GoからLuaのユーザーコードを実行する

# やりたいこと

Goの中で安全にユーザーコードを実行したい。GoにはいくつかのLua処理系が移植されているので、Goの空間からLuaを呼び出す方法を試した。**なお、この記事は試したこと、気付いたことを書捨てているだけなのであまり参考にしないよう。**

# わかったこと

Lua処理系は [gopher-lua](https://github.com/yuin/gopher-lua) を使った。この処理系はLua 5.1の機能を提供している（一部機能は未実装）。

Go上でのLuaスクリプトの実行は、文字列を読み込んで評価する方法、外部ファイルを読み込んで実行する方法がある。次の２つはどちらも `hello` と出力する。

## 文字列を評価して実行する
```golang
L := lua.NewState()
defer L.Close()
if err := L.DoString(`print("hello")`); err != nil {
    panic(err)
}
```

## 外部ファイルを読み込んで実行する
```golang
L := lua.NewState()
defer L.Close()
if err := L.DoFile("hello.lua"); err != nil {
    panic(err)
}
```

## ユーザーコードをサンドボックスに閉じ込める

* [lua-users wiki sand boxes](http://lua-users.org/wiki/SandBoxes)

Lua 5.1では `env` に利用可能な関数を登録し `setfenv()` を利用してユーザーコードを実行することで、信頼されていないコードの実行中に利用可能な機能を制限できる。

```lua
-- ここで利用可能な関数を宣言する。 {} は何もなし
local env = {} -- add functions you know are safe here

-- 信頼されないコードを実行するための run関数
local function run(untrusted_code)
  -- この辺何やってるかよくわからん…
  if untrusted_code:byte(1) == 27 then return nil, "binary bytecode prohibited" end

  -- loadstringでユーザーコードの文字列を評価する
  local untrusted_function, message = loadstring(untrusted_code)

  -- 評価結果が得られなかったら何もしない
  if not untrusted_function then return nil, message end

  -- setfenvを使用して、ユーザーコード（を評価したもの）に実行可能な関数を定義した env を渡す。
  setfenv(untrusted_function, env)

  -- ユーザーコードを実行する
  return pcall(untrusted_function)
end
```

実行すると次のようになる。

```lua
-- print, debugは定義されていない関数なので実行できない
assert(not run [[print(debug.getinfo(1))]]) --> fails

-- 式はOK
assert(run [[x=1]]) --> ok
assert(run [[while 1 do end]]) --> ok (but never returns)
```

```lua
-- 正常に実行できる
print(run([[a=1]]))

-- エラー終了する
print(run([[print("hello")]]))
```

# Goからどのようにユーザースクリプトを実行するか？

`L.DoFile` を使って直接的にファイルを読み込むと、サンドボックス環境の生成前にスクリプトが実行されてしまうため利用できない。Go上でサンドボックスを立ち上げるコードとユーザーコードを連結し、 `DoString` で実行するといいかもしれない。

```golang
L := lua.NewState()
defer L.Close()

val := "" +
	"local env = {print=print}\n" +
	"\n" +
	"local function run(untrusted_code)\n" +
	"  if untrusted_code:byte(1) == 27 then return nil, 'binary bytecode prohibited' end\n" +
	"  local untrusted_function, message = loadstring(untrusted_code)\n" +
	"  if not untrusted_function then return nil, message end\n" +
	"  setfenv(untrusted_function, env)\n" +
	"  return pcall(untrusted_function)\n" +
	"end\n"

user_script := "" +
	"run [[print 'hello go!']]\n" +       // -> hello go!
	"run [[print(5.1)]]\n" +              // -> 5.1
	"run [[print(math.floor(5.1))]]\n" +  // -> mathがないので実行されない!!!
	"run [[print 'good bye']]"            // -> good bye

L.DoString(val + user_script)
```
Vue.js使いだして２年くらい経ったけど、使ったことないAPIを使ってみる「グローバルAPI」(2/2)

## [Vue.filter( id, [definition] )](https://jp.vuejs.org/v2/api/index.html#Vue-filter)

```js
Vue.filter('addCommas', function (value) {
  if (isNaN(value)) {
    return value
  }
  return value.toLocaleString('ja-JP')
})
```
```vue
{{ 1234 | addCommas }} // 1,234
```

`computed`でもできるけどもっと汎用的にどこでも使いたい場合に使うといいっぽい。

## [Vue.compile( template )](https://jp.vuejs.org/v2/api/index.html#Vue-compile)

全く使い方が思い浮かばないけど、

```js
var res = Vue.compile('<div><span>{{ msg }}</span></div>')
```
`console.dir(res.render)`
としてみると以下が含まれてる。レンダリングの仕組みを紐解くヒントになりそう。

```js:
(function anonymous(
) {
with(this){return _c('div',[_c('span',[_v(_s(msg))])])}
})
```

## [Vue.version](https://jp.vuejs.org/v2/api/index.html#Vue-version)

```js
Vue.version // 2.5.17
```
プラグインを作って配るときなどに、対応してない`Vue`のバージョンで使えないようにするとき便利。
「最小努力の法則」とコード品質

自戒の弁。

# 最小努力の法則

「最小努力の法則」というものがある。
これは、ある目標を達成するのに複数の方法が存在する場合、人間は最終的にもっとも少ない努力で済む方法を選択する、というものである。
私はこの法則を[「ファースト&スロー」](https://amzn.to/2GcTTVN)で知った。

これが、コード品質にも言えて、人間は動くための最小努力をして満足してしまう。
コードが動いた状態で満足してしまう。

# 立ち止まって見直そう

ここで本当はやらなくてはいけないのは、一度立ち止まって自分のソースコードを見直すということだ。
Gitなどでdiffをとって、本当にこのコードでいいかどうか、論理的に欠陥はないかを確かめてることが大切なのだ。

[「ファースト&スロー」](https://amzn.to/2GcTTVN)で言うところの **怠け者**のシステム2(遅い思考。論理的な思考)に働いてもらわなければいけない。

# 欠陥を探すためのテスト

私も直感型の人間なので、怠け者だ。
怠け者はテストを書くのをサボリがちだ。

ただ、上記で書いた論理的欠陥を洗い出すためにはテストが有効だ。
テストケースを正常系/異常系でテストケースを考え、入力に対して正しく出力されるかを確かめるのだ。
人間の認知の限界をテストで超えなければならない。

# テストが書きやすいコードを

ここで大事なのは **テストがしやすいコード** であることなのである。
テストをしづらいと、テストが書く気力が湧かない。
人間は低きに流れるので、できる限り流れないようにここをしっかりしなければならない。

今は大いに反省している。人類はもっとテストを書かなければならない。
初めてのJavaScript④



**オブジェクト**
配列と同じく複数のデータをまとめて管理するのに用いられる。

例
配列・・・[値1,値2,値3]
オブジェクト・・・{プロパティ1:値1,プロパティ2:値2}

・配列は複数の値を並べて管理するのに対して
オブジェクトはそれぞれの値にプロパティと呼ばれる名前をつけて管理する。

・オブジェクトも定数に代入することができる。

・オブジェクトの値を取り出すには、対応するプロパティ名を用いて 、
**「オブジェクト.プロパティ名」**のようにする。

・**「オブジェクト.プロパティ名 = 新しい値」**とすることで
オブジェクトの値を更新することができる。

・[{プロパティ1:値1…},{プロパティ2:値2}]という配列も作ることができる。
配列の中のオブジェクトのプロパティの値を取り出すには、
**「配列[インデックス番号].プロパティ名」**と書く。


-------
・躓いた点
console.log(`名前は${character.name} です`);
と入力したい時、「`」ではなく「'」を入力しており
正しく出力できなかった。

・気づいた点
パッと見るとややこしく感じるけれど
今まで使用した要素や文を覚えていたら問題なく理解できる。

-------

次はundefinedからです。
【Bootstrap】navbarの文字色を変えた時にちょっと詰まったこと

# はじめに
多分調べればほかにいい記事は出てきます。
自分がちょっと詰まったところなので、メモとして残しておきます。

# 変更方法
文字色の場合は`navbar-light`か`navbar-dark`、
背景色の場合は`bg-light`か`bg-bark`を削除して、別途スタイルシートなどに色を指定する。

```..html
# 変更前
<nav class="navbar navbar-light bg-light">
              --省略--
  <ul>
    <li>...</li>
  </ul>
</nav>

# 変更後(文字色背景色ともに変更する場合)
<nav class="navbar">
              --省略--
  <ul>
    <li>...</li>
  </ul>  
</nav>
```

変更したら好きな色を指定しましょう。

```..css
.navbar {
  background-color: 'カラーコード';
}

li {
  color: 'カラーコード';
}
```

# ハンバーガーメニューを搭載している場合
ハンバーガーメニューがある状態で、上記のように色の変更をするとハンバーガーメニューが見えなくなってしまいます。
そのためハンバーガーメニューの色も変更する必要があります。
変更点は枠と三本線の色ですが、必要に応じて背景色も変えられます。

```..css
.navbar-toggler {
  # 枠の色
  border-color: 'カラーコード';

  # 背景色
  background-color: 'カラーコード';
}

.navbar-toggler-icon {
  # 三本線の変更
  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='カラーコード' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 8h24M4 16h24M4 24h24'/%3E%3C/svg%3E");
}
```
三本線はSVGを利用しているようです。
`stroke=`の部分を変更して色を変えます。

# 参考
[Bootstrap4のハンバーガーメニューの色を変える方法](https://www.konnect-kollect.info/bootstrap4-hamburger-menu-customize.html)
[Bootstrap4においてハンバーガーメニューの色変更について](https://ja.stackoverflow.com/questions/51281/bootstrap4%E3%81%AB%E3%81%8A%E3%81%84%E3%81%A6%E3%83%8F%E3%83%B3%E3%83%90%E3%83%BC%E3%82%AC%E3%83%BC%E3%83%A1%E3%83%8B%E3%83%A5%E3%83%BC%E3%81%AE%E8%89%B2%E5%A4%89%E6%9B%B4%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6)
【テンプレートリテラル】と【オブジェクトリテラル】を覚えたら「ちょっと」いい感じにコードが書けた！

#概要
**【テンプレートリテラル】**と**【オブジェクトリテラル】**を覚えて**「ちょっと」**いい感じにコードが書けるようになったので、早速アウトプットします！

#テンプレートリテラル
バッククウォート`` `~` ``で囲む。シングルクォーテーション`'~'`じゃないよ。
極めたい人は[こちら](https://qiita.com/kura07/items/c9fa858870ad56dfec12)の記事を参照


```JavaScript
const today = new Date();
const year = today.getFullYear();
const month = today.getMonth() + 1;
const week = today.getDay();
const day = today.getDate();
const yobi =['日','月','火','水','木','金','土']

//es5
console.log("現在は"+year+"年"+month+"月"+day+"日"+yobi[week]+"曜日です。"); //現在は2019年1月30日水曜日です。

//es6
console.log(`現在は${year}年${month}月${day+1}日${yobi[week+1]}曜日です。`); //現在は2019年1月31日木曜日です。
```

- 毎回文字列と変数の間に__`+`__を書かなくて済む
- 文字を書く際に`"~"`をつけなくて良い
- 変数や計算式は${~}のなかにを入れることで表現できる

#オブジェクトリテラル
たくさん書き方があるらしいんですけど、とりあえず２つご紹介
オブジェクトリテラルマスターになりたい人は[こちら](https://qiita.com/kura07/items/356bd37733f457d3177f)から

オブジェクトのkeyとvalueが同じ名前の場合１回書くだけで良い

```javascript
return {
        //es5
        inventory: inventory
        
        //es6
        inventory
 }
```

オブジェクトのvalueがfunctionの場合「: function」を省略可

```javascript
return {
        //es5
        inventoryValue: function(){
            return this.inventory.reduce((sum,dvd) => sum += dvd.price,0);
        },
        priceForTitle: function(title){
            return this.inventory.find(dvd => dvd.title === title).price;
        }

        //es6
        inventoryValue(){
            return this.inventory.reduce((sum,dvd) => sum += dvd.price,0);
        },
        priceForTitle(title){
            return this.inventory.find(dvd => dvd.title === title).price;
        }
}
```
CloudFunctionsからCloudStorageへ画像をアップロードする

```javascript
async function createPhoto(data: string) {
  try {
    const base64EncodedImageString = data.replace(
      /^data:image\/\w+;base64,/,
      '',
    )
    const imageBuffer = Buffer.from(base64EncodedImageString, 'base64')
    const file = admin
      .storage()
      .bucket()
      .file(`${cloudStoragePhotoPath}/test.jpg`)
    await file.save(imageBuffer, { metadata: { contentType: 'image/jpeg' } })
    const url = await file.getSignedUrl({
      action: 'read',
      expires: '01-01-2099',
    })
    return url
  } catch (e) {
    throw e
  }
}
```




# 何をやってるのか
CloudFunctionsなので、どこかにあるファイルから画像は読み込めない。なのでbase64でCloudFunctionsへ画像を送る前提。

## データをBufferにする

```javascript
    const base64EncodedImageString = data.replace(
      /^data:image\/\w+;base64,/,
      '',
    )
    const imageBuffer = Buffer.from(base64EncodedImageString, 'base64')
```
ここでデータをBufferに。エンコーディング時の識別子があれば、replaceでそれを消す。

## ファイルの作成
```javascript
    const file = admin
      .storage()
      .bucket()
      .file(`${cloudStoragePhotoPath}/test.jpg`)
```
ここでCloudStorage上にファイルを作成。この時点ではファイルのデータはここに書き込まれていない。

参考：　https://cloud.google.com/nodejs/docs/reference/storage/2.3.x/File

```javascript
    await file.save(imageBuffer, { metadata: { contentType: 'image/jpeg' } })
```

`save()` でやっとファイルにデータを書き込む。コンテントタイプもここで忘れずに指定。

## URLの取得

```javascript
    const url = await file.getSignedUrl({
      action: 'read',
      expires: '01-01-2099',
    })
```
これで公開用のトークン付きURLを取得できる。トークンさえあれば基本誰でも画像にアクセスできる。`action`をwriteにすれば、このURLにPOSTすることで画像の上書きをもできるとのこと。普通の使い方ではないけど、そういう用途で使ってみるのも面白いのかも。
AtCoderの問題をランダムで表示するブックマークレットを作りました。

AtCoderを日課にしようと意気込む事、誰しもが経験すると思います。
そんなモチベーションを持続させる為にAtCoderの問題をランダムで表示するブックマークレットを作りました。

## AtCoder Beginner Contest(ABC：初級者向け)をランダムで開く
```js:ブックマークレット
javascript:(function() { var arr = [ "a", "b", "c", "d" ] ; var chr = arr[ Math.floor( Math.random() * arr.length ) ] ; var min = 1 ; var max = 102 ; var ran = Math.floor( Math.random() * (max + 1 - min) ) + min ; var num = ('0' + ran).slice(-3); var newurl="https://abc" + num + ".contest.atcoder.jp/tasks/abc" + num + "_" + chr ; window.open(newurl); })();
```

## AtCoder Regular Contest(ARC：中級者/上級者向け)をランダムで開く
```js:ブックマークレット
javascript:(function arcrand() { var arr = [ "a", "b", "c", "d" ] ; var chr = arr[ Math.floor( Math.random() * arr.length ) ] ; var min = 1 ; var max = 100 ; var ran = Math.floor( Math.random() * (max + 1 - min) ) + min ; var num = ('0' + ran).slice(-3); var newurl="https://arc" + num + ".contest.atcoder.jp/tasks/arc" + num + "_" + chr ; window.open(newurl); })();
```

## 作った理由
- 問題選ぶのが面倒くさい！
- パパっと1問だけやりたい！
- 難しい(;_;)

たまに失敗してABCおよびARCのトップページが開きます。
NEO-CLI設定ファイル（PC１台で起動する場合）


プライベート環境にNEOのブロックチェーンを構築する場合最低４ノードを立ち上げる必要があります。実機やVirtualBoxでノードを作成するのはさすがに面倒なので、localhostに4ノードを構築できる設定ファイルを作成しました。

```protocol.json
{
  "ProtocolConfiguration": {
    "Magic": 1704630,
    "AddressVersion": 23,
    "StandbyValidators": [
      "03f32d62f2da4b077e3ff9255c8cd4c3fe51475fc3711480dce960000ffdc2e90e",
	  "0269745d8a00af55ac17c9b54ddb52d497a44dabd6b46e10b81002d68816a1322e",
      "039100c3a54f904f1573abcf449672c69e3f00bd737a5a7a64dcb2eec8a36e4f30",
      "03498475d1a29153e2ee0e7e679f380b457a95585f190b4573f6f659479915e7de"
    ],
    "SeedList": [
      "localhost:10333",
      "localhost:20333",
      "localhost:30333",
      "localhost:40333"
    ],
    "SystemFee": {
      "EnrollmentTransaction": 0,
      "IssueTransaction": 0,
      "PublishTransaction": 0,
      "RegisterTransaction": 0
    }
  }
}
```


```config.json
{
  "ApplicationConfiguration": {
    "Paths": {
      "Chain": "Chain_{0}",
      "ApplicationLogs": "ApplicationLogs_{0}"
    },
    "P2P": {
      "Port": 10333,
      "WsPort": 10334
    },
    "RPC": {
      "Port": 10332,
      "SslCert": "",
      "SslCertPassword": ""
    },
    "UnlockWallet": {
      "Path": "",
      "Password": "",
      "StartConsensus": false,
      "IsActive": false
    }
  }
}

```
WordPress で Kintone の API へアクセスする

WordPress の関数で Kintone の API へアクセスするには以下のような感じ。

```
public function request( $url, $query )
{
    $args = array(
        'method' => 'POST',
        'blocking' => true,
        'headers' => array(
            'X-Cybozu-API-Token' => $this->token,
            'Authorization' => 'Basic ' . $this->auth,
            'Content-Type' => 'application/json',
            'X-HTTP-Method-Override' => 'GET',
        ),
        'body' => json_encode( $query )
    );

    $result =  wp_remote_post( $url, $args );

    if ( ! is_wp_error( $result ) ) {
        return json_decode( wp_remote_retrieve_body( $result ), true );
    } else {
        return $result;
    }
}
```

Kintone の API にアクセスする際に渡すパラメータは、クエリー文字列か以下のようなフォーマットの JSON を利用できますが、JSON のほうが余計なコードを書かなくてすみます。

```
{
    "app": 8,
    "query": "updated_time > \"2012-02-03T09:00:00+0900\" and updated_time < \"2012-02-03T10:00:00+0900\" order by $id asc limit 10 offset 20",
    "fields": ["$id", "created_time", "dropdown"]
}
```

でも、Kintone のレコードをとってくるには、リクエストメソッドが `GET` かつ body で JSON を放り投げるという仕様で、WordPress の `wp_remote_get()` とか `wp_remote_request()` ではそれができないんですよね。

なので、`wp_remote_post()` を使って、リクエストヘッダーで `X-HTTP-Method-Override: GET` を放り投げてあげる感じです。
Python + OpenCVでのHSVヒストグラム情報によるパターンマッチング

HSV情報によるパターンマッチング方法
模様系のパターンのマッチングでは結構使える印象

# 実施結果

イラストの机模様のパターンをもとに机の箇所を特定してみた

**１．認識対象画像用意**
認識対象用の画像を用意
![targetImg.png](https://qiita-image-store.s3.amazonaws.com/0/172093/649787a9-4523-3aa7-328e-a62f1427d94b.png)

**２．机模様パターン画像用意**
上記画像から机の部分画像を切り取り
![imgTmp.png](https://qiita-image-store.s3.amazonaws.com/0/172093/843d5cb4-a6e0-cd08-fd84-fea90e0ee288.png)

**３．机の箇所を特定**
以下のように机の箇所のみがマーキングされる（明るい赤の箇所が最も机の確度が高い箇所）
![markImg.png](https://qiita-image-store.s3.amazonaws.com/0/172093/2afc9f6e-6bdb-9011-d405-54c460a728ba.png)

# ソースコード

上記実施時のソースコードです

```ruby:test.py

import cv2
import os

# 対象画像読み込み
img = cv2.imread("targetImg.png",cv2.IMREAD_COLOR)
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

# 画像情報（幅，高さ，チャンネル数，depth）を取得
height, width, channels = img.shape[:3]

# 机模様のテンプレート画像読み込み
imgTmp = cv2.imread("imgTmp.png",cv2.IMREAD_COLOR)
heightTmp, widthTmp, channelsTmp = imgTmp.shape[:3]
hsvTmp = cv2.cvtColor(imgTmp, cv2.COLOR_BGR2HSV)

# マーキング画像生成
imgMark = img

ch_names = {0: 'Hue', 1: 'Saturation', 2: 'Brightness'}

# 対象領域を順に切り出し確認
for x in range(0,int(width / widthTmp)):
    for y in range(0,int(height / heightTmp)):

      # 対象領域を切り出し
      hsvClp = hsv[int(y * heightTmp):int((y + 1) * heightTmp),int(x * widthTmp):int((x + 1) * widthTmp)]

      # 各チャンネルごとにヒストグラムの類似度を算出する。
      scores, hists1, hists2 = [], [], []
      for ch in ch_names:
          h1 = cv2.calcHist([hsvTmp], [ch], None, histSize=[256], ranges=[0, 256])
          h2 = cv2.calcHist([hsvClp], [ch], None, histSize=[256], ranges=[0, 256])
          # 類似度を算出
          score = cv2.compareHist(h1, h2, cv2.HISTCMP_CORREL)
          hists1.append(h1)
          hists2.append(h2)
          scores.append(score)
      mean = np.mean(scores)

      # 一定閾値の箇所のみマーキング 
      if mean > 0.20 :
        cv2.rectangle(imgMark, (int(x * widthTmp), int(y * heightTmp)), (int((x + 1) * widthTmp), int((y + 1) * heightTmp)), (0, 0, int(mean * 500)), 2)

cv2.imwrite("markImg.png", imgMark)

```




# 参考文献
- [OpenCV - 2枚の画像の類似度を compareHist() で計算する。](http://pynote.hatenablog.com/entry/opencv-comparehist)
JavaScriptでオブジェクトをマージする方法(ES6)

## JavaScriptでオブジェクトをマージする方法(ES6)
ES6では次のように簡単に書くことができます。


```javascript
const obj = { a:1, b:2 }
const objToMerge = { c:3, d:4 } 
const merged = {...obj, ...objToMerge}
console.log(merged) // { a:1, b:2 c:3, d:4 } 
```
## 終わりに
私は現在、Web3のサービスの開発をしています。詳しくはこちらの記事をご覧下さい。
        [無料でイーサリアムが当たる、Web3時代の寄付サイトを作った話](https://note.com/kenroda/n/n814347fbdcd7)
TeamUp Developers LAB #2～メルカリのピープルアナリティクス分野のプロが登壇～ 勉強会メモ


# 概要

[TeamUp Developers LAB #2～メルカリのピープルアナリティクス分野のプロが登壇～](https://teamup.connpass.com/event/117911/)

> テクノロジーの進化に伴い、HRに関する様々な情報が集約される時代になりました。経験や勘など、これまで属人化していた組織や人に関する意思決定はデータ主導に置き換えられています。実際に、GoogleやMicrosoftなどの巨大組織だけでなく、LINEやメルカリなど日本発のグローバルベンチャーも「ピープルアナリティクス」を用いた組織づくりを進めています。
(中略)
そこで、今回はHR分野において様々な新しい取り組みを進めているメルカリからピープルアナリティクスの専門家・友部様をお呼びして、基本的なトピックから、これまでの成功／失敗事例などのリアルなお話までを共有していただきます。

# 発表「強い組織を作るためのPeople Analyticsとは」

## スピーカー

株式会社メルカリ People Growth & Analytics 博士(情報理工学) 友部博教 様

## 内容


- people analytics
    - 人事データを分析することで組織の課題を解決

    - できそうなことに対する多大な期待がかかりがち
        - 例えば、退職予測、ポテンシャルをもつ従業員発掘、チーム編成
        - 分析までと分析自体に困難がある
        - 分析できたとしても、施策に落とし込むのが難しい

- おおまかな全体の流れ
    - データの収集・蓄積
    - 組織内データの集約・統合
    - データの可視化
    - 分析
    - 施策実行

- 特に難しいステップ
    - データの収集
    - 分析&施策で改善するKPIの設計

- 人事分析にかかわるデータ
    - 社内で取得する必要なデータ
        - 人事労務
        - 採用
    - 意識的に入力するデータ
        - パルスサーベイ
        - 各種アンケート
    - 無意識に収集するデータ
        - 入退室記録
        - センサーデータ

- サーベイやアンケート
    - 顕在化している課題の状況把握・定点観測に有効
    - 運用時の工夫
        - 一定数真面目に答えない人がいる
        - 一方、真面目に答える人は、サーベイのたびに負荷がかかる
        - 定期運用のため、迅速なフィードバックを行う姿勢が必要
    - 設問の設計が重要
        - 信頼性・妥当性を設問設計が必要
    - eNPS(employee NPS)のような総合的な設問を必ずおく
        - アンケートにおける総合的な評価指標として扱う
        - 各設問スコアとeNPSスコアの相関から、組織課題の優先度付けに利用

- センサーデータ
    - コストの問題を解決できれば、従業員負担が低く、大量のデータが集まる
    - 一方で、何に使っていいか分からない分析あるある
    - センサーデータは普通のデータよりも扱いが難しく、扱える人材も少ない

- 人事におけるKPI設計
    - 分析時には、KPIを設計して改善の行う
    - KPI設計には、AsIsの把握に基づいたToBeの設定が必要
        - 人事において、ToBeの設定は難しい
        - 理想的な従業員像から、具体的なToBeの落とし込みへ
   
## Q&A

- 扱っているコミュニケーションデータについて
    - ランチミーティング補助
    - slack
    - googleカレンダーのスケジュール

- 人事におけるKPI設計の例
    - コンディションの最適化KPIとして、平均出社時間の分散
    - 小さいほど安定してて良いコンディション

- アンケートデータの匿名化について
    - メルカリでは、人事・経営陣を含む全員が個人を特定できない状態に
    - 所属部署やマネージャは把握できるようにしている
    - 組織の規模が小さいと課題箇所の特定が重要であるが、心理的安全性を高めることも必要なので、総合的な判断に基づく対応が必要
Linuxカーネルにおけるstrn系関数の挙動のまとめ

LKMLでパッチをレビューしていて気になったのと、一部の混乱の原因には私も加担していると思っているので、個人用のメモを兼ねてここらでまとめておきたい。適当にメモしたので間違っていたらあとで修正する。
対象となるカーネルは、linux-5.0(-rcX)である。

# 背景
Linuxカーネルには独自に実装されたstring操作系（特にコピー系の）関数がいくつか存在する。基本的には標準ライブラリから持ってきたもの（カーネルはビルド時に標準ライブラリをリンクできない。標準ライブラリの関数はユーザ空間で実行されることを前提にしている）が多いのだが、OS特有の特権レベルやメモリ空間を意識した拡張関数も存在する。

問題は、これらの実装の中で、実装を見ていくと'\0'つまりNULL終端の扱いが色々と違っているのだ。

## strncpy系

`strncpy()`、`strlcpy()`、`strscpy()`、`strncpy_from_user()`、`strncpy_from_unsafe()`がある。

- `strncpy(dst,src,n)`：srcからdstへ文字列をコピーする。文字列がnより長い場合'\0'はコピーされない。dstを返す。
- `strlcpy(dst,src,n)`：srcからdstへ文字列をコピーする。文字列がn-1より長いと'\0'を最後に追加する。srcにある文字列の'\0'を含まない長さを返す。(コピーした長さではない)
- `strscpy(dst,src,n)`：srcからdstへ文字列をコピーする。文字列がn-1より長いと'\0'を最後に追加して-E2BIGを返す。コピーした文字列の長さを返す。（常に戻り値がn-1より小さい）
- `strncpy_from_user(dst,src,n)`:ユーザ空間にあるsrcからdstへ文字列をコピーする。文字列がnより長い場合'\0'はコピーされない。コピーした文字列の'\0'を含まない長さを返す。ユーザ空間の上限を越える、あるいはページフォルトが起きた場合は-EFAULTを返す。
- `strncpy_from_unsafe(dst,src,n)`:カーネル空間にあるsrc(但しアクセスできるとは限らない)からdstへ文字列をコピーする。文字列がn-1より長いと'\0'を最後に追加する。'\0'を含むコピーした文字列の長さ(最大値n)を返す。アクセスに失敗した場合-EFAULTを返す。

## strlen系
`strlen()`、`strnlen()`、`strnlen_user()`がある。

- `strlen(str)`, `strnlen(str,n)`:　'\0'をカウントしないで文字列の長さを返す。nより長い場合はnを返す。
- `strnlen_user(str,n)`: '\0'を含むユーザ空間にある文字列の長さを返す。nより長い場合はn+1以上の値を返す。nは'\0'を含む値であること。ユーザ空間の上限を越える、あるいはページフォルトが起きた場合は0を返す。

## strdup系

`kstrdup()`、`strndup_user()`、`memdup_user_null()`、`kmemdup_null()`がある。memdup_null系は文字列の長さが分かっている場合にstrdup系の代わりに使われることが望ましい。

- `kstrndup(str,n,gpf)`:メモリを確保し、最大nバイトの文字列をコピーする。文字列がnより長い場合、n文字コピーし、最後に'\0'を追加する。つまり、確保するメモリは最大 n + 1 になる可能性がある。メモリが確保できなければENOMEMを返す。
- `strndup_user(str,n)`:メモリを確保し、最大n-1バイトの文字列をコピーする。文字列がn-1より長い場合は-EINVALを返し、ユーザ空間アクセスに失敗した場合は-EFAULTを返す。メモリが確保できなければENOMEMを返す。
- `kmemdup_null(src,n,gpf)`：メモリを確保し、nバイトのデータをコピーし、n+1バイト目に'\0'を追加する。メモリが確保できなければENOMEMを返す。
- `memdup_user_null(src,n)`:メモリを確保し、nバイトのデータをコピーし、n+1バイト目に'\0'を追加する。ユーザ空間アクセスに失敗した場合は-EFAULTを返し、メモリが確保できなければENOMEMを返す。


## 番外編

- `strstarts(str,prefix)`: strがprefixから始まっていればtrue、そうでなければfalseを返す。
- `str_has_prefix(stre,prefix)`: strがprefixから始まっていればprefixの長さを、そうでなければ0を返す。 

同じ処理だが戻り値が違う。それだけである。ftraceの中の処理で多用されるパターンで、prefixの長さがわかったほうがいいよね、ということで後者が導入されたんだけど・・・。

# まとめ

strn系のカーネル内APIの混乱ぶりが分かっていただけただろうか・・・。strcpy系は0フィルするかどうか書き忘れたけど、多分strcpy以外は0フィルしないだろう。
PythonでTCP通信(クライアント編)

#あらすじ
前回PythonでTCPサーバ(すごく簡易な)を実現するためのコードを書いた
https://qiita.com/keiusukematsuda/items/aacded313fdb6c08f410
今回はその続きとしてTCPクライアントを実現するためのコードを書く

最後にはサーバ<->クライアント間で通信させて遊んでみる

# コードを書く
<pre>
# -*- coding : UTF-8 -*-

# 0.ライブラリのインポートと変数定義
import socket

target_ip = "127.0.0.1"
target_port = 8080
buffer_size = 4096

# 1.ソケットオブジェクトの作成
tcp_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 2.サーバに接続
tcp_client.connect((target_ip,target_port))

# 3.サーバにデータを送信
tcp_client.send(b"Data by TCP Client!!")

# 4.サーバからのレスポンスを受信
response = tcp_client.recv(buffer_size)
print("[*]Received a response : {}".format(response))
</pre>

ガチのマジでシンプル

# コードの解説

####0.ライブラリのインポートと変数定義
サーバ同様にsocketライブライをインポート

####1.ソケットオブジェクトの作成
サーバとまったく同じ

####2.サーバに接続
connect関数でリモートソケット(サーバ側ソケット)と接続する
こちらもサーバのbind関数と同様に引数はタプルを渡すため、()が2重になることを忘れないように

####3.サーバにデータを送信
send関数で接続済みのサーバ側ソケットにバイナリメッセージを送信する

####4.サーバからのレスポンスを受信
サーバからデータの返信があった場合は、recv関数にてデータを受信し標準出力に出力する
今回は4096byteを一回に受け取れるデータ量の最大値にしている


#レッツ動作確認

サーバ　-> クライアントの順番にスクリプトを実行する

実行した結果は以下の通り

####サーバ
<pre>
# python tcp-server.py
[*] Connected!! [ Source : ('127.0.0.1', 37870)]
[*] Received Data : b'Data by TCP Client!!'
</pre>

####クライアント
<pre>
# python tcp-client.py
[*]Received a response : b'ACK!!'
</pre>


できたー
LinuxのデスクトップにVMWareの共有フォルダのショートカットを作成する

何をいまさら…という感じですが、備忘録のため記載。

VMWareにUbuntu18.04をインストールしていて、VMWareの共有フォルダを有効にし、windows上に共有フォルダを設定。

その後、下記コマンドでhgfsの配下をマウント。

<pre>
sudo vmhgfs-fuse -o allow_other -o auto_unmount .host:/ /mnt/hgfs
</pre>

毎回上記コマンドを打つのは邪魔くさいので、/etc/fstabに以下のコマンドを記述する。
<pre>
.host:/ /mnt/hgfs fuse.vmhgfs-fuse allow_other,auto_unmount,defaults 0 0
</pre>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223945/e928c1f6-0bba-1a16-2e49-c0f0b405a9d3.png)

その後、いちいち

<pre>
cd /mnt/hgfs/01_共通フォルダ
</pre>

と入力してアクセスするのは非常に邪魔くさいので、デスクトップにショートカットを作成する。

下記コマンドにて、デスクトップにショートカットを作成できる。

<pre>
ln -sf /mnt/hgfs/01_共通ファイル/ /home/XXXX/デスクトップ/
</pre>
※　XXXXは、各自のPCのユーザ名か何か...。


![20190219_ショートカットの作成方法.PNG](https://qiita-image-store.s3.amazonaws.com/0/223945/417d3da7-dffa-cbd1-5232-e34075cb0179.png)
WordPressの管理画面でログインユーザー以外のコンテンツを非表示にする

WordPressの管理画面でログインユーザー以外のコンテンツを非表示にするには以下のような感じ。

```
/**
 * 管理画面でログインユーザー以外のユーザーのコンテンツを非表示にする。
 */
add_action('pre_get_posts', function( $wp_query ) {
	global $current_user;
	if( is_admin() && ! current_user_can('edit_others_posts') ) {
		$wp_query->set( 'author', $current_user->ID );
	}
} );
```

以上でメディアも含めて、ログインユーザー以外のコンテンツが非表示になります。

でも、以下のような「投稿の件数」は、ログインユーザー以外の記事の件数もカウントされてしまって、ちょっと違和感があります。

![](https://www.evernote.com/l/ABWsGfrNP_1DEJE9e_zFs0XvGF5OapY5tsEB/image.png)

この数字をログインユーザーの記事の件数にするには `wp_count_posts` というフックを使用します。

```
/**
 * 管理画面のテーブルでログインユーザーの投稿数のみをカウントする。
 *
 * @param $counts
 * @param $type
 *
 * @return array|object
 */
add_filter( 'wp_count_posts', function ( $counts, $type ) {
	if ( is_admin() && ! current_user_can('edit_others_posts') ) {
		global $wpdb;

		$query = "SELECT post_status, COUNT( * ) AS num_posts FROM {$wpdb->posts}
				WHERE post_type = %s AND post_author = %d GROUP BY post_status";
		$query = $wpdb->prepare( $query, $type, get_current_user_id() );
		$results = (array) $wpdb->get_results( $query, ARRAY_A );
		$counts = array_fill_keys( get_post_stati(), 0 );

		foreach ( $results as $row ) {
			$counts[ $row['post_status'] ] = $row['num_posts'];
		}

		return (object) $counts;
	}

	return $counts;
}, 10, 3 );
```

カスタム投稿タイプだと `edit_others_posts` の部分は `edit_others_xxxs` みたいなことになることもあるので、適時修正してください。
小学校用の教材モーターカーをハックした

obnizを使って子供用の小学校教材のモーターカーをパックして、ラジコン化してみました。

#はじめに
obnizとは、Javascriptと、HTMLで組んだプログラムが、クラウド経由で簡単に実装できるマイコンで、接続した機器やセンサーを操作できるIoT端末です。

#教材
子供用の小学校教材であるモーターカーは電池駆動で、スイッチをオンにすることにより前進します。
それを、obnizでサーボモーターとモーターを操作することによりラジコン化させます。

#使用機器
・obniz
・サーボモーターSG-90
※秋月電子で購入するも3個中2個不良…
・ミニ四駆などの普通のモーター

#仕様
obnizのクラウドで、サーボモーターやモーター用のSDKがあるため、これを使用します。
0,1,2ピンをサーボモーターとし、3,4ピンをモーターとします。
画面はHTMLで記載し、全身後退、左右を操作できるようにします。

#画像
前輪と後輪の間に強引にサーボモーターを組み込み、モーターは電池駆動を止めobniz直接駆動とします。
サーボは後輪部分に接続し、前輪とは棒で接続して左右に動かせるようになっています(つまようじ・・・)
前輪には滑り止めのガムテープを貼っています。
![P_20190202_152207_vHDR_Auto.jpg](https://qiita-image-store.s3.amazonaws.com/0/263670/81c939f0-3f15-7b1d-a40d-9d4d34f80191.jpeg)

#ソース
```html
<!-- HTML Example -->
<html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script src="https://obniz.io/js/jquery-3.2.1.min.js"></script>
  <script src="https://unpkg.com/obniz@1.16.1/obniz.js"></script>
</head>
<body>

<div id="obniz-debug"></div>
<h1>ラジコン</h1>
<button id="susumu">進む</button><br>
<button id="modoru">戻る</button><br>
<button id="stop">止める</button><br>
左右<input id="slider1" type="range"  min="0" max="180" /><br>
パワー<input id="power" type="range"  min="0" max="200" value="100" /><input id="powertxt" type ="text"><br>

<script>
  var power = 100;
var obniz = new Obniz("OBNIZ_ID_HERE");
obniz.onconnect = async function () {
 var motor = obniz.wired("DCMotor",{"forward":3, "back":4});
  var servo1 = obniz.wired("ServoMotor", {gnd:0, vcc:1, signal:2});
  $("#slider1").on('input', function() {
    servo1.angle($("#slider1").val());
  });
  $("#power").on('input', function() {
    power = Number($("#power").val());
    if(power > 100){
    motor.power(power-100);
    motor.move(true);
    }else{
    motor.power(100-power);
    motor.move(false);
    }
  });
  $("#susumu").on("click",function(){
    motor.power(power);
    motor.move(true);
  });
  $("#modoru").on("click",function(){
    motor.power(power);
    motor.move(false);
  });
  $("#stop").on("click",function(){
    motor.stop();
  });
};

obniz.onclose = async function(){
   $("#slider1").off('input');
   $("#power").off('input');
};
</script>
</body>
</html>
```

#完成
これをスマホで操作することで完成です。
サーボモーターを操作することで左右に曲がる際にサーボモーターの音がキーキー泣いて、虫のよう、と子供に評判（？）でした。
PythonでTCP通信(サーバ編)

# はじめに
今更だがPythonの勉強なう
一人でコードを書いていてもむなしいため共有することにする

今回はPythonのsocketライブラリを使用してTCPサーバをつくる
別にTCPクライアントもつくるので、サーバ <-> クライアント間で通信させて遊んでみる

クライアント編は以下に
https://qiita.com/keiusukematsuda/items/362450fda4beca76c030

# 環境
 - CentOS7
 - Python3.6

# コードを書く
クライアントからデータを受信して、それを標準出力に表示させる
またデータを受信したらクライアントに返信する

<pre>
# -*- coding : UTF-8 -*-

# 0.ライブラリのインポートと変数定義
import socket

server_ip = "127.0.0.1"
server_port = 8080
listen_num = 5
buffer_size = 1024

# 1.ソケットオブジェクトの作成
tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 2.作成したソケットオブジェクトにIPアドレスとポートを紐づける
tcp_server.bind((server_ip, server_port))

# 3.作成したオブジェクトを接続可能状態にする
tcp_server.listen(listen_num)

# 4.ループして接続を待ち続ける
while True:
    # 5.クライアントと接続する
    client,address = tcp_server.accept()
    print("[*] Connected!! [ Source : {}]".format(address))

    # 6.データを受信する
    data = client.recv(buffer_size)
    print("[*] Received Data : {}".format(data))

    # 7.クライアントへデータを返す
    client.send(b"ACK!!")

    # 8.接続を終了させる
    client.close()
</pre>

たったのこれだけ
とても簡単でございます

# コードの解説

####0.ライブラリのインポートと変数定義
socketライブラリを使用するのでインポートする
通信を待ち受けるアドレスとポートは変数化しておく、今回は同一ホスト内でクライアント <-> サーバ通信をさせるためにループバックアドレスを使用する

####1.ソケットオブジェクトの作成
socket関数を使用してソケットオブジェクトを作成する
第一引数にsocket.AF_INETを渡すことで作成するソケットオブジェクトはIPv4に対応する
また第二引数にsocket.STREAMを渡すことでTCPに対応する
つまり今回作成するソケットはIPv4でTCP通信を行うソケットになる
UDPに対応したソケットオブジェクトを作成したい場合は第二引数にsocket.DGRAMを渡せばよい

####2.作成したソケットオブジェクトにIPアドレスとポートを紐づける
bind関数でオブジェクトにアドレスとポートを紐づける
引数にはタプルを渡すため()が二重になることに注意する

####3.作成したオブジェクトを接続可能状態にする
listen関数を使用してソケットオブジェクトに接続できる状態にする
この時引数には整数を渡す、これはソケットオブジェクトに接続できるコネクション数の最大値となる

####4.ループして接続を待ち続ける
特に言うことなし(^^)

####5.クライアントと接続する
accept関数によりクライアントからデータの送受信を行うための新しいソケットオブジェクトとデータの送信元であるクライアントのアドレスを受け取る
送信元アドレスを標準出力に出力させる

####6.データを受信する
新しく作成したソケットオブジェクトのrecv関数でクライアントからデータを受信する
引数に一度に受信できるデータサイズの最大値を渡す
今回は1024byteを最大値とする

####7.クライアントへデータを返す
クライアントにデータを送信する
引数は送信するデータをbyte型として渡す

# 動作確認
クライアント編でやるので見てくださいませ！

とりあえず今回はここまで！おつかれちゃん！
[Flutter] 自然な画面移動してみよう。

こんにちは! Flutter楽しんでますか？

アンドロイドアプリ作ってみるとActivity移動が必要場合あります。
その時、intentを使うんですね？startActivityとかさ。

FlutterでActivity移動ももちろん、
で
き
ます。

例えば、こんな感じです。

```dart

1. Navigator.pop(context);
2. Navigator.of(context).pop();
3. Navigator.of(context).push();
4. Navigator.of(context).push(builder:()...);
```

はい。stackです。

アンドロイドNative開発もactivityはStack Memoryにどんどん溜まっていきます。あなたはActivity間移動する際にアニメーション付けたくなりませんか？ FlutterではPageRouteBuilderを相続して、作りたい移動クラスをコーティングすると簡単にできます。

こんな感じです。

```dart

import 'package:flutter/material.dart';

class ScaleRoute extends PageRouteBuilder {
  final Widget widget;

  ScaleRoute({this.widget})
      : super(pageBuilder: (BuildContext context, Animation<double> animation,
            Animation<double> secondaryAnimation) {
          return widget;
        }, transitionsBuilder: (BuildContext context,
            Animation<double> animation,
            Animation<double> secondaryAnimation,
            Widget child) {
          return ScaleTransition(
            scale: Tween<double>(
              begin: 0.0,
              end: 1.0,
            ).animate(
              CurvedAnimation(
                  parent: animation,
                  curve: Interval(0.00, 0.5, curve: Curves.elasticIn)),
            ),
            child: ScaleTransition(
                scale: Tween<double>(
              begin: 0.5,
              end: 1.0,
            ).animate(CurvedAnimation(
                    parent: animation,
                    curve: Interval(0.5, 1.0, curve: Curves.decelerate,
                    )
                ),
                ),
              child: child,
            ),

          );
        });
}
```

簡単？ですかね

1．pageBuilder　：（）｛｝
2．transitionsBuilder（）｛｝

に、あなたが試してみたいアニメーションを使うとオッケーです。
他言語からMatlabに来た人がハマりそうなlength()の話

## 物の見事にハマった

lengthで文字列の長さを取ろうとしたら思ったようにとれず、コマンドウインドウでこんなコマンドを叩いてみた。

```matlab:コマンドウインドウ
> hoge = "somestring";
> length(hoge)

  ans =
        1

```

*違う、そうじゃない。*

## stringで文字数が欲しい場合はstrlengthで。

lengthではなくstrlengthを使うと文字数が取れます。

```matlab:コマンドウインドウ
> hoge = "somestring";
> strlength(hoge)

  ans =
        10

```

**やったぜ**

## そもそもstringは最近実装された型

Matlabのドキュメンテーションで確認すると、stringが実装されたのは「R2016b」(=2016年後期)。
めちゃんこ最近です。
文字配列を数値配列に変換するやり方として「str2num」や「str2double」がありますが、「strだからstringだろ」とstringを突っ込むと前者はエラー、後者は空の行列になります。

Matlabで文字列を扱うときは**charを使いましょう**。
[PHP] 連想配列をオブジェクトに変換したい（ネストに対応）

## はじめに
連想配列をオブジェクト型として扱いたいことってありませんか？
`(object)` でキャストするという方法もありますが、ネストしていた場合は完全にオブジェクトとはなりません。

```php
$array = [
    'id'   => 1,
    'name' => 'sample',
    'list' => [
        'id'   => 10,
        'name' => 'test',
    ],
];
$obj = (object) $array;
echo $obj->list->name;
// PHP Notice:  Trying to get property 'name' of non-object in php shell code on line 1
// Notice: Trying to get property 'name' of non-object in php shell code on line 1
var_dump($obj);
/*
object(stdClass)#3 (3) {
  ["id"]=>
  int(1)
  ["name"]=>
  string(6) "sample"
  ["list"]=>
  array(2) {
    ["id"]=>
    int(10)
    ["name"]=>
    string(4) "test"
  }
*/
```

## 結論

一旦JSON形式にしてもう一度デコードするといけるようです。
でもこのやり方は本来の用途とは違う気がするので、もしやる場合は再帰的にObjectにしたほうが良さそう。
またリソースの観点からもあまりおすすめはできないようです。

### json_encodeしてjson_decodeする（非推奨）

```php
$array = [
    'id'   => 1,
    'name' => 'sample',
    'list' => [
        'id'   => 10,
        'name' => 'test',
    ],
];
$obj = json_decode(json_encode($array));
echo $obj->list->name;
// test
var_dump($obj);
/*
object(stdClass)#1 (3) {
  ["id"]=>
  int(1)
  ["name"]=>
  string(6) "sample"
  ["list"]=>
  object(stdClass)#2 (2) {
    ["id"]=>
    int(10)
    ["name"]=>
    string(4) "test"
  }
}
*/
```

### 再帰的に置換する

```php
// ref: https://stackoverflow.com/questions/4790453/php-recursive-array-to-object
function array_to_object($array) {
  $obj = new stdClass;
  foreach($array as $k => $v) {
     if(strlen($k)) {
        if(is_array($v)) {
           $obj->{$k} = array_to_object($v); //RECURSION
        } else {
           $obj->{$k} = $v;
        }
     }
  }
  return $obj;
} 
```

## 参考

- https://pyama.fun/archives/2582
- https://thewebtier.com/php/convert-array-object-php/
- https://stackoverflow.com/questions/4790453/php-recursive-array-to-object
Django カスタムユーザモデルの参考記事

Django カスタムユーザモデルの参考記事を紹介します。
一つ目が非常に分かりやすく書いてある

1
https://hombre-nuevo.com/python/python0048/

**2 DjangoのUserモデルを拡張する方法**
主にOne to One Field についての記載が参考になった
https://hodalog.com/how-to-extend-django-user-model/

3
https://qiita.com/okoppe8/items/10ae61808dc3056f9c8e

**4 Userモデルと他のモデルを一対一対応させる方法**
https://narito.ninja/blog/detail/47/


また、デフォルトのDjangoのUserモデルのフィールドは
以下の通り
![userのfiled.png](https://qiita-image-store.s3.amazonaws.com/0/342318/e524ab20-7939-8885-55a0-920c7fbff1c8.png)
javascriptの＝＝と＝＝＝の違い

#導入
皆さんは下の2つのコードの結果違いが分かりますか？
下のようなコードを見たとき`===`は厳格に比較するという認識があると思います。
では、厳格に比較するとはどうゆうことでしょうか？
初心者以外の人はわかっていると思いますが、お付き合いください。
#問１　
```javascript:hoge.js
var f1 = 1;
var f2 = "1";

console.log(f1 == f2); //➀
console.log(f1 === f2); //➁

//この2つのconsole.logの結果はどうなるでしょう？
```

➀の結果は`true`
➁の結果は`false`となります。
➁はなぜ`false`となるのでしょうか？
これは型の比較までしているからです。
f1は整数型（正確にはjsではすべての数値は浮動小数点なのですが）で、f2は文字列ということで型まで比較したとき➁は型が異なるので`false`になるのです。

では次の場合はどうでしょうか？

#問2　nullとundefinedの場合
```javascript:hoge.js
var f3 = null;
var f4; //undefinedが入ってる

console.log(f3 == f4); //➀
console.log(f3 === f4); //➁

//この2つのconsole.logの結果はどうなるでしょう？
```
これも➀の結果は`true`
➁の結果は`false`となります。
➁はなぜ`false`となるのでしょうか？
これも型が違うというのが理由です。
jsではプリミティブ（基本的な型。これ以上細かくできないもの）でnull,undefinedがそれぞれ定義されています。
つまり`null`と`undefined`は型が違うので`false`となるのです。

#問3　オブジェクトの比較の場合

```javascript:hoge.js
var obj1 = { f1 : 1 };
var obj2 = { f1 : 1 };
var obj3 = obj1;

console.log(obj1 === obj2 ); //➀
console.log(obj1 === obj3 ); //➁

//この2つのconsole.logの結果はどうなるでしょう？
```
➀の結果は`false`
➁の結果は`true`となります。
①はなんで内容は一緒なのに`false`になるんでしょうか？
オブジェクトの比較の場合は参照している場所が等しいかどうかで判断しているためです。

#まとめ
どうだったでしょうか？
自分は厳格に比較するという知識だけでどう厳格に比較しているか最近まで分かってませんでした。
とりあえず`===`を使っとけばいいやという感じで(-_-;)
オブジェクトについても調べて初めて知ったことだったのでここで知っておかなければ、いつか挙動がなぜこうなるか深みにはまって苦労することがあったかもしれません。
それでは次の投稿はやったけどまだ書いていない[PHP修行の道＃02　～学習環境を整えるの巻～](https://qiita.com/harachan/items/7815a39be93804a5ae24)の続きであるPHP修行の道＃03　～PHP基本的なことと型の巻～を投稿したいと思っています。
よかったら過去のものも読んでもらえると嬉しいです。
ERC20トークンのサンプル

ERC20トークンのサンプルです。

```erc20.sol
pragma solidity ^0.4.25;
contract ERC20 {
  //トークンの名前
  string public name;
  //トークンのシンボル
  string public  symbol;
  //トークンの総発行量
  uint256 public totalSupply;
  //トークンの桁数
  uint8 public decimals = 18;
  //各アドレスの残高
  mapping (address => uint256) public  balances;
  mapping (address => mapping (address => uint))public  allowed;
  event Transfer(address indexed _from, address indexed _to, uint256 _value);
  event Approval(address indexed _owner, address indexed _spender, uint256 _value);
  //コンストラクタ
  constructor(uint256 initialSupply, string tokenName, string tokenSymbol) public {
      totalSupply = initialSupply * 10 ** uint256(decimals);
      balances[msg.sender] = totalSupply;
      name = tokenName;
      symbol = tokenSymbol;
  }
  //トークンの名前を返す
  function name() public view returns(string) {
      return name;
  }
  //トークンのシンボルを返す
  function symbol() public view returns(string) {
      return symbol;
  }
  //トークンの桁数を返す
  function decimals() public view returns(uint8) {
      return decimals;
  }
  //トークンの総発行量を返す
  function totalSupply() public view returns (uint256) {
      return totalSupply;
  }
  //アドレスの残高を返す
  function balanceOf(address _userAddress) public constant returns(uint256 balance){
      return balances[_userAddress];
  }
  //トークンの送金
  function transfer(address _to, uint256 _amount) public returns (bool success) {
      if (balances[msg.sender] >= _amount
      && _amount > 0
      && balances[_to] + _amount > balances[_to]) {
          balances[msg.sender] -= _amount;
          balances[_to] += _amount;
          //イベント
          emit Transfer(msg.sender, _to, _amount);
          return true;
      } else {
          return false;
      }
  }
  //権利が与えられたトークンを送金する
  function transferFrom(address _from,address _to,uint256 _amount) public returns (bool success) {
      if (balances[_from] >= _amount
      && allowed[_from][msg.sender] >= _amount
      && _amount > 0
      && balances[_to] + _amount > balances[_to]) {
          balances[_from] -= _amount;
          allowed[_from][msg.sender] -= _amount;
          balances[_to] += _amount;
          //イベント
          emit Transfer(_from, _to, _amount);
          return true;
      } else {
          return false;
      }
  }
  //_spenderに指定量のトークン使用権を与える
  function approve(address _spender, uint256 _amount) public returns (bool success) {
      allowed[msg.sender][_spender] = _amount;
      emit Approval(msg.sender, _spender, _amount);
      return true;
  }
  //_spenderが引き続き_ownerから引き出せる量を返す
  function allowance(address _owner, address _spender) public constant returns (uint256 remaining) {
      return allowed[_owner][_spender];
  }
}
```
mysql 起動時のThe server quit without updating PID file エラーの回避法

mysqlが起動できない問題に遭遇。
こんな感じでエラーが出てくる。

```
$ mysql.server start
Starting MySQL
.. ERROR! The server quit without updating PID file (/usr/local/var/mysql/****.pid).
```

調べてみるとこの事象の解決法に関しては色々なパターンがあるが、
総じて以下の2つっぽい。

1. そもそもpidファイルが存在していない。
2. pidファイルに適切な権限が設定されていない

私は上記2つの合わせ技だった。
(おそらく1.に当てはまる場合は自動的に2.にも引っかかる)
発生環境＆解決策を以下記載。

# 事象の発生環境
```
$ sw_vers
ProductName:	Mac OS X
ProductVersion:	10.13.4
$ mysql --version
mysql  Ver 14.14 Distrib 5.7.21, for osx10.13 (x86_64) using  EditLine wrapper
```
(*)mysqlはbrew経由でinstall(brew install mysql)


# 解決策
## "1. そもそもpidファイルが存在していない"への対応
`/usr/local/var/mysql`にpidファイルが無い場合は、
まずpidファイルの作成が必要。

空ファイルで良いので、とりあえず適切な名前のpidファイルを作ってやればOK.

```
$ touch /usr/local/var/mysql/*****.local.pid
```
*****には マシンのホスト名 を入力。
ホスト名は`uname -n`で確認できる。

**参考**
https://qiita.com/nishina555/items/4d0149a1b20079d4b8b4
https://qiita.com/yuki0208/items/1d5554d98e9ec76084bd

## "2. pidファイルに適切な権限が設定されていない"への対応
pidファイルはあっても、mysqlに権限が無いとエラーになる様子。
以下のコマンドで、
/user/local/var/mysql以下のファイルの所有者をすべて_mysqlにすることで解決。

```
sudo chown -R _mysql:_mysql /usr/local/var/mysql/
```
**参考**
https://qiita.com/mogetarou/items/e34ca51d3756d55d7800
## それでもダメな場合
mysqlの再インストールでなんとかなる、らしい。

**参考**
https://qiita.com/_natsu_no_yuki_/items/ae4c94187093e4ab3cdc
Rails view の作り方 (チュートリアル3章まとめ)

Railsチュートリアルの三章やったのでまとめてみる。(cssは今回は触れない)

# Railsのview-controllerについて

RailsはMVCアーキテクチャだが、JSP-Servlet(古い…)みたいにviewに値を埋め込んで返すのではなく、コントローラがviewをレンダリングして返却する。ざっくりした図だが、下の様なイメージ。

<img src="https://qiita-image-store.s3.amazonaws.com/0/167729/4ce07d39-11c6-b27a-e792-29270a1bfa58.png" width="75%">

# erb

Railsのviewでは、htmlにrubyコードを埋め込む'erb'ファイルがよく使われる。
正直erbより[haml](http://haml.info/)とかの方が便利そうだけど、(hamlはタグ無しで書ける)
勉強のために、書き方がhtmlに近いerbの方を使っていく。

erbにrubyコードを埋め込むには、`<% %>`を使用する。
rubyコードの実行結果をタグの中に埋め込みたい場合は`=`をつけて`<%= %>`とする。

例えば、タグ内で`:title`をyieldしたい時は下の様に書く

```
<title><%= yield(:title) %></title>
```

# layout

Webシステムを作成する時、ページのタイトルやレイアウト等、全ページに共通する要素がいくつもある。
これを一つ一つのerbファイルに書いていくと、共通部分という時も全て編集しないといけなくなる。

例えば、10ページほどで構成されているWebページのレイアウトが変わってしまったという場合は
10ページ全てで手作業で編集する羽目になるし、バグの原因にもなりかねない
こうした共通部分をlayoutに括り出すことによって、全ページの修正を一回で済ませることができる。

# provide, yield

layoutの共通部分に変数を埋め込みたい場合は、erbでprovideヘルパーを使う。
erbでprovideした変数をlayout側でyieldすると、その変数を評価してerbに埋め込まれる。
yieldに引数を与えない場合は、viewをそのまま評価する

- layout

```
<!DOCTYPE html>
<html>
  <head>
    <title><%= yield(:title) %></title>
  </head>
  <body>
    <%= yield %>
  </body>
</html>
```

- view

```
<% provide(:title, "ブログ")%>
<h1>ホーム</h1>
<p>
　 修得した技術や所感をまとめていきたいと思っています。
  <a href="https://qiita.com/flowerhill">Qiitaもやってます</a>
</p>
```

上の様にlayoutとviewを作成すると、ブラウザからアクセスした時次の様なhtmlを生成する

```
<!DOCTYPE html>
<html>
  <head>
    <title>ブログ</title>
  </head>
  <body>
    <h1>ホーム</h1>
    <p>
      修得した技術や所感をまとめていきたいと思っています。
      <a href="https://qiita.com/flowerhill">Qiitaもやってます</a>
    </p>
  </body>
</html>
```

画面で表示するとこうなる。
<img width="663" alt="スクリーンショット 2019-02-19 22.33.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/167729/0d3b6872-b987-f69f-3362-32e5e9796b10.png">

# まとめ
RailsからControllerを呼び出した時に、どの様にViewを呼び出すか大体理解できたと思う。
erbの書き方やlayoutの使い方まで修得できた。

本当はヘルパーメソッドやテスト(rspec)の書き方もまとめたかったけど、長くなるので一旦ここまで。(正直疲れた…)

# 参考

- [Railsチュートリアル三章](https://railstutorial.jp/chapters/static_pages?version=5.1#cha-static_pages)
vagrantとホストOSで共有フォルダを作成する

#共有フォルダの作成
vagrantで作成した仮想環境（Linux)で、ホストOSとの共有フォルダがあると便利です。
例；ゲストOSで作ったファイルをエディタ（Atom等）で編集したい。
共有フォルダに格納しておけば、ホストOS側（Mac等）で、選択することが可能です。
#環境
MacOS Mojave
ubuntu16.04
#作成
`Vagrantfile`に下記コードを記入。
今回は、ホストOS側のフォルダ（`Vagrantfile`があるフォルダ）に`space`というフォルダを作成し、ubuntu側ではホームディレクトリ直下にも`space`というフォルダを作成。

```python:Vagrantfile
# 左がホストOS、右がubuntu(ゲストOS）の場所
# pwdでゲストOS側のホームディレクトリを確認。"/home/ubuntu/space"が正しい場合もある。
config.vm.synced_folder "./space", "/home/vagrant/space"
```
あとは、コマンド`vagrant up`から、`vagrant ssh`で仮想環境内に入り、`space`フォルダ内でファイル等を作成すると、自動的にホストOS側にも共有されている（ホストOS側からの作成も同様）。
micro:bitでデータ取得してExcelにて取得

#加速度を1秒間隔で表示

- シリアル通信でWin上のエクセルにデータ取得ができるという記事があったので、試してみました。無事に動作しました。以下が得られたエクセルのデータとグラフ![取得画面.PNG](https://qiita-image-store.s3.amazonaws.com/0/237044/eaa584a4-cde5-3169-3678-a0384b12fad1.png)
- [作成したコード](https://makecode.microbit.org/_aVLXc2dbp5b3)
- エクセルについては、情報元サイトの[「ms6_80704.xlsm」のファイル](http://www.micro-bit.info/%E3%80%8Cexcelbit%E3%80%8Dmicrobit-x-excel%E3%82%B7%E3%83%AA%E3%82%A2%E3%83%AB%E9%80%9A%E4%BF%A1%E3%82%BD%E3%83%95%E3%83%88)を使わてもらいました。設定シートのページを改訂することで、計測している表の列名を更新することもできました。β版のようで３つしか、データを取得できませんが、簡単なサンプルを作成するには重宝しそうです。
- 以前公開した[ソロバン表示](https://qiita.com/tmdoi/items/208aa2526273e305ee4a)を無理やり使っています（笑）。時間のあるときに、マイナスも表示できるようにしないといけないな、と思いました。


#考察・メモ。

- 長時間稼働させると、接続がきれてエラーになるようです。
- Windows10, Excel2016でも動作確認済み。mbedドライバのインストールは必要。
- サンプリングは1000msが安定の限界。
- 最速500msは動作したが、マクロの処理が重くなるところ（31個目以降の処理？）でエラーになった。
- 以前作ったブロックは、Javascriptエディターからコピーすれば、無理やりですが、持ってこれることがわかりました。今度からは、最初に開いて持ってこよう（汗）
- 私のWin7 と Excel2010の環境でも動作しました。
- たまに1micro:bitからの通信がないとエラーがでて、プログラムがとまりました。
- β版ということで、３つのデータ取得までが、可能なようです。

# 情報元サイト
-  [「excel:bit」micro:bit x Excelシリアル通信ソフト](http://www.micro-bit.info/%e3%80%8cexcelbit%e3%80%8dmicrobit-x-excel%e3%82%b7%e3%83%aa%e3%82%a2%e3%83%ab%e9%80%9a%e4%bf%a1%e3%82%bd%e3%83%95%e3%83%88)

#関連サイト

- [Mbed Serial Driverのインストールについて](https://os.mbed.com/handbook/Windows-serial-configuration)
- [シリアル通信のためのインストール方法（Win編）](https://sanuki-tech.net/micro-bit/appendix/windows-serial-configuration/)
- [シリアル通信出力20180626](https://makecode.microbit.org/v0/53136-09822-51683-50539)
Nuxtで開発をしていて、コンポーネント名やURLがわからなかったときの確認方法

Nuxtで開発をしていて、pages以下にvueファイルを作ると動的にURLが作成されます。<br>
コンポーネント名に関しても、指定をしていなければ動的に作成されます。

Nuxtルーティングについて
https://ja.nuxtjs.org/guide/routing/

ただ、実際に生成されたURLやコンポーネント名がわからないときがあります。
./.nuxt/以下にURLとコンポーネント名が記載されているJSファイルがあるので、
そのファイルから確認ができます。
(Vue Router設定ファイル)

```./.nuxt/router.js
export function createRouter() {
  return new Router({
    mode: 'history',
    base: '/',
    linkActiveClass: 'nuxt-link-active',
    linkExactActiveClass: 'nuxt-link-exact-active',
    scrollBehavior,

    routes: [{
      path: "/inspire",
      component: _7648baee,
      name: "inspire"
    }, {
      path: "/",
      component: _631623e6,
      name: "index"
    }],

    fallback: false
  })
}
```
Python+xlrd+msoffcrypto-tool でパスワードの掛かったエクセルファイルを読込む

## この記事について

この記事では [`xlrd`](https://xlrd.readthedocs.io/en/latest/api.html) という、 Python からエクセルファイルを読み込むライブラリを使って、パスワードの掛かったエクセルファイルを読み込む方法について紹介します。なお、パスワード自体は __既知__ であるという前提です。

`xlrd` 単体では、パスワードの掛かったエクセルを開くことができないため、この記事では [`msoffcrypto-tool`](https://github.com/nolze/msoffcrypto-tool) という、別の Python ライブラリを使ってパスワードを解除し、通常のワークブックの状態に戻してから `xlrd` で読込むという手順を踏みます。

## 環境

自分の環境は以下の通りでしたが、ヴァージョンが違っても概ね動くと思います。

- Python 3.6.8
- xlrd 1.2.0
- msoffcrypto-tools 4.6.4
- macOS Mojave 10.14.3

## スニペット

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

import tempfile

import xlrd
import msoffcrypto


def open_workbook(workbook_file_path, password=None):
    if password is None:
        wb = xlrd.open_workbook(workbook_file_path)
    else:
        with open(workbook_file_path, 'wb') as fin,\
                tempfile.TemporaryFile() as tfp:
            encrypted = msoffcrypto.OfficeFile(fin)
            encrypted.load_key(password=password)
            encrypted.decrypt(tfp)
            tfp.seek(0)
            wb = xlrd.open_workbook(file_content=tfp.read())
    return wb
```

`open_workbook` 関数に `password` 引数を渡すと、 `msoffcrypto-tool` でパスワードを使った復号化を行い、内容をテンポラリファイルに書き込みます。そして `xlrd` に復号化したテンポラリファイルを渡しています。 `xlrd.open_workbook` 関数は通常ファイルパスの文字列を渡しますが、 `file_content` キーワード引数を渡すとバイト列をそのまま読み込んでくれるようです。

## 参考文献

- [nolze/msoffcrypto-tool: A Python tool and library for decrypting MS Office files with passwords or other keys, https://github.com/nolze/msoffcrypto-tool](https://github.com/nolze/msoffcrypto-tool)
- [API Reference — xlrd 1.1.0 documentation, https://xlrd.readthedocs.io/en/latest/api.html](https://xlrd.readthedocs.io/en/latest/api.html)
- [python-excel/xlrd: Library for developers to extract data from Microsoft Excel (tm) spreadsheet files, https://github.com/python-excel/xlrd](https://github.com/python-excel/xlrd)
travisをローカルで動かす

# 概要
travisの設定を変更して、毎回pushして確認するのではなく、ローカルで確認する手順をメモ

# 環境
mac上のdockerで動かすことができないようなので、vagrantで起動したcentos上のdockerで試す。

```
❯  cat /etc/redhat-release
CentOS Linux release 7.6.1810 (Core)
```

# 準備
docker起動。今回はpythonのimageを使用。

```
❯ sudo docker run -it -u travis quay.io/travisci/travis-python /bin/bash
travis@6492bd86030a:/$
```

ruby 2.3.0をインストール

```
$ ruby -v
ruby 1.9.3p551 (2014-11-13 revision 48407) [x86_64-linux]
$ rvm install 2.3.0
...
$ rvm use 2.3.0
Using /home/travis/.rvm/gems/ruby-2.3.0
$ ruby -v
ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-linux]
```
travis-buildの準備

```
$ cd ~/builds
$ git clone https://github.com/travis-ci/travis-build.git
$ cd travis-build/
$ gem install travis
$ travis
$ ln -s `pwd` ~/.travis/travis-build
$ gem install bundler
$ bundle install
```

gem installでsslのエラーが出る場合はhttpを使用するように設定

```
gem source -r https://rubygems.org/
gem source -a http://rubygems.org/
```
```ruby:Gemfile
source 'http://rubygems.org'
```

ssh key作成し、githubに登録

```
$ ssh-keygen -t rsa -b 4096 -C your@email.com
$ cat ~/.ssh/id_rsa.pub
```

ビルド対象のレポジトリをclone

```
$ mkdir ~/builds/bassaer
$ cd ~/builds/bassaer
$ git clone git@github.com:bassaer/travis-local.git
$ cd travis-local
```

travisのスクリプトをコンパイルして生成

```
$ travis compile > ci.sh
```

travis関連のファイルがないと怒られる場合は

```
cannot load such file -- travis/support
```

以下のようにbuildしてinstall

```
$ git clone https://github.com/travis-ci/travis-support.git
$ gem build travis-support.gemspec
$ gem install travis-support-0.0.1.gem
```
自分の環境では同様の作業を以下でも必要だった

- travis-rollout
- travis-github_apps

加えてaddressableコンフリクトするエラーがあったので対象のバージョンをuninstall

```
$ gem uninstall addressable -v 2.5.2
```

これでスクリプト生成

```
$ travis compile > ci.sh
detected repository as bassaer/travis-local
```

ブランチ名が`dev`の場合は以下のように修正

```diff:ci.sh

-    travis_cmd git\ clone\ --depth\=50\ --branch\=\'\'\ https://github.com/bassaer/travis-local.git\ bassaer/travis-local --echo --retry --timing
+    travis_cmd git\ clone\ --depth\=50\ --branch\=\dev\ https://github.com/bassaer/travis-local.git\ bassaer/travis-local --echo --retry --timing
```
準備完了。

# 実行

```
$ bash ci.sh
```