OmniAICreator/Qiita-1.07M huggingface dataset:
NokogiriでHTMLを生成するメモ

パースするだけがNokogiriじゃない。　

ちょっとしたhtmlを生成するのに、ERBみたいなテンプレートエンジン使うのも面倒だ。
そんなときにNokogiriを使うといい感じに書けます。

とはいえいつも使い方を忘れるのでメモ。

# 例
## NokogiriでHTMLを生成するスクリプト
```rb
require 'nokogiri'

l = %w(foo bar baz)

root = Nokogiri::HTML::DocumentFragment.parse("")
Nokogiri::HTML::Builder.with(root) do |doc|
  doc.div.nav.index do
    doc.h1 "LIST"
    doc.ul do
      l.each.with_index do |x, i|
        doc.li x, class: "item-list", id: i
      end
    end
    
    doc.br # これだと<br>になる
    doc << "<br />" # ノードを挿入する場合
    doc.text "<br />\n" # テキストノードとして挿入する場合(自動的にエスケープされる)
  end
end

puts root.to_html
```

## 生成されたHTML

```html
<div class="nav index">
<h1>LIST</h1>
<ul>
<li class="item-list" id="0">foo</li>
<li class="item-list" id="1">bar</li>
<li class="item-list" id="2">baz</li>
</ul>
<br><br>&lt;br /&gt;
</div>
```

# 覚書
- doc.*タグ名*\[.*クラス名*\. ...]([*テキスト*][, 属性]){ 入れ子 }
- タグ名をメソッドとして呼び出す。入れ子はブロックの中で記述する。
- 動的にタグ名を変える場合はsendとか使う。
- 属性は {*attr*: *value*[, ...]} の形。
- classはメソッドチェインでの指定も可能(複数OK)
- テキストノードはメソッドの第1引数に渡すか、 doc.text で追加する。
- 既に作ってあるノードを挿入する場合は doc<<
- 閉じタグ付きの改行`<br />`を挿入しても閉じタグ外れるらしい。


# おまけ：ヒアドキュメントでなんとかした例
Rubyのヒアドキュメントは便利なのではじめはこうやろうとしました。

```rb
l = %w(foo bar baz)

html = <<HTML1 + l.map.with_index{|x,i| <<HTML2 % [i, x]}.join + <<HTML3
<div class="nav index">
  <h1>LIST</h1>
  <ul>
HTML1
    <li class="item-list" id="%s">%s</li>
HTML2
  </ul>
</div>
HTML3

puts html
```

```html
<div class="nav index">
  <h1>LIST</h1>
  <ul>
    <li class="item-list" id="0">foo</li>
    <li class="item-list" id="1">bar</li>
    <li class="item-list" id="2">baz</li>
  </ul>
</div>
```

このあと滅茶苦茶ノコギリした。
Lenovo X1 Carbon (4th gen)にManjaroをインストールする。

#1 インストール用USBからのブート
##1.1 起動時の注意点
※ブートシーケンスの順序変更やSecureブートオフなどの部分は割愛。
USBからブートをしようとしてもデフォルトのままで起動しようとすると、うんともすんとも言わず、固まってしまう。
ポイントは起動する際、キーボードのeを押して、カーネルコマンドの編集モードに入り、下記を追記する。

> intel_pstate=disable

これでとりあえずインストール用OSが起動してくる。

あとはGUIベースでインストールするなり、テキストモードでインストールするなり、おまかせでほぼOK。

##1.2 パーティション設定時の注意点
上でおまかせでほぼOKと書いてしまったが、何も考えずにインストールして再起動してみたら、ブートローダが起動してこなかった。
BIOS/MBRではだめで、UEFI/GPTでインストールするとうまくいった。

※ここまで参考URLの事象と同じだった。とても参考になる解説だった。

#2 インストール後の注意点
##2.1 カーネルコマンドラインの追記を忘れずに
インストール完了後、再起動するタイミングでも忘れずに、

> intel_pstate=disable

これをつけて起動すること。
そして、無事に起動したあとは、terminalを起動して、

> \# vim /etc/default/grub
`GRUB_CMDLINE_LINUX="intel_pstate=disable net.ifnames=0"`
※net.ifnames=0はeth0とかの名前にするための設定
>\#grub-mkconfig -o /boot/grub/grub.cfg 

これでOK。

#3 その後の不具合について
- 起動中にフリーズ　( kernel 4.4, 4.5で確認 )してしまう
> kernel 4.6 に変更することで安定化（したと思われる）

その他細かい設定はひとまず置いといて、インストール時の注意点でした。

参考：
http://sakura-education.com/myblog/archives/780
r3.largeでswap領域としてエフェメラルディスクをマウントする

◆実施したいこと
・r3.largeで新規にAmazon Linux(ami-6154bb00)を構築
・EC2を再起動しようが停止しようがインスタンスストアを
　恒久的にswap領域として利用したい

◆手順
①インスタンスストアボリュームのデバイス名を確認
　# lsblk -p

　例えば、以下のようなコマンド出力結果の場合、
　# lsblk -p
　NAME         MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
　/dev/xvda    202:0    0   8G  0 disk
　└─/dev/xvda1 202:1    0   8G  0 part /
　/dev/xvdb    202:16   0  30G  0 disk

　上記のケースでは /dev/xvdb が対象となる。
　MOUNTPOINT が / のボリュームではない方を対象にすること。

②インスタンスストアボリュームのアンマウント
　# umount /dev/(①で確認したボリューム)

③デバイスに Linux スワップ領域をセットアップ
　# mkswap /dev/(①で確認したボリューム)

④新しいスワップ空間を有効
　# swapon /dev/(①で確認したボリューム)

⑤新しいスワップ空間が使用されていることを確認
　# swapon -s

⑥システム起動毎にスワップ空間を自動的に有効化
　# vi /etc/fstab
　(下記内容を追加)
　/dev/(①で確認したボリューム)       none    swap    sw  0       0
　→既に/dev/xvdb/media/ephemeral0autodefaults,nofail,comment=cloudconfig02
　　という記載がある場合、その項目を削除して置き換える。

　　(公式ドキュメント抜粋)
　　======
　　/etc/fstab ファイルに /dev/xvdb（または /dev/sdb）用の項目がある場合は、
　　それを以下の行に合わせて変更。
　　このデバイス用の項目がない場合は、/etc/fstab ファイルに
　　以下の行を追加（システムのスワップデバイス名を使用）。
　　http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/instance-store-swap-volumes.html
　　======

⑦/etc/cloud/cloud.cfg の設定を修正
　# vi /etc/cloud/cloud.cfg

　＜修正前(例)＞
　---
　mounts:
　- [ ephemeral0, /media/ephemeral0 ]
　- [ swap, none, swap, sw, "0", "0" ]
　---
　＜修正後(例)＞
　---
　mounts:
　 - [ ephemeral0, swap, swap ,"defaults", "0", "0"]
　---
　※注意：mounts: の次の行の先頭のハイフンの前に半角スペースが必要。

⑧swapの有効化のため、/etc/rc.local の編集
　# vi /etc/rc.local

　末尾に以下を追加(---は回答上の区切り文字のため、実ファイルには反映しないこと)
　---
　mkswap /dev/xvdb
　swapon -a
　---
　※ /dev/xvdb は手順①で確認したボリュームを記載すること。

⑨インスタンスを再起動して、swap が設定されているか確認
　# lsblk -p
　NAME         MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
　/dev/xvda    202:0    0   8G  0 disk 
　mq/dev/xvda1 202:1    0   8G  0 part /
　/dev/xvdb    202:16   0   4G  0 disk
Pepperでios風のデータピッカーを表示したい。


#前書き
Pepperのタブレット上で、ios風のデータピッカーを表示して欲しいと話がありいろいろと試行錯誤してみたのですが、うまく行かず、どなたかの知識が借りられればと思っての投稿です。

#開発環境
機種名 : MacBook Pro
OS : Yosemite 10.11.5
プロセッサ名 : Intel Core i5 2.6 GHz
メモリ : 16 GB
グラフィック : Intel Iris 1536MB
Choreographe : 2.4.3.28

#本題
##案1
セレクトBOXを使ってうまい具合にする。
###結果
選択肢がすごく小さく表示されてしまい、思ったような感じにならなかった。

##案2
テキストの上下にボタンを置いてダイアル錠のような感じに作る

###結果
ios風のデータピッカーではない

##案3
外部ライブラリを使う

###結果
http://jsdo.it/omatoro/1gI6

こちらを活用させてもらおうと思ったのだが、一ページに複数のデータピッカーを並べることが難しく、想定しているデザインにいまいちマッチしない。

#感想
何かいい案ある方いらっしゃいますか？

#関連URL
http://jsdo.it/omatoro/1gI6
C言語でRubyのeachっぽいものを書いてみる

備忘録。
この手の記事は多いみたいだけれど、自分でも作成してみた。

```each_sample.c
#include <stdio.h>

#define ARRAYSIZE(array) (sizeof(array)/sizeof(array[0]))
#define EACH(array,type,obj) for(type* obj=array;obj<=&array[ARRAYSIZE(array)-1];obj++)

long array[10];

int main()
{
    array[0] = 0;
    array[1] = 1;
    array[2] = 2;
    array[3] = 3;
    array[4] = 4;
    
    EACH(array,long,obj)
    {
        printf("%d\n", *obj);
    }
}
```

