OmniAICreator/Qiita-1.07M huggingface dataset:
構造化ログのススメとRuby向けロガーOugaiを作った理由

## 構造化ログ

**構造化ログ** とは、機械的に処理しやすいログのことであり、その機構（ロギング）である。
英語圏では、 **Structured Logging** と表記される。たとえば Google Cloud の Stackdriver のドキュメントには下記の説明ページがあります。（残念ながら執筆時点で、これの日本語ページがまだできてないので、Google がどう訳すか興味深い）
https://cloud.google.com/logging/docs/structured-logging

## 普通のログと構造化ログの比較

普通のログは、基本的に **タイムスタンプ** 、**レベル** 、そして **メッセージ** の文字列だけである。ログとして残す事象（イベント）のコンテキストになる情報はメッセージに適当に埋め込む。コンソール等で人が読みやすいものである。

構造化ログは、メッセージに埋め込んでいたコンテキストになる情報をそれぞれログ構造のフィールドに独立して持たせる。そのため後から解析がしやすい。そして出力するログはテキストベースで JSON にすることが多い。

（続く）

[続きは tilfin's note へ](https://blog.tilfin.com/2018/05/13/2018-05-13-185342/)
golangで二分探索

「珠玉のプログラミング」を読んでいて、二分探索をc言語で書いてみるくだりがあったので、golangで書きなおしてみました。

二分探索はソートされている配列に対して、探索範囲を半分ずつに絞ることによってO(log N)で探索することができるアルゴリズムです。

下のコードでは、関数solveに整数の配列arrayと探索対象のtargetを渡すと、存在した場合は配列のindex、存在しない場合は-1を返します。

```go
package main

import "fmt"

// array[0..n-1]からtargetを探す
// targetの位置をpとして
// targetがないとき、p=-1
// targetがあるとき、0<=p<=n-1 && target=array[p]
func main() {
	array := []int{1, 3, 6, 9, 100, 101}
	target := 100
	p := solve(array, target)
	fmt.Println("target index is ", p)
}

func solve(array []int, target int) int {

	// 範囲start < endを探索する
	arrayLen := len(array)
	start := 0
	end := arrayLen - 1
	var index int
	for {
		if end < start {
			return -1
		}
		index = (start + end) / 2

		if array[index] == target {
			return index
		}

		if array[index] < target {
			start = index + 1
		} else {
			end = index - 1
		}
	}
}
```

startとendの距離がループする毎に短くなっていくため、end < startとなるまでに探索対象が存在しない場合は終了します。

以上、golangで二分探索を書いてみた例でした。
origin/masterの備忘録

## 概要

複数ブランチ運用しているときに
リモートのmasterブランチへ
マージするときにすごく苦労したので
備忘録として書き起こしておこうと思います。

## 手順

1. 作業ブランチでpushする
2. masterブランチにmergeする
3. masterブランチでpushする

## 1. 作業ブランチでpushする

私はいつも以下のようにしています。

``` git:コマンドライン
git add .
git commit -m "[コミットメッセージ]"
git push origin [現在のブランチ]
```

少し脱線しますが
最近になって知った事で
`git add`コマンドに
`-u`、`--all`、`-A`なるオプションがあるらしいですね

`-u`は`--update`の短縮形で
前回のステージングから変更があったものを対象に加えます

`--all`と`-A`は同じ意味で
意味的には`.`、`-u`の組み合わせだとか...
`-u`で事足りているのでちょっとこれは理解していません(笑)

## 2. masterブランチにmergeする

私がよくするのは以下ですね

```git:コマンドライン
git checkout master
git merge --no-ff [作業ブランチ] 
```

`--no-ff`オプションは
fast-forwardの関係であっても
必ずマージコミットを作る
・・・そうです(笑)
今までこうするものだと思ってやってました
今回書き起こすにあたって調べて知ったわけです

## 3. masterブランチでpushする

今の手順通りであれば
マージコミットが作られているので
何もせずに以下のコマンドを打ち込みます

```git:コマンドライン
git push origin master
```

お馴染みですね
これでorigin/masterブランチに
マージが反映されました

もし、`--ff`オプション(デフォルト)で
mergeされた場合は
恐らくcommitが必要になると思います。

## まとめ

- push
- merge --no-ff
- push

すみません、かなり雑です

ですがこの備忘録作ってるとき
一人趣味プロジェクトやってるとき
こういう問題だったりとか
コマンドの意味を調べてみたりだとか
やってみてすごく勉強になりました
やっぱり自分ってまだまだだなと思いながら。

もし間違ったところ、補足等あれば
コメントいただきたいです。

## 参考文献

[git mergeコマンドのオプションまとめ](https://qiita.com/saekis/items/544d2fb9d21e9a239b7d)
[Gitコマンドについて調べる【git add】](http://kimromi.hatenablog.jp/entry/2015/08/04/082357)
Forge + Vultr ではじめてLaravelアプリをデプロイするときにつまずいたこと

# Forge + Vultr の導入方法
Laracastに従って、Digital Oceanの部分をVultrに置き換えればおおむねできますが、つまずいた点がいくつかありました。

https://laracasts.com/series/server-management-with-forge

# 困ったところ
## APIキーが通らない
ForgeとVultrを連携させるには、VultrのAPIキーをForgeに登録する必要があります。

ところが、VultrのAPIキーを生成してForgeに登録しても、エラーで通りません。

### 解決法
Vultrの設定（Account > API）から、Access Controlを確認。

ForgeのIPを指定するか、「Allow All IPv4」を設定しましょう。

Allow All IPv4したくない時は、以下を参照してIPを指定すればいいらしい（このIPが正しいのか、筆者は未確認）。

https://forge.besnappy.com/laravel-forge#servers-5454

## サーバーが立てられない
サーバーを作ろうとしたら、画像のようなエラーが出てサーバーが立てられない。
![スクリーンショット 2018-05-13 15.45.43.png](https://qiita-image-store.s3.amazonaws.com/0/32771/a09fecfd-0eef-f452-f7c4-0a1f4bcf0170.png)

### 解決法
Vultrから来たメール認証をしていなかっただけでした。

メールボックスを確認し、メール認証をしましょう。
![スクリーンショット 2018-05-13 15.52.31.png](https://qiita-image-store.s3.amazonaws.com/0/32771/e8599423-8f4a-e712-b7af-1038791bdc30.png)

## DNS設定が反映されない
ドメインを取得し、ドメイン管理サービス（今回はムームードメイン）でネームサーバーやレコードを設定。その後２、３日経ってドメインにアクセスしても「IPアドレスが見つかりません」となる。

### 解決法
これも至って単純。VultrのDNS設定の画面で、取得したドメインを登録する。すぐに変更が反映されました。

![DNS_-_Vultr_com.png](https://qiita-image-store.s3.amazonaws.com/0/32771/c06df3c0-b232-940b-c72b-fa0bc762b373.png)

# まとめ
他に困ったところはありませんでした。

ForgeもVultrも直感的に操作でき、Laracastでも丁寧に説明してくれています。

しかし、こういう「書か無くてもわかるだろう」レベルの凡ミスで困ったりするので、気をつけましょう。
Laravel  データの取得と抽出


初心者メモ
基本操作

viewの作成の続き

##Postのデータを全件取得してみる

```app/Http/Controllers/PostsController.php

<?php

/* 名前空間 */
namespace App\Http\Controllers;

use Illuminate\Http\Request;

class PostsController extends Controller
{
  # indexアクションを定義
  public function index() {
   # データの取得
    $posts = \App\Post::all(); //Postのデータ全て$postsに代入(データ全件取得)
    return view('posts.index'); //view('ディレクトリ名.ファイル名');
  }
    //
}

```
追加内容:$hogehoge = \App\model::all();
この式で取得可能

```PostsController.php
<?php

$posts = \App\Post::all();

?>

このコードでPostのデータ全件取得が可能になったが、名前空間(\App\Postの部分)が長くなってしまうのでuseを設定していく
```
use 設定:

```PostsController.php追加
<?php
//useすることで名前空間に\App\Post::処理内容();等と書かないといけないものが、Post::処理内容();と省略できる
use App\Post; 

?>
```

```PostsController.php編集後
<?php

/* 名前空間 */
namespace App\Http\Controllers;

 //use: 名前空間を省略化
use Illuminate\Http\Request;
use App\Post;

class PostsController extends Controller
{
  # indexアクションを定義
  public function index() {
   # データの取得
    $posts = Post::all(); //Postのデータ全て$postsに代入(データ全件取得)
    return view('posts.index'); //view('ディレクトリ名.ファイル名');
  }
    //
}

```

```
use App\Post; することで

$posts = Post::all(); ←のように省略して表現できるようになった
```

これでコードはスッキリ。

ここで一旦正しくデータが取得できたか確認してみる
・dd();というLaravelの機能を使って確認 (dump dieの略: デバックしてその場で処理を終了。みたいな感じ？)

dd($posts->ToArray()); で配列で表示させてみる

```PostsController.php

//dd();を追加

  public function index() {
   # データの取得
    $posts = Post::all(); //Postのデータ全て$postsに代入(データ全件取得)
    dd($posts->ToArray()); 
    return view('posts.index'); //view('ディレクトリ名.ファイル名');
  }
```

この状態でブラウザを起動すると出力される
![スクリーンショット 2018-05-13 18.35.27.png](https://qiita-image-store.s3.amazonaws.com/0/174952/571f700d-2658-85a9-0560-6084ace71c55.png "スクリーンショット 2018-05-13 18.35.27.png")

![スクリーンショット 2018-05-13 18.36.05.png](https://qiita-image-store.s3.amazonaws.com/0/174952/17455990-d04a-93e6-0679-ced90c376aa6.png "スクリーンショット 2018-05-13 18.36.05.png")


ちゃんと取得出来ていることを確認！！
問題なしですね。


##取得データを降順にする

```
$posts = Post::all();
```
上記のコードを下記に変更すれば降順で表示される

```
$posts = Post::orderBy('created_at', 'desc')->get(); 
```
orderBy();を使う場合はallは無しで良い

ちなみに降順にする方法は他にもあって

posts = Post::latest()->get(); を使ってみる
これはposts = Post::orderBy('created_at', 'desc')->get();と同じ意味で省略された型

```PostsController.php
  public function index() {
   # データの取得
    $posts = Post::latest()->get(); //Postのデータ全て$postsに代入(データ全件取得)
    dd($posts->toArray()); //dump die
    return view('posts.index'); //view('ディレクトリ名.ファイル名');
  }
```

```
$posts = Post::latest()->get();を使うと
idが２(最新)からに変更されている
```

![スクリーンショット 2018-05-13 18.55.41.png](https://qiita-image-store.s3.amazonaws.com/0/174952/80d3f93e-f2c5-c68f-62cb-860c86ce2d9d.png "スクリーンショット 2018-05-13 18.55.41.png")



データの抽出確認がおわったのでdd();はコメントアウトするか削除しておく
POSTされた画像をExpressで取得する

クライアントが`'Content-Type': 'multipart/form-data'`で画像をPOSTした場合
Expressでどういう処理をすればいいのか悩んだので記載しておきます。
[multer](https://github.com/expressjs/multer)を使います。

```javascript
const express = require('express')
const multer = require('multer')
const app = express()
const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    // 保存したいパス
    cb(null, '/var/image')
  }
  ,
  filename: function (req, file, cb) {
    // アップロードしたときのファイル名で保存
    cb(null, file.originalname)
  }
})
const upload = multer({ storage: storage })

// listening 3000 port
const server = app.listen(3000)

app.post('/image', upload.single('file'), function(req, res, next) {

  // POSTされた画像の情報をJSONで取得
  const req_file_json = JSON.stringify(req.file)

　　　　// ***************
  // お好きな処理をここに
　　　　// ***************

  res.json({'result': 'success!'})
})
```

上記の場合サーバ側では `/image/var/[ファイル名]` に画像が保存されます。
画像の情報も一行で取得できるので便利ですね。

```javascript
// POSTされた画像の情報をJSONで取得
const req_file_json = JSON.stringify(req.file)
```

bodyにも情報が入っている場合は

```javascript
const req_body_json = JSON.stringify(req.body)
```

で取得できますね。
画像をアップロードするときに他の情報（画像の正解ラベル等）がbodyに入っていてもこれで対応できますね。
python でデータサイエンスを始めるにあたって覚えたほうがいいメソッドまとめ（kaggle titanic tutorial）

## 背景
今回 [kaggle の titanic チュートリアル](https://www.kaggle.com/c/titanic/)を行いました。
精度は78.5%前後と、大した精度ではなかったので手法は書きませんが、
なれない python でのデータ分析だったので、自分用のメモとして、
もしくはこれから同じようにpythonでデータ分析を始める人向けにまとめておこうと思います。

#pandasのメソッド
`import pandas as pd`　で使えるようになります。
###CSVの読み込み
`pd.read_csv('filename')`

##Dataframe の操作
###CSVとして書き込み
`data.to_csv('filename')`

###Dataframe を1カラムで初期化する
`dataframe = pd.DataFrame({'col_name':[]})`

###keyの一覧を取得する
`dataframe.keys()`

###先頭n個のデータ表示
`dataframe.head(n)`

###特定のカラムすべてのデータに対する操作
`dataframe["col_name"].apply(lambda x: 0 if x == 'hoge' else 1)`

###特定のカラムをカラムごと削除
`dataframe.drop(["col1", "col2"], axis=1 )`
###特定のカラムを置換
`dataframe.replace({"A":0, "B":1, "C":2})`

###for文を利用してすべてのデータを参照
`for column_name, item in dataframe.iterrows():`

###データの追加
`fare_mean_arr.append(data)`

###特定のカラムでnullを特定の値に置換
`dataframe["col"].fillna(num)`

###特定のカラムにおける全データの最大値を取得
`dataframe['col_name'].max()`

###特定のカラムにおける全データの平均値を取得
`dataframe['col_name'].mean()`

###特定のカラムにおける全データの中央値を取得
`dataframe['col_name'].median()`

###各カラムにnullが含まれているか
含まれていれば `true` なければ `false` が帰ってくる
`dataframe.isnull().any()`

###各カラムに入っているデータ型の一覧を取得
`dataframe.dtypes`

###データ分布の確認
`dataframe['col'].hist()`

###特定のカラムを正規表現で置換
例は数値を削除する時
`train['col'] = train['col'].replace('[0-9]*','',regex=True)`

#scikit-learn の学習メソッド

`from sklearn import {classifier}`
でclassifierのメソッドが呼べるようになります。
二分木やsvmなどいろいろあります。
今回は二分木を使いましたのでそちらで説明します。

###二分木の分類機を作る
`clf = tree.DecisionTreeClassifier(max_depth=3)`

###分類機で学習する
`clf.fit(train_data, answers)`

###学習した分類機で分類を実行する
`predict = clf.predict(data)`


#まとめ
今後も新しくメソッドを使うたびにまとめていこうと思いますが、
これだけ使えればとりあえず簡単な分類はできると思います。
[#TouchDesigner] CloneとCloneImmuneについて

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f3132373430322f34633563393131652d623935642d343337392d343239392d3361303263313462336430342e706e67.png](https://qiita-image-store.s3.amazonaws.com/0/127402/72f7d19d-056d-963e-6e04-52a6e460b749.png)

# はじめに
TouchDesignerのコンポーネントノードでは、コピー&ペーストや、ReplicatorCOMPを用いて、指定したノードへの参照を保持する形で、ノードの複製を行うことができます。
この、参照を保持したノードの複製を、特別に**Clone**と呼称しますが、
今回はCloneの詳細について公式のドキュメントから抜粋して日本語でまとめてみようと思います。

[Derivative official documentation - Clone](https://docs.derivative.ca/index.php?title=Clone)

## Cloneとは
冒頭に述べたように、TouchDesignerでは、ReplicatorCOMPを用いて動的にノードを生成することができます。
(コピー&ペーストでも同様のことができますので、今回はReplcatorCOMPに集中して記述します。)
TouchDesignerにおける「ノードの複製」では、単に同じノードを新規作成して複製する方法と、参照を保持して複製するCloneの、2通りの方法が用意されています。
その指定方法は、**複製する対象のCOMPノードのパラメータ->Commonタブ->Clone Master**で設定を行います。

例えば、それぞれのコンテナの内部に異なるMovieを配置していたとします。
![2018-05-13_165550.png](https://qiita-image-store.s3.amazonaws.com/0/127402/3d46e634-69be-2746-20c9-54db38f7a2b4.png)

<img src="https://qiita-image-store.s3.amazonaws.com/0/127402/7513156f-3aad-c04d-5230-525efcb982af.png" width="600px">

<img src="https://qiita-image-store.s3.amazonaws.com/0/127402/9ac9902a-d6d0-c491-0c39-0306f180e45e.png" width="600px">

その後に、container2の パラメータ -> Commonタブ -> Clone Master にcontainer1を指定すると、container2の状態がそっくりそのままcontainer1の状態に置き換えられます。
![2018-05-13_165609.png](https://qiita-image-store.s3.amazonaws.com/0/127402/19324ab6-f676-48ce-fcce-a2ef5c6a4962.png)
この時のcontainer1がクローンの**Master**、container2が**クローン**となります。

Clone Masterを設定した後にこれを解除して、Ctrl+zを押しても、Clone以前の情報は戻って来ないので注意してください。
![2018-05-13_165642.png](https://qiita-image-store.s3.amazonaws.com/0/127402/0e4d65fc-f636-3dd4-8d31-7b8bdce21189.png)

Clone後にクローンされたノードの内部のパラメータを操作することは可能ですが、
Masterのパラメータが変化した瞬間上書きされてしまいますので、
クローンした場合に操作するパラメータをMasterのみに限定するのが一般的かと思います。

## Cloneの際の特徴
### クローン間で共通化されるもの

- クローン内部には、Masterが保持しているノードと同一のものを含む
- ノード間の接続とレイアウトが同一となる
- **クローン内部の**ノードのパラメータは、Master内にあるノードのパラメータと強制的に一致する(本体のCOMPのパラメータは変化可能)
- クローン内部のノードのフラグ(バイパスやビュワーなど)は強制的に一致する

### クローン間で独立するもの

- **コンポーネントへの入力** - inを介してクローン内部に入るCHOPやSOPのようなオペレータは、異なる入力を持つことがあります。したがって、クローン内のノードからのデータ出力は、クローン自体からのデータ出力と同様に、異なることがあります。
- **変数** - オペレータの親の名前、番号を使用したクローン内のノードにある変数はクローン間で変化します。たとえば、クローンされたノード名の数字(digits)を使用して、テーブルの値を検索することができます。したがって、パラメータは同じ式ですが、評価値が異なる場合があります。
- **Immuneノード** - クローン内部にあり、Immuneフラグが有効になっているノードは操作不可で、ユニークです。Immuneフラグが設定されているノードは、クローンのマスターと一致させる必要はありません。たとえば、Immuneフラグが有効なTable DATをクローン内に置くことで、ユニークにカプセル化し、移植性のあるものにすることができます。
- **コンポーネントのパラメータ** - クローンされたコンポーネントのパラメータ(レイアウト、Background、オーバーライド、トランスフォーム)などは変化します。これは、クローン内部のノードのパラメータではなく、クローン自体のパラメータです。


## クローンのImmunityとImmuneフラグ
Clone Immunityは、クローン内部に存在するノードをMasterと独立して存在することを許可するという意味を持ちます。
Immuneされたノードは、ノードのImmuneフラグを有効にすることで作成することができます。

クローン内部に任意の数のImmuneノードを追加することが可能で、
マスターの内容が変更されてもオーバーライドされません。
例えば、クローン間で独立したDATテーブルをクローン内に保つためにImmuneフラグを使用します。

Immuneノードをマスターに配置すると、現時点でのマスターの値を使用し、初回クローンのみ各クローンにそのImmuneノードが作成されます。
その後、マスター内のImmuneノードの値を変更、削除しても、クローン内のImmuneノードは更新されません。

## すでに作成したクローンのパラメータをMasterと揃える
マスターの任意のパラメーターを右クリックし、「Copy to all clones」を選択します。これにより、すべてのクローンが検索され、値がすべて同じになります。
パパさんSEの心得

1.やりたいことは子供と嫁が非稼動のときにするべし(昼寝中、深夜など)

2.子どもの世話は積極的に行うべし(嫁の機嫌とりにも◯)

3.洗濯機を回す、洗濯物を積極的に干して嫁を楽にすべし

4.休日は料理を作り、嫁に楽させるべし

9999999.年収2000万になってお手伝いさんを雇えるようになるべし

思い付いたら追加していきます
ngrokの使い方

## ngrokとは？
[ngrok公式サイト](https://ngrok.com/product)に書いてある通り、ローカルのサーバを外部に公開するツールです。

詳しくは公式サイト見てください。

## 導入方法

まずは`SIGN UP`からアカウント登録をします。

その後、ダウンロード方法が表示されます。

そこから落としてもいいんですが、面倒なので`brew`で入れちゃいます。

```:zsh
brew install ngrok
```

**人によってはbrewでは出来ないときもあるので、その場合は `brew cask` で入れます。**

```:zsh
brew cask install ngrok
```

その後、先程作成したアカウントと接続し使えるようにします。

```
ngrok authtoken authトークン: ngrokのダッシュボードにある
Authtoken saved to configuration file: /Users/mimikun/.ngrok2/ngrok.yml
```

## 使い方
共有したいものが使っているポート番号を指定し、実行します。

railsのプロジェクトだったら3000番ポートとか。

```
ngrok http 3000
```
LaravelでControllerの作成とルーティング設定


初心者メモ

##ルーティング設定

まずはGetでアクセスした場合のルーティング設定

```delete
今回はデフォルトのルーティングを使わないので以下コード削除

//デフォルトではルートにアクセスすればviewディレクトリのwelcomenにアクセスするとなっている
Route::get('/', function () {
    return view('welcome');
});

```
新しくルーティングの追加：
rootにアクセスした場合PostsControllerのindexアクションを実行するという命令を書いてみる

```routes/web.php
//rootにアクセスした場合PostsControllerのindexアクションを実行
Route::get('/','PostsController@index');
```

##Controller作成
現状PostsControllerがないので、artisanコマンドでコントローラー作成
(php artisan make:controller コントローラー名 実行)

```ターミナル
$ php artisan make:controller PostsController
```
Controller作成完了！

続いてindexアクションを定義する：
・ルート（indexアクション）にアクセスした時に'hello'と表示されるよう命令してみる

```app/Http/Controllers/PostsController
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class PostsController extends Controller
{
  #indexアクションを定義
  public function index() {  ←ここを追加
    return "hello";
  }
    //
}
```
##ブラウザで表示
準備ができたのでブラウザを立ち上げてみる
ifconfigでIPアドレス確認

下記コードでLaravelサーバーにアクセスしてみる：
php artisan serve --host IPアドレス --port 8000

自分の環境ではIPアドレスが192.168.10.1だったので下記コマンド実行

```ターミナル
Laravelサーバー起動：
$ php artisan serve --host 192.168.10.1 --port 8000 



結果：
Laravel development server started: <http://192.168.10.1:8000>
```

<http://192.168.10.1:8000>
アクセスしてブラウザで確認

![スクリーンショット 2018-05-13 17.12.48.png](https://qiita-image-store.s3.amazonaws.com/0/174952/19cd3cae-fb9d-5370-2074-b503293164ca.png "スクリーンショット 2018-05-13 17.12.48.png")

表示されてるのでOK
application.ymlでJdbcTypeForNullにNULLを指定する場合はクォーテーションをつける

タイトルのとおりです。単純なことですがハマったので書き残しておきます。

# 環境
- Spring Boot 2.0.2
- MyBatis 1.3.2

# application.ymlにおけるJdbcTypeForNullの設定方法

yamlで値として`NULL`を指定すると、読み込み時にnull値として扱われてしまいます。
JdbcTypeForNullの値に`JdbcType.NULL`を設定したい場合、application.ymlではクォーテーション付きで`'NULL'`と指定する必要があります。

``` yaml:application.yml
mybatis:
  configuration:
    jdbc-type-for-null: 'NULL'
```

ちなみに、プロパティファイルの場合は、値は常に文字列で扱われるため、クォーテーションは必要ありません

``` properties:application.properties
mybatis.configuration.jdbc-type-for-null=NULL
```

# JdbcTypeForNullについて

DBのカラムにnullを設定する際は、NULL値とJDBC型のマッピングを指定する必要があります。
Mybatisでは、デフォルトで`JdbcType.OTHER`が指定されるように設定されていますが、Oracleなど一部のJDBCドライバは`JdbcType.OTHER`をサポートしていないため、デフォルト設定ではエラーが発生します。
Oracleの場合は`JdbcType.NULL`を指定すると解決するようです。

# 参考URL
- [MyBatis – MyBatis 3 \| 設定](http://www.mybatis.org/mybatis-3/ja/configuration.html#settings)
- [mybatis\-spring\-boot\-autoconfigure – MyBatis Sring\-BootStarter \| Reference Documentation](http://www.mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure/index.html#Configuration)
- [6\.2\. データベースアクセス（MyBatis3編） — TERASOLUNA Server Framework for Java \(5\.x\) Development Guideline 5\.3\.0\.RELEASE documentation](https://terasolunaorg.github.io/guideline/5.3.0.RELEASE/ja/ArchitectureInDetail/DataAccessDetail/DataAccessMyBatis3.html#nulljdbc)
M5stackでAquesTalk pico for ESP32を使って音声合成

#はじめに
M5stackには、スピーカーもついてる。
どうせなら、音声合成したい。
とはいえ、ラズパイのようには行かないから、難しいかと思ったら、AquesTalkならできるようなので、試してみた。

# 参考サイト
[ESP32で音声合成(AquesTalk pico for ESP32)](http://blog-yama.a-quest.com/?eid=970188)
この通りやったらできました。

# 感想
日本語を簡単に喋らせれます。
しかし、テキストは、ローマ字にする必要アリです。
Google Homeに喋らせる

# GoogleHomeに喋らせたい

初投稿です。
GoogleHomeを使ってなにかやってみたいと検索したところ、次の記事を見つけました。

【node.js】Google Home Notifierを使ってGoogle Homeにしゃべらせる - echo("備忘録");
http://makky12.hatenablog.com/entry/2018/01/28/221600

手順はこの記事で紹介されているものそのままなので省きます。
個人的につまずいた部分をまとめてみます。

# 環境
PC:Windows10
Google Home(同一LAN上)


# .NETが必要だった
```
npm install google-home-notifier
```

でエラーが発生してしまいました。

他の記事でも当たり前のように省略されていますが、.NETが必要です。
このPCで開発やるの初めてだったため、入っていませんでした。

以下のページから.NET Core SDKと.NET Framework Develop Packをダウンロードしインストールしました。
Frameworkのほうは必要なかったかもしれません。
https://www.microsoft.com/net/download/windows


これでgoogle-home-notifierのインストールが無事完了しました。

# 作成したプログラムはプロジェクトのルートに置く
適当にデスクトップにjs置いて、実行しようとしてましたが、

```
var googlehome = require('google-home-notifier');
```

で落ちます。

```
node-gyp configure
```

したフォルダに配置しましょう。
Node.js自体初めて触ったのでこんなことでつまずきました。

# 最後に
初投稿なので生暖かい目で見て下さると助かります。
Readable Code を読む - はじめに ~ 第１章 -

Readable Code を読む
====================
今までほぼ我流でコーディングしてきたので，ずっとどうにかしたいと思っていました．
そんなときに，O'REILLYの **Readable Code** を奨めてもらったので，読んで自分用にまとめてみようと思います．

今回の内容は，**はじめに**から**第１章**まで（第1部の前までの最初の部分）についてです．

[はじめに・第1章はこちら](https://qiita.com/hsmtknj/items/8e126c81e7a055242135)
[第1部と第2部はこちら](https://qiita.com/hsmtknj/items/bc784cbff60256c951cc)
[第3部と第4部はこちら](https://qiita.com/hsmtknj/items/31601e3ebd51f22231b2)

本書は次のリンク先等で入手できます．
[Readable Code](https://www.amazon.co.jp/リーダブルコード-―より良いコードを書くためのシンプルで実践的なテクニック-Theory-practice-Boswell/dp/4873115655/ref=pd_lpo_sbs_14_t_0?_encoding=UTF8&psc=1&refRID=77RQXSX2C82VCWRW3S02)


はじめに
=======
> **美しいコードを見ると感動する**
> **優れたコードは見た瞬間に何をしてるかが伝わってくる**

本書の目的は**コードをよくする**こと．
コードは読んでいる時間が非常に長いので，**読みやすいコード**を書くことは重要である．
具体的に読みやすくするための項目に以下のようなものが挙げられる．

- 変数の名前をつける
- ループの処理を書く
- 問題を関数のレベルまで落とす

「読みやすいコード」を書くことは「理解しやすいコード」を書くことであり，**「優れたコード」**につながる．


### 本書の構成
本書は大きく4つの部に分かれている．

1. **表面上の改善**
    名前・コメント・見た目のようなコード全体に適用できる簡単なヒント

2. **ループとロジックの単純化**
   プログラムのループ・ロジック・変数などを改善して理解しやすくする方法

3. **コードの再構成**
    巨大なコードブロックを再構成して問題を関数のレベルに分解する方法

4. **選抜テーマ**
    「理解しやすさ」をテストや大きなデータ構造に適用する方法

各章は独立しているので，どの章からでも読み進められる．



1章 理解しやすいコード
====================
コーディングの基本定理を以下のように考える．
> コードは他の人が**最短時間で理解できる**ように書かなければいけない．

ここでいう**理解ができる**とは次のようなことができることを指す．

- 変更を加えることができる
- バグを見つけることができる


## コードは短ければいいってもんじゃない
コードは確かに短い方がいいが，あくまで基本原則の**「理解するまでにかかる時間」**を短くする方が大切である．

次の２つのコードはどちらも同じ動作をする．

```py
if (num == 10):
    flag = True
```

```py
# change flag into True, when num is 10
if (num == 10):
    flag = True
```
上のコードの方が短いが，下のようにコメントをつけた方が**読みやすい**こともある


ここで大事なことは**「このコードは理解しやすいだろうか？」**と自問自答することだ．



# 今回のまとめ
コードを読む立場になって，読みやすいコードってなんだろう．と考えてみることが第一歩ですね．
コードを読むのは半年後・１年後の自分かもしれません．
MacでM5Stack！〜Hello Worldまで

# はじめに
ゴールデンウィーク中に、スイッチサイエンスさんで、M5Stack購入できました。
Arduino IDEで、Hello Worldを表示するところまで、やってみました。

## USBドライバーのインストール
[SiLabs CP2104 Driver](https://www.silabs.com/products/development-tools/software/usb-to-uart-bridge-vcp-drivers)から、Mac用のドライバーを取得する。
Macの場合は、このページは必読
[M5Stackであそぼう](http://mag.switch-science.com/2018/02/28/getting-started-with-m5stack/)
「注意点として、MacOSXの10.13.3（Hight Sierra）ではUSBドライバのインストールをしても、USBデバイス（/dev/tty.SLAB_USBtoUART）が出現しません。実はドライバをアクティベートするには、システム環境設定のセキュリティーとプライバシーのところで「許可」ボタンを押す必要があることにしばらくして気がつきました。みなさんもお気をつけください。」


# ESP32 Arduino Coreのインストール
[Installation instructions for Mac OS](https://github.com/m5stack/M5Stack/blob/master/docs/arduino-ide/mac.md#installation-instructions-for-mac-os)

この手順でうまくいくようだが、私の環境ではエラー。
同じエラーの方がいた。
[Arduino core for the ESP32(mac版)のget.pyで発生したエラーのシュート](https://qiita.com/mgr206/items/5ee76d18c7382985de34)
こちらを行い無事完了！

ここまで来たら、以下で。
[M5Stack Library](https://github.com/m5stack/M5Stack)

# 参考
ここまでまとめてたら先人の良いまとめ記事がありました。
[ESP32 > M5Stack > Hello world!](https://qiita.com/sugasaki/items/a763f238aa360e4df414)
Linux OSのバージョンを調べる方法




# 1. OSのディストリビューション名を調べる
## cat /etc/os-release
>[account /]$ cat /etc/os-release
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"'

>CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"

# 2. ディストリビューションのバージョンを調べる

今回はCENTOSだったので以下のコマンドを実行
## cat /etc/redhat-release 
[account /]$ cat /etc/redhat-release 
CentOS Linux release 7.4.1708 (Core) 

 ※基本的には/etc/以下で[ディスロ名]-releaseファイルを探して中身を見れば解決

# 補足. Linuxカーネルのバージョンを調べる

以下のどちらでも良い
## cat /proc/version

>[account /]$ cat /proc/version
Linux version 4.4.0-121-generic (buildd@lcy01-amd64-004) (gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9) ) #145-Ubuntu SMP Fri Apr 13 13:47:23 UTC 2018

　⇨なぜにUbuntu文字が？？？

## uname -a

>[account /]$ uname -a
Linux localhost 4.4.0-121-generic #145-Ubuntu SMP Fri Apr 13 13:47:23 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
Mac で FreeDOS 起動 USB メモリスティックの作成

macOS High Sierra で FreeDOS 起動 USB メモリスティックを作成した際のメモ

- Windows がインストールされていない PC の BIOS アップデートの際に利用しました

# 参考
- [MacOSでFreeDOSの起動USBメモリを作る方法](http://d.hatena.ne.jp/pyopyopyo/20120912/p1)

# 手順

1. どこかから `FreeDOS-1.1-USB-Boot.img` を入手して `~/Downloads` に保存
    - 私は [http://derek.chezmarcotte.ca/wp-content/uploads/2012/01/FreeDOS-1.1-USB-Boot.img.bz2](http://derek.chezmarcotte.ca/wp-content/uploads/2012/01/FreeDOS-1.1-USB-Boot.img.bz2) から入手

1. USB メモリスティックを接続後、デバイスパスを確認

    ```
  $  diskutil list
    ```

1. USB メモリスティックをアンマウント（N はデバイスパス番号）   

    ```
  $  diskutil unMountDisk /dev/diskN
    ```

1. dd コマンドでFreeDOS 起動 USB メモリスティックの作成（N はデバイスパス番号）
 
     ```
  $  cd ~/Downloads/
  $  sudo dd if=FreeDOS-1.1-USB-Boot.img of=/dev/rdisk3 bs=1m
     ```

1. USB メモリスティックの取り出し（N はデバイスパス番号） 

    ```
  $  diskutil eject /dev/diskN
    ```
お手軽!!5分でGoogle Homeに任意の文章を喋らせる

# やっていること

* Google Homeからアクセス可能なURLにMP3音声ファイルを作成する。
* python3のライブラリ[pychormecast](https://github.com/balloob/pychromecast)を使用し、Google HomeにMP3の再生指示を出す。
* Google Homeで再生される。

# 必要な物

* Google Home
* PC
    * python3
    * pip

# 

# 準備

## ネットワーク接続

PCとGoogle Homeを同一ネットワークに接続する

## [pychromecast](https://github.com/balloob/pychromecast)のインストール

```bash
$ pip install pychromecast
```

## MP3音声ファイルの作成

最短での実現を目指すため[Sound of Text](https://soundoftext.com/)を利用

1. Textに喋らせたい文章を入力
2. Voiceで言語を指定
3. Submitを押す
4. Downloadのリンク先URLをコピーする　※PCにはダウンロードしない

# 実行

以下通り実行するとGoogle Homeが喋ります。
xxxは実際の値ではありません。

```bash
$ python
>>> import pychromecast
>>> chromecasts = pychromecast.get_chromecasts()
>>> chromecasts
[Chromecast('192.168.10.8', port=8009, device=DeviceStatus(friendly_name='リビング', model_name='Google Home Mini', manufacturer='Google Inc.', uuid=UUID('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'), cast_type='cast'))]
>>> google_home = chromecasts[0]
>>> mc = google_home.media_controller
>>> mc.play_media('https://soundoftext.nyc3.digitaloceanspaces.com/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.mp3','audio/mp3')
```

# 最後に

最短でGoogle Homeを喋らせることを目標としましたが、
任意の文章を動的に生成するなら[Pythonを使って、Google Homeに喋らせてみる
](https://qiita.com/attakei/items/c5de47f3c1f53992c353)のような方法でやる必要がありそうです。
Twilio通話ログ取得

#Twilio REST API

REST APIをcurlで実行。

```bash:Twilio_REST_API_curlで実行
curl -G https://api.twilio.com/2010-04-01/Accounts/[account_sid /Calls.csv?PageSize=1000&StartTime=2018-05-10 \
    -u 'account_sid:auth_token'
```

REST APIをPythonで実行。

```python:Twilio_REST_API_Pythonで実行
import urllib.request
import datetime

yesterday = datetime.date.today() - datetime.timedelta(days=1)
target_date = yesterday.strftime('%Y-%m-%d')
account_sid = 'account_sid'
auth_token = 'auth_token'
url = "https://api.twilio.com/2010-04-01/Accounts" \
            + "/" + account_sid \
            + "/Calls.csv?PageSize=1000&StartTime=" \
            + target_date

# Basic認証
password_mgr = urllib.request.HTTPPasswordMgrWithDefaultRealm()
top_level_url = "https://api.twilio.com/2010-04-01/Accounts/"
password_mgr.add_password(None, top_level_url, account_sid, auth_token)
handler = urllib.request.HTTPBasicAuthHandler(password_mgr)
opener = urllib.request.build_opener(handler)

# URLへ接続
with opener.open(url) as res:
    html = res.read().decode("utf-8")
    print(html)
```

#Twilio Pythonモジュール
Twilio Pythonモジュールはインストールが必要。

```bash:Twilio_Pythonモジュールインストール
pip install twilio
```

```python:Twilio_Pythonモジュール
from twilio.rest import Client
import datetime
import traceback

try:
    # クライアント準備
    account_sid = 'account_sid'
    auth_token = 'auth_token'
    client = Client(account_sid, auth_token)

    yesterday = datetime.date.today() - datetime.timedelta(days=1)
    # 通話ログ取得
    calls = client.calls.list(
        start_time=yesterday
    )

    # ログ出力
    for record in calls:
        print(record.sid)

except:
    traceback.print_exc()

```
RESTAPIと同様にCSV形式で取得したかったが、やり方が見つからず断念。

ちなみに、RESTAPIの場合は以下の記述がありサクッとできた。
> 出力形式についてのメモ: リソースURIに「.csv」の拡張子を追加すると、カンマ区切り値の形式でリソースを取得できます。 これは通話ログの取得に特に便利です。 以下をお試しください:
> GET /2010-04-01/Accounts/AC5ef87.../Calls.csv


#注意
ログが多い場合一度に取得できない。
`PageSize=1000`を指定することで、一度に取得できる件数を1000件にできる。
デフォルトは50件。

1000件以上のログを1度で取得したい場合は工夫が必要になる。
ドキュメントだと以下の対応が必要とのこと
> API が返す結果のページを複数取得する場合は、受け取った nextpageuri パラメーターを使って、次のページの結果を取得します。 すべての Twilio Helper ライブラリ は、nextpageuri を使ってページを移動します。

ただ、json取得だとページ情報が含まれていたが、CSV取得では見当たらなかった。


#参考

https://jp.twilio.com/docs/usage/api
https://jp.twilio.com/docs/voice/tutorials/how-to-retrieve-call-logs-python
https://jp.twilio.com/docs/voice/api/call
https://jp.twilio.com/docs/libraries/python
https://docs.python.jp/3/howto/urllib2.html
https://jp.twilio.com/docs/voice/api/call#paging
https://jp.twilio.com/docs/usage/twilios-response#response-formats-list-paging-information
laradockでlaravel開発環境構築

laradock
https://laradock.io/

## 1.laradockインストール

```terminal
$ mkdir {project_dir}
$ cd {project_dir}
$ git clone https://github.com/Laradock/laradock.git # laradockをclone
```

## 2. laradock内のenv-exampleをコピーして.env作成

```terminal
$ cd laradock/ 
$ cp env-example .env
```

## 3.コンテナを起動

```terminal
$ docker-compose up -d nginx redis mysql workspace # コンテナ起動
```
`laradock`内の`docker-compose.yml`ファイルのあるディレクトリで行う。
初回起動時は時間かかります。

## 4.workspaceに入る

```terminal
$ docker-compose exec --user=laradock workspace bash # workspaceへ入る
```

`--user=laradock` で入らないと、`root`で入ることになり、`composer install`するときに怒られます。

## 5. laravelインストール

#### 新規プロジェクトをインストール(ver5.5)する場合

```terminal
$ composer create-project --prefer-dist laravel/laravel {project_name} "5.5.*"
```

#### 既存プロジェクトファイルをgit cloneする場合

```terminal
$ 　git clone {project_repository}
```

## 6. exitしてコンテナ停止
次の、`laradock`の`.env`を編集する前に、コンテナを停止します。

```terminal
laradock@hoge:/var/www$ exit # workspaceから抜ける
$ docker-compose stop # コンテナ停止
```

## 7. `laradock`の`.env`を編集して、プロジェクトディレクトリをマッピング

```terminal
$ vim .env

...(略)
# Point to the path of your applications code on your host
APP_CODE_PATH_HOST=../{project_name}
```

## 8. 再度コンテナ起動して、workspaceへ入る

```terminal
$ docker-compose up -d nginx redis mysql workspace # コンテナ起動
$ docker-compose exec --user=laradock workspace bash # workspaceへ入る
```

## 9. composer install

```terminal
$ composer install
```

## 10. アプリケーションキー生成(新規は省略可)
既存プロジェクトの場合

```
$ php artisan key:generate
```

## 11 .コンテナを再起動して反映させる

```
laradock@hoge:/var/www$ exit # workspaceから抜ける
$ docker-compose restart # コンテナ再起動
```

## 12. http://localhost/ にアクセス

![スクリーンショット 2018-05-13 16.13.58.png](https://qiita-image-store.s3.amazonaws.com/0/92407/be729e55-69f4-0229-8229-19898829b98d.png)
XREAにSSHで入る方法

#事前準備 
Macの場合は自前のターミナル起動
windowsの場合はコマンドプロンプトか、teraterm, puttyなどのツール　を起動

#実施
ssh -l userid(XREAのアカウント) sXXXX.xrea.com

※気をつけること
　そのままだとXREAのSSH接続が許可されていないため、事前に設定を変えること

　サイト設定　＞　ツール/セキュリティー　＞　SSH接続IP許可

以上！
Haskellを使ってRubyのクラスメソッドを書く(その4)まとめ

## 目次
**Haskellを使ってRubyのクラスメソッドを書く**
[(その1)FFI](https://qiita.com/ki073/items/6350747cce51e45a5e9b)
[(その2)FFI+JSON](https://qiita.com/ki073/items/e6f2a4f80b6ce790b781)
[(その3)FFI+MessagePack](https://qiita.com/ki073/items/dd01b5d3849531caa805)
(その4)まとめ　<- ここ

##ベンチマークの結果
Ruby側で
data=[*1..1000].map(&:to_f)
の1000個の要素からなる配列用意しencode->(Haskell側)decode->2倍->encode->(Ruby側)decodeを100回繰り返した時間を測定しています。単位はミリ秒です。

|  | 全体(a) | Ruby部分(b)| (a)-(b)|
|:-----------|------------:|------------:|------------:|
|FFI (その1)            |  5.8|  1.6|  4.2|
|FFI+JSON (その2)       |298.8| 40.6|258.2|
|FFI+MessagePack (その3)| 72.4|  4.3| 68.1|

(b)はRuby側だけの処理でencode->(Ruby側)decodeでHaskell部分を取り除いた時間
(a)-(b)は引き算してHaskell側だけの時間にした値です。Haskell側の処理がかなりかかっているようですので、改善の余地はありそうです。

FFIが一番高速で単純なデータ構造の場合はこちらが適しているようです。
MessagePackが健闘しており、複雑なデータ構造の場合は良さそうです。
(JSON, MessagePack共に)　[[Double]] -> [(Int, Int, Double)]のような構造でも簡単に受け渡しできます

CPU Intel Core i7-2600 CPU 3.40GHz
Scientific Linux 7.3
GHC 8.2.2
Ruby 2.5.1p57
stack 1.6.5
composer diagnoseでMissing pubkeyのとき

composerが急に調子が悪くなったので、`composer diagnose`で診断した。
すると、下記のようなエラー。

```
$ composer diagnose
Checking platform settings: OK
Checking git settings: OK
Checking http connectivity to packagist: OK
Checking https connectivity to packagist: OK
Checking github.com rate limit: OK
Checking disk free space: OK
Checking pubkeys: FAIL
Missing pubkey for tags verification
Missing pubkey for dev verification
Run composer self-update --update-keys to set them up
Checking composer version: OK
```

`Missing pubkey`と言われているので、下記コマンドを実行。

```
$ composer self-update --update-keys to set them up
```
https://composer.github.io/pubkeys.html
からkeyをコピペして(`Dev`と`Tags`)貼り付けして完了。
du コマンドの -Sオプションありとなしの表示の違い 

#はじめに

[duコマンドでサブディレクトリを含めたディレクトリ容量を表示する。](https://qiita.com/isotai/items/8fafd01bd44f55673288)という記事を書いた際に、
`du -S`と`du`　の表示の差異が気になったのでまとめています。


#結論

- `-S`はサブディレクトを含めない、ファイルの容量をディレクトごとに表示する。
- ディレクトそれぞれの使用量が知りたいのであれば`-S`オプションを付ける。
- ディレクトの合計使用量が知りたいのであれば、`-S`は付けない。


#-Sオプションとは

`man`コマンドで調べると以下のように表示されます。
直訳すると、*ディレクトリに対して、サブディレクトリの容量を含めず表示する。*　となります。

> -S, --separate-dirs
              for directories do not include size of subdirectories

#実行例
左が`du`右が`du -S`の実行結果です。
![2018-05-10_13h36_13.png](https://qiita-image-store.s3.amazonaws.com/0/162167/af5b87a1-b792-84fd-3a4f-b785c3e1a2b3.png)

4行目がを見ると`base`ディレクトが`du`の結果35M、`du -S`結果6.0Mとなっています。
2,3行目、サブディレクトの`base/gen`は29M,`/base/packages`は0で、同じ結果です。

`du -S`の結果であるbase(6.0M) +  base/gen(29M)　は　`du`の結果であるbase(35M)となります。

では`du -S`の結果であるbase(6.0M)は何を指しているのか、baseディレクト配下のファイルのみ一覧で表示します。

```sh
[root@-new base]# find  ./ -maxdepth 1 -type f -exec du -sh {} \;
4.0K    ./mirrorlist.txt
4.0K    ./repomd.xml
0       ./cachecookie
160K    ./9346184be1deb727caf4b1ecf4a7949155da5da74af9b92c172687b290a773df-c7-x86_64-comps.xml.gz
5.8M    ./0c34273ad0292747ee5e15c047d3e51c67ca59861a446972db45d71abacc7ad7-primary.sqlite.bz2
```
base配下のファイルの合計は約6Mであることが分かり、`du -S`のbaseに対する容量表示とほぼ同様になります。
[ メモ ]コマンド一覧

# [ メモ ]コマンド一覧

プログラム初心者がよく使うコマンドを集めたメモです。

###ファイル

- **cd ファイル名**
作業するディレクトリを変更

- **ls**
現在のディレクトリの中にあるファイル名を表示

- **pwd**
現在作業しているディレクトリ（パス）を表示

###npm

- **-v**
バージョンを表示

- **npm into**
package.jsonを生成する

- **npm install**
プロジェクトにパッケージをインストールする

- **npm run （watch）**
npm scriptsと呼ばれるタスク実行機能を呼び出す

###composer 

- **composer install** <br>
パッケージをインストールする

###vagrant
- **vagrant up**
仮想マシーンの起動

- **vagrant ssh**
仮想マシーンを接続（ログイン）

- **exit**
ログアウト

- **vagrant halt**
仮想マシーンを停止（終了）

- **vagrabt destory**
仮想マシーンを削除

- **vagrant status**
仮想マシーンの状態を確認

###Laravel artisan

- **php artisan key:generate** <br>
アプリケーションキーの設定(APP_KEY)

#####マイグレーション(migration)

- **php artisan make:migration create_ファイル名_table --create=テーブル名（複数形）**
マイグレーションの作成
 - **--create=テーブル名** <br>
 テーブルを作成
 - **--table=テーブル名** <br>
 **(php artisan make:migration add_votes_to_ファイル名_table --table=テーブル名)** <br>
 すでに存在しているテーブルを更新
<br>

- **php artisan migrate**
　マイグレーションの実行

#####モデル(model)
- **php artisan make:model ファイル名（クラス名）（単数系）** <br>
モデルの作成

#####Seeder
- **php artisan make:seeder ファイル名Seeder**
　seederの作成

- **php artisan db:seed**
seederの実行

- **php artisan db:seed --class=ファイル名Seeder**
個別でseederを実行

#####コントローラー(controller)
- **php artisan make:controller ファイル名Controller** <br>
コントローラーの作成



学んだコマンドは随時書いていきます。
RailsAdmin で enum を使うときの決まり文句を無くしたい

# RailsAdminEnumConfigurable を作った経緯
`RailsAdmin` いいですよね。開発初期あるいはリリース後も管理画面まで手が回らないときは重宝します。

しかし `enum` を使うときだけはどうも面倒で，

```ruby
class User < ApplicationRecord 
  enum status: { active: 1, supended: 2, deleted: 3 }

  def status_enum
    { active: 1, supended: 2, deleted: 3 }
    # self.class.statuses とするとより dry
  end
end
```

というように， `xxx_enum` というメソッドを定義してあげないと正しく動きません ([ドキュメント](https://github.com/sferik/rails_admin/wiki/Enumeration)にもそう書いてあるし，なんでそうなっているかは[該当コード](https://github.com/sferik/rails_admin/blob/ffa30e0563e86a91bf88a312911b77d1bfffc2dc/lib/rails_admin/config/fields/types/enum.rb#L15)を読むのが一番早い)。

`enum` を使う度にこれを毎回やるのは不毛なので，このメソッド定義をよろしくやってくれる gem を作りました。その名も `RailsAdminEnumConfigurable`。 concern として作っているので，

```ruby
class User < ApplicationRecord
  include RailsAdminEnumConfigurable
  
  enum status: { active: 1, supended: 2, deleted: 3 }
end
```

とするだけです。

```ruby
class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true
  include RailsAdminEnumConfigurable
end
```
というように親に読み込ませてしまえば各モデルの変更すら不要です。

同じ苦悩をお持ちの方はぜひ使われてみてください。
https://rubygems.org/gems/rails_admin_enum_configurable

# 蛇足
enum を使っているカラム一覧を取得できるメソッドも付いてきます (使うケース全くなさそうですが...)。

```ruby
User.enum_attributes # => [:status]
```
Mac treeコマンド　ディレクトリの階層を見やすく

Macbookで開発をやっていて、リポジトリの階層をREADME.mdに記載した方が新規参画の人にわかりやすいと思い、記載をしようと思ったけどtreeのやり方が分からず、調べたら直ぐ出たのでメモ書き程度に、、、

---
調べたら【homebrew】を使用すれば、一発解決

homebrewのインストールそのものは以下参照
　・[homebrewのインストール方法(macbook)](https://qiita.com/_daisuke/items/d3b2477d15ed2611a058)

---

##インストール方法
```bash

brew install tree
```

##treeコマンドの実行
インストールされたら階層を見たいディレクトリでtreeコマンドの実行

```bash
$ tree
.
├── img
│   ├── 1.jpg
│   ├── 2.jpg
│   ├── 3.jpg
│   ├── 4.jpg
│   └── 5.jpg
├── index.html
├── infiniteslide.js
├── jquery.pause.min.js
└── readme.md
```
階層が複雑になってきたときに視覚化できると何かと便利ですね
【UiPath】Web上の画像を簡単にダウンロードする

UiPathにはData Scraping（２クリックでWeb上のリスト情報を一括で取得する）のように
強力なデータ取得機能がありますが、取れるのはテキスト情報だけで画像は対象外です。

画像をダウンロードするには右クリック→名前をつけて画像を保存→保存ダイアログでOK、という
人間と同じ手順を実装してもいいのですが、ちょっと芸がない。
前回から引き続き、Flickrでもう少し遊んでみます。

# 画像をダイアログ開かずにダウンロードする
画像のURLさえわかればHTTP Requestアクティビティを使って直接ダウンロードできます。

画面中央の投稿写真をダウンロードしてみたいと思います。
![picture.png](https://qiita-image-store.s3.amazonaws.com/0/255097/a01c2623-740e-bb8d-b20a-df5929463b38.png)

### Get Attributeで画像のURLを取得
というわけで、まずは画像のURLを取り出します。
IEであればF12（又は右クリック→「要素の検証」）でHTMLの構造をチェック。
".jpg"で探すと画像のURLが見つかりました。
![html.png](https://qiita-image-store.s3.amazonaws.com/0/255097/5b36c282-6ab0-52ca-6010-bf60a127b5f8.png)
content, property, metaタグで掴めそうです。

URL取り出しに使うのはGet Attributeアクティビティ。
content要素の値を取りたいので、Attributeには"content"を指定。
![property.png](https://qiita-image-store.s3.amazonaws.com/0/255097/7afd89ad-4c7f-616d-8e9c-2007e1a39eaf.png)
[前回](https://qiita.com/UmegayaRollcake/items/ac34152fe1c0e37f65ac)同様、Flickrの場合は自動で生成されるSelectorがアテにならないので、自分でSelector組みます。
![selector.png](https://qiita-image-store.s3.amazonaws.com/0/255097/a7bec799-19e2-e9d2-5cb6-5165c7a2c9bd.png)
これを実行すればcontent要素の値=画像のURLを取得できるので、後はダウンロードするだけです。

### Http Requestでローカルフォルダにダウンロード
Http Requestアクティビティで、画像URLにGETかけてファイルをダウンロードします。
・EndPointには画像URL（この例では"URL"という変数に入れてます）
・MethodはGETのまま
・ResourcePathにはダウンロード先のファイルパス
　※フォルダ省略した場合は自分のプロジェクトフォルダに落ちてきます。
![property2.png](https://qiita-image-store.s3.amazonaws.com/0/255097/e809c17b-ae7f-2753-b7f7-8524f8ab29ca.png)

で、実行。プロジェクトフォルダ内にダウンロードできました。
実際にはファイル名は固定でなくPath.GetFileName(URL)で元の名前を生かした方が良いですね。
![download.png](https://qiita-image-store.s3.amazonaws.com/0/255097/a4ba72fb-f641-a485-10f5-6d62763a06f3.png)

今回はここまで。
Seleniumでページ巡回してconsole.logを保存

# 概要
ページ全体で、https対応しているか、M70対応（信頼されなくなる証明書を使っているページがあるか）を確認したくて、Seleniumでページを巡回して、Chromeのconsole.logを自動で保存する仕組みを作成。

# 環境
- macOS(sierra)
- node.js(9)
- chromedriver 2.37.0
- selenium-webdriver 4.0.0-alpha.1（何も考えずにインストールしたら、alphaだった）

# Chromeのconsole.logを保存するための起動オプション(mac)
```
open /Applications/Google\ Chrome.app --args --enable-logging --log-level=0
```

# SeleniumのWebDriverの起動方法(node.js)
- 検索しても、言語が違ったり、バージョンが違ったりして、設定方方法をなかなかみつけらず。試行錯誤したら動いた。

```javascript
const capabilities = webdriver.Capabilities.chrome()
const chromeOptions = {
    'args': ['enable-logging'],
}
capabilities.set('chromeOptions', chromeOptions)

let driver = await new webdriver.Builder()
.withCapabilities(config['capabilities'])
.build()
```

# 動作イメージ
![360p_gif.gif](https://qiita-image-store.s3.amazonaws.com/0/256894/a5f8b6f2-2d99-2a88-6210-31653407e243.gif)
https://youtu.be/2RXbYS8AKDw

# ソースコード(github)
```
https://github.com/uebusin/save_chrome_log
```
ファイルに特定ユーザーの権限だけ付与する

```console
// 権限設定
$ setfacl -m u:'ユーザー名':rw 'ファイル名' # rwは権限

// 権限確認
$ getfacl 'ファイル名'

// ディレクトリ内の全てのファイルに権限設定
$ ls | xargs setfacl -m u:'ユーザー名':rw
```
Firebase で無料認証サービスを試してみた

無料でID管理ができる時代。そろそろ覚えないといけないと思った。

# 事前準備（Webブラウザで実行）

- [Firebase コンソール](https://console.firebase.google.com/) でプロフェクトを作成
- DEVELOP> Authentication に遷移
- 「SIGN-IN METHOD」タブで、パスワード認証を Enable にして
- 「USERS」タブで、以下の実験で使うユーザを作成

Project Overview の設定アイコンから、以下を控える

- Project ID
- Web API Key


# クライアント側
とりあえず Nodeで確かめたけど、ブラウザのJSでもほぼ手順は同様

まずは、SDKのインストール

```
npm i --save firebase

// browserの場合
// <script src="https://www.gstatic.com/firebasejs/4.10.1/firebase.js"></script>
```



SDKを初期化したら、ID（メールアドレス）とパスワードでログインして、JWTトークンを得る。

```js
const firebase = require('firebase');

(async () => {
  // initialize SDK
  const config = {
    apiKey: 'XXXXXXXXXXXXXXXXXXXXXX',
    authDomain: 'XXXXXXXXXX.firebaseapp.com', // project ID
  };
  const app = firebase.initializeApp(config);

  // authentication
  const auth = app.auth();
  const email = 'XXXXXXXXXXX@XXXXXXXXXX.com';
  const password = 'XXXXXXXXXXX';
  await auth.signInWithEmailAndPassword(email, password).catch(console.log);
  const me = auth.currentUser;
  console.log(me.email, me.emailVerified);

  // retrieve JWT
  const token = await me.getIdToken();
  console.log(token);
})();
```

# サーバ側

[Firebase コンソール](https://console.firebase.google.com/) でサービスアカウントを作成

- Project Overview の設定アイコンから設定画面に遷移
- SERVICE ACCOUNTS タブからGENERATE NEW KEYをする
    - JSONがダウンロードされる。これは公開しちゃダメなファイル

アドミン用のSDKをインストール

```
npm i --save firebase-admin
```

クライアントの生成したJWTをバリデーションする。

```js
const admin = require('firebase-admin');
const account = require('./key.json');

const token='XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';

(async () => {
  // initialize SDK
  const credential = admin.credential.cert(account);
  const app = admin.initializeApp({ credential });

  // verify
  const auth = app.auth();
  const decoded = await auth.verifyIdToken(token).catch(console.log);
  console.log(decoded.uid, decoded.email);
})();
```

IDとしては、 uid を用いるのがよい。

# 補足
クライアント側のコードを書くのがめんどくさい場合は、[firebase/firebaseui-web](https://github.com/firebase/firebaseui-web) が使える。[デモサイト](https://fir-ui-demo-84a6c.firebaseapp.com/) がある。

無料枠: https://firebase.google.com/pricing/ つまりは無制限ってことでいいのかな。
LINE SDKをさくらのレンタルサーバーに入れてみる。

#備忘録

さくらのレンタルサーバーにLINESDKをいれました。

参考ページ
[さくらのレンタルサーバーにSSHする](https://help.sakura.ad.jp/hc/ja/articles/206054152-SSH-%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6)
[さくらのレンタルサーバーでcomposerめも](https://qiita.com/tonosamart/items/e1d7ee95bf1b2a4532ff)

参考ページを参照してSSHでログインしてComposerを入れる。

```
$usr/local/bin/composer.phar require linecorp/line-bot-sdk
```

これをやるとしばらく待ってからごにょごにょ言って、Generating autoload filesと出れば完了

```
$ls vendor/
autoload.php    composer        linecorp
```

linecorpがいれば完了です。
まだ実際にSDKを使用していないので、入れるだけ入れたところです。
Bootstrapを使ったvue.jsのフォームバリデーション

# はじめに

vue.jsを勉強し始めたばかりですが、動くものを作っているとやはり見た目は綺麗にしておきたいと思い、Bootstrapを入れてみました。今回はフォームバリデーション周りを扱ってみたいと思います。

### バージョン
- Bootstrap(4.0.0)
- vue.js(2.4.2)

# Bootstrapのリンク
まず、htmlにリンクを記載する。

```html
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js"></script>
```

# サンプル

```vue
<form :class="[ 'mx-auto' , { 'was-validated' : !isFormValid } ]"  id="mainForm">
      <input type="email"  v-model.trim="mail" class="form-control" id="mailInput" name="mail">
      <input id="submit" type="button" name="submit" value="作成" v-on:click="addTodo" class="btn btn-primary btn-block" :disabled=isNoInput>
</form>
<script>
export default {
  data () {
    return {
      isFormValid: true
    }
  },
  methods: {
    addTodo: function () {
      const formho = document.getElementById('mainForm')

      if (!formho.checkValidity()) {
        this.isFormValid = false
      } else {
        this.isFormValid = true
      }
    }
  }
}
</script>
```


# バリデーションエラー時に\<form>タグに'was-validated'クラスを挿入
###vueのv−bindを使って'was-validated'クラスを動的に設定

```vue
<form :class="[ 'mx-auto' , { 'was-validated' : !isFormValid } ]"  style="width: 300px;" id="mainForm">
```
ここに記載しているisFormValidはフォームのsubmit後のバリデーション結果を返すようにしています。

上記のaddTodoメソッドは以下のsubmitボタンで起動するようにしています。

```vue
<input type="button" value="作成" v-on:click="addTodo" class="btn" >
```

###'was-validated'クラスの役割

'was-validated'はBootstrapのクラスで、バリデーションチェックでエラーがあった際に\<form>タグに設定すると、バリデーションエラーとなった\<input>の枠の色を赤く、エラーがない箇所は緑色にします。
ここでのポイントは、**\<input>タグにclassを追加するにではなく、\<form>タグに追加する**ことです。なぜかというと、Bootstrapの内部cssは以下のように、子孫セレクタで指定しているからです。

```css
.was-validated .form-control:invalid {
　　　　　　　　border-color: #dc3545;
}
.was-validated .form-control:valid {
　　　　　　　　border-color: #28a745;
}
```

###HTML５のバリデーション
バリデーションに失敗した\<input>タグには擬似クラスである:invalidが付与されます。成功した場合は:validが付与されます。この擬似クラスを元に、Bootstrapは\<input>の枠の色をつけています。
Linuxでの大きなサイズのランダムデータ生成　補足:Base64

テストとかで個人的にはよく使うランダムデータとbase64、その度に調べるのもなんなので残しておきます。

##ランダムデータ生成

`/dev/urandom`というデバイスファイルがランダムデータを吐き出してくれます。

なので、

```
head -c 2m /dev/urandom > tmp.dat
```
とやるとランダムのバイナリデータが吐き出されます。上記だと2Mbyteになります。

文字列にしたいならこんな感じでbase64エンコーディングするとよいです。

```
head -c 2m /dev/urandom | base64 | tr -d "\n">> tmp.txt
```
`base64`は入力値をデータを印字可能な英数字に変更する(Base64エンコード)為のコマンド。
その後ろの`tr -d "\n"`は改行削除です。

エンコード後はサイズが約4/3倍になるのでご注意ください。

##補足: Base64エンコード

`Base64`は上記でも記載した通り、入力値をデータを印字可能な英数字に変更する為のエンコード方式です。
可逆(デコードすると全く同じデータに戻せる)なので、ネットワーク通信でのメッセージ定義や、今回のようにバイナリデータを文字にして扱いたいなんてケースで見かけることがあります。
大体の言語で標準的に使えるので、ふとしたバイナリデータでの保存めんどくさい！みたいなケースでの利用は割と便利だったりします。

Linuxなら以下のような感じ

```:エンコード
$ echo "test" | base64
dGVzdAo=
```

```:デコード
$echo "dGVzdAo=" | base64 -d
test
```

Wikipediaより、以下のような仕組みとなっています。

>Base64変換の手順を以下に挙げる。
>1. 元データを6ビットずつに分割。（6ビットに満たない分は0を追加して6ビットにする）
>2. 各6ビットの値を変換表を使って4文字ずつ変換。（4文字に満たない分は = 記号を追加して4文字にする）

6bit <=> 4文字に変換するので、エンコード後のデータサイズは約4/3倍です。(最後に=埋めされる分、ピッタリ4/3倍にはならないです。)

変換表も定まっています。興味のある方はwikipediaを参照ください。

参考:
https://ja.wikipedia.org/wiki/Base64
Batファイルとして Node.js の JavaScript ファイルを動かす方法

# 対象

Windows
Batファイルのように Node.js のJS を動かしたい方

# はじめに

Windows には WSH(Windows Scripting Host) の JScript という JavaScript があって、拡張子 .js として保存したファイルをダブルクリックで動かせて便利なのです。

が、弱点がありまして、
かなり古い JavaScript だって所です。
最近のフロントエンド開発者や、node.js 系の開発者からすると、WSHなんて使えねーよ。と鼻で笑われてしまうかもしれません。

なので、WSH JScript は捨てて、代替として　Batファイルに Node.js の JavaScript を組み込みました。

これで Windows Bat を Node.js JavaScript で置き換えていくことでBat系開発の効率がアップするでしょう。BatファイルなのでエクスプローラなどのGUIからも呼び出しやすくて、Node.js プログラムとGUIとの連携も便利です。

Windows 版の Node.js はインストールしておいてください。

# Batファイル内に Node.js JavaScript を組み込む

実例として、次のファイルを、`C:\temp\test\nodeInBat\` ここに配置しました。

~~~js:nodeInBat.bat
//&cls&node %0 %1&pause > nul&exit

var child_process = require('child_process');

function cmdRun(command) {
  return child_process.execSync(command).toString();
}

function cmdOut(command){
	result = cmdRun(command);
	console.log("> " + command + "\n => " + result);
  return result;
}

cmdOut( "echo test" );

ret = cmdOut( "node -v" );

console.log( "nodejsバージョン:" + ret.match( /[0-9\.]+/ )[0]);
console.log("");
console.log("引数:"+ process.argv);

var i = 0;
process.argv.toString().split(',').forEach(function(element) {
  i += 1;
  console.log(i.toString() + ' ' + element);
});
~~~

Batファイルを実行すると、コマンドプロンプトが表示されて、次の通りの出力結果になります。

~~~
> echo test
 => test

> node -v
 => v9.10.1

nodejsバージョン:9.10.1

引数:C:\Program Files\nodejs\node.exe,C:\temp\test\nodeInBat\nodeInBat.bat
1 C:\Program Files\nodejs\node.exe
2 C:\temp\test\nodeInBat\nodeInBat.bat
~~~

Batファイルに test.txt というファイルをドラッグ＆ドロップで引数を渡した場合の出力結果は次の通り。

~~~
> echo test
 => test

> node -v
 => v9.10.1

nodejsバージョン:9.10.1

引数:C:\Program Files\nodejs\node.exe,C:\temp\test\nodeInBat\nodeInBat.bat,C:\temp\test\nodeInBat\test.txt
1 C:\Program Files\nodejs\node.exe
2 C:\temp\test\nodeInBat\nodeInBat.bat
3 C:\temp\test\nodeInBat\test.txt
~~~

引数を受け取ることができることも確認できました。

# Batファイル先頭行の仕組み

nodeInBat.bat の先頭行の Bat ファイルの記載を説明しておきます。

この先頭行です。

~~~
//&cls&node %0 %1&pause > nul&exit
~~~

* //

これは JavaScript ではコメントアウトですが、Batファイルでは無意味なコマンドです。Batファイルで通常この行だと、

~~~
'//' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。
~~~
このように出力されます。が、次に続くコマンド

* &cls

こちらで、出力はクリアされるので見えなくなります。

* &node %0 %1

ここで node コマンドを呼び出していて %0 はこのファイル自身、%1 はBatに渡される引数を示します。
node コマンドに、自分自身のファイルを渡しているので、このファイルの JavaScript コードが実行されるわけです。

* &pause

このコマンドでは、動作をとめます。

* > nul

空ファイルに出力します。これを行わないと、pause コマンドで待機していることを示す

~~~
続行するには何かキーを押してください . . .
~~~
というメッセージが出てしまうので、これを消すためです。

* exit

ここで、Batファイルとしての処理を終了しています。
こうすることで、この Node.js を内包した Batファイルの JavaScript 部分のコードが
Batファイルとして認識されてエラーになるのを防いでいます。

# 応用

先頭行から、pause と > null を除外して次のようにすると、コマンドプロンプトの表示は動作後すぐに消えます。

~~~
//&cls&node %0 %1&exit
~~~

出力結果を表示しなくてもよいようなBatプログラムの場合はこのようにしてください。


また、引数をもっとたくさん受け取りたい場合は次のようにして、%数値 を増やします。

~~~
//&cls&node %0 %1 %2 %3 %4&pause > nul&exit
~~~


# 参考

WindowsのバッチをNode.jsで書く雛形
https://gist.github.com/mofukuma/8f0db9624d7c34824298

こちらのコードで学ぶことができました。
感謝感謝です。
CakePHP3でリレーション先のモデルのカラムを取得条件に指定

`matching`メソッドを使う
`Emails.email`を条件に`Users`を取得。

```php
// メール送信対象のユーザー一覧取得
$sleepUsers = $this->find('all', [
     'conditions' => [
          'Users.delete_flag' => 0
      ]
])->matching('Emails', function ($q) {
      return $q->where([
           'Emails.email' => $email,
      ]);
})->toArray();
```
Qiitaの使い方 II

# ここで色々まとめられているよ

* [Markdown記法 チートシート](https://qiita.com/Qiita/items/c686397e4a0f4f11683d)
* [Qiitaが教えてくれない記述方法](https://qiita.com/consolesoup/items/37241ee79501523fb49e)
* [Qiitaでシンタックスハイライト可能な言語一覧](https://qiita.com/Qiita/items/e84f5aad7757afce82ba)
* [Qiitaのシンタックスハイライト覚書](https://qiita.com/vmmhypervisor/items/00dfc1117aa3a14940a6)

# HTMLも記述できるよ

例えば<font color="#ff0000"> **文字の色** </font>を変えたりとか

```html
例えば<font color="#ff0000"> **文字の色** </font>を変えたりとか
```
例えば[リンク](https://qiita.com/glaciesworkspace/items/83de60fadaff2ec156ea "ここにピョコって出てくるアレの事ですよ")にタイトルつけたいとか

```html
例えば[リンク](https://qiita.com/glaciesworkspace/items/83de60fadaff2ec156ea "ここにピョコって出てくるアレの事ですよ")にタイトルつけたいとか
```

ていうか https://www.google.co.jp/ ってURL書くだけでスッとリンクされるっぽい。

別窓で出したい時はやっぱりHTMLで書かなきゃダメっぽいね。
<a href="https://www.google.co.jp/" target="_blank">グーグル</a>

```html
<a href="https://www.google.co.jp/" target="_blank">グーグル</a>
```

# 絵文字つけられる。ただ使うかなこれ・・・

[絵文字チートシート](https://www.webpagefx.com/tools/emoji-cheat-sheet/)

:pencil: メモ
:paperclip: クリップ。添付してますよ的な
:exclamation: びっくりマーク
:question: クエスチョンマーク
:e-mail: メール

```
:pencil: メモ
:paperclip: クリップ。添付してますよ的な
:exclamation: びっくりマーク
:question: クエスチョンマーク
:e-mail: メール
```

# コード貼り付けるあれこれ

* ソースコードをクリップボードにコピペ
* 半角で`（バッククォート。「＠」をShiftキー押しながら入力）を3回＋言語指定
* C#(cs), C++(cpp), css, html, xml, java, javascript, php, perl, python, ruby, sql など
* 半角で`を3回＋ファイル名指定で頭にファイル名が表示
* 最後`を3回

```hello.cs
sing System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class print : MonoBehaviour {
 
    // Use this for initialization
    void Start () {
        //単純にコンソールで文字を表示させるだけ
        print("ハローワールド");
    }
 
// Update is called once per frame
    void Update () {        
    }
}
```