OmniAICreator/Qiita-1.07M huggingface dataset:
Androidのdrawableの画像リソースから、高速でバイト列を取得する方法


Androidのdrawabaleに組み込んだ画像リソースから、検索してよく出てくる方法よりも素早くデータのバイト列を取得する方法です。
私がXamarin使いなのでXamarinのc#コードで例示しますが、XamarinのAPIは基本ラッパなので、JavaでAndroid開発されている方にも基本伝わるかと思います。

drawableの画像リソースをバイト列で取得する方法を検索していて、よく出てくる方法は以下のようなものです。

```csharp:drawableリソース取得法1
var res_id = context.Resources.GetIdentifier ("res_name", "drawable", context.PackageName);
if (res_id == 0) {
    throw new Java.IO.FileNotFoundException("Resource Not Found");
}

var bitmap = BitmapFactory.DecodeResource(context.Resources, res_id);
byte[] data;
using (var stream = new MemoryStream())
{
    bitmap.Compress(Bitmap.CompressFormat.Png, 0, stream);
    data = stream.ToArray();
}
return data;

```

ですが、これ、クソ重いです。
小さなアイコン画像とかだと気にならないのかもしれませんが、全画面サイズくらいのレベルの画像を取得しようと思うと、本当に一息つくというレベルでデータ取得までに時間がかかります。
考えてみれば当たり前で、元々pngでresourceに登録されているデータを、Bitmapに戻してから、またpngに圧縮してバイト化してるので、無駄な解凍/圧縮処理の分負荷と時間がかかってしまいます。

解決方法を探していて、以下のやり方を見つけました。

```csharp:drawableリソース取得法2
var res_id = context.Resources.GetIdentifier ("res_name", "drawable", context.PackageName);
if (res_id == 0) {
    throw new Java.IO.FileNotFoundException("Resource Not Found");
}

var ins = context.Resources.OpenRawResource(res_id);      

var baos = new ByteArrayOutputStream();
var buff = new byte[10240];
var i = int.MaxValue;
while ((i = ins.Read(buff, 0, buff.Length)) > 0)
{
    baos.Write(buff, 0, i);
}

return baos.ToByteArray();
```

この方法だと、resourceから直接InputStreamを取得しているので、無駄な解凍/圧縮をしなくてよい分、一瞬でデータ取得できます。
Githubを使わずにチームでGitを共有する方法



通常、ローカルでgitリポジトリを作成するには、

- `git init`
- `git clone`

のいずれかのコマンドを叩く。

リモート用のgitディレクトリを作成するには、下記を叩けば良い。

```
git init --bare --shared /path/to/hogehoge.git
```

- `--bare`：ベアレポジトリ（作業ファイルを持たず、管理のみ行うリポジトリ）を作成するオプション
- `--shared`：グループアクセス可能なパーミッションを追加するオプション
- リモート用のリポジトリ（ベアリポジトリ）の拡張子は`.git`とするのが慣例

AWSなど、チームでアクセスできるサーバ上で上記ディレクトリを作成すれば、Githubの代わりとして使える。
ローカルにSourceTreeのアプリも入れておくと便利！（ツリー構造がひと目で分かる）

※参考URL
▼ベアリポジトリについて - Git
http://www.proton.jp/main/programming/git/bare.html
PHPで日付関数を使いこなす（date, strtotime）


# 1. date関数
```php
date(フォーマット)
date(フォーマット, タイムスタンプ)
```

- date関数は引数を1つ（or2つ）持てる
  - 第1引数：フォーマット（string）
  - 第2引数：タイムスタンプ（int）
- 引数1つの時：「現在の時刻」を「指定したフォーマット」で出力
- 引数2つの時：「第2引数のタイムスタンプ」を「指定したフォーマット」で出力
- 戻り値はstring

### 使用例
下記、2015年3月10日(火)朝6時に叩いたコマンドである。

```php
<?php

date_default_timezone_set('Asia/Tokyo');

echo date("Y/m/d H:i:s") . "\n"; //「2015/03/10 06:00:00」
echo date("Y/m/01") . "\n"; //「2015/03/01」
echo date("Y/m/t") . "\n"; //「2015/03/31」

$w = date("w");
$week_name = array("日", "月", "火", "水", "木", "金", "土");

echo date("Y/m/d") . "($week_name[$w])\n"; //「2015/03/10(火)」
```

- `date_default_timezone_set('Asia/Tokyo');`：まずタイムゾーンの設定をすること。
- `Y`：年（4桁表記）
  - `y`：年（2桁表記）
- `m`：月（2桁表記）
  - `n`：月（先頭にゼロつけない）
- `d`：日（2桁表記）
  - `j`：日（先頭にゼロつけない）
- `H`：時間（24時間単位）
  - `h`：時間（12時間単位）
- `i`：分
- `s`：秒
- `t`：指定した月の日数
- `w`：曜日番号（0[日曜]から6[土曜]の値）
- `.`：文字列連結
- `\n`：改行

# 2. strtotime関数
```php
strtotime(日時)
strtotime(日時, タイムスタンプ)
```

- strtotime関数は引数を1つ（or2つ）持てる
  - 第1引数：日時（string）。相対日時や絶対日時を指定可能。
  - 第2引数：タイムスタンプ（int）
- 引数1つの時：「現在」を基準とした、「第1引数の日時」のタイムスタンプを出力
- 引数2つの時：「第2引数のタイムスタンプ」を基準とした、「第1引数の日時」のタイムスタンプを出力
- 戻り値はint

### 使用例
下記、2015年3月10日(火)朝6時に叩いたコマンドである。

```php
<?php

date_default_timezone_set('Asia/Tokyo');

echo date("Y/m/d H:i:s", strtotime('-1 day')) . "\n"; //「2015/03/09 06:00:00」
echo date("Y/m/d", strtotime('last Saturday')) . "\n"; //「2015/03/07」
echo date("Y/m/d 10:00:00", strtotime('last Saturday', strtotime('2015-03-07'))); //「2015/02/28 10:00:00」
echo date("Y/m/d 10:00:00", strtotime('last Saturday', strtotime('2015-03-03') + 7 * 24 * 60 * 60)); //「2015/03/07 10:00:00」
```

- strtotimeの第1引数には`last Saturday`や`'2015-03-07'`などが使える。
  - `last Saturday`のような相対日時を使う場合、第2引数なしなら「現在から見たlast Saturday」、第2引数ありなら「タイムスタンプの日付から見たlast Saturday」
- タイムスタンプに`7 * 24 * 60 * 60`を足したら7日後を表す。

※参考URL
▼[PHP]date
http://php.net/manual/ja/function.date.php
▼[PHP]strtotime
http://php.net/manual/ja/function.strtotime.php
▼strtotimeの引数に有効な書式
http://php.net/manual/ja/datetime.formats.php
MySQLでクエリのログを記録する

概要
----

開発中にアプリケーションからどのようにMySQLにクエリが実行されているのかを確認します。

前提
----

* CentOS上のMySQL5.6.14で確認しました

手順
----

### my.cnfを編集する

```
$ sudo vim /etc/my.cnf
```

mysqldディレクティブの下に下記のように指定します。

```
[mysqld]
general_log=ON
general_log_file=/var/log/mysqld_query.log
```

### MySQLを再起動する

```
$ sudo /etc/init.d/mysqld restart
```

### ログファイルを確認する

```
$ sudo tail -f /var/log/mysqld_query.log 
Time                 Id Command    Argument
150310  5:52:45	    1 Connect	UNKNOWN_MYSQL_USER@localhost as  on 
		    1 Quit	
150310  5:53:05	    2 Connect	cid@localhost on sample
		    2 Query	SELECT `article`.`title`, `article`.`body`, `article`.`id`, `article`.`createdAt`, `article`.`updatedAt` FROM `articles` AS `article`   LIMIT 1 OFFSET 1
		    2 Query	(SELECT * FROM `tags` AS `tag` WHERE `article_id` = 3  ORDER BY `tag`.`id` ASC)
```

### 備考

最初調べてると、my.cnfに下記のように書く例が多かったんですが、

```
[mysqld]
log=myquery.log
```

動かしてみると、エラーになるので、今回設定したような方法になりました。

```
/usr/sbin/mysqld: ambiguous option '--log=/var/log/mysql.log' (log-bin, log_slave_updates)
```
Linuxでのmkdirのm,pオプションの同時使用時の注意

#本文

Linuxにてmkdirコマンドでディレクトリを作成するときに

```bash
mkdir -m 777 hoge 
```
とするとパーミッション777のディレクトリhogeが作成できます。


```bash
mkdir -p hoge/fuga 
```

とするとディレクトリhogeの作成と同時に中にディレクトリfugaが作成できます。
この時のデフォルトパーミッションは

Linuxのファイル・ディレクトリ作成した時のパーミッション (umask)
http://qiita.com/yuki2006@github/items/3774bf765eb5ef7deabc
の記事通りです。

（ちなみに、-pはすでにディレクトリがあった時などのエラーメッセージ抑制にも使えます）


さて、-mと-pオプションを同時に使用したらどうなるでしょうか？

```bash
mkdir -m 777 -p hoge/fuga 
```

この場合、
ディレクトリhogeと同時に中にディレクトリfugaが作成できるのですが、

fugaがパーミッション777なのですが、

hogeディレクトリは **デフォルトパーミッション**（上記）になる罠があります。


# ちなみに

```bash
  info coreutils 'mkdir invocation'
```

