OmniAICreator/Qiita-1.07M huggingface dataset:
C > 再帰計算 > (計算の打切りによる高速化 > 1.5msecが1.0msecになった) / (再帰をやめる >13.90msecが10.48msecになった) > 処理時間は0.495倍

```
C++ Builder XE4
```

- マイコンと共通実装のC言語での計算処理
- 処理を2倍に高速化したい

以下は計算処理の一部の擬似コード。

```
static int get_someValue(int idx_st1) 
{
   int res;
   double avg;   

   if (idx_st1 <= 2) {
      return 1;
   }

   // ここでavg計算

   if (avg > 0.75) {
      res = 0;
   } else {
      res = 1;
   }
   res = res * get_someValue(idx_st1 - 1);
   return res;
}
```

上記は再帰計算を使っているわけだが、改善できる場所に気づいた。

```
   if (avg > 0.75) {
      res = 0;
```

を以下のようにする。

```
   if (avg > 0.75) {
      // res = 0; // 不要
      // continue; // 間違い
      return 0;
```

0に何をかけても0になる。無駄にそれ以降の再帰をする必要がない。

XE4上での計算時間は1.5msecから1.0msecになった。
マイコン上の実行時間はこの100倍くらい。

再帰計算をやめるという手もありそうだが、自分の能力不足ですぐに実装できない。

### 間違い訂正

@shiracamus さんの指摘のもと、上記を訂正しました。

間違いの指摘に感謝です。

擬似コードは実行をして確認できないので、あまりよくないですね。


### さらなる高速化

@shiracamus さんの再帰なしコードを参考にしました。

http://qiita.com/7of9/items/98f68dfcf3537925b407#comment-a9f1e6e8711f62a1090a

13.90msecの処理が10.48msecになりました。
a-blog cmsで管理ページの削除ボタンを無効化する

a-blog cmsの管理ページ「ブログ」「カテゴリー」「ユーザー」の詳細画面は、青い「保存」ボタンのすぐ横に赤い「削除」ボタンがあります。

このボタンが「押してしまいそうで怖い」と言われたので（一応、onclickで警告は出ますが）、根幹の設定に関わる親ブログのブログ・カテゴリーの削除操作を禁止してみました。

a-blog cmsの重要な機能を封印するので、取り扱いには注意してください。

## 管理ページのhead要素について

管理ページのhead要素テンプレートは */themes/system/include/head/* 以下にあります。これを利用中のテーマの同じ階層に複製・編集すれば良いのですが、バージョンアップ後もコアのCSS・JSに影響を出ないよう編集するのが難しいです。

唯一問題が起きても大丈夫そうなのが、「ブログのキーカラー」のCSSを呼び出している以下のファイルです。

*/themes/system/include/head/blog-color.html*

ここにコードを追記することにします。

## CSSを追加する

以下のとおりa-blog cmsのIFブロックとCSSを追加してください。

```html:blog-color.html
<!-- BEGIN_IF [%{BID}/eq/1] -->
<style>
/* 管理ページ内でサイトの根幹に関わる設定の削除を禁止する */
.acms-admin-form input[name^="ACMS_"][name*="Blog_Delete:"],
.acms-admin-form input[name^="ACMS_"][name*="Category_Delete:"] {
	position: relative;
	background: #ccc none;
	color: #333;
	border-color: #999;
	opacity: .5;
	pointer-events : none;
}
</style>
<!-- END_IF -->
```

まず、IFブロックで**封印するのはルートのブログのみ**としました。
さらにフォームのボタン内のname属性を解析し、「ACMS_」ではじまり「Blog_Delete:」「Category_Delete:」を含むボタンを無効化しています。

pointer-eventsはIE11以降とモダンブラウザで有効になり、CSS側でクリックイベントを禁止します。

## 補足

「JavaScriptでonclick禁止とdisabled付与をすればいいのでは？」と突っ込まれそうなのですが、blog-color.htmlテンプレートはacms.jsの呼び出しよりも前に書かれているため、ACMSオブジェクトを利用することができません。

管理画面にも、head要素末尾に安全に自作テンプレートを追加できるようになればいいなと思います。
Swift3 Kingfisher で画像取得エラーの際にエラー画像を表示する

# [Kingfisher](https://github.com/onevcat/Kingfisher) でエラー画像表示

URL を渡して画像を取得するのに Kingfisher を利用してて大変便利なのだが、取得エラーになった際のやり方がわかりにくかったのでメモ。

## やり方

```
extension Kingfisher where Base: ImageView {
    func setImageWithError(url: URL) {
        setImage(with: url,
            completionHandler: { (_, error, _, _) in
                if let _ = error {
                    self.base.image = #imageLiteral(resourceName: "error")
                }
            }
        )
    }
}
```

`completionHandler` で error があれば `self.base.image` にエラー画像を渡してあげると良い。
`setImage` の引数に `errorImage` とかないかな〜と思ったけどなかった。

上記は Extension にしてて、 `imageView.kf.setImageWithError(url)` で叩けるようにしてある。
正規表現で特定の文字パターンに合致したある部分のみ置換


```rb
hash = {"1"=>"3", "2"=>"4"}

'test1test2foo'.gsub(/(test)(\d+)/){ "#{$1}#{hash[$2]}" }
=> "test3test4foo"
```

`()` で括ると `$` で参照できる。
デザインパターン(GoF:生成に関するパターン)

# GoFの23パターンについて
[RubyでGoFデザインパターンの適応]
(http://www.nulab.co.jp/designPatterns/designPatterns1/designPatterns1-2.html)


[Java言語で学ぶデザインパターン入門 ]
(https://www.amazon.co.jp/dp/4797316462)

[【初心者向け】Rubyによる使えるデザインパターン(GoF)]
(http://qiita.com/moriyaman/items/0ff9e969901b55da5463#_reference-d948951bae1648337d42)

GoF以外(参考)
[デザインパターン紹介]
(http://www.hyuki.com/dp/dpinfo.html)

## 原則
1. 変わるものを変わらないものから分離する
2. インターフェイスに対してプログラミングし、実装に対して行わない
3. 継承より集約
4. 委譲、委譲、委譲
5. 必要になるまで作るな(You Ain’t Gonna Need It./YAGNI)

## 利点

- 機能の追加・更新がしやすくなる
- バグの特定がしやすくなる
- 共通言語でスムーズにコミュニケーション

## 生成に関するパターン
### AbstractFactory パターン
矛盾のないオブジェクトの組み合わせを作る
→子クラスのありえない組み合わせを防ぐ（同じグループのオブジェクトをくくる）

#### 利点
* 関連し合うオブジェクトの集まりを生成することができる
* 整合性が必要となるオブジェクト群を誤りなしに生成できる
http://qiita.com/Momozono/items/27f0a2b1cf46bf02a515

#### コードサンプル

http://morizyun.github.io/blog/ruby-design-pattern-14-abstract-factory/

#### 使いどころ
複数のモデルの関連、操作が同じ場合。

### Builder パターン
柔軟にオブジェクトを生成をする。

複雑なコンポーネントの組み立てを簡単に使えるようにするとともに、内部ロジックを隠蔽する。また、コンポーネントの組み立て方に誤りはないか、不足はないかなどのチェックを設けることもできる。
より簡単に使えるようにするためにmethod_missingメソッドを使ったマジックメソッドを使うテクニックがある。

#### 使いどころ
コンポーネントが複数あり、それらを組み立てる必要がある場合。

#### サンプルコード
http://morizyun.github.io/blog/ruby-design-pattern-11-factory-method/


### FactoryMethod パターン
正しいクラスを選び出す。

使用するクラスの選択をサブクラスに押し付けることで多様な使い方を提供する。これをFactory Methodパターンと言い、クラスを選択するメソッドをファクトリメソッドという。
クラスの種類が増えるとファクトリメソッドも増えるため、ファクトリメソッドにパラメータを持たせることで汎用化する。
クラスの組み合わせに矛盾がないようにあらかじめ組み合わされたファクトリをアブストラクトファクトリという。またこの方法をAbstract Factoryパターンという。


使用するクラス（部品）を時々に応じて選択したい場合。
ActiveRecordがDBConnectionを得るためにデータベース名を指定して使用する部品（この場合はメソッド）の選択を行っている。

#### サンプルパターン
http://morizyun.github.io/blog/ruby-design-pattern-12-builder/

### Prototype パターン
クラスからインスタンスを生成するのではなく、インスタンスから別のインスタンスを作り出す
Rubyではインスタンスに対してextendを行い拡張することができる。
それらのオブジェクトに対してdupメソッドを用いてインスタンスのコピーをすれば、Prototypeパターンが実現可能。

#### サンプル
http://morizyun.github.io/blog/ruby-design-pattern-12-builder/
http://qiita.com/onody/items/2e7de1f6db75d7b4c60b


### Singleton パターン
あるクラスのインスタンスが、プログラム内に1個しか生成されないことを保証する
[シングルトンモジュール]
(https://docs.ruby-lang.org/ja/2.2.0/class/Singleton.html)

#### サンプルコード

```
public class Moon{
    private static Moon moon = new Moon();
    private Moon(){}
    public static Moon getInstance(){
        return moon;
    }
}
```

Singletonパターンではまず、コンストラクタの識別子をprivate（プライベート）にします。private識別子のついたものは、外部クラスからの呼び出しが拒否されるため、新しいインスタンスを作り出すことができなくなるのです。これによって、Moonクラスのインスタンスは

`private static Moon moon = new Moon();`

によって生成されている1つだけに限定されます。
Moonクラスのインスタンスが欲しいときには、

`Moon moon = Moon.getInstance();`

として取得せざるをえないようなつくりになっているのです。


## 構造に関するパターン
http://qiita.com/kayo_h/items/756a2fe1f98e19453f92

## 振る舞いに関するパターン
http://qiita.com/kayo_h/items/52fafd9588a6f4aa5678
そろそろJOINの使い方を考えようか？

#その前に
これはBigQueryの**JOINを否定するものじゃありません。**
BigQueryのJOINはチューニングとか考えないでいいし、本当に最強だと思います。これのおかげで数千万x数億とかでもサクサク動いてくれるし。
ただ、今まではこれでよかったのですが。。。。。。
#みんなTierって知ってるか？
2016年以降に作ったProjectで利用されている方はご存知かと思います。
クエリを投げた後に『お前のクエリはTier2以上でよろしく』って言われたことあると思います。
残念ながら2016年以前に作られたProjectではこれが出ません。
（※ごめん、最近は出てるのかな？）
だから、自分もあんまり意識してなかったのですが最近作ったProjectで出始めたので調査してみました。Tierはどういうことなのか？以下の表に示します。

| Tier | 費用 |
|:-:|:-:|
|Tier1|$5/TB|
|Tier2|$10/TB|
|Tier3|$15/TB|

[こちら](https://cloud.google.com/bigquery/pricing#high-compute)に詳しく記載があります。
と、いうことでTierがあがっていくうちに今までのクエリの料金が2倍、3倍とあがっていきます。Tierがあがる閾値は正直わかりません。ただ、以下のような記載があります。

*『複雑なクエリでは、処理されるバイト数と比べて膨大なコンピューティング リソースが消費されることがあります。通常、そうしたクエリには非常に多くの JOIN 句や CROSS JOIN 句、複雑なユーザー定義関数が含まれます。』*

こういった経緯から、今までJOINしまくってViewを使ったりしていましたが、そろそろクエリがコケはじめてくると思います。考える時期にきたのかもしれません。

**※注：2016/10/01より課金があがるように書いていますが、どうやら2017/01/01からという情報もあったり。今のところ実際に課金はあがっていないように見えます。たぶん。**

#じゃ、どうする？
一番最初に書きましたが、JOINが悪いとは思いません。
**段階的に使っていくのが良いと思います。**
人間っていうのは欲が出ます。案外簡単に結果が出来ると『あれも欲しい、これも欲しい』となるものです。JOINやViewを利用することで、その要望も簡単に答えられます。
しかし、いつまでも2倍、3倍の料金を支払うのもどうかと。ですから、**プロトタイプや初期段階ではJOINやViewで運用し、定着し始めたらJOINやViewの結果をテーブルに落としこんで非正規化してそっちを使う。**
こういう使い方が良いと思います。もうとっくに気づいてる人も多いと思いますけどね（笑）

あとは割り切っちゃう方法もありです。[こちら](https://support.google.com/cloud/contact/bigquery_high_compute_queries_quota_request_form)を申し込むとTierに関係なくいつでも元気にTier3で回すという富豪的使い方も出来ます。ご利用は計画的に。

#ということで。
今まで自分が『JOIN最高！Viewで使いまくれ！』って言ってましたが、そろそろ考えるときがきました。（そもそも、JOINを使うとぶちあてるカラムの課金が二重になっているわけで。）
Tierで課金があがらないうちに、みなさん見直していきましょうね。
あぁ、わしも考えねば。。。。。。。orz
Google Apps Script で riot.js を使って業務アプリを作ったら めちゃくちゃ簡単だった話


# ざっくりとした知識

## Google Apps Script 
- Google がホスティングするサーバーでAppsをJavascriptでかけるシステム。

## Google Apps Script で 業務アプリを作る利点
- Googleの各種サービスに非常に簡単にアクセスできる。

## riot.js とは
react.js ライク な フロントエンドを構築する javascript のライブラリ。
[フロント界隈で一番イケてるのは AngularJS でも React でもなく Riot.js だという話](http://phiary.me/frontend-riot-js-no1/)
を読んでみよう。

## boostrap とは

グリッドシステムがとても使いやすいCSSのフロントエンドのフレームワーク。

# 実践

## Google Apps Script の基本部分を作成

[コード.js]

```
function doGet(){
  var pageTemplate = HtmlService.createTemplateFromFile('index');
  pageTemplate = pageTemplate.evaluate()
  pageTemplate.setSandboxMode(HtmlService.SandboxMode.IFRAME);
  pageTemplate.addMetaTag('viewport', 'width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0');
  return pageTemplate;
}
```

## Google Apps Script の index.html を作成。

Google Apps ScriptはSPA　(Single Page Application) 構成で、
複数ページの編成はできない。

上記のdoGetでGetアクセスがきた時、index.htmlを読み込む設定にしたのでindex.htmlを作成する。

また、すべてのファイルを **.html のファイルで入れる。

### bootstrap を読み込む。

[index.html]

```
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css" rel="stylesheet">
```

cdnで読み込むと簡単
riot.jsも読み込むが、javascriptはコンテンツの一番最後に読み込むのでここでは書かない。
同時にfont-awesomeも読み込むと激しくおすすめなので書いておく。

### ファイルを分割

css, javascriptを分割しておく。
css.html, javascript.htmlを作成して、これを別途読み込むようにしておく。
このincludeはriot.jsのタグを読み込む際にも利用する。

[コード.gs]

```
function include(filename) {
  return HtmlService.createHtmlOutputFromFile(filename)
      .getContent();
}
```

[index.html]

```
<?!= include("css") ?> <!-- これでcss.htmlが読み込まれる-->
```

### バックグラウンドを設定

Google Scriptではこれをやらないと一番最初の表示領域外の部分がレンダリングされないというバグが発生したことがある。
その対処のため、html直下に以下の様なdivを挟む

[index.html]

```
<div id="backgroundbox"> 
</div>
```

[css.html]

```
#backgroundbox{
  height:100%;
  width:100%;
  position:absolute;
  top:0%;
  left:0%;
  margin:0px;
  padding:0px;
  overflow:scroll;
}
```

## riot.jsの読み込み

```
<script src="https://cdnjs.cloudflare.com/ajax/libs/riot/2.6.2/riot+compiler.min.js"></script>
```


## riotのタグファイルを作成して読み込む

riot.jsではオリジナルのタグファイルを作成して読み込ませるが、
Google Apps Scriptでは以下の様に行う。

- まず、tagファイルを **.html の名前で作成し、その中にriotのタグを作成する。

例： start.html

```
<start>
 <div>....</div>
</start>
```

- 次に、このタグファイルを読み込む。

[index.html]

```
<script>
riot.compile('<?= include("start") ?>')
</script>
```

読み込んだ「start.html」をriot.compileにかけることによって、タグが読み込まれる。

あとは 

```
riot.mount('app', 'start')
```

などのようにすると、

```
<app></app>
```

に startタグがマウントされる。

めっちゃ簡単。めっちゃ楽しい！
AndroidでTimerを使わずHandlerだけでお手軽に定期実行してあげる


# UIスレッドの処理をTimerを使わずHandlerだけで簡単定期実行したい

『1秒間隔で定期的に何かの処理を行う』という実装を行う際、パッと思いつくのはTimerとTimerTaskを使った以下のような実装。
ただ、その際TimerTask.run()の中で実行されるコードはTimerのThreadなので、
UIパーツへの操作など、UIスレッドで実行が必要な操作をするにはHandlerを使う必要があります。

## 課題
そうなると、

1. UIスレッドがTimerを実行
1. TimerスレッドがUIスレッドに返す
1. UIスレッドでdoSomething実行

みたいな、ちょっとわかりづらい処理になってしまいます。

コードだとこんな感じが必要になります。
（ネストが深いですが、処理のループがわかりやすいので、そのまま。）

## Before

```java

final Handler handler = new Handler();
TimerTask task = new TimerTask() {
    int count = 0;    
    @Override
    public void run() {
        // Timerのスレッド
        handler.post(new Runnable() {
            @Override
            public void run() {
                // UIスレッド
                if (count > 5) { // 5回実行したら終了
                    cancel();
                }
                doSomething(); // なにかやる
                count++;
            } 
        });
    }
};
Timer t = new Timer();
t.scheduleAtFixedRate(task, 0, 1000);
```

## 対策

TimerとTimerTaskがほとんど何もやってない感じなので、その2クラスを消したいです。
HandlerのpostDelayedを使うと、Timer・TimerTaskを削除して、定期実行することができるようになります。

## After

```java

final Handler handler = new Handler();
final Runnable r = new Runnable() {
    int count = 0;
    @Override
    public void run() {
        // UIスレッド
        count++;
        if (count > 5) { // 5回実行したら終了
            return;
        }
        doSomething(); // 何かやる
        handler.postDelayed(this, 1000);
    }
};
handler.post(r);
```

キャンセルしたいときは
`handler.removeCallbacks(r);`
で、runnableとの関係を切ってあげればOKです。

割と直感的なコードになりました。
この程度であればお手軽にUIスレッドでも定期実行できそうです。

## 参考

[TIMER(TASK) = BAD! DO IT THE ANDROID WAY: USE A HANDLER](http://www.mopri.de/2010/timertask-bad-do-it-the-android-way-use-a-handler/)
おしゃれにシステム管理(1) ajenti

以前、Qiitaへ投稿した[EasySCPで快適サーバ管理生活](http://qiita.com/kouta_hara/items/13164b855e7b96d28b93)と同じ趣旨で、第１回の今回はより洗練されたUIを有するajentiの紹介。

# agenti is 何者
サーバへインストールすることで、Web上からサービスの稼働状態やリソースの状態を確認でき、各種設定を変更する事が出来る。
全体的におしゃれでモチベーション上がる。

# 動作イメージ
実際に動いている状態では、このような画面でサーバの状態が確認できます。
![agenti_image.jpg](https://qiita-image-store.s3.amazonaws.com/0/131348/2cf3f3a3-fff3-3f3f-b1ad-8d144ab4af92.jpeg)

※.VirtualBox上のCentOSへインストールしています。

# インストール
## CentOS 6
```
curl https://raw.githubusercontent.com/ajenti/ajenti/1.x/scripts/install-rhel.sh | sh
```

## CentOS 7
```
curl https://raw.githubusercontent.com/ajenti/ajenti/1.x/scripts/install-rhel7.sh | sh
```

以上。簡単すぎて怖いかもしれませんが、これでおしまいです。
ここまで作業時間5分かからず。

インストール完了後、指示に従ってhttps://\<address\>:8000へアクセスすると、以下の画面が表示されます。

![agenti_installed.jpg](https://qiita-image-store.s3.amazonaws.com/0/131348/f11a7f8e-830d-7a67-faeb-dc0f23652e71.jpeg)

デフォルトのID/PASSである[root/admin]でログインすると、以下のダッシュボードが表示され、サーバの状態を大まかに確認する事ができます。
![agenti_dashboard.jpg](https://qiita-image-store.s3.amazonaws.com/0/131348/873c742a-490c-a82d-e3f0-cec3e76d027c.jpeg)

設定から言語を日本語に設定すれば日本語化も問題なく完了。
![agenti_jp_service.jpg](https://qiita-image-store.s3.amazonaws.com/0/131348/8939fc87-cef0-e8f9-b6c3-d9360e6375d2.jpeg)

左のメニューからCron,Apache,DB,FireWall,ユーザ等、幅広く設定が可能です。
正直、ここまで出来るとは思ってなかったので、ワクワクします。
まずは個人的な環境で使ってみたいと思います。
python3 urlretrieve

urlretrieveは、ネット上からファイルをダウンロードし保存するのに使う。しかし、2系と3系とで違いがありググラビリティが低い。なので、書き記す。

python3では

```py3
import urllib.request
urllib.request.urlretrieve(目的のURL, 保存先のファイル名)
```

とする。以上。
EC2の時刻を特定時刻に変更する


## はじめに
EC2の時刻を一時的に特定時刻に変更する例です。

## 変更する手順
### 1. ntpdを停止する
時刻は、現在時刻のデータを配信しているサーバ(NTPサーバー)と時刻合わせして設定しています。ntpdというデーモンで実行されているため、時刻合わせされないようにまずntpdを停止します。

```
$ sudo service ntpd stop
Shutting down ntpd:

$ sudo service ntpd status
ntpd is stopped
```

### 2. dateコマンドで変更する
ソフトウェアクロックをdateコマンドで変更します。


```
$ date
2016年 10月 11日 火曜日 16:31:16 JST

$ sudo date -s "10/05 13:00 2016"
2016年 10月  5日 水曜日 13:00:00 JST

$ date
2016年 10月  5日 水曜日 13:00:02 JST
```

## 元に戻す手順
ntpdを起動させれば元に戻ります。

```
$ sudo service ntpd start
$ date
```

## 参考
* [dateコマンドでLinuxサーバの時刻変更](http://qiita.com/na0AaooQ/items/af6b853faf32c58c21d3)
特定のマシンだけネットに繋がらなくて悩みまくった件


## 症状
* 他のマシンはネットに繋がる。
* LAN ケーブルを別のマシンに繋いでも、そのマシンではネットに繋がる。
* IP で PING をすると、 LAN 内外問わず疎通を確認できる。
* LAN 内の他のマシンから PING しても応答する。
* nslookup がたまにだけ DNS を引いてくるが、ほとんどの場合で DNS サーバに到達できないというエラーがでる。
* nslookup の検索先を 8.8.8.8 (google) にしても DNS サーバに到達できないというエラーが出る。
* ファイアウォールを全部止めても同じ。
* USB 接続の LAN アダプタ経由だと nslookup も引ける (!)。

## 結論から書くと
マザーボードに内蔵されている NIC がおかしかったようだ。

## 道程
原因が判明するまでは結構長かった。
まさか買ったばかりのマザーボードが死んでるとは思わなかったので、散々トライアンドエラーして USB の LAN アダプタを刺したのは一番最後だった。
「ネットに繋がらない」というのは、 URL ベースでアクセスするブラウザやメールソフトなどで、名前解決できていないからそういう症状になっていたというだけで、 IP での PING 自体は通るので厳密にはネット自体はつながっていた。

### 外部に PING は通るの？
通る。

### LAN 内部の別のマシンへの PING は通るの？
通る。

### LAN 内部の別マシンから PING は通るの？
通る。

### ルータは生きているか？
他のマシンから `ipconfig /flushdns` をやった後に `nslookup` で適当なドメインを引けるか試したところ、ちゃんと引けた。

### ファイアウォールが悪さしてないか？
ファイアウォールを全て停止してみたが、症状は変わらず。

### アンチウィルスやフィルタは？
停止してみたが、症状は変わらず

### Local IP を固定してみては？
症状に変化なし。
DHCP からレンタルしても同じ。

### IPv6 を停止させてみてはどうか？
もともと停止していた。
有効にしてみても症状に変化なし。

### デバイスドライバの NIC の状態を確認して見る
特にエラーは出ていない。

### デバイスドライバから NIC を一度削除して再認識させてみては？
削除後再起動し自動認識させてみたが、症状は変わらず。

### 別の NIC を使ってみたら？
USB の奴の刺してみたら動いた！

## 一言
疲れた。
Cakephp3でFacebookSDKをつかったログインを行う


`session_start()`を使わずに、FacebookSDKを使ったログインを処理します。

# 環境
- PHP 7.0.9
- CakePHP 3.3.2
- facebook/php-sdk-v4 5.2.0

# 問題
CakePHPでFacebook SDK for PHPのドキュメント通りに実装すると、callback処理の時に`Cross-site request forgery validation failed. Required param “state” missing`というエラーが発生してログイン処理できません。

これは、loginUrl生成時に`state`という値がセッションに設定されていなかったために発生していました。

これを解決するために調べてみると、ほとんどの場合は`session_start()`を実行してからloginUrl生成→callback関数とすればイケるよ！と書いてありましたが、これだと都度`session_start()`しないといけません。何だかなぁと思っていたらクラスを作っても対応できるとのことなので、その時の方法をメモしておきます。

# 対応方法
`new Facebook`をする時に、`persistent_data_handler`を指定することで、`session_start()`をすることなくCakePHPのSessionを使用しながらFacebookログインできました。

例えば、以下のような`src/Handler/MyFbPersistentDataHandler`を実装しました。

## 実装例
```php:MyFbPersistentDataHandler.php
<?php

namespace App\Handler;

use Facebook\PersistentData\PersistentDataInterface;


class MyFbPersistentDataHandler implements PersistentDataInterface
{
    private $_session = null;

    public function __construct($session)
    {
        $this->_session = $session;
    }


    public function get($key)
    {
        return $this->_session->read($key);
    }

    public function set($key, $value)
    {
        $this->_session->write($key, $value);
    }
}
```


## 使い方
あとはドキュメント通りにログイン画面の生成と、callback関数の処理を記述します。

```php:UsersController.php

use App\Handler\MyFbPersistentDataHandler;

...


public function createFbUrl(){
    ...
    
    $fb = new Facebook([
        'app_id' => FACEBOOK_API_ID,
        'app_secret' => FACEBOOK_APP_SECRET,
        'default_graph_version' => DEFAULT_GRAPH_VERSION,
        'persistent_data_handler' => new MyFbPersistentDataHandler($this->request->session())
    ]);
    $helper = $fb->getRedirectLoginHelper();
    
    ...
}


public function fbLoginCallback(){
    ...
    
    $fb = new Facebook([
        'app_id' => FACEBOOK_API_ID,
        'app_secret' => FACEBOOK_APP_SECRET,
        'default_graph_version' => DEFAULT_GRAPH_VERSION,
        'persistent_data_handler' => new MyFbPersistentDataHandler($this->request->session())
    ]);
    $helper = $fb->getRedirectLoginHelper();
    
    ...
}
```

これでFacebookログインできました。

# 参考
- [FuelPHPでFacebook SDK for PHP v5を使う](http://case-k.com/blog/2015/08/04/fuelphp%E3%81%A7facebook-sdk-for-php-v5%E3%82%92%E4%BD%BF%E3%81%86/) 
- [The persistent data handler interface for the Facebook SDK for PHP](https://developers.facebook.com/docs/php/PersistentDataInterface/5.0.0)
- [Facebookログインの例](https://developers.facebook.com/docs/php/howto/example_facebook_login)
- [グラフAPIを使ったユーザープロフィールの取得](https://developers.facebook.com/docs/php/howto/example_retrieve_user_profile)
CakePHP3でCASE WHEN EXISTSを作る


#環境
- PHP 7.0.9
- CakePHP 3.3.4
- MySQL 5.6.30

#問題
コードと手間を減らすために、selectのCase文でEXISTSを使うSQLを構築する必要がありました。
公式にはCase文とEXISTSの書き方は記載されてますが、それらを組み合わせた書き方は記載されておらず、四苦八苦したのでメモを残しておきます。

## Case文の作り方
[公式のCase文](http://book.cakephp.org/3.0/ja/orm/query-builder.html#case)にもあるように、例えば`SELECT CASE WHEN status is null THEN 'red' ELSE 'green' END AS 'result' FROM cities;`というSQLを作りたい場合は、

```php
# SELECT CASE WHEN status is null THEN 'red' ELSE 'green' END AS 'result';
$query = $this->Countries->find()
    ->select(['result' => function($q){
      return $q->newExpr()->addCase(
        [$q->newExpr)->add(['status is'=>null])],
        ['red','green'],
        ['string']
      )
    }]);
```
のように書けます。


## EXISTSの作り方
[公式のEXISTS](http://book.cakephp.org/3.0/ja/orm/query-builder.html#advanced-query-conditions)では、一度サブクエリを作成してからwhere句で構築を行っています。

```php
# SELECT id FROM Cities WHERE Countries.id = Cities.country_id AND Cities.population > 100; 
$subquery = $this->Cities->find()
    ->select(['id'])
    ->where(function($exp,$q){
      return $exp->equalFields('Countries.id','Cities.country_id');
    })
    ->addWhere(['Cities.population >'=> 1000]);
    
#where句でsubqueryを使う
$query = $this->Countries->find()
  ->where(fucntion($exp, $q) use ($subquery){
    return $exp->exists($subquery);
  });

#WHERE EXISTS(SELECT id FROM Cities WHERE Countries.id = Cities.country_id AND Cities->population > 100)
```

## CASE WHEN EXISTSの作り方
公式の例ではwhere句でexistsを使っていますが、今回はselect句で使いたい、かつCase文も使う必要がります。
ネストが深くなると混乱の元なので、サブクエリは別で定義することにしました。サブクエリは上記と同じものを使用して、

```
# SELECT id FROM Cities WHERE Countries.id = Cities.country_id AND Cities->population > 100; 
$subquery = $this->Cities->find()
    ->select(['id'])
    ->where(function($exp,$q){
      return $exp->equalFields(''Countries.id',Cities.country_id');
    })
    ->addWhere(['Cities.population >'=> 1000]);

#select句でCASEとEXISTSを使う
$query = $this->Countries->find()
  ->select(function($q) use ($subquery){
    return [
      'id',
      'name',
      'result' => $q->newExpr()->addCase(
          [$q->newExpr()->add([$q->newExpr()->exists($subquery)])],
          ['red', 'blue'],
          ['string']
        )
      ];
  });
```

このクエリビルダーで作られるSQLは、こんな風になるはずです。

```sql
SELECT
 id,
 name,
 CASE WHEN EXISTS(
    SELECT id FROM Cities WHERE Countries.id=Cities.country_id AND Cities.population > 1000
    ) THEN 'red'
  ELSE 'green' END AS result
FROM Countries;
```


#もやもやする点
上記の例ではCase文の値の型を`string`に指定していますが、真偽値(true|false)が欲しい場合`boolean`型を指定すると、なぜか文字列(例えば`"1"`)が返ってきてしまいます。`integer`でも文字列となってしまうので、うまく`Cake\Database\Type\BoolType`として変換されてなさそうです。

#参考文献
- [クエリビルダ - CakePHP3公式ドキュメント](http://book.cakephp.org/3.0/ja/orm/query-builder.html)
[Linux] Nmapでポートスキャンを行う(ポートの解放状況の確認)

ポートが解放されているかの確認を行う時に使用する。個人的メモ。

```bash:ポートを指定して実行
# 単一ポートの場合
$ nmap -Pn -sT -p <port> <ip address>

# 複数ポートの場合(カンマ区切り)
$ nmap -Pn -sT -p <port1>,<port2> <ip address>
```

nmapに関しては以下の記事が詳しいです。
[nmapコマンドで覚えておきたい使い方11個 | 俺的備忘録 〜なんかいろいろ〜](https://orebibou.com/2015/06/nmap%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%A7%E8%A6%9A%E3%81%88%E3%81%A6%E3%81%8A%E3%81%8D%E3%81%9F%E3%81%84%E4%BD%BF%E3%81%84%E6%96%B911%E5%80%8B/)

# 参考
[Linuxコマンド集 - 【nmap】ポートスキャンを実施する：ITpro](http://itpro.nikkeibp.co.jp/atcl/column/14/230520/072800001/)
[nmapコマンドで覚えておきたい使い方11個 | 俺的備忘録 〜なんかいろいろ〜](https://orebibou.com/2015/06/nmap%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%A7%E8%A6%9A%E3%81%88%E3%81%A6%E3%81%8A%E3%81%8D%E3%81%9F%E3%81%84%E4%BD%BF%E3%81%84%E6%96%B911%E5%80%8B/)
[清く、正しい、nmapの使い方](http://www.yk.rim.or.jp/~shikap/security/use_nmap.html)
[nmap デフォルトの対象ポート＆その他のオプション - Qiita](http://qiita.com/watarin/items/736b53b52675ef041e1c)

# 関連
[sshの接続前に確認を行う(port番号を指定しての特定IPの疎通確認) - Qiita](http://qiita.com/koara-local/items/6df5f73126810d3d9589)
[Linuxのtracerouteコマンドで覚えておきたい使い方8個 | 俺的備忘録 〜なんかいろいろ〜](https://orebibou.com/2015/05/linux%E3%81%AEtraceroute%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%A7%E8%A6%9A%E3%81%88%E3%81%A6%E3%81%8A%E3%81%8D%E3%81%9F%E3%81%84%E4%BD%BF%E3%81%84%E6%96%B98%E5%80%8B/)

## Windowsでの確認方法
### PowerShell
[telnetコマンドのないWindowsでのTCPポート確認 - Qiita](http://qiita.com/_norin_/items/8f534bd0531a960af5e9)
メソッドの引数にメソッドの返り値を渡す場合、blockの渡し方に注意する

たとえば、 こんなメソッドがあるとします。

```ruby
def foo(arg)
  puts "#{arg}, #{block_given?}"
end

def bar
  if block_given?
    yield
  else
    'no block'
  end
end
```

下記のようにブロックの渡し方で`foo`メソッド側のblockとなったり`bar`メソッド側になったりします。想定した渡し方になってない場合があるので注意です。

```ruby
foo bar do
  'block'
end
# => no block, true

foo bar {
  'block'
}
# => block, false

foo(bar do
  'block'
end)
# => block, false
```
Xcode8でRealmSwift全然動かなくてワロえない

#このコードで動きます(なぜかは知らない)




```

# Uncomment this line to define a global platform for your project
# platform :ios, ’10.0’

target 'countTap' do
  # Comment this line if you're not using Swift and don't want to use dynamic frameworks
  use_frameworks!

  # Pods for countTap

  target 'countTapTests' do
    inherit! :search_paths
    # Pods for testing
  end

  target 'countTapUITests' do
    inherit! :search_paths
    # Pods for testing
  end
  
  
pod 'RealmSwift'

end



post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['SWIFT_VERSION'] = '2.3' # or '3.0'
    end
  end
end

```

#ここが大切（なぜかは知らない)

```

post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['SWIFT_VERSION'] = '2.3' # or '3.0'
    end
  end
end
```
Core Graphicsで文字列を中央寄せにする

<img width="46" alt="スクリーンショット_2016_10_11_16_19.png" src="https://qiita-image-store.s3.amazonaws.com/0/12939/74dd5c8f-5089-8696-48da-68207e89b4d9.png">


文字列のスタイルを変更するには、

1. デフォルトのスタイルのコピーを取って、
2. そのプロパティを変更し、
3. 適用する。

```swift
title = "title"

//ダメ let style = NSMutableParagraphStyle.defaultParagraphStyle()

let textStyle = NSParagraphStyle.defaultParagraphStyle().mutableCopy() as! NSMutableParagraphStyle
    textStyle.alignment = NSTextAlignment.Center
    let textFontAttributes = [
        NSParagraphStyleAttributeName: textStyle
    ]
    
let textRect = CGRectMake(0, 0, 20, 10)
title.drawInRect(textRect, withAttributes: textFontAttributes)
```

---
ブログやっています：http://weed.nagoya
jQueryで動的に行を追加し、POSTする

フロントだけではなく、管理画面においても動的にフォームの行を追加して処理をする事が増えてきたように思います。
行の追加はjQueryを使用しています。
簡単に記述していますので、実際に使用する場合はXSS対策を行って下さい。

## HTML

```html
<form method="post">
<table>
  <thead>
    <tr>
      <th>果物</th>
      <th>数量</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><input type="text" name="fluit[0]" value="りんご"></td>
      <td><input type="number" name="quantity[0]" value="3"></td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <td colspan="2"><button id="add_row" type="button">行追加</button></td>
    </tr>
  </tfoot>
</table>
<input type="hidden" name="row_length" value="1">
<input type="submit" name="send" value="送信">
</form>
```

## jQuery

tbodyの最終行にテンプレートを追加、その後配列処理が出来るようにname属性を変更。
あとphpで処理を楽にするために行数を書き換えます。

```js
$(document).on('click', '#add_row', function(e) {
  var tr_row = '' +
  '<tr>' +
    '<td><input type="text" name="fluit" value=""></td>' +
    '<td><input type="number" name="quantity" value=""></td>' +
  '</tr>';// 挿入する行のテンプレート
  var row_cnt = $("table tbody").children().length;// 現在のDOMで表示されているtrの数
  $(':hidden[name="row_length"]').val(parseInt(row_cnt) + 1);// input type=hiddenに格納されている行数を変更
  $(tr_row).appendTo($('table > tbody'));// tbody末尾にテンプレートを挿入
  $('table > tbody > tr:last > td > input').each(function() {
    var base_name = $(this).attr('name');
    $(this).attr('name', base_name + '[' + row_cnt + ']');
  });// input name部分を変更
});
```

## 行追加テスト

[行追加]ボタンをクリックするとDOMが以下のように変更されます。

```html
<form method="post">
<table>
  <thead>
    <tr>
      <th>果物</th>
      <th>数量</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><input type="text" name="fluit[0]" value="りんご"></td>
      <td><input type="number" name="quantity[0]" value="3"></td>
    </tr>
    <tr>
      <td><input type="text" name="fluit[1]" value=""></td>
      <td><input type="number" name="quantity[1]" value=""></td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <td colspan="2"><button id="add_row" type="button">行追加</button></td>
    </tr>
  </tfoot>
</table>
<input type="hidden" name="row_length" value="2">
<input type="submit" name="send" value="　送信　">
</form>
```

## POST結果

var_dump($_POST);

```html
array(4)
{
  ["fluit"]=> array(2)
    {
      [0]=> string(9) "りんご"
      [1]=> string(0) ""
    }
  ["quantity"]=> array(2)
    {
      [0]=> string(1) "3"
      [1]=> string(0) ""
    }
  ["row_length"]=> string(1) "2"
  ["send"]=> string(12) "送信"
}
```

## php整形

このままだと微妙に処理しにくいので。

```php
if(isset($_POST["send"]))
{
  $count = $_POST['row_length'];
  for($i=0; $i<$count; $i++)
  {
    $result[$i]['fluit'] = $_POST['fluit'][$i];
    $result[$i]['quantity'] = $_POST['quantity'][$i];
  }
  echo print_r($result, true);
}
```

```html
Array
(
  [0] => Array
    (
      [fluit] => りんご
      [quantity] => 3
    )
  [1] => Array
    (
      [fluit] =>
      [quantity] =>
    )
) 
```

[デモはこちら](http://www.artib.net/demo/demo4/)
白黒画像からAndroid通知用アイコンic_notification.pngを作る

ImageMagick を使って白黒のグレースケール画像から、白の部分のみをイキにして、黒の部分を透過にして、透過PNGを作成して、Android アプリの通知用アイコン `ic_notification.png` をコマンドラインで生成する手順。

```sh
# 白黒グレースケール画像から、黒の部分を透過に抜く。白の部分はイキ
convert black.png -background white -channel a -combine white.png

# dpi 別のフォルダ
mkdir mipmap-mdpi mipmap-hdpi mipmap-xhdpi mipmap-xxhdpi mipmap-xxxhdpi

# xxxhdpi: 96x96
convert white.png -resize 96x96 mipmap-xxxhdpi/ic_notification.png

# xxhdpi: 72x72
convert white.png -resize 72x72 mipmap-xxhdpi/ic_notification.png

# xhdpi: 48x48
convert white.png -resize 48x48 mipmap-xhdpi/ic_notification.png

# hdpi: 36x36
convert white.png -resize 36x36 mipmap-hdpi/ic_notification.png

# mdpi: 24x24
convert white.png -resize 24x24 mipmap-mdpi/ic_notification.png
```

関連記事：[iPhone用アプリアイコン画像からAndroid用画像をImageMagickで一発生成する](http://qiita.com/kawanet/items/d121eb61588cfba0ff74)
同一ホスト内Sphinxドキュメント間のリンク切れをJenkinsでチェックする

複数のSphinxドキュメントを作っていて、sphinx.ext.extlinksを使って他のSphinxドキュメントにリンクしていたりすると、
開発時に割とリンク切れが起きる。
そのリンク切れをJenkinsでチェックする方法。ただし、サーバ内のリンク切れのみ。

ビルドを以下のように設定している。
Windowsバッチでwgetしているのは、JenkinsがWindows Serverにあるからで、
判定をGroovyにしているのは、Jenkinsでラクにスクリプトを動かせるから。
当然、これを1つのシェルスクリプトでやっても良いと思う。

## Windowsバッチファイル

```bat
C:\z\wget\bin\wget.exe --spider --recursive --no-directories --no-verbose --no-parent http://hoge.com/docs/ > wget.log 2>&1
type wget.log
```

## Execute Groovy script
```groovy
new File("${System.getenv('WORKSPACE')}/wget.log").eachLine {
  if ((it =~ /^Found.*$/).find()) {
    def errors = it.replace("Found ", "").replace(" broken links.", "")
    if (errors == "no") {
      System.exit(0)
    } else {
      System.exit(1)
    }
  }
}
```

安易な判定方法をしてるし、ビルドのコンソール出力を見ないと切れてる箇所は分からないけど、最低限リンク切れがあればビルド失敗、なければ成功が実現できる。
これを1時間に1回ぐらいで実行するようにしておくと、意外と役に立った。
Built-in Shrinkerを使ってデバッグビルドで64k問題を回避する


### ※ Built-in Shrinkerは、Android Gradle Plugin 3.3からR8に置き換わりました。

Androidには64k問題という開発者にとって非常につらい問題があります。
こやつはそれ自体よりも、multidex化によるビルド時間の増加によって引き起こされる開発イテレーションの低下のほうが問題になります。

# proguardによる回避

proguardのshrink工程において、参照していないメソッドが削除され、これによって64k問題の回避が可能になります。

# proguardの問題

proguardに難読化処理も含まれているため、debugビルドでかけるとデバッグ効率が悪くなります。
そのため、通常はreleaseビルドでない限りproguardをかけないのが一般的かと思います。

しかし、proguardをかけないということは前述のshrinkが行われないため、releaseビルドでは64kに達していないのにdebugビルドでは64kを超えてしまってい、やむなくmultidex化するということが起こります。

また、proguardはInstant Runに対応していないため、Instant Runを有効にしている場合も問題になります。

# Built-in Shrinker

これらの問題を解決するために`gradle-plugin 2.0.0`で新たに、`Built-in Shrinker`という仕組みが追加されました。
これは、難読化はせず、shrink処理のみを行う**debugビルドにおける**proguardの代替ツールです。

使い方は`build.gradle`の`debug`の`buildType`に以下の設定をするだけです。

```build.gradle
android {
    …

    buildTypes {
        debug {
            debuggable true
            minifyEnabled true
            useProguard false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
```

`minifyEnabled`を`true`、`useProguard`を`false`にして、releaseビルド同様に`proguardFiles`を設定します。

この設定により、debugビルドでもshrinkが有効になり、debugビルドだけ64kに達するということを回避できます。
体感のビルド時間は、「proguardなしよりも遅く、proguardより早い」程度になります。

なお、Built-in Shrinkerは**multidexをサポートしていない**のでmultidexの設定は全て消す必要があります。
まあ状態としては排他になるはずなので、既存のmultidex設定を消す手間以外には問題にはなりません。

# その他

## 警告あるぞエラーが出る

~~(gradle plugin 2.2.1で出なくなった？)~~ 起きました

```
Error:Execution failed for task ':app:transformClassesWithNewClassShrinkerForDebug'.
> Warnings found during shrinking, please use -dontwarn or -ignorewarnings to suppress them.
```

ビルドすると、こんなエラーが出ることがあります。

以下の定義のファイルを用意して、

```shrinker-rules.pro
-ignorewarnings
```

`proguardFiles` の定義に追加すればOKです。

```build.gradle
android {
    …

    debug {
        debuggable true
        minifyEnabled true
        useProguard false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro', 'shrinker-rules.pro' // ← 追加
    }
}
```

## Analyze APK

Android Studio 2.2から、**Analyze APK**という機能が追加されました。
これを使うすることで既存のAPKの解析が行えるのですが、その中にはdexファイル内のメソッド数をカウントしてくれる機能があります。

こちらは
`Build - Analyze APK`
から利用できるので、こちらも活用してみてください。

[KeepSafe/dexcount-gradle-plugin](https://github.com/KeepSafe/dexcount-gradle-plugin)というプラグインを利用していましたが、メソッド数を知るためにわざわざプラグインを入れなくてもよくなったは良いですね。

## dexguard

`dexguard 7.2.07` 時点では、どうやらdexguardプラグインは`minifyEnabled`のみで有効化し、`useProguard`の値を見てくれないみたいで、shrinkerを有効にする方法がわかりませんでした。

## そもそもメソッド数を増やさないためには

Jake神の教えに従おう
[Exploring Java's Hidden Costs](https://realm.io/news/360andev-jake-wharton-java-hidden-costs-android/)

Android Studioで、デフォルトで無効になっているLintがあるので有効にしてこ？などの話があります。

# 参考

[Built-in shrinker](http://tools.android.com/tech-docs/new-build-system/built-in-shrinker)
pyenvまとめ

__※本記事を読む前に[pyenvが必要かどうかフローチャート - Qiita](http://qiita.com/shibukawa/items/0daab479a2fd2cb8a0e7)を参照することをおすすめします。__

pyenvについてまとめたいと思います。

#pyenvとは
Linuxにおいて、Pythonの実行環境を管理するツールです(例えば、2.x系と3.x系を使い分ける、といった用途が想定されるかと思います)。

#インストール
##pyenv
1. [anyenvまとめ - Qiita](http://qiita.com/SUZUKI_Masaya/items/51366be1510f7fde7cdf)に従って、anyenvをインストールします。
2. Ubuntuの場合、以下のコマンドを実行し、Pythonの実行環境をインストールするのに必要なパッケージや実行環境のダウンロードを高速化させるパッケージをインストールします。

```bash
$ sudo apt install curl llvm sqlite3 libssl-dev libbz2-dev libreadline-dev libsqlite3-dev libncurses5-dev libncursesw5-dev python-tk python3-tk tk-dev aria2
```

2. 以下のコマンドを実行し、pyenvをインストールします。

```bash
$ anyenv install pyenv
```

1. 以下のコマンドを実行し、pyenvのコマンドを有効にします。

```bash
$ source ~/.bashrc
```

##pyenv-virtualenv
ある実行環境を元に複数の実行環境を生成したい場合に使うプラグインです。
1. 以下のコマンドを実行し、pyenv-virtualenvをインストールします。

```bash
$ git clone https://github.com/yyuu/pyenv-virtualenv $(pyenv root)/plugins/pyenv-virtualenv
```

##pyenv-ccache
ccashe (詳しくは[ccacheでC/C++のコンパイルを高速化する - Qiita](http://qiita.com/bgpat/items/f1990846ac9166710ff5)を参照) を使うことで、CPython (公式によるPython実装) のインストールの高速化を図るプラグインです。

2. ccasheをインストールします (Ubuntuの場合、以下のコマンドを実行します)。

```bash
$ sudo apt install ccache
```

1. 以下のコマンドを実行し、pyenv-ccacheをインストールします。

```bash
$ git clone https://github.com/yyuu/pyenv-ccache $(pyenv root)/plugins/pyenv-ccache
```

##pyenv-pip-update
pipやcondaで管理されているライブラリのアップデートを簡単に行えるようにするプラグインです。

1. 以下のコマンドを実行し、pyenv-pip-updateをインストールします。

```bash
$ git clone https://github.com/massongit/pyenv-pip-update $(pyenv root)/plugins/pyenv-pip-update
```

#コマンド

|コマンド|内容|
|:-:|:-:|
|`$ pyenv`|ヘルプ|
|`$ pyenv root`|pyenvのインストール先の絶対パス|
|`$ pyenv shell`|シェルにおける実行環境|
|`$ pyenv shell 実行環境名`|シェルにおける実行環境の設定|
|`$ pyenv global`|デフォルトの実行環境|
|`$ pyenv global 実行環境名`|デフォルトの実行環境の設定|
|`$ pyenv install 実行環境名`|指定された実行環境のインストール|
|`$ pyenv uninstall 実行環境名`|指定された実行環境のアンインストール|
|`$ pyenv pip-update`|pipやcondaで管理されているライブラリのアップデート (pyenv-pip-update)<br>※condaを使用する実行環境 (anacondaやminiconda) については、condaで管理されているライブラリのみアップデート|
|`$ pyenv virtualenv 実行環境(A)名 実行環境(B)名`|`pyenv install`でインストールされた実行環境(A)を元に実行環境(B)を生成する (pyenv-virtualenv)|
|`$ pyenv versions`|インストールされている実行環境一覧|
※anyenvにanyenv-updateをインストールしてある場合、pyenv本体やプラグインのアップデートはanyenvのアップデートの一部として行うことができる
__※pipを行うときにroot権限で実行しないようにする__

#参考文献
* [Common build problems · yyuu/pyenv Wiki](https://github.com/yyuu/pyenv/wiki/Common-build-problems)
* [bashスクリプトでの.bashrc変更内容を起動したシェルへ反映する – bgbgbg](http://blog.bgbgbg.net/archives/2366)
* [Shimの意味 - Qiita](http://qiita.com/ironsand/items/4f0342f5914a9ae99b0e)
* [pyenvを使ってPython環境を構築 - 計算物理屋の研究備忘録](http://keisanbutsuriya.hateblo.jp/entry/2015/03/21/183323)
* [Macでpyenv+virtualenv - Qiita](http://qiita.com/maosanhioro/items/47a52f96fefba7126f9b#virtualenv)
* [pyenv-ccache/README.md at master · yyuu/pyenv-ccache](https://github.com/yyuu/pyenv-ccache/blob/master/README.md)
anyenvまとめ

anyenvについてまとめたいと思います。

#anyenvとは
Linuxにおいて、複数のバージョンの実行環境を管理するツールとして、\*\*env(pyenv, rbenv......etc)があります。
この\*\*envを管理するツールがanyenvです。

#インストール
##anyenv
1. gitをインストールします(Ubuntuの場合は以下のコマンドを実行します)。

```bash
$ sudo apt install git
```

1. 次のコマンドを実行し、anyenvをインストールします。

```bash
$ git clone https://github.com/riywo/anyenv ~/.anyenv
```
1. `~/.bashrc`の末尾に以下を追記します。

```bash
if [ -d $HOME/.anyenv ]
then
    export PATH="$HOME/.anyenv/bin:$PATH"
    eval "$(anyenv init -)"
fi
```

1. 以下のコマンドを実行し、`~/.bashrc`の変更をシェルに適用します。

```bash
$ source ~/.bashrc
```
##anyenv-update
anyenvやそこで管理している\*\*envのアップデートを簡単に行えるようにするプラグインです。

1. 以下のコマンドを実行し、プラグイン用のディレクトリを作成します。

```bash
$ mkdir -p $(anyenv root)/plugins
```

1. 以下のコマンドを実行し、anyenv-updateをインストールします。

```bash
$ git clone https://github.com/znz/anyenv-update.git $(anyenv root)/plugins/anyenv-update
```

#コマンド

|コマンド|内容|
|:-:|:-:|
|`$ anyenv`|ヘルプ|
|`$ anyenv init`|初期化|
|`$ anyenv envs`|インストールされている\*\*env一覧|
|`$ anyenv root`|anyenvのインストール先の絶対パス|
|`$ anyenv install -l`|インストールできる\*\*envの一覧|
|`$ anyenv install **env`|指定された\*\*env のインストール|
|`$ anyenv version`|\*\*envごとのシェルにおける実行環境|
|`$ anyenv versions`|\*\*envごとのインストールされている実行環境一覧|
|`$ anyenv global`|\*\*envごとのデフォルトの実行環境|
|`$ anyenv update`|アップデート (anyenv-update)<br>※**envやそのプラグイン含む|

#関連記事
* [pyenvまとめ - Qiita](http://qiita.com/SUZUKI_Masaya/items/7ba3fef9eb7c9603762a)

#参考文献
* [anyenvで開発環境を整える - Qiita](http://qiita.com/luckypool/items/f1e756e9d3e9786ad9ea)
* [Mac に anyenv でサクッとマルチ開発環境構築 - Qiita](http://qiita.com/yutackall/items/6c48cf56317d8501f6df)
App store へアップロードで Invalid Binary

アップロードは成功（Success）で後に、iTunes connectでステータスが
... has changed to Invalid Binary とになった場合の解決について。

問題の詳細はメールで届くようで、以下のようなメッセージが届きます。

```
Dear developer,

We have discovered one or more issues with your recent delivery for "My app name". To process your delivery, the following issues must be corrected:

Invalid Icon - The watch application 'myapp.app/Watch/watch.app' contains an icon file 'myapp.app/Watch/watch.app/AppIcon98x98@2x.png' with an alpha channel. Icons should not have an alpha channel.

Once these issues have been corrected, you can then redeliver the corrected binary.

Regards,

The App Store team
```
このメッセージでは、**アイコン画像にアルファチャンネルが含まれていてはいけない**というものでした。

その他に私が体験したエラーは、

**ユーザーデータへアクセスする目的を記述することが必要**
```This app attempts to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSPhotoLibraryUsageDescription key with a string value explaining to the user how the app uses this data.
```
これは、BaseSDK iOS10から必要になった、カメラやマイク、フォトライブラリなどにアクセスするアプリは、使用目的をinfo.plistに記述しなくてはならないといものに関連したものです。

私は、keyの設定はしていたのですが、value を後で書こうとおもっていてそのまま送信してしまった際にエラーとなりました。

関連URL:
[[iOS 10] 各種ユーザーデータへアクセスする目的を記述することが必須になるようです](http://dev.classmethod.jp/smartphone/iphone/ios10-privacy-data-purpose-description/)
複雑な型宣言とデータの扱い


クラスのメンバーにオブジェクトを持つ場合、必要以上にクラス宣言をするのも面倒なため、any型などを指定しがちですが、型指定を行うこともできます。
本投稿では、型の宣言方法および、データのset/get方法を記載します。


## 扱うJSONデータ

`[ほにゃらら]`部分はキー値ですが、スクリプト側から指定する値です。

```json
{
	"families":{
		[yamada] :{
			"members" :{
				[ichiro] :{
					"type" : "owner"
				},
				[jiro] :{
					"type" : "son"
				},
				[kotaro] :{
					"type" : "dog"
				}
			}
			
		},
		[satou] :{
			~省略。構成は同じ~
		}
	}
}
```

## 型の定義

ややこしいので、最小単位(`ichiro`など)の型定義から順番に行います。

```ts:
// name = ichiroで、 type = ownerを持つプロパティ
member  : {[name :string] :{type :string}}

// memberの配列
members :[{[name :string] :{type :string}}]

// surname(姓)の下に、membersを持つ
family  :{[surname :string] :[{[name :string] :{type :string}}]}

// familiyの配列
families :[{[surname :string] :[{[name :string] :{type :string}}]}]
```

## プログラムからJSONへ

JSONライクに記載できます。注:es5以上？

```ts:
  setter(){
    this.member = {["ichiro"]:{type:"owner"}};
    this.members = [{["ichiro"]:{type:"owner"}},{["jiro"]:{type:"son"}}];
    this.family  = {["yamada"] :[{["ichiro"]:{type:"owner"}},{["jiro"]:{type:"son"}}]};
    this.families = [{["yamada"] :[{["ichiro"]:{type:"owner"}},{["jiro"]:{type:"son"}}]},~~省略~~];
  }

```

## 値の表示
各値の取得例を記載します。

```ts
output(){

  // 1. memberの処理
  // member  : {[name :string] :{type :string}}
    console.log(this.member);
    // {ichiro: {type: "owner"}}

    console.log(Object.keys(this.member)[0]);
    // ichiro

    Object.keys(this.member).forEach(
      (val, idx, ary) => {
        console.log(val);
        // ichiro
        console.log(this.member[val].type);
        // owner
      }
    )

  // 2. membersの処理
  // members :[{[name :string] :{type :string}}]

    console.log(this.members);
    // [{ichiro: {type: "owner"}}, {jiro: {type: "son"}}]

    this.members.forEach(
      val =>  console.log(val)
      // {ichiro: {type: "owner"}}
      // -> あとはmemberの処理方法で処理する
    );

  // 3.familyの処理
  // family  :{[surname :string] :[{[name :string] :{type :string}}]}

    console.log(this.family);
    // yamada: Array (2)
    // 0 {ichiro: {type: "owner"}}
    // 1 {jiro: {type: "son"}}

    console.log(Object.keys(this.family)[0]);
    // yamada

    Object.keys(this.family).forEach(
      val => console.log(this.family[val])
      // [{ichiro: {type: "owner"}}, {jiro: {type: "son"}}]
      // -> あとはmembersの処理方法で処理する
    );


  // 4. familiesの処理は省略
  // families :[{[surname :string] :[{[name :string] :{type :string}}]}]

}
```

以上です。
備忘録_Vagrantメモ

## Vagrantを使用するメリット

- ローカル環境と本番環境を揃える
- チームで開発する際の環境を揃える

## 初期の流れ

基本的に仮想マシンごとにディレクトリを作成してあげるようにする

```
//ディレクトリ作成
mkdir test_dir

//作成したディレクトリに移動
cd test_dir

//vagrantの初期化(※ここでVagrantfileが作成される)
//ちなみにVagrantfileはRubyで記述されている
vagrant init <使用するbox名>

//起動
vagrant up

//sshログイン(※仮想マシンにsshログインできる)
vagrant ssh

//終了
vagrant halt

//※boxが入らなくなった際は削除
vagrant destroy

```


## コマンド編

### バージョン確認

```
vagrant -v
```

### 所有しているboxの確認

```
vagrant box list
```

### 再起動

```
vagrant reload
```

### 状態確認

```
vagrant status
```

### 一時停止

```
vagrant suspend
```

### 一時停止からの復帰

```
vagrant resume
```

### シャットダウン

```
vagrant halt
```

### 起動

```
vagrant up
```


### boxの作成

```
vagrant package
```

### boxの追加(※vagrantの公式ある)

```
vagrant box add <boxの名前(任意)> <boxのURL>
```

#### 番外編

```
//vagrant box　コマンドで何が使えるかを観れる
vagrant box -h

//主に下記のものがある
- add
- list
- remove
- repackeage

```

### boxの初期化

```
vagrant init
```

### boxの削除

```
vagrant destroy
```

### プロビジョニング

```
vagrant provision
```

### プラグイン関係

```
//下記のコマンドでいろいろ確認できる
vagrant plugin -h

//主に使用できるのは下記
- install
- license
- list
- uninstall
```


## vagrantに関して

### 知識として

Vagrant自体はRubyで書かれている。
Vagrantには仮想環境に関する機能はないのでVBを必ず合わせて使用する

Vagrantはboxをグローバルに管理する。
1つのboxを複数のプロジェクトから利用することが可能。
Vagrantはboxをクローン元のベースイメージとして使用するので変更が衝突することはない

1つのboxイメージから複数の仮想マシンを作成することが可能
必ずしもboxイメージと仮想環境が1:1の関係でないことを覚えておく

### boxファイルがある場所

```
//下記の場所にダウンロードしてきたboxのデータがある
cd ./.vagrant.d/boxes
```


### sshログイン

下記コマンドで仮想環境にsshログインできる

```
vagrant ssh
```

#### 番外編

```
vagrant ssh-config --host HOSTNAME >> ~/.ssh/config
```

上記を実行することで`ssh HOSTNAME`でログイン可能にもできる


### Vagrantfileに関して

プロジェクトごとに1つのVagrantfileを持つ※`vagrant init`で生成
作成したファイルを見るといろいろ書いてあるが最小構成下記

```
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "<box名(boxをダウンロードした際につけた名前)>"
end
```

- 1行目でV2設定
- 2~4行目で基本的な設定値を変数に代入

#### V2設定に関して

VagrantにはV1とV2の2つのバージョンがある

- V1は安定版
- V2は最新版

V1に設定する場合は

```
Vagrant::Config.run do |config|
  # 設定
end
```

V1とV2を混在させる

```
Vagrant::Config.run do |config|
  # V1の設定
end

Vagrant.configure("2") do |config|
  # V2の設定
end
```

### ネットワークの設定

Vagrantを使用することで、ゲストマシンに静的なIPを割り当て、ホストとゲストだけからなるプライベートなネットワークを構築することが可能。

```sample
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "<box名>"
  //ip表示じゃない方法でアクセスさせる際は下記(オプション機能)
  config.vm.hostname = "local.test.me"
  
  //下記の部分でIPを指定
  config.vm.network :private_network, ip: "192.168.33.10"
end
```

上記のように設定することで`192.168.33.10`にアクセスが可能になる

※オプションを指定した際は`http://local.test.me`でもアクセスが可能になる

### Vagrantの共有ファイル設定

vagrant用に作成したでディレクトリはsshログインした後の`cd /vagrant`とリンクしている

ローカルで作業しているファイルを即座に仮想環境上に反映させたいときは下記みたいにする

```
//シンボリックリンクをはる
ln -fs /vagrant /var/www/html
```
備忘録_ssh系メモ(秘密鍵/公開鍵)

## 秘密鍵の作成

```
cd ~/.ssh
ssh-keygen -t rsa -C "メールアドレス" -f "鍵のファイル名"
```

上記実行後、下記の鍵が生成される
※鍵ファイルの名前を指定しなかった場合

- id_rsa 秘密鍵
- id_rsa.pub 公開鍵


## クリップボードへ貼り付け

```
pbcopy < ~/.ssh/id.pub
```


## 登録

各ホスティングサービスへ登録


## configファイルの設定

下記のサイトを参考にさせていただいた

http://qiita.com/passol78/items/2ad123e39efeb1a5286b


## sshの多段接続

下記のサイトを参考にさせていただいた

https://www.xmisao.com/2013/10/08/ssh-proxy-command.html


## ssh-agent


### 秘密鍵の登録確認

```
ssh-add -l
```


### 秘密鍵の登録

```
//登録したい鍵を指定
ssh-add ~/.ssh/id_rsa

//ちなみに上の設定で鍵を保存した場合はターミナルの再起動で登録した鍵も消えてしまう・・・
//対応作は下。(-K のオプションを指定)

ssh-add -K ~/.ssh/id_rsa
```


## 秘密鍵の削除

```
//特定の鍵の削除
ssh-add -d ~/.ssh/<削除したい鍵>

//ALL削除
ssh-add -D
```
PHP プリペアドステートメントの「静的」・「動的」、エミュレートの設定について

SQLインジェンクション対策に有効なプリアドステートメントですが、よく分かっていなかった「静的」、「動的」の意味と、エミュレートの設定について、今後迷うことがないよう、まとめてみました。

先に結論から書くと脆弱性を無くすには、「エミュレートは使わない」、プレースホルダは、「静的」にする、が正解です。

## プレースホルダ

  * 「本物」 (静的プレースホルダ)
  * 「偽物（エミュレーション）」 (動的プレースホルダ)
      * プリペアドらしい記述を文字列結合してSQLを構築する
      * 文字コードの違いや不正文字によるエスケープ抜けは起こりうる
      
PHP + MySQL では動的プレースがデフォルトなので、パラメータを変更する必要があります。
PHP + Postgres は…?　分からない時は、設定しましょう。
こんな感じですね。 $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

      
## PDO::ATTR_EMULATE_PREPARES

PDO::ATTR_EMULATE_PREPARES の true/false でどうなるかをまとめました。
まずこれは、「プリペアドステートメント」のエミュレーションを有効または無効にするものです。


* true
    * 常にプリペアドステートメントをエミュレート(パフォーマンスはあがるので、あえて true にするアプリもある…)
* false
    * ネイティブのステートメントを使う
    * SQLが正しく準備できなければ、エミューレートを使う（※1）

### PHP の「プリペアドステートメント」のエミュレーション・モードのデフォルト状態
* 5.1 false
* 5.2 true
* 5.6 ?
      
PDO　を使うときは、明示的に「PDO::ATTR_EMULATE_PREPARES を false にする」が正解です。
が、※1 のように、SQLに何かしら不備があれば、エミュレートモードになってしまう…。これは怖い。
デバッグツールなど使って、実行時のSQLを確認することの大切さが分かりました。

PHP ではデフォルト値が最近は　true になっているのかも。
また時間があれば、更新します。
SQLServer Express


昔のSQLServerのデータをリストア

```shell-session
sqlcmd -S コンピューター名\SQLExpress
```

データベース一覧
```sql
1> sp_databases
2> go 1
```

わかりやすい
http://kanariya0922.hatenablog.com/entry/2012/02/03/202903

```shell-session
RESTORE FILELISTONLY 
FROM DISK='バックアップのファイル名'
go

RESTORE DATABASE TODB FROM DISK = ' 'バックアップのファイル名' WITH REPLACE,
move '論理DBPLogicalName' to '論理DBPhysicalNameの¥DATA¥までのパス\TODB.mdf',
move 'トランザクションログLogicalName' to 'トランザクションログPhysicalNameの¥DATA¥までのパス\TODB.ldf'
go
```
HTTPS for Tomcat behind Nginx behind SLB

HTTPS for Tomcat 7 Project.

All SLB and ECS are in Aliyun Environment. SLB would receive https request from client and send request in http to ECS, ECS may process http and response to SLB, SLB would respond to client.

ISSUE:

IF HTTP, OK AS

[HTTP 80]
SLB - CERT VALIDATER
[HTTP 80]
ECS / NGINX
[HTTP 8080]
ECS / TOMCAT
[HTTP]
BROWSER

HOWEVER, IF HTTPS, FALLS TO HTTP, AS

[HTTPS 443]
SLB
[HTTP 80]
ECS / NGINX
[HTTP 8080]
ECS / TOMCAT
[HTTP]
BROWSER

SOLUTION:

[HTTPS 443] or [HTTP 80]
SLB - CERT VALIDATER
[HTTP 80]
ECS / NGINX
[HTTPS 8443]
ECS / TOMCAT - CERT VALIDATER
[HTTPS]
BROWSER
systemd起動のDockerでdnsオプションを有効にする

# はじめに
Proxy配下のUbuntu上で docker build の際にdns設定で困ってしまいました。Dockerfileに書かれたyumの最中に、外部のネットワークに到達できずに止まってしまいます。
proxy設定はbuildのオプションで渡せますが、dnsのオプションはありません。対処方法をメモに残します。

# 環境
 * Ubuntu 16.04
 * Docker 1.12.1

Dockerはパッケージでインストールしています。

# そもそもの原因
 * dockerのホストであるUbuntuでは、デフォルトでdnsmasq が有効になっていて、 /etc/resolv.confが下記のように自分を見る設定になっている。
  
 ```:/etc/resolv.conf
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 127.0.1.1
search xxx.jp
 ```  

 * dockerはこの設定をコピーするとローカルにDNSがなくて困ってしまうので、デフォルトでパプリックなDNSを指定するようになっている（らしい）。
http://docs.docker.jp/engine/installation/linux/ubuntulinux.html#docker-dns  
  なので、docker buildしたイメージの中で、/etc/resolv.confが下記のようになる。

```:/etc/resolv.conf
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
search xxx.jp

nameserver 8.8.8.8
nameserver 8.8.4.4
```

 * docker build中にyumやらやっていると、proxyの名前解決をしようとして、8.8.8.8に問い合わせしようとするが、ネットワーク的に到達できずにこける。 


 ちなみにbuildしようとしているDockerfileはこちら。
https://github.com/Mashape/docker-java8/blob/master/Dockerfile
yumやらwgetやらやっています。

# 対応方法
はじめ、 /etc/default/docker を修正しましたが、設定が効きませんでした。dockerがsystemd起動なので、/etc/default のほうは見ないらしいです。

http://docs.docker.jp/engine/admin/systemd.html#custom-docker-daemon-options
を参考に以下のようにしています。

```:/etc/systemd/system/docker.service.d/docker.conf
[Service]
Environment="DOCKER_NETWORK_OPTIONS=--dns dnsサーバのIP"
ExecStart=
ExecStart=/usr/bin/dockerd -H fd:// $DOCKER_NETWORK_OPTIONS
```

本当はお作法的にはEnvironmentFileを設定してそちらにEnvironmentを書くべきだと思うのだけれど、どこにファイルを作るかを考えあぐねてこうなっています。

systemdのリロードとdockerの再起動。

```
$ sudo systemctl daemon-reload
$ sudo systemctl restart docker
```

念のためshowで確認。

```
$ systemctl show --property=Environment docker
Environment=DOCKER_NETWORK_OPTIONS=--dns\x20dnsサーバのIP HTTP_PROXY=http://your-proxy:port/
```

HTTP_PROXYを/etc/systemd/system/docker.service.d/http-proxy.conf  で設定しているので一緒に見えています。

この状態で docker build したらやっと最後までできました。

```
$ docker build -t centos_java8 --build-arg http_proxy=http://your-proxy:port/ --build-arg https_proxy=http://your-proxy:port/  .
```

### もしや
buildで引き渡すhttp_proxyをIPで書けばこんなことしなくてもいいんじゃネ、って気がしなくもないけど試してない。