OmniAICreator/Qiita-1.07M huggingface dataset:
OpalのNativeはどのように実装されているのか

この記事は[Opal Advent Calendar 2016](http://qiita.com/advent-calendar/2016/opal)の23日目の投稿として書いています。

今日は`Native`の実装について書こうと思います。
その前に`Native`のつかいかたです。

```ruby
require 'native'

%x{
  var foo = new Object();
  foo.bar = function() {
    return 'bar';
  };
  foo.baz = 'baz';
}

n = Native(`foo`)
puts n.bar
puts n.baz
```

こんなプログラムを実行してみましょう。`n.bar`も`n.baz`もそれぞれ文字列を返します。
Rubyのこれらの呼び出しはすべてメソッド呼び出しになります。
一方、JavaScriptではプロパティに関数だったり、文字列だったりをアサインすることができます。
Nativeは関数であれば関数を実行した結果を返すし、文字列などの値であればその値を返すようになっています。
それでは、これらがどのように実装されているか見てみましょう。

`Native`は*stdlib/native.rb*に定義されています。

まずは`Native()`の定義をみてみます。

```ruby
  def Native(obj)
    if `#{obj} == null`
      nil
    elsif native?(obj)
      Native::Object.new(obj)
    else
      obj
    end
  end
```

`native`であれば`Native::Object`を返します。`native?`はどのように判定しているのでしょうか?

```ruby
  def native?(value)
    `value == null || !value.$$class`
  end
```

`null`の場合もしくは、`$$class`が定義されていない場合は`native`であると判定しています。
`$$class`はRubyのクラスを表す変数です。この定義があればRubyのクラスから生成されたオブジェクトと言えます。

`Native::Object`のメソッド呼び出しは`method_missing`でnativeの呼び出しに変換されます。

```ruby
  def method_missing(mid, *args, &block)
    %x{
      if (mid.charAt(mid.length - 1) === '=') {
        return #{self[mid.slice(0, mid.length - 1)] = args[0]};
      }
      else {
        return #{::Native.call(@native, mid, *args, &block)};
      }
    }
  end
```

メソッド名の最後が`=`だったらプロパティへの代入になります。
`Native::Object#[]`はJSのプロパティを返します。

```ruby
  def [](key)
    %x{
      var prop = #@native[key];

      if (prop instanceof Function) {
        return prop;
      }
      else {
        return #{::Native.call(@native, key)}
      }
    }
  end
```

メソッド名が`=`で終らない場合は、`Native#call`が呼ばれます。

```ruby
  def self.call(obj, key, *args, &block)
    %x{
      var prop = #{obj}[#{key}];

      if (prop instanceof Function) {
        var converted = new Array(args.length);

        for (var i = 0, length = args.length; i < length; i++) {
          var item = args[i],
              conv = #{try_convert(`item`)};

          converted[i] = conv === nil ? item : conv;
        }

        if (block !== nil) {
          converted.push(block);
        }

        return #{Native(`prop.apply(#{obj}, converted)`)};
      }
      else {
        return #{Native(`prop`)};
      }
    }
  end
```

`Native#call`の中身はプロパティが関数の場合は引数をnativeに変換して関数を呼び出します。
関数の場合は関数の呼び出し結果、それ以外ならプロパティそのものを`Native::Object`でラップして返します。

引数の変換は`to_n`メソッドでおこなわれます。

```ruby
  def self.try_convert(value)
    %x{
      if (#{native?(value)}) {
        return #{value};
      }
      else if (#{value.respond_to? :to_n}) {
        return #{value.to_n};
      }
      else {
        return nil;
      }
    }
  end
```

`to_n`メソッドは*native.rb*のなかでいくつか定義されています。
たとえば、`Numeric`なら

```ruby
class Numeric
  def to_n
    `self.valueOf()`
  end
end
```

`valueOf()`でプリミティブを返すようになっています。

*native.rb*にはほかにもさまざまなクラスに`to_n`の定義をしています。`Array``Hash`などもあります。
もちろん、`Native::Object`自身も`to_n`メソッドをもちます。
しかし、`to_n`が定義されていないクラスに関しては、nativeへの変換は行なわれませんので注意が必要です。
逆に`to_n`を定義すればnativeのメソッドに引数として渡すことができるようになります。

`Native`の実装についてみてきましたがいかがでしょうか。次回は`JS`の実装を見てみましょう。
では、Happy hacking!
Objective-CからSwiftへの移行でバグりやすいポイント

最近はSwift2.*→3の移行で非常に苦しんでいるエンジニアの方も多いかと思いますが、まずはObjective-C(以下obj-c)からSwiftへの移行で不具合が発生しやすいポイントをまとめてみました。気づき次第追記したいと思います。他にもあればコメントも大歓迎です :smile:

## Optional関連
### 意図せずwrapされた値を使用してエラー
Intが入っていると思っていたのに、```optional(10)``` のように余計な文字列が含まれている場合があります。optionalで定義した値の場合、unwrapしないと想定した値にならず、思わず不具合を引き起こす恐れがあります。

```swift:例
var badgeCount: Int?
badgeCount = 5
print("\(badgeCount)") // Optional(5)が出力され、警告も出ない
```

### 意図しないnil
obj-cの時はnilの値が入っていた場合は基本的にクラッシュはせず処理が続行されていましたが、Swiftの場合Xcodeが補完してくれるがままにunwrapなどしていると、nilが入ってアプリが意図せずクラッシュするという問題に遭遇すると思います。obj-cの時以上に、どのような値が入るかを想定する必要がありそうです。

下記例では、recordクラスのnameというメンバがnilを許可していて、labelにnameをセットするタイミングでunwrapするとエラーが発生する。

```swift:例
let apiClient = ApiClient()
let response = ApiClient().fetchHogeData()
let record = response.records[0]
label.text = record.name! //エラー発生
```

## 型の制約
obj-cでは数値といえば、NSInteger/NSUInteger/NSNumberなど種類が多かったと思いますが、swiftの場合は基本的にIntを使うことが多いかと思います。しかし、両言語が混在していて、Swift→objcに渡す場合はNSIntegerなどにcastする必要があります。Swift単体の場合はあまり意識しなくて良いかもしれませんが、移行過程などでは注意する必要がありそうです。

```swift
let memberID: Int = 50
let objcClass = objcClass() // memberIDというNSUIntegerのメンバ変数を持っているとする
objcClass.memberID = UInt(memberID) // memberIDをそのまま渡すとエラーになるのでUIntでキャストする必要がある
```

## obj-cでSwiftのクラスを使う場合の制約
obj-cでswiftのクラスを使う場合は、swiftのクラスがNSObjectを継承している必要があります。

