OmniAICreator/Qiita-1.07M huggingface dataset:
EP 25 Initialize Parent Classes with `super`


> - Python's standard method resolution order (MRO) solves the problems of superclass intialization order and diamond inheritance.
- Always use the `super` built-in function to initialize parent classes.

> Effective Python


# Early python 2

```python
from pprint import pprint

class MyBaseClass:
    def __init__(self, value):
        self.value = value

class TimesTwo:
    def __init__(self):
        self.value *= 2

class PlusFive:
    def __init__(self):
        self.value += 5

class OneWay(MyBaseClass, TimesTwo, PlusFive):
    def __init__(self, value):
        MyBaseClass.__init__(self, value)
        TimesTwo.__init__(self)
        PlusFive.__init__(self)

print(OneWay(5).value)
```

Two problems:
- Multiple inheritance
- Diamond inheritance


## Multiple inheritance


```python
class OneWay(MyBaseClass, TimesTwo, PlusFive):
    def __init__(self, value):
        MyBaseClass.__init__(self, value)
        TimesTwo.__init__(self)
        PlusFive.__init__(self)
```

We can initilize class against the order of inheritance.

```python
class OneWay(MyBaseClass, TimesTwo, PlusFive):
    def __init__(self, value):
        MyBaseClass.__init__(self, value)
        PlusFive.__init__(self)
        TimesTwo.__init__(self)
```




## MRO: Method Resolution Order
Diamond inheritance with bad practice

```python
# diamond inheritance
class TimesFive(MyBaseClass):
    def __init__(self, value):
        MyBaseClass.__init__(self, value)
        self.value *= 5

class PlusTwo(MyBaseClass):
    def __init__(self, value):
        MyBaseClass.__init__(self, value)
        self.value += 2

class ThisWay(TimesFive, PlusFive):
    def __init__(self, value):
        TimesFive.__init__(self, value)
        PlusTwo.__init__(self, value)

foo = ThisWay(5)
print(foo.value)
```
Expected:
5 * 5 + 2 = 27

Actual:
7


However, we get 7 because `self.value` is initialized `TimesFive.__init__(self, value)` and `PlusTwo.__init__(self, value)`. 



## `super`

```python
# Python2
class TimesFiveCorrect(MyBaseClass):
    def __init__(self, value):
        super(TimesFiveCorrect, self).__init__(value)
        self.value *= 5

class PlusTwoCorrect(MyBaseClass):
    def __init__(self, value):
        super(PlusTwoCorrect, self).__init__(value)
        self.value += 2

# Python 2
class GoodWay(TimesFiveCorrect, PlusTwoCorrect):
    def __init__(self, value):
        super(GoodWay, self).__init__(value)

foo = GoodWay(5)
print(foo.value)

print(GoodWay.mro())

>>>
[<class '__main__.GoodWay'>,
<class '__main__.TimesFiveCorrect'>,
<class '__main__.PlusTwoCorrect'>,
<class '__main__.MyBaseClass'>,
<class 'object'>]
```

## `__class__` does not work in Python2.

```python
# Python 3
class Explicit(MyBaseClass):
    def __init__(self, value):
        super(__class__, self).__init__(value * 2)

class Implicit(MyBaseClass):
    def __init__(self, value):
        super().__init__(value * 2)



```
[Angular] RestangularにてTypeErrorが出る件の解決




TypeError: オブジェクトは 'includes' プロパティまたはメソッドをサポートしていません。

