OmniAICreator/Qiita-1.07M huggingface dataset:
Tips: HTMLTableElement

# HTMLTableElement.rules
https://developer.mozilla.org/en-US/docs/Web/API/HTMLTableElement/rules

下記のようにすると内罫線が表示される。非表示にしたい場合はこの記述を削除する。

```html
<table rules="all">
```

# HTMLTableElement.cellPadding
https://developer.mozilla.org/en-US/docs/Web/API/HTMLTableElement/cellPadding

テーブルの余白を指定したいとき

# HTMLTableElement.cellSpacing
https://developer.mozilla.org/en-US/docs/Web/API/HTMLTableElement/cellSpacing

テーブルのセル間隔を指定したいとき
内罫線を指定している場合はこの値を大きくすると内罫線も太くなる
Redmineの補助ツール

いろんなところで作られてると思いますが、GitHubやQiitaの使い方を覚えたり、pythonの勉強もかねて。

## 概要
Redmineのチケットの状況を見るツール
pluginみたいに統合されたものではなく、別マシンでデータを集めて表示するだけの仕組みです。

[Y05H1/rtv](https://github.com/Y05H1/rtv)

![rtv-index.png](https://qiita-image-store.s3.amazonaws.com/0/146857/9a562483-c640-cf4f-3d5d-512c40ab3547.png)


## インストール

### 事前準備
必要なライブラリ一式を入れる
CentOS6.8(python2.6.6)で確認

```
# yum install python-setuptools
# easy_install pip
# pip install requests
# yum install python-dateutil
# yum install numpy
# yum install git
```

### インストール
webサーバをインストールしてcloneする

```
# yum install httpd
# cd /var/www/html/
# git clone https://github.com/Y05H1/rtv.git
# /etc/init.d/httpd restart
```

### セットアップ
redmineのapi_keyとhostを設定する

```
# pwd
/var/www/html/rtv/python
# cat collector.py
...
""" parameter """
redmine_api_key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
redmine_host = 'http://127.0.0.1/'
...
```


## 使い方
### Redmineからデータを取得する

```
# pwd
/var/www/html/rtv/python
# python collector.py 
```

### 下記にアクセスする

```
http://<インストールしたマシン>/rtv/
```
[WebPSVR]Windows10でPlaystation VRの加速度を取得する方法(PS4不要)#WebPSVR

#準備するもの
Windows10 installed PC(Not sure before Win7)
Playstation VR

#Please install these software before using WebPSVR
Chrome ver 54+ (Download from [here](https://www.google.com/chrome/browser/desktop/))
Zadig (Download from [here](http://zadig.akeo.ie/))

#Setup
####01. Prepare Windows10 installed PC and Playstation VR
![14876229_1143654875703549_890630932_o.jpg](https://qiita-image-store.s3.amazonaws.com/0/145134/d950b2c0-7d3f-0ffc-3dfc-cc81d1574d34.jpeg)    

####02. Loop HDMI cable from HDMI-PS4 output to front HDMI Input(x □).
![14881348_1143657689036601_1913638751_o.jpg](https://qiita-image-store.s3.amazonaws.com/0/145134/508ac4c1-1258-b378-424e-d81c97052aeb.jpeg)

####03. Connect USB cable to your PC. Plug in AC adapter.
![14881632_1143673199035050_482873905_o.jpg](https://qiita-image-store.s3.amazonaws.com/0/145134/3154096d-bd9c-e419-0c5c-a2a951ab42f2.jpeg)

####04. Connect PSVR HDMI to your PC and other one to unit.
![14858654_1143677369034633_1216067839_o.jpg](https://qiita-image-store.s3.amazonaws.com/0/145134/4f3ba941-5a24-2f19-30c3-9f9f86cef046.jpeg)

####05. Turn on your Playstation VR
![14907813_1143679299034440_2119519959_o.jpg](https://qiita-image-store.s3.amazonaws.com/0/145134/c025ddbd-8f9c-654c-ce21-ef6d7e3134a7.jpeg)

####06. Open Zadig
![01-openZadig.jpg](https://qiita-image-store.s3.amazonaws.com/0/145134/bee0027e-7f4c-5305-ea07-cf118feb43a7.jpeg)

####07. Menu -> Options -> List All Devices
![02-option.jpg](https://qiita-image-store.s3.amazonaws.com/0/145134/b7f738a8-d864-19a2-37fc-4025e11ca9e3.jpeg)

####08. Select "PS VR Sensor(Interface 4)
![03-psvr4.jpg](https://qiita-image-store.s3.amazonaws.com/0/145134/e0f08367-26fd-5b8d-3be4-e9b2dd70dab8.jpeg)

####09. Click Reinstall Driver
![04-reinstall04.jpg](https://qiita-image-store.s3.amazonaws.com/0/145134/378d191d-7bbb-1dda-0bf3-eff71072dc35.jpeg)

####10. Reinstall PSVR driver from Interface 4 - 7
![05to07.jpg](https://qiita-image-store.s3.amazonaws.com/0/145134/770a36a8-5c50-343b-57f0-2ac11b482892.jpeg)

####11. Right click on Google chrome and show "Properties"
![06-chrome.jpg](https://qiita-image-store.s3.amazonaws.com/0/145134/5718fe54-6f8b-7682-7984-6c0253707929.jpeg)

####12. Open "Google Chrome Properties" Menu -> Shortcut -> Target and input
```
"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --disable-webusb-security --enable-webusb --enable-experimental-web-platform-features
```
![10-01-target.jpg](https://qiita-image-store.s3.amazonaws.com/0/145134/c0dd9630-c4e4-5a96-0d3d-1d30392d8a0a.jpeg)


####13. Open [https://webpsvr.github.io](https://webpsvr.github.io)
![11-01-webpsvr.jpg](https://qiita-image-store.s3.amazonaws.com/0/145134/2c9b1964-fd61-529b-8adb-964976bca6c5.jpeg)

####14. Click "Find device" , select PlayStation VR and connect
![12-01.jpg](https://qiita-image-store.s3.amazonaws.com/0/145134/b3529933-fde7-862d-64a2-0c5d2161ac62.jpeg)

####15. If your PSVR's LED turn on with streaming data preview, it is success to use WebPSVR!
![14876020_1143719685697068_27318275_o.jpg](https://qiita-image-store.s3.amazonaws.com/0/145134/528edd02-54b3-426c-c058-6633d2cd0f0f.jpeg)
環境別にcomposer.jsonを使い分ける

やり方
-----------
Composerは`require-dev`で開発環境だけに必要なパッケージを指定できるが、`require-prod`のような本番だけの指定はできない。

そこで、`COMPOSER`環境変数で`composer.json`ファイルを指定することで特定の`.json`を使用することができる。
環境別に例えば、`composer-prod.json`や`composer-dev.json`を作成し、下記の様にパッケージの更新をかけることで、それぞれの環境でことなるパッケージを`require`することができる。

```bash
COMPOSER=composer-dev.json composer update
```

`.lock`ファイルもちゃんと使用した`.json`ファイルのベースネームで作成してくれる。
例えば、`composer-dev.json`からは`composer-dev.lock`が生成される。

[公式ドキュメント](https://getcomposer.org/doc/03-cli.md#composer)

背景
---------
そもそも、なぜこんなことをするかと言うと、[OctoberCMS](http://qiita.com/pikanji/items/ac05bbfbab955bf7fc5b)のようなプラグインアーキテクチャで、composer管理したメインプロジェクトのコードベースの中に、同時開発しているプラグインがある場合、`composer update`することで開発中のプラグインがリリース済みのバージョンで上書きされるのを防ぎたかったから。
composerの使い方次第ではあるが、自作プラグインもcomposerで同時にデプロイして欲しいので`composer.json`の`require`に入れているため、このような問題が起こる。

この解決策としての自分のやり方はこうだ。

`composer-dev.json`の`require`には自作プラグインを含めない。
`composer-prodstg.json`の`require`に自分のプラグインを含める。
ステージング環境で下記でプラグインをデプロイする。

```bash
COMPOSER=composer-prodstg.json composer update
```

テストを実施して問題なければ、生成された`composer-prodstg.lock`をコミットして本番では下記でステージングと同じパッケージ群をデプロイする。

```bash
COMPOSER=composer-prodstg.json composer install
```

いかがでしょう？
Windowsでgem installでSSLのエラーが出た話

WindowsでRails環境を構築しようと思ってRubyInstallerからインストールしたが

```bash
$ gem update --system
ERROR:  While executing gem ... (Gem::RemoteFetcher::FetchError)
SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (https://api.rubygems.org/specs.4.8.gz)
```

とエラーが表示されて先に進めない問題が発生
エラーをググるも，証明書のリンク先が404ばっかりで解決まで手こずったので書き残しておきます

## 解決

- RubyGemsの公式ドキュメントに載ってました
- [SSL Certificate Update - RubyGems Guides](http://guides.rubygems.org/ssl-certificate-update/#installing-using-update-packages)

1. `rubygems-update-x.x.x.gem`をダウンロード
    - [Download RubyGems](https://rubygems.org/pages/download)から
2. コマンドプロンプトでダウンロードしたファイルを実行(手動でのアップデート)

    ```bash
    $ gem install --local ./rubygems-update-x.x.x.gem
    $ update_rubygems --no-ri --no-rdoc
    ```

3. gemのバージョンを確認してx.x.xになっていれば成功

## 解決しなかった人
- 証明書の問題が発生しており，手動で追加する必要があるようです

1. [SSL Certificate Update - RubyGems Guides](https://bundler.io/v2.0/guides/rubygems_tls_ssl_troubleshooting_guide.html#updating-ca-certificates)から`GlobalSignRootCA.pem`をダウンロード
2. 次を実行してrubygemsのパスを取得
 
    ```bash
    $ gem which rubygems
    C:/Ruby/lib/ruby/site_ruby/2.3.0/rubygems.rb(例)
    ```

3. 取得したパスの`.rb`を消して`/ssl_certs`を追記したパスにダウンロードした`GlobalSignRootCA.pem`をコピー

    ```diff
    - C:/Ruby/lib/ruby/site_ruby/2.3.0/rubygems.rb
    + C:/Ruby/lib/ruby/site_ruby/2.3.0/rubygems/ssl_certs
    ```

4. `bundle install`とかやってみてください

## おまけ
- PowerShellでも上記のことができます
ネットワーク接続時に Thumbs.db ファイルの作成を抑制する方法

macOSの
[ネットワーク接続時に .DS_Store ファイルの作成を抑制する方法](http://qiita.com/tetsuo_jp/items/37086621c878d0b2c6f8)
の
>.DS_Store は Windows ユーザからすると不可解なファイル

に対して、
Thumbs.dbはMacユーザからすると不可解なファイル

ネットワークドライブでThumbs.dbを生成させない方法
http://citrras.com/archives/1688
WindowsでThumbs.dbファイルを作成しないようにするhttp://www.atmarkit.co.jp/ait/articles/0602/04/news012.html
調剤薬局のためのデータベース講座 #6.5 在庫データ・出庫データの生成

元動画はこちら https://youtu.be/Q9J7EnkoeRg

```sql:yakkyokuテーブルの作成
CREATE TABLE `yakkyoku` (
  `pharmacy_id` int(11) PRIMARY KEY,
  `name` varchar(45) NOT NULL
);

INSERT INTO `yakkyoku` values
(1, 'とうきょう薬局'),
(2, 'ワシントン薬局'),
(3, 'ロンドン薬局'),
(4, 'パリ薬局'),
(5, 'モスクワ薬局'),
(6, 'ウィーン薬局'),
(7, 'ベルリン薬局'),
(8, 'マドリード薬局'),
(9, 'ローマ薬局'),
(10,'キャンベラ薬局');
```

```sql:zaiko,&nbsp;shukkoテーブルの作成
CREATE TABLE `shukko` (
  `date` date NOT NULL,
  `pharmacy_id` int(10) unsigned NOT NULL,
  `yj` char(12) NOT NULL,
  `amount` float NOT NULL DEFAULT '0',
  PRIMARY KEY (`date`,`pharmacy_id`,`yj`)
);

CREATE TABLE `zaiko` (
  `pharmacy_id` int(10) unsigned NOT NULL DEFAULT '0',
  `yj` char(12) NOT NULL,
  `amount` float unsigned NOT NULL DEFAULT '0',
  PRIMARY KEY (`pharmacy_id`,`yj`)
);
```

```sql:zaiko,&nbsp;shukkoデータのランダム生成
set @saiyo_fact = 0.15,
    @dead_fact = 0.2,
    @shukko_fact = 0.1,
    @zaiko_base = 100,
    @shukko_base = 100,
    @date_begins = '2016-01-01';

truncate table shukko;
truncate table zaiko;
create temporary table if not exists A (n int primary key);
create temporary table if not exists B (n int primary key);
insert ignore into A values (0), (1), (2), (3), (4), (5), (6), (7), (8), (9);
insert ignore into B values (0), (1), (2), (3), (4), (5), (6), (7), (8), (9);

insert ignore into zaiko(
select pharmacy_id, iyakuhin.yj, floor(rand() * @zaiko_base + 1)
       FROM (iyakuhin, yakkyoku)
       left join (SELECT max(c32) as yj FROM y group by c32 having count(c3) = 1) y2 on iyakuhin.yj = y2.yj
       left join (select yj9, count(yj)  as c from iyakuhin where generic = 0 group by yj9) i2 on iyakuhin.yj9 = i2.yj9
       where generic = 0
             and y2.yj is not null
             and (rand() < @saiyo_fact)
             and ((rand() * i2.c) < 1)
       );

insert ignore into zaiko(
select pharmacy_id, iyakuhin.yj, floor(rand() * @zaiko_base + 1)
       FROM (iyakuhin, yakkyoku)
       left join (SELECT max(c32) as yj FROM y group by c32 having count(c3) = 1) y2 on iyakuhin.yj = y2.yj
       left join (select yj9, count(yj)  as c from iyakuhin where generic = 1 group by yj9) i2 on iyakuhin.yj9 = i2.yj9
       where generic = 1
             and y2.yj is not null
             and (rand() < @saiyo_fact)
             and ((rand() * i2.c) < 1)
       );

insert ignore into shukko (
select date, zaiko.pharmacy_id, zaiko.yj, ceil(rand() * 100)
       from (zaiko, (select B.n*10 + A.n as id, adddate(@date_begins, B.n*10 + A.n) as date from A, B) as dates)
       natural left join (select pharmacy_id, yj, rand() as fact from zaiko where rand() < (1 - @dead_fact)) z2
       where dates.id < (91 * fact) 
             and rand() < 0.1);
drop table A, B;
```
iOSのアプリ内WebViewでテキストフィールド内の日本語が未確定の状態のときに「完了(done)」ボタンを押すとフォーカスのイベントが発火する

ま、タイトルのとおりなんですが。

テキストフィールド内で、値をフォーカス時（`focus`、`focusin`どちらでも）に値を変数内に保持し、Blurした時（focusoutでも）に入力内容に変更があればうんぬんかんぬんというJavaScriptを作成していて、一定の条件下でその判定が動かないという現象に遭遇しました。条件は以下です。

- iOSのアプリ内のWebView(8/9で確認、10は未確認。確認後追記します)
- テキストフィールドでの日本語キーボード
- 変換を確定していない段階で「完了(done)」を押す

というものです。

字だけではわかりにくいのでスクリーンショットで解説します。

まず、テキストフィールドに対して、`forcus/focusin`の時点での値と`blur/focusout`での値を表示する領域を作成しました。今回は`forcusin/out`で確認しています。

1. まずは変換を確定後に「完了(done)」を押します<br>
![スクリーンショット 2016-10-31 20.54.20.png](https://qiita-image-store.s3.amazonaws.com/0/4088/4a9f3fd8-bef1-35d7-93c2-c121dfd08a74.png)
2. `blur/focusout`のみに値が表示されます<br>
![スクリーンショット 2016-10-31 20.54.31.png](https://qiita-image-store.s3.amazonaws.com/0/4088/b34a1e35-6169-be8f-2bf1-3919aeddb5f2.png)
3. つぎに変換を確定していない状態で「完了(done)」を押します<br>
![スクリーンショット 2016-10-31 20.55.06.png](https://qiita-image-store.s3.amazonaws.com/0/4088/1653fdd9-19e9-09f4-9242-1c89bf7eff1a.png)
4. `focus/focusin`にも入力内容が表示されます<br>
![スクリーンショット 2016-10-31 20.55.12.png](https://qiita-image-store.s3.amazonaws.com/0/4088/c574c6d0-436e-3922-913b-9b64113d3b4f.png)

この現象はsafariでは確認できていないので、アプリ内のWebViewのみで発生する模様です。フォーカス中のフィールドに対し、フォーカスアウトが発火せずに再度フォーカスが発火するという現象なので、想定していなかったらハマるかと思いますのでご注意を。私はハマりました。

検証用のWebViewだけのアプリとHTMLは

https://maepon.github.io/webViewFocusTest/

に置いておきますので、興味ある方はご参照ください。
SpineにPhotoshopの日本語レイヤーをインポートする方法

#はじめに
Spineが公開しているPhotoshopからレイヤーデータをエクスポートするための拡張スクリプトがありますが、日本語のレイヤーがあるとエラーになってSpine上にインポートすることができません。
せっかくSpine3.0で日本語が扱えるようになったのに・・・って感じですよね。
そこで、Photohop用の拡張スクリプトを改造して日本語レイヤーも扱えるようにしたいと思います。

#どうして日本語レイヤーが使えないのか？
Spine自身は日本語にも対応したはずなのに、なぜ日本語レイヤーがインポートできないのでしょう？
不思議に思って色々調べてみると答えは簡単なことでした。
それは・・・

　　***『出力されるJSONファイルの文字エンコードがShiftJISだから！』***

Photoshopの拡張スクリプトは何も指定していない場合、SHiftJISでデータを出力しようとします。
ところが、Spine内部ではFTF-8として読込を行うので日本語が含まれていると文字化けしてエラーになるんですね＾＾；

#じゃぁ、どうすればいいの？
文字エンコードの違いが問題なら解決方法は簡単♪
PhotoshopからエクスポートしたJSONファイルをUTF-8に変換して保存しなおせば万事解決！
めでたしめでたし♪・・・じゃないですよねｗ

#スクリプトを改造して日本語もサポートさせる
いちいち手動で変換してやるなんで面倒すぎ！
ということで、本題です。と言っても直ぐに終わります。
「Photoshopの拡張スクリプトは何も指定していない場合、SHiftJISでデータを出力しようとする」わけだから、UTF-8で出力しろと指定すれば済むだけの話です。

やりかたは、LayerToPNG.jsxの215行目に以下の1行を追加すればOK

　　file .encoding = "UTF-8";

バージョンの違いで行番号が変わってる可能性もあるので「// Output JSON file.」というコメント探して、以下のコードのように書き換えれば大丈夫だと思います。

```LayerToPNG.jsx
// Output JSON file.
if (writeJson) {
	var name = decodeURI(originalDoc.name);
	name = name.substring(0, name.indexOf("."));
	var file = new File(absProjectDir + name + ".json");
	file.remove();
	file.open("w", "TEXT");
	file .encoding = "UTF-8";   // ←ここに追加
	file.lineFeed = "\n";
	file.write(json);
	file.close();
}
```

この一行を追加するだけで日本語も対応完了＾＾ｖ
Spineでの作業が楽になりますよ♪
Rubyでarrayにインデクシング

ruby で array.indexが遅いのがいやなので、hashに変換する関数を書いた。

```rb
def indexing(arr)
	last = arr.length-1
	arr2 = (0..last).to_a
	tarr = [arr.reverse, arr2.reverse].transpose
	Hash[*tarr.flatten]
end
```

使い方は

```rb
arr1 = ["hoge", "huga", "hana", "foo", "bar", "hoge"]
arr1_indexed = indexing arr1
arr1_indexed["hoge"] # => 0
```

元からこういうのあったら恥ずかしいですね。。

追記：みなさまコメントありがとうございます。

```rb
arr1.each_with_index.inject({}){|h, v| (h[v[0]] = v[1]) unless h[v[0]]; h}
```

でOKですね。
オフラインリアルタイムどう書くE09 の問題の ruby による実装例


問題 : http://nabetani.sakura.ne.jp/hena/orde09_penwa/
実装リンク集 : http://qiita.com/Nabetani/items/1c0a2bb20b3ab3e7f55b

5角形という、扱うことがあまりない図形を扱う問題。
難しかった模様。

5角形の向きは 4種類、辺は各5本なので、4×5=20 個の条件を書ききれば勝てるはず。
座標系の導入には、

* 六角形のあつまりとみなす
* 四角形のあつまりとみなす

という2つの視点が考えられて、どちらでも解けるけど、後者のほうが楽になるんじゃないかなぁ。

私の実装は、ちと長くなったけどこんな感じになった。


```ruby
class Stat < Struct.new( :x, :y, :f, :dir )
  def initialize( x, y, f, dir )
    super( x, y, f, dir )
  end
  def key
    [x,y,f].join(",")
  end
  def horz?
    x%2 == y%2
  end
  def upside_down
    Stat.new( x, -y, horz? ? 1-f : f,-dir )
  end
  def flip
    Stat.new( y,x+1,f,-dir )
  end
  def unflip
    Stat.new( y-1,x,f,-dir )
  end
end

def move_h( s )
  case s.f
  when 0
    case s.dir % 5
    when 0; Stat.new( s.x, s.y, 1, 0 )
    when 1; Stat.new( s.x+1, s.y, 0, 2  )
    when 2; Stat.new( s.x, s.y-1, 1, 1 )
    when 3; Stat.new( s.x, s.y-1, 0, 4 )
    when 4; Stat.new( s.x-1, s.y, 1, 3  )
    end
  when 1
    move_h( s.upside_down ).upside_down
  end
end

def move_v( s )
  move_h( s.flip ).unflip
end

def move( cmd, s )
  case cmd
  when "a"; Stat.new( s.x, s.y, s.f, s.dir+4 )
  when "c"; Stat.new( s.x, s.y, s.f, s.dir+1)
  when "F"; s.horz? ? move_h(s) : move_v(s)
  end
end

def solve(src)
  stat=Stat.new( 0, 0, 1, 0 )
  hist={stat.key=>0}
  src.each_char do |cmd|
    new_stat = move( cmd, stat )
    if cmd=="F"
      if n=hist[new_stat.key]
        return [ hist.size, n].join(",")
      end
      hist[new_stat.key] = hist.size
    end
    stat=new_stat
  end
  return "-"
end

if $0==__FILE__
  DATA.each do |line|
    num, src, expected = line.split(/\s+/)
    actual = solve( src )
    ok = actual==expected
    p [ ok ? "ok" : "**NG**", num, src, expected, actual ]
  end
end

__END__
0 FcFcFaF 3,0
1 FccFaaFcFcF -
```

私は四角形の集まりとみなす方にした。
五角形のマスを特定するには `[ x, y, f ]` という3つの数が必要で、`f` は 0 または 1。

`x%2==y%2` の場合、水平分割、そうでなければ垂直分割。
`f` の値が 0 だと上または左で、1だと下または右だったと思う。

`flip` と `upside_down` を使って、水平分割のマスの上部に寄せて移動。`unflip` と `upside_down` で元に戻す。という作戦。

`flip` は、概ね x と y の入れ替えなんだけど、水平分割のマスを `flip` すると垂直分割のマスになって欲しいので、ちょっとゴニョゴニョしている。ゴニョゴニョの影響で、 `unflip` が必要になっている。なまえは transpose の方が良かったかな。
gradleでのjava起動オプションの設定

#gradleでのjava起動オプションの設定
jvmArgsに値を設定することでjava起動オプションが反映される。

```build.gradle
jvmArgs = ['-Dspring.profiles.active=test']
```


#gradle経由でspringテスト実行時のapplication.propertiesを切り替える
以下のように設定することでテスト実行時のプロパティファイルを
`application.properties`から`application-test.properties`に切り替えることが可能。

```build.gradle
test {
  // テスト用プロパティファイルの読み込み（application-test.properties）
  jvmArgs = ['-Dspring.profiles.active=test'] 
}
```

#参考サイト
application.propertiesの切替方法や読込順に関しては
以下のサイトが非常に詳しく記載してあって分かりやすいです。

[Spring Bootの外部設定値の扱い方を理解する](http://qiita.com/kazuki43zoo/items/0ce92fce6d6f3b7bf8eb#%E5%A4%96%E9%83%A8%E8%A8%AD%E5%AE%9A%E5%80%A4%E3%81%AE%E6%8C%87%E5%AE%9A%E6%96%B9%E6%B3%95)
ネットワーク接続時に .DS_Store ファイルの作成を抑制する方法

以下を実行して再起動すると良い．[出典](https://support.apple.com/ja-jp/HT1629)

```bash
defaults write com.apple.desktopservices DSDontWriteNetworkStores true
```
# 設定した理由

* .DS_Storeとは？ shttps://en.wikipedia.org/wiki/.DS_Store
* .DS_Store は Windows ユーザからすると不可解なファイル
Caution Java String#split

渡されたデータによっては期待する配列を返してくれないというお話。

https://docs.oracle.com/javase/jp/8/docs/api/java/lang/String.html#split-java.lang.String-

```java:split.java
String str = ",,,";
String[] arrays = str.split(",")
# arrays => []
# arrays.length => 0
```

このように、例えば、「,,,」というデータを受け取ると長さ0の配列を返す。
これをカンマで区切られた空文字もデータとして扱いたい場合は次のように書く。
String#split(String regex, int limit) とlimit引数のあるAPIを利用する。

https://docs.oracle.com/javase/jp/8/docs/api/java/lang/String.html#split-java.lang.String-int-

```java:split.java
String str = ",,,";
String[] arrays = str.split(",", -1)
# arrays => ["", "", "", "", ""]
# arrays.length => 4
```

これはlimitに負の値を渡すことで配列の長さが制限されないようになるため、空文字もデータと見なして配列を返してくれるようになる。
ふぁ、ファイルが作れない！

# File fromF = new File(ret[0]);じゃ、ダメ。File fromF = new File(ret[0].trim())でなくっちゃ！;

 	    File fromF = new File(ret[0].trim());
 	    if(fromF.exists()){
	        System.out.println("存在"); 	    	
 	    }else{
	        System.out.println("不在");
 	    }
実行結果は、「存在」
しか〜し、
 	    File fromF = new File(ret[0]);
 	    if(fromF.exists()){
	        System.out.println("存在"); 	    	
 	    }else{
	        System.out.println("不在");
 	    }
だと、実行結果は、「不在」となるんですね。
知らんかった！

<h1>$timeって、シェルの予約語なのか〜、知らんかった！</h1>

$ mdfind 'kMDItemDisplayName=="*.tex" && kMDItemFSCreationDate><b><font color=red>$time.iso(2009-10-01)</font></b> && kMDItemFSCreatorCode!="MMKE"'
:relaxed:
いまさらだけど、iOS 7型のアプリケーションレシートとアプリ内課金レシートの挙動をまとめた

もはや3年も前の話ですが、iOS 7からSKPaymentTransactionオブジェクトからレシートを取得することがdeprecatedになりました(Swiftではそもそも取得できない)。
代わりに、以下のコードでアプリケーションレシートを取得すれば、購入時のレシート情報を確認することが出来ます。

```NSData(contentsOfURL: NSBundle.mainBundle().appStoreReceiptURL!);```

最近になってようやくiOS 7型のレシートの挙動について調べたので、
iOS 7型のアプリケーションレシートの処理を実際に動かしてみて分かったことを備忘録的にまとめました。

- Apple IDでログインしていても、アプリインストール時点ではアプリケーションレシートはnil
- リストア/課金を行うことでアプリケーションレシートにアプリ内課金レシート情報が書き込まれる
- Apple IDをサインアウトしたり別のApple IDでサインインしても、アプリケーションレシートにアプリ内課金レシート情報は残る
 - ただし、後者のApple IDで購読したりリストアして過去のトランザクションを復元した場合、後者のApple IDの課金レシートのみになる
- アプリをアンインストールするとアプリケーションレシートは消える(その際、paymentTransactionのレシート情報も消える)
- アプリケーションレシート内の`in_app`にはアプリケーションで処理したpaymentTransactionのレシートが含まれる
- アプリケーションレシート内の`latest_receipt_info`には全てのpaymentTransactionのレシートが含まれる

以上。
Jessie Backports に Nginx の HTTP2 版が来ていた

SPDYってもう古いのね。
Nginxで設定してもChromeで使えない。
なのでHTTP2を使おうとして…。

Nginx公式サイトのDebian用リポジトリを追加してインストールしてもHTTP2がオンにならない。
…と思ったら、OpenSSLの方も1.0.2にしないといけないらしい。

で、こちら。
http://serverfault.com/questions/775298/debian-jessie-nginx-with-openssl-1-0-2-to-use-alpn-rather-than-npn
8月の投稿だけれども、jessie backports で使えるようになっているようだ。
AdWords APIを利用して、広告運用の仕事を95%削減するまで


# はじめに
Google AdWordsの運用を任され、2週間で一定の成果を出せた。
次に取り掛かる仕事もあるため、自動化をしようと思う。

利用するのは、[AdWords API](https://developers.google.com/adwords/api/docs/guides/start?hl=ja)である。
![logo](https://developers.google.com/adwords/images/150512_Ads_AP01-04.png)

# 導入の目的

今回、自分が導入しようと思った目的は以下のとおり。

- 広告レポートを自動で取得し保存
- 実際の成果データと、レポートデータを紐付ける (※1)
- 指定したルールに応じて、広告の停止/CPCの調整を行う
- クリエイティブメンバー用のレポートツールを自動で作成 (※2)

※1 AdWordsでは、成果通知タグで成果のカウントができる。
しかし、タグだけでは成果がカウントされないことがある。
タグで成果を測る場合、1〜3割くらい成果が欠損する。

※2 弊社では、広告運用担当とクリエイティブ担当がペアとなって広告を運用する。
クリエイティブ担当は画像を作成し、運用担当は数値を調整したりする。
クリエイティブ担当に、どのクリエイティブの効果がよかったかという資料をつくるのは運用担当。


ちなみに公式サイトには以下のように書いてある。

> 一般的な活用例は以下のとおりです。
> 
> アカウント管理の自動化
> カスタム レポートの作成
> 商品の在庫に合わせた広告の管理
> ビジネスデータを基準にした入札単価の管理

# 導入の効果
## 導入前
- 各案件ごとにレポート作成 : 10分 × 案件数
- 広告の配信/停止設定 : 5分 × 案件数
- CPCの調整 : 5分 × 案件数

## 導入後
- CPCと広告配信状況を目視でチェック : 1分 × 案件数

## 結果
改善前 : 20分/案件
改善後 : 1分/案件
ということで、もとの1/20 = 5%まで削減された。

# 導入手順
## AdWordsAPI利用の申込
以下のページがよくまとまっている。
[キーワードプランナーもログインせずに自由自在！ AdWords API の申請と使い方](http://pct.unifas.net/programming/php/2874/)

記事に書いてある通り、実際に利用するためには、
何のために、どのように利用するかという資料が必要となる。
自分が提出した資料は以下のものである。

![ab8c818e-55ad-3b21-0601-84d0cfba7bfc.png](https://qiita-image-store.s3.amazonaws.com/0/14275/bc544665-e2cb-0692-63d0-df837e04044e.png "ab8c818e-55ad-3b21-0601-84d0cfba7bfc.png")


## プロジェクトの作成
[AdWords APIのライブラリ](https://developers.google.com/adwords/api/docs/clientlibraries?hl=ja)として、Java, .NET, PHP, PERL, Python, Rubyが用意されている。
今回の言語はPHPを利用した。

つまづきやすいポイントは、composerの設定と、初期設定ファイル置き場なので、そこだけまとめておく。

### composerの設定
公式に書いてあるとおり、PHPライブラリにはネームスペースが使われていない。
理由は、ネームスペースがコンフリクトする箇所があるからだ。

ということで、composer.jsonを以下のように設定した。

```
{
    "repositories": [
        {"type": "vcs", "url": "git@github.com:googleads/googleads-php-lib.git"}
    ],
    "require": {
        "googleads/googleads-php-lib": "dev-master"
    },
    "autoload": {
        "classmap": [
            "var/composer/vendor/googleads/googleads-php-lib/src/Google/Api/Ads/AdWords/Util/v201609"
        ]
    },
    "config": {
        "vendor-dir": "var/composer/vendor"
    },
    "minimum-stability": "dev"
}
```

### 設定ファイルの置き場所
設定ファイルはcomposerでインストールしたフォルダ内に置く必要がある。
プロジェクトフォルダ内に置けないので注意。

ちなみに設定すべきファイルは以下の2つ。

```
googleads-php-lib/src/Google/Api/Ads/AdWords/auth.ini
googleads-php-lib/src/Google/Api/Ads/AdWords/settings.ini
```

## 実際の画面
### 自動でCPCを調整
自動で推奨CPCを計算して設定することができる。
JavaScriptを利用して、テーブルのソートが行えるようになっている。
自動で推奨CPCを設定することも可能。
![cpcs.png](https://qiita-image-store.s3.amazonaws.com/0/14275/ea211bba-3726-2888-1b74-6867edde2af1.png "cpcs.png")


### 広告ごとのパフォーマンスのレポート
自動でレポートがダウンロードされ、成果のよい広告を一覧できる。
JavaScriptを利用して、テーブルのソートが行えるようになっている。
成果の悪い広告は自動で停止させることもできる。

![creatives.png](https://qiita-image-store.s3.amazonaws.com/0/14275/1ec86f75-4a5d-e343-6111-aeac01042e9a.png "creatives.png")


# まとめ
これまではAdWordsの運用担当と、クリエイティブ担当が必要だったが、
AdWordsAPIを利用することにより、運用担当者を(ほぼ)不在にすることができた。

今後、もしも開発を続けるとしたら、以下の機能を追加していくだろう。

- CPCの調整に地域属性/デバイス/時間帯を考慮に入れる
- 一度の入稿で、複数広告グループに同じ広告を追加 ※ AdWordsEditorで代用可
PHP セレクトボックスはfor,while,foreachを使っても作れる

■test05.php 入力画面
■foreach構文版

```php
	<form action="test05_output.php" method="post">
		<p>
			<select name="number">
			<?php
			$number = array (
					"10",
					"20",
					"30",
					"40",
					"50"
			);
			foreach ( $number as $value ) {
				echo '<option value="', $value, '">', $value, '</option>';
			}
			?>
			</select>
		</p>

		<input type="submit" value="送信">
```

■for構文版

```php
<body>

	<form action="test05_output.php" method="post">
		<p>
			<select name="number">
		<?php
		for($number = 10; $number <= 50; $number = $number + 10) {
			echo '<option value="', $number, '">', $number, '</option>';
		}
		?>
		</select>
		</p>

		<input type="submit" value="送信">

	</form>

</body>
```

■while版

```php
<body>

	<form action="test05_output.php" method="post">
		<p>
			<select name="number">
			<?php
			$number = 10;
			while ( $number <= 50 ) {
				echo '
				<option value="', $number, '">', $number, '</option>';
				$number = $number + 10;
			}
			?>
			</select>
		</p>

		<input type="submit" value="送信">

	</form>

</body>
```
■test05_output.php 結果画面

```php
<?php
$number = $_POST ['number'];
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xm1ns="http://www.w3.org/1999/xhtml">
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="Content-Script-Type" content="text/javascript">


	<title>PHP入門</title>

</head>
<body>
<?php
echo $number;
?>

</body>
</html>
```
javascriptのaddEventListenerで実機の反応が悪いときはHTMLのaタグを疑ってみる話

なんか実機でスクロールとクリックイベントが重なると反応が悪いと思ったら、buttonで実装すればよかったみたい。

`a`じゃなく`button`でHTMLコーディングすれば👌。

リンクイベントと重なるのかな。
とりあえず反応が直感的になってよかった。
[EN][TIPS] Relating issue and commits in GitHub

Have you ever had troubles looking back at your old commits, looking for when you have made certain change?

Sometimes when we look back at commits, we face trouble that we do NOT know in which commit we made change, and which commit was related to which issue.

And when this kind of things happen, we will not be able to check diffs, or even roll-back, just because we don't know when & where the change was made.

So, to resolve that kind of problems, lets use a small tip that will eventually save your day.

# Relating commits with issue
All you need to do to relate issue & commit is just write a bit on your <b>commit message</b>.

All you need, is just add ```#<issue-number>``` in your commit message.

For example, write commit message like this.
```edit readme for "Relate issue and Commits" sample #1```

By putting ```#1``` at the end of commit message, this commit will be related with <b>Issue or PullRequest #1</b>.

And when you <b>push</b> your changes, this commit message will be shown in the Issue / PullRequest page, as shown in the image below.

![スクリーンショット 2016-10-31 17.22.12_2.png](https://qiita-image-store.s3.amazonaws.com/0/85904/3d0bef3b-74ca-4002-ad94-df280bf273d4.png)

You can check the actual sample issue here
https://github.com/table-cloth/Sandbox/issues/1

And now we are done!
Have a nice day :satisfied:
Unity Cloud Buildでユニットテストを実行するには

## はじめに
Unity Cloud Buildにはビルド時にユニットテストを実行する機能があります。今回はその設定方法を紹介したいと思います。


## 前提条件
* Unity Cloud Buildの基本設定が完了していること
* Unityのバージョンは5.4.1f1で確認


## テストスクリプトの作成
Projectウィンドウ左上の「Create」→「Editor Test C# Script」をクリックし、テストスクリプトを作成します。今回は「SampleTest」という名前でテストスクリプトを作成します。あくまでもサンプルなので、テストスクリプトの中身はデフォルトのまま使うことにします。

![Kobito.dhH7CE.png](https://qiita-image-store.s3.amazonaws.com/0/5879/23c7a673-fd57-4dcb-9045-b0fd5341dc4b.png "Kobito.dhH7CE.png")

```C#:SampleTest.cs
using UnityEngine;
using UnityEditor;
using NUnit.Framework;

public class SampleTest {

	[Test]
	public void EditorTest()
	{
		//Arrange
		var gameObject = new GameObject();

		//Act
		//Try to rename the GameObject
		var newGameObjectName = "My game object";
		gameObject.name = newGameObjectName;

		//Assert
		//The object has a new name
		Assert.AreEqual(newGameObjectName, gameObject.name);
	}
}
```


## テストの実行
メニューの「Window」→「Editor Tests Runner」をクリックし、Editor Testsウィンドウを表示します。

![Kobito.IueDn8.png](https://qiita-image-store.s3.amazonaws.com/0/5879/d59cf5bc-ada9-d7bd-a20b-998cd4f74b34.png "Kobito.IueDn8.png")


Editor Testsウィンドウの左上の「Run All」ボタンをクリックするとテストが実行されます。Unity Cloud Build上でテストを実行する前に、まずはローカルでテストが成功することを確認します。グリーンになればテスト成功です。

![Kobito.Uqi2bc.png](https://qiita-image-store.s3.amazonaws.com/0/5879/51dd4c7a-ff37-bdd1-c535-fd5be86e3e82.png "Kobito.Uqi2bc.png")


テストの動作確認が完了したら、Unity Cloud Build上でテストを実行するためにテストスクリプトをリポジトリにcommit/pushしておきます。


## Unity Cloud Buildの設定
Unity Cloud Buildの「設定」→「テストの設定を表示」の中の「テスト設定の変更」をクリックします。

![Kobito.bVwvZp.png](https://qiita-image-store.s3.amazonaws.com/0/5879/69b6f366-5479-e779-adcf-7d2aacf64abc.png "Kobito.bVwvZp.png")


「Enabled」にチェックを入れて「Next Save→」をクリックします。

![Kobito.ms9HVq.png](https://qiita-image-store.s3.amazonaws.com/0/5879/93d903c4-5954-d327-4da8-54e735bccf6a.png "Kobito.ms9HVq.png")


なお、ここで設定可能なオプションの説明は以下の通りです。

| オプション | 説明 |
|--------------------|--------------------|
| Enabled | ビルド時にユニットテストを実行する |
| Failed Unit Test Fails Build | ユニットテストが失敗した場合にビルドを失敗扱いとする |
| Unit Test Method Name | ユニットテストを実行するメソッド名(特に変更する必要なし) |


早速ビルドを実行し、完了後にテスト結果を確認してみましょう。「履歴」タブの当該ビルドの「ログ」をクリックします。

![Kobito.68cxBX.png](https://qiita-image-store.s3.amazonaws.com/0/5879/e2d93f08-28b1-4fb8-a399-008d8590858c.png "Kobito.68cxBX.png")


一番右側の「Tests」をクリックするとユニットテストの結果が表示されます。

![Kobito.xWhDTo.png](https://qiita-image-store.s3.amazonaws.com/0/5879/ea271c10-1ec6-5e2e-8ab3-0122517f765b.png "Kobito.xWhDTo.png")


なお、テストケースが1ケースしか存在しない場合、「undefined - 5」と表示されますが、テストケースが複数ある場合は以下のように正しく結果が表示されます。これでUnity Cloud Build上でユニットテストを実行することができました。

![Kobito.iwobSs.png](https://qiita-image-store.s3.amazonaws.com/0/5879/7a8b764b-df07-fcb4-502f-609bd7ecc141.png "Kobito.iwobSs.png")


また、「履歴」タブの各ビルドの一番右にある「▼」をクリックし、「Unit Tests のダウンロード」をクリックすると、ビルドに紐づくユニットテストの実行結果をXML形式でダウンロードすることができます。

![Kobito.7IMo6J.png](https://qiita-image-store.s3.amazonaws.com/0/5879/619e7155-df29-6b3c-85e3-2fb643158a60.png "Kobito.7IMo6J.png")


## 参考
* [Unity Cloud Buildの使い方](http://www.slideshare.net/MakotoIto2/unity-cloud-build-61397358 "Unity Cloud Buildの使い方")
フロントエンドの技術メモ1

jQueryにはもう頼らない！無限スクロールをネイティブで実装する最新テクニック
https://www.webprofessional.jp/intersectionobserver-api/


UX思考を学ぶ。UIデザインパターン全28選
http://ohako-inc.jp/uiux-japan/ui-design/201410-ui_design_patterns.html
[Resolved] Qiita > ストック数の多い記事を{ ストック | ストック解除 }できない

```txt:動作環境
Windows 7pro
Windows 8.1 pro
Windows 10
各OS上でGoogle Chrome(最新版)を使用
```

ここ数日、Qiitaの記事のストックをしようとしても処理が重いです。

2つの異なるネットワーク環境で再現しています。

1500ストックの記事をストックしようとしたらタイムアウトのためかストックできませんでした。

こちらの環境なのか、Qiita側の問題かは切り分けできていません。

<hr>
(追記 2016/11/16)

「いいね」機能が追加された頃から正常に機能するようになったようです。
五角形の世界であなたは過去の自分に出会う


- 図形はだめ
  - 立体図形じゃないだけましですが…
  - 六角形ですらきついのに五角形とか。
  - はなびら([凸頂点の数](http://nabetani.sakura.ne.jp/hena/orde03nofconv/))はxy座標に直せましたが、今回は…
- しえるさんごろし禁止＾ｑ＾
  - 前回は手を動かすことができたでしょうが、今回は１時間座っているだけだった可能性もありえます…

## 答案1

- 縦長の六角形と見て、上が0、左が1、右が2、下が3

```rb:tyama_henae09.rb
#!/usr/bin/env ruby
#http://nabetani.sakura.ne.jp/hena/orde09_penwa/
#http://qiita.com/Nabetani/items/1c0a2bb20b3ab3e7f55b

T=[
	[[0,0,1,4],[-1,0,2,3],[0,-1,3,2],[1,-1,1,2],[0,0,2,1]],
	[[0,0,2,0],[0,0,3,4],[-1,1,0,3],[-1,0,3,1],[0,0,0,0]],
	[[0,0,1,0],[0,0,0,4],[1,-1,3,3],[1,0,0,1],[0,0,3,0]],
	[[0,0,2,4],[1,0,1,3],[0,1,0,2],[-1,1,2,2],[0,0,1,1]],
]

while gets
	cur=[0,0,0,2]
	trail={cur[0,3]=>0}
	i=0
	if $_.chomp.each_char{|c|
		if c=='a'
			cur[3]=(cur[3]-1)%5
		elsif c=='c'
			cur[3]=(cur[3]+1)%5
		elsif c=='F'
			i+=1
			dx,dy,z,dir=T[cur[2]][cur[3]]
			cur=[cur[0]+dx,cur[1]+dy,z,dir]
			if trail.has_key?(cur[0,3])
				puts '%d,%d'%[i,trail[cur[0,3]]]
				break
			end
			trail[cur[0,3]]=i
		end
	}
		puts '-'
	end
	STDOUT.flush
end
```

## 答案2

手裏剣型なら1つの五角形を回転移動させて単位図形を作れるのか…悔しい…

```rb:e09_mod.rb
=begin
T=[
	[[0,0,1,1],[0,0,3,0],[0,-1,2,2],[0,-1,1,4],[1,0,3,3]],
	[[0,0,2,1],[0,0,0,0],[1,0,3,2],[1,0,2,4],[0,1,0,3]],
	[[0,0,3,1],[0,0,1,0],[0,1,0,2],[0,1,3,4],[-1,0,1,3]],
	[[0,0,0,1],[0,0,2,0],[-1,0,1,2],[-1,0,0,4],[0,-1,2,3]],
]
=end
D=[[0,-1],[1,0],[0,1],[-1,0]]
T=4.times.map{|i|
	[[0,0,(i+1)%4,1],[0,0,(i+3)%4,0],[*D[i],(i+2)%4,2],[*D[i],(i+1)%4,4],[*D[(i+1)%4],(i+3)%4,3]]
}
```
RedHatEnterpriseLinuxのインストール

# RHEL6.5をインストールしてみる。

**これはだいぶ昔に書いたブログ（今は消滅）の記事です。
間違ってた箇所、更新された箇所などあればご指摘ください。**

1. オフィシャルからRHEL6.5をダウンロード。
(要会員登録)

2.インストール作業。
基本的にはすべてはいを選択。
サーバーは「基本サーバ」で。
(こっそりGUI入れましたが。)

3.インストール後、SELinux、IPtablesの無効化

``` 
/etc/rc.d/init.d/iptables stop
chkconfig iptables off

chkconfig --list iptables
iptables 0:off 1:off 2:off 3:off 4:off 5:off 6:off

setenforce 0
```

4.host設定

```
IPADDR=XXX.XXX.XXX.XXX
DNS1=XXX.XXX.XXX.XXX
GATEWAY=XXX.XXX.XXX.XXX
NETMASK=XXX.XXX.XXX.XXX

ONBOOT=no
↓
ONBOOT=yes

BOOTPROTO=dhcp
↓
BOOTPROTO=static
```


5.リポジトリをEPEL(centOSのリポジトリ)に変更（無償で使う場合のみ）

uname -a

であらかじめ、x86_64かi386か見ておくこと。

```
wget http://dl.fedoraproject.org/pub/epel/6Server/x86_64/epel-release-6-8.noarch.rpm
rpm -Uvh epel-release-6-8.noarch.rpm
```

6.リブート

```
reboot
```

インストール完了！
遊び倒すぞっ！！！
Hiveクエリでハマりやすいエラーの処方箋

HIVEクエリを書いていてハマったエラーと、その対処法を記載していきます。

### WINDOW関数で集計範囲が異なる時のエラー

ROWS BETWEENかの指定が異なる物が混じってるときに発生するエラーです。
他と記述を合わせることで、エラーは解消しました。

```
FAILED: SemanticException Failed to breakup Windowing invocations into Groups. At least 1 group must only depend on input columns. Also check for circular dependencies. 
Underlying error: Expecting right window frame boundary for function lag((TOK_TABLE_OR_COL weight), 12) 
```

エラーが発生するクエリの例

```sql
SELECT
  last_value(weight) over(PARTITION BY pref_name,city_name ORDER BY year_month ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) as last_weight,
  lag(weight, 12) over(PARTITION BY pref_name,city_name ORDER BY year_month ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
FROM
  ...
```

### WINDOW関数のLAG/LEAD関数のハマリどころ

1つ前の値を次のように取ろうとすると、Prestoでは動きますがHiveではエラーとなります。

```sql
SELECT
  --1つ前の値を取得するLAG関数
  LAG(weight) over(partition by pref_name, city_name order by year_month ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)
FROM
 ...
```

解決法は簡単です。次のようなエラーが起きたら、`ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING`と指定しましょう。

```
FAILED: SemanticException Failed to breakup Windowing invocations into Groups. At least 1 group must only depend on input columns. Also check for circular dependencies.
Underlying error: Expecting left window frame boundary for function LAG((TOK_TABLE_OR_COL weight)) org.apache.hadoop.hive.ql.parse.WindowingSpec$WindowSpec@75a39d3e as _wcol0 to be unbounded. Found : 1
```

ここでもし、`1 PRECEDING`を`UNBOUNDED PRECEDING` に書き換えても、エラー出力にrightの差はあるが同様にエラーとなります。


```sql
SELECT
  --1つ前の値を取得するLAG関数
  LAG(weight) over(partition by pref_name, city_name order by year_month ROWS BETWEEN UNBOUNDED PRECEDING AND 1 FOLLOWING) 
FROM
 ...
```

```
FAILED: SemanticException Failed to breakup Windowing invocations into Groups. At least 1 group must only depend on input columns. Also check for circular dependencies.
Underlying error: Expecting right window frame boundary for function LAG((TOK_TABLE_OR_COL weight))
```



<!--
### WINDOW関数で集計範囲が異なるためのエラー

### empty string

count(1) でも良いので、意味の無い集計クエリに書き換えると解消します。（TODO）

-->
phpの5.5へのバージョンアップによるlibphp5.so抜け落ち問題

# phpのバージョンアップによるlibphp5.so抜け落ち問題

**これはだいぶ昔に書いたブログ（今は消滅）の記事です。
間違ってた箇所、更新された箇所などあればご指摘ください。**

http://web.mt-systems.jp/archives/889

上記サイトを見てphpをインストールしたところ、
phpファイルが閲覧できない問題が…


どうやら

http://blog.goo.ne.jp/ucchanx/e/16bb2144ce134a9e15c7e946cebde170

を見たところ、phpのバージョンアップを行うと、「libphp5.so」が生成されないケースがあるとのこと。

```
sudo apt-get install libapache2-mod-php5
```

を行うことで、正常にサイトを閲覧できるようになった。

httpd.conf周りの問題と考えてて、気づくのが遅かった…。。。

なんにせよ、これでphp5.5にバージョンアップ完了！！
expectを使ってみた

# expectを使ってみた

**これはだいぶ昔に書いたブログ（今は消滅）の記事です。
間違ってた箇所、更新された箇所などあればご指摘ください。**

scpって言うファイルの転送コマンドがあるのですが、これ、対話型なんで、
phpなどでスクリプトキックしてもうまく転送してくれなかったりするんですよ。

そんな時に使うのがexpect。
何かを入力するときに自動的に入力してくれる素敵コマンドです。
素敵です。shell叩くだけでファイル転送してくれます。

作ってみたは良い物の、正直言うとshell初心者なので、結構ひどい事になってます。。。

添削できる方・・・添削をお願いします！

scp_send_file.sh
Shell

```
#!/bin/sh
# $1 scp_send_file example: working.txt
# $2 scp_send_host example: hage@hogehoge.jp
# $3 password example: hogehoge
# $4 port example: 22
# *usage
# ./scp_send_file.sh working.txt hage@hogehoge.jp hogehoge 22

expect -c "set timeout 5
spawn scp -P $4 $1 $2:$1
expect \"s password\"
send \"$3\n\"
interact"
```
もしもディレクトリ内に~（チルダ）ディレクトリができてしまったら

# もしもディレクトリ内に~（チルダ）ディレクトリができてしまったら

こんばんは、あまりネタがないのでちょっとした小ネタでも書いておきます。

## 恐怖の~（チルダ）ディレクトリ

ふと、サーバーを見てみると、怪しげなディレクトリが。

```
[rache@testserverF1 work]$ ls
html                   lib
test				   ~
```

こいつ消そうにも、この~マークはホームディレクトリを示しているので簡単には消せないんですよね。
下手にrm -r ~/ とか打ってしまったら、大爆笑者です。
ホームディレクトリが全消しされ、大発狂することになってしまいます。

## どうすれば消せるのか

1. `rm -r ./~/`

./を加えることで、このディレクトリにあるチルダディレクトリを消せという意味になります。

2. `rm -r \~/`

　\(エスケープ文字)を加えることで、このディレクトリにあるチルダディレクトリを消せという意味になります。

上記二通りの削除方法があります。

## 検証

```
[rache@testserverF1 work]$ rm -fr ./~/
[rache@testserverF1 work]$ ls
html                   lib
test				   ~
[rache@testserverF1 work]$ ls ~
archive.zip                test         testhtml
```

わーい、消えたー。
念のためにホームディレクトリも確認したけど消えてない！！！
以上、しょうもない小ネタでした。
Vagrantで共有フォルダを設定してみる

# 概要

VagrantではVagrantfileに一行書くだけでホストマシンとフォルダの共有が出来るということなのでやってみました。
VirtualBoxの設定とmountコマンドを併用して設定するやり方もありますが、Vagrantfileに共有フォルダ設定などを書きたくない場合はそちらを使うといいかと思います。

# Vagrantfile

各仮想マシンのVagrantfileの設定に以下のような項目を加えます。

```
# config.vm.synced_folder {host_path}, {guest_path}, option...
config.vm.synced_folder "./shared", "/home/vagrant/shared", owner: "vagrant", group: "vagrant"
```

* host_path : ホストマシンの共有フォルダへのパスです。Vagrantfileからの相対パスが使えます。
* guest_path : 仮想マシン上でのディレクトリパスを指定します。

# Options

オプションに関しては以下の物を複数設定出来る模様です。([公式サイト](https://www.vagrantup.com/docs/synced-folders/basic_usage.html))

| 名前 | 型 | 説明 |
|:--|:-:|:--|
|create|boolean|trueの場合、ホストマシンにフォルダが無かった場合作成する。|
|disabled|boolean|trueの場合、フォルダの同期が無効になります。|
|group|string|共有フォルダのグループを指定できます。デフォルトはSSHのユーザーです。|
|mount_options|array|mountコマンドに渡す追加のmountコマンドオプションのリスト。   |
|owner|string|共有フォルダのオーナーを指定できます。デフォルトはSSHのユーザーです。|
|type|string|フォルダのタイプを指定できます。指定しない場合は最適なタイプを選んでくれるようです。(mountコマンドの-tオプション相当)|
|id|string|mountポイントの名前を指定できます。デフォルトはディレクトリパスのスラッシュをアンダーバーに変換した物|

# VM再起動

これで再度vagrant up, vagrant reloadを行うと設定が反映された状態で仮想マシンが起動します。
g++における__threadキーワードとnon-POD型変数の初期化

#はじめに 

GCCにはスレッド局所記憶のためのキーワードとして`__thread`がある。これはPOD(Plain Old Data)型のみ受け付け、non-POD型は対応していない。しかし、あるバージョンから対応したように見えるので覚書。

# 実行環境

* g++ 4.4.7
* g++ 4.8.5
* g++ 5.1.0

# 現象

以下のようなコードを書く。

```cpp:test.cpp
#include <vector>

void func2(std::vector<int> &v);

int
func(int index){
  static __thread std::vector<int> v;
  func2(v);
  return v[index];
}
```

これをg++ 4.4.7でコンパイルすると、non-POD型はthread-localにできない旨を怒られる。

```shell-session
$ g++ -c test.cpp
test.cpp: In function ‘int func(int)’:
test.cpp:7: error: ‘v’ cannot be thread-local because it has non-POD type ‘std::vector<int, std::allocator<int> >’
test.cpp:7: error: ‘v’ is thread-local and so cannot be dynamically initialized
```

要するに`__thread`指定できるのは、自明なコンストラクタを持つ場合のみに限られる・・・はずだった。

しかしこのコード、g++ 4.8.5や、5.1.0では問題なくコンパイルできる。

```shell-session
$ g++ -c test.cpp

$  # コンパイル成功
```

これに関連することを某ベンダーさんに問い合わせたら調べてくれて、どうやらGCC 4.8でC++11のthread_localキーワードに対応したのだが、このタイミングでnon-POD型に__threadを指定可能になったらしい。

こんなコードを書いてみる。

```cpp:test2.cpp
#include <vector>

void func2(std::vector<int> &v);

int
func(int index){
  thread_local static std::vector<int> v;
  func2(v);
  return v[index];
}
```

さっきの`__thread`を、`thread_local`に書き換えただけのコード。`thread_local`キーワードはnon-POD型にも使えるので、これは問題なくコンパイルできる。

```shell-session
$ g++ -std=c++11 -c test2.cpp 

$ # コンパイル成功
```

で、これもその方に教えてもらったのだが、g++ 4.8以降では、`__thread`指定したものと、`thread_local`指定したものが、全く同じコードを吐く(-Sで見てみるとわかる)。

# まとめ

g++ 4.8以前ではnon-POD型な変数に`__thread`キーワードは指定できなかったが、g++ 4.8以降では指定できるようになった上に、`thread_local`指定した場合と全く同じコードを吐く。

ベンダーの人はそうとは明言しなかったが、おそらくthread_localが実装された段階で、`__thread`がthread_localのエイリアス扱いになったのではないか？それで、本来non-POD型は許されないはずの`__thread`キーワードにnon-POD型が許されるようになったのか？

ただし、[GCC4.8 Changes](https://gcc.gnu.org/gcc-4.8/changes.html)には、

> g++に`thread_local`が実装されたが、これはGNUの`__thread`キーワードとは違うもので、ちょっと遅くなる場合があるからそういう時には`__thread`使ってね

みたいなことが書いてあって、どういうことになっているのかまだよくわかってない。
【Git】GUIツールなんて辞めてしまえ。Git初心者がCUIに乗り換えたら抜群に使えるようになった件

<h2>Gitとの出会い</h2>
私は、大学入学後、直ぐにGitに出会いました。

それはインターンシップです。

インターン先ではGitで全てのプロジェクトのソースを管理しており、

私も強制的にGitを使うハメになったのでした。

<h2>GUIの闇</h2>

Gitに出会い、会社の方にGitの知識をわけわけしてもらい、

いざ、某源木と言うGUIツールでGitを始めた。

GUIだからマウス操作でGitが使える、初心者な私からすればGUIツールは心強い味方だと思っていた。

だがその思いは直ぐさま覆されるのであった。。。。

<h2>エラーの連続から始まるGit</h2>

GUIツールを使い始めてから毎日がエラーの嵐。

エラーは続出、そもそも英語が読めないので原因がワケがわからない。

ググってもなかなか良いのにヒットしない。

変な操作をしたらなんかぶっ壊れてよくわからなくなる。

下手をしてリモートリポジトリを破壊寸前まで追い込んだこともしばしば.....

<h3>
Gitってなんでこんな複雑なの？<br>
専門用語多すぎワケわかんない<br>
てかこれ逆にコスト高くなてね？</h3>
<br>
そう、GUIのGitには問題があった。

<b>それは、専門用語、選択肢、チエックボックス、なんでもありすぎてわけわかめ問題である。</b>


<h2>Git再び</h2>

自分で面白い新しいWebサービスを考え、開発を行うことにした。

将来性も考えてGitにもう一度トライすることにもした。

「一度コマンドラインでやってみるか」

そう、これが運命の分かれ道であった。


<h2>あれ？Gitってこんなに簡単だっけ？</h2>

今回のサービスを開発する上で使ったコマンドリスト


```.git

/* 最初だけ使う→ほぼ覚えてなくても良い */
$git init
$git flow init
$git clone https://hoge.foo/hoge.git

/* たまに使う */
$git checkout develop

/* 結構使う */
$git branch
$git flow feature start hoge
$git flow feature finish hoge
$git add -A
$git commit -m "text"
$git push -u origin hoge
```

<h3>理解する内容Git知識コスト小<br>コマンドを覚えるコスト小<br></h3>
常に使うコマンドに関しては6個覚えておけば大体OK
そのうち二つは似通っている。
TOEIC100点な私からすればfeatureのスペルを覚えるのに二日かかったくらい
（忘れる時はfinishする時ぐらいでgit branchコマンドで単語が出現するのでそこまで問題では無い。startする時はfinishの時に上に表示されるのでそれを見てました。）

<h2>結論</h2>
<h3>GUIの場合</h3>

・GUIで初心者も安心という風潮がある（実際楽という人はいる）
・知らなくても良いコマンドや到底使わないコマンドや似たようなコマンドが陳列されており、Git初心者的には複雑に見える
・画面の遷移数が多いため、慣れるのに時間が掛かる
・エラーの検索がヒットしにくい（体験談）

<h3>CUIの場合</h3>
・黒い画面でエンジニア風に見える→カッコイイ
・一人で開発する場合、メインは6個、計10個のコマンドを覚えたら問題が無い限りこれだけでOK
・画面の遷移は少ない。コマンドも上矢印キー、Historyコマンドで記録されるので前はどうやったのかがわかったりする。→すぐに慣れる
・それっぽいところコピペして検索すると良い確率でヒットしやすい→GUIよりコマンド単位での解決が圧倒的に多い


<h3>恐れずにCUIを使いましょう。救われます</h3>
Parse.comからNCMBへのデータ移行ツールを作りました

[ニフティクラウドmobile backend (NCMB)](http://mb.cloud.nifty.com/) エバンジェリストの小山です。

[Parse.com](http://parse.com)のサービス終了日2017年1月28日まで、あと3ヶ月ほどに迫ってきました。すでに代替サービスへの移行作業を進めている方も多いと思います。

今回 NCMB 向けに、Parse.comの データを移行するツール「parse2ncmb」を作成しました。これは Parse.com のエクスポートデータを読み込んで、値を一部修正しながら NCMB のデータストアに書き込むツールです。

https://github.com/NCMBMania/parse2ncmb

その使い方を手順を追って書いていきます。

## Parse.com のエクスポートデータを用意する

Parse.com では OSS で公開した [Parse Server](https://github.com/ParsePlatform/parse-server) 向けに、Parse.com のデータをエクスポートする機能を提供しています。以下のやり方でエクスポートデータを取得します。

* Parse.com のダッシュボードから
  * 「App Settings」
  * → 「General」
  * → 「Export app data」
  * → 「Export Data」ボタンを押します。
* 「Your app is being exported! We'll email you a link when it's ready.」という
メッセージが表示されるので、登録メールアドレスにリンクが届くのを待ちます。
* メールが届いたら、そこに書かれている URL からデータをダウンロードします。

エクスポートデータは、複数の JSON ファイルをまとめた zip ファイルになっています。

## parse2ncmb の準備

* まずは手元に parse2ncmb のコード一式を用意するために、git clone します。

```bash
$ git clone git@github.com:NCMBMania/parse2ncmb.git
```

* 移行先のNCMBアプリの app_key/client_key を config/default.yaml に登録します。
  * config-dist.yaml に雛形がありますので、それをコピーして使うと良いでしょう。

```bash
$ cd parse2ncmb/config
$ cp config-dist.yaml config.yaml
$ vi config.yaml
```

config.yaml は以下のようなファイルです。

```yaml
config:
  app_key: "xxxxxxxxxxxxxxxxxxxxxxxxxxx"
  client_key: "xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
```

* 使用している npm モジュールをインストールします。

```bash
$ cd ..
$ npm install
```

## parse2ncmb の実行

parse.com のエクスポートデータを適当なディレクトリに展開します。仮にここでは /var/parse_export としておきます。

```bash
$ cd /var/parse_export
$ unzip /some/path/xxxxxxxx-xxxxxxx_export.zip
```

parse2ncmb ディレクトリに移動してツールを起動します。

### DataObject のインポート

Parse.com で登録されていたオブジェクトIDのまま NCMB に登録することはできません。NCMB に登録する際にかならず新規のオブジェクトIDが発行されてしまいますので、Parse と NCMB の2つのオブジェクトIDの対応表を作らなければいけません。その変換処理のために、2段階のフェーズに分けてツールを実行します。

まずはID変換の必要のない DataObject 等のインポートを行います。これには --phase オプションに 1 を指定してコマンドを起動します。

```bash
$ cd parse2ncmb
$ ./parse2ncmb --phase 1 /var/parse_export
```

### リレーション、ポインタのインポート

次にID変換の必要なリレーション、ポインター等のインポートを行います。フェーズ1の実行で、db ディレクトリに ID 対応を記述したファイルができていますので、それを読み込んで ID を変換しながら、リレーションとポインタの設定を追加していきます。

```bash
$ ./parse2ncmb --phase 2 /var/parse_export
```

## 制約事項

parse2ncmb は Parse.com に登録されたデータを全くそのままの形で NCMB データストアに再現するものではありません。仕組み的にどうしても変更を余儀なくされる情報があります。

### objectId が変わる。

すでに述べたように、Parse 側の objectId のままでの登録はできませんので、objectId は新規に発行されます。Parse の objectId は parseObjectId という項目に保存されます。

### タイムスタンプ

同様に Parse の createdAt, updateAt フィールドは、parseCreatedAt, parseUpdateAt という項目にそれぞれ保存されます。

### ポインタについて

Parse のデータモデルでは一つのプロパティに複数のポインタを登録できますが、NCMB では一つのプロパティに登録できるポインタは一つのみです。変換元データに複数のポインタがあった場合は、最初のデータのみポインタとして登録します。

### ユーザへのポインタについて

ユーザ情報へのポインタは現時点ではサポートしていません。これは NCMB では新規にユーザを作成した際に、標準で本人のみ読み書き可という ACL が設定されてしまい、そのためポインタの登録ができないためです。

## 作ってみた感想

Node.js の同期/非同期まわりにはかなり苦労して、当初考えていたよりずいぶん時間がかかってしまいました。基本的には Promise を用いて非同期処理をすればよいわけですが、同時実行数を制限した並列を行おうとして throat を用いたあたりから Promise への内部構造への理解不足が露呈し始め、色んなやり方を試しては思うように動かない試行錯誤を繰り返しました。ある程度複雑な手順をすべて Promise ベースで行うのは、自分には荷が重かったようです。
Mac Os をSierraにしたらHomebrewがupdateできなくなった？

# HomebrewをUpdateしてみる
OsをSierraにしたので、このタイミングでbrewをupdateしようと思ったのですが、
少し手こずったので共有したいと思う。

$ brew update
Error: /usr/local is not writable. You should change the ownership
and permissions of /usr/local back to your user account:
  sudo chown -R $(whoami) /usr/local

早速エラーメッセージが出てしまい、上手くいきませんでした。
でもここに答えはあった。

#sudoで対応を試みる

$ sudo brew update
Password:
Error: Running Homebrew as root is extremely dangerous. As Homebrew does not
drop privileges on installation you are giving all build scripts full access
to your system. As a result of the OS X sandbox not handling the root user
correctly HOMEBREW_NO_SANDBOX has been set so the sandbox will not be used. If
we have not merged a pull request to add privilege dropping by November 1st
2016 running Homebrew as root will be disabled. No Homebrew maintainers plan
to work on this functionality.
Error: Cowardly refusing to 'sudo brew update'
You can use brew with sudo, but only if the brew executable is owned by root.
However, this is both not recommended and completely unsupported so do so at
your own risk.

sudoは素人では下手したら困り果てる、
ということは教えて頂いたことはあるが、エラーメッセージからsudoは危険という警告を受け、
とりあえず立ち止まった。

# エラーメッセージを見つめ直す
最初の
$ brew update
Error: /usr/local is not writable. You should change the ownership
and permissions of /usr/local back to your user account:
  sudo chown -R $(whoami) /usr/local

ここで答えはあった。

そう、<strong>sudo chown -R $(whoami) /usr/local </strong>

これでupdateできる。

エラーメッセージは友達だね。


#参考にしたサイト
http://www.papa-programing.jp/entry/2016/10/30/200000
python 初心者向けの教科書

#pythonとは
pythonはコンパイラ型言語(C言語など)のように実行可能ファイルを作成する必要がなく、機械語翻訳と同時に実行を行うインタープリタ型言語です。
本記事はC言語を基礎知識として持っている人向けです。
python 2系向けに作成。
コードは[paiza.io](https://paiza.io/projects/tc92ZjBiCR7nPdpiuF3NVA)にて動作テストをしています。

#基本事項
ソースファイルの拡張子は".py"
コメント文は#の後に書く
自動的に改行が行われるので**C言語のように\nと表記する必要はない。**
以下に基本的なソースコードの記述を記載する。

```python.py

#文字コードは以下のように指定する(UTF-8を指定する場合)
# coding:UTF-8

#変数を定義する場合(型を指定する必要はない)
a = 5
b = 'str'

#四則演算や演算子は基本的にC言語と同様である
c = a + 5 

#print文は, "と'どちらを用いてもよい
print'Hello world!!'

```


#基本的な文法


##3大制御構造
3大制御構文とは、上から順に実行する**順次**、条件によってケースを選んで実行する**選択**、ある条件を満たす場合だけ繰り返す**反復**の3つである。ここではif文、for文、while文を記載する。

###if文(if-else文)
条件式が真のときのみ実行する。偽の場合の処理も指定したい場合にはelseを使う。
C言語のように{}は必要とせず、インデントを用いて記述する。

```if.py
# coding:UTF-8

'''構文
if 論理式 :
  真のときの実行式
else
  偽のときの実行式
'''

#例
x = 10
y = 5

if x>y:
  print 'xはyより大きい'
else:
  print 'yはxより大きい'

'''実行結果例

xはyより大きい
'''
```

###for文(for-range文)
pythonでのfor文はrange関数を用いることによって、繰り返す回数を指定することができる。また**引数には負の数を指定することもできる。**

```for.py
# coding:UTF-8

'''構文
for var in range():
  実行式
'''

#例：-5から5までの数字を表示させる
for i in range(-5, 6):
  print i

'''実行結果
-5
-4
-3
-2
-1
0
1
2
3
4
5
'''
```


###while文
条件式が真である限り繰り返し実行式を行う。

```while.py
# coding:UTF-8
'''構文
while 条件式:
  実行式
'''

#例
a= 0
while(a<5):
  print a
  a++

print a

'''実行結果例
0
1
2
3
4
5

'''
```

##関数
関数を定義する場合にはdef文を使用する。
returnにて戻り値を指定するが、これを省略するとNoneを返す
またpythonにはメソッドがある。これはクラス内に定義されているものを指しており、モジュール内で定義されているものが関数である。

```func.py
#coding UTF-8
'''構文
def 関数名(仮引数):
  関数の実行処理記述
'''
#例:乗数を返す関数を定義
a = 3
def func(a):
    return a**2

print func(a)

'''実行結果例
9
'''
```

##文字列
文字列は''で括って表す。
pythonではバイト文字列とUnicode文字列を扱うことができる。Unicodeは日本語などを扱うときに使用する。
またprint文の最後にコンマをつけると改行されなくなる。

```japanese.py
#coding UTF-8

#日本語を表示させる文字列
print('日本語')

#文字列もリストのように要素から読み込める
j = 'japanese'
print j[2]

#文字の連接は+を用いて行う
f = 'food'
print(j + f)

#文字列の検索
#('検索したい文字列' in 検索する文字列)
#実行結果はTrueまたはfalseが返ってくる
print('japan' in j)


'''実行結果例
日本語
p
japanesefood
True

'''

```




##リスト
C言語でいう配列にあたるデータ構造である。リストの大きさを指定する必要はなく、また整数や文字列など**異なったオブジェクトを並べても構わない。**

```list.py
#coding UTF-8

# coding: utf-8
# Here your code !
#listの作成(連番はrange関数を利用すると手間が省ける)
a = range(5)
b = [6, 7, 8]
print a

#要素はC言語と同様に0から始まる
print a[4]

#リストの一番後ろに要素を追加(異なるオブジェクトでもよい)
a.append(5.00)
print a

#指定した位置の要素を代入する
a[0] = 'zero'
print a

#指定した位置に要素を追加する
#n番目mを追加する場合 list.insert(n, m)
a.insert(0, -1)
print a

#リストから指定した要素を削除する
del a[0]
print a

#リストの結合
a.extend(b)
print a

'''実行結果例
[0, 1, 2, 3, 4]
4
[0, 1, 2, 3, 4, 5.0]
['zero', 1, 2, 3, 4, 5.0]
[-1, 'zero', 1, 2, 3, 4, 5.0]
['zero', 1, 2, 3, 4, 5.0]
['zero', 1, 2, 3, 4, 5.0, 6, 7, 8]
'''

```
##辞書
辞書はとは、キーと対になる値のペアをリスト化したものである。
値はどのような型でも指定できるが、キーには変更不能なオブジェクトを指定しなければならない。

```dic.py
#coding utf-8

'''構文
dic = {キー:値, キー:値、キー:値...}
'''

#例
age = {'tanaka':20, 'yamada':16, 'eto':33}
print dic[eto]

#辞書は結合させることもできる
age2 = {'wada':45, 'seki':12}
age.update(age2)
print age

#辞書の削除
del age['wada']
print age
```


#参考ページ
[大東文化大学 経済学部 経済学科 水谷正大氏のWebページ](http://www.ic.daito.ac.jp/~mizutani/python/index.html)
[python入門](http://www.tohoho-web.com/python/index.html)
[ほぷしぃ 特集PC技術 Pythonを学ぼう](http://www.isl.ne.jp/pcsp/python/)
環境変数からprivate_keyを読み込んだ際にJWT Clientを初期化出来ない場合の対処方法


# 概要

[Google APIs Node.js Client](https://github.com/google/google-api-nodejs-client)でJWTでのサービスアカウントを使用した認証を行った際にハマったことのメモです。

# 問題

環境変数に`client_secret.json`の`private_key`を登録し、それをコードから`process.env`で参照して認証に使用しました。

```JavaScript
const jwtClient = new google.auth.JWT(
	process.env.SERVICE_ACCOUNT_EMAIL,
    null,
    process.env.SERVICE_ACCOUNT_KEY,
    ['https://www.googleapis.com/auth/drive'],
	null);
```

このコードで上手く行きそうなのですが、実際には以下のようなエラーが出て上手く認証ができませんでした。

```bash
Error: error:0906D06C:PEM routines:PEM_read_bio:no start line
```

private_keyをハードコーディングした場合には問題なく認証できており、keyが間違っている訳ではありませんでした。

# 解決策

環境変数から読み込んだprivate_keyの改行コードを`.replace(/\\n/g, '\n')`で置き換えることで解決しました。

コードは以下の通りです。

```JavaScript
const jwtClient = new google.auth.JWT(
	process.env.SERVICE_ACCOUNT_EMAIL,
    null,
    process.env.SERVICE_ACCOUNT_KEY.replace(/\\n/g, '\n'),
    ['https://www.googleapis.com/auth/drive'],
	null);
```