## moduleのimportでの不具合
![スクリーンショット 2016-12-22 16.26.11.png](https://qiita-image-store.s3.amazonaws.com/0/10532/c812c30a-5236-a4ee-11ba-b8e514db32bb.png)
今までcocoapodsなどのライブラリを使用する場合は、特定の.hファイルをimportしていたと思いますが、swiftからはモジュール指定でimportすることになります。しかし上記のようにimportの候補に表示されるものの、打ち消し線がでているので使えないかと思いきや、特に問題なく使えてしまいます。下記の記事によるとXcodeのバグではないかとコメントされていますが、なんだか気持ちが悪いですね。。 
http://stackoverflow.com/questions/36463653/what-is-this-red-line-through-the-xcode-import-auto-suggest

## まとめ
Swiftなり色々とすっきりと記述できるようになった反面、obj-cの時と比べると型に関しては厳格になりました。特にXcodeの表示されるunwrap関連の警告を、あまり理解せず"?"や"!"を付けて進めていないでしょうか？特にobj-cとswiftが混在してしまうコードの場合、どうしてもOptional属性をうまく使いながら実装をする必要があります。きちんと理解した上で適切な属性を使ってコードを書かないと後から痛い目に遭いますので、気をつけましょう :sweat_smile: 

## 参考
[どこよりも分かりやすいSwiftの"?"と"!"](http://qiita.com/maiki055/items/b24378a3707bd35a31a8)
[Swift3のIUO(!)型から属性への変更に考えさせられたこと](http://qiita.com/morimorim/items/c4e4e329278089021686)
Sinatraを簡単に紹介

#はじめに
謝罪
####***遅れてしまって大変申し訳ありません***
この記事は、[SLP_KBIT Advent Calendar 2016 - Qiita](http://qiita.com/advent-calendar/2016/slp_kbit)の21日目の記事です。
[SLP_KBITその２ Advent Calendar 2016 - Qiita](http://qiita.com/advent-calendar/2016/slp_kbit2)の20日目にも、記事を書いていますので、良かったらそちらも読んでくださいな。

今日(執筆開始日)は12月23日です。この記事は12月21日用の記事です。
反省してます。

今回はSinatraで簡単にWebページ表示しようかなって思います。
サーバ上で行っていると思ってください。
なんとなくしか理解できていないので、間違ってたら指摘していただけると嬉しいです。

#Sinatraとは
Sinatraは軽量なWebアプリケーションフレームワークです。
「Railsむずそう」とか、「ちょっとしたことしかしない」って時にいいんじゃないかと思います。

適当に好きなディレクトリ作って
```$ bundle init```
すると Gemfile なるものが出来上がってると思いますので
```gem 'sinatra'```
を書き加えます。

```$ bundle install --path vendor/bundle```
を実行してgemをインストールします。

#とりあえず Hello World
下記のようなファイルを用意します。

```ruby:hello.rb
require 'sinatra'
set :bind, '0.0.0.0'

get '/' do
  'Hello World'
end
```

Sinatraはデフォルトでローカルホストからのアクセスしか受け付けないので
```set :bind, '0.0.0.0'``` を書く必要があります。

```bundle exec ruby hello.rb``` で実行します。
デフォルトでは4567番ポートで実行されます。
pオプションをつけてポート番号を指定して実行することもできます。

ブラウザで
http://サーバのIPアドレス:ポート番号
にアクセスすればHello Worldと表示されていると思います。

ローカルでポートの指定をせずに実行している場合は
http://localhost:4567
にアクセスすればいいです。

Hello Worldと出力されていると思います。

#erbファイルを使う
erbファイルというものがあります。これは、htmlファイルの中にRubyのコードを埋め込んだようなものです。(あってるのかな?)
まず先ほどの```hello.rb```を以下のように書き変えます。

```ruby:hello.rb
require 'sinatra'
set :bind, '0.0.0.0'

get '/' do
  @world = 'World'    # erbファイルで使う変数
  erb :hello    # hello.erbを呼び出す
end
```

次に、```hello.rb```と同じ階層に```views```というディレクトリを作ります。
そして```views```の中に以下のファイルを用意します。

```erb:hello.erb
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Hello World</title>
  </head>
  <body>
    <p>Hello <%= @world %></p>
  </body>
</html>
```

インスタンス変数を用意することで、erbファイルに変数を渡すことができます。
erbファイルでは<%= %>の中で書かれた部分はRubyのコードとして実行し出力します。制御構文など、出力をしない部分は<% %>で囲みます。
先ほどと同様にブラウザでアクセスすると```@world```の部分が展開され、Worldになって出力されているはずです。

#最後に
Sinatraとerbファイルについて簡単に紹介しました。
ところどころ、この表現正しいのかな？とか考えながら書いてましたので、間違えてる場所もあるんじゃないかと思いますので、指摘していただけるとありがたいです。
GoでAESアルゴリズム(GCMモード)を使った実装をする

なんでもセキュリティの24日目です。誰も登録しなかったので書きますが、セキュリティエンジニアはみんなリア充らしいです。妬ましい。お前のとこにランサムウェアおくったろか。

そんなことは置いといて、[GoでAESアルゴリズム(CBCモード)+PKCS7パディング+HMACを使った実装をするの続きです](http://qiita.com/ken5scal/items/82d15c2f51c71759fcb9)

さて、前回はHMACを組み合わせることで、暗号化における機密性(Confidentiality)だけでなく、完全性(Integrity)からなる認証まで実現することができました。しかし、これには１つ問題があります。面倒くさい！ 面倒くさければ、手間を省こうと実装しないかもしれないし、よしんばしても実装ミスが発生するおそれがあります。その問題に対応するために出てきたのが、認証付き暗号(Authentication Encryption)です。

GCMはその１つで、アメリカ国立標準技術研究所(NIST)にも標準として認められています。また、暗号処理を並列化することで高速な処理を可能としています。そのためなのか、最新ブラウザ <--> サーバ間通信であれば、デフォルトでAES-GCMのTLS通信として選択されています。

![image](https://qiita-image-store.s3.amazonaws.com/0/59166/ce4f3f70-0905-35f9-4d55-ef6082285661.png)

また、GCMはパディングが不要なストリーム型の暗号です。

# GoにおけるAES-GMCの実装
なんと、Goの"crypto/cipher"パッケージにデフォルトで入ってました。hmacみたいに独立してないし、Paddingのように自前実装が必要ないので、暗に「お前ら、うだうだ言わずGCM使っとけ？」と言われている気がします。勿論、私はそうさせて頂きますよ、Google様。

```go

// GCM encryption
func EncryptByGCM(key []byte, plainText string) ([]byte, error) {
	block, err := aes.NewCipher(key); if err != nil {
		return nil, err
	}

	gcm, err := cipher.NewGCM(block); if err != nil {
		return nil, err
	}

	nonce := make([]byte, gcm.NonceSize())// Unique nonce is required(NonceSize 12byte)
	_, err = rand.Read(nonce); if err != nil {
		return nil, err
	}

	cipherText := gcm.Seal(nil, nonce, []byte(plainText), nil)
	cipherText = append(nonce, cipherText...)

	return cipherText, nil
}

// Decrypt by GCM
func DecryptByGCM(key []byte, cipherText []byte) (string, error) {
	block, err := aes.NewCipher(key); if err != nil {
		return "", err
	}
	gcm, err := cipher.NewGCM(block); if err != nil {
		return "", err
	}

	nonce := cipherText[:gcm.NonceSize()]
	plainByte, err := gcm.Open(nil, nonce, cipherText[gcm.NonceSize():], nil); if err != nil {
		return "", err
	}

	return string(plainByte), nil
}

func main() {
	cipherText, _ = EncryptByGCM(key, "12345")
	decryptedText, _ = DecryptByGCM(key, cipherText)
	fmt.Printf("Decrypted Text: %v\n ", decryptedText)
        // Decrypted Text: 12345
}
```

以上。取り急ぎ、これでGoにおけるAESアルゴリズムを用いた実装は一通り紹介出来たかと思います。

# NONCE, 初期化ベクトルについて
これらは各データで一度きりしか使われないことを担保しなければいけません。元々の存在理由がリプレイ攻撃への対策です。
リプレイ攻撃は、例えばEC2サイトに注文した暗号通信を盗聴し、再度おなじ暗号通信を再送（リプレイ）することで２重の発注をさせてしまう様な攻撃です。もしくは、自分の口座に対する送金をする通信を盗聴し、それをリプレイすることで、何回も振り込ませてしまうような攻撃です。

これを使い捨てのナンスを使い暗号文を検証することで防御できるので、使いまわしてはいけません。なので、毎回ランダムに作り直しましょう。
タイムラプス動画の自動速度調整の試み（後編）

## 前編

[タイムラプス動画の自動速度調整の試み（前編）](http://qiita.com/sosuke/items/c729304efc18e004edf6)

上記記事の続きになります。

調べる力が足りなすぎたので、とりあえず手を動かしました。

## phash (前編より)

https://youtu.be/BOHDtW9_tlQ

このタイムラプス動画のフレーム間ハッシュ距離がこんな感じになっていました。

```
clip = moviepy.editor.VideoFileClip("path to video file")
phashs = [imagehash.phash(PIL.Image.fromarray(frame)) for frame in clip.iter_frames()]
distances = [phashs[i+1] - phashs[i] for i in range(len(phashs)-1)]
```

![アートボード_1.png](https://qiita-image-store.s3.amazonaws.com/0/32636/39df1233-a12f-1107-253b-3d345560a6a3.png)


## z score

とりあえず、z score とってみました。

```
z_scores = scipy.stats.zscore(distances)
```

![z_scores.png](https://qiita-image-store.s3.amazonaws.com/0/32636/5caf8afa-a848-4746-9e42-d71750f00492.png)

## gaussian blur

z score にブラーをかけて、絶対値の平均のマイナスを閾値にしてみました。

```
blured = cv2.GaussianBlur(z_scores, (49, 49), 0)
threshold = numpy.average(numpy.sqrt(numpy.power(z_scores, 2)))
```


![blured_z_scores.png](https://qiita-image-store.s3.amazonaws.com/0/32636/ea932ee9-7d18-ce3c-a4e5-1b5f2acaa82e.png)


上図の閾値を下回っている１つの連なりを１つのイベントとして
動画再生を速度を変えたものが以下になります。

https://youtu.be/iPMuMYygbDg

## 課題

思い描いていたものには近いづいていますが、
イベントとして検出した部分の前後も徐々にスピードが落ちたり、早くなったりさせてちょっと境目にマージンを持たせたらもう少しましになるかもとは思いました。

今回 `moviepy` というpythonのライブラリを使いましたが
その使い方がもう少しわかったらチャレンジしてみたいと思います。

https://github.com/Zulko/moviepy


使ったライブラリをのせておきます。

```
# requirements.txt
ImageHash==3.1
matplotlib==1.3.1
moviepy==0.2.2.11
numpy==1.7.1
Pillow==3.4.2
progressbar2==3.11.0
scipy==0.13.2
seaborn==0.7.1
```

コードはこちら。
https://github.com/sosuke-k/timelapse-optimizer
Oracle null判定の方法をいくつか

ソースコードから寄せ集めたSQLが同じnull判定をいろんなパターンで行っていて、面白かったのでメモ

下記のコード(パターン4以外)は、`col_name` の値が `null` であれば `0` 、`null` 以外であれば `1` を返却している。
Oracle 11gにて検証


# パターン1： NVL2関数 を使う
```sql
SELECT
  NVL2(col_name, 1, 0)  AS null_flg
FROM
  table_name
```
> **NVL2 ( expr1 , expr2 , expr3 )**
戻り値：
　式 expr1 が NULL 以外なら 式 expr2 の値（expr1 の型）
　式 expr1 が NULL なら 式 expr3 の値（expr3 の型）
[NVL2、NULLIF - オラクル・Oracle SQL 関数リファレンス](http://www.shift-the-oracle.com/sql/functions/nullif.html)

# パターン2： DECODE関数 を使う

```sql
SELECT
  DECODE(col_name, NULL, 0, 1) AS null_flg
FROM
  table_name
```

# パターン3： 検索CASE式 を使う

```sql
SELECT
  CASE 
    WHEN col_name IS NULL THEN 0 
    ELSE 1 
  END AS null_flg
FROM
  table_name
```


# パターン4： 単純CASE式 を使う（と、できないので注意！）

```sql
SELECT
  CASE col_name 
    WHEN NULL THEN 0 
    ELSE 1 
  END AS null_flg
FROM
  table_name
```
これは `col_name` が `NULL` であっても、`1` が返却されるため、間違ったパターン。
理由については以下を参照 ↓

> 単純 CASE 式は NULL との評価はすべて NULL になる。
[CASE と DECODE 関数の違い - オラクル・Oracleをマスターするための基本と仕組み](http://www.shift-the-oracle.com/sql/case-decode-difference.html)
ローカル環境PostgreSQL + phpPgAdmin でデフォルトユーザーでログインできないときの対処

**あくまでローカル環境でテストするときのみ使用する場合の対応です。**

コマンドラインから

```
>psql -U postgres
password:*****
```

では入れるのにphpPgAdminで上記ログインができなかったのですが、
phpPgAdmin>FAQ>login
のところに書いてありました。

```
Question #4

For some users I get a “Login disallowed for security” message.

Answer: Logins via phpPgAdmin with no password or certain usernames (pgsql, postgres, root, administrator) are denied by default. Before changing this behaviour (setting $conf['extra_login_security'] to false in the config.inc.php file) please read the PostgreSQL documentation about client authentication and understand how to change PostgreSQL's pg_hba.conf to enable passworded local connections.
```

とのことで、

```config.inc.php
$conf['extra_login_security'] = false;
```

にすることでログインできました。

**セキュリティ上好ましくないと思われるので、あくまでローカル環境でテストするときのみ使用する場合の対応です。**
nginx virtualhost 設定メモ

#はじめに
Dockerのnginxでvirtualhost試したいと思います
そもそもDockerのオプション使えって話かもしれませんが。。

#ホスト側環境
Dockerはインストール済みということで。
foderaでやってます

```
cat /etc/redhat-release
```
->Fedora release 24 (Twenty Four)

#nginx立ち上げる

```
docker run --name test-nginx -d -p 8080:80 nginx
```

まずは確認
http://localhost:8080/

welcomeみたいなのが出てたらおっけです

#virtualhostの設定

##やりたいこと
1つのipアドレスに対して2つのFQDNを使えるようにする
そのために、virtualhostを利用する。
ちなみにipはローカルを使う。(そもそもLAN内での接続が前提です)

##要素
一つ目のホスト->www.test1.co.jp
二つ目のホスト->www.test2.co.jp
ipアドレス->127.0.0.1(まぁ、ローカルホストです)

```
#コンテナのファイルをいじりますので。
docker exec -it test-nginx bash

#vim install ファイルをコピーでもいいんですが。。
apt-get update
apt-get install vim -y

#ファイルを作成します
mkdir /var/www/test1
mkdir /var/www/test2
echo "<html>test1</html>" > /var/www/test1/index.html
echo "<html>test2</html>" > /var/www/test2/index.html

#該当ファイルを編集します
vi /etc/nginx/conf.d/default.conf 
```

##virtualhostのためのコンフィグ設定
先程の二つを追加で記述します。
saerver_nameにFQDN、
rootにドキュメントルートを書く感じですね。
下記みたいな感じです。

```/etc/nginx/conf.d/default.conf
#defaultはそのままで下記を追加

server {
    listen       80;
    server_name  www.test1.co.jp;

    location / {
        root   /var/www/test1;
        index  index.html index.htm;
    } 
}

server {
    listen       80;
    server_name  www.test2.co.jp;

    location / {
        root   /var/www/test2;
        index  index.html index.htm;
    }
}            
```

##設定の確認

```
/etc/init.d/nginx configtest
```

成功できたらおっけ。exitする

##再起動
docker restart test-nginx

##hostsの設定
本当は、DNSサーバーでってなるのですが、
ローカルで試したいので、ホストマシン(今回はfodera)の
/etc/hostsに例の二つを加え、名前解決させます。

```/etc/hosts
127.0.0.1   www.test1.co.jp
127.0.0.1   www.test2.co.jp
```


#最後に確認
http://www.test1.co.jp:8080
http://www.test2.co.jp:8080

それぞれtest1とtest2の文字列が出力されれば成功です。

#おわりに
めちゃくちゃ眠い

#参考
[library/nginx]
(https://hub.docker.com/_/nginx/)
BigQueryとAmazon Athenaを軽く比べてみたよ

# はじめに

この記事は[Google Cloud Platform(1) Advent Calendar 2016](http://qiita.com/advent-calendar/2016/gcp)7日目の記事です。
まだ投稿がなかったのと、ちょうど社内のQiitaTeamにBigQueryとAmazon Athenaの簡単な比較ネタを投稿していたので、それを載せます

# やったこと

* TreasureDataからBigQuery出力しているデータがあったので同じものをS3に出力
* BigQuery, Athenaにクエリなげてパフォーマンスを比較

# Athenaデータ準備

## データベース作成

```sql
CREATE DATABASE test;
```

## テーブル作成

データはweblogをちょっとサマリしたものです。

```sql
CREATE EXTERNAL TABLE IF NOT EXISTS test.weblog (
  summarize_date string,
  user_id string,
  host string,
  url string,
  os string,
  browser string,
  ip_address string,
  logs bigint 
)
PARTITIONED BY ( dt string )
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe'
WITH SERDEPROPERTIES (
  'serialization.format' = '	',
  'field.delim' = '	'
) LOCATION 's3://path/to/weblog/';
```

* PARTITIONは日付を入れるので、`dt`という名前で設定

## PARTITIONINGを設定

11/1,11/2の2日分を入れたので２つ設定

```sql
ALTER TABLE test.weblog ADD
  PARTITION (dt='20161101') LOCATION 's3://path/to/weblog/20161101/'
  PARTITION (dt='20161102') LOCATION 's3://path/to/weblog/20161102/';
```

確認

```sql
show partitions test.weblog;
```

結果。できてますね。

```
dt=20161101
dt=20161102
```

## クエリをなげてみる
カウント

```sql
select
  count(1)
from test.weblog;
-- (Run time: 4.12 seconds, Data scanned: 121.19MB)  result: 2541225
```

パーティションが効くかどうか。
レコード数も減ったし処理データ量も減った

```sql
select
  count(1)
from test.weblog
where dt = '20161101';
-- (Run time: 4.33 seconds, Data scanned: 60.99MB) 　result: 1277304
```

# BigQueryとAWS Athenaを比較

## ホスト名別のUU数

### クエリ

```sql
 select 
  host,
  count(distinct user_id)
 from weblog
group by 
  host
ORDER BY
  host
```

### 結果

* BQ: **Query complete (2.8s elapsed, 107 MB processed)**
* Athena: **(Run time: 6.19 seconds, Data scanned: 121.19MB)**

## URL別ログ数 Top1000

SQLは割愛。結果は以下の通りでした。

* BQ: **Query complete (3.9s elapsed, 152 MB processed)**
* Athena:  **(Run time: 5.86 seconds, Data scanned: 121.19MB)**

すごく簡単な検証かつ、データ量もそこまで多くありませんでしたが、BigQueryのほうが速いという結果になりました。

# 所感

* コストをまじめに比較していないのだが、実際のところどうなんだろうか
* UIがかなり酷似している
* Athenaの場合、クエリ結果がキャッシュされない、かつクエリの結果がS3に出力されているので、注意しないとクラウド破産する
逃げるのは恥でも何でもないし役に立つ（今までの転職で得た教訓の話）

（2017-05-30 追記）
この記事は、転職 Advent Calendar 2016の 24 日目の記事でした。
転職 Advent Calendar は Qiita 運営側により削除されましたが、カレンダー作成者の方が ADVENTAR にカレンダー自体を移植されています。[転職 Advent Calendar 2016 (ADVENTAR 版)](http://www.adventar.org/calendars/2067)
（2017-05-30 追記ここまで）

参考になるかどうかはわからないですが、おっさんエンジニアの転職遍歴を思うところを交えながらここに記します。

# 転職するまで

エンジニアになったきっかけは、無職時代に当時の彼女[^1]が見つけた未経験OKの求人に応募したらたまたま通っただけのことで、まあ実質ド素人からのスタートでした。
この会社では殆どの期間を客先常駐で過ごしていました。まあいわゆる一束なんぼで売られている労働力の一員というわけです。

[^1]: 今の妻

# 一度目の転職

この会社では、ありがたいことにそれなりに評価されていましたし出世もできそうでした。また、残業代もちゃんと出ていたし手当も厚く支給されていたので所得面でも大きな不満はありませんでした。
しかし、5 年ほど働いたところで一度目の転職を決意しました。
理由は大きく分けて二つあり、一つは年齢と経験的なところから、そろそろ（いわゆる）PG から（いわゆる）SE になってほしいと言われるようになっていたのですが、まだまだプログラマとしてやりたい、やっていけるという思いが捨てられなかったこと。もう一つは、客先常駐ではなくて自社内で仕事がしたかったこと。（必ずしも自社製品やサービスじゃなくてもいいので）
当時はまだ景気が悪くなかったこともあり、書類審査はほぼ全て通過していた記憶があります。
が、今思うと初めての転職でどうしても自分をよく見せようと背伸びをしていたことや、そもそもコミュニケーション能力が残念なこともあり、一次面接を通過したのはたったの一社でした。
結局、その一社に採用していただくことになります。

## ここで得た教訓

- 自分の技術力がどの程度なのか正確に把握することと、持っている技術を他人に説明できることが大切
    - とくに、天狗になっていないか、井の中の蛙になっていないか、ということに気をつける
- 面接では正直に話さないと、結局お互い幸せになれない

# 二度目の転職

ふたつ目の会社は、社長も含め会社全体がスキルの高さを売りにしていました。私のスキルもここで相当に引っ張りあげられています。
ここでも 5 年ほど働いたところで再度の転職を決意しました。リーマン・ショックが会社に与えたダメージが大きかったことと、詳細は控えますが対人関係の問題が主な原因です。私には自覚があまりなかったのですが、妻に言わせると、その会社を辞める直前の私は相当病んでいたそうです。

## ここで得た教訓

- 好景気は大抵の人にとって他人事だけど、不景気は殆どの人にとって他人事じゃない
    - 自分の都合だけではどうしようもないこともある
- エンジニアとしての能力よりも何よりも、人としてどうかのほうがはるかに重要
    - スキルしか見ない、人間性に問題がある上司がいたらすぐ逃げろ
    - 逃げるのは恥でも何でもなくて役に立つ

# 今

今の会社に入って 5 年目です。全く悪い会社ではないのですが、周期的にはそろそろ転職を考えだす時期・・・？
もし何かあれば、来年の Advent Calendar で。

(2018-10-20 追記)
2017年中には転職しなかったのですが、なぜか結局転職の周期はきっちり守られてしまいました。
顛末はブログ（[六年目のジンクス](https://mdstoy.hatenablog.com/entry/2018/04/01/175336)）に記載しています。

# 結論

見も蓋もない言い方になってしましますが、結局収まるところにしか収まらないんだというのが今の率直な感想です。そして、自分自身を正しく売り込めなければ、収まるところにすら収まれないのではないかと思います。
そして、自分自身が自分の能力を正しく把握するためには、[プログラマ 35 歳定年説を超えて](http://qiita.com/mdstoy/items/557dfc1a779723ae5fc5)という記事でも書いたのですが、積極的に外に出てみることが重要だと今は感じています。
IntelliJ IDEA でクリップボードと diff をとる

diff 大好きエンジニアの @oohira です。コードにしろドキュメントにしろ、目的の修正と関係ない差分が混ざっているとテンションが下がりますよね。特に、空白やタブが意図せず混入していた暁には、「コミット前に diff は確認したのか！」と叫びたくなります。

そんな私が好きな IntelliJ IDEA のニッチ機能が、編集中のコードとクリップボードのテキストを比較できる **「Compare with Clipboard」** 機能です。

## 使い方

1. あらかじめ比較対象のコードをコピーしてクリップボードに入れておく
1. IntelliJ IDEA でクリップボードと比較したいコードを範囲選択する
1. 右クリックから `Compare with Clipboard` を実行する
![image](https://qiita-image-store.s3.amazonaws.com/0/33668/368f5411-957e-4da4-7dd9-422d7cc9f819.png)

## 何が嬉しいのか

エンジニアであれば誰しも次のようなシーンで diff を使ったことがあると思います。

* あるファイルをコミットする前に、ローカルで加えた修正の差分を確認する
* あるファイルを過去のコミット（リビジョン）と比較し、修正の差分を確認する
* 2つのファイルを比較し、重複コードや実装差異を確認する

しかし、これらはいずれもファイル単位の比較となるため、もっと細かい粒度で比較したい場合には不便です。例えば、次のようなシーンではクリップボードと直接 diff を取れると、該当コードを一度ファイルに保存する必要がないのでとても便利です。

* リファクタリングで 2 つのファイルにある類似メソッドを共通化するときに、たしかに同じ（あるいは違う）ということを確認したい
* 2 つのファイルにあるクラスが共通のインタフェースを実装しているが、メソッドの定義順がばらばらなのでファイル同士ではうまく差分を確認できない
* コマンドラインなどの実行結果をエディタの一部分と比較したい（Macだと `pbcopy` コマンドでクリップボードに積めるので）

## まとめ

IntelliJ IDEA の「Compare with Clipboard」機能を簡単に紹介しました。そんなにしょっちゅう使う機能ではありませんが、リファクタリングのときなどにはとても重宝するので、こんなニッチな機能まで備えている IntelliJ IDEA はやっぱり素敵です。 

脱線しますが、未だに WinMerge より使いやすいと思える Mac 用の GUI の diff ツールに出会えずに困っています。有償ならあるのかもしれませんが、Mac の数少ない不満の 1 つです。情報をお持ちの方がいればそっと教えてくださいませ。
destroyのバリデーションするとき、return falseじゃなくてthrow :abortになったよ

# before_destroy
OmniAuthログインできるサービスをつくるとき、facebook,twitter,github,googleなど複数のプロバイダーとアカウントを連携させることがあります。
でも、すべてのアカウント連携を解除してしまうとセッションが切れた時にログインできなくなってしまうので少なくとも一つの認証用アカウントが必要です。

そんなときに、destroyメソッドにバリデーションをつけるために、Rails4までは**before_destroy**を使い、`return false`を返すとコールバックがストップしてくれるのでそうしてました。

# rails5からは`throw :abort`になりました。

今まで通り`errors.full_messages`などが使えます。

[<img width="732" alt="スクリーンショット 2016-12-24 0.22.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/108235/5b902ba5-0122-8511-afbb-250f831245db.png">](https://speakerdeck.com/claudiob/better-callbacks-in-rails-5)

# 

```rb:social_profile.rb
class SocialProfile < ActiveRecord::Base
  belongs_to :user
  store :other
  validates :uid, uniqueness: { scope: :provider }, length: { in: 6..128 }
  validates :provider, inclusion: { in: Settings.auth_config.keys.map(&:to_s) }
  include Logic::SocialProfile
  include Logic::SocialProfile::InitializeWithCallbackInfo

  # before_destroyでdestroyメソッドを実行する前にバリデーションをかけます
  before_destroy :least_one

  private

  def least_one
    if self.user.social_profiles.count == 1
      errors.add :base, '少なくとも1つ、ログイン用の認証が必要です'
      # return false　ではなく throw :abort
      throw :abort
    end
  end
end
```

railsは仕様変更も楽しいですね
ポストエフェクトをもっと手軽に: "PracticalPixelEffects"の紹介


とりあえず、こんな感じのものが作れるようになります。
![ezgif.com-video-to-gif.gif](https://qiita-image-store.s3.amazonaws.com/0/94115/9c77204e-d2b9-a54e-2ed9-c702d069f388.gif)
ヘッダファイルはこちらになります: https://gist.github.com/Pctg-x8/da0000a41a640b7ac5a24c9adea7d02a

## 概要

"PracticalPixelEffects"はポストエフェクトに代表されるようなピクセルエフェクトの製作を補助するSiv3D向けのヘッダライブラリです。Siv3Dでは遅延シェーディングは絵作りまですべてライブラリが面倒を見てくれるためパイプラインに入り込む余地がありませんが、PracticalPixelEffectsは出来上がりのテクスチャおよび描画命令のまとまりを受け取ってエフェクトを適用するので、遅延シェーディングのみならずForward Rendering(適切な日本語訳がわからない)でも利用できるようになっています。
ライセンスはMITです。Gistにあるものをそのままppfx.hなどと命名したファイルに張り付けてご利用いただければと思います。

## 実装

実装としては単純なヘッダライブラリで、ピクセルエフェクトそのものを表し様々な補助関数を有する`PixelEffect`クラスと、GPUを使用して高速にプロシージャルなテクスチャを作成するクラスの補助をする`AcceleratedGeneratorBase`クラスの2つで構成される非常にシンプルなライブラリとなっています。

`PixelEffect`クラスでは、`const String& path, const Size& framesize`の2つを受け取って初期化するようになっています。このクラスのメインとなるメソッドは`void drawEffected(RendererFunction)`となっており、これをオーバーライドすることでコアな表現を提供することになります。引数はエフェクト適用前の、ソースとなるテクスチャを描画するためのコードで、`drawEffected`内部では必ずこのコードを実行する必要があります。サンプルの波紋エフェクトでは次のように定義しています。

```cpp
void drawEffected(RendererFunction func)
{
    this->clearBackbuffer(Palette::Black);
    this->renderToBackbuffer(func);

    Graphics2D::BeginPS(this->shader());
    if(this->mappedTexture.has_value())
    {
        Graphics2D::SetTexture(ShaderStage::Pixel, 1, this->mappedTexture.value());
    }
    else
    {
        Graphics2D::SetTexture(ShaderStage::Pixel, 1, none);
    }
    Graphics2D::SetConstant(ShaderStage::Pixel, 1, this->params);
    this->backbuffer().draw();
    Graphics2D::EndPS();
}
```

前段2行でエフェクト適用元の初期化(どちらも`PixelEffect`クラスで提供されるメソッド)、後段で実際にパラメータを設定してエフェクトの適用を行っています。(Graphics2D::SetTextureにOptionで指定できるオーバーロードがあってもよい(むしろそっちのほうがいい)と思うのですがいかがでしょうか)

続いて`AcceleratedGeneratorBase`クラスですが、こちらは`const String& path`を受け取って初期化するようになっています。こちらは特にオーバーライドすべきメソッドは存在しなくて、追加パラメータ関係のメソッドをはやすだけで使用可能となっています。サンプルの波紋シェーダではディスプレースメントの量と方向を決めるためにプロシージャルテクスチャの生成を行っていますが、その場合は次のようなクラス定義になります。

```cpp
// Accelerated WaterWave Texture Generator
class WaterWaveGenerator : public AcceleratedGeneratorBase
{
	struct OffsetInfoBuffer
	{
		float phaseOffset, padding[3];
	};
	ConstantBuffer<OffsetInfoBuffer> offsetInfo;

	virtual void setAdditionalBuffers() override
	{
		Graphics2D::SetConstant(ShaderStage::Pixel, 2, this->offsetInfo);
	}
public:
	// Initialize generator
	WaterWaveGenerator() : AcceleratedGeneratorBase(L"./waterwave.hlsl") {}

	/// vvv Custom Properties vvv ///

	// Set phase offset of sine curve
	void setPhaseOffset(float ph) { this->offsetInfo->phaseOffset = ph; }
};
```

## シェーダ入力

シェーダ入力セマンティクスはSiv3Dのそれに準拠します。具体的には以下のものを共通で受け取れるようになっています。

```hlsl
struct VSOutput
{
	float4 pos : SV_Position;
	float2 texcoord : TEXCOORD0;
	float4 color : COLOR0;
};
```

## おしまい

簡単にですが以上で紹介を終わりにします。ゲーム作りにおいてポストエフェクトが与える影響というものは図り知れないものがあると思うのでぜひとも絵作りに役立てていただければと思います。

サンプル背景: GTGraphics Windows10 Themeから http://gtgraphics.de/en
プレゼン資料作成について

エンジニアでも社内発表会など、資料作成をする時があると思います。適当に作るより、下記を意識して書いていくと良い資料が作れるのでは？という話です。

### まずは一般的な資料作成のコツ
---

[見やすいプレゼン資料の作り方 - リニューアル増量版](http://www.slideshare.net/yutamorishige50/ss-41321443)

### エンジニア的な資料でわかりやすいやつ
---

↑は一般的な資料作成のコツですが、それを踏まえて他の方の資料を見るとより良くなるかと。個人的に良かったと思うスライドは下記です。

[【改訂版】PHP7で堅牢なコードを書く - 例外処理、表明プログラミング、契約による設計 / PHP Conference 2016 Revised by Takuto Wada](https://speakerdeck.com/twada/php-conference-2016-revised)

[動画版もあります](https://www.youtube.com/watch?v=17i1EL9pBwA)

※余談ですが、最近の動画プレイヤーは倍速再生出来るので、基本的に倍速再生推奨です。

### Markdownの使えるスライド作成ツール
---

Markdownを使える[Marp](https://yhatt.github.io/marp/)という資料作成ツールなどありますので、そちらを使うのもありかもしれないです。Marpは、見た目がカスタマイズできないので嫌だという人もいますが、気にならなければいい感じです。
エンジニアとして気をつけていること 5選

# エンジニアとして気をつけていること 5選

はじめまして、Monstar Lab Inc.でiOSのエンジニアをしている菊池です。

今回は社会人になって大体6年くらい働いたので失敗、問題の経験を振り返って気をつけて行っていること5個を事例を挙げながらお話しようかと思います。<BR>
大きく<プライベート編>、＜仕事編＞に分けて記載いたします。<BR>

## <プライベート編>
### 1. 業界関係者以外の人と話す(折衝を含む)際は、専門的な技術的なキーワードはなるべく避けて相手の人が理解できるキーワードに変換して話すこと

#### Q. 何に失敗したのか?
#### A. 相手は自分が話したキーワードを理解できなかったので会話のキャッチボールが困難になった。

これは各業界方面の人はあるあるの話なのではないかな?と思います。

```
失敗例)
Aさん 「菊池さんってどんなお仕事されているんですか?」
菊池 「普段はiOSのエンジニアやってますね。」
Aさん 「iOSって何ですか？」
菊池 「iOSとはiPhoneの中に入っているAppleが提供するオペレーティングシステムでありまして・・・・」
Aさん 「・・・・・(何それ、わからない・・・)」
```

正直、IT業界の人ならこれで通じますが、iPhoneのシェアが6〜7割ある([日本のiPhone比率は世界一！](http://hikakaku.com/blog/日本のiphone比率は世界一%E3%80%82米国よりなんと30もシェア/))日本でもiOSというキーワードがそれほど認知されてないなと感じた出来事でした。私の経験ですが、10人中4人くらいは何それ?的な反応されました。<BR>
なので、以下のように変換したら割と伝わりました。

```
成功例)
Aさん 「菊池さんってどんなお仕事されているんですか?」
菊池 「普段はiPhoneのアプリ開発をやってますね。」
Aさん「そうなんですねーどんなアプリ作ってるんですか？」
```

こんな感じに会話が続くようになります。「iOS」→「iPhone」これくらいの簡単な変換で伝わり方がかなり違ってきます。iOSよりもiPhoneというキーワードの方が一般的に認知されているからだと思われます。<BR>
人に説明するということは自分の話したいことを一方的に伝えるのではなくて、人に理解してもらって初めて成立すると自分は考えています。なので、会話しながらうまく伝わってないかなと思ったら相手に理解してもらえそうなキーワードに変換するということを心がけてみてはいかがでしょうか？<BR>
また、逆説的に応用するなら会話する相手の業界のキーワードを覚えると会話がスムーズになると思うので仲良くなれるチャンスが増えるかと思います。

### 2. セミナーには積極的に参加してみること
#### Q. 何に失敗したのか?
#### A. 普段の業務だけだと自分のスキル不足(井の中の蛙)を痛感する。

同じPJに長期間所属しているとどうしてもそこでの運用ルールや開発が優先されると思います。それだけをずっとこなしているとそれで良いかと満足してしまって、どんどん技術が進化していっているのにそのうちレガシー(時代遅れな)な技術を続けることになり置いてかされるかもしれません。
普段の業務以外の技術をキャッチアップしやすくするために勉強会に参加してみてはいかがでしょうか?<BR>
私が普段勉強会を探すときに利用しているサービスをここで紹介したいと思います。土日のイベントもよくやってるので平日よりも参加しやすいかもしれません。

##### connpass - エンジニアをつなぐIT勉強会支援プラットフォーム
* https://connpass.com

##### Doorkeeper: セミナー・勉強会・イベント管理ツール
* https://www.doorkeeper.jp

##### dots. [ドッツ] - IT勉強会・セミナーなどのイベント情報サイト
* https://eventdots.jp

##### OpenCU | Learning Platform Designed for Creative
* http://www.opencu.com

## <仕事編>
### 3. 仕事は時間で管理すること

#### Q. 何に失敗したのか?
#### A. 複数の仕事を抱えすぎてキャパオーバーを起こす。そして体調を崩して仕事ができなくなる。

これはもしかしたら、私の考え方に反対な意見を持つ方がいるかもしれません。仕事の向き合い方の考え方の1つと捉えていただければと思います。<BR>
まず仕事は時間で管理することとか当たり前ではないかと思うかもしれませんが、経験上自分も含めてできない人はたくさんいたと思います。どうしても納期があるとトラブルや割り込み作業があったりして仕事が積み上がってくるとパニックになってきて振り切ってやろうとすると大概正常な判断ができなくなり大きな失敗を起こします。<BR>
私が行ったことは改善策は一つ一つの細かいタスクを時間換算すること。それで見積もり上難しい場合はリスケを行う。また、急な依頼や割り込み作業は全て鵜呑みにせず、可能であるならやるができないなら断るくらいをした方が良いと考えています。<BR>
自分の仕事のせいだけでなく、ビジネス的な理由で対応を急ぐ場面は遭遇するかもしれません。その場合でもまずは冷静に分析し、次のタイミングで実施するか今対応するかは上長の判断等で柔軟に判断すれば良いかと思います。<BR>
時間換算をすることが上長の判断材料になるケースは多いはずです。

### 4. 説明は図を多用すること

#### Q. 何に失敗したのか?
#### A. 会話だけの説明だと仕様を理解してもらえないことが多発する。

これは<プライベート編>.1に通ずる内容なのですが、技術的な内容を会話のみで相手に理解してもらうのは普段仕事をしていて難易度が高いと考えています。<BR>
処理が複雑であるならシーケンス図を書くなり、システムの振る舞いを説明したいならユースケース図を書いたりして説明した方が相手に理解してもらえます。エビデンスにもなるので後から入った新規メンバーにも情報共有がしやすいです。<BR>
ただ、これらの図を完璧に書く必要はないと考えています。仕様を理解してもらうことがポイントなので伝われば無駄に工数をかけず簡略化して良いと考えています。

### 5. 挨拶をすること

#### Q. 何が問題なのか?
#### A. 開発はチーム戦が多いです。一人で仕事はできるかもしれませんが、多くの人に支えてもらって世の中のサービスは成り立っています。

挨拶をしてください。今までの経験上私も含めてエンジニアのコミュ症率は非常に高いと考えています。無言で出社、退社するよりもちょっとの会話で心を開いてくれて相手と仲良くなれたりするものです。仕事上で仕様的な問題にぶつかったりする際は相談できる良きパートナーになるかもしれません。<BR>
意識的にいつも朝、夜、すれ違いで挨拶をしているのですが現状挨拶をしてくれない方も中にはいらっしゃいます。シャイなんだと思ってポジティブに考えています。<BR>
「うっす」、「・・っす」、うなずくくらいからでも良いのでぜひできてない人はやってみてください。

次回は技術ネタを書いていきたいと思います。
広告に夢を求めて

# この記事を書いたきっかけ
　一番最初はAmazon Lambdaのことを書こうと思ったけど、もうすでにそういう記事はたくさんあるので、書かなくていいと思った。次に、Amazon Auroraの話を書こうかと思ったけど、流石に1つのAdvent Calendarに3つのAurora記事を自分で書くのは気が引けてやめた。そして、これからやってくるであろう受難の時代のために私達が何をできるのか、というのを考えたけど、それは1ヶ月や2ヶ月で終わるテーマじゃなかった。

　なので、ここでは、私が昔嫌で嫌で仕方がなかったはずなのに、今、それについて何をおいても1番に取り組まないといけないと思っているインターネット広告について、私の考えがどう変わってきたのかを書きたいと思う。エンジニア的には共感してくれる人も多いといいなと思っている。

　ちなみに、この記事は主観的なもので、私が属する会社の意見を代表するようなものではないので、それには注意してほしいと思う。

# インターネット広告とのなれそめ

　初めてのインターネット広告への接触は、多分どっかのホームページのバナー広告だったんじゃないかと思う。1998年〜2000年前後、Yahoo!とかInfoseekとか、まだあんまりみんなググっていなかったころだ。そういうときにバナー広告を見ていたけど、特にクリックしたいな、とは思わなかった。

　自分が作っているホームページが本に載ったり、いくつかソフトウェアを公開しているうちに、うちの広告を掲載してくれませんか、っていう奇特な企業も現れたりした。でもその時の私は（GoogleやNECの数年遅れで）ホームページのリンク構造を解析するのに夢中で、そういうのに興味はなかったからスルーしていた。
　そのうちに、どんどんバナー広告は増えてきたけど、そんなに意識する存在でもなかった。

　そして、GoogleさんがAdWordsやAdSenseを持ってきた。Googleが広告をやるなんて！って多分みんなが思ってた。でも、Googleは最近までEvilじゃなかったので、そうは言ってもみんなGoogleを信じていたけどね。

　その後、Amazon.comもアフィリエイトを持ってきた。Amazonアソシエイトというやつ。そうこうするうちに、雨後の筍のようにアフィリエイトをやるECサイトがたくさんできた。なんかホームページにアフィリエイトを貼り付けると非難される時代で、私のインターネット広告への第1の印象はこれだった。

# インターネット広告事業との関わり

　その後、アドテクとかProgrammatic Advertisingとかいうのが勃興し、隆盛を極めている、というのは恥ずかしながら去年になってから知ったんだけど、広告はインターネットで何かを見たり、調べたりするために邪魔な存在で、なんとかして時間を取ろうとして、なんとかしてクリックさせよう、タップさせよう、という存在でしかなかった。

　私は個人の自由を信じていたので、個人の情報が企業に握られる、ということについて、あまり良く思っていなかった。なんで広告をやるために情報を集めるのか、なんで商品を売るために個人のプライバシーを犠牲にするのか、その謎を解き明かす前に、その力関係をなんとか逆転できないものか、と考えた。

　その取り組みは、残念ながら今は実現していないけど、そのうち、この十年くらいには実現できると思っている。

　ともあれ、なんでそんなことするの？って思っていた。

　そんなとき、仕事でインターネット広告に取り組むという壁が私の前に立ちふさがった。

　悩み、調べ、書いた。そのおかげでインターネットでここ10年でやることには困らないくらいの課題がたくさんできた。

# それでは、これからどうするか？

　そこで考えたことで、広告についてよく言われていることの一つは、広告はそれを本当に欲しがっている人に出してあげるのであれば、その人達の役に立つものになるんじゃないか、ということだ。

　私が欲しいものを提示してくれたら、私はそれを見て、それを買う。欲しいものが出るなら、たくさん買うし、たくさんクリックするよね。

　でも、それが本当に自動化されたとき、私が欲しいものは何なんだろう？私の個人情報とはなんだろう？

　そしてもう一つは、「広告」というくくりでなくても、大体の技術は私達の消費を効率化することで成り立っているということだ。

　広告だけが目立つから、広告についてあれこれいうけど、最近のベンチャーは広告の代わりに何かを効率化することでどこかから何かを生み出すビジネスだ。

　そうしたら、何もかもを効率化してしまったときに、私達に残るものはなんだろう？

　その答えは今はないけど、それに一番近づけるのが、広告を仕事にする、ということなんだと思う。

　人工知能とか、次世代の人類とかじゃなくて、私達を一番最初に脅かすのは広告なんじゃないだろうか？そして、そんな心配をしなくても、広告や、広告に突き動かされて何かをする、ということを超えて、私達は自分たちの何がオリジナリティーなのか、ということを見つけ出せるんじゃないだろうか？

　私たちは無理でも、私達の子供たちはそういうものを見つけられるんだと思う。

　少なくとも私たちは前の世代が反発していたいろいろなものを受け入れて今ここにいる。私達の子供たちもそうであると信じたい。

　かつて手書きの履歴書が印字した履歴書よりも真面目さがある、と言われたように、広告も昔は邪魔な存在だったけど、と言われるようになるだろう。

　そうなったとき、私たちは広告に費やしていた時間をまるまる削ることができるようになる。

　その時、私たちは広告を使ってどんなことをするんだろう？
Flexboxを使ってみた

# 自己紹介
HAL大阪卒
Tech:Campでエンジニアをしている山本です。
初めての投稿なので至らないことがありますがよろしくお願いします。
[HAL Advent Calendar 2016](http://qiita.com/advent-calendar/2016/hal)
HAL生によるアドベントカレンダーで投稿した記事です。

※今回は画像がないのでわかりにくいです。。。

#Flexboxの概要
複雑な Web ページをレイアウトすることを目的とし、画面やブラウザー ウィンドウのサイズがさまざまに変化する場合にも要素の相対的な位置とサイズを一定に保つ場合に、特に役立ちます。位置とサイズを正しく設定するのが難しいフロートへの依存を軽減できます。

[IE10の開発者向けガイド](https://msdn.microsoft.com/library/hh673531(v=vs.85).aspx)から引用

前から気にはなっていたのだがBootstrapなどがあったので使う機会がなかった。
この機会に勉強してみました。

##Flexboxの便利なこと
今まで色んなプロパイを組み合わせていたことがFlexboxなら簡単にできる

- CSSで一行追加するだけで横並びにできる
- 横並びになった要素の高さが最初から揃ってる
- 要素を上下左右、好きな順序に並び替えられる
- スペースの操作も自由自在
- 高さの異なる横並びの要素を、簡単に上下中央揃え

#では実際に使用してみる
```html:html
  <ul class="flexbox">
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
  </ul>

```

##基本レイアウト
適用したい要素の**親要素**にflexを指定します。

```css:css
  .flexbox {
    display: flex;
  }

```


##上から下に配置
上から下に配置させる場合はflex-direction: column;を指定します。

```css:css
  .flexbox {
    display: flex;
    flex-direction: column;
  }

```



##下から上に配置
「column」と同じで縦に配置されるが、並ぶ順序は「下から上」場合はcolumn-reverse;を指定します。

```css:css
  .flexbox {
    display: flex;
    flex-direction: column-reverse;
  }

```

##左寄せ
左に寄せる場合はjustify-content: flex-start;を指定する

```css:css
  .flexbox {
    display: flex;
    justify-content: flex-start;
  }

```

##右寄せ
右に寄せる場合はjustify-content: flex-end;を指定します。

```css:css
  .flexbox {
    display: flex;
    justify-content: flex-end;
  }

```



##中央寄せ
中央に寄せる場合はjustify-content: center;を指定します。

```css:css
  .flexbox {
    display: flex;
    justify-content: center;
  }

```



##均等に間隔をあける
均等に間隔をあける場合はjustify-content: space-between;を指定します。

```css:css
  .flexbox {
    display: flex;
    justify-content: space-between;
  }

```


##左右の端にも半分ずつ間隔を空ける
均等なおかつ左右の端にも半分ずつ間隔を空けるのはjustify-content: space-around;を指定します。

```css:css
  .flexbox {
    display: flex;
    justify-content: space-around;
  }

```



##あとがき
とりあえず画像の貼り付け方がわからなかったので諦めました。。。
また勉強して編集します
すごくわかりにくいですが申し訳ないです。



などなどこのようにfloatなどを使わなくても簡単にできます。
他にも色々組み合わせることで便利に使えます。
勉強不足で伝えるのが下手くそで申し訳ないです。。。。
最後までありがとうございました。
Google Cloud Speech APIの利用方法について（syncrecognizeメソッド）

# はじめに
本投稿の情報を利用することによって生じるいかなる損害についても、責任を負うものではありません。
また、発言は個人の見解であり、所属する組織の見解ではありません。


# 音声認識について
近年GoogleやMicrosoft、IBMをはじめとする企業において、ディクテーション（書き起こし）を行うAPIがリリースされています。今回はこの中から近年８割から９割近い制度を叩き出していると噂のGoogle Cloud Speech API を使ってみました。

※参考  
Google [Google Cloud Speech API](https://cloud.google.com/speech/)  
Microsoft [Bing Speech API](https://azure.microsoft.com/ja-jp/services/cognitive-services/speech/)  
IBM [Speech to Text](http://www.ibm.com/smarterplanet/jp/ja/ibmwatson/developercloud/speech-to-text.html)  

# APIを使ってみる（準備編）

各社とも前節のリンクからリアルタイムで試すことはできます。

<img width="1362" alt="音声認識.png" src="https://qiita-image-store.s3.amazonaws.com/0/135467/9a164db9-41a5-987c-4780-67b08343b1ea.png">
↑”日本語（日本）”を選択してマイクアイコンからディクテーションが可能です。

せっかくなら録音した長文（〜60sec）も試してみたいところ。

利用までの手順は大きく４つ  
①プロジェクトを作成する
②APIを有効にする
③APIキーを生成する
④Webコンソールorお好みの言語からAPIを叩く

①〜③に関しては参考資料を参照していただくか、[QuickStart](https://cloud.google.com/speech/docs/getting-started)を参考にされることをおすすめします。

# APIを使ってみる（実行編）
Google Cloud Storageに保存した音声をAPIに投げて、認識結果を受け取ります。

## Google Storageからファイルを読み込む
Google Storageに音声ファイルを上げ、APIに投げるためにJSONファイルに音声の詳細をまとめる


``` sync-request.json  
{
  'config': {  
      'encoding':'LINEAR16',
      'sampleRate': 16000,
      'languageCode': 'ja-JP'
  },
  'audio': {
      'uri':'gs://cloud-samples-tests/speech/brooklyn.flac'
  }
}  
```

### config  
encoding:拡張子を指定します。".wav"で読み込む際は'LINEAR16'とします。
sampleRate:サンプリング周波数を指定します。ファイルと一致してないと動かないです。
languageCode: 言語情報を指定します。（英語のときは’en-US’）

### audio  
uri:ファイルの保存先を指定します。今回はGoogle StorageのURIを指定します。

## サービスアカウントを認証
サービスアカウントキーを[認証情報を作成](https://console.cloud.google.com/apis/credentials)から作成し、以下のコマンドを実行  

```      
$ gcloud auth activate-service-account --key-file=service-account-key-file
```

## アクセストークンの発行

```
$ gcloud auth print-access-token

access_token //APIを叩くときに利用
```
## syncrecognizeメソッドを実行

```
$ curl -s -k -H "Content-Type: application/json" \
    -H "Authorization: Bearer access_token" \
    https://speech.googleapis.com/v1beta1/speech:syncrecognize \
    -d @sync-request.json
```
”access_token”には前項で取得したものを利用

```
{
  "results": [
    {
      "alternatives": [
        {
          "transcript": "こんにちは",
          "confidence": 0.00000000
        }
      ]
    }
  ]
}

```


# おわりに
今回はGoogle Cloud Speech APIの利用方法について簡単にまとめました。
何はともあれ分からないことがあれば公式ドキュメントを参照ください。
[Google Cloud Speech API Documentation](https://cloud.google.com/speech/docs/)
60sec以上の文章を読み込ませる場合に関してはまた改めて書きたいと思います。


# 参考  
[Google Cloud Speech API Beta でwavファイルの音声認識](http://qiita.com/sn6/items/a227cc92453817eeab11)
[]()
uwsgiをEC2インスタンスにインストールしようとして失敗した話

#概要
EC2インスタンスにuwsgiをインストールして失敗したので、
トラブルシューティング用のメモ

#背景
もともと、pythonのフレームワーク"Django"を使ってWEBアプリケーションを作っていました。
それをEC2上でnginx+wsgiで動かそうとして、インストール中にエラーが出たという感じです。
開発経験は皆無なので、なんでその仕様で動かそうとしたの？って突っ込まれたら、
(特に理由は)ないです
って答えちゃうと思うのですが、コメントいただければ参考にします。

#環境
##EC2インスタンスのスペック
- OS：Red Hat 7.3
- インスタンスタイプ：t2.micro


#手順
というわけでEC2インスタンスにインストール

`pip install uwsgi`

しようとしたら、こんなエラーが出てきてしまった。

>Traceback (most recent call last):
    File "<string>", line 1, in <module>
    File "/tmp/pip-build-pV1pAc/uwsgi/setup.py", line 124, in <module>
      distclass=uWSGIDistribution,
    File "/usr/lib64/python2.7/distutils/core.py", line 152, in setup
      dist.run_commands()
    File "/usr/lib64/python2.7/distutils/dist.py", line 953, in run_commands
      self.run_command(cmd)
    File "/usr/lib64/python2.7/distutils/dist.py", line 972, in run_command
      cmd_obj.run()
    File "/usr/lib/python2.7/site-packages/wheel/bdist_wheel.py", line 215, in run
      self.run_command('install')
    File "/usr/lib64/python2.7/distutils/cmd.py", line 326, in run_command
      self.distribution.run_command(command)
    File "/usr/lib64/python2.7/distutils/dist.py", line 972, in run_command
      cmd_obj.run()
    File "/tmp/pip-build-pV1pAc/uwsgi/setup.py", line 77, in run
      conf = uc.uConf(get_profile())
    File "uwsgiconfig.py", line 742, in __init__
      raise Exception("you need a C compiler to build uWSGI")
  Exception: you need a C compiler to build uWSGI
  ----------------------------------------
  Failed building wheel for uwsgi

C compilerが必要だぞ！って怒られちゃいました。
じゃあC compilerが使えるようにしよう。

そしてググってみた。

結果、そういえばDevelopment Toolをインストールしていなかったので、
インストールしてみよう。

`sudo yum groupinstall "Development Tools"`

これでインストールできた。
というわけで再度インストール。

>   In file included from plugins/python/python_plugin.c:1:0:
    plugins/python/uwsgi_python.h:2:20: 致命的エラー: Python.h: そのようなファイルやディレクトリはありません
     \#include \<Python.h>

    コンパイルを停止しました。


うわぁ。。。マジか。。。
ファイルがないと怒られてしまったので、再度ググりました。
参考記事：http://zashikiro.hateblo.jp/entry/2012/10/02/130031

というわけで、python2.7-devというパッケージをインストール。
`sudo yum install python-devel`
これでPython.hが参照できるようになるはず。

再度挑戦してみよう。

すると。。。
>Collecting uwsgi
  Using cached uwsgi-2.0.14.tar.gz
Building wheels for collected packages: uwsgi
  Running setup.py bdist_wheel for uwsgi ... done
  Stored in directory: /root/.cache/pip/wheels/c4/ad/56/f70a70b63fa4b0f2c0518db6f41381c9d33cd5cc5ac9a9494b
Successfully built uwsgi
Installing collected packages: uwsgi
Successfully installed uwsgi-2.0.14

インストールできた！やったね！

というわけで今度はデプロイするところまでやってみようかな〜
[はじめての深層学習]Deelインストール後のサンプル実行時のメモ

shi3zさんの作られたDeelをインストールしてみました。
※参考書籍をご参照下さい
CUDAとかgitとかpythonとかはDIGITSで構築したり
別の参考書籍でChainerをインストールしていたので
詳細は飛ばしてtiny.pyの実行から始めたのですが
いきなりエラーに見舞われたので上手くいった手順メモです。

書籍内のリスト1.1の tiny.pyを実行すると
下記のようにprotobuf2がないと言われる。

```
python tiny.py
Traceback (most recent call last):
  File "tiny.py", line 2, in <module>
    from deel.network import *
  File "/home/keigo/Development/deel/deel/network/__init__.py", line 5, in <module>
    from deel.model.caffefunction import CaffeFunction
  File "/home/keigo/Development/deel/deel/model/caffefunction.py", line 38, in <module>
    from chainer.links.caffe.protobuf2 import caffe_pb2 as caffe_pb
ImportError: No module named protobuf2
```

##tiny.pyが実行出来た方法

chainer のバージョンは参考書の中では
1.14.1との事でしたがそのバージョンを指定したらこれまた
バージョンが存在しないと言われます。
1.17.0をインストールしてみたら上手くサンプルは動きました。

###インストール
$ sudo pip install chainer=="1.17.0"


###Chainerのバージョン指定インストール
```
$ python
Python 2.7.6 (default, Jun 22 2015, 17:58:13) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import chainer
chainer.__version__
>>> chainer.__version__
'1.17.0'
```

###tiny.py実行
```
$ python tiny.py
Loading bvlc_alexnet.caffemodel
Converting from bvlc_alexnet.caffemodel
data 5
conv1 4
relu1 18
norm1 15
pool1 17
conv2 4
relu2 18
norm2 15
pool2 17
conv3 4
relu3 18
conv4 4
relu4 18
conv5 4
relu5 18
pool5 17
fc6 14
relu6 18
drop6 6
fc7 14
relu7 18
drop7 6
fc8 14
loss 21
#1 | loupe, | 22.5%
#2 | hook, | 10.0%
#3 | corkscrew, |  5.2%
#4 | combination |  4.2%
#5 | stethoscope |  4.1%
#6 | buckle |  4.0%
#7 | face |  3.3%
#8 | stopwatch, |  2.5%
#9 | cassette |  2.0%
#10 | analog |  1.4%
#11 | knot |  1.4%
#12 | digital |  1.4%
#13 | chain |  1.2%
#14 | padlock |  1.2%
#15 | muzzle |  1.1%
#16 | magnetic |  1.0%
#17 | lens |  1.0%
#18 | sunglasses, |  0.9%
#19 | whistle |  0.8%
#20 | nail |  0.8%
```

まぁ、本を読み進める上でバージョンがこれでいいのか
怪しいですがとりあえず、このまま進めていき
駄目だったら本記事を併せて修正します。
まずは備忘録的にメモを残します。

参考書
[はじめての深層学習(ディープラーニング)プログラミング ](https://www.amazon.co.jp/exec/obidos/ASIN/4774185345/minatokuakasa-22/)
[github uei/deel]
(https://github.com/uei/deel/tree/master/examples)
OnsenUIでSpineを動かすまで

# 使うもの
OnsenUI
https://ja.onsen.io/

Spine
http://ja.esotericsoftware.com/

# SpineRuntime
https://github.com/EsotericSoftware/spine-runtimes/tree/master/spine-ts
で、Canvasを利用

# Spineアニメーションデータおよび表示参考HTML
https://github.com/EsotericSoftware/spine-runtimes/tree/master/spine-ts/canvas/example
から持ってきます

# OnsenUIでSpineアニメーション表示する

```
<canvas id="canvas"></canvas>
```
を表示したいところに入れるだけですが、
```
<ons-page>
</ons-page>
```
内にcanvasを入れて表示するため、
```
ons.ready(function() {
   // spineの初期化などなど
});
```
を利用しましょう。
(<ons-page></ons-page>タグの後に<script></script>を書いてそこで初期化してもcanvasのサイズが０になるようで表示されないです)

# できたもの
![image](https://qiita-image-store.s3.amazonaws.com/0/142784/371f1b21-5262-e56d-b84e-ce42eaf52300.png)
※つなぎ合わせてます

# その他
## 当たり前といえば当たり前ですが
```
// これはOK
<ons-list-item tappable v-for="item in items">

// これはだめ(v-forを最初に入れたらダメですよねぇ
<v-for="item in items" ons-list-item tappable>
```
２０分ぐらい悩んだので残すｗ
How to plant a Christmas tree ?

こんにちは、Perl 6 Advent Calendar 2016の24日目の投稿になります。
今回は、Inline::Perl5でPerl 5の[Acme::POE::Tree](http://search.cpan.org/~rcaputo/Acme-POE-Tree-1.022/lib/Acme/POE/Tree.pm)を呼び出してクリスマスツリーを植えたいと思います。

# イントロダクション

+ 下記プログラムを動かしてみましょう

```pl:poetree.p6
use Acme::POE::Tree:from<Perl5>;

my $tree = Acme::POE::Tree.new(
    star_delay => 11.5,
    light_delay => 2,
    run_for => 10
);

$tree.run;
```

+ 実行してみましょう

```bash:木が生えない？
$ perl6 poetree.p6
Can't use string ("run_for") as a HASH ref while "strict refs" in use at /home/itoyota/perl5/perlbrew/perls/perl-5.24.0/lib/site_perl/5.24.0/Acme/POE/Tree.pm line 19.
```

+ うまく実行できませんね。ではどうしたらよいでしょうか

# クリスマスツリーの植え方

+ `${}`でハッシュをitem context(※)にしたものを渡すようにしましょう
+ プログラムを下記のように書き直してみましょう

(※itemについてより詳しく知りたい方はこちらを参照してください：https://docs.perl6.org/type/Any#sub_item)

```pl:poetree.p6
use Acme::POE::Tree:from<Perl5>;

my $tree = Acme::POE::Tree.new(
    ${
        star_delay => 11.5,
        light_delay => 2,
        run_for => 10
    }
);

$tree.run;
```

# 🎄

+ では、実行してみましょう。

![tty.gif](https://qiita-image-store.s3.amazonaws.com/0/149227/d8b6fa20-9fb4-a8f8-ba25-dc4e85768749.gif)

以上、Perl 6 Advent Calendar 2016の24日目の投稿でした。

**P.S.**
実は、この解決策を教えてくれたのはInline::Perl5の開発者の方です。
https://github.com/niner/Inline-Perl5/issues/85
勢いで買ってしまいそうなデバイスとか色々（2016末版）

# 勢いで買ってしまいそうなデバイスとか色々（2016末版）

今年見かけた色々なものをつらつらと

## [gatebox](http://gatebox.ai/) (空間ディスプレイ)

空間ディスプレイにホログラムのようにキャラクターを映し出す
カメラ・マイク・メールなどでコミュニケーションができ、google homeやamazon echoのようなホームアシスタントのような立ち位置での利用
ディラッドボード＋小型の短焦点プロジェクターのような感じ実現しているようです
HDMIで外部から入力もできるから、色々出来ますよねこれ
値段が気軽には手を出せないなぁ(30万)

## [holovect](https://www.kickstarter.com/projects/2029950924/holovect-holographic-vector-display)（空間ディスプレイ）

こちらはレーザで実際に空間に描画するタイプの空間ディスプレイ
霧とか描画するためのものなしで描いているようなのだがどうやっているんだろう
これが発達していくと映画の世界が再現できそう

## [ossic-x](https://www.kickstarter.com/projects/248983394/ossic-x-the-first-3d-audio-headphones-calibrated-t)（サウンド）

今までVR用のヘッドホン、と思っていたけどVR用ではないですね
VR利用に最適なヘッドホン

頭の大きさ、耳の形状など検知する機構があって、内部のジャイロセンサー複数の音源（片耳４つ？)により全方位から聞こえてくる音を再現するそうです

VR系のガジェットは色々でているけどその中でも一番欲しい

## [idoll](http://idoll.tokyo/)(ロボ)

最近は実物をイベントとかで見かけます
いつ発売するんだろう

駆動系を外に持っているので人形部分は小型
スマートフォンのアプリで操作とかも

## [MOFI7](http://speecys.com/MOFI7.html)(ロボ)

高いけど、MMDのモーションを使えるらしい
RaspberryPiで作られている？
こちらもサーボモータ外側もっている

## [teslasuit](https://www.kickstarter.com/projects/247607504/teslasuit-feel-what-you-play)(フィードバック)


全身に低周波治療機がある感じ？でいいのかな
スーツの電気刺激でゲーム中で触れたものや銃弾とかの衝撃とかをフィードバック
値段高い方のモデル(Prodigy)は52箇所電気刺激を流すところがあるらしい

## [nunulo](http://www.nunulo.com/about-nunulo)(VR)

レンズにこだわったVRデバイス（カードボード）

## [dextarobotics](http://www.dextarobotics.com/)(フィードバック)

触覚再現
物体に触った触覚をフィードバック
振動で触ったことを伝えるものではなく、外骨格使ってフィードバック

## [rephone-kit](https://www.kickstarter.com/projects/seeed/rephone-kit-worlds-first-open-source-and-modular-p)(DIY)

携帯電話の自作
去年あたりからずっとやりたいと思って、手を出せずにいる。
rephone-kit３Gに対応しているんだけど、日本のバンドには対応していないから実際に買っても動かないはず（日本対応版でないかなぁ）
実際にラズベリーパイとかで3GSIMモジュールとか買うと3万ぐらいするので、色々部品自力で集めるとDIYで7万近くいきそうなんですよねぇ
文章の幸せ度を判定するプラグインを作ってみた

予定よりも時間が過ぎてしまいましたが、年明けまでには完成したので許してください。
こちらが完成のコードです。
https://github.com/Ooshita/hapinaser.vim

GooglePlatformのNatural Language APIを使用して文章のネガポジ判定を行うプラグインです。

![alt](https://raw.githubusercontent.com/Ooshita/hapinaser.vim/master/art/vim_sentime.gif)

解析したい文章の行にカーソルを合わせてノーマルモードの時に<C-g> (Ctrlとg)を押すと解析が始まります。

documentSentimentというのが文章全体の解析結果であり、そこの行だけ表示しています。
scoreは-1から1の間を取り、−１に近いほどネガティブな表現、1に近いほどポジティブな表現ということになります。

magnitudeは文章が感情的であるかを表しています。
詳しくはこちらのURLを見てください。
https://cloud.google.com/natural-language/docs/sentiment-tutorial

24日に公開する予定でしたが、vim scriptの初心者ということもあり、予定より結構遅れましたが、vim pluginを書くことはかなり楽しく、いい遊びになりました。

途中で助けていただいたり参考になるコードを見せてくれた@mattnさん、変数についておしえてくれた@tyruさんに感謝いたします。

[今後の予定]
文章の幸福度によってvimのカラースキーマの色を変えることや文章全体のネガポジ判定をするのとかやりたいです。では良いお年を！！
手書きで数式を書きつつストレス無くノートをデジタル化する方法

まず @srtk86 さん，[数学 Advent Calendar 2016](http://qiita.com/advent-calendar/2016/math)  をオーガナイズしていただき，
ありがとうございます．
実は [数学 Advent Calendar 2015](http://qiita.com/advent-calendar/2015/math) は私がオーガナイズしていまして，
今年も作ろうと思った矢先に，カレンダーが出来ていてとても嬉しかったです．
そして， [昨年のカレンダー](http://qiita.com/advent-calendar/2015/math) にリンクまでしていただき感謝しています．
***

# 手書きで数式を書きつつストレス無くノートをデジタル化する方法

1. [ペンタブ](https://amzn.to/2Id272j)で[Math](http://webdemo.myscript.com/views/math.html#)に数式を書く
2. $\TeX$ に変換  
3. ペースト

以上の方法で僕は手書きの数式をデジタルで保存しています．
***
## なぜ数学のノート[^1]をデジタル化したいのか
* 分散しがちな様々な分野の手書きのメモやノートを一元化したい．

## 試した過程
そこで，デジタルにして管理しようと考えました．
しかし $\TeX$ で書くと集中力が途切れがちでした．
手書きの数式を改めて $\TeX$ にするのも，数学をするという本来の目的からすると時間のムダに思えました．

* そこでまずは $\TeX$ 表記は諦め，iPad発売当初(2010年)，スタイラスを使いました．
しかしあまり良いアプリが無く，書きづらかったり，不安定だったりで結局は手書きのノートに戻っていました．
当時の画像です．
![IMG_0120.jpg](https://qiita-image-store.s3.amazonaws.com/0/65919/970c0c74-14aa-503d-352f-e3db450c552a.jpeg)

* 次に，ページを入れ替えられるという機能で[ルーズリーフ](http://amzn.to/2i0WOW2)を使っていました．
しかし，数式以外の文字はキーボード入力の方が速く，綺麗．．．

* そんな折，iPad Pro と apple pencil の発売(2015年)
改めて数学のノートのデジタル化を試そうと考えました．

* iPad Pro & apple pencil と surface を試しました．
書く際にディスプレイを近くで見続けると目が疲れる(気がする)ので，保留にしました．
目の疲れが気にならない方は良いかもしれません．[^2]

* 次に，google keep の手書き機能を試しました．
nexus4, 5, 5x, 7(2012), chromebook, macbook pro で試しました．
書いていないところに書かれたり，
redoが出来ず，一度消しゴムで消したら全て同期してしまったり，
使いづらかったです．
当時の画像です．
<img width="1680" alt="Screen Shot 2016-12-23 at 15.00.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/65919/9f7181c5-b458-ab3b-89f4-b62e32580906.png">

* その後，数式を手で書くと $\TeX$ に変換するサイト[Math](http://webdemo.myscript.com/views/math.html#)を知り，
その際に， [WACOMのペンタブ](https://amzn.to/2Id272j)を導入してみました．

1. [ペンタブ](https://amzn.to/2Id272j)で[Math](http://webdemo.myscript.com/views/math.html#)に数式を書く
2. $\TeX$ に変換  
3. ペースト

<img width="1680" alt="Screen Shot 2016-11-24 at 19.26.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/65919/7de6ba7c-caab-d4bc-38f7-739ace17a399.png">

以上で手書きの数式がデジタルで保存できます．
***
この方法によって，数式を $\TeX$ 表記にするストレスが軽減でき数学に集中できるようになりました．
僕の場合，集中して数学が出来るのは基本的に自宅なので，iPad Pro のような携帯性は無くても構いませんでした．
みなさんのお役に立てたら幸いです．

ちなみに，
[機械学習に必要な高校数学やり直しアドベントカレンダー Advent Calendar 2016](http://qiita.com/advent-calendar/2016/math_for_ml)の[24日](http://hidenori-t.hatenablog.jp/entry/2016/12/23/194356)にも参加させていただいたので，読んでいただけたら嬉しいです．

それでは，みなさん良いクリスマスを!! :santa:[^3]

***
[^1]: 数学のノートの取り方について[この本](https://amzn.to/2Id2ZnB)がおすすめです．
[^2]: ディスプレイよりも紙を見たときのほうが情報処理の効率が上がるということが言われているようです．
[^3]: Please donate at [wish list](http://amzn.to/343JRQu) if you find this useful:thumbsup_tone1: