OmniAICreator/Qiita-1.07M huggingface dataset:
Swiftでの音声ファイルトリミング(Crop)と結合(Concat)

- 録音した音声を保存してから指定秒数でトリミング
- 数個の音声ファイルを結合

これら2つの機能を組み合わせて使いたかったので、
その際のメモ兼備忘録。

# 前提
AVAudioSessionとAVAudioRecorderを使ってデバイス内に音声ファイルが保存されていること。


# トリミング(Crop)
## 音声ファイルの末尾から規定秒数分を切り出すケース
まずは切り出し開始位置を決める。
(audioRecorderは録音中のAVAudioRecorderオブジェクト)

```swift
let cropTime:TimeInterval = 10 // 10秒分切り出す
let recordedTime = audioRecorder.currentTime
audioRecorder.stop()
```

切り出し位置が決まったら、Export用にコードを実装する。
(cropTimeより短い時間のファイルなら何もしない)

```swift
if recordedTime > cropTime {
    let croppedFileSaveURL = NSURL(fileURLWithPath: "fineName.caf")
    let trimStartTime = recordedTime - cropTime
    // arg1 / arg2 = CMTimeらしいので、とりあえず1で除算
    // 本当はもっと厳密にやったほうが良いかも
    let startTime = CMTimeMake(Int64(trimStartTime), 1)
    let endTime = CMTimeMake(Int64(recordedTime), 1)
    // 開始時間、終了時間からCropするTimeRangeを作成
    let exportTimeRange = CMTimeRangeFromTimeToTime(startTime, endTime)

    // AssetにInputとなるファイルのUrlをセット
    let asset = AVAsset(url: audioRecorder.url)
    // cafファイルとしてExportする
    let exporter = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetPassthrough)
    exporter?.outputFileType = AVFileTypeCoreAudioFormat
    exporter?.timeRange = exportTimeRange
    exporter?.outputURL = croppedFileSaveURL

    // Export
    exporter!.exportAsynchronously(completionHandler: {
        switch exporter!.status {
        case .completed:
            print("Crop Success! Url -> \(croppedFileSaveURL)")
        case .failed, .cancelled:
            print("error = \(exporter?.error)")
        default:
            print("error = \(exporter?.error)")
        }
    })
}
```


# 結合(Concat)
## 複数の音声ファイルを1つのファイルに結合するケース


```swift
let audioFileURLs = [fileA_Url, fileB_Url, fileC_Url]
var nextStartTime = kCMTimeZero
let composition = AVMutableComposition()
let track = composition.addMutableTrack(withMediaType: AVMediaTypeAudio, preferredTrackID: kCMPersistentTrackID_Invalid)

// 結合するファイル毎に、timerangeを作りtrackにinsertする
for url in audioFileURLs {
    let asset = AVURLAsset(url: url as URL)
    if let assetTrack = asset.tracks(withMediaType: AVMediaTypeAudio).first {
        let timeRange = CMTimeRange(start: kCMTimeZero, duration: asset.duration)
        do {
            try track.insertTimeRange(timeRange, of: assetTrack, at: nextSoundStartTime)
            nextSoundStartTime = CMTimeAdd(nextSoundStartTime, timeRange.duration)
        } catch {
            print("concatenateError : \(error)")
        }
    }
}

if let exportSession = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetPassthrough) {

    let concatFileSaveURL = NSURL(fileURLWithPath: "fineName.caf")

    exportSession.outputFileType = AVFileTypeCoreAudioFormat
    exportSession.outputURL = concatFileSaveURL as URL

    exportSession.exportAsynchronously(completionHandler: {
        switch exportSession.status {
        case .completed:
            print("Concat Success! Url -> \(concatFileSaveURL)")
        case .failed, .cancelled:
            print("error = \(exporter?.error)")
        default:
            print("error = \(exporter?.error)")
    })
}
```
ALB(ApplicationLoadBalancer)とELB

# ALBとELB

