OmniAICreator/Qiita-1.07M huggingface dataset:
勉強会用：Jenkinsユーザ・カンファレンス2015 の見どころまとめ

[以前書いた記事](http://qiita.com/kmats@github/items/cf221b6995b6e6b0d256)を勉強会用に再編してみまっす

---

### 基調講演 Jenkinsプロジェクトの現状とワークフロー
* 見どころはずばり[Workflow plugin](https://github.com/jenkinsci/workflow-plugin)
    * 特徴
        * 複雑な活動を簡潔に指揮・記述
            * それなりの学習コストが必要そう
            * 複雑なことを完結に書くためにはそれなりのノウハウとかいるよね
        * 一つのジョブで必要な全てを記述
            * これまでpipelineとかbuild-flowとかで管理していたものが置き換えられそう
        * GroovyによるDSL
            * Snippet Generatorがある
            * でも(まだ)細かいところはgenerateしてくれないしバグも沢山あるっぽい
        * JVMのロスや再起動に耐えるデザイン
            * ジョブ実行中にJenkins再起動などがあっても途中から再開できる
            * JenkinsEnterpriseだとチェックポイント作れるらしい
        * 拡張性
            * 他のプラグインと連携できるってことだと思う、けど正直良く分かってない
    * サンプル
        * https://github.com/jenkinsci/workflow-plugin-pipeline-demo/blob/master/flow.groovy
        * 勉強会ではコードリーディングしてみましょう
            * 参考 http://qiita.com/yasuhiroki/items/6be3da7a89b1ac0dfc1d

### はてなにおける継続的デプロイメントの現状とDockerの導入
* 見どころはDocker+Jenkinsでの開発中の確認環境構築
* 従来
    * ![従来](http://image.slidesharecdn.com/20150111jenkinsweb-150113212719-conversion-gate02/95/docker-64-1024.jpg?cb=1421206538)
* Docker利用
    * ![Docker利用](http://image.slidesharecdn.com/20150111jenkinsweb-150113212719-conversion-gate02/95/docker-70-1024.jpg?cb=1421206538)
    * Plack?
> PSGI（Perl Web Server Gateway Interface）は、プログラミング言語Perlで使われる、WebアプリケーションとWebサーバを接続するインタフェースの1つであり、PerlにおけるWebアプリケーション用標準インタフェースとして使われることが意図されている。

        * http://ja.wikipedia.org/wiki/PSGI
        * Perlに思い入れがなければ他のものが良さそう
    * DockerAPI
        * たぶんこんなの https://docs.docker.com/reference/api/docker_remote_api_v1.13/
    * DockerAPIを使ったポート番号解決
        1. DockerAPI(json)から、Image="hogehoge:latest"なエントリを見つける
        1. Portsからホスト側のポートを取得
            * Docker使うと簡単にホスト-コンテナでポートフォワード可能
            * http://deeeet.com/writing/2014/05/11/docker-network/
                * *ホスト側のIPの指定を省略することもできる．この場合，自動でポートが選ばれる．* らしいのでポートが被るとか心配しなくてよさそう
        1. ポート番号解決用のアプリで処理できるようにごにょごにょする
    * イメージビルドにはキャッシュを上手く使う(使えるようにする)と時間が短くできるので是非
    * 課題
        * コンテナの破棄がめんどうらしい
            * 例えば毎日0時にリセットする、などすれば解決できる？
            * 確認環境だと割り切れば翌日には使えなくなっても許容されるのではないか


### JenkinsとPuppet+ServerspecでインフラCI
* 割とエモい話
* ![jenkins+puppet+serverspec.png](https://qiita-image-store.s3.amazonaws.com/0/22341/7e4690df-bc26-bcef-4b22-86d684a86150.png)
    * つまりはこういうことだと思う
        1. infrastructure as code(Puppet/Chef)
        2. コードにはテストを用意しよう(Serverspec)
        3. コード変更したらテストをCIで回そう(Jenkins)
            * コードの適用先が必要になるので、そこは何とかする必要がある
            * Dockerとか使えれば難しくはないはず
        4. 以上！

### おまけ
* [「Infrastructure as a CodeにおけるJenkinsの役割」 〜環境構築も継続的インテグレーションを行う時代です〜](https://docs.google.com/presentation/d/1odaKAEXJAY_DIfgYkPJFFQLSy54hU2COy3Hp5xjr9P0/pub?start=true&loop=true&delayms=3000&slide=id.g60646d830_0147) は聴講はしてないけどインフラ系の人は読むと良いと思いました、特にAWSとか使ってる人
    * (今回の勉強会では扱わない予定だけど
nmcliでwifi設定

Raspberry Pi 買ってwifiセットアップしたのでメモ。
一緒に購入したのはこちら。
[BUFFALO 無線LAN子機 コンパクトモデル 11n技術・11g/b対応 WLI-UC-GNM](http://www.amazon.co.jp/BUFFALO-%E7%84%A1%E7%B7%9ALAN%E5%AD%90%E6%A9%9F-%E3%82%B3%E3%83%B3%E3%83%91%E3%82%AF%E3%83%88%E3%83%A2%E3%83%87%E3%83%AB-11n%E6%8A%80%E8%A1%93%E3%83%BB11g-WLI-UC-GNM/dp/B003NSAMW2/ref=pd_cp_computers_2)

OSはpidoraを入れて、nmcliで設定。コマンド一つでいけた！
これでDHCPでIPふられる。

```
nmcli device wifi connect [SSID] password [PASSWORD]
```

#### 参考
- http://fedoraproject.org/wiki/Networking/CLI
仕事中や通勤中に聴くテック系podcastメモ


すぐ忘れるのでメモしておく

rebuild.fm 宮川さん
http://rebuild.fm

dorikin ガジェット
http://backspace.fm/

技術系 @Jxck_
http://mozaic.fm/

モダシンさん ガジェットとか
http://www.aivy.co.jp/BLOG_TEST/nagasawa/c/podcast/

devops系
http://admins.bar/

技術系・日常系
http://wada.fm/

技術系・日常系
http://dandy.fm/

技術系
http://codelunch.fm/

セキュリティ
http://www.tsujileaks.com/

データサイエンス
https://rubyist.club/

その他
http://engineer-meeting.tumblr.com/
http://www.agileradio.info/

英語
最近だとio.jsの話題とか
http://thechangelog.com/
SCPクライアント不要なTeraTermのSCP機能

# はじめに
通常SCPクライアント(WinSCP等)を使用するファイルのアップロード/ダウンロード。
TeraTermのみで、ファイルのアップロード/ダウンロードを簡易に実施する方法。

# ダウンロード編
## 手順
1. TeraTermで作業している状態で、[ファイル]》[SSH SCP]を選択する。
2. [Receive]のボタンがある方の[From]へ取得したいファイルのフルパスを記載する。
3. [To]の隣の[...]ボタンを押下して、ダウンロード先を指定する。
4. [Receive]のボタンを押下する。

## 説明
最初にログインしたユーザのread権限があるファイルのみ受信可能なようです。

# アップロード編
## 手順
1. TeraTermで作業している状態で、[ファイル]》[SSH SCP]を選択する。
2. [Send]のボタンがある方の[From]の隣の[...]ボタンを押下して、対象ファイル指定する。
3. [To]へファイルのアップロード先ディレクトリを入力する。
4. [Send]のボタンを押下する。

# その他
## さらに簡易にアップロードする方法
最初にログインしたユーザのホームディレクトリへファイルをアップロードしたい場合は、そのファイルをTeraTermへドラッグ＆ドロップして、表示された[SCP]ボタンを押下するとより簡単にファイルをアップロード可能です。
## 説明
[SCP]のボタンの他に、[Send File]と[Cancel]があるが[Send File]ボタンは押してはNGです。
[Send File]ボタンを押すとファイルの内容がターミナルに送信され、大事故になります。
ホームディレクトリにワケの分からないファイルが作成されたり、シェル内のコマンドが流れたりします。
Fakerを使用して日本語を含んだCSVダミーファイルを作成する方法


CSVのダミーデータを作る場合、巷にダミー作成サイトは沢山ありますが
大概の場合は日本語に対応されていません。

そこでPythonの [Faker](https://github.com/joke2k/faker) を使用してCSVダミーデータを日本語で作成した時のメモ



## 環境

* OSX 10.9.5

## 参考にしたサイト

* [fake-factoryでダミーデータ生成
](http://open-groove.net/python/dummy-data-by-fake-factory/)
* [joke2k/faker](https://github.com/joke2k/faker)

## 事前準備に必要なもの

* python 2.6.9 (で試しました。他はわかりません・・・)
* pip

## Fakerのインストール

```bash:/path/to/hoge
pip install fake-factory
```

## Fakerは日本語対応していません

[joke2k/faker](https://github.com/joke2k/faker)より引用

> You can check available Faker locales in the source code, under the providers package. The localization of Faker is an ongoing process, for which we need your help. Please don't hesitate to create a localized provider for your own locale and submit a Pull Request (PR).

> Included localized providers:

> bg_BG
cs_CZ
de_DE
dk_DK
.
.

ja_JPは現在ないです。
なので独自のproviderを作成して日本語を含んだダミーデータを作成します。



## 日本語を含んだCSVダミーデータを作るサンプルプログラム

``` fake.add_provider() ``` を使用して独自プロバイダを作成します。


```python:ja_dummy.py
#! /usr/bin/env python
# -*- coding: utf-8 -*-

from faker import Factory
from faker.providers import BaseProvider
import csv
import random

class MyStatusProvider(BaseProvider):
    def state(self):
        return random.choice(['状態1', '状態2', '状態3'])
    def name(self):
        return random.choice(['田中', '鈴木', '山崎'])
    def phone_number(self):
        return random.choice(['080-1111-2222', '090-1234-5678', '070-1234-5678'])


fake = Factory.create()
fake.add_provider(MyStatusProvider)

with open("dummy_data.csv", "w+") as f:

    csv_writer = csv.writer(f)

    for i in range(5):
        l = [fake.md5(), fake.random_number(1), fake.date(pattern="%Y-%m-%d %H:%M:%S"), fake.random_int(min=0, max=1), fake.boolean(), fake.state(), fake.name(), fake.phone_number() ]
        csv_writer.writerow(l)
```

* ``` for i in range({数字}) ``` の部分がCSVの作成行数を指定しています
* l = [fake.md5(), ...., .....]の部分に作成したい部分のデータを指定してください。[Faker](https://github.com/joke2k/faker) が元々持っているダミーデータ作成メソッド(provider)は [Faker](http://www.joke2k.net/faker/) のFormattersの部分を読むと大体わかります。

## よく使いそうなダミーデータの作成方法

ちょこっとしか触っていないのでなんともいえませんが・・・

### 日付

patternの部分を変更すれば任意の日付型にできます

```pyhton
fake.date(pattern="%Y-%m-%d %H:%M:%S")
fake.date(pattern="%Y年%m月%d日 %H時%M分%S秒")
```

### 数字range

0-9まで数字でランダムにデータを作成したい場合

```python
fake.random_int(min=0, max=9)
```

### md5

```python
fake.md5()
# 292bfff99620e2ae2f3b2f5b9fab4232
# 739169affdb932770deed3ff5f29f7b9
```

### True or False

```python
fake.boolean()
# False
# True
```

### email

```pyhton
fake.email()
# wood.dubuque@strosin-ratke.com
```

詳しくは[Faker](http://www.joke2k.net/faker/) 参照してください。
DBのサンプルデータやファイルIOのテスト用にどうぞ
なぜ960pxがグリッドにするときに良いのか計算してみた


三周か四周遅れな話でレスポンシブだどうのこうの考える時代になんでこんなことをやっているんだと思いつつ実際深く考えたことなかったのでちゃんと調べた。

結論としてはsusyでも960px(or 940px)のグリッドは妥当になりうるかなというところ。

### 前提
そもそもこの前提を成り立たせるには条件があると思う。

- 現状横幅としては1200がmaxだろう
- 広告などでサイドバーを300pxにする制約がかかりやすい
- レイアウトはsusyのようなgrid systemで計算する
    - 「960であれば割りやすい」というのはあるのだけど機械的に行うので、この理由を一旦除外する。

横幅を広げるほどファーストビューの情報量も増えるだろうし、特に広告などの制約が無いならサイトのユーザーに合わせて1024ぐらいでやっちゃっていいんじゃないかと思う。

### 計算
上記前提で、サイドバーが300pxにならないといけないとすると`span(x)`で300pxが算出されるgutterとcolumnの組み合わせでないといけない。

そういう組み合わせがどの程度存在するのかを知りたいのでテキトースクリプトでざざっと計算する

```calc.js
var span = function(x, gutter, column){
  return column * x + gutter * (x - 1)
}
var grid = function(g, gutter, column){
  var arr = []
  for(var i=1; i <= g; i++){
    arr.push(span(i, gutter, column))
  }
  return arr
}

var num = 1 // 説明陽の通し番号
var gridNum = 12
var target = 300
for(var g = 10; g < 30; g++){
  for(var c = 50 ; c < 90; c++){
    var result = grid(gridNum, g, c)
    result.forEach(function(r){
      if(r == (target)){
        console.log("Hit number: "+ num)
        console.log(c, g, (result[11]+g)+" grid")
        console.log(result)
        console.log("")
        num++;
      }
    })
  }
}

```

この結果がこちら

```result
Hit number: 1
52 10 '744 grid'
[ 52, 114, 176, 238, 300, 362, 424, 486, 548, 610, 672, 734 ]

Hit number: 2
66 12 '936 grid'
[ 66, 144, 222, 300, 378, 456, 534, 612, 690, 768, 846, 924 ]

Hit number: 3
63 16 '948 grid'
[ 63, 142, 221, 300, 379, 458, 537, 616, 695, 774, 853, 932 ]

Hit number: 4
88 18 '1272 grid'
[ 88, 194, 300, 406, 512, 618, 724, 830, 936, 1042, 1148, 1254 ]

Hit number: 5
60 20 '960 grid'
[ 60, 140, 220, 300, 380, 460, 540, 620, 700, 780, 860, 940 ]

Hit number: 6
86 21 '1284 grid'
[ 86, 193, 300, 407, 514, 621, 728, 835, 942, 1049, 1156, 1263 ]

Hit number: 7
57 24 '972 grid'
[ 57, 138, 219, 300, 381, 462, 543, 624, 705, 786, 867, 948 ]

Hit number: 8
84 24 '1296 grid'
[ 84, 192, 300, 408, 516, 624, 732, 840, 948, 1056, 1164, 1272 ]

Hit number: 9
82 27 '1308 grid'
[ 82, 191, 300, 409, 518, 627, 736, 845, 954, 1063, 1172, 1281 ]

Hit number: 10
54 28 '984 grid'
[ 54, 136, 218, 300, 382, 464, 546, 628, 710, 792, 874, 956 ]
```

ふむ。組み合わせは色々あるようだ。
細かく見てみると
1番はまず小さすぎて論外だろう。
2,3も960よりは小さい。
3,6,7,9は奇数が含まれるしあえて好んで使う理由もないだろう
4,6,8,9は1200オーバーになってカバーできるユーザーが少なそう

となると残るは10の984gridか5番の960gridということになる。

あとは好き好みな感じだが14px広がる程度だとだいたい1行あたり1文字文ファーストビューが上がりやすくなるとは言える。
が、300以外の数値の数値の綺麗さで言っても960が選ばれるだろう。

ということで960pxのグリッドはやっぱ無難なんですね。という結論に至った。
1000〜1100px台でよさそうな組み合わせが出てくれればと思ったけどそういう感じにもならなかった。


### Susyでの指定

ちなみにsusyのドキュメントの960gridのショートハンドが間違っていたので注意([pullreq済み](https://github.com/ericam/susy/pull/432)）

```
@include layout(12 (60px 20px) split static);
```

もし10番の 984 gridを使いたければ

```
@include layout(12 (54px 28px) split static);
```
となるだろう。
gitignoreファイルを無視させる


## 課題
`.gitignore`ファイルに追記したいが、その追記を無視させたい時がある。
オリジナルの`.gitignore`ファイルを作成したい時の対処法が[Github Help](https://help.github.com/articles/ignoring-files/)に書いてあったのでご紹介。

## 解決方法
`.git/info/exclude`に無視したいファイルを追記すればOK。
ここに追記したファイルは無視される一方、`.git/info/exclude`への追記も無視される。
chkconfig ランレベルについて

**ランレベルについて**

サーバを再起動したらログがダウンロードできない。。。 
FTPサーバに自動起動を設定していなかったのが原因。 
サーバ起動時に自動で立ち上げるにはchkconfigでランレベルの設定が必要ですと。 


自動起動設定するのにchkconfigでランレベルの設定は何回かやってるが、 
いったいランレベルがどういうものなのか理解していないので調べた。



**現在のランレベルの調べ方**  
runlevelコマンドで現在のランレベルを表示する

```bash
$ runlevel
$ N3
```

現在のランレベルは３でデフォルトの状態。 
ランレベルは以下７つあるらしい  

**ランレベルの種類** 
 
* ランレベル 0 : システムの停止  
* ランレベル 1 : シングルユーザモード  
* ランレベル 2 : マルチユーザモード (NFSマウントなし)  
* ランレベル 3 : マルチユーザモード (通常 : コンソールログイン)  
* ランレベル 4 : 未使用  
* ランレベル 5 : マルチユーザモード (通常 : ディスプレイマネージャ使用)  
* ランレベル 6 : システムの再起動  


３が通常状態なのはわかったけど、他がどういう状態なのかわからない


telinitコマンドでランレベルを変更できるらしい
例えばtelinit 3でシステム停止、telinit 6で再起動ができるらしい
ということは、0と6は文字通り停止、再起動時の状態を示しているのか

あとの1～5の違いがいまいちわからない

**ランレベル1 シングルユーザモード** 
Windowsのセーフモード的なもので、文字通り1人(root)しかログインできない。 
メンテナンスなどをする際に使う。

**ランレベル2** 
ランレベル３とほぼ同じ。NFSのサービスが起動してないらしい。 
何か有るのかな？使いどころがわからない。  

**ランレベル3** 
デフォルトのモード。通常はこのモード。  


**ランレベル5 グラフィカルログイン** 
GUIで起動するモードらしい。
業務で使うことあるのかな？多分使わないと思う。 
個人でなら使うことあるかもしれないけど。


デフォルトのランレベルの設定は、/etc/inittabに記述されている

```
# Default runlevel. The runlevels used are:
#   0 - halt (Do NOT set initdefault to this)
#   1 - Single user mode
#   2 - Multiuser, without NFS (The same as 3, if you do not have networking)
#   3 - Full multiuser mode
#   4 - unused
#   5 - X11
#   6 - reboot (Do NOT set initdefault to this)
#
id:3:initdefault:

```
0と6は(Do NOT set initdefault to this)と書いてあり、 
ランレベル0と6はデフォルトにはしてはいけない。 
多分停止と再起動の状態だからですね。 


ということで0と6は使わない、1はメンテナンス用 
なので、通常時は2～5の状態のいずれかだと言えるのか  


なるほど、ランレベルとは現在のサーバの状態だとわかった。  
しかし、FPTやapacheとかの各種サービスの自動起動するためにランレベルの設定？ってのがよくわからない。  


どうやらlinuxではランレベルによって起動するサービスが決まっている。  
``/etc/init.d/``  
配下にrc0.d～rc6.dとランレベル毎のディレクトリがある 
 
```bash
$ ls /etc/rc.d
init.d  rc  rc.local  rc.sysinit  rc0.d  rc1.d  rc2.d  rc3.d  rc4.d  rc5.d  rc6.d
```

各ランレベルのディレクトリ配下にそのランレベル用の起動用シェルがある。  


``chkconfig postfix on``  
を実行すると、httpdの2,3,4,5がonになる 
つまり、/etc/init.d/rc2.d～rc5.dに起動用シェルが作られる。 
0、6は停止と再起動、1はメンテナンス用だから、すべての状態で起動と同義なわけですね。  

```bash
chkconfig --list postfix
postfix         0:off   1:off   2:on    3:on    4:on    5:on    6:off

find /etc/rc.d/rc*.d | grep postfix
/etc/rc.d/rc0.d/K30postfix
/etc/rc.d/rc1.d/K30postfix
/etc/rc.d/rc2.d/S80postfix
/etc/rc.d/rc3.d/S80postfix
/etc/rc.d/rc4.d/S80postfix
/etc/rc.d/rc5.d/S80postfix
/etc/rc.d/rc6.d/K30postfix
```

あれ、rc0.d～rc6.d全部のディレクトリにシェルが入ってる？ 
2,3,4,5だけにしか入っていないと思ったのに 
調べると、頭文字Sで始まるものはStartする起動用、Kで始まるのはkillするスクリプト

ところで停止時や再起動時にonになるサービスってそもそもあるのだろうか? 
chkconfig --listで確認したかぎりでは0と6はすべてoffだった。  
/etc/rc.d/rc0.dを見てみると
  
```bash
$ ls /etc/rc.d/rc0.d/S*
/etc/rc.d/rc0.d/S00killall  /etc/rc.d/rc0.d/S01halt
```
haltとkillallを実行する様子
sort + ブロックではなくsort_by + ブロックを使おう

[Ruby 2.1.0リファレンスマニュアル Enumerable#sort_by](http://docs.ruby-lang.org/ja/2.1.0/method/Enumerable/i/sort_by.html)に

>Enumerable#sort と比較して sort_by が優れている点として、 比較条件が複雑な場合の速度が挙げられます。 sort_by を使わない以下の例では比較を行う度に downcase が実行されます。 従って downcase の実行速度が遅ければ sort の速度が致命的に低下します。

>```ruby
>p ["BAR", "FOO", "bar", "foo"].sort {|a, b| a.downcase <=> b.downcase }
>```

>一方、次のように sort_by を使うと downcase の実行回数は要素数と同じです。 つまり、その部分の実行時間は O(n) のオーダーです。

>```ruby
>p ["BAR", "FOO", "bar", "foo"].sort_by {|v| v.downcase }

と書いてありました。

要するにsortのブロック内では比較対象を作るための処理を何度も呼ぶ必要があり、それが速度低下を引き起こすらしいです。

検証してみました。

```bench.rb
require "benchmark"

class Integer
  def piyo
    $n += 1
    self
  end
end

def bench ary
  puts "------------"
  puts "length:#{ary.length}"

  $n = 0
  puts "sort"
  puts Benchmark.realtime { ary.sort {|a, b| a.piyo <=> b.piyo } }
  puts $n

  $n = 0
  puts "sort_by"
  puts Benchmark.realtime { ary.sort_by {|i| i.piyo } }
  puts $n
end

bench(10_000.times.map {|_| rand(100000) })
bench(100_000.times.map {|_| rand(100000) })
bench(1_000_000.times.map {|_| rand(100000) })
bench(10_000_000.times.map {|_| rand(100000) })
```

```
$ ruby bench.rb
------------
length:10000
sort
0.028192596999815578
240766
sort_by
0.007100288999936311
10000
------------
length:100000
sort
0.3362468350001109
3072618
sort_by
0.09367915700022422
100000
------------
length:1000000
sort
4.030596262000017
37349434
sort_by
1.0217048670001532
1000000
------------
length:10000000
sort
46.01518444800013
440193772
sort_by
12.482706402000076
10000000
```

環境は
Core i5 3210M
メモリ4GB
windows8.1上のVirtualboxで動かしているUbuntu14.04
ruby 2.2.0p0
です。

piyoは軽い処理にも関わらず実行時間はsortに比べてsort_byが1/4ほどになっています。

例えばpiyoが10msかかる処理だと、要素数が100でもsort_byの方が10倍程度の速かったです。

**結論**
sort + ブロックをせずにsort_by + ブロックを使おう。
Webview内でtel: mailto: リンクに遷移する時の対応

### Webview内でtel:とmailto:リンクに飛ぼうとするとエラーになる。。。

http://www.tagindex.com/html5/text/a_tel.html
http://www.tagindex.com/html_tag/link/a_mailto_sub.html
本来このリンクは、電話をかけるたりメールを出したりするリンクである。

しかしAndroid Webview内でリンクを踏むとエラー画面に・・・
そこで tel: と mailto: リンクを踏んだ際は、WebViewClientのshouldOverrideUrlLoadingで検知してIntentに変換してみる。

### tel:の時は発信しますか？のダイアログを付けてみた版
```java
public class MainActivity extends FragmentActivity {	
	private WebView mWebView;
 
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.activity_main);
 
		mWebView = (WebView) findViewById(R.id.webview);
		mWebView.setWebViewClient(new WebViewClient(){
			@Override
			public boolean shouldOverrideUrlLoading(WebView view, String url) {
				if (url.startsWith("tel:")) {
					// 電話発信ダイアログ
					TelDialogFragment dialogFragment = TelDialogFragment.newInstance(url);
					dialogFragment.show(MainActivity.this.getSupportFragmentManager(), "tel_dialog");
					return true;
				}else if(url.startsWith("mailto:")){
					Intent intent = new Intent(Intent.ACTION_SENDTO,Uri.parse(url));
					startActivity(intent);
					return true;
				}
				return true;
			}
		});
		mWebView.loadUrl("http://");;
	}
 
	// 電話確認ダイアログ
	public static class TelDialogFragment extends DialogFragment {
		public static TelDialogFragment newInstance(String telNumber){
			TelDialogFragment frag = new TelDialogFragment();
			Bundle args = new Bundle();
			args.putString("tel_number", telNumber);
			frag.setArguments(args);
			return frag;
		}
		@Override
		public Dialog onCreateDialog(Bundle savedInstanceState) {
			AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
			builder.setTitle("確認");
			builder.setMessage("発信しますか?");
			builder.setPositiveButton("はい",new DialogInterface.OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {
					String telNumber = (String) getArguments().get("tel_number");
					Intent intent = new Intent();
					intent.setAction(Intent.ACTION_VIEW);
					intent.setData(Uri.parse(telNumber));
					startActivity(intent);
				}
			});
			builder.setNegativeButton("いいえ",new DialogInterface.OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {}
			});
			return builder.create();
		}
	}
}
```
Mac; OS X Mavericsにgccを使ってOpenJTalkを導入する

ほとんど以下のサイトの焼き直しです。感謝！

[Mac OS X Lion で OpenJTalk-1.05 を動かす](http://naoh-dev.blogspot.jp/2012/01/mac-os-x-lion-openjtalk-105.html)

これはclangでOpenJTalkのビルドにつまずいた人向けの文書です。
clangでやりたい人は以下参照
http://qiita.com/yawara/items/2cb20f7bbb07615229ec

## 準備
/usr/local以下にOpenJTalkディレクトリを用意する。
その下にvoiceディレクトリをそれぞれ用意する。

```
mkdir -p /usr/local/OpenJTalk/voice
```

ストレートにclangでビルドしようとすると、[unknown arguments](https://kaspermunck.github.io/2014/03/fixing-clang-error/)のエラーに出会うのでgccを用意する。
以下では[Homebrew](http://brew.sh/)経由でgccをインストールしたものとする。

```
brew install gcc
```

## hts_engine APIのインストール
[本家サイト hts_engine API](http://hts-engine.sourceforge.net/)

ターボールは以下のリンクから。
http://sourceforge.net/projects/hts-engine/files/hts_engine%20API/hts_engine_API-1.09/hts_engine_API-1.09.tar.gz/download?use_mirror=jaist

例によって

```
tar xzvf hts_engine_API-1.09.tar.gz
cd hts_engine_API-1.09
CC=/usr/local/bin/gcc-4.9 CXX=/usr/local/bin/g++-4.9 ./configure --prefix=/usr/local/OpenJTalk
make && make install
```

おそらくhts_engineのビルドにはgccは必要ない。ただ使っても問題ない。

## OpenJTalkのインストール
[本家サイト OpenJTalk](http://open-jtalk.sourceforge.net/)

ターボールは以下のリンクから。
http://downloads.sourceforge.net/open-jtalk/open_jtalk-1.08.tar.gz

例によって

```
tar xzvf open_jtalk-1.08.tar.gz
cd open_jtalk-1.08
```

ここで内容によって読み上げの間延びをしてしまうのをふせぐために以下のパッチを用意する。
詳しくは『[OpenJTalkの導入](http://oohito.com/nqthm/archives/2034)』を参照のこと。
パッチのコードは上記サイトからコピペしてきた。

```
cat<<EOF>manobi.patch
*** jpcommon/jpcommon_label.c.orig      2012-12-24 17:18:53.000000000 +0900
--- jpcommon/jpcommon_label.c   2013-05-27 16:35:45.195252424 +0900
***************
*** 284,289 ****
--- 284,290 ----
        if (index == a)
           break;
     }
+    if (i > 3) i = 3;
     return i;
  }

***************
*** 383,388 ****
--- 384,390 ----

     for (i = 0, index = m->next; index != NULL; index = index->next)
        i++;
+    if (i > 10) i = 10;
     return index_mora_in_utterance(m) + i;
  }
EOF
```

パッチを適用する。

```
patch -p0 < manobi.patch
```

環境変数CC、CXXでそれぞれC、C++のコンパイラにGCCを指定してビルドする。

```
CC=/usr/local/bin/gcc-4.9 CXX=/usr/local/bin/g++-4.9 ./configure --prefix=/usr/local/OpenJTalk --with-hts-engine-header-path=/usr/local/OpenJTalk/include --with-hts-engine-library-path=/usr/local/OpenJTalk/lib --with-charset=UTF-8
make && make install
```

ここで、-with-hts-engine-header-pathと--with-hts-engine-library-pathとが先ほどインストールしたhts_engine APIのヘッダーとライブラリを参照している。

### HTS Voiceのインストール
ダウンロードは以下のリンクから。
http://sourceforge.net/projects/open-jtalk/files/HTS%20voice/hts_voice_nitech_jp_atr503_m001-1.05/hts_voice_nitech_jp_atr503_m001-1.05.tar.gz/download?use_mirror=jaist

バイナリなので解凍してvoice以下に設置する。
利便性のために適当なシンボリックリンクを貼る。

```
tar xzvf hts_voice_nitech_jp_atr503_m001-1.05.tar.gz
mv hts_voice_nitech_jp_atr503_m001-1.05 /usr/local/OpenJTalk/voice
cd /usr/local/OpenJTalk/voice
ln -s hts_voice_nitech_jp_atr503_m001-1.05 m001
```

インストール完了！

## OpenJTalkを使ってみる。
sample.txt中のテキストを読み上げてout.wavとして出力。

```
open_jtalk -x /usr/local/OpenJTalk/dic -m /usr/local/OpenJTalk/voice/m001/nitech_jp_atr503_m001.htsvoice -ow out.wav sample.txt
```

* -xで辞書ディレクトリを指定。
* -mでHTS Voiceファイルを指定。
* -owでアウトプットのファイル名指定。
OS X + Android SDK Managerの設定で2回も苦労した


ので同じ轍は踏みたくないからメモ

## ざっくり言うと

- OS XでAndroid SDK Managerを使いたい

- Proxy設定したいのにメニューにPreferencesがない

- Command+TabしたらPreferences出てきた

- [大変参考になりましたありがとうございます](http://yuzu441.hateblo.jp/entry/2014/02/10/120253)

## 細かく言うと

### 前提条件

- OS X (Yosemite)

- [Android SDK Tools](http://developer.android.com/sdk/index.html)のzipを入手

- Proxy設定しないと外部NWにつなげられない

- ビルドに使うだけなので、余計なもの(IDEとか)は入れたくない


### 轍を踏むまで

SDK Toolsのzipを解凍して``android-sdk-macosx/tools/android``を実行。
セキュリティ云々言われるのでそのあたりを設定。
改めて``android-sdk-macosx/tools/android``を実行。
Preferenceは上のメニューに……
![](http://p.twpl.jp/show/orig/yuhuA)
……ターミナルて。
……これ前もひっかかったんだよ。どうしたんだったか自分。

### 轍を抜けるまで

10分くらいかかった。
**結論としては、ウィンドウを切り替えれば表示される**。
Command+Tab, 別のウィンドウをクリックしたあとSDK Managerのウィンドウをクリック, デスクトップ切り替えて戻す, 等 

### 轍を抜けた後

これでProxyも設定できるよ! やったね!
![](http://p.twpl.jp/show/orig/HjEMa)

前はどうやって解決したんだったかは謎のままだ。

## 何がしたいかと言うと

Markdownの練習
「objectに拡張メソッド定義すると・・・」を使えるようになるまで

Temarin_PITAさんの[objectに拡張メソッド定義すると大変なことになるので…](http://qiita.com/Temarin_PITA/items/2ce7e1a710048530a87c)の記事を見て使えるようになりたいと調べてみた。
しかし、imlicit、ラムダ式初心者の私にとってハードルが高く、いろいろ調べ自分の環境で動かせるサンプルを書いてみた。

```csharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SampleExtension
{
    public struct Extension<T>
    {
        public Extension(T value)
        {
            _value = value;
        }
        public T _value;
        public T Value { get { return _value;}}

        public static implicit operator Extension<T>(T o)
        {
            return new Extension<T>(o);
        }

        public static implicit operator T(Extension<T> o)
        {
            return o.Value;
        }
    }

    public static class ExtensionExt
    {
        public static Extension<T> ToExtension<T>(this T source)
        {
            return new Extension<T>(source);
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            object src = "abc";
            Console.WriteLine(src.ToExtension().Value);
            Console.WriteLine("123".ToExtension().Value);

        }
    }
}

```

Temarin_PITAさんの提示されたコードから比較すると良くないが実務で役に立つコードがかけそうだ。
ラムダ式・・・ まだまだ理解できていない。
Temarin_PITAさんに感謝！！
Toolbar を使ってちょっとおしゃれなダイアログを作る


# イメージ

Toolbar なので、左上と右上2つのアイコンにはイベント処理を入れられます。画像のように、ポジティブ／ネガティブボタン的なものを用意すればアラートダイアログのように使えるでしょうか。

今回の実装のように、アラートダイアログの View の部分のみをセットする方法であれば、4系と5系で同じデザインにできます。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/39324/67c58ad8-2bdb-5b35-dbaf-385a8129e620.png "qiita.png")



# コード

Activity は ActionBarActivity を継承してください

```java:SampleFragment.java
LayoutInflater inflater = getActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.dialog_sample, null);

Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // ナビゲーションアイコンクリック時の処理
    }
});
toolbar.inflateMenu(R.menu.menu_sample);
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
    @Override
    public boolean onMenuItemClick(MenuItem menuItem) {
        // メニュークリック時の処理
        return false;
    }
});

new AlertDialog.Builder(getActivity())
        .setView(view)
        .show();
```

### レイアウト
```xml:dialog_sample.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:navigationIcon="@drawable/ic_navigation_alert"
        app:subtitle="Subtitle"
        app:title="Title" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="16dp">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="EditText" />

        <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="8dp" />

        <CheckBox
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="CheckBox" />
    </LinearLayout>

</LinearLayout>
```

### メニュー
```xml:menu_sample.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/action_cancel"
        android:icon="@drawable/ic_action_cancel"
        android:orderInCategory="100"
        android:title="@string/action_cancel"
        app:showAsAction="always" />

    <item
        android:id="@+id/action_done"
        android:icon="@drawable/ic_action_done"
        android:orderInCategory="110"
        android:title="@string/action_done"
        app:showAsAction="always" />
</menu>
```
intel edison用にWindowsでクロスコンパイル

今更感がありますが、**intel edison**を手に入れました。
Windowsでedison用のバイナリをビルドしようと思ったのですが、
クロスコンパイルすること自体ほぼ初めてだったため、だいぶ遠回りしてしまったので
もしかしたら、同じような人もいるかな？と思ったので、ここに残しておきたいと思います。

SDKをインストールする
==================
1. [Edison - Software Downloads](https://communities.intel.com/docs/DOC-23242)から**Edison SDK Windows 32**をDLします。
64bitの方でも大丈夫だと思いますが今回は32bitの方を使用しました。

2. DLしたzipファイル、中のbz2アーカイブを展開し、適当なディレクトリに配置します。
ディレクトリはなるべく浅い方がいいと思います。
今回は`C:/Tools/edison`以下に`sysroot/`とその他ファイルを配置しました。

3. pathを通す
`C:/Tools/edison/sysroots/i686-pokysdk-mingw32/usr/bin/i586-poky-linux`にpathを通します。
nyagosを使っていれば~/.nyagosに
`addpath('C:/Tools/edison/sysroots/i686-pokysdk-mingw32/usr/bin/i586-poky-linux')`
と書くだけでいいで便利です。

コンパイルしてみる
================
僕はさんざんググりまくり&試行錯誤しまくりだったのですが、
結局`--sysroot`オプションさえ付ければOKでした。
クロスコンパイルやる人にとっては常識なんでしょうね、
ググってもなかなか`--sysroot`のキーワードに辿りつけませんでした。。。

さて、例によって`helloworld.c`を準備してください(もちろん内容込で)。
あとは

```
i586-poky-linux-gcc --sysroot=C:/Tools/edison/sysroots/core2-32-poky-linux helloworld.c -o helloworld
```
とコマンドを打てばedison用のバイナリが出来上がります！
scpかなんかで転送して実行できれば成功です。

あとがき
=======
実はedisonが手元に届いたのはついさっきですｗ
うずうずして、実機が届く前からクロスコンパイル方法を模索していました。
これからちょっとずつ触ってみようと思います。
Swift で UIImage の方向を強制的に変換する

# 元ネタ (Objective-C)

http://stackoverflow.com/questions/5427656/ios-uiimagepickercontroller-result-image-orientation-after-upload

「 UIImage で作った JPEG の向きがおかしいんだけど」
「 imageOrientation というプロパティで正しい方向を持ってる。それを使って、強制的に方向を変換することもできる」

というやりとり。

Objective-C でカテゴリ拡張を行い ```fixOrientation``` というメソッドを足す例を示している。

同様の Gist: https://gist.github.com/alex-cellcity/1531596

# Swift 版

せっかくなので、全く同じメソッドを ```Swift``` で書き直してみました。

```swift:UIImage+fixOrientation.swift
//
//  UIImage+fixOrientation.swift
//

import UIKit

extension UIImage {
    func fixOrientation () -> UIImage {
        if self.imageOrientation == UIImageOrientation.Up {
            return self
        }
        var transform = CGAffineTransformIdentity
        typealias o = UIImageOrientation
        let width = self.size.width
        let height = self.size.height
        
        switch (self.imageOrientation) {
        case o.Down, o.DownMirrored:
            transform = CGAffineTransformTranslate(transform, width, height)
        case o.Left, o.LeftMirrored:
            transform = CGAffineTransformTranslate(transform, width, 0)
            transform = CGAffineTransformRotate(transform, CGFloat(M_PI_2))
        case o.Right, o.RightMirrored:
            transform = CGAffineTransformTranslate(transform, 0, height)
            transform = CGAffineTransformRotate(transform, CGFloat(-M_PI_2))
        default: // o.Up, o.UpMirrored:
            break
        }
        
        switch (self.imageOrientation) {
        case o.UpMirrored, o.DownMirrored:
            transform = CGAffineTransformTranslate(transform, width, 0)
            transform = CGAffineTransformScale(transform, -1, 1)
        case o.LeftMirrored, o.RightMirrored:
            transform = CGAffineTransformTranslate(transform, height, 0)
            transform = CGAffineTransformScale(transform, -1, 1)
        default: // o.Up, o.Down, o.Left, o.Right
            break
        }
        let cgimage = self.CGImage

        let ctx = CGBitmapContextCreate(nil, UInt(width), UInt(height),
                CGImageGetBitsPerComponent(cgimage), 0,
                CGImageGetColorSpace(cgimage),
                CGImageGetBitmapInfo(cgimage))
        switch (self.imageOrientation) {
        case o.Left, o.LeftMirrored, o.Right, o.RightMirrored:
            CGContextDrawImage(ctx, CGRectMake(0, 0, height, width), cgimage)
        default:
            CGContextDrawImage(ctx, CGRectMake(0, 0, width, height), cgimage)
        }
        let cgimg = CGBitmapContextCreateImage(ctx)
        let img = UIImage(CGImage: cgimg)
        return img!
    }
}
```
bashのコマンドラインでコメント(#)の使いみち

bashってコマンドラインで#のコメントが使えるのでこんなこともできたりするじゃないですか。

```
masami@saga:/proc$ # hello, world
masami@saga:/proc$
```

これ自体は全く意味ないのですが、コマンドラインを長々と打ち込んでから「あ、その前にやることが！」ってなる場合がありますよね。
zshだとbuffer stack(日本語だとコマンドラインスタックとも）があるので一旦スタックにpushして別のコマンドを実行して戻ってからpopしてやりかけたコマンドを実行できるんだけど、bashってその機能無いよな（多分）ってことでCtrl-Aで先頭に移動して#でコメントにして実行してるんですけども、もっと上手い方法は無いものか・・・
gitをロールプレイングゲームに例えると分かりやすい

### はじめに

日常的にgitを使うようになって、初めは概念が難しかったが最近ちょっと分かるようになってきた（気がする）ので雑記
脱git初心者のための考え方とかを書きます。
具体的なコマンドの説明とかは出てきません。


### gitはギャルゲーだ

よく出る例えですね。
「例えばギャルゲー・エロゲーでルート分岐の前でセーブする。そんな感じ」
でもこの例えはbranchにのみ有効な気がしている。
「A子ちゃんとB子ちゃんどっち攻略するか、その分岐手前でセーブ」
この場合A子ちゃんとB子ちゃんはそれぞれがブランチ
A子ちゃん攻略してる途中でB子ちゃんを攻略しに行こうとすると色々な不都合が起きる。

* A子ちゃんが嫉妬（commitせずにbranchを変えると変更点は付いてくる）
* B子ちゃんとのことがバレる（conflict）
* B子ちゃんのところに行きたいときはちゃんとA子ちゃんに断ってからいく（commitしてからbranch移動）かバレないように行く（stash）

とまぁ、当てはめてみると割としっくりくる（私だけかもしれないが）

### gitはロールプレイングゲームだ

私はギャルゲーで例えるよりもRPGで例えた方が分かりやすいのではないかと思う。
大事なボス戦前のセーブポイント
ここでしっかり準備を整えないと負けてしまうかもしれない

* 宿屋に泊まって回復したか？
* パーティーのメンバーはそれで正しいか？
* メンバーそれぞれの装備はそれでいいか？
* アイテムはそれで足りるか？
etc...

この項目1つ1つがgitのcommitだと思うと分かりやすい。

プログラムの大きな変更
細かくコミットしていかないと重大なバグを生んで取り返しのつかないことになってしまうかもしれない

* 変数名を統一したコミット
* メソッドの引数を増やす対応をしたコミット
* メソッドの中のロジックを変えるコミット
* 新しいメソッドを増やしたコミット
etc...

とまぁ、こんなイメージ
細かいまとまりのあるところでコミットしてあると、何か問題が起きた時に問題のない状態まで戻しやすい。
例えばメンバーの装備が間違っていた（メソッドのロジックが間違っていた）らその直前のセーブ（commit）まで戻ればいい。

あるプロジェクトに途中参加するということは、その途中まで進めたセーブデータの続きからプレイすることとほぼ一緒
前のプレイした人が作ったウルトラサイキョーキャラを使って別のボスを倒しに行ってもいいし（既存のメソッドや機能を流用して新機能実装）、ちょっと弱いキャラをレベル上げして使いやすく（既存のバグを含むメソッドのリファクタ）しても良い。
その際、どんな変更をしてもいいが前のプレイヤーに怒らたら困るのでしっかり戻せる状態にしておく、つまりセーブデータを分けておくことが大切なのである。

ちなみに1人で作っているサービスや、そこまで機能が大きくないプログラムに関してはわざわざgitで管理しなくても良いと思っている。
ソロプレイのゲームや雑魚戦ばかりの難易度の低いゲームでセーブデータを分岐させないのと同じ理由ですね。

### おわりに

ふと思ったことをつらつらと書いたのでところどころ「何言ってんだこいつ？」と思うところがあるかとは思いますが、gitが少しでも身近なものになればと思います。
[Blender] オブジェクトの頂点・辺・面の選択順序を取得する方法

Blenderのプラグインの新規機能を追加した時に、オブジェクトの頂点・辺・面を選択した順序を取得する方法を学んだので紹介します。
右クリックで選択したもの(以降デフォルトのキー配置を想定)だけを対象としています。
Bキーなどでも同時に複数の頂点・辺・面を選択することが出来ますが、現時点でのBlenderでは選択順序を取得することができません。

# ソースコード

現在選択されているオブジェクトについて、選択順序を取得するスクリプトを以下に示します。
blenderの内部構造にアクセスするためのbpyの他に、bmeshをインポートすることを忘れないようにしましょう。
blenderのバージョン依存の処理が含まれていますが、Blender 2.73から必要になったためです。
詳細は、[http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.73/Addons](http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.73/Addons)をご覧ください。

## 面の選択順序を取得

```py3:get_face_selection_sequence.py
import bpy
import bmesh   # 追加でインポートが必要

obj = bpy.context.active_object

bpy.ops.object.mode_set(mode='EDIT')  # 処理はEDITモードで行う必要がある
bm = bmesh.from_edit_mesh(obj.data)

# blenderのバージョンが2.73以上の時に必要
if bpy.app.version[0] >= 2 and bpy.app.version[1] >= 73:
    bm.faces.ensure_lookup_table()

# 面の選択順序を表示
for e in bm.select_history:
    if isinstance(e, bmesh.types.BMFace) and e.select:
        print(repr(e))
```

## 辺の選択順序を取得

```py3:get_edge_selection_sequence.py
import bpy
import bmesh   # 追加でインポートが必要

obj = bpy.context.active_object

bpy.ops.object.mode_set(mode='EDIT')  # 処理はEDITモードで行う必要がある
bm = bmesh.from_edit_mesh(obj.data)

# blenderのバージョンが2.73以上の時に必要
if bpy.app.version[0] >= 2 and bpy.app.version[1] >= 73:
    bm.edges.ensure_lookup_table()

# 辺の選択順序を表示
for e in bm.select_history:
    if isinstance(e, bmesh.types.BMEdge) and e.select:
        print(repr(e))
```

## 頂点の選択順序を取得

```py3:get_vert_selection_sequence.py
import bpy
import bmesh   # 追加でインポートが必要

obj = bpy.context.active_object

bpy.ops.object.mode_set(mode='EDIT')  # 処理はEDITモードで行う必要がある
bm = bmesh.from_edit_mesh(obj.data)

# blenderのバージョンが2.73以上の時に必要
if bpy.app.version[0] >= 2 and bpy.app.version[1] >= 73:
    bm.verts.ensure_lookup_table()

# 頂点の選択順序を表示
for e in bm.select_history:
    if isinstance(e, bmesh.types.BMVert) and e.select:
        print(repr(e))
```

# 実行結果

実行した結果を以下に示します。

```pycon:result.py
>>> for e in bm.select_history:
...     if isinstance(e, bmesh.types.BMFace) and e.select:
...         print(repr(e))
<BMFace(0x108482cf0), index=4, totverts=4>
<BMFace(0x108482c80), index=2, totverts=4>
>>>
>>> for e in bm.select_history:
...     if isinstance(e, bmesh.types.BMEdge) and e.select:
...         print(repr(e))
<BMEdge(0x11241f380)>, index=11, verts=(0x10849a960/6, 0x10849a998/7)>
<BMEdge(0x11241f1a0)>, index=5, verts=(0x10849a880/2, 0x10849a8b8/3)>
>>>
>>> for e in bm.select_history:
...     if isinstance(e, bmesh.types.BMVert) and e.select:
...         print(repr(e))
<BMVert(0x10849a960), index=6>
<BMVert(0x10849a8f0), index=4>
>>>
```

# 参考情報

* http://blender.stackexchange.com/questions/5781/how-to-list-all-selected-elements-in-python#5833
* http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.73/Addons
Ruby で MatchData#named_captures が欲しい

# `$1` は分かりにくい

正規表現検索でキャプチャーした文字列を取り出すのにこんな書き方をしていた。

```rb
def parse_isbn(isbn)
  /(\d+)-(\d+)-(\d+)-(\d+)-(\d)/ =~ isbn
  {prefix: $1, group: $2, publisher: $3, title: $4, check_digit: $5}
end

p parse_isbn("978-4-7561-3254-3")
  #=> {:prefix=>"978", :group=>"4", :publisher=>"7561", :title=>"3254", :check_digit=>"3"}
```

なんか馬鹿らしい。名前と番号の対応を考えるのがめどい。

ISBN のような，単純かつ一度作ったら変更の無いようなものならいいけど，開発中に正規表現の形がコロコロ変わるようだと，`$n` の `n` を正しく変更するのが大変だ。

※話を簡単にするため，与えられる ISBN は常に正しいと仮定している。


# そうだ名前付きキャプチャーを使おう

Ruby 1.9 になって正規表現エンジンが Oniguruma（鬼車）になり，名前付きキャプチャーが使えるようになった。キャプチャーに名前を付けておいて，対応する部分文字列を番号でなく名前で参照できるというアレだ。ちなみに Ruby 2.0 からは Oniguruma のフォークである Onigmo（鬼雲；u は入らない）に代わっている。

キャプチャーについての詳細はるりまの「正規表現」をどうぞ：

http://docs.ruby-lang.org/ja/2.2.0/doc/spec=2fregexp.html

これを使おうではないか。

ただ，名前付きキャプチャーを使うと正規表現が長くなりすぎるきらいがあるので，`x` オプションでフリーフォーマットにして書くことにする。

```rb
def parse_isbn(isbn)
  /(?<prefix> \d+ ) # 接頭記号（978 か 979）
   -
   (?<group> \d+ ) # グループ記号（国，地域，言語圏）
   -
   (?<publisher> \d+ )
   -
   (?<title> \d+ )
   -
   (?<check_digit> \d )
  /x =~ isbn
  Regexp.last_match
end

p parse_isbn("978-4-7561-3254-3")
  #=> #<MatchData "978-4-7561-3254-3" prefix:"978" group:"4" publisher:"7561" title:"3254" check_digit:"3">
p parse_isbn("978-4-7561-3254-3")[:publisher] #=> "7561"
```

`x` オプションというのは，正規表現リテラル中の空白文字を無視してくれるもの。ご覧の通り `#` 以降がコメントとみなされる。

でもさ，MatchData じゃなくてキャプチャー文字列のハッシュが欲しいわけよ。

あ，ちなみに `MatchData#[]` の引数に名前を与えるとき，名前は String でも Symbol でもいい。

http://docs.ruby-lang.org/ja/2.2.0/method/MatchData/i/=5b=5d.html

# 名前付きキャプチャーのハッシュを返すメソッドは無い

絶対そういう目的のメソッドがあるはずと思って調べたけど，どうやら無い。

http://docs.ruby-lang.org/ja/2.2.0/class/MatchData.html

キャプチャー文字列を配列で返す `MatchData#captures` ならある。

名前付きキャプチャーの名前のリストを返す `MatchData#names` もある。（シンボルの配列じゃなくて文字列の配列を返すことに注意）

# 無ければ作れ

こんなでいいかな。

```rb
class MatchData
  def named_captures
    Hash[ names.map{ |name| [name.to_sym, self[name]] } ]
  end
end
```

# （2016-08-03 追記）Ruby 2.4.0 でキター！

Ruby 2.4 で `MathData#named_captures` が入るようです。

http://ruby-doc.org/core-2.4.0_preview1/MatchData.html#method-i-named_captures

```bsh
> ruby -v
ruby 2.4.0preview1 (2016-06-20 trunk 55466) [x86_64-linux]
```

で試しました。

```rb
def parse_isbn(isbn)
  /(?<prefix> \d+ ) # 接頭記号（978 か 979）
   -
   (?<group> \d+ ) # グループ記号（国，地域，言語圏）
   -
   (?<publisher> \d+ )
   -
   (?<title> \d+ )
   -
   (?<check_digit> \d )
  /x =~ isbn
  Regexp.last_match.named_captures
end

parse_isbn "978-4-7561-3254-3"
#=> {"prefix"=>"978", "group"=>"4", "publisher"=>"7561", "title"=>"3254", "check_digit"=>"3"}
``` 

やたー！
Ubuntuでsecurity updateのみ自動的に適用する


あるのかな〜と思って探したらオフィシャルドキュメントにあった。

* [AutomaticSecurityUpdates](https://help.ubuntu.com/community/AutomaticSecurityUpdates)

自動更新には`unattended-upgrades`パッケージが必要。コマンドラインから実行するには
`dpkg-reconfigure -plow unattended-upgrades`し、パッケージ設定のビューになるので **Yes** を選択する。

![kobito.1423050318.052715.png](https://qiita-image-store.s3.amazonaws.com/0/29860/3a8bfb8b-43c4-2239-1f65-52c2498c3912.png "kobito.1423050318.052715.png")

設定ファイルとして`/etc/apt/apt.conf.d/20auto-upgrades`が生成される。

```text:/etc/apt/apt.conf.d/20auto-upgrades
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
```

実際にどういったパッケージを更新するかは`/etc/apt/apt.conf.d/50unattended-upgrades`ファイルにまとめられている。デフォルトではセキュリティアップデートのみ有効。

```text:/etc/apt/apt.conf.d/50unattended-upgrades
// Automatically upgrade packages from these (origin:archive) pairs
Unattended-Upgrade::Allowed-Origins {
        "${distro_id}:${distro_codename}-security";
//      "${distro_id}:${distro_codename}-updates";
//      "${distro_id}:${distro_codename}-proposed";
//      "${distro_id}:${distro_codename}-backports";
};
```

更新ログは`/var/log/aptitude`を確認しましょう。

```
Aptitude 0.6.8.2: log report
Wed, Feb  4 2015 11:37:09 +0000

IMPORTANT: this log only lists intended actions; actions which fail due to
dpkg problems may not be completed.

Will install 0 packages, and remove 0 packages.
===============================================================================
[HOLD, DEPENDENCIES] linux-headers-generic:amd64
[HOLD, DEPENDENCIES] linux-headers-virtual:amd64
[HOLD, DEPENDENCIES] tzdata-java:amd64
[HOLD] libelf1:amd64
[HOLD] linux-image-virtual:amd64
[HOLD] linux-virtual:amd64
[HOLD] python3-software-properties:amd64
[HOLD] rsyslog:amd64
[HOLD] software-properties-common:amd64
[HOLD] tzdata:amd64
===============================================================================

Log complete.
```
grepとpecoによる順次絞り込みするシェルスクリプト


名付けて**grepeco**。

[peco/peco: Simplistic interactive filtering tool](https://github.com/peco/peco)

## 色んなデータを柔軟に絞り込みしたい
各種のデータをパイプで処理するとき、適当にワードで絞り込んでからpecoでインクリメンタルサーチしたいことがよくある。これを簡単にできるようにしたい。

想定される用途はこんな感じ。

```bash
$ ls | grepeco hoge
```

パイプで与えられたデータを、ターミナルから入力された文字列で絞り込む。

## パイプからの入力とターミナルからの入力を区別する
ここで、パイプで与えられたデータとはシェルスクリプトの**標準入力**、ターミナルから入力された文字列とは**引数**である。

シェルスクリプト内において、この二つは以下のように得ることができる。

```bash
# 標準入力を得る
cat -
# 引数を得る
echo "$1" # 1つめ
echo "$*" # すべて（1つの文字列として）
for i in "$@" # すべて（配列として）
do
  echo "arg: $i"
done
```

この場合、引数を配列として扱うのであれば、**複数の検索語による、複数の検索結果からさらに絞り込む**ことができる。

## コード
以上を踏まえて、コードは以下のようになる。

```grepeco.sh
#!/bin/bash
# 引数を単一の文字列として扱う
# 変数を初期化
pipes=()
prompt="select stdin from pipe"
optm=""
usage () {
  echo "Usage: grepeco [-1h] [-p prompt] <args>" 1>&2
  echo "  -1: find only one" 1>&2
  echo "  -p: change peco prompt" 1>&2
  echo "  -h: view help" 1>&2
}
while getopts "1p:h" OPT
do
  case $OPT in
    1)
      optm="m1" # grepのオプションを変更
      ;;
    p)
      prompt="$OPTARG" # pecoのプロンプトを変更
      ;;
    h)
      usage
      exit 0
      ;;
    ?)
      echo "ERROR: Undifined option" 1>&2
      usage
      exit 1
      ;;
  esac
done
shift $(($OPTIND - 1))
if [ -p /dev/stdin ];then # パイプ入力があるか判断
  while read pipe
  do
    pipes+=("$pipe")
  done < <(if [ -n "$1" ]; then # 引数があるか判断
    cat - | grep -i"$optm" "$*"
  else
    cat -
  fi)
else
  echo "ERROR: No stdin from pipe" 1>&2
  exit 1
fi
case  "${#pipes[@]}" in # pipesの要素数による分岐
  0 )
    echo "ERROR: No hit." 1>&2
    exit 1
    ;;
  1)
    echo "${pipes[*]}"
    ;;
  *)
    for i in "${pipes[@]}"
    do
      echo "$i"
    done | peco --prompt "$prompt"
    ;;
esac
```

```grepeco.sh
#!/bin/bash
# 引数を配列として扱う
-  done < <(if [ -n "$1" ]; then
-    cat - | grep -i"$optm" "$*"
-  else
-    cat -
-  fi)

+  done < <(if [ -n "$1" ]; then
+    stdin="$(cat -)" # ループで標準出力がリセットされるため変数に格納
+    for arg in "$@"
+    do
+      echo "$stdin" | grep -i "$arg"
+    done | sort -u # 重複する結果を削除
+  else
+    cat -
+  fi)
```

**if文の結果をwhile文に渡す**ということを思いついてコードがシンプルになった。

## 参考
* [ShellScript - シェルスクリプトでパイプを判断する - Qiita](http://qiita.com/b4b4r07/items/77c589f21a99db8bb682)
* [シェルスクリプトでパイプからの入力とキーボード入力を区別する](http://rcmdnk.github.io/blog/2014/01/15/coputer-bash-zsh/)
* [Bash - パイプ出力を**現在のシェル**上のwhileに喰わせる上手いやり方 - Qiita](http://qiita.com/kawaz/items/6fd4cd86ca98af644a05)
* [bash によるオプション解析 - Qiita](http://qiita.com/b4b4r07/items/dcd6be0bb9c9185475bb)
基本の話: 「変数や関数を節約すればパフォーマンスが上がる」わけではない

# 注意

<strong>この記事を書いている人は、日常的に C を書いているわけではありません。</strong> 
普段は Python とか Java とか書いてます。

もしかすると見当違いの内容があるかもしれません。
補足・ツッコミ・愛のマサカリは、ぜひお願いします…。

# 経緯

去年、情報系の専門学校に通う学生（以下、その子）から、 C 言語のソースコードをみせてもらって、添削することがあった。

C 言語を使いこなせてるとは、お世辞にもいえない私が見ても、その子のコードはいろいろと厳しい感じだった。

その子とよく話してみると <strong>変数や関数の宣言をしないことが、資源の節約になると思い込んでいる</strong> ようだった。

その時は「節約にならない」という内容を口頭で伝えたのだけど、コードにしたほうがわかりやすいので、検証して記事を書いた。

# 今回の例示に使うコンパイラとバージョン

私の OS X に入ってた LLVM の cc を使った。

```shell-session
$ cc --version
Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin14.1.0
Thread model: posix
```

# ファイル

24 と出力するだけの C 言語のソースが 3 つある。
この 3 つのファイル a.c, b.c, c.c をコンパイルしよう。

```C:a.c
#include <stdio.h>
 
int main(void)
{
    printf("%d\n", 24);
    return 0;
}
```

```C:b.c
#include <stdio.h>
 
int main(void)
{
    int i = 1;
    int j = 2;
    int k = 3;
    int l = 4;
    int m = i * j * k * l;
    printf("%d\n", m);
    return 0;
}
```

```C:c.c
#include <stdio.h>

static int x2(int x)
{
    return x * 2;
}

static int x3(int x)
{
    return x * 3;
}

static int x4(int x)
{
    return x2(x2(x));
}

int main(void)
{
    int x = x4(x3(x2(1)));
    printf("%d\n", x);
    return 0;
}
```

- a.c は値をほぼそのまま表示してる
- b.c は変数を何個も使ってる。
- c.c は関数を定義して何個も呼び出している

# コンパイル

これをそれぞれ最適化オプション ```-O3``` でコンパイルする

```shell-session
$ cc -c -O3 a.c b.c c.c
```

# 比較

バイナリを比較するため、 ```cmp``` コマンドを使う。

```shell-session:コマンドの実行例
$ cmp a.o a.o
$ cmp a.o d.o
a.o d.o differ: char 1153, line 1
```

ファイルを 2 つ指定し、 2 つの中身が同じなら何も出力せず、
違う場合はその違いを表示するコマンド。

さっき作ったファイルを比較してみると

```shell-session
$ cmp a.o b.o
$ cmp b.o c.o
$ cmp c.o a.o
```

実は<strong> 3 つとも全く同じ実行ファイルになる </strong> ！

# アセンブラを見てみる

-S オプションをつけるとアセンブリのファイルを出力する

```shell-session
$ cc -O3 -S a.c
```

```assembly:a.s
	.section	__TEXT,__text,regular,pure_instructions
	.globl	_main
	.align	4, 0x90
_main:                                  ## @main
	.cfi_startproc
## BB#0:
	pushq	%rbp
Ltmp2:
	.cfi_def_cfa_offset 16
Ltmp3:
	.cfi_offset %rbp, -16
	movq	%rsp, %rbp
Ltmp4:
	.cfi_def_cfa_register %rbp
	subq	$16, %rsp
	leaq	L_.str(%rip), %rdi
	movl	$24, %esi
	movl	$0, -4(%rbp)
	movb	$0, %al
	callq	_printf
	movl	$0, %esi
	movl	%eax, -8(%rbp)          ## 4-byte Spill
	movl	%esi, %eax
	addq	$16, %rsp
	popq	%rbp
	retq
	.cfi_endproc

	.section	__TEXT,__cstring,cstring_literals
L_.str:                                 ## @.str
	.asciz	"%d\n"


.subsections_via_symbols
```

コンパイラが、見事に全部 ```24``` にして、不要な代入などは消去してるのが分かる。

最適化オプション ```-O3``` では、変数も関数も名前もなくなってしまった。


# gcc で同じ実験をする場合の注意

```shell-session
$ cc -c -O3 -S a.c
```

gcc は生成するファイルに元ファイルの情報を含むので、上の例は生成されるファイルには必ず差分が発生してしまう。
```-S``` オプションをつけて、アセンブリの diff をとれば、ファイル名以外には相違ないことが確かめられる。

# その子に伝えたいこと

- ```-O3``` オプションをつけたり、 ```inline``` キーワードをつけることで、コンパイラが頑張ってくれるので、人間が手で変数や関数を減らす必要はない。
- 結果的に生成される実行ファイルが同じなら、変数や関数を減らすことは、「実行する機械資源の節約」にはならないよね。
- それよりも、読みやすいスタイル・デバッグしやすいスタイルで書くことが「人間の労力を節約」になるんじゃないかな。
stylusでループを使う方法

**Stylus**

```scss
for num in (1..5)
  .mt{num}
    margin-top: (num)px
```

**↓**

**CSS**

```css
.mt1 {
  margin-top: 1px
}
.mt2 {
  margin-top: 2px
}
.mt3 {
  margin-top: 3px
}
.mt4 {
  margin-top: 4px
}
.mt5 {
  margin-top: 5px
}
```

for num in (1..100)みたいにすれば100までループされます。
こんな感じで.mt1でmargin-top:1px、.mt100でmargin-top:100pxみたいなスタイルを量産することができました。
mysql5.6のclientだけインストール＠CentOS6.6


rpmで入れるとnot relocateableだけど、
インストール先を指定したいので、cmakeを使ってソースからコンパイルして入れる

使用するソース・ファイルは下記からDLする。
http://dev.mysql.com/get/Downloads/MySQL-5.6/mysql-5.6.23.tar.gz


## コンパイル環境を整える


```
# yum -y install gcc-c++
Installed:
  gcc-c++.x86_64 0:4.4.7-11.el6                                                                                                                                                     

Dependency Installed:
  cloog-ppl.x86_64 0:0.15.7-1.2.el6               cpp.x86_64 0:4.4.7-11.el6                        gcc.x86_64 0:4.4.7-11.el6           glibc-devel.x86_64 0:2.12-1.149.el6_6.5      
  glibc-headers.x86_64 0:2.12-1.149.el6_6.5       kernel-headers.x86_64 0:2.6.32-504.8.1.el6       libgomp.x86_64 0:4.4.7-11.el6       libstdc++-devel.x86_64 0:4.4.7-11.el6        
  mpfr.x86_64 0:2.4.1-6.el6                       ppl.x86_64 0:0.10.2-11.el6                      

Complete!
```

```
# yum -y install cmake
 Installed:
  bison.x86_64 0:2.4.1-5.el6                                                                                                                                                        

Dependency Installed:
  m4.x86_64 0:1.4.13-5.el6                                                                                                                                                          

Complete!
```

```
# yum -y install ncurses-devel
Installed:
  ncurses-devel.x86_64 0:5.7-3.20090208.el6                                                                                                                                         

Complete!
```

## アーカイブダウンロード

```
# cd /tmp
# wget http://dev.mysql.com/get/Downloads/MySQL-5.6/mysql-5.6.23.tar.gz
```

## アーカイブファイル解凍

```
# tar zxvf mysql-5.6.23.tar.gz
```



## Cmakeする

```
# cd mysql-5.6.23

# cmake -DCMAKE_INSTALL_PREFIX=/sb/mysql/mysql5.6 -DWITHOUT_SERVER=ON -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci .


〜中略〜
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/source/mysql-5.6.23
```
-DCMAKE_INSTALL_PREFIXでインストール先指定
-DWITHOUT_SERVER=ONでクライアントだけに指定
-DDEFAULT_CHARSETでキャラセット指定（クライアントだけだといらないかも）
-DDEFAULT_COLLATIONでコレーション指定（クライアントだけだといらないかも）
その他のオプションは下記参照
http://dev.mysql.com/doc/mysql-sourcebuild-excerpt/5.5/en/source-configuration-options.html#option_cmake_cmake_install_prefix


## makeする

```
# make
〜中略〜
Linking C static library libmysqlservices.a
[100%] Built target mysqlservices
```

## インストールする

```
# make install
〜中略〜
-- Installing: /sb/mysql/mysql5.6/bin/mysql_find_rows
-- Installing: /sb/mysql/mysql5.6/bin/mysqlhotcopy
-- Installing: /sb/mysql/mysql5.6/bin/mysqldumpslow
-- Installing: /sb/mysql/mysql5.6/bin/mysqld_multi
-- Installing: /sb/mysql/mysql5.6/bin/mysqld_safe
-- Installing: /sb/mysql/mysql5.6/bin/mysql_secure_installation
```

## お掃除

```
# rm -rf CMakeCache.txt
# make clean
```

## おまけ〜アンインストール〜

```
# xargs rm < install_manifest.txt 
```


## 動作確認

```
# /sb/mysql/mysql5.6/bin/mysql --version
/sb/mysql/mysql5.6/bin/mysql  Ver 14.14 Distrib 5.6.23, for Linux (x86_64) using  EditLine wrapper
```