OmniAICreator/Qiita-1.07M huggingface dataset:
フォームとGASで簡易ワークフローを作ってみた

#【まえがき】
今回はGoogleDriveの機能だけでワークフローできないかなーということで
挑戦してみた件をご紹介いたします。
※あんまり実際のScriptが書いていないので役に立たなかったら、すいません。

AddOnとか3rd party製でいいものあると思いますが、
そのあたりとは比べないでくださいね。

#【まとめ】
フォームとGASを使えば簡単なワークフローは組める！！
#【ポイント】
####①すべてのデータを集約するシートを作る
　⇒承認状況を確認できるように！
####②申請Noを持ち、キー項目とする
　⇒ワークフローで異常が起きないように！
####③マスタシートを作成し、承認者の変更にも対応可能とする
　⇒部署異動等にも対応！
#【設計】
####前提：2段階承認⇒繰り返せば何段階でも…可
####処理概要
①　申請者がフォームから必要事項を入力し、申請
②　SpreadSheetにフォームの回答が入る
③　SpreadSheet上で別シートにデータをコピーする（処理用シート）
④　コピーされたシートのデータを元に承認者にメールを配信する）
⑤　届いたメールのリンクから承認用フォームを開き、承認・否認を入力する
⑥　SpreadSheetに⑤のフォームの回答が入る
⑦　⑥のデータを元に処理用シートに承認結果でStatusを書き換える
⑧　⑦の結果を元に承認であれば、最終承認者にメールを配信する。
　　否認の場合は否認メールを本人に配信する
⑨　⑤～⑧を繰り返す（さらに繰り返せば・・・）
⑩　結果を元に承認完了か否認かのメールを本人に配信する
![キャプチャ.JPG](https://qiita-image-store.s3.amazonaws.com/0/33027/5fd34b8e-8129-750a-8c6c-054904ea66f5.jpeg)

#【作成したもの】
####★Form & SpreadSheet 3セット
　>申請用フォーム&申請用回答シート/処理用シート/マスタシート
　>承認用フォーム&承認用回答シート
　>最終承認用フォーム&最終承認用回答シート

####★AppsScript 
  ・申請用回答シート
　 >dataCopy(申請用回答シート)　…10分に1度ぐらいで十分
　  申請フォームの回答を処理用シートにコピーする処理
　 
　 >mailSend　…10分に1度ぐらいで十分
　  Statusに基づきメールを配信
　 
　 >dataClear　…1日に1度ぐらいで十分（夜間処理）
　  フォームの回答を日時で削除

　・承認用回答シート/最終承認用回答シート
　 >dataSend　…10分に1度ぐらいで十分
　  承認/否認の回答を元に処理用シートのStatusを変更
#【Scriptのポイント】
全部のScriptを書くのもちょっとあれなので、
ポイントになるところだけ…

####●申請用回答シートへのデータコピー（dataCopy）時のポイント
1.承認フラグ（Status）列を作り、その結果を元にユーザーに分かり易い承認状況列を表示させる
　dataCopy 処理時に元データにプラスして下記2項目を作る
　①「承認状況列」
　　例：回答用シート.getRange(最終行+1,列).setFormula('=vlookup(U'+最終行+1+',flg!A:B,2,false)');
　　⇒flgシートには承認状況と承認フラグのマスタを作っておく

　②「承認フラグ列」に1をSet
　　⇒1は「未処理」を意味する
　
　この「承認フラグ列」の値を別シートから更新することで、ワークフローの条件分岐に使う

例：mailSendで下記条件に基づきメール配信を行う
　1	未処理		：申請された状態
　10	一次承認待ち：一次承認メールが配信された状態
　15	一次否認	：一次承認にて否認された状態
　20	一次承認済み：一次承認にて承認された状態
　30	最終承認待ち：最終承認メールが配信された状態
　35	最終否認	：最終承認にて否認された状態
　40	最終承認済み：最終承認にて承認された状態
　50	完了		：40の状況から承認完了メールが申請者に送付された状態
　98	一次否認	：15の状況から否認メールが申請者に送付された状態
　99	最終否認	：35の状況から否認メールが申請者に送付された状態
※あくまで一例です。使いやすいように調整してください。

2.承認依頼メールの承認フォームへのリンク
　mailSendで承認依頼メールを送る際に、承認フォームのリンクを送付します
　その際に、「処理用シート」のデータ行とマッチングを書けるために、
　「申請No. 」デフォルトセットしたフォームのURLを送ります。
　var formURL = "https://docs.google.com/フォームのURL?entry_XXXXXX="+対象の行No;
　※entry_XXXXX="+対象の行Noのところがキモなのですが
　　このentry_XXXXXというのはフォームの項目をセットします
　　⇒対象のフォームをライブフォームで開き、右クリック⇒ページのソースを表示とすると
　　　＜label class="ss-q-item-label" for="entry_XXXXXX"><div class="ss-q-title"＞申請No.
　　　と対象の項目のentry keyがわかりますので、そちらをセットします。

3.メールの送信先
　mailSendで承認依頼メールを送る際の宛先もマスタ化して、
　承認フラグと他のキー項目（所属部署等）によって、
　対象の承認先を取得して送信
　※このあたりはSpreadSheetのループ処理で対象者を探す感じです。

ちょっといろいろと端折りすぎちゃいましたが、
一応こんな感じで作るとワークフローがこんな感じで組めました。

社内の稟議通すぐらいのワークフローであれば、こんな感じで十分かなと思われます。
#【さらに！】
「フォームじゃファイルの添付ができねーじゃねーか！」というご指摘もあるかと思いますが、
そんな時は、DriveにアップしてそのURLを項目に記載してもらえば対応可能です！
注：権限の付与を忘れずに！

#【あとがき】
２年振り２回目の投稿ということにふと気が付きましたが、
そんなことは置いといて・・・

「こんなんじゃわかんない！」とか「もっと詳細を！」とかあれば、
コメントいただけたら嬉しいです！
できる限りコメントでお答えしたいと思います！

*最後までお読みいただきありがとうございました！*
JAVA 練習問題13-3答え(P527)

■A.java

```java
//宣言時にfinalが付いているクラスは継承できない
public final class A extends Y {
	public void a() {
		System.out.print("Aa");
	}

	public void b() {
		System.out.print("Ab");

	}

	public void c() {
		System.out.print("Ac");
	}

}

■B.java

```java

public class B extends Y {
	public void a() {
		System.out.print("Ba");

	}

	public void b() {
		System.out.print("Bb");
	}

	public void c() {
		System.out.print("Bc");
	}

}
```

■X.java

```java

public interface X {
	void a();

}
```

■Y.java

```java
public abstract class Y implements X {
	public abstract void a();
	public abstract void b();

}
```

■Main23.java

```java
public class Main23 {
	public static void main(String[] args) {

		X obj = new A();

		//練習 13-3
		A obj1 = new A();
		B obj2 = new B();

		Y[] objj = new Y[2];
		objj[0] = new A();
		objj[1] = new B();

		for(Y temporaryVariable : objj) {
			temporaryVariable.b();
		}
	}
}
```

■実行結果
AbBb
高輝度ストロボを自作するための予備検討

# はじめに
科学実験用に高輝度なストロボを作りたい。
要求仕様としては100Hz点滅をする数百lmストロボを考えて検討を行った。


# 必要なもの
- パワーLED
- LEDドライバ回路
- ストロボ機能回路
- Arduino

方針は、常時点灯のドライバ回路の電源自体をON/OFF制御することでLEDの点滅制御を行うことである。
100Hz点灯が目的ならば、モジュールの時定数は遥かに早いはずだと考えた（要実測）
（本来はストロボ機能も付いているLEDドライバを買ってマイコン制御するのが良いのかもしれないが、安いのが見つからなかった。）


## パワーLED
秋月や千石で100円くらいから買える。1Wか3Wから選ぶ感じ。消費電流は0.1-0.4A位を多く聞く。
通常の砲弾型φ5LEDだと数mAなので２桁ほど違う。

## LEDドライバ
たとえばストロベリー・リナックスで扱っている[LED定電流ドライバ](https://strawberry-linux.com/catalog/items?code=13001)などが参考になる。
明るさはモジュールに組み込まれている可変抵抗を制御すれば良い。
ON/OFF制御する場合は定電流駆動している電源側でスイッチングをすれば良いとのこと。

## ストロボ機能回路
電源側入力の12V電源自体をスイッチングすることでLEDドライバごと駆動側LEDを点滅させてやる散弾。

パワーLEDで１A近い電流が流れるはずなので、ダーリントン接続でのスイッチングを試みる。
[この記事](http://www.asahi-net.or.jp/~bz9s-wtb/doc/circuit/No1/tic1c2a.pdf)によると、たとえば2SC2235と2SC2230をくっつければいいらしい。

（予備実験ではよく使われるトランジスタ2SC1815を用いてストロボ回路を組んだところアツアツに焦がしてしまった。定格0.15mAなので、そもそも無理があったと後でわかる。）

## Arduino
ストロボ機能回路への制御入力として用いる予定。

# 基礎知識
トランジスタによるスイッチングについては[この記事](http://www.asahi-net.or.jp/~bz9s-wtb/doc/circuit/No1/tic1c2a.pdf)がとてもわかり易くまとまっていた。

LED定電流ドライバについては[この説明書](https://strawberry-linux.com/pub/cc350-manual.pdf)も参考になった。
boost::asio::ip::address  を使ってipアドレスを変換する

# 目的

コマンドライン引数より入力した dotted decimal形式のipv4アドレス
例：192.168.1.2
を、バイト配列に変換しようと思いました

もちろん .でsplitして自力で分解しても良いのですが
asioの機能を使うべきでしょう
それには　boost::asio::ip::address_v4 を使えば良いようです

http://www.boost.org/doc/libs/1_59_0/doc/html/boost_asio/reference/ip__address_v4.html

ここが　Referenceです


# ところが上手くいかなかった
コンストラクタは、default constructor、バイト配列、long値、コピーコンストラクタ
のみで、dotted decimal文字列からは構築出来ないので
default constructorで構築し、from_string で設定し
to_xxx　で変換

方針は決まったので早速　コーディング

```cpp:address_v4
  boost::asio::ip::address_v4 ipp;
  ipp.from_string("192.168.1.2");
  std::cout << "to_string()  " << ipp.to_string() << std::endl;
  std::cout << "to_ulong()  " << ipp.to_ulong() << std::endl;
  auto bt(ipp.to_bytes());
  std::cout << "to_bytes()  " << (int)bt[0] << "." << (int)bt[1] << "." << (int)bt[2] << "." << (int)bt[3]  << std::endl;



実行結果
to_string()  0.0.0.0
to_ulong()  0
to_bytes()  0.0.0.0
```

・・・ あれ？？　ダメじゃん


## ip::address_v4 を調べる

仕方ないので コードを調べます
引数が  const char*、const char*, error_code&、 const string&、 const string&, error_code
と４つオーバーライドがありますが　どれも同じなので


```cpp:address_v4.hpp
  /// Create an address from an IP address string in dotted decimal form.
  BOOST_ASIO_DECL static address_v4 from_string(const char* str);
```

```cpp:address_v4.ipp
address_v4 address_v4::from_string(const char* str)
{
  boost::system::error_code ec;
  address_v4 addr = from_string(str, ec);
  boost::asio::detail::throw_error(ec);
  return addr;
}
```


ん？？？　staticメソッド。
from_stringは　factoryパターンのようです


# 完成版
ということで、factoryパターンに対応させます



```cpp:address_v4
  auto ipp = boost::asio::ip::address_v4::from_string("192.168.1.2");
  std::cout << "to_string()  " << ipp.to_string() << std::endl;
  std::cout << "to_ulong()  " << ipp.to_ulong() << std::endl;
  auto bt(ipp.to_bytes());
  std::cout << "to_bytes()  " << (int)bt[0] << "." << (int)bt[1] << "." << (int)bt[2] << "." << (int)bt[3]  << std::endl;



実行結果
to_string()  192.168.1.2
to_ulong()  3232235778
to_bytes()  192.168.1.2
```

うまくいきましたね。


# 悩み
from_string()の戻りは この場合一時オブジェクトになり 右辺値参照になるんでしたっけ？
なので
  auto ipp = std::move(boost::asio::ip::address_v4::from_string("192.168.1.2"));
とは 書いていないけど　どうだっけ・・

あと、今回は代入演算子で行っているが コピーコンストラクタの方が良いのか？

あるいは　参照で受け取るのか

イマイチ 右辺値参照を本格的に理解していないので
疑問は残ったので
もっと勉強が必要だ
Excel VBAで複数列で最終行を取得する関数

Excel VBAで、空白を含んだ場合の最終行の取得を行いたかったのでメモ。
複数の列の最終行を取得して、一番大きい物を返す。

下の例だと12を返す。
![get1.png](https://qiita-image-store.s3.amazonaws.com/0/93950/8cf2adcd-6c00-2cc4-71e2-c99fb84a29a6.png)

歯抜けになっていてもどこかの列の最終行を返す。下の例だと14を返す。
![get2.png](https://qiita-image-store.s3.amazonaws.com/0/93950/4b741bfe-2e99-98f6-ff8b-cadb688c2e8d.png)

# ソース

```vbnet:
'***************************************************
' @fn データ最終行を取得
' @param I N:(lastColIndex) データ列の最終列
' @return 最終行番号
'***************************************************
Function GetLastRowIndex(ByVal lastColIndex As Long) As Long
    Dim colIndex As Long   ' 現在列
    Dim wkIndex()          ' 作業用配列
    
    ' データ列の全ての最終行を配列に格納
    colIndex = 1 ' 最初の列
    ReDim wkIndex(lastColIndex) ' 配列数定義
    Do
        wkIndex(colIndex - 1) = Cells(Rows.Count, colIndex).End(xlUp).Row
        
        colIndex = colIndex + 1 ' 次の列へ
        If colIndex > lastColIndex Then
            Exit Do
        End If
    Loop
    
    ' 最終行で一番大きいものを格納する
    Dim i As Long
    Dim maxnum As Long: maxnum = -1 ' 最大値
    For i = 0 To UBound(wkIndex)
        If wkIndex(i) > maxnum Then
            maxnum = wkIndex(i)
        End If
    Next i
    GetLastRowIndex = maxnum
End Function
```

# 使い方

ヘッダ行が5行目、データ列が3列、データ行の始まりが6行目からあるとする。

```vbnet:
'************************************
' クリアボタンクリック
'************************************
Sub ClearButton_Click()
    Dim FastRowIndex As Long                   ' ヘッダを除くデータ行から
    Dim lastRowIndex As Long                   ' 最終行
    Dim res As VbMsgBoxResult
    Dim lastColIndex As Long: lastColIndex = 3 ' 最終列

'    res = MsgBox("データ行をクリアします。" & vbCr & "よろしいですか？", vbOKCancel)
'    If res = vbCancel Then
'        Exit Sub
'    End If
        
    ' 最初のヘッダを除くデータ行を取得
    FastRowIndex = Cells(1, 1).End(xlDown).Row + 1
    
    ' 最終行取得
    lastRowIndex = GetLastRowIndex(lastColIndex) + 1
    
    ' データ行クリア
    Range(Cells(FastRowIndex, 1), Cells(lastRowIndex, lastColIndex)).ClearContents
End Sub
```

●ヘッダを除くデータ行の値を全て削除してくれる。
![クリア１.png](https://qiita-image-store.s3.amazonaws.com/0/93950/ebcdfe0a-a7b1-8998-9302-c30399111eca.png)
↓
![クリア２.png](https://qiita-image-store.s3.amazonaws.com/0/93950/9405bef2-5c78-8b07-5b72-203368b4c6ba.png)

●突き抜けたデータがあったり空白を含んでいても全ての最終行を削除してくれる
![クリア３.png](https://qiita-image-store.s3.amazonaws.com/0/93950/ea89e361-6d49-64ed-2ff5-c190e85bf10f.png)
↓
![クリア４.png](https://qiita-image-store.s3.amazonaws.com/0/93950/96485c9d-7811-5460-d850-71064011720f.png)

この関数は、データを処理するときの最終行を取得するために使うのも良いかも。
IntelliJ IDEAでctpファイルをphpファイルとして認識させる

はじめてCakePHP触る人向け
一緒にCakeStormも入れると吉
　
1. Preferences >> Editor >> File Types
2. PHPを選択後Registered Patternsの下にある+から*.ctpを追加
![スクリーンショット 2015-11-10 16.10.10.png](https://qiita-image-store.s3.amazonaws.com/0/24401/26a8fd7d-2fa7-eda2-1ef4-702ffa49f89e.png)
CakePHP3のTimeクラスでUNIXタイムスタンプをparseする時のタイムゾーンについて

CakePHP3でUNIXタイムスタンプを

```php
$date = Time::parse($timestamp);
```

のようにしてDBに入れていたのですが、これではどうやらUTCになってしまうらしく、9時間ずれていました。
そこで、

```php
$date = Time::parse($timestamp);
$date->timezone = 'Asia/Tokyo';
```

としたら、正しい値が入るようになりました。

bootstrap.phpで

```php
date_default_timezone_set('Asia/Tokyo');
```

と書いてあるし、PHPの設定でもtimezone設定されてるから、自動的にやってくれてもいいのになーと思うのだけど…。
CentOSのログインスクリーンにIPアドレスを表示する

ランレベル3の時に、いちいちログインしなくてもIPアドレスを確認できるようにするハック

## やり方

```
# rootユーザで
cat >> /etc/rc.d/rc.local <<-EOF
if [ ! -f /etc/issue.org ]; then
    /bin/cp /etc/issue /etc/issue.org
fi
/bin/cp -f /etc/issue.org /etc/issue
/sbin/ip address show eth0 | /bin/awk '/inet / {print $2}' | /bin/cut -d/ -f1 >> /etc/issue
EOF
```

必要に応じて、デバイス名（`eth0`）の部分を変更すること。

## 解説

* `/etc/issue`って何？

ランレベル3の時のログインスクリーンに表示される内容は、`/etc/issue`に定義されているので、そこにIPアドレスを記載してやることでログインスクリーンに表示されるようになる。

```text:/etc/issue
CentOS release 6.7 (Final)
Kernel \r on an \m
```

* `/etc/rc.d/rc.local`って何？

`/etc/rc.d/rc.local`は、サービスが全て起動し終わった後に実行されるので、**network**や**NetworkManager**を使って、イーサネットを起こしてDHCPなどでIPアドレスを取得するようになっていれば、実行時にはIPアドレスが決まっている状態になっている。

```shell-session:/etc/rc.d/rc.local
#!/bin/sh
#
# This script will be executed *after* all the other init scripts.
# You can put your own initialization stuff in here if you don't
# want to do the full Sys V style init stuff.

touch /var/lock/subsys/local
if [ ! -f /etc/issue.org ]; then
    /bin/cp /etc/issue /etc/issue.org
fi
/bin/cp -f /etc/issue.org /etc/issue
/sbin/ip address show eth0 | /bin/awk '/inet / {print $2}' | /bin/cut -d/ -f1 >> /etc/issue
```

* `/etc/rc.d/rc.local`に記載した内容を見る

```shell-session
if [ ! -f /etc/issue.org ]; then
    /bin/cp /etc/issue /etc/issue.org
fi
/bin/cp -f /etc/issue.org /etc/issue
```

毎回、`/etc/issue`に追記していくと、起動する度にIPアドレスが記載されている行が増えていってしまうので、オリジナルのファイルを複製して保持しておく。

```shell-session
/sbin/ip address show eth0 | /bin/awk '/inet / {print $2}' | /bin/cut -d/ -f1 >> /etc/issue
```

`eth0`のIPアドレスを取得し整形した上で、`/etc/issue`へ追記する。
tensorFlowのimportでTypeErrorが出る場合


先ほど[こちらの記事](http://qiita.com/bohemian916/items/62ef3fe4d90745cc92f6)でローカル環境でtensorFlowの環境を構築したが、GPUが使えなかったので、AWSのGPUインスタンスでGPUを試みようとしたところ、インストール後にこんなエラーが出てつまづいた。

```
$ python tensorflow/models/image/mnist/convolutional.py 
Traceback (most recent call last):
  File "tensorflow/models/image/mnist/convolutional.py", line 13, in <module>
    import tensorflow.python.platform
  File "/home/ec2-user/virtualenv/tensorflow/local/lib/python2.7/site-packages/tensorflow/__init__.py", line 4, in <module>
    from tensorflow.python import *
  File "/home/ec2-user/virtualenv/tensorflow/local/lib/python2.7/site-packages/tensorflow/python/__init__.py", line 13, in <module>
    from tensorflow.core.framework.graph_pb2 import *
  File "/home/ec2-user/virtualenv/tensorflow/local/lib/python2.7/site-packages/tensorflow/core/framework/graph_pb2.py", line 16, in <module>
    from tensorflow.core.framework import attr_value_pb2 as tensorflow_dot_core_dot_framework_dot_attr__value__pb2
  File "/home/ec2-user/virtualenv/tensorflow/local/lib/python2.7/site-packages/tensorflow/core/framework/attr_value_pb2.py", line 16, in <module>
    from tensorflow.core.framework import tensor_pb2 as tensorflow_dot_core_dot_framework_dot_tensor__pb2
  File "/home/ec2-user/virtualenv/tensorflow/local/lib/python2.7/site-packages/tensorflow/core/framework/tensor_pb2.py", line 16, in <module>
    from tensorflow.core.framework import tensor_shape_pb2 as tensorflow_dot_core_dot_framework_dot_tensor__shape__pb2
  File "/home/ec2-user/virtualenv/tensorflow/local/lib/python2.7/site-packages/tensorflow/core/framework/tensor_shape_pb2.py", line 22, in <module>
    serialized_pb=_b('\n,tensorflow/core/framework/tensor_shape.proto\x12\ntensorflow\"d\n\x10TensorShapeProto\x12-\n\x03\x64im\x18\x02 \x03(\x0b\x32 .tensorflow.TensorShapeProto.Dim\x1a!\n\x03\x44im\x12\x0c\n\x04size\x18\x01 \x01(\x03\x12\x0c\n\x04name\x18\x02 \x01(\tb\x06proto3')
TypeError: __init__() got an unexpected keyword argument 'syntax'
```

## 解決方法
python-protobufというモジュールのバージョンが古い場合、TensorFlowで要求されているprotobuf-3.0.0a4とコンフリクトしてうまく動かないらしい。
なのでpython-protobufを一度アンインストールする。

```
pip uninstall protobuf
```

これでもう一度importしてみると、解決した。


## 参考
[Error in python after 'import tensorflow': TypeError: __init__() got an unexpected keyword argument 'syntax'](http://stackoverflow.com/questions/33622842/error-in-python-after-import-tensorflow-typeerror-init-got-an-unexpect)
Linuxでディスクが一杯になった時の対処法

サーバーがディスク容量一杯になると、ほとんどの処理が失敗するようになってしまいかなり焦ります。
今回はそんな時の対処法をまとめました。

## 1. dfコマンドでディスク容量を確認

```
/dev/disk1     234586112 199512808  34561304    86% 25003099 4320163   85%   /
devfs                372       372         0   100%      644       0  100%   /dev
map -hosts             0         0         0   100%        0       0  100%   /net
map auto_home          0         0         0   100%        0       0  100%   /home
```

## 2. duコマンドで一番容量を食っているディレクトリを探す

```
du -sh * | sort -nr
```

上記のコマンドは現在のディレクトリでディスク利用率が多い順に表示するコマンドです。
ルートディレクトリ配下を表示する場合は、Root権限が必要なので適時sudoをつけて実行してください。

## 3. 容量が大きいファイルを削除する
2のコマンドを各ディレクトリで実行すると容量が大きくディスクを一杯にしている原因のファイルが特定できます。
そのファイルを削除していけば、改善していくと思います。

## 2015-11-10追記
inode枯渇の場合が漏れている指摘を頂いたので、追記します。
iノード（inode）とは http://kazmax.zpp.jp/linux_beginner/inode.html

inodeに関しては上記のサイトが一番わかりやすいです。
実データとは別にファイルの所属情報(ユーザー等)を管理しているもので、上限が決まっており
inode枯渇とは、上限以上にファイルを作成すると、エラーが出てしまうというものです。

```
// こんな感じのエラーが出ます。
touch: cannot touch `test.txt': デバイスに空き領域がありません
```

inode枯渇でファイル作成が出来ない場合は、`df -i`で現在のinode利用量を確認するようにしましょう。
ぼくのかんがえた最強のfor文でアルファベット

# まとめ
for文はintに対してのみ使おう。

# 経緯
for文でアルファベット http://qiita.com/ao_love/items/b08286c9344ab8fd33f0
を読んで、キモいPHPerである私は「PHPなら文字列直接インクリメントできるよ」と思って書いてみたのだが、思わぬ落とし穴にハマった。

# 前提
`for($i='a';$i<'z';$i++) echo $i;`
は
`abcdefghijklmnopqrstuvwxy`
となる。`"a"`の次は`"b"`であり、実に **直感的な** 挙動である。

# 本題
`for($i='a';$i<='z';$i++) echo $i;`
は
`abcdefghijklmnopqrstuvwxyz`
とはならない。

# ネタバレ
`abcdefghijklmnopqrstuvwxyzaaabacad（中略）aybycydyeyfygyhyiyjykylymynyoypyqyrysytyuyvywyxyyyz`

# どうしてこうなった
`'z'`をインクリメントすると`'aa'`になる。
`'z' <= 'z'` は当然trueだが、その次も `'aa' <= 'z'` となり、結果はtrueとなりループが`'z'`で止まらない。
26進数を進めていって、`yz`の次、`za` に到達したところでようやく `'za' <= 'z'` という比較になり、結果がfalseとなってループが停止する。

# 社内の反応
弊社内では大好評でした。以下のような反応を頂いております。
> "なんで文字列をインクリメントするんですか……"
> "これもう(プログラミング言語なのか)わかんねぇな"
> "こんな謎挙動を誘発するコードを書くほうが悪い"
> "くるっとる"

> 別にPHP固有じゃないよね...
> `ruby -e 'i="a"; while i <= "z" do; puts i; i.succ!; end'`
[Ruby] 英字アルファベットを𝕱𝔯𝔞𝔨𝔱𝔲𝔯に変換する

フラクトゥール、カッコいいですよね。
アルファベットから変換するやつがなかったので作ってみました。

~~とても久しぶりにRubyを書いたのであんまり綺麗じゃないですが、~~
~~もっと良い書き方があったらぜひ教えて下さい。~~

カッコいい書き方を教えてもらったので書き直しました。

```rb
def fraktur(str)
  str.tr('a-zA-Z', '𝔞-𝔷𝕬-𝖅')
end

puts fraktur("Oh, sprechen Sie Deutsch?") # => 𝕺𝔥, 𝔰𝔭𝔯𝔢𝔠𝔥𝔢𝔫 𝕾𝔦𝔢 𝕯𝔢𝔲𝔱𝔰𝔠𝔥?
```

実行すると以下のように出力されます
![スクリーンショット 2015-11-10 15.01.53.png](https://qiita-image-store.s3.amazonaws.com/0/19778/9ad26c41-ae39-d21f-24ba-459dc933c806.png)
Shadow Proxyのご紹介 at Quipper

この記事はQuipperのテックブログに書いた以下の記事の日本語版での要約です。
http://quipper.github.io/2015/11/11/introducing-shadow-proxy.html

## Shadow Proxyとは？
本番のHTTPリクエストから同等のリクエストをステージング環境に適用するための仕組みです。主な目的は、2年以上の運用で肥大化したMongoDBに対するindexの追加/削除/つけ忘れなどを事前に検証・検知するためです。

## 構成
Fluentdが大活躍しています。

![](https://cloud.githubusercontent.com/assets/899217/11035957/da75a8b0-8738-11e5-87db-2544349ab659.png)

### Reverse Proxy
Log AggregatorにNginxのアクセスログを転送する

### Log Aggregator
S3(バックアップ),BigQuery(調査用),Shadow Proxyにアクセスログを転送する

### Shadow Proxy
アクセスログをもとにステージングのアプリにHTTPリクエストを送信する。
[こちらの記事](http://qiita.com/toyama0919/items/ae4bc88423317e6668b1)を参考にfluent-plugin-http_shadowを利用しているのですが、オリジナルをForkしてQuipper独自仕様をいくつか追加してます。

- Request Bodyを送信可能に
  - POSTリクエスト時に使うため
- リクエスト送り先ごとに送信レートを設定可能に
  - 一部のステージングアプリが本番のアクセス数だと捌き切れない、かつコンテンツ作成アプリのリクエストは100%通したいため
- その他の修正は[こちら](https://github.com/quipper/fluent-plugin-http_shadow/pulls?q=)を参照

### 実際運用してみて
ぶっつけ本番で適用するのが怖かったindexの追加/削除が出来るようになり大活躍しています！
Bitcode対応版Google Analytics SDKをCocoapodsで入れる方法

バージョン3.13以前のGoogleAnalytics SDKを使うプロジェクトをXCode7でコンパイルすると、bitcodeでどうのこうのというエラーが発生する。
```エラーメッセージ
ld: '/<abbreviated>/Vendor/Analytics/GoogleAnalytics/libAdIdAccess.a(TAGActualAdIdAccess.o)' does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)
```
どうやらGoogleAnalytics SDKがApple様の新機能bitcodeに対応していないから怒られた。XCodeの設定でBitcodeを無効にできる。しかい、watchOS、tvOSアプリのビルドには必須である。
Google先生がいやいやしながらも2015年10月23日にbitcode対応版Ver.3.14をリリースしたが、11月10日時点でまだCocoapodsに反映していないようである。

###対策###
いろいろググったら、podspecを自前で作成して対応させた達人devxoulさんを見つけた。対応方法を説明させてください。

1. 3.14版に対応した[GoogleAnalytics.podspec](https://gist.github.com/devxoul/161fb4d57067327d9d07/raw/dbc8aee7e33aab58252a91c3522bdd18b9134b60/GoogleAnalytics.podspec)をダウンロードして、Podfileと同じディレクトリに保存してください。
2. PodfileのGoogleAnalyticsのとろこを下記のように変更する。  
```
pod 'GoogleAnalytics', :podspec => 'GoogleAnalytics.podspec'
```
3. pod updateでライブラリを更新させる  
```
pod update GoogleAnalytics
```

これでbitcode対応版の反映が完了。

###独り言###
これがGoogle先生がiOS開発者に対する嫌がらせではないだろう。ないだろう。きっと。。。
El Capitanの新機能Split Viewを使ってわかったメリットとデメリット

Webサイトの参考資料を見ながらコーディングをするとき、デモ動画を見せながらプレゼンをするとき、みなさんはどうしていますか？　**macOS 「[El Capitan](http://www.apple.com/jp/osx/?cid=wwa-jp-kwg-mac)」で実装された「Split View」という機能を使えば、ディスプレイ上にアプリを2つ自動で並べて表示できます**。今回はこのSplit Viewの基本的な使い方とメリット・デメリットをご紹介します。

![Split Viewデモ](https://qiita-image-store.s3.amazonaws.com/0/67884/e16d4c22-1955-9f8c-7941-b8270452565b.jpeg)

#Split Viewを使うメリット
##参考資料を見ながらの制作作業が効率的になる
Webサイトの参考資料を見ながらコーディングをしたり、電子書籍を見ながらデザイン作業をしたり、といった場面で重宝します。特にMacbook等の小さなディスプレイを使っている場合は、できるだけ画面いっぱいにアプリを開く必要があるため、Split Viewで自動的に画面サイズが最大化されるのは便利です。

##プレゼンで２つの画面を効率的に見せることが可能
Split Viewは上記で紹介したように、参考サイトを見ながら効率的に制作作業を行う他に、プレゼンでも大いに役に立ちます。プレゼン発表では、プレゼン資料の他にデモなどもう一画面を見せたいケースが多くあります。この場合にSplit Viewを使えば、デモや参考サイトを紹介を見せつつプレゼン資料を説明することが可能になります。２つの画面サイズは変更することができ、資料を大きく見せたい時やデモを大きく見せたい時もすぐに可能です。また、不要な他の画面を見せる心配もなくなります。

![スライドキャプチャー](https://qiita-image-store.s3.amazonaws.com/0/67884/24188f81-9e21-4c9b-d2b2-c1ce3818b24a.jpeg)

#Mission Controlの起動が楽になる
複数の仮想ディスプレイを扱える「Mission Control」という機能がOS Xには搭載されているのですが、Split Viewを有効にすると、任意のアプリをドラッグしたままメニューバーに高速にぶつけるだけで、Mission Controlが起動できるようになります。

# Split Viewの設定方法
Split Viewを実際に使ってみましょう。この機能を使用するには、下記の設定を行う必要があります。
① 設定画面を開き、[Mission Control]→[ディスプレイごとに個別のスペース]にチェック

![スクリーンショット 2015-11-10 11.50.26.png](https://qiita-image-store.s3.amazonaws.com/0/67884/128d8c67-d4a7-c058-8079-0d611fec5aa6.png)

② Macを再起動（※ 1度設定すれば以後は再起動は不要です）

# 使い方
では実際にSplit Viewを使っていきましょう。
①並べて表示したいアプリを開いておく。
 
![並べて表示したいアプリを開いておく](https://qiita-image-store.s3.amazonaws.com/0/67884/d98c219c-0a7c-a8c3-77b5-410170d3cf1b.jpeg)

②一方のアプリの最大化ボタンを押す。

![最大化ボタン](https://qiita-image-store.s3.amazonaws.com/0/67884/8b3db2d0-4b3a-d392-9cbc-040bab23a7a7.png)

③アプリの配置位置を決める画面になるので、右側か左側に配置する。

![位置決定中](https://qiita-image-store.s3.amazonaws.com/0/67884/f9451d64-0f2c-db1d-e5b7-ac85f230a085.jpeg)

![位置決定後](https://qiita-image-store.s3.amazonaws.com/0/67884/4d9162a4-a5e8-aa81-5fbf-a408d205fb44.jpeg)

④もう一方のアプリを選択する。

![もう一方のアプリを選択する](https://qiita-image-store.s3.amazonaws.com/0/67884/7e7db9b9-9021-530a-e211-3a8ea3b8ceb4.jpeg)

⑤ウインドウが2つ並ぶ。

![Split Viewデモ](https://qiita-image-store.s3.amazonaws.com/0/67884/e16d4c22-1955-9f8c-7941-b8270452565b.jpeg)

#Split Viewの不便な点
Split Viewを使っていていくつか不便な点もいくつかあります。
##Split Viewを起動するまでがやや遅い
Windows 10の画面分割機能であるスナップ機能は、[ウィンドウズキー]＋[矢印]で画面分割機能が素早く使えますが、Split Viewは上記で紹介したようにいくつかの手順が必要です。
##Mission Controlで隣のディスプレイにアプリを移動するのが面倒
Split Viewを無効にしている時、任意のアプリを画面左右にドラッグすると、仮想ディスプレイが切り替わってアプリを移動できる機能があり、仮想ディスプレイ間のアプリの移動が楽でした。Split Viewを有効にするとこれが使えず、アプリの移動にはMission Controlを都度起動する必要があります。
##複数ディスプレイを使用するとアプリの表示が一部途切れる
複数ディスプレイ使用している時、ディスプレイをまたいでアプリを表示しようとすると、表示が途切れてしまいます。下図をご覧ください。Display 2に表示したウインドウが途中で途切れ、Display 1には表示されていません。Split Viewを無効にした場合はこの現象は発生しません。

![SplitView有効](https://qiita-image-store.s3.amazonaws.com/0/67884/39c18494-f825-713a-908b-d652f5433e49.jpeg)

#最後に
使用シーンを選ぶものの、Split Viewは便利な機能だと感じます。**特にプレゼン発表をする時には、資料とデモという形が多いので、あらかじめSplit Viewで2つのアプリを起動しておき、必要に応じて画面サイズを切り替えながら発表できるのは非常に便利**です。是非一度Split Viewを有効にして、自分のスタイルに合っているかどうかを試してみてくださいませ。
babelify 更新時の Unknown option: base.optional while parsing file エラーを解決する

# 問題

とある Rails プロジェクトで、ES6 のトランスパイルに babelify を利用しています。そして、そのバージョンを v6.4.0 から v7.2.0 に更新した時に問題が起きました。

`gulp build` 実行時に以下の警告が表示されるようになったのです。

```
Unknown option: base.optional while parsing file
```

ちなみに `gulp build` タスクの内容は以下のとおりです。

```gulpfile.coffee
gulp.task 'build', ->
  files = glob.sync('./frontend/javascripts/**/*.{js,coffee}')

  browserify
    entries: files,
    debug: true
  .transform(babelify.configure(optional: ['es7.functionBind'])
  .bundle()
  .on('error', (error) ->
    console.log(error.message)
    this.emit('end')
  )
  .pipe(source('bundle.js'))
  .pipe(gulp.dest('app/assets/javascripts'))
```

# 原因

公式の GitHub に [該当する issue](https://github.com/babel/babelify/issues/129) がありました。
そこでこう言及されていました。

> optional isn't a valid option anymore. babelify 7.0 uses babel 6.0 and things changed a lot. Please read the README.

なるほど。依存する Babel のバージョンが 5.x から 6.x となり、仕様が大幅に変わったようですね。主な変更点は 6.x 以降は [plugin あるいは preset](https://babeljs.io/docs/plugins/) を指定する必要があるとのことです。 
次に [babelify の README.md](https://github.com/babel/babelify/blob/master/README.md) を読んでみると、やはり babelify の設定の記述形式も変わっていました。

# 解決

## 方法 1: gulpfile を更新する
`gulp build` タスクで transform の引数を以下のように変更します。

```gulpfile.coffee
# 変更前
.transform(babelify.configure(optional: ['es7.functionBind'])

# 変更後
.transform('babelify', { presets: ['es2015', 'stage-0'] })
```

[ES2015 preset](http://babeljs.io/docs/plugins/preset-es2015/) の他に、[Function Bind Syntax](https://github.com/zenparsing/es-function-bind) も利用したいので [Stage 0 preset](http://babeljs.io/docs/plugins/preset-stage-0/) も追加しています。

これで `gulp build` が正しく実行できるようになりました。

## 方法 2: .babelrc ファイルを作成する

コメントで @nanila さんに教えて頂いた方法です。
.babelrc (僕の環境の場合は Rails プロジェクトのルートディレクトリに配置する) に以下の設定を記述します。

```:.babelrc
{
  "presets": ["es2015", "stage-0"]
}
```

次に gulpfile の `gulp build` タスクで transform の引数を以下のように変更します。

```gulpfile.coffee
# 変更前
.transform(babelify.configure(optional: ['es7.functionBind'])

# 変更後
.transform('babelify')
```

以降、Babel に関する設定は gulpfile ではなく .babelrc に記述することにします。

Babel の設定は専用の設定ファイルに集約できたほうが都合がいいので、僕自身もこちらの方法に変更しました。
Python 2 > 改行なしのprint > print "1test", print "2test"

http://ideone.com/WAClJU

```test.py
print "1test",
print "2test"
```

```txt:結果
Success	time: 0.02 memory: 44680 signal:0
1test 2test
```

参考
http://www.lifewithpython.com/2013/12/python-print-without-.html
[Git][Linux] Gitの最新をソースからビルドする

# 目的

Gitの最新を使いたいのでソースをビルドしてインストールする。

# 検証環境

Ubuntu 14.04

# ビルド手順
## Gitの最新ソースを取得
ソースは以下にホスティングされています。

[git/git: Git Source Code Mirror](https://github.com/git/git)

## 依存パッケージの取得
新しいGitではOpenSSLに依存があるため、先にインストールします。

```bash:apt
sudo apt-get install libcurl4-openssl-dev libexpat1-dev
```

## ビルド

Git の取得時に git コマンドがあるのは期待できないため、wgetでzipを取得する手順も記載しています。

```bash
# gitがある場合
git clone https://github.com/git/git.git
cd git

# gitがない場合
wget https://github.com/git/git/archive/master.zip
unzip master.zip 
cd git-master/

# ビルド
make prefix=/usr/local all
sudo make prefix=/usr/local install
```

```
# バージョン確認
$ git --version
git version 2.12.0
```

# インストールスクリプト例

[dotfiles/build.sh at master · koara-local/dotfiles](https://github.com/koara-local/dotfiles/blob/master/build/git/build.sh)
[ chef ]data_bagsの書き方と取り出し方その１(基本パターン)

備忘のためのメモ
基本パターンver.

##1. data_bags

```json:data_bags/sample/sample001.json

{
    "id":"sample001",
    "samplekey01":"samplevalue01"
}

```
data_bagsの下にディレクトリを切り、jsonファイルを作成する。
jsonファイルの1行目は必ず`id`を指定する必要がある。そしてこのidの値はjsonファイルのファイル名と同一でなければならない。この例ではシンプルなkey:value形式のデータがdata_bagに設定されている。これをレシピで取り出すときは以下のようにする。


##2. recipe
```ruby:sample_recipe.rb
sample_item = data_bag_item('sample','sample001')
tmpvar = sample_item['samplekey01']

```

data_bagsのデータを取得するときは`data_bag_item`メソッドを使う。第1引数にはdata_bagsの下に切ったディレクトリ名、第2引数にはjsonファイル名(=id名)を指定する。

すると、`"samplekey01":"samplevalue01"`のキーペアを取ってくることができる。そして`sample_item['samplekey01']`のように指定すると`samplevalue01`を取り出せる。

また単に`data_bag_item('sample','sample001')['samplekey01']`と書いても同じ値を取り出すことが可能である。


### < to do >
その他
リストパターン
ネストされたハッシュパターン
などまとめる予定
python > 複数行のテキスト > multi_line_quote = '''1st line[改行]2nd line[改行]3rd line'''

https://www.youtube.com/watch?v=N4mEzFDjqtA
の6:50頃

http://ideone.com/Nj3pEw

```test.py
print "hello"

multi_line_quote = '''1st line
2nd line
3rd line'''

print multi_line_quote
```

```txt:結果
Success	time: 0.02 memory: 44632 signal:0
hello
1st line
2nd line
3rd line
```
Gitで消してpushしたファイルを復活させる


```sh
# 例

# ファイル名とそのパスを探す
git log --stat > gitlog.txt

# そのファイルの最新のコミットIDを取得する
git rev-list -n 1 @ -- [file_to_path]

# そのコミットからそのファイルを復活させる
git co [commit_id]^ -- [file_to_path]
```

```sh
# 具体例

git log --stat > gitlog.txt
> public/js/index.js

git rev-list -n 1 @ -- public/js/index.js
> abcdefg

git co abcdefg^ -- public/js/index.js
```
磁気センサアレイの実装方法を検討した



# はじめに
複数物体の位置検出のために、磁気センサをアレイ状に配列することを検討している。
具体的なセンサアレイの実装法について検討した。

目標とするのは、格子間隔3cm程度の16x16磁気センサアレイ。

[以前の記事](http://qiita.com/UT-HACKs/items/564d65db4b4ab759cbe1)で磁気センサの種類のうち、リードスイッチもしくはOH090Uを利用することを考えている。


# 手法
**・磁気センサー**
[こんな製品](http://www.acc-sys.jp/htmlp/prd_uds1098.html)があった。センサ間隔がfixである点が今回の応用と合わない。

**・抵抗分圧方式**
ADCなんかで使われてるもの。分解能を出そうとすると抵抗値の精度が急に厳しくなる。
例えば[こんなアレイセンサ](http://www.rm.mce.uec.ac.jp/sj/index.php?%A5%CD%A5%C3%A5%C8%BE%F5%B6%E1%C0%DC%B3%D0%A5%BB%A5%F3%A5%B5)の読み出し方式に使われている。

[この記事](http://blog.eldhrimnir.com/wordpress/?p=597)や[この製品](https://www.switch-science.com/catalog/1686/)もその仲間。
ただし、同時に１つまでの入力値でないと正しく読むことができない。
原理は[こちらのページ](http://www3.big.or.jp/~schaft/hardware/tips/ResDiv/page003.html)に詳しい。

**・電流加算方式**
OPアンプを用いる。読み出しに結構な電力を消費するので選外とした。

**・シリアルパラレル変換**
マッチョに16x16のセンサ一個ずつにアクセスして値を読んでみようという話になった。
利用検討デバイスはスイッチサイエンスから出ている[16chアナログマルチプレクサ](https://www.switch-science.com/catalog/137/).
利用例は[こんな感じ](http://bildr.org/2011/02/cd74hc4067-arduino/)で、非常に簡単に読み出しが可能らしい。

##その他のセンシング手法
**・画像ベース**
画像処理は非常に簡便。ただし、撮影距離を撮るために上部か下部の数十cm離れた位置にカメラを設置する必要があるため、システムがコンパクトにならない問題がある。


**・タッチパネル応用**
複数タッチ対応としては、タッチパネルも有力だ。
感圧式は誤検知が怖いので、静電式マルチタッチのパネルを埋め込むことを検討してもよいかもしれない。



# まとめ
基板プリントからユニバーサル基板実装も検討したが、対象の大きさゆえにMDFに穴を開けてそのまま回路実装を行うことになりそう。


#　そのほか
大量のセンサーを読み出したい欲求は、実験物理学の人たちの間でありそう。
どのような実装をしていたのか今一度、対応する研究室の修士論文などを読んでみたくなった。
for文でアルファベット


### 大文字
```php
for($i=0; $i<26; $i++){
    echo chr(65+$i);
}
// ABCDEFGHIJKLMNOPQRSTUVWXYZ
```

### 小文字
```php
for($i=0; $i<26; $i++){
    echo chr(97+$i);
}
// abcdefghijklmnopqrstuvwxyz
```

`chr`は指定されたASCIIコードの文字を返す関数。
Google api でinvalid_grantが発生したときの問題

```
Message from application: Authorization failed.  Server message:
{
"error" : "invalid_grant"
} (Signet::AuthorizationError)
/rails/app/path/vendor/bundle/ruby/2.1.0/gems/signet-0.6.1/lib/signet/oauth_2/client.rb:966:in `fetch_access_token'
/rails/app/path/vendor/bundle/ruby/2.1.0/gems/signet-0.6.1/lib/signet/oauth_2/client.rb:983:in `fetch_access_token!'
/rails/app/path/vendor/bundle/ruby/2.1.0/gems/google-api-client-0.8.6/lib/google/api_client/auth/jwt_asserter.rb:105:in `authorize'
```

サーバの時間がずれていたので、ntpdateで時間を合わせた
```
/usr/sbin/ntpdate ntp1.jst.mfeed.ad.jp
```
【Sublime Text】El Capitanでsublコマンドを有効にする

[元ブログ - 【Sublime Text】El Capitanでsublコマンドを有効にする](http://blog.dalt.me/1189)

久しぶりのブログとなってしまいましたので軽いネタでも。

今やエンジニアの中では言わずとも知れたSublime Text。
このファイルをSublimeで開きたいなんてことはあるはず。

そんな願いを叶えてくれるのがsublコマンドです。

そんなsublコマンドはSublime Textをインストールするだけで使えるは使えます。

※このブログはSublime Text3での話となります。

```
/Applications/Sublime\ Text.app/Contents/SharedSupport/bin/subl [対象のファイル名]
```

ですが、鬱陶しいのでシンボリックリンクを貼ります。

```
sudo ln -s /Applications/Sublime\ Text.app/Contents/SharedSupport/bin/subl /usr/bin/subl
```

するとこんなエラーが。
```
ln: /usr/bin/subl: Operation not permitted
```

ん、おかしいなぁ。

どうやら、El Capitanでは/usr/bin/sublではなく/usr/local/bin/sublに対して貼るらしいです。

[sublime symlink disappeared after upgrading to El Capitan](http://stackoverflow.com/questions/32915464/sublime-symlink-disappeared-after-upgrading-to-el-capitan)

```
sudo ln -s /Applications/Sublime\ Text.app/Contents/SharedSupport/bin/subl /usr/local/bin/subl
```

これで無事に通りました。

次回からは

```
subl [対象のファイル名]
```

でsublimeで対象ファイルが開きます！

Enjoy Sublime Life!

誰かのお役に立てば。
udp > パケットサイズと転送レート > 最大1518バイト / -14 / -4 / -20 / -8 > 1472

UDPで通信した時のデータサイズについて。

http://blogs.itmedia.co.jp/komata/2011/04/udp-8fa9.html
> Ethernetフレームは最大サイズが1518バイトですので、そこから、Ethernetヘッダ（14バイト）とFCS（4バイト）を除いた、1500バイトが送出できる最大サイズになります。IPv4でUDPを送出するには、IPv4ヘッダ（20バイト以上）とUDPヘッダ（8バイト）を除き、1472バイト以下がデータサイズになります。

上記以外にも詳しい数値をもとに説明がされている。
Javaのバージョンを簡単に切り替える


色々な案件を転々としていると、Javaのバージョンをしょっちゅう切り替えないといけないことがありますよね。
シェルスクリプトの勉強を兼ねて、Javaのバージョンを簡単に切り替えられるスクリプトを作ってみました。

参考サイト：[OSXでJavaのバージョンを切り替える](http://qiita.com/ringo/items/db58b34dc02a941b297f)

#Javaのバージョンを確かめる

```bash:
$ java -version
java version "1.6.0_65"
Java(TM) SE Runtime Environment (build 1.6.0_65-b14-466.1-11M4716)
Java HotSpot(TM) 64-Bit Server VM (build 20.65-b04-466.1, mixed mode)
```

今更書くまでもないが、```java -version```でバージョンを確認できる

#java_homeコマンド
```java_home``` コマンドは、```/System/Library/Frameworks/JavaVM.framework/Versions/A/Commands``` にあるコマンドで、引数にバージョンを与えると、そのバージョンのJavaがインストールされているパスを返す

```
$ /System/Library/Frameworks/JavaVM.framework/Versions/A/Commands/java_home -v 1.6
/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
$ /System/Library/Frameworks/JavaVM.framework/Versions/A/Commands/java_home -v 1.8
/Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home
```

1.6と1.8ではインストールされているパスが違う
バージョンによる違いかと思っていたが、参考サイトによると、どうやらJavaの提供元によってインストール場所が違うようだ

Javaへのパスを通すときに、このコマンドを使うことによって、マイナーバージョン違いや、インストールパスの差異を吸収することができる

#シェルスクリプトを書く

.bash_profileの内容をsedで置換して、それを一旦バックアップに保存し、それを./bash_profileに上書きする[^1]

```bash:change-java-version.sh
#!/bin/sh
  2 VERSION=$1
  3 
  4 cat .bash_profile | sed "s/java_home -v \"1.[0-9]\"/java_home -v \"$VERSION\    "/" > tmp.sh
  5 
  6 mv tmp.sh .bash_profile
```

```source .bash_profile```を最後に書いていたのだが、どうもうまくいかないのでとりあえずこれでよしとする
このファイルをホームディレクトリなりに置いて、実行してから```source .bash_profile```を実行する[^2]

```bash:
$ java -version
java version "1.6.0_65"
Java(TM) SE Runtime Environment (build 1.6.0_65-b14-466.1-11M4716)
Java HotSpot(TM) 64-Bit Server VM (build 20.65-b04-466.1, mixed mode)
$ sudo ./change-java-version.sh 1.7
Password:
$ source .bash_profile
$ java -version
java version "1.7.0_79"
Java(TM) SE Runtime Environment (build 1.7.0_79-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.79-b02, mixed mode)
```

これでコマンド2つで（ホントは1つにしたかった）Javaのバージョン切り替えができるようになった

[^1]: 直接.bash_profileに上書きしようとしたら、.bash_profileが真っ白になってしまった。どうやら、自分自身を書き換えるのはご法度らしい（教えてくれたみうみうさんありがとう)
[^2]: カッコ悪いのでシェルスクリプトの中に組み込みたい。教えて、エラい人
コントロールセンターの表示を2段階にする

##メモ
コントロールセンターの表示を2段階表示にするには、ステータスバーを非表示にする必要がある
http://weekly.ascii.jp/elem/000/000/173/173843/

iOS7以降のステータスバーの非表示の設定は以下の参照

##参考
http://www.sirochro.com/note/xcode-statusbar-hide/
CloudWatch LogsからElasticSearch Serviceに日本語ログを送る時の注意点



##追記(2016/01/20)
先ほどCloudWatch Logs -> Elasticsearch Serviceのログストリームを立ち上げたところ、本記事で実施しているエンコードの変更がすでに実施されていました。
現時点では以下の対応を行わなくともマルチバイト文字ありのログもぶん投げれるようになっているみたいです。

##追記前の記事はここから
CloudWatch LogsからElasticSearch Serviceにログ送れるようになりましたね。
ElasticSearch Serviceにkibana4ついてるんでログ監視が便利になりそうな予感がガンガンします。

ただエラー文に日本語などのマルチバイト文字が混ざっていると、間に入っているLambdaが落ちてElasticSearchにログが送れません。

というわけでこれやる人はLambdaをちょっといじりましょう

##説明めんどいのでコードで

###書き換え前

        // v1.1.0
        var https = require('https');
        var zlib = require('zlib');
        var crypto = require('crypto');

        var endpoint = 'search-amimoto-test-mdsry53hwls334ce4yobnpypsq.ap-northeast-1.es.amazonaws.com';

        exports.handler = function(input, context) {
            // decode input from base64
            var zippedInput = new Buffer(input.awslogs.data, 'base64');

            // decompress the input
            zlib.gunzip(zippedInput, function(e, buffer) {
                if (e) { context.fail(e); }       

                // parse the input from JSON
                var awslogsData = JSON.parse(buffer.toString('ascii'));

###書き換え後
        // v1.1.0
        var https = require('https');
        var zlib = require('zlib');
        var crypto = require('crypto');

        var endpoint = 'search-amimoto-test-mdsry53hwls334ce4yobnpypsq.ap-northeast-1.es.amazonaws.com';

        exports.handler = function(input, context) {
            // decode input from base64
            var zippedInput = new Buffer(input.awslogs.data, 'base64');

            // decompress the input
            zlib.gunzip(zippedInput, function(e, buffer) {
                if (e) { context.fail(e); }       

                // parse the input from JSON
                var awslogsData = JSON.parse(buffer.toString('utf8'));


間違い探しもいいところですが、
最後の行の「JSON.parse(buffer.toString('ascii'))」を「JSON.parse(buffer.toString('utf8'))」に変えてます。

これだけでLambdaが死ななくなるので安心です。
Spring + ElasticsearchTemplateで全件検索する方法

SpringBootでElasticsearchを使っていて、全件検索をしていたら何故か10件しか取ってこれなかった。

Javaプロジェクトに入れたライブラリは

* SpringBoot 1.2.5
* spring-data-elasticsearch 1.1.3

で、以下のコードを実行してみた。

```java
@Autowired
private ElasticsearchTemplate elasticsearchTemplate;

...

SearchQuery searchQuery = new NativeSearchQueryBuilder()
                        .withIndices("model-search")
                        .withTypes("model")
                        .withQuery(QueryBuilders.matchAllQuery())
                        .build();

List<Model> models = elasticsearchTemplate.queryForList(searchQuery, Model.class);
// 何故か10件しか取得できない
```

おかしいなと思って調べていたら、どうやらそういう仕様らしく解決方法も見つかった。

* [3. Miscellaneous Elasticsearch Operation Support](http://docs.spring.io/spring-data/elasticsearch/docs/1.0.4.RELEASE/reference/html/elasticsearch.misc.html)
* [how to disable page query in Spring-data-elasticsearch](http://stackoverflow.com/questions/30730504/how-to-disable-page-query-in-spring-data-elasticsearch)

ここに書いてあるのは、「一度に1ページ分しか取得できないなら、スクロールさせて全件取ってくればいいじゃない！」という方法。

```java
SearchQuery searchQuery = new NativeSearchQueryBuilder()
            .withQuery(QueryBuilders.matchAllQuery())
            .withIndices("model-search")
            .withTypes("model")
            .withSearchType(SearchType.SCAN)
            .withPageable(new PageRequest(0, NUM_ITEMS_PER_SCROLL))
            .build();
String scrollId = elasticsearchTemplate.scan(searchQuery, SCROLL_TIME_IN_MILLIS, false);
boolean hasRecords = true;
while (hasRecords) {
        Page<Model> page = elasticsearchTemplate.scroll(scrollId, SCROLL_TIME_IN_MILLIS, Model.class);
        if (page != null) {
            // DO something with the records
            hasRecords = (page.getContent().size() == NUM_ITEMS_PER_SCROLL);
        } else {
            hasRecords = false;
        }
}
```

なるほど出来た。

ちなみに、取ってくる件数がInteger.MAX_VALUE以下であることがわかっていれば、一度に取ってくる件数を増やしても対応できます。（パフォーマンスは未調査。）

```java
SearchQuery searchQuery = new NativeSearchQueryBuilder()
                        .withIndices("model-search")
                        .withTypes("model")
                        .withQuery(QueryBuilders.matchAllQuery())
                        .withPageable(new PageRequest(0, Integer.MAX_VALUE))
                        .build();

List<Model> models = elasticsearchTemplate.queryForList(searchQuery, Model.class);
```
powerpoint 2013 > UI > コピーして同じ横位置、別の縦位置に置く > 選択 / Ctrl押しながらドラッグ

```txt:動作確認
PowerPoint 2013
```

テキストなどを手っ取り早くコピーする。その際、位置合わせもある程度したい。

1. コピー対象をクリック
2. Ctrlを押しながらドラッグする
3. 赤破線によるガイドが出るので、それを見ながら横位置を合わせて別の縦位置に置く

横方向にコピーもできる。

ガイドの出方が２種類あるが、未調査。

<hr>
(追記)
上と下にテキストがあった時、位置によっては、上と下の空きが等しくなる時のガイドも表示される。

ドラッグ中にCtrlを離すと、コピーから移動に変わる。
MySQL最低限のチューニング（というか設定事項）


チューニングと呼ぶには恥ずかしいレベルの最低限の対応。
まず、メモリ等のmy.cnfの設定はこちらを見て下さい。

##インデックス

何は無くてもインデックス。もちろん貼り過ぎには注意する。まあ、通常は、1テーブルにつき、主キー以外にもう1つ程度かと。

###テーブルにindexがはられているかの確認

```bash
mysql> show index from table_name
```

###indexの追加

テーブル作成後。

```bash
mysql> alter table table_name add index index_name(column_name);
```

テーブル作成時は、

```bash
create table tablename(
	id int,
	member_no varchar(32),
	index(member_no)
);
```
などとする。

###indexの削除

```bash
mysql> alter table table_name drop index index_name;
```

##その他

その他、クエリは極力全文検索を避け、WHEREによる絞込やページングを行う。

##スロークエリへの対応

テスト中からスロークエリの把握、対応をしておく。もちろん、運用後も。

###とりあえず確認

何は無くとも、ひとまず下記コマンドを叩いてみる。

```bash
mysqladmin status -u root -p
```
すると、

```bash
Uptime: 11413351  Threads: 3  Questions: 4468035  Slow queries: 38  Opens: 34  Flush tables: 1  Open tables: 27  Queries per second avg: 0.391
```
すると、4番目の結果に、Slow queriesがある。標準では、10秒以上がスロークエリとして設定されているようです。但し、内容は、設定していないとログとしては出力されないようです（標準では未出力）。

###ログ保存設定

標準では、スローログはロギングされない。5.1の場合、my.cnfに、

```bash
[mysqld]
slow_query_log=ON
slow_query_log_file=/path/mysql-slow.log
long_query_time=1.0
```

という感じ。5.1からは、long_query_timeを0.5といった感じで1秒以下に設定できるようになったとのこと。

なお、スローログは、DBにためることもできる。その場合は、

```bash
[mysqld]
log_output=TABLE
```

とする。log_output=TABLE,FILEとすれば両方に出力できるらしい。
ちなみに、出力されるテーブルは、

mysql.slow_log
mysql.general_log

というものらしい。
MySQL最低限のメモリ設定


環境にもよりますが、MySQLのデフォルトのメモリ関連の設定は控えめな感じになっています（私のCentOS環境では、key_buffer_sizeが8M,innodb_buffer_pool_sizeも8Mとなっています）ので、適切な状態への変更が必要です。

>MySQLのメモリについては、いろいろな情報がありますが、MySQLのsupport-filesの中にあるサンプルを見ればいいでしょう（ちょっと、サイズの感覚が古いですが）。多くの場合、my-huge.cnfかmy-innodb-heavy-4G.cnfを参考にすればいいでしょう。

後は、[本家Oracleさんの資料](http://www.oracle.com/technetwork/jp/ondemand/database/mysql/mysql-perftun-1484759-ja.pdf)も参考になります。


##グローバルバッファとスレッドバッファ

MySQLでは、mysqldが共通に使うグローバルバッファと、スレッド（コネクション）毎に割り振られるスレッドバッファがあります。MySQLのメモリ使用量は、

メモリ使用量 = グローバルバッファ + （スレッドバッファ x スレッド数）

の関係で表すことができるとされています。

##MyISAMとInnoDB

MySQLの代表的なストレージエンジンはMyISAMとInnoDBですが、利用するエンジンによりメモリ（グローバルバッファ）の使い方は異なります（スレッドバッファは共通）。5.5からは、デフォルトのエンジンがInnoDBになったので、基本、InnoDBのことだけ考えておけばいいのですが、システムDBはMyISAMということなので、MyISAMのことも最低限考えておく必要があります。

###InnoDB（グローバル）

InnoDBは、乱暴に言うと、全てのデータをinnodb_buffer_pool_sizeで指定されたメモリ内に保存するので、innnodb_buffer_pool_sizeの値を適切に設定する必要があります。DB専用のサーバであれば搭載メモリの80%程度とも言われています。

* innodb_buffer_pool_size
* innodb_log_file_size

log_file_sizeは、innodb_buffer_pool_sizeの25%程度すればよいらしい。が、大きくても64MB程度とも。

```bash
innodb_buffer_pool_size = 256M
innodb_log_file_size = 64M
```

###MyISAM（グローバル）

MyISAMでは、一部のデータのみをkey_buffer_sizeで指定されたメモリに保存し、それ以外は、OSのメモリに保存するため、key_buffer_sizeを搭載メモリの25%程度に留めて設定し、OSのメモリにデータ等が保存されるよう（OSのメモリを圧迫しないよう）設定します。

key_buffer_sizeを大きくし過ぎると、OSのメモリを圧迫し、むしろパフォーマンスが低下することがあるようです。

* key_buffer_size

```bash
key_buffer_size = 256M
```

###スレッドバッファ

スレッドバッファは、メモリ割りて自体のオーバーヘッドやスレッド（コネクション）毎に利用されるため、あまり大きくし過ぎないことが重要なようです（128K ~ 1M程度）。

* read_buffer_size（index無しの全体スキャン時に利用される）
* sort_buffer_size（ソート処理に利用される）
* read_rnd_buffer_size（indexを利用したソート処理に利用される）

```bash
read_buffer_size = 1M
sort_buffer_size = 1M
read_rnd_buffer_size = 4M
```


##設定情報の確認

###MySQL

####各種パラメータ値

MySQLの現状がどのような設定なのかを確認するには、以下のコマンドを利用します。

```bash
mysql> show variables;
```
like等で絞り込む事もできます。

####そもそもどのエンジンを利用してるか？

デフォルトのエンジンや、DBがどのエンジンを利用しているかの確認。

デフォルトエンジンの確認。

```bash
mysql> show engines;
```
DBの各テーブルがどのエンジンを利用しているか？

```bash
show table status from db_name;
```

エンジンの変更。

```bash
alter table table_name engine=InnoDB;
```
なお、多くの場合、エンジンの変更は問題が無いが、下記の場合には気をつける。

* INSERT IGNOREを利用している場合
* auto_incrementの挙動（InnoDBでは、値が詰まる）


###OS

そもそもOSのメモリの搭載量、使用量を確認するには、

```bash
$ free
```
が一般的です。Linuxに置いて注意するのは、-/+ buffers/cache: 行のfreeの箇所を見ることです（ここが実際の空きメモリに該当）。

##パラメータの設定

MySQL関連の設定は、（私は）my.cnfで行いますが、SET GLOBALコマンドでも設定可能です。

```bash
msyql> set global key_buffer_size = 128 * 1024 * 1024;
```
などとします。
activeadminでCSVダウンロード時のみpaginate外す

paginateをtrueにしていると、CSVダウンロード時にも有効になってしまう。
CSVダウンロード時にはpaginateしたくない。そんな時の対処。

あらかじめ、最大件数を設定しておく

```lang:config/initializers/active_admin.rb
config.max_per_page = 60_000
```

モンキーパッチ当てる（どこかから拾ったんですが・・w)

```lang:lib/monkey_patches/active_admin/resource_controller/collection/pagination.rb
module ActiveAdmin
  class ResourceController
    module Collection
      module Pagination
        def per_page
          return max_per_page if request.format == 'text/csv'
          return max_per_page if active_admin_config.paginate == false
          @per_page || active_admin_config.per_page
        end
      end
    end
  end
end
```

これでOKです。 CSVダウンロード時のみ、最大件数まで取得できます
ちなみに、他のメソッド内とかで呼びたい時は基本、

```
config.max_per_page
```

でいいのですが、たまにnilで返ってくる時があります。（なんか拡張するようなコード書いてる時etc...)
そんな時は、

```
active_admin_config.namespace.application.max_per_page
```

で設定した最大件数が取得できる・・・はず。

何かの参考になれば
MacでcsvがExcelで編集後文字化けするのを修正する

スクリプトで使うcsvファイルをexcelで開いてソートすると、コンソール（ターミナル）から見たとき文字化けしてしまう。その修正方法を備忘録的に。

ここでの文字化けしない＝文字コードUTF-8＋改行コードCR+LF＝コンソールでlessしてみても文字化けしていない　の認識。
なのでこれ以外の設定がいい人は任意で変更してください。

##excelでcsvファイルをソートする（昇順）
ファイ等のcsvをexcelで開いて、フィルタ機能でソート。
終わったらフィルタ消して、一番上の項目（名前、メールアドレスとか）も消す。csvで邪魔になるから
終わったら保存してexcel邪魔だから一旦閉じる。


##テキストエディタを開く
Macでmiを使用。おそらくこの時点では文字化けしていない。
上のメニューから全部変更出来る。
![スクリーンショット 2015-11-10 午前10.55.55.png](https://qiita-image-store.s3.amazonaws.com/0/94362/f6163ba2-879a-2073-b487-6a16473f7532.png)
・文字コードを変更する。
多分最初は「x-mac-japanese」になってるのでそれを「UTF-8」に変更する。
・改行コードを変更する。
こちらも最初は「CR」か「LF」になっているので「CR+LF」に変更する。

できたら保存。テキストエディタややこしいから一旦閉じる。


##コンソールから見れるか確認
コンソール（ターミナル）を開いて文字化けしてないか（ちゃんと見れるか）確認する。

`$ less ファイル名`

ちゃんと表示されてたらok。^Aとか^Mとか白抜き（白背景？）で表示されてたら文字化けなので注意。文字化けしてなかったら改行もちゃんとlessコマンドで表れるはずなので、改行してるかどうかもちゃんと見る。


以上です！めちゃくちゃ初歩なんですけど毎回わすれがちなので
Slim(php)メモ

# .htacess

```
RewriteEngine On

# Some hosts may require you to use the `RewriteBase` directive.
# If you need to use the `RewriteBase` directive, it should be the
# absolute physical path to the directory that contains this htaccess file.
#
# RewriteBase /

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]
```

# サンプル1
http://blogaomu.com/2012/09/23/try-slim-php-micro-framework
powerpoint 2013 > スライドのサイズを変更 > デザインタブ > ユーザ設定 > スライドのサイズ > 標準

```txt:動作確認
PowerPoint 2013
```

スライドを新規作成するとワイドサイズになっていた。

以下で標準のサイズに変更する。
1. デザインタブを開く
2. ユーザ設定を選択
3. スライドのサイズを選択
4. 標準を選択

参考: http://fanblogs.jp/saikyopresen/archive/6/0
【Excel】関数だけで重複項目のチェック

Excelにおいて、手動でデータ入力する際に重複された行とかあったら困るときってありますよね。あるんですよ。
そんな時にさくっと使える技があったのでメモ。

関数で以下のように記述して、あとはオートフィルとかで全適用します。

```
=IF(COUNTIF($C$2:$C$400,C2)>1,"Overlap","")
```

通常のIF関数に、COUNTIFで重複項目範囲と対象を指定し、その個数を数え上げて、個数が1よりも上ならば(=2以上)、Overlapって出力するようにしています。
Maven導入メモ

# Mavenを入れるテスト
- Java 1.8 with Maven
- Eclipse 4.3

## 既存プロジェクトにMavenを入れる
- 参考: http://did2memo.net/2012/12/03/how-to-convert-eclipse-project-with-ant-to-maven-project-procedure/
- 右クリック → 構成 → Mavenプロジェクトへ変換
  - groupIDとかはあんじょうする
- libを消す
- ビルドパスから.jarに通してたものを削除する
- pom.xmlを更新する

## Eclipseのm2eを1.5にアップデートする
- エラー: JREを1.8にしてもMavenを更新するとJ2SE1.4とかになる
- m2eの更新:  http://download.eclipse.org/technology/m2e/milestones/1.5

## プロジェクトファセットを1.8に設定できるようにする
- 参考: http://badbivouac.blog.fc2.com/blog-entry-4.html
- `Java コンパイラー・レベルが、インストールされている Java プロジェクト・ファセットのバージョンと一致しません。 ` というエラー
  - `右クリック → プロパティ → プロジェクトファセット` のJavaが1.8を選択できない
- マーケットプレイスから`Java 8 Facet for Web Tools for Eclipse Kepler SR2`をインストール
- とりあえずエラーは消えた
Mavenを使ってtomcatにJerseyで作成したWebサービスをデプロイするメモ

Mavenを使って既存のリモート(ローカルも可)のtomcatにJerseyで作成したWebサービスをデプロイするメモ

## 環境 
- tomcat7
- Maven 3.3.1
- Java 1.8系

## tomcat側

### tomcat-users.xml

    <tomcat-users>
      <user username="user" password="pass" roles="manager-gui,manager-script" />
    </tomcat-users>

- Managerまわりが入っていなかった場合
    - yum install tomcat7-admin-webapps

## maven側
### setting.xml修正
mavenが参照する設定ファイル。Eclipseで確認する場合は設定>maven>ユーザー設定


      <settings>
        <servers>
          <server>
            <id>tomcat-test</id>
            <username>user</username>
            <password>pass</password>
          </server>
        </servers>
      </settings>

###  pom.xml
    <!-- Tomcat plugin -->  
    <plugin>  
        <groupId>org.apache.tomcat.maven</groupId>  
        <artifactId>tomcat7-maven-plugin</artifactId>  
        <version>2.2</version>  
        <configuration>  
            <server>tomcat-test</server>
            <path>/hogehoge</path>  
            <url>http://SERVER_ADDRESS:8080/manager/text</url>  
        </configuration>  
    </plugin>

### pom.xmlにユーザー設定等をまとめて書くやり方

    <!-- Tomcat plugin -->  
    <plugin>  
        <groupId>org.apache.tomcat.maven</groupId>  
        <artifactId>tomcat7-maven-plugin</artifactId>  
        <version>2.2</version>  
        <configuration>   
            <server>tomcat-test</server>
            <path>/hogehoge</path>  
            <update>true</update>  
            <url>http://SERVER_ADDRESS:8080/manager/text</url>  
            <username>user</username>  
            <password>pass</password>  
        </configuration>  
    </plugin>

## 実行
- goals
 `package tomcat7:deploy`
- deployではすでに存在している場合上書きしてくれない模様なので
 `tomcat7:redeploy` にして行う

### Eclipse上でのエラー
- Dmaven.multiModuleProjectDirectory system propery is not set
 - `-Dmaven.multiModuleProjectDirectory=$M2_HOME` を`Window-> Preference -> Java -> Installed JREs -> Edit`の`Default VM arguments `に入力
 - 参考: http://stackoverflow.com/questions/29330577/maven-3-3-1-eclipse-dmaven-multimoduleprojectdirectory-system-propery-is-not-s
- 他にもJavaがない，みたいなことを言われるときは，`JREシステムライブラリー右クリック → プロパティ → 環境 → 互換性のあるJREにチェック`