でみたマニュアルでは (man mkdirには書かれていない）

```text
 Note: The `--mode',`-m' option only applies to the right-most
     directories listed on the command line.  When combined with
     `--parents', `-p' option, any parent directories are created with
     `u+wx' modified by umask.
```

と書いてあるので一応仕様通りらしいです。

#代替策（installコマンド）

```bash
install --directory --mode=777 hoge/fuga
```

```bash
install -d -m 777 hoge/fuga
```

これで、hogeもfugaも777のパーミッションで作成されます。


#参考

man MKDIR
http://linuxjm.sourceforge.jp/html/GNU_fileutils/man1/mkdir.1.html
ターミナルにQRコードを表示する


[RQRcode](https://github.com/whomwah/rqrcode)と[Colorize](https://github.com/fazibear/colorize)を使う。

```text
$ gem install rqrcode colorize
```

指定した文字列を扱える最小サイズのQRコードを作る。
空白の背景にColorizeで色をつけて表示する。

```rb:print_qr.rb
require 'rqrcode'
require 'colorize'

# 引数を受け取る (無ければ標準入力から受け取る)
str = ARGV[0] || $stdin.read

# QRコードを作成
qr = (1..40).each{|n| break RQRCode::QRCode.new(str, size:n) rescue next}
raise "文字列が大きすぎます。" unless qr.instance_of? RQRCode::QRCode

# QRコードを文字列にする
black = "  ".on_black
white = "  ".on_light_white

qr_s = qr.to_s true:black, false:white

# 白枠つける
hr = white * qr.module_count # 横幅
qr_s = [hr, qr_s, hr] * "\n"
qr_s.gsub! /^.*$/, "#{white}\\&#{white}"

# 表示
puts qr_s
```

![qr.png](https://qiita-image-store.s3.amazonaws.com/0/18902/ab6062e9-ccd3-9fc3-07a2-d2ff16cc86d4.png "qr.png")


iPhoneアプリ(Workflow)で試したら普通に読めた。
使い道は不明。

あと日本語無理。

----

(追記: QRコードは白黒が反転してても大丈夫だったので、これでもいけた)

```rb:print_qr.rb
require 'rqrcode'
require 'colorize'

# 引数を受け取る (無ければ標準入力から受け取る)
str = ARGV[0] || $stdin.read

# QRコードを作成
qr = (1..40).each{|n| break RQRCode::QRCode.new(str, size:n) rescue next}
raise "文字列が大きすぎます。" unless qr.instance_of? RQRCode::QRCode

# 文字列にして表示
puts qr.to_s(true:"  ".swap, false:"  ")
```

# メモ

## [RQRCode](https://github.com/whomwah/rqrcode)について

RQRCodeはドキュメント無い部分が多くて、ちゃんと使うならソースだいぶ読む必要がある。
Wikipediaで用語だけでも仕入れるとだいぶ分かる(気がする)。
特に「module」は点のことであって、Rubyのmoduleと全く関係ないので注意。

[QRコード - Wikipedia #QRコードの用語](http://ja.wikipedia.org/wiki/QR%E3%82%B3%E3%83%BC%E3%83%89#QR.E3.82.B3.E3.83.BC.E3.83.89.E3.81.AE.E7.94.A8.E8.AA.9E)

`RQRCode::QRCode.new`のsize(バージョンと呼ぶ)には1〜40を指定できる。
4ピクセルずつ大きくなる。情報量も増える。
省略した場合のデフォルト値は4。

文字列の大きさがそのバージョンで扱いきれなければ`RQRCode::QRCodeRunTimeError`を吐く。

今回のコードは1〜40まで順番にエラーが出るか試すという頭の弱い方法。
明らかにもっといい方法ある。遊びだしめんどいからやらないけど。

QRコードには数字、英数、バイナリ、漢字のモードがある。
漢字のモードにすれば日本語も扱えるっぽい。
RQRCodeでもそのモードを切り替える設定あるっぽいんだけどやり方が分からなかったので諦めた。

(あと全然関係ないけど、レシートにQRコードで買い物のCSV乗っけてくれれば家計簿の記録捗るのにね)

## [Colorize](https://github.com/fazibear/colorize)について

`String.color_samples`で、どんな色があるかを表示できる。
色を変えるにはその色のメソッドを使うか、String#colorizeにシンボルを渡す。

```rb
puts "文字を黄色に".yellow
# "文字を黄色に".colorize(:yellow) #同じ

puts "背景を黄色に".on_yellow
# "背景を黄色に".colorize(background: :yellow) #同じ
```

文字色・背景色を変える以外に、太字にしたり下線をつけたりもできる。

```rb
String.modes
#=> [:default, :bold, :underline, :blink, :swap, :hide]

puts "太字にする".bold
puts "下線をつける".underline
puts "点滅させる".blink

puts "文字色と背景色を入れ替える".swap
puts "文字色を背景色と同じにする".hide

# puts "太字".colorize(mode: :bold) # シンボルで指定する場合はこう
```

(今回のコード、1文字ずつ色を変えてるのであんまり良くないけど気にしない)

# 参考

- [Rubyで簡単にQRコード画像を生成する方法 - Qiita](http://qiita.com/ryosy383/items/c753103c93fa177e4466)

今回使ったgem

- [whomwah/rqrcode](https://github.com/whomwah/rqrcode)
- [fazibear/colorize](https://github.com/fazibear/colorize)

QRコードの知識

- [QRコード - Wikipedia #QRコードの用語](http://ja.wikipedia.org/wiki/QR%E3%82%B3%E3%83%BC%E3%83%89#QR.E3.82.B3.E3.83.BC.E3.83.89.E3.81.AE.E7.94.A8.E8.AA.9E)
- [QRコードの情報量とバージョン｜QRコードドットコム｜株式会社デンソーウェーブ](http://www.qrcode.com/about/version.html)
Pythonでos.mkdir時の注意

(備忘録なメモです）

Pythonでディレクトリを作成するときに
os.mkdir(path,[mode])
http://docs.python.jp/2.7/library/os.html#os.mkdir

を使いますが

```py:mkdir_NG_0777

os.mkdir("hoge",0777)

```
としてもパーミッション0777でディレクトリが作成されません。
マニュアルにあるとおりumaskがかかるので以下の記事で説明した挙動を受けます。
(つまり第2パラメータは、パーミッションの設定ではありません！）

参考：
Linuxのファイル・ディレクトリ作成した時のパーミッション (umask)
http://qiita.com/yuki2006@github/items/3774bf765eb5ef7deabc


つまり以下のようにしないといけません。

```py:mkdir_OK_0777

os.mkdir("hoge")
os.chmod("hoge",0777)

```

ちょっといけてない（冗長な）感じがしますがどうなんでしょうか。。
（いい方法がありましたら教えて下さい。
Linuxのファイル・ディレクトリ作成した時のパーミッション (umask)

(備忘録なメモです）

Linuxでtouchやmkdirでファイル・ディレクトリを作った時のデフォルトのパーミッションは
umask値によります。


ファイルなら666
ディレクトリなら777が基本値で

(基本値)-(umask値)がデフォルトのパーミッションになります。

例 umask値が022でディレクトリを作成したら
777-022=755

```text:umask取得
$ umask
022
```

```text:umask設定
$ umask 022
```


参考：

【 umask 】 ファイル作成時のパーミッションを指定する
http://itpro.nikkeibp.co.jp/article/COLUMN/20060227/230913/

ファイル新規作成時のパーミッションを変更するには
http://www.atmarkit.co.jp/flinux/rensai/linuxtips/474deffilepermssion.html

パーミッション早見表
http://qiita.com/YusukeHigaki/items/7a4ef34916a9140ec1cc
Perlプロジェクトのドキュメントをmakeで一括生成

## はじめに

Perl プロジェクトのソースコードに記された POD から、GNU make を使ってドキュメントを一括生成する方法を紹介します。
比較的シンプルな Makefile で実現できました。

## プロジェクト構成例

プロジェクトの構成が、以下のようになっているとします。

```
.
├── bin
│   ├── bar.pl
│   └── foo.pl
└── lib
    ├── Foo
    │   └── Bar.pm
    └── Foo.pm
```

## ドキュメント生成要件

ドキュメントは以下のルールで生成するとします。

* doc/ ディレクトリ以下に、ソースコードのパスを元に1ファイルずつ生成する
* pod2html コマンドを使って HTML 形式で出力

## Makefile

Makefile をプロジェクトのルートディレクトリに配置します。
内容は以下のようにします。

```mf
.PHONY: html

GENHTML = pod2html
BINS    = $(shell find bin -type f)    # (1)
LIBS    = $(shell find lib -name *.pm) # (2)
SRCS    = $(BINS) $(LIBS)
DOCDIR  = doc
HTMLS   = $(SRCS:%=$(DOCDIR)/%.html)   # (3)

html: $(HTMLS)      # (4)

$(DOCDIR)/%.html: % # (5)
        @if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi # (6)
        $(GENHTML) --infile $< --outfile $@
```

以下、この Makefile を少し詳し目に解説します。

(1) bin/ 以下の実行ファイルを展開します。
(2) lib/ 以下の .pm ファイルを展開します。
(3) 出力ファイルリストを `$(SRCS)` リストから生成します。
(4) メインの html タスクの設定です。出力ファイルすべてに依存します。
(5) 全出力ファイルに対する生成コマンドの設定です。
(6) ディレクトリがない状態で `pod2html` を実行するとエラーになってしまうので、予め作成しておきます。

## 実行結果

make を実行すると、以下のように各ソースコードに対して pod2html が実行されます。

```
% make
pod2html --infile bin/bar.pl --outfile doc/bin/bar.pl.html
pod2html --infile bin/foo.pl --outfile doc/bin/foo.pl.html
pod2html --infile lib/Foo/Bar.pm --outfile doc/lib/Foo/Bar.pm.html
pod2html --infile lib/Foo.pm --outfile doc/lib/Foo.pm.html
```

ソースファイルが更新されるまでは、make を再実行してもビルドは行われません。

```
% make
make: Nothing to be done for `html'.
```

doc/ 以下のファイル構成は以下のようになりました。

```
doc
├── bin
│   ├── bar.pl.html
│   └── foo.pl.html
└── lib
    ├── Foo
    │   └── Bar.pm.html
    └── Foo.pm.html
```

## 展望

Makefile を編集することでさまざまな拡張をすることができます。
例えば、pod2html に任意のオプションを加えて CSS を指定したり、pod2html 自体を別のコマンドに差し替えることも可能です。

あるいは、ドキュメントのリストページを生成するタスクを別途設定し、ドキュメント群と合わせてWebサーバでホスティングすることで、オンラインドキュメントを作ることもできるでしょう。

## その他のやり方

今回紹介した以外で、Perl プロジェクトのドキュメントを生成する方法をいくつか挙げておきます。
他にもよいやり方をご存知の方はお知らせ下さい。

### Module::Build のタスクとして実行する

下記を参照下さい:
[(メモ) Module::Build による Perl ドキュメント生成 - weblog of key_amb](http://keyamb.hatenablog.com/entry/2015/03/09/030039)

### Daiku を使う

[Daiku](https://github.com/tokuhirom/Daiku) は Ruby の Rake にインスパイアされて作られた Perl 用のビルドツールです。
Rake の RDoc::Task のように、簡単にドキュメントを生成できる方法があるかはわかりませんが、Rake のようなインタフェースを持ち、任意コマンドも実行できるので、やってやれないことはなさそうです。
また、Daikufile(Makefile や Rake の Rakefile 相当)には Perl のコードが記述できるので、POD との相性はよさそうです。

## まとめ

Perl プロジェクトのソースコードから、GNU make を使ってドキュメントを生成する方法を紹介しました。

## 参考

- GNU make について
  - [GNU make: Top](http://www.gnu.org/software/make/manual/html_node/index.html)
  - [GNU make 日本語訳(Coop編) - 目次](http://www.ecoop.net/coop/translated/GNUMake3.77/make_toc.jp.html)
defstructに関するメモ

# はじめに
　最近「ANSI Common Lisp　ポール・グレアム著」を読んでいます.この本で構造体について学習したことをメモしておきます.

# 表示関数を自分で定義
　**defstruct** を使用して構造体を定義する際に,構造体の内容をどのように表示するかを定義した関数を引数に渡すことにより,構造体の内容の表示方法を任意に指定することができます.これを省略すると構造体の内容は,デフォルトの表示方法で表示されます.下のコードによって違いを示します.

```cl
;;; デフォルトの表示
(defstruct human
  (height 0)
  (weight 0))

(make-human :height 160 :weight 40) ;=> #S(HUMAN :HEIGHT 160 :WEIGHT 40)

;;; 自分で定義
;; humanという構造体を重複して定義することによって引き起こるエラーを防ぐための処理
(unintern 'human)						

(defstruct (human (:print-function print-human))
  (height 0)
  (weight 0))

(defun print-human (human stream depth)
  ;; #< マクロで始まるものは,readで読み込むとエラーになる.
  (format stream "#<~Acm, ~Akg>" (human-height human) (human-weight human)))

(make-human :height 160 :weight 40) ;=> #<160cm, 40kg>
```

　このコードにある **print-human** という関数により,表示方法を任意に指定することが可能になります.ですが **depth** という引数を使用していないので定義するときに警告が出ます.これを防ぐための方法としてまず考えることができるのは, **depth** という変数を使用しないと宣言することです.コードを下に示します.

```cl
(defun print-human (human stream depth)
  (declare (ignore depth))
  (format stream "#<~Acm, ~Akg>" (human-height human) (human-weight human)))
```

　ですがこれを毎回書くのは面倒です.そういった時には **defstruct** のキーワード引数 **:print-function** の代わりに, **:print-object** を使うといいみたいです.コードを下に示します.

```cl
(defstruct (human (:print-object print-human))
  (height 0)
  (weight 0))

(defun print-human (human stream)
  (format stream "#<~Acm, ~Akg>" (human-height human) (human-weight human)))

(make-human :height 160 :weight 40) ;=> #<160cm, 40kg>

```

# 補足
　コード中に **#<** という **read** で読み込まれるとエラーになるマクロが出てきました.こういった形式で表示するために **print-unreadable-object** というマクロがあるようです.先程の **print-human** をこのマクロを使って書き換えてみます.

```cl
(defun print-human (human stream)
  (print-unreadable-object (human stream)
	(format stream "~Acm, ~Akg" (human-height human) (human-weight human))))
```
SE教育の記録#1


###記述する動機
私、とある専門学校でPGを教えています。はや８年。
いまだにSEもやってます。
学生さんたちに読んでもらうために書いているのですが、悩めるプログラマ、悩めるSE、悩める教育関係者にも何かのヒントにはなると思い、公開していきたいと思います。全て実例です。個人名は秘密！！

###SE教育
これで何回目になるのだろう。
今回は、国の仕組みでJavaは勉強したということです。
実に疑わしい。

###スタート時点
８名
ボギャブラリ無さ過ぎ。
サーバーやってない。
フロントやってない。
SQL全然知らない。
Linux知らない。
うん。予想を超えてます。

###予測
最大４割なので、３人がSE合格ライン。
PGとしては、＋２名
何とかしてあげたいな。

###設計から
基本要件はできてるので、コンバートで実践。
明日から泣いていただいます。
Apple Watch / Watch Kitで現時点できないことまとめ

Apple Watchが発表される前に現時点(3/9時点)でできないことの整理をしておきたいと思います。
開発の前に「できないこと」を知っておくことで、何が作れるのかより考えやすくなるのではないかと思います。

###1. マップは動かせない（スクロールできない）、GPS非搭載（表示のみ、ピンは刺せる）
意外にも、マップ機能はまだそこまで充実していません。マップの上下左右にボタンを設置してあたかもスクロールできるかのようにしたアプリはあります。
![スクリーンショット 2015-03-10 1.42.40.png](https://qiita-image-store.s3.amazonaws.com/0/44837/1aa13bc7-3b9b-0424-ca68-093475d09ada.png)

###2. viewを自由にいじれない（objectの追加・順番変更・削除=絶対値配置ができない）
文字にすると少し分かりづらいですが、Watch Kitではプログラムからviewをaddすることができません。常にストーリーボードとプログラムをセットで動かす必要があります。この辺は割とすぐ変わってくれそうな気がしていますが。
![スクリーンショット 2015-03-10 1.30.11.png](https://qiita-image-store.s3.amazonaws.com/0/44837/7bafd655-2289-ef5a-4030-c85730efe235.png)


###3. AppleWatchからiPhoneのアプリを起動させられない
iPhoneと連携させたアプリを作るときは直接ではなく、サーバを介したり、App Groupを利用することで連携はできます。

###4. バックグラウンド処理はサポートされていない
バックグラウンドで動くような処理・動作が重い処理はWatch Kitでは実行できません。

###5. 心拍数等のセンサー値は直接取れない
<a href="http://qiita.com/TECHFUND/items/dddaeb8616b053d568be">こちら</a>にも書きましたが、センサー値を取るには一度iPhone側のHelth Kitと通信をする必要があります。この辺は早いところ直接取れるようになってほしいですね。Appleさん、お願いします。![949c68cc-f188-b804-349d-226c7efb0fcc.png](https://qiita-image-store.s3.amazonaws.com/0/44837/5694f3a5-502c-943d-703c-b79888c3dc04.png)


###6. キーボードが無い
簡単な応答（スタンプのようなUI）やSiriの利用をApple側も推奨しています。
![スクリーンショット 2015-03-10 1.31.11.png](https://qiita-image-store.s3.amazonaws.com/0/44837/b512ade6-f069-5455-08dc-2f45a4c15265.png)
この辺は新しいUIの提案で解決していきたいポイントですね。
![スクリーンショット 2015-03-10 1.42.02.png](https://qiita-image-store.s3.amazonaws.com/0/44837/fcb366f5-1861-147e-7c41-f868876f7c80.png)

###7. 動画は非対応
パラパラマンガのように写真を繋ぎ合わせて動画のようにすることは可能です。

###8. Digital Crownの処理はできない
公式アプリでは使えるようですが、まだAPIがありません。

###9. 音の操作はできない
アラート音、通知音を含む音楽を鳴らすことができません。


公式アプリではできることも多いので、上記もすぐ対応される可能性はあります。Appleさんのアップデートに期待しましょう。
以上、参考になれば幸いです。
GASを使って管理画面の情報を非エンジニアが編集出来るようにする


GoogleSpreadSheet+GoogleAppsScriptで簡単な管理画面代わりのものが作れをますよ、そして便利でしたよっていうお話。
たいした話じゃないけど、もし同じような悩みを持ってる人がいれば参考にしてください。


## 何に困っていたか？
 + たまに修正が入るようなエクセルで管理された情報を画面に表示させたい。
 + その修正がある度に、該当の部署から更新依頼。
 + 量的にはDBにテーブルを作る程ではない、でも毎回手動で書き換えるとちょっとだけ面倒。
 + 手動で書き換えるとたまにエラーになることも。（更新作業のミス）
 + かと言ってやっぱりテーブルは作りたくない。（たまにカラムの変更もあるし）

## どういう運用をしていたか？
 + 定期的にCSVをアップロードしてもらってそれを表示
 + もしくはDBにテーブルを作って、管理画面も作ってそこから更新

## どういう方向性で解決したかったか？
 + ミス+時間ロスに繋がるので手動で修正自体のフローをやめる
 + 部署間のやり取りを減らすために極力該当部署が直接編集できるようにする
 + DBにテーブルは作らない。
 + 極力管理画面とか作らない。

## どう解決したか？
 + GoogleSpreadSheetの情報をJSON形式で返してきて、それを画面上に表示させる。

例えば以下のようなGoogleSSを作っておき、ログインしてるユーザ毎に該当するIDの行があればそのタイトルと内容をJSONで返して表示してあげる、みたいなイメージです。

| id |  title | content |
|:-----------|:------------|:------------|
| 1     | 今日の天気 | 今日は晴れです  |
| 2     | 今日の運勢 | 今日は大吉です  |
| 3     | 今日の天気 | 今日は大雨が降るので傘を忘れずに  |
| 4     | ラッキーカラー | 青があなたの運命を変えるかも |
| 5     | ラッキーアイテム | 今日は漫画を持ち歩くと運勢UP  |

## ソースコード

#### GoogleAppsScript
今回のメインとなる部分ですが、ググったら[この方のブログ](http://daichan4649.hatenablog.jp/entry/2014/02/08/160453)で全部事足りました。
ブックのURLとシート名を自分の情報と合わせればコピペで動きました。
なのでコードは割愛させて頂きます。

#### サーバーサイド
GASは便利ですがレスポンスが遅かったり、仮に落ちたり（Googleなのであまりないとは思うが）した場合にこちらでは何も出来なくなってしまいます。
なので僕は今回は日次でサーバー側に一度キャッシュさせておき、それを画面上に表示するという方法にしました。といってもたいしたことはしてませんが参考までに。

```ruby
  def user_data_cache
    con_result = open("GASで動かしてるWebアプリのアドレス")
    raise HTTPStatusError unless con_result.status[0] == '200'
    result_json =  con_result.read
    Rails.cache.write("key", result_json)
  end
```

## 最後に
割と便利です。
スプレッドシートで管理してるデータは少なくないので、他にも色々生かせそうな気がしています。
ClusterHQのFlockerのチュートリアルを試してみた

[GCEのライブマイグレーションのすごさをまとめてみた](http://qiita.com/kazunori279/items/41520689337a644a87b4)を見て、Dockerにもライブマイグレーションのツールないのかな？と思って調べてみたらClusterHQの[Flocker](https://clusterhq.com/)があるのを知りました。チュートリアルが簡単に試せたので、これはその感想です。

## チュートリアルの実行方法
[Getting Started](https://docs.clusterhq.com/en/0.3.2/gettingstarted/)の通りに試せば、ライブマイグレーションを体験できます。一応手順をまとめると以下のような流れです。

1. Flocker CLIをインストールする
2. VagrantとVirtualBoxを使ってFlocker clusterがセットアップされたVMを起動
3. チュートリアルアプリのリポジトリをクローン。このアプリはfig
4. flocker-deployコマンドでデプロイ(deployment-node1.ymlの設定を仕様、webとredisが同じnode上で実行)。アクセスカウンタが表示されるwebアプリが表示されます。![counterapp.png](https://qiita-image-store.s3.amazonaws.com/0/18519/92867e9c-4bd8-afd7-529e-a6977420c054.png)

5. flocker-deployコマンドでredisのサービスを別ノードにライブマイグレーション。4でカウントされたカウンタがそのまま継続することを確認できます。

## Flockerの感想
手元で試したところ、5でマイグレーションを実行した時に、3秒ほどwebアプリにアクセスしてもエラーが表示される瞬間がありました。GCEのライブマイグレーションは0.5secで完了して、パケットロスなどもないとのことだったので、現時点ではだいぶ差がある気がします。まだClusterHQ社もFlockerのバージョンも若いので今後に期待したいです。
mplayer でバイナリを聴く

こういうことをやろうという話です。

<blockquote class="twitter-tweet" lang="ja"><p>windows の主要ファイルを wav として直接再生し鑑賞するジャンルがあると知る。どの exe の何分何秒あたりが素敵だとか議論しててついていけないと思った。&#10;でも shell32.dll の 8:12 からの展開は結構好き。<a href="https://t.co/TfeAjPsotN">https://t.co/TfeAjPsotN</a></p>&mdash; yosshin (@yosshin4004) <a href="https://twitter.com/yosshin4004/status/574600436595884032">2015, 3月 8</a></blockquote>

mplayer は raw audio (ヘッダも何もないただデータだけの音声ファイル) を扱えるので、コマンドラインだけで雑にあらゆるファイルを音声として再生できます。

```
mplayer -rawaudio samplesize=2:channels=2:rate=48000 -demuxer rawaudio <filename>
```

という感じでファイルを与えてやると再生が始まります。

与えるファイルは何でも良いので、当然 `/dev/random` とかも再生できます。
メインスレッドはキャンセルできない

メインスレッドのcancelメソッドは**効かない**ようだ。

```objc
NSLog(@"main thread isCancelled 1:%d", [[NSThread mainThread] isCancelled]);
[[NSThread mainThread] cancel];
NSLog(@"main thread isCancelled 2:%d", [[NSThread mainThread] isCancelled]);
```
の結果

```
main thread isCancelled 1:0
main thread isCancelled 2:0
```

---

サブスレッドにて

```objc
NSLog(@"sub thread isCancelled 1:%d", [[NSThread currentThread] isCancelled]);
[[NSThread currentThread] cancel];
NSLog(@"sub thread isCancelled 2:%d", [[NSThread currentThread] isCancelled]);
```
の結果は、当然こうなる

```
sub thread isCancelled 1:0
sub thread isCancelled 2:1
```
Go入門 vol.3 〜Go言語の基本文法（if、for、switch）〜

## はじめに

Go 言語に入門します。第 3 回目になります。
今日もひたすら写経です。

教材などについての説明は、
下記リンクの中の Go 入門の vol.1 をご参照くださいね。

### Go入門リンク

* [Go入門 vol.1 〜Go言語の特徴〜 - Qiita](http://qiita.com/megu_ma/items/6fad257345af2d748dbe "Go入門 vol.1 〜Go言語の特徴〜 - Qiita")

* [Go入門 vol.2 〜Go言語の基本文法（main パッケージ、インポート、組込み型、変数）〜 - Qiita](http://qiita.com/megu_ma/items/f5e66293b2934e117731 "Go入門 vol.2 〜Go言語の基本文法（main パッケージ、インポート、組込み型、変数）〜 - Qiita")


## 学習内容

今回は、前回に引き続き

Go言語の基本文法（if、for、switch）

について、簡単にまとめていきたいと思います。

## Go言語の基本文法

### if

Go では、if 文の条件部に丸括弧は必要ありません。

```go:
func main() {
	a, b := 10, 100
	if a > b {
		fmt.Println("a is larger than b")
	} else if a < b {
		fmt.Println("a is smaller than b")
	} else {
		fmt.Println("a equals b")
	}
	// 1行による波カッコ省略不可！
	// 三項演算子もなし！
}
```

言語によっては、if 文の処理が 1 行の場合に波括弧を省略できる場合がありますが、
Go ではそうした省略はコンパイルエラーになります。

また、三項演算子はありません。if/else 文を使用します。

### for

Go の for 文では、C や Java では必要な条件部の丸括弧が必要ありません。

```go:
func main() {
	for i := 0; i < 10; i++ {
		fmt.Println(i)
	}
	// While文もなし！
	// すべてfor文でかくべし！
}
```

Go で繰り返しを表現する方法は for 文のみです。

ほかの言語における while 文や do/while 文、loop 文といったような表現は、
すべて for 文を用いて行います。

#### while も for で

たとえば C の while 文は、 for 文で次のように表現します。

```go:
func main() {
	// C
	//	int n = 0;
	//	while (n < 10) {
	//		printf("n = %d\n", n);
	//		n++;
	//	}

	// Go
	n := 0
	for n < 10 {
		fmt.Printf("n = %d\n", n)
		n++
	}
}
```

#### 無限ループ

C の場合、 for 文を使って次のように無限ループを表現します。

```go:
func main() {
	// C
	//	for (;;) {
	//		doSomething();
	//	}

	// Go
	for {
		doSomething()
	}
	// for文の条件部を省略することで表現できる！
}
```

Go では、 for 文の条件部を省略することで同様の表現ができます。

#### break, continue

繰り返し制御には C や Java と同様に、

* ループを終了する break
* ループの最初から処理を再開する continue

を使用できます。

```go:
func main() {
	n := 0
	for {
		n++
		if n > 10 {
			break // ループを抜ける
		}
		if n%2 == 0 {
			continue // 偶数なら次の繰り返しに移る
		}
		fmt.Println(n) // 奇数のみ表示
	}
}
```

### swich

if/else 文が繰り返す場合は、switch 文を用いたほうがスッキリ書ける場合があります。
Go の switch 文は非常に柔軟であり、値の比較だけでなく条件分岐にも使用できます。

#### 値での分岐

まず、値を用いた switch 文は次のようになります。

```go:
func main() {
	n := 10
	switch n {
	case 15:
		fmt.Println("FizzBuzz")
	case 5, 10:
		fmt.Println("Buzz")
	case 3, 6, 9:
		fmt.Println("Fizz")
	default:
		fmt.Println(n)
	}
}
```

* switch 文に指定した値に一致する case が実行される
* どの case にも一致しなかった場合は default が実行される
* case には単一の値だけでなく、カンマで区切った値も指定できる

#### fallthrough

C や Java などの switch 文は、 1 つの case が実行されると
その次の case に処理が移るため、単一の case の実行で終わらせたい場合に、
case ごとに break を書く必要がありました。

しかし、 Go の switch 文では、
case が 1 つ実行されると次の case に実行が移ることなく switch 文が終了するため、
break をいちいち書く必要はありません。

ただ、case の処理が終わったあとに、次の case に処理を進めたい場合もあります。
そうした場合は、case 内に `fallthrough` を書くことで、
明示的に次の case に処理を進めることができます。

```go:
func main() {
	n := 3
	switch n {
	case 3:
		n = n - 1
		fallthrough
	case 2:
		n = n - 1
		fallthrough
	case 1:
		n = n - 1
		fmt.Println(n) // 0
	}
}
```

#### 式での分岐

Go の switch 文では、case に値だけでなく式も指定できます。

```go:
func main() {
	n := 10
	switch {
	case n%15 == 0:
		fmt.Println("FizzBuzz")
	case n%5 == 0:
		fmt.Println("Buzz")
	case n%3 == 0:
		fmt.Println("Fizz")
	default:
		fmt.Println(n)
	}
}
```

たとえば上記のように case に式を指定すれば、
評価結果が true になる case が実行でき、if/else 文の代わりに使用できます。


以上、おわり。
自作Frameworkをプロジェクトに含め、直接実行する場合の設定(Runpath Search Paths)

自作Frameworkをプロジェクトに含めた時、
デバッグ実行は問題ないけど、直接実行した際に以下のようなエラーとなることがある。

```
Dyld Error Message:
  Library not loaded: @rpath/MyLibrary.framework/Versions/A/MyLibrary
```
```
dyld: Library not loaded: @rpath/MyLibrary.framework/Versions/A/MyLibrary
```

---

こういった場合、プロジェクト設定の「Build Settings」－「Linking」－「Runpath Search Paths」を追加すればいい。

Cocoa Application なら
`@executable_path/../../..`

Command Line Tools なら
`@executable_path`
Unity 4.6.1 から Unity 5.0.0 へ Upgrade後にしたこと

Unity 5がリリースされました
さっそく個人で作成しているゲームのプロジェクトを5.0.0で開いてみることにしました
すると...?



# Unity 4.6.1 から Unity 5.0.0 へ Upgrade後にしたこと

4.6.1で作成していたプロジェクトを意気揚々とインストールしたての5.0.0で開こうとすると、こんなウィンドウが。

![unity5_upgrade.png](https://qiita-image-store.s3.amazonaws.com/0/62924/a54dfb7d-e74d-1491-1a0e-881754c312d1.png)

要するに、「君のコードを5.0.0用にアップグレードしてあげるよ！」ということらしいです。
「〜. Go Ahead!」を押してアップグレード。

この結果、主に二つの出来事が起こりました。
そのことについて軽く書きたいと思います。


## 既存コードの置き換え

Unity5 betaでは当たり前のようでしたが、

```csharp
rigidbody2D.velocity = direction * speed;
```

このような呼び出しは廃止されたようです。

```csharp
GetComponent<Rigidbody2D>().velocity = direction * speed;
```

このように、直接rigidbody2Dにアクセスせずに、GetComponentでコンポーネントを取る必要があるそうです。
コンポーネント全般に言えることのようです。
例えば、audioやparticleSystemもGetComponent呼び出しに変わっていました。

この置き換えをUnity5さんが勝手にやってくれていました。
この部分は、既存の動作に全く影響を与えませんでした。


## RigidBody2Dが動かなくなった？

インパクトがでかかったのはこっちです。
RigidBody2Dのvelocityを使っている処理の"一部"が動かなくなってしまいました。
ちゃんと該当のvelocityには値が入っているようなのに、止まったままぴくりとも動きません。

未熟な自分は原因にたどり着くことはできませんでしたが、もとの動作に戻すことはできました。
結局やったこととしては、**「全く同じプレハブをもう一度１から作り直す」**でした。

<font color="red">※2015/03/23追記</font>
deyu_noteさんのご指摘より、該当オブジェクトにおけるAnimatorコンポーネントの「Apply Root motion」のチェックが変換時にオンになってしまっていたことが原因であることがわかりました。

バージョンアップ時の変換によって上記のような挙動になってしまった場合、「Apply Root motion」のチェックを外してみましょう。
deyu_noteさん、ご指摘ありがとうございました！

~~なぜこれで上手くいったのかはさっぱりわかりませんが、同じ問題を抱えている人が一人でもこの記事で救われるとうれしいです。~~

~~ちなみに、自分が調べてわかったことを一応残しておきます~~

~~* RigidBody2DがアタッチされているプレハブからRigidBody2Dを削除、再びアタッチしてもダメ~~
~~* velocityにはちゃんと値が入っている~~
~~* ちゃんと動いているものもある（動くのとそうでないもののプレハブの差異はわかりませんでした...）~~

こんなのに遭遇したのは自分だけなんですかねぇ...
だれかの助けになれば幸いです

では良いUnity5ライフを〜
Cocoa Frameworkでクラスを公開する方法

クラスを公開する場合、以下の２つの設定が必要。

1. プロジェクトにデフォルトで付いてくるヘッダーに公開するヘッダーをimportする。

```objc:MyLibrary.h
#import <MyLibrary.h/MyLibClass.h>
```

2.プロジェクトの設定－「Build Phases」－「Headers」の「Public」に公開するヘッダーを設定する。
singleTask/singleInstanceなActivityで、2つの別インスタンスが共存してしまうケース

launchModeが`singleTask`や`singleInstance`であるActivityのインスタンスを、完全なsingletonのつもりで設計していたら、えらくハマったのでメモまで。

要は、singleTask / singleInstanceなActivityで`finish()`メソッドを呼んだ後に、自分自身を再起動すると、別々のインスタンスで共存する区間ができてしまう。


## (おさらい1) 通常のActivity遷移

Activity **A** からActivity __B__ を`startActivity()`で起動する場合。
ActivityのlaunchModeは`standard`であるとしておく。

このとき、Activityのライフサイクルにまつわるメソッドは以下のような順序で呼ばれる。

* **A** から __B__ をstartActivity()
* **A**: onPause() ※1
* __B__: onCreate()
* __B__: onStart()
* __B__: onResume()
* **A**: onStop() ※2

ポイントは2箇所。

* ※1 起動元 **A** の `onPause()` 処理が終わらないと、起動先の __B__ の `onCreate()` は呼ばれない
* ※2 起動元 **A** の `onStop()` や `onDestroy()` は、起動先の __B__ の `onResume()` の後に呼ばれる模様。
ただし、**A** のonStop()やonDestroy() は状況によってはそもそも呼ばれないことがある。(Aの画面が隠れず見えている場合など)

※1については、気にしている人が少ないようで、onPause()で重い処理を書いてしまうと、画面遷移における速度低下の原因になってしまう。

* 参考
    * [Activityのライフサイクルに関する間違い](http://tech.cm55.com/wiki/Android/Activity)


## (おさらい2) singleTask / singleInstance な Activityの再起動

launchModeが`singleTask`もしくは`singleInstance`であるActivity **A** について、**A** から **A** を起動(再起動)する。

「同じActivityに再起動させることなんてあるのか」と突っ込まれそうだが、起動引数に応じて画面の表示内容を更新する場合などに利用できる。

このとき、Activityのライフサイクルにまつわるメソッドは以下のような順序で呼ばれる。

* **A** から **A** をstartActivity()
* **A**: onPause()
* **A**: onNewIntent()
* **B**: onResume()

ポイントは、`singleTask`や`singleInstance`の場合は、起動元と同じActivityインスタンスが呼び出される。
そのため、`onCreate()` は呼ばれず、代わりに `onNewIntent()`で再起動時に指定するIntentが渡される。


## (本題) 別々のActivityインスタンスが共存するケース

上記の __(おさらい2)__ とほとんど同じだが、`singleTask`もしくは`singleInstance`の Activity **A** について、 **A** から **A** を起動 (再起動) する。 ただし、再起動前に、自分自身を終了させるため `finish()` メソッドを実行する。

例えば、以下のような感じ。

```java:MainActivity.java
     : (略)

    ((Button) findViewById(R.id.button))
            .setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 一旦、自分自身を終了してから、
                finish();

                // 続けて、自分自身を起動する。
                Intent i = new Intent(MainActivity.this, MainActivity.class);
                startActivity(i);
            }
        });

     : (略)
```

このとき、Activityのライフサイクルにまつわるメソッドは以下のような順序で呼ばれる。

* **A**をfinish()し、続けて **A** から **A** をstartActivity()
* **A**: onPause()
* **A'**: onCreate()  -- (1)
* **A'**: onStart()
* **A'**: onResume()
* **A**: onStop()
* **A**: onDestroy()  -- (2)

ここで **A'** はActivity **A** とは別に生成されるActivityインスタンス。
上記のとおり、(1) から (2) の間は、`singleTask` / `singleInstance` であるActivityのインスタンスが2個共存することになり、こうしたActivityのインスタンスはVM上で完全なsingletonではないことが分かる。

共存区間(1)-(2)は刹那なため、実影響は少ないように思えるが、自身のハマりケースの場合、Activityとは別のアプリコンポーネントの状態制御をonPause()やonDestroy()などのメソッドをトリガーに行うよう設計していて(設計されていて)、どハマりした。上記のように、`finish()`される **A** インスタンスの onDestroy() が最後っ屁のように実行されてしまうため、意図しない終了処理が実行されてしまう。

また余談だが、`finish()` メソッドもかなりのクセもの。

Activityの `onDestory()` が確実にCallされる目的とかで、開発終盤のバグFixフェイズにしれっとまぎれてくることがあるが、Activityのライフサイクルの見通しを悪くしてしまうので、多用を避けることをお勧めしたい。
AWS EC2 Amazon Linuxインスタンス セキュリティ関連モジュールの自動アップデート


yum-cron-securityパッケージをインストールすると、crondが日々自動でセキュリティ関連アップデートパッケージのチェックを行い、アップデートがあった際には、自動でパッケージのアップデートをすることができます。

# yum-cron-securityのインストール

```bash:yum-cron-securityのインストール
$ sudo yum install yum-cron-security -y
```

yum-cronパッケージがインストールされていない場合は、合わせてyum-cronが自動でインストールされます。


# yum-cronの起動

yum-cronが起動されていない場合は起動します。

`service yum-cron status`で、yum-cronの起動状態を確認できます。

```bash:yum-cronが起動されている場合
$ service yum-cron status
Scheduled yum updates are enabled.
```

```bash:yum-cronが起動されていない場合
$ service yum-cron status
Scheduled yum updates are disabled.
```

yum-cronが起動されていない場合は、yum-cronを起動します。

```yum-cronの起動
$ sudo service yum-cron start
```

インスタンスの起動時に自動でyum-cronサービスが起動するように設定しておきます。

```bash:インスタンスの起動時に自動でyum-cronサービス起動するように設定
$ sudo chkconfig yum-cron on
Enabling scheduled yum updates:                            [  OK  ]
```

```bash:自動サービス起動設定確認
$ chkconfig --list yum-cron
yum-cron 0:off 1:off 2:on 3:on 4:on 5:on 6:off
```

# アップデート通知先の設定

`/etc/yum/yum-cron-security.conf`を編集し、アップデートがあった際のメール通知先の設定をします。
デフォルトでは、localhostのrootユーザ宛にメールが届くように設定がされています。

```bash:/etc/yum/yum-cron-security.confの編集
$ sudo vi /etc/yum/yum-cron-security.conf
```

```text:/etc/yum/yum-cron-security.confのデフォルト設定
[email]
# The address to send email messages from.
email_from = root@localhost

# List of addresses to send messages to.
email_to = root
```

自分のメールアドレス宛にメールが届くように設定しましょう。

```text:自分のメールアドレス宛にメールが届くように設定
[email]
# The address to send email messages from.
email_from = yum-cron-security@xxxxxx.com

# List of addresses to send messages to.
email_to = user@xxxxxx.com
```

アップデートがあった際には以下のようなメールが届きます。

```text:メール
Subject: Yum: Updates installed on ip-xx-xx-xx-xx
From: yum-cron-security@xxxxxx.com
To: user@xxxxxx.com

The following updates will be applied on ip-xx-xx-xx-xx:
================================================================================
 Package            Arch       Version                  Repository         Size
================================================================================
Installing:
 kernel             x86_64     3.14.34-27.48.amzn1      amzn-updates       16 M
Updating:
 kernel-headers     x86_64     3.14.34-27.48.amzn1      amzn-updates      965 k
Removing:
 kernel             x86_64     3.14.27-25.47.amzn1      @amzn-updates      67 M

Transaction Summary
================================================================================
Install  1 Package
Upgrade  1 Package
Remove   1 Package
The updates were successfully applied
```

以上です。
【c++】enum struct(class)とは

<a href="http://blog.dalt.me/1071">元ブログ</a>

c++でenumを宣言する際に以下の様な宣言を見たことはないですか？

```cpp
// どこかのheaderファイル
enum struct HogeEnum
{
  FAILURE,
  SUCCESS,
};
```

※structはclassにもなり得る

このstructとかclassって何なんだろう？と言う疑問があり調べてみました。

## struct(class)の二つの意味

結論、二つの意味がありそうでした。
<em>
・異なるenum値で同じ列挙子を用いる事を可能にする
・int値との違いを明確なものにする
</em>

## 少し解説

※参考
<a href="http://www.amazon.co.jp/gp/product/4797375957/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=4797375957&linkCode=as2&tag=dalt1003-22">プログラミング言語C++第4版</a><img src="http://ir-jp.amazon-adsystem.com/e/ir?t=dalt1003-22&l=as2&o=9&a=4797375957" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />

以下の様なコードはコンパイルは通るでしょうか？

```cpp

// Test.h
enum Color
{
    RED,
    BLUE,
    PURPLE,
};
enum TrafficLight
{
    RED,
    YELLOG,
    GREEN
};

// Test.cpp
Color c_red = Color::RED;
TrafficLight t_red = TrafficLight::RED;
```

まぁ、流れ的に分かりそうですがこれは通りません。

<a href="http://blog.dalt.me/wp-content/uploads/2015/03/スクリーンショット-2015-03-09-17.12.27.png"><img src="http://blog.dalt.me/wp-content/uploads/2015/03/スクリーンショット-2015-03-09-17.12.27.png" alt="redefinition_enum_red" width="328" height="174" class="alignleft size-full wp-image-1087" float="left"/></a><br clear="left">

では、どうすれば通るのでしょうか？

## 同名の列挙子を用いる事を可能にする

以下の様に変更すると通ります。(c++11以降 [thanks for 7of9さん])

```cpp

enum struct Color
{
    RED,
    BLUE,
    PURPLE,
};
enum struct TrafficLight
{
    RED,
    YELLOG,
    GREEN
};
```

structを追加しました。
※classでも通ります。
※両方にstructを追加していますが片方だけ追加するだけで通ります。

structを追加したことにより、各列挙子のスコープが明確なものになり、ビルドが通るようになりました。

## intとの相互変換

structを加えなければ実はそのまま代入が出来ます。

```cpp

int red = Color::RED;
```
の具合ですね。

structがある場合は以下の形で相互に変換出来ます。

#### int => enum値
```cpp
Color enumColorRed = static_cast<Color>(0);
```

#### enum値 => int
```cpp

int intColorRed = static_cast<int>(Color::RED);
```
コマンドラインのSubversionでsvn+ssh接続する方法 windows

公開鍵などを使わず、ユーザー名とパスワードでsvn+ssh接続する方法です。
日本語情報が少なくて苦戦しましたのでメモしておきます。windowsです。

##■そのままやったらエラー出ました

なんの準備もせずにsvn list svn+ssh://~
というようなsvn+sshを含むコマンドを実行すると、

```
svn: E170012: Unable to connect to a repository at URL 'svn+ssh://~'
svn: E170012: トンネルを作成できません
svn: E720087: トンネルを作成できません: パラメーターが間違っています。
```

このようなエラーが出てコマンドを実行することが出来ませんでした。
しかし、以下の手順を踏むことでエラーを回避することが出来ました。

##■１．PuTTYをインストールする

>http://webkaru.net/linux/putty-install/

こちらのサイトを参考にさせて頂きました。
普通のインストーラーで普通にインストールして下さい。

##■２．環境変数SVN_SSHにplink.exeを設定する
環境変数SVN_SSHに、先ほどインストールしたPuTTYのplink.exeまでのパスと、ユーザー名とパスワードを登録します。
↓こんな感じです。

```
set SVN_SSH=C:/Program Files (x86)/PuTTY/plink.exe -l [ユーザー名] -pw [パスワード]
```

[ユーザー名]と[パスワード]にそれぞれの値を入れて下さい。
※パスの区切り記号は[￥]ではなく[／]を使用して下さい。でないとうまく動きません。

##■３．svn+sshを含むコマンドを実行する

以上でうまくいくはずです。
ただし、setコマンドでSVN_SSHをセットした場合、コマンドプロンプトを一度閉じると
またSVN_SSHをセットし直さなければいけないので、windowsの環境変数ダイアログから登録しておいた方が便利かも
しれませんね。

以上です。
関数もアプリカティブ

学習の素材は、
[すごいHaskellたのしく学ぼう!](http://www.amazon.co.jp/すごいHaskellたのしく学ぼう-Miran-Lipovača/dp/4274068854)

> 今回は、教材に載っていない自分の意見・考えが多い為、番外扱いとしています。

## 関数もアプリカティブ
関数 `(->) r` もアプリカティブであり、[インスタンス宣言されている](http://hackage.haskell.org/package/base-4.7.0.2/docs/src/Control-Applicative.html#pure)。

```hs 
instance Applicative ((->) a) where
    pure = const
    (<*>) f g x = f x (g x)
```
 `const` は一つ目の引数で与えられた値を必ず返す関数。 よって、 ` pure 1` が返す関数は、どんな引数を取っても1を返す。


## 関数をアプリカティブファンクターのインスタンスとして考える
おさらいとして、アプリカティブファンクターの型クラス定義は次のようになっている。

```hs
class Functor f => Applicative (f :: * -> *) where
  pure :: a -> f a
  (<*>) :: f (a -> b) -> f a -> f b
```
なので、関数に特殊化すると `pure` 、 `<*>` はそれぞれ次のように書ける。

```hs
  pure :: a -> (r -> a)
  (<*>) :: (r -> (a -> b)) -> (r -> a) -> (r -> b)
```

関数の場合、アプリカティブ値の中身とはなんぞやということになるのだが、ここでは **関数の計算結果** を指すのだろう。よって、関数の計算結果を、与えられた関数で写すことになる。写された中身が最終的に値になるには、`r`型の引数が必要になる。

## 関数に対して、続けざまにアプリカティブ値の中の関数を適用する
 
例として 次のコードは、`508` を返す。

```hs
(+) <$> (+3) <*> (*100) $ 5 --508
```

インスタンス宣言の定義にある`(<*>) f g x = f x (g x)` それぞれをに当てはめてみると、

```hs
(\a -> (+) ((+3) a)) 5 ((\b -> (*100) b) 5)
```

ということになる。


> `(+) <$> (+3)` は `fmap (+) (+3)` であり、`\x -> (+) ((+3) x)` となる。
 
アプリカティブな関数のインスタンスが何をやっているかを、変形後の式から読み解いてみると・・。

1. まず左辺は、**引数をとって、引数に３を加算した結果を左辺に持つセクションを返す(`Num a => a -> a -> a`)**。
2. 次に右辺。こちらは、**単純に引数を100倍して返す関数を返す(`Num a => a -> a`)**。
3. `<*>` は、この左辺の最初の引数と、右辺の引数に5を与える。すると、それぞれセクション(  `(+8)` )と値(`500`）になる。このセクションが値に適用され、`508` が求まる。

## まとめ
インスタンス宣言だけ見ても意味を取ることが難しいが、`Applicative` 型クラス定義を関数に特殊化して具体化していくと、何をやっているかがつかめてくる。また、`<*>` は関数合成 `(.) :: (b -> c) -> (a -> b) -> a -> c` と少し似ているが、左辺が２引数関数である点が異なっていて、結果も変わってくる。
アプリカティブな関数が何の役に立つのか学習教材の中でも明確に書かれていないものの、アプリカティブな関数のインスタンス `(->) r` が面白いことはわかった。
PowerShellで複数のExcelファイルを一括検索する

500本あるExcelの設計書の中から「ほげほげ」が書いてあるところを全部探さないといけなくなった。。。
そんな時に！

いろいろと応用も効くと思います！

```SrchExcel.ps1
Param(${dir}="", ${word}="")

if (${dir} -eq "") {
    ${dir} = Split-Path $myInvocation.MyCommand.Path -Parent
}

if (${word} -eq "") {
    echo "キーワードが指定されていません。"
    return
}

echo "Dir : ${dir}"
echo "Keyword : ${word}"

${excel} = New-Object -ComObject Excel.Application

Get-ChildItem "${dir}" -Include "*.xlsx","*.xls","*.xlt" -Recurse -Name | % {
    ${childPath} = $_
    ${wb} = ${excel}.Workbooks.Open("${dir}\${childPath}")
    ${wb}.Worksheets | % {
        ${ws} = $_
        ${wsName} = ${ws}.Name
        ${first} = ${result} = ${ws}.Cells.Find(${word})
        while (${result} -ne $null) {
            echo "${childPath}[${wsName}][$(${result}.Row), $(${result}.Column)] : $(${result}.Text)"
            ${result} = ${ws}.Cells.FindNext(${result})
            if (${result}.Address() -eq ${first}.Address()) {
                break
            }
        }
    }
    ${wb}.Close(0)
}

${excel}.Quit()

${ws} = $null
${wb} = $null
${excel} = $null
    [System.GC]::Collect([System.GC]::MaxGeneration)
```
海の向こうにあるZabbixサーバの表示をWebサーバのチューニングだけで高速化する


海外で展開しているサービスがある関係上各サーバの監視に利用しているZabbixサーバも海外にあるのですが、ほとんどチューニングされておらず、ZabbixのWebUIの画面をロードするのが遅くて遅くてしょうがないので頑張ってチューニングしてみた時の話です。


また、チューニング前後でダッシュボードのロードにかかった時間を計測してみました。

## 準備

まず、Google ChromeのDeveloper Toolsでキャッシュを無効にします。

![chrome-cache-disable.png](https://qiita-image-store.s3.amazonaws.com/0/1608/f1cc7100-982b-27af-8436-c1bbef3b4db2.png)

## チューニング前の状態

ZabbixはよくあるApache+mod_phpによる構成です。この状態でZabbixのダッシュボード(dashboard.php)に**HTTPS**でアクセスするとブラウザ左下のステータスバーにページのロードにかかった時間が表示されます。

![zabbix-us-default.png](https://qiita-image-store.s3.amazonaws.com/0/1608/71455174-ff0c-1cc5-1154-0f4326353679.png)

2.7秒かかっています。すごく遅いです。体感でわかるくらい遅いです。

Zabbixが定期的にポーリングしているせいか放っておくとどんどんrequestsやtransferred、経過時間が増加していくので今後これと同じ26requests処理するのにかかった時間を計測していきます。

## チューニング開始

というわけでチューニング開始です。とりあえずApacheの設定を変更していきます。

### KeepAliveを有効にする

Chrome Developer Toolsで各リソースのレスポンスヘッダを確認すると「Connection: close」になってます。
これでKeepAliveが無効だったことがわかったので有効にしてみました。

```apache
KeepAlive On
```

キャッシュを無効にした状態でZabbixのダッシュボードを再びロードします。

![zabbix_us_keepalive.png](https://qiita-image-store.s3.amazonaws.com/0/1608/6ef5320e-739a-d101-f0e6-6b45c821c632.png)

おお、少し速くなりました。

### gzip圧縮を有効にする

さらにレスポンスヘッダを見てみるとCSSやJavaScript、HTMLのどれにも「Content-Encoding: gzip」が付いてないのがわかりました。また、ステータスバーをよく見るとダッシュボードの画面を表示するのに766KBものデータがネットワークを流れています。

というわけで`mod_deflate`で静的コンテンツを圧縮しましょう。

```apache
<IfModule mod_deflate.c>
    AddOutputFilterByType DEFLATE text/html
    AddOutputFilterByType DEFLATE text/css
    AddOutputFilterByType DEFLATE text/javascript
</IfModule>
```

キャッシュを無効にした状態でZabbixのダッシュボードを再びロードします。

![zabbix_us_keepalive_gzip_expire.png](https://qiita-image-store.s3.amazonaws.com/0/1608/e50b2b98-0104-133a-03c3-76b9da3dbf3a.png)


ページのロードにかかる時間が約半分になりました！

## Apacheの前にnginxを配置する

さて、実のところApacheはあまり得意ではないので自分の得意なnginxに切り替えたいところです。また、mod_phpを利用している関係上、ApacheのMPMはpreforkなのでmod_spdyが利用できません。

さらに言うとFastCGIの設定するのは面倒なのでやりたくありません。というわけでこれまでのチューニングを施したnginxを前段に配置してHTTPSのかわりにSPDY3.1で通信するようにしてみました。


![zabbix_us_nginx_again.png](https://qiita-image-store.s3.amazonaws.com/0/1608/cecea3a7-8294-2188-910d-3bcb9b5c490a.png)


1秒切りました！なお、できるだけApacheのときと同じネットワーク転送量になるように設定しましたが、自分でも知らない部分での最適化が効いてるかもしれません。

## まとめ

海の向こうにあるZabbixサーバの表示をWebサーバのチューニングだけで高速化してみました。元は2.7秒かかっていましたが、

![zabbix-us-default.png](https://qiita-image-store.s3.amazonaws.com/0/1608/71455174-ff0c-1cc5-1154-0f4326353679.png)

最終的に1秒を切ることができました。

![zabbix_us_nginx_again.png](https://qiita-image-store.s3.amazonaws.com/0/1608/cecea3a7-8294-2188-910d-3bcb9b5c490a.png)

実際にやったことは、

 * KeepAliveを有効にする
 * gzip圧縮を有効にする
 * Apacheの前段にnginxを配置 & SPDY3.1化

上記では紹介していませんが実際にはこれに加えて

 * TLS Session Ticketsの有効化
 * OCSP Staplingの有効化

を行っています(TLS Session Cacheは最初から有効でした)。今回は地理的に遠いサーバだったのでネットワークの帯域やレイテンシを減らすのが効果的だったようです。
CygwinではじめてのGit Clone(Memo程度)

たとえばbitbucketとかからクローンするときに
(ssh-keygenとbitbucketへのSSH.pubキー登録は済ませておく。)

```bash
cd ~/import_project
git clone git@bitbucket.org:yourname/yourProject.git
```

とすると、

```bash:

WARNING: UNPROTECTED PRIVATE KEY FILE! 
```

とでるはずなので、ファイルパーミッションとグループの設定をする。

```bash:
chmod 600 ~/.ssh/id_rsa
chmod 664 ~/.ssh/id_rsa.pub
chgrp anyuser ~/ssh/*
```

とりあえず上記で動く。
住所からGoogle Mapをサイトに表示する方法

住所からGoogle Mapをサイトに表示させるメモ

地図を表示させたい場所に

```html
<div id="map" style="width: 330px; height: 100px;"></div>
```
と書く

スクリプトを読み込みます

```html
<script type="text/javascript" src="//maps.google.com/maps/api/js?sensor=false"></script>
```

次に住所から座標を求めてGoogle Mapを表示させる

```html
<script>
    function drawMap(address) {
        var geocoder = new google.maps.Geocoder();
        //住所から座標を取得する
        geocoder.geocode(
                {
                    'address': address,//検索する住所　〒◯◯◯-◯◯◯◯ 住所　みたいな形式でも検索できる
                    'region': 'jp'
                },
                function (results, status) {
                    if (status == google.maps.GeocoderStatus.OK) {
                        google.maps.event.addDomListener(window, 'load', function () {
                            var map_tag = document.getElementById('map');
                            // 取得した座標をセット緯度経度をセット
                            var map_location = new google.maps.LatLng(results[0].geometry.location.lat(),results[0].geometry.location.lng());
                            //マップ表示のオプション
                            var map_options =
                            {
                                zoom: 13,//縮尺
                                center: map_location,//地図の中心座標
                                //ここをfalseにすると地図上に人みたいなアイコンとか表示される
                                disableDefaultUI: true,
                                mapTypeId: google.maps.MapTypeId.ROADMAP//地図の種類を指定
                            };

                            //マップを表示する
                            var map = new google.maps.Map(map_tag, map_options);

                            //地図上にマーカーを表示させる
                            var marker = new google.maps.Marker({
                                position: map_location,//マーカーを表示させる座標
                                map: map//マーカーを表示させる地図
                            });
                        });
                    }
                }
        );
    }
    drawMap(住所);
</script>
```

これで画面に地図が表示される。
hetemlにrocketeerでLaravelを設置する

# 概要
レンタルサーバーのhetemlにrocketeerでlaravelを設置する手順
(べつにhetemlじゃなくても良い)

使う予定であったが、結局使う機会には恵まれなかったので記事として残し
糧としたい

# 各バージョン

- php: 5.4以上
- Laravel: 5.0.1
- Rocketeer: 2.1.0

# Laravelプロジェクトの作成
Laravelに関しては特殊なことはしない

```zsh
$ composer create-project laravel/laravel --prefer-dist
```

githubにでもpushしておく

# Rocketeerの準備
RocketeerはLaravelと一緒にはせず、別のディレクトリに置く
Rocketeerは2015-03-11時点で `Laravel 4.0` の Illuminateを参照しようとするため
利用 Laravel が 5.0 だと同じディレクトリに配置できない

```zsh
$ cd <別ディレクトリ>
$ composer require anahkiasen/rocketeer:dev-master
# 設定ファイルの生成(全てエンターにする)
$ ./vendor/bin/rocketeer ignite
```

各種設定ファイル

```php:.rocketeer/config.php
    // ...
    'connections'      => [
        'heteml' => [
            'host'      => 'ssh***.heteml.jp:2222',// :の後にportを指定できる
            'username'  => '<username>',
            'password'  => '',
            'key'       => '~/.ssh/id_rsa',
            'keyphrase' => '',
            'agent'     => '',
            'db_role'   => true,
        ],
    ],
```

Rocketeerがdeployにremote先でcomposerを使うため
heteml側にcomposer.pharを準備しておく

```zsh:hetemlにssh
$ cd ~
$ mkdir bin
$ cd bin
$ php -r "readfile('https://getcomposer.org/installer');" | php
```

```php:.rocketeer/paths.php
    // Path to Composer
    'composer' => '/home/sites/heteml/users/u/s/r/<user>/bin/composer.phar',
```

```php:.rocketeer/remote.php
    // ..
    'root_directory' => '/home/sites/heteml/users/u/s/r/<user>/web/',
    'app_directory'  => 'laravel', // 空でも良い
    // ..
    'shared'         => [
        'storage/logs',
    ],
    // ..
    'permissions'    => [
        'files'    => [
        ],
        'callback' => function ($task, $file) {
            return [
                // php実行ユーザが同じなので0755にするだけで動く
                sprintf('chmod -R 755 %s', $file),
            ];
        },
    ],
```

```php:.rocketeer/scm.php
リポジトリやユーザ名をgitリポジトリにアクセスできるように設定する
```

`.rocketeer/tasks.php`　を作成する

"hetemlに" とタイトルでついているのはここの為に有ります
composerが生成する `storage/framework/compiled.php` があると激しい文字化けに襲われるため配置後に削除する処理を書く

```php:.rocketeer/tasks.php 
<?php
use Rocketeer\Facades\Rocketeer;
 
Rocketeer::addTaskListeners('deploy', 'before-symlink', function ($task) {
    // composerによって生成されるcompiled.phpを削除しないとhetemlで文字化けに襲われる
    $output = $task->runForCurrentRelease("rm storage/framework/compiled.php");
});
```

あとはheteml側でgitリポジトリにアクセスできるように設定

```zsh:hetemlにssh
$ cd ~
$ mkdir .ssh -m 0700
$ ssh-keygen -t rsa -C "heteml"
$ cat id_rsa.pub
# githubのプロジェクト単位 deploy keyとかに登録する
$ echo "Host github
    HostName github.com
    User git" >> config
$ chmod 0600 config
$ ssh github
Hello ******! ...
```

## Rocketeer についての補足
2015-03-09時点ではCapistranoの様にローカルにgitリポジトリを持ってきて
tar等にまとめてscpで転送し、deployする機能はありません...

# deploy
これで設定は終わりです
全てうまく設定できていればdeployできるハズ

```zsh
./vendor/bin/rocketeer deploy --on="heteml"
```
僕はどうしてもseleniumでコピーしたかった

###selenium webdriverで文章をコピーしたい！

でもseleniumにはコピーなんてコマンドなかった！（見落としてるだけかもしれない）


sendkeysでctrl+C やればいいやと思ったけどできない

#ならばこうしてやるわ！！

環境:ubuntu12.04,python2.7,selenium,chrome

```lang:python
copy = driver.execute_script("return window.getSelection().toString();")
```

execute_scriptで選択範囲の文字を取り出して変数に代入

seleniumからjavascriptを実行させてコピーできました！！


ちなみに全選択はこう

```lang:python
driver.execute_script("document.execCommand('SelectAll');")
```
PHPでSlackに通知を送る


# 1. APIを使うためにAPIキーを作成する
- https://api.slack.com/web
- Slack Web APIのAuthenticationにてポチッと作成

# 2. PHPでSlackに通知を送る
```php:
<?php

$slackApiKey = 'xxxx-xxxxxxxxx-xxxx'; //上で作成したAPIキー
$text = 'Hello!';
$text = urlencode($text);
$url = "https://slack.com/api/chat.postMessage?token=${slackApiKey}&channel=%23hogehoge&text=${text}&as_user=true";
file_get_contents($url);

```


- `urlencode($text)`：urlに埋め込むときはurlエンコードをする。
- リクエストパラメータ（`token`, `channel`, `text`は必須パラメータ）
  - `token`：作成したAPIキー
  - `channel`：通知を送るチャンネル名（`%23`は`#`のurlエンコード。この例なら、チャンネル名は「`#hogehoge`」）
  - `text`：通知内容
  - `as_user`：これを指定しなければ「bot」が投稿。trueにしたら、「APIキーの作成者」が投稿。
  - ドキュメントは下記参照。
  - https://api.slack.com/methods/chat.postMessage
ipython notebookで.RDataをpandas dataFrameとして読み込む

```py:sample.py
import os
import urllib
import pandas
import pandas.rpy.common as com
import rpy2.robjects as robjects

rdata = "http://sample/d.RData"
urllib.urlretrieve(rdata, './d.RData')
robjects.r.load("./d.RData")
loaddata = com.load_data('d')
#os.remove('./d.RData')

print loaddata.head()
```
↓

          x         y         z
1  0.001000  0.000887 -6.907755
2  0.017306  0.023465 -4.056695
3  0.033612  0.069876 -3.392865
4  0.049918  0.034340 -2.997366
5  0.066224  0.026520 -2.714705

おまじないのような「robjects.r.load」が必須
無いと、com.load_dataで何をしてもnot found しか返ってこなくてハマる。

参考：
http://stackoverflow.com/questions/24220720/pandas-rpy-common-load-data-usage-documentation
Laravel 4 で依存解決すると、d11wtq/boris の解決でエラーが起こる

Laravel 4.2.x のプロジェクトで、composer install(update) すると、エラーが発生。

```
  Problem 1
    - Installation request for d11wtq/boris v1.0.10 -> satisfiable by d11wtq/boris[v1.0.10].
    - d11wtq/boris v1.0.10 requires ext-pcntl * -> the requested PHP extension pcntl is missing from your system.

    Problem 2
    - d11wtq/boris v1.0.10 requires ext-pcntl * -> the requested PHP extension pcntl is missing from your system.
    - laravel/framework v4.2.17 requires d11wtq/boris ~1.0 -> satisfiable by d11wtq/boris[v1.0.10].
    - Installation request for laravel/framework v4.2.17 -> satisfiable by laravel/framework[v4.2.17].

```

下記が、原因。

* Laravel 4.2.x が、d11wtq/boris: ~1.0 を require してる。
* d11wtq/boris が、1.0.9（2015-02-26リリース） から、ext-readline, ext-pcntl, ext-posix が require になった。（1.0.8 までは、suggests）
* これらの拡張が無い環境でエラー

動作させるアプリケーションでは、boris は無くても良いので、composer.json で、1.0.8 を指定する。

```composer.json
    "require": {
        "laravel/framework": "4.2.*",
        "d11wtq/boris": "1.0.8"
    },
```
Vim: カーソル行を基準にスクロールする方法


カーソル行を基準にスクロールするための３つのキーバインドを忘れないようにメモ。

| キーバインド | 挙動                                       | 
|:-----------|:------------------------------------------|
| `zt`       | カーソル行が画面の上端にくるようにスクロール |
| `zz`       | カーソル行が画面の中央にくるようにスクロール |
| `zb`       | カーソル行が画面の下端にくるようにスクロール |


実際には、「上端」「下端」の位置は`scrolloff`に設定されている値によって変わる。

例えば、`set scrolloff=5`のように.vimrcに記載されている場合、以下のようにスクロールが実行される。

* 上端の位置: 画面の上端から5行下
* 下端の位置: 画面の下端から5行上

おしまい。