OmniAICreator/Qiita-1.07M huggingface dataset:
Excelの苦しい業務もVBAで気を紛らわす

`VBA`を利用して、`csv`のある列から抽出したデータを一つのファイルに並べていく方法です。

現場にて、必ず発生するExcel作業。
その中で今回は、某資産管理ツールから数百台の端末それぞれに入っている全アプリケーション情報をエクスポートし、各部門ごとの標準アプリケーションを決める仕事を任された。

まず辛かったのはエクスポート作業。
イケてない管理方法とツールのお陰様で１台１台エクスポートをぽちぽち押して、Excelファイルにしていく。。。

これだけで苦痛だが、さらに台数分ある、アプリケーション情報をまとめて全台数中どのくらいの割合で各アプリケーションが入っているのか見ていくのだ。

これには心が折れそうになった。
数百あるExcelファイルで各ファイル中必要な情報は１行だけ。
それらを抽出し、一つのファイルにまとめる作業から入らなければならない。

せっかく最近プログラミングというものを覚えてきたので、それに近しいVBAを利用してこの作業を自動化することで行き場のない思いを晴らすことにした。

やりだすとそこそこ楽しかったので備忘録的に残しておく。

 ***以下、`VBA Scrypt`(と簡単な説明)***

■環境
OS : Windows10
Tool : Microsoft Office Excel 2013

■説明
複数のエクセルシートから同じ列の値を横に並べていく
ファイル名`1.xlsx`~`n.xlsx`で`C:\sample`配下にあるとする。 (nは実際の数字を入れること)
抽出したい列は`B`、で順に並べていく

基本的には

　対象ファイルを開く
→ B列を抽出する
→ まとめファイルに貼り付け
→ ファイルを閉じる
→ ファイル数分繰り返し

■手順
`macro.xlsx(←名前はなんでも可)`を同フォルダに置き開く 
⇒ `Alt` + `F11` 
⇒ `挿入`　
⇒ `標準モジュール`　
⇒ `下記のスクリプトを貼り付け実行`

```vba:VBA
//関数の名前
Sub MacroChallenge()

//myPathを定義
  Const myPath As String = "C:\sample\"

//wbを定義
  Dim wb As Workbook
  Set wb = Workbooks("macro.xlsx")

//rIdxに数字`1`を代入
  Dim rIdx As Long
  rIdx = 1

//fNameを定義
  Dim fName As String

//"n.xlsx"という名前のファイルまで来たら抽出して貼り付けていく作業を辞める。
  Do Until rIdx = n + 1 (→`n + 1`には実際の数字を入れる)

//fNameに"n.xlsx"を代入
    fName = Dir(myPath & rIdx & ".xlsx")

//"n.xlsx"を開く
    Workbooks.Open Filename:=myPath & fName

//"n.xlsx"の１枚目のシートから"B"列を抽出して"macro.xlsx"の"macro"シートのA列から1列ずつ貼り付けていく
    wb.Worksheets("macro").Columns(rIdx).Value =　Workbooks(fName).Worksheets(1).Columns(2).Value

//"n.xlsx"を閉じる
    Workbooks(fName).Close SaveChanges:=False

//rIdxに１を加えてrIdxに代入
    rIdx = rIdx + 1

//  "Do Until rIdx = n + 1"に戻る
  Loop
End Sub
```

上記のものでも200ファイルで5分ほどかかったので、もっといい方法があれば随時更新（きっと）。
遊び感覚でできて良い。
自習サイト一覧(今後追加していく予定)

##安定
###dotinstall
安定。ほとんどの言語のさわりを行うのに十分。
とりあえずこれやっとけばおk

###progate
dotinstallよりもより深く勉強したいときにオススメ
取り扱っている言語はdotinstallより多くはないが、十分使える。
最近はコマンドラインやgitも実装されるらしいので、触れておきたい。

##なんか良さそう
###codeprep
穴埋め形式で勉強可能。
言語のみではなく、様々な機能の実装も記載されている
復習とかに良いかも


##いつか触っていきたいかも
###paiza
dotinstallみたいに動画を見て勉強するやつ
上のものでやることがなくなったらやれば良いかも

##結論
毎日勉強ですね。15分とか短時間でもやれば、1ヶ月で450分 -> ７時間30分。
1年でも5400分 -> 90時間となる。
だらだらとやるのではなく、短時間に集中的に取り組むように頑張っていこう。
自分にすごい突き刺さるな・・・
rbenvインストール手順

rbenvのインストール手順を記録に残しておく。
rbenvは複数のRubyのバージョンを管理することができ、アプリケーションごとに異なったRubyのバージョンを使うことができる。

## 環境

使用したOSバージョンは次の通り。

* CentOS 6.8

## 手順

1. rbenvスクリプトを配置する。

    ```
    git clone https://github.com/rbenv/rbenv.git ~/.rbenv
    ```
2. rbenvスクリプトの実行設定を行う。

    ```
    echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
    ```
3. 下記コマンドを実行し、指示にしたがう。

    ```
    ~/.rbenv/bin/rbenv init
    ```

    今回の環境では次の行を```~/.bash_profile```に追記するよう指示された。

    ```
    eval "$(rbenv init -)"
    ```

4. 設定反映のため、シェルに入り直す。

5. rbenvスクリプトの動作確認を行う。

    下記コマンドを実行し、```rbenv is a function```が表示されることを確認する。

    ```
    type rbenv
    ```
6. ruby-buildをインストールする。

    ruby-buildプラグインをインストールすることで、Rubyのインストールを自動化できる。

    ```
    git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
    ```

7. Rubyの依存パッケージをインストールする。

    ````
    sudo yum install -y gcc openssl-devel readline-devel zlib-devel
    ```

8. Rubyをインストールする

    インストールできるバージョンは```rbenv install -l```で確認できる。

    ```
    rbenv install (インストールするバージョン)
    ```

## 使い方

rbenvでRubyのバージョンを切り替える方法は次の2種類がある。

* ディレクトリごとにバージョンを指定
* システム全体でバージョンを指定

※両方の指定がある場合はディレクトリごとのバージョン指定が優先される。

### ディレクトリごとにバージョンを指定する場合

1. バージョンを指定するディレクトリに移動する
2. バージョンを指定する

    ```
    rbenv local (バージョン)
    ````
3. バージョンが指定されたか確認する

    ````
    rbenv version
    ruby -v
    ```

### システム全体でバージョンを指定する場合

1. バージョンを指定する

    ```
    rbenv global (バージョン)
    ```

2. バージョンが指定されたか確認する

    ````
    rbenv version
    ruby -v
    ```

### rbenvサブコマンド

よく使うサブコマンドは次のものがある。

rbenvでインストールしているすべてのRubyのバージョンを表示

```
rbenv versions
```

現在指定されているRubyのバージョンを表示

```
rbenv version
```

## 参考ページ

rbenvインストール
https://github.com/rbenv/rbenv#basic-github-checkout
ruby-buildインストール
https://github.com/rbenv/ruby-build#installation
エンジニア未経験者による客先常駐先で学んだことの復習

##本内容について
エンジニア未経験者がとりあえず現場に飛び込んでみて学んだことを記載する。
今回初投稿なので、現場に入ってからしばらく働いてみて、特になるほどと感じたことを記載。
正直ほとんどの方には役立たないのでご了承を。あくまで自分用なので

##なるほどと感じたこと
・ブラウザにてF12キーを押すとそのページのコードやアクセスに関する情報を確認することができる
-> これを開発者ツールという。
-> 最初は開発者ツール開いてと言われてもわからんかった・・・


・開発者ツールを開いて、
- Network
- 上のDisable cacheにチェック 
- 左上の更新ボタンを長押し
- キャッシュの削除とハードの再読み込みをする
-> これでキャッシュが削除された状態で再読み込みが可能となる
-> このとき下に表示されるrequestsがリクエスト数、transferredがリクエストサイズを示す
-> リクエスト数、リクエストサイズが小さいほど、サーバーへの負荷が小さい
-> そもそもリクエスト数とはなんぞやってレベルだから、ここも調べないと意味ないわ・・・


・Chromeの拡張機能に関して
- HTMLエラーチェッカー(現在閲覧しているサイトの閉じタグなどをチェックできる)
- FireShot(現在閲覧しているサイトのキャプチャショットを保存可能)
- Smart QrCode Generator(現在閲覧しているサイトのアクセスQRコードを作成)
-> これらは結構使えるし、入れといて損はないかな


・ブラウザチェック
- Chrome
- IE
- Firefox
- Android
- iOS
-> 基本はこれらでチェック。バージョンもどこまでやるかはその時々で
-> こんなにやるのかよと正直思いましたよ・・・


##まとめ
正直まだまだおっと思ったことはたくさんあったはず。ただ忘れた。
仕事中とか家でふっと思い出した時はまたここにメモ程度で書き込んでいく。
とりあえず今日はこんな感じで。


##今日の自習内容
dotinstall git入門
-> まだここ勉強してる時点で結構やばいな・・・
sorceryというRubyの認証便利gemを使う その2 Activity logging

# はじめに
Railsの認証系をなにか触ってみたく、sorceryというものをいじってます。
https://github.com/Sorcery/sorcery

[前回の投稿](http://qiita.com/fukumura/items/7f2f99fc8897e350523d) のものをベースに機能を追加したいと思います。
今日は、Activity logging というsubmoduleを使ってActivityのロギングができるようにします。

# Activity loggingを試す

名前からして気になりました。（Brute Force Protectionも気になってますが今日はこれ）
https://github.com/Sorcery/sorcery/wiki/Activity-logging

 ```zsh:
% rails g sorcery:install activity_logging --only-submodules
Running via Spring preloader in process 23570
Expected string default value for '--jbuilder'; got true (boolean)
        gsub  config/initializers/sorcery.rb
      insert  app/models/user.rb
      create  db/migrate/20170112143345_sorcery_activity_logging.rb
fukumura@ubuntu-xenial(14:33:45) ~/projects/sorcery-sample
``` 
↑中身がサンプル結果と違うけど突き進んでみます。

 ```zsh:
% rake db:migrate
== 20170112143345 SorceryActivityLogging: migrating ===========================
-- add_column(:users, :last_login_at, :datetime, {:default=>nil})
   -> 0.0381s
-- add_column(:users, :last_logout_at, :datetime, {:default=>nil})
   -> 0.0155s
-- add_column(:users, :last_activity_at, :datetime, {:default=>nil})
   -> 0.0082s
-- add_column(:users, :last_login_from_ip_address, :string, {:default=>nil})
   -> 0.0362s
-- add_index(:users, [:last_logout_at, :last_activity_at])
   -> 0.0057s
== 20170112143345 SorceryActivityLogging: migrated (0.1071s) ==================
``` 

で、実行しようとしたらError。

 ``` 
Showing /home/fukumura/projects/sorcery-sample/app/views/layouts/application.html.erb where line #25 raised:

undefined local variable or method `current_users' for #<UsersController:0x007f9ea4107800>
Did you mean?  current_user
               current_user=
               @current_user
``` 

調べてみたら、current_usersは、[sorcery0.10でremove](https://github.com/Sorcery/sorcery/blob/e358a6d4e9efafc6da70f95d1f0fe04b2439d1eb/CHANGELOG.md#0100)されたそうな。たしかに使いみちなさそうだ。

これでおしまい。
ログイン・ログアウトしてみると(pumaを再起動してから)値が入るようになりました。
![スクリーンショット 2017-01-13 0.11.14.png](https://qiita-image-store.s3.amazonaws.com/0/1153/97525a0b-5c1f-7d5d-1a28-a9bec4ae2c50.png)

ソースコードはこの辺。
https://github.com/Sorcery/sorcery/blob/master/lib/sorcery/model/submodules/activity_logging.rb


今日の差分。
https://github.com/fukumura/sorcery-sample/commit/057f1cdbca4ea2d955bfe2b01eff52506c808915

次回は、Brute Force Protection。
Ruby｜条件を変えながらグルーピングしてみた

```ruby
arr = [8, 11, 0, 0, 12, 8, 0, 10, 7]

module Arch
  refine Array do
    def less_than(threshold, step)
      return {} if self.empty?

      lhs, rhs = self.partition{|v| v < threshold}

      {}.tap {|h|
        h.store(threshold, lhs)
      }.merge(rhs.less_than(threshold + step, step))
    end
  end
end

using Arch

p arr.less_than(5, 1)
#=> {5=>[0, 0, 0], 6=>[], 7=>[], 8=>[7], 9=>[8, 8], 10=>[], 11=>[10], 12=>[11], 13=>[12]}

p arr.less_than(5, 3)
#=> {5=>[0, 0, 0], 8=>[7], 11=>[8, 8, 10], 14=>[11, 12]}
```

## やりたかったこと
グルーピングする条件を刻々と変えながら、グルーピング済の要素は対象とせずまたグルーピングしたかった。

## きっかけ
リファレンスをぱぱっとみて、なさそうだったのでｗ
Scrutinizer CI の各メトリクスの意味

## 概要
業務でPHPを使ったウェブサービスを複数人のチームで運営していますが、経年と共にソースコードが劣化してきており、改善とその効果を測るためにScrutinizer CIという静的解析のSaaSを導入しました。
英語のツールのため導入時にチームメンバーに各メトリクスを説明しましたがので、備忘録も兼ねて投稿します。

## Scrutinizer CIとは
GitHubのリポジトリを登録することで、ソースコードの静的解析を自動的に行ってくれるサービスです。
詳しい説明は以下の記事がとてもわかりやすかったので、ご参照ください。

 - https://www.slideshare.net/mobile/hinakano/scrutinizer-ciphp
 - http://labs.oratta.net/2016/06/140/

## 各メトリクスの意味
インスペクションの対象がメソッドかクラスかによって、指標の種類が違います。

### メソッドレベルのメトリクス

**Complexity(複雑度)**

項目|意味
:--|:--
Conditions|制御フロー（ifやループ）を変更する決定ポイントの数。循環的複雑度とも呼ばれる。
Paths|循環を考慮しない異なる実行パスの数。

**Duplication(重複)**

項目|意味
:--|:--
Lines|重複している行数。
Ratio|重複率。

**Size(コードサイズ)**

項目|意味
:--|:--
Total Lines|メソッドの行数。
Code Lines|メソッドの行数から空白や｛｝だけの行を除外した行数。

**Importance(重要度)**

項目|意味
:--|:--
Changes|オペレーションが最近変更された回数（原則的に過去30日間）。

### クラスレベルのメトリクス

**Coupling/Cohesion(結合度/凝集度)**

項目|意味
:--|:--
Components|このクラスの切断されたコンポーネントの数。この数値が少ないほど、単一の責任を持つ集中的なクラスを示すため、一般的には優れている。
Dependencies|このクラスが依存する他のクラスの数。この数が少ないほど、クラスが壊れにくくなるため、一般的には優れている。

**Complexity(複雑度)**

項目|意味
:--|:--
Total Complexity|制御フロー（ifやループ）を変更する決定ポイントの数。

**Size/Duplication(コードサイズ/重複)**

項目|意味
:--|:--
Total Lines|クラスのソースコードの総行数。
Duplicated Lines|ソースコードの重複率。

**Importance(重要度)**

項目|意味
:--|:--
Changes|オペレーションが最近変更された回数（原則的に過去30日間）。

## まとめ

メトリクスについて日本語でまとまっている情報がなかったので何かのお役に立てればと思い書きました。
些か説明が足りない部分もありますが、勉強してわかったことを追記していきます。
RxJava 2でNoSuchElementExceptionに遭う件

##NoSuchElementException
RxJava 2では、CompletableをtoMaybe()、flatMapSingle()と繋ぐと、NoSuchElementExceptionに遭遇します。
CompletableからSingleへ繋げたいパターンです。

##サンプル

```java
private Completable hoge() {
    return Completable.complete();
}

private Single<String> fuga() {
    return Single
            .fromCallable(new Callable<String>() {
                @Override
                public String call() throws Exception {
                    return "fuga";
                }
            });
}
```

```java
hoge()
        .toMaybe()
        .flatMapSingle(new Function<Object, SingleSource<String>>() {
            @Override
            public SingleSource<String> apply(Object o) throws Exception {
                return fuga();
            }
        })
        .subscribe(new SingleObserver<String>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onSuccess(String s) {
                Log.d("onSuccess", String.valueOf(s));
            }

            @Override
            public void onError(Throwable e) {
                Log.d("onError", e.toString());
            }
        });
```

出力結果

```
onError: java.util.NoSuchElementException
```

##回避方法
CompletableをMaybeに変換せずにSingleに繋ぎます。

```java
hoge()
        .toSingleDefault(new Object())
        .flatMap(new Function<Object, SingleSource<String>>() {
            @Override
            public SingleSource<String> apply(Object o) throws Exception {
                return fuga();
            }
        })
        .subscribe(new SingleObserver<String>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onSuccess(String s) {
                Log.d("onSuccess", String.valueOf(s));
            }

            @Override
            public void onError(Throwable e) {
                Log.d("onError", e.toString());
            }
        });
```

出力結果

```
onSuccess: fuga
```
dockerでRedmineを起動する

##はじめに
dockerを使ったことがなかったので試してみた。
VPS上にdockerをインストールし、Redmineの公式イメージから起動させる。
（環境）
OS:CentOS7

##dockerインストール
※適宜sudoすること。

1.docker

```
$ yum install -y docker
```

2.docker compose（[公式サイト](https://docs.docker.com/compose/install/)を参考にしました）

```
$ curl -L "https://github.com/docker/compose/releases/download/1.9.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
$ chmod +x /usr/local/bin/docker-compose
```

##docker-compose.yml

[Redmineの公式リポジトリ](https://hub.docker.com/_/redmine/)を参考に以下のようにした。

```
version: '2'
services:
  redmine:
    image: redmine
    ports:
      - 3000:3000
    environment:
      REDMINE_DB_MYSQL: db
      REDMINE_DB_PASSWORD: redmine
    depends_on:
      - db
    restart: always

  db:
    image: mariadb
    environment:
      MYSQL_ROOT_PASSWORD: redmine
      MYSQL_DATABASE: redmine
    restart: always