![WS000011.JPG](https://qiita-image-store.s3.amazonaws.com/0/49910/0b8597ad-0d7a-64e9-838b-4106549d0737.jpeg)


```html
    <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min.js"></script>
    <script src="../Scripts/restangular.js"></script>
```


restangular.js（v1.5.2）とunderscore-min.js（1.4.4）とのバージョンの差が原因だったもよう

最新を使い（2016.4.13現在）
restangular.js（v1.5.2）とunderscore-min.js（1.8.3）の組合せにしたらエラーが消えました。
GIGABYTE100シリーズにWindows7をインストールするのにハマったのでメモ

#Windows7のインストールも安心！のはずが…
秋葉原の某PCショップでGIGABYTE製 GA-B150M-D3H DDR3 を購入した。
昨今のマザーボードではWindows7をインストールしようとするとUSBキーボードを認識せず、汗を流しながらインストール作業を行わなければならないらしい。
しかし、このGA-B150M-D3H DDR3はWindows7のインストールも安心だという。ファミ通の攻略本くらい安心できる！そう思って購入した。

#Windows7も安心と言ったな。あれは嘘だ。
確かにUSBキーボードは認識した。
言語選択画面を抜けると不足しているドライバを入れろとの画面が。
よっしゃCDいれたるやで～と意気込むも・・・

* CDドライブが参照先に見えない。
* USBドライブも参照先に見えない。
* 不足しているドライバを入れられない

インストール作業はわずか2工程目で詰みとなった。

#答えはYoutubeにあった。
GIGABYTE 100 Series Windows 7 USB Installation Tool
https://youtu.be/ufsczv8cIeM

要するにGIGABYTEのツールを使ってインストールUSBを作れということだそうだ。
動画を要約してここに転記します。

### 必要なもの
* Windows USB Installation Tool（下からダウンロード）
http://www.gigabyte.jp/products/product-page.aspx?pid=5516#utility

* Windows7のインストールメディア
* 十分に空きのあるUSBメモリ
    * とりあえず8GBUSBメモリで事足りた。

###手順
1. 圧縮ファイルを解凍し、WindowsImageTool.exeを実行
2. Windows7のインストールディスクを挿入
3. Source Path(CD-ROM)にディスクのドライブを指定する。
4. Destination Path(USB Drive)にUSBドライブを指定する。
5. STARTを押して、しばらく待つ。（かなり待つ。30分以上）
6. 終了したらUSBブートでセットアップを行う。あとは通常のWindows7導入と同じ。


#愚痴
Youtubeで手順上げるの別にいいけど、テキストでも手順くれや。
ユニティちゃんを走らせてみた

昼休みにふと思いついて
ひたすらユニティちゃんを走らせるようにしてみた。

#動画

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

8秒ごとに位置を変えるボールに向かってユニティちゃんが走っていきます。

# ダウンロード (Unityパッケージ)はこちら
[Unity_FootstepsADX2LE_tatmos.unitypackage](https://drive.google.com/open?id=0B_omSCuMqg3eY2J5Ukxlai1QR1k)

```
上記パッケージをインポートして自由に使っていただいて構いません。
ってか遊んでみてね。
```

[ksilogic](http://qiita.com/ksilogic)さんのQiita記事
「[超使えるフリーサウンド素材集 OculusAudioPack01を効果的に使ってみよう](http://qiita.com/ksilogic/items/954685dd9618da7846f8)」から
プロジェクトを拝借して改変しています。
足音ついているだけでも大分いい感じで、
床属性で音が変わるのでなんだか楽しい。

これを自動で走らせることにしてみました。

#　走らせるためにナビメッシュ使ってみた

[unity 経路探索](https://www.google.co.jp/search?q=unity+%E7%B5%8C%E8%B7%AF%E6%8E%A2%E7%B4%A2&oq=unity+%E7%B5%8C%E8%B7%AF&aqs=chrome.1.69i57j0l5.11325j0j4&sourceid=chrome&ie=UTF-8)でググるといろいろでてきたので参考に動かしている。

##床とか壁とかを選択して「Navigation Static」とし、Bakeする。

![image](https://qiita-image-store.s3.amazonaws.com/0/96808/643294d1-ef5d-027b-9cb9-0dd9f60b73d7.png)

![image](https://qiita-image-store.s3.amazonaws.com/0/96808/832f67c6-1897-1c9c-fe78-468dbd67296e.png)

##あと、ユニティちゃんにもスクリプトをつけて

![image](https://qiita-image-store.s3.amazonaws.com/0/96808/03fe6d6a-cc70-cfb7-55b3-945842e33146.png)

``` MoveToTarget.cs
using UnityEngine;
using System.Collections;

public class MoveToTarget : MonoBehaviour {
    public Transform target;
    NavMeshAgent agent;

    void Start () {
        Reset();
    }

    void Update () {
        agent.SetDestination(target.position);

        animator.SetFloat("Speed", agent.velocity.sqrMagnitude);
    }

    [SerializeField, HideInInspector] Animator animator;

    void Reset()
    {
        agent = GetComponent<NavMeshAgent>();
        animator = GetComponent<Animator>();
    }
}
```

##ターゲットのSphereにもスクリプトつけて

![image](https://qiita-image-store.s3.amazonaws.com/0/96808/05e219b6-6df0-4512-1bce-6bf8f73382c3.png)

``` RandomMove.cs
using UnityEngine;
using System.Collections;

public class RandomMove : MonoBehaviour {
    void Start () {
        Reset();
	}
	
    float lastMoveTime = 0f;

	void Update () {
        if(Time.timeSinceLevelLoad > lastMoveTime)
        {
            Reset();
        }
	}

    void Reset()
    {
        this.transform.localPosition = new Vector3(Random.Range(0,5),5,Random.Range(0,-50));
        lastMoveTime = Time.timeSinceLevelLoad+8;
    }

    // 接地したら
    void OnCollisionEnter (Collider col){
        if(col.tag != "ground")
        {
            Reset();
        }
    }
}
```
#完成

足音変わるだけでもずいぶん楽しい。
ただ、アニメーションとかまだ不自然なところとかどうしたものか・・・もっと驚いてくれたり喜んでくれたりとか・・・
エラー「Invalid Signature」「Signing failed」があらわれた！

#iTunes ConnectにアップロードするとInvalid Signatureとなる

Adobe AIR 21 SDKで開発したアプリをアップロードしたところ、Invalid Signatureが返ってきました。

##既知の問題？

リリースノート | Flash Player® 21、AIR® 21
https://helpx.adobe.com/jp/flash-player/release-note/fp_21_air_21_release_notes.html

> [iOS][Win] Windows コンピューター上でパッケージされた IPA を Apple App Store に提出できない。iTunes Connect で「このビルドは無効です」というエラーが発生する。

リリースノートの既知の問題にそれっぽい記載を見つけました。とりあえず原因をこれだと仮定して、Windowsを使わずにMac OS X上でIPAファイルにパッケージングしてみることにします。

##パッケージ化に失敗する

Mac OS X上で、AIR SDKのADTコマンドを使用してIPA形式にパッケージ化を試みますが、

> Error: Signing failed

というエラーが出て失敗しました。 

AppleのDeveloperサイトに行って、有効な証明書とプロビジョニングファイルをダウンロードして使用しても同様に失敗しました。

##原因：指定している証明書が無効

Signing failedエラーの原因としては、ADTコマンドに指定している証明書が「無効」と判断されているためのようです。 

指定するP12形式の証明書ファイルをダブルクリックしてキーチェーンに登録し、「この証明書は有効です」という表示になるとエラーが発生しなくなりました。また、iTunes Connectへのアップロードも問題ありませんでした。

<img width="438" alt="keychain.png" src="https://qiita-image-store.s3.amazonaws.com/0/10269/19a97d7d-2d32-d404-1d97-e9d0416b0ec2.png">

いろいろと試していたので定かではないですが、Appleの新しいWWDR証明書を入れないと有効にならないかもしれません。

##おまけ：versionLabel警告

ADTコマンドでのIPAファイルへのパッケージ化で次の警告が出ました。

> Warning: Invalid format specified in &lt;versionLabel&gt; tag. Ignoring its value.

app.xmlのversionLabelに「1.2.3.4」などと書いていると出ます。「1.2.3」のような形式にすると警告が出なくなりました。 
[Adobeの仕様](http://help.adobe.com/ja_JP/air/build/WSfffb011ac560372f2fea1812938a6e463-8000.html#WSfffb011ac560372f2fea1812938a6e463-7ffa)ではversionNumberは「3 個以下の連結した整数をピリオドで区切っ」たバージョン番号で、versionLabelの方は特に制限なく文字列でバージョンを表現できます。 
※AIR 18 SDKからはversionLabelの値は CFBundleShortVersionStringに、versionNumberの値は CFBundleVersionにマップされるようになっています。 
[Appleの仕様](https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/20001431-111349)を確認すると、CFBundleShortVersionStringのバージョン番号はピリオド区切りの3つの数字だとあります。 

ということで、versionLabelにはApple様の言う通りのバージョン番号（ピリオド区切りの3つの数字）を記入しましょう。
Wrangle x Python本やってみたメモ [1]

#これはなに？
COMITIA115(2016/01/31 於：東京ビッグサイト)にて頒布された
**Houdini実践ハンドブックWrangle×Python**（サークル『魔法の蒸留水』）
http://majou.jp/archives/667/

の、Pythonの例文に取り組んでみたときのメモです。

#p.10　「3 Wrangle x Python の実践」　3.1 Pointの移動

##準備

新規シーン → geometryノード作成
![geo1.png](https://qiita-image-store.s3.amazonaws.com/0/102581/eebb79eb-fddd-2444-9326-7865726007a6.png)

中に入ったら（元からあるfile1は削除して）
gridを作成
pythonを作成
つなぎます
![gridWithPy.png](https://qiita-image-store.s3.amazonaws.com/0/102581/8b36603e-bc7d-125e-6fbe-7aaf5e29d649.png)

##setPosition()
p.10にある例文を
Pythonノード内のPython Code欄に書いていきます
![code01.png](https://qiita-image-store.s3.amazonaws.com/0/102581/23b40e86-3c7a-c7f5-41f2-4847d3b43622.png)

最初の2行はPythonノードを作成した時点で書き込まれているので、
そのあとの4行だけ。
（※この最初の2行については p.6 に記述アリ）

```py:
for point in geo.points():
    pos = point.position()
    pos += hou.Vector3(0,2,0)
    point.setPosition(pos)
```

`geo.points()`のpointsをpointにタイポしていて「あっれー」ってなったのはここだけのヒミツ

結果
![result01.png](https://qiita-image-store.s3.amazonaws.com/0/102581/ed43e71f-51ae-2631-f681-1b7af260f5e7.png)
Y方向に 2 移動したぞおおおおおおおおお

***

以下のように書き換えて遊んだりもします

```py:書き換え1
for point in geo.points():
    point.setPosition( point.position()+hou.Vector3(0,2,0) )
```

```py:書き換え2
x = 0
y = 2
z = 0
pos = hou.Vector3(x,y,z)

for point in geo.points():
    point.setPosition( point.position()+pos )
```

##hmath.buildTranslate

p.10 二つ目の例文

```py:
for point in geo.points():
    pos = point.position()
    mtx = hou.hmath.buildTranslate((0,2,0))
    pos = pos * mtx
    point.setPosition(pos)
```

![result02.png](https://qiita-image-store.s3.amazonaws.com/0/102581/b7ba6247-934d-0445-d3cb-7b17408c2760.png)

`pos = pos * mtx` は代入演算子にしても可。`pos *= mtx`

#まとめ

とりあえずp.10のPythonの例文だけ。

Wrangle x Python本、とらのあなで注文可能な模様
https://www.toranoana.jp/mailorder/article/04/0030/38/99/040030389986.html
~~僅少らしいです~~　＜[2]を書くタイミングで確認したら売り切れてました！

#備考
##サジェスト
`hou.hmath.b`あたりとか、打ってる途中で入力補完が出ます

![suggest.png](https://qiita-image-store.s3.amazonaws.com/0/102581/7a9885f8-7da6-ebb2-d172-d3b582a90b12.png)

##関数の説明
関数の引数を入力し始めると、関数の説明が出ます。

![guide.png](https://qiita-image-store.s3.amazonaws.com/0/102581/08457894-5d1d-5d17-25f0-9258c104713f.png)

##printやhelp
Python Code内に`print`や`help()`を入れると
**「Houdini Console」**という別ウィンドウに表示されます。
![console.png](https://qiita-image-store.s3.amazonaws.com/0/102581/6413331f-0858-1175-c358-ebdf05d03f46.png)

行数が多すぎると流れちゃうので注意です。
例えば上図は`help(hou.hmath)`したときの例ですが、冒頭部分は流れちゃって読めませんでした。（さすがにhelpはPython Shellで〜）

##参考

> Vector3
http://sidefx.jp/doc/hom/hou/Vector3.html

> Matrix4
http://sidefx.jp/doc/hom/hou/Matrix4.html

> setPosition
http://sidefx.jp/doc/hom/hou/Point.html#setPosition

> hmath
http://sidefx.jp/doc/hom/hou/hmath.html

公開されている日本語ドキュメントも意外と日本語化されてなかったりするのでおとなしく本家に行くのが早いことが多いです。

***

ちなみにHoudiniのPython環境については
こちらでもすこし触れています

> Maya, Houdini, blender, Nuke でのPythonインタープリタ
http://qiita.com/it_ks/items/ae1d0ae01d831c2fc9ae#houdini
troff でズンドコキヨシ

どうやら最近、[troff]に注目が（チョットだけ）集まっているようである。

[troff]: http://www.troff.org/

  * [Brian Kernighanがプログラミング言語Goの組版に使ったのはなんとtroff](http://cpplover.blogspot.jp/2016/04/brian-kernighangotroff.html)

というわけで、必然的に「troffで[ズンドコキヨシ]」することになった。

[ズンドコキヨシ]: http://qiita.com/shunsugai@github/items/971a15461de29563bf90

## ソースコード

```text:zundoko.troff
.ps 14
.vs 17p
.nr RS ((\n(yr*12+\n(mo)*30+\n(dy)*7+(\n($$*27)
.nr RB 0
.de RB
.nr RB (\\n(RS/134217728)+(\\n(RS/4)%2
.nr RS \\n(RS%134217728*2+\\n(RB
..
.nr TC 28
.de RW
.RB
.nr TC -1
.if \\n(TC>0 .RW
..
.RW
.nr ZR 0
.de ZZ
Zun
.nr ZR +1
..
.de ZD
Doko
.if \\n(ZR>=4 .nr ZR (-1)
.if \\n(ZR>0 .nr ZR 0
..
.de ZL
.RB
.if \\n(RB=1 .ZZ
.if \\n(RB=0 .ZD
.if \\n(ZR>=0 .ZL
..
.ZL
KI-YO-SHI!
```

えっ、マクロパッケージ……？ それナンテTeX？

## 実行してみる

動作確認： GNU troff (groff) 1.22.3

```shell-session
me@here$ groff zundoko.troff > zundoko.ps
```

これで次のように綺麗に組版されたPostScriptファイル zundoko.ps が出力される[^gs]。
（ズンドコキヨシなので、もちろん実行する度に結果は異なる。）

![image-zdktroff-1.png](https://qiita-image-store.s3.amazonaws.com/0/14550/22d5f88a-c1f3-a97e-600e-089ad87cb426.png)


[^gs]: GhostScriptがインストールされていれば、ps2pdfコマンドでPostScript文書をPDF文書に変換できる。

groffの場合、プレーンテキストで出力させることもできる。（ただし紙面に出力した状態の模倣なので、大量の“余白”が出力される。）

```shell-session
me@here$ groff -Tascii zundoko.troff
Zun  Doko  Doko Doko Zun Doko Zun Zun Doko Doko Zun Doko Zun Doko
Doko Zun Doko Zun Doko Zun Zun Zun Doko Zun Zun Doko Doko Zun Zun
Doko Zun Zun Zun Zun Doko KI-YO-SHI!

(大量の空白行が続く)
```

## まとめ

というわけで、とうとうtroffに手を出してしまった……（うわぁ）
僕がnpm installに-gをつけないわけ

Node.js開発に欠かせない`npm install`
その中でもgulpやmochaみたいにコマンドから起動する類のものには`-g`オプションをつけることが多いかと思います。
ていうかサンプルとかだと普通に「`-g`つけてね」みたいな感じのノリです。

[例](http://www.atmarkit.co.jp/ait/articles/1501/09/news040_2.html#062):`npm install`でググってみたら上の方に出たやつ(注:リンク先の記事では`npm install -g gulp`となってますが、2016-04-14現在公式で`npm install -g gulp-cli`が推奨されています)


しかし私は極力`-g`を使いたくないのです。ていうか全く使わなくていいのではとさえ思っています。
というわけで`-g`について徒然なるままに心にうつりゆくよしなし事を書き綴ります。

# なぜ-gが必要か

そもそもなぜ`-g`が必要なのでしょうか。
`-g`をつけないとパスが通らないからですね。
gulpで試してみましょう。

```
npm install gulp --save
gulp 
```

当然「そんなコマンド無えよ」と叱られます。
しかし、パッケージはインストールされているので、ちゃんとパスを指定してやればgulpは動くはずです。
こんな感じで

`./node_modules/gulp/bin/gulp.js`

一応gulpは動きますが、タスク内で相対パスを使ってたらちゃんと動くのだろうか...
それ以前にこれを毎回打ち込むのはすこぶる面倒くさい。

gulpはまだ良心的な方で、インストール時にnode_modules直下にできるディレクトリがgulpディレクトリだけで済むからどいつを起動すればいいかすぐにわかります。
browserifyをインストールしたらbrowserify〇〇というディレクトリが10個ほど出来上がってしまうため、パスを指定して起動するのも一苦労です。

それが`-g`つけたらどこからでもコマンド一発でよびだせるからそりゃあ便利ですよね。

# ではなぜ-gを使いたくないのか

「こんなに便利だとわかってて使いたくないとか馬鹿なの？」みたいなツッコミがきそうなので、
私が考える`-g`を使うべきでない理由を述べます。

一言で表すなら**ポータビリティが損なわれる**からです。

## ポータビリティが損なわれるってどういうこと?

`-g`でインストールしてると他の環境に引っ越したりコピーしたりするのが非常に面倒ということです。
自分のマシンだけで開発するならそれでも問題ありませんが、「本番環境にデプロイする」「他の人と共同で開発する」となると事態は一変します。

gitからソースを落としてきて`npm install`、
これでいけるはずなのになんか上手くいかない...
「しまった、あれをインストールしないと」「ああ！あれも必要だった！」という悲劇が起きかねません。

## どうしてこうなった...

理由は簡単で、`-g`が付いていた場合例え`--save`とかつけててもpackage.jsonに追記されません。
プロジェクトにではなくグローバルな領域にインストールしたのですから。
`-g`を外して`npm install --save`すればpackage.jsonには追記されます。
しかしそれをコマンドとして使用する旨は記載されません。

すがるような気持ちで`npm list -g`とかやるとそこにはコンソールに収まらないほどのディレクトリツリー...
こうなってしまったら一つずつ確認していくしかありません。
考えたくもないですね。

しかし`-g`でインストールしないとgulpのような便利ツールが使えない。
どうすれば良いのか。

# 救世主npm run

そこで颯爽と登場するのが`npm run`コマンド。
こいつはpackage.jsonのscriptsのところに記載したスクリプトを起動してくれるのですが、なんとローカルインストールしたパッケージについても自動的にパスを通してくれる優れものです。

例えば

```package.json
{
  "name": "sample",
  "version": "1.0.0",
  "description": "sample",
  "main": "index.js",
  "directories": {
    "test": "tests"
  },
  "scripts": {
    "gulp": "gulp"
  },
  "author": "Mic-U",
  "license": "MIT",
  "devDependencies": {
    "gulp": "^3.9.1",
  }
}

```

こんな感じでpackage.jsonを書いていれば`npm run gulp`でgulpコマンドと同様に動作します。
そのままで`npm run gulp hoge`みたいにタスクを指定することもできます。
若干打ち込むコマンドが長くなりますが、`-g`のリスクを考えると許容範囲ではないでしょうか。

[参考]
[npm で依存もタスクも一元化する](http://qiita.com/Jxck_/items/efaff21b977ddc782971)
SeleniumWebDriver で wait.until しても 60秒で Net::ReadTimeout になってしまう


とあるサイトで、とある処理を自動化したくて、SeleniumWebDriverで下記のように書きました。

- Windows8
- ruby 2.2.2p95

```rb
driver = Selenium::WebDriver.for :firefox
driver.get("とあるURL")

button.click # とあるボタンをクリックする

wait   = Selenium::WebDriver::Wait.new(:timeout => 600) # 10分
wait.until {
  driver.find_element(:how, :what) # 表示まで2,3分かかるエレメント
}
```

ってやると**60秒後**に

```:抜粋
Net::ReadTimeout
IO::EWOULDBLOCKWaitReadable:
A non-blocking socket operation could not be completed immediately. - read would block
```

というエラーになってしまいました。

SeleniumWebDriverで「要素が表示されるまで待つ」と言ったら 上記の`wait.until`じゃないですか。これ以外知らないじゃないですか ←勉強不足

巡り巡って、[webdriverのタイムアウトを設定する - Qiita](http://qiita.com/yooo_gooo/items/50e66aa2624f521183a2)

の記事にたどり着いて


```rb
client = Selenium::WebDriver::Remote::Http::Default.new
client.timeout = 600 # 10分

driver = Selenium::WebDriver.for :firefox, :http_client => client
driver.get("とあるURL")

button.click # とあるボタンをクリックする

driver.find_element(:how, :what) # 表示まで2,3分かかるエレメント
```

ってやったらうまくいきました。

んー、でもみなさん `client = Selenium::WebDriver::Remote::Http::Default.new`こんなことしてないですよね。どういう時にこういうことになるのかな。。。
イラストレーターからsvgを書き出すときにはidに注意


イラレからsvgを書き出す時、イラレ上のレイヤー名がsvgタグのid値として付与される。
従って、何も考えずにレイヤー名も特につけずに書き出すと、たくさん書きだした時に同一idのsvgタグがページ内に複数存在することになってしまう！

![layer_1.jpg](https://qiita-image-store.s3.amazonaws.com/0/43677/dc386c91-8a7c-44be-d9db-c3d992ffbf83.jpeg "layer_1.jpg")


また、svgタグだけでなく、その内部にもidが振られる場合があり、これも同じく重複しないように注意する必要がある。
例えば、use 等を使う場合にはidが付与される。
ページ内で複数svgをインラインで埋め込んだとき、予期せぬ挙動をしてしまった場合はidを疑いましょう。
僕はこれで長い時間ハマりました。。
速報 apple/swift の PR "Port to Android" がマージされてました

今年 2 月ごろに GitHub の [apple/swift](https://github.com/apple/swift) リポジトリに [Android をビルドターゲットにする Pull Request](https://github.com/apple/swift/pull/1442) が上がっていました。

本日、どうやら master にマージされていたようなので、思わず記事にしてみました。

![マージ済.png](https://qiita-image-store.s3.amazonaws.com/0/25886/8dce11ee-179e-e43d-dfd5-a8d3bcab228c.png)

<blockquote class="twitter-tweet" data-lang="ja"><p lang="en" dir="ltr">The Swift Android port is merged! Thanks <a href="https://twitter.com/zhuowei">@zhuowei</a> and many others! <a href="https://t.co/r0kzpBeAgw">https://t.co/r0kzpBeAgw</a></p>&mdash; Brian Gesiak (@modocache) <a href="https://twitter.com/modocache/status/720139771771805697">2016年4月13日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>


喜ばしいことですね。

最近はニュースでも Google が Swift を採用するか否かの件で、毎日賑わせている最中だったのですが、今回のマージはその動きに影響はあるのでしょうか？

今後の展開が非常に気になります。

- [Appleのオープンソース開発言語SwiftをAndroidに採用？](http://www.itmedia.co.jp/news/articles/1604/09/news026.html)
- [グーグルの「Swift」採用はあり得るのか、アプリ開発言語を考える](http://ascii.jp/elem/000/001/148/1148860/)

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr"><a href="https://twitter.com/modocache">@modocache</a> <a href="https://twitter.com/zhuowei">@zhuowei</a> よくわかんかいけど、別にまだandroidアプリをswiftで書けるようになったわけじゃないのね。</p>&mdash; あらき (@taiaraky) <a href="https://twitter.com/taiaraky/status/720386768290193408">2016年4月13日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr"><a href="https://twitter.com/taiaraky">@taiaraky</a> そのとおり！</p>&mdash; Brian Gesiak (@modocache) <a href="https://twitter.com/modocache/status/720392729847586816">2016年4月13日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

とのこと
GitHub登録からプッシュまでの流れ

# GitHub（ターミナル操作手順）

個人的なメモとしてGitHubの登録からターミナルでのコミット、プッシュの流れを簡単にまとめてみました。少々雑なところもありますが、お役に立てればと思います。

## 手順

1. GitHubアカウント作成
2. 通信の暗号化（SSH鍵の設定）
3. リポジトリの作成
4. GitHubへのpush

<br />

1, 2に関しては下記のサイト通りなので割愛します。大変お世話になったリンク先を載せておきます。
#### [GitHubアカウント作成](https://github.com/)

#### [SSH鍵を作成、登録](http://qiita.com/knife0125/items/50b80ad45d21ddec61a9)

<br />
<br />
<br />

# commit → puchの流れ
<br />
##手順０	ユーザー設定
	$ git config --global user.name "ユーザ名”
	$ git config --global user.email メールアドレス

こちらは一度設定してしまえば次回からは設定する必要ありません。

<br />

## 手順１　リポジトリ作成
#### リポジトリを作成するディレクトリに移動
	$ cd ~/使用するプロジェクトのフォルダ

#### README.mdの作成
	$ touch README.md

>* README.md（リポジトリにアップしたソースコードの説明などを書くファイル）
>* 拡張子(.md)は[マークダウン](https://ja.wikipedia.org/wiki/Markdown)記述（軽量マークアップ言語）

#### リポジトリ作成
	$ git init

#### README.mdファイルをローカル上のステージングエリアに上げる
	$ git add README.md

<br />

## 手順２　ローカルリポジトリにコミット
#### コミット
	$ git add .　
	$ git commit -m “first commit”

>* ステージングエリアへ登録（コミット待ちになる）
>* ローカルリポジトリへコミット

#### 確認
	$ git log
>コミットしたログの確認を行えます。


## 間違えてコミットしてしまった場合
#### 削除
	$ git reset --hard HEAD^
	$ git reset --hard HEAD^^
	$ git reset --hard HEAD^^^

>* １つ前のコミット取り消し
>* ２つ前のコミット取り消し
>* ３つ前のコミット取り消し

#### 上書き
	$ git commit --amend
>直前のコミットに上書きをします。

<br />

## 手順３　GitHubにプッシュ
#### URL指定
	$ git remote add origin プッシュするURL

#### プッシュ
	$ git push -u origin master
>これで完了です。[GitHub](https://github.com/)に戻って確認してみましょう！

#### 追加したURLを削除したいとき
	$ git remote rm origin
>間違えても削除を行えるのでプッシュし直せます。


## プッシュ時のエラーの対応方法
私が遭遇した下記のエラーの対応方法を記述します。

	failed to push some refs to ‘URL’

<br />

#### 方法１　fetchしてmergeする

	git fetch
	git merge origin/master
>* リモートの変更を取ってくる
>* マージする

<br />

#### 方法２　fetchしてrebaseする（リモートの変更の後に自分の変更を持ってくる ）

	git fetch
	git rebase origin/master
>* リモートの変更を取ってくる
>* 自分の変更を持ってくる

<br />

#### ※ 方法３　pullする

	git pull

> こちらは慣れないうちは使わないほうがいいみたいです。

<br />

ちなみにそれぞれこのような意味を持ちます。

|git push | git fetch |git merge|
|:-------:|:---------:|:-------:|
|アップロード|ダウンロード|２つのブランチを合流|

<br />
___

最後にこちらのまとめの元となったリンク先の一覧を載せておきます。

## 参考URL
リポジトリ作成、README.md：http://mae.chab.in/archives/2306
コミット、プッシュ：http://qiita.com/iron-breaker/items/6da9e0f1af0b4c2c1cfa
コミット削除：http://qiita.com/shuntaro_tamura/items/06281261d893acf049ed

push時にfailed to push some refs to ‘URL’の対処法：https://www.softel.co.jp/blogs/tech/archives/3569

<br />

## その他
Markdown：https://ja.wikipedia.org/wiki/Markdown
pullを使うべきでない３つの理由：http://dqn.sakusakutto.jp/2012/11/git_pull.html
pullとfetch+mergeの違い：http://qiita.com/Teloo/items/95a860ae276b49edb040# 

<br />
___

GitHubを始めたばかりの初心者なので、何か間違えているところがありましたらご指摘頂けると幸いです。
最後まで見て下さりありがとうございました。
Dockerコンテナを--rmフラグをつけてdetach実行するには

`docker run`のdetachedモード`-d`, `--detach`と自動削除オプション`--rm`は排他的です。

```shell-session
$ docker run -d --rm -p 10080:80 nginx
Conflicting options: --rm and -d
```
あとで参照することのないコンテナは自動で削除してしまいたいのですが`--detach`を指定するとそれができません。detachedモードではコンテナIDが返ってくるのでそれを頼りに`docker rm`すればいいのですが忘れることもありますよね。そうして、これなんだっけ、なコンテナIDがじわじわと溜まっていく。。

避けたいときは自分は次のようにしています。

```shell-session
$ docker run --rm -p 10080:80 --name detach_test nginx > /dev/null 2>&1 &
[1] 37254
```
よく見るプロセスのバックグラウンド実行ですよね。こうすることでdetachedモードと同等の結果が得られるはずです。
もちろんコンテナを停止すると次の通り自動的に削除してくれます。

```shell-session
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                            NAMES
3f58b460cbba        nginx               "nginx -g 'daemon off"   35 seconds ago      Up 34 seconds       443/tcp, 0.0.0.0:10080->80/tcp   detach_test
$ docker stop detach_test
detach_test
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
[1]+  Done                    docker run --rm -p 10080:80 --name detach_test nginx > /dev/null 2>&1
```

ヘルプにもあるようにコンテナIDを出力しないので不便に思うかもしれません。

```shell-session
$ docker run --help | grep "\-d,"
  -d, --detach                    Run container in background and print container ID
```
それでしたらファイルに書き出すことになりますが`--cidfile=`なんていかがでしょうか。

```shell-session
docker run --help | grep "--cidfile"
  --cidfile                       Write the container ID to the file
```
標準出力を /dev/null に捨てているので不安だったりしますか？ 大丈夫です。

```shell-session
$ curl http://localhost:10080/
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
$ docker logs detach_test
172.17.42.1 - - [12/Apr/2016:11:22:36 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-"
```
コンテナが停止するまでは`docker logs`で参照できます。必要ならば`docker attach`してもいいです。

コンテナはdetachedモードではSTDOUTとSTDERRが無効になりますが、

```shell-session
$ docker run -d --name detached_container nginx
$ docker inspect detached_container | grep AttachStd
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
```
フォアグラウンドで実行したときはSTDOUTとSTDERRが有効になります。

```shell-session
$ docker run --rm --name foreground_container nginx
$ docker inspect foreground_container | grep AttachStd
            "AttachStdin": false,
            "AttachStdout": true,
            "AttachStderr": true,
```
ですから`&`でバックグラウンド実行するとともに`> /dev/null 2>&1`でSTDOUTとSTDERRを捨てている、というわけです。考え方は通常のプロセス実行のときと同じですね。
django-import-exportのインポートがくそ遅い理由と対処



https://github.com/django-import-export/django-import-export
https://django-import-export.readthedocs.org/en/latest/index.html


たかだか2000行程度のCSVをインポートしようとするだけで、どうしようもないぐらい処理が重たい `django-import-export` ではありますが、どうやら大量にDBアクセスしとる様でした。


## 解決策

ただひたすらにDBへのアクセスを減らせばそれなりに早くなります。
とりあえずサンプル。

```python
from import_export.admin import ImportExportModelAdmin
from import_export import fields, resources, widgets
from import_export.instance_loaders import CachedInstanceLoader

from .models import Foo


class FooResource(resources.ModelResource):
    related_item = fields.Field(
        column_name='related_item_id',
        attribute='related_item_id',
        widget=widgets.IntegerWidget(),
    )

    class Meta:
        model = Foo
        skip_unchanged = True
        instance_loader_class = CachedInstanceLoader


class FooAdmin(ImportExportModelAdmin):
	resource_class = FooResource
	skip_admin_log = True

```


### ForeignKeyWidget を使わない

モデルのフィールドが `ForeignKey` で定義されてると、ImportExportライブラリは `widgets.ForeignKeyWidget` を利用する様になります。

https://github.com/django-import-export/django-import-export/blob/0.4.5/import_export/resources.py#L671

こいつがインポート時にDBへアクセスを行ってるので、 `widgets.IntegerWidget` に置き換えてあげると早くなりますよ。

https://github.com/django-import-export/django-import-export/blob/0.4.5/import_export/widgets.py#L272


### CachedInstanceLoader を使う

インポート時に毎行 `PrimaryKey` の値でDBにアクセスしやがります。

https://github.com/django-import-export/django-import-export/blob/0.4.5/import_export/instance_loaders.py#L33

ので、先にがっつり全部読んでからやってくれる `CachedInstanceLoader` を使うとDBへのアクセスは1回になるので素敵。


### 変更のないデータを無視する（skip_unchange=True を使う）

不要な UPDATE文 を実行させない様に `skip_unchange=True` を書いて置くと更新時は少し早くなる。

https://github.com/django-import-export/django-import-export/blob/0.4.5/import_export/resources.py#L427



### 管理画面の変更ログを作らない様にする（skip_admin_log=Trueを使う）

いちいちご丁寧に大量の変更ログを作ってくれやがるので、 `skip_admin_log=True` で丁重にお断りしましょう。

https://github.com/django-import-export/django-import-export/blob/0.4.5/import_export/admin.py#L163
エクセルで表示される座標をインデックスに変換する

よくcsv形式で作成したファイルをjsonに変換したりするのですが、そのときにRubyでCSVをパースすると二次元配列となります。
この二次元配列から指定座標の値を取得するためにはindexを指定して取得する必要があります。

しかし、エクセルやオープンオフィス等で表示される'AA10'といった座標の値を取得するためには、'AA'が配列でいう何番に対応するのかかなりわかりづらく、数え間違えもしやすく面倒です。

そこで、'AA'を２次元配列のindexに置き換えるコードをRubyで書いてみました。

## 書いたコード
```rb
CODES = ('A'..'Z')
CODES_SIZE = CODES.to_a.size

def code2index(code)
  code.split('').reverse.map.with_index do |c, i|
    n = c.ord - CODES.first.ord
    n += 1 unless i == 0
    n *= CODES_SIZE ** i
    n
  end.inject(:+)
end

```

実際に実行してみるとこんな感じになります。

```rb
irb(main):001:0> code2index('A')
=> 0
irb(main):003:0> code2index('Z')
=> 25
irb(main):002:0> code2index('AA')
=> 26
irb(main):004:0> code2index('BA')
=> 52
irb(main):005:0> code2index('ZZ')
=> 701
irb(main):006:0> code2index('AAA')
=> 702
```

## 仕組みについて
一見すると単純な25進数に見えるのですが、実は二桁以上になると罠があります。
25進数として考えると下記のようになってしまいます。

code | 25進数 | 10進数
:-: | :-: | :-:
A | 0 | 0
B | 1 | 1
Z | 25 | 25
AA | 0, 0 | 0
BA | 1, 0 | 26
AAA | 0, 0, 0 | 0

二桁目以降の扱いが単純な25進数となっていないため、'A'が0となってしまうと'A'と'AA'と'AAA'が同一のものとして扱われてしまいます。
そこで二桁目以降は、1を可算した形で表現することで対処します。

code | 25進数 | 10進数
:-: | :-: | :-:
A | 0 | 0
B | 1 | 1
Z | 25 | 25
AA | 1, 0 | 26
BA | 2, 0 | 52
AAA | 1, 1, 0 | 702

これでやっと座標に対応したインデックスを取得することが出来ます。

ちなみに、逆変換はこちら。

```rb
def index2code(n)
  chars = ''
  codes = CODES.to_a
  i = 0

  begin
    n -= 1 unless i == 0
    chars << codes[n % CODES_SIZE]
    n = n / CODES_SIZE
    i += 1
  end while n > 0

  chars.reverse
end
```

## 最後に
実際のCSVの座標の値を取得したりするのに便利なので、Gemとして作ってみました.
ご自由にお使いください。

[kei-p/CSVCoordinateAccessor](https://github.com/kei-p/CSVCoordinateAccessor)
root権限がない計算機で各種アプリケーションを管理する


# 概要
大型計算機などでインストールされていないソフトウェアを利用する際に、自分のホームディレクトリにソフトウェアをソースからコンパイルしてインストールする必要がある。
その際に、ソースコード管理ツールである["porg"](http://porg.sourceforge.net/)を使って上手にツール管理をする。
"porg"を使うことにより、アプリケーションの削除が容易になる。

# 実行環境

- CentOS Linux release 7.1.1503 (Core)
- Intel(R) Xeon(R) CPU E3-1246 v3 @ 3.50GHz

# porgのインストール

## インストール
```sh
# prefixでporgのインストール先を指定する。 $HOME/envなど
# またそれに併せて、porgのログファイルのインストール先も指定する。
$ /configure --prefix=/lab/takahashi/env --disable-grop --with-porg-logdir=/lab/takahashi/env

$ make
$ make install
```

## パスの設定

例の場合は`/lab/takahashi/env/`以下にインストールされる。
パスを指定しないと絶対パスでコマンドを入力しなければならないので、パスをシェル設定ファイルに指定する。

```bashrc,zshrcなど
PATH=$PATH:/lab/takahashi/env/bin
```

# porgを利用したインストール例
## jqをインストール

```
$ git clone https://github.com/stedolan/jq.git
$ cd jq
$ autoreconf -i
$ ./configure --disable-maintainer-mode --prefix=/lab/takahashi/env
$ make
$ porg -lp jq "make install"
```

## porgの確認

```
$ porg -a
jq
```

`porg -a`でporgを使ってインストールしたアプリケーションが表示される。

基本的に、`./configure --prefix==インストール先`とporgでインストールするということを押さえておく。
Gradleって結局何か。AndroidのGradle 2.0.0って何か。ざっくり調べてみた。

AndroidのGradleがアップデートされたぞー！
Instant Runに対応するぞー！！
そんな時に遭遇した、Gradleってなんなのかという素朴な疑問。
ざっくり調べてみた。

と、意気込んで、build.gradleをアップデート。

```
dependencies {
    classpath 'com.android.tools.build:gradle:2.0.0'
}
```

すると……
今度は、gradle-2.10以上……的なことを言われたりします。

gradle上げたじゃん、的な。

## 結局、Gradleってなに。

ざっくりまとめると、
Gradle自体は、ビルドツール。依存ライブラリとかをまとめて管理できて便利なやつ。
いつも、dependencies、compileとかを書いているから、なんとなくわかるかなと。
ざっくりね。

## じゃぁ、gradle 2.0.0になったっていうのは何か
こっちは、正確には「Android Plugin for Gradle」が2.0.0という話。
GradleのAndroid用プラグインが、バージョン２になったというわけか。
上で書いた、build.gradleでは、プラグインのバージョンを指定していたのね。

Android Plugin for Android
http://developer.android.com/intl/ja/tools/building/plugin-for-gradle.html
http://developer.android.com/intl/ja/tools/revisions/gradle-plugin.html#updating-plugin

これを読むと、「Android Plugin for Gradle 2.0.0」は、「gradle 2.10 or higher」で対応って書いてある。

いろいろ探してみると、gradle-wrapper.propertiesというファイルには、どのバージョンのgradleを使うかが書いてある。

```
distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-bin.zip
```

なるほどなるほど、2.8なのね。そりゃたしかに、gradleをアップデートせよと出てくるわけだ。
ちなみに、Gradleそのものは、既に2.12とかになっている……。

## まとめると……

Androidをビルドするプラグインをversion 2に上げようとするなら、
ビルドに使っているGradleは、2.10以上にしないとね、という話だった。
これからPHPでFacebook Messenger Botづくりを始める人向けの簡易スターターキット


[LINE BotをHerokuで動かすキット](http://qiita.com/tmtysk/items/2f33c7e08caefbf55548)の二番煎じです. 最小限のことしかやってません.
下のボタンを押すと、すぐに動かせます. Silex を使っています.

[![Deploy](https://www.herokucdn.com/deploy/button.svg)](http://bit.ly/fbmessengerbot-test-deploy)

動かし方は、[リポジトリ](https://github.com/CoachUnited/fbmessengerbot-test) に含まれる README を読んでください.

# ソースはこちら

* [CoachUnited/fbmessengerbot-test](https://github.com/CoachUnited/fbmessengerbot-test) .. スターターキット
よく使うSQL Queryメモ


よく忘れるのでメモ。

## ユーザー作成
```sql
GRANT ALL PRIVILEGES ON テーブル名.* TO ユーザー名@localhost IDENTIFIED BY 'パスワード' WITH GRANT OPTION;
```

## テーブル作成
```sql
CREATE TABLE IF NOT EXISTS `hoge`
(
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    classid VARCHAR(10),
    name VARCHAR(100),
    unit VARCHAR(50),
    example TEXT,
    note TEXT,
    created DATETIME DEFAULT NULL,
    modified DATETIME DEFAULT NULL
)ENGINE=MyISAM DEFAULT CHARSET=utf8;
```

## テーブル削除
```sql
DROP TABLE hoge;
```

## データ挿入
```sql
INSERT INTO hoge(classid, name, unit, example, note)
VALUES
("hoge", "hoge", "hoge", "hoge","hoge"),
("hoge", "hoge", "hoge", "hoge","hoge");
```

## テーブル内のデータ全削除
```sql
TRUNCATE TABLE hoge;
```
Mac で Unity を使うときに困ったこと

Mac で Unity を使おうとしたら厄介な場所で躓いたのでメモ。
これから Mac & Unity を使う方は注意して下さい。

以前[『Mac を初めて使うエンジニアにオススメする環境づくり』](http://qiita.com/koizumi_yakumo/items/ab9c8b2408558e58796c)でファイルシステムについて書いているのですが、Unityは逆に区別するとプロジェクトを作れない & 開けません。

具体的には以下のエラーメッセージが出ます。

```　message
The project is on case sensitive file system.
Case sensitive file systems are not supported at the moment.
Please move the project folder to a case insensitive file system.
```

ファイルシステムは変更しないほうが良さそうです。

# 愚痴

Unity の作りが悪いとしか思えない。
プロジェクト作る前にもわかるだろうし、
大文字・小文字を区別しないような特殊な環境macぐらいでは…。
アプリ内課金のstaticItem購入でハマったエラー

# 前提
In-app Billing　v3使用。
サンプルほぼそのまんま。

# 経緯
アプリ内課金でstatic Item(android.test.purchased)の購入をしようとしたら、

(1)verify signatureエラーが起き、

```
E/IABUtil/Security(5973): Purchase verification failed: missing data.
E/IabHelper(5973): In-app billing error: Purchase signature verification FAILED for sku android.test.purchased
```

(2)queryInventoryが失敗するようになった

```
Error refreshing inventory (querying owned items). (response: -1003:Purchase signature verification failed)
```

(3)とりあえずまた買おうとすると、

```
Unable to buy item, Error response: 7:Item Already Owned
```

こう出るので、じゃあ消費しようとするが、(2)の通りqueryInventoryが失敗するので、ownedListが取得出来ず、consumeができない

テストアカウントが社内で使い回しているアカウントなので、全員に影響が出るんじゃないかと、冷や汗ダラダラでした。

# 現象解除方法

ひとまず復元も何も出来なくなるので、いったんこの現象をクリアする必要がある。

(1)14日待つ
14日経てば消費されるという記述があったが、verifyが失敗しててもいいんだろうか？

(2)Playストアのデータを削除する
これしか無いようだ。
ということは、同じアカウントを使っている端末があったとしても、影響しないようだ。
（まあサーバーと通信してなさそうだから当たりまえか）
購入テストをする前に、Playストアアプリを一度起動しておくのを忘れないように。

# 購入を通過させる方法

さて、今後このテスト購入は通過させる必要がある。
購入後のフロー確認のためだけに、何度も購入＆消費を繰り返すのは大変だからだ。
特に、購入情報はサーバーにも置いているので、消費した場合、サーバー側も消してもらわないと行けなくて、担当者が別人で休んでたりするとお手上げだ。

ということで検索して、見つけました。

こちらに助けられました(ノД`)
http://yome9.blogspot.jp/2014/10/in-app-billing-v3.html

サンプルまんまなら、util.Securityというクラスがあるはずなので、以下のようにVerifyメソッドを修正する。

```java:Security.java

    private static boolean ignoreVerifyError = true;

    public static boolean verifyPurchase(String base64PublicKey,
                                         String signedData, String signature) {
        if (TextUtils.isEmpty(signedData) || TextUtils.isEmpty(base64PublicKey)
                || TextUtils.isEmpty(signature)) {
            Log.e("Purchase verification failed: missing data.");
            if (BuildConfig.DEBUG && ignoreVerifyError) {
                Log.w("!!!! DEBUG ONLY !!! ignoring VerifyError!!!");
                return true;
            }
            return false;
        }

        PublicKey key = Security.generatePublicKey(base64PublicKey);
        return Security.verify(key, signedData, signature);
    }
```

もっと几帳面にやるなら、signedDataからPurchaseクラスに入れて、productId(sku)もチェックするといいかも。
今回は、外からignoreVerifyErrorを指定して、通過させるかどうかを決定出来るようにしました。
データベースからすべてのラージオブジェクトを削除

###SQL
```sql:TRUNCATE_LARGE_OBJECTS.sql
SELECT lo_unlink(l.oid) FROM pg_largeobject_metadata l;
```
###「pg_largeobject_metadata」とは
>pg_largeobject_metadataはラージオブジェクトに関連したメタデータを保持します。 実際のラージオブジェクトデータはpg_largeobjectに格納されます。 

###「lo_unlink()」とは
>データベースからラージオブジェクトを削除する関数。引数はoid。

####参考資料（というかそのまま）：
 http://stackoverflow.com/questions/33138588/delete-all-large-objects-from-postgresql-database
ElixirでOrientDBにアクセスしてみる

## 1. 気になったこと

[以前の投稿](http://qiita.com/letusfly85/items/95054ba7446168772a30)で軽く、OrientDBに接続してみました。

GitHubやTwitter, Facebookなどから人物相関図を作りたいな、と思った時にはなかなかに便利そうなOrientDBですが、手動でぽちぽちとデータは登録したくはないですね。

せっかくなので、Elixirでなにかないかなー、とGitHubを検索すると下記がありました。

* https://github.com/MyMedsAndMe/marco_polo

便利な世の中です。。

## 2. 使ってみる

## 2-1. Mixプロジェクトに依存を追加する

```ex
  defp deps do
    [{:marco_polo, "~> 0.1"}]
  end
```

からの、mix.deps getをします。

## 2-2. iexで試してみた

`iex -S mix`して、使ってみます。

```ex
iex(1)> {:ok, conn} = MarcoPolo.start_link(user: "admin", password: "admin", connection: {:db, "GratefulDeadConcerts", :graph})

{:ok, #PID<0.383.0>}
```

これで、接続はできたようです。

次にクエリを投げてみます。

```ex
iex(4)> query = "select * from employee"
"select * from employee"
iex(5)> MarcoPolo.command(conn, query)  
{:ok,   
 %{linked_records: #HashDict<[]>,
   response: [%MarcoPolo.Document{class: "Employee",
     fields: %{"empno" => 101, "firstName" => "John", "lastName" => "Jacob",
       "out_WorksAt" => {:link_bag, [#MarcoPolo.RID<#19:0>]}, "sal" => 5000},
     rid: #MarcoPolo.RID<#17:0>, version: 2},
    %MarcoPolo.Document{class: "Employee",
     fields: %{"empno" => 102, "firstName" => "Adam", "lastName" => "Bill",
       "out_WorksAt" => {:link_bag, [#MarcoPolo.RID<#19:1>]}, "sal" => 7000},
     rid: #MarcoPolo.RID<#17:1>, version: 2},
    %MarcoPolo.Document{class: "Employee",
     fields: %{"empno" => 103, "firstName" => "David", "lastName" => "Manon",
       "out_WorksAt" => {:link_bag, [#MarcoPolo.RID<#19:2>]}, "sal" => 4000},
     rid: #MarcoPolo.RID<#17:2>, version: 2}]}}
```

`linked_records`なるものが取得されます。
この中で、リンクの属性があるものについては、`link_bag`というものが付与されて、Vectorが取得できるみたいです。

他にもデータ登録系のクエリもごくごく普通に登録できそうなので、なかなか便利だな＾＾　という印象です。

## 3. 感想

* [elixir-graphql](https://github.com/graphql-elixir/graphql)も使ってみたいです。
* [graphqlをphoenixで使うプロジェクト](https://github.com/graphql-elixir/hello_graphql_phoenix)で試してみようかな
* 集めたデータをいったん登録してみようと思います＾＾
* Neo4Jも触ってみたい。。

* [利用予定リポジトリ](https://github.com/letusfly85/github_star_net)

---

本日は以上となります。
h2oの後ろにRails、アクセス制限とHTTPをHTTPSへリダイレクト


先人たちが色々踏んでおり、h2oとRailsの組み合わせでの問題は特に無くなっているような気がしたので使ってみた。


h2oはただの`proxy.reverse`でも色々よしなするようで、設定はとても少なくて済む。
ファイルがあったら〜な処理も並べるだけで、次へ次へと進んでいく。ほかはセキュリティ要件などに応じて、それ系のヘッダをつけておく位でよいかな。

```yaml:h2o.conf
access-log: /dev/stdout
user: nobody

hosts:
  "*":
    listen: 80
    listen:
      port: 443
      ssl:
        certificate-file: certs/server.crt
        key-file: certs/server.key
    paths:
      "/":
        mruby.handler-file: limit_access.rb
        file.dir: /srv/app/public
        proxy.reverse.url: http://rails:8080/
        proxy.preserve-host: ON
```

これはDocker-Compose管理で、`rails`サービスにlinkしています。なので`file.dir`に指定しているpublicはVOLUMEです。


## アクセス制限とHTTP接続のリダイレクト

今回これにテスト環境用のアクセス制限と、HTTP=>HTTPSへのリダイレクトをつけることにしました。だったらmrubyかなー。

アクセス制限は下記で紹介されているmruby-ipaddress_matcherでします。

- 参考: [kaihar4.com - mruby-ipaddress_matcherを使ってh2oでIPアドレスベースのアクセス制御をする](https://kaihar4.com/2015/11/01/mruby-ipaddress_matcher.html)

で、リダイレクトの要件、ホスト名をコンフィグに書いてしまってよいならh2oの`redirect`でいいんですが、実はドメインがまだ決まってないとかそういうこともあるのでアクセス制限のついでにやることにしました。

IP制限部分は参考サイトにちょっと環境変数での分岐をつけて、IPを評価するまえに`env['rack.url_scheme']`をチェックして`http`なら出なおしてもらう処理を追加しました。もちろんハンドラを分けても大丈夫のはず。

```ruby:limit_access.rb
case ENV['ACL_ENVIRONMENT']
when 'public'
ALLOW_CIDRS = %w(
0.0.0.0/0
)
else
ALLOW_CIDRS = %w(
x.x.x.x/32
x.x.x.x/32
x.x.x.x/28
)
end

class Acl
  def initialize(*args)
    @allow_regexps = ALLOW_CIDRS.map {|cidr| IPAddressMatcher::CIDR.new(cidr).to_regexp }
    super
  end

  def call(env)
    if env['rack.url_scheme'] == 'http'
      return [301, {'Location' => "https://#{env['HTTP_HOST']}/"}, []]
    end
    if @allow_regexps.select {|allow_regexp| env['REMOTE_ADDR'] =~ allow_regexp }.empty?
      [403, {'Content-Type' => 'text/plain;charset=utf-8'}, ['Forbidden']]
    else
      [399, {}, []]
    end
  end
end

Acl.new
```

なお、ここに書いた例ではenv['HTTP_HOST']を直接Locationに使ってますが、HTTP1.0などで来られてHostヘッダがないとここはSERVER_NAMEと同じ値が入ります。先のh2oコンフィグでは"*"になっちゃいますね。
`HTTP_HOST`が空なら`REMOTE_ADDR`を使うようにすれば良いケースもあります。それもDockerの内部ネットワークを使うとコンテナのIPになってたりして微妙。まあ環境に応じて適当に変更します。


ついでにHSTSをしたい場合は`header.append: "Strict-Transport-Security: max-age=39420000"`と入れたりします。
Ubuntu14.04 への　Chainerのインストール中にsetuptoolsインスコで躓いたのでメモ


Ubuntu14.04へChainerをインストールするにあたって下記のコマンドで関連ライブラリのインストールをしていきました。
参考はイラストで学ぶディープラーニング

<ul>

<li><a href="http://www.amazon.co.jp/%E3%82%A4%E3%83%A9%E3%82%B9%E3%83%88%E3%81%A7%E5%AD%A6%E3%81%B6-%E3%83%87%E3%82%A3%E3%83%BC%E3%83%97%E3%83%A9%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0-KS%E6%83%85%E5%A0%B1%E7%A7%91%E5%AD%A6%E5%B0%82%E9%96%80%E6%9B%B8-%E5%B1%B1%E4%B8%8B-%E9%9A%86%E7%BE%A9/dp/406153825X
" target="_blank" >イラストで学ぶディープラーニング</a><i class="fa fa-external-link"></i></li>
</ul>

```
$ sudo apt-get install python2.7
$ sudo apt-get install python-numpy
$ sudo apt-get install libhdf5-dev
$ sudo pip install -U setuptool
$ sudo pip install -U cython
```

しかしここでsetuptoolのupgaradeがうまくいかなくなった。
こんなエラーで止まる。

```
  Could not find a version that satisfies the requirement setuptool (from versions: )
No matching distribution found for setuptool
```

調べていくとどうやらpipのバージョンが古いと
アップグレードが上手くいかない事があるらしい
<ul>

<li><a href="https://daichiahl.wordpress.com/2016/01/15/chainer-1-5-1%E3%82%92ubuntu14-04%E3%81%AB%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB/" target="_blank" >Chainer 1.5.1をUbuntu14.04にインストール</a><i class="fa fa-external-link"></i></li>
</ul>


下記のコマンドでアップグレードする
```
$ sudo pip install --upgrade pip
```

pipが7.1.2から8.1.1へアップグレードされる

```
.
.
Collecting pip
  Downloading pip-8.1.1-py2.py3-none-any.whl (1.2MB)
    100% |████████████████████████████████| 1.2MB 584kB/s 
Installing collected packages: pip
  Found existing installation: pip 7.1.2
    Uninstalling pip-7.1.2:
      Successfully uninstalled pip-7.1.2
Successfully installed pip-8.1.1
```

pipのバージョンを確認

```
$ pip -V
pip 8.1.1 from /usr/local/lib/python2.7/dist-packages (python 2.7)

```

再度setuptoolsのアップグレードを上記参考サイトの手法で実施した

```
$ sudo pip install --upgrade setuptools
```

最終的にsetuptools-20.7.0のインストールに成功

```
.
.
.
Collecting setuptools
  Downloading setuptools-20.7.0-py2.py3-none-any.whl (508kB)
    100% |████████████████████████████████| 512kB 2.8MB/s 
Installing collected packages: setuptools
  Found existing installation: setuptools 3.3
    Uninstalling setuptools-3.3:
      Successfully uninstalled setuptools-3.3
Successfully installed setuptools-20.7.0
```


※後で正の方のコマンドで再インストールかけたら上手くいったので
　多分この問題は参考にした本の下記のコマンドsetuptools->setuptoolの誤記が原因?

```
誤　$ sudo pip install -U setuptool
正　$ sudo pip install -U setuptools

正の結果
Requirement already up-to-date: setuptools in /usr/local/lib/python2.7/dist-packages

```
よく使うgitコマンドのエイリアスを設定して開発効率をアップする

gitコマンドを打つのがダルかったりtypoしまくるので、よく使うコマンドのエイリアス（ショートカット）を設定して開発速度を若干上げる。

# エイリアスの設定
`git config [option] alias.短縮形 展開形` でエイリアスを設定する。

例えば以下のような感じ

```
$ git config --global alias.st status
$ git config --global alias.co checkout
$ git config --global alias.br branch
$ git config --global alias.cm commit
$ git config --global alias.df diff
$ git config --global alias.gr grep
```

これで `git status` が `git st` でいけたりする。


## 設定レベル
オプションで設定レベル（適用範囲）を指定できる。

| 設定オプション | 適用範囲 | 設定レベル |
|:-----------|:------------|:------------|
| オプションなし       | リポジトリ固有 |     3     |
| --global       | Gitユーザー固有 |     2     |
| --system       | マシン全体 |     1     |

優先度は、リポジトリ > ユーザー > マシン

#gitコマンドも省略する
もはや`git`って打つのもダルくね？
`$ alias g='git'`
これで `git status` が `g st` でいける。

オプション含めてもっと短くもできるので好きにカスタマイズしよう。

# 設定の確認方法
エイリアスなに設定したか忘れたら
`$ git config --global --list | grep ^alias\.`
で確認しよう。

#参考
- [エンジニアのためのGitの教科書 実践で使える！バージョン管理とチーム開発手法](http://www.amazon.co.jp/dp/B01AIB438A/)
- [gitで便利なエイリアス達 - Qiita](http://qiita.com/peccul/items/90dd469e2f72babbc106)
【簡単API実装】SilexによるAPI開発(EC2上にゼロベースから開発環境構築からSilex入門まで)

さくっと簡単なAPIを実装したいときにフレームワークで開発すると実装が大袈裟になりますが、そこで便利なマイクロフレームワーク。



[PHPのマイクロフレームワークまとめ](http://matome.naver.jp/odai/2139135784828113601)にPHPのさまざまなマイクロフレームワークがまとまっていますが、聞いたことがないものまで数多くあります。

有名どころではSilexやSlimなどが挙げられますが、今回はSilexをAWSのEC2インスタンス上にゼロベースで開発環境を構築し、Silex入門まで取り上げます。


#httpdのインストール

```bash
yum install httpd -y
service httpd start
httpd -v
chkconfig httpd on
chkconfig --list httpd
```

#PHP環境のインストール
```bash
yum install php php-devel php-mysql php-gd php-mbstring -y
```

#PHP バージョンのアップデート
インストールされたPHPのバージョンが古いのでPHP 5.6にアップデート

```bash
yum remove php-* httpd-*
sudo wget http://rpms.famillecollet.com/enterprise/remi-release-6.rpm
sudo rpm -Uvh remi-release-6.rpm
sudo yum install php56 php56-devel php56-fpm php56-mysqlnd php56-mbstring php56-opcache
```

#composerのインストール
```bash
curl -sS http://getcomposer.org/installer | sudo php
sudo mv composer.phar /usr/local/bin/composer/composer.phar
```
#Silexのインストール
##/user/local/bin/composer以下にcomposer.jsonを作成
```text:composer.json
{
    "require": {
        "silex/silex": "1.0.*@dev"
    }
}
```

##Composerの実行
```bash
cd /user/local/bin/composer
php composer.phar install
```

#ドキュメントルートの変更
Aliasの設定をしないと、http://{IP Address}/index.php やhttp://{IP Address}/index.php/api のようにアクセスしないといけないので、 http://{IP Address}/ やhttp://{IP Address}/api でアクセスできるようにする。

/etc/httpd/conf/httpd.conf
に以下を追加してhttp://{IP Address}/ のアクセスはすべてhttp://{IP Address}/index.php へエイリアス

```text
<IfModule alias_module>
    Alias / "/var/www/html/index.php/"
</IfModule>
```

Webサーバを再起動

```bash
sudo service httpd restart
```


#SilexによるAPIのソースコード
```php:index.php
<?php

use Symfony\Component\HttpFoundation\Request;
require_once "/usr/local/bin/composer/vendor/autoload.php";


// Generate Silex object
$app = new Silex\Application();

// Access to http://{IP Address} => Return strings of 'Hello, World.'
$app->get('/', function() {
        return 'Hello, World.';
});


// Access to http://{IP Address}/api => Return strings of 'Hello, specific API'
$app->get('/api', function() {
        return 'Hello, speific API';
});


// Access to http://{IP Address}/api/7 => Return strings of 'Hello, specific API with 7'
$app->get('/api/{id}', function(Request $request, $id)  use ($app) {
        return 'Hello, specific API with '.$id;
});


// Execute Silex application
$app->run();
```
proxy環境でvagrantでVM作るとき、vagrantfileに書いたことまとめ

一身上の都合により転職し、proxy通さないと色々通信できない、フルオープンだった今までより少し不便な環境に身を置いています。  

ローカルのnodejsな開発環境をvagrantで構築しようとして主にproxyの罠を踏み抜きまくったので、僕がvagrantfileに書いたproxy設定等を備忘録としてまとめてみます。

# yum
``yum update``したりgitの依存パッケージ入れるためにyumは必須…  

```sh
if ! grep -Fxq 'proxy=proxy:port' /etc/yum.conf;
then
  sudo sh -c "echo 'proxy=proxy:port' >> /etc/yum.conf"
fi
```

# curl
.curlrcつくる

```sh
[ ! -f ~/.curlrc ] && echo 'proxy="proxy:port"' > ~/.curlrc
```

# wget
.wgetrcつくる

```sh
[ ! -f ~/.wgetrc ] && echo 'http_proxy="proxy:port"' > ~/.wgetrc
```

# git
yumとcurl/wgetが出来るようになったので、gitがインストールできるようになりました。gitにもproxy設定をしましょう。

```sh
git config --global http.proxy proxy:port
git config --global https.proxy proxy:port
```

# bash
bashはproxyというよりパスでハマってました。
vagrantfileで~/.bashrcや~/.bash_profile弄ろうとすると、``/root``にあるやつを弄ろうとしちゃうので、``/home/vagrant/``と書いてあげておくのがポイントだそうです。

```sh
if ! grep 'proxy=proxy:port' /home/vagrant/.bashrc;
then
  sudo sh -c "echo 'export http_proxy=proxy:port' >> /home/vagrant/.bashrc"
  sudo sh -c "echo 'export https_proxy=proxy:port' >> /home/vagrant/.bashrc"
  source /home/vagrant/.bashrc
fi
```

# node/npm
上記までの設定でnvmとnvmからnodeがインストールできるようになりました。  
あとはnpm最新にしたら…！。npmもproxy必要です。

```sh
npm config set proxy proxy:port
```

# めもおわり
vagrantfileに色々入れんでansibleで良いなーとも思ったりしましたが、ちょちょいっとやるにはやりすぎな気もしたと言い訳しておきます。