OmniAICreator/Qiita-1.07M huggingface dataset:
JavaScript バブルソート

##バブルソート(単純交換方)
「泡」が浮かび上がるように値が移動していくので「バブルソート」と呼ばれる。
すべての隣りあった値を比べて行って、小さい方が前に移動するように交換する。
データが大量になると時間がかかってしまう。

**手順**
前提　配列に未整列の値が用意してある
1 末尾の二つの値を比べる。後ろの値が小さい場合、前の値と交換する。
2 前方に向かって繰り返す
3 添字(index)0まで繰り返すと、「最も小さい値」が先頭になる
4 残りの値にも同じように処理を繰り返す
5 最後まで処理が終わると昇順に並んでいる

```script.js
//ソート前の配列データ
var a = [1,3,10,2,8];

//調べる範囲の開始位置を１つずつ後ろへ移動するfor文
for(var i = 0; i < a.length; i++){
    //後ろから前に向かって小さい値を浮かび上がらせるfor文
    for(var j = a.length-1; j>i ; j-- ){
        //隣りあう２つの値を比べて、後ろが小さければ交換する
        if(a[j]<a[j-1]){
            var tmp = a[j];
            a[j] = a[j-1];
            a[j-1] =tmp;
        }
    }
}
//ソート後の配列の表示
console.log(a);
```

**補足**
・「浮かび上がらせる範囲の開始位置を後ろに移動するfor文」
・「小さい値を後ろから前へ浮かび上がらせるfor文」
二重の繰り返しをおこなっている。
dinghyでもSSHポートフォワードして `https://localhost` でアクセスできるようにする

# TL;DR

```bash
$ sudo bash -c "$(dinghy env); ssh docker@$(dinghy ip) -i $DOCKER_CERT_PATH/id_rsa -L 443:localhost:443"
```

# 背景
Docker for Macだと IOが遅くて多少マシなdinghyを使ってる。

dinghyだと内部的にVirtualBoxでboot2dockerのVMが動いてるので、例えばホストの80番ポートをバインドすると、localhostではなくてVM上の80ポートがバインドされる。

IPアドレスは `dinghy ip` コマンドで確認できるので、多くの場合は、 `http://(dinghyのIPアドレス)` みたいなかんじでIPアドレス指定でアクセスするなり、 `hoge.localdomain` みたいな適当なホスト名で `/etc/hosts` に登録しておけば問題ない。

しかしながら、Google認証のOAuth2のリダイレクトのテストとかをローカルでやろうとすると、 `https://localhost` みたいなURLでアクセスできないと困ることがある。Google認証のリダイレクトURLは正式なTLD (TopLevelDomain) ではない `hoge.localdomain` みたいな 適当なドメイン名は登録できずエラーになる。ただしテスト用に `localhost` は許可されているようだ。

# やってみた
というわけで前置きが長くなったけど、 dinghyでも `https://localhost`　 でアクセスしたい。
なんとなくVirtualBoxの設定でもできそうな気もしつつ、設定画面を眺めてもよくわからんかったので、SSHポートフォワードでやってみた。

最初443をポートフォワードすればよいんだから、こんなかんじかなーっと思ってやってみたけど、この方法はうまくいかない。

```bash
$ docker-machine ssh dinghy -L 443:localhost:443
```

一般ユーザ権限では1024以下のWell Knownポートがバインドできないからだ。

じゃあsudoすればよいかと思ったけど、これもうまくいかない。

```bash
$ sudo docker-machine ssh dinghy -L 443:localhost:443
```

sudoするとdinghyの環境変数が見えなくなる。

結論として、とりあえずこうすればポートフォワードできた。

```bash
$ sudo bash -c "$(dinghy env); ssh docker@$(dinghy ip) -i $DOCKER_CERT_PATH/id_rsa -L 443:localhost:443"
```

もっとスマートなやり方がありそうな気もするんだけど。
ジェネリクスを使ってDelegateの振る舞いを変更する

IOS開発を行うと、多くの場合Delegateパターンを利用して開発を行うことになると思います。

例えば、WebAPIリクエストを行う処理を考えてみましょう。

```swift
// Delegate用Protocol
protocol RequestDelegate : class {
    func begin()
    func done()
}

// APIリクエストクラス
class Request {
    weak var delegate: RequestDelegate?

    func call() {
        delegate?.begin()
        delegate?.done()
    }
}

// APIリクエストを行うViewController
class MyViewController: UIViewController, RequestDelegate {
    private var request: Request?

    override func viewDidLoad() {
        super.viewDidLoad()

        // リクエストクラスをメンバ変数に保持して、Delegate先に自身を設定
        request = Request()
        request.delegate = self
    }

    func apiCall() {
        requst.call()
    }
}

// Delegate処理の実装
extension RequestDelegate {
    func begin() {
        print("request begin.")
    }

    func done() {
        print("request done.")
    }
}
```

さて、開発を進めていく中でこのViewControllerが管理する画面とほとんどが同じだがAPIの呼び出し前後の処理だけ変更した新しい画面が必要になったとします。

この時、真っ先に対応策として思いつくのは画面ごとのフラグを用意してAPIの呼び出し前後の処理に条件分岐を与えることではないでしょうか？

```diff
  class MyViewController: UIViewController {
+     private(set) var originView: Bool = true
        .
        .
        .
  extension MyViewController: RequestDelegate {
      func begin() {
-         print("request begin.")
+         originView ? print("request begin.") : print("new begin.")
      }

      func done() {
-         print("request done.")
+         originView ? print("request done.") : print("new done.")
      }
  }
```

条件分岐が出来てしまったので、バグがないことを確認するためにもテストコードを書いておかないとなりませんね。

でも、Swiftのジェネリクスを利用すればこの程度の改修は型チェックのみでなんとかできてしまうのです。

まずは、`MyViewController`を改修します。

```diff
- class MyViewController: UIViewController, RequestDelegate {
+ class MyViewController<T>: UIViewController, RequestDelegate {
```

`MyViewController`にジェネリクスをもたせました。

次にジェネリクスに適用させたい適当な型を定義しておきます。

新しい画面の追加なので、`NewMyView`としておきましょう。

```swift
// 実装はいりません
class NewMyView {}
```

さて、ここまで出来たら新しい画面のためのエクステンションを作れば完了です。

```swift
// 新しい画面のためのDelegate処理の実装
extension RequestDelegate where Self: MyViewController<NewMyView> {
    func begin() {
        print("new begin.")
    }

    func done() {
        print("new done.")
    }
}
```

いかのようにして利用することで、新しい画面用の処理と、これまでの画面の処理が分離出来ていることが確認出来ます。

```swift
let originVc = MyViewController<Any>()
originVc.apiCall() // request begin. request done.

let newVc = MyViewController<NewMyView>()
newVc.apiCall() // new begin. new done.
```

---

通常、Delegateパターンを利用したextensionは、対象のクラスにDelegateProtocolを適合させて拡張します。

```
extension MyViewController: RequestDelegate {
    .
    .
    .
}
```

しかし、このように定義した場合__制約と継承は同時に行えない__というジェネリクスの性質に引っかかってしまうため、DelegateProtocol側に、誰に拡張を与えるか？という方針を取らせるようにしています。

今回テーマにしたケースの解決策としてはViewControllerをもう一つ作るというのもありますが、ほぼ同じ性質のクラスを複数用意するのは面倒ですよね？

クラスのサブタイプにジェネリクスを持たせておくと、色々と小回りが利いて便利ですね。

---

今回のソースコードの完成系はGistに置いてあります。
https://gist.github.com/k-motoyan/888832d3ce23767143951c2f3ad860db
初学者によるswiftでopencvざっくりメモ


今度のハッカソンで
顔画像認識機能付きのiOSアプリを作りそうな感じなので
勉強したときのざっくりメモ



#セットアップ
##CocoaPods導入
CocoaPodsっていうのを使えば良いらしい
のでターミナル起動して
```sudo gem install cocoa pods```　入力
しばらくするとインストール終わるので
```pod setup```
で完了。

##プロジェクト作成
Xcodeで新規プロジェクト作成→言語でswiftを選択
作っておきながら一度そのプロジェクトを閉じ
ターミナルでそのプロジェクトのディレクトリに```cd ```で移動
```pod install```でpodファイルが作成されるので
その中の```use_frameworks!```って記述の下に
```pod 'OpenCV'```の1行を追加

その後ターミナルで```pod install```ってやるとOpenCVが使えるようになります。

##プログラムファイル作成
ファイル追加でCocoa classを追加。言語はobjective-cを選択
ブリッジヘッダを作るか聞かれるのでYes
新しくできたファイルの拡張子を「.m」から「.mm」に変更
linked framework and libraryに余計なのが入ってエラーになってる時は「-」でそれを削除