```

##docker起動
コンテナの作成、及びバックグラウンドで実行する。

```
$ sudo docker-compose up -d
```
※root権限でcommand not foundとなる場合はパスを追加すること。

##起動確認
少し時間を置いてアクセスする。
http://\<VPSのIP>:3000

<img width="1051" alt="Redmine初期画面.png" src="https://qiita-image-store.s3.amazonaws.com/0/38219/e9a25ba9-28c5-021e-7005-11609ed967d6.png">

起動していることが確認できた。

##内部エラー
プロジェクトを作成しようとした所、以下のようなエラー画面が表示された。
どうやら日本語が対応できていない模様。

<img width="621" alt="InternalError.png" src="https://qiita-image-store.s3.amazonaws.com/0/38219/c15225c9-b1b9-e5e9-4552-8291653ea372.png">

[MariaDBの公式リポジトリ](https://hub.docker.com/_/mariadb/)（Configuration without a cnf fileの所）を参考にdocker-compose.ymlを修正する。

```
version: '2'
services:
  redmine:
    image: redmine
    ports:
      - 3000:3000
    environment:
      REDMINE_DB_MYSQL: db
      REDMINE_DB_PASSWORD: redmine
    depends_on:
      - db
    restart: always

  db:
    image: mariadb
    environment:
      MYSQL_ROOT_PASSWORD: redmine
      MYSQL_DATABASE: redmine
    command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci
    restart: always
```

修正箇所：dbの所にcommandを追加。
（筆者の環境ではutf8mb4では起動できなかった）

再起動後、日本語の登録ができることを確認！

<img width="1048" alt="プロジェクト作成.png" src="https://qiita-image-store.s3.amazonaws.com/0/38219/3c9f4191-c3b5-ca9e-d4b9-b61dce0e00d8.png">
SQLの基礎の基礎をメモしていくよ

## ★データを抽出する

#### テーブルの項目すべて
``` SQL
select  * from テーブル名;
```
#### テーブル項目すべてのうち、条件に合致するものだけ
``` SQL
select  * from テーブル名
where 条件;
```
*条件とは、フィールド名 > 1000 など

#### 一部のフィールドだけ
```SQL
select 抽出したいフィールド名１, 抽出したいフィールド名２ from テーブル名;
```
#### 抽出時に別名をつける
```SQL
select 抽出したいフィールド名 as 抽出後につけたいフィールド名
from テーブル名 as 抽出後につけたいテーブル名
where 抽出条件;
```
#### LIKEによるあいまい抽出
任意の０文字以上の文字列
%
任意の１文字
_

```SQL
select * from テーブル名
where 抽出したいフィールド名 like '%抽出したい文字列%';
```
#### BETWEENによる範囲指定抽出
between ● and ●

```SQL
select * from テーブル名
where 抽出したいフィールド名 between '範囲指定の開始：文字列は囲む' and '範囲指定の終了値';
```
#### IN / NOT INによる複数値比較
in (比較する値,比較する値,比較する値) 

```SQL
select * from テーブル名
where 抽出したいフィールド名 in ('比較文字列1', '比較文字列2');
```


---
## ★データを追加する

#### 行の挿入
```SQL
insert into テーブル名
values ('追加データ：文字列は囲む', ０)
```
---
## ★データを更新する

#### データの更新
```SQL
update テーブル名
set 更新対象のフィールド名 = 更新する値
```
#### 条件つきのデータの更新
```SQL
update テーブル名
set 更新対象のフィールド名 = 更新する値
where 更新条件があるフィールド名 = 更新条件の値
```
---

## ★データを削除する

#### データの削除
```SQL
delete from テーブル名
where 削除条件があるフィールド名 = 削除条件の値
```
---
## ★テーブルを結合する
#### AとBテーブルを結合する
* joinで結合する他の表を指定
* onで結合条件を指定 　　
　EX)テーブルA.結合対象のフィールド名 = テーブルB.結合対象のフィールド名


```SQL
select 抽出したいフィールド名１,抽出したいフィールド名２
from テーブルA
join テーブルB
on 結合条件
```
#### 結合相手が複数あるとき　　
　EX)テーブルA.結合対象のフィールド名 　該当が１つあった
　　　テーブルB.結合対象のフィールド名　該当が２つあった

→　**Aのフィールドの値が１つコピーされ、Bの値が２つ収まる（結合の結果、行が増えている）**

#### 結合相手がいないとき
　EX)テーブルA.結合対象のフィールド名 　該当が１つあった
　　　テーブルB.結合対象のフィールド名　該当が１つもなかった

→**結合結果が出力されない** 

#### 結合相手がいないときでも出力をしたいとき
* テーブルAを左表、Bを右表とする
* Bの表に該当がなくても、Aの表をすべて表示させる

```SQL
select ~~　from テーブルA
left join テーブルB
on 結合条件
```

* テーブルAを左表、Bを右表とする
* Aの表に該当がなくても、Bの表をすべて表示させる

```SQL
select ~~　from テーブルA
right join テーブルB
on 結合条件
```


* テーブルAを左表、Bを右表とする
* 左右どちらの表も全行を必ず表示させる

```SQL
select ~~　from テーブルA
full join テーブルB
on 結合条件
```


## ★NULLの判定方法

#### NULLであることを判定
```SQL
is null
```
#### NULLでないことを判定
```SQL
is not null
```
Pythonを使うなら欠かせない！演算を高速化するNumpyの使い方!

※こちらの記事は、プロスタ編集部が現在大変人気の高いPythonの文法記事を公開することで、皆様の学習にお役に立ちたい意図で投稿しております。

参考サイト：[Pythonを使うなら欠かせない！演算を高速化するNumpyの使い方!](http://programming-study.com/technology/python-numpy/)

#Pythonを使うなら欠かせない！演算を高速化するNumpyの使い方!


Pythonには便利なライブラリが数多く用意されており、自由に使うことができます。ライブラリを使うことで、高度な計算や複雑な処理を簡単に実現することができます。そんなライブラリの中でも特に良く使われるのがNumPyです。NumPyは科学技術計算などで配列や行列の演算を高速で行うために使われます。研究などで数学的な計算をしたいときに、非常に有効なライブラリとなっています。

今回は、そんなNumPyの基本的な使い方について説明します。

##NumPyのインストール

NumPyはpipコマンドを使うことで簡単にインストールすることができます。コンソールから以下のコマンドを入力してインストールしてください。

```
pip install numpy
```

ただし、Pythonのバージョンなどによってはpipでのインストールが失敗する可能性があります。その場合は以下のページからNumPyをダウンロードして、そのダウンロードしたファイルをpipコマンドでインストールするようにしてください。

http://www.lfd.uci.edu/~gohlke/pythonlibs/

NumPyのファイルは複数ありますので、ご自身のPythonのバージョンやOSのバージョンに合ったものをダウンロードしてくさい。ファイル名のcp○○がPythonのバージョン、win_amd○○がOSのバージョンを表しています。

例えば、「numpy‑1.12.0rc2+mkl‑cp36‑cp36m‑win_amd64.whl」というファイルはPythonのバージョンは3.6、OSのバージョンは64bitOS、ということを表します。

ダウンロードが終わったら、pipでそのファイルをインストールします。コマンドは以下の通りです。

>pip install さきほどダウンロードしたファイルのパス

```
NumPyのインポート
```

NumPyのインストールが終わったら、NumPyをインポートします。これで、NumPyを使う準備が完了です。

```
import numpy  #NumPyを使う際には必ず必要
```

##NumPy配列を扱う

###配列の生成

NumPyは配列や行列の計算を高速で行うことができるライブラリです。まずは、NumPyで配列を生成します。NumPyの配列はarrayメソッドで生成することができます。

```
import numpy

n_array = numpy.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(n_array)
```

実行結果
>
[[1 2 3]
[4 5 6]
[7 8 9]]

また、NumPyでは数学などで使われる行列を表現することができます。行列を生成するにはmatrixを利用します。

```
n_matrix = numpy.matrix('1,2 ; 3, 4')
print(n_matrix)
```

>実装結果
[[1 2]
[3 4]]

###配列の演算

NumPyの配列はPythonの通常のリストのように扱えますし、行列も言い換えれば2次元のリストとほぼ同じです。では、通常のリストとの違いは何なのでしょうか？それは、行列や配列に対して数学的な演算が簡単に行えることです。

例えば、通常のリストに定数を掛けるとそのリストが複製されますが、NumPyの配列に定数を掛けると、行列に定数を掛ける演算が行われ、各要素が定数倍された配列になります。

```
n_array = numpy.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(n_array * 3)
```

実行結果
>
[[ 3 6 9]
[12 15 18]
[21 24 27]]

このほかにも、配列と定数や、配列同士の四則演算を行うことができます。また、NumPyには演算用の関数が多数用意されているほか、標準ライブラリであるmathモジュールで定義されている数学関数も利用できます。NumPyで利用できる関数には以下のようなものがあります。

|関数|効果|
|---|---|
|numpy.add(配列, 定数)|	配列に定数を足す
|numpy.multiply(配列, 定数)|	配列に定数を掛ける
|配列.dot(配列)|	配列（行列）の内積を計算する
|numpy.mean(配列)|	配列の平均を計算する
|numpy.median(配列)|	配列の中央値を計算する
|numpy.std(配列)|	配列の標準偏差を計算する
|numpy.var(配列)|	配列の分散を計算する

```
n_array = numpy.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

print('n_arrayの平均値：{}'.format(numpy.mean(n_array)))
print('n_arrayの中央値：{}'.format(numpy.median(n_array)))
print('n_arrayの標準偏差：{}'.format(numpy.std(n_array)))
```

実行結果
>
n_arrayの平均値：5.0
n_arrayの中央値：5.0
n_arrayの標準偏差：2.581988897471611
Canvasで波紋みたいなアニメーション 2

[この記事](http://qiita.com/g0nta1899/items/85175f03e4b80a72d793)の続きです。
とらドラのOPイントロのファファファファってやつを作りたい！というのが最初のモチベーションだったのでとりあえず満足かなという感じ。

以前のでは全ての波紋の初期半径が0だったため、足並みが揃ってしまいました。
修正版では

1. 初期半径をランダムにセット
2. 波紋が一定の大きさになったら半径を0にセット
3. 中心をランダムにセット
4. 以下繰り返し

という風にしています。簡単でしたね。

ソースコードを以下に貼っておきます。(HTMLは省略します)

```js
var circleArr=[];
var canvas = document.getElementById('mycanvas');
var ctx = canvas.getContext('2d');
var w=canvas.width;
var h=canvas.height;
window.onload = function(){
  draw_circle();
  animation();
}