しっかりと作りこんであるのは、
[ココ](http://qiita.com/matyapiro31/items/ec4cb3a63d52cf2045a9) とか、
[ここ](http://d.hatena.ne.jp/ekrea/20130620/1371742962) にあり。
C#におけるasによるキャストと()によるキャストの違い

# 概要
asによるキャストと()によるキャストを

* キャストできないときの処理
* 使用できる型
* 処理速度

という観点でみていきます。


# 本題
## キャストとは
* キャストとは、ある型を指定した別の型に変換することを言います。
* アップキャストとダウンキャストがあります。

### アップキャスト
* 派生クラスから基底クラスへの型変換です。
* 暗黙的な型変換が行われます。

```object obj = new Person();```

### ダウンキャスト 
* 基底クラスから派生クラスへの型変換です。
* 暗黙的な型変換は行われません。

```Person p = (Person)obj;```

ダウンキャストの場合、継承関係のない型同士の変換ではコンパイルは通りますが、実行時に例外が発生してしまいます。

## キャストできないときの処理
* asによるキャスト: ```null```を返します。
* ()によるキャスト: ```System.InvalidCastException```という例外を投げます。

```csharp

using System;

class CastSample{
    public static void Main() {

        object nyanchu = "nyanchu"

        CastSample cs1 = nyanchu as CastSample
        Console.WriteLine(cs1 == null); // True

        try 
        {
            CastSample cs2 = (CastSample)nyanchu;
        } 
        catch(InvalidCastException e)
        {
            Console.WriteLine(e.ToString());  // System.InvalidCastException: 指定されたキャストは有効ではありません。 at CastSample.Main()      
        }
    }
}


```

## 使用できる型
* asによるキャスト: 参照型への変換のみ行うことができます。
* ()によるキャスト: 値型・参照型問わず使用できます。

```csharp

// OK
int i = (int)1;

// NG
int i = 1 as int;
// コンパイル時に
// 「as オペレータは参照型で使用してください ( 'int' は値の型です )。」

```

### 参照型と値型
* 値型
 * 変数を宣言すると、値そのものが格納される領域が用意されます。
 * メソッドの引数に渡される場合は値の複製が作られ、その複製が渡されます。
 * 代入するときは代入先の変数領域に値が複製されます。
 * 継承ができません。
 * string、配列、クラス等

* 参照型
 * 変数を宣言すると、オブジェクトへの参照が格納される領域が用意されます。
 * メソッドの引数に渡される場合はインスタンスへの参照が渡されます。
 * 代入するときはインスタンスの参照が代入されます。
 * 原則として継承できます。
 * byte、int、long、double、decimal、char、bool、構造体等

## 処理速度
* ()によるキャストよりもasによるキャストの方が高速。
* 例外処理を考慮し、isで型チェックを行ってもなおasによるキャストの方が高速。

（ということが[この記事](http://www.atmarkit.co.jp/ait/articles/0304/04/news004.html)を読むとわかります！）


### is演算子
* あるオブジェクトが指定された型と互換性があるかをチェックしてboolを返してくれます。

```csharp
object obj = new Nyanchu();
bool b1 = obj is Nyanchu; // True
bool b2 = obj is object; // True
bool b3 = obj is Oneisan; // False
// ※ NyanchuとOneisanに継承関係がない場合

```


# 参考
* [as演算子とキャストの違いは？](http://www.atmarkit.co.jp/ait/articles/0304/04/news004.html)
* [『C#プログラミング入門』](https://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E5%85%A5%E9%96%80%E2%80%95%E3%80%8C%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91%E3%80%8D%E3%81%AE%E3%80%8C%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E6%89%8B%E6%B3%95%E3%80%8D%E3%82%92%E5%9F%BA%E7%A4%8E%E3%81%8B%E3%82%89%E8%A7%A3%E8%AA%AC-I%E3%83%BBO-BOOKS-%E5%87%BA%E4%BA%95-%E7%A7%80%E8%A1%8C/dp/4777515982/ref=sr_1_2?ie=UTF8&qid=1466349829&sr=8-2&keywords=C%23%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E5%85%A5%E9%96%80)
* [【C#】いろんな型変換（キャスト）Convert vs Parse vs ToString](http://kuroeveryday.blogspot.jp/2014/04/convert-vs-parse-vs-tostring.html)
Node.js：JSONデータをPOSTする

※「≈≈≈」は省略を表す

# バージョン

```console
$ node -v
v6.2.1
```
```console
$ cat package.json
{
  ≈≈≈
  "dependencies": {
    "request": "~2.72.0",
  }
}
```

# POSTでJSONデータを送信する
```js
var request = require('request');
var options = {
  uri: "http://example.com/test",
  headers: {
    "Content-type": "application/json",
  },
  json: {
    "key1": "param1",
    "key2": "param2"
  }
};
request.post(options, function(error, response, body){});
```

# おまけ：POSTでパラメータを送信する(いわゆるフツーのPOST)(未検証)

```js
var request = require('request');
var options = {
  uri: "http://example.com/test",
  headers: {
    "Content-type": "application/x-www-form-urlencoded",
  },
  form: {
    "key1": "param1",
    "key2": "param2"
  }
};
request.post(options, function(error, response, body){});
```
nimプロセス実行

# 概要
nimのプロセス実行操作をコツコツと。
## 以下メモ
### プロセス実行
```nim
import osproc,streams,times
proc `$`(t:TimeInfo) : string = format(t, "yyyy/MM/dd HH:mm:ss ")
block:
  var p: Process
  defer:
    p.close
  # プロセス実行
  p = startProcess("/usr/bin/ping","",@["-c","5","127.0.0.1"])
  echo p.processID
  # 標準出力を取得し、コンソールに表示
  let outstr = p.outputStream
  var line:string = ""
  # ストリームから１行ずつフェッチ
  while outstr.readLine(line):
    # 現在時刻を取得
    let now: TimeInfo = getLocalTime(getTime())
    echo now,line
  # 終了待機
  echo p.waitForExit()
```
```
(stdout)
10256
2016/06/23 00:24:59 PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
2016/06/23 00:24:59 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.050 ms
2016/06/23 00:25:00 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.043 ms
2016/06/23 00:25:01 64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.044 ms
2016/06/23 00:25:02 64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.051 ms
2016/06/23 00:25:03 64 bytes from 127.0.0.1: icmp_seq=5 ttl=64 time=0.047 ms
2016/06/23 00:25:03
2016/06/23 00:25:03 --- 127.0.0.1 ping statistics ---
2016/06/23 00:25:03 5 packets transmitted, 5 received, 0% packet loss, time 3999ms
2016/06/23 00:25:03 rtt min/avg/max/mdev = 0.043/0.047/0.051/0.003 ms
0
```
シェルスクリプトで距離行列を内積の値に変換

距離行列が与えられている時に、その行列を内積の値に変換する。

そもそも距離行列とは

  a b c d e
a 0,4,6,4,4
b 4,0,5,3,3
c 6,5,0,3,1
d 4,3,3,0,3
e 4,3,1,3,0

というような形で与えられ、上の例ではa~eのお互いの距離が記された行列である。

この距離行列が用いられる場面では、ここから多次元尺度構成法などで、二次元にプロットなどが行われる。実際にプロットを行うためには、この距離行列を内積の値に変換し、固有ベクトルを求めることで座標を得る必要があるが、シェルスクリプトで内積の値への変換を行ってみる。


内積への変換は、まず、距離行列のそれぞれの成分を2乗して2で割ったものをそれぞれの成分に置き換え、それを新たな距離行列とし、距離行列の名前をmatrix、各行の平均をそれぞれ、ave_1,ave_2,ave_3....、matrix全ての値の平均をall_ave、matrixの成分をmatrix[1,2]などとした時に、各行列の成分を以下のように変換することでなされる。
なお、以下の "=" は代入

```matrix[x,y]=ave_x + ave_y - all_ave - matrix[x,y]```

標準入力として、以下のようなカンマ区切りの行列を想定して、内積値への変換スクリプトを書いてみる。
0,4,6,4,4
4,0,5,3,3
6,5,0,3,1
4,3,3,0,3
4,3,1,3,0

```change.sh
#!/bin/bash
#標準入力を変数へ
data=$(cat -)
#全値の平均を変数へ、各行の平均を配列へ
all=$(echo "$data" | tr ',' '\n' | awk '{sum+=$1*$1/2}END{print sum/NR}')
temp=$(echo "$data" | awk -F, '{sum=0;for(i=1;i<=NF;i++){sum+=$i*$i/2};print sum/NF}' | sed '/^$/d' | grep -n ".")
#上記の値を用いてデータを変更
row=1
col=1
echo "$data" |
while read line_1;do
  echo "$line_1" |
  tr ',' '\n' |
  sed '/^$/d' |
  while read line_2;do
    m1=$(echo "$temp" | awk -F : -v num="$row" '$1==num{print $2}')
    m2=$(echo "$temp" | awk -F : -v num="$col" '$1==num{print $2}')
    val=$(echo "$m1 + $m2 - $all - ${line_2} * ${line_2} / 2" | bc)
    echo "$val"
    col=$(($col + 1))
  done | tr '\n' ','
  echo ""
  row=$(($row + 1))
done | sed 's/,$//g' | sed -e 's/-\./-0\./g' -e 's/^\./0\./g' -e 's/,\./,0\./g'
```
シェルスクリプトでやる意味があるのか？（無いと思う）
そもそもこのシェルスクリプト、無駄が多くね？（かなり適当に書いてる）
awkで計算ってことはでかい数字だと計算ズレね？（だよねー！）
Django で認証されたページでテストする方法


Djangoはテストもわりと簡単に出来るんですが、今回認証が必要なページで単純なアクセステストをしたらハマったので書いておきます。

```py3:test.py
from django.test import TestCase, RequestFactory
from django.contrib.auth.models import User

from .views import SomeGenericView


class TestSomeView(TestCase):
    def test_some_auth_page(self):
        user = User.objects.create_user(...)  # ログインユーザー作成
        rf = RequestFactory()
        request = rf.get("/some/auth/page")
        request.user = user
        res = SomeGenericView.as_view()(request)
        
        self.assertEqual(res.status_code, 200)

```

`RequestFactory()`でリクエストオブジェクトを生成して、それに認証したいユーザーを突っ込む的なやり方でした。

ドキュメントはこちら
[Advanced testing topics | Django documentation | Django](https://docs.djangoproject.com/en/1.9/topics/testing/advanced/#example)

もうちょっとやりやすいやり方はないのだろうか・・・

ちなみに、POSTしたいときは、

```py3:test_post.py
class TestSomeView2(TestCase):
    def test_some_auth_page_post(self):
        user = ...  # 同上
        
        rf = RequestFactory()
        req = rf.post("/some/post/url", data={"edit": "value"})  # ここだけ違う
        req.user = user  # ユーザーを突っ込む
        res = SomeGenericView.as_view()(req)
        
        self.assertEqual(res.status_code, 302)
```

で行けそうです。
Ubuntu Mate 16.04 LTS on Raspberry Pi3 が 重い件 の 対処

# Ubuntu Mate 16.04LTS on Raspberry Pi3

で、以下のように、brlttyがSECCOMPでひっかかって落ちまくる件。
意外に重いので、なんとかする。
(brlttyは、accesibilityのserviceだが、落ちていてどうせ動いていない。)

```
Jun 22 00:15:14 oreserver systemd[1]: Started Braille Device Support.
Jun 22 00:15:14 oreserver systemd[1570]: brltty.service: Failed at step SECCOMP spawning /bin/sh: Invalid argument
Jun 22 00:15:14 oreserver systemd[1]: brltty.service: Main process exited, code=exited, status=228/SECCOMP
Jun 22 00:15:14 oreserver systemd[1]: brltty.service: Unit entered failed state.
Jun 22 00:15:14 oreserver systemd[1]: brltty.service: Failed with result 'exit-code'.
```

```
$ sudo apt-get remove --purge brltty
```
しようとすると、ubuntu-mate-desktopやcoreまで削除しようとする。うそん。。。

というわけで、どうせ落ちていて動かないんだし、強制的に殺す。

```
$ dpkg --purge --force-depends brltty
```

消せた。
そして、/var/log/syslogから上のメッセージはなくなった。

sshでのコンソールの動きまで早くなった！
iPhoneのピッカーを作りたい

# iPhone風ののピッカーを作りたい

アンドロイド等のタブレットでもiPhone風のセレクトボックスを作りたいと考えています。
http://jsdo.it/omatoro/1gI6

上記のライブラリを使って、動くように実装してみました。
セレクトボックスを開きを選択後し、その後もう一度セレクトボックスを
開いた場合に1度目に選択した値に青いチェックがつけたままにしたいのですが、
どのように、実装すればよいでしょうか？
Macのキーボードで｀（バッククォート）の入力

#環境
MacOSX El Capitan 10.11.5 USキーボード

#入力
Option + チルダーキー（~）

#用途
Markdownでインライン表示させるときとか。
なんかたまにOption忘れて、「あれ？打てない？？？」ってなるから書いた。
ubuntuで日本語入力を行う

#環境
Ubuntu16.04

#Mozcのインストール
ibus-mozcを入れる
`$sudo apt-get install ibus-mozc`
ibusを再起動
`$killall ibus-daemon`
`$ibus-daemon -d -x &`

#テキスト入力設定
ubuntuの 「設定」>「テキスト入力」の使用する入力ソースに「日本語(Mozc)(iBus)」を追加し、
「日本語(Mozc)(iBus)」、「日本語」の順にする。

次のソースへ切り替えのところで半角/全角キーを押して「Zenkaku Hankaku」になるようにする。

#Mozcの入力モード
全角/半角キーを押しても英語のままの場合、画面右上の「Mozc」のアイコンをクリックして入力モードで「ひらがな」に切り替える。
Zipkin＆Springメモ（下書き中）


SpringIO報告会で面白そうだったのでメモメモ。
試した結果とかは後ほど追加。

# Zipkin

http://zipkin.io/

```bash
wget -O zipkin.jar 'https://search.maven.org/remote_content?g=io.zipkin.java&a=zipkin-server&v=LATEST&c=exec'
java -jar zipkin.jar
```

# Spring Cloud Sleuth

https://cloud.spring.io/spring-cloud-sleuth/

乱暴に要約するとSpringでログを勝手に出してくれる。
Zipkinとの連携も標準である。
dependencyに追加するだけで使用可能。
英語が苦手なのでWWDCのセッション動画を日本語字幕で見る


# TL;DR
WWDCの動画見るときは、YouTubeに(非公開で)アップロードすると、自動的に英語字幕を付けてくれます。
字幕はGoogle翻訳を通して日本語も表示することができます。

https://support.google.com/youtube/answer/6373554?hl=ja
> YouTube の音声認識技術を利用して自動的に動画の字幕を作成することもできます。ただし、こうした字幕は機械学習アルゴリズムによって自動生成されたものなので、品質にばらつきが出る可能性があります。


# 方法
## セッションの動画をダウンロード
WWDCの動画はすべて公開されていて、ダウンロード可能です。
https://developer.apple.com/videos/wwdc2016/

## YouTubeに非公開でアップロードする
**非公開**でアップロードします。
![スクリーンショット_2016-06-22_22_40_37.png](https://qiita-image-store.s3.amazonaws.com/0/11454/2bb31ede-2713-7084-2253-fd46701f6712.png "スクリーンショット_2016-06-22_22_40_37.png")

※動画ファイルが大きい場合、アカウントをSMSや電話を使って認証させる必要があります。

## 動画の設定を変更する
アップロード完了後、字幕を表示するために設定を変更します。
### クリエイターツールを開く
ページ右上の自分のアカウント → クリエイターツール
![スクリーンショット_2016-06-22_22_50_11.png](https://qiita-image-store.s3.amazonaws.com/0/11454/6fabf21a-33f9-5457-6d2c-b2f3ff83c09a.png "スクリーンショット_2016-06-22_22_50_11.png")

### 動画の詳細設定ページを開く
動画のサムネイル右のプルダウンメニューから「情報と設定」をクリック。
![スクリーンショット_2016-06-22_23_15_09.png](https://qiita-image-store.s3.amazonaws.com/0/11454/5194e1e4-8623-024e-7939-973f7c6f3a0b.png "スクリーンショット_2016-06-22_23_15_09.png")

### 字幕の認定
「このコンテンツは米国内のテレビで放送されたことはありません。」を選択。
![スクリーンショット 2016-06-22 23.14.22.png](https://qiita-image-store.s3.amazonaws.com/0/11454/7c91af0b-70b7-898c-3403-f23c56f97906.png "スクリーンショット 2016-06-22 23.14.22.png")

米国のテレビで放送された動画は、規制の対象だそうです。
> 米国のテレビで放送されたコンテンツは、字幕に関する FCC 規則の対象となることがあります。必要に応じてここで字幕の認定を行います。

### 動画の言語設定
「英語 (アメリカ合衆国)」に設定。英語字幕を表示するためにおそらく必要。
![スクリーンショット 2016-06-22 23.14.48.png](https://qiita-image-store.s3.amazonaws.com/0/11454/482b553e-3ec3-95b5-bab4-de68208aa74d.png "スクリーンショット 2016-06-22 23.14.48.png")

これで設定は終わり。あとは字幕の生成が完了するまで数時間待ちます。

### 字幕の生成完了
字幕が表示できるようになりました。
![スクリーンショット 2016-06-22 22.30.40.png](https://qiita-image-store.s3.amazonaws.com/0/11454/fef2309e-032e-fcb4-e9bc-7c2caea065f1.png "スクリーンショット 2016-06-22 22.30.40.png")

Google翻訳を通して日本語字幕を表示。
![スクリーンショット 2016-06-22 22.29.48.png](https://qiita-image-store.s3.amazonaws.com/0/11454/7badd0b9-6b5f-2e8c-1538-cec800b0e8b1.png "スクリーンショット 2016-06-22 22.29.48.png")

機械翻訳なので日本語のクオリティはご愛嬌。
テーマによっては英語字幕の方がわかりやすいこともあります。

# 最後に
例年通りであればWWDCの公式ページの動画でも英語の字幕が表示できます。
(この記事を書いている時点では字幕は表示されませんが、後日公開されるかと思います。)
2015年の動画では、英語と中国語の字幕が表示できます。

WWDCに限らず、海外のセッションでも動画ファイルがあれば同じ方法が使えます。

# 追記
今年のWWDCでは日本語字幕に対応する動画も出てきているようです。(keynoteの動画のキャプチャ)
<img width="811" alt="スクリーンショット 2016-06-26 10.34.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/11454/7128c748-1d63-bb3d-ee0b-b1cd87be4f81.png">
しばらく待っていればすべての動画が日本語字幕に対応するのかもしれません。

# リンク
- [WWDC 2016 Videos](https://developer.apple.com/wwdc/live/)
- [自動字幕起こし機能を使用する - YouTube ヘルプ](https://support.google.com/youtube/answer/6373554?hl=ja)
Sketchで少しだけ迷ったこと

##はじめに
Illustratorや、Fireworksでは簡単にできていたけど、
Sketchだとどうやるんだろう？と悩んだ機能についてメモしていきます。

##文字をアウトライン化する

アウトラインをかけたい文字を選択し、
ツールバーの「Type」から「Convert Text to Outlines」を選択する。

![スクリーンショット 2016-01-05 11.38.54.png](https://qiita-image-store.s3.amazonaws.com/0/11290/07ca8232-4946-d30f-32a0-f9e83a45ae18.png)

文字がアウトライン化される。

![スクリーンショット 2016-01-05 11.39.18.png](https://qiita-image-store.s3.amazonaws.com/0/11290/054e73e3-76b6-1df9-51ae-5742f6528e96.png)

##塗でグラデーションを設定する
塗でグラデーションを設定する場合はまずインスペクターメニュー（右側のプロパティ設定とかするところ）から「Fill」を選択。

![スクリーンショット 2016-01-14 16.53.16.png](https://qiita-image-store.s3.amazonaws.com/0/11290/1e80f477-bb0e-8fe9-d78d-6dd77b084881.png)

表示されるメニューの中から、「Linear Gradient」を選択。

放射状のグラデーションがかけたい場合は「Radial Gradient」
円錐を描くようなグラデーションの場合は「Angular Gradient」

![スクリーンショット 2016-01-14 16.55.40.png](https://qiita-image-store.s3.amazonaws.com/0/11290/1c79a018-8c23-c2e9-4b26-1502fad4ec1a.png)

「Linear Gradient」を選択することで、グラデーション設定用のメニューが表示される。
グラーデーションの角度を変えるには、オブジェクトに表示される、ポイントを移動させる。
(角度変更用のポイントは、Fillを選択しメニューが表示されている場合のみ表示される）

![Untitled.png](https://qiita-image-store.s3.amazonaws.com/0/11290/8329b59f-cfc4-546a-79c7-2eb5d93009fd.png)

##画像をグレースケールにする

sketchは画像のレタッチはあまり得意ではないです。
グレースケールにするには、少し工夫が必要です。

画像の上にモノトーンのシェイプを置いて、 **Blending**を **Color**にすることで、グレースケール画像に見えます。

<img width="695" alt="demo_sketch.png" src="https://qiita-image-store.s3.amazonaws.com/0/11290/14a490f5-537c-caff-009f-5fced82836d8.png">

##オブジェクトをロック、ロック解除する方法
レイヤーに``option``を押しながらフォーカスすると、南京錠マークが表示されるので、南京錠マークをクリックします。

<img width="334" alt="あ.png" src="https://qiita-image-store.s3.amazonaws.com/0/11290/2c60d712-3858-567d-560e-544c087995fc.png">

ショートカットは``command + shift + L``です。

全てのロックを解除したい場合には、全レイヤーを選択して``command + shift + L``で解除できます。
ただ全レイヤーをつかむのが面倒なので、下記のプラグインが便利です。
[Unlock all layers](https://medium.com/truth-labs/sketch-plugin-unlock-all-layers-1ff9252f0689#.deb99z7zs)

##シンボルを解除
sketchで便利なシンボル機能ですが、解除するのを少し悩みました。
解除はコンテキストメニューの「Detach from Symbol」からできます。

<img width="619" alt="Untitled.png" src="https://qiita-image-store.s3.amazonaws.com/0/11290/fa618bdd-ac10-05c4-646c-9b859963c512.png">

##シンボル便利
今回の趣旨とちょっと変わってしまいますが、モジュールを作る場合はシンボル便利です。

<img width="466" alt="Untitled.png" src="https://qiita-image-store.s3.amazonaws.com/0/11290/b8c19df5-4140-3cc2-b650-8f4fde02007b.png">

画像を塗りで指定しておくと、シンボルのインスタンス毎に写真を変更することができます。

##角丸を特定の角だけつける

**10/10/0/0** のように設定することで、特定の角のみ角丸にすることができます。

<img width="580" alt="Untitled.png" src="https://qiita-image-store.s3.amazonaws.com/0/11290/7e427166-e78e-5648-2cc7-5639e8dc039a.png">


##終わり
まだまだ使いこなしていないです。もっと便利に使えるはずなので、もっと調べたいと思います。
Ansible の unarchive で No such file or directory 

# 概要
unarchive モジュールを使う playbook を実行する際の
No such file or directory エラー対処


## playbook のエラー箇所

```
- name: copy src
  unarchive: src=hoge.tar.gz dest=/usr/local/src/
```

## エラー内容
```
fatal: [ono1]: FAILED! => {"changed": false, "failed": true, 
"msg": "Unexpected error when accessing exploded file: 
[Errno 2] そのようなファイルやディレクトリはありません: '/usr/local/src/hoge'"}
```

## 解決策（暫定対応）
environment に LANG: C, LC_ALL: C, LC_MESSAGES を追加  

```
  unarchive: src=hoge.tar.gz dest=/usr/local/src/
  environment:
    LANG: C
    LC_ALL: C
    LC_MESSAGES: C
```

## その他
アップデートで対応されているらしい？？

https://github.com/ansible/ansible-modules-core/issues/3706

自分のは 2.1.0.0 だけど直ってない場合があるのかも。

```
# ansible --version
ansible 2.1.0.0
  config file = /home/ono/ansible/ansible.cfg
  configured module search path = Default w/o overrides
```
現場改善

# 自己紹介
 - 氏名：島村友造
 - 所属：株式会社サイバード
    - クリエイティブ統括本部 PM統括部
 - 主な仕事：PM業と現場改善

---
# 本資料について
- 本年度入社した新卒に向けての「現場改善」とはナニかの説明資料となります。
- 持ち時間30分しかないので簡単な説明とワークショップでサクッと体験してもらおうと思います。

---
# Agenda
1. 現場改善とは
2. 目的
1. 活動内容
1. ワークショップ
1. 最後に

---
# 現場改善とは
- 「現場」の定義
    - 開発の現場のことを指します。
- 「改善」の定義
    -   誤りや欠陥を是正し、より良い状態にする事、行為。[^1] 
 
[^1]: https://ja.wikipedia.org/wiki/改善

---
# つまり開発現場を良い状態にする！

---
# 目的
チームを自己組織化し、メンバー自らが自律的に改善していく文化を醸成する。

---
# 活動内容

---
## ナニをやるのか
- チームの目的やミッションを明確にする。
- チームメンバーが相互理解する。
- 暗黙知を形式知（見える化）にする。
- ムダを見つけ効率化を図る。
- 改善サイクルを回し続ける。

---
## 具体的な指標
 - リードタイム
    - どれだけ早くリリースできるか
 - スループット
    - どれだけ多くリリースできるか

---
## 具体的なツールや手法
1. インセプションデッキ
- スキルマップ
- ドラッカー風エクササイズ
- タスクボード
- カンバン
- 朝会
- ふりかえり
- KPT
- バリューストリームマップ
- タイムライン
- 因果関係図
- 制約理論（TOC）
- クラウド（対立の構造の理解）
- グラフィックファシリテート

等々

---
## 具体的な成果
- 「管理画面やワークフローの改善をおこない、5~7日かかっていた開発期間を4~5日に短縮できました。」
- 「メンバーの得意なことがわかり最適なタスクの割り振りができました。」
- 「毎日の朝会でお互いのタスクと優先度を知ることができ、チームが円滑に回るようになりました。」
- 「少しづつですが改善がされて、なんとなく楽になりました。」

---
## まとめ
- チームで課題に取り組みましょう。
- ムダを無くしましょう。
- 改善し続けましょう。

---
### なにかお困りでしたら遠慮なくお声掛けください！
---

# ワークショップ

---

## コイン渡し [^2]
### 準備
1. 4人がテーブルを囲んで座ってください
1. 別の4人が各々の座っている人の後ろに立ちます。
1. 立っている人はスマホなどで時間を計測できるように準備してください。
1. 別にもう一人、全体の時間計測する人を用意してください。（9人目）
1. コイン20枚を座っている1人の前に集める。

[^2]: [カンバン仕事術 - チームではじめる見える化と改善](https://www.oreilly.co.jp/books/9784873117645/)

---
### Try.1 ルール説明
1. **20**枚すべてを裏返しして、すべて裏返したら時計回りで隣の人に渡してください。
1. 計測する人は作業し始めた所から**20**枚目を裏返して隣の人に渡し終わるまでの時間を計測してください。
1. 全体計測の人は最初のコインが完了までの時間と最後のコインが完了するまでの時間を計測してください。
1. それぞれ掛った時間を報告してください。

---
### Try.2 ルール説明
1. **５**枚すべてを裏返しして、すべて裏返したら時計回りで隣の人に渡してください。
1. 計測する人は作業し始めた所から**５**枚目を裏返して隣の人に渡し終わるまでの時間の合計を計測してください。
1. 全体計測の人は最初のコインが完了までの時間と最後のコインが完了するまでの時間を計測してください。
1. それぞれ掛った時間を報告してください。

---
### Try.3 ルール説明
1. **1**枚を裏返しして時計回りで隣の人に渡してください。
1. 計測する人は作業し始めてから隣の人に渡し終わるまでの時間の合計を計測してください。
1. 全体計測の人は最初のコインが完了するまでの時間と最後のコインが完了するまでの時間を計測してください。
1. それぞれ掛った時間を報告してください。

---
### 集計
---

## ふりかえり
- いかがでしたか？

---
## 伝えたかったこと
- チーム全体の効率（スループット）を考えましょう
- きちんと優先度つけて集中して作業しましょう
    - WIPの制限
    - 過度なマルチタスクはしない
- 小さく進めましょう。

---
# まとめ
- あらゆるムダをなくしましょう。
    - 人も仕事も組織も。
- 小さく高速に改善を回しましょう。
- 終わらせることを始めましょう。
C++, Java, Pythonでプログラムの実行結果を計測してみる．

## はじめに
自分でC/C++, Java/Scala, Python/Ruby/JavaScriptなどのスクリプト言語でそれぞれベンチマークプログラムを書き，その実行速度の結果を議論せよという課題が出たので書いてみる．
## 書いたプログラム
とりあえず全て 100**3 = 1000000回だけ `test` と出力するようなプログラムにした．

# C++
## プログラム 
```c++:benchmark.cpp
#include <iostream>
#include <chrono>
using namespace std;

void benchmark();

int main() {
  std::chrono::system_clock::time_point start = std::chrono::system_clock::now();
  benchmark();
  std::chrono::system_clock::time_point end = std::chrono::system_clock::now();
  std::cout << "elapsed time: " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() /1000.0 << "[sec]\n";

  return 0;
}

void benchmark() {
  for (int i = 0; i < 100; i++)
    for (int j = 0; j < 100; j++)
      for (int k = 0; k < 100; k++)
        std::cout << "test\n";
}
```

## 実行結果
コンパイラ: Apple LLVM version 7.3.0 (clang-703.0.31)
`elapsed time: 2.076[sec]`
# Java
## プログラム
```java:benchmark.java
public class benchmark {
  public static void main (String[] args) {
    long start = System.currentTimeMillis();
    benchmark();
    long end = System.currentTimeMillis();
    System.out.println("elapsed time: " + ((end - start) / 1000.0) + "[sec]");
  }
  private static void benchmark() {
    for (int i = 0; i < 100; i++)
      for (int j = 0; j < 100; j++)
        for (int k = 0; k < 100; k++)
          System.out.println("test");
  }
}
```

## 実行結果
コンパイラ: javac 1.8.0_74
`elapsed time: 3.581[sec]`

# Python
## プログラム
```python:benchmark.py
import time
def benchmark():
    for i in xrange(100):
        for j in xrange(100):
            for k in xrange(100):
                print 'test'

if __name__ == '__main__':
    start = time.time()
    benchmark()
    end = time.time()
    print ("elapsed time: {0}".format(end - start)) + "[sec]"
```

## 実行結果
バージョン: Python 2.7.11
`elapsed time: 2.25964999199[sec]`
Ardupilotのドキュメント

### Ardupilotのドキュメント
Ardupilotについて、個人的に興味があって調べた。忘れないようにメモ。
Ardupilotについては、良いドキュメントがある。それはWiki。しかも、git cloneも可能である。

https://github.com/ArduPilot/ardupilot_wiki

### documentの生成
cloneしたardupilotディレクトリの下でmakeする。
しかし、失敗。

```
ImportError: No module named sphinx_rtd_theme
```

sphinx_rtd_themeはpipでインストールすればよい。

```
pip install sphinx_rtd_theme
```

sphinx_rtd_themeについては、[このページ](http://esperia.hatenablog.com/entry/2015/07/04/131745)で簡潔に述べられている。感謝。

再度makeするが、またビルドエラー。

```
Extension error:
Could not import extension sphinxcontrib.youtube (exception: No module named sphinxcontrib.youtube)
```

またpipで必要なものをインストール。

```
pip install sphinxcontrib.youtube
```

ビルドが無事完了。これでHTMLが生成された。
例えば、developer向けの文書がみたいときはdev/build/htmlの下にあるindex.htmlを開けば良い。
これで、Wi-Fiが入らない場所でも心行くまでドキュメントが読めるぞ。
コードでAutolayoutを簡単に書く方法2つ

動的に生成されるViewに対して、marginなどを指定したいとき
Autolayoutをコードで書く必要があります。

ただ、普通に書くと..

```swift
addConstraint(NSLayoutConstraint(
    item: button1,
    attribute: .Right,
    relatedBy: .Equal,
    toItem: button2,
    attribute: .Left,
    multiplier: 1.0,
    constant: -12.0
))
```

たかだか左右のmarginを書くだけでもこれだけのコード量を書かねば
ならず、直感的ではないです。

何かCSSのように、簡単に書ける方法がないか探したところ
2パターンの書き方がありました。

## [パターン1]Cartographyを使う

![](https://raw.githubusercontent.com/robb/Cartography/master/images/pirates2.png)

[Cartography](https://github.com/robb/Cartography)　というライブラリを使うと、
Swiftのクロージャを使って簡単にレイアウトが組めます。
例えば、上記の例だと

```swift
constrain(button1, button2) { button1, button2 in
    button1.right == button2.left - 12
}
```
こんなに簡単に書けます。(公式サイトの例を抜粋)
第1引数にレイアウトを指定したいView、第2引数に相対関係にあるViewを指定します。

更に簡略化して、こう書けます。

```swift
// swiftのクロージャーには略式の引数($0, $1..)が予め設定されている。inも要らなくなる
constrain(button1, button2) {
    $0.right == $1.left - 12
}
```

## 実際に使ってみた

親Viewの内側にいい感じにUILabelをレイアウトしたい

```swift
constrain(footerLabel, containerView) {
    $0.edges == inset($1.edges, 7, 16, 0, 16) // 左から、top, leading, bottom, trailing　のmarginを指定
}
```

高さを指定

```swift
constrain(view) {
    view.width  == 100 // 幅に変更がなくても、指定しないと通常のAutolayout同様エラーで表示されない
    view.height == 200
}
```

めちゃ便利です。


## [パターン2]NSLayoutAnchorを使う

iOS9以上であれば、NSLayoutAnchorというクラスを使えば、簡潔にAutolayoutが書けます。
こちらも実際に使ってみました。

親Viewにピッタリフィットした、WKWebView
(WKWebViewはStoryBoardに置けるUIパーツがないので、Autolayoutをコードで指定する必要がある)

```swift
// 上辺の制約
webview.topAnchor.constraintEqualToAnchor(containerView.topAnchor, constant: 0.0).active = true
// 下辺の制約
webview.bottomAnchor.constraintEqualToAnchor(containerView.bottomAnchor, constant: 0.0).active = true
// 左辺の制約
webview.leadingAnchor.constraintEqualToAnchor(containerView.leadingAnchor, constant: 0.0).active = true
// 右辺の制約
webview.trailingAnchor.constraintEqualToAnchor(containerView.trailingAnchor, constant: 0.0).active = true
```
簡単!!


## どっちを採用する？
NSLayoutAnchorはiOS9~なので、iOS8の対応が必要な場合は、
iOS8対応もしている、Cartography一択。

iOS9以上が対象であっても、個人的にはCartographyのほうが未だシンプルなので、
採用するかと思います。

## 参考サイト

[Cartography](https://github.com/robb/Cartography)
[[iOS 9] NSLayoutAnchorを使ってNSLayoutConstraintを簡潔に書こう！](http://dev.classmethod.jp/smartphone/iphone/ios-9-nslayoutanchor-nslayoutconstraint/)
BitbarでSplatoonのフレンド状況をメニューバーに表示する

[元記事](http://saboyutaka.hatenablog.com/entry/2016/06/22/230529)

すごい今さら感があるけど、書こう書こうと思ってずっと書いてなかったので書いておく。

![splanet.png](https://qiita-image-store.s3.amazonaws.com/0/28262/a05269aa-f844-c5f6-11d6-ac44cbb22da7.png)


[イカリング](https://splatoon.nintendo.net/)で友達入ってるのかとか、Twitterの[スプラトゥーン ステージ情報bot](https://twitter.com/splatoon_stage)でこの後のステージなんなのかとか毎回調べるのめんどうですよねぇ。
~~イカリング、描画のjsがGCしてないのかCPU使用率がめちゃくちゃ高くなってファンがファーーってなるしくそ~~
メニューバーに表示されてたら楽なのにって思って表示させるようにしました。

## Bitbar

表示させるツールとしてはBitbarを使いました。Shellスクリプトでもいいし、好きな言語で標準出力に出せば表示できるのは便利です。
最初、Shellスクリプトで書いてたけどeachとかArray#joinとか使いたくなってRubyに書き換えました

[Bitbar](https://getbitbar.com)


## Bitbarで実行するRubyのコード
```ruby
#!/usr/bin/env /Users/yutaka/.rbenv/shims/ruby

require 'splapi'
require 'time'
require 'httparty'

puts 'Splanet'
puts '---'

client = SplAPI::Client.new

def print_stage(h)
  puts "#{Time.parse(h['start']).strftime('%H:00')}~ #{h['rule']}: #{h['maps'].join(', ')} | color=blue href=https://splatoon.nintendo.net/schedule"
end

puts 'Stages & Rule | size=16'
res = client.gachi_now.body
print_stage(res['result'][0]) if res['result'][0]

res = client.gachi_next_all.body
res['result'].each { |h| print_stage h } if res['result'].any?

puts '---'
puts 'Friends | size=16'

# ここはイカリングにログインして、Cookieに入っているwag_sessionをコピーしてください
wag_session = 'K25YUzJVYUxXTGU2YzJaSjRpWUNuR3VzTlM4ZXZPclJvdEFjdWk0Q2RYVVZGRFNGYVdUQ1hVRkJJT0luY295UG5WUzJPLzMVINHhIVE5aREQ0ckNJU2JZMVVZa0NOdFFkbWFqa1MzODhFQTR5cHcvY1dMNmRCRTBZemQ0SS82bkpnQTkzK2RqSVM0dDc5anV1aVhHUHFEYjQ5RDZFMFA3eXpGNllrdFdoUlpQWU9ZdHNMNnhYbEtKN1dFN0J6QUF5VzRvbUNpSVRIaFlFQStuYWhqcko5V0ZHc1BPTjVRTUJjcEY1SFVGcDMzeURieHJoOXhQQzJSTWZyQ0xxY2U2cG1rNzBaYW9KZjZaMkJTemZYUnVONmRsTEY1RUlsdlkvTVJtVnpack5uanJEVm9HRG5BU1VYaXZIUUVtcjkyZXMyYUtjeUtjOCtkenNjTzIrQkx4NUpmMjc1NjRDSEJqcDZodWNmOFV5LS1vdHVVTHA1TkRoU2d5QnZOeDFhVUNRPT0%3D--7bd8f9569'

res = HTTParty.get('https://splatoon.nintendo.net/friend_list/index.json', headers: { 'Cookie' => "_wag_session=#{wag_session}"} )

res.sort_by {|h| h['mode'] }.each do |h|
  puts "#{h['mii_name']}: #{h['mode']} | color=black href=https://splatoon.nintendo.net/profile/#{h['hashed_id']}"
end


```

## Rubyの実装
* rbenv使ってるので `#!/usr/bin/env /Users/yutaka/.rbenv/shims/ruby` とした
* httparty, time, splapi gem を使う
* splapiでステージ情報を取得する
* `friend_list/index.json`でフレンド情報を取得する
* session情報をcookieのwag_sessionという値を使ってるのでここだけは最初にブラウザでログインして、自分で取得する必要がある。

## splapi gem


[splapi - スプラトゥーンのステージ情報がとれるやつ](http://docs.splapi.apiary.io/#introduction/api)を作っている方がいたのでgemを作成させてもらいました。

https://github.com/saboyutaka/splapi_gem

ステージの情報はこちらから取得してます

## まとめ
PCから簡単に友達がログインしてる状況を把握できるようになりました。便利。
イカ、よろしくー。
Makefileのhelpを表示するコマンドunmake

Makefileをしばしば書くことがあるのですが、コマンドを追加したり、ファイル分割したりしていると、
使い方がわからなくなることがあります。そのためhelpをMakefile内に書いたりするのですが、内容を追従するのが面倒になったりします。

もしMakefileのhelpとかusageとかをPythonのdocstringっぽくかければ
、usageを書きやすくなるかなとおもい [unmake](https://github.com/TakesxiSximada/unmake) というコマンドをGoで書いてみました。
なのでちょっと説明を書いておきます。

https://github.com/TakesxiSximada/unmake

## インストール

go getでインストールします。

```
$ go get github.com/TakesxiSximada/unmake
```

インストールが完了すると `$GOPATH/bin` 配下にunmakeコマンドが作成されます。

## 使い方

### シンタックス

Makefileのコマンドの次の行に `\t@##` もしくは `\t@#` でコメントを記述します。
一行目を `\t@##` で始めた場合は、オプションパラメータとして表示されます。 オプションパラメータの記述は省略することもできます。`\t@#` は説明として表示されます。 

以下の例の場合は、 `param1=value1 param2=value2` がオプションパラメータです。
`document 1`、 `document 2`、 `document 3` がコマンドの説明です。

```
.PHONY: command
command:
    @## param1=value1 param2=value2
    @#
    @# document 1
    @# document 2
    @# document 3

    echo "EXECUTE COMMANDS..."
```

### 実行

第一引数にMakefileへのPATHを渡します。

```
$ unmake /PATH/TO/YOUR/Makefile
```

https://github.com/TakesxiSximada/unmake/blob/master/examples/Makefile にサンプルがあります。このサンプルを実行すると以下のように表示されます。

```
$ unmake examples/Makefile
* help

      display usage

* run target=NO

      execute an application.


* get target=NO_TARGET

      Install a application.
      ex) unmake

```

よかったら使ってね ٩(•౪• ٩)
Node.js+Express.js+i18n+ECT:多言語サイトを構築したい

多言語サイトを構築したい。

※「≈≈≈」は省略を表す

# バージョン

```
$ node -v
v6.2.1
```

```
$ cat package.json
{
  ≈≈≈
  "dependencies": {
    "ect": "^0.5.9",
    "express": "~4.13.1",
    "i18n": "~0.8.2",
    ≈≈≈
  },
  ≈≈≈
}
```

# localesの用意

```
$ mkdir locales
```
```
$ cat locales/en.json
{
  "i18ntest": {
    "Hello": "Hello world!"
  }
}
```
```
$ cat locales/ja.json
{
  "i18ntest": {
    "Hello": "素敵な世界！"
  }
}
```

# app.js

```
≈≈≈
var ect = require('ect');
var i18n = require('i18n');
≈≈≈
// view engine setup
var ectRenderer = ect({ watch: true, root: __dirname + '/views', ext : '.ect' });
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ect');
app.engine('ect', ectRenderer.render);
≈≈≈
// i18n settings
i18n.configure({
  locales: ['ja', 'en'],
  defaultLocale: 'ja',
  directory: __dirname + '/locales',
  objectNotation: true
});

app.use(i18n.init);

app.use(function (req, res, next) {
  if (req.session.locale) {
    i18n.setLocale(req, req.session.locale);
  }
  next();
});
≈≈≈
```

# 使い方

```
$ cat app.js
≈≈≈
var test = require('../routes/test');
≈≈≈
app.use('/', test);
≈≈≈
```
```
$ cat routes/test.js
var express = require('express');
var router = express.Router();

router.get('/', function(req, res, next) {
  res.render('test', {});
}

module.exports = router;
```
```
$ cat views/test.ect
<!DOCTYPE html>
<html>
        <head>
                <meta charset="UTF-8">
                <title><%= @__("i18ntest.Hello") %></title>
        </head>
        <body>
                <h1><%= @__("i18ntest.Hello") %></h1>
        </body>
</html>
```

# 確認方法

ブラウザの言語設定を日本語/英語にしてアクセス
例）Chrome(51.0.2704.103 (64-bit))：英語：
<img width="693" alt="スクリーンショット 2016-06-22 23.06.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/130752/4c536202-7015-1d9c-0b6d-4b8c9d87f854.png">

# 応用編

```
$ cat routes/test.js
var express = require('express');
var router = express.Router();

router.get('/', function(req, res, next) {
  res.render('test', { message: 'Hello' });
}

module.exports = router;
```
```
$ cat views/test.ect
<!DOCTYPE html>
<html>
        <head>
                <meta charset="UTF-8">
                <title><%= @__("i18ntest.Hello") %></title>
        </head>
        <body>
                <h1><%= @__("i18ntest." + @message) %></h1>
        </body>
</html>
```
2016年 日本語版　Google Analytics API 取得可能項目一覧

## きっかけ
先日、業務でGoogle Analytics API を使って取得できるデータ項目を調査することになりました。

調査していて結構大変だったなぁということもあり、「Google アナリティクスにさして詳しいわけでもないけれど、デベロッパとしてGoogle Analytics API を使ってマーケティング部門の要望に応えなければならない」というお仕事を担当されている方の為に調査結果を公開しようと思います。

下記ＵＲＬのリンク先にアップロードしたものが、調査した結果のExcelファイルとなります。

http://yahoo.jp/box/Z3SqJK


## 調査仕様

### 作成方針について

Google公式サイトにGoogle Analytics APIから取得できる指標とディメンションが一覧化されているので、こちらを翻訳します。使用するAPIは、調査時点の最新版であるCore Reporting API v3.0 としています。
※コホート等、一部API v4.0 を使用している箇所もあります。

### 調査時期

2016/4/23(土) ~ 2016/5/14(土)

### 調査対象外項目

業務の関係で、下記の項目は調査対象から外しています。

![image](https://qiita-image-store.s3.amazonaws.com/0/34636/7007ae23-aa46-9c07-1aa6-4390b090926e.png)
プロバイダ(ISP)って何のためにあるんだっけ？

#スライド機能が使いたかった
最初に言っときます。

参考資料: http://www.slideshare.net/yuyarin/ss-39061287 

上記URLの、内容の詰まった分かりやすい説明を、ISPの存在意義を説明するためだけに、引用したのがこのスライドです。

---

#最近多いですね、光コラボの勧誘
うちはフレッツ使ってるのですが。NTTと関係ありそうに装ってくるのが、すごく腹立ちます
「フレッツご利用状況の調査」「来月から安くなる」(フレッツ使ってると答えると)「ありがとうございます」はほぼテンプレ

---

#それでも話を聞いてみた
フレッツ辞める気はないが。「けど、プロバイダ変わるんでしょ？」って試しに言ってみたら衝撃的な言葉が。

「プロバイダは必要なくなるんです」　**えっ！？**
「プロバイダって、実際に何しているか、ご存じないですよね？」　**うぐっ！！**

---

#ということで、調べてみた。

---

#パッと思いつく役割

・IPアドレスを割り当ててくれる
・DNSサーバとか、メールサーバを使わせてくれる

けど、IPアドレスなんて、衝突しないように気をつけたら好きなの名乗ればよくね？　DNSもメールもGoogleがタダで提供してるし。そもそもGoogleとかもISPと契約してるの？

---

#ASへの参加
インターネット = インター(〜の間) + ネットワーク
⇒ネットワークのネットワーク
AS(autonomous system: 自律システム)という単位のネットワークが、相互接続を行っている

その一員にならないと、インターネットに繋がらない。

---

ASにはAS番号が割り当てられており、日本のASはJPNICが管理している。
日本のAS一覧: https://www.nic.ad.jp/ja/ip/as-numbers.txt

世界中のAS番号を検索: https://www.ultratools.com/tools/asnInfo

有名なプロバイダや、YahooやGoogleは独自でASを作っていることがわかる。

---
#ルーティング
AS同士の相互接続を頼って、目的地までトラフィックを届けるわけだが。
慈善事業じゃないので。タダじゃ届けてくれない。
設備だってタダじゃないし。

---
#金で解決

・トランジット: 自分よりも多くのASとつながっているASに、お金を払って届けてもらう

・ピア: よくやりとりするAS同士が、いつもトランジットを経由するとお金もったいないので直接やりとりする

⇒どこにトランジットしてもらって、どことピアを結ぶか、ASは考えないといけない。

---
#結論

---
#プロバイダ(ISP)の役割

・ユーザをASという小さなネットワークの一員にする
・AS同士のネットワークに参加し、安く世界中にトラフィックを届けられるように、他ASと、トランジットやピアの関係を結ぶ

これらが自前でできるなら、ISPは不要。一般人には無理なので、ISPは必要。
MacにMaven導入〜プロジェクト作成

Mavenを理解するためのメモです。

スコープ: mavenの導入からプロジェクト作成まで
環境： mac

1. 公式サイトからmavenをダウンロード
http://maven.apache.org/download.html
-> apache-maven-3.3.9-bin.tar.gz

2. mavenの展開
cd /usr/local/
tar xzvf apache-maven-3.0.5-bin.tar.gz

3. mavenの設定
export M3_HOME=/usr/local/apache-maven-3.0.5
M3=＄M3_HOME/bin
export PATH=＄M3:$PATH

source ~/.bash_profile

4. mavenのバージョン確認
mvn --version

5. mavenでサンプルプロジェクト作成
mvn archetype:generate -DgroupId=com.example -DartifactId=sample

[下記操作]
Choose a number or apply filter: [Enter]
Choose a number: [Enter]
groupId: org.sample
artifactId: sample
version: 1.0-SNAPSHOT
package: org.sample
Y: : y[Enter]



◆進捗
Maven | TECHSCORE(テックスコア)の
「2.3. プロジェクトの作成」まで完了


◆参考サイト
・Maven | TECHSCORE(テックスコア)
http://www.techscore.com/tech/Java/ApacheJakarta/Maven/index/

・Maven基礎
http://www.slideshare.net/taktos/maven-28516988

・Mac OS X に maven3 (3.0.5) をインストールする手順
http://oscasierra.net/2013/05/install-maven-3-0-mac/
Node.js+Express.js+log4js

※「≈≈≈」は省略を表す

# バージョン

```
$ node -v
v6.2.1
```

```
$ cat package.json
{
  ≈≈≈
  "dependencies": {
    "express": "~4.13.1",
    "log4js": "^0.6.37",
    ≈≈≈
  },
  ≈≈≈
}
```

# log4jsの設定

```
$ mkdir modules
$ cat modules/logger.js 
var log4js = require('log4js');

log4js.configure({
    "appenders": [{
      "category": "access",
      "type": "dateFile",
      "filename": "/var/log/nodejs/access.log",
      "pattern": "-yyyy-MM-dd",
      "backups": 3
    },
    {
      "category": "system",
      "type": "dateFile",
      "filename": "/var/log/nodejs/system.log",
      "pattern": "-yyyy-MM-dd",
      "backups": 3
    },
    {
      "category": "error",
      "type": "dateFile",
      "filename": "/var/log/nodejs/error.log",
      "pattern": "-yyyy-MM-dd",
      "backups": 3
    },
    {
      "type": "console"
    }],
    "levels": {
      "access": "ALL",
      "system": "ALL",
      "error": "ERROR"
    }
});

module.exports = { 
  access: log4js.getLogger('access'),
  system: log4js.getLogger('system'),
  error: log4js.getLogger('error'),
  express: log4js.connectLogger(log4js.getLogger('access'), {level: log4js.levels.INFO}),
  isDebug: function(category) {
    return (log4js.levels.DEBUG.level >= category.level.level);
  }
};
```

# app.js

```
$ cat app.js
≈≈≈
var logger = require('./modules/logger');
≈≈≈
app.use(logger.express);
≈≈≈
```

# 使い方

```
$ cat app.js
≈≈≈
var test = require('../routes/test');
≈≈≈
app.use('/', test);
≈≈≈
```
```
$ cat routes/test.js
var express = require('express');
var logger  = require('../modules/logger');
var router = express.Router();

router.get('/', function(req, res, next) {
  if(logger.isDebug(logger.system)) {
    logger.system.debug("debugログは、DEBUGレベルの時だけ呼びたい。");
  }

  logger.error.error("errorじゃないけどね！");
}

module.exports = router;
```
[PostgreSQL] DISK FULL TRUNCATE できない


ディスクFULLでTRUNCATEができない事案に遭遇したのでそのときの対処をメモで。

そもそも削除できなかった理由
PostgreSQLの場合、TRUNCATE時にも一時ディスク領域を使用するため、結局削除のために利用できるディスク領域が存在しないため、TRUNCATEができない事案に遭遇します。

対処法
1.追加ディスクをマウントする。
　　USBでもNFSでもなんでもOKです。
　　対象となるデータベースのディスクスペースの1.5倍程度の容量が必要です。
　　このときはサーバがデータセンターにあったので追加ディスクが
　　用意できなかったので、NFSサーバを緊急で立ててディレクトリをマウントしました。
2.追加ディスクにテーブルスペース保管用のディレクトリを作成する
3.対象データベースにコンソールログインする。
4.CREATE TABLESPACEで2で作ったディレクトリにディスクスペースを割り当てる
CREATE TABLESPACE backup_space LOCATION ‘追加ディスクに作成したディレクトリ’;
5.ALTER TABLE 対象テーブル SET TABLESPACE backup_space;
6.テーブルサイズが大きい場合は時間がかかります。
　　経験則ですが28G程度で15分くらいかかりました。
7.完了するとディスクスペースが空いていますので、TRUNCATEが実施できます。
8.バックアップしたテーブルは元のディスクスペースに戻す場合は
　　ALTER TABLE 対象テーブル SET TABLESPACE 元のテーブルスペース;
　で戻します。
9.戻し終わったら DROP TABLESPACE backup_space;
　　で綺麗にしておきます。
10.追加したディスクに作成したディレクトリも削除しておきます。
11.これで復旧を再度確認し、問題がなければ完了です。
Pythonでシェルコマンドの実行結果をリストで渡す方法(ブロックしない版)


[Pythonでシェルコマンドの実行結果をリストで渡す方法](http://qiita.com/kentarosasaki/items/033751ba8b26cc51cf2a) において、こんなソースがあった。これ、考え方はいいんだけど、シェルコマンドの終了を待つという点が惜しい。

```python:res_cmd_no_lfeed.py
#!/usr/bin/python

import subprocess

def res_cmd_lfeed(cmd):
  return subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True).stdout.readlines()

def res_cmd_no_lfeed(cmd):
  return [str(x).rstrip("\n") for x in res_cmd_lfeed(cmd)]

def main():
  cmd = ("ls -l")
  print(res_cmd_no_lfeed(cmd))

if __name__ == '__main__':
  main()
```

## そこで、yield を使う

```python:res_cmd_no_lfeed.py
#!/usr/bin/python

import subprocess

def res_cmd_lfeed(cmd):  # 戻り値はリストではなく各行
  for line in subprocess.Popen(cmd, stdout=subprocess.PIPE,shell=True).stdout:
      yield line

def res_cmd_no_lfeed(cmd):
  return [str(x).rstrip("\n") for x in res_cmd_lfeed(cmd)]

def main():
  cmd = ("ls -l")
  print(res_cmd_no_lfeed(cmd))

if __name__ == '__main__':
  main()
```

res_cmd_lfeed はコマンド終了までずっとブロックしてしまうのではなく、ループの中で1行受け取ったら yield 、つまりそのループをいったん停止し、そのときの結果を返す。
「次よこせ」と言われたら再開して、次の結果を返す……というように動作する。

この例だと結局は res_cmd_no_lfeed で Arrayが全部完成するまで待つので意味ないんだけどね。
Webアプリだったら、どんどんブラウザに応答を返しちゃうとか、できる。

## なにがうれしいのか

* シェルコマンドが無限に出力を生成するような場合でも、その途中までの結果を受け取れる。
* シェルコマンドの実行に時間がかかる場合でも、途中までの結果を早期に受け取れる。
* 一度に作業する対象が小さいので、ワーキングメモリが最小限で済む。
* 後半で失敗したとしても、途中までの結果を返しちゃってるので、取り返しがつかない。うれしくない

```cmd:forevertime.bat
@echo off
:TOP
echo %time%
goto top
```
こんなのを実行してみるとわかる。このバッチファイルは無限に出力しつづけるので、前者のソースだと readlines() で待ち続けてしまうが、後者は結果をどんどん取り込んで処理する。「ちぎっては投げ」のように。

## 注意。パイプにはバッファがある

* シェルコマンドの結果を受け取ってやらないと、シェルコマンド側が出力が詰まってしまって停まることがある。Windows10で試したところ、12kb程度のバッファが存在している模様。受け取るほうがのんびりしてると、タイムスタンプが10秒飛ぶ――みたいな現象として観測できる。

```cmd:forevertime.bat(大量出力版)
@echo off
:TOP
set /P X=0123456789012345678901234567890123456789012345678901234567890123<NUL
set /P X=0123456789012345678901234567890123456789012345678901234567890123<NUL
set /P X=0123456789012345678901234567890123456789012345678901234567890123<NUL
set /P X=0123456789012345678901234567890123456789012345678901234567890123<NUL
set /P X=0123456789012345678901234567890123456789012345678901234567890123<NUL
set /P X=0123456789012345678901234567890123456789012345678901234567890123<NUL
set /P X=0123456789012345678901234567890123456789012345678901234567890123<NUL
set /P X=0123456789012345678901234567890123456789012345678901234567890123<NUL
echo %time%
goto top
```

もっともっとチューニングできそうだけれど、まあ、このへんにしておくか。
Parslet で SystemVerilog のパーサを作るまでの道のり

パーサ初心者、かつ PEG 初心者だけども必要に狩られてパーサを書いてみる。
少しずつ更新していきます。

## SystemVerilog の規格書
とりあえず正確な規格書がなければと思い、[IEEE 1800-2012](https://standards.ieee.org/getieee/1800/download/1800-2012.pdf) から規格書を入手。1300ページ以上あるが、文法に関しては100ページ無いくらい。

## Parslet のインストール
gem でインストール出来るので、インストールはらくちん

```shell-session
gem install parslet
```

## 2進数リテラルの Parse
とりあえず練習がてらに Verilog の 2進数リテラルをパース出来るものを考える。
Verilog の 数値リテラルは以下の用に [`bitwidth`]'[`s|S`][`base`]数値 となっていて、
`s|S`は signed, `base` は 2 進数なら `b|B`となる。また数値は桁数を
数えやすいように `0000_1111` の用にアンダースコアを混ぜて良い。

```verilog
wire a = 1'b1; // 1bit
wire [1:0] b = 2'b10; // 2bit で 2
wire [7:0] c = 8'b1111_0000;
```

### パーサ実装
とりあえず Parslet の Getting Started を参考にしつつパーサを書いてみる。
というものの、ほとんど規格書の定義どおり。

```rb
require 'parslet'

class VBinaryParser < Parslet::Parser
  rule(:nz_dec_digit) { match('[1-9]') }

  rule(:dec_digit) {
    str('0') | nz_dec_digit
  }
  
  rule(:nz_us) {
    nz_dec_digit >> (str('_') | dec_digit).repeat
  }
  
  rule(:binary_digit) { match('[01]') }

  rule(:binary_base) {
    str('\'') >> (match('[sS]').maybe >> match('[bB]').as(:base))
  }
  
  rule(:binary_val) {
    binary_digit >> (str('_') | binary_digit).repeat
  }
  
  rule(:binary_num) {
    nz_us.maybe.as(:size) >> binary_base >> binary_val.as(:value)
  }

  root(:binary_num)
end

# test
require 'pp'
parser = VBinaryParser.new

pattern = [
  "'b1", 
  "1'b1",
  "2'b10",
  "8'b1111_0000",
  "2'b2"
]

pattern.each do |str|
  pp parser.parse(str)
end

```

### 実行結果

```shell-session
$ ruby v_bin.rb                                                  (git)-[master]
{:size=>nil, :base=>"b"@1, :value=>"1"@2}
{:size=>"1"@0, :base=>"b"@2, :value=>"1"@3}
{:size=>"2"@0, :base=>"b"@2, :value=>"10"@3}
{:size=>"8"@0, :base=>"b"@2, :value=>"1111_0000"@3}
/usr/lib/ruby/gems/2.3.0/gems/parslet-1.7.1/lib/parslet/cause.rb:70:in `raise': Failed to match sequence (size:(NZ_US?) BINARY_BASE value:BINARY_VAL) at line 1 char 4. (Parslet::ParseFailed)
        from /usr/lib/ruby/gems/2.3.0/gems/parslet-1.7.1/lib/parslet/atoms/base.rb:49:in `parse'
        from v_bin.rb:44:in `block in <main>'
        from v_bin.rb:43:in `each'
        from v_bin.rb:43:in `<main>'
```
最初の3つのケースは問題無くパースできているようだし、最後のパターンは正しくエラーと
認識されている。大丈夫な様子。

8進数, 10進数, 16進数についても同様に出来るだろう。ただ、コードが冗長になるので
うまく記述出来る方法を考えねば…
ElectronでChrome Extension使えるようにするまでのハマりどころ


そんなに使わないのでいつも流し見していたのだけど、どうしてもReact Dev ToolをElectronに入れたくなって本気出したら詰んだ。

ドキュメントはこのあたり。両方読まないとはまりがち。

- https://github.com/electron/electron/blob/master/docs/tutorial/devtools-extension.md
- https://github.com/electron/electron/blob/master/docs/api/browser-window.md#browserwindowadddevtoolsextensionpath


最終形のjsはこんな具合

```js
const {BrowserWindow} = electron;

const os = require('os')
const path = require('path')
const fs = require('fs')

function createWindow() {
  　:
  　:
  // react dev toolのID
  const id = "fmkadmapgofadopljbjfkapdkoienihi"
  
  // extensionの場所、"~/Library"だとダメだった
  const extensionDir = path.resolve(os.homedir(), "Library/Application Support/Google/Chrome/Default/Extensions/")

  // version指定
  const versions = fs.readdirSync(`${extensionDir}/${id}`).sort()
  const version = versions.pop()

  // 利用
  BrowserWindow.addDevToolsExtension(`${extensionDir}/${id}/${version}`)
}

app.on('ready', createWindow);

```

# ポイントなど
- ドキュメントには書いてることとか
  - Chromeからインストールしておく必要がある。
  - extensionのIDを調べておかないといけない
- ハマりどころとか工夫とか
  - `BrowserWindow.addDevToolsExtension`は`ready`後じゃないと使えない
  - `"~/Library"`のような相対指定だとうまくいかないっぽかった。
    - なので`os.homedir()`と`path.resolve`を使って解決。（直接絶対パスにしてもいい）
  - versionも指定しないといけない。
    - 調べてもいいけど、多分だるいだろうなーと思ったので、`fs.readdirSync`を使うって楽をする。
      - `sort`して`pop`すれば多分最新versionがとれる。はず。
rails logger

rails 使用ruby标准库里面的logger

rails 3

```rb
1.9.3-p551 :017 > ActiveSupport::Logger
NameError: uninitialized constant ActiveSupport::Logger
	from (irb):17
	from /home/vagrant/.rvm/gems/ruby-1.9.3-p551@expermental/gems/railties-3.1.1.rc1/lib/rails/commands/console.rb:45:in `start'
	from /home/vagrant/.rvm/gems/ruby-1.9.3-p551@expermental/gems/railties-3.1.1.rc1/lib/rails/commands/console.rb:8:in `start'
	from /home/vagrant/.rvm/gems/ruby-1.9.3-p551@expermental/gems/railties-3.1.1.rc1/lib/rails/commands.rb:40:in `<top (required)>'
	from script/rails:6:in `require'
	from script/rails:6:in `<main>'
1.9.3-p551 :018 > Logger
 => Logger 
```

rails 4

```rb
vagrant@precise64:~/data/times$ rails c
Running via Spring preloader in process 6718
Loading development environment (Rails 4.2.5)
2.2.3 :001 > ActiveSupport::Logger
 => ActiveSupport::Logger 
2.2.3 :002 > Logger
 => Logger 
```


rails 3 and rails 4


```rb
2.2.3 :004 > a = Logger.new($stderr)
 => #<Logger:0x00000004299a10 @progname=nil, @level=0, @default_formatter=#<Logger::Formatter:0x000000042999e8 @datetime_format=nil>, @formatter=nil, @logdev=#<Logger::LogDevice:0x00000004299880 @shift_size=nil, @shift_age=nil, @filename=nil, @dev=#<IO:<STDERR>>, @mutex=#<Logger::LogDevice::LogDeviceMutex:0x00000004299808 @mon_owner=nil, @mon_count=0, @mon_mutex=#<Mutex:0x00000004299768>>>> 
2.2.3 :005 > a.debug "lala"
D, [2016-06-22T12:49:08.272686 #6718] DEBUG -- : lala
 => true 
2.2.3 :006 > a.debug "lala"
D, [2016-06-22T12:49:12.829268 #6718] DEBUG -- : lala
 => true 
2.2.3 :007 > a.debug?
 => true 
```


```rb
2.2.3 :008 > log = StringIO.new
 => #<StringIO:0x000000041efba0> 
2.2.3 :009 > a = Logger.new(log)
 => #<Logger:0x000000041cb9f8 @progname=nil, @level=0, @default_formatter=#<Logger::Formatter:0x000000041cb840 @datetime_format=nil>, @formatter=nil, @logdev=#<Logger::LogDevice:0x000000041cb598 @shift_size=nil, @shift_age=nil, @filename=nil, @dev=#<StringIO:0x000000041efba0>, @mutex=#<Logger::LogDevice::LogDeviceMutex:0x000000041cb2c8 @mon_owner=nil, @mon_count=0, @mon_mutex=#<Mutex:0x000000041cb0c0>>>> 
2.2.3 :010 > a.debug "lala"
 => true 
2.2.3 :011 > a.debug "gaga"
 => true 
2.2.3 :012 > log.string
 => "D, [2016-06-22T12:50:25.016790 #6718] DEBUG -- : lala\nD, [2016-06-22T12:50:28.860896 #6718] DEBUG -- : gaga\n" 
```