OmniAICreator/Qiita-1.07M huggingface dataset:
cdコマンドの履歴で”戻る/進む”機能を実装する3行のAlias

#経緯
むか～し新人研修でUnixやってるときに、暇だったので書いてみたやつです。

"cd -"でも、一個前のディレクトリには戻れますが、一個だけしか戻れないのでついカッとなって書きました。
~~今見たら、若干理解に苦しむのですが、~~この記事上げてから、改めて見直したら理解出来ました（笑）。~~シンプルですが、でも大体動くんだよな。。。~~見直したら結構動いてませんでした。（恥）なので、見直しして今は大丈夫。（のはず）


#良い所（2016/03/15追記）
pushd/popdという方法も有るらしいというtweet頂き、確認したところ確かに有るようですね。知らなかった。有難うございます。
ただ、pushdとか指定しないとスタックに積めないってのはめんどい。

このaliasの特徴としては、以下となるかと思います。
・ユーザーは、特にスタックを意識せずに日常的にcd XXXXとかやれば良い。
・ヒストリを戻りたい時はb、戻ってきたヒストリをやっぱり元に進み（？）たい時はfで進めます。
・幾つかヒストリを戻ってきて、そこで再度全然別のDirにcdすると、そこから新たにヒストリを積み直しますから、ブラウザの履歴の動きとほぼおんなじです。
・もちろん、`cd -`も`cd`も問題なく動く。



#実装
エイリアスで、以下の3つを登録します。

2016/03/15追記
当初のやつはバグがありました。ストックしてくれる人が~~意外にも~~有り難い事にいらっしゃったので、大体うごく、で公開しちゃいかんだろと反省し、十年前の拙さを多少補いました。
以下はかなりちゃんと動きます。

```
alias b='if [[ $l -le 1 ]]; then l=1; if [[ $f2 -eq 1 ]]; then f2=;if [ "$la" != "$PWD" ]; then h=$PWD:$h;la=$PWD;fi;fi;fi;((l=l+1));f=1;cd'
alias f='f=1;if [[ $l -le 1 ]]; then l=1;f=;else ((l=l-1));cd;fi'
alias cd='((l2=l+1));if [[ $f -eq 1 ]];then f=;t=`echo $h|cut -f$l -d:`;else f2=1;if [ "$la" != "$PWD" ]; then h=$PWD:`echo $h|cut -f$l2- -d:`;la=$PWD;fi;l=0;t=;fi;cd $t'
```