function animation(){
  ctx.clearRect(0,0,w,h);
  for(var i=0; i<circleArr.length; i++){
    var this_circle = circleArr[i];
    this_circle.update_me();
  }
  requestAnimFrame(animation);
}

function draw_circle(){
  for(var i=0; i<15; i++){
    circleArr[i]=circle();
  }
}

function circle(){
  var x=Math.floor( Math.random()*w );
  var y=Math.floor( Math.random()*h );
  var r=Math.floor( Math.random()*100 );

  var update_me = function(){
    ctx.beginPath();
    ctx.arc(x,y,r,Math.PI*2, false);
    ctx.stroke();
    if(r<100){
      r += 2;
    }else{
      x=Math.floor( Math.random()*w );
      y=Math.floor( Math.random()*h );
      r =0;
    }
  }
  return{
    update_me:update_me,
    x:x,
    y:y,
    r:r
  }
}

window.requestAnimFrame = (function(){
  return window.requestAnimFrame     ||
  window.webkitRequestAnimationFrame ||
  window.mozRequestAnimationFrame    ||
  window.oRequestAnimationFrame      ||
  window.msRequestAnimationFrame     ||
  function(callback){
    window.setTimeout(callback, 1000/60);
  };
})();

```
長期休暇のすゝめ

東京でSEやっております、nackybearと申します。
今更Java9がどうなるか気になりますね。

さて、**去年の12月23日から今年の1月9日まで**、休暇にしていました。
年末年始休みと有給休暇をつなげて、**18日間**のリフレッシュ期間を作りました。
そこで感じたことをここにまとめようと思います。
退職や休職ではないですが、少々長めの休みを取ってみてはいかがでしょうか？


# 休むと心身は元気になる
当たり前といえば当たり前ですが、人は休むことで驚くほど元気になります。
私自身、去年は以下のような散々な状況でした。

- 微熱が何ヶ月も続き最終的に気管支炎になる
- 目眩で会社に行けなくなる
- 右耳が感音性難聴になる
- 不眠症になる

その悪い流れを断つべく、この長期休みを取りました。
**実際休んでみると、みるみる元気になっていくのがわかります。**
いや、ほんと元気になっていくのが実感できます。
たっぷり寝て、たっぷり太陽を浴びて、たっぷり食べて、たっぷり運動するだけで、乱れてた生活リズムも戻ります。
仕事を思い出さないで済むほどの休暇の長さだったので、次の項目に関係するのですが、気が楽になり精神的な面も回復してました。


# 思考に余裕が生まれる
いや、仕事してる時もそんな切羽詰まっている自覚はなかったのですが、
いざ休むと、仕事している時期の自分は**狭い世界でしか物事を考えられなくなっていた**ことに気づきます。
給料の不満や、上司からの評価や、土日しかない休みをどう活用するかや、うまくいかない毎日を宝くじに託したりとか、仕事やその延長にある日常に関することについてが、頭の中をぐるぐるしていました。

**でも世界ってもっと広いんですよね。**
私自身、海のはるか向こうの国のカナダに行ってみたのですが、そこには仕事のもやもやを忘れるほど綺麗なオーロラと未体験の極寒(-20℃)がありました。
犬ソリをして見た風景はいつもの通勤風景とはかけ離れた、美しい銀世界でした。
また外国に行くことで、繰り返される毎日の連続から離れることができるので、しがらみから離れたのか気持ちが開放的になりました。

# 日常の大事さに気づく
何も遠くに行かなくてもいいのです。
カメラを片手に、ふらふらと家の周りを散歩すると、足元にある花を見つけ、見向きもしなかったお地蔵さんに気づき、知らなかった道を発見し、青い空と白い雲と北風を感じて、そういえばもう季節は冬なのだと知りました。
忙しい毎日の繰り返しのせいで気付かなかったこの日常は、実はこんなに美しいところがあったのだなと思いました。
ゆっくりスーパーをうろつき、いつもと違う料理を食べ、皿を洗い、暖かい湯船に身を沈め、うとうとと床につく。
日常とは、実は素晴らしく、そして美しいのだと気付きました。

# やりたいことができる
「まとまった時間があったらこれがしたい」
「時間があればここに行きたい」
「一生に一度はここに旅行してみたい」
そんなふうにやりたいと思っていることが一つや二つあるのではないでしょうか。
**まとめて休みを取ると、そのやりたいことができます。**
実際に自由な時間があるので、「いつかやる」をやらない言い訳ができないわけです。
「いつか」を「今」に一押しするいいチャンスかもしれません。
私の場合でいえば、「オーロラを見に行くこと」や「地方の友達に会いに行くこと」を実際にやってみました。
やりたいことをやってみると、スッキリしてストレス解消にもなるので、精神衛生的にも良いものとなりました。

# やりたいことが浮かぶ
加えて、「これからやりたいこと」が思い浮かびます。
気持ちにゆとりが出たことで、昔したかったことや、自分自信の興味に気づき、ふと、やりたいことが浮かびます。
雑誌やテレビやネットを見て、興味を覚えた映画や展覧会やイベントにも行けます。
私の場合、いつか買いたい登山靴とか買いに行けましたし、新しい趣味としてフイルムカメラも始めました。
仕事をしていた時は、不思議とこういう「やりたいこと」があまり出てこなかったのですが、
たっぷり時間があって「やろうと思えば今すぐできる」という状況があることで、
人はやりたいことを想像しやすくなるのだと思いました。

# この先将来をゆっくり考えられる
この先の人生をどうするか、仕事をどうするかなどを考える機会は、
忙しい毎日の中ではどうしても作るのが難しいものです。
**「まとまった時間があれば考えたい」と思っていて、いつのまにかずるずる月日が経ってしまいます。**
そこでこの長期の休みを良い機会として考えてみました。
一旦会社の毎日から離れることで、客観的に見られますし、休みを利用して人と会うことで考えも深まります。
ほんとこういう時間大事です。


　
　


# 結論：疲れたら休もう！やりたいことをやろう！
仕事をするのは大事です。
でも自分らしく豊かに健康に毎日を過ごすことは、それ以上に大事なことです。
長期の休みはそのバランスをメンテナンスする良い機会です。
何かの機会に、あまった有給休暇をかき集めて、長期休暇取ってみることをお勧めします！:sunny:



※ただやりたいことをやるとお金もかかるので、ある程度お金を貯めておくことをお勧めします…w
Reek - Boolean Parameter Smell

Ruby の静的解析ツール一式をまとめて実行できる [RubyCritic](http://tbpgr.hatenablog.com/entry/2016/09/02/022606) を使って静的解析をしていたところ、
[Reek](http://tbpgr.hatenablog.com/entry/2016/08/25/230610) の Boolean Parameter の警告がでてきて怒られました。

## <i class='fa fa-warning'></i> Boolean Parameter Smell
Reekのドキュメントにおける Boolean Parameter の臭いの説明は以下です。

>Boolean Parameter is a case of Control Couple, where a method parameter is defaulted to true or false.
>A Boolean Parameter effectively permits a method's caller to decide which execution path to take.
>This is a case of bad cohesion. You're creating a dependency between methods that is not really necessary, thus increasing coupling.

[Boolean Parameter - docs - troessner/reek](https://github.com/troessner/reek/blob/master/docs/Boolean-Parameter.md)

## <i class='fa fa-check-circle'></i> 問題点
フラグがあるということは、そのメソッドは2つの役割をするということです。
その役割の結合度は増し、一つの変更が及ぼす影響が大きくなります。
また、その引数が名前付き引数ではない場合、呼び出し元のコードを見ただけでは
何の動作を切り替えているのか把握できません。

```ruby
class Numbers
  def self.list(limit, include_zero)
    if include_zero
      [*0..limit]
    else
      [*1..limit]
    end
  end
end

# true, false で何が変わるかコードを見てもわからない
print Numbers.list(10, true), "\n"  # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print Numbers.list(10, false), "\n" # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
```

## <i class='fa fa-smile-o'></i> 改善
メソッドを分けることで依存を減らし、呼び元からも分かりやすくします。

```ruby
class Numbers
  def self.list_include_zero(limit)
    [*0..limit]
  end

  def self.list_exclude_zero(limit)
    [*1..limit]
  end
end

print Numbers.list_include_zero(10), "\n" # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print Numbers.list_exclude_zero(10), "\n" # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
```

## <i class="fa fa-book" style="font-size:1em;"></i> 外部資料
* [FlagArgument - martinfowler.com](https://martinfowler.com/bliki/FlagArgument.html)
* [A side effect of boolean parameters in Ruby - http://railsguides.net/](https://silkandspinach.net/2004/07/15/avoid-boolean-parameters/)
Spark Framework + Kotlinで書いたGradleプロジェクトをHerokuにデプロイする

# 概要
　タイトルの通りです。

# build.gradle
```groovy
apply plugin: 'kotlin'
version '1.0-SNAPSHOT'

buildscript {
  ext.kotlin_version = '1.0.6'
  
  repositories {
    mavenCentral()
  }
  dependencies {
    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
  }
}

