OmniAICreator/Qiita-1.07M huggingface dataset:
1行のコマンドでアプリ開発に利用してる全てのPNG画像を全て圧縮する


# はじめに
みなさんは、大きいサイズの画像と小さいサイズの画像どちらが好きですか？僕は小さいサイズの方が好きです。

アプリを開発されてる方の中には[TinyPNG](https://tinypng.com)などのサービスを利用して画像を圧縮してるよ、という方も結構多いのではないでしょうか。しかしながら、ブラウザでいちいち画像を指定するのはなかなか面倒なものです。

また、既にたくさんの画像をアプリで利用していて、これまで圧縮などをしたことはなかったけどバイナリのサイズが気になってきた..という方もいると思います。

そこで、1コマンドでプロジェクト内の画像を全て圧縮するという(乱暴ではあるが)便利なコマンドを考えてみました。

# pngquantをインストールする
[pngquant](https://pngquant.org)はコマンドラインから利用できるPNG画像圧縮ツールで、TinyPNGでもこのコマンドが利用されているそうです。今回は、このツールを利用して画像を再帰的に圧縮するコマンドを叩きます。
　
pngquantのインストールは、brewをお使いならば下記のコマンドだけでインストール出来ます。

```bash
$ brew install pngquant
```

ちなみに、この記事ではpngquantの細かなコマンドについては説明しませんが下記の記事などが参考になります。

参考: [シンプルで強力な PNG オプティマイザ pngquant](http://server.etutsplus.com/install-pngquant/)

# 実行するコマンド
pngquantのインストールが完了したら、あとは下記のコマンドをアプリのプロジェクトのディレクトリで実行すれば全ての画像を圧縮することが出来ます。

```bash
find ./ -name "*.png" | xargs -L1 -P8 pngquant --ext .png --speed 1 --skip-if-larger --force
```

上記コマンドでは並列で処理を実行することもあり、画像の量やマシンの環境にもよりますが、数百個くらいの画像なら大体1分以内に終わるんじゃないかと思います。参考までに、手元のMabBookProで400個ほどの画像があるプロジェクト内で実行したところ10秒ほどで圧縮が完了しました。

# 同じ画像をpngquantで何度も圧縮するとどうなるのか？

気になって調べてみたのですがpngquantで圧縮済みの画像に対してpngquantを適用するとどうなるのか、という点については開発者であるpornelさんが下記の様にコメントしています。

https://github.com/pornel/pngquant/issues/34

>If you run pngquant on image that is already paletted it won't degrade it (except when you use --quality option to deliberately lower the quality).

>もし、既に圧縮済みの画像に対してpngquantを実行したとしても、それによって品質が下がることはありません（ただし、--quality オプションを利用して明示的に品質を下げる場合は除く）

実際に、上記のコマンドを繰り返し実行しても画像のサイズは1度実行したときと同じで、見た目上にも特に劣化などは見られませんでした。

# 審査提出時/リリースのタイミングで全圧縮
新しく追加した画像をpngquantで都度圧縮していくという運用も悪くはないのですが、手間を考えると若干乱暴ではありますがリリースビルド生成時に上記コマンドで毎回全ての画像を圧縮する、という対応もアリかもしれないという気がしています。

CI環境などが既に整っている場合は、上記の様な操作をCIで行ってしまうというのもアリかもしれません。

ただし、この方法では既に圧縮済みの画像についても差分が生じてしまうのでその点は気持ち悪く感じます。


# git pre-commit hookを利用する
管理コストなく全ての画像を圧縮する方法としてもう一つ考えられるのは、`git pre-commit hook` を利用する方法です。これは、gitでcommitする前(コミットメッセージが入力される直前)に特定のスクリプトを動作させることが出来る、という仕組みです。

ここで、新しくgit管理下に画像が追加されようとしていたならばpngquantで圧縮、という処理を行えば全ての画像を圧縮するよりスマートに同様のことを実現できそうです。

同様なことをしようとしている方がいたので、まだ試してはないのですが下記の様なスクリプトを `.git/hooks/pre-commit` に配置することでcommit時に画像を圧縮することができるはずです。(pngquantのオプションはプロジェクトに合わせて調整するのが良いでしょう）

https://gist.github.com/DelvarWorld/5906379
Cisco Spark REST-API 入門

#Cisco Spark に対して REST-API でアクセスしたい

学習用コンテンツが [Cisco DevNet](https://developer.cisco.com/site/devnet/home/index.gsp) に用意されている（DevNet > Collaboration > Spark for Developers に 3つの Learning Lab がある）。

* Learning Lab #1: Rooms and Messages
* Learning Lab #2: App Registration and Authentication
* Learning Lab #3: Webhooks

懇切丁寧な作りになっているので手順に沿って進めれば「POSTMAN を使って REST-API 経由で Cisco Spark へアクセスする方法」が一通り学べる。

ここではその次のステップとして、POSTMAN を Python へ変更する方法をまとめてみる。

# Access Token の取得
Cisco Spark へ REST-API でアクセスするには Access Token が必要。Access Token は Cisco Spark の登録を行うと個人に付与される認証用文字列のこと。以下の方法で取得する：

https://developer.ciscospark.com/
へアクセスしてログイン。

※Cisco Spark の登録が済んでいない場合は登録を行う必要あり

ログインに成功すると右上にアバター（人の顔をしたアイコン）が表示される。

アバターをクリックすると Access Token が表示される。Access Token は他人には決して知られていけない情報なので取り扱いには細心の注意が必要。

#実験１：Cisco Spark から Room List を取得する

参考：Cisco Spark の [API Reference](https://developer.ciscospark.com/endpoint-rooms-get.html)

http GET を以下の条件で実行すればよい:

* URI: https://api.ciscospark.com/v1/rooms
* Headers: Authorization: Bearer (Access Token)
* Headers: Content-Type: application/json

Python で HTTP GET を実行するのは [requests](http://docs.python-requests.org/en/latest/user/quickstart/) を使う。コードは例えば以下：

```
import requests

access_token = 'ここに Access Token を入力'

url = 'https://api.ciscospark.com/v1/rooms'
headers = {
    'Authorization' : 'Bearer ' + access_token,
    'Content-Type' : 'application/json'
}

r = requests.get(url, headers = headers)

print(r.json())
```

Room ID だけを取り出したいのであれば、最後の行の print(r.json()) を以下の形に変える：

```
for line in r.json()['items']:
    print line['id']
```

#実験２：Cisco Spark から Room の Message を取得する

Message を取得するには、実験１で取得した Room ID を使って http GET を以下の条件で実行すればよい:

* URI: https://api.ciscospark.com/v1/messages
* Headers: Authorization: Bearer (Access Token)
* Headers: Content-Type: application/json
* Payload: 'roomId' : (Room ID)

以下はユーザのメールIDとメッセージを表示するサンプルスクリプト：

```
# -*- coding: utf-8 -*-

import requests

urlr = 'https://api.ciscospark.com/v1/rooms'
urlm = 'https://api.ciscospark.com/v1/messages'
headers = {
    'Authorization' : 'Bearer ' + access_token,
    'Content-Type' : 'application/json'
}

r = requests.get(urlr, headers = headers)

for line in r.json()['items']:
    payload = {'roomId' : line['id']}
    print '################### Room: ', line['title']
    r2 = requests.get(urlm, headers = headers, params = payload)
    try:
        for mline in r2.json()['items']:
            try:
                print mline['personEmail'], '>>>', mline['text']
            except KeyError:
                pass
    except KeyError:
        pass
```

※2017/8/1 少し内容を修正しました。
現役女子大生がmyThingsとMESHで世界初を作ってみた。

#[ConnectlyLab.](http://www.connectly.net/)に[MESH](https://first-flight.sony.com/pj/4/MESH%20-%20%E8%AA%B0%E3%81%A7%E3%82%82%E7%99%BA%E6%98%8E%E5%AE%B6%E3%81%AB%E3%81%AA%E3%82%8C%E3%82%8BDIY%E3%82%AD%E3%83%83%E3%83%88)がやってきた！

こんにちは！リノベるでインターンをしている高橋です。
MESH全7種類がConnectlylabへやってきました。一気にConnectlylabが賑やかになりましたよ！
[こちら](http://www.connectly.net/)からユーザー登録をすると誰でもご自由にMESHをはじめ、connectlylabに設置されているデバイスや、他の方が作成したアプリなどを使うことができます。

![image](https://qiita-image-store.s3.amazonaws.com/0/104464/4b3946d1-d09e-3f2f-3775-8c95ecd60ccd.png)

##MESHと[myThing](http://mythings.yahoo.co.jp/)をつなげてみた

今回は、ポストに人感センサーのMESHを設置し、郵便物がポストに投函にされるとMESHのセンサーが反応してGmailに通知がきて、myThings経由でBOCCOが「郵便物が届いたよ！」と知らせてくれる世界初のシステムを作りました。

こんな感じです。
![スクリーンショット 2015-12-11 12.01.01.png](https://qiita-image-store.s3.amazonaws.com/0/104464/18734591-6d98-92cb-5ec2-d2a3a7d1a614.png)

#人感センサーが反応したらGmailが届く
MESHのアプリ上ににGmailの拡張タグをドラッグ＆ドロップします。
次に、人感センサーとGmail拡張タグを繋ぎます。(繋がったときの音が好きです)
![IMG_0057.PNG](https://qiita-image-store.s3.amazonaws.com/0/104464/26c9aff6-fe35-9053-eb94-b8794c97f9a6.png)



Gmailタグをクリックすると送信先と件名を打ち込めるので書きます。
送信先と件名に「郵便物が届いたよ！」と記入したらおっけいです。
![IMG_0046.PNG](https://qiita-image-store.s3.amazonaws.com/0/104464/c7e40a42-8e47-2da6-8518-ba9e8b24006a.png)


これでMESHでの作業はおしまいです。

#my Thingsを経由してGmailが届いたら[BOCCO](http://www.ux-xu.com/product/bocco)がしゃべる
早速、myThingsを使っていきましょう！
新しくファイルを開き、「トリガーを追加してください」をクリック！
![IMG_0048.PNG](https://qiita-image-store.s3.amazonaws.com/0/104464/686fa245-041e-a4d3-2cc5-4802d4ba7259.png)
<br>

Gmailのアイコンを選択します。(MESHからGmailを受け取ります)
![IMG_0049.PNG](https://qiita-image-store.s3.amazonaws.com/0/104464/1a30948a-0542-d8bf-4eb9-c38cc314dc44.png)
<br>

次にトリガーの選択をします。
「特定の誰かからメールを受信したら」を選択します。
![IMG_0050.PNG](https://qiita-image-store.s3.amazonaws.com/0/104464/165a9550-af10-8f39-df30-4a98a2de2eb7.png)

トリガーの詳細設定で先ほど使ったメールアドレスを入力します。
![IMG_0051.PNG](https://qiita-image-store.s3.amazonaws.com/0/104464/73db70b2-9ee8-33a8-63e2-65e8b2c726b0.png)



<br>
次に「アクションを追加してください」を選択します。

![IMG_0052.PNG](https://qiita-image-store.s3.amazonaws.com/0/104464/a0163c17-fd0c-365e-1dea-24991adb0977.png)

<br>
チャンネルの選択でBOCCOを選択します。
![IMG_0053.PNG](https://qiita-image-store.s3.amazonaws.com/0/104464/5d4d5c06-3607-56dc-e9b7-0c591e89a3f0.png)

<br>
アクション設定でBOCCOを選択し、メッセージ内容を記入。ここは{{件名}}にしておきましょう。
![IMG_0055.PNG](https://qiita-image-store.s3.amazonaws.com/0/104464/3101ab05-97e6-d4b4-570c-c40fa9c49775.png)

[![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/z-dBDxab9yE/0.jpg)](http://www.youtube.com/watch?v=z-dBDxab9yE)

〜 １５分後 〜
[![IMAGE ALT TEXT HERE](http://img.youtube.com/vi/3gn1Y86h0BM/0.jpg)](http://www.youtube.com/watch?v=3gn1Y86h0BM)
**これで世界初のシステムの完成です♩**


# 最後に
今プログラミングを猛勉強中なのですが、わからないことが沢山で幾度となくmacを破壊したくなる衝動に駆られます。そんな私ですが、MESHやmyThingsを使ったことで２つの発見がありました。
１つ目は**プログラムを書いてないのにプログラミングした気分になれる**ということ。２つ目は、もっとこんながことしたい欲が湧いてきて、そのためにはプログラミングが必要なので**プログラミング頑張るぞという気持ちが生まれる**ということです。
myThingsとMESHを触ってプログラミング始めたい！もっと勉強したい！って思う人が増える理由が分かりました＾＾

最後までお読み頂いてありがとうございます！
SSL通信のプロセス：


---
###SSL(Secure Socket Layer)って？

通信時のセキュリティ担保のための技術で、通信時に使われている（ブラウザに出てくる鍵マークとか）ってことはわかるんだけど、実際どんな技術を使っているのかイマイチ理解出来ない。

ってことでいろいろ調べた結果を以下にまとめてみました。


####参考:
https://www.cybertrust.ne.jp/sureserver/basics/ssl1.html

---
###SSLのプロセスざっくり

まず認証のプロセスとして、安全を保つために大きく２つのプロセスに分かれてます。

(1)ネゴシエーション
　接続相手を認識して、通信に必要な共通鍵を作成するプロセス。

(2)暗号化通信
　作成した共通鍵で通信するプロセス。

※公開鍵認証 / 共通鍵認証については、時間があったら。
 知らないひとはQiiてね。


---
###細かいプロセス

####(1)ネゴシエーション

　ネゴシエーションって交渉とか折衝とかいう意味。
　まず、通信開始する前に、サーバ、クライアントが　

　「全く同じ共通鍵を作ってデータ通信したい。
　　でも直接共通鍵渡すとパクられたりしそうでちょっと怖い」
　　
　を解決するためにちょっと面倒な手順を踏む。
　公開鍵/秘密鍵の暗号/複合を使って確認する。   

<br>
   
```SSLネゴシエーション


 a)接続要求  [クライアント → サーバ]
 
  倉：「おーい、SSL通信したいんだけどOK?」
  鯖：「ちょいまちー」

 b)返答：公開鍵（サーバ証明書）の送付[サーバ → クライアント]

  鯖：「通信暗号化するための公開鍵送るんで受け取ってー。」
  倉：「おK。待ってる・・・公開鍵キタコレ」
  
  ※共通鍵作成のための公開鍵を、サーバからクライアントに渡す（同じ公開鍵を持つ）
            
 c)通信用データ作成、送付 [クライアント → サーバ]

　倉：「したら通信用のデータ作っておくるわー。暗号化してくれる？」
　鯖：「まかせろー」

　※通信用公開鍵作成のためのデータをクライアントからサーバに渡す（同じデータを持つ）

 d)暗号化通信用鍵作成 [クライアント & サーバ]
　
　鯖：「そしたらもらったデータ暗号化して共通鍵作るわー（作った）」
　倉：「おけおけ。こっちも作る(出来た）」
　
　※同じ公開鍵で同じデータを暗号化することで、サーバとクライアントが同じ共通鍵を持つ。
```  
　　
　重要なのは「サーバ側が持つ公開鍵」と「クライアントがつくるデータ」を掛けあわせて共通鍵を作ること。
　通信でやりとりをするのはこの２つ。
　
　これで、直接（メールとかで）共通鍵を渡すことなく
　全く同じ共通鍵をクライアントとサーバが持つことになる。


####(2)暗号化通信

　作成した共通鍵を使ってデータのやりとりをする。

```暗号化通信


a)データ送信 [クライアント → サーバ」

　倉：「データ暗号化しておくるよー。（共通鍵を使って暗号化）」
　鯖：「ばっちこーい。」
　
b)データ受信「サーバ」

　鯖：「届いたー、復号すんね（共通鍵を使って復号）」
　倉：「りょ。つづけておくるよー（エンドレス）」

```
 

負荷の高い公開鍵/秘密鍵暗号化を、相互の認証（共通鍵作成）のために使い、
その後は負荷の小さい共通鍵を使う、というSSLの仕組みでした。


###ではまた！！
macから.DS_Storeを消しさる


## はじめに
不可視ファイルを見える状態にしていてmacを使ってると.DS_Storeってのがいつもどのフォルダにできていてうざいので

それを _ターミナル_ で消す方法を紹介します。

まずその前に.DS_Storeとはなんぞや？
とゆうところを少し紹介します。

## .DS_Storeとは？

 - mac側で作成された独自の形式の隠しファイル。
 - Finderやらリモート上アクセスする全てのフォルダに.DS_Storeが作成される。
 - 独自のmeta情報



## ターミナルでいっきに消す
**アプリケーション > ユーティリティ > ターミナル.app**
から **ターミナル.app**を立ち上げます。

立ち上げると

```
$ user-name
```

となってると思うのでここが **ホームディレクトリ**だと思うので（デフォでは）
もしホームディレクトリにいない場合は
```
$ cd ~/
```
でホームディレクトリに戻れます。

そこから

```
$ cd ../
```
と今いるディレクトリから一個下がります。

そしたら今度は
```
$ sudo find $USER -name .DS_Store -print -exec rm {} ';'
```
と打つと
_password?_と聞かれるので
macログイン時のパスワードを入れます。
パスワード入れたらEnterキーを押す
※この時パスワードは反映されません

そしたらターミナルにたくさんのログっぽいのが出てきて
macから.ds_Storeが消えていくかと思います！

## .DS_Storeをそもそもmacから作成されないようにする（ネットワーク接続時）
Apple側も.DS_Storeを問題視はしてくれてるようなのですが
色々と以下の理由で.DS_Storeが作成されるを嫌がる人たちがいるかと思います。

嫌がる人たち / 嫌がられるケース

 - windowsな人たち
 - svn / gitやらに意図せず含まれるケースがある(.gitignoreで設定可能）
 - 納品時に含まれる恐れがある
 - etc...

このようなことがありうるので.DS_Store ファイルの作成を抑制する方法が[Appleの公式](https://support.apple.com/ja-jp/HT1629)にもありますね。


ターミナルで

```
defaults write com.apple.desktopservices DSDontWriteNetworkStores true
```

を実行してmacを再起動でいいらしです。

ただこの方法はFinder上やアプリケーションが開かないなど色々と不具合があるようなので個人的にはおすすめしませんがやりたい方は
上記コマンドをやってみてください。

※ 責任は負いかねます。


とまー初投稿でした。
色々と至らないかと思いますが何かあれば教えていただけたりするとありがたいです。
2015年、ディレクター業務を振り返って

ディレクター兼フロントエンドやってます。
2015年、ディレクターとして業務がメインだったので、色々と振り返ってまとめたいと思います。

#2015年、ディレクション業務を通して感じたこと
基本、受託開発のディレクターをやっているのですが、以前の会社ではほぼ1人で作業を行っていたので、実際に別の方に作業を依頼する事がありませんでした。
チーム（バックエンド、フロント、デザイナー）でプロジェクトに当たる事がほぼ初めての経験なので、色々と試行錯誤が多かった年だと思います。自分なりに2015年に実践した事を書いておきます。

##資料（仕様書）の確認
当たり前の事なんですけど、実は結構大事な部分だと思います。

営業段階で提出された資料等が共有されないままプロジェクトが進み、プロジェクト終盤になった頃に発覚する等が多々あったり。
ディレクターとして業務を行う際には、資料の有無、尚且つある程度理解できるまで何度も読み返す。不明点があれば、すぐにクライアント、もしくは営業に確認。

実際、やってみて下記の部分で効果あった気がする。

- クライアントとの認識のズレ
- クライアントと打合せを行う際に実際の仕様や資料を把握していないと不安にさせてしまう
- ディレクターの都度確認で、プロジェクトがスムーズに進まない

作業者に質問されて「わかんなーい」で返すのは本当ダメだよなー。って個人的には思います。

##WF（ワイヤーフレーム）の作成
自分が一番時間をかけている部分です。

よく「ヘッダー」「グローバルメニュー」「コンテンツ」「サイドメニュー」「フッダー」って大きな枠だけで構成されているWFを見かけるんですが、あれって見ただけでは何が必要かわからないですよね？それを渡されてデザインをおこしたり、コーディングしたりとかすごく非効率だし作業者のストレスが多いなーと思ったので、WFは要素がわかるように可能な限り細かく作るようにしました。

結果、要素に関しての質問はかなり減ったし、クライアントともWFを見ながら項目の確認等が行えるようになったので、やってみてよかったなーと感じる部分です。

細かく作る事によってデザインの領域になってしまっていないか、注意が必要だと感じてます。あくまでも設計書である事は忘れないようにしたいです。

##フローの可視可
このページにはどんな機能や要素が必要なのか？という部分でごちゃごちゃ考えて何をどうすればいいのか、わからなくなったりする事があります。
そんな時、実際にそのシステムを使う人のフローを時間軸を使ってチャート図に起こします。
可視可する事によって、必要な機能の把握と整理ができるので、考えがまとまりやすくなります。
また、クライアントとの認識合わせにも使えたりもするので一石二鳥です。

実際、受託開発を行っているとノウハウの無い業界のプロジェクトもあったりするので、何かに迷ったらユーザーのフローを考えるようにすると、とても良さそうです。フローを可視可しておくとチーム内での打合せもスムーズになりそうです。

##まとめてみて感じたこと
自分なりにまとめてみたものの、ディレクターを長くやってる方には「当たり前」な事ばっかりなんだろうなって思ってます。

ディレクションに関するノウハウって社内で共有する事もほとんど無いし、そもそもディレクターがいないというのもあってディスカッションも難しい状態。
少しずつノウハウ貯めていくしかないなー。他社のディレクターの方と色々情報交換してみたいなーと思う今日この頃。

2016年も新しい事を試して、糧にしていきたいと思います。
Git | 現在のブランチルートから rebase  -i する方法

エイリアスを設定しておく。

```~/.gitconfig
[alias]
branch-root = merge-base master HEAD
```

そして

`$ git rebase -i $(git branch-root)`

でOK。



<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# メンター受付


https://menta.work/user/5694

<!-- Update From Qiita API -->
[JavaScript] 日時計算に便利なMoment.jsを使ってみる

**JavaScript の Date クラスはやや使いづらさがあります。Moment.js を使うと、フォーマット（書式整形）や日付計算・時間計算に大変便利です。**

# ![](//goo.gl/tuSQrq) 導入

<a href="http://momentjs.com/" target="_blank">本家サイト</a>からダウンロードするか、<a href="https://cdnjs.com/libraries/moment.js/" target="_blank">CDN</a> から読み込みます。

<a href="https://cdnjs.com/libraries/moment.js/" target="_blank">CDN</a> から読み込む

```html
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/locale/ja.js"></script>
```

曜日を日本語表記にしたい場合は、２つ目のも導入します。

# ![](//goo.gl/tuSQrq) 使ってみる

```js:JavaScript
// 日本時間
var now_jpn = moment();
alert("日本時間 " + now_jpn.format("YYYY年MM月DD日(ddd) HH:mm:ss"));

// 米国太平洋時間(PST)
var now_pst = now_jpn.add(-17, "hours"); // 日本時間から17時間を引く
alert("米国太平洋時間 " + now_pst.format("YYYY年MM月DD日(ddd) HH:mm:ss"));
```

⇒ <a href="https://jsfiddle.net/yasumodev/yztdvzkh/" target="_blank">デモソースはこちら</a>

(･o･ゞ いじょー。

# ![](//goo.gl/tuSQrq) 参考URL

- <a href="http://momentjs.com/" target="_blank">Moment.js｜Home（本家サイト）</a>
- <a href="https://cdnjs.com/libraries/moment.js/" target="_blank">moment.js｜CDN</a>
- <a href="http://qiita.com/kyota/items/806da61fb8fffa34b695" target="_blank">日付処理が楽になる！Moment.jsの使い方</a>
- <a href="http://qiita.com/osakanafish/items/5ef636bbcb2c3ef94953" target="_blank">Moment.jsを使う</a>
- <a href="http://blog.asial.co.jp/1158" target="_blank">JavaScriptで日付を扱うならこれ！「moment.js」</a>
Javaと再帰とスタックオーバーフロー

# 1. はじめに

最近、関数型言語で再帰を書く機会があり。
ようやく理屈が少しだけ分かったので、大好きなJavaでやってみました。

# 2. Javaの再帰??

そもそも手続き型のJavaで**再帰を書くことはあるのか？**

周りの先輩エンジニアたちに聞いてみました。

## 2.1 アンケート

**Q. 「Javaで再帰書くことってありますか？」**

Aさん 「書けるけど、書かないといけない理由が無いと**書かない。**」
Bさん　「業務では**書かない。**」
Cさん　「変に書くと、メモリ食って**スタックオーバーフロー**するよ。」

## 2.2 アンケート結果

**A. 「書かない」**

_もし効果的に書けるケースがあれば、コメント欄で教えていただけると嬉しいです！_

# 3. とはいえやってみる

書かないとはわかりましたが、出来るならやってみたいですね。
と、いうわけで。**Listの長さをintで返すlengthメソッド**を実装してみました。

length(List) : int　←　こんなん

## 3.1 やってみた

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

```java
public static int length(List list) {
	if (list.isEmpty()) {
		return 0;
	} else {
		list.remove(0);
		return length(list) + 1;  // ここでもっかい自分自身を呼び出し
	}
}
```

動かしてみましたが、ちゃんとできてました！

## 3.2 短くしてみた

調べてみると三項演算子使ってることが多かったので。
書いてみると、半数以下の行になりました。

ですが、可読性は低そう。。

```java
public static int length(List list) {
	return list.isEmpty() ? 0 : length(list) + 1;
}
```

**しかし、動かしてみたところ。。**

## 3.3 あれがおきた

↑の三項演算子の方のlengthメソッドを動かしてみたところ。。

```java
Exception in thread "main" java.lang.StackOverflowError
	at qiita.Recursion.length(Recursion.java:26)
	at qiita.Recursion.length(Recursion.java:26)
	at qiita.Recursion.length(Recursion.java:26)
	at qiita.Recursion.length(Recursion.java:26)
	...
```

# 4. StackOverflow

でました!!
[Java 再帰] で検索するとこのエントリーがよく出ますね！
スタックオーバーフローだ!!
(Listの中身を消し忘れていたので当然ですね)

## 4.1 スタックオーバーフローって？

再帰呼び出しを続けた結果、
**「メモリを使い切ってしまった」**的なエラーであることは、何となくは想像できます。

折角なので、今回はもう少し深くまで考えてみたいです。

## 4.2 コールスタック

プログラム中に再帰を呼び出す問題点の一つに、

* 再帰呼び出しを一回行うごとに**コールスタック**を一つ消費する必要がある。

と、いう事があるらしいです。

コールスタックぅ？
> コールスタックとは新たな作業を始めるためのスペースだと思ってください。
人が並んで座れる長机だと考えるとわかりやすいかもしれません。このスペースがなくなるまで(つまり、隣に人が座れなくなるまで)再帰を続けるとスタックオーバーフローというエラーが起こります。

**ジャパネットに電話した時にお話しする人とは関係ないようですね。**

## 4.3 つまり

JVM内のPermanent領域から、OSのスタック領域にメソッド情報がガンガン送られてきて。
スタック領域が一杯になってしまう。というエラーなんですね。(なんでしょうかね。。？)

はじめは、「ガベージコレクションは仕事しないの？」と、思ったのですが。
GCってJVMのNew領域とOld領域をホニャラララしてくれるものだったから、仕事のしようが無いということですね。(なんでしょうかね。。？)

というかこのへんやっぱりよくわかってないんで、ちゃんと勉強しなきゃですね。

# 5. まとめ

Javaで再帰を書いてみて、よくセットで言われるスタックオーバーフローについて考えてみました。
特に、結論とかは無いので。もしここまで読んでいただいた人がいらっしゃったら時間を無駄にさせてしまったかと思います。。
ありがとうございます！！

# 参考

http://rn4ru.com/blog/posts/2014/Feb/14/tail-recursion/
http://promamo.com/?p=2828
El Capitanにしたらば、色々動かんくなって困った対処を書くべ


#Homebrewの再インストールが必要だべ

```terminal
$ sudo chown -R $(whoami):admin /usr/local
$ brew update 
```

#GEMも前のパスが変わって使えなくなったので、インストール先を再設定やな

新しいPATHを設定しておくべ

```.bash_profile
export GEM_HOME=/usr/local/gems
export PATH=$GEM_HOME/bin:$PATH
```

必要なのを再インストールすっだ

```
$ gem install bundle
```


#Xtra Finder使えなくなったべ・・・

http://qiita.com/whitefox_105/items/0b70f7a504dcb72788e6

この記事の通りにやれば動くらしいだけど、まぁSIPへの理解が薄い人は下手に手出すべきではないべ



他にもなんかあっだら追記すっぺ
ROMAのクライアントその1(ruby client)

ROMAには何種類かクライアントがありますが、そのうちの一つのRuby Clientの使い方を簡単に紹介します

# Ruby Client
https://github.com/roma/roma-ruby-client

# 準備
`$ gem install roma-client`

# サンプル

```rb
require 'roma/client'

nodes = ["localhost_10001", "localhost_10002"]
rc = Roma::Client::RomaClient.new(nodes)

# set(key, val, expt = 0, raw = false)
rc.set('foo', 'bar') # STORED

# get(key, raw = false)
rc.get('foo') # bar

# delete(key)
rc.delete('foo') # DELETED
rc.get('foo') # nil

# stats(filter: "", node: @rttable.nodes.first)
rc.stats(filter: "nodes") # {"routing.nodes.length"=>"2", "routing.nodes"=>"[\"localhost_10001\", \"localhost_10002\"]", "routing.vnodes.length"=>"512", "routing.short_vnodes"=>"0", "routing.lost_vnodes"=>"0", "routing.version_of_nodes"=>"{\"localhost_10001\"=>66048, \"localhost_10002\"=>66048}"}
```


その他基本的な使い方は以下のPageにあります
https://github.com/roma/roma-ruby-client/blob/master/lib/roma/client/rclient.rb
https://github.com/roma/roma-ruby-client/tree/master/lib/roma/client/plugin


# 参照URL
ROMA ruby client: http://roma-kvs.org/docs/rubyclient.html
PHP PDO PostgreSQL 接続サンプル

PHPのPDOにて、PostgreSQLにアクセスするサンプルプログラム
失敗時は例外処理を実施する

```php:DB_PDO_sample.php
<?php
$dsn = 'pgsql:dbname=dbname_1 host=db.host.com port=5432';
$user = 'postgres_user';
$password = 'db_passsword';
try{
	$dbh = new PDO($dsn, $user, $password);
	$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $query =<<<__QUERY__
 SELECT :test ;
__QUERY__;
        $stmt = $dbh->prepare($query,array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
        $array = array(':test'=>' aaaa ');
        $stmt->execute($array);
        $result = $stmt->fetchAll(PDO::FETCH_ASSOC);
}catch (PDOException $e){
	print $query;
	print('Error:'.$e->getMessage());
	die();
} catch (Exception $e) {
	print('Error:'.$e->getMessage());
	die();
}

```
Android Studio の NDK 対応を追っかける

# 概要

Android Studio の NDK 対応が、従来の `Android.mk` によるものを十分に置き換えることができるようになるまでの過程を追っかけます。

 - [Experimental Plugin User Guide - Android Tools Project Site](http://tools.android.com/tech-docs/new-build-system/gradle-experimental)

# 今後の対応の予想

2015/12/18 時点では、まだ正式な NDK 対応ではなく、理想的な NDK 開発はできません。そもそも Gradle が C/C++ をサポートしたのが最近のことですし、従来の `Android.mk` スタイルの開発の方が無難と言えそうです。

しかし、以下を見る限り Gradle は Android NDK だけではなく Clang、GCC、Xcode、Visual Studio のツールチェインにも対応し、C/C++ だけでなくアセンブリ、Objective-C にも対応していくように思えます（もしくは Gradle 2.9 で既に対応している？）。

 - [Chapter 56. Building native binaries](https://docs.gradle.org/current/userguide/nativeBinaries.html)
 - [gradle/subprojects/docs/src/samples/native-binaries at gradle/gradle](https://github.com/gradle/gradle/tree/master/subprojects/docs/src/samples/native-binaries)

プラットフォームも Android だけでなく Linux、OS X、iOS、Windows にも対応していくように思えます。Eclipse や他の IDE から移行さえちゃえという本気度が伺えますね。

マルチプラットフォーム、マルチツールチェインに対応したネイティブのビルドツールといえば、最近だと Swift のビルドを支えている CMake、Google 製プロダクトのビルドを支えている GYP、GN と Ninja の組み合わせがありましたが、Gradle がそこまでやってくれるのであれば徐々に移行を考えていきたいところですね。

時間はかかりそうですが、非常に楽しみです！

# 更新履歴

## Pluging 0.4.0

複数の NDK プロジェクトの対応と、ただのネイティブライブラリを作れるようになっています。まだ完全ではありません。Gradle でコンパイルすることはできますが、編集はデバッグにはまだサポートされていません。

### ただのネイティブライブラリ

gradle-experimental:0.4.0 では、Android アプリケーション・ライブラリなしのただのネイティブライブラリを作れるようになっています。DSL は Android アプリケーション・ライブラリに似ています。以下のサンプルは `src/main/jni` のソースをビルドして `libhello.so` を作ります。

```groovy:build.gradle
apply plugin: "com.android.model.native"

model {
    android {
        compileSdkVersion = 21
    }
    android.ndk {
        moduleName = "hello"
    }
}
```

ただし、ソースを編集したら手動でビルドしないとアプリケーションに再リンクされません。

### NDK の依存関係

以下のようなネイティブライブラリプロジェクトがあったとすると・・・

```groovy:lib/build.gradle
apply plugin: "com.android.model.native"

model {
    android {
        compileSdkVersion = 21
    }
    android.ndk {
        moduleName = "hello"
    }
}
```

アプリケーションでは以下のようにして参照することができます。

```groovy:app/build.gradle
apply plugin: "com.android.model.application"

model {
    android {
        compileSdkVersion = 23
        buildToolsVersion = "23.0.0"
    }
    android.sources {
        main {
            jni {
                dependencies {
                    project ":lib1"
                }
            }
        }
    }
}
```

詳細は省きますが、Gradle の旨味のひとつである flavor にも対応しているようです。

## Pluging 0.6.0

ものはあるようですがドキュメントがまだありません。
Macのバッテリー状況をSlackに通知する

古いMacBookなんかをサーバ用途で使ってたりするときに，なにかの拍子で電源ケーブルが外れてしまいバッテリー切れとかなるとテンションだだ下がりなので死活監視がしたいです，安西先生．

## やること

SlackのIncoming Webhookを作成しておきます．

あとは↓なシェルを用意して適当な場所におき

```bash:battery_check.sh 
#!/bin/bash

# /usr/bin/pmset -g ps
#
# Now drawing from 'AC Power'
#  -InternalBattery-0	26%; charging; 2:22 remaining
#
# Now drawing from 'Battery Power'
#  -InternalBattery-0     100%; discharging; (no estimate) present: true

if `pmset -g ps | grep 'AC Power' &>/dev/null`; then
  rm -f /tmp/low_battery
  exit 0
fi

if [ -e /tmp/low_battery ]; then
  exit 0
fi

REMAINING=`pmset -g ps | tail -1 | cut -f2 | cut -d';' -f1 | tr -d '%'`
if [ $REMAINING -lt 20 ]; then
  touch /tmp/low_battery
  curl 	-X POST \
	--data-urlencode 'payload={"channel": "#general", "username": "怒りのバッテリー", "text": "バッテリーキレチャウヨ", "icon_emoji": ":ghost:"}' \
	https://hooks.slack.com/services/xxxxxxxx
fi
```

LaunchDaemonで60秒おきにチェック．周期は適当です．ほんとはLaunchAgentsでやれば良いと思う．．．

```xml:/Library/LaunchDaemons/local.battery_check.plist 
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Label</key>
	<string>local.battery_check</string>
	<key>ProgramArguments</key>
	<array>
		<string>/Library/LaunchDaemons/battery_check.sh</string>
	</array>
	<key>LowPriorityIO</key>
	<true/>
	<key>StandardOutPath</key>
	<string>/tmp/local.battery_check/stdout</string>
	<key>StandardErrorPath</key>
	<string>/tmp/local.battery_check/stderr</string>
	<key>RunAtLoad</key>
	<true/>
	<key>StartInterval</key>
	<integer>60</integer>
</dict>
</plist>
```

これでバッテリーで20%切ると通知されるようになります．

`pmset`コマンドはいろいろ取れそうなのでもっと何かできるかも．
BracketsでPSDをバラバラにする方法

# Extract for Brackets

こんな感じのPSDを...

![extract04.png](https://qiita-image-store.s3.amazonaws.com/0/83040/38ab90e3-882a-10b6-7a02-d10421a99d36.png)

## HTML

```lang:HTML
<a href="" class="btn">お問い合せはこちらから</a>
```

## CSS

```lang:CSS
.btn {
    font-size: 13px;
    color: #463c37;
    text-decoration: none;
    display: inline-block;
    padding: 15px 15px 15px 40px;
    background: url(images/icon_mail.png) no-repeat 15px 50%,
        -webkit-linear-gradient(90deg, #f7f2ee 0%, #ffffff 100%);
    background: url(images/icon_mail.png) no-repeat 15px 50%,
        -moz-linear-gradient(90deg, #f7f2ee 0%, #ffffff 100%);
    background: url(images/icon_mail.png) no-repeat 15px 50%,
        -o-linear-gradient(90deg, #f7f2ee 0%, #ffffff 100%);
    background: url(images/icon_mail.png) no-repeat 15px 50%,
        -ms-linear-gradient(90deg, #f7f2ee 0%, #ffffff 100%);
    background: url(images/icon_mail.png) no-repeat 15px 50%,
        linear-gradient(0deg, #f7f2ee 0%, #ffffff 100%);
    border-radius: 5px;
    border: 1px solid #d6bca4;
}
```

## Images
![icon_mail.png](https://qiita-image-store.s3.amazonaws.com/0/83040/d702ee4b-f428-5fff-3ee5-e9f646ad37a9.png)

一瞬でこんな感じにできます。

手順と完成品
http://blog.lqd.jp/html/001026.html
なぜ Realm を使うのか改めて振り返る

Realm の Advent Calendar を見ていると、だいたいみんな同じようなことを考えて対処しているんだなあ、と感じます。

ここでは、改めてなぜ Realm を使うのか（使ったのか）というところを振り返って書いてみたいと思います（なお、iOS アプリ開発で、Obj-C/Swift 混在環境で使いました）。

# なぜ Realm を使うのか

まず、そもそも、スマートフォンアプリにデータベースが必要なのでしょうか？

データベースって、特定の状況では便利なものだけど、一方で面倒なことも多いもの、というイメージがあるかと思っています。解決したい問題がちょっとしたものだったりすると、そのためにデータベースを導入するのは大袈裟すぎるのでは？ スマートフォンアプリ内部にわざわざデータベースを内蔵するのか？ という感じもします。

実のところ、データベースが欲しい、というよりも、次のような問題を解決する手段が欲しい、という望みがあります。

* アプリ内で使うオブジェクトをストレージに永続化したい。
    * 例えば、オンラインの場合はサーバからデータを取得するが、オフラインの場合はストレージにあるものを使いたい。あるいはキャッシュ的な用途。
* 永続化したオブジェクトに簡単にアクセスしたい。
    * 永続化したオブジェクトにアクセスするとき、何らかの展開・変換をしないと使えないようなものはつらい。

これを実現する有力な手段として、データベースを使うという手段があると考えています。言ってしまえば、その程度のことなので、導入や実装に労力がかかりすぎるとつらいわけです。

そこで、Realm が良い、という話になります。

導入は、他の一般的なライブラリと同じです。実装も、Realm で扱うオブジェクトは普通のアプリのモデルオブジェクトと同じような感覚で実装できて、簡単です。そして、永続化するのが簡単で、アクセスも簡単。欲しい要件が満たされています。

さらに言えば、アプリ内の Realm ファイルを外部に取り出して Realm Browser アプリで簡単に見れるので、デバッグやテストでも都合が良いです。

# Realm を使ううえでの注意点

Realm のオブジェクトを扱う場合に、普通のオブジェクトと扱いが違う点には注意を払う必要があります。

* オブジェクトを変更する場合はトランザクションの中で行う。
* 別スレッドにオブジェクトを渡すことはできない。

データベースなんだから普通そうだろう、という注意点です。しかし、データベースを使うというよりも永続化にちょっと便利なライブラリを使うという感覚で Realm を使うわけなので、改めて意識を払っておいたいポイントです。

特に後者は、個人的にはよく引っかかりました。将来的には Realm が対応してくれるらしいということで期待しています。

# 実装時によく使ったパターン

別スレッドにオブジェクトを渡すというのはやはり行いたいところです。対策としては、Realm のオブジェクトを別のオブジェクトに変換するという方法を、個人的には採用しています。通常の struct の static メソッドに次のようなものを定義して使いました。

```swift
struct Hoge {
    let param1: Int
    let param2: String
    ...

    static func fromRealm(object: RealmHoge) -> Hoge {
        return Hoge(
            param1: object.param1,
            param2: object.param2,
            ...
        )
    }
}
```

と言っても、Realm のオブジェクトをメインスレッドで使いたい場合に、単にそのメインスレッドで Realm のクエリを呼び出して使うようにしている箇所もあります（クエリが高速に動作するので、わざわざ専用のスレッドでクエリしなくても事足りる）。

（なお、以前 Realm meetup で発表した Realm と RxSwift のパターンは、今回は諸事情で使っていません・・・。普通に、RxSwift の subscribe の中で Realm のクエリを行うようにしました）

また、Web API から JSON で渡されるデータをそのまま Realm に保存したい、という場合があったので、APIKit と Himotoki との組み合わせで次のような感じで対処しました。

```swift
struct GroupRequest: AppAPIRequest { // <- APIKit
    func responseFromObject(object: AnyObject, URLResponse: NSHTTPURLResponse) -> Response? {    
        let response = try? decode(object) as Response // <- Himotoki
        if let response = response {
            dispatch_async(AppRealm.sharedInstance.queue) {
                let realm = try! RLMRealm(configuration: AppRealm.sharedInstance.configuration)
                realm.transactionWithBlock {
                    realm.addOrUpdateObjectsFromArray(response)
                }
            }
        }
        return response
    }
}
```

# まとめ

Realm のおかげで、データベースに対する抵抗というか苦手意識みたいなものがだいぶ軽減された、と個人的には思いました。Realm の今後に期待しています。
org-revealで細かい設定をしたい

# はじめに
こんにちは。nasa9084です。今日も元気にemacsを愛でていますでしょうか。
[Emacs Advent Calendar](http://qiita.com/advent-calendar/2015/emacs "Emacs Advent Calendar")、18日目です。
扨、emacsにはorg-reveal(MELPAではox-reveal)という、org-modeからreveal.jsを吐き出せるパッケージがあります。org-modeで適当に書いて、C-c C-e R Rするだけでreveal.jsを吐き出せるため、急ぎでスライド資料を作るときには非常に便利です。もちろん、reveal.jsなので、それなりに綺麗なスライドができますから、常用しても便利です。
しかし、org-revealを使っていくうえで、ちょっと変更したいけどどうしたらいいかとつまづいた部分がありましたので、今日はそのお話をしたいと思います。

## 基本的な設定方法
org-revealで設定を行うには、init.elで設定する方法と、orgファイル内で設定する方法がありますが、今回はorgファイル内で設定する方法をお話します。
orgファイル内で設定などのメタ情報を入力するには、行頭で`#+`から始まるメタ文字列を記入します。
ファイル内のどこに記入しても大丈夫なよう(未検証)ですが、設定情報なので、ファイルの頭に書いておくのがいいかと思います。

# 目次はいらない
org-revealで出力したスライドには標準で目次がつきます。正直、これいらないなって思うこともあります。また、目次はすべての見出しが表示されるため、見出しが増えると、下にはみ出ちゃうこともあります。
しかし、この設定方法はorg-revealのREADMEには書いてなかったんです。
目次を生成しないには、次の設定構文を書きます。

```
#+OPTIONS: toc:0
```

tocはTableOfContentsの略のようです。

# 生のHTMLを埋め込みたい
例えば、画像を左寄せしたいときなど、`<div style="float:left;">`なんかを埋め込みたいときがあると思います。
このとき、READMEには、`#+REVEAL_HTML`を使え、としか書いていませんでした。これではよくわかりません。
実際には、以下のように使います。

```
* org-revealの左寄せ
 #+REVEAL_HTML: <div style="float:left;">
- list
- list
- list
 #+REVEAL_HTML: </div>
```

# タイトルページもいらない
目次もいらない、生のHTMLがかけるようになったとなると、サブタイトルなどを入力できない標準のタイトルページではなく、タイトルぐらいは自分で書くという選択肢もあるかと思います。
しかし、タイトルページは標準で出力されるのです。
こんな時は、次のようなオプションを追加しましょう。

```
#+REVEAL_OPTIONS: reveal_title_slide:nil
```

# まとめ
org-revealのREADMEには載っていない、ちょっとした設定項目をご紹介しました。まぁ、二つはorg自体の項目でもあるんですけどね。org-revealについて、こんな便利機能、こんな設定があるよ！というのがございましたら教えてください。
[連載] WebVR入門 vol.3


この記事は [WebVR Advent Calendar](http://qiita.com/advent-calendar/2015/webvr) 16日目の記事です。

ちょっと遅くなっているのはご愛嬌です；

-------------------------------------------


[[連載] WebVR入門 vol.1](http://qiita.com/edo_m18/items/793ef4d96b41adcf3db3)で、ごく簡単なキューブの表示をWebVRで行う、という記事を書きました。
ただあまりにシンプル過ぎてVRらしさが皆無でした。

なので今回はこれにちょっと手を入れてVRとして見栄えのするものを作ろうと思います。
今回のサンプルは前回の続きとなります。


## 辺りを見渡せるようにSkyboxを追加する

真っ暗闇の中にキューブが浮いているのを立体視してもなにも面白くありませんね。
というかなんなら不気味な感じですらあります。
（まぁ普段経験できないようなことが体験できるのもVRの醍醐味ですがｗ）

なので、ここにSkyboxを追加してみようと思います。


### Skyboxって？

VRの話から若干それるのであまり詳細は説明しませんが、`Sky` と名前が付いていることからも分かる通り、空や遠景などを表示する手法です。
3Dの世界はとにかく負荷が高く、できるだけ人間の目を誤魔化すように誤魔化すようにと作られています。
このSkyboxも例外ではなく、遠景に当たる部分を、ワールド空間全体を覆うほど大きなキューブの中に閉じ込めて、そのキューブの中に空や遠景のテクスチャを貼ることで、まるで遠景も3Dでレンダリングされているかのように見せるテクニックです。

今回はこれを導入して、VRコンテンツの世界観をよりリアルなものにしたいと思います。


### Skyboxを生成する

前回からの差分はまさにSkyboxを作る部分のみです。
以下のコードは、Three.jsのexamplesに含まれているコードです。


```js
// Skybox
var cubeMap = new THREE.CubeTexture([]);
cubeMap.format = THREE.RGBFormat;
cubeMap.flipY = false;

var loader = new THREE.ImageLoader();
loader.load('texture/skyboxsun25degtest.png', function (image) {
    var getSide = function (x, y) {
        var size = 1024;
        var canvas = document.createElement('canvas');
        canvas.width  = size;
        canvas.height = size;

        var context = canvas.getContext('2d');
        context.drawImage(image, -x * size, -y * size);

        return canvas;
    }

    cubeMap.images[0] = getSide(2, 1);
    cubeMap.images[1] = getSide(0, 1);
    cubeMap.images[2] = getSide(1, 0);
    cubeMap.images[3] = getSide(1, 2);
    cubeMap.images[4] = getSide(1, 1);
    cubeMap.images[5] = getSide(3, 1);
    cubeMap.needsUpdate = true;
});

var cubeShader = THREE.ShaderLib['cube'];
cubeShader.uniforms['tCube'].value = cubeMap;

var skyboxMaterial = new THREE.ShaderMaterial({
    fragmentShader: cubeShader.fragmentShader,
    vertexShader: cubeShader.vertexShader,
    uniforms: cubeShader.uniforms,
    depthWrite: false,
    side: THREE.BackSide
});

var skybox = new THREE.Mesh(
    new THREE.BoxGeometry(10000, 10000, 10000),
    skyboxMaterial
);

scene.add(skybox);
```

上記のコードを追加すると以下のようになります。
![cap.png](https://qiita-image-store.s3.amazonaws.com/0/5616/4569845e-d1f3-458f-8f31-858219a947f0.png "cap.png")

[デモはこちら](http://edom18.github.io/webvr-advent-calendar/step2/)

デモのほうはOrbitControlsを付けて、マウスでドラッグすると辺りを見渡せるようにしてあります。
Oculus Riftがなくてもいちおう動作するのでよかったら見てみてください。

見てもらうと分かりますが、SkyboxをつけるだけでだいぶVR感が出てきましたね。


## 実は

さて、今回の記事、気づいている方は気づいていると思いますが、実はWebVR特有なことはなにもしていません。
ただのWebGLによるSkyboxの実装です。

ではなぜこれを書いたのかというと、VRというとちょっと特殊なイメージを持たれている方が多いと思ったからです。
ですが、今回実装したように、 **普通に** WebGLの実装を行い、シーンを構築し、あとはレンダリングのときにそれをVRモードで表示するだけで、どんなコンテンツもVR化することができる、ということを知ってもらいたかったからです。

もちろん、2Dのスクリーンに映しているから成り立っている演出などもあります。
ですが、それはそれなりに高度であったり、最終的なディティールのところになるので、VRを作る上では基礎的なところをしっかりやるだけでそれなりのコンテンツが作れるのです。

次回はこれにモバイル対応を入れて見たいと思います。
（まぁ実はこれも・・・）

ということで、今回は以上です。
Vim | vim -v は綺麗

それだけの話。

# コマンド

`$ vim -v `

# 結果

![image](https://qiita-image-store.s3.amazonaws.com/0/90607/5c619e6e-0e5b-0599-7ba8-6eacd0404fed.png)


# バージョン情報

画像を参照。



<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# メンター受付


https://menta.work/user/5694

<!-- Update From Qiita API -->
whileをやめてAWKにするその１

http://tech.aainc.co.jp/archives/9435 についてコメントを書きたかったがコメント欄が見つからなかったし自分のblogに書くのもなんか嫌なので何故かQiitaに投げてみる。Twitterだと文字数が足りなかった。なぜまる一年前のアドベントカレンダーを見ていたのかは秘密。

> awkで完結できないかと思っていたのですが、結局whileで回すことにしました。

僕はパフォーマンスの理由からwhileは~~目の敵にしている~~極力使わないでawkに任せようとしている。結論はやっぱりほぼawkで書ける。真面目に書くと

```
git branch -a --merged|awk '/^[^\*]/{print $1;cmd="git show --summary --pretty=format:\"%aN (%aE)%n\" " $1; for(i=0;i<2;i++){cmd |getline;print}close(cmd)}'
```

みたいな感じになる。

```
git branch -a --merged|awk '/^[^\*]/{print $1;"git show --summary --pretty=format:\"%aN (%aE)%n\"" $1|getline;print $0"\n"}
```

でも良さそう。
最安でSSL証明書が買えるサイト

## GoGetSSL

調べた中でこちらが多分最安。ものによっては90%OFFくらいで買える。
https://www.gogetssl.com/


## SSLs.com

こちらもかなり格安。加えてUIがシンプルでわかりやすい。
https://www.ssls.com/

もっと安く買えるところがあれば教えてください。
Git | commit --amend を途中で取り消しする方法  (コミットメッセージ入力中のキャンセル)

# 問題

## アメンドするぜ！

`$ git commit --amend` 

## やっぱりやめたい！

```
Fix you brain

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# ...
```

## 保存せずに抜けるぜ！

`:q!` ( vim のコマンド )

## うわあああ、コミットされてしまったああ！

```
 Date: Fri Dec 18 13:38:52 2015 +0900
 2 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 you-need-amend.rb
 create mode 100644 but-i-walk-my-way.sh
```

# 解決策1

`commit --amend` を

## 1.コミットメッセージをすべて削除する。

コミットメッセージが1行もない状態にする。(コメント行はあっても良い)

```
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Fri Dec 18 13:38:52 2015 +0900
```

ただし。空行・コメント行以外がひとつでもあるとコミットされてしまうので。
***ファイル内容を全削除***してしまった方が安全だろう。 ( `d` キーでも押しつつければ良い )

## 2.保存終了する

`:x` ( vim のコマンド )

## 3.結果

コミットされない。（元に戻る）

```
Aborting commit due to empty commit message.
```


# 解決策2

![image](https://qiita-image-store.s3.amazonaws.com/0/90607/8e4e0b47-d4b4-babf-9085-ca3b0f7d44d9.png)

# 普通はどうなの？

amend ではない普通の commit では。
ただ保存せず終了すればOKのようだ。 ( `:q!` )

# 環境

- git version 2.3.8 (Apple Git-58)
- vim 7.3

# 余談

コミット編集中のメッセージで明確に説明されていたことに、後で気づいた。

`an empty message aborts the commit.`



<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# メンター受付


https://menta.work/user/5694

<!-- Update From Qiita API -->
attr_encryptedでもwhereとかfind_byしたい

Ruby+ActiveRecordでDBの暗号化を行うGemとして[attr_encrypted](https://github.com/attr-encrypted/attr_encrypted)がありますが、暗号化する関係でFinderがちょっとめんどくさくなったりしたので適当にラッパを書きました、という話です。
( `:per_attribute_iv_and_salt`モードでは使えません)

## 現状
`uuid`, `email` というフィールドを暗号化しておきたいとすると、次のようなメソッドがGemにより自動的に使えるようになります。

```rb
user = User.find_by_uuid(plain_uuid)
```

しかし残念ながら`where(uuid: plain_uuid)`のような呼び方ができないのはちょっと不便です。

```rb
group.users.where(uuid: array_of_plain_uuids) # => マッチしない
```

また、メソッドチェーンの最後に`find_by_uuid()`のような呼び出しを置くこともできません。`find_by_xxx()`はattr_encryptedされたクラスに実装されているためです。

```rb
group.users.find_by_email(plain_email) # => NoMethodError
```

## 対策
というわけで、次のようなモンキーパッチを当てると（自分の環境では）気持ちよくコードがかけるようになります。

```rb:attr_encrypted_patch.rb
module ActiveRecord
  module QueryMethods
    def where_encrypted(opts = :chain, *rest)
      return where(opts, *rest) unless opts.is_a?(Hash)

      klass = self.klass

      encrypted_attrs = klass.try(:encrypted_attributes)
      return where(opts, *rest) unless encrypted_attrs

      # TODO: error handling?
      encrypted_arg =
          opts.map { |k, v|
            if (enc_info = encrypted_attrs[k])
              # key: wrap with prefix / suffix
              enc_k = "#{enc_info[:prefix]}#{k}#{enc_info[:suffix]}"

              # value:
              #   Array: each of its content must be encrypted
              #   Other: encrypted its value
              enc_v =
                  if v.is_a? Array
                    v.map { |each_v| klass.encrypt(k, each_v) }
                  else
                    klass.encrypt(k, v)
                  end
              [enc_k, enc_v]
            else
              [k, v]
            end
          }.to_h

      where(encrypted_arg)
    end

    def find_encrypted_by(attrs)
      where_encrypted(attrs).take
    end

    def find_encrypted_by!(attrs)
      where_encrypted(attrs).take!
    end

  end
end
```

## 結果
これによって、次のような呼び出し方ができるようになります。

```rb
users = group.users.where_encrypted(uuid: array_of_plain_uuids)
user = group.users.find_encrypted_by!(email: plain_email)
```

ただし、attr_encryptedで暗号化されているフィールドとされていないフィールドを一つの`where_encrypted`に含めることはできません。その場合は

```rb
hoge.where(not_enctypted_field: value).where_encrypted(enctypted_field: val)
```
のようにチェーンしてください。ORMがよしなにしてくれるので効率も問題ないはずです。

## 注意
…で、`opts = :chain`って何ですかね…？こういう変更かけても大丈夫なの？と不安ですが、とりあえず手元ではちゃんと動いてくれているようです。このコードだとこういう場合にうまく動かないよ、というようなご指摘があれば是非よろしくお願いします。
Node.js + MongoDB サイト構築メモ

### 概要 ###
以下のような軽い思いから Node.js、MongoDB について調べて情報を残してみます。

- NoSQLのデータベースに興味があったので MongoDB を使ってみる。
- ついでに MongoDBと相性の良い Node.js も使ってみる。
- 何か自分用の実際に使えるサイトを構築したい。

とりあえず試すための環境構築についてのメモとして残します。

### 対象環境＆モジュール（2015/12/17 時点）###
#### 対象環境 ####
- OS：Windows 8.1 Pro

#### 使用モジュール ####
- [Node.js ver.5.3.0 Stable 64bit msi版](https://nodejs.org/en/download/stable/)
- [MongoDB ver.3.2.0 stable 64bit msi版](https://www.mongodb.org/downloads#production)
- [Git ver.2.6.4](https://git-for-windows.github.io/) 

### インストール手順 ###
#### 1. Node.js のインストール ####
+ ダウンロードした Node.js をインストールする。
+ インストールはデフォルトのままで特別な指定は行う必要はなし。
+ 動作確認としてコマンドラインから `node -v` と入力して、バージョンが確認できればOK！

```text:コマンドライン
> node -v
v5.3.0

>
```
#### 2. MongoDB のインストール ####
+ ダウンロードした MongoDB をインストールする。
+ インストールはデフォルトのままで特別な指定は行う必要はなし。
+ 途中の Custom Or Complete を選択するダイアログでは Complete を選択
+ インストール後に PATH の設定を行う。<br>デフォルトでは `C:\Program Files\MongoDB\Server\3.2\bin\` なのでPATH に追加する。
+ `mongo --version` と入力してバージョンが確認できればOK。

```text:コマンドライン
> mongo --version
MongoDB shell version: 3.2.0

>
```

#### 3. Git のインストール ####
+ ダウンロードした MongoDB をインストールする。
+ インストールはデフォルトのままで特別な指定は行う必要はなし。
+ インストール後に PATH の設定を行う。<br>デフォルトでは `C:\Program Files\Git\bin\` なのでPATH に追加する。
+ `git --version` と入力してバージョンが確認できればOK。

```text:コマンドライン
> get --version
git version 2.5.0.windows.1

>
```

あとは、Node.js のモジュールを追加するだけなので取りあえずここまで。
次回は Node.js のモジュールの導入について残す予定です。

以上
[swift] [iOS] 実は簡単な画像フィルター

画像加工で周りを暗くして真ん中だけ元の色を残すやり方が以外に簡単だったので


##まずは元の画像はこんな感じ
<img width="100" alt="スクリーンショット 2015-12-18 13.15.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/13635/8a5f3a88-8a5f-73b5-966e-a10d448137b9.png">


##結果
<img width="100" alt="スクリーンショット 2015-12-18 13.15.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/13635/0f0febec-f05d-10e1-ae1f-6821296f2e73.png">




###ここからがコード

記載するコードはこれだけ
※コメントのほうに@loveeさんから指摘して頂いたコードが
あるので下記のコードと照らしあわせてみてください。

    override func viewDidLoad() {
        super.viewDidLoad()
        
        viewImage.image = UIImage(named: "IMG_3368")
        
        let filteredImage = CIImage(image: self.viewImage.image!)
        let filter = CIFilter(name: "CIVignette")
        
        filter!.setValue(filteredImage, forKey: "inputImage")
        filter!.setValue(NSNumber(float: 9.0), forKey: "inputIntensity")
        
        
        let ciContext = CIContext(options: nil)
        let imageRef = ciContext.createCGImage((filter?.outputImage)!, fromRect: (filter?.outputImage!.extent)!)
        let outputImage = UIImage(CGImage: imageRef)
        self.viewImage.image = outputImage
        
    }


###とりあえず適当な画像をいれる
`code`
viewImage.image = UIImage(named: "任意の画像")


###UIImageをCIImageにキャスト
`code`
let filteredImage = CIImage(image: self.viewImage.image!)

###フィルターを選ぶ
`code`
let filter = CIFilter(name: "CIVignette")
※フィルターは色々あるのでこちらを参考に色々ためしてみてくださいー
[Core Image Filter Reference by Apple](https://developer.apple.com/library/ios/documentation/GraphicsImaging/Reference/CoreImageFilterReference/index.html#//apple_ref/doc/uid/TP40004346)

###フィルターに値を入れていく
`code`
イメージをセット
filter!.setValue(filteredImage, forKey: "inputImage")

周りの色の濃さを変更
filter!.setValue(NSNumber(float: 9.0), forKey: "inputIntensity")
※NSNumber(float: 9.0)ここの数値を変更すると色の濃さが変わる


###コンテキストをつくってフィルターを適応
※このCIContextがいまいち意味がわからん
let ciContext = CIContext(options: nil)
let imageRef = ciContext.createCGImage((filter?.outputImage)!, fromRect:  filter?.outputImage!.extent)!)


###フィルターを通した画像を変数に入れる
`code`
let outputImage = UIImage(CGImage: imageRef)

###フィルタ加工した画像を代入してやる
self.viewImage.image = outputImage



とまぁこんな感じで簡単だった。
処理が結構重いのか表示に少し時間がかかるので、そのへんの細かいところは
UXでカバーしてみる。。。


間違っているところなどあれば、優しくつっこんでください！
imgのRetina対応の対策

#わたしの行ってるRetina対応の仕方
わたしの場合、Retina対応は`srcset`で行います。

```html:html
<img
  src="img.jpg"
  srcset="img.jpg 1x,
          img@2x/jpg 2x"
  alt="image">
```

`srcset`が対応してない場合は`src`に
`1x`で通常、`2x`で解像度２倍のとき用（２倍サイズの画像）ですね。

##ここから本題、わたしの体験上でのRetina対応の程度

というのが、１度全ての画像をRetina対応したのですが、これをすると

* macでの読み込みが遅くなる
* 画像差し替えで手間が２倍になる

といったことになります。
で、わたしが大変だったのが画像の差し替え。

すごいことに**１００枚以上の差し替え**が起きてしまった（なにがあった）んですが、
これ、全部Retina対応させてたせいで軽く**２００枚以上の差し替えになりました**・・・

ということで、上記のことによりRetina対応させる画像は以下に該当する場合がいいと思いました。

* サイズが**大きくない画像**
* **テキストを含む**そこまで大きくない画像

なぜこれかというと、そもそも大きい画像は表示時に縮小されてるので、割と綺麗に見えます。
もちろん、画像メインのページはRetina対応させてもいいと思います。

また**テキストのボケは顕著に出ます**。
大きい画像は縮小されてそこまでぼけないのですが、
ボタンなどで画像にした場合は対応すべきでしょうか。

---
###まとめ
今回わたしの経験上からのRetina対応をする範囲について書きました。

とりあえず画像全部をRetina対応させると大変だよ！ってことですね。（パフォーマンスもわるくなりますしね）

**適度な対応**を心がけてみてはいかがでしょうか。
日々のデバッグを楽しくする小技集

## 積み上がっていくクラッシュログ

日々モバイルアプリを開発、運用していると、どうしても避けられないのがアプリのクラッシュです。最近はクラッシュログを収集するサービスが充実してきており、公式のストアのコンソールでは得られない情報も簡単に集められます。

一方で、どんなに堅牢な設計で開発を進めていても、予期していないクラッシュログが集まってくるのも事実です。一週間もすれば細かいクラッシュログがどんどん積み上がって行きます。そして往々にして、その中の幾つかは深い闇に包まれた業の深いクラッシュログとして、解決するまでに時間を要することになります。

![日々積み上がっていくクラッシュログの山](https://qiita-image-store.s3.amazonaws.com/0/31829/569f3f63-13a3-5c4c-4a7e-37912c67169e.png)

中には自分たちだけでは解決の難しい、ライブラリの不具合に起因するものもありますが、そういったものを選り分けていくと、自分たちが対処すべきものが見えてきます。そして、すぐに解決できるもの、すぐには出来ないものと言ったものも見えてきます。

## クラッシュログの対応をモチベートする

すぐに対応できるものは速やかに対処するとして、直ぐにできそうにないものにどう対応していくかは重要な意思決定になります。ユーザの端末ではクラッシュし続けているので、なんとかしないとユーザは離れていってしまいます。

しかし、中々緒の見えないクラッシュログに対処するのは骨が折れるので、モチベーションの高いうちに対処しないと後回しになってしまいがちになります。

この記事では、どうやって対処方法を見出すか、意思決定の方法については**触れず**、いかにして**問題への対処のモチベーションを上げていくか**にフォーカスしてみようと思います。つまり、ほとんどネタです。

### TODOリストやタスク管理と併用する

Fabric であれば、Trello や GitHub といったサービスと連携して、クラッシュログへの対応をタスクに落とすことが出来ます。

### それぞれのクラッシュに名前をつける

できるだけ、そのクラッシュを解決したら何か良いことが起こることを想起させるような名前にしましょう。そう、例えば

- 焼き肉クラッシュ (対応が完了したら焼き肉が食べられる！)
- 焼酎バグ (対応が完了したら焼酎が飲める！)
- フォンダンショコラ例外 (対応が完了したらフォンダンショコラがもらえる！)

自分に思いつくのは食べ物ばかりですが、それ以外のものを選んでも良いです。そう、例えば

- 告白クラッシュ (俺、この対応が完了したらAさんに告白するんだ……)
- 温泉バグ (温泉宿にこもってデバッグするのでさがさないでください)

とにかく、ハングリーにクラッシュログの対応をしたくなる名前にしましょう。

### TODOリストやタスクチケットに画像を貼り付ける

ただ単に名前をつけただけでは刺激が足りない場合は、一緒に画像も貼り付けましょう。Trello なら、タスクリストに添付画像のサムネイルが表示されるので、楽しさ倍増です。

![寿司、うな重、お好み焼き](https://qiita-image-store.s3.amazonaws.com/0/31829/cf1a29f2-11c8-55ce-22e5-5cda60f2c4db.png)

ああ＾〜美味しそう。

## まとめ

いかがでしたでしょうか。悩ましい面倒なクラッシュログも、これなら後回しにせずなんとかしようという気分になりそうです。

現場からは以上ですが、とりあえずお好み焼きが食べたいです！！
備忘録 001 Linq to Sql を使ってみる(表示編)

※超初心者による備忘録の為、突っ込みどころ満載ですが、そこはスルーで、、、

1、Visual Studioでプロジェクトを作り、ソリューションエクスプローラーで追加→「Linq to Sql」「任意名01」.dbml
2、「任意名01」が真っ白画面で表示される。そこにサーバーエクスプローラーから入れたいテーブルをドラック&ドロップする。
(サーバーエクスプローラーにない時はその接続からする。)
3、ここで「F5」これ大事!!
これで「任意名01」.dbmlが、全体に自動で反映してくれる。
4、Blendを起動して、プロパティやらなにやらの領域をデータダブに切り替える。
5、データソースの作成→「オブジェクトデータの作成」
(昔は+CLRなんたらって、要は共通言語で翻訳したデータ作るよって意味なのだろう。)
6、色々出てくるけど、↑でデーブルを登録しているから、プロジェクト名下、テーブル名があるのでそれを選択する。と、かってにソース名が、テーブル名+DataSourceで作られる。
(任意名に変えれるのだろうけど分かりやすいからこのままでOK)
7、xamlに　DataGrid Name="「任意名02」"/>　を書き足す。(例はMainWindow)
8、.csのpublic MainWindow()の前で、DataContextとして読み込んで、後ろで「任意02」のItemsSourceとして吐き出す???で「とりあえずは表示される」。

```c#:MainWindow.xaml.cs
namespace プロジェクト名
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public 任意名01DataContext
            dataContext = new 任意名01DataContext();

        public MainWindow()
        {
            InitializeComponent();
            this.任意名02.ItemsSource = dataContext.テーブル名;
        }
    }
}

///比較用
namespace sql_test002
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public sql001DataContext
            dataContext = new sql001DataContext();

        public MainWindow()
        {
            InitializeComponent();
            this.list01.ItemsSource = dataContext.Test01;
        }
    }
}
```

usingは自動生成されたものを使用。
これでとりあえず表示だけはできる。

本当はXAML側から引っ張ってきたかったがどうBindingしてもからっぽになるからやはり流れの構造を理解する必要がありそう。

次はTextBoxからの追加と、DataGrid上での編集・更新・反映に進みたいところでもある。
先が長そうだ、、、

※尚、冒頭でもあるように、関数のネーミングセンスだったり、usingを最低限に絞るだの、構造の理解度だったりは、超初心者がツールの力とweb上のそれっぽいコードをたよりにやりたいことに対して直感的にやっているだけなのでアドバイスはうれしいですが、ご指摘をいただいてもその言っている意味が分からないかと思います。
「基礎から学べ」等ご意見もあるとは思いますが、それができない(心理的に)人間だからプログラムもできずこんなことでつまずいているわけで、、、あくまでも備忘録なのでそこらへんはお察しください。
[iOS] AppDelegateのPush通知用メソッドチートシート


毎回コピペするので。

```swift:AppDelegate.swift
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        
        registerForRemoteNotifications(application)
        
        if let userInfo = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] {
            // アプリが起動していない時にpush通知が届き、push通知から起動した場合
        }
        
        //...
    }
    
    //...
}
```

```swift:AppDelegate+RemoteNotifications.swift
import Foundation

extension AppDelegate {
    
    func registerForRemoteNotifications(application: UIApplication) {
        // 通知登録
        if #available(iOS 8.0, *) {
            let settings = UIUserNotificationSettings(forTypes: [.Badge, .Sound, .Alert], categories:nil)
            application.registerUserNotificationSettings(settings)
            application.registerForRemoteNotifications()
        } else {
            application.registerForRemoteNotificationTypes([.Badge, .Sound, .Alert])
        }
    }
    
    // Push通知登録完了
    func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData ) {
        print("deviceToken: \(deviceToken.description)")
        let deviceTokenString: String = deviceToken.description
            .stringByTrimmingCharactersInSet(NSCharacterSet(charactersInString: "<>"))
            .stringByReplacingOccurrencesOfString(" ", withString: "")
        print("deviceTokenString \(deviceTokenString)")
    }
    
    // Push通知利用不可
    func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {
        print("devideToken register error: " + "\(error)")
    }
    
    func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
        switch application.applicationState {
        case .Active:
            // アプリ起動中にPush通知を受信したとき
            break
        default:
            // アプリがバックグラウンドにいる状態で、Push通知から起動したとき
            break
        }
    }
}
```

# 参考

[iOS8以降]Push通知の実装とテスト(swift) - Qiita
http://qiita.com/k-yamada@github/items/258aec32a0d5b514f1cf

SwiftでPush通知 - Qiita
http://qiita.com/sawapi/items/feba100851de47fbe412
crontabの書き方とcrontabでのサーバ時刻合わせ設定 (AWS EC2 - Amazon Linux -- NTP)



# crontabでのサーバ時刻合わせ設定（NTP）

時刻合わせにはroot権限が必要なはずなので、rootで設定しましょう。

```bash
# 時刻合わせ
0 * * * * /usr/sbin/ntpdate -bs ntp1.noah.idc.jp > /dev/null 2>&1
```



# crontabの設定方法

###``/etc/crontab``の初期状態

```bash
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/

# For details see man 4 crontabs

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name command to be executed
```

###設定ファイル内容（``/etc/crontab``）

**環境変数設定**

変数の設定について説明します。
cronにはユーザの環境変数が引き継がれないため、ここで設定する必要があります。

``SHELL``

cronで使用されるシェルを設定します。

``PATH``

cronに教えるパスの設定します。
ここで設定されていないパス上にあるコマンド等を実行させる場合は、フルパスでコマンド等を設定する必要があります。

``MAILTO``

cronの実行結果を送るユーザまたはメールアドレスを指定します。
メールを送信したくない場合は「MAILTO=""」と設定します。

``HOME``

cronが実行されるカレントディレクトリとなります。

``その他の環境変数``

その他にも環境変数を設定したい場合は任意で設定することが可能です。
（変数名も任意で設定できます）


###コマンドスケジュール設定

```bash
# 分　時　日　月　曜日　実行ユーザ　実行コマンド

# 毎時15分に、「logger」コマンドで「/var/log/messages」にをログを書き出す設定
15 * * * * root logger crontab-test

```

**設定可能な数値**

|設定項目|数値|
|:-----------:|:------------:|
|分|0-59|
|時|0-23|
|日|1-31|
|月|1-12|
|曜日 |0-7 (0または7は日曜日）|0=日、1=月、2=火、3=水、4=木、5=金、6=土、7=日

※曜日補足
0=日、1=月、2=火、3=水、4=木、5=金、6=土、7=日

**実行時間指定方法**

|指定方法	|設定例	|説明|
|:-----------:|:------------:|:------------:|
|リスト|0,10,20,30|分フィールド指定した場合は0,10,20,30分に実行します。|
|範囲|1-5|月フィールドで指定した場合、1,2,3,4,5月に処理を実行します。|
|共存|1,6,9-11|時間フィールドで指定した場合、1時、6時、9時、10時、11時に処理を実行します。|
|間隔|*/10|分フィールドで指定した場合、10分間隔で処理を実行します。「/」の後ろに指定した値の間隔で処理を実行します。|


### ``/etc/cron.d``ディレクトリ内のファイル書き方

**「/etc/crontab」と同じ書式でかけば良いです。**


**注意をする点としては**

**1. パーミッションは644**
**2. 所有者はrootで**

ファイル名はなんでも良いようです。

「/etc/cron.d/」ディレクトリ内の「0hourly」ファイルを確認してみると、「/etc/crontab」と同じ書式で書かれていることが分かります。

「/etc/cron.d/0hourly」ファイル

```bash:/etc/cron.d/0hourly
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/
01 * * * * root run-parts /etc/cron.hourly
```


## cronが動かない場合

cronが動かない場合の切り分けとして下記の方法を試してみてください。

- ログを確認
- メールの確認
- ファイルのパーミッション・所有者の確認
- パスの確認
- 改行コードの確認？
- crondが動作しているか確認