○○-Bridge-header.hにobjective-c++ファイルをインポート
あと```#import <Foundation/Foundation.h>```
```#import <UIKit/UIKit.h>```

.mmファイルに
```#import <opencv2/opencv.hpp>```
```#import <opencv2/imgcodecs/ios.h>```

ひとまずこれで準備完了。

あとは処理を.mmに書いていって
GUIもストーリーボードとかで配置していけばOK
永遠にcompleteしない画像

JavaScriptで画像を制御していたら、IEだけうまく動かない場面が出てきてしまいました。

# 先回りしづらい`onLoad`

イメージが読み込まれたことを検知するときに、教科書的な手法としては、`<img>`の`load`や`error`イベントを拾う方法があります。ただ、状況によってはイベントを付ける前にキャッシュから画像が読み込まれてしまって、うまく動かないことがあります。

# 完了報告のプロパティ

そんなこともあるからか、`<img>`のDOM上には、`.complete`というプロパティが用意されています。[HTML5の勧告](https://www.w3.org/TR/html5/embedded-content-0.html#dom-img-complete)によれば、`.complete`は「画像のロードが完了した場合」以外にも、

* `src`属性のない場合
* 画像が壊れていた（ファイル形式が合わない、404などアクセスできない）場合

にも`true`になるとされています。ダウンロード失敗でも、もうそれ以上画像は変わらないわけなので`complete`、ということなのかもしれません。

# I……E……？

ところが、Internet Explorerにかかれば、この仕様通りには動かず、リンク切れの画像はずっと`complete`が`false`のままとなります。

「全部の画像が`complete`したとき」という状況を待っているコードがあったのですが、このお陰でIEだけ処理が先に進まなくなっていました。

[試しに作ってみたjsFiddle](https://jsfiddle.net/9yzxmkhw/1/)
SSL/TLS 証明書の情報を Ruby で取得する

# <i class="fa fa-fw fa-cog"></i> 実装

```rb
require 'socket'
require 'openssl'

def get_certificate(host)
  certificate = nil

  TCPSocket.open(host, 443) do |tcp_client|
    ssl_client = OpenSSL::SSL::SSLSocket.new(tcp_client)
    ssl_client.hostname = host
    ssl_client.connect
    certificate = ssl_client.peer_cert
    ssl_client.close
  end
  
  certificate
end
```

上記の `get_certificate` メソッドは、ホスト名を引数に取り、[OpenSSL::X509::Certificate](https://docs.ruby-lang.org/ja/latest/class/OpenSSL=3a=3aX509=3a=3aCertificate.html) オブジェクトを返す。OpenSSL::X509::Certificate は [X509](https://ja.wikipedia.org/wiki/X.509) 証明書を表すクラスで、このオブジェクトは証明書のさまざまな情報、例えば公開鍵や発行者、有効期限などを持っている。

```rb
get_certificate('qiita.com')
=> #<OpenSSL::X509::Certificate
 subject=#<OpenSSL::X509::Name CN=*.qiita.com,OU=Domain Control Validated - RapidSSL(R),OU=See www.rapidssl.com/resources/cps (c)15,OU=GT01505012>,
 issuer=#<OpenSSL::X509::Name CN=RapidSSL SHA256 CA - G3,O=GeoTrust Inc.,C=US>,
 serial=#<OpenSSL::BN 195919>,
 not_before=2015-03-15 03:55:03 UTC,
 not_after=2017-05-16 01:59:04 UTC>
```

# <i class="fa fa-fw fa-info"></i> 使用例

SSL/TLS 証明書の有効期限を調べてみる。

```rb

require 'active_support'
require 'active_support/core_ext'

certificate = get_certificate('qiita.com')
not_after = certificate.not_after.in_time_zone('Japan')

diff = ((not_after - Time.now) / 1.days)

def time2str(time)
  d = time.strftime('%Y/%m/%d')
  w = %w(日 月 火 水 木 金 土)[time.wday]
  t = time.strftime('%H:%M:%S')

  "#{d} (#{w}) #{t}"
end

puts("有効期限: #{time2str(not_after)} (残り #{diff.to_i} 日)")
```
```
有効期限: 2017/05/16 10:59:04 (火) 10:59:04 (残り 101 日)
```

# <i class="fa fa-fw fa-book"></i> 参考

* Ruby 2.4.0 リファレンスマニュアル
    * [TCPSocket](https://docs.ruby-lang.org/ja/latest/class/TCPSocket.html)
    * [OpenSSL::SSL::SSLSocket](https://docs.ruby-lang.org/ja/latest/class/OpenSSL=3a=3aSSL=3a=3aSSLSocket.html)
    * [OpenSSL::X509::Certificate](https://docs.ruby-lang.org/ja/latest/class/OpenSSL=3a=3aX509=3a=3aCertificate.html)
PHPのWebフレームワーク githubスター数まとめ(2017-02-03 22:24 時点)

- どのフレームワーク使うか迷ったので他人の評価を鵜呑みにしてみた
- github の star 数比較です
- 2017-01-28 20:33 と 2017-02-03 22:24 に手作業で調べたものです
- リストアップしたのは自分が知ってるフレームワークだけです

| PHP Framework | star 1/28 20:30|star 2/3 22:24|star 3/1 02:50|
|:-----------|------------:|------------:|------------:|
|https://github.com/laravel/laravel|29020|29218 (+198)|29962|
|https://github.com/symfony/symfony|13729|13750 (+21)|13935|
|https://github.com/bcit-ci/CodeIgniter|13700|13729 (+29)|13900|
|https://github.com/yiisoft/yii2|-|-|9718|
|https://github.com/slimphp/Slim|7594|7608 (+14)|7710|
|https://github.com/phalcon/cphalcon|7570|7582 (+12)|7684|
|https://github.com/cakephp/cakephp|6907|6919 (+12)|6952|
|https://github.com/zendframework/zendframework|5472|5471 (-1)|5482|
|https://github.com/yiisoft/yii|4711|4713 (+2)|4728|
|https://github.com/silexphp/Silex|3435|3447 (+12)|3472|
|https://github.com/fuel/fuel|1414|1414 (0)|1414|

- star数は laravel が圧倒的である
- 人気のあるフレームワークほど増分は多いが laravel たった３日で +198 って凄い勢い
- 3/1 時点追加してみた
- yii2 忘れてた
[Python]Anacondaで環境構築[Mac]

##事前に
Mac OS X El Capitan以降
XcodeおよびHomebrewのインストールおよびアップデート

##AnacondaとHomebrewの不和と分立
(そもそも、2つ以上のパッケージ管理システムを共存させるには注意が必要ということなのでしょう。)
Anacondaをダウンロードおよびインストールする。
`.bash_profile`を確認すると

```
#added by Anaconda3 4.0.0 installer
export PATH="/Users/*ユーザーネーム*/anaconda/bin:$PATH"
```
このままだとHomebrewとAnaconda環境がバッティングするのでコメントアウトしておく。

```
#export PATH="/Users/*ユーザーネーム*/anaconda/bin:$PATH"
```

そして、`~/.bashrc`に以下の関数を追加する。

```
#!/usr/local/bin/bash
function enter_conda()
{
   source /Users/*ユーザーネーム*/anaconda/bin/activate root
}
function quit_conda()
{
   source /Users/*ユーザーネーム*/anaconda/bin/deactivate
}
```
以後、Anacondaで管理しているPythonは`enter_conda()`を実行すればルートモードで使用することができる。`quit_conda()`でルートモードを出る。

これで、AnacondaがHomebrewに干渉することはなくなり、HomebrewがAnacondaに干渉することもなくなる。
RedisにIDのリスト(100万件)を格納するときgzip圧縮するべきか

## 前提

```bash:
$ ruby -v
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-darwin15]
$ grep redis Gemfile.lock
    redis (3.3.1)
    redis-actionpack (5.0.1)
      redis-rack (>= 1, < 3)
      redis-store (>= 1.1.0, < 1.4.0)
    redis-activesupport (5.0.1)
      redis-store (~> 1.2.0)
    redis-rack (2.0.0)
      redis-store (~> 1.2.0)
    redis-rails (5.0.1)
      redis-actionpack (~> 5.0.0)
      redis-activesupport (~> 5.0.0)
      redis-store (~> 1.2.0)
    redis-store (1.2.0)
      redis (>= 2.2)
  redis (~> 3.0)
  redis-rails

$ bundle exec rails c

[1] pry(main)>
```

## テストデータ

```ruby:
[1] pry(main)> ids = (1..1_000_000).to_a
```

## Marshal vs JSON

```ruby:
[2] pry(main)> json = ""
=> ""
[3] pry(main)> marshaled = ""
=> ""

[4] pry(main)> Benchmark.realtime { marshaled = Marshal.dump(ids) }
=> 0.06611821899423376
[5] pry(main)> marshaled.size
=> 4934095

[6] pry(main)> Benchmark.realtime { json = ids.to_json }
=> 0.7926974160072859
[7] pry(main)> json.size
=> 6888897
```

## raw vs gzip

- redis は docker で立ち上げ、ポートフォワーディングしてホストから繋いでいます

```ruby:
[8] pry(main)> host = "192.168.99.100"
=> "192.168.99.100"
[9] pry(main)> port = 6379
=> 6379
[10] pry(main)> db = 0
=> 0
[11] pry(main)> redis = Redis.new(url: "redis://#{host}:#{port}/#{db}")
=> #<Redis client v3.3.1 for redis://192.168.99.100:6379/0>

[12] pry(main)> res = ""
[13] pry(main)> Benchmark.realtime { redis.set('cachekey', marshaled) }
=> 0.08158121499582194
[14] pry(main)> Benchmark.realtime { res = redis.get('cachekey') }
=> 0.34710412900312804
[15] pry(main)> res.size
=> 4905295

[15] pry(main)> gzip = ""
=> ""
[15] pry(main)> gzip2 = ""
=> ""
[15] pry(main)> res2 = ""
=> ""
[16] pry(main)> Benchmark.realtime { gzip = Zlib::Deflate.deflate(marshaled); redis.set('cachekey_gzip', gzip) }
=> 0.6087514339888003
[17] pry(main)> Benchmark.realtime { gzip2 = redis.get('cachekey_gzip'); res2 = Zlib::Inflate.inflate(gzip2) }
=> 0.06563029202516191
[18] pry(main)> gzip.size
=> 1505444
[19] pry(main)> gzip2.size
=> 1448046
[20] pry(main)> res2.size
=> 4934095
```

## 結論（になっていない)

- サンプル数は少ないが数回叩いても大きな差異はなかった
- to_json より marshal のほうがよさげ
- 圧縮すると redis の get は速くなるが圧縮に時間はかかるので gzip圧縮しないほうが全体としては高速という結果
- ただ圧縮するとredisのメモリは節約できる
- 速度重視だとして、実際にはネットワークI/O がもっとかかるのでこの結果だけでは圧縮するべきかどうかは何ともいえない
Itamaeでgoをインストールする

# 環境

- Ubuntu16.04(amd64)

# レシピ

```rb
# cookbooks/go/default.rb:

execute "install go" do
  cwd "/tmp"
  command <<-EOC
    wget https://storage.googleapis.com/golang/go1.7.5.linux-amd64.tar.gz
    tar -C /usr/local -xzf go1.7.5.linux-amd64.tar.gz
    rm -rf go1.7.5.linux-amd64.tar.gz
    export PATH=$PATH:/usr/local/go/bin
    echo 'export PATH=$PATH:/usr/local/go/bin' >> /etc/profile
  EOC
  not_if "test -e /usr/local/go"
end
```

# 参考

- [The Go Programming Language - インストール](http://golang-jp.org/doc/install)
SketchUpで自家製MQOローダー

#概要
SketchUpでMQOファイルを読み込んで見た。

#写真
![mqo.jpg](https://qiita-image-store.s3.amazonaws.com/0/18104/91cea23a-822e-0a44-d2ac-6aaa677ca9ba.jpeg)


#環境
SketchUp
v7.1.6860
v8.0.16846

#サンプルコード
mqo_ld.rb

```
require "sketchup.rb"

def mqo_ld
  entities = Sketchup.active_model.entities
  groups = {}
  vertices = []
  mirror = 0
  f = UI.openpanel "Select .mqo file", "", "*.mqo"
  return unless f
  lines = IO.readlines(f)
  lines.each do | line |
    next if line[0] == ?#
    line = line.gsub(/\(/, " ( ")
    line = line.gsub(/\)/, " ) ")
    line.strip!
    values = line.split
    next if values.length == 0
    cmd = values.shift
    case cmd
    when "Object"
      gname = values[0].gsub(/\"/, "")
      if (groups[gname].nil?)
        groups[gname] = Sketchup.active_model.entities.add_group
        groups[gname].name = gname
      end
      entities = groups[gname].entities
      vertices = []
      mirror = 0
    when "mirror"
      mirror = 1
    when "4"
      face = []
      face << Integer(values[2])
      face << Integer(values[3])
      face << Integer(values[4])
      verts = face.map {| v | vertices[v]}
      begin
        entities.add_face verts
      rescue
        UI.messagebox line
        p verts
      end
      face = []
      face << Integer(values[4])
      face << Integer(values[5])
      face << Integer(values[2])
      verts = face.map {| v | vertices[v]}
      begin
        entities.add_face verts
      rescue
        p verts
      end
      if mirror == 1
        vertices.collect! {| v | [-v[0], v[1], v[2]]}
        face = []
        face << Integer(values[4])
        face << Integer(values[5])
        face << Integer(values[2])
        verts = face.map {| v | vertices[v]}
        begin
          entities.add_face verts
        rescue
          UI.messagebox line
          p verts
        end
        face = []
        face << Integer(values[4])
        face << Integer(values[3])
        face << Integer(values[2])
        verts = face.map {| v | vertices[v]}
        begin
          entities.add_face verts
        rescue
          UI.messagebox line
          p verts
        end
      end
    when "3"
      face = []
      face << Integer(values[2])
      face << Integer(values[3])
      face << Integer(values[4])
      verts = face.map {| v | vertices[v]}
      begin
        entities.add_face verts
      rescue
        UI.messagebox line
        p verts
      end
      if mirror == 1
        vertices.collect! {| v | [-v[0], v[1], v[2]]}
        face = []
        face << Integer(values[2])
        face << Integer(values[3])
        face << Integer(values[4])
        verts = face.map {| v | vertices[v]}
        begin
          entities.add_face verts
        rescue
          UI.messagebox line
          p verts
        end
      end
    when "2"
      #
    else
      if cmd.match(/^[\d-]/)
        v = []
        v << Float(cmd) / 10
        v << Float(values[1]) / 10 * -1
        v << Float(values[0]) / 10
        vertices << v
      end
    end
  end
end

if (not file_loaded?("mqo_ld.rb"))
  UI.menu("Plugin").add_item("mqo_loader") {mqo_ld}
end

file_loaded("mqo_ld.rb")

```
SketchUpで自家製ROKローダー

#概要
SketchUpでROKファイルを読み込んで見た。

#写真
![rok.jpg](https://qiita-image-store.s3.amazonaws.com/0/18104/b7a421bf-3b6a-38ff-a18f-ffcc98d705f9.jpeg)


#環境
SketchUp
v7.1.6860
v8.0.16846

#サンプルコード
rok_ld.rb

```
require 'sketchup.rb'

def rok_ld
  entities = Sketchup.active_model.entities
  vnam = 0
  lnam = 0
  state = 0
  fmod = 0
  verts = 0
  x, y, z, s, e = 0
  c = 0
  v = []
  l = []
  f = UI.openpanel "Select .rok file", "", "*.rok"
  return unless f
  lines = IO.readlines(f, "\r")
  lines.each do | line |
    line.strip!
    case line
    when "POINT"
      state = 1
    when "LINE0"
      state = 2
      lnam = 0
    when "FACE0"
      state = 3
    when "END00"
      UI.messagebox "ok"
    else
      if state > 0
         c += 1
      end
      if state == 1
        if c == 1
          vnam = Integer(line)
        end
        if c == 6
          x = Float(line)
        end
        if c == 7
          y = Float(line)
        end
        if c == 8
          z = Float(line)
        end
        if c == 8
          v[vnam] = [x * 10, z * 10, -y * 10]
          c = 0
        end
      end
      if state == 2
        if c == 1
          s = Integer(line)
        end
        if c == 2
          e = Integer(line)
        end
        if c == 3
          lnam += 1
        end
        if c == 4
          l[lnam] = [s, e]
          c = 0
        end
      end
      if state == 3
        if c == 1
          fmod = Integer(line)
        end
        if c == 2
          f = []
        end
        if c == 4
          f[0] = Integer(line)
        end
        if c == 5
          f[1] = Integer(line)
        end
        if c == 6
          f[2] = Integer(line)
          if fmod == 3
            verts = [v[l[f[0]][0]], v[l[f[0]][1]], v[l[f[1]][0]], v[l[f[1]][1]], v[l[f[2]][0]], v[l[f[2]][1]]]
            verts.uniq!
            begin
              entities.add_face verts
            rescue
              UI.messagebox fmod
            end
            c = 0
          end
        end
        if c == 7
          f[3] = Integer(line)
          if fmod == 4
            verts = [v[l[f[0]][0]], v[l[f[0]][1]], v[l[f[1]][0]], v[l[f[1]][1]], v[l[f[2]][0]], v[l[f[2]][1]] , v[l[f[3]][0]], v[l[f[3]][1]]]
            verts.uniq!
            begin
              entities.add_face verts
            rescue
              entities.add_face [verts[0], verts[1], verts[2]]
              entities.add_face [verts[2], verts[3], verts[0]]
            end
            c = 0
          end
        end
      end
    end
  end
end

if (not file_loaded?("rok_ld.rb"))
  UI.menu("Plugin").add_item("rok_loader") {rok_ld}
end

file_loaded("rok_ld.rb")

```
SketchUpで自家製OBJローダー

#概要
SketchUpでOBJファイルを読み込んで見た。

#写真
![obj.jpg](https://qiita-image-store.s3.amazonaws.com/0/18104/d607a07f-908a-666e-2fe0-5e46c76372ff.jpeg)


#環境
SketchUp
v7.1.6860
v8.0.16846


#サンプルコード
obj_ld.rb

```
require "sketchup.rb"

def obj_ld
  entities = Sketchup.active_model.entities
  groups = {}
  vertices = []
  f = UI.openpanel "Select .obj file", "", "*.obj"
  return unless f
  lines = IO.readlines(f)
  lines.each do | line |
    next if line[0] == ?#
    line.strip!
    values = line.split
    next if values.length == 0
    cmd = values.shift
    case cmd
    when "v"
      v = values.map {| e | Float(e)}
      vertices << v
    when "g"
      gname = values.join "_"
      if (groups[gname].nil?)
        groups[gname] =  Sketchup.active_model.entities.add_group
        groups[gname].name = gname
      end
      entities = groups[gname].entities
    when "f"
      face = []
      values.each do | v |
        w = v.split("/")
        face << Integer(w[0])
    end
    verts = face.map {| v | vertices[v - 1]}
    begin
      entities.add_face verts
    rescue
      #UI.messagebox line
    end
    end
  end 
end

if (not file_loaded?("obj_ld.rb"))
  UI.menu("Plugin").add_item("obj_loader") {obj_ld}
end

file_loaded("obj_ld.rb")

```
Javaにおけるファイルコピー処理について

## 結論
- Java7以降で、特別な事情がない場合は __java.nio.file.Files#copy(Path, Path, CopyOption)__ 等、標準ライブラリの機能をご利用ください。

- Java6以前の場合、可能であれば __Apache Commons__ の、Commons-IOに含まれる__FileUtils#copyFile(File, File)__ 等、定評のあるライブラリの機能をご利用ください。


## どうしても独自実装したい場合
2017年現在、独自実装する必要はないはずですが、なんらかの理由により独自実装する場合の話です。Webを検索すると、以下のようなコードが散見されます。

```java:サンプル1

public static void copyFile(File sf, File df) {
		FileChannel sc = null, dc = null;
		try {
			sc = new FileInputStream(sf).getChannel();
			dc = new FileOutputStream(df).getChannel();
			dc.transferFrom(sc, 0, sc.size());
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (dc != null) try { dc.close(); } catch (IOException e) {}
			if (sc != null) try { sc.close(); } catch (IOException e) {}
		}
	}
```

このメソッド、基本的には動作に問題ないのですが、静的構文解析ツールによっては、

```java
	sc = new FileInputStream(sf).getChannel();
```

このFileChannelをメソッドチェインで取得している箇所で、__「FileInputStreamが閉じられていない可能性がある」__と警告してきます (FileOutputStreamも同様)

幸い、Java6の __java.io.FileInputStream#close()__ のドキュメントには、

>ファイル入力ストリームを閉じ、このストリームに関連するシステムリソースを解放します。
>このストリームにチャネルが関連付けられている場合は、そのチャネルも閉じます。

とありますので、FileInputStream(FileOutputStream)を閉じましょう。こんな感じでしょうか (FileChannelも閉じても問題ないです。FileInputStreamとFileChannel、両方のcloseメソッドを呼んでも落ちることはありません。意味もありませんが)


```java:サンプル2
	public static void copyFile(File sf, File df) {
		FileInputStream fis = null;
		FileOutputStream fos = null;
		try {
			fis = new FileInputStream(sf);
			fos = new FileOutputStream(df);
			
			FileChannel sc = fis.getChannel();
			FileChannel dc = fos.getChannel();
			dc.transferFrom(sc, 0, sc.size());
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (fos != null) try { fos.close(); } catch (IOException e) {}
			if (fis != null) try { fis.close(); } catch (IOException e) {}
		}
	}

```

ということで、__サンプル2__の方が、後から静的構文解析ツール等を導入した際、警告される可能性が低くなります。Webを検索して__サンプル1__をコピペするくらいなら、__サンプル2__をご利用ください。~~後でメンテナンスする人が楽になりますので~~

なお、Java7以降で独自実装する場合は、[try-with-resources文](https://docs.oracle.com/javase/jp/8/docs/technotes/guides/language/try-with-resources.html)をお使いください。すごくシンプルになります。

### 参考
+ [Javaでのファイルコピー史](http://qiita.com/kawasima/items/145231e9a51b5c05d589)
 * いままでの主なファイルコピー方法と、その実装・処理速度について解説なされています
SketchUpで自家製STLローダー

#概要
SketchUpでSTLファイルを読み込んで見た。


#写真
![stl.jpg](https://qiita-image-store.s3.amazonaws.com/0/18104/4ab53f5c-5650-6bac-86e7-6e132320bd6e.jpeg)


#環境
SketchUp
v7.1.6860
v8.0.16846

#サンプルコード
stl_ld.rb

```
require "sketchup.rb"

def stl_ld
  entities = Sketchup.active_model.entities
  groups = {}
  vertices = []
  state = 0
  f = UI.openpanel "Select .stl file", "", "*.stl"
  return unless f
  lines = IO.readlines(f)
  lines.each do | line |
    next if line[0] == ?#
    line.strip!
    values = line.split
    next if values.length == 0
    cmd = values.shift
    case cmd
    when "facet"
      state = 0
      vertices = []
    when "vertex"
      state = state + 1
      v = []
      v << Float(values[0])
      v << Float(values[2])
      v << Float(values[1])
      vertices << v
      if (state == 3)
        begin
          entities.add_face vertices
        rescue
          UI.messagebox "err"
          p vertices
        end
      end
    end
  end 
end

if (not file_loaded?("stl_ld.rb"))
  UI.menu("Plugin").add_item("stl_loader") {stl_ld}
end

file_loaded("stl_ld.rb")

```
GAでA/Bテストするときの必須修正事項 (2017/02/03現在)

2017/02/03現在、GAのA/Bテストのテストコードをそのまま貼ってはいけない！

テストコードとはこういうやつ ↓

```html
<!-- Google Analytics Content Experiment code -->
<script>function utmx_section(){}function utmx(){}(function(){var
k='********-**',d=document,l=d.location,c=d.cookie;
if(l.search.indexOf('utm_expid='+k)>0)return;
function f(n){if(c){var i=c.indexOf(n+'=');if(i>-1){var j=c.
indexOf(';',i);return escape(c.substring(i+n.length+1,j<0?c.
length:j))}}}var x=f('__utmx'),xx=f('__utmxx'),h=l.hash;d.write(
'<sc'+'ript src="'+'http'+(l.protocol=='https:'?'s://ssl':
'://www')+'.google-analytics.com/ga_exp.js?'+'utmxkey='+k+
'&utmx='+(x?x:'')+'&utmxx='+(xx?xx:'')+'&utmxtime='+new Date().
valueOf()+(h?'&utmxhash='+escape(h.substr(1)):'')+
'" type="text/javascript" charset="utf-8"><\/sc'+'ript>')})();
</script><script>utmx('url','A/B');</script>
<!-- End of Google Analytics Content Experiment code -->
```
下から３行目のバックスラッシュを削除しないと、
A/Bテストが全く始まらなかった。
`<\/sc'+'ript>`
　↓
`</sc'+'ript>`

これは罠ですか？
git pull origin <現在のブランチ> を楽にする

git pull origin <現在のブランチ> を楽にする

`.bashrc` とか `.bash_profile` に
下記のaliasを貼っておくと
`git pull origin <現在のブランチ>` とか長い文字を
毎回打たなくて便利

```bash:bashrc
alias gp='git pull origin $(git rev-parse --abbrev-ref HEAD)'
```
Rails で文字列で保存していた uuid や JSON を PostgreSQL が提供する型をそのまま利用するようにマイグレート

こんな感じのコードで、

- ユーザIDを文字列からUUIDに変更し、ついでに自動生成に対応
- 他のテーブルで利用されているユーザIDもUUIDに変更
- ユーザ設定の型を文字列からJSONに変換

することができる。


```rb
class ChangeColumnType < ActiveRecord::Migration[5.0]
  def change
    change_column_string_to_uuid(:users, :id, new_default: 'uuid_generate_v4()')
    change_column_string_to_uuid(:messages, :user_id)

    change_column_string_to_jsonb(:users, :settings, old_default: '{}', new_default: {})
  end

  def change_column_string_to_jsonb(table, column, old_default: nil, new_default: nil)
    reversible do |dir|
      dir.up do
        change_column_default table, column, nil if old_default
        change_column         table, column, :jsonb, using: "cast(#{column} as json)"
        change_column_default table, column, new_default if new_default
      end
      dir.down do
        change_column_default table, column, nil if new_default
        change_column         table, column, :string
        change_column_default table, column, old_default if old_default
      end
    end
  end

  def change_column_string_to_uuid(table, column, old_default: nil, new_default: nil)
    reversible do |dir|
      dir.up do
        change_column_default table, column, nil if old_default
        change_column         table, column, :uuid, using: "#{column}::uuid"
        change_column_default table, column, new_default if new_default
      end
      dir.down do
        change_column_default table, column, nil if new_default
        change_column         table, column, :string
        change_column_default table, column, old_default if old_default
      end
    end
  end
end
```

このマイグレーションスクリプトは、保存されている文字列がUUIDやJSONとして不正だった場合に失敗する。
本番DBをダンプ、ローカルにストアしておいて、 `rake db:migrate` して事前確認しておくこと。
EC-Cube2で複数同時購入された商品郡を一挙に確認して、配送するときに必要になるファンクションの実用例

普通のショップでは使わないと思うのですが、
MySQLでのファンクションをどのように使えばいいか？
についての話。

#MySQLのfunctionとはなになのか？について
こういえば一発で判ると思います。
*functionとは、Rubyならdef Perlならsub MySQLならfunctionです。*
ただ、ほとんど普段は使う必要がありません。

## 今回、functionで何を行ったか
EC-Cube2の高度な管理から出力するCSV出力を使ったCSV作成処理で、
11111の商品を買った時と22222の商品を買った時で、【選択Aがある】と【選択Aがある】【選択Bがある】と【選択Bがある】の３値をとる可能性が出てきたため、今後選択CやDが増える可能性がある状態を考慮しつつ、これを　[商品選択状況]というカラム１個にまとめる処理をSQLとfunctionで実現

##なぜこの対応が必要だったかという背景　
EC-Cube2からデータをＣＳＶで配送会社のシステムに送った際、この配送会社のシステムが少し賢いため、order_idを基準に1回の出荷としてまとめてくれています。とても素敵な機能なのですが、出荷指示の項目だけが上書き処理されるため、たとえば3つの商品を購入した際に、2個目の商品と3個目の商品でおまけグッヅが異なる場合には、3個目の商品についてくるオマケだけが記載され、ピッキング処理にわたってしまう問題が起きていました。

この状況を解決するために、EC-Cube2から出力するCSV自体に、同時購入商品に関連する全てのおまけぐっづ情報を記載し、1つの受注idでどのように上書きされても必ず全てのオプションがピッキング指示に入るようになりました。



##以下が実現したfunction
order_idを使い、同じorder_idで他の対象AやBの同時購入チェックを行い、文字列で返却するファンクションを作って対応しています。


```sql






DROP FUNCTION IF EXISTS checkitem;
DELIMITER //
CREATE FUNCTION checkitem (orderId INT) RETURNS CHAR(50) DETERMINISTIC


BEGIN

  DECLARE x TEXT;
  DECLARE y TEXT;
 
  /* 初期値を置いておくことにした */
  SET x = "";
  SET y = "";
  
  /* 選択肢Aが入る条件のテスト */ 
  CASE 
    WHEN (SELECT product_id FROM dtb_order_detail WHERE order_id = orderId and product_id in (商品ID, 商品ID) limit 1)  then 
     SET x = "【Bあり】";
    ELSE BEGIN END;
  END CASE;

  /* 選択肢Bが入る条件のテスト */
  CASE 
    WHEN (SELECT product_id FROM dtb_order_detail WHERE order_id = orderId and product_id in ( 商品ID, 商品ID)  limit 1) then 
     SET y = "【Aあり】";
    ELSE BEGIN END;
  END CASE;
    

 RETURN concat(x,y);

END 

//
DELIMITER ;
 

```


## 運用方法
新しい特殊対応商品が増えた際は、caseを増やしていくことで、
いくらでも対応できることになります。
レンタルサーバなどではできないことかもしれませんね。

## 使い道
特殊な配送会社とシステム会社があって必要となる機能なので、普通は使わないと思います。
【珍プレイ集】WORDPRESS高速化したらコケた

WORDPRESSが遅かったのでKUSANAGIにリプレイスした。
速いがいくつも困難があった。心の傷が癒される前にQiita。


# WP REST APIのリターンが型おかしい

## 問題

```
[{"id":14944,"d ~
```

とならなければならないところを

```
{"0":{"id":144944,"d ~
```

となってしまう

## 原因
WORDPRESS 4.7以前ではJSONでの出力を公式にサポートしていなかったので、プラグインWP REST APIで入れるしかなかった。
しかし4.7以降、正式にサポートされるようになり、JSONをサポートした事が起因しているようだ（断定はできない）。


## 対応方法
最新版WORDPRESS 4.7.2がリリースされたが、
リリースノートを見るとWP REST APIへの変更がいくつも入っていた。
まず最新版のWORDPRESSをインストールした。

その後、W3 Total Cache　というプラグインが有効にしている時、
無効にしている時により、JSONのリターンの型が変わることが分かった。
W3 Total Cacheを無効にしたが、そもそもキャッシュはKUSANAGIにも入っているので
W3 Total Cache自体消しても問題ないと判断し削除した。



# FCACHED(fuelPHP)を有効にしていると、レスポンスタイムが10分おきに速くなる

## 問題
レスポンスタイムが速いことはいいことだ。
しかし、極端に速くなった後おそくなり、また速くなり、遅くなる。
というのが10分おきに起きた。

逆のパターン「10分おきに遅くなる」だったら、キャッシュが消えたタイミングかなとあたりは付くが、速くなるパターンなので気持ち悪い。

![qiita-res.JPG](https://qiita-image-store.s3.amazonaws.com/0/75761/2da2bb3e-d086-e9f0-3bd5-dfe5d18466d3.jpeg)

## 原因
未解決
KUSANAGI勉強会で問題提起したが、解決には至らなかった。

## 対応方法
気持ち悪いので問題が起きた環境ではFCACHEDをオフ。
根本解決できておらず。


# KUSANAGI化したのに速くならない

## 問題
せっかくKUSANAGIにリプレイスしたのにレスポンスタイムが思ったほど速くならない。

## 原因

 - プラグインを入れすぎている。
 - コンテンツ内にFacebookやtwitterなど外部リンクを多く含まれている

## 対応方法
元々使っていたプラグインをアンインストール。
コンテンツの中身を見直す（とはいえ、オウンドメディアとして作っていたので、Facebookやtwitterなど外部リンクを削除はできていない。）


# プラグインが動かない。

## 問題
WORDPRESS,KUSANAGIどちらが問題なのか切り分けできていないが、
長年使ってきた古いWORDPRESSでは動いていたプラグインが、新しい環境だと動かなくなってしまう問題が発生。

![qiita-non-support.JPG](https://qiita-image-store.s3.amazonaws.com/0/75761/1d682450-1844-3e4b-ffe2-1347ab9ce78d.jpeg)

## 原因
プラグインが古すぎて新しいWORDPRESSをサポートしていなかった。

## 対応方法
元々使っていたプラグインをアンインストール、
代替になるプラグインを新しくインストール。

WORDPRESSでは、数年更新されていないプラグインは検索に引っかからなくなるように設定しているとのこと。


# 同じ名前のプラグインがありふれている

## 問題
代替のプラグインをインストールしようとした際、同じ名前のプラグインがありふれていて混乱。

![qiita-filemanager.JPG](https://qiita-image-store.s3.amazonaws.com/0/75761/9975b3b4-9eda-d6cc-9e48-bae00d7b0f3c.jpeg)

## 原因
同じ名前で作られているので、ユーザーはどーもこーもできーん。

## 対応方法
片っ端から試す。


とりあえず以上。
またいろいろ出ると思うので、都度追記します。
Macで共有ファイルサーバがマウントできなかった件 (ファイルないんだかあるんだか)


↓の記事を参考にOS Xのコマンドで共有ファイルサーバ(smb)のマウントを行おうとした。
* [MacでターミナルからSambaをマウントする](http://qiita.com/mach3/items/e7021b9e50f2b536a86b)

しかし、

```shell-session
$ mount_smbfs //User@Server/Dir/ /Volumes/Dir
mount_smbfs: could not find mount point /Volumes/Dir: No such file or directory
```

といわれてしまった。
なので、ディレクトリを作ってあげる。

```shell-session
$ mkdir /Volumes/Dir
$ mount_smbfs //User@Server/Dir/ /Volumes/Dir
mount_smbfs: mount error: /Volumes/Dir: File exists
```

なければ「ない」で怒られて、作れば「もうある」と怒られて、意味が分からん。<br>
結局、↓のサイトで`df`使うと状況が見えるよ! とのことで、やってみる。
* [Mac OS X Mountain Lion で smb ファイルサーバのマウントをする](http://cat-s-tail.blogspot.jp/2013/08/mac-os-x-mountain-lion-smb.html)

```shell-session
$ df
Filesystem                512-blocks       Used Available Capacity   iused     ifree %iused  Mounted on
/dev/disk1                1951137792 1112360520 838265272    58% 139109063 104783159   57%   /
(一部略)
//User2@Server/Dir        1048576000 1039060792   9515208   100% 129882597   1189401   99%   /Volumes/testDir
```

別の人がマウント済でした。
ので、1回アンマウントしてあげたら無事に読み込めました。

```shell-session
$ umount /Volumes/testDir
$ mount_smbfs //User@Server/Dir/ /Volumes/Dir
```
WordPress 管理画面でカスタム投稿タイプの投稿一覧にカスタムタクソノミーの絞込をつける

# 仕様
管理画面の投稿一覧のように、カスタム投稿タイプの投稿一覧でもカスタム分類による絞込のドロップダウンをつけたい
![スクリーンショット 2017-02-03 18.21.54.png](https://qiita-image-store.s3.amazonaws.com/0/18348/4626712d-6e94-8c1a-a98e-2f843926ab50.png)

余談だが、投稿一覧でカラムにカスタム分類を追加するのは `register_taxonomy()` の `show_admin_column` 引数でできるのでよしなに（デフォルトではでないけど）
https://developer.wordpress.org/reference/functions/register_taxonomy/

正直 `register_taxonomy()`に引数あってもいいのになって思う。

# コード
なお、WordPress 4.4移行。

フックする場所は `restrict_manage_posts`。
https://developer.wordpress.org/reference/hooks/restrict_manage_posts/

ドロップダウンは `wp_dropdown_categories()` でオケ。
https://codex.wordpress.org/Function_Reference/wp_dropdown_categories

```php:add_term_dropdown.php
<?php
add_action( 'restrict_manage_posts', 'add_term_dropdown', 10, 2 );
function add_term_dropdown( $post_type ) {
	if ( 'session' == $post_type ) { // カスタム投稿タイプ 'session' の場合
		$term_slug = get_query_var( 'session_track' );
		wp_dropdown_categories( array(
			'show_option_all'    => __( 'All Tracks', 'my_theme' ),
			'selected'           => $term_slug, // 絞り込んだあとそのタームが選択されている状態を維持
			'name'               => 'session_track', // select の name 属性
			'taxonomy'           => 'session_track', // カスタムタクソノミーのスラッグ
			'value_field'	     => 'slug',	// option の value属性の中身を何にするか
		));
	}
}
```

`wp_dropdown_categories()` は優秀だよねってオチ。

現場からは以上です。
【Concrete5】バージョン8でサービスプロバイダーオーバーライドするには？

## 概要
Concrete5でコアファイルをカスタマイズする際の、サービスプロバイダーオーバーライドの方法に関して。
バージョン5.7は、マニュアルがあったが、バージョン8はないので記載。
[バージョン5.7の場合](https://concrete5-japan.org/help/5-7/recipes/override-almost-any-core-file-in-5-7/)

ちなみに、上記URLのやり方で書くと

> 予期せぬエラーが発生しました。
> Class '\Application\Page\PageList' not found

となる。

## 手順
#### 前提
1. ページリスト表示処理をカスタマイズするために、/concrete/src/Page/PageList.phpをカスタマイズ対象とします。
2. [バージョン5.7の場合](https://concrete5-japan.org/help/5-7/recipes/override-almost-any-core-file-in-5-7/)を参考にし、バージョン5.7との違いを説明していきます。

#### １.app.phpを作成。
**/concrete/config/app.php**
バージョン5.7の場合

```php:app.php
<?php

return array(
    'providers' => array(
        'PageList' => '\Application\Src\Page\PageList'
    )
);
```

バージョン8の場合

```php:app.php
<?php
return [
    'canonical-url' => '',
    'canonical-ssl-url' => '',
    'aliases' => [
        'PageList' => '\Application\Concrete\Page\PageList',
    ]
];
```

- 既存ソースにある、「canonical・・・」はそのまま。aliasesを追加します。
- カスタマイズするソースのパスを変えます。**Src** → **Concrete**

#### ２.カスタマイズしたいファイルをコピー。
バージョン5.7の場合
**/application/src/Page/PageList.php**

バージョン8の場合
**/application/src/Concrete/Page/PageList.php**

- **Concrete**ディレクトリはないので作成する必要があります。

#### ３.ファイルの中身を修正
バージョン5.7の場合

```php:PageList.php
<?php
namespace Application\Src\Page;

class PageList extends \Concrete\Core\Page\PageList

{
    // カスタマイズ内容を記載
}
```

バージョン8の場合

```php:PageList.php
<?php
namespace Application\Concrete\Page;

class PageList extends \Concrete\Core\Page\PageList
{
    // カスタマイズ内容を記載
}
```

- **namaspace**を変える必要があります。

以上。
【検証】ブラウザから印刷したときのDPIっていくつなの？

ブラウザから印刷したときのDPIの値はいくつなのか気になり調べてみました。

#**検証方法**

今回は Windows7の環境で試しました。
HTMLファイルをローカル上に作成して、各ブラウザで開いてA4用紙に印刷します。
印刷されたものを普通の定規で測って調べました。
顕微鏡などを使って正確に測ったわけではないので、おおよそのDPIになります。

ブラウザから印刷したときのDPIは、システムDPIまたはモニタDPIの影響を受けるのかも確かめるために、それぞれの値を変更して印刷してみました。

##**HTMLファイル**

今回、下記のHTMLファイルを使って印刷しました。

```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>browser - DPI</title>
</head>
<body>
<div style="width:100px; height:100px; background:#03F;"></div>
</body>
</html>
```

##**モニタDPIの設定**

![モニタDPI.jpg](https://qiita-image-store.s3.amazonaws.com/0/72985/59802b74-a4b1-b7d4-e909-914477c77807.jpeg)

##**システムDPIの設定**

![システムDPI.jpg](https://qiita-image-store.s3.amazonaws.com/0/72985/112de3e1-7b54-7381-d0be-0845b0e03f64.jpeg)

#**結果**

InternetExplorer、GoogleChrome、Firefox、Operaで、CSS100pxの矩形を印刷した結果は下記の通りです。

### Windows7 64bit

![結果.jpg](https://qiita-image-store.s3.amazonaws.com/0/72985/4720f4ab-796d-dadd-1f6d-eeef1b88df96.jpeg)

**全て約2.65cm（約96DPI）で印刷されました。**
**モニタDPI、システムDPIの値を変更しても印刷される大きさは変わりませんので、モニタDPI、システムDPIの影響はないという結果になりました。**

# **なんで96DPIなの？**

ここからは推測ですので、確証はありません。
誤りがあれば、ご指摘ください((_ _ (´ω｀ )ﾍﾟｺ

96という値は、CSSの長さを定義するのに使われている値です。
CSSの長さは相対単位と絶対単位の2つあります。
絶対単位は `cm, mm, Q, in, pc, pt, px` の7つの単位が定義されています。

|単位|名前|等値|
|:--|:--|:--|
|cm|センチメートル|1cm = 96px/2.54|
|mm|ミリメートル|	1mm = 1/10cm|
|Q|4分の1ミリメートル|1q = 1/40cm|
|**in**|**インチ**|**1in = 2.54cm = 96px**|
|pc|パイカ|1pc = 1/6 in|
|pt|ポイント|1pt = 1/72 in|
|px|ピクセル|	1px = 1/96 in|

+ [CSS Values and Units Module Level 3](https://www.w3.org/TR/css3-values/#absolute-lengths)
+ [CSS Values and Units Module Level 3 日本語訳](https://momdo.github.io/css3-values/#absolute-lengths)

ご覧のように インチ をベースに他の単位が定義されていますが、そのインチは 96px と定義されています。
96px が基準になっています。
ドットバイドットの環境では、1pxが1物理ピクセルになります。
その環境下ではCSSの絶対単位は、96物理ピクセルが基準になっています。

CSSで長さ5cmの矩形を作り、印刷するとします。
CSSでの1cmは、先ほどの表の通り `1cm = 96px / 2.54` と定義されています。
1cm = 37.7952755...px になります。
今回は5cmですので5倍した 188.976...px を指定しているということになります。

先ほどの検証結果では印刷したときは 96DPI でした。
1インチは 2.54cm ですので、1.9685インチ が 5cm になります。
96DPI では1インチあたり 96px で印刷しますので、 `1.9685インチ * 96` で 5cmで印刷したときのピクセル数が求められます。
188.976pxとなります。
これは先ほどCSSで指定した5cmのpxと一致します。
CSSで5cmと指定すれば、5cmで印刷されます。

**CSSの絶対単位のベースは96pxです。**
**印刷時のDPIも96にするこにより、同じ大きさで印刷されます。**
**このような理由から、96DPIという値にしているのではないかと思います。**

# note

note でも記事を公開してるので、興味がある方はご覧ください。

・[【初学者向けコードリーディング】 PHP の TODO アプリのコードを一緒に読み解こう](https://note.mu/7968/n/n46a8beb87c93)
DatasetMixinクラスを継承するときの注意

# この記事について　

ChainerでTrainerを使おうと思い、lIteratorにデータを渡すためのクラスであるDatasetMixinを継承して自前データセットを作った時に、単純な勘違いでありながら若干苦労をしたので記録として残します。

(追記) この記事内で想定しているChainerのバージョンは1.20です。新しいバージョンでは状況が変化するかもしれません。

## 遭遇したエラーメッセージ

出力されるエラーメッセージが原因解決につながりづらい(わかりづらい)ものでした。

```py3
  File "cupy/cuda/device.pyx", line 66, in cupy.cuda.device.Device.__enter__ (cupy/cuda/device.cpp:1621)
  File "cupy/cuda/device.pyx", line 81, in cupy.cuda.device.Device.use (cupy/cuda/device.cpp:1862)
  File "cupy/cuda/runtime.pyx", line 178, in cupy.cuda.runtime.setDevice (cupy/cuda/runtime.cpp:2702)
  File "cupy/cuda/runtime.pyx", line 130, in cupy.cuda.runtime.check_status (cupy/cuda/runtime.cpp:2028)
cupy.cuda.runtime.CUDARuntimeError: cudaErrorInvalidDevice: invalid device ordinal
```

このメッセージを見た時に自分は「モデルかデータのGPU処理を書き間違えたかな?」と考えました。なのでcuda.cupy周りを必死にいじってみたりしたのですが、解決に至りませんでした。

ドキュメントを注意深く読めば気がついたかもしれませんが、最終的に自分はchainerのソースをみて原因を理解しました。

## 作成したコードの一部

```py3
class MyDataset(chainer.dataset.DatasetMixin):
    def __init__(self, path):
        label_list = {}
        def get_label(l):
            num = label_list.get(l, -1)
            if num < 0:
                label_list[l] = len(label_list)
                return label_list[l]
            return num
        flist = []
        llist = []
        for root, dirs, files in os.walk(path):
            label = os.path.basename(root) # ディレクトリ名をラベルとする
            label_num = get_label(label)
            for file in files:
                flist.append(os.path.join(root, file))
                llist.append(label_num)
        self.flist = flist
        self.llist = llist

    def __len__(self):
        return len(self.flist)

    def get_example(self, i):
        fname = self.flist[i]
        label = self.llist[i]
        img = Image.open(fname)
        img = np.asarray(img, dtype=np.float32).transpose(2, 0, 1)
        return img, label
```

GPUを有効化したchainerで、このクラスを使ってIterator, Trainerを使った学習をさせると、GPUの利用の有無にかかわらず先ほどのようなエラーが出ます。

CPU版chainerでは次のようなエラーになりました。

```py3
    check_cuda_available()
  File "/path/to/lib/python3.4/site-packages/chainer/cuda.py", line 83, in check_cuda_available
    raise RuntimeError(msg)
RuntimeError: CUDA environment is not correctly set up
(see https://github.com/pfnet/chainer#installation).CuPy is not correctly installed. Please check your environment, uninstall Chainer and reinstall it with `pip install chainer --no-cache-dir -vvvv`.
```

## 原因

シンプルな話で、get_exampleが返すラベルの値がnumpyオブジェクトでないことが原因です。
Trainerを使わずにコードを書いている時は、値をVariableにwrapする時点でnumpyオブジェクトになっていないとTypeError("numpy.ndarray or cuda.ndarray are expected.")が出るので気が付きやいのですが、Iterator/Trainerに任せると異なるエラーが出てくるので私はなかなか原因に辿りつけませんでした(型チェックを行うような要望をすべき?)。

## 対策

この場合ラベル値の入っている配列llistをnumpyオブジェクトにすれば解決です。

```diff
@@ -16,7 +16,7 @@
                 flist.append(os.path.join(root, file))
                 llist.append(label_num)
         self.flist = flist
-        self.llist = llist
+        self.llist = np.asarray(llist, dtype=np.int32)
 
     def __len__(self):
         return len(self.flist)
```

## 最後に

Trainerを使うとファンシーな進捗出力(ProgressBar())が出せてかっこいいのでぜひTrainerを使いましょう。
stylusとpostcssを併用する

poststyle (postcssをstylusパッケージで使えるようラップしたもの)を使わず、
stylusとpostcssを併用しようと思い、
ごにょごにょ書いてました。

A:stylus -> css, B: css -> css
の流れで2回ソースマップの生成があります。

それらをA.map, B.mapとしたときに、、
A.map + B.map = C.mapが欲しい。（足し算はイメージです）

postcssのオプションで、ソースマップを渡すことができ、
書き方やディレクトリ構成によってはうまくマージしてくれるようなんですが、

なんかうまくマージされなかったので、
multi-stage-sourcemap というパッケージを使って、
（poststyleのコード見たら、その中でも使われてた）
C.mapを生成しました。
書き方、ドキュメント見ればわかるんですが、パラメーターの順番に注意です。
from B, to Aです。

```js
var Cmap = require('multi-stage-sourcemap').transfer({
  fromSourceMap: Bmap
, toSourceMap: Amap
})
```

ごにょっと書いた全容です。タスクランナーって便利だなと思いました。

```js
var fs = require('fs')
  , del = require('del')

  , pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'))

  , stylus = require('stylus')
  , stylusStr = fs.readFileSync('./stylus/main.styl', 'utf8')

  , postcss = require('postcss')
  , autoprefixer = require('autoprefixer')
  , csswring = require('csswring')

  , msMaper = require('multi-stage-sourcemap').transfer
  , cssName = 'hello.css'
  ;

var style = stylus(stylusStr)
              .set('filename', './stylus/main.styl')
              .set('paths', ['./stylus/'])
              .set('sourcemap', {
                  'sourceRoot': '//localhost:' + pkg.config.server.dev.port
                , 'comment': false
                })
              ;

style.render(function(err, css){
  if (err) throw err;

  postcss([
      autoprefixer(pkg.config.stylus.autoprefixer)
    , csswring(pkg.config.stylus.csswring)
    ])
    .process(css, {
      from: 'main.css'
    , to: cssName
    , map: (pkg.config ? {inline: false, sourcesContent: false} : false)
    })
    .then(result => {
      // Clean up
      del.sync([pkg.config.path.app + 'css'], {'force': true})

      // Make directory
      mkdirp(pkg.config.path.app + 'css', function(err) {
        if (err) throw err;

        if (pkg.config.isDebug) {
          // Output sourcemap
          fs.writeFileSync(
            pkg.config.path.app + 'css/' + cssName + '.map'
          , msMaper({
               fromSourceMap: result.map.toString()
             , toSourceMap: style.sourcemap
             })
          , 'utf8'
          );
        }
        // Output css
        fs.writeFileSync('css/' + cssName, result.css);

        console.log('🍺  Compiled stylus!')
     })
   });

});

```

パッケージAが提供するAPIをラップしたBをラップしたCを使ったGulpのパッケージを使ってコンパイル、とかやってると、
Aがどう動いてるのかとか、どういうAPIを提供しているのかがわからず、
Aのバージョンアップで機能追加されたときに、B, C, Gulpパッケージのアップデートをまったり、いちいちプルリクすんの面倒だね
というブログ記事とかを読んで触発されてこんな面倒なことしています。

面倒です。
gulp-slim でgulpからslimに渡す変数の1文字目は小文字でないとエラーになります

gulp-slim(0.3.0)では、以下の様にgulpからslimに変数を渡せます。（dataのところです）

```js

gulp.src("./src/slim/*.slim")
  .pipe(slim({
    pretty: true,
    data: {
      Title: "Just a list of usernames",
      Users: [
        { name: "Fred" },
        { name: "Bill" },
        { name: "Harry" }
      ]
    },
    options: "encoding='utf-8'"
  }))
  .pipe(gulp.dest("./dist/html/"));
});
```

ここのkeyの1文字目を大文字にすると以下の様なエラーがでました。

```
events.js:160
      throw er; // Unhandled 'error' event
      ^

Error: no writecb in Transform class
    at afterTransform 
    at TransformState.afterTransform 
    at Socket.<anonymous> (
    at emitNone (events.js:91:20)
    at Socket.emit (events.js:185:7)
    at endReadableNT (_stream_readable.js:974:12)
    at _combinedTickCallback (internal/process/next_tick.js:74:11)
    at process._tickCallback (internal/process/next_tick.js:98:9)
error Command failed with exit code 1.
```

1文字目は小文字にしておけば、エラーがでませんでした。
PostgreSQLで禁断の配列型カラムを使ってみた

ちょっとした気の迷いでint配列型のカラムを使うことにした。
普段、配列型のカラムは使わず、正規化してテーブルを分けることがほとんどだった。

配列型カラムについての簡単なまとめ
>PostgreSQLで配列型のカラムを使ってみる
http://d.hatena.ne.jp/pasela/20070301/postgresql

公式Documentでは以下のような警告が…
>ティップ: 配列は集合ではありません。特定の配列要素に検索をかけることはデータベース設計が誤っている可能性を示唆しています。配列の要素とみなされるそれぞれの項目を行に持つ別のテーブルを使うことを検討してください。この方が検索がより簡単になり要素数が大きくなっても拡張性があります。
http://www.postgresql.jp/document/pg823doc/html/arrays.html

嫌な予感しかしないが、とりあえずやってみた。

- int配列 `array(0,1,1,2,3,5)` をカラムに格納したい

`{0,1,1,2,3,5}` という **文字列** に変換してinsertしなければいけない。

```php:
public static function toIntArray($values)
{
    if (is_array($values)) {
        return '{' . implode(',', $values) . '}';
    }
    return null;
}
```

- カラムに格納されたint配列をfetchしたい

fetchすると、なんと`{0,1,1,2,3,5}` という **文字列** が返ってきてしまう。
したがって、`{}`でtrimしてからexplodeすることが必要になる。

```php:
public static function fromIntArray($value)
{
    $value = trim($value, '{}');
    if (strlen($value) === 0) {
        return [];
    }
    $values = explode(',', $value);
    return array_map(function ($v) {
        return intval($v);
    }, $values);
}
```

もし、int配列ではなくstring配列が欲しい場合、`intval($v)`を`strval($v)`に書き換えるだけ。

「正規化して別テーブルに書いたほうがいいのは明らかなんだけど、たった数個のカラムのテーブルを作る抵抗感…」というときには悪くないかもしれない。やや注意が必要という話。
CloudWatchLogsの通知をLambdaで受け取る

# 概要

CloudWatchLogsのログイベントをAWS LambdaでClojure使って取得したらけっこう面倒だった

## CloudWatchLogsの仕様

[サブスクリプションフィルタの使用 - AWS Lambda](http://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/Subscriptions.html#LambdaFunctionExample)

>Lambda の配列を含むレスポンスが表示されます。Lambda レコードの [Data] 属性は、Base64 でエンコードされており、gzip 形式で圧縮されています。Lambda が受け取る実際のペイロードは、{ "awslogs": {"data": "BASE64ENCODED_GZIP_COMPRESSED_DATA"} } の形式になります。raw データは、コマンドラインから次の UNIX コマンドを使用して調べることができます。

結構面倒だぞ、最初Base64だけかと思ってたけどGZIP圧縮もされてる。

## Java8あるしClojure使おう

設定は [Writing AWS Lambda Functions in Clojure](https://aws.amazon.com/jp/blogs/compute/clojure/) を参考にした

## ソースサンプル

* テストデータがJSON型だとイベントハンドラの関数もそれに対応した型を宣言しないとだめっぽい
    * `(defn -handleEvent [^java.util.HashMap m]` ← これ
    * それをClojureのMapに変換 `(def am (into {} m))`
    * `get-in`で取り出し `(def data (get-in am ["awslogs" "data"]))` Rubyの`dig`関数っぽい

```clojure:core.clj
(ns core
  (:import org.apache.solr.common.util.Base64)
  (:import java.io.ByteArrayInputStream)
  (:import java.util.zip.GZIPInputStream)
  (:import org.apache.commons.io.IOUtils)
  (:gen-class
   :methods [^:static [handleEvent [java.util.HashMap] String]]))

(defn -handleEvent [^java.util.HashMap m]
  (def am (into {} m))
  ;; CloudWatchLogsはBase64形式で来る => {awslogs={data=XXX}}
  (def data (get-in am ["awslogs" "data"]))
  (println (str "aws cloud logs with Base64 => " data))

  ;; デコードしてGZIP解凍するべし
  (let [bytes (Base64/base64ToByteArray data)
        bi (new ByteArrayInputStream bytes)
        zi (new GZIPInputStream bi)
        json (IOUtils/toString zi)]
    ;; やっと表示
    (println (str "aws cloud logs => " json)
    json)))

```

ライブラリは以下を使用した

```:project.clj
[org.apache.solr/solr-solrj "6.0.0"]
[commons-io/commons-io "2.5"]
[com.amazonaws/aws-lambda-java-core "1.1.0"]
```

Clojureをもっと使っていきたい
要素数が少ないUITableViewで残りの部分や余白を消す

### 追記: 2017/04/03

**UITableViewにgroupedというタイプがあることを知りませんでした＞＜**

もしかしたらお探しの結果はTableViewをgroupedにすることで実現するかもしれません。

元記事も残しておきますが、かなりのチカラワザであることをご承知ください:bow:

# 元記事

空のUIViewかなんかをtableFooterViewに設定してあげると良いみたいです。

| Before | After |
| --- | --- |
| <img width="244" alt="螢幕快照 2017-02-03 17.31.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/15144/9109784f-09f4-a663-dc0a-8e61d158a718.png"> | <img width="244" alt="螢幕快照 2017-02-03 17.32.40.png" src="https://qiita-image-store.s3.amazonaws.com/0/15144/d119f507-02e4-0e4f-8b77-59257f9cf031.png"> |

```swift:Swift
view.backgroundColor = .groupTableViewBackground

let tableFooterView = UIView(frame: CGRect.zero)

tableView.tableFooterView = tableFooterView
```

もしうまくいかなかったら、最初の行の `view` を `tableView` に変えてみてください。

参考

[UITableViewのPlainスタイルで空のセルを表示させないようにする](http://kohkimakimoto.hatenablog.com/entry/2014/10/10/144022)
[How to remove empty cells in UITableView? [duplicate]](
http://stackoverflow.com/questions/14520185/how-to-remove-empty-cells-in-uitableview)
【Unity】マルチシーンエディティングについて

#マルチシーンエディティングとは？
http://tsubakit1.hateblo.jp/entry/2016/01/13/233000　
引用
>　マルチシーンエディティング（Multi Scene Editing）はUnity 5.3から入った機能で、複数のシーンを同時の編集する機能です。
複数のシーンを同時に編集できる、それだけではありますが、その機能を応用すると色々な用途に使えそうです。
例えば
・「ステージ」や「ギミック」毎にシーンに分割して、お互いに管理する
・広大なステージを複数のシーンに分割して、必要になったら読む
・UIをシーン毎に管理する
・テストシーンで作成した機能を本番シーンに移植する

最近できて結構使いやすく分業するにはこれだと思ったのでメモ程度ですが記事にします。
ちょっとでも参考に出来ればと思います。

#使い方など
こちらを参照して頂ければ大体の事がわかります。
　http://tsubakit1.hateblo.jp/entry/2016/01/13/233000
  http://tsubakit1.hateblo.jp/entry/2016/04/18/011411

二つ注意としては、
・シーン間の参照（例えば　オブジェクトのアタッチ）などができないので、もしシーン間の参照がしたいのであれば、各シーンにシングルトンクラスをアタッチしたオブジェクトを配置し　それで、参照すればいいと思います。　ちなみに[サンプルプロジェクト](https://github.com/SatoSeiichi/MultiSceneEditing)でもそういった感じで実装されています。
・シーンの遷移演出などをした場合、シーンかぶりが発生し、事前にレイヤー分けをしておかないと
かぶった時大惨事が起きます。なので事前に設計が必要
例えば、ライティングがかぶって　めちゃくちゃ光量があるように見えたりします。

＃サンプルプロジェクトについて
今ままでちょっと難しかったシーンの遷移演出などが入っている簡単なサンプルプロジェクトです。
https://github.com/SatoSeiichi/MultiSceneEditing