repositories {
  mavenCentral()
}

dependencies {
  compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
  compile 'com.sparkjava:spark-core:+'
  compile 'org.slf4j:slf4j-simple:+' // Failed to load classで怒られるので入れる
}

// ライブラリのコピー
task copyToLib(type: Copy) {
  into "$buildDir/libs"
  from(configurations.compile)
}

// Herokuから実行されるタスク
task stage(dependsOn: ['clean', 'build', 'copyToLib'])
build.mustRunAfter clean
```

# Procfile
　クラスフォルダとコピー後のライブラリフォルダのパスを通し、実行クラス名を記述します。

```bash
web: java $JAVA_OPTS -cp build/classes/*:build/libs/* app.Main
```

# Main.kt
```kotlin
package app

import spark.Spark
import spark.Spark.*


object Main {
  @JvmStatic fun main(args: Array<String>) {
    System.getenv("PORT")?.let {
      Spark.port(it.toInt())
    }
    get("/") { req, res -> "Hello World!" }
  }
}
```

# .gitignore
　ビルドが上手くいかずアプリがクラッシュしたままになってしまうので、下記はGit管理から除外してください。

```
.gradle
.idea
build
```

# プロジェクト構成
<img width="221" alt="スクリーンショット 2017-01-12 22.52.01.png" src="https://qiita-image-store.s3.amazonaws.com/0/110768/89c6a630-9b49-fccb-b0b4-92fa4e58effa.png">

# サンプル
 - [kenichi-odo/spark-kotlin-gradle-heroku](https://github.com/kenichi-odo/spark-kotlin-gradle-heroku)

# 参考文献
 - [Deploying Gradle Apps on Heroku](https://devcenter.heroku.com/articles/deploying-gradle-apps-on-heroku)
 - [Writing and deploying a simple application using Java 8 + Spark + Gradle + Heroku + Intellij IDEA](https://junhopark.com/posts/2016/08/10/writing-and-deploying-a-simple-application-using-java-8-spark-gradle-heroku-intellij-idea)
Python覚書2

pythonでサクッとツール作ったので、覚書。
ソースは会社とかのあれがあれなので、要所要所を覚え書き

# ディレクトリの再帰処理
## すべてのファイルを取得するFunction
[こちら](http://qiita.com/suin/items/cdef17e447ceeff6e79d)をとても参考にさせてもらいました。

```py
def get_all_files(directory):
    for path, dirs, files in os.walk(directory):
        for file in files:
            yield os.path.join(path, file)
```

## すべてのディレクトリを取得するFunction
[こちら](http://qiita.com/suin/items/cdef17e447ceeff6e79d)から拝借。

```py
def get_all_files(directory):
    for path, dirs, files in os.walk(directory):
        yield path
```

## すべてのディレクトリとファイルを取得するFunction
[こちら](http://qiita.com/suin/items/cdef17e447ceeff6e79d)から拝借。

```py
def get_all_files(directory):
    for path, dirs, files in os.walk(directory):
        yield path
        for file in files:
            yield os.path.join(path, file)
```

使う時

```py
for file in get_all_files('/tmp/test'):
    print file
```

## yieldについて

[こちら](http://www.aipacommander.com/entry/2014/06/15/104756)がとても参考に成った。
簡単に言うと、処理の内容をretrunせずにおいておけるものらしい
で、ループで回したり、next()で取得できる。つまり

```py
def test():
	yield 'a'
	yield 'b'
	yield 'c'

for i in test():
	print i
```
を実行すると

```text
a
b
c
```
と出力される。

# ファイル処理

## フルパスからファイル名を取得する
これはよく使う

```py
file_name = os.path.basename(file)
```

## フルパスから拡張子とそれ以外分割する
拡張子を見たかったので

```py
file_title, file_ext = os.path.splitext(file_name)
```

## ファイルをUTF-8で開いて、全行を読み込む
UTF-8で開くときは、unicodeに気をつける必要がある

```py
f = codecs.open(file, 'r', 'utf-8')
list = f.readlines()
f.close()
```
## ファイルをUTF-8で開いて、書き込む
ファイルが存在しない時は作成する。
stringはunicodeであれば日本語でも書き込める。
printするときは、`print(string.encode('utf-8'))`のようにする。
`\n`いれないとCRLF改行でひらいたときに改行されない。

```py
result = codecs.open(outfile, 'a', 'utf-8')
result.write(format("string --> %s\n" % string))
result.close()
```

読み込んだファイルを比較するときは文字コードを統一しないといけなくて
結構ハマった。。。

# 文字列比較

## 任意の文字列が含まれるかどうか

```py
line = "1abcdefg23456789"
target_string = "1a"

if (target_string in line):
```

処理が増えてくると、Pythonでうーん、、と感じることも何回かありましたが
さくっと書くにはPythonはいいですね。好きです。
Qiita Advent Calendar 2016 で削除されたカレンダーを調べてみた

はてな匿名ダイアリーで[こんなの](http://anond.hatelabo.jp/20170107021400)が書かれていてあるカレンダーが削除されたのを知ったのですが、どうやら他にも削除されたカレンダーがあるようなので調べてみました。

# 調べ方

[AdventCalendarのページ](http://qiita.com/advent-calendar/2016)には削除されたカレンダーのリンクは当然ないのでここからは調べようがありませんが、幸いにカレンダーのURL一覧が載っている投稿があったのでこれを使用しました。

[Advent Calendarを立てた人自身は何日目にエントリーするのか調べてみた - Qiita](http://qiita.com/sudoyu/items/0a51593b257f419aeb20)

> 12/3(木)22時頃の時点でQiitaに開かれていたAdventCalendar 499件です。

だそうです。

ここに載っているURLにアクセスして、`404 Not Found` ならば削除されたカレンダーということになります。

約500件を手作業で確認するわけにはいかないのでPythonで書きました。

```py3:deleted_calendar.py
import re

import requests
import time


def main():

    url = "http://qiita.com/sudoyu/items/0a51593b257f419aeb20.md"
    print(url)
    res = requests.get(url)
    print("status code: {}".format(res.status_code))
    if res.status_code != 200:
        return

    r = re.compile("^\* (.+)$")
    calendar_urls = [m.group(1) for m in map(r.match, res.text.split("\n")) if m]

    deleted_url = []
    for idx, url in enumerate(calendar_urls):
        time.sleep(0.2)
        while True:
            print("({:3d}/{:3d}) {} ... ".format(idx, len(calendar_urls), url), end="", flush=True)
            status_code = requests.head(url).status_code
            print(status_code, flush=True)

            if status_code == 404:
                deleted_url.append(url)
            if status_code in [200, 404]:
                break

            print("retry...")
            time.sleep(30)

    print("--------\ndeleted calendars")
    for url in deleted_url:
        print(url)


if __name__ == "__main__":
    main()

```

# 結果

削除されたカレンダーは18件見つかりました。
カレンダー名はGoogle検索のキャッシュなどから調べました。

- カレシ・カノジョできないエンジニア(advent-calendar/2016/give_me_kareshi)
- GPD WIN(advent-calendar/2016/gpd-win)
- ITイベントに参加してJGC(advent-calendar/2016/it_event_de_jgc)
- 聖性論争部(advent-calendar/2016/holydisupute)
- 儀式(advent-calendar/2016/rite)
- フリーランス残酷物語(advent-calendar/2016/free_zankoku)
- test(advent-calendar/2016/test)
- いなふ進捗(advent-calendar/2016/enough)
- DeNA2(advent-calendar/2016/dena2)
- 転職（その2）(advent-calendar/2016/job2)
- カノジョできてるエンジニア(advent-calendar/2016/yes-girlfriend)
- チャットボット(advent-calendar/2016/chat-bot)
- DeNA(advent-calendar/2016/dena)
- 筋肉(advent-calendar/2016/muscle)
- ポエム(advent-calendar/2016/poet)
- カノジョできない機械学習界隈エンジニア(advent-calendar/2016/no-girlfriend-ml)
- カノジョできないエンジニア(advent-calendar/2016/no-girlfriend)
- 転職(advent-calendar/2016/job)

カッコ内の文字列でGoogle検索するとトップに出てくるので、▼のキャッシュで削除前の内容を確認できます。
カレンダーは削除されてもリンク先の投稿・ブログはそのまま残っているようです。

# どんなカレンダーが削除されたのか

主に 
> Qiitaは、プログラミングに関する知識を記録・共有するためのサービスです。

というポリシーに合っていないカレンダーが削除されたようです。

「筋肉」や「カレシ・カノジョ〜」などのネタ系は購読数ランキングで人気がありましたが、ほとんどの投稿がプログラミングには無関係なので削除されて当然ですね。

他にも「フリーランス残酷物語」「転職」などエンジニアに関するカレンダーでもプログラミングに関係しないと判断されたものは削除されたようです。
ただしこの辺りの判断基準はアバウトなようで、似たようなテーマでも削除されずに残っているものも多いですね。

問題を起こした企業のカレンダーもありますが、こちらは自主的に削除したんでしょうかね。
Unityで(IAP)Purchaseを実装したらiTunes Connectでリジェクトされたので対応する

## 経緯
以前の記事（[UnityでPurchase(課金)を実装する](http://qiita.com/KotaroInc/items/b13426216c92518bb189)）でPurchaseを実装して、iTunes Connectでアプリ公開の申請を行ったが、リジェクトされた。
その対応を記載する。（ただし、現在、申請許可待ち。申請が通ったら記事を更新する。）

ちなみに、以下がリジェクト時のメッセージ

> 差出人: Apple
> 0. 9.0 BEFORE YOU SUBMIT: IN-APP PURCHASE
> Before You Submit

> We are unable to complete the review of your app since one or more of your in-app purchase products have not been submitted for review.
> 
Please be sure to take action and submit your in-app purchase(s) AND upload a new binary in iTunes Connect. Learn more about submitting in-app purchases for review in the In-App Purchase Configuration Guide for iTunes Connect.

> Once you've submitted your in-app purchases and uploaded a new binary, we can proceed with your review.

> Note: Apps that offer in-app purchase products that must be restorable are required to include a "Restore" feature. The following in-app purchase types must be restorable:

> - non-consumable products
> - auto-renewing subscriptions
> - free subscriptions

> For more information, please see the Restoring Purchased Products section of the In-App Purchase Programming Guide.

英語は苦手なので、あまり何を言っているか理解できていない部分もあるが、要は、**iOSでPurchase(Non Consumable[^1])を利用するときは、リストア[^2]機能をちゃんと実装してね**ってことだと思う。
今までは**「再購入[^3]」をした場合にリストアが走るようになっていた**が、そうではなく、**インストール直後にリストアが走るようにした。**

## 前提
### 各ツール・プラグイン等
- Unity 5.5.0p3
- Xcode 8.2.1

### プラットフォーム
- 開発機
    - macOS (MacBookPro)
        - Windowsの場合は大差はないが、適宜読み替えること
- リリース
    - Android
    - iOS
 
## 内容
### IAPButton.csの修正
```cs:IAPButton.cs
public void OnInitialized (IStoreController controller, IExtensionProvider extensions) {
    this.controller = controller;
    this.extensions = extensions;

    // 以下の記載を追加
    extensions.GetExtension<IAppleExtensions>().RestoreTransactions(result => {
        if (result) {
            // リストア成功時の処理を書く
            Debug.Log("Restore Success.");
        } else {
            // リストア失敗時の処理を書く
            Debug.Log("Restore Failed.");
        }
    });
}
```

以上。

## 補足
[^1]: Non Consumable: 非消費型アイテム（１度購入したら永続的に有効になる）
[^2]: 購入済みのNon Consumableのアイテムを有効化すること
[^3]: アプリをアンインストールした後にインストールし直したり、別の端末でインストールすること
Postfix: virtual で"User unknown in local recipient table;"問題解決




久々に使うと忘れているので、忘備録


## 問題

postfix で /etc/postfix/virtual にメアド追加後、以下をしたのに

```
/usr/sbin/postmap /etc/postfix/virtual && /etc/init.d/postfix restart
```

以下のエラーがでる問題

```
Recipient address rejected: User unknown in local recipient table;
```

元に設定していたメアドには送れる


## 解決方法

/etc/aliases に同じ名前を入れる
【Java】Aizu Online Judgeの小噺1

#募集:いい考え方
小噺という建前で
アイデアがほしいという本音が丸見えなのは置いといて・・・

問題は
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0008
の**Sum of 4 Integers**という問題。
AOJの問題は簡単なのもあるのですが、結構骨のある問題がそろっています。
この問題は最初のほうなので、簡単な部類なりますかね。

***ざっくり言うと・・・***

0個以上36個以下の **「おまんじゅう」** と 3個の **「仕切り」** がある。
この**「おまんじゅう」**と**「おまんじゅう」**の間に**「仕切り」**を入れる。
ただし、**「仕切り」**と**「仕切り」**の間には1個も**「おまんじゅう」**が無くても構わないが、
10個以上**「おまんじゅう」**があってはならない。

わかりにくいので図で説明すると
![image](https://qiita-image-store.s3.amazonaws.com/0/139300/2ef35e70-3042-5f63-6f89-525b87cff0be.png)


仕切りの入れる場所をきめるので、

おまんじゅうの個数　と　36-おまんじゅうの個数　の小さいほうの数を**A**とすると、

```math
_{A+3}C_{3}
```
で　仕切り方の通りの数が出る

***と思うじゃん？***

答えは　**「出ないです」**

#なぜなら
4つ0-9の数字を選ぶ(同じ数を選んでもよい)通りは、

```math
10＾4=10000通り
```
存在します。
しかし、

```math
_{A+3}C_{3}
```
で答えを求めると、

```math
2\sum_{A=0}^{17} (_{A+3}C_{3})=2(1+4+10+20+35+56+84+120+165+220+286+364+455+560+680+816+969+1140) ....①\\
_{18+3}C_{3}=1330....②\\
①+②＝13300
```
つまり　謎の組み合わせが　**3300通り**存在します。
この謎の組み合わせは
仕切りで区切った空間に10個以上**「おまんじゅう」**がある時。

これを数え内にはどうすればいいのだろう?

#考え方をお待ちしております！
**もちろん、執筆者本人も熱血考え中です。**
**アイデアが出次第、小噺2にでもそのアイデアを出したいと思います。**
**乞うご期待を！(誰得)**

#↓小噺2書きました！
http://qiita.com/66zaha_9su/items/1d4b884a7936e60bc903
Rails5のproduction環境でlib/配下のクラス読込みがNameErrorになるのはautoloadが無効化されたからだった


# 環境
Ruby 2.3.1
Rails 5.0.0


# lib/配下の独自のクラスを呼んでもNameErrorに...
Railsではユーティリティ等の独自に定義したクラスを

```ruby:lib/utils/hoge_util.rb
class HogeUtil
end
```

と作成し、`config/application.rb`にて

```ruby:config/application.rb
config.autoload_paths += %W(#{Rails.root}/lib)
```

なんてよくやったりしますが、いざこれを本番で動かしてみると
`NameError: uninitialized constant HogeUtil`を食らったので
autoload周りの設定が違うのかな〜と思い色々ググるも出てくるのは「`autoload_paths`に`/lib`を読ませればok」といった記事ばかり...

それもそのはず、出てくる記事の情報はRails4以前のものばかりで、今回のエラーが出るのはRails5から。
原因に辿り着くまでに時間がかかってしまった...



# 解決策
若干厄介なのは本番環境時においてはautoloadが無効化されておりeager load(rails起動時にまとめて読み込む機能)が有効で、開発環境では逆にautoloadが有効でeager loadが無効になっています。(デフォルトの設定の場合。参考: [Rails アップグレードガイド | Rails ガイド](https://railsguides.jp/upgrading_ruby_on_rails.html#production-環境での起動後は自動読み込みが無効になる))

故にautoloadとeager loadどちらでもクラスが読み込まれるようにしなければなりませんが、素直にやると

```ruby:config/application.rb
config.autoload_paths += %W(#{Rails.root}/lib)
config.eager_load_paths += %W(#{Rails.root}/lib)
```
なのですが毎回2つ定義するのもなんとも煩わしい

少し調べた所 [Rails5: production環境でのAutoloadの廃止 - Qiita](http://qiita.com/joooee0000/items/3ab0f3d791e0d0beb639) にて

```ruby:config/application.rb
config.paths.add 'lib', eager_load: true
```
なんて書き方があり、スッキリしてて良さそうです。
UITabBarにcustomなバッジをつける

## 環境
Swift3, Xcode8.2。

## 普通の赤いバッジのつけかた
```swift
let tabItem: UITabBarItem = self.tabBar.items![0]
tabItem.badgeValue = ""
```
こだわりがなければこれでデフォルトの赤丸がつく。
今回は任意の画像をバッジとして表示したい。

## 自分で`addSubview`するしかないっぽい
`UITabBar`には気の利いたインターフェイスは用意されていないので、自分で`UITabBar`の上に貼り付ける。
**問題は貼り付ける座標の求め方。**ググると`self.tabBar.frame.width...`のようにタブバーの横幅をタブ数で割り、バッジの位置を算出するものが散見されるが、 iPad でのタブは画面中央に寄り気味となるので、**ずれる**。
今回は`UITabBar`の`subViews`の`subViews`からアイコンの`view`を取得できたので、そこに`addSubview`した。

## できあがりイメージ
<img width="654" alt="スクリーンショット 2017-01-11 9.55.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/92385/bf844d60-f39e-cfc0-21bd-6b6c8e68de9c.png">
アイコンの`view`は`UITabBarSwappableImageView`クラスらしい。非公開なクラスなのでクラス名を指定したりするとリジェクトの対象となるかも。`UIImageView`にキャストできたので、`UIImageView`として使用した。

## コード
```swift:CustomBadgeTabController.swift
import UIKit

final class CustomBadgeTabController: UITabBarController {

    private enum Tab {
        case left
        case center
        case right
        
        static var allCases: [Tab] {
            return [.left, .center, .right]
        }
    }
    
    private var badges: [UIImageView] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.initViewControllers()
        self.initBadges()
    }
    
    private func initViewControllers() {
        let vcs = Tab.allCases.map { tab -> UIViewController in
            let vc = UIViewController()
            vc.tabBarItem = UITabBarItem(tabBarSystemItem: .search, tag: 0)
            return vc
        }
        self.setViewControllers(vcs, animated: false)
    }

    // タブバーのバッジを作成
    private func initBadges() {
        let image = UIImage(named: "Badge")
        let size = CGSize(width: 8, height: 8)
        
        // tabBar.subviews.subviewsからアイコンのviewを取得、バッジ貼り付け
        self.tabBar.subviews.forEach { tabBarButton in
            for subView in tabBarButton.subviews {
                guard let icon = subView as? UIImageView else { continue }
                let badge = UIImageView(image: image)
                // アイコンの右上
                badge.frame.origin = CGPoint(x: icon.frame.width - size.width / 2, y: 0)
                badge.frame.size = size
                icon.addSubview(badge)
                self.badges.append(badge)
            }
        }
    }
}
```
【小ネタ】任意のセル領域の数式を一斉に置換する

イメディエイトウインドウでも、コロンを使えば複数行が書けることを初めて知った。
だいぶ便利になったので、以下備忘録。

0. 置換を施したいセル全体を選択
0. Alt+F11でVBEを開く
0. もしイメディエイトウインドウが無ければCtrl+Gで開く
0. イメディエイトウィンドウに以下を打ち込んでEnterを「ッターン！」するだけ

`for each cell in selection:cell.formula=replace(cell.formula,"AAA","BBB"):next`

どうせ使い捨ての命令だから体裁とか美しさとか全無視でべた打ちすればよい。
これで、選択したセルの数式に含まれる全てのAAAという文字列がBBBになる。
（数式以外のAAAも変わるので注意）

実用的には、他のブックからシート間リンクを含む領域をコピーして来るときによく使う。
普通に貼り付けるとシート間リンクがブック間リンクになってしまい、「そうじゃなくて貼り付け先のブックの同名シートにリンクしてほしいんだよ！」となる時にこの技を使えば瞬時にブック間リンクが消せる。
他にもそこそこ使い道があるので、もはやこの一行をIMEに単語登録しておくべきかもしれないと思い始めている。
slackにqiitaに投稿された記事を自動投稿できるようにする

slackbot feed test

slackにqiitaに投稿された記事を自動投稿できるようにする

`/feed`を使えばいける. 
例: 
`/feed subscribe http://qiita.com/keitas0318/feed`
or
`/feed http://qiita.com/keitas0318/feed`
など. 

hatena blogも同様に
`/feed http://ksumiya.hatenablog.com/feed`
でおk. 
hatenaはrss
`/feed http://ksumiya.hatenablog.com/rss`
もいけるっぽい. 

http://ksumiya.hatenablog.com/entry/2017/01/12/204246
DockerでFuelPHPをデバッグする際の開始ファイルpublic/index.phpから/にリダイレクトする

Dockerを使った開発で、ソースはコンテナとローカルでマウントして共有する。
なんて事をした際に、NetBeans等のIDEからデバッグする場合
開始ファイルを選択しないといけません。
しかし、そうするとデバッグ開始の最初のURLがpublic/index.phpになってしまい
最初のページとしてあまり適切ではありません。

そんな時は
app\config\routes.php
に以下を追記すると、
DOMEIN/publicほげほげなURLは全てDOMEIN/にリダイレクトしてくれます。


'public([!-~])*' => 'welcome/index',
Ruby - stackprof の出力結果を Graphviz で可視化する

## dot ファイルの生成

stackprof の dump ファイルから dot ファイルを生成できます。

```bash
stackprof --graphviz stackprof-*.dump > stackprof.dot
```

## Graphviz による可視化

Mac の場合、Homebrew で Graphviz をインストールすることができます。
Graphviz に付属の `dot` コマンドを使って PDF 等の形式で出力することができます。

```bash
# インストール
brew install graphviz
# dot ファイルを PDF 化
dot -T pdf -o stackprof.pdf stackprof.dot
```

## 参考

- https://github.com/tmm1/stackprof
- http://www.graphviz.org/
- [Profiling Ruby Code - Stack Overflow](http://stackoverflow.com/questions/4092641/profiling-ruby-code/4092705 "Profiling Ruby Code - Stack Overflow")
- [Graphvizとdot言語でグラフを描く方法のまとめ - Qiita](http://qiita.com/rubytomato@github/items/51779135bc4b77c8c20d#dotexe "Graphvizとdot言語でグラフを描く方法のまとめ - Qiita")
【エンジニア悲痛】天皇陛下の譲位に伴う新和暦対応 新元号は2019/01/01の切り替え当日に発表

これ、なんとかならないんですかね...

[ネタ元]http://internet.watch.impress.co.jp/docs/yajiuma/1038382.html

>天皇陛下が在位３０年を節目として譲位を希望されていることを受け、政府は、平成３１（２０１９）年１月１日（元日）に皇太子さまの天皇即位に伴う儀式を行い、同日から新元号とする方向で検討に入った。

新元号への切り替えは平成31年元旦からだそうです。
つまり2年後に平成が終わる予定ですが、当日まで新元号が発表されないとのこと。

公共系や金融系のシステムなどではUI上は主に和暦が用いられています。
(預金通帳を見て頂くと納得出来ると思います)

もちろん、ほとんどのシステムでは内部(RDBMS)的に西暦で保持されていますが。

通常は西暦<->和暦変換用のマスタに1レコード追加するだけで済むはずですが、当日まで新元号が発表されないは困りものですね。
***
底辺フリーランサーな私は元旦出勤確定です...
user-selectで要素のテキスト選択を「させる」

CSSのプロパティ `user-select` について。

>参考： user-select - CSS | MDN
https://developer.mozilla.org/ja/docs/Web/CSS/user-select

>ブラウザサポート状況：
http://caniuse.com/#search=user-select

#user-selectとは
（ざっくり言うと）HTML上の要素の選択を制御することができるプロパティです。

##指定できる値
|キーワード  | 説明                             |
|:---:|---|
| element | 指定された要素内で選択を開始するときに、<br>**テキストを選択できます。**<br>テキスト選択はその要素の境界に制限されます。 |
| none | 指定された要素内で選択を開始するときに、<br>**テキストを選択できません。**<br>指定された要素の外で開始されるテキスト選択では、<br>引き続き要素を入力できます。 |
| text | 指定された要素内で選択を開始するときに、<br>**テキストを選択できます。**<br>テキスト選択はその要素の境界に制限されず、<br>境界を越えて拡張できます。 |
| auto | これは**初期値**です。要素に input 要素など<br>編集可能テキストが含まれる場合、<br>contenteditable が "true" に設定された要素の場合、<br>テキストは選択可能です。 それ以外の場合、<br>選択は親ノードの -ms-user-select プロパティの<br>値によって決定されます。 |

>引用：
CSS を使って Web ページにおけるテキスト選択を防ぐ (または有効にする) 方法
https://msdn.microsoft.com/ja-jp/library/jj152140(v=vs.85).aspx

##＜応用発想＞ 要素のテキスト選択を「させる」
「テキスト選択をさせないため」のプロパティとして紹介されがちですが、逆に**「テキスト選択をさせるため」**として利用することもできます。

タブ切り替えのトリガーなど、JavaScriptで動きを制御している要素では「テキスト選択ができない」といった状況に陥っているものがあります。
そういった場合、該当要素に `user-select: text;` を設定することで、テキストが選択できるようになりました。
「ドキュメント作成」について考えてみた。

##きっかけは、
**「ドキュメント作成の時間短縮ってどうやったら出来るんだろう……」**
っていうところから始まりました。


##ドキュメント作成時の、おおまかな流れ
人によって違うとは思いますが...

###①書く事を決める
- 仕様や要件に沿って、書く内容を決める。

###②ざっくりと下書き
- ①のアウトライン書く
- アウトラインに沿って内容を書く

###③自己レビュー
- 書いてる内容が正しいか確認
    - 仕様や要件などに沿っているか確認
    - 正しくなければ修正して再度確認
- 体裁や文章表現の確認
    - ノイズを取り除く
        - 固有名詞の統一
        - 漢数字/算用数字の統一  など

##分析

###①について
開発フェーズでいうところの**「設計」**。
仕様や要件に沿って書く事を決めるだけなので、
そこまで時間かからないかなと思ってます。
（実際に僕もここには時間かかってません。）

###②について
開発フェーズでいうところの**「開発」**。
①が決まってれば、アウトライン書いて、内容をざざっと書くだけなので、
ここもそこまで時間かからないかなと。

###③について
開発フェーズでいうところの**「試験」**。
**ここが問題なんです。**
試験のようにOK/NGが出るわけでもないので、「こうなれば正解」もないし、自分の裁量次第になる。
だから不安になって何度も見直す。
僕の場合、①②の2～3倍の時間がかかってます。

勿体ない。

しかも、自己レビューで修正する箇所なんて全体の1割程度。

勿体ない。(大事な事なので2回言いました)


##つまり何が言いたいのかというと、
- 自己レビューにはあまり時間をかけず、さっさと他の人にレビューしてもらいましょう。←一番伝えたい事
- **何か良い方法教えて下さい。**←一番聞きたい事


以上。

****

##追記( 2017/01/13 )
Amazon AWS EC2 VPCのIPv6対応 インスタンスへのIPv6アドレス付与は m-flagつきRA + stateful DHCPv6

# サマリ

Amazon VPC内のEC2インスタンスへのIPv6アドレス付与は RA with m-flag + stateful DHCPv6 で行われている。

# ubuntu 16.04 のインスタンスを立てて、DHCPv6の設定をする

Developers.IO: Amazon EC2とVPCがIPv6に対応しました #reinvent
http://dev.classmethod.jp/cloud/aws/vpc-ipv6/

上記の記事の通りに、オハイオリージョンのVPCにIPv6の設定をして、ubuntu 16.04 LTSのEC2インスタンスを作ってみたが初期設定では、eth0にIPv6アドレスがつかない。

eth0 I/Fに prefix information option を含むRAが降ってくるが、m-flagがついるので、stateful DHCPv6クライアントを起動(IA_NAをリクエスト)してIPv6アドレスを取得する。

手動で起動するなら

```
# sudo dhclient -6 eth0
```

OS起動時の設定にするなら下記の設定を入れておく

```
# echo "iface eth0 inet6 dhcp" > /etc/network/interfaces.d/60-default-with-ipv6.cfg
```


# Amazon Linux, Windows インスタンスの初期設定

Amazon提供のドキュメントには下記の記述があり、標準でDHCPv6クライアントを起動する設定が入っている。Windowsについては、m-flagつきRAを受け取った時、stateful DHCPv6クライアントを起動するのはOSデフォルトの挙動である。

> Amazon Linux 2016.09.0 以降、または Windows Server 2008 R2 以降のバージョンを使用してインスタンスを起動した場合、インスタンスは IPv6 に設定され、追加の手順は必要ありません。

# Amazon提供のドキュメント

日本語版も不自然な翻訳は見当たらず質が高いですが、英語版のほうが改定が進んでいて若干の違いがあります(2017.1.12現在)

[1] 日本語版 IPv6 への移行 http://docs.aws.amazon.com/ja_jp/AmazonVPC/latest/UserGuide/vpc-migrate-ipv6.html
[2] 英語版 Migrating to IPv6 http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/vpc-migrate-ipv6.html
Fedora25 英語版のFirefoxで「の」の表示がおかしくなる問題

##概要
Firefox上で「の」の表示がおかしい。
###環境
* Fedora25 英語版
* Firefox50

##症状
以下のとおりである。
さほど問題ではないが、気にはなる。
>![before.png](https://qiita-image-store.s3.amazonaws.com/0/159482/f04769d3-b6bf-df95-d0e2-fa78d263a32c.png)
(参照: http://qiita.com/mpyw/items/b00b72c5c95aac573b71)

##原因
STIX Regularというフォントがこの「の」を表示する。
![Screenshot.png](https://qiita-image-store.s3.amazonaws.com/0/159482/76311518-6da9-5a35-75bf-a36ebc8f153f.png)

##解決方法
about:preferences#content の Fonts for: Latinで正常に「の」が表示されるフォントを指定。
この場合はIPAexフォント。
![firefox.png](https://qiita-image-store.s3.amazonaws.com/0/159482/3bf17cb2-acd1-d9fa-d67b-17b34fa5082b.png)

##結果
無事解決した。
>![after.png](https://qiita-image-store.s3.amazonaws.com/0/159482/6d5259fa-8d90-bc01-fb8d-4d6a8b538233.png)
(参照: http://qiita.com/mpyw/items/b00b72c5c95aac573b71)

##考察
なぜSTIX Regularが標準フォントとして使用されているのかは不明だが、問題が解決したので気にしないこととする。
WebViewのセキュリティについて

JSSECが公開している『Androidアプリのセキュア設計・セキュアコーディングガイド』の2016-09-01版を共有用にまとめているもののうち、「4.9. WebViewを使う」のものとなります。
詳細やサンプルコードについては原著の方を参考ください。

## チェックポイント

- [ ] JavaScriptを有効にする場合、自社が管理しているコンテンツ以外にアクセスしない(※厳密な条件は後述)
- [ ] 自社管理サービスとの通信にはHTTPSを使用する
- [ ] Intent等、他から受け取ったURLはJavaScriptを有効にしない
 * 有効にする必要がある場合は、事前にアプリ内でホワイトリストを持っておき、照合する

#### 端末内のローカルコンテンツを表示する場合

- [ ] 端末内のコンテンツをWebViewで表示し、JavaScriptを有効にする場合、assetsとresディレクトリ以外へのアクセスを禁止する

#### インターネット上の自社管理コンテンツを表示する場合

- [ ] サービス側の用意するコンテンツは、自社の管理していないコンテンツを参照しない
- [ ] アプリ側はSSL通信エラーを適切にハンドリングする
- [ ] アプリ側は表示するURLをHTTPSプロトコルだけに限定する
- [ ] アプリ側は表示するURLを自社管理コンテンツだけに限定する

#### 自社管理コンテンツ以外を表示する場合

- [ ] JavaScriptを有効にしない
- [ ] HTTPS通信の場合、SSL通信のエラーを適切にハンドリングする

## Tips
### JavaSctiptを有効にして良いタイミング
厳密には、安全性が保証できるコンテンツにアクセスする場合のみ、JavaScriptを有効にしても問題ありません。そのため、正確には、自社管理というより、自社以外が書き換え不可能なコンテンツにアクセスする場合になります
例えば、各コンテンツがサーバ内のみを参照かつ、適切なセキュリティ対策がされているならば問題ありません
また、apk内のassets等も他アプリから書き換え不可能なため、JavaScriptを有効にして問題ありません。外部記憶装置に配置されたコンテンツは書き換え可能なため、JavaScriptは無効にする必要があります
もし、JavaScriptを有効にし、自社以外が書き換え可能なコンテンツにアクセスする場合は、そのコンテンツに対する信頼性と、問題が起こった際の責任を考える必要があります

### HTTP通信について
自社サービスに確実に接続するため、HTTPSを使用する必要があります
また、HTTPS通信でSSLエラーが発生した場合、エラーをユーザーに通知し、サービスとの通信を終了する必要があります
AndroidのWebViewにはSSLエラーを通知する仕組みがないため、通知部分に関しては、自前での実装が必要です。

### Android4.2未満の脆弱性について
Android4.2未満ではaddJavascriptInterface()に起因する脆弱性があり、JavaScriptからJavaのリフレクションを用いて、任意のJavaメソッドが実行できる脆弱性があります
Android4.2以降では@JavascriptInterfaceが指定されたメソッドしか操作できないように対策がされたので、この脆弱性はありません

### fileスキームに起因する問題について
WebViewをデフォルト設定で使用する場合、fileスキームを利用してアクセスすると、アプリがアクセス可能なすべてのファイルにアクセスすることができます
対策としては、JavaScriptを有効にしないことのほかに、Android4.1以降の場合は

* setAllowFileAccessFromFileURLs()
* setAllowUniversalAccessFromFileURLs()

を利用してfileスキームによるアクセスを禁止することが出来ます

### Web Messaging利用時の送信先オリジン指定について
Android6.0以降はHTML5 Web Messagingを実現できます
実装の際に、postWebMessage()の第二引数にて、送信先オリジンを指定します
が、この引数にはワイルドカードの指定も可能であり、その場合、どのようなオリジンに対してもメッセージの送信が行われるため、何らかの被害に繋がる可能性があります
そのため、第二引数のオリジンは明示的に指定するべきです

## 参考
『Android アプリのセキュア設計・セキュアコーディングガイド』【2016年9月1日版】
https://www.jssec.org/dl/android_securecoding.pdf
PHPExcelですべてのシートデータをJSONに変換する

自分用メモ

Excelで複数シートにまたがる、数千レコードのデータをJSONに変換する必要があったので、PHPExcelを使って変換してみた。

##環境
* MacOS（Elcapitan）
* PHP 7.0.10
* PHPExcel v1.8.1

##PHPExcel インストール
composerでインストールするのが一番早そうです。
```
composer require phpoffice/phpexcel
```

## 変換してみる
```php:convert-excel-to-json.php
<?php
// composer require phpoffice/phpexcel
require "vendor/autoload.php";

// Memory CacheだとFatal Errorが発生するため、"/tmp"にFile Cacheとして保存する
$cacheSettings = array("dir" => "/tmp");
$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_to_phpTemp;
PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings);

// Excelファイル読み込み
$reader = PHPExcel_IOFactory::createReader("Excel2007");
$book   = $reader->load("foo.xlsx");

// getSheetNames()ですべてのシート名を配列として取得
foreach ($book->getSheetNames() as $sheetName) {
    // シート名からレコードを取得
    $sheet = $book->getSheetByName($sheetName);
    $items = $sheet->toArray(null, false, true, true);

    foreach ($items as $item) {
        // 余分な空配列を除去
        if ($item = array_filter($item)) {
            $records[$sheetName][] = $item;
        }
    }
}

// JSONファイルとして保存
$fp = fopen("bar.json", "a") or dir("Can't open file");
fwrite($fp, json_encode($records, JSON_PRETTY_PRINT));
fclose($fp);
```

PHPExcelを読み込んでデータ取得するだけなので簡単だと考えていたけど、数千レコードあるためかメモリー足りずにFatal errorが出てにっちもさっちもいかない状態で困った。ファイル分割すれば良かったんだけど、シートだけでも数十あったので回避策探したほうが早そうだったので、以下の記事参考にキャッシュ方法変更してみる。

[PHPExcelで大きいエクセルファイルを読み込んだ際にFatal error: Allowed memory size of XXXXX exhausted](https://mistymagich.wordpress.com/2014/08/16/phpexcel%E3%81%A7%E5%A4%A7%E3%81%8D%E3%81%84%E3%82%A8%E3%82%AF%E3%82%BB%E3%83%AB%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%82%93%E3%81%A0%E9%9A%9B%E3%81%ABfatal-error/)

あと、↓みたいなシートの取り方もあるみたいなので、お好きな方で

```php
// Excelファイル読み込み
$reader = PHPExcel_IOFactory::createReader("Excel2007");
$book   = $reader->load("foo.xlsx");

// シート数
$count = $book->getSheetCount();
for ($i = 0; $i < $count; $i++) {
    // 指定位置のシートを取得
    $book->setActiveSheetIndex($i);
    $sheet = $book->getActiveSheet();
}
```