OmniAICreator/Qiita-1.07M huggingface dataset:
汎用のLambda FunctionをデプロイするLambda Functionを作った

汎用のLambda FunctionをデプロイするLambda Functionを作りました。

* [lambda-deploy-custom-resource-function](https://github.com/k-kinzal/lambda-deploy-custom-resource-function)

# 汎用のLambda Function？

そもそも、汎用のLambda Functionって何？という話ですが、自分はLambda Functionを作っていて常々疑問に思うことがありました。
例えばサムネイルを生成するLambda Functionで

```js
var params = {
  srcData: data.Body,
  format: extension,
  width: 256,
  height: 256
};
im.resize(params, callback); 
```

のようにリサイズするサイズをマジックナンバー指定しますが、別のサイズでサムネイルを生成したいときはプロジェクトをコピーしてマジックナンバーを書き換えて別コードとして管理する必要があります。
それが凄い嫌だったので自分は[node-config](https://www.npmjs.com/package/config)を使って、設定ファイルを使ってマジックナンバーを置き換えるようにしています。

```json:config/local.json
{
  "width": 256,
  "height": 256
}
```

```js
var params = {
  srcData: data.Body,
  format: extension,
  width: config.get('width'),
  height: config.get('height')
};
im.resize(params, callback); 
```

こうすることでコードの管理自体は一元化しつつ。デプロイ時に設定ファイルを書き換えることで複数のサイズのリサイズに対応したLambda Functionを作成することができます。
プロジェクト独自のLambda Functionならこういったことをする必要はありませんが、よくあるLambda Functionなら汎用的に扱えるようにすると車輪の再発明をする必要がなくなるので楽をできます。
（環境変数とかを注入できればこんなことしなくても良かったんですけどね・・・）

# モチベーション

とはいえ、汎用のLambda Functionにもデメリットがあります。
デプロイフローが

1. プロジェクトを取得
2. 設定ファイルを生成
3. 設定ファイルを含んでZIP化
4. 作成したZIPファイルをアップロード

という手順に固定化されてしまうため、このフローに載せれてないエコシステムに乗せることができなくなります。
ついでに、S3以外のところ（GitHub releaseとか）に配置したファイルとかを直接アップロードしたいなというモチベーションでlambda-deploy-custom-resource-functionを作りました。

蛇足ですが1箇所にデプロイするだけなら[TravisCI](https://github.com/travis-ci/dpl#lambda)がデプロイの前処理を挟んだりしやすいのでオススメです。

# 使い方

事前に`lambda-deploy-custom-resource-function`をデプロイするか、`AWS::Lambda::Function`で依存系として定義します。

```json
"LambdaExampleFunction": {
  "Type": "AWS::CloudFormation::CustomResource",
  "Version" : "1.0",
    "Properties" : {
      "ServiceToken": "[lambda-deploy-custom-resource-function ARN]",
      "URL": "[Your Lambda function URL]",
      "FunctionName": "example-function",
      "Handler": "src/index.handler",
      "Role": { "Fn::GetAtt": ["LambdaExampleExecuteRole", "Arn"] },
      "Runtime": "nodejs",
      "Description": "Example function.",
      "MemorySize": 128,
      "Publish": true,
      "Timeout": 3,
      "Config": {
        "key1": 1,
        "key2": "str",
        "key3": [1, 2, 3]
      }
    }
  }
}
```

基本的には`AWS::Lambda::Function`と同じ形ですが、独自のプロパティとして`URL`に汎用のLambda FunctionのZIPのURLを、`Config`に汎用のLambda Functionに設定する値を埋め込みます。

# まとめ

これでCloudFormationを使えばコードの一元管理をしつつ、設定を変えた複数のLambda Functionをデプロイすることができるようになりました。
これで汎用のLambda Functionの作り方から、テスト、デプロイまで一通り見えたなという感じです。
そのあたりの話は[LambdaのAdvent Calendar 2015](http://qiita.com/advent-calendar/2015/lambda)で書こうかなとか思います。

関係ないですが、[AWS LambdaでのCustomResourceの作り方](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/walkthrough-custom-resources-lambda-cross-stack-ref.html)を久しぶりに調べてみたらCloudFormationに直接コードを埋め込めるようになっていて笑えました。
やりたい放題できるのでAPI GatewayのCloudFormationのサポートまだかなとか考えてる間に自作した方が話早そうですね。
Max/MspでTCP通信・UDP通信を行う方法


Max/MspでTCP通信・UDP通信を行う方法を紹介します。
ipアドレス:192.168.0.5, ポート番号:80にそれぞれ、
左側：UDP通信・右側：TCP通信を行っています。

<img width="820" alt="スクリーンショット 2015-11-15 17.01.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/96806/f16cdd80-6ab8-b42e-9959-ed0f7f6ef471.png">
DCファン12VをArduinoから制御する



# はじめに
ドライヤーをHACKしてPCからON/OFF制御する機構をつくりました。

12VのDCファンを5Vのデジタル出力からスイッチングします。


# トランジスタによるスイッチング回路
トランジスタによるスイッチング回路は基本中の基本。

DCファンの駆動電流が150mAなので1815の電流上限ギリギリで足りそう。
よって単純なトランジスタ１段で電流増幅を行うことにした。

なお、よく見かけるトランジスタには2SC1815と2SA1015という２つがある。
（電子工作サイトでは1815と1015という名前でよく見かけるので覚えておくと良い）

本当はなれたNPN型の1815で回路を組みたかったが、手元にはPNP型の1015しかなかったので、[こちら](http://www.geocities.jp/zattouka/GarageHouse/micon/circuit/TR.htm)のサイトを参考に回路を組んだ。

### 抵抗選定の考え方
ベース入力抵抗には数kΩ、駆動負荷のプルアップ（プルダウン）抵抗には数百Ωを考えておけば良い。

ベースは数mAを入力すればいいので大きめの抵抗を、駆動負荷のプルアップ電流は駆動負荷への電流も制限することになるので小さめの抵抗を選定するのがコツである。

# その他

PNPトランジスタスイッチングは **入力論理と出力論理が反転する** ので注意。
Xcode7系と6系が同居している環境でXcode6.4のXibファイル関係でビルドに失敗する問題への対処（Circle CIも）

Xcode7.0とかXcode7.1は前から入っていたんだけど、いきなり、Xcode6.4でxibを開くとクラッシュするようになった。ビルドも失敗する。Xcode7.1で開発を始めたら発生したので、Xcode7系でビルドをしたり何かをしたのがトリガーになったみたい。

さらに、Circle-ciでのビルドも失敗する。

[Xcode 6.4 で発生する Interface Builder のエラーを回避する - Qiita](http://qiita.com/msa_uccky/items/29ff43390c7bd185569b) を参考にさせてもらって解決を図ろうとしたけど、

```
/System/Library/PrivateFrameworks/PepperUICore.framework: Operation not permitted`
```

となってしまって、成功しなかった。El Captanだからかもしれない。幾つか対応策を調べて、対応が簡単なものを試してみた。

[iOS Simulator crashes after xCode 7 and xCode 6.4 installation - Stack Overflow](http://stackoverflow.com/questions/31435697/ios-simulator-crashes-after-xcode-7-and-xcode-6-4-installation/33405942#33405942)

が良かった。

> Solution: i don't know why Xcode 6.4 will use iOS 9.0.simruntime when run simulator, so i open finder and then go to /Library/Developer/CoreSimulator/Profiles/Runtimes move iOS 9.0.simruntime out then Xcode6.4 will be fine.

## Local

`/Library/Developer/CoreSimulator/Profiles/Runtimes` にいって、 `iOS 9.0.simruntime` を移動させると、今まで通りビルドができた。この辺りよくわからなかったので、ビルドが成功したら元に戻しておいた。

Xcode7系と6系の共存は苦しいですな。はやくXcode7系に移行作業終えたい（個人プロジェクトで移行始めたところ）。

## Circle ci

`circle.yml`のdependencies:に下記の文言を追加した。

```
override: 
- sudo mv "/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 9.0.simruntime" "/Library/Developer/iOS 9.0.simruntime_moved" 
```

`mv` じゃなくて `rm -fr` でもよかったかも。
ラズパイ+Webカメラでタイムラプス撮影してみた 後処理編


前回 [撮影設定編](http://qiita.com/him0net/items/b8dfda504263ed673a2b) の続きです。

撮影した画像をつなげた動画に変換します

## ラズパイから画像をひっぱてくる

ラズパイで動画変換をするのは厳しい（時間がかかる）のでそれなりのGPUが乗っているマシンに画像を持ってきて動画に変換します

avahi-daemonがインストールがインストールされていれば直接ラズパイと優先でマシンをつなげてもおk

参考
[Raspberry Piを家の外に持ち出してMacとLANケーブル直結で使う設定](http://qiita.com/hnw/items/e0d0a19a64d8d079afb5)

SCPでファイルを転送します

{hostname}.localよリ画像を持ってくる

今回は，MacBook処理するため，Cyberduckを用いてファイルの転送を行った

<img src="https://qiita-image-store.s3.amazonaws.com/0/69007/9538abe9-3fad-7dad-af70-339bf5c0a7b6.png" width="600">

## 動画へ変換

0埋め5桁の連番ファイル名にリネームします．

```Shell:rename
$ ls *.jpg | awk '{ printf "mv %s %05d.jpg\n", $0, NR }' | sh
```

ついに動画に変換します

```Shell:ffmgeg
$ ffmpeg -f image2 -r 15 -i %05d.jpg -an -vcodec libx264 -pix_fmt yuv420p video.mp4
```

出来上がり

ffmpgがない場合はパッケージマネージャでインストールする

-rオプションが1秒あたりのフレーム数なのでどうがの長さはこの値をいじって調整するといい

100枚の画像を-r10で処理すると10秒になる
Windows環境でProtractor動かしてみる

# nodeを入れる
入っている方は読み飛ばしてください。
## nodeのバージョン管理ソフト「nodist」を入れる
公式サイトからインストーラを取得する。
https://github.com/marcelklehr/nodist#installing-with-the-official-installer

特に問題がなければデフォルトのままインストールする。

参考：
http://qiita.com/yokoh9/items/20d6bdc6030a3a861189

## Gitクライアントを入れる
Gitクライアントにパス通っていれば良い。
無ければ入れる。

Git GUIを入れる。
ここからインストーラを取得する。
http://git-scm.com/download/win

設定を二か所、デフォルトから変更する。

- cmd.exe以外からも使うように設定変更する。
- checkoutとcommitをas-isで行うように設定変更する。

## nodeを入れる
コマンドプロンプトを再起動した後

```bash:nodeの初回インストール
nodist update
```

```bash:nodeのバージョン切り替え例(オプション)
nodist 4.2.2
```

```bash:確認
node -v
```

# Protractorを入れる
まずはnode-gypでビルドするための環境を作る
https://github.com/nodejs/node-gyp
## Pythonを入れる
2.7系推奨(node-gypが推奨している)。
入っている方は読み飛ばして下さい。
https://www.python.org/downloads/
(今回は最新版として2.7.10で試します。)

インストール後

- パスを通す。
- コマンドプロンプトを再起動する。

```bash:確認（大文字なので注意）
python -V
```

## visual studio 2013入れる
Visual Studio Express 2013 for Desktopを入れる
https://www.visualstudio.com/ja-jp/downloads/download-visual-studio-vs.aspx
### 設定ファイルを変更する
ライブラリのインクルードを設定する。
C:\Users\$username\"Local Settings\application Data"\Microsoft\MSBuild\v4.0\

```xml:Microsoft.Cpp.x64.user.props
<?xml version="1.0" encoding="utf-8"?> 
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ImportGroup Label="PropertySheets">
  </ImportGroup>
  <PropertyGroup Label="UserMacros" />
  <!--追加と変更ここから-->
  <PropertyGroup>
    <ExecutablePath>$(ExecutablePath)</ExecutablePath>
    <IncludePath>$(IncludePath)</IncludePath>
    <ReferencePath>$(ReferencePath)</ReferencePath>
    <LibraryPAth>$(LibraryPAth)</LibraryPAth>
    <SourcePath>$(SourcePath)</SourcePath>
    <ExcludePath>$(ExcludePath)</ExcludePath>
  </PropertyGroup>
  <!--ここまで-->
  <ItemDefinitionGroup />
  <ItemGroup />
</Project>
```
http://create-something.hatenadiary.jp/entry/2014/07/21/185404
## Protractorを入れる
```bash:インストール
npm install -g protractor
```

```bash:webdriverインストール
webdriver-manager update
```

```bash:確認
webdriver-manager status
```
参考：
https://angular.github.io/protractor/#/
http://seleniumeasy.com/protractor-angularjs-tutorials/install-protractor

# 試しにテストを一つ
```bash
cd ~\node_modules\protractor\example\
protractor conf.js
```

Google Chromeが起動してテストを実行する。
ansibleでbrew caskインストールのdirが指定できない？

# はじめに
osxをクリーンインストールしたので、
下記の記事を参考に、ansibleでローカル環境の構築をした。
http://mawatari.jp/archives/mac-provisioning-by-homebrew-and-ansible

その時につまずいたメモ。

# caskで入れたアプリのインストール先が変更できない?

caskで入れるものは、`/Applications`にインストールしたい。
でも参考の記事を元に変数設定などしたが
`$HOME/Applications`にsymlinkがつくられる。。

○試したこと。

- 環境変数にHOMEBREW_CASK_OPTS指定。 →ダメ
- コマンド実行時に、`HOMEBREW_CASK_OPTS="--appdir=/Applications"`を指定 →ダメ
- ansible使わず`brew cask install hoge --appdir=/Applications` →OK

**未解決なので、分かる方教えてくださいm(_ _)m**


# 参考にしたもの

http://t-wada.hatenablog.jp/entry/mac-provisioning-by-ansible
http://docs.ansible.com/ansible/homebrew_cask_module.html
Railsのモデルのクラスメソッド内でeachを使うときのメソッドの定義の仕方


以下のdestroy_all_safelyメソッドのように、where条件で返されるレコードに作用するクラスメソッドを定義することを考える.
destroy_all_safelyメソッドではeachメソッドを使って各インスタンスに処理を行うメソッドとする.

```ruby
class User < ActiveRecord::Base
  class << self
    def call_singleton_method
      User.where(id: [1, 2, 3]).destroy_all_safely
    end
  end
end
```

以下のようにクラスメソッドにするとeachがundefined method for <Class >と怒られる.

```ruby
class User < ActiveRecord::Base
  class << self
    def destroy_all_sefely
      each do |user| # => undefined method
        # some processes to be safe
      end
    end
  end
end

```

いくつかの実装方法があるがActiveRecord_Relationクラスをオープンしてメソッドを定義すると上手くいく.

これはUser.where(id: [1, 2, 3])で評価される結果が、User::ActiveRecord_Relationクラスのインスタンスになっているからである.

```ruby
User.where(id: [1, 2, 3]).class # => User::ActiveRecord_Relation

class User < ActiveRecord::Base
  class ActiveRecord_Relation
    def destroy_all_safely
      each do |user|
        # it works
      end
    end
  end
end
```

## 別解

オープンクラスが仰々しいという場合は以下のようにクラスメソッド内でallを呼ぶことでもできる

```ruby
class User < ActiveRecord::Base
  class << self
    def destroy_all_safely
      all.each do |user|
        # it works
      end
    end
  end
end
```
suとsudoの違い

suとsudoはオプションの違いはあるものの、できることはほぼ重複している。
ただ、suは切替先ユーザー（root）のパスワードが要求されるのに対し、sudoは元のユーザーのパスワードが要求される。sudoは/etc/sudoersで権限を細かく設定できるので、どちらか片方だけ覚えるならsudoだけを覚えておくとよい。

オプションによって実行後のカレントディレクトリや環境変数が変わってきて、それでハマることがあるので違いをまとめておく。
（Amazon Linuxで確認。CentOSでもほぼ同じと思うが、他のディストリビューションでは違う可能性あり）

|コマンド|.bash_profile|.bashrc|pwd|HOME|PATH|
|----|----|----|----|-----|----|
|su|n|y|変わらない|/root|/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/opt/aws/bin:/home/ec2-user/.local/bin:/home/ec2-user/bin:/opt/aws/bin|
|su -|y|y|/root|/root|/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/opt/aws/bin:/root/bin|
|sudo -i|y|y|/root|/root|/usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin:/opt/aws/bin:/root/bin|
|sudo -s|n|y|変わらない|/root|/sbin:/bin:/usr/sbin:/usr/bin:/opt/aws/bin|
|sudo bash|n|y|変わらない|/root|/sbin:/bin:/usr/sbin:/usr/bin:/opt/aws/bin|
|sudo bash --login|y|y|変わらない|/root|/usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin:/opt/aws/bin:/root/bin|

.bash_profileはログインシェルのときだけ読み込まれ、その中から.bashrcを読み込む。

* できるだけ忠実にrootの環境を再現したいときはsu -かsudo -iを使うとよい
* su -とsudo -iで$PATHの/usr/local/binが違う。/usr/local/binがどこで設定されているのか、/etc/bashrcや/etc/profile.dを探しても見つからなかったが、man suに書いてある

>ENV_SUPATH (string)
>           Defines the PATH environment variable for root. The default  value  is  >/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin.

が効いているのだろうか。そうだとするとコンソールからrootでログインしたときは/usr/local/binは含まれていないのだろうか。

「CentOSのsudoまとめ」も参照。
http://qiita.com/aosho235/items/bfb8034fbe1c84d7489f

# 雑学

sudo は sudo パッケージに含まれている。
su は util-linux パッケージに含まれている。
つまり開発元が別。ソースをちら見してみたら、全然別物のようだった。

useradd などを提供する shadow-utils パッケージ（の源流）にも su が含まれている。Debian 系ではこちらの su が使われているのだろうか？
http://pkg-shadow.alioth.debian.org/features.php

sudo は 1980 年頃 Robert Coggeshall と Cliff Spencer によって書かれた。
su は Version 1 Unix にすでに含まれていた由緒正しいコマンド。
Unity + iOSで GameObjectのtouchの検出と関連処理の実行


やりたかったこと
* iOSでsphere objectをタッチすると、そのsphereに割り当てられた情報を Canvasに出力する。



はまった点(伝わりづらくてすみません)
Raycast した結果、hitしたObjectの処理を実行する部分と、ローカルの関数が同じスクリプトなので、hitした Objectの関数を実行しないといけないところ、ローカルの関数を実行したことにより、対象のObjectの処理が実行できなかった.

下のEventScriptをSphereのコンポーネントとして追加して利用.


```C#
public class EventScript : MonoBehaviour {

	void Start () {
	}
	
	void Update () {
		if (Input.touchCount > 0){
			Touch _touch = Input.GetTouch(0);
			if(_touch.phase == TouchPhase.Began){
				Ray ray = Camera.main.ScreenPointToRay(_touch.position);
				RaycastHit hit = new RaycastHit();
				
				if (Physics.Raycast(ray, out hit)){

					// タッチされたobjectの色を変える
					hit.collider.GetComponent<MeshRenderer>().material.color = Color.red;

					// タッチの対象をtargetタグを持つobjectに限る
					if (hit.collider.transform.tag == "target") {
						GameObject obj = hit.collider.gameObject;
						Debug.Log(obj.name);
						
						// Coroutineの実行
						StartCoroutine(obj.GetComponentInParent<EventScript>().showInfoCanvas());
					}
				}
			}
		}
	}
	
	IEnumerator showInfoCanvas(){
		// ...
		// WWW などを利用
	}
}
```

StartCoroutineの記述部分ではまった。localのshowInfoCanvasを実行していたら、他にも同じスクリプトが設定されているsphereのshowInfoCanvasも実行されてしまい、大量にイベントが発生する事態に...

結局は、タッチされたsphereの showInfoCanvasを実行するように記述したら上手く動いた.

```
// 上手く動かなった記述
StartCoroutine(showInfoCanvas()); // localのshowInfoCanvasを実行

// 正しい動き
StartCoroutine(obj.GetComponentInParent<EventScript>().showInfoCanvas()); // タッチされたobjectのshowInfoCanvasを実行
```


でも、そもそもタッチを検出するスクリプトと、イベントの内容が同じScript内にない方が良さそうだし、タッチ検出の処理は、どこかもっとグローバルなObject(カメラとか？)に設定して、検出処理を１回に止めた方が良さそう.
設定する対象を間違えている気がする...
Lambdaでアップロードしたzipに対してハンドラーを指定する方法についての、あまりなさそうな勘違い

※handlerの設定方法を根本的に勘違いして半日ぐらい無駄にした感じがするので、自戒を込めて記録を残しておきます。


# 結論

Lambdaのハンドラの指定方法は、`file-name.function-name` という形式なので、

* 間違い：path.to.module.handler
* 正しい：__path/to/module.handler__


# 作業記録

## やりたかったこと

小さいサービス向けに、Lambda関数のセットをまとめた状態でzipにしたものを関数作成時に指定したくて、

### フォルダ構成

```
+ attakei/
  + __init__.py
  + models.py
  + handlers.py 
```

### ファイルの中身(一部)

``` python:attakei/handlers.py
def get_articles(event, context):
    return {}

def search_by_tags(event, context):
    return {"""something"""}
```

のような構成にした上で、Lambda関数作成時に、__attakei.handlers.get_articles__ のように各種ハンドラーを指定していくことで、関数をセットで管理したい。

## なぜかできない

この状態でAWSのルール通りにzipを作成してS3にアップロード→上記の書式でハンドラーを指定すると、Test実行時に全く動かない。こんなログが出続ける。

```
Unable to import module 'attakei.handlers': No module named attakei.handlers
```

## トライ&エラー

上の結論に至るまでに試してみたことの羅列

* lambda-uploadを使ってアップロード ... NG
* main.pyを用意して、main内の関数で`attakei.handlers.get_articles` を呼ぶようにする ... OK
* main.pyを用意して、main内では`from attakei.handler import get_articles`のみ書いて、main.get_articlesをハンドラー登録する ... OK

この辺で、「なんだこれ？」と感じで [ドキュメント](http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/python-programming-model-handler-types.html)読みに行ってハッとなって問題点解決。
ドキュメントはちゃんと読まないとダメですね


# 愚痴

pythonのパッケージ作る際にコンソールコマンドを定義する時って、`モジュールパス:関数名` って記載するから、完全に意識をそっちに向けてしまって脳が停滞してしまっていた模様。
でも、この形式に合わせてもらった方が個人的にはありがたかったかな...
Visual Studioのコンソールアプリケーションで実行結果をじっくり見たい

Visual StudioでC#の勉強をしようと思ってとりあえずコンソールアプリケーションとして基礎文法をお勉強！コードを書いて早速、実行結果を見てみようとすると…

あれ??
一瞬だけ表示されてすぐにコンソールが閉じちゃったぞ!?
これはいったい…
大丈夫です。単に`Ctrl`+`F5`で「デバッグなしで開始」を選べばよいのです!!
そうすると実行結果をじっくり見てコンソール上に表示される「続行するには何かキーを押してください」という表示に従って終了してください。

【追記】
この方法だとブレークポイントを打ったりステップ実行ができないというご指摘を頂きました。詳しくは下のコメントを見ていただければと思います。またテストプロジェクトの有効活用についてもアドバイス頂いております。[Temarin_PITA](http://qiita.com/Temarin_PITA)さん、[kiichi54321](http://qiita.com/kiichi54321)さん、それぞれありがとうございます。
Redmineのセキュリティについて（Basic認証も認証必須設定もしない場合のデメリット）

# 概要

## 目的
Redmineを外部アクセス可能な状態で運用するときにBasic認証やRedmineの認証必須設定をしない事に関する注意喚起と対策について

## 経緯
1. Redmineをインスコ完了後、タスクバーにある「チケット」ボタン押下で404となった
2. 対策を検索する
3. 検索結果に偶然見て良いのかわからないチケットが多数見つかる
4. 検索結果に出てくるのはよくないと思ってコレを書くことにしました

# 事例（デメリット）

なんかこんな感じの、 あかんやつ があった気がします。

1. ある会社：サービスについての情報公開
1. ある団体：研究について公開
1. 他多数

# 対策
では、「どうすればおまえはいいと思ってるの？」という事に関して。

## 取り敢えずの対応
以下どちらかを使ってれば最低限いいんじゃないですか、不正な方法を使わないとアクセスできなくなるだろうし。

* Redmineの認証必須設定
    * http://redmine.jp/faq/administration/require-auth/
* RedmineのBasic認証設定
    * http://syossan.hateblo.jp/entry/2014/08/05/112059

## 外部に公開する意味を今一度考える
きちんと利用方法を考え選択してみてはいかがでしょう。なんとなく導入して情報漏洩なんて笑えません。

* 例：社外からのアクセスが必須
    * 仕方が無い理由がある
        * 協力会社さんとの連係に必須
        * 自宅作業OKなどでIPが定まっていない
        * 海外に発注してたりしてIPに制限がかけられない
        * 打ち合わせでよく社外に居る
* 例：物理的に社内限定公開のサーバーが設置できない
* 例：利用者が情報弱者
    * おじさま/おばさまが、利用する場合などで認証をかけると使えない
* 例：その他何らかのシステム的な理由

## Redmineを選ぶ理由を今一度考える
自身で管理して・・・というのは工数が掛かると思います。
自身で管理して得られるメリット(経験値,カスタマイズ性等)は魅力的ですが、
Redmineを選ばなければならない理由を今一度考えてみてはいかがでしょうか

* 例：契約的な制限
* 例：予算的な制限
* 例：Redmineを使ってきた歴史が長い
* 例：社内事情（Redmine推進派が台頭してる等）
* 例：敢えて公開して迷い込んだ人を釣る

## じゃ、おまえだったらRedmine使うときどうしてるの？
だいたい以下をおこなってます。（できれば）

1. Redmineを選ぶことになった経緯をメモる
    * 例えば「予算」が原因だったなら予算に余裕がでたときに別サービスを検討するため。
1. Basic認証設定ON
2. Redmineの認証必須設定ON
3. 新規登録は管理者が手動で登録
4. 適切なプロジェクトの閲覧設定
5. 社内サーバーに導入して社外からアクセスできないようにする（可能であれば）
6. IPを制限（可能であれば）
7. Redmineを公開するポートを80じゃないのにする（可能であれば）
8. 定期的に登録者アカウントの棚卸し（出入りが激しければ）
9. 退職者が出たとき社外からアクセス可の状態であれば、Basic認証やポートの設定を見直す

# 最後に。
検索結果に出てくるのはよくないと思いました。（こなみかん

他に何かこれも考えた方がいいよ！というのがありましたら、教えて下さい :octocat:
travisのCIでt::Utilがコンパイルエラーを起こしているとエラー内容を検知できない場合の対処方法


タイトル通りの内容です。

### エラーの内容
TravisでpushごとにCIを走らせている設定にしていたんですが、以下のようなことを言われた。
（以下はtravisのログのコピペ）

```bash
$ PERL5OPT='-MDevel::Cover=-db,./cover_db' carton exec prove -lrv t && carton exec cover -ignore_re "^local/" -report coveralls
Can't load module t::Util at /home/travis/perl5/perlbrew/perls/5.20/bin/prove line 12.
The command "PERL5OPT='-MDevel::Cover=-db,./cover_db' carton exec prove -lrv t && carton exec cover -ignore_re "^local/" -report coveralls" exited with 2.
Done. Your build exited with 1.
```
エラーが起こったことはわかったんだけど、エラー内容がわからなくて対処できんというやつです。

proveはモジュール読み込みで失敗した際、存在有無とかコンパイルエラーとか原因に関わらず単純に「エラーだよ」というメッセージしか出さないみたいです。どうしよう。

### 対処方法
どう対処するかと言ったらinstall hookでperlを動かしてみて検知するしかない。
以下のように install時に `carton exec perl t/Util.pm` を実行するように追記。

```.travis.yml
# 前略
install:
  - carton install
  - carton exec perl t/Util.pm
# 後略
```

そして `git push` 後にログを見る。

```bash
$ carton exec perl t/Util.pm
Can't locate String/CamelCase.pm in @INC (you may need to install the String::CamelCase module) (@INC contains: /home/travis/build/celeron1ghz/p5-Hirukara-Web/t/../lib /home/travis/build/celeron1ghz/p5-Hirukara-Web/local/lib/perl5/x86_64-linux /home/travis/build/celeron1ghz/p5-Hirukara-Web/local/lib/perl5 /home/travis/perl5/perlbrew/perls/5.20/lib/site_perl/5.20.0/x86_64-linux /home/travis/perl5/perlbrew/perls/5.20/lib/site_perl/5.20.0 /home/travis/perl5/perlbrew/perls/5.20/lib/5.20.0/x86_64-linux /home/travis/perl5/perlbrew/perls/5.20/lib/5.20.0 .) at /home/travis/build/celeron1ghz/p5-Hirukara-Web/t/../lib/Hirukara.pm line 47.
BEGIN failed--compilation aborted at /home/travis/build/celeron1ghz/p5-Hirukara-Web/t/../lib/Hirukara.pm line 47.
Compilation failed in require at t/Util.pm line 65.
BEGIN failed--compilation aborted at t/Util.pm line 65.
The command "carton exec perl t/Util.pm" failed and exited with 2 during .
Your build has been stopped.
```

はい、dependenciesの追記忘れですね。

`carton`でやっていれば大体はそんなことは起こらないんですが、うっかり`carton install`でなく`cpanm`でインストールすると、開発環境だと存在するけれどテスト実行環境だとないモジュールが存在する感じになります。

こういう場合はvagrantとかで手元にクリーンな環境を用意してそれを利用すべきですが、すぐ解決したい場合にご参考ください。
Raspberry PiでHDMIで接続したディスプレイの制御

#ディスプレイをオフにする
```sh
$tvservice -o
```
#ディスプレイをオンにする
```sh
$tvservice -p
$fbset -depth 8
$fbset -depth 16 #使用するディスプレイによっては24,32の場合もある
$xrefresh -d :0.0
```
参考にしたサイト
[Raspberry Piで、HDMI出力をON/OFFする](http://blog.soramimi.jp/?p=73)
lldbでerror: ::posix_spawnp … err = Permission denied (0x0000000d)が出た時の対処法

lldbを使ってて、```run```した時に

```shell-session
error: error: ::posix_spawnp ( pid => 53252, path = '…***.o', file_actions = 0x7fff57047268, attr = 0x7fff570472a8, argv = 0x7fc6a9f333b0, envp = 0x7fc6a9f32fc0 ) err = Permission denied (0x0000000d)
```

のようなエラーが出た時は、
実行ファイルの権限が実行可能になっていないので、これを```chmod```を使って権限を付与してやると良いかと思います。
XCTestを使ったUITestで、値のValidateをするときはAccessibilityLabelを編集してはいけない

XCTestを使ってiOSアプリのUITestを実行する際に、編集方法によっては判定すべき値を正しくとれないときがあったので、残しておきます。

## AccessibilityLabelを設定されているUILabelなどの値を判定する

これがうまくいきませんでした。

例えば、こんなコードを書きます。

```
// in Application
// コードまたは、StoryboardでAccessibilityLabelを設定
label.accessibilityLabel = "ResultLabel"

// in UI Test
let resultLabel = app.staticTexts["ResultLabel"]
XCTAssertEqual(resultLabel.label, "6")
```

実行してみると。。。

```
XCTAssertEqual failed: ("Optional("ResultLabel")") is not equal to ("Optional("6")")
```

画面上、該当のラベルには"6"と表示されています。なにかおかしいですね。

いろいろ試した結果、AccessibilityLabelが設定されている場合に、`XCUIElement.label`はAccessibilityLabelの値を返すことがわかりました。(観測)

__値を扱いたいときは、AccessibilityLabelではなく、AccessibilityIdentifierを指定しましょう。__

表示している値を検証しない場合は、AccessibilityLabelでも問題ありません。
要素の特定はうまくいきます。

## StoryboardでAccessibilityLabelを消したんだけど、うまくいかない

罠ですね。

AccessibilityLabelでは、値を取得できないことがわかったのでStoryboardでAccessibilityLabelを空にしました。かわりに、AccessibilityIdentifierに"ResultLabel"を指定しました。

コードを少し直して実行してみます。

```
// in UI Test
let resultLabel = app.staticTexts["ResultLabel"]
XCTAssertEqual(resultLabel.label, "6")
```

```
XCTAssertEqual failed: ("Optional("")") is not equal to ("Optional("6")")
```

画面上、該当のラベルには"6"と表示されています。またもや、なにかおかしいですね。
値を正常に取得できていません。

Main.storyboardを開いてみましょう。

該当のラベルのAccessibilityタグを見ると。
ラベルの設定がありますよ! (label="")

```
<accessibility key="accessibilityConfiguration" identifier="SliderIdentifier" label=""/>
```

一度でも編集すると、タグが作られ、それによってAccessibilityLabelがNilにならなくなるようです。

labelプロパティを直接けずって、再実行するとうまくいきました。

```
<accessibility key="accessibilityConfiguration" identifier="SliderIdentifier"/>
```

### なぜAccessibilityLabelを使っていたのか (追記)

今回の問題を見つけるに至った最初のプロジェクトは、XCode 6.4で作成したプロジェクトでした。
このプロジェクトでは、UI TestをKIFを使って書いており、その際、多くの要素の特定にAccessibilityLabelを使っていました。
今回、XCode7でプロジェクトを作り直しましたが、Storyboardファイルはそのまま持ってきたため、AccessibilityLabelが設定済みで、罠にはまることになりました。

KIFを使っていたプロジェクトを移行する際には、ご注意ください。
Archlinuxにetcdを導入する

# etcd is 何？
分散型のkey-value store。つまり一個のサーバーで値を入れたら他のサーバーでも値が更新されている。
CoreOSの基盤の一つ。クラスタ管理機能のfleetの基盤となっているので導入する。
なおfleetを使用するにはetcdクラスタを構成した後、個々のノードでfleetdを起動すればいいが、
この際他のノードはetcd経由で探索するため、クラスタの設定としてはetcdだけで完了となる。

# AURからインストールする

```command
yaourt -S etcd
```

これで`/usr/bin/etcd`の他に環境変数を設定する`/etc/conf.d/etcd`とsystemdのサービスである`etcd.service`が入る。
`etcd`は引数として監視するポート等を設定できるが、環境変数によって設定することもできるので、テスト時は引数、
導入時は環境変数として設定するのが良いだろう。

# `/etc/conf.d/etcd`の設定

クラスタを作る場合、他のノードをどのようにして見つけるか、という問題がある。
etcdは何通りか方法を提供している:[Clustering Guide](https://github.com/coreos/etcd/blob/master/Documentation/clustering.md)
ここではstaticの方法を取る。他の方法は試していない。
今回設定したのは以下の通り

- ETCD_NAME=host1
- ETCD_DATA_DIR="/var/lib/etcd" (default)
- ETCD_LISTEN_PEER_URLS="http://host1:7001"
- ETCD_LISTEN_CLIENT_URLS="http://host1:4001"
- ETCD_INITIAL_ADVERTISE_PEER_URLS="http://host1:7001"
- ETCD_INITIAL_CLUSTER_TOKEN="etcd_cluster" (default)
- ETCD_ADVERTISE_CLIENT_URLS="http://host1:4001"
- ETCD_INITIAL_CLUSTER="host1=http://host1:7001,host2=http://host2:7001"

これはhost1の設定でhost2では最後のを除いて入れ替える。

```command
systemctl start etcd
```

でetcdが起動する。host1/2の両方で起動しないと相方が見つからないというログを出し続けるので注意。

次はfleetの導入についても書く予定。
Docker Toolboxで検証環境構築


# インストール
- 下記URLより、Docker Toolboxをダウンロード
- https://www.docker.com/docker-toolbox
- 手順はこのへん
- https://docs.docker.com/v1.8/installation/mac/

# Docker Quickstart Terminal

- 利用するターミナルを選択する画面が出たので、「iTerm(Always)」を選択した。多分なんでもいいと思う。

- 数分待つとこんな画面になる。

![スクリーンショット 2015-11-15 14.47.38.png](https://qiita-image-store.s3.amazonaws.com/0/99704/c0739dfb-f0c1-6b82-e58b-c8a6f001fe7e.png "スクリーンショット 2015-11-15 14.47.38.png")

- 起動するタイミングで「default」という名前のVMがない場合、作成しているらしい。

- この「default」については後述


# とりあえずubuntuを動かしてみる
```bash
$ docker run -it ubuntu bash
```

- なんとなく動くからこれでOK！

- なーんて、ここで終わりなわけがない。

# これどうやって動いているんだ？
- コンテナって、知ってる範囲では下記のような動作イメージ。

![Container01.png](https://qiita-image-store.s3.amazonaws.com/0/99704/cc7416a3-18b9-212a-6f6a-10aed71904f0.png "Container01.png")

- Mac Kernel != Ubuntu(Linux Kernel) のはずなので、これは動作するはずがない。
- じゃあどういう原理なんだ？と思って調べた結果
- まぁ、公式ページの焼き直しだけど。

![Container02.png](https://qiita-image-store.s3.amazonaws.com/0/99704/36189332-b06a-e554-9d06-13b4dfbbe671.png "Container02.png")


- 納得。
- 19:48 図が違ったので修正。
Swift勉強メモ(2)-Array、Dictionary、Tuple-

以下の続き。
[Swift勉強メモ(1)-四則演算・変数宣言-
](http://qiita.com/ultrabirdtech/items/cc6a9136a7daea049f54)

Swiftに触れて2日目です。
なにやらSwiftには複数のデータを扱うためには、３つほど種類あったので、それについての勉強メモ。

## 配列(Array)
プログラム言語としてお馴染みの配列です。
複数のデータをセットで扱うことができます（ざっくり
一つの配列には一つの型までしか格納できません。

```
// arrayの宣言
var array = [1,2,3]     // [1,2,3]

//  配列の中身をぐるぐるする時
for i in array{
    print(i)
}

// 要素を追加する時は、append。
array.append(4) // [1,2,3,4]

// 要素を途中に入れる時は要素とindexを指定して、insert。
array.insert(0, atIndex:0) //[0,1,2,3,4]

// 要素を消す時はindex指定してremove。
array.removeAtIndex(0)  // [1,2,3,4]

// 要素を全部消す時はremoveAll。
array.removeAll()       // []

// 配列に同じ要素をcountで指定した回数配列に値としていれることができる
var intArray3 = Array(count: 3, repeatedValue: 3)       //[3,3,3]
var strArray5 = Array(count: 5, repeatedValue: "A")     //["A","A","A","A","A"]
```

## 辞書(Dictionary)
パッと見、Rubyでいうところのハッシュ。便利。
Swiftでは辞書というらしい。
keyで検索してvalueが出てくるのだから、確かに動きは辞書ですね。

```
// 辞書を宣言
var strDictionary = [1:"A", 2:"B", 3:"C"]     //[2:"B", 1:"A", 3:"C"]

// keyが1のvalueを取り出す
strDictionary[1]      // "A"

// 要素をぐるぐる
for (key,value) in strDictionary {
    print("キーは\(key)値は\(value)")    // キーは1値はA\nキーは2値はB\n,キーは3値はC,
}

//　要素追加keyを指定して、valueを右辺に
strDictionary[4] = "D"
strDictionary   //[2:"B", 1:"A", 3:"C", 4:"D"]

// 要素削除はremoveValueForKeyで引数にkeyを指定する
strDictionary.removeValueForKey(4)
strDictionary   //[2:"B", 1:"A", 3:"C"]
```
なんか、辞書の中身の表示の順番が少しずれる？
何か規則性あるのか？
調べてみたら、公式で「辞書の順番は、保証をしていないよー」って書かれているみたい。
今度、公式のリファレンスしっかり見ておきます。

## タプル(Tuple)
複数のデータをセットで扱うことが可能。
配列と似ているけど配列との違いは、異なるデータ型を扱うことができること。
あと、要素を追加したり、削除することはできない。
これは、そもそもTupleはデータの受け渡しのために使うために作られたかららしい
ほぉ！！なるほど！！こういうものを用意してくれているのですか！！
調べてみたら関数の返り値で使うようです。
確かに返り値で使うだけなら、追加や削除いらないか。

```
// tupleを宣言
var tuple = ("ultraBirdTech", 23, false)    //(.0 "ultraBirdTech", .1 23, .2 false)

// データの取り出し
var (name, age, bool) = tuple
name        //"ultraBirdTech"
age         //23
bool        //false

// ERROR。受け取る変数が足りないため(？)エラー
 var (name1, age2) = tuple
```

ここで発覚したのがSwiftでも配列やTupleからの複数変数への多重代入が可能だということ
ただ、Rubyと違って受け取る変数の数と要素の数が同じじゃないとエラーになるみたい。

## おまけ
if文(分岐)とかfor文(繰り返し)は、あまり面白みなかったので割愛。
他の言語で学んでいれば、特に問題はないと思います。
分岐と繰り返しの練習も兼ねてfizzbuzzはやってみました。

```
// fizzbuzz
// 1から100まで繰り返して以下の判断を行う。
// 3の場合はFizz。5の場合はbuzz。両方の場合はFizzBuzzを表示する。
for i in 1...100 {
    if i % 3 == 0 && i % 5 == 0 {
        print("FizzBuzz")
    } else if i % 3 == 0 {
        print("Fizz")
    } else if i % 5 == 0 {
        print("Buzz")
    } else {
        print(i)
    }
}
```

## まとめ
まだ、実戦で使ってはいないので、それぞれがアプリのどういう場面で使えるかは、ぼやっとしかイメージできてません。
ただ、一旦は配列やら辞書の中身を繰り返したり、取り出したりして中の値を操作できるようになれば大丈夫ですよね。
なんか、他にも色々な便利なメソッドがありそうです。
暇な時にでも公式ドキュメントで、どんなメソッドがあるか見てみます。
Kotlinの拡張関数でRealmにタイプセーフAPIを追加するライブラリを作った

## できたもの
https://github.com/75py/KotliNames

**【2017/01/09追記】**
約一年放置していましたが、本家での対応はまだみたいなので、2.2.2 に対応したバージョンを公開しました。

## 経緯
開発中のアプリにRealmを導入しようとして、サンプルに驚きました。
たとえばequalToで絞り込もうとするとこうなります。

```kotlin:Cat.kt
open class Cat : RealmObject() {
    @Required
    open var name: String = ""
}
```
```kotlin
Realm.getInstance(context).use {
    var cats = it.where(Cat::class.java)
        .equalTo("name", "たま") // (1)
        .equalTo("name", false) // (2)
		.findAll()
}
```

問題点はふたつ。

1. name というフィールド名をベタ書きすることになる
2. name の型をコンパイル時に判定しないので、"たま"のところに 1 とか false とかも書けてしまう（実行時例外）

これを解決したいと思った時に思い出したのが、S2JDBCのタイプセーフAPIです。
http://s2container.seasar.org/2.4/ja/s2jdbc_typesafe.html

S2JDBCの実装と合わせるならRealmQuery側に受け取り口が必要ですが、Kotlinならさくっとメソッドを追加できます。
どうせなら、RealmQueryにタイプセーフなメソッドを直接生やしてみよう。
ということで作ってみた。

## ライブラリの内容

やってることは以下の通り。

(1) APTで `@RealmClass` が付与されているクラスのフィールド名クラスを自動生成
なお、`@RealmClass`は RealmObject に指定されているので、何もしなくて大丈夫です。

```java:CatNames.java
// Generated class
public class CatNames {
  public static KRequiredStringPropertyName name() {
    return new KRequiredStringPropertyName("name");
  }
}
```
(2) Kotlinの拡張関数で、タイプセーフなメソッドを追加

```kotlin:KotliName.kt（抜粋）
fun <E : RealmObject> RealmQuery<E>.equalTo(fieldName: KRequiredPropertyName<String>, value: String) : RealmQuery<E> = equalTo(fieldName.name(), value)

// @Requiredなしの場合はこっち（valueがnull可）
fun <E : RealmObject> RealmQuery<E>.equalTo(fieldName: KNullablePropertyName<String>, value: String?) : RealmQuery<E> = equalTo(fieldName.name(), value)
```

こんな感じになりました。

```kotlin
Realm.getInstance(context).use {
    var cats = it.where(Cat::class.java)
        .equalTo(CatNames.name(), "たま") // nameって自分で書く必要が無い
        .equalTo(CatNames.name(), false) // String以外はコンパイルエラー
        .equalTo(CatNames.name(), null) // nameはnull不可なのでコンパイルエラー
		.findAll()
}
```

RealmQueryのメソッドは一通り実装してみたので、よかったらどうぞ。
https://github.com/75py/KotliNames


## 補足 公式サポートは？
タイプセーフAPIについては、RealmのIssueにも上がっているものの、「現時点では優先度が低い」ということらしいです。
https://github.com/realm/realm-java/issues/1744#issuecomment-155158923

KotliNamesはJavaでも使えるようにしてありますが、拡張関数なしではせいぜい タイポ対策にしかなりません。
ベタ書きよりはマシですが。

Javaでのタイプセーフに関しては、公式にサポートされるのを待ったほうが賢明かと思います。
（一応kotlinamesjにJava向けコードを置く余地は残しているので、気が向いたら書くかもしれませんが。）

## 補足 RealmObjectをKotlinで書く場合の注意点

RealmObjectをKotlinで書く場合はいろいろ注意が必要です。
Javaに変換されたときどうなるかを必要以上に意識することになりますので、おとなしくJavaで書いておいた方が無難かもしれません。

```kotlin:Cat.kt
// KotlinではデフォルトがJavaで言うfinalなので、クラス・フィールドにopen指定が必要
// 【2017/01/09追記】 1.0.6で All-open compiler plugin が公開されたので、今後はこれを使うのが良いでしょう
open class Cat : RealmObject() {
    @Required
    open var name: String = "" 
    // Javaだと public String name;
    // 特に問題なく動いているっぽい

    open var age: Int = 0 
    // Javaだと public int age;
    // プリミティブ型になるので、@RequiredなしでNULL不可になる

    open var weight: Double? = 0.0 
    // Javaだと public Double weight;
    // これはNULL可

    @Required
    open var hoge: Int = 0 
    // int型になるので、「プリミティブ型には@Requiredつけられないよ！」とRealm先生に怒られる
}
```

## その他言いたいこと

* Kotlinかわいいよー
【2017/01/09追記】 Dagger2との併用は茨の道（自力とググり力が試される）
深すぎるif文for文の入れ子を書き換える

 引継いだソースコードには深すぎるif文・for文の入れ子があった。ようやくそれを解消できる見通しがついてきたので、そこから得た教訓を書いてみる。

####**まだ手をつけるな。テスト環境が先だ**
　プログラムの断片を書き変えているときには、それによって、バグを生み出している可能性は高くなる。
　深すぎる入れ子のif文は、長すぎる関数のソースコードに見られがちの症状だ。可読性を損なっていることは明白なので、書き直したいという衝動に駆られる。しかし、書き換えによって動作を変えてしまっていないことをチェックできるようにテスト環境を用意してからにしよう。

####**テスト用のデータセットを準備する**
そのルーチンをテストするのに十分なテストセットを用意する。
SVNなどをバージョン管理を導入し、ソースコードを管理しておく。

####**テスト環境ができても、すぐには手をつけない理由**

1.　ぶら下がりのelseの罠
　深すぎる入れ子のif文は、if()else if() elseの対応関係を間違えやすい罠がある。
2. elseの記述がない罠
　複雑なif文の入れ子を生じると、elseのときの動作がどうなるのかがわからなくなって、そのときにこのコードはどういう結果になるのかがわからなくなる。
3.　副作用の罠
いっけんif文で判定する順序を入れ替えてもよさそうなコードでも、関数が副作用を持つ場合だと、順序を入れ替えると挙動が変わってしまう。
4.　0回のforループの罠
　for文は０回のループの可能性がある。
　for文の中で値を設定していると、０回ループのfor文だと、そこでは値を設定されていないということを見落としがちである。
5. breakで抜けたときと最後まで到達したときの区別を無自覚なときにはまる罠
　for文の中にbreakがあるときには、forループを抜けたときの条件には、breakでぬけたときとbreakをせずに抜けた場合とがあって、それによってその後の処理の意味合いが変わってくる。breakしたときの制御変数が重要な意味をもつ場合がある。
6. continue文だけしか通らず、実質的な処理がされない可能性を無自覚なときにはまる罠
　for文の中にcontinue文があるときには、for文の中で実質的な処理がされずに、for文を抜けてくる場合と、意味がある処理をされてくる場合とがある。その場合のどちらかということ。
7. 検索処理であることを無自覚である場合の罠
　for文とbreakの組み合わせは、実は検索をしていて、条件を満たす最初の要素を見つけ出して処理している場合がある。その場合には、検索処理までをfor文で書き、検索に成功した場合の処理と検索に失敗した場合の処理とをfor文の外に書いたほうがわかりやすい。
8. 抽出すべき関数が隠れている罠
 深すぎるif文for文の入れ子は、「関数の抽出」をした方がよい場合もある。

 自分がいま相手にしているコードが、どのようなコードか十分わかっていない段階で、安易な書き換えは、バグを導入する危険があまりにも高い。
 それらの理由から、あまりに階層が深く、何を行っているのかが理解できていないコードには慎重に対処したい。

####**準備しておこう**
・内部で呼び出している関数の副作用について用心するためにも、引数にはconst属性を付ける。入力で値を渡しているのにもかかわらずconstをつけられない変数がある場合には、その理由をその関数のドキュメンテーションコメントに書いておく。
・どういう条件でその深いif文やfor文の制御を抜けるのかを読み解こう。
　数百行もあって、入れ子が6以上にもあるようなコードの場合、どのような条件で制御を抜けるのかがまちまちである。
・聞き取り調査をしよう
　そのコードを書いた人が身近にいる場合、聞き取り調査をしよう。あなたが1時間ソースコードを読んでも気づき得ないことを、コードを書いた人は知っている。
　そのコードが実行させるときの前提条件がどうかによって、「正しいプログラム」かどうかは変わってくる。

####**コーディングスタイル**　
・if文の後が一文であっても、ifには必ず{}を用いる。
・for(int i=0 ; i< iend; i++){}のようにループの変数iはforの中に書く。
　そうできない場合には、iを有効な値としてfor文のあとで利用していることを示している。
(例：配列に対して検索をしている場合、条件を満たしたiの値を利用していることがある。)
・他にも変数のスコープを可能な限り狭くしておく。
　{}である範囲を囲ってみる。

そのような準備作業を行って入れ子を減らす準備をしておく

####**入れ子を１つ減らすごとに回帰テストをする**
テストが実行できる状況になって、少しずつ書き換えを行っていく。
・elseは何に対応しているのかを注意深く確かめておく。
・省略されているelseはどういう条件なのか

・入れ子の階層を１つ浅くしたたびに、動作を変えていないことを回帰テストでテストする。
(この回帰テストをして動作を変えていないことを検証するためにも、十分な数のテストデータがそろわないうちは、ソースコードの書き換えを先送りした。)

以下のページは、書き換えのヒントになるでしょう。

[ガード節による入れ子条件記述の置き換え]
(http://bleis-tift.hatenablog.com/entry/20090124/1232768059)

[深いネストはバグの温床]
(http://refactoring-brique.info/logic/nest/)


###**追記：深すぎるif文for文の入れ子を書き換えるとどうなったか。**
・ある種の判定条件の関数が切り出された。
・for文を用いた検索関数が切り出され、検索で見つかったとき、見つからなかったときの動作の記述に変わった。
・ある処理を行う場合の前提条件のチェックがさまざまな項目でチェックされて、
　それらの前提条件を満たしたときだけ処理を行うことが明確になった。
・条件を満たしたときの動作が、for文を含むものでも意味のまとまりとして抽出されるようになった。

・その中で使われているロジックが明確になったので、現状のロジックの前提や課題が見えやすくなりました。

###**追記：**
  このようなコードの場合、関数の外部仕様が十分自明という状況になっていない懸念があります。このようなコードで、Doxygenでドキュメンテーションコメントに基づいてドキュメントを生成しても品質は確保できません。外部に委託した開発では、このようなレベルでドキュメント作成のコストを減らすために、Doxygenを使ってはならないでしょう。
UDP通信でPCからLED(on Arduino)の点滅を制御する

#はじめに
[前回](http://qiita.com/UT-HACKs/items/5ca791a9480a00bc9983)、ArduinoをTCP通信を用いて制御することに成功しました。今回はこれをUDP通信に変える方法を紹介します。UDP通信にすることで

- 遅延が少なくなる。
- Max/Mspでのコーディングが楽になる。 

という利点があります。

#コード
コードは以下の通りです。付属している UDPSendReceiveを改変して使いました

```lang:udp.ino
#include <SPI.h>        
#include <Ethernet2.h>
#include <EthernetUdp2.h>  

//macコードを入力
byte mac[] = {
  *,*,*,*,*,*
};
//IPコードを入力
IPAddress ip(*,*,*,*);

unsigned int localPort = 80;      //ポート番号

// buffers for receiving and sending data
char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet,
EthernetUDP Udp;

void setup() {
  // start the Ethernet and UDP:
  Ethernet.begin(mac, ip);
  Udp.begin(localPort);
  pinMode(9,OUTPUT);
  Serial.begin(9600);
}

void loop() {
  // if there's data available, read a packet
  int packetSize = Udp.parsePacket();
  if (packetSize){
    Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
    for(int i=0;i<packetSize;i++){
      if(packetBuffer[0]=='a'){
        digitalWrite(9,HIGH);
        break;
      }else if(packetBuffer[0]=='b'){
        digitalWrite(9,LOW);
        break;
      }
    }
  }
}

```
#注意
ライブラリEthernet2はArduino 1.7.1以降のideでないと実行できません。これは[こちら](http://www.arduino.org/software)でダウンロードできます。
OttoでAWSにWebアプリケーションをデプロイする


Otto

- https://ottoproject.io/

ほぼチュートリアルに沿ってひとまず通す。

- https://ottoproject.io/intro/getting-started/install.html


# 環境など

- Otto 0.1.2
- OS X Yosemite

# VirtualBoxのインストール

- https://www.virtualbox.org/wiki/Downloads

からOS X版をダウンロード・インストールする。

# Ottoのインストール

- https://ottoproject.io/downloads.html

からOS X版zipをダウンロード・解凍し、バイナリをパスの通ったところに置く。

# チュートリアルのアプリケーションのダウンロード

```console:
$ git clone https://github.com/hashicorp/otto-getting-started.git
$ cd otto-getting-started/
```
中身はセッションを使う程度の単純なSinatraアプリ。

# Appfileの作成

このファイルは必須ではない。またMongoDBへの依存を登録してあるが使わない。

```console:
$ vim Appfile

application {
  name = "otto-getting-started"
  type = "ruby"

  dependency {
    source = "github.com/hashicorp/otto/examples/mongodb"
  }
}

project {
  name = "otto-getting-started"
  infrastructure = "otto-getting-started"
}

infrastructure "otto-getting-started" {
  type = "aws"
  flavor = "simple"
}

customization "ruby" {
  ruby_version = "2.1"
}

```


# コンパイル
```console:
$ otto compile
```

Appfileが参照されるが、なくてもRubyアプリケーションであることをOttoが検出する。

# 開発環境の作成


```console:
$ otto dev
```

Vagrantがなければインストールされる。

- https://www.vagrantup.com/

# 開発環境ログイン

```console:
$ otto dev ssh
```

```console:
vagrant@precise64:/vagrant$ ruby -v
ruby 2.1.7p400 (2015-08-18 revision 51632) [x86_64-linux-gnu]
```

設定した依存サービスを名前解決できることを確認する。

```console:
vagrant@precise64:/vagrant$ nslookup mongodb.service.consul

```
# 開発環境でのアプリケーション動作確認
```console:
vagrant@precise64:/vagrant$ bundle && rackup --host 0.0.0.0
```

アドレスを確認する。

```console:
$ otto dev address
```

9292番でアプリケーションが立ち上がっているのを確認。




# 本番インフラ設定
対応インフラは現在AWSのみ。公開鍵がなければ作り、また秘密鍵を`ssh-add`しておく。

```console:
$ ssh-keygen -y -f ~/.ssh/my.pem > ~/.ssh/my.pub
$ ssh-add ~/.ssh/my.pem 
```

```console:
$ otto infra
```

access key,secret keyと公開鍵の場所を要求されるので入力する。passwordは適当に決める。
インフラ管理にTerraformを使うので、なければインストールされる。

- https://terraform.io/

passwordはこのあとずっと使う。環境変数に入れておけば入力しなくてよい。

```console:
$ export OTTO_CREDS_PASSWORD=XXXXX
```

結果を確認する。

```console:
$ otto status
..
    Infra:           READY
..
```




うまくいけば不要だが、`otto infra`の設定を何回もミスったので以下でクレデンシャルのキャッシュを削除してやり直した。

```console:
$ rm -rf  ~/.otto.d/cache/creds/otto-getting-started
```


EC2のリージョンはデフォルトでus-east-1になる。（`main.tf`にリージョンを書いてみたが反映されなかった）

```console:
$ otto infra info
..
region = us-east-1
..
```


# ビルド

結構時間がかかる。

```console:
$ otto build
```
イメージ管理にPackerを使うので、なければインストールされる。

- https://www.packer.io/


t2.microインスタンスが作成され、インスタンスへのSSHログイン、Consulや各種ミドルウェアインストールが行われた後、AMIが作成される。

結果を確認する。

```console:
$ otto status
..
    Build:           BUILD READY
..
```





# デプロイ
```console:
$ otto deploy
```
作ったAMIをもとにアプリケーションがデプロイされてURLが表示されるので動作確認する。
RaspberryPi2と仲良くなるシリーズ番外編 - 日本語の文字化けを解消してみた

#はじめに
RaspberryPiは一応日本語で使えるんだけど、日本語を指定して普通に起動すると文字化けします。
それをググりながら解消しました。
なぞ挙動が多すぎて何故かとかよくわからんけどばっかりですのでご了承下さい。
#さっそくはじめる
##RasbberryPi+日本語+文字化けで検索
たくさん出てきたから適当なわかりやすいページを選定して始めます
今回はこちらを参考にしてみました
[IT女子のラズベリーパイ入門奮闘記 - 第4回「ラズベリーパイ遊び初め！」](http://deviceplus.jp/hobby/raspberrypi_entry_004/#add01)
書いていることそのままやるのでさっさとやります
## さっさとやる
```
$ sudo aptitude -y install jfbterm
```
すると[jfbterm](https://osdn.jp/projects/jfbterm/)というパッケージをinstallする
で、

```
$ jfbterm
```

なんか、よくわからんけど白い文字が出てきて動いたので次
ラズパイの設定を開いてtimezoneをTokyoに設定します

```
$ sudo raspi-config
```

Setup Optionが出てくるので
「4 Internationalisation Options」→「I2 Change Timezone」
を選択
奮闘記では既に日本語になっていてアジアを選択していたけど、
私の環境ではまだ文字化けをしていたので、それっぽいものを選択

それでも文字化けが直らず・・適当に動かしていたら日本語が出てました。
なんででしょう謎です。
ちゃんと解決できなくて無念。
RaspberryPi2と仲良くなるシリーズ第1弾 - 初期起動してみる

# はじめに
dots.女子部でRaspberryPiで盛り上がったのでRaspberry Pi 2のスターターキットを買ってきて遊んでみました。
今回はとりあえず初期起動してみたよって話。

# では、あそびはじめます
## 用意したもの
* スターターキット
 * RaspberryPi2本体
 * RaspberryPi2のケース
 * OS(NOOBS ver1.4.1)インストール済みmicroSD
 * HDMIケーブル
 * LANケーブル
 * USBケーブル
 * 電源アダプタ
* USBマウス
* USBキーボード
* ディスプレイ

さあ、これらをつなげて準備万端なので動かしてみます

## はじめからつまずく
はい、つまずきました。
電源に繋いでみたら

`---[ end Kernek panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)`

とかいうのが出て止まった。
調べてみるとどうやらSDの相性が悪いらしい。
(え、スターターキット・・)

ラズパイとSDの相性が淡々と書かれているページ
http://elinux.org/RPi_SD_cards

スターターキッドに入っていたSD・・ちょっとどれかよくわかんないけど、microSDに書かれていたprofessionalで検索してみると **nok** ってでてくる。

## 絶望

とりあえず、解決策をググッてみる
色々解決法出てきたけど、一緒にいたOSinstall職人@rllllhoにNOOBSを入れなおしてもらうことに
入れてもらったのでインストール方法は(後でまとめます)。

インストールしてもらって起動してみたところ、ちゃんと動きました！

動いたということはSDの相性が悪いわけではなかった模様。
もっとちゃんと調べるとSDとの相性問題以外にも色々原因がありそうだった。
けど、とりあえず入れなおしたら動いちゃったのでそのまま進めます。

ここまでで3時間ほどかかりました。
postcssでsassの形式（っぽく）書く

#nodeでsass（っぽく）かく構造化されたcssを書く
1. nodeがインストールされている環境でnode-sassなどを使うと、他コンパイラのinstallが面倒（windowsだけかもしれないが
2. postcssを使うが、よく言われている、cssnextでの書き方をしらない人にとっては、少し記法が違うので新しく覚えるのが面倒。

ということから、どうにかしてnode onlyでsassの記法でcssをかけないかという事を考えてた。
非常に申し訳ないが、自分の環境（すでに.netがインストールされていたりといろいろ前提がある）なのでうまく行かなくても怒らないでください。

## 要望
要するにまとめると
1. 開発環境はwindowsです（会社ではそっちが主流）
2. sass的に書きたい
3. できればnodeのインストールのみですませたい
4. watchしてほしい（できれば
5. cssを圧縮してほしい

## 以下要望をまとめるとこんな感じ
とりあえずnodeで書くとしたらpostcssか
https://www.npmjs.com/package/postcss
そんでもってsassっぽくかけるのでprecssかな
https://github.com/jonathantneal/precss
これらを使ってやる。

```js:gulpfile.js
var gulp = require('gulp'); // watch
var webserver = require('gulp-webserver'); // 非推奨になってしまったconnectの代わり
var browser = require("browser-sync"); // 反映があったらブラウザのリロードをしてくれる
var plumber = require("gulp-plumber"); // エラーハンドリング
var rename = require("gulp-rename"); // scss→css的なことをする
var postcss = require("gulp-postcss");

gulp.task('default', ['connect', 'watch']);

gulp.task('css', function () {
	var plugins = [
		require('postcss-nested'), // いらないかも
		require('precss')({ /* options */ }),
		require('cssnext'), // prefixほしい
		require('cssnano') // 圧縮
	];
	gulp.src("app/scss/**/*.scss")
		.pipe(plumber())
		.pipe(postcss(plugins))
		.pipe(rename({
			extname: '.css'
		}))
		.pipe(gulp.dest("app/css"))
		.pipe(browser.reload({stream:true}));
});

gulp.task('watch', function () {
	gulp.watch('app/**/*.scss', ['css']).on('change', browser.reload);
});

gulp.task('connect', function() {
	browser({
		notify: true,
		open: true,
		server: {
			baseDir: "./app"
		}
	});
});
```

フォルダ構成としては以下のとおり

```
app
├ css
└ scss
```

動かすにはdefaultでwatchとconnectを動かすので以下のとおり

```
gulp
```

```scss:test.scss
$icon-size: 10px;
$display-size: 20em;

%main-font {
	font-size: $display-size;
}

@define-mixin icon $name {
	width: $icon-size;
	&::after {
		content: "";
		background-url: url(/icons/$(name).png);
	}
}

th.division {
	@extend %main-font;
	margin-left: $icon-size;
}

.search {
	@mixin icon search;
}
```

```css:test.css
th.division{font-size:20em;margin-left:10px}.search{width:10px}.search:after{content:"";background-url:url(/icons/search.png)}
```
とりあえずmixinとextendsはいけてるので、おそらく、precssに書いてある部分は問題無いだろうと思う(nestは書いてないけど行けました

## 最後に
本当にinstallが楽なのか……。.netとか消してから検証するのが一番なんだろうけど……。今丁度その環境がない。
ちょっと後でやってみます。
最新のCA証明書をGoパッケージに取り込むシェルスクリプト書いた

Goで`https://`なリクエスト飛ばそうとしたらTLSエラーになる環境があったので取り急ぎ作りました。やっぱり移植性がウリなGoだし証明書全部バイナリに閉じ込めちゃったほうがいいよね。

以下に**[mpyw/go-ca-bundle-generator](https://github.com/mpyw/go-ca-bundle-generator)** の内容を日本語で適当に書き下します。

------

## なぜ必要？

`https://`経由でWebサイトに接続しようとしたとき、**最新のCA証明書を持たない**環境ではTLSエラーが発生する可能性があります。これを解決するためには`ca-bundle.crt`が必要です。

ソースレポジトリはこちらです: **[bagder/ca-bundle](https://github.com/bagder/ca-bundle)**

## 使い方

### ソース生成

`generate.sh`をプロジェクトルートディレクトリで実行してください。

```shell-session
mpyw@localhost:~$ cd /path/to/project
mpyw@localhost:/path/to/project$ curl https://raw.githubusercontent.com/mpyw/go-ca-bundle-generator/master/generate.sh | bash
```

### パッケージAPI

`./cabundle` をインポートしてください。
すると以下に示す様々なレベルのAPIが利用できるようになります。

#### cabundle.GetCertPool()

`ca-bundle.crt`を内部的に利用している`x509.CertPool`へのポインタを返します。

#### cabundle.GetTlsConfig()

`cabundle.GetCertPool()`を内部的に利用している`tls.Config`へのポインタを返します。

#### cabundle.GetTransport()

`cabundle.GetTlsConfig()`を内部的に利用している`http.Transport`へのポインタを返します。

#### cabundle.GetClient()

`cabundle.GetTransport()`を内部的に利用している`http.Client`へのポインタを返します。

## 動作確認

`go run test.go` を実行するとTwitterのAPIサーバにダミーリクエストが送られます。
Tumblrからはてなブログへの記事移行をAPI経由で行う方法

Tumblrからはてなブログへの記事移行をやってるんですが、それをAPI経由で行った方法です

# 環境
OSX 10.10.5
Ruby 2.2.3p173

# 全体手順

1. Tumblrから全記事をローカルにexportする
2. ローカルにexportした記事を<b>いい感じ</b>に加工しながらAPI経由ではてなブログに新エントリーを投稿する

## 1. Tumblrから全記事をローカルにexportする
これには[sky-tumblr-export](https://www.npmjs.com/package/sky-tumblr-export)を使います

```shell-session
$ npm install -g sky-tumblr-export
```
とかでサクッと入るんですが、実際に実行するとpandocをインストールしてくれと言われるので、cabal経由でインストールします

```shell-session
$ brew install haskell-platform
$ export PATH=${HOME}/.cabal/bin:$PATH
$ cabal update
$ cabal install cabal-install
$ cabal install pandoc
$ export PATH="$HOME/Library/Haskell/bin:$PATH"
```

ここまで来てやっとpandocが使えるようになったので、sky-tumblr-exportを使います

```shell-session
$ sky-tumblr-export -u blog.kinzal.net -d /tmp/tumblr --titles
```

/tmp/tumblr以下にexportされているので、確認してみましょう

## 2. ローカルにexportした記事を<b>いい感じ</b>に加工しながらAPI経由ではてなブログに新エントリーを投稿する
ここからは正直試行錯誤になりそう…
全体的にはgistに投稿してあるので、こちらを見てください
https://gist.github.com/henteko/28a5557a8655de8ae767

基本的な流れとしては、

2.1. exportしたtumblrのデータを読み込んで、タイトルと投稿日時と内容を取得
2.2. 取得したものを元にはてなブログに投稿日時に合うようにアップロード

という感じです

### 2.1 exportしたtumblrのデータを読み込んで、タイトルと投稿日時と内容を取得
exportしたtumblrデータからタイトルと投稿日時と内容を取得します
今回はRubyを用います

```rb
title, date, body = '', '', ''
conf_flag, blank_flag = false, false
blank_count = 0
File.open('/path/to/tumblr_file.md') do |file|
  file.each_line do |labmen|
    if md = labmen.match(/^raw: (.*)/)
      json = md[1]
        hash = JSON.parse(json)
        title = hash["title"]
        date = Time.parse(hash["date"]).utc.iso8601
      end
      body += labmen if blank_flag

      # タイトル部分を本文から除外する(改行含めて5行ある)
      if conf_flag && !blank_flag
        blank_count += 1
        blank_flag = true if blank_count >= 5
      end
      # -->から上は除外する
      conf_flag = true if labmen.match(/^-->/)
    end
  end
end
```
なかなかバカみたいなことをしてますが、普通には取り出せないのでこんな感じにしてます
これで、title, date, bodyに取得すべきものが取れます
ちなみにdateははてなブログのAPIに合うように、utcのiso8601に変形してます

### 2.2. 取得したものを元にはてなブログに投稿日時に合うようにアップロード
ブログに実際に投稿していきます

```rb
require 'atomutil'

user_name = 'your_hatena_user_name'
blog = 'your_blog_domain'
url = "http://blog.hatena.ne.jp/#{user_name}/#{blog}/atom/entry"
auth = Atompub::Auth::Wsse.new(
  :username => user_name,
  :password => 'password'
)
client = Atompub::Client.new(:auth => auth)
entry = Atom::Entry.new(
  :title => title,
  :updated => date.to_s,
  :content => content)
client.create_entry(url, entry)
```
これではてなブログにアップロードが出来ます
しかしここで問題があって、文字コードの問題でエラーになる場合があります
なので、自分では[ruby-atomutil](https://github.com/lyokato/ruby-atomutil)をforkして、自分のブログエントリ内容に合うように改良してそれを使うようにしました
https://github.com/lyokato/ruby-atomutil/compare/954c5d1b387bff63db3462d19d3f7abf196d2b1f...henteko:304e3f464fd84ba2a0b0a50d71e6a0895ac8a8b4

# おわりに
これでTumblrからはてなブログへの記事移行は完了です
正直、Tumblrが公式にexportをサポートしてくれたり、はてなブログがTumblrからの移行をサポートしてくれたら一番いいんですが、そんな需要が果たしてどれほどあるのかと疑問になる機能を開発しないですよね

# 参考
http://www.rpms.me/entry/900036583469/transfer-to-hatena-blog
http://developer.hatena.ne.jp/ja/documents/blog/apis/atom
http://qiita.com/k1LoW/items/4c4ecf4afc1e753038f8
https://gist.github.com/FromAtom/6445620
Python で、LibreOffice アプリを使う（2）calc を操作する（マクロと外部から）

## まずは、calc を操作してみます。
操作は単純で、A1 のセルに数字をだすだけです。**windows** で試しています。

準備としては、まずは、新規calc を立ち上げます。

### **マクロ**
自作マクロのところに、下記を書いたpython スクリプトをいれてください。

```py3
def a1():
  doc = XSCRIPTCONTEXT.getDocument()
  sheet = doc.getSheets().getByName('Sheet1')
  A1 = sheet.getCellRangeByName('A1')
  A1.Value = 100
```

ツール→マクロ→マクロの管理→python→該当スクリプト→a1 を実行します。A1に、
100 が入ります。

### **外部から操作する**
マクロだとデバッグが大変なので、外部から、python のスクリプトをつかって操作できるようにします。今のところ、windows では、事実上、LibreOffice 付属のpythonしかつかえません。Mac ,Ubuntu でも状況は同じらしいです。つまり、**自由にモジュールを追加できないので、かなり不便**だということです。

**(準備)**
- python は、LibreOffice 付属を使う（他のpython とは競合しないようにする）
- path を、LibreOffice　の python に通す。
- libreoffice を　操作可能な状態で**起動(次に説明)**する

**(起動)**
下記のようにオプションつけて、バッチコマンド（名前は自由につけてください）で起動します。２行になっているので注意。DOS窓は開きっぱなしです。サービスにしたほうがいいのですが、とりあえずは、これでいきます。起動したら、**一度シートをクリックします。** 原因不明ですが、一度クリックしないと動きません。

```
"C:\Program Files (x86)\LibreOffice 5\program\soffice.exe" ^
--calc --norestore --accept=socket,host=localhost,port=8100;urp
```

マクロと同じことをするのが下記です。libreoffice 付属なので、uno は　import 
できるはずです。 新規のcalcが開いているのが前提です。 access the current  document　以下が、マクロと同じ内容になります。それ以前は、意味がまだ、よくわからない部分ありです。
python スクリプト名（名前は自由にどうぞ）　で実行します。

```py
# -*- coding: utf-8 -*-
import uno
localContext = uno.getComponentContext()
resolver = localContext.ServiceManager.createInstanceWithContext(
    "com.sun.star.bridge.UnoUrlResolver", localContext)
#connect to the running office
ctx = resolver.resolve( "uno:socket,host=localhost,port=8100;urp;StarOffice.ComponentContext" )
smgr = ctx.ServiceManager
# get the central desktop object
desktop = smgr.createInstanceWithContext( "com.sun.star.frame.Desktop",ctx)

# access the current  document ( calc )
doc = desktop.getCurrentComponent()
sheet = doc.getSheets().getByName('Sheet1')
A1 = sheet.getCellRangeByName('A1')
A1.Value = 999
```

マクロと外部が同じことができるようになったので、開発はマクロだけよりはましになりました。外部といっても、libreoffice 付属をつかわないといけないので（現時点ではですが）、pip や、ipython が使えず不便です。
[Git] 一部のファイル、部分的な変更点のみgit stashする

# 一部の変更点のみ退避する
以下を使用する

```
git stash -p
```

操作は`git add -p`と同様。

# 指定したstashから、特定のファイルの内容のみ取り出す
以下を使用する

```
git checkout stash@{[stashの番号]} [ファイル名]
```
shashの番号、変更ファイル名は以下で確認できる

```bash:取得例
# stashのリストを取得
$ git stash list
stash@{0}: fix hoge
stash@{1}: add fuga

# 各stashの変更ファイルを表示
$ git stash show stash@{0}
 hoge.cpp | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)
```

詳細なstashのdiffの確認は以下などを参照

[git stash した内容をさっくり確認したい](http://qiita.com/udzura/items/26e41da43d2adefa51b8)

# 参考
[[git]一部のファイルだけstashする、またはstashから取り出す - dackdive's blog:](http://dackdive.hateblo.jp/entry/2014/07/15/132855)
[git stash した内容をさっくり確認したい](http://qiita.com/udzura/items/26e41da43d2adefa51b8)