## ALB(ApplicationLoadBalancer)
### 機能
[Application Load Balancer の詳細](https://aws.amazon.com/jp/elasticloadbalancing/applicationloadbalancer/)

* パスベースルーティング
	* AkamaiのProxyPathみたいにパスでルーティングできる
* コンテナ化されたアプリケーションのサポート
	* ECS（EC2 ContainerService）と連携する？
* HTTP/2サポート
* WebSocketサポート
* StickySessionの強化
* ヘルスチェックの強化
	* インスタンスのヘルスチェックは従来通りHTTP/HTTPSでping
		* 期待するレスポンスコードが指定できるようになった（200〜299複数）
	* CloudWatchのメトリクスが細かくわかるようになった（ターゲットグループ単位とか）
* 高可用性
	* 2以上のアベイラビリティゾーン指定が必須になった
* レイヤー 7 の負荷分散
	* リクエストヘッダーみて分散させるとか
* ウェブアプリケーションファイアウォール
	* AWS WAFを利用できるようになった

### ELBとの大きな違い

* パスベースルーティング機能
* ELBは直接インスタンスをぶら下げる形だが、ALBはターゲットグループというグループでインスタンスを束ねてそれを紐つける。そのターゲットグループに対してルーティングを決定する。ターゲットグループがインスタンスの死活監視をする役目

### 価格

* ELBとは料金の発生に変更がある
	* 1時間あたりの料金（ELBに較べて１０％引き）
	* LCU（ロードバランサーキャパシティーユニット）時間あたりの料金
* LCU詳細
	* トラフィックを処理する下記の３つの要素の１時間あたりの平均のうち最も高いもので決定する

```
* 1LCUに含まれる要素
	1 秒あたり最大 25 個の新規接続
	1 分あたり最大 3000 個のアクティブ接続
	最大 2.22 Mbps（1時間で約1GBの転送量）
```
* ELBに比べて金額のシミュレーションが難しくなった
* ELBは転送量が課金対象だったが、帯域に課金が変わったので使用量が増加する可能性
* ただ、時間辺りの料金が下がったのでELBに比べて大きく変動はないかも？
* HTTP/2やWebSocketは接続しっぱなしになるため料金体系がかわったのでは？とのこと

### 雑感

* 特別な用途（Websocket、HTTP/2）でなければELBで問題ないと思われる
* パスパターンでAPIのバージョンやロケールで向き先を変更するみたいな運用があるかもしれないが、構成が複雑になるのでおすすめできないと思うが、スパイクするURLと時間がわかっていれば、スポット的にターゲットグループを割り当ててそちらに向かせるなどもありかも。イベントとか
* ELBと比べてどの程度、料金が変わるのか難しい
    * 機能が足りてるなら、費用によってはELBのほうが安価になるケースも有るのかも？
Azure Functionsでエラー検知してChatworkにメッセージを送る

# 背景

Azureにはアラートという機能があって、エラー検知してWebhookでリクエストが送れる。

でも、その検知するエラーの内容がイマイチわからないし、

検知したいのは、Azureのストレージに載せたアプリのログで、
それはテーブルストレージに格納されるので、
エラーログのレコードが追加されたらその内容を知りたい。

ということで、パーフェクトな感じではないけど、Azure Functionsのタイマーで、
エラー検知したら、チャットワークに投げようと思います。

# 方法

１. Azure Functions でTimerTrigger-JavaScriptを選択し、1分間隔で実行
２. kuduでパッケージをインストール

```
npm init -y
npm install request underscore --save
```

３. 統合タブの入力で、取得するテーブルストレージのテーブルを選択
４. 関数に下記の処理を書く

```
var counter = 0;
var error_counter = 0;
var _ = require('underscore');

module.exports = function (context, myTimer) {
    if (counter != context.bindings.RbTraceLog.length) {
        var i = 0;
        var info = _.where(context.bindings.RbTraceLog, { Category: 'error' });
        var len = info.length - error_counter;
        for (; i < len ; i++) {
            setTimeout(function(i) {
                postChat(info[info.length - i - 1], context);
            }, 1000 * i, i);
        }
        error_counter = info.length;
    }

    counter = context.bindings.RbTraceLog.length;

    context.done();
};

function postChat(body, context) {
    var request = require('request');
    var end_point = 'https://api.chatwork.com/v2/rooms/るーむID/messages';
    var header = {'X-ChatWorkToken': 'トークン'};
    var options = {
        url: end_point,
        headers: header,
        form: {"body": JSON.stringify(body)}
    };

    request.post(options, function (error, response, body) {
        if (!error && response.statusCode == 200) {
            context.log('success: '+ response.statusCode);
        } else {
            context.log('error: '+ response.statusCode);
        }
    });
}
```

# まとめ

ちなみにFunctionsは100万回/月が無料なので、1分に一回だと無料です。

アラートからいい感じに検知できるようになったら、また書きたいと思います。
File Transfer Manager CLIを使ってOracle Storage Cloud Serviceにファイルを転送してみた

# 概要

クラウドサービスの利用を検討する際に、課題の一つとしてネットワークの帯域が挙げられます。

Oracle Storage Cloud Serviceでは、サービスに付属のコマンドラインツールを利用することで、Storage Cloud Serive上に高速にファイルを転送できます。
（複数のセグメントに自動分割し、マルチスレッドで転送することで高速化を図っています）

*ネットワーク環境に依存しますが、日本からUSへのアップロードで10~15MB/s程度でした*

尚、利用時の要件は[こちら（File Transfer Manager CLI）](http://docs.oracle.com/en/cloud/iaas/storage-cloud/csclr/preparing-use-oracle-storage-cloud-file-transfer-manager-cli.html#GUID-5BB8647F-DDAD-4371-A519-1116402245FB)


# FTM CLI Client ツールのダウンロード

  http://www.oracle.com/technetwork/topics/cloud/downloads/index.html.


# 初期設定

## ftmcli.propertyファイルの編集
ダウンロードしたZIPファイルを展開し、プロパティ・ファイルにアイデンティティ・ドメインやユーザ名等、接続情報を記載します。

```ftmcli.property
#saving authkey
#Tue Feb 28 14:53:29 JST 2017
segment-size=200
user=XXXX@yyy.com
service=Storage
identity-domain=aXXXXX
retries=5
storage-class=Standard
auth-url=https\://us2.storage.oraclecloud.com
max-threads=15
https-proxy-host = proxy.company.com
https-proxy-port = 8080
```


## 認証キーの取得
`C:\Upload2StorageCloud\ftmcli_v2.1.0> java -jar ftmcli.jar list --save-auth-key`

パスワードを入力後、問題なければStorage Cloud Service上のコンテナ一覧が表示されます。
このとき、ftmcli.propertyファイルに認証キー（auth-key）が埋め込まれ、ftmcliKeystoreが作成されます。


#各種操作
##オブジェクトの確認
### コンテナの確認
Storage Cloud Service上に作成されているコンテナの確認
`java -jar ftmcli.jar list`

###コンテナ内の確認
コンテナtest01内のオブジェクトの確認
`java -jar ftmcli.jar list test01`

##ファイルのアップロード
test01コンテナにsample.zipファイルを10MBずつのセグメントに分け、最大100スレッドでアップロード
`java -jar ftmcli.jar upload -T 100 -G 10 test01 sample.zip`

ファイル名を変更しつつ、アップロード
`java -jar ftmcli.jar upload -T 100 -G 10 -N sample_1.zip test01 C:\Upload2StorageCloudService\sample.zip`

### 補足
・Storage Cloud Service上に当該コンテナが存在しない場合は、upload時に指定したコンテナが新規に作成されます。
・セグメント化してアップロードするために、test01_segmentsコンテナが自動で作成されます。


##ファイルのダウンロード
100スレッドでtest01コンテナのsample.zipファイルをDドライブ以下にダウンロード
`java -jar ftmcli.jar download -T 100 -O D:\sample_01.zip test01 sample.zip`

### 補足
・Oracle Storage Cloud ServiceのArchive Storageに格納した場合は、ダウンロード実行前に一旦オブジェクトをリストアする必要があります。

test01-archiveコンテナのsample.zipファイルをリストア
`java -jar ftmcli.jar restore test01-archive sample.zip`

test01-archiveコンテナのsample.zipファイルのリストア状況の確認
`java -jar ftmcli.jar restore -s test01-archive sample.zip`


##ファイルのDelete
test01コンテナのsample.zipファイルの削除
`java -jar ftmcli.jar delete test01 sample.zip`

#コンテナのDelete
test01コンテナの削除
`java -jar ftmcli.jar delete test01`
react.jsの導入(Babel + browserify + Gulp)

# パッケージの導入
ターミナル立ち上げて各々のモジュールをインストール。

## React
ReactとReactDOMをインストール

```
npm install --save-dev react react-dom
```

## Bebel
ES2015,ES2016で書かれたコードをブラウザで解釈できるコードに変換するツール。

```
npm install --save-dev babelify
```

React用のbabelのプリセットをインストール

```
npm install --save babel-preset-react //JSX記法のコンパイル
npm install --save-dev babel-preset-es2015 //ES2015記法を利用する場合
```

## browserify
複数のjavascriptファイルの依存関係を克服して1つのjavascriptファイルにまとめてくれる。

```
npm install --save-dev browserify
```

## vinyl-source-stream
browserifyのbundle()で吐き出されたオブジェクトがvinyl形式ではないのでvinyl形式に変換しなければならない。
gulpはvinylオブジェクトをイジイジしてファイルを書き出しているので、その過程でvinylオブジェクトが存在しなければならない。
そのため、このパッケージをインストールする必要がある。

```
$ npm install --save-dev vinyl-source-stream
```

# browserifyの記述方法
jsファイルを複数にまとめて一つに統合できる。

- 例)　二つの数値を足し合わせた値を返す処理を別ファイル(add.js)に記述し、その処理を統合元のjsファイル(main.js)から実行する。

``` script-add.js
//addメソッドをexports(アロー関数)
export const add = (a, b) => {
  return a + b;
}
```

``` main.js
const add = require("./script-add.js"); //外部のjsファイルを参照

console.log("合計値："　+ add.add(20,50)); //script-add.jsのaddメソッドを実行
```

# gulpfile.jsの作成
編集元のjsファイルを保存したら以下の処理を自動で実行してくれるタスクを導入

- ES2015記法をbabelでコンパイルする
- browserifyで一つのファイルにまとめる
- 最終的なjsファイルのアウトプットをdestディレクトリに吐き出す
- destファイルに生成されたjsファイルを圧縮する

``` gulpfile.js
var gulp = require("gulp");
var uglify = require("gulp-uglify");
var source = require('vinyl-source-stream');
var browserify = require("browserify");
var rename = require("gulp-rename");
var plumber = require('gulp-plumber');
var browserSync = require("browser-sync");
var runSequence = require("run-sequence");


gulp.task("js", function(callback) {
  return runSequence("browserify","js-min",callback);
});

gulp.task("browserify", function(callback) {
  console.log("---------- babel-browserify ----------");
  return browserify(src.js + "main.js", { debug: true })
  .transform("babelify", {presets: ["es2015", "react"]})
  .bundle(function(err){
    if(err){
      //エラー時でもgulpのwatchタスクを終了させない措置
      return callback(err)
    }
  })
  .on('error', function(err){
    //jsの記法でエラーがあればログを吐き出す
    console.log("JSのエラー："　+ err.message);
    console.log(err.stack);
  })
  .pipe(source('main.js'))
  .pipe(plumber({
    errorHandler: notify.onError("Error: <%= error.message %>")
  }))
  .pipe(gulp.dest(dest.js));
});

//圧縮
gulp.task("js-min", function() {
  console.log("---------- js圧縮 ----------");
  gulp.src(dest.js + "**/*.js")
  .pipe(plumber({
    errorHandler: notify.onError("Error: <%= error.message %>")
  }))
  .pipe(uglify())
  .pipe(rename({ extname: ".min.js" }))
  .pipe(gulp.dest(dest.jsmin))
  .pipe(browserSync.reload({stream:true}));
});
```

# reactを記述

## React,ReactDOMをインポートする

``` js
import React from "react";
import ReactDOM from "react-dom";
```

DOMを描画する処理を入れる。

``` js
ReactDOM.render(
  <h1>ハロー世界！！</h1>,
  document.querySelector("#wrapper") //#wrapper内を<h1>ハロー世界！！</h1>に書き換える
);

```
Cloud Robotics Azure Platform V1 が試せます

Pepper World 2017 2日目の基調講演「IoTとRobotの未来について」にて、Pepper IoT Connectが発表になりました。

http://robotstart.info/2017/02/09/pepper-world-11.html

Pepper IoT Connectは、ロボットやプリンタ、ロボットや液晶デバイスなど、様々なデバイスを連携させるプログラム※なのですが、このSDKとして、Cloud Robotics Azure Platform SDKが公開されています。

※クラウドロボティクスに関して
http://www.softbank.jp/robot/developer/dev-support/cloud_robotics/

Cloud Robotics Azure Platform SDKはサンプルコードとして無償で公開されていますので、誰でも試すことができます。今回、こちらをご紹介したいと思います。
https://github.com/seijim/cloud-robotics-azure-platform-v1-sdk

##まずはダウンロード

上記のGitHubにアクセスしてダウンロードして展開します。
![image](https://qiita-image-store.s3.amazonaws.com/0/167354/da0273e6-19cd-9646-83a4-709084c3784c.png)

※展開時の注意

 展開する際にフォルダの階層深く展開してしまうと、ビルドの際に以下のエラーが出ることがあります。ですので、C:¥直下に配置することをお勧めいたします。

> エラー  プロジェクト CloudRoboticsUtil で NuGet パッケージの復元に失敗しました: 指定されたパス、ファイル名、またはその両方が長すぎます。完全限定型名は 260 文字未満で指定し、ディレクトリ名は 248 未満で指定してください。。

##ハンズオン！
このSDKにはかなり詳細なハンズオン資料が添付されています。かなり詳細な手順と画面ショット付ですので、これを見て頂ければ一通りお試しいただけます。
![image](https://qiita-image-store.s3.amazonaws.com/0/167354/93276162-48aa-1950-179c-69c57a2d8cdb.png)

##全体の流れ
詳細な手順はHands-on資料をご覧いただければと思いますので、全体的な流れを以下に記載します。

Tutorial 01：リソースグループ＆ストレージの作成
Tutorial 02：Azure IoT Hubの作成
Tutorial 03：SQL Databaseの作成
Tutorial 04：SQL Database上にテーブルを作成
Tutorial 05：Cloud Robotics SDK のビルドと設定
Tutorial 06：デバイス間通信の為の設定
Tutorial 07：デバイス間通信のテスト (Cloud Robotics FX のデバッグ実行)
Tutorial 08：Cloud Robotics FX のディプロイ
Tutorial 09：Cloud Robotics FX 上で、アプリを実行
Tutorial 10：Stream Analytics の設定

##Tutorial 01～07まで
こちらを実施すると、ローカル環境でCloud Robotics FX を動かすことができます。

かなり詳細なHands-onテキストが用意されていますので、あまり躓くことはないかもしれませんが、以下をご注意ください。

#T05_02：各ソリューションのビルドができない
各ソリューションをビルドする際に、SignTool.exeが見つかりませんというエラーが出ることがあります。まずはVisualStudioの変更を試していただくのですが、それでもうまくいかなかった場合、Windows 10 SDKをインストールして当該フォルダにSignTool.exeをコピーいただく方法があります。ご参考まで。
http://ssiscirine.moe.hm/archives/24148

#T05_03：Cloud FXの設定
この設定を間違えると動きませんので注意深く設定します。
全体的にコピペでうまくいくのですが、ADO.NETの設定を入れる際に、T03_05でちゃんとユーザID/パスワード部分を入力していないとハマるので注意です。

テキストの記載通り実行すると、ローカルでデバイスシミュレータを起動できます。
とても簡単ですね。

![image](https://qiita-image-store.s3.amazonaws.com/0/167354/3861834d-0890-e6d0-b0dd-c1389077382c.png)

ここまでCloud Robotics FX をローカル環境で実行できるようになりました。
次回はクラウド上にデプロイしたいと思います。

<第2回>
http://qiita.com/minorungj/items/7c45a788ce84772973c9

<第3回>
http://qiita.com/minorungj/items/3cb50091d8a982bcae43
MacにAndroid Studioをインストールして簡単に設定した


内容はタイトルの通りです。特にトラブル無くインストールできました。メモ的に残しておきます。

## 環境

- macOS Sierra（10.12.3）

## やること

1. Javaのインストール
2. Android Studioのインストール
3. Android Studioの設定

## Javaのインストール

まず確認

```bash:
$ javac -version
javac 1.7.0_79
```

1.8が欲しいのでbrewでインストールします

```bash:
$ brew cask install java
🍺 java was successfully installed!
$ javac -version        
javac 1.8.0_121
```

(※ちゃんとpathが通っているか確認してください)

## Android Studioのインストール

以下のサイトからダウンロードします
https://developer.android.com/studio/index.html

展開して、applicationsに放り込むだけ。あとは起動すると処理が走ってインストールされます。

![SS 2017-02-28 16.54.53.png](https://qiita-image-store.s3.amazonaws.com/0/31659/f7a09e92-320d-0332-ece6-4a7e4e4ff0b4.png "wellcome画面")

## Android Studioの設定

以下のサイトを参考に設定しました。
http://dev.classmethod.jp/smartphone/android/android-studio-customize-settings/

フォントはRicty Diminishedを使っています
https://github.com/edihbrandon/RictyDiminished

## 以上

これ設定しておいたほうが良いよとか、これ入れておいたほうが良いよなどがありましたら、ぜひコメントください。
【メモ】Facebook Graph API「v2.2」の使用期限が迫っています。

本日（たぶん）、もう更新していないFacebookページにアラートメッセージが届いていました。

**「2017年3月27日にサポートが切れるので、Graph API v2.3 またはそれ以上にアップグレードしてね」**という内容のようです。

changelog を確認してみたところ、
「v2.2」の使用期限が **2017年3月25日まで** と記載されていました。（2日猶予くれてるw）
https://developers.facebook.com/docs/apps/changelog/

　
ついでに。
今までのリリース間隔からすると、
次回のAPIの最新バージョン（2.9）は 4月頃にリリースされそう。
4月に新しいページを作る場合は、少し気にしておいた方がよさそうです。
How to fix "write /var/lib/docker/tmp/GetImageBlob00000000: no space left on device" error




## Reason

too many inode?


To check inode info

```
df -i
```


## How to fix
 

### 1

Kill processes. (This didn't work for me)

```
docker kill $(docker ps -qa)
```

Delete them.

```
docker rm -v $(docker ps -qa)
```

Delete all images.

```
docker rmi -f $(docker images -q)
```

 
* Ref. [No space left on device in default machine · Issue #1779 · docker/machine](https://github.com/docker/machine/issues/1779)

>@jklemm Check out this repo, it worked for me too https://github.com/chadoe/docker-cleanup-volumes

This didn't work on macOS.


### 2


I haven't tried this.

```
# remove stopped containers
docker rm $(docker ps -a -q)

# remove dangling images
docker rmi $(docker images -q --filter "dangling=true")
```

* Ref. [Error pulling image (...) no space left on device · Issue #10613 · docker/docker](https://github.com/docker/docker/issues/10613)
matplotlibを使って時系列グラフを書いてみる

### 環境
MacOS Yosemiteで動作確認

### Install

```bash
$ pip install matplotlib
```

### 設定
そのまま使うと下のようなエラーがでるので、http://stackoverflow.com/questions/21784641/installation-issue-with-matplotlib-python
を参考に`~/.matplotlib/matplotlibrc`に`backend: TkAgg`を書いておく

```
Python is not installed as a framework. The Mac OS X backend will not be able to function
 correctly if Python is not installed as a framework. See the Python documentation for 
more information on installing Python as a framework on Mac OS X. Please either reinstall 
Python as a framework, or try one of the other backends.
```

### ヒストグラムを書いてみる

```py3
import sys
from datetime import datetime 
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.dates as mdates

date = []
for line in sys.stdin:
    yymm = line.rstrip()[:-3]
    if yymm:
        date.append(datetime.strptime(yymm, '%y/%m'))
fig, ax = plt.subplots(1,1)

d = mdates.date2num(date)
ax.hist(d, bins=50)
ax.xaxis.set_major_locator(mdates.MonthLocator())
#ax.xaxis.set_major_locator(mdates.AutoDateLocator())
ax.xaxis.set_major_formatter(mdates.DateFormatter('%y/%m'))
plt.show()
```

`ax.xaxis.set_major_locator`の部分で指定している`mdates.AutoDateLocator()`の部分を変更するとx軸の単位を指定できる。`mdates.MonthLocator()`を指定すると月ごとになる。`mdates.YearLocator()`だと年ごと。  
`mdates.MonthLocator()`を指定した場合  
<img width="1011" alt="Screen Shot 2017-02-28 at 16.51.51.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/32856/e22c5278-4168-d534-66af-28b35b56a3b3.jpeg">

`mdates.YearLocater()`を指定した場合  
<img width="870" alt="Screen Shot 2017-02-28 at 16.53.29.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/32856/c1f6419e-4f0a-30ee-a889-6116823c7d78.jpeg">

`ax.hist`の`bins`の数を大きくするとグラフの幅が狭くなる  
`bins=100`  
<img width="1022" alt="Screen Shot 2017-02-28 at 16.56.48.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/32856/6c3e091f-d894-1438-3621-03e5e4dcb8ed.jpeg">

`bins=19`
<img width="1061" alt="Screen Shot 2017-02-28 at 17.00.40.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/32856/18d08217-c932-8383-555a-d8c0c96713fe.jpeg">
アイテムの数と同じ数をbinsに指定するとこんな感じになる。
Numpy を使わない多次元配列計算

#Python 小技　配列演算
pypyでpython scriptを実行するときにつかった小技のメモ。
pypyとはpython scriptを高速実行するための異なるpython実行系である。こいつは確かに速い。しかし、pypyとnumpyの相性が猛烈に悪い. 最近はinstallとimport自体はすんなり通るものの、当のnumpyによる計算が猛烈に遅くなる。
これでは意味がないということでpypyを諦める人もいそうなので、ここではnumpyを使わない配列演算を扱ってみる。

###1. 1次元配列の加減乗除
まずは単なるlist同士の足し算
   
    array1 = [4,5,6]
    array2 = [1,2,3]
    array_add = list(map(lambda x,y: x+y, array1, array2))
    #[5,7,9]

解説すると
lambdaは手軽に関数を作りたいときに便利なやつ。上の例では、ｘとｙを2つの引数を足し算して返す関数を作っている。一方で map()は、1つ目の引数に関数、そして2個目以降の引数には1つ目の関数の引数を要素に持った配列をとり、配列の中の要素を順番に関数にかけてくれる。 つまり、(x,y)には(4,1),(5,2),(6,3)が順番に、lambdaで作った関数に渡されて、その返り値である和が計算される。map()はpython2.系ではtupleが返り値になるが、python3.系ではiterが返り値になるので、2.でも3.でも動くようにlist()で囲むことをおすすめする。
同様に

    #引き算
    array_subtract = list(map(lambda x,y: x-y, array1, array2))
    #[3,3,3]

    #掛け算
    array_multiple = list(map(lambda x,y: x*y, array1, array2))
    #[4,10,18]

    #割り算
    array_div = list(map(lambda x,y: x/y, array1, array2))
    #[4,2.5,2] python3.系 
    #[4,2,2] python2.系
 



###2. 2次元配列の足し算
1次元のときのことを応用すれば、numpyを使わないで多次元配列の加減乗除だってできる。

    array1 = [[1,2,3],[1,2,3]]
    array2 = [[2,3,4],[2,3,4]]
    array_add = list(map(lambda x,y: list(map(lambda a,b: a+b, x,y)), array1, array2))
    #[[3, 5, 7], [3, 5, 7]]

と、このようにnumpyを使わなくてもmapとlambdaを駆使すれば、配列同士の演算はおちゃのこさいさいである。pypyを使わないひとも、わざわざnumpyをimportしなくてもなぁというときに使ってみてください。

### おまけ.  転置
演算以外によく使うものとして、2次元配列の転置。

     array1 = [[1,2,3],[3,4,5],[6,7,8]]
     array1_t = list(zip(*array1))
     #[(1,3,6),(2,4,7),(3,5,8)]
[メモ](RaspberryPi) Building ZFS on Raspbian

## 概要/Overview
- ZFS を Raspbian で使用する
- 参考: [zfsonlinux/zfs:Building ZFS](https://github.com/zfsonlinux/zfs/wiki/Building-ZFS)
- `linux-headers-$(uname -r)`の代わりに、`raspberrypi-kernel-headers`


## 環境/Environment
- Raspberry Pi 2/3
- Raspbian: `2017-01-11-raspbian-jessie-lite` 


## 手順
1. いつもの
 - Burn Raspbian to SD
 - パッケージ更新:<br>`sudo apt-get update && sudo apt upgrade -y`

2. ビルドに必要なパッケージのインストール

    ```bash:こぴぺ
sudo apt-get install -y build-essential autoconf libtool gawk alien fakeroot raspberrypi-kernel-headers && \
sudo apt-get install -y zlib1g-dev uuid-dev libattr1-dev libblkid-dev libselinux-dev libudev-dev libdevmapper-dev && \
sudo apt-get install -y parted lsscsi ksh
```

3. ビルドとインストール

    ```bash
DIR_WORK=${HOME}/work
#
cd ${DIR_WORK}
# ソース取得.
wget https://github.com/zfsonlinux/zfs/releases/download/zfs-0.6.5.9/spl-0.6.5.9.tar.gz
wget https://github.com/zfsonlinux/zfs/releases/download/zfs-0.6.5.9/zfs-0.6.5.9.tar.gz
# ワークフォルダにソース展開.
mkdir zfs
cd zfs
tar xf ../spl-0.6.5.9.tar.gz
tar xf ../zfs-0.6.5.9.tar.gz
# OR 
##git clone https://github.com/zfsonlinux/spl
##git clone https://github.com/zfsonlinux/zfs
# ビルドとインストール.
cd spl-*
./autogen.sh && ./configure && make -j4
sudo make install
# sudo sh -c 'PATH=/home/pi/.local/bin:$PATH porg -lD "make install"'
cd ..
cd zfs-*
./autogen.sh && ./configure && make -j4
sudo make install
#sudo sh -c 'PATH=/home/pi/.local/bin:$PATH porg -lD "make install"'
cd ..
#
# 共有Libの更新
sudo ldconfig
#
cd ${HOME}
# カーネルモジュール更新.
sudo depmod -a
```

4. テスト : 256MBのファイルをつくって、そこで、zfsを使用してみる.

    ```bash
#rootになる.
# rootでないと、'Permission denied the ZFS utilities must be run as root.'
sudo -s
# カーネルモジュール読み込み
modprobe zfs
lsmod
# 256MBのファイル作成 
dd if=/dev/zero of=/tmp/zfs256MB bs=1M count=256
#プールテスト
zpool create tank /tmp/zfs256MB 
zpool list
zpool status
# FS作成
zfs create tank/test1
zfs list
chown pi.pi -R /tank/test1
# プールの破棄
zpool destroy tank
zpool list
```


    ```shell-session:実行例
	pi@raspberrypi:~ $ sudo zpool status
	  pool: tank
	 state: ONLINE
	  scan: none requested
	config:

		NAME             STATE     READ WRITE CKSUM
		tank             ONLINE       0     0     0
		  /tmp/zfs256MB  ONLINE       0     0     0

	errors: No known data errors
	pi@raspberrypi:~ $ sudo zfs list
	NAME         USED  AVAIL  REFER  MOUNTPOINT
	tank          89K   208M    19K  /tank
	tank/test1    19K   208M    19K  /tank/test1
	pi@raspberrypi:~ $
```

## その他
- もうちと、zfsをお勉強しないといけない。
- USBドライブで、`zpool create hogehoge /dev/sda`みたいにできたはず。
- USBドライブ2台とかで、ミラーリングとかできるのだろうか？
- 起動時に再マウントするにはどうするのがいいだろうか？<br>=> (2017-3-2追記) [archlinuxのZFSの自動起動](https://wiki.archlinuxjp.org/index.php/ZFS#.E8.87.AA.E5.8B.95.E8.B5.B7.E5.8B.95)のあたりから

	```bash
	# pool作成後
	zpool set cachefile=/usr/local/etc/zfs/zpool.cache <pool>
	systemctl enable zfs.target
	systemctl enable zfs-import-cache
	systemctl enable zfs-mount
	```
	cachefileは、`/etc/default/zfs`の`ZPOOL_CACHE=～`で指定?

- Raspbianで、rootfsとして使えるのだろうか？
Serverless Python Requirements で楽をする

AWS Lambda で Python のモジュールを使うとき、Amazon Linuxでコンパイルしなくてはいけないモジュールを使うには、[面倒な手順](http://qiita.com/mkisono/items/b2add04203f7b4a6da67)が必要だと思っていたのですが、もっとお手軽な方法がありました。[serverless framework](https://serverless.com/) と [プラグイン](https://github.com/UnitedIncome/serverless-python-requirements) を使います。

ほぼ[クラスメソッドさんの記事](http://dev.classmethod.jp/cloud/aws/managing-external-modules-with-serverless-framework-plugin/)の通りなのですが、一部 yaml の書き方が異なっていました。

non-pure-Python モジュールをコンパイルする場合は、serverless.yml に以下の設定を追加します。

```serverless.yml
plugins:
  - serverless-python-requirements

custom:
  pythonRequirements:
    dockerizePip: true
```

これだけ、実に楽チンです。

なお、requirements.py はどこにあるんだ？ と思った方は、以下のコマンドを実行してみてください。

```bash
% sls requirements install
```
Rでインストールされている全てのパッケージをアップデートする方法

定期的にググってる気がするのでメモ書き。
Rを起動して以下のコマンドを入力。

```R
# アップデート可能な全てのパッケージをインタラクティブにアップデート。
update.packages()

# 上のコマンドでは更新するかどうかパッケージごとにきかれるが、
# "ask = FALSE" を引数に与えると、全てのパッケージを問答無用にアップデートできる。
# バイナリのパッケージがない場合はソースからコンパイルするかどうか最初にきかれたかもしれない。
update.packages(ask = FALSE)
```

その他のアップデート関連のコマンド。

```R
# アップデート可能な古いパッケージをリストアップする
old.packages()

# 特定のパッケージをアップデートする際は`install.packages()`で可能。
install.packages("ggplot2")
```

##参考
http://neondataskills.org/R/Packages-In-R/
ECCUBE3で後からSSLを導入した際にしたこと（html/indxe.php省略）

ECCUBE3系でhtml/index.phpを省略し、運営していたのですが途中でSSLを導入することになったのですが、いろいろ困って解決したのでメモ

■ 管理画面にアクセスするときhttpにリダイレクトされる場合
/autoload.php　の先頭に
if (isset($_SERVER['HTTP_X_SAKURA_FORWARDED_FOR'])) {
$_SERVER['HTTPS'] = 'on';
$_ENV['HTTPS'] = 'on';
$_SERVER['HTTP_HOST'] = 'ドメイン名';
$_SERVER['SERVER_NAME'] = 'ドメイン名';
$_ENV['HTTP_HOST'] = 'ドメイン名';
$_ENV['SERVER_NAME'] = 'ドメイン名';
}
を追記。

■いろいろ設定していたせいでhtaccessでhttpからhttpsにリダイレクトすることができない

/app/config/eccube/config.yml
の
force_ssl: null　を force_ssl: 1　に変更。

自分は技術不足なため、まだまだ情報が少ないECCUBE3は辛いっす
地味に役立つショートカットキー

#基本系
**▼(Ctrl+C)　　　　　　　コピー**
**▼(Shift+矢印キー)　　　選択領域の調整**
*テキストコピーのお供に*
**▼(Ctrl+V)　　　　　　　貼り付け**
**▼(Tab)　　　　　　　　インテンド移動、カーソル移動等**
*マウス不良時に良く使う*
**▼(Tab+Shift)　　　　　(Tabに対して)インテンド逆移動、カーソル移動等**
**▼(Ctrl+Z)　　　　　　　戻る**
*ミスったらとりあえず押下*
**▼(Ctrl+Y)　　　　　　　進む**
*ミスって戻ってしまったときに押下*
**▼(Ctrl+S)　　　　　　　セーブ(保存)**
*大学時代お世話になりましたw。*
**▼(Shift+CapsLock)　　スペースロック(スペースボタン押下状態)**　
*大文字の入力するときに活用。パスワードを把握されてもこれをやっておけば少しは効果あるかも…ｗ*
**▼(Shift連打)　　　　　固定キー設定**
*ゲームとかで出てきて困るやつ。5回ぐらい押すと出てきます。どういう効果があるかは知りません*
**▼(F5)　　　　　　　　　リロード**
*押下しすぎるとDos攻撃になるから注意*
**▼(F11)　　　　　　　　全画面表示**


#スクロールバーをクロール
**(Ctrl+上下矢印キー)**
*手をキーボードから離さずかつ右手のみで扱えるのが良い(キーボード配置によっては出来ないかもしれません)*
エディターによって異なるかもしれない
**・以下動作確認完了エディター**
　*VisualStudio2015,サクラエディター*

#NumLock押下後のテンキー構成
--随時追加

#知ってると便利なショートカット

**▼(Ctrl+Delete)　　　　**
*カーソルの箇所までスペースやタブキーで作成した空白を削除します。*
*コメントを整えるときに便利*
例)
 ![Ctrl+Delete](https://qiita-image-store.s3.amazonaws.com/0/159061/5b8ae253-8d48-5f4a-ae95-ecfd2ad561ff.png)

#エクセル系
**▼(Ctrl+Pgup)  or　(Ctrl+Pgup)** 
*シートを移動します。*
(Ctrl+Pgup)はシートの古い方に動く[シート2 → シート1]
(Ctrl+Pgup)はシートの若い方に動く[シート1 → シート2]

#VisualStaudio
#####[Alt+上下]
- 当該の行をそのまま移動させる。
  - 切り取りして貼り付けより便利
- 欠点
  - 一行ずつしか移動できない
.NET Webアプリ開発 Azure 公式サイトリンク

* 公式サイトでの.NET Webアプリのリンク集
* アプリとは今回の場合、通常のWeb Sitesである。
* この順番に開発すると一通り理解が進む


[初めての Web アプリを Azure に&5; 分でデプロイする](https://docs.microsoft.com/ja-jp/azure/app-service-web/app-service-web-get-started-cli-nodejs)

[初めての Web アプリに機能を追加する] (https://docs.microsoft.com/ja-jp/azure/app-service-web/app-service-web-get-started-2)

[Azure Active Directory 認証を使用した基幹業務 Azure アプリの作成](https://docs.microsoft.com/ja-jp/azure/app-service-web/web-sites-dotnet-lob-application-azure-ad)
javascript オブジェクト指向プログラミング

# オブジェクト生成
従来のjavascriptではクラスを直感的に定義できなかったがES2015ではクラスを作成することができる。

「クラス」とは、生成するオブジェクトのひな形となる要素のことを指す。
そのオブジェクトのひな形を生成してプログラム上にて実体化したものを「インスタンス」という。
インスタンスを生成する際に初期化をする必要があり、その初期化を行うメソッドを「コンストラクタ」という。

## クラス生成
```js
//クラス
class Human {
  constructor(height, weight){
    //コンストラクタ
    //プロパティ生成(thisはこのクラスのインスタンスを指す)
    this.height = height;
    this.weight = weight;
  }
    
  walk(distance) {
    //クラスが保有するメソッド
    console.log("身長："　+ this.height + "、体重："　+ this.weight + "の人が");
    console.log(distance + "m歩いた。");
  }
}

//Humanクラスのインスタンス生成
const man = new Human(170,68);
man.walk(30); //インスタンスが持つメソッドを実行

//同じクラスから別のインスタンスを生成
const woman = new Human(155,50);
woman.walk(100);
console.log("身長："　+ woman.height); //プロパティ参照　(身長：155)

```

# 継承
クラスが持つ情報を継承して新たなクラスを生成する。

```js

//継承
class Tanakasan extends Human{
  constructor(){
    super(); //継承元のクラス(スーパークラス)のコンストラクタを呼び出す

  }
}

const tanaka = new Tanakasan();
tanaka.height = 155;
tanaka.weight = 34;
tanaka.walk(3000);
```
AWSバッドノウハウ集 2017/02

###おことわり
- 主観であり何らかのデータにもとづいてはいない
- この記事に書いてあることは信じずに自分で試そう

#EC2 t2 ファミリーは他ファミリーと比べて不安定
どのインスタンスもいつかは死ぬという点では共通なのですがそのなかでもt2は故障したり不具合が発生したりする確率が非常に高い気がする

なので死んだり、死にかけ状態で動き続けたりしてほしくないインスタンスはあんまりリソースを使わなくても t2.micro とかじゃなくて m3.medium にしとくとすこし可用性があがる

追記: CPUクレジット理解していないだけではとか書かれていたんですがその辺は確認している。
t2の可用性が問題になったケースいくつかあるんだけど、自分の場合はネットワークがたまに断する問題が多くて、分散DBクラスタの死活監視で1secごとにpingするだけでCPUは常に1%以下みたいなものとかに使うとカジュアルに10sec以上ネットワーク断してくれることが多くて困ったりとか。

t2.medium以上のサイズはm3ファミリーを選択してしまうので使ったことないので、いいのかもしれないですね

#インスタンスをまとめて起動すると同じホストに配置されがちで同時に死ぬ
なのでホストが故障するとインスタンスもまとめて死にます。サポートにきくと「複数のAZに分散して配置していただくことで、、、」と案内されますが、3台のDBを2AZにそれぞれ1台と2台配置して、2台が同時に故障したりすると目も当てられないのは明白です。

「もしくはDedicated Hostsを…」とか案内されたりもするので、我々の取れる対策としては

- なるべくAZをわける
- Tokyoを捨てて3AZ以上使えるRegionに引っ越す
- クラスタにインスタンスファミリーが別のものを加える
- なるべく時間を空けてインスタンスを起動する
- Dedicated Hostsを2台以上かりてそれぞれに配置する（すごく高い）

あたりでしょうか。Tokyoで使えるAZふやしてくれー

#EBSはガチャ
(少なくともGP2とPIOPSについては）相当な頻度で故障して、裏側で再構築が走ったり、ギリギリ故障判定のしきい値に達せずに低性能のまま放置されていたりする。サポートに問い合わせると故障していたと教えてもらえることもあるが、問い合わせることでそのEBSが直るということはないので破棄して再構築したほうが早い

最近だとインスタンスストレージ付きのi3がr3と同じくらいの値段で使えるのでそういうのを使ってEBSにDBを置く頻度を減らすとEBSの障害も回避できるかも

RDSはそうなったときの対処がfailoverしかない上にMulti-AZでEBSの故障率も2倍なので本当に酷いことになりがち、AuroraはEBSはそこそこ故障したり調子が悪くなるという教訓を元に設計されつくられているのでできればAurora使ったほうがいいのではないでしょうか

#VPCについているDNSサーバーは以外と貧弱
以外と貧弱なのでDBなどをドメイン名で指定していたりと、頻繁に名前解決しまくるようなサービスだとDNSが死ぬ。各インスタンスでDnsmasq起動してキャッシュして負荷低減に勤しんだり、自前でDNSキャッシュサーバー建ててVPC付属のやつを使わないようにしよう

#99%の障害はコンソールには何も表示されていない
https://status.aws.amazon.com/
こことか Management Console とか見ても何も書いていないことがほとんど

サポートに問い合わせると50%くらいの障害は「そういった事象が発生していました」と教えてもらえるのですが「すでに直った」か「再構築をお願いします」と言われることが多い。なんかおかしいなーという箇所は全部再構築すると大抵直るのでおすすめです
KUSANAGIを使っているWordPressでコメントが書き込めなくなったのはログがディスクを逼迫していた

# はじめに
KUSANAGIで運用しているサイトでコメントが書き込めなくなりました。
スパムコメントを消すとコメントを書き込めます。
ということでディスクがいっぱいになっていないか、ということを疑いました。

muninのログを見るとディスク使用量が100％を突き抜けていました。
![Screen Shot 2017-02-26 at 17.28.50.png](https://qiita-image-store.s3.amazonaws.com/0/47327/a09f3cd4-c8c1-8d35-6a3b-f9f18f2baaf5.png)

Oh...

ディスクを食っている原因を調べたところ、hhvmのログが大きくなっていました。

![Screen Shot 2017-02-28 at 14.05.23.png](https://qiita-image-store.s3.amazonaws.com/0/47327/34331329-0690-0ac1-fce7-89682ba0a180.png)

![Screen Shot 2017-02-28 at 13.57.02.png](https://qiita-image-store.s3.amazonaws.com/0/47327/b708b2eb-1017-1823-1ffc-360870d4866e.png)

圧縮後で3GB超えはまずいですね。

# 対処

ログを確認するとKUSANAGIのキャッシュプラグインでSQLのインサートエラーが出ていました。
一行あたりの表示が大きいので表示できるようにcutコマンドと組み合わせてみます。

```bash
$ tail -n 100 error.log | cut -c1-700 | less
```

![Screen Shot 2017-02-28 at 14.00.15.png](https://qiita-image-store.s3.amazonaws.com/0/47327/28ccb9d3-f091-a876-eefe-7fcc703c0141.png)

`type`というカラムがnullなのでエラーになっているようです。
すでに報告されているエラーのようですので、参考サイトを元にプラグインを書き換えます。
typeがnullの場合にはキャッシュしないように一部を書き換えた差分です。

```php:DocumentRoot/wp-content/mu-plugins/kusanagi-core/modules/page-cache.php
...L652
-		if ( ! $row ) {
+		if ( ! $row && !is_null($data['type'])) {
...
```

これでログが抑止されました。


# 参考サイト
KUSANAGIでWordPressデータベースエラーが出る時の対処法
> https://keikenchi.com/kusanagi-wordpress-db-error
10進数の文字コード値から文字に変換する

10進数の文字コード値をbyteにして文字に戻すのに苦労したので、とりあえず書きます。
UTF8とかでも同じようにできると思います。
（ビッグエンディアンの時のテストができてないのでそこはかなり怪しいです）
（ビッグエンディアンのときはどう返ってくるかイマイチ理解が及ばない…）

# 前提
文字列「にゃーん」はShiftJISだと、こうなります。

|文字|Shift_JIS(16進)|
|:-:|:-:|
|に|82 C9|
|ゃ|82 E1|
|ー|81 5B|
|ん|82 F1|

こいつをさらに10進数にします（符号ありで）

|文字|Shift_JIS(16進)|10進数|
|:-:|:-:|:-:|
|に|82C9|-32055|
|ゃ|82E1|-32031|
|ー|815B|-32421|
|ん|82F1|-32015|

この10進数をそれぞれ文字に戻したいです。

# 実装
↓な感じで実装してみました。


```csharp:実装
        /// <summary>
        /// 文字コード値(10進数)を変換する(1文字)
        /// （例）引数「-32055」を受け取り、変換後文字「に」を返す。
        /// </summary>
        /// <param name="sJisCharCode">変換するコード値</param>
        /// <returns>変換後文字(1文字)</returns>
        public static string DecodeSJisWord(int sJisCharCode)
        {
            byte[] byteArray = GetSJisBytes(sJisCharCode);

            return Encoding.GetEncoding("shift_jis").GetString(byteArray);
        }

        /// <summary>
        /// ShiftJISの文字コード値を10進数（符号あり）からbyte配列に変換
        /// </summary>
        /// <param name="sJisCharCode">文字コード値(10進数)</param>
        /// <returns>変換後文字コード値(1or2byte 10進数)</returns>
        private static byte[] GetSJisBytes(int sJisCharCode)
        {
            // コードからbyteを取得(4byte)
            byte[] byteArray = BitConverter.GetBytes(sJisCharCode);

            // ShiftJISは2byteのため、4→2byteに変換する
            byte[] rtn = new byte[2];

            // 環境によってバイトの格納順を変更
            if (BitConverter.IsLittleEndian)
            {
                rtn[0] = byteArray[1];
                rtn[1] = byteArray[0];
            }
            else
            {
                rtn[0] = byteArray[2];
                rtn[1] = byteArray[3];
            }

            // 1バイト文字の場合は2→1バイトに変換する
            rtn = Convert2To1ByteIfNeeded(rtn);

            return rtn;
        }

        /// <summary>
        /// 1バイト文字だったら1バイトにする、2バイト文字の場合はなにもしない
        /// （必要に応じて2バイトを1バイトに変換する）
        /// </summary>
        /// <param name="checkArray">変換対象(2byte)</param>
        /// <returns>変換後byte配列</returns>
        private static byte[] Convert2To1ByteIfNeeded(byte[] checkArray)
        {
            // 1バイト文字のとき
            if (checkArray[0] == 0)
            {
                return new byte[] { checkArray[1] };
            }
            // 2バイト文字
            else
            {
                return checkArray;
            }
        }

```

# さいごに
とてもニッチなのか、ぐぐってもろくにでなくて大変でした。
エンディアンとか知らなかったですし…。
とりあえず動くんですけど、なんかもっといい方法とかかっこいい書き方ないですか…。
ストレージ権限を付与せずにカメラ撮影のIntentを投げる

ツイッター公式とかがランタイムパーミッション求めてくるけど、別になくてもいけるよな？って思ってやってみた。

# やること

* `READ_EXTERNAL_STORAGE`及び`WRITE_EXTERNAL_STORAGE`権限を付与しない
* アプリから`ACTION_IMAGE_CAPTURE`でアプリを起動する
* 撮影された写真(Uri)をBitmapに復元する

# 実装

## FileProviderを定義する

```xml:AndroidManigest.xml
<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="${applicationId}.provider"
    android:grantUriPermissions="true"
    android:exported="false">

    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_provider" />

</provider>
```

```xml:res/xml/file_provider.xml
<paths xmlns:android="http://schemas.android.com/apk/res/android">

    <files-path name="image" path="temp/"/>
</paths>
```

# 出力先のUriを用意する

ファイルを作ります

```java
private File createOutputFile() {
    File tempFile = new File(context.getFilesDir(), "temp/sample");
    if (!tempFile.exists()) {
        try {
            tempFile.getParentFile().mkdirs();
            tempFile.createNewFile();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    return tempFile;
}
```

ファイルが存在していないと、カメラ側で`FileNotFoundException`になるので空ファイルを作ってください。

作ったファイルを`FileProvider`を使ってUriに変換します。

```java
FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", file);
```

## Intentを起動する

```java
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputUri);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

startActivityForResult(intent, REQUEST_CAPTURE);
```

## 結果を受け取る

```java
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == REQUEST_CAPTURE && resultCode == RESULT_OK) {
        Uri uri = outputUri();
        Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
    }
}
```

`ACTION_IMAGE_CAPTURE`では、出力先Uriが返却されない糞仕様なので、出力先Uriは起動側でどうにかして保持しておく必要があります。
Uriを動的に生成する場合、カメラ起動時にメモリ食ってActivityが破棄される可能性も考えると`onSaveInstanceState()`を実装したりとそこそこめんどくさいですが、頑張ってください。


# 仕組み

出力先ファイルはアプリ領域に用意し、`FileProvider`を使って`Uri`化しています。

この`Uri`は通常、当該アプリしかアクセスできませんが、`Intent`に `FLAG_GRANT_WRITE_URI_PERMISSION`フラグを追加することで、一時的に外部アプリにアクセス権限を与えることができます。

# 課題

## KitKat以前は、暗黙的Intentに`FLAG_GRANT_*_PERMISSION`が付与されない

暗黙的IntentにUriのアクセス権限が付与できないようです。

以下のようにすることで、付与できるようですが、ユーザーが起動するアプリ以外にも付与される気がするのでどうなんだろ…

```java
List<ResolveInfo> resolves = getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);

for (ResolveInfo resolveInfo : resolves) {
    grantUriPermission(resolveInfo.activityInfo.packageName, outputUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
}
```

ちなみに`grantUriPermission()`したら、必要に応じて`revoke`してあげたほうがいいみたいです。

```
revokeUriPermission(outputUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
```


# 参考

[Setting Up File Sharing | Android Developers](https://developer.android.com/training/secure-file-sharing/setup-sharing.html)

[Android:FileProviderでファイル共有 | Yukiの枝折](http://yuki312.blogspot.jp/2014/04/androidfileprovider.html)
elixir で Unix Domain Socket を読み書きする

# Elixir で Unix Domain Socket
自分用メモ

Elixir から Unix Domain Socketを作ったり送ったりするには
erlangのgen_udpをそのままいじればよい。

```elixir:iex
{:ok,socket}= :gen_udp.open(0, [{:ifaddr, {:local, "/tmp/testsockin"}}])
:gen_udp.send(socket,{:local, "/tmp/testsockin"}, 0, "test test \r\n")
receive do
tmp ->
  IO.inspect tmp
after 3000 ->
  IO.puts "time out"
end
```
送るのにも同じソケットを使ってしまっているけどもこれは本来的には別のsocketを作って送るべきなんだろうな。
案件で役に立つFlexbox

# 前提
Flexbox使える使えるってよく聞きますが、
実際の案件のどういった場面で使えるのかがピンときていない人のために（主に私）。

# Flexboxの各プロパティ
コリスさんにとても詳しく書いてあります。よく見てます。
[CSS3 Flexbox の各プロパティの使い方をヴィジュアルで詳しく解説](http://coliss.com/articles/build-websites/operation/css/css3-flexbox-properties-by-scotch.html)

各プロパティはわかった。でもそれがそんなに便利なの？？

# ヘッダーのロゴとナビゲーションを左右に振り分ける
ロゴは左、ナビゲーションは右に振り分けるときに使う。
（引用）[flexbox[CSS3]で実践的なレイアウトを。実際の現場で使うflexboxの4パターン](https://web-bruno.com/flexbox-css3/)
こちらの例では、
コンテナに justify-content: flex-end;、左に寄せたいロゴにmargin-right: auto;をつけているけど、
コンテナに justify-content: space-between;で左右に振り分けてもよいのでは？

# 画像＋テキストを画像を左右交互に並べるとき
HTMLは画像→テキストの順番で作っておいて、
コンテナにflex-direction: row-reverse;　で
奇数又は偶数のときに並びを入れ替える
（引用）[flexbox[CSS3]で実践的なレイアウトを。実際の現場で使うflexboxの4パターン](https://web-bruno.com/flexbox-css3/)

# HTMLの順序と表示順序を変える
PCでは真ん中メインだけどSPではメインを一番上に持っていきたい場合や、
真ん中のコンテンツだけど、HTMLでは最初に書きたい場合に。
order: 1;
order: 2;
など順番を付与するとできる。
-1とかも指定できる！

# input+横についているボタンの高さ揃え
きれいに高さ揃えたいときに便利。
（引用）[Solved by Flexbox](http://hashrock.github.io/solved-by-flexbox-ja/demos/input-add-ons/)

# グリッドシステム
等幅コンテンツなら、幅を指定せずにflexアイテムを突っ込むだけ。
幅を指定したいなら、そこだけwidthを指定すればよいだけ。
1/2,1/4,1/4レイアウトも簡単！
（引用）[Solved by Flexbox](http://hashrock.github.io/solved-by-flexbox-ja/demos/grids/)


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

縦方向もめっちゃ使える。
flex-direction: column;が活躍する場面を知らなかった。


# ボタンを右下に配置する場合
画像＋（テキスト＋ボタン）のときに、ボタンを画像の下揃えにしたいとき、
その上のテキストとボタンを縦のflexboxにして、
ボタンの指定をalign-self: flex-end;にすると、下に寄る。
（引用）[css3のflexboxを使うとすごい簡単になるレイアウトを試してみた](http://sterfield.co.jp/designer/css3%E3%81%AEflexbox%E3%82%92%E4%BD%BF%E3%81%86%E3%81%A8%E3%81%99%E3%81%94%E3%81%84%E7%B0%A1%E5%8D%98%E3%81%AB%E3%81%AA%E3%82%8B%E3%83%AC%E3%82%A4%E3%82%A2%E3%82%A6%E3%83%88%E3%82%92%E8%A9%A6%E3%81%97/)


# ページが短いときにフッターをウィンドウ枠の下揃えにする
高さが不明のときもOK！！！！
（引用）[Solved by Flexbox](http://hashrock.github.io/solved-by-flexbox-ja/demos/sticky-footer/)
ページ上に書いてある記述と、ソースと、Githubのソースが違うけど、、たぶんできるのかな？

# (参考)
コリスさんになんでも載ってる。
[[CSS]Flexboxのこれが知りたかった！今まで出来なかったことがシンプルで簡単に実装できるスタイルシートのまとめ](http://coliss.com/articles/build-websites/operation/css/particular-design-problem-with-flexbox.html)
[これが知りたかった！よく使うUI要素をFlexboxを使ってシンプルに簡単に実装するチュートリアル](http://coliss.com/articles/build-websites/operation/css/using-flexbox-for-ui-components.html)
[Ubuntu] visudoのエディタをnanoからvimに変更する

visudoでnanoが立ち上がるという不条理を経験したので変更手順をメモ

# TL;DR

`sudo update-alternatives --config editor` を使用する

追記：コメントで指摘頂きましたが、以下のように直接指定してもよさそうです

```bash:直接指定
$ sudo update-alternatives --set editor /usr/bin/vim.basic
```

# 変更手順例

```console:vim.basicに変更
$ sudo update-alternatives --config editor
There are 5 choices for the alternative editor (providing /usr/bin/editor).

  Selection    Path                Priority   Status
------------------------------------------------------------
* 0            /bin/nano            40        auto mode
  1            /bin/ed             -100       manual mode
  2            /bin/nano            40        manual mode
  3            /usr/bin/code        0         manual mode
  4            /usr/bin/vim.basic   30        manual mode
  5            /usr/bin/vim.tiny    10        manual mode

Press enter to keep the current choice[*], or type selection number: 4
update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/editor (editor) in manual mode
```
```console:変更の確認
$ sudo update-alternatives --config editor
There are 5 choices for the alternative editor (providing /usr/bin/editor).

  Selection    Path                Priority   Status
------------------------------------------------------------
  0            /bin/nano            40        auto mode
  1            /bin/ed             -100       manual mode
  2            /bin/nano            40        manual mode
  3            /usr/bin/code        0         manual mode
* 4            /usr/bin/vim.basic   30        manual mode
  5            /usr/bin/vim.tiny    10        manual mode

Press enter to keep the current choice[*], or type selection number:
```

# 参考
[Ubuntuのvisudoエディタが変nanoになる - それマグで！](http://takuya-1st.hatenablog.jp/entry/20110423/1303585363)
Windows10でVS2005 のプロジェクトをビルドするときに”LC.exeが見つからない"でエラーになる場合の対処

Windows10 に VS2005を入れていいのか、って話は置いておいて、古いプロジェクトがVS2005で作られていて外部ベンダーのカスタムコントロールを使っていたりしてどうしてもサポートしなければならなくたなった場合のメモ

メッセージにはこう表示されている(モジュール名は適当)

```
エラー	1	"LC.exe" が見つからなかったため、または .NET Framework SDK v2.0 がインストールされていないため、タスクに失敗しました。タスクは、レジストリ キー HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework の値 SDKInstallRootv2.0 で指定された場所の下にある "bin" サブディレクトリで "LC.exe" を探しています。次の 1 つを行うことによって問題を解決できる可能性があります:  1.) .NET Framework SDK v2.0 をインストールする  2.) 上記のレジストリ キーを正しい場所に手動で設定する  3.) 正しい場所をタスクの "ToolPath" パラメータに渡す	WindowsApplication1
```

で、この指示通りにやってもまるで改善しない。

## 64bit Windowsではレジストリ キー の検索場所が違う

VS2005はもともと32bit版だった。64bit Windowsではそこに指示されたキーを探していない。

## 正しいキーの場所

ここです。

```
HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework
```

"WOW6432Node" が重要、らしい。
ここに 文字列 "SDKInstallRootv2.0" を作成し、"C:\Program Files (x86)\Microsoft Visual Studio 8\SDK\v2.0" を設定することでLC.exeのエラーはなくなる。
Upload pack　スマホの回転対応する方法

スマホの回転リサイズに対応するには。。。。

```Cakeのroot/app/Plugin/upload_pack/Model/Behavior/UploadBehavior.php

    private function _resize($srcFile, $destFile, $geometry, $quality = 75, $alpha = false) {

        copy($srcFile, $destFile);
        @chmod($destFile, 0777);
        $pathinfo = UploadBehavior::_pathinfo($srcFile);
        $src = null;
        $createHandler = null;
        $outputHandler = null;
        $imgFrame = new Imagick($destFile);

        $orientation = 0;
        if(method_exists($imgFrame, "getImageOrientation") ){
            $orientation = $imgFrame->getImageOrientation();
        }
        if(!$orientation && function_exists("read_exif_data")){
            $exif = read_exif_data($imgFrame);
            $orientation = $exif['Orientation'];
        }

        $rotetation = 0;
        switch((int)$orientation) {
            case 0:
                break;
            case 1:
                break;
            case 2:
                $imgFrame->flopImage();
                break;
            case 3:
                $imgFrame->rotateImage(new ImagickPixel(), 180 );
                break;
            case 4:
                $imgFrame->flipImage();
                break;
            case 5:
                $imgFrame->rotateImage(new ImagickPixel(), 270 );
                $imgFrame->flipImage();
                break;
            case 6:
                $imgFrame->rotateImage(new ImagickPixel(), 90 );
                break;
            case 7:
                $imgFrame->rotateImage(new ImagickPixel(), 90 );
                $imgFrame->flipImage();
                break;
            case 8:
                $imgFrame->rotateImage(new ImagickPixel(), 270 );
                break;
        }
        $imgFrame->writeImages($destFile, TRUE);
以下略```
Jupyterの小技3

Jupyterの小技3
[Jupyterの小技2](http://qiita.com/Tsutomu-KKE@github/items/708ae8fe0cf293f7f986)の続き
# 世界一のものを表示させる

準備として、まず、下記を実行してください。

```py3:jupyter_notebook
import random, re, urllib, IPython.core.getipython
from itertools import takewhile
with urllib.request.urlopen('https://ja.wikipedia.org/wiki/'
    '%E4%B8%96%E7%95%8C%E4%B8%80%E3%81%AE%E4%B8%80%E8%A6%A7') as fp:
    s0 = fp.read().decode('utf8')
s = re.sub('<img.*?/>', '', s0.replace('\u3000', ''))
le = 0
while le != len(s):
    le = len(s)
    s = re.sub(r'<(a|b|i|span|strong|sup)[^>]*>(.*?)</\1>', r'\2', s)
s = re.sub(r'\[[0-9]*]', '', s)
ll = re.findall('<li>(.*?)</li>', s[10000:])
ll = [i for i in takewhile(lambda s: not s.startswith('ギネス世界記録'), ll)
    if '最' in i or '世界一' in i or len(i) > 15]
def G_impl(s, lst=ll):
    print(random.choice(lst))
ip = IPython.core.getipython.get_ipython()
if ip:
    ip.register_magic_function(G_impl, magic_name='G')
```

# 実行してみる

```py3:jupyter_notebook
G
>>>
音節が世界一少ない言語（の一つ）→ ハワイ語 - 35音節。
```

```py3:jupyter_notebook
G
>>>
不規則動詞が世界一多い言語→ フランス語 - 570個。
```

以上
Passive Event Listenersのミニマムpolyfillを書いた。

# Passive Event Listenersとは?

addEventListenerの第三引数に指定できる新しいオプションです。
https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md

こんな感じで使います。

```javascript
window.addEventListener('scroll', function(){...}, {passive: true});
```

簡単に言うと、scrollイベントの発生時にpreventDefault()が呼ばれるかどうかの確認をスキップし、scrollイベントの効率化を図るものです。

存在を知ったのは半年くらい前で、その時は知識として留めていたのですが、そろそろ実務で実験的に使いたいと思い、最低限のpolyfillを作って実装を入れ込みました。入れようと思った理由は、モダンブラウザの対応が進んできたからですね。
http://caniuse.com/#search=passive

※Safariの10以上、iOS Safariの10.2以上でサポートされているのはなかなか大きいと思います。

# どうしてpolyfillが必要？

冒頭のサンプルコードを思い返してください。

```javascript
window.addEventListener('scroll', function(){...}, {passive: true});
```

第三引数にpassive:trueを指定しているのですが、このオプションがサポートされていないブラウザでは空のオブジェクトだと見なされます。
JavaScriptでは空のオブジェクトはtrue扱いになるので、IEやEdge(__2017/02/28時点で最新のEdge__)では以下の記述と同様の判断をされてしまいます。

```javascript
window.addEventListener('scroll', function(){...}, true);
```

第三引数のuseCaptureが意図せずtrueになるのは避けたいため、addEventListener時にブラウザ実装有無を確かめる必要があるわけです。

# 今回書いたpolyfill

```javascript
function isSupportPassive(){
  if (typeof window === 'object' && typeof window.addEventListener === 'function' && Object.defineProperty) {
    let passive = false;
    const options = Object.defineProperty({}, 'passive', {
      get() { passive = true; }
    });
    window.addEventListener('test', null, options);
    return passive;
  }
}

// how to use
window.addEventListener('scroll', function(){...}, isPassiveSupport() ? {passive: true} : false);
```

最低限の実装ですが、これで処理分けを実現できます。

codepenで[デモ](http://codepen.io/rukiadia/pen/zZGNdZ)も作ったので、興味の有る方がお試しを。

# まとめ
- lazyload
- 要素をスクロール途中から追従させる

この辺の処理をやっている箇所には入れてあげるといいかもしれません。
二つ目の「途中から追従」に関しては、position:stickyという解決策もあるので、後々もっと楽に実装できるようになると思います。
Mysqlでのプロシージャ更新でエラー

ALTER PROCEDURE で直そうとすると
```1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near～～～```
と怒られるので、一回
```DROP PROCEDURE `【プロシージャ名】`;```
で消してから
```CREATE PROCEDURE ～～```
Git よく使う命令（随時更新）

# Git よく使う命令（随時更新）
## ラストコミットをUndo/撤回する

```bash
git reset HEAD~
```

## 一つcommitを別のブランチに反映する

```
git cherry-pick <COMMIT_ID>
```

## Commitを無しにする

```
git revert <COMMIT_ID>
# ラストCommitを消すわけではない、ただ新しい　Commitを作って変更を削除した状態に戻す
# めったに使うな
```

## Rebase VS merge

[Rebase VS merge](http://powerful-code.com/blog/2012/11/merge-or-rebase/)
[Rebase vs merge](https://ja.atlassian.com/git/tutorials/merging-vs-rebasing)


## マルチアカウントでpublic keyをそれぞれセットする方法


```config
# .ssh/config
# first
Host github.com-<git repo master account name>
    HostName github.com
    User git
    IdentitiesOnly yes
    IdentityFile ~/.ssh/<first public key>.pem

# second
Host github.com-<git repo master account name>
    HostName github.com
    User git
    IdentitiesOnly yes
    IdentityFile ~/.ssh/<second public key>.pem
    

# ハマるどころ
# remoteのurlがssh/configのHOSTと違ったらむしされるので各repoのurl修正が必要


# 解決策1

git clone git@github.com:<git repo master account name>/<repo>.git
を最初から
git clone git@github.com-<git repo master account name>:<git repo master account name>/<repo>.git
で持ってくる


# 解決策2
# repo/path/.git/config

[remote 'origin']
    url = git@github.com:<git repo master account name>/<repo>.git
    
     ↓　に変更
     
[remote 'origin']
    url = git@github.com-<git repo master account name>:<git repo master account name>/<repo>.git
       
     
```

## error: src refspec mas does not match any.

git initでcommitしてない

```
git add .
git commit -m'???'
git push origin master
```

## git gc (garbage collection)

.git/objectsに情報がたまり過ぎている時に役に立つコマンド
[参考](https://git-scm.com/book/ja/v1/Git%E3%81%AE%E5%86%85%E5%81%B4-%E3%83%A1%E3%82%A4%E3%83%B3%E3%83%86%E3%83%8A%E3%83%B3%E3%82%B9%E3%81%A8%E3%83%87%E3%83%BC%E3%82%BF%E3%83%AA%E3%82%AB%E3%83%90%E3%83%AA)

## git checkout ignore rules

`git status --ignored -s`
or 
`git clean --ndX`

[From](http://qiita.com/suin/items/9d0a4421e795ef04790f)

## What is git flow 

* [A successful Git branching model](https://havelog.ayumusato.com/develop/git/e513-git_branch_model.html)
* [Git branches](http://www.backlog.jp/git-guide/stepup/stepup1_4.html)

## Git tag vs branch

* [Tag VS Branch](https://www.drupal.org/node/1066342)