OmniAICreator/Qiita-1.07M huggingface dataset:
iPython-notebook & ansible on CentOS7

# はじめに

ここでは iPython-notebook と ansible を CentOS7 上にインストールする方法と、iPython-notebook 上で ansible コマンドを実行し、別ホストのユーザーでコマンドを実行する一例を述べます。

iPython-notebookに関しては、下記の記事がとてもわかりやすかったです。（ついでに公式も）

 * [IPython Notebook チュートリアル](http://qiita.com/payashim/items/d4fe5227b21a5215e78b)
 * [The IPython Notebook 公式](http://ipython.org/notebook.html)

# インストール

```bash
sudo yum -y update
sudo yum -y install python-pip python-devel gcc gcc-c++ epel-release sshpass
sudo pip install jinja2 tornado pyzmq ipython paramiko pyyaml httplib2 ansible requests
```

# iPython-notebook

## iPython-notebook で使用するポート

CentOS7でのfirewall設定例。
ここでは8888をpublicにしています。

```bash
sudo firewall-cmd --list-all --zone=public
sudo firewall-cmd --add-port=8888/tcp --zone=public --permanent
sudo firewall-cmd --reload
sudo firewall-cmd --list-all --zone=public
```

## iPython-notebook を起動

notebook-dirは任意の場所でOKです。
永続化するのであれば & を最後に付けましょう。

```bash
mkdir /tmp/notebook
ipython notebook --no-browser --ip=0.0.0.0 --port=8888 --notebook-dir=/tmp/notebook
```

これで8888番ポートにブラウザからアクセスすると、iPython-notebookが使用できます。

# ansible

ansible を使うため、ホストをもう1台用意します。
ここでは、ホストAに ipython-notebook, ansible をインストールし、もう一方のホストBを notebook 上で操作することを目的とします。

## ホストAの設定

ここで生成した公開鍵はホストBで使用します。

```bash
mkdir -p /etc/ansible
echo "[defaults]" > /etc/ansible/ansible.cfg
echo "host_key_checking = False" >> /etc/ansible/ansible.cfg
cd /tmp/notebook
ssh-keygen -t rsa -f id_rsa -C "" -N ""
```

続いて、 ansible 用の inventry ファイルを作成します。
xxx.xxx.xxx.xxx はホストBのアドレスを書いて下さい。

```bash
echo 'xxx.xxx.xxx.xxx ansible_ssh_user=ansible' >> /tmp/inventry
```

## ホストBの設定

こちらで ansible ユーザーを作成し、ホストAで生成した公開鍵をauthorized_keysに設定します。

```bash
sudo adduser ansible --disabled-password
sudo mkdir /home/ansible/.ssh
sudo vim /home/ansible/.ssh/authorized_keys
sudo echo ansible ALL=\(ALL\) NOPASSWD: ALL > /etc/sudoers.d/ansible
sudo chmod 440 /etc/sudoers.d/ansible
```

## ansible を実行

まずは iPython-notebook を起動します。
これまでの設定の場合、ブラウザの notebook 上で下記のように実行することで、ホストB内のansibleユーザーを使うことができます。

```bash
!ansible --sudo -a "sh -c 'touch hoge.txt'" --private-key /tmp/notebook/id_rsa -i /tmp/inventry xxx.xxx.xxx.xxx
```

# おわりに

iPython-notebook は出力結果が残るので、作業履歴が明確になります。自分が見直すときも良いですが、引き継ぎにもnotebookを渡すだけで済みそうです。

使い道はいろいろあると思いますので、各々のベストプラクティスを探してみてはいかがでしょうか？
Excelファイル(xls, xlsx)をRubyで2次元配列として読み書きする


WIN32APIをそのまま触るとつらかったのでラッパーにしてみました。Windows専用です。

Excelファイルのシート単位で2次元配列として読みだして、慣れてるオブジェクト操作をして、出来上がったものをシート単位で書きだそう、という考えを適用しています。2次元配列ならみんな慣れてるので楽です。

WIN32OLEを直接触ることで他の操作も可能です。

なお、ExcelのWIN32APIのラッパーは[WrapExcel](https://github.com/tomiacannondale/wrap_excel)というGemがあります。

## 使い方
インスタンス生成時にファイルを指定します。相対パスでも絶対パスでも可能です。
存在しないファイルを指定した場合には、新規作成となります。

```ruby:末行に値を追加する
xl = ExcelTable.new('Book1.xlsx')

# Sheet1を2次元配列として読み出す
# シートの指定は数字でも可能
table = xl.read("Sheet1") 
table # => [["tes"]]

# 2次元配列を編集する
row = ["hoge", "ふが", Time.now, true, false, nil, 33, 3.14 ] # これらが使用可能なオブジェクト
table << row # 1行追記する

# 2次元配列をSheet1に反映
xl.write(table, "Sheet1") 

# 変更を保存して終了
xl.close 
```

実行結果↓
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/29945/03f68631-e4b4-f344-0404-efc15a8ca82c.png "キャプチャ.PNG")


`close`を忘れたり例外によって停止した場合、`at_exit`によってExcelを「変更を保存せずに終了」します。


## コード

```rb:excel_arrays.rb
class ExcelTable
  def initialize(file_path)
    require 'win32ole'
    @excel = WIN32OLE.new('Excel.Application')
    @fp = WIN32OLE.new('Scripting.FileSystemObject').GetAbsolutePathName(file_path)
    # cf. http://d.hatena.ne.jp/maluboh/20070709/p1

    @wbook = if File.exist?(@fp)
      @excel.Workbooks.Open(@fp)
    else
      @excel.Workbooks.Add
    end

    @allow_type = [ String, Numeric, Time, TrueClass, FalseClass, NilClass ]
    raise "\n#{file_path} は既に開かれているか読み取り専用です" if @wbook.Readonly

    # 例外時でもちゃんと閉じる
    # (不十分な実装)@excelが既に閉じているかどうかを調べるWIN32API関数？
    at_exit{ begin close(false) rescue nil end }
  end
  attr_accessor :excel, :wbook, :allow_type, :fp

  def read(sheet_key=1)
    sheet2table(@wbook.sheets[sheet_key])
  end

  def write(table, sheet_key=1)
    value_type_checking = table.all?{|a| a.all?{|v| @allow_type.any?{|type|v.kind_of?(type)} } }
    raise "非対応の型が含まれています" unless value_type_checking
    table2sheet(table, @wbook.sheets[sheet_key])
  end

  def close(is_save=true)
    if is_save
      @excel.DisplayAlerts = false
      @wbook.SaveAs(@fp)
    end

    @wbook.Close
    @excel.Quit
  end

  private
  def sheet2table(sheet)
    sheet.UsedRange.Rows.each.map{|row|
      a = row.Value
      a[0].class == Array ? a[0] : [a]
    }
  rescue
    []
  end

  def table2sheet(table, sheet)
    table.each.with_index(1) do |arr, i|
      arr.each.with_index(1) do |val, j|
        sheet.Rows[i].Columns[j] = val
      end
    end
  end
end
```




## おことわり
数式に対応していません。「=A1+A2」で計算結果が3.0のセルがあるとき、このラッパーはそれを`3.0`として読み込みます。さらに、`ExcelTable#write`はシート上の数値を全て上から値貼り付けするので、もとの「=A1+A2」という情報は失われます。

存在しないシートを指定したなど、例外処理してない例外は`method_missing`になります。
Vuforia 4.0 で、カメラ初期化に失敗する場合はCocoaPodsを外す

# Vuforia 4.0 で、カメラ初期化に失敗する場合はCocoaPodsを外す

2月にリリースになった、64bit対応の Vuforia4.0。
旧版からクラス変数に違いがあって、微妙に修正しないと古いコードでは動かないと思います。

新版のサンプルソースを見ながら修正を行いましたが、とあるところで大ハマり。


それは、カメラを初期化して起動する部分

```Objective-C
QCAR::CameraDevice::getInstance().init
```

にて、なぜか以下のようなエラーでこけました。

```
'*** -[AVCaptureVideoDataOutput setVideoSettings:] - b32a (1647522401) is not a supported pixel format type.  See AVCaptureOutput.h for a list of supported formats.  Available pixel format types on this platform are (420v, 420f, BGRA).'
```

AVCaptureOutput.hで定義されているプロパティに、b32aというピクセルフォーマットはないよというものらしいです。


### 結論
試行錯誤した結果、CocoaPods を外すと解決しました。
このプロジェクトでは不要だったのでよかったですが。
stubcellを使ってみた

## 紹介

リポジトリはこちら https://github.com/yosuke-furukawa/stubcell

要するに、json返すサーバーのモックが簡単に作れる的なもの
動くドキュメント的な用途で、ローカルで動す or 開発最初期にとりあえず実際のサーバーに立てておいても良いのではないかという感じですね

バージョンがまだ1.0になっていないのでこれから感はありますが、期待をこめてメモ残しておきます

## インストール

```bash
$ npm install stubcell
```

簡単！

## プロジェクト作成

まずは適当にディレクトリ作成

```bash
$ mkdir mock-server
$ cd mock-server
```

### entry.yaml

何はなくともこれが必要

今回はこんなかんじでGETのみ用意
レスポンスには bodyで直書き or fileで切り出し

```yaml
- # ルートのアクセステスト
  request:
    url: /
    method: GET
  response:
    status: 200
    body: '{ result: "ok" }'

- # ユーザーリスト
  request:
    url: /users
    method: GET
  response:
    status: 200
    file: users/index.json

- # ユーザー指定
  request:
    url: /users/:id
    method: GET
  response:
    status: 200
    file: users/show.json
```

### json file

必要なjsonファイルを作成

```bash
$ mkdir users
$ touch users/index.json
$ touch users/show.json
```

中身はこんな感じ

```json:users/index.json
{
    // stubcellのメリットとしてコメントが使えるらしいです( JSON5
    "users": [
        {
            "id": 1,
            "name": "user1",
            "message": "hello i'm 1"
        },
        {
            "id": 2,
            "name": "user2",
            "message": "hello i'm 2"
        },
        {
            "id": 3,
            "name": "user3",
            "message": "hello i'm 3"
        },
        {
            "id": 4,
            "name": "user4",
            "message": "hello i'm 4"
        },
        {
            "id": 5,
            "name": "user5",
            "message": "hello i'm 5"
        }
    ]
}
```

```json:show.json
{
    "id": 1,
    "name": "user1",
    "message": "hello i'm 1"
}
```

## サーバー起動

```bash
$ npm install stubcell -g
$ stubcell
```

で、とりあえず起動できます
デフォルトなら`localhost:8090`に立つので、アクセスを確認して見てください

オプションなどは https://github.com/yosuke-furukawa/stubcell へー
既存iOSアプリをCrashlyticsに対応させる

## 注意点
公式推奨のやり方とは少し異なります
変更点

- フレームワークはPodで導入しています
- Info.plistに手動で追記しています

## 準備

Fabricに登録しておく必要があります

また、Fabricプラグインを導入していなければ
https://fabric.io/downloads
よりDLして、起動、ログインをしておきます

## Podでフレームワークを導入

以下を追記

```rb:Podfile
pod 'Fabric/Crashlytics'
```

インストール

```bash
$ pod install
```

## AppDelegateに初期化処理追加

```objc:AppDelegate.m
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [Fabric with:@[CrashlyticsKit]];
    return YES;
}
@end
```

## Info.plistの編集
ソースコードで開き、以下を追加します
APIKeyは置き換えで

```xml
<key>Fabric</key>
<dict>
	<key>APIKey</key>
	<string><-YOUR-API-KEY-></string>
	<key>Kits</key>
	<array>
		<dict>
			<key>KitInfo</key>
			<dict/>
			<key>KitName</key>
			<string>Crashlytics</string>
		</dict>
	</array>
</dict>
```

## RunScriptの追加

Targetの設定 -> Build Phrases -> +ボタン -> New RunScript Phrase
で、以下を追加します
APIKeyとBuildSecretは適切なものへ変更します

```bash
./Pods/Fabric/Fabric.framework/run <YOUR-API-KEY> <YOUR-BUILD-SECRET>
```

ここまでで、ビルドが通ればOK
Fabricのページを見ると、勝手にアプリが追加されているはずです

## Answersの有効化 (Optional)
AnswersはFabricのDashboardの一番上のタブにある、リアルタイムの起動やDAUなんかを見れるパネルです
初回にページを開くと、有効にしますか？的なことを聞かれるはず
以下のように有効化しました

- `Yes, I want`的なボタンをクリック -> 待ち状態に
- 実機にインストールし、一旦Macから接続を外してアプリを再起動


## JenkinsやCI上での設定 (Optional)
設定しておくと、自動でBetaで配布することができるようになります

ビルド後に以下のスクリプトを追加

```bash
./Pods/Fabric/Crashlytics.framework/submit <YOUR-API-KEY> <YOUR-BUILD-SECRET> -ipaPath <YOUR-IPA-PATH> -groupAliases <YOUR-DISTRIBUTE-GROUP>
```

パスなどは適時変更で
gulp.watchはパスを./で始めると新規ファイルを処理しない

以下のようなbrowserifyするだけのgulpfile.jsは、よくある感じに見えるが、新しく.jsファイルが増えてもbrowserifyしてくれない。

```js
var gulp = require('gulp');
var gutil = require('gulp-util');
var browserify = require('browserify');
var source = require("vinyl-source-stream");

gulp.task('browserify', function(){
    return browserify('./js/main.js')
        .bundle()
        .on('error', function(err) {
            gutil.log(err);
            this.emit('end');
        })
        .pipe(source("app.js"))
        .pipe(gulp.dest('./dist'));
});

gulp.task('watch', function(){
    gulp.watch('./js/*.js', ['browserify']);  // ここがポイント
});
```

こうするとよい：

```js
var gulp = require('gulp');
var gutil = require('gulp-util');
var browserify = require('browserify');
var source = require("vinyl-source-stream");

gulp.task('browserify', function(){
    return browserify('./js/main.js')
        .bundle()
        .on('error', function(err) {
            gutil.log(err);
            this.emit('end');
        })
        .pipe(source("app.js"))
        .pipe(gulp.dest('./dist'));
});

gulp.task('watch', function(){
    gulp.watch('js/*.js', ['browserify']);
});
```

参考
https://github.com/sindresorhus/gulp-ruby-sass/issues/11
BigQuery で月別に分割されたテーブルを指定の日付範囲でスキャンする


次のようなフォーマットで月別にテーブルがあるとする。

```
nginx.access_201412
nginx.access_201501
nginx.access_201502
nginx.access_201503
```

2015-02-15 から 2015-03-03 までの範囲指定をしたいときは、料金節約のため、次のテーブルのみをスキャンしたい。

```
nginx.access_201502
nginx.access_201503
```

TABLE_DATE_RANGE は日付毎に分かれているテーブルにしか使えないため、TABLE_QUERY を駆使する。

```
SELECT
  *
FROM (
  TABLE_QUERY(nginx, "
    TIMESTAMP(
      REGEXP_EXTRACT(table_id, r'access_(\d{4})\d{2}') + '-' +
      REGEXP_EXTRACT(table_id, r'access_\d{4}(\d{2})') + '-01 00:00:00'
    ) <= TIMESTAMP('2015-03-03 00:00:00')
    AND
    TIMESTAMP(
      REGEXP_EXTRACT(table_id, r'access_(\d{4})\d{2}') + '-' + 
      REGEXP_EXTRACT(table_id, r'access_\d{4}(\d{2})') + '-01 00:00:00'
    ) >=
    TIMESTAMP(
      STRING(YEAR(TIMESTAMP('2015-02-15 00:00:00'))) + '-' + 
      STRING(MONTH(TIMESTAMP('2015-02-15 00:00:00'))) + '-01 00:00:00'
    )
"))
WHERE
  time >= '2015-02-15 00:00:00' AND time < '2015-03-03 00:00:00'
  ...
```

もっとスマートな方法があったら教えて下さい( ´∀｀)
Mokkosuでグモウスキー・ミラ写像を描画してみた

研究室の先輩が作ったプログラム言語Mokkosuで
グモウスキー・ミラ写像を描画するプログラムを作りました。

#スクリーンショット
![e4e.png](https://qiita-image-store.s3.amazonaws.com/0/70577/a6087fcb-caab-95ba-cb12-0e68356a6661.png)

#ソースコード
```
include "Graphics.mok";

#x(n+1) = y(n) + a(1-b y(n)^2)y(n) + f(x(n))
#y(n+1) = -x(n) + f(x(n+1))
#f(x) = mu x + 2(1-mu)x^2/(1+x^2)
let window_size = 500;
let x0 = 0.1;
let y0 = 0.1;
let a = 0.008;
let b = 0.05;
let mu = ~-.0.496;
let m = 11.5;

let iteration = 100000;

let calc_gumowski xpr ypr = 
  let f x = mu *. x +. 2.0 *. (1.0 -. mu)*. x *.x /. (1.0 +. x *. x) in
  let xn x y = y +. a *. (1.0 -. b *. y *. y)*.y +. (f x) in
  let yn x xn = ~-.x +. (f xn) in
  let x = xn xpr ypr in
  let y = yn xpr x in
  (x, y);  

let draw_gumowski gr =
  fun loop xpr ypr n =
    if n > iteration -> () else 
    let (x, y) = calc_gumowski xpr ypr in
    let distance = pow (x *. x +. y *. y) 0.5 *. m in
    let draw_x = double_to_int (x *. m) + window_size / 2 in
    let draw_y = double_to_int (y *. m) + window_size / 2 in
    let color_m =  distance /. (int_to_double (window_size / 2)) in
    let h = if color_m > 1.0 -> 360.0 else 360.0 *. color_m in
    let (r,g,b) = hsv_to_rgb h 0.6 0.9 in
    do draw_pixel gr r g b draw_x draw_y in
    loop  x y (n + 1)
  in
  loop x0 y0 1;
  
do scene "main" {
  ~Draw(gr) -> do
     draw_gumowski gr;
   end;
  _ -> ();
};

do set_size window_size window_size;

do show_window "main";
```
【javascript】配列と文字列の変換


#配列→文字列
区切り文字列で結合する。

```js
ary = ['Spring','Summer','Fall','Winter'];
str = ary.join(',');
console.log(str);
//=>Spring,Summer,Fall,Winter
```

#文字列→配列
区切り文字列で配列にする。

```js
str = 'Spring,Summer,Fall,Winter';
ary = str.split(',');
console.log(ary);
//=>["Spring", "Summer", "Fall", "Winter"] 
```
raspbian 初期設定

##IPアドレスを固定

```
$ sudo vi /etc/network/interfaces
```
ファイルを開く

```
iface eth0 inet static
address XXX.XXX.XXX.XXX
netmask 255.255.255.0
gateway XXX.XXX.XXX.XXX
```
eth0 を変更。address、netmask、gatewayを追加する。

##容量の確認
```
$ pi@raspberrypi ~ $ df -h
Filesystem      Size  Used Avail Use% Mounted on
rootfs          2.9G  2.4G  364M  87% /
/dev/root       2.9G  2.4G  364M  87% /
devtmpfs        460M     0  460M   0% /dev
tmpfs            93M  232K   93M   1% /run
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           186M     0  186M   0% /run/shm
/dev/mmcblk0p1   56M   15M   42M  26% /boot
```
容量を確認すると、本来のSDカードの容量が使われていない。

```
$sudo raspi-config
```
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/70042/bb4fb1dd-7d29-f398-648f-f6e0a4cc7cc5.png)

設定ツールを起動して、`1 Expand Filesystem`⇒`YES`⇒`YES`で再起動。

```
pi@raspberrypi ~ $ df -h
Filesystem      Size  Used Avail Use% Mounted on
rootfs           15G  2.4G   12G  17% /
/dev/root        15G  2.4G   12G  17% /
devtmpfs        460M     0  460M   0% /dev
tmpfs            93M  232K   93M   1% /run
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           186M     0  186M   0% /run/shm
/dev/mmcblk0p1   56M   15M   42M  26% /boot
```
無事本来の容量を認識した。

##言語設定
```
$sudo raspi-config
```
`4.Internationalisation Options ⇒　I1 Change Locale ⇒　ja_JP.UTF-8 UTF-8` を選択

`4.Internationalisation Options`⇒`I2 Change Timezone`⇒`Tokyo`を選択

設定ツールから言語を日本語、タイムゾーンを東京に設定。

`8.Advanced Options`⇒`A1 Overscan`⇒`Enable`を選択。

画面の表示方法をOverscanに設定。


##更新作業
```
$sudo apt-get update
$sudo apt-get upgrade
```
最新版をとってきて色々更新。

##再起動を実施
```
$sudo reboot
```

初期設定は以上。

##Wireless LAN Adapterの接続

```
$ lsusb
```

![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/70042/a902ac7b-42b0-283b-7b4e-a9e2bc33953a.png)

lsusbで接続したAdapterが認識されているかを確認する。

```
$ sudo vi /etc/wpa_supplicant/wpa_supplicant.conf

ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1

network={
    ssid="XXXXXXXXXXXXXXXXX"
    psk="XXXXXXXXXXXXXXXXX"
    # 0: default, 1: stealth
    scan_ssid=1
}
```
ssidとpskをコンフィグファイルに設定。
scan_ssidはステルス機能有効時に必要。

```
$ sudo rebbot
```
リブートして無線LANで接続が可能か確認する。
45歳以上はMongoDBを使ったシステムが使えなくなる件

MongoDBを使うシステムが、最近多いと思います。
2.6系(安定版)の最新2.6.7ですが、Date型のインポート処理にバグがありそうです。

「1970/01/01」以前の Date型 を mongoexport すると、負の "$numberLong" として出力されるのですが、それを mongoimport すると、それ以降のフィールドが欠落してしまうのです。

例えば、ユーザマスタに「誕生日」フィールドがあると、45歳以上の人は「1970/01/01」以前の値が入っているわけで、マスタデータを移行したりでもすると、その人のフィールドがガッツリ無くなってしまいます。でも若手は大丈夫だから「どうせ部長の使い方がおかしいんでしょwww」といういつもの「偉い人に限って障害が発生する」パターンが展開されます。


大急ぎで調べた所、以下が判明しました。

2.6形式

```
"1965-11-17T00:00:00Z" → "$date : { $numberLong": "-130118400000" }
"2014-04-24T00:00:00Z" → "$date": "2014-04-24T09:00:00.000+0900"
```

2.4形式

```
"1965-11-17T00:00:00Z" → "$date : -130118400000
"2014-04-24T00:00:00Z" → "$date": 1398297600000
```

2.4系では "$numberLong" を使わないフォーマットです。また、2.6系は2.4系のエクスポートファイルであれば、正常に読み込むことができるようです。


そこで、2.6系で出力したjsonを安全に読めるように変換するコンバータを作成しました。(node.js版)
(エクスポートしたjsonを標準入力で受け取り、標準出力に吐き出す)

```js
var fs = require('fs'),
  readline = require('readline'),
  rs = process.stdin,
  rl = readline.createInterface({'input': rs, 'output': {}});

var re1 = new RegExp(/({ "[$]date" : { "[$]numberLong" : "-[0-9]+" } })/g);
var re2 = new RegExp(/({ "[$]numberLong" : "(-[0-9]+)" })/);
rl.on('line', function (line) {
  line = line.replace(re1, function (term) {
    term = term.replace(re2, function (a, b, num) {
      return num;
    });
    return term;
  });
  console.log(line);
});
rl.resume();
```

使い方

```
$ node convert.js < エクスポート.json > 変換後エクスポート.json
```

これで、上司に怒られずに済みますね。
heroku+bottleで使ってみたいのでmongoDBを試してみる。

データベースに接続してjinja2テンプレートでリスト表示するところまで。

* ``pip install pymongo``でpymongoを入れて後は任せる。
* pythonのリストと辞書をちゃんと勉強すること。
* objectIDがあるのでjsonで困る問題はググるとみんなそうらしい、BSONで``from bson.json_util import dumps, loads``するのはやってみた。
* とりあえず{name:"name"}というデータの"name"をjinja2でforループ表示するのに、<a href="http://stackoverflow.com/questions/11166763/python-bottle-template-issue-attributeerrordict-object-has-no-attribute-ci">この方法</a>で試した。
* herokuにデプロイするときにはデータベースのパスとか変えるはずなので（<a href="https://1000ch.net/posts/2014/flask-mongodb-polymer.html">参考</a>）、またあとでやってみる。



```py:app.py

rom bottle import run, get, post, request
from bottle import TEMPLATE_PATH, jinja2_template as template
import pymongo
import bottle

@app.route('/', method=['GET' ,'POST'])
def index():
    if request.method=='POST':

        name = request.forms.get("name")

        conn=pymongo.Connection()
        db=conn.mydb
        db.mycol
        db.mycol.save({"name":name})

        result = db.mycol.find()
        viewmodel=[]
        for row in result:
          l = dict()
          for column in row:
            l[str(column)]=row[column]
            viewmodel.append(l)

        return template('form.html', mylist = viewmodel)

    elif request.method =="GET":

        conn=pymongo.Connection()
        db=conn.mydb
        db.mycol


        result = db.mycol.find()
        viewmodel=[]
        for row in result:
          l = dict()
          for column in row:
            l[str(column)]=row[column]
            viewmodel.append(l)

        return template('form.html', mylist = viewmodel)

```



```html:form.html

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
</head>
<body>
	
<form method="post" action="/">

<p>name: <input "form-control" type="text" name="name" size="50"></p>

<p><input type="submit" value="OK"></p>

</form>

{{name}}

<br>
<ul>
{% for item in mylist %}
<li>{{item}}</li>
{% endfor %}
</ul>

<br>
<ul>
{% for item in mylist %}
<li>{{item.name}}</li>
{% endfor %}
</ul>


</body>
</html>

```
Scala学習メモ

returnは存在するけど、ほとんど使わない。
最後の行だけが評価される。
副作用は入れるべきではない。
関数型プログラミングに向く。
高速な変化に耐えうる。
汚く書こうと思えば汚く書ける。
評価式なのかそうでないのかは意識する。
全角スペースは使用できない。
メソッドの中身に？？？と書いてコンパイルが通る▶︎テストから先に書ける。
すでにステージ上にあるファイルを.gitignoreに追加する

#先に結論
##ファイル
```linux
git rm --cached [rmしたいファイル]
git add -A
git commit -m "add xxx to .gitignore"
```

##ディレクトリ
```linux
git rm -r --cached [rmしたいディレクトリ]
git add -A
git commit -m "add xxx to .gitignore"
```

##全部
```linux
git rm -r --cached . 
git add -A
git commit -m "update .gitignore"
```

#git rmについて

① rmのみ

```linux
git rm text.php
```

ワーキングディレクトリおよびステージから削除。

② --cached

```linux
git rm --cached text.php
```

ステージから削除。ワーキングディレクトリには残っているので`git add`すればふつうにまたステージにあがる。
これは特にtext.phpを.gitignoreに追加したときにやるとよい。`.gitignore`はワーキングディレクトリからステージに`add`するときにフィルタとして通すので、一度ステージにあがってしまったものを`.gitignore`にあげても無視されない。一度ステージから削除する必要がある.

③ -r --cahced

```linux
git rm -r --cached
```
ディレクトリをステージから削除するときは`-r`オプションをつける。
Facebook連携　〜① Facebook開発者登録 〜

***
【目的】
iOSで、FaceBook連携をしたいのでまずは、Facebookの開発者登録から
2015.2.26
***

①　[Facebook Developers](https://developers.facebook.com/)から、ログインをすると右上部のメニューから「Requests」を選択する。（これの場所がわからず、無駄に時間がすぎた・・・）

<img src="https://qiita-image-store.s3.amazonaws.com/0/70430/15cefaef-ddd4-2f80-e7f5-a3e0ba4f18e2.png" width=500/>

②　「Register Now」をクリックして次に進む。
<img src="https://qiita-image-store.s3.amazonaws.com/0/70430/27079dd3-2e74-6ea4-c4e4-e59f4e703d35.png" width="500"/>

③　「はい」を選択して次に進む
<img src="https://qiita-image-store.s3.amazonaws.com/0/70430/4a2da87f-e0a5-8c9b-cef7-7a0f4083f08e.png" width="300"/>

④　確認コードを要求する。
・一回、ここではまりました。何回押しても確認コードが届かなかったのですが、1日置いたら確認コードが届くようになりました。
<img src="https://qiita-image-store.s3.amazonaws.com/0/70430/55a81993-28e7-252e-86a3-69c9f751a651.png" width="300"/>

⑤ 登録完了
<img src="https://qiita-image-store.s3.amazonaws.com/0/70430/80dc4c9e-e225-d977-a062-dc229e48f88a.png" width="300"/>

***
【結果】
確認コードが取れないという現象で悩んでいる人もいるみたいですが、1日経ったらいけるようになったので、原因は不明でした。
無事、開発者登録が完了したので、アプリ登録をしていきます。
***
nginxに配置したapkをインストール

#はじめに
apkのインストールをnginxでするためのメモ
設定ファイルの置き場所は特に指定がない場合のデフォルトです。

#設定
（１）mime.types
（２）conf

#mime.types

 >$ sudo vi /etc/nginx/mime.types

として下記を追加する

```:mime.types
application/vnd.android.package-archive  apk;
```

#conf

 >$ sudo vi /etc/nginx/conf.d/default.conf

```:default.conf
location ~ \.apk {
    add_header  Content-Type    application/vnd.android.package-archive;
}
```
#.htaccessを置くとどうなるか
ダウンロードできてしまいます。
nginxで動いていることを知らないユーザが誤って配置したりしてないか
管理しきるのは難しいです。

confなどでdeny allにして、実際にダウンロードされないのか試してみることをお勧めします。

#設定の読み込み

再起動前にテスト
>$ sudo nginx -t

設定を読み込むだけのパターン
>sudo service nginx reload

or 

>sudo nginx -s reload

再起動するパターン
>sudo service nginx restart

#参考URL
http://nginx.org/en/docs/beginners_guide.html

#apkのインストール
URLからアクセスしてインストール。

##URLの例
http://[ドメイン]/hoge.apk

#さいごに
探してもなかったので書いてみました。
htaccessを間違えておいてしまうことや、Webサーバの切り替えをapacheのドキュメントルート差し替えで対応してしまったりは結構ありそうな気がします。
Chef実行時に必要な環境変数の設定方法

```rb
execute "go get github.com/github/hub" do
  environment "GOPATH" => "/root/gocode"
end
```

こんな感じでこのrecipeを実行する時に必要な環境変数を設定できます。（永続的な環境変数ではありません）

一度のchef-soloの実行内でこの処理の前にbashのprofile等で環境変数を設定したりしているかもしれませんが、一度の実行中だと反映されていません。なので、そのコマンドで必要な環境変数は、上記のようにenvironment attributeで設定する必要があります。

なお、複数の環境変数を設定したい場合は以下のようにします。

```rb
execute "go get github.com/github/hub" do
  environment(
   "GOPATH" => "/root/gocode",
   "PATH" => "/usr/local/go/bin:#{ENV["PATH"]}"
  )
end
```


参考：

[https://docs.chef.io/resource_execute.html](https://docs.chef.io/resource_execute.html)
[http://d.hatena.ne.jp/rougeref/20141217](http://d.hatena.ne.jp/rougeref/20141217)
[PHP]送信されたフォームを判別して返信内容を分けるシンプルな方法。

一つのウェブサイトで複数のフォームを扱う際、フォームによって自動返信するメッセージや宛先などを変えるシンプルな方法です。

結論から言えば、switchやif文などの条件分岐を使うというお話で、PHP初心者向けになります。

**フォーム設置ページがHTMLの場合**

```html
<form action="sendmail.php" method="post" name="contact">
	<input type="text" name="name1">
	<input type="text" name="name2">
		…

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

	<!-- ここが判別スイッチ。ここに隠れ入力欄を入れ、値(value)にフォームの名前を入れる。 -->
	<input type="hidden" name="formtype" value="contact" checked="checked">
	<!-- 【解説】 type="hidden"←ページには表示されない name="①この入力欄の名前" value="②フォームの名前を分かりやすく入れましょう" -->
</form>
```

**フォーム設置ページがPHPの場合**

```html+php
<?php 
	$formtype = "contact";	//フォームの種類を分かりやすく決めておくと便利です。見積もりフォームなら "estimate" など。
 ?>
<form action="sendmail.php" method="post" name="<?php echo $formtype; ?>">
	<input type="text" name="name1">
	<input type="text" name="name2">
		…

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

	<!-- ここが判別スイッチ。ここに隠れ入力欄を入れ、値(value)にフォームの名前を入れる。 -->
	<input type="hidden" name="formtype" value="<?php echo $formtype; ?>" checked="checked">
	<!-- 【解説】 type="hidden"←ページには表示されない name="①この入力欄の名前" value="②フォームの名前を分かりやすく入れましょう" -->
</form>

```

**値を渡すPHP**

↑の例では sendmail.php に書くコードです。

```php
/* <input name="formtype" value="ここの値で判別させます">
	条件分岐を上手に使ってフォーム別に変更したいように内容をカスタマイズしましょう。
	今回は　"contact" と "estimate"　という値を例にしています。
*/
if(isset($_POST['formtype'])) {		//↑①name値
	$sendform = $_POST['formtype'];


	/* 	以下例	*/


	switch ($sendform) {
		// ↑②value値が contact なら以下の処理 ===========================
		case 'contact':
			$replyval = array(
				'mail' => 		'info@xxxxx.com',
				'subtitle' =>	'お問合せいただきありがとうございます。');
			$message = "この度はお問合せいただきありがとうございます。";
			break;

		// ↑②value値が estimate なら以下の処理 ==========================
		case 'estimate':
			$replyval = array(
				'mail' => 		'estimate@xxxxx.com',
				'subtitle' =>	'お見積りのご依頼ありがとうございます。');
			$message = "お見積りのご依頼を承りました。";
			break;

		// デフォルト（初期設定）。いずれでも無かった場合の処理。 ===================
		default:
			//処理処理
			break;
	}

} else {
		// 判別スイッチなしの場合の処理
}
```

上記のように配列や変数にそれぞれ設定すれば、簡単にフォーム別に異なる内容を送信できます。

**送信処理**

```php
$to = 		$replyval['mail'];
$subject = 	$replyval['subtitle'];
$header = 'hogehoge';

mb_send_mail($to, $subject, $message, $header);
```
Debian7へOracle Java8をインストールする方法

ちょっとだけハマったので自分用メモ

#1 debファイルを作成するための下準備その１
デフォルトの状態で`apt-get install java-package`してもそんなもの見つからないよと言われます。
[hatayanlog-Debian (sarge) で Java-package をつかって Java をインストール](http://www.hatayan.org/weblog/archives/2006/02/21/165141.php)
を参考に
/etc/apt/sources.listに

`deb ftp://ftp.riken.go.jp/pub/Linux/debian/debian/ stable contrib`

を追加したらインストールできました

#2 debファイルを作成するための下準備その２
OracleサイトからJDK(tar.gz)をダウンロードしてきて
`fakeroot make-jpkg`するとJDK1.8の場合
`No matching plugin was found.`
と怒られます。
そこで/usr/share/java-package/orale-j2sdk.shに以下を追加

`        "jdk-8u"[0-9][0-9]"-linux-i586.tar.gz") # SUPPORTED
            j2se_version=1.8.0+update${archive_name:6:2}${revision}
            j2se_expected_min_size=190 #Mb
            j2se_priority=317
            found=true
            ;;
`
*jdk-7uのところをパクって8に変えただけです。64bitの人はamd64|x86_64-linux-gnu)のところでjdk-7uをパクってください*


#3 debファイルを作成する
`fakeroot mke-jpkg ダウンロードしてきたJDK.tar.gz`
でdebファイルが出来上がるので
`dpkg -i 出来上がった.deb`
でインストール完了

#4  標準で使用するJavaに設定する

`update-alternatives --config java`
でさきほど入れたJavaを標準で使用するように設定して終わり
NightmareでE2Eテストしつつスクリーンショットとってgifに結合したら目視チェックが最高に楽になった


最近またe2eを書いたりしてる。色々悩んだけど、やっぱNightmareを使うことにした。

Nightmareについては僕が前書いた記事を参考にしてください [NightmareでE2E - Qiita](http://qiita.com/mizchi/items/2c406b501a4f93ca9752 "NightmareでE2E - Qiita")


## Nightmareの良い点

- Zero configuration
- というかただのスクレイパー

## 悪い点

- プロセス立ちあげるのが遅い
- JSわかってないと読みづらい


PrecepeterとかTestiumとかProtractor試したけどどれも走らせるだけでいっぱいいっぱいで、もう面倒臭い。

僕は行儀が悪いのでスクレイパーを走らせられればいいです。エビデンス() はスクリーンショットで確保する方向で。



## 連番のスクリーションショットを取りながらNightmareを走らせるサンプル


```coffee
Nightmare = require 'nightmare'

class TestRunner extends Nightmare
  constructor: (@capture_dir='') ->
    super()
    @cnt = 0

  init: (url) ->
    @
    .viewport(800, 600)
    .goto url

  zeroPaddingNum = (n) =>
    switch n.toString().length
      when 1 then '00' + n.toString()
      when 2 then '0' + n.toString()
      when 3 then n.toString()
      else
        throw 'too big'

  capture: (name) ->
    r = @screenshot __dirname + "/screenshots/#{@capture_dir}/"+zeroPaddingNum(@cnt)+'-'+name+'.png'
    @cnt += 1
    r

```

こんな風に使う

test/e2e/main-test.coffee

```coffee
describe 'Test', ->
  it 'test', (done, reject) ->
    url = path.resolve __dirname + '/../../public/index.html'
    new TestRunner('case1')
    .init url
    .wait()
    .capture('main')
    .click('.js-goto-sub')
    .wait(300)
    .capture('sub')
    .run (err) ->
      if err then return done(err)
      done()
```

どこから実行するかによるけど、実行したらこんな風に書きだされてるはず

```
screenshots/case1/001-main.png
screenshots/case1/002-sub.png
...
```


で走らせ終わったら、 ImageMagick で `convert -delay 30 -loop 0 **/*.png e2e.gif` で0.3sごとに切り替わるgifが作れる。雑に目視チェックしてホワイトアウトしてないか、ミスって画面切り替わりそこねてないかとか確認して、問題なかったらコミット。みたいな感じ。


(実際に撮影したgifは開発中のアプリの情報を含むため表に出せない…あとでなんか別のサンプルを用意する)


楽になったし、連番スクショは仕様わからない人にも説明しやすい。
executeリーソースとbashリソースのある違い


```rb

execute "go get github.com/github/hub"
```

```rb

bash "go get github.com/github/hub"
```

前者は動くのに後者はなぜか動かず、瞬間で処理が終了してしまっていた。エラーも吐かず正常終了しているように見えるので、原因がわからなかったが、公式ドキュメントを読み原因がわかった。

[https://docs.chef.io/resource_execute.html](https://docs.chef.io/resource_execute.html)
[https://docs.chef.io/resource_bash.html](https://docs.chef.io/resource_bash.html)


executeのnameの説明

>name is the name of the resource block; when the command attribute is not specified as part of a recipe, name is also **the command to be executed**

bashのnameの説明

>name is the name of the resource block; when the command attribute is not specified as part of a recipe, name is also **the name of the command to be executed**


ということで、bashの場合は、nameをコマンドとして取り扱ってくれるわけでないということのようです。
[初心者向け] VirtualBoxとVagrantを利用して、MacOS X上にCentOSの仮想環境を構築

# 1. 概要
MacOS X上にCentOSのローカル開発環境を構築します。

今回は、仮想環境の構築手法として一般的な、
VirtualBoxとVagrantを利用した方法を書いております。

# 2. VirtualBoxのインストール
仮想環境を立ち上げるために必要なものです。

**ダウンロードURL (公式サイト)**
[https://www.virtualbox.org/wiki/Downloads](https://www.virtualbox.org/wiki/Downloads)

途中いろいろと聞かれますが、全部デフォルトで大丈夫です。

# 3. Vagrantのインストール
仮想環境を簡単に立ち上げることができるツールです。

**ダウンロードURL (公式サイト)**
[http://www.vagrantup.com/downloads.html](http://www.vagrantup.com/downloads.html)

ここでもいろいろと聞かれますが、全部デフォルトでOK。

**vagrantバージョン確認コマンド** (正常にインストールされたか確認)
`$ vagrant --version`
> **実行結果**
`Vagrant 1.7.2`

# 4. Vagrantにboxの追加
Vagrantには、boxと呼ばれる仮想環境にいれるテンプレート(OS)がたくさん用意されています。

box追加コマンドを利用して、お好みのOS環境を追加することができます。

**box追加コマンド**
`$ vagrant box add [任意のbox名] [ダウンロードURL]`

**各テンプレート(OS)ごとのboxファイルダウンロードURL一覧**
[http://www.vagrantbox.es/](http://www.vagrantbox.es/)

今回は、CentOSの仮想環境をつくりたいので、
一覧にある「**CentOS 6.4 x86_64**」というboxを、
「**centos-6.4**」というbox名で追加したいと思います。

**「centos-6.4」box 追加コマンド**
`$ vagrant box add centos-6.4 https://github.com/2creatives/vagrant-centos/releases/download/v6.4.2/centos64-x86_64-20140116.box`

**追加済みbox 確認コマンド** (正常に追加されたか確認)
`$ vagrant box list`
> **実行結果**
`centos-6.4        (virtualbox, 0)`

# 5. Vagrantの初期化
実際に、vagrantの立ち上げ(=仮想環境の立ち上げ)を行う前に、初期化を行い、
**Vagrantfile** と呼ばれる設定ファイルを生成します。

**Vagrant 初期化コマンド**
`$ vagrant init [box名]`

今回は、「**centos-6.4**」というboxを利用して、Vagrantを初期化します。
`$ vagrant init centos-6.4`

# 6. Vagrantの立ち上げ (= 仮想環境の立ち上げ)
ここまでで、仮想環境の立ち上げの準備は完了です。
あとはVagrantを実行すれば、仮想環境は立ち上がります。

**Vagrant 実行コマンド**
`$ vagrant up`

# 7. 仮想環境にログイン
無事に仮想環境が立ち上がったら、その仮想環境にログインし、
シェルへアクセスできるようになります。

**仮想環境ログインコマンド**
`$ vagrant ssh`
> **実行結果**
`[vagrant@vagrant-centos-6.4 ~]`
Python で Project Euler #15「格子経路」

[Problem 15 「格子経路」](http://odz.sakura.ne.jp/projecteuler/index.php?cmd=read&page=Problem%2015)

> 2×2 のマス目の左上からスタートした場合, 引き返しなしで右下にいくルートは 6 つある.
> 
> ![p_15.gif](https://qiita-image-store.s3.amazonaws.com/0/2570/13089be6-c7aa-c885-8a95-30b8961c41a6.gif)
> 
> では, 20×20 のマス目ではいくつのルートがあるか.

```py:Python
# n = 2
n = 20

route_nums = {}

seq = range(1, n+2)

def compute_route_num(i, j):
  if(i == 1 or j == 1):
    return 1
  else:
    return route_nums[(i-1, j)] + route_nums[(i, j-1)]

for i in seq:
  for j in seq:
    route = compute_route_num(i, j)
    route_nums[(i, j)] = route

result = route_nums[(n+1, n+1)]
result

print result
print result == 137846528820
```

```:結果
137846528820
True
```
[ネーミング]Railsのscopeはアンダースコアはじまりで書くとすっきりすると思う


コーディング規約とかサンプルアプリとかWebでいろいろ見ても、どこにもそんなこと書いてないオレオレ規約だけど、
scopeは `scope :_active, -> { where(active:true) }` みたいに書いたらすっきりすると思う。

[rails-style-guide README-jaJA.md at master · satour rails-style-guide · GitHub](https://github.com/satour/rails-style-guide/blob/master/README-jaJA.md#named-scopes)

を見ると、こういう風に書けばいいよとあるけど

```user.rb
class User < ActiveRecord::Base
  scope :active, -> { where(active: true) }
  scope :inactive, -> { where(active: false) }

  scope :with_orders, -> { joins(:orders).select('distinct(users.id)') }
end
```

アンダースコアではじめて

```user.rb
class User < ActiveRecord::Base
  scope :_active, -> { where(active: true) }
  scope :_inactive, -> { where(active: false) }

  scope :_with_orders, -> { joins(:orders).select('distinct(users.id)') }
end
```

こうするとなにがうれしいかというと、
メソッドチェーンで書いてもレシーバが変わってないのがひと目で分かる。

Modelにはメソッドもあれば、belongs_toやhas_manyなどのアソシエーションもあり、いまselfが何を指してるか注意しないといけない。

`User.active.with_orders`
より
`User._active._with_orders`
のが断然わかりやすいと思うんだがどうだろうか？
stash でユーザー名を忘れたら

stashのセットアップで何気なくユーザー名を入力したので、
セットアップ完了後にユーザー名を忘れてログインできなくなってしまいました。

メールサーバを設定していないと、システム的に再設定はできないようです。

仕方ないので、データベースを直接見に行きました。

cwd_user テーブルの user_name がユーザーネームでした。
惚れるほど更新しやすいExcelレポートの作り方

# はじめに
週次や日次でKPIのレポートなどを提出する際、システムから吐き出したCSVファイルや別のExcelシートからデータをコピペして、、、とかなり面倒な作業をしなければいけないことってありますよね。

そんな時、レポートのExcelシートの構成を少しだけ工夫するだけで、データの更新やメンテがとてもやりやすくなります。

# よくあるExcelレポートの問題
たとえば、レポートを作成するのに、

* CSVファイルを一旦ピボットテーブルで整理して、
* 前回作成したExcelレポートの中に値貼り付けして、
* 別のExcelファイルから一部分を切り取って値貼り付けして、
* 一部の数字を手で書き換えて

なんてなことをやっていませんか？

このようなやり方だと、

* Excelレポートの中の一部の値を更新し忘れてたり、
* せっかく苦労して作ったセルの計算式をうっかり壊してしまったり、
* 前任者から引き継いだExcelレポートの計算式が複雑すぎてメンテできない、

といった問題が絶えません。Excelデータと格闘して一日が終わる、という笑えないことになりかねません。

# データ更新の必要なシートを切り出す
一つのExcelレポートを作成するために、通常、複数のデータを参照し集計する必要があります。

よくありがちなExcelレポートの問題は、提出するレポートの表の中のセルを直接手で値を更新しなければいけない、というものです。表の中のあっちこっちを更新しなければいけないとなると、作業も煩雑になり、更新漏れや間違って別のセルを書き換えてしまうというミスがおきます。

そこで、データを更新しなければいけないものを切り出して、データ入力のための専用のシートに分けましょう。

このときできれば、データソースごと・種別ごとに別々のシートにしてしまうのがオススメです。無理に一つのシートにいろいろなデータを混在させるのは混乱の元です。

![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/21349/c2dec073-621c-cffa-112d-2f6f423f4cdc.png)

データの更新で注意すべき事項や操作方法についてのメモをこのシートの余白に書いておくようにしましょう。あとで、ほかの人に作業を引き継ぐのがとても楽になります。

# データの集計処理を1つのシートにまとめる
データの集計処理も別シートに切り出しましょう。

提出用のレポートの表の中で複雑な計算をすると、表示内容や位置を変更するたびに計算式を修正しなければならなくなってしまいます。

データ入力シートからレポートに作成に必要な集計処理を行い、レポートの表示に必要な集計をすべてこの集計シートの中で行います。

ポイントはデータ入力シートを更新するだけで、すべての集計が自動で計算式の中だけで行われるように組み立てることです。データを手作業でピボットテーブルに組むなどの作業が必要ないように、計算式だけで処理できるようにします。どうしても計算式だけで処理できない手作業が発生する場合は、VBAでマクロにします。

このようにしておくことで、不用意に計算式を壊してしまうなどのミスを最小限にすることができます。

# 最後に報告用のシートを作る
報告用のレポートシートは、これまで作ってきたデータ入力シートや集計シートで計算した内容を元に、見やすくレイアウトを作っていきます。レポートの中は、集計シートなどで計算した結果を参照するだけにして、極力レポートの中では計算はしないようにしましょう。

このようにすることで、データの更新も簡単になり、あとからレポートの体裁を修正するのも簡単になります。また、レポートの元データが同じExcelファイル内に残っていることから、集計結果の検算や別のレポートへの加工をする際に、元データのありかを探したりする必要もなくなります。
TurnipでAction Mailer Previewsを使う


Turnipでスクリーンショット取りたくてやってみたら出来たからメモです.

前提としてRails4.1以上でTurnipのテストができる状態になってることとします.

## 書き足したソース

RailsのAction Mailer Previewsは[`development`環境でしか使えない](https://github.com/rails/rails/blob/d6dec7fcb6b8fddf8c170182d4fe64ecfc7b2261/railties/lib/rails/application/finisher.rb#L23)ので自前でルートを追加.

```ruby:config/routes.rb
if Rails.env.test?
  get '/rails/mailers'      , to: "rails/mailers#index"
  get '/rails/mailers/*path', to: "rails/mailers#preview", as: 'mail_preview'
end
```

ついでにパスもspecに変更.

```ruby:config/application.rb
config.action_mailer.preview_path = "#{Rails.root}/spec/mailers/previews"
```

最後に送信したメールを対象にプレビュー表示させておく.

```ruby:spec/mailers/previews/test_mailer_preview.rb
class TestMailerPreview < ActionMailer::Preview

  def last
    ActionMailer::Base.deliveries.last
  end
end
```

`step`を以下のように書いておくと`feature`で開ける。
あとはスクリーンショットのステップをコールすればいい感じ。

```ruby:spec/steps/mail_steps.rb
step %(最後に送信したメールを表示) do
  url = mail_preview_path(path: 'test_mailer/last')
  visit url
end
```

## やろうとして諦めたこと

### メールプレビューからメールヘッダのチェック等をするstep

プレビューのHTMLがシンプルすぎて諦めた.

### メールプレビューから本文を使ったstep

本文部分がiframeだったので萎えて諦めた.

[stackoverflowに取得の仕方](http://stackoverflow.com/questions/16034224/handling-iframe-with-capybara-ruby)が書いてあったけど未検証.

```ruby
within_frame(find('<css rule>')) do
  <code for dealing with iframe entries>
end
```
Android Studioでアプリケーションを実行しても画面が表示されない

Android Studioでアプリケーションを実行（デバッグ実行）しても画面が表示されないという問題が発生。
色々と調べていた所、アプリケーション実行時にActivityを立ち上げないという設定がOnになっておりました...そんな設定があるとは。

同設定は`Run > Edit Configurations > Android Application > app`にあります。
その他にも特定のActivityを立ち上げる事もできるみたいですね。
いい勉強になりました。

![001.png](https://qiita-image-store.s3.amazonaws.com/0/68456/b5cda153-b7ce-4148-8a9e-d8337181e927.png)
特定の文字を含むテキストリンクをクリックする


FireBugやWebKit系では`$x`関数でxpathをつかって指定できるらしいので、それを使った。

例 無効とinnerTextに書かれたリンクの1番目をクリック

```js
$x("//a[contains(text(), '無効')]")[0].click()
```
cocos2d-js (v3.2) で多角形をレンダリングする

http://qiita.com/nise_nabe/items/c4d07c5c9fc34f0a616c と同様のことを v3.2 で実現するためのコードです。

v3.2 では多角形を表示する際には DrawNode を用います。[DrawNode](http://www.cocos2d-x.org/reference/html5-js/V3.2/symbols/cc.DrawNode.html) (APIリファレンス)

## 内容

cocos new で作成される src/app.js を下記のように変更していきます。
描画の指定は DrawNode の drawPoly() で行います。drawPoly の第一引数には各頂点座標の情報を cc.Point の配列の形式で指定します (cc.Point は cc.p を使用して作成します)。この配列の値にしたがって辺が描画されます。

```js
var DrawLayer = cc.Layer.extend({
    node: null,
    ctor:function () {
        this._super();
        this.node = new cc.DrawNode();
        this.addChild(this.node);

        this.node.drawPoly([cc.p(0, 0), cc.p(200,0), cc.p(200, 200)]);
        return true;
    }
});

var DrawScene = cc.Scene.extend({
    onEnter:function () {
        this._super();
        var layer = new DrawLayer();
        this.addChild(layer);
    }
});
```

また、加えて drawPoly に塗りつぶしの色と線の太さ、線の色を指定することも可能です。色の指定は cc.color() を使用し、引数として R,G,B,A の順に 0から 255の値を指定します。

```js
        this.node.drawPoly([cc.p(0, 0), cc.p(100,0), cc.p(100, 100)],
                          cc.color(255, 0, 0, 255), 3, 
                          cc.color(255, 128, 128, 255));

```
【小ネタ】 HTML のチェックボックスを readonly にする

HTML のチェックボックスには何故か `readonly` 属性がないらしい。ただし HTML のチェックボックスは OFF 時には項目そのものが送られないため、普通は `hidden` タイプの要素を組み合わせる。

```html
<input type="hidden" name="checkItem1" value="0">
<input type="checkbox" onclick="this.form.checkItem.value=this.checked ? 1 : 0" id='normal'> <label for='normal'>通常のチェックボックス</label>
```

<input type="hidden" name="checkItem1" value="0">
<input type="checkbox" onclick="this.form.checkItem1.value=this.checked ? 1 : 0" id='normal'> <label for='normal'>通常のチェックボックス</label>

したがって、チェックボックスを readonly にするには `disabled` 属性を使って

```html
<input type="hidden" name="checkItem2" value="0">
<input type="checkbox" id='checkoff' disabled='disabled'> <label for='checkoff'>チェック OFF の状態で固定</label>
<input type="hidden" name="checkItem3" value="1">
<input type="checkbox" id='checkon' disabled='disabled' checked='checked'> <label for='checkon'>チェック ON の状態で固定</label>
```

<input type="hidden" name="checkItem2" value="0">
<input type="checkbox" id='checkoff' disabled='disabled'> <label for='checkoff'>チェック OFF の状態で固定</label>
<input type="hidden" name="checkItem3" value="1">
<input type="checkbox" id='checkon' disabled='disabled' checked='checked'> <label for='checkon'>チェック ON の状態で固定</label>

とすればいいようだ。
gulp + decomposer: Bower経由でインストールしたアセットをSASS(SCSS)で@importする仕組みをつくる

gulp + browserify(+ debowerify)という構成でWebサイトを作っていると、SASSにもdebowerify相当のものが欲しくなってくる。

ちなみに、__debowerify__というのは、

```js
var Velocity = require("velocity");
```

というJavascriptを、

```js
var Velocity = require("./../../bower_components/velocity/velocity.js");
```

という風に、bower_components内のパスに解決してくれるbrowserify transformだ。
欲しいのはこれのSASS版。

「あったらいいのにな〜」と思うようなライブラリはGithubで検索すれば必ず出てくる。はずだったが、無かった。

そこで [decomposer](https://www.npmjs.com/package/decomposer) というgulpプラグインを作った。

# 使い方

まずは`npm install --save-dev gulp gulp-sass decomposer`で必要なものをインストールしておく。既存のプロジェクトに追加するならdecomposerだけでいい。

__gulpfile.js__はこのように定義しておく。

```js
var gulp = require('gulp');
var sass = require('gulp-sass');
var decomposer = require('decomposer');

gulp.task('styles', function() {
  gulp.src('src/styles/**/*.sass')
    .pipe(decomposer())
    .pipe(sass({indentedSyntax: true}))
    .pipe(gulp.dest('dist/css'));
});
```

ポイントは`sass`__よりも前__に`decomposer`を挟むこと。なぜなら、外部から@importしたmix-insや変数はSASSコンパイル時に解決されるからだ。`sass`よりも後に置くと、SASSが@importを解決出来ずにエラーが発生する。

続けてSASSを書こう。

```sass
@import normalize.sass
@import styles/font

body
  font-family: $ff-gothic
```

> `$ff-gothic`は [uetchy/styles](https://github.com/uetchy/styles) の _font.sass で定義されているfont-familyだ。

最後にBowerを使って必要なアセットをインストールする。

```console
$ bower i --save normalize.sass
$ bower i --save uetchy/styles
```

これで完成。後は`gulp styles`を実行するだけだ。

# ファイルパス解決時のポイント

decomposer はBowerモジュールに入っている任意のファイルを指定して@importすることが出来る。
記法はこのようになる。

```sass
@import [Bowerモジュール名]/[ファイル名]
```

例えば、よく使うスタイルをまとめた [uetchy/styles](https://github.com/uetchy/styles) の___font.sass__ を@importするなら、

```sass
@import styles/font
```

と書ける。
ここでもし`@import styles`と、ファイル名を省略して書くとどうなるのだろうか？コンパイルに失敗する？そんなことはない。

モジュール名だけを書くと、decomposerは__bower.json__に書かれているmainファイルを見つけ出して、それを@importしてくれるのだ。

もしmainファイルが複数指定されていたら、`index.sass`とか`[モジュール名].sass`とか、__mainっぽい名前__を持つファイルを@importする。

つまり、

```sass
@import normalize.sass
```

と書けば、

```sass
@import ../bower_components/normalize.sass/normalize.sass
```

という風に解決される。

# まとめ

これでスタイルの@importをすっきり書けるようになった。
とはいえ、component対応やPlain CSSのインライン展開、.less対応など、追加したい機能は色々ある。

もしContributionに興味があるなら、[Githubリポジトリ](https://github.com/uetchy/decomposer)をフォークしてほしい。
Android Studio で compileSdkVersion を Google APIs にする

\<ANDROID_SDK\>/add-ons/addon-google_apis-google-21 を compileSdkVersion にする方法を調べました。

Eclipse の Properties > Android > Project Build Target で Google APIs を選択したプロジェクトを作成し、Android Studio にインポートしたところ、下記の指定がされていました。

    compileSdkVersion 'Google Inc.:Google APIs:21'

これらは manifest.ini にある値下記の形式で構成されているようです。

    <vendor>:<name>:<api> 

```ini:manifest.ini
# SDK Add-on Manifest

name=Google APIs
name-id=google_apis
vendor=Google Inc.
vendor-id=google
description=Android + Google APIs

# version of the Android platform on which this add-on is built.
api=21

# revision of the add-on
revision=1

# list of libraries, separated by a semi-colon.
libraries=com.google.android.maps;com.android.future.usb.accessory;com.google.android.media.effects

# details for each library
com.google.android.maps=maps.jar;API for Google Maps
com.android.future.usb.accessory=usb.jar;API for USB Accessories
com.google.android.media.effects=effects.jar;Collection of video effects

SystemImage.GpuSupport=true
```
curlでファイルのFTPアップロード


```
$ curl -T ${FILENAME} -u ${USER}:${PASSWORD} --ftp-create-dirs -ssl -k ftp://${HOSTNAME}:${UPLOAD_PATH}
```


* -k は「安全でないSSL/TLS接続を行う」なので、基本外して使う。
* --ftp-create-dirs はディレクトリがない場合に作成してくれる
springのデフォルトスコープをprototypeにする

良いか悪いかは別にしてspringのDIでデフォルトのScopeが「singleton」になっているために事件が発生してしまう事があります。

これを変更する際には@Scopeアノテーションを使って都度指定する方法が良く見つかりますが「いちいち面倒だし忘れて事故るの嫌だから全部prototypeでいいよ！」って時にデフォルトを変更する方法。

springの設定ファイルでcomponent-scanの設定時にscope-resolverに「org.springframework.context.annotation.Jsr330ScopeMetadataResolver」を指定します。

```xml
<context:component-scan base-package="your.base.package"
  scope-resolver="org.springframework.context.annotation.Jsr330ScopeMetadataResolver" />
```

こうする事で、意図的にsingletonにしたい時だけ@Scope("singleton")と書けるようになります。


**本来、Jsr330ScopeMetadataResolverはJSR330の仕様ではデフォルトスコープがprototypeであるため、JSR330のアノテーションでDIしたいときに使うものです。**
javascript無名関数でハマった話

```
// メインループ
var loop = function() {
...
setTimeout(arguments.callee, 1000 / 30);
}

// 準備ができたらloopを開始
(function(){
if (okay) loop();
else setTimeout(arguments.callee, 1);
})();
```

これ`undefined is not function`が出るんだけど、

```
var loop = function(){...}(...)();
```

と解釈されてた・・・。

正しくは

```
// メインループ
var loop = function() {
...
setTimeout(arguments.callee, 1000 / 30);
}; // 行末セミコロン

// 準備ができたらloopを開始
(function(){
if (okay) loop();
else setTimeout(arguments.callee, 1);
})();
```


あるいはこっちの構文だと問題ない。



```
// メインループ
function loop() {
...
setTimeout(arguments.callee, 1000 / 30);
} // 行末セミコロン不要

// 準備ができたらloopを開始
(function(){
if (okay) loop();
else setTimeout(arguments.callee, 1);
})();
```

気づかんわ！！
confluence > "["で始まる文章を入力したい > ".["で始めて"."を消す

confluenceではconfluence上の機能を使う時に"["という入力を使う。このため、"["をテキストで入力する時に面倒くさい。

"["の記号は行頭で使われた時にconfluenceの機能が動作する。
行の途中で"["を入力した時は、普通のテキストとして認識される。
これを利用して、以下の手順で入力する。

    1. ".["で文章を書き始める
    2. 文章を書き終わってから行頭の"."を削除する
    
<hr>
@の入力と同様に"["入力直後に[Esc]キーを押すことでConfluenceの機能をやめることができた。ただ、そのまま入力をして"]"を入力した時に"["から"]"までを変換する別の機能が動いてしまう。上記の方法だとこういうややこしいことにならない。
InstagramのハッシュタグRSS取得について

# 2015/02/26時点でのハッシュタグRSSの取得はできない？

## InstagramでハッシュタグのRSSが取得できるURL(現在使用不可？)

既存の内容かもしれない。
以下の参考ページでの記事により、次のURLで特定ハッシュタグに関する写真一覧のRSS取得ができるはずだったが、できなかった。日付が確認できる記事は2014年2月9日に投稿されていた為、まだ使用できると考えていたのだが。

http://instagram.com/tags/タグ名/feed/recent.rss

参考:http://s-wander.com/blog/web/210.html
参考:http://empitsu88.tumblr.com/post/2970990939/instagram-api
記事作者様有難うございます。

## どうやら現在(2015/02/26)では、OAUTH2認証を経たうえでWEB APIでハッシュ関連写真一覧の取得を行うようだ。

APIのリファレンスはこちら。
[Instagram Developer Documentation](https://instagram.com/developer/)

取得したかったハッシュに関する写真一覧の取得は次のAPIを使用して行う模様。
https://api.instagram.com/v1/tags/{tagname}/media/recent

ただし、このAPIで取得できるのは、Instagram APIで定められたJSON形式のオブジェクトなので、他のサービスに投げる場合等はRSSに変換する必要がある。
cocos2d-js のアニメーションを動かす / 反転させる

まぁ出来るだろうと思って試した。
cc.RepeatForever でアニメーションさせておきつつ MoveBy で動かせる。
cc.Spawn で同時に動かしたりしなくていいのかな、と思ったんだけどこれでいけた。

```js
var animation = cc.AnimationCache.getInstance().getAnimation('animation_name');
animation.setRestoreOriginalFrame(true);
var animation_sprite = cc.Sprite.create( image_path, cc.rect(0, 0, width, height) );
animation_sprite.setPosition(220, 240);
layer.addChild(anime_sprite, 300);

animation_sprite.runAction( cc.RepeatForever.create( cc.Animate.create(animation)) );
animation_sprite.runAction( cc.MoveBy.create(10, cc.p(200,100) ) );
```

反転は setScale に負の値を指定したらできた。これはアニメーションじゃなくてもそういう挙動になるってことだね。

```js
var animation_sprite2 = cc.Sprite.create( image_path, cc.rect(0, 0, width, height) );
animation_sprite2.setPosition(420, 240);
animation_sprite2.setScale(-1);
this.addChild(animation_sprite2, 300);

animation_sprite2.runAction( cc.RepeatForever.create( cc.Animate.create(animation)) );
```
WindowsでJavaセキュリティ例外サイトを追加するスクリプト

#javaのセキュリティ例外リストにサイトを追加する
##概要
Javaのセキュリティ要件がどんどん厳しくなってきています。
テスト環境では正式な署名したりしないので、例外サイトに登録してしまう事も多いと思います。

今回は例として以下のサイトを追加するバッチを、DOSバッチとPowerShellで作成してみます。

　http://sample1.com/
　https://sample2.com/

といっても、単純に以下のファイルにURLを追加するだけです。
Vista以降
%APPDATA%\..\LocalLow\sun\Java\Deployment\Security\exception.sites
XP
%APPDATA%\sun\Java\Deployment\Security\exception.sites

ただし、最低限の汎用性を持たせるために、以下の条件を実装しました。
* 既存の登録済サイトは残したまま登録対象を追加する
* 登録対象が既に追加されていた場合は2重登録しないようにする

##DOSバッチ
```bat:DOS-Batch
SETLOCAL ENABLEDELAYEDEXPANSION

REM SET EX_PATH="%APPDATA%\sun\Java\Deployment\Security\exception.sites"
SET EX_PATH="%APPDATA%\..\LocalLow\sun\Java\Deployment\Security\exception.sites"

REM ここで登録するサイトをリストアップ
SET EX_SITE[0]=http://sample1.com/
SET EX_SITE[1]=https://sample2.com/

REM 　　　　　　　　↓終了インデックスは登録数に合わせる
FOR /L %%i IN (0,1,1) DO (
	FINDSTR !EX_SITE[%%i]! %EX_PATH%
  IF ERRORLEVEL 1 ECHO !EX_SITE[%%i]!>> %EX_PATH%
)
```

##PowerShell
デフォルトのセキュリティ設定ではスクリプトファイル*.ps1が実行できないので要注意。

```ps1:PowerShell
# file path
#$ex_path = "$env:APPDATA\Sun\Java\Deployment\security\exception.sites"
$ex_path = "$env:APPDATA\..\LocalLow\Sun\Java\Deployment\security\exception.sites"

# target site
$ex_sites = @("http://www.example1.com/","https://www.example2.com/")

foreach($ex_site in $ex_sites){
  if( -Not(Select-String $ex_site $ex_path -quiet) ){
    Add-Content $ex_path "$ex_site"
  }
}
echo "例外サイト追加しました"
```