以下は本記事公開当初のものですが、色々イケてないので非推奨。（[家康のうんこ漏らし絵](http://arufa.hatenablog.jp/entry/2015/10/02)的に自戒の念を込めてそのまま載せます。）

```
alias b='flag=1;if [[ $level -le 0 ]]; then level=0;fi;((level=level+1));cd'
alias f='flag=1;if [[ $level -le 0 ]]; then level=0;else ((level=level-1));fi;cd'

alias cd='if [[ $flag -eq 1 ]];then target_dir=`echo $thpa|cut -f$level -d:`;else thpa=$PWD:`echo $thpa|cut -f$level- -d:`;level=0;target_dir=;fi;flag=;cd $target_dir'
```

んで、好きなだけcdとかして、bってコマンドうつと、ブラウザの戻るボタンと同じ。
fってコマンド打つと、ブラウザの進むボタンと同じ。それだけです。

解説は、、、~~あんまり覚えてないので出来ません。。~~そのうち書きます。
~~大体動きます。大体。~~わりとちゃんと動きます。割とレアなケースで、bしても1回だけ移動せずに同じディレクトリに残る様に見えるケースがある位で、あとは大丈夫。（のはず。）

以上です。

#実際のところ、、（これも2016/03/15追記）

**作者はあんまり使ってません。 :stuck_out_tongue_closed_eyes:**
というのも、

- 研修後アサインされた部署では何百もあるUnixサーバーの運用とかやってたので、一々サーバー毎のAliasとか管理面倒くさかったから。「こっちにはあるけどコッチにはないじゃん。あーーーー」となる。
- 先輩と会話したら、「そういう便利なのが何にも無い状況で障害対応せざるを得なかったらどうするんだよ。パス覚えとけ。」と一蹴され、確かに一理ある、と思いました。
- 仕事でそういう体になってしまったので、そもそもaliasで何か登録するという行為自体をやらなくなった。
- 今は複数のUnix（Linux）に入るし、作ったり消したりも多いので、ますます個別カスタマイズなんてやらないのが当たり前になった。

まぁ、そういうスタイルなので実質的にあんまり使えないだけです。
人によっては役に立つのかもしれないので、そういう人は使ってみてください。
Paizaで美少女とPythonを学んでみた#02



[Pythonで彼女ができる](https://paiza.jp/poh/ando)と噂のPaizaさんの[美少女とPythonが学べる](https://paiza.jp/learning)サービスをこなしてみたので感想など雑感です。なお、本記事は入門編2です。1は[こちら](http://qiita.com/sayamada/items/328f7c273664b27618aa)をご覧ください。


## 入門編2(約60分)
## chapter1:IF文による条件分岐 (4:44)

* IF文について
* 数字の条件で表示を変える

```python
if 条件:
    条件を満たしたときのアクション
else:
    条件を満たさなかったときのアクション
```

* インデントは4スペース
* ==で等しいという条件
* **:**を忘れがちなので注意
* インデントも大事なので忘れないように
* ブロックという概念、同じインデントがそろっている範囲が同じブロック


### 演習課題

* 4問
* if,elseの使い方
* 間違いやすい構文エラー

## chapter2:複数の条件を組み合わせてみよう (3:46)

* elifでほかの条件を指定できる

```python
if 条件1:
    action1
elif 条件2:
    action2
else:
    action3
```


### 演習課題

* 2問
* 構文エラーとelif



## chapter3:比較演算子で条件分岐してみよう (4:54)

* ==以外の演算子として >や<が登場
* ```>=``` と```<=```で以上以下
* ```!=``` で等しくない 


### 演習課題

* 3問
* 少し難易度あがり、条件式を自分で書くように
* 構文ミスではなくロジックミスの指摘問題も

## chapter4:おみくじを作ってみよう (5:04)

* if else elifあたりの総括
* 期待した動作になっているかrandintの結果をprintデバッグしながら動かす

### 演習課題

* 1問
* あまりchapter3と変わらないかも

## chapter5:RPGのクリティカルヒットを再現 (2:46)

* if文の中のブロックでもう少し込み入ったことをしようという話

### 演習課題

* なし

## chapter6:西暦から平成何年かを求めてみよう (4:19)

* ifはいったん終わり
* 西暦 - 1988で処理する話
* 今年の取得に```datetime.date.today().year```がでてきた

### 演習課題

* 1問
* 昭和を求める


## ざっくりとした感想

これで現在公開されているPython入門編が終わりました。さすがに入門1よりはレベルが高いですがそれでも初歩の初歩といった感じです。"プログラミング言語のPython"としての"プロ"あたりの説明を丁寧にしている感じです。ただ構文としてはifしかでてこないので、せめてfor/whileがでてくるといいのかなと思いました。
ufw initscript 覚書

``/etc/default/ufw`` のコメント行の和訳。

# IPV6

```
IPV6=yes
```

IPv6 サポートをルールへ適用する場合は yes を設定する。 
(loopback 上の IPv6 以外も許可する) 
変更を適用する為に下記のコマンドで ufw を再起動する必要がある。

```
ufw disable && ufw enable
```

# DEFAULT_INPUT_POLICY

```
DEFAULT_INPUT_POLICY="DROP" | "ACCEPT" | "REJECT"
```

既定の受信ポリシーへ ACCEPT, DROP, または REJECT を設定する。 
設定を変更した場合、ルールの調整が必要となることが多い。

# DEFAULT_OUTPUT_POLICY

```
DEFAULT_OUTPUT_POLICY="ACCEPT" | "DROP" | "REJECT"
```

既定の送信ポリシーへ ACCEPT, DROP, または REJECT を設定する。 
設定を変更した場合、ルールの調整が必要となることが多い。

# DEFAULT_FORWARD_POLICY

```
DEFAULT_FORWARD_POLICY="DROP" | "ACCEPT" | "REJECT"
```

既定の転送ポリシーへ ACCEPT, DROP, または REJECT を設定する。 
設定を変更した場合、ルールの調整が必要となることが多い。

# DEFAULT_APPLICATION_POLICY

```
DEFAULT_APPLICATION_POLICY="SKIP" | "ACCEPT" | "DROP" | "REJECT"
```

既定のアプリケーションポリシーへ ACCEPT, DROP, REJECT 
または SKIP を設定する。ACCEPT を設定した場合、
セキュリティリスクとなる場合がある。詳細は ``man ufw`` を参照。

# MANAGE_BUILTINS

```
MANAGE_BUILTINS=no | yes
```

既定では ufw は ufw 自身のチェーンのみを操作する。 
yes を指定した場合、 ufw は組込みのチェーンも管理する。

*Warning:*
yes を指定した場合、 ufw 以外のアプリケーションが管理する
ファイアウォールのルールも改変する。

# IPT backend
## IPT_SYSCTL

```
IPT_SYSCTL=/etc/ufw/sysctl.conf
```

iptables バックエンドを使用する場合のみ有効にする。

## IPT_MODULES

```
IPT_MODULES="nf_conntrack_ftp nf_nat_ftp nf_conntrack_netbios_ns"
```

拡張接続トラッキングモジュールの読込設定。 
完全なリストはカーネルソースの ``net/netfilter/Kconfig`` を参照。

### 一般的なモジュール
#### DCC (Direct Client to Client) support

* nf_conntrack_irc
* nf_nat_irc

#### NetBIOS (samba) client support

* nf_conntrack_netbios_ns

#### PPTP over stateful firewall/NAT

* nf_conntrack_pptp
* nf_nat_pptp

#### active FTP support

* nf_conntrack_ftp
* nf_nat_ftp

#### TFTP support (server side)

* nf_conntrack_tftp
* nf_nat_tftp
MySQLのデータをカラム指定してcsv,tsv形式でダンプする

# 手順
MySQLのデータをカラム指定してcsv,tsv形式でダンプするには、
`mysqldump`と `cut`コマンドを組み合わせる必要があります。

1.mysqldumpでcsvデータを作成
2.cutで必要なカラムだけを抽出

 
# mysqldumpでデータをダンプ

[MySQLのデータをカラム指定してcsv,tsv形式でダンプする](http://qiita.com/d-dai/items/e56c2e5abf558328373f)　を参考にcsv(tsv)データを作ります。


```
$ mysqldump -u{ユーザー名} -p --tab=/tmp --fields-terminated-by=, {DB名} {テーブル名(省略可能)}
Enter password:パスワードを入力
```

# cutコマンドで指定カラムだけを抽出
`cut` はテキストファイルからバイトやカラムを指定して抽出できるunixコマンドです。

```
$ cut --help
使用法: cut [オプション]... [ファイル]...                                  
ファイルの各行から選択した部分だけを切り出して, 標準出力に表示します.

長いオプションに必須の引数は短いオプションにも必須です.
  -b, --bytes=LIST        select only these bytes
  -c, --characters=LIST   select only these characters
  -d, --delimiter=DELIM   use DELIM instead of TAB for field delimiter
  -f, --fields=LIST       select only these fields;  also print any line
                            that contains no delimiter character, unless
                            the -s option is specified
・・・
```
`-d`と `-f`オプションを使うことで、指定カラムだけを抽出できます。

## `-d`オプション
区切り文字を指定するオプションです。
省略時はタブが区切り文字となります。

## `-f`オプション
抽出するフィールドを指定するオプションです。
カンマ区切りで複数指定でき、`-f 1,3`と使うと、1列目と3列目だけを抽出できます。



例えばcsvのファイルの1，3列目を抽出するには、以下のように実行します。

```
$ cut -d , -f 1,3 {ファイル名}
```

ファイルに出力する場合はリダイレクトします。

```
$ cut -d , -f 1,3 {ファイル名} > {出力ファイル名}
```
ズンドコキヨシ with Go

元ネタ：https://twitter.com/kumiromilk/status/707437861881180160

Golang初心者が頑張って書いてみたよ！

https://github.com/syossan27/zundo-go

## Go

Sleepを挟んだのはズンドコ感を味わってもらうためです。

```
package main

import (
  "fmt"
  "math/rand"
  "time"
  "reflect"
  "os"
)

func main() {
  zun := "ズン"
  doko := "ドコ"
  zundoko := []string{zun, doko}
  zzzzdoko := []string{zun, zun, zun, zun, doko}
  lyrics := []string{}

  rand.Seed(time.Now().UnixNano())

  for {
    time.Sleep(1 * time.Second)
    word := zundoko[rand.Intn(2)]
    fmt.Print(word + " ")
    lyrics = append(lyrics, word)
    if len(lyrics) >= 5 {
      length := len(lyrics)
      some_lyrics := lyrics[length-5:]
      if reflect.DeepEqual(some_lyrics, zzzzdoko) {
        fmt.Print("キ・ヨ・シ！")
        os.Exit(0)
      }
    }
  }
}
```
MySQLのデータをcsv,tsv形式でダンプする

#MySQLのデータをcsv,tsv形式でダンプする

MySQLには `mysqldump`というダンプツールがあります。
基本的な使い方は以下のようになります。

```
$ mysqldump -u{ユーザー名} -p {DB名} {テーブル名(省略可能)} > {出力ファイル}
Enter password:パスワードを入力
```

出力形式はSQLのCREATE文とINSERT文になりますが、オプションを指定することで、
`csv`や `tsv`形式にすることが可能です。

#csv,tsv出力のオプション
csv(tsv)で出力するには、 `--tab`と `--fields-terminated-by` の2つのオプションを使用します。

##--tabオプション
ファイルの出力先ディレクトリを指定するオプションです。
`--tab=/tmp`と指定すれば、/tmp以下にファイルが出力されます。
このオプションは、csv(tsv)形式で出力する場合は必須です。

##--fields-terminated-byオプション
区切り文字を指定するオプションです。
デフォルトはタブになりますので、tsvファイルで出力する場合はこのオプションは不要です。

csv形式で出力したい場合は、 `--fields-terminated-by=,`と指定します。


##tsv形式で出力する例
```
$ mysqldump -u{ユーザー名} -p --tab=/tmp {DB名} {テーブル名(省略可能)}
Enter password:パスワードを入力
```


##csv形式で出力する例
```
$ mysqldump -u{ユーザー名} -p --tab=/tmp --fields-terminated-by=, {DB名} {テーブル名(省略可能)}
Enter password:パスワードを入力
```
vagrant で synced_folder の権限変更


使ってる version は、`vagrant-1.6.3`。

vagrant の VM 内で、ディレクトリに `chmod` しても反映されない現象。
今回は、`/home/vagrant/shared_vagrant` の権限を変えたい。

```
[vagrant@localhost vagrant]$ ls -la /home/vagrant | grep shared
drwxr-xr-x  1 vagrant vagrant   102 Mar 11 22:21 shared_vagrant
[vagrant@localhost vagrant]$ chmod 777 shared_vagrant
[vagrant@localhost vagrant]$ ls -la /home/vagrant | grep shared
drwxr-xr-x  1 vagrant vagrant   102 Mar 11 22:21 shared_vagrant # 755 のまま…
```


どうやら、`synced_folder` として設定していたのが原因のようだった。

```ruby
config.vm.synced_folder "./shared_host", "/home/vagrant/shared_vagrant"
```

`synced_folder` の option に、`mount_options` というのがあるので、権限を変更したければ、これを指定してあげるのがよさそう。
https://www.vagrantup.com/docs/synced-folders/basic_usage.html


Vagrantfile に下記のように記述を追加。
`dmode` がディレクトリの権限で、`fmode` がファイルの権限のご様子。
権限はよしなに指定する。今回は雑に `777` で。

```ruby
config.vm.synced_folder "./shared_host", "/home/vagrant/shared_vagrant", :mount_options => ['dmode=777', 'fmode=777']
```

編集が終わったら、一度ホスト側で reload する。

```
% vagrant reload
```

ssh して対象ディレクトリの権限を確認すると、指定した権限が反映されている。

```
[vagrant@localhost vagrant]$ ls -la /home/vagrant | grep shared
drwxrwxrwx  1 vagrant vagrant   102 Mar 11 22:21 shared_vagrant
```

# 補足
`mount_options` に何を指定すればよいのかわからなかったので、調査した時のメモ。
まずはソースコード見てみる。

```
% grep -nri mount_options /Applications/Vagrant/
```

見つかったこのファイルを確認したところ、`mount -t vboxsf` に、そのまま渡しているように見える。
`/Applications/Vagrant//embedded/gems/gems/vagrant-1.6.3/plugins/guests/linux/cap/mount_virtualbox_shared_folder.rb`

vboxfs は virtualbox ぽいなってことぐらいしかわからなかったので、`mount.vboxsf` ってコマンドの option を調べた。

```
[vagrant@localhost vagrant]$ sudo mount.vboxsf
Usage: mount.vboxsf [OPTIONS] NAME MOUNTPOINT
Mount the VirtualBox shared folder NAME from the host system to MOUNTPOINT.

  -w                    mount the shared folder writable (the default)
  -r                    mount the shared folder read-only
  -n                    do not create an mtab entry
  -o OPTION[,OPTION...] use the mount options specified

Available mount options are:
     rw                 mount writable (the default)
     ro                 mount read only
     uid=UID            set the default file owner user id to UID
     gid=GID            set the default file owner group id to GID
     ttl=TTL            set the "time to live" to TID for the dentry
     dmode=MODE         override the mode of all directories to (octal) MODE
     fmode=MODE         override the mode of all regular files to (octal) MODE
     umask=UMASK        set the umask to (octal) UMASK
     dmask=UMASK        set the umask applied to directories only
     fmask=UMASK        set the umask applied to regular files only
     iocharset CHARSET  use the character set CHARSET for I/O operations
                        (default set is utf8)
     convertcp CHARSET  convert the folder name from CHARSET to utf8

Less common used options:
     noexec,exec,nodev,dev,nosuid,suid
```

これで、`dmode`/`fmode` てところまでたどり着いた、つもり。
ズンドコキヨシ with Wren

参考: http://qiita.com/y__sama/items/7c451dfd706f9b36729d

```
import "random" for Random
var z = "ズン"
var d = "ドコ"
var zd = [z, d]
var expected = [z, z, z, z, d].join()
var random = Random.new()
var tmp = []
(0..4).each {tmp.add(random.sample(zd))}
var actual = tmp.join()
System.print(actual)
while(actual != expected) {
    tmp.removeAt(0)
    var x = random.sample(zd)
    System.print(x)
    tmp.add(x)
    actual = tmp.join()
}
System.print("キ・ヨ・シ！")
```

## <i class="fa fa-image" style="font-size:1em;"></i> Playground
![スクリーンショット_031216_012204_AM.jpg](https://qiita-image-store.s3.amazonaws.com/0/43480/0d465aab-846d-9f0a-3f47-ac810312a09a.jpeg)

## <i class="fa fa-book" style="font-size:1em;"></i> 外部サイト
* [wren Playground](http://ppvk.github.io/wren-nest/)
* [munificent/wren - GitHub](https://github.com/munificent/wren)
フォームからファイルを選択した際に、submitする前にプレビュー表示する方法(jQuery"無し"版)

## はじめに
フォームの入力の際に、入力に間違いがないかプレビュー表示する
この機能を実現するためにFileAPIを利用する
JavaScriptのFileAPIは2016年3月現在ほぼすべてのブラウザに対応している(IEさえも)

本サンプルコードはpureなJavaScriptのみでjQueryを使っておりません。

※[前回書いた記事](http://qiita.com/kon_yu/items/f98df7ac826e7c36cc6c)ではjQueryのセレクタやその他メソッドを使っていただ普通のJSだけで書いたらどうなるか気になったので書いてみた。

## Demo
動作を確認できるデモはこちら
[Demo](http://jsdo.it/kon_yu/iKFn)

## 対象のコード
```html
<form>
    <input type="file">
</form>

<div class="preview" />
```

```js
// documentと毎回書くのがだるいので$に置き換え
var $ = document; 
var $form = $.querySelector('form');// jQueryの $("form")相当

//jQueryの$(function() { 相当(ただし厳密には違う)
$.addEventListener('DOMContentLoaded', function() {
    //画像ファイルプレビュー表示
    //  jQueryの $('input[type="file"]')相当
    // addEventListenerは on("change", function(e){}) 相当
    $.querySelector('input[type="file"]').addEventListener('change', function(e) {
        var file = e.target.files[0],
               reader = new FileReader(),
               $preview =  $.querySelector(".preview"), // jQueryの $(".preview")相当
               t = this;
        
        // 画像ファイル以外の場合は何もしない
        if(file.type.indexOf("image") < 0){
          return false;
        }
        
        reader.onload = (function(file) {
          return function(e) {
             //jQueryの$preview.empty(); 相当
             while ($preview.firstChild) $preview.removeChild($preview.firstChild);

            // imgタグを作成
            var img = document.createElement( 'img' );
            img.setAttribute('src',  e.target.result);
            img.setAttribute('width', '150px');
            img.setAttribute('title',  file.name);
            // imgタグを$previeの中に追加
            $preview.appendChild(img);
          }; 
        })(file);
        
        reader.readAsDataURL(file);
    }); 
});
```
ridgepole


### migration
migrationの利点はスキーマの変動が激しい開発現場では前の以前のものに復元したい場合があります。そのときにとても有効な機能


#### Ridgepole

`Schemafile`というファイルに `Ruby DSL`でテーブル定義を書くことで反映させます。

`Schemafile`に一行足せば、dbを変えることができる強力なものです。



## コマンド

### スキーマを変更

$`bundle exec ridgepole -c config/database.yml -f Schemafile --apply`

## dbからのインポート

$`bundle exec ridgepole -c config/database.yml --export -o Schemafile `


## dry　run 

$`bundle exec ridgepole -c config/database.yml --dry-run -e test`
モデルの書き方


#dependent

`dependent`はモデル削除時に関連先のモデルも削除するかどうか

## destroy

```
 class User < ActiveRecord::Base
   has_many :blog, :dependent => :destroy
 end

```
このようにして
Userのオブジェクトをdestroyすると、blogのdestroyも呼び出されるそう

## nullify

```
 class User < ActiveRecord::Base
   has_many :blog, :dependent => :nullify
 end
```

Userをdestoryすると、blogのsaveを呼び出さずに
blogのuserへのforign_keyをnullにする。


#foregin_key

`foregin_key`　アソシエーションで使用する外部キー列の名前




#検証の書き方

`presence`は値で空ではないか




#参考

[Ruby on Rails/has_manyのdependentオプション](http://www.ark-web.jp/sandbox/wiki/390.html)
ズンドコキヨシ with Scala

[元ネタ](https://twitter.com/kumiromilk/status/707437861881180160)

Scalaらしく再帰とパターンマッチで。

```scala:kiyoshi.scala
import scala.util.Random
def zundoko(zd: List[String] = Nil): Unit = zd match {
  case "ドコ" :: "ズン" :: "ズン" :: "ズン" :: "ズン" :: _ => println(zd.reverse.mkString + "キ・ヨ・シ！")
  case _ => zundoko((if(Random.nextBoolean) "ズン" else "ドコ") :: zd)
}
zundoko()
```

再帰とパターンマッチ……[先を越されてしまいました](http://qiita.com/fujimura/items/52ded074c97b2f1327ec)orz

あ、あとYコンビネータで

```scala:kiYoshi.scala
import scala.util.Random
def Y[A, B](f: ((A => B), A) => B, x: A): B = f((y: A) => Y(f, y), x)
Y((zundoko: List[String] => Unit, zd: List[String]) => zd match {
  case "ドコ" :: "ズン" :: "ズン" :: "ズン" :: "ズン" :: _ => println(zd.reverse.mkString + "キ・ヨ・シ！")
  case _ => zundoko((if(Random.nextBoolean) "ズン" else "ドコ") :: zd)
}, Nil)
```

[参考](http://yuroyoro.hatenablog.com/entry/20100204/1265285318)
PlexmediaserverでKodiのライブラリを利用する

Kodiで映画などの情報をexport libraryでseparate fileで書き出しておく。

Plexmediaserverのpluginで

https://forums.plex.tv/discussion/38402/metadata-agents-for-exported-xbmc-library
が利用できる。

https://github.com/gboudreau/XBMCnfoMoviesImporter.bundle
から
XBMCnfoMoviesImporter.bundle-master.zip
をdownloadして
XBMCnfoMoviesImporter.bundle
とrenameしておく。

入れるPlug-insフォルダは
OSXでは
~/Library/Application Support/Plex Media Server/Plug-ins

ubuntu(Linux)では
/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/Plug-ins

ここに入れる。

Plexmediaserverで
ライブラリを編集のところでエージェントを
XBMCnfoMoviesImporterに変更
use plog instead of outlineをチェックして
変更を保存する。
Functoolsで過剰にスマートなPHPを書こう (無名再帰篇)

こんにちは！ 一年ほど前に作ったPHPのための函数プログラミング用ライブラリ[Teto Functools](https://github.com/BaguettePHP/Functools/)の利用者が全然増えないので、~~信者~~利用者を増やすために、べんり機能を紹介します。

## インストール方法

はじめに[Download Composer](https://getcomposer.org/download/)を読んで`composer`をインストールしてね。

そして、Functoolsをインストール。

```
composer global require zonuexe/functools
```

既存のPHPライブラリに組込むにはこうします。

```
composer require zonuexe/functools
```

とりあえず`global`指定でインストールしたことを前提にコード書くよ。

## 無名再帰とは

[無名再帰](https://ja.wikipedia.org/wiki/%E7%84%A1%E5%90%8D%E5%86%8D%E5%B8%B0)は、無名函数(ラムダ式とも呼ばれる)を使って[再帰](https://ja.wikipedia.org/wiki/%E5%86%8D%E5%B8%B0)することだよ。具体的には[不動点コンビネータ](https://ja.wikipedia.org/wiki/%E4%B8%8D%E5%8B%95%E7%82%B9%E3%82%B3%E3%83%B3%E3%83%93%E3%83%8D%E3%83%BC%E3%82%BF)ってテクニックを利用するんだ。その中でも一番有名なのが「Yコンビネータ」だよ。ネットビジネスやベンチャーについて興味のあるひとは[Y Combinator](https://ja.wikipedia.org/wiki/Y%E3%82%B3%E3%83%B3%E3%83%93%E3%83%8D%E3%83%BC%E3%82%BF_(%E4%BC%81%E6%A5%AD))を知ってるはずだけど、このベンチャーキャピタルを率ゐる[ポール・グレアム](https://ja.wikipedia.org/wiki/%E3%83%9D%E3%83%BC%E3%83%AB%E3%83%BB%E3%82%B0%E3%83%AC%E3%82%A2%E3%83%A0)は有名なLisperなんだ。

[Haskell/不動点と再帰 - Wikibooks](https://ja.wikibooks.org/wiki/Haskell/%E4%B8%8D%E5%8B%95%E7%82%B9%E3%81%A8%E5%86%8D%E5%B8%B0)によれば、Haskellでは`fix`って名前らしいから、恥も外聞もなくぱくってきたよ。カッコイイ用語に酔って中二心が溢れ出してきたのでYコンビネータを実装しようと思ったけど、[`Teto\Functools::fix()`](https://github.com/BaguettePHP/Functools/blob/master/src/Functools.php#L147)で採用されてるのは正確には正格評価の言語でも利用可能なよう変形した「Zコンビネータ」だよ。正格だけにね！

## 無名再帰のやりかた

PHPでショートコーディングしたいと思ふじゃないですか。

```php
<?php
($f = function ($n, $max) use (&$f){
    if ($n <= $max) {
        printf("%dは%s".PHP_EOL, $n, ($n % 2 === 0) ? "偶数" : "奇数");
        $f($n + 1, $max);
    }
})(1, 20);
```

↑ このコードはPHP7では動くけど、PHP5系ではSyntax errorなんだ…！

```php
<?php
use Teto\Functools as f;
require_once getenv('HOME') . '/.composer/vendor/autoload.php';

call_user_func(f::fix(function ($f) {
    return function ($n, $max) use ($f){
        if ($n <= $max) {
            printf("%dは%s".PHP_EOL, $n, ($n % 2 === 0) ? "偶数" : "奇数");
            $f($n + 1, $max);
        }
    };
}), 1, 20);
```

これでPHP5でも式プログラミングができるぞ！ ついでに、見すぼらしい`$f = `も消えて超ハッピー。

## 無名再帰の活用例

[ズンドコキヨシ with PHP - Qiita](http://qiita.com/shinderuman@github/items/7c432e8cb7719d35342a)を見たら触発されたので書いてみたよ。

```php
<?php
use Teto\Functools as f;
require_once getenv('HOME') . '/.composer/vendor/autoload.php';

call_user_func(f::fix(function ($func) {
    $zundoco = function () {
        static $zundoco = ['ズン', 'ドコ'];
        return $zundoco[mt_rand(0, 1)];
    };

    static $pattern = ['ズン', 'ズン', 'ズン', 'ズン', 'ドコ'];
    return function (array $a) use ($zundoco, $pattern, &$func) {
        $len = count($a);
        if (isset($a[$len - 1])) {
            echo $a[$len - 1], PHP_EOL;
        }
        if ($a === $pattern) {
            echo 'キ・ヨ・シ！', PHP_EOL;
        } else {
            $func(array_merge(
                ((count($pattern) > $len) ? $a : array_slice($a, 1)),
                [$zundoco()]
            ));
        }
    };
}), []);
```
AWS CLI を Amazon S3 じゃなくて S3 API 互換オブジェクトストレージで使うときの方法

# はじめに
ことのきっかけは、このリポジトリをたまたま発見したせいだ。

[openstack/ec2-api](https://github.com/openstack/ec2-api)

元々 OpenStack Nova には ec2-api が組み込まれていたのだが、そっちは現在廃止予定になっている。その代わりに別途このリポジトリが出来て Nova とは切り分けて開発されている。

このリポジトリの README を読み進めると、AWS CLI を使った使い方が記載されている。普段、AWS を使っていない自分としては AWS CLI など全く馴染みがなかったのだが、かなり昔に確認した時には `--endpoint-url` などどいうオプションはなかった気がしたのである。

EC2 はこの際どうでもいいのだが、ここでふと気になったのは本家 Amazon S3 ではない S3 API 互換オブジェクトストレージを使う際に AWS CLI が使えるんじゃねーかということである。

# S3 API 互換オブジェクトストレージ
S3 API 互換のオブジェクトストレージはいくつかある。他にもあった気がするがパッと思い浮かんだのはこれくらい。

* [Riak S2](https://github.com/basho/riak_cs)
* [LeoFS](https://github.com/leo-project/leofs)
* [Minio](https://github.com/minio/minio)
* [OpenStack Swift + swift3](https://github.com/openstack/swift3)
* [Cloudian](http://cloudian.jp/cloud-storage-products/)
* [Scality](http://www.scality.com/)
* [Cleversafe](https://www.cleversafe.com/)
* [Amplidata](http://amplidata.com/)

# AWS CLI のインストール
インストールには `pip` を利用する。

```shell-session
$ curl "https://bootstrap.pypa.io/get-pip.py" -o "get-pip.py"
$ sudo python get-pip.py
$ sudo pip install awscli
```

`~/.aws/config` というファイルを作成して必要な情報を入力する。

```text:~/.aws/config
[default]
aws_access_key_id = 1b0e3f78d53d47at8ed4fbb8debc036b
aws_secret_access_key = 9bb06f230ffg4dldbe1e896947f41df3
region = us-east-1
```

# 使ってみる
とりあえず上記のオブジェクトストレージのうちどれかを使って試してみる必要があるので、オープンソースである LeoFS を構築した。なお、構築方法は省略する。`192.168.1.10:80` で `leo_gateway` が起動していると仮定する。

以下のコマンドでバケットの一覧を出力できる。

```shell-session
$ aws --endpoint-url http://192.168.1.10 s3 ls
2016-03-11 15:10:12 mybucket
```

他にもサブコマンドが沢山あるが一通り問題なく実行可能なはずである。

試してないが、たぶん Riak S2 でも Minio でも問題なく AWS CLI が使えるはずである。というか、たぶん上記のオブジェクトストレージなら全て問題ないであろう。
標準出力と標準エラー出力をファイルに追記する

##command
`$ hoge.sh 1>>file 2>&1`
##1
標準出力だよー
##1>>file
標準出力をfileに追記しますよー
##2
標準エラー出力だよー
##2>&1
標準エラー出力の出力先を標準出力の出力先と一緒にしますよー
##つまり...
標準出力と標準エラー出力を一緒にfileに追記しますよー

##参考
- [http://www.creatology.jp/unix/outin.html](http://www.creatology.jp/unix/outin.html)
- [http://to-developer.com/blog/?p=1001](http://to-developer.com/blog/?p=1001)

##余談
初投稿〜、初Markdown〜
OS X 環境での Atom Editor で env を適正化する

# どういう問題?

OS X に Atom Editor をインストールした際に、Dock や Spotlight から Atom.app を起動すると `.bash_profile` などで設定した環境変数が設定されない。

これにより `PATH` も `/usr/bin:/bin:/usr/sbin:/sbin` となってしまうので、homebrew や rbenv などでインストールしたコマンドを使用するには絶対PATH 指定しないといけない。
例えば [script package](https://atom.io/packages/script) はもちろん、`rubocop` や `ag` などなど。

# そこで environment package ですよ

[environment package](https://atom.io/packages/environment)

この package をインストールすることで login shell の環境変数をそれとなく Atom の process.env に置き換えてくれます。

# 不思議

でも全ての環境変数が process.env に入るわけじゃないのはなぜなんだろう…。ちゃんと追ってないのでちょっと不思議。
CakePHP3をMacにインストールする際に行ったこと

cakephp3をmacにインストールする際に行ったことを備忘録としてまとめた記事です。

参考にしたサイト様

- http://blog.milds.net/2015/03/macphpintl.html
- http://mori.moripower.jp/eqwip/cakephp/3283.html 

#発生した問題
- composerを用いてcakephpをインストールする際に以下のエラーが発生しました
    - エラーの主原因は extension-intlがないことらしい
- `composer create-project --prefer-dist cakephp/app bookmarker`
    - エラー文

```
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    cakephp/cakephp 3.2.4 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    cakephp/cakephp 3.2.3 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    cakephp/cakephp 3.2.2 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    cakephp/cakephp 3.2.1 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    cakephp/cakephp 3.2.0 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    Installation request for cakephp/cakephp ~3.2 -> satisfiable by cakephp/cakephp[3.2.0, 3.2.1, 3.2.2, 3.2.3, 3.2.4].
```



#解決策その１(☓)
- `cd /usr/lib/php`
- `sudo php install-pear-nozlib.phar`
    - Capitanの場合、SIPを無効にする必要あり
- `brew install icu4c`
- `sudo pecl install intl`
    - `ICU libraries and headers path is: /usr/local/opt/icu4c/`
- `sudo brew install autoconf`
- `sudo brew install automake`
- `$vi /etc/php.ini`
    - 以下の行を付け加えた
    - `extension=/usr/lib/php/extensions/no-debug-non-zts-20121212/intl.so`
しかし、エラ―は直らず。

#解決策その2(◯)
- php.ini は上記のまま
- `curl -s https://getcomposer.org/installer | /Applications/XAMPP/bin/php`
- `/Applications/XAMPP/bin/php composer.phar create-project --prefer-dist cakephp/app bookmarker`

インストールできました。

#疑問
- 解決策1と2の違い
    - `usr/bin/php`を使うか`/Applications/XAMPP/bin/php`を使うか
        - なぜ `/Applications/XAMPP/bin/php`を使用するとうまくいくのか

なぜ解決策2でインストールができたのかが不明ですが、ひとまず解決です。
ズンドコキヨシ with JavaScript

流行り？のズンドコキヨシのJavaScript版です。ついでにコードゴルフしてみました。結果は文字列に足していき、最後に`console.log`で全て出力します。また、文字数を数えるときはカタカナなども1文字としています。


##配列にどんどん突っ込む

```js:
z="ズン\n", d="ドコ\n", s="", a=[]
while(a.join("") !== z+z+z+z+d) {
  a.shift()
  a[4] = Math.random() < 0.5 ? z : d
  s += a[4]
}
console.log(s + "キ・ヨ・シ！")
```

JavaScriptの`==`と`!=`は比較の時に型が変換されることや、`while`より`for`の方が短くかけることなどを利用して、宣言なども地道に短くしていくと、

```js:
for(a=[z="ズン\n",d="ドコ\n",s=""];a+""!=[z,z,z,z,d];s+=a[4]=Math.random()<.5?z:d)a.shift();console.log(s+"キ・ヨ・シ！")
```

111文字だった。


##文字列を切り取って比較

```js:
z="ズン\n", d="ドコ\n", s=""
while (s.slice(-15) !== z+z+z+z+d) {
  s += Math.random() < 0.5 ? z : d
}
console.log(s + "キ・ヨ・シ！")
```

同様に短くすると、

```js:
for(z="ズン\n",d="ドコ\n",s="";s.slice(-15)!=z+z+z+z+d;)s+=Math.random()<.5?z:d;console.log(s+"キ・ヨ・シ！")
```

99文字だった。先ほどの`[4]`もですが、`-15`のマジックナンバー感が微妙ですね……。


##ズンをカウントし、ドコのとき4以上ならキヨシ、そうでなければリセット

```js:
z="ズン\n", d="ドコ\n", c=0, s=""
while(1) {
  if (Math.random() < 0.5) {
    s += z
    c++
  } else {
    s += d
    if (c >= 4) break
    else c = 0
  }
}
console.log(s + "キ・ヨ・シ！")
```

フラグ、型変換、三項演算子、短絡評価などを組み合わせ、

```js:
for(f=z="ズン\n",d="ドコ\n",c=s="";f;)s+=Math.random()<.5?++c&&z:(f=c<4,c=0,d);console.log(s+"キ・ヨ・シ！")
```

98文字だった。ちょっと複雑すぎる。


##文字列検索

```js:
z="ズン\n", d="ドコ\n", s=""
while (s.indexOf(z+z+z+z+d) === -1) {
  s += Math.random() < 0.5 ? z : d
}
console.log(s + "キ・ヨ・シ！")
```

`indexOf`より`match`の方が短いので、

```js:
for(z="ズン\n",d="ドコ\n",s="";!s.match(z+z+z+z+d);)s+=Math.random()<.5?z:d;console.log(s+"キ・ヨ・シ！")
```
95文字だった。


##まとめ

というわけで、自分の技量だと95文字が限界でした。文字列検索するのが一番短かったわけですが、シンプルでわかりやすい上、マジックナンバーが無く応用しやすそうでいいですね。もっと短く出来るという方、お待ちしております。

##参考

[ズンドコキヨシまとめ](ズンドコキヨシまとめ)
[「ズン ドコ」の検索結果 - Qiita](http://qiita.com/search?q=%E3%82%BA%E3%83%B3+%E3%83%89%E3%82%B3&sort=created)

##追記１

ES2015（ES6）で記録更新しました。
[ズンドコキヨシ with ES2015 (ES6)](http://qiita.com/liburari/items/137c1d6425ffae0c8c10)

##追記２

@gaogao_9 さんの提案をもとに、83文字に！

```js
for(s="";!/(ズン){4}ド/.test(s);s+=Math.random()<.5?"ズン":"ドコ");console.log(s+"キ・ヨ・シ！")
```

##追記３

`s`の検索と結合をまとめた。82文字！

```js
for(s="";!/(ズン){4}ド/.test(s+=Math.random()<.5?"ズン":"ドコ"););console.log(s+"キ・ヨ・シ！")
```
Sum from 1 to 10



```python
>>> sum(range(11))
55
>>> sum([i for i in range(1,11)])
55
>>> sum(i for i in range(1,11))
55
>>> import functools
>>> from functools import reduce
>>> reduce(lambda x,y: x + y, range(1,11))
55
>>> from operator import add
>>> reduce(add, range(1,11))
55
>>> def add_r(n):
	if n == 0:
		return 0
	return n + add_r(n-1)

>>> add_r(10)
55
>>> def add_tr(n, r=0):
	if n == 0:
		return r
	r += n
	return add_tr(n-1, r)

>>> add_tr(10)
55
>>> s = 0
>>> for i in range(1, 11):
	s += i
	
>>> s
55
```
ズンドコキヨシ with Haskell

[ズンドコキヨシ with Perl6
](http://qiita.com/B73W56H84/items/519e27a1aed5e6d5304f)をHaskellでやってみました。もうちょっと短くなるような気もします。

```hs
import           Control.Monad
import           System.Random

data Sound = Z | D | K deriving (Eq, Ord, Show)

main :: IO ()
main = genSound >>= go [] >> putStr "\n"
 where
   go (D:Z:Z:Z:Z:_) _ = putStr (showZDK K)
   go xs x            = putStr (showZDK x) >> genSound >>= go (x:xs)

genSound :: IO Sound
genSound = (!!) [Z,D] <$> getStdRandom (randomR (0,1))

showZDK :: Sound -> String
showZDK Z = "ズン"
showZDK D = "ドコ"
showZDK K = "キ・ヨ・シ！"
```

ところでズンドコキヨシって何？
Crashlytics Beta の api token とか build secret の調べ方

Fastlane の設定してたら、「api token」とか「build secret」を設定する部分があったんだけど、CrashlyticsのWebのUIはすごいアレなので、全然みつからない。で、メモしておく。

結論から行くと、Webで探すんじゃなくて、xcodeprojの `Build Phases` に追加されてる `Run Scripts` の中から持ってくる。

以下のようになっていて、第一引数がapi token, 第二引数が build secret らしいよ。

```
./Fabric.framework/run 098f9a8sf9as8f asdfoias0f8ausof
```

うーん。。。
Composer とバージョン管理 


https://getcomposer.org/doc/articles/versions.md

## 範囲指定

*はセグメント毎に利用可能。

`>=` `<` `<=` `!=`のように比較演算で指定することが出来る。この辺は分かる。

複数の範囲を指定する時は `,` や` `(半角スペース)を利用可能。複数の範囲指定は AND で認識されるので、OR指定が必要な場合には `||`を使用する。

## ハイフン

`-`は両端を含む形で、期待通りの動作をする。

`1.0 - 2.0`は`>=1.0.0 <2.1`と等価で、
`1.0.0 - 2.1.0`は`>=1.0.0 <=2.1.0`と等価。

## チルダ

`~` は指定するバージョンセグメントに応じて、マイナーリリースのみを受け入れる記法

`~1.2`は、`>=1.2 <2.0.0`と等価になり、
`~1.2.3` は、`>=1.2.3 <1.3.0`と等価である。

## キャレット

`^`はチルダよりも積極的に更新を受け入れる。

`^1.2.3`は `>=1.2.3 <2.0.0`と等価になる。

ただし0.x系のバージョンは破壊的変更を頻繁に伴うので、`^0.3`は`>=0.3.0 <0.4.0`と等価として扱われる。
Ubuntuで端末からスクリーンショットを撮る方法まとめ

# はじめに
Ubuntuでもスクリーンショットを撮りたい！！
コマンド調べたのでまとめました。

## 環境

- Ubuntu 16.04 (LTS)
- スクリーンショット（Ubuntuのプリセットアプリケーション）


# 方法

### 全画面を撮る
- **「PrintScreen」** キーを押す。
- **端末**から下記の通り実行する。


```bash:~/
 gnome-screenshot
```

端末からも撮れるのでいろいろ使い途が広がりそうですね。


### 範囲を指定して撮る
- **「Shift」+「PrintScreen」** キーを押す。
- **端末**から下記の通り実行する。


```bash:~/
 gnome-screenshot --area
```

`--area`をつけると範囲指定できます。
どちらも実行後、マウスポインタが✚こんな感じになり、ドラッグで画面上の任意の範囲を指定できるようになります。


### ウィンドウを指定して撮る
- **「Alt」+「PrintScreen」** キーを押す
- **端末**から下記の通り実行する。


```bash:~/
 gnome-screenshot --window
```
こうすると選択しているウィンドウのスクリーンショットが撮れます。
しかし、このままだと端末からは端末しかスクリーンショット出来ません。
そんな時は…

### 時間差で撮る
- **delay**オプションをつける。


``` bash:~/
 gnome-screenshot --window --delay=5
```
こんな感じ。今回の例だと実行後5秒後に、選択されているウインドウがスクリーンショットの対象になります。


いろいろオプションがあるので

```bash:~/
 man gnome-screenshot
```
から見てみましょう。

# 参考文献

[[Ubuntu, Linux Mint] スクリーンショットを撮る](http://motw.mods.jp/Linux/screenshot.html)

[ask ubuntu From gnome-screenshot command line, how do you predefine the are?](http://askubuntu.com/questions/504733/from-gnome-screenshot-command-line-how-do-you-predefine-the-are)
ズンドコキヨシ with SQL

関連: http://qiita.com/yancya/items/1167e9764719151d0c80

PostgreSQL の[再帰 SQL](http://www.postgresql.jp/document/9.5/html/queries-with.html) を使って頑張って書いた

## SQL

```sql
WITH RECURSIVE t(w) AS (
        VALUES ('')
         UNION
        SELECT w || ('{ズン, ドコ}'::TEXT[])[TRUNC(RANDOM() * 2) + 1]
          FROM t
         WHERE NOT w ~ 'ズンズンズンズンドコ$'
               )
        SELECT w || 'キ・ヨ・シ！'
          FROM t
      ORDER BY LENGTH(w) DESC
         LIMIT 1;
```

## 解説

1. 最初、t は '' という w を持つ行のみ
2. 次のループで、t の各行の w の末尾に 'ズン' か 'ドコ' を結合した行を UNION（重複を除く） する。ただし、末尾が 'ズンズンズンズンドコ' となっている行を除く。これを繰り返していく
3. 末尾が 'ズンズンズンズンドコ' となっている行がある状態のループでは、UNION により１行も増加しないので、そこで再帰が終了して t が返る
4. t の中で w が一番長い行の末尾が 'ズンズンズンズンドコ' となっているはずなので、その行だけを対象に 'キ・ヨ・シ！' を結合して返す
【2016/03】スマートフォンのOSのシェアとバージョン毎のシェア

#日本のスマートフォンのOSシェア
※2016年01月のシェア

|OS|シェア|
|---|---|
|iOS|50.3 <font color="#888888">%</font>|
|Android|48.7 <font color="#888888">%</font>|
|Windows|0.5 <font color="#888888">%</font>|
|BlackBerry|0 <font color="#888888">%</font>|
|Other|0.5 <font color="#888888">%</font>|

<img src=https://qiita-image-store.s3.amazonaws.com/0/88925/d932538a-b423-e81d-36d9-bf8c87d9515a.png>
Source:[Kantar Worldpanel ComTech](http://www.kantarworldpanel.com/global/smartphone-os-market-share/)

#iOSのバージョン別シェア
※2016年3月7日のバージョン別シェア

|バージョン|シェア|
|---|---|
|iOS 9|79 <font color="#888888">%</font>|
|iOS 8|16 <font color="#888888">%</font>|
|それ以前|5 <font color="#888888">%</font>|


<img src=https://qiita-image-store.s3.amazonaws.com/0/88925/0a27e425-70bf-5401-86ec-491decd672fb.png>
Source:[Apple](https://developer.apple.com/support/app-store/)


#Androidのバージョン別シェア
※2016年3月7日のバージョン別シェア

|バージョン|CodeName|API|シェア|
|---|---|---|---|
|2.2|Froyo|8|0.1 <font color="#888888">%</font>|
|2.3.3 - 2.3.7|GingerBread|10|2.6 <font color="#888888">%</font>|
|4.0.3 - 4.0.4|IceCream Sandwich|15|2.3 <font color="#888888">%</font>|
|4.1.x|Jelly Bean|16|8.1 <font color="#888888">%</font>|
|4.2.x|〃|17|11.0 <font color="#888888">%</font>|
|4.3|〃|18|3.2 <font color="#888888">%</font>|
|4.4|KitKat|19|34.3 <font color="#888888">%</font>|
|5.0|Lolipop|21|16.9 <font color="#888888">%</font>|
|5.1|〃|22|19.2 <font color="#888888">%</font>|
|6.0|Marshmallow|23|2.3 <font color="#888888">%</font>|

<img src=https://qiita-image-store.s3.amazonaws.com/0/88925/3310370a-f15c-23f9-988f-6d37b0b10898.png width="600px">
Source:[Android](http://developer.android.com/intl/ja/about/dashboards/index.html)

#おまけ
日本のスマートフォンのOSシェアのSourceの [Kantar Worldpanel ComTech](http://www.kantarworldpanel.com/global/smartphone-os-market-share/) は
最新の世界のスマートフォンOSのシェアを見ることができます。
さらに過去のデータも参照できたり、比較する事もできます

<img src=https://qiita-image-store.s3.amazonaws.com/0/88925/3de5b66f-be2d-2287-43b1-b527108cb5dd.png>
2015年8月の日本のOSシェア
Androidが64.5%と多いですね。

<img src=https://qiita-image-store.s3.amazonaws.com/0/88925/f0f88a95-87e6-76cd-1e41-3c338e015a70.png>
2016年1月の日本とアメリカの比較
アメリカはAndroidの方が強い印象です。
oil create project でSSL/TLS関連のエラー

(ずっと下書きに溜めたまま忘れたたのを思い出した。いまさらニーズがあるかどうかわからないけど公開してみる)

PHPの素人がFuelPHPで新規プロジェクトを作成しようとしたら以下のエラーに遭遇しました。
赤い背景に白い文字で表示されるなんだか恐ろしそうなエラーです。

> Unable to locate a valid CA certificate file. You must set a valid 'cafile' option.
> A valid CA certificate file is required for SSL/TLS protection.
> It is recommended you upgrade to PHP 5.6+ which can detect your system CA file automatically.
> You can disable this error, at your own risk, by setting the 'disable-tls' option to true.
>                                                                                
>  [Composer\Repository\InvalidRepositoryException]
> No valid composer.json was found in any branch or tag of https://github.com/fuel/parser, could not load a package from it.

環境は以下です。
* Ubuntu 14.04.4
* PHP 5.5.9

PHP5.6以上にすれば自動的に解決するらしいですが現在の環境のままエラーを解消する方法を探したところ、
「[ComposerからLaravelを導入しようとしてOpenSSL周りのエラーで困った件](http://qiita.com/dora_kou/items/c9c2f7d8d53303ee1aab)」と同じ方法で解決できました。

OpenSSL(正確にはcurl)で使用するCAをダウンロード
> $ wget http://curl.haxx.se/ca/cacert.pem
> $ sudo mv cacert.pem /usr/local/share/ca-certificates/ca-bundle-curl.crt

/etc/php5/cli/php.ini を編集、以下を追加
> curl.cainfo=/usr/local/share/ca-certificates/ca-bundle-curl.crt
> openssl.cafile=/usr/local/share/ca-certificates/ca-bundle-curl.crt

[dora_kou](http://qiita.com/dora_kou) さん、ありがとう！
ssh越しのvimにクリップボードからペーストする方法

ssh越しのvimに対してクライアントOSのクリップボードから貼り付けしたい。
うっかり普通に貼り付けるとオートインデントが効いてしまっておかしな事になるのでなんとかしたい。

## 方法１．:set pasteする

自分が今まで行っていた方法。
`:set paste`するとオートインデントやキーマッピングが無効になり、入力したテキストがそのまま入力される。

```
nnoremap <F10> :<C-u>exe "normal" (getline(".")==""?"I":"o")<CR>i<C-o>:set paste<CR>
au InsertLeave * set nopaste
```

こんなマッピングを作り、F10でインサートモードに入ると同時に:set paste、インサートモードから抜けたときに自動的に:set nopasteするようにしていた。

## 方法２．:r!cat

```
:r!cat
<貼り付け>
<Ctrl-dでcatを終了>
```

自分の.vimrcが入っていない環境ではこれがよさそう。

## 方法３．exコマンドの:aを使う

```
:a
<貼り付け>
.<Enterで:aを終了>
```

しかしこれだとオートインデントやコマンドラインモードのmapやabbrevが効いてしまう模様。残念。
Vimに空気を読んで引用符記号を自動補完してもらう

Vimでは以下のように設定すれば対応する括弧や引用符を自動補完してくれる。

```vim
inoremap { {}<Left>
inoremap [ []<Left>
inoremap ( ()<Left>
inoremap " ""<Left>
inoremap ' ''<Left>
```

括弧に関して言えばこれで良いが、引用符（"と'）の場合は引用を閉じようとしているのに補完されてしまうケースがあり煩わしい。
そこで簡単な関数を用意して、既に対応する引用符が存在する時には補完を行わないようにした。（Vimに空気を読んでもらった）

```vim
function! QuotesCompletion(char)
    let counter = 0
    let line = getline(".")
    for i in range(strlen(line))
        if line[i] == a:char
            let counter += 1
        endif
    endfor
    if counter % 2 == 0
        return a:char.a:char."\<Left>"
    else
        return a:char
    end
endfunction

inoremap <silent> <expr> " QuotesCompletion("\"")
inoremap <silent> <expr> ' QuotesCompletion("\'")
```

現在いる行において引用符が偶数個だったら補完して、奇数個だったら既に対応する引用符があると判断して補完しない。
初心者なのでPHPで円の面積を求めてみた

> 整数で値をひとつ読み込み、それを半径とする円の面積を求めて表示するプログラムを作成しなさい。 円周率は3.14とし、計算結果は、小数第2位を四捨五入して小数第一位まで表示すること。

知恵袋方面に上記のプログラムをPHPで書きたい人がいるという噂を聞きました。世の中にはPHPの宿題が出る学校があったりするのかもしれません。PHPなら任せろー、というわけでPHPのLua拡張を利用して書いてみましょう。LuaもLua拡張も初心者ですが、がんばります！

まず手元のPHPのバージョンを確認します。今回はPHP 7.0.4を使います。

```
$ php -v
PHP 7.0.4 (cli) (built: Mar  9 2016 16:14:46) ( NTS )
Copyright (c) 1997-2016 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies
    with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2016, by Zend Technologies
    with Xdebug v2.4.0, Copyright (c) 2002-2016, by Derick Rethans
```

手元のマシンはMacなのでLuaをHomebrewでインストール。

```
$ brew install lua
```

[Lua拡張](https://pecl.php.net/package/lua)は2.0.0からPHP 7に対応しているので、これをダウンロード＆ビルドします。

```
$ wget https://pecl.php.net/get/lua-2.0.0.tgz
$ tar xvzf lua-2.0.0.tgz
$ cd lua-2.0.0
$ phpize
$ ./configure --with-lua=$(brew --prefix lua)
$ make
$ make install
```

インストールできました。

```
$ php -dextension=lua.so -i |grep -C2 -i '^lua'
libXML streams => enabled

lua

--

lua support => enabled
lua extension version => 2.0.0
lua release => Lua 5.2.4
lua copyright => Lua 5.2.4  Copyright (C) 1994-2015 Lua.org, PUC-Rio
lua authors => R. Ierusalimschy, L. H. de Figueiredo, W. Celes

mbstring
```

どうやら動きそうです。さっそく問題を解いてみましょう。

```php:lua.php
<?php
if ($_SERVER['argc'] === 1) die();
$l = new lua();
$l->assign('input', $_SERVER['argv'][1]);
$l->eval(<<<'CODE'
    function round (x)
        return x>=0 and math.floor(x+0.5) or math.ceil(x-0.5)
    end

    pi_x100=314
    area_of_circle=round(pi_x100*input*input/10)/10
    print(string.format("%.1f\n", area_of_circle))
CODE
);
```

PHP（とLua）のプロの人ならスラスラ書けるのかもしれませんが、初心者なので割と時間がかかりました。では動かしてみましょう。

```
$ php -dextension=lua.so ./lua.php 1
3.1
$ php -dextension=lua.so ./lua.php 2
12.6
$ php -dextension=lua.so ./lua.php 3
28.3
$ php -dextension=lua.so ./lua.php 4
50.2
```

やった！初心者だけど出来ちゃった！
「Postman Intercepter」Cookie利用時のREST用ツール


### はじめに
RESTの開発時にツールとして「[Postman](https://chrome.google.com/webstore/detail/postman/fhbjgbiflinjbdggehcddcbncdddomop)」が有名ですが、そのままではCookieを用いたログインをしているサイト内でリクエストを投げる事ができません。

そこで「[Postman Intercepter](https://chrome.google.com/webstore/detail/postman-interceptor/aicmkgpgakddgnaphhhpliifpcfhicfo?hl=ja)」を利用します。

### 使い方

「[Postman Intercepter](https://chrome.google.com/webstore/detail/postman-interceptor/aicmkgpgakddgnaphhhpliifpcfhicfo?hl=ja)」からChromeに追加します。

インストール後、ツールバーにアイコンが表示されるので「Request Capture」をONに設定します。
![Postman Intercepter](https://qiita-image-store.s3.amazonaws.com/0/92510/5c1b8350-0ca5-e34a-9737-657a73d4b33c.png)

Postman側でも同様に「Intercepter」をONに設定します
![20160315_155135.png](https://qiita-image-store.s3.amazonaws.com/0/92510/e89e5b29-9ff4-0791-b20c-56194647cb6a.png)

あとは対象サイトにログイン後、Postmanでリクエストを行うと、ログイン状態でリクエストを投げることができます。

※ アイコンが表示されない場合は、Chromeの再起動や「設定」＞「拡張機能」で有効となっていることを確認してください。
animateWithDuration実行時にユーザー入力を受け付けるためには

画像などの表示時にふわぁ〜っという感じで表示させることがあるかと思います。 
しかし、下記のように実装してしまうと、アニメーション実行最中は画面タップに反応しなくなってしまいます。

```objc:option未指定
imageView.alpha = 0.0;
[UIView animateWithDuration:0.8
                 animations:^{
                     imageView.alpha = 1.0;
                 }];
```

animateWithDurationにはoptionを指定できるメソッドが用意されているので、下記のようにUserInteractionを有効化してあげると、思った通りの動作をするようです。

```objc:option指定
imageView.alpha = 0.0;
[UIView animateWithDuration:0.8
                      delay:0
                    options:UIViewAnimationOptionAllowUserInteraction
                 animations:^{
                     imageView.alpha = 1.0;
                 }
                 completion:nil];
```
COLLADA

#COLLADAってなんですか？

- ３DCGツール間で受け渡しするときの共通データ・フォーマット
 - 詳細な説明はこちら https://www.khronos.org/files/collada_spec_1_5_0_jp.pdf
- xml で記述されている
 - テキストファイルである
 - ファイルサイズがでかくなる
 - ツール間で受け渡し用に設計されているのでゲーム開発で使うなら専用ファイルに変換したほうが扱いが簡単である
 - 仕様を見るにあっちこっち参照が入るためCPUからGPUに送りづらい
 - もちろんファイルをロードした時に専用形式に変換する方法もあるけどユーザーには無駄な処理だよね
 - カメラ情報とかいらないし
 - コンバータのみならずリソース管理システム作ると便利そうですね！
 - 要素内のid属性は インターネットでいうところのURIで書かれている
 - 自作ツールを作る場合は文字列のエスケープもおこなったほうがいい
 - 相対パスで書くほうがいい習慣である
 - ファイルの読み込みは ライブラリを使うと便利(https://sourceforge.net/projects/collada-dom/)
スマホで閲覧した時だけJavaScriptを一部無効化したり有効化したりする

ユーザーエージェントでスマホかPCか判別してやる方法です。
※画面サイズを取得してやる方法もあります。こちらが参考になりました。
[ウィンドウ幅をjQueryで取得して動作を制御する覚書 | 9ineBB](http://9-bb.com/%E3%82%A6%E3%82%A3%E3%83%B3%E3%83%89%E3%82%A6%E5%B9%85%E3%82%92jquery%E3%81%A7%E5%8F%96%E5%BE%97%E3%81%97%E3%81%A6%E5%8B%95%E4%BD%9C%E3%82%92%E5%88%B6%E5%BE%A1%E3%81%99%E3%82%8B%E8%A6%9A%E6%9B%B8/)

# コード
```js:無効.js
if(!navigator.userAgent.match(/(iPhone|iPad|iPod|Android)/)){
//ここに書いた処理はスマホ閲覧時は無効となる
}
```
```js:有効.js
if(navigator.userAgent.match(/(iPhone|iPad|iPod|Android)/)){
//ここに書いた処理はスマホ閲覧時のみ有効となる
}
```

# 使用例
スマホで閲覧時、jQueryのcolorboxプラグイン(モーダルウィンドウ)を無効化する

```js:JavaScript
if(!navigator.userAgent.match(/(iPhone|iPad|iPod|Android)/)){
$(document).ready(function(){
$('.colorbox').colorbox();
});
}
```

# 応用
スマホで閲覧時、colorboxプラグインを無効化し、新規ウィンドウで開くようにする

```js:JavaScript
if(!navigator.userAgent.match(/(iPhone|iPad|iPod|Android)/)){
//スマホの場合無効になる処理
$(function(){
$('.colorbox').colorbox();
});
} else {
//スマホの場合有効になる処理
$(function(){
$('.colorbox').click(function(){
  //クリックすると新規ウィンドウで開く
  window.open(this.href,'_blank');
  return false;
})
});
}
```
```html:HTML
<a href="image.jpg" class="colorbox">
<img src="image_thumb.jpg">
</a>
```


[追記] colorboxを無効にせずにこっちのほうがいい気がしてきた。
スマホで閲覧時は開く画像がどれだけ大きくても画面内に収まるように、パーセント指定をする

```js:JavaScript
if(!navigator.userAgent.match(/(iPhone|iPad|iPod|Android)/)){
$(function(){
$('.colorbox').colorbox();
});
} else {
$(function(){
$('.colorbox').colorbox({maxWidth:"100%",maxHeight:"100%"});
});
}
```
タプルをメソッドの引数とすることで引数を区分するTips


RxSwiftのサンプルコード見てたらこれは興味深いなと思ったのでメモっとく

サンプルコードはこれ
https://github.com/ReactiveX/RxSwift/blob/2.2.0/RxExample/RxExample/Examples/GitHubSignup/UsingDriver/GithubSignupViewModel2.swift#L46-L58


具体例としてinitメソッドを抜粋すると、引数にinputとdependencyという2つのタプルを渡している。

```swift
class GithubSignupViewModel1 {
	// ...中略...
	
    init(
        input: (
            username: Driver<String>,
            password: Driver<String>,
            repeatedPassword: Driver<String>,
            loginTaps: Driver<Void>
        ),
        dependency: (
            API: GitHubAPI,
            validationService: GitHubValidationService,
            wireframe: Wireframe
        )
    ) {
        let API = dependency.API
	     // ...中略...
    }
    // ...中略...    
}
```

そのinputとdependancyのタプルにそれぞれの要素を定義している。これで2種類の引数を区分していて、これのもう一つ良い所としてはタプルの要素のアクセスがめちゃくちゃ楽。dependencyタプルのAPIにアクセスするのはdependency.APIでいいという事。

呼び出す側のコードは次のような感じ

```swift
override func viewDidLoad() {
    super.viewDidLoad()

    let viewModel = GithubSignupViewModel1(
        input: (
            username: usernameOutlet.rx_text.asObservable(),
            password: passwordOutlet.rx_text.asObservable(),
            repeatedPassword: repeatedPasswordOutlet.rx_text.asObservable(),
            loginTaps: signupOutlet.rx_tap.asObservable()
        ),
        dependency: (
            API: GitHubDefaultAPI.sharedAPI,
            validationService: GitHubDefaultValidationService.sharedValidationService,
            wireframe: DefaultWireframe.sharedInstance
        )
    )
}
```

要素のみ数えると7つで、Observableとかなんだよってなると思うので少し詳しく書くと、inputにはUIControlを継承したオブジェクト達の値をバインディングすることを目的としていて、dependencyには利用したいAPIやバリデーションなどのビジネスロジックを担当する奴らを渡している。最後のwireframeっていうのはAlertを出すサンプル用のものなので気にしないで欲しい。

## 追記

そもそも論として

> 全てのSwiftの関数は、tupleを一つだけ受け取る関数なのである。

http://qiita.com/dankogai/items/46fedc447dd93d1e0fbc

なので(input:, dependency:)がそもそも名前無しタプルでそれを踏まえるとめちゃくちゃタプルが多いんで説明が紛らわしいかもねって感じ。

## まとめ

- タプルの使い勝手が良い
- 引数が多い時、引数の要素にタプルを渡すのは良いかも
- 引数が明確に役割を分担していてそれを明示する時、引数の要素にタプルを渡すのはいいかも
「文化を調和させる」をやってみる - Try “Blending Culture”


# これはなに？
- try! Swiftの１日目で行われた Daniel H Steinberg氏の発表「文化を調和させる(Blending Culture)」を自分でやってみたという内容


# Daniel H Steinberg 氏について
- https://twitter.com/dimsumthinking
- http://dimsumthinking.com/


# 実際にやってみる - Try “Blending Culture”
- 社内勉強会で発表するために、Daniel 氏のスライドを参考に捕捉説明を自分なりにつけたスライドを作成
- スライドは107枚の超大作になりました
  - https://speakerdeck.com/masashi_sutou/wen-hua-wodiao-he-saseru-woyatutemiru-try-blending-culture

# トランプアプリのデモソース
- サンプルの「トランプアプリ」をソースの変更に合わせて確認できるように４つのブランチに分けてみた
  - [first_demo](https://github.com/masashi-sutou/BlendingCulturesExample/tree/first_demo)
  - [second_demo](https://github.com/masashi-sutou/BlendingCulturesExample/tree/second_demo)
  - [third_demo](https://github.com/masashi-sutou/BlendingCulturesExample/tree/third_demo)
  - [forth_demo](https://github.com/masashi-sutou/BlendingCulturesExample/tree/forth_demo)
  - 上記を順に追えば「try! Swift」で発表された「Blending Culture」を理解しやすくなると思います
  - なお、このリポジトリは[try! Swift 1日目 "Blending Cultures"の内容をサンプルアプリに起こしてみた](http://qiita.com/su_k/items/42c29a0e136faa3f9e08)をフォークしたmasterブランチをもとに作成しています
  - できるだけ当日の発表と同じようにソースのブランチを切りましたが、もし間違いがあったら教えてくれると助かります


# スライドやデモソースの作成に使用した参考資料
- 「Blending Culture」 - try! Swift 2016.3.2 by Daniel Steinberg 
  
- [「try! Swift 文化を調和させる #tryswiftconf Day1-8」](http://niwatako.hatenablog.jp/entry/2016/03/02/160011)


- [「try! Swift 最速レポート 1日目午後 #tryswiftconf」](http://dev.classmethod.jp/smartphone/tryswift-1st-day-pm/)

- [「try! Swift 1日目 "Blending Cultures”の内容を サンプルアプリに起こしてみた」](http://qiita.com/su_k/items/42c29a0e136faa3f9e08)

- [「Swiftのクラスと構造体の使い分けについてのメモ」](http://qiita.com/mini_house/items/22b7b88794b9f8a32381)

- [「Swift 2.0 で追加された guard のいいところ」](http://qiita.com/mishimay/items/75fb0958f33079ff0e8a)

- [「Swift の Subscript について」](http://qiita.com/happy_ryo/items/72b68859ed8ace9f5fb4)

- [「Swiftのprotocol extensionでmixin的なものを 実現する」](
http://qiita.com/sagaraya/items/5e73501ff7a3f0c502c0)


# Try! “Blending Culture”をやってみた感想
- 発表時間により、やむなく省略されてしまった部分があることにやってみて気づく。
- なので、自分で実際にやってみると、とても学びが多い。
- 自分の手を動かしながら実際にやってみることをお勧めします。
- サンプルではなく、もう少し機能の多いプロジェクトに導入すると、 **どのようにソースが変化するのか**、 **まだ変化せざるを得ないのか**、次回はそこに挑戦する。
「しまった！」の時、ほしいGit対策 &通常運用_メモ

何回も発生して、やり方確認することを時間かかるから、メモしておきます！
今後も追加し続けます～

## 間違ったCommitした

commitしたくないファイルは、addしちゃったとか、コミットを取り消したい...

git resetの方法を使います。その中で、2種類があります。
　--soft → コミットだけを取り消す。ワークディレクトリの内容は変更しない。
　--hard → コミット取り消した上でワークディレクトリの内容も変更される。


1.まずcommitのログを見る
　```$ git log```


2.直前のコミットを取り消す
　```　$ git reset --soft HEAD^```
　```　$ git reset --hard HEAD^```
　commitのハッシュ値を指定することもできる。


※その他
・直前のコミット内容を修正する
　```$ git commit --amend```


##間違ったブランチで開発しちゃった

急いで修正入りたいから、Fix用のブランチを切り忘れました時...

1.現在の作業を一時的に退避する
　```$ git stash save```

　退避した作業の一覧を表示して確認する
　```$ git stash list```

　```$ git status```
　"nothing to commit (working directory clean)"　を表示すれば、退避OK。

2.正しいBranchを(新規作成)切り替える
　```$ git checkout -b ほしいブランチ```


3.退避した作業を復元する
　```$ git stash pop```
　stash@{1} のように引数を指定すれば、特定の作業を復元することができる。
　引数を指定しなければ、退避した作業の中で最新の作業を復元する。

　そして、普通のcommit、push作業をする。


※もう要らない退避した作業を削除する
　```$ git stash drop```
　stash@{1} のように引数を指定すれば、特定の作業を削除することができる。
　引数を指定しなければ、退避した作業の中で最新の作業を削除する。

・退避した作業を全て削除する
　```$ git stash clear```


##間違ったPushした
1.commitのログを見る
　```$ git log```

2.git revert で取り消したいコミット番号を指定する
　```$ git revert コミットID```

3.revertの結果をpushする
　```$ push origin ブランチ名```


pushすると、コミット内容を取り消すことは、リモートのgit上にも反映します。


##修正箇所が競合でマージできない



ブランチ間の差分をマージ(競合でマージできない場合)

1.ブランチ間のファイル差分を確認　(例：現在のブランチとdevelopブランチの差分確認）
　```$ git diff develop```

　※ブランチaaaとbbbの差分の確認
　　```$ git diff aaa bbb```


2.他のブランチで変更の内容を今のブランチに反映する場合。
　例）今いる"feature1"ブランチに、developブランチの変更を反映したい場合
　
　```$ git checkout feature1　　　//まず反映したいブランチに移動```
　```$ git merge develop　　　　　//develpの変更内容がfeauter1に反映```

参考：
[git diffでブランチ間のファイル差分を確認するあれこれ](http://easyramble.com/git-diff-between-branches.html)
[別のブランチの修正を取り込む](http://network.station.ez-net.jp/special/git/usage/merge.asp)


##ブランチの整理
・ローカルのブランチ一覧を表示
　```$ git branch```
　--remoteのオプションを追加すると、リモートのブランチを一覧表示する。

・ローカル&リモート 両方のブランチ一覧を表示
　```$ git branch --all```

・マージされた、ローカルにあるブランチを削除する
　```$ git branch -d ブランチ名```
　※マージしたかどうかを問わずに削除する -Dのオプションを利用。

・Remoteで既に削除されたブランチを、ローカルにも消します。
　```$ git fetch --prune```

・　（リモートのブランチを削除したいとき、Pushでやる）


##他の基本運用（ボケのとき参考用）

**git pull**

リモートのコピーをローカルに取ってくる
　```$ git fetch ```

リモートのコピーからマージ
　```$ git merge origin/ブランチ名```


(git pull = git fetch + git merge )
更新されたリモートのソースを、ローカルに持ってきて、マージする
　```$ git pull origin ブランチ名```

$ git pull origin ”リモートブランチ名:ローカルブランチ名”って、
　ローカルにマージするブランチを指定できます。

**git push**
ローカルブランチをリモートに反映する
　```$ git push origin ブランチ名 ```


参考情報：
[サルでもわかるGit入門](http://www.backlog.jp/git-guide/)
[git pull と git pull –rebase の違いって？　（かわいい絵が！）](http://kray.jp/blog/git-pull-rebase/)
[ionic]com.ionic.keyboardのplugin idの変更

com.ionic.keyboardのplugin idが変更されていてはまったのでメモ。
id変更前の古いアプリで`ionic state restore`をすると下記のようなエラーになります。

```console
HogeBook:AppSample hage$ ionic state restore
Attempting to restore your Ionic application from package.json

Restoring Platforms

cordova platform add ios
cordova platform add android

Restore platforms is complete

Restoring Plugins

cordova plugin add com.ionic.keyboard
 ✗ Caught exception:
 undefined 

Mind letting us know? https://github.com/driftyco/ionic-cli/issues
```

# plugin idの名称を修正する
以下のようにidを修正して、`ionic state restore`を再度実行すればOKです。

```package.json
{
  "cordovaPlugins": [
    "ionic-plugin-keyboard"
  ]
}
```

参考
https://github.com/driftyco/ionic-plugin-keyboard/issues/83