OmniAICreator/Qiita-1.07M huggingface dataset:
docker-machineでguest to hostの通信をする


## 環境

- MacOSX Yosemite
- docker 1.9.1
- docker-machine 0.5.3

## 概要

dockerで作成したコンテナからMacOSXへポートで通信したかったが、docker-machineが間に立ってるので出来なかった。

結論から言うと、docker-machineからMacOSXへSSH port forwardすることで解決した。

## docker network

dockerのネットワークはデフォルトで `172.17.0.0` を使用する。
dockerデーモンを起動しているホスト側に通信したい場合、 `172.17.0.1` を指定すれば良い。

## docker-machine

docker-machineはデフォルトでvirtualboxをプロバイダにして動作する。
virtualbox上にboot2dockerのVMが起動して、そのVMを介してコンテナとやりとりを行っている。

ハマりどころとしては

- （MacOSXでは） `/Users` のみをboot2dockerへマウントする
- docker-machineからコンテナへのポートフォワーディングは自動で行ってくれるが、docker-machineホストからコンテナへのポートフォワーディングは行ってくれない（逆も）

## docker container(guest) to host OS

前述のとおりコンテナからホスト側には `172.17.0.1` を指定すれば通信出来るが、このホスト側は **docker-machine** のことを指す。
そのため例えば、「コンテナからMacOSXで起動しているMySQLに接続したい」などの時に困ることとなる（今回はコレ）。

## 解決策

**docker-machine上でSSHポートフォワーディングする**

以下、docker-machineの名前が `default` としてコマンド例。

```shell
$ docker-machine ssh default
Boot2Docker version 1.9.1, build master : cef800b - Fri Nov 20 19:33:59 UTC 2015
Docker version 1.9.1, build a34a1d5
docker@default:~$ ssh -gfNL 3306:localhost:3306 usename@192.168.60.1 -p22 # ユーザ名はMac側のユーザ名
```

SSHのポートフォワーディングについては詳しくはここでは説明しません（ぐぐれば出てきます）
コレを実行することで、docker-machineへの3306ポートへの接続をMacOSX側の3306ポートへとforwardingすることが出来ます。
MacOSX側のIPが `192.168.60.1` となっていますが、僕はdocker-machineのネットワークを `192.168.60.1/24` に指定して作成したためコレになっています。

```shell
$ docker-machine create --driver virtualbox --virtualbox-hostonly-cidr 192.168.60.1/24 default
```

わからない場合のネットワークの確認方法はいくつかありますが、docker-machine上で確認するのが一番手軽だと思います。
`ip addr` とか打ってそれっぽいのがそうです（多分eth1）

## 解決してないこと

ログインせずに `docker-machine ssh default ssh -gfNL 3306:localhost:3306 usename@192.168.60.1 -p22` って実行すると、ttyが繋ぎっぱなしになって帰って来ない
というか、 `docker-machine` 関係なく（普通のsshでも）帰ってこない……。
向こう側ではちゃんとコマンド実行されてるのになー。なんでだろう。
誰かおしえてください＼(^o^)／

## おまけ

docker-machineのSSH鍵は `~/.docker/machine/machines/default/` に設置されています（machine名が `default` の場合）
コンテナからSSHでdocker-machine側にNOPASSWORDしたい場合は、このディレクトリを `~/.ssh` としてコンテナ側にマウントしてやればOKでした。

```
$ docker run -v $HOME/.docker/machine/machines/default:/root/.ssh` hoge /bin/bash
```
PHP7の上で Zend Framework 2.5 を動かす②

「[PHP7の上で Zend Framework 2.5 を動かす](http://qiita.com/mighty5/items/80033f99dc34cf0fb526)」を書いてから、『もっとスマートにでき方法ないのかな〜』と探っておりまして、『あっそういえば、[Githubに気になるコマンド](https://github.com/zendframework/ZendSkeletonApplication#installation-using-composer)があったけど、あれ実行するとどうなるの？』ということで、やってみました。

『わお。全部入じゃないですか！』

#結論#
[composerが動くなら](http://qiita.com/CatCable/items/02364adacf36410f449e#%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%A7%E5%85%A5%E5%8A%9B)、セットアップしたいディレクトリに移動し

```apache:composer
composer create-project -n -sdev zendframework/skeleton-application ./cocodajo
```

これで実行後に出来上がる`./cododajo`ディレクトリの中に、
その時点で<b>最新のZF2.5以降がインストール</b>されてる！
なんとあっさり、でもコクがある（まるで京都ラーメンだね）

この記事を書いた時点では`./cocodajo/vendor/zendframework`
の中にフレームワークの部品が一式入っていました。

##ちなみにcomposerのインストールは##
http://mawatari.jp/archives/install-composer-in-mac
一応「mac」とありますが基本は同じなので、どの階層からでも`composer`一発で呼び出せて便利。

#気づいたこと#
Zend社はZendFramwrowk2.5推しでcomposerインストールを推進しているのですね。

もう`library`がなくなっているということは、これを抜き出して部品として自由に使って行ってねというメッセージなんでしょうねぇ。もはやPEARは スガシカオの「あまい果実」のようですから。

ZendFramework2って、日本語であまり追いかけられてないし、なんかとっつきにくかったので「ZF2.5になってもっと高度にややこしくなってるんじゃね？」って疑心暗鬼で見られてるんじゃないかな？でもcomposerでのインストールの敷居の低さからして「色々とシンプルに使いやすくしてみましたがいかがでしょう？」みたいなのも伝わって来ます。たぶんトレンドは急速にPHP7になるはずなので（爆速はスルー出来ないっしょ）また本命になるのかな。

#自分メモ#
開発時、自分も含めみんなの思想を揃えるために…
[ZendFramework2の入門から極意まで徹底解説](http://zf2.t-pg.net/)
[PSR-2に準拠した PHP コードを書いてみて気づいたこと](http://bashalog.c-brains.jp/15/08/13-100000.php)
[CentOS 7 に LAMP 環境を構築する手順](http://weblabo.oscasierra.net/apache-installing-apache24-yum-centos7-1/) CentOS7はapache2.4入れる前提なんですね。
Android TextureView、SurfaceViewで簡単にスプライトシート アニメーション 〜FPSAnimator〜

#SpriteSheetアニメーションの作成

FPSAnimatorの基本的な使い方は<a href="http://qiita.com/MasayukiSuda/items/4e0eff096ae2e7183f3a">こちら</a>に記述しました。
今回の記事ではSpriteSheetに関して詳しく書きます。


<img src="https://raw.githubusercontent.com/MasayukiSuda/FPSAnimator/master/art/spriteSheet.gif" width="38%">


1. SpriteSheetDrawerを作成
インスタンス作成時に、SpriteSheetのBitmap frameWidth、frameHeight、スプライトシートのフレーム数をコンストラクタに入力。

2. DisplayObjectを生成し、FPSTextureView、FPSSurfaceView or ContainerにAddする。
withの後にTweenアニメーションをするならばtween()、放物線運動のアニメーションを行うならparabolic()を記述。

```
    SpriteSheetDrawer spriteSheetDrawer = new SpriteSheetDrawer(
            spriteBitmap, 
            frameWidth, 
            frameHeight, 
            frameNum);

    DisplayObject displayObject = new DisplayObject();
    displayObject
            .with(spriteSheetDrawer)
            .tween()
            .tweenLoop(true)
            .transform(-frameWidth, windowHeight / 2)
            .toX(3000, windowWidth)
            .end();

    mFPSTextureView
                .addChild(displayObject);
```


#SpriteSheetDrawerのプロパティ

| 関数名 | 機能 |
|:---|:-----|
|spriteLoopNum(int) | スプライトシートアニメーションのループ回数を指定できます |
|dpSize(context) | スプライトシートの描画を、Bitmapをそのままのサイズではなく、デバイス密度に合わせたサイズで表示 |
|spriteLoop(boolean) | trueでspriteアニメーションが再生され続けます。ただし、spriteLoopNumが指定されていた場合、無視されます |
|frequency(int) | FPSに対して、どれだけの頻度でスプライトシートアニメーションを更新するかを入力できます。例えば、全体のFPSが30でfrequencyが2になっている場合、FPS15でスプライトシートアニメーションが再生されます。 |
|spriteAnimationEndCallBack(AnimCallBack) | スプライトシートアニメーションが最後のフレームに到達した際、リスナーをセットできます。 |
|spritePause(boolean) | スプライトシートアニメーションを一時中止させることが可能です。trueにすれば再開します。 |
|customFrameList(List<Integer>) | Integer配列を入れることにより、その配列の順番でスプライトシートアニメーションが動きます。 |

記述例

```
        // 0〜26までスプライトシートフレームが再生
        List<Integer> list = new ArrayList<Integer>();
        for (int i = 0; i <= 26; i++) list.add(i);

        SpriteSheetDrawer spriteSheetDrawer = new SpriteSheetDrawer(spriteBitmap,
                frameWidth,
                frameHeight,
                frameNum)
                .dpSize(this)
                .customFrameList(list)
                .frequency(2)
                .spriteLoopNum(3)
                .spriteAnimationEndCallBack(new AnimCallBack() {
                    @Override
                    public void call() {
                        // 3回スプライトシートアニメーションが実行された際にdispatchされる。
                    }
                });



```

ぜひ、libraryにgithubのStarをお願いします。
<a href="https://github.com/MasayukiSuda/FPSAnimator">FPSAnimator</a>
Javaにおける日付の整形について

日付を扱う場合、想定していなかった
動きとなりましたので、記載しておきます。

Androidアプリを作成していて、サーバサイド側からJSONの形で
日付情報を受け取り、整形しようとしたとき実行時例外が発生しました。

処理概要
1.Androidアプリから、サーバサイドにGETリクエスト送付
2.サーバサイドからJSONの形でレスポンスを送付
3.Androidアプリでレスポンスを受け取って以下処理
　a.日付をString型→Date型に変換
　b.Date型→String型に変換（フォーマット整形）
4.Androidの画面上に日付表示

3-a、3-bの処理だけ抜粋
入力するデータ：2016-02-14T12:41:57.000Z
出力したいデータ：2016/02/14 12:41

NGケース

```jikan.java
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date formatDate = sdf.parse(jsonObject.getString("created_at"));
SimpleDateFormat format2 = new SimpleDateFormat("yyyy/MM/dd HH:mm");
String format_after = format2.format(formatDate);
Log.d("debug",format_after) // sdf.parse()で、java.text.ParseException
```

修正箇所

```java
before SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
after  SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
```

以下のページによると、日付のフォーマットはW3Cで表記法が制定されていて、合計６種類あるそうです。Java内部の動き含めて、もう少し勉強したいと思います。

（参考）日付の表記に関するノート
http://www.kanzaki.com/docs/html/dtf.html
Wordpressで「""」(ダブルクォーテーション)が「“”」(引用符)に置換される条件を検証してみた


#Wordpressでは基本的に、「""」は「“”」に、「''」は「‘’」に置換される

みなさん、これって知ってました？

私は記事を300件ほど更新してきて編集作業も板についてきたかな、って時に気づいて愕然としています。

そういえば昔、どっかの個人ブログのcssをコピペしたら(もちろんコピペOKのサイト)、謎のエラーに悩まされてよく見たらダブルクォーテーションが全角になっていて「どんな嫌がらせだよ！」と叫んだことがありました。

これは、Wordpressのデフォルトの仕様だったんですね……。

なんですが、置換後の「“”」(引用符)が、「“」(左ダブル引用符)と「”」(全角のダブルクォーテーション)の組み合わせにならないことがままあることに気づいたんです。

ということで、今回は私の備忘録がてら、引用符が置換される条件を検証してみました。

##検証結果

####▼置換前


これは"テスト"です

これは "テスト" です

これは " テスト " です

"これ"はテストです

"これ" はテストです

" " "" """

####▼置換後

これは”テスト”です

これは “テスト” です

これは ” テスト ” です

“これ”はテストです

“これ” はテストです

” ” “” “””

となったので、次の結論が導き出されます。

##結論

1. 「"」は、基本的に「”」に置換される。

2. 直前に半角スペースorタグ(改行含む)があり、直後に文字がある場合のみ、「“」に置換される

よって、引用符を使う場合は、その囲いの外に半角スペースを入れればいい、ということが分かりました。

これは、とても “重要な” 発見ですね。

まあ、「カギ括弧」を使えば一発で解決なのですが。


##置換を停止する方法
Wordpressの設定を変えて、置換できなくするには、

```ruby:functions.php
remove_filter('the_content', 'wptexturize');
remove_filter('the_excerpt', 'wptexturize');
remove_filter('the_title', 'wptexturize');
```

ひとまずは、「functions.php」のこの3行を足すだけでOKです。
ただ、これはあくまで急場しのぎで、コメント欄に対応してないし、ダブルクォーテーション以外の特殊文字の置換も停止します。もっと細かく設定したい時は、関数の中身を書き換えるか新しい関数を作るのが早いっぽいですね。

##「“”」はどんなシチュエーションで使うべき？

英語圏のジェスチャーにあるように、「“”」で囲まれた単語は、(ほんとはそうじゃないんだけどね……)という皮肉の意味になってしまいます。

What a "funny" joke!

みたいな。

また、文全体で囲われている場合は、単なる引用の意味で使われることが多いようです。

日本語の引用は、「」が使われることが多いですし、基本的に日本語の記事を書くにあたって「“”」は避けるのが無難なのかもしれませんね。
PHPの記法メモ1

PHPの基本的な記法のメモです。
今までJavaしか触っていなかったので、Javaとの違いに着目しています。

#出力
```echo("Hello Java!");```

#変数
変数を使用するときは宣言時も呼び出し時も"$"を頭につけます。
```$str = "Hello";```
```$str = 64;```
```$str = true;```
Javaとは違って、型を記述する必要がありません。

#配列
配列を宣言するときは二通りのやり方があります。
```$str = array["あか","あお","きいろ"];```
```$str = ["あか","あお","きいろ"];```
この2つは同じ結果になります。

文字列をキーとした連想配列はこのように記述します。
```$str = ["あか"=>"りんご","あお"=>"鯖","きいろ"=>"パイナップル"];```

#Stringの結合
phpでは文字列の結合に"."演算子を使います。
文字列同士を"+"演算子で結合することはできません。

```$hoge1 = "Hello";```
```$hoge2 = "Java!";```
```$hoge3 = $hoge1.$hoge2```
```echo $hoge3```

![hoge.PNG](https://qiita-image-store.s3.amazonaws.com/0/109506/3832f809-89b8-5767-db93-5a40049b8d09.png)


#シングルクォートとダブルクォート
PHPではダブルクォートで括られた変数は変数として解釈をされます。

```$hoge = "Hello";
echo "$hoge Java!"``` →　```Hello Java!```

変数としての解釈を避けたいときはシングルクォートで括りましょう。

```$hoge = "Hello";
echo '$hoge Java!'``` →　```$hoge Java!```

![hoge2.PNG](https://qiita-image-store.s3.amazonaws.com/0/109506/84cfbba0-b8c7-554b-608f-aa880cc85b5b.png)

#if文
PHPのif文はJavaと同じのようです。
比較演算子はJavaと一致しているので、変数の前に"$"がつくことにさえ気をつければ同じように使えます。

![hoge3.PNG](https://qiita-image-store.s3.amazonaws.com/0/109506/64e7f666-8527-7a11-5e40-d45cae590750.png)


#for文
PHPのfor文は基本的にはJavaと同じです。
カウンター変数の前に必ず"$"がつくことに気をつけましょう。
```for($i=0; $i<count($array); $i++){
　　　echo $array[$i]};```
配列の長さを求める記述がphpの場合は```count($array)```となります。
Javaにおける```array.length```と同じ結果になります。

##for-each文
foreach文はこのような書き方になります。
出力先の型を意識しなくて良い分Javaより分かりやすい感じを受けました。
```foreach($array as $i){
　　　echo "$i";}```

また、PHPにはfor-each文にもう一つ書き方があります。
```foreach($hoge as $i):
	　　　echo $i;
endforeach;```
という書き方です。通常のforeach文で使う波括弧"{}"の代わりに、":"から始まり"endforeach;"で括ります。
各行をhtmlに埋め込む際に可読性が上がるとのことです。

![hoge4.PNG](https://qiita-image-store.s3.amazonaws.com/0/109506/2d22ce14-95e1-427e-0667-c381368fdd13.png)
（ありきたりなfor文）
githubのプルリクのコメントがwebhookされない

# 問題
プルリクのdiffに対するコメントは飛んでくるのに、プルリク自体のコメントは飛んでこない。。。
Files Changedの会話は飛んでくるのに
[![https://gyazo.com/170908c76186dab9a1e2549ad25aba3d](https://i.gyazo.com/170908c76186dab9a1e2549ad25aba3d.png)](https://gyazo.com/170908c76186dab9a1e2549ad25aba3d)

Conversationの会話が飛んでこない
[![https://gyazo.com/ea560df3ca6a906de6e03e2b62f9550b](https://i.gyazo.com/ea560df3ca6a906de6e03e2b62f9550b.png)](https://gyazo.com/ea560df3ca6a906de6e03e2b62f9550b)

# 答え
この設定だとwebhookされない
[![https://gyazo.com/75f3fb6002bf2a5603a5f0ac125f3f4d](https://i.gyazo.com/75f3fb6002bf2a5603a5f0ac125f3f4d.png)](https://gyazo.com/75f3fb6002bf2a5603a5f0ac125f3f4d)

issue commentを入れるとと飛んでくる
[![https://gyazo.com/196a8113b7c57569a698b40c2b91d03a](https://i.gyazo.com/196a8113b7c57569a698b40c2b91d03a.png)](https://gyazo.com/196a8113b7c57569a698b40c2b91d03a)

https://developer.github.com/webhooks/#events
[![https://gyazo.com/db4f87ae2a3cd2689078ead077fd150c](https://i.gyazo.com/db4f87ae2a3cd2689078ead077fd150c.png)](https://gyazo.com/db4f87ae2a3cd2689078ead077fd150c)
名前わかりにくいよぉぉ。。。


以上、誰かの役に立てば。
画面録画して動くGIFに変換できるアプリを使って見ました。

#Qiitaなどに記事を掲載する時に画面の動きを動くGIFで載せたいと思う方が大勢いると思います。私もその一人です。

今回はそのアプリを実際使ってみた感想を書いてみました。　

>Googleで検索して**Recordit**っているアプリを設置してみました。
>簡単に動くGIFが生成されサーバーまで転送されてURLが生成されるのでURLを貼り付けだけで済むからこれは便利だな。。。。と思いました。
>でもあれ！！**もし間違えて画面上の個人情報がそのままサーバーに転送されたらどうなるんだろう。。**って疑問を感じってすぐ削除してローカルでできるアプリを使うか今回作ってみようかと思いました。
最近、便利すぎて個人情報がいつ漏れるか心配になりますね。
使わないといけない場合もあるので使うとき個人情報に気を付けながら使うしかないと思います。

これをきっかけに個人情報の管理に気をつけたいと思います。
**個人情報が漏れた後は遅いです。皆さま気を付けましょう。**
Apache Virtual Host で存在しないURLでアクセスするとディレクトリ内の意図せぬvhost設定が読みこまれる

はまったのでメモ

#現象
開発サーバーに **aa.sample.com** というドメインを割り振り、Apacheのバーチャルホスト機能でドキュメントルートを設定。

今回のバーチャルホストは **/etc/httpd/vhosts** に格納されており、ファイル名は**aa.sample.com.conf** としていました。
（バーチャルホストの設定方法は[こちら](http://qiita.com/terrym/items/ba988394fbe6099b4485)から）

そして、この開発サーバーには別のドメインも割り振られていてました。
仮に **dummy.whizzy.co.jp** とします。

**dummy.whizzy.co.jp** は、過去にはgoogleのクロール対象ともなっていましたが、コンテンツを破棄し既に運用していません。
従い、 **dummy.whizzy.co.jp** のdocument root は空の状態です。

また、バーチャルホストの設定 (confファイル) も破棄しているため、**dummy.whizzy.co.jp** については、ドメインが開発サーバーを向いているだけという状態です。（DNS設定を削除し忘れ）

このように **dummy.whizzy.co.jp** についてはバーチャルホストの設定をしていないため、 **dummy.whizzy.co.jp** にアクセスすると、デフォルトのドキュメントルー **/var/www/html** を見に行くであろうと考えていたため全く考慮しておりませんでした。

***しかし、ここに落とし穴があったのです！***

vhostが設定されていないURLの場合、WebサーバーのApacheの挙動としてバーチャルホストの設定ファイルのうち、アルファベット順で一番早いファイル（今回は、 **aa.sample.com.conf** ）を見に行くという挙動を行っていたようで（下記参考URL参照）、結果として **dummy.whizzy.co.jp** が **aa.sample.com** と同一内容になってしまっていました。

更に **dummy.whizzy.co.jp** は過去にGoogleのクロール実績があったため、**aa.sample.com** にアップロードした内容が **dummy.whizzy.co.jp** としてGoogleにインデックスされてしまいました。

#解決策
1.conf を作り、そこで default の **/var/www/html** 等を見るようにしておき、そこには当たり障りのないコンテンツを置いておく。

#参考URL
[http://blog.flatlabs.net/20100301_204946/](ApacheのVirtualHostについて、設定してあるServerNameに一致しないドメインには、一番最初の設定が適用されます。)

#後日談
googleにindexからの削除要請をして、ようやく見えなくなりました。
Vagrant boxを小さくする

Googleで検索すると、Vagrant boxを小さくする方法が色々と公開されていたりしますが、ざっくりとまとめてみます。

```
sudo su -
umount /vagrant
aptitude autoclean && apt-get autoremove && apt-get clean
find /var/log -type f | while read f; do echo -ne ‘’ > $f; done && rm -rf /var/log/* /tmp/* /var/tmp/* /usr/local/src/* /var/ww/html
e4defrag / && dd if=/dev/zero of=/EMPTY bs=1M; rm -f /EMPTY
rm /root/.bash_history && /home/vagrant/.bash_history
exit
```

こんな感じ。
要は、ゴミを消してデフラグして、空いた領域をゼロクリア埋めする感じですね。
ちょいと、Ansibleのplaybook化してみました。

ちなみに、以前書いた「[UbuntuのVirtualBox向けEFI対応](http://qiita.com/poad1010/items/8c143b06b4575eb1be12)」の対応内容も合わせて入れています。

https://bitbucket.org/poad1010/ansible-playbook/src/e052413a86b8a2aa9957046adf36187426463ef4/ubuntu-vagrant-box/?at=master
arduinoでジャイロ

#概要
arduino unoにジャイロセンサーをつないで見ました。
L3GD20は、SPIで接続します。ライブラリー書きました。
#ログ
![kaku.JPG](https://qiita-image-store.s3.amazonaws.com/0/18104/af49eaed-c6ff-3db7-d4e5-d2a6e86e6ad4.jpeg)
#写真
![MVC-015S.JPG](https://qiita-image-store.s3.amazonaws.com/0/18104/ffc33ba2-910f-7dc0-25cc-ed007a55a8d2.jpeg)
#回路図
![l3gd20.JPG](https://qiita-image-store.s3.amazonaws.com/0/18104/2ece7db3-efe6-7d25-727d-c50a88ffdf21.jpeg)
#ライブラリー
https://github.com/ohisama/L3GD20
#サンプルコード
```
#include <SPI.h>
#include <L3GD20.h>

L3GD20 gyro(10);
int dc_offsetX = 0;
int dc_offsetY = 0;
int dc_offsetZ = 0;
unsigned long time;
int rateX;
int rateY;
int rateZ;
int prev_rateX = 0;
int prev_rateY = 0;
int prev_rateZ = 0;
double angleX = 0;
double angleY = 0;
double angleZ = 0;
void setup()
{
	int sampleNum = 500;
	short X, Y, Z;
	float x, y, z;
	Serial.begin(115200);
	Serial.print("start\t");
	gyro.begin();
	Serial.println(" ok!");
	for (int n = 0; n < sampleNum; n++)
	{
		X = gyro.read(L3GD20_X_H);
		x = (X << 8) | gyro.read(L3GD20_X_L);
		dc_offsetX += (int) x;
		Y = gyro.read(L3GD20_Y_H);
		y = (Y << 8) | gyro.read(L3GD20_Y_L);
		dc_offsetY += (int) y;
		Z = gyro.read(L3GD20_Z_H);
		z = (Z << 8) | gyro.read(L3GD20_Z_L);
		dc_offsetZ += (int) z;
	}
	dc_offsetX = dc_offsetX / sampleNum;
	dc_offsetY = dc_offsetY / sampleNum;
	dc_offsetZ = dc_offsetZ / sampleNum;
	Serial.print(" X: ");
	Serial.print(dc_offsetX);
	Serial.print(" Y: ");
	Serial.print(dc_offsetY);
	Serial.print(" Z: ");
	Serial.println(dc_offsetZ);
}
void loop()
{
	int sampleTime = 10;
	short X, Y, Z;
	float x, y, z;
	if (millis() - time > sampleTime)
	{
		time = millis();
		X = gyro.read(L3GD20_X_H);
		x = (X << 8) | gyro.read(L3GD20_X_L);
		Y = gyro.read(L3GD20_Y_H);
		y = (Y << 8) | gyro.read(L3GD20_Y_L);
		Z = gyro.read(L3GD20_Z_H);
		z = (Z << 8) | gyro.read(L3GD20_Z_L);
		rateX = ((int) x - dc_offsetX) / 100;
		angleX += ((double) (prev_rateX + rateX) * sampleTime) / 2000;
		prev_rateX = rateX;
		if (angleX < 0)
		{
			angleX += 360;
		}
		else if (angleX >= 360)
		{
			angleX -= 360;
		}
		rateY = ((int) y - dc_offsetY) / 100;
		angleY += ((double) (prev_rateY + rateY) * sampleTime) / 2000;
		prev_rateY = rateY;
		if (angleY < 0)
		{
			angleY += 360;
		}
		else if (angleY >= 360)
		{
			angleY -= 360;
		}
		rateZ = ((int) z - dc_offsetZ) / 100;
		angleZ += ((double) (prev_rateZ + rateZ) * sampleTime) / 2000;
		prev_rateZ = rateZ;
		if (angleZ < 0)
		{
			angleZ += 360;
		}
		else if (angleZ >= 360)
		{
			angleZ -= 360;
		}
		Serial.print("X: ");
		Serial.print(angleX);
		Serial.print(" rate: ");
		Serial.print(rateX);
		Serial.print(" Y: ");
		Serial.print(angleY);
		Serial.print(" rate: ");
		Serial.print(rateY);
		Serial.print(" Z: ");
		Serial.print(angleZ);
		Serial.print(" rate: ");
		Serial.println(rateZ);
	}
}
```
kubenetes(v1.1)でdocker private registryを利用する (AWS)

kubernetesでコンテナイメージをdocker hubではなく、自分でたてたprivate registryからpullする。
すべてAWS上で実現します。
※シンプルにprivate registry用EC2 ×１台と、kubernetes(master/minion兼用)用EC2 ×１台を同一VPC上に作成し、両者間のdocker pullはSSLを使わないケースです。


##1.private registryを用意

以下を参照し、AWS上にdocker private registryを立てる

http://qiita.com/suzukihi724/items/c8135fcfbf74fcbc80d0


##2.kubernetesクラスタを用意

以下を参照し、EC2(CentOS7)１台にkubernetesクラスタを立てる。
この時、1で立てたprivate registryを同じVPC上とする。

http://qiita.com/suzukihi724/items/4e120fdc66b014cfa972


##3.kubernetesでprivate docker registryを利用する設定

2で立てたkubernetesクラスタ上でdocker設定ファイルを編集
/etc/sysconfig/dockerに以下を追加

private registryパスを追加
`ADD_REGISTRY='--add-registry <private registryのプライベートIP>:5000'`

SSLを使わない場合の設定
`INSECURE_REGISTRY='--insecure-registry <private registryのプライベートIP>:5000'`


例）

```

$ sudo vi /etc/sysconfig/docker

# Modify these options if you want to change the way the docker daemon runs
OPTIONS='--selinux-enabled'

# If you want to add your own registry to be used for docker search and docker
# pull use the ADD_REGISTRY option to list a set of registries, each prepended
# with --add-registry flag. The first registry added will be the first registry
# searched.
ADD_REGISTRY='--add-registry 172.20.0.84:5000'

# If you want to block registries from being used, uncomment the BLOCK_REGISTRY
# option and give it a set of registries, each prepended with --block-registry
# flag. For example adding docker.io will stop users from downloading images
# from docker.io
# BLOCK_REGISTRY='--block-registry'

# If you have a registry secured with https but do not have proper certs
# distributed, you can tell docker to not look for full authorization by
# adding the registry to the INSECURE_REGISTRY line and uncommenting it.
# INSECURE_REGISTRY='--insecure-registry'
INSECURE_REGISTRY='--insecure-registry 172.20.0.84:5000'

(以下省略)

```


編集後、dockerサービス再起動

`sudo service docker restart`


##master/minionのホストを分ける場合

masterとminionが異なるホストの場合は、/etc/sysconfig/dockerの設定はminion含めた全ホストで反映する必要がある。
※minion側の反映がされていない場合、kubectl createでpod作成時に、docker pullによるimage取得がエラーとなる。


##トラブルシューティング

(1)エラー：unable to ping registry endpoint
podをcreateしても以下のようなエラーとなる場合は、次の理由が考えられる

エラー）

```
$ kubectl get pod
NAME      READY     STATUS    RESTARTS   AGE
my-pod    0/1       unable to ping registry endpoint https://172.20.0.84:5000/v0/
v2 ping attempt failed with error: Get https://172.20.0.84:5000/v2/: x509: cannot validate certificate for 172.20.0.84 because it doesn't contain any IP SANs
 v1 ping attempt failed with error: Get https://172.20.0.84:5000/v1/_ping: x509: cannot validate certificate for 172.20.0.84 because it doesn't contain any IP SANs   0         6s
```

理由）
①/etc/sysconfig/dockerの設定が反映されていない

②/etc/sysconfig/dockerのADD_REGISTRY設定に誤りがある

③/etc/sysconfig/dockerのINSECURE_REGISTRY設定に誤りがある

設定が正しい事を確認し、sudo service docker restart を実行する
PHP向け静的解析SaaSの主観的比較 (Scrutinizer, SensioLabsInsight, CodeClimate)

静的解析というのは、自動テストを実行せず、コードを解析してソースコードの複雑さやバグの起こりやすさを検出してくれるサービス。テストがなくても即座に導入できる手軽さがあり、テストとは違う面でソースコードの品質を高めるのに役立ってくれる。

CI(Continuous Integration)の一種ではあるが、特にContinuous Inspectionと呼ばれることもある。「全自動コードレビュー」と言う方が近いだろうか。
Travis-CIで各種OSSを組み合わせて似たような処理を実行させることもできるが、設定が面倒くさいし、レポートをどうするか考える必要もある。特化型SaaSの方はこの辺をよく考えてくれている。

PHPに対応したInspection系のSaaSといえば、Scrutinizer、CodeClimate、SensioLabsInsightの3つが有名なので、簡単に機能面を比較してみた。

PushやPullRequestをフックして自動的に解析を行ってくれるのは3つとも同じ。

いずれも、publicリポジトリであれば無料で解析してくれる。(無料版だけでこれを書いている)

## Scrutinizer

https://scrutinizer-ci.com/

![スクリーンショット 2016-02-14 10.36.10.png](https://qiita-image-store.s3.amazonaws.com/0/1126/34e96d2a-f25b-9e88-4ff0-910cf724b205.png)

CodeClimateがPHP対応していなかった時期にPHP特化型として始まったやつ。おそらく一番有名。
スコアは10段階評価(最大10)。
有料版は月額€49から。 https://scrutinizer-ci.com/pricing

### 良い所

* かなり詳しい解析を行ってくれる
* テストを実行する機能があるので、CIサーバーとしても使えなくはない
* 各種OSSも乗っかっていることが多いので、点数の比較ができる
* 簡単なパッチを作ってPull Requestを投げてくれる機能がある

### 悪い所

* 解析速度が遅い
* CI機能はTravis-CIなどより遅く、ショボい。実行コンテナ数はUnlimitedプランでやっと2に増える。オマケだと思ったほうがいいね
  * カバレッジレポートはTravisから送ることもできるよ
* 無料版だと解析結果を1ヶ月しか保持してくれない。毎月何か更新しているPJなら問題はないんだけど。
* スマホでdashboardを見ると著しく表示崩れする


## SensioLabsInsight

https://insight.sensiolabs.com/

![スクリーンショット 2016-02-14 10.50.35.png](https://qiita-image-store.s3.amazonaws.com/0/1126/78d13ee8-f7c7-324f-b433-04f128083802.png)

Symfonyで有名なSensioLabsが運営している解析サービス。Symfony関連のOSSは必ずと言っていいほど導入している。
点数はメダル方式で、最大は★4のプラチナメダル。
有料版はprivate repo5つで月額€39から。 https://insight.sensiolabs.com/pricing

### 良い所

* PHPに特化しており、特に各種フレームワークのベストプラクティスも指摘してくれる。これが大変良い
    * 今のところSymfony(3,2,1), Laravel, Drupal, その他のPHPプロジェクトなどに対応
* どこを直せばよいコードになるのか、指示がすごく具体的。順番に直していけば必ずスコアが上がるようになっている。
* 修正にかかる時間の目安が出るのも面白い

### 悪い所

* PHP以外は一切対応していない
    * JSも含まれるリポジトリだと物足りないかも
* 解析の種類が若干Scrutinizerと異なるので、OSSならば両方導入してみてもいいのではないか。


## CodeClimate

https://codeclimate.com/
![スクリーンショット 2016-02-14 11.47.40.png](https://qiita-image-store.s3.amazonaws.com/0/1126/c745250f-246a-13df-524e-b00dc362e4bb.png)

RubyやJavaScriptで有名な解析サービス。途中でPHP対応が発表された。
点数はGPAで最大が4。
有料プランはホスティングにかかる費用のようだ。大部分は無料で実行できるみたい。OSS化されている機能が多い。
https://codeclimate.com/pricing

### 良い所

* ちょっと思いつかない
* しいて言うならば、PHP以外の言語用のインスペクションが充実しているので、JavaScript度が高ければいいかもしれない

### 悪い所

* **PHP用の解析オプションがPHPMD一択**
* しかも設定デフォルト
    * PHPMDのデフォルト設定は非常にうざい指摘ばかりなことで有名
    * 調教用のxmlを書けばいいんだけど、俺はそれがしたくないからSaaSを使ってるんだよ！！
    * みんな自分用に設定を書くから、GPAがあてにならない
* この程度の内容ならTravis-CIでもできるぞ…

RubyやJSだと標準的なのだろうけど、CodeClimateのPHP対応はすごく微妙なので選択肢に入るレベルにないと思う。なんでLaravelはこんなサービスを使っているのか。。
Windows10 64bit にPython2.7を導入する

Python2.7をwindowsに導入する際にpipの設定等で悪戦苦闘したのでメモ．

# Pythonのインストール
Pythonの[公式ページ](https://www.python.org/)に記載されている"Download"の項目以下からPython 2.7.11を選択し，リンク先からWindows x86-64 MSI installerをダウンロードして実行する．

インストール時にPathを設定するオプションがあるのでオンにしておくと後が楽．
設定し忘れればあとで"c:\Python27"をpathに追加すればよい．
[Windows10で環境変数（システム環境変数、ユーザ環境変数）を追加](http://www.wannko.net/windows10/etc/kankyo.html)

ちゃんと動作するかコマンドプロンプトで"python"と打って確認するとよい．

#pipのインストール

ここからが本題．
最新のpythonではインストール時からpipがインストールされているのだが，私の環境ではちゃんと動かなかった．

曰く

```
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-12: ordinal not in range(128)
```

みたいな感じのことを言われて動作しなかった．

文字コードがASCIIなのが悪いのはわかるが，根本的な原因がわからなかったが，いろいろ調べた結果以下の記事にたどり着いた．
[pip install でUnicodeDecodeError が発生した際の対処（日本語を含むパスで）](http://qiita.com/Go-zen-chu/items/fdde8839935d2807b6cd)

Windowsの管理者アカウント名が日本語だったのがよくなかったようだ．
というわけで
"c:/Python27/Lib/site-packages"内に "sitecustomize.py"という名のファイルを作成して

```.py
import sys
sys.setdefaultencoding("cp932")
```

と記述したらpipが動作した．

```.py
python -m pip install --upgrade pip
```

とやればpipのアップグレードも行われて一件落着．

#パッケージの導入

ついでなので，導入に困る人が多そうなNumpyのインストール方法も述べておく．

[Unofficial Windows Binaries for Python Extension Packages](http://www.lfd.uci.edu/~gohlke/pythonlibs/)
で非公式にWindows用のバイナリファイルが配布されている．
ここから[Numpy](http://www.lfd.uci.edu/~gohlke/pythonlibs/#numpy)をPythonのバージョンとWindowsのビットにあったものをダウンロードする．

あとはダウンロードしたディレクトリに移動して

```
pip install (ファイル名).whl
```

としておけば完了．
同様の方法でmatplotlibなども導入できる．
CollectionViewの選択フレームワーク

わかりずらいコレクションビューの選択フレームワークをまとめておく

#選択フレームワーク
コレクションビュー自体にセルの選択状態を複数持たせれる。
チェックボックスのようなイメージ
<img width="372" alt="スクリーンショット 2016-02-14 午前11.09.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/32586/a3bdb92a-eb5f-e0b2-7720-3a1f2d4505e8.png">
灰色　→ 非選択
黒色  → 選択
赤色  → チェックボックスの代わり

#使い方
``self.collectionView?.allowsMultipleSelection = true``でOK

#何が難しい
1.よくあるインターフェースで、セルをタップしたら詳細画面、右上のチェックボックを押したら
選択にしたい場合。チェックボタンを押しても、セルは選択状態にならない。セルをタップすると
選択状態になる><

2.reloadData系を呼ぶと、選択状態が解除される。

#ソリューション
1.ボタンをタップした時に``selected``を見て選択/非選択にする

```
   if cell.selected {
        collectionView.deselectItemAtIndexPath(indexPath, animated: true)
   }else{
        collectionView.selectItemAtIndexPath(indexPath, animated: true,    scrollPosition: UICollectionViewScrollPosition.Bottom)
   }
```
2.セルのタップで選択/非選択無効化

```

func collectionView(collectionView: UICollectionView, shouldSelectItemAtIndexPath indexPath: NSIndexPath) -> Bool{

     return false
}

func collectionView(collectionView: UICollectionView, shouldDeselectItemAtIndexPath indexPath: NSIndexPath) -> Bool{

     return false
}
```

3.詳細画面への遷移をどうする？
↑の２つのAPIでタップが拾えるので頑張る

#結論
自分で選択状態管理したほうが良さげ
STGを作ろう

 ## 1. 東方，インベーダー　2DSTG  (2Dのシューティングゲーム)
#### ゲーム内容
プレイヤーを操作して，敵の攻撃を避けつつ，敵を倒して進む．
#### クリア条件
死なずに，ボスを倒すこと
#### 操作方法
プレイヤー移動　矢印キー
(弾丸を打つ　Xキー)
#### 作るもの
プレイヤー
敵(ザコ，ボス)
PostgreSQLアンチパターン：インデックス関連の三本立て


# SQLプランナの過信

time_of_report に インデックスつけてあるから大丈夫だろうと思っていたら、Seq. Scan になっていたSQL です。

```sql
SELECT id  FROM reports
 WHERE user_id = 12345
 AND date_trunc('day', time_of_report) = current_date;
```

WHERE句でdate_trunc 関数：timestampの丸めを使ったせいで、インデックスを使ってくれなかった。
それはそうですね。関数一般を適用した結果は、値の順序が変わってしまう＝index上の位置が変わってしまう、可能性があるので。

対策：

- 性能の欲しいWHERE句で、高頻度でその関数を使うなら、インデックスも関数値で作る
  ` USING btree(date_trunc('day', time_of_report))`
- date_trunc() のように、元の値のindex順でも十分に絞込可能な関数は、SQLプランナの替わりに人間が評価式を置き換える
`time_of_report >= current_date AND time_of_report < current_date + interval '1days'`

pg_stats_reporter や postgres log で SlowQuery を見つけたら、インデックスが意図通り使われているかどうか、explain で確認してください。

# 早すぎるインデックス作成

インデックスは必要悪です。スペースは食うし、更新コストは排他制御含めると1本で2倍,2本で3倍といった調子で上昇するし、たまに 再作成しないとゴミがたまって保守工数までとられる始末です。できればつけたくない。適切にスコープ管理された要件で、シンプルに正規化・分割したTABLE設計で、各TABLEの主キーだけで間に合わせたい。それが理想です。

前項の２つの対策なら、クエリの方をインデックスに合わせる方がいいです。緊急に性能改善する必要に迫られたら、date_trunc()関数インデックスを作る方が早いときもありますが。

全部のSQLを予め確認しようとしたり、初回のコードレビューの段階でexplainするのはやめましょう。チェックしきれるものではありません。無理にやるのは「早すぎる最適化」アンチパターンです。
無駄に工数を消費するだけでなく、運用DBに実際には役に立たないインデックスを抱え込むリスクがあります。
みんなに使ってもらえるはずの機能がそっぽ向かれて、リリース予定からドロップしたとか、あるTABLEの成長が遅かったとか、完全に止まったとか、こっちのクエリにはがんがんリクエストが来るのに、ちょっとひねったこっちのクエリはさっぱり来ないとか、あるでしょう？

シナリオを想定できてそれなりの量のテストデータを用意した性能検証段階や、サービスインしてデータが貯まって、Queryの利用頻度の実測値を得てからが、インデックスチューニングです。

運用で作成済みのインデックスをみて、後から「えー、これっているのかな。効いてないんじゃない？」と思っても、実証するのは大変です。

- 性能検証環境がサービス実需を全部シミュレートできているでしょうか？
- 運用環境を pg_stats などでモニタしていても、月一度、四半期に一度の低頻度 batch処理 まで、モニタ範囲に入っているでしょうか？

漏れがあったら DROP INDEX した瞬間、あるいはDROP INDEXしたことをすっかり忘れた頃になってから、Database Blackout（DB Server応答無し） のリスクがあります。
10人年単位で数えるコード量をかかえて、担当者が代替わりしまったサービスだと、「漏れなく事前チェック」は工数的に現実味がありません。
では、リスクを承知で蛮勇を奮いますか？　「現状で動いてるものを触るな」原則が優先します。

必要悪のインデックス が、こうして増え続けます。混沌との戦いに勝ちはありません。いつまでその場に踏みとどまっていられるかの後退遅滞戦闘です。せめて後退するときは必要性を実測確認してからにしましょうよ。

# 1本ですむところに2本のインデックス

「SQLプランナの過信」で言及した件は、btree(time_of_report) と btree(date_trunc('day', time_of_report)) の 2本ができかねいところを、クエリの方を調整することで1本にできる例でした。
インデックス本数を減らすのには、2キーインデックス 、3キーインデックスの活用の手もあります。

たいがいのサービスで、user_id が真っ先に必要になります。他人の情報を見せる必要はない、見せてはならないのですから。
btree(user_id) が各TABLE で必要になりそうですが、「早すぎるインデックス作成」しないでもう一歩待ちましょう。
各TABLEで固有の、user_id の次に重要なキー、そのTABLEのクエリで高頻度で使用するキーも発見できるのでは？
あったら btree(user_id, when) のように、2キーインデックスにして、btree(user_id)は作らずにすませましょう。

- when だけで絞り込むのは意味がない。必ず user_id も指定される
- user_id だけで絞り込むこともある。

このように絞込のキー評価順が固まっているなら、2キーインデックスは、1キーインデックス と 2キーインデックス を兼用できるので1本で2倍の使いでがあります。
3キーなら3本兼用ですが、4キー以上だとちょっとあやしい。4キーで、SQLプランナが判断を間違って、Seq.Scan になった事件をみたことがあります。

運用中の既存インデックスの削除は現実には無理という話をしましたが、こういうキー定義の重なりがあるときの小さい方は削除可能なはずです。それでも、びびってDROP INDEXのリターンキーはなかなか押せないです。
避けげー

![Failed to upload "スクリーンショット 2016-02-1![スクリーンショット 2016-02-14 11.02.12.png](https://qiita-image-store.s3.amazonaws.com/0/113505/c32a1889-02e2-007f-85ce-39b7fd5a6c8c.png)
4 11.02.12.png": Please try again later.]()


避けげーでございまーす
CarrierWaveでファイルのアップロードをテストしたいときは

## 今北産業

・[ここにあるように](http://tanihiro.hatenablog.com/entry/2014/01/09/004022)fixture_file_upload railsを使うと良い｡

・[この]
(http://stackoverflow.com/questions/24584742/carrierwaveformnotmultipart-error-when-creating-records-using-seed-rb-file)やり方は効果がない


・Paramにファイルパスをじかに渡すとCarrierWaveが

```rb
You tried to assign a String or a Pathname to an uploader, for security reasons, this is not allowed.
```

と出て受け取ってくれない

##経緯
CSVファイルをアップロードして､その内容をDBに登録し､データに操作をくわえて､CSVファイルを吐き出す｡という業務用のCSV編集アプリをRailsでつくろうとしてました｡

CarrierWaveをいれて､CSVをアップロードしてやるためにコントローラーをつくりました｡

```rb
   def import
    @uploaded_file = CsvUploader.new
    @uploaded_file.store!(params[:file])
    file_path = @uploaded_file.file.file
   end
```

こんな感じでファイルを受け入れてやって､アップロードされたファイルのパスを手に入れた後は､DBに登録させる・・・・というふうにしました｡手動でやるとうまく動いてるようなのでRspecでテストを書きました｡(本来テストは先に書くべきです｡ただ､どう動くのかわからない状況だったため､結果を記録する意図でテストを書きます｡)


```
post :import, params      expect(CsvData.all.count).to eq(100)
```

paramsに直接ファイルパスを文字列で渡したところ

```
 You tried to assign a String or a Pathname to an uploader, for security reasons, this is not allowed.
```

おやおやエラーが・・・じゃあ・・・[stackoverflowをみて](http://stackoverflow.com/questions/24584742/carrierwaveformnotmultipart-error-when-creating-records-using-seed-rb-file)

```
csv_src = File.join(Rails.root, "/public/csv/test.csv")
csv_file = File.new(csv_src)

```
とやって文字列の代わりに渡してあげました｡そしたら・・・

```
file_path = @uploaded_file.file.file
```

この箇所でNoMethodエラーが出るんですね｡Pryで手動の実行結果と､テスト時の実行結果を比較してみると　
@uploaded_file
内のオブジェクトが違います｡どうも正確にアップロードできてないみたいです｡

で､[ここにあるようなやり方](http://tanihiro.hatenablog.com/entry/2014/01/09/004022)をしてみたところうまく行きました｡

ハマってる方は御参考に｡

しかしなんで動かなかったんでしょうね｡
fixture_file_upload rails　ってCarrierWaveのメソッドなんでしょうか?
[CSS] 今さら聞けないfont-familyの正しい指定方法

最近のおしゃれなWebデザインにはfont-family指定が必須ですよね。

## フォント指定のだめな例とよい例

例えば、
「日本語フォントをおしゃれに表示したいので、游ゴシックを指定したい！」という場合。

☓ だめな例

```
font-family: "游ゴシック" , "Yu Gothic”;
```

なぜだめかとういうと、↑この2つがデバイスに入っていないと、
**意図しないフォントがあたってしまうことがあるからだ。**

たとえば游ゴシックが入っていないスマホやwindowsなどでは、勝手に明朝体が適用されてしまったりする。
また、英字フォントの指定がないという問題もあるので、半角英数だけ意図しないフォントが適用されてしまったり。

◯ よい例

```
font-family: "Helvetica Neue" , Helvetica , Arial , Verdana , Roboto , "游ゴシック" , "Yu Gothic" , "游ゴシック体" , "YuGothic" , "ヒラギノ角ゴ Pro W3" , "Hiragino Kaku Gothic Pro" , "Meiryo UI" , "メイリオ" , Meiryo , "ＭＳ Ｐゴシック" , "MS PGothic" , sans-serif;
```

font-familyの値は、カンマ区切りで左からマッチしたものが適用されていくので、ほぼすべての機種で大体意図したフォントを適用さることができる。


このフォント指定の意図は、翻訳すると
**「macで游ゴシックとHelvetica Neue、windowsでメイリオとArial、iphoneならヒラギノと Helvetica, 、その他、Androidなどは機種によって違いすぎるからなんでもいいのでゴシック体当ててくれー」**
と言った感じです。

## ※ sans-serif, serifについて

sans-serif → ゴシック体のデバイスフォント
serif → 明朝体のデバイスフォント

を選んでくれるのでどんなときも必須。

とくにフォントにこだわりがないときはこれで明朝かゴシックかだけ指定しておけばOK。
というか、何も指定しないとブラウザのデフォルトはほとんどsans-serifである。
Swift読書勉強会#2 補足資料


## 目的

本資料は、[詳解Swift読書勉強会](http://connpass.com/event/26778/participation/#participants)で説明した補足資料です。





## 確認
今回は、Caper02関数をとりあげたのでここ学んだことをSwiftに記載されているソースコードで確認してみます。


確認事項は
 * ワイルドカード "-" 使用例
 * defaultの使用例


## 実習

例えば、以下のコードがあるとします。

```swift
let i = Int("3")

```


<img src="https://qiita-image-store.s3.amazonaws.com/0/40229/94601f50-8890-caa5-72b6-bcda4f326c7d.png" width="450px">


optionキーを押しながら変数をクリックするとこんな感じで内容が表示されますが、ここでの定数iはオプショナル型です。ということは、Intのイニシャライザメソッドには返り値としてオプショナル型を返すものが定義されていることが推測できます。

次の作業としては、Intのイニシャライザメソッドを確認します。確認方法としては、Intの箇所をCommandキーを押しながらクリックします。



<img src="https://qiita-image-store.s3.amazonaws.com/0/40229/5d7be479-8330-69df-a427-bed33f4cabfa.png" width="450px">


クリック先で初期化メソッドの返り値がオプショナルのものがみつかったので、これが使われていたということが分かります。


```swift

public init?(_ text: String, radix: Int = default)


```

ここで、ワイルドカード"_"が外部引数として使われているので実際使うときには引数名を指定しなくて問題ないことがわかります。

また、第二引数のradixはデフォルト値がついているので、使わなくてもいいということがわかります。
もちろん、実際には、必要に応じて以下のように書くことができます。

```swift
let i = Int("3", radix:10)

```

radixは進数を意味するので16とすると16進数を意味します
PythonでCSVデータをExcelに貼り付ける際のスタイリッシュ技

###やりたいこと
PythonでCSVデータ取得、整形、Excel貼り付け
そんなシチュエーションないと思いますが不幸にも僕はあったので。

***
2016/02/14　追記
ウルトラスタイリッシュ技をコメントに@okadate さんが残してくださいました。
そちらをご参照ください。
以降は、深夜テンションで作り上げてしまった残骸となります。
***

#環境
Windows7
Python3.4

##こういうCSVデータをこう貼り付けたい
```csv:sample.csv
 ,Label,Area,Mean,Min,Max
1,4mas.tif,40000,0.000,0,0
2,10mas.tif,40000,32757.335,30635,34880
3,25mas.tif,40000,32784.505,1039,64761
4,40mas.tif,40000,32836.377,1371,65157
```

上記CSVをコピーしてExcelに値貼り付けすると
![jg.PNG](https://qiita-image-store.s3.amazonaws.com/0/35159/90cf5da1-0099-bde9-70ca-a3cf081689e9.png)
こうなってしまう。

理想はこう
![gjapo.PNG](https://qiita-image-store.s3.amazonaws.com/0/35159/fb43c8b0-c6ab-03aa-06d6-f9f7fcce810f.png)


###私はこうした

```python:sample.py
import win32com.client as win32
xlApp = win32.Dispatch("Excel.Application")
xlApp.Visible = 1
wb = xlApp.Workbooks.Open("C:/Users/user/Documents/1.xls")
Sheet = xlApp.Workbooks(1).Sheets(1)
f=open("C:/Users/user/Documents/sample.csv",'r')
for i,line in enumerate(f.readlines()):#ここがミソ
    for n,label in enumerate(line.split(",")):
        cell = Sheet.Cells(i+1,n+1)#win32では1からCellを開始する為
        cell.Value = label
```

そこがミソです。
enumerateはインデックスとともにループするので、それに+1してCellに合わせてます。
Pythonっぽい書き方ですね（言いたいだけ）

手でやったら一瞬なのですがPythonでやりたかったんです。
（夜中に思いついたのでなにか重要な事を見落としてる気がする）

他にいい方法ありましたら教えて下さい

###問題
問題が。。。
![hgap.PNG](https://qiita-image-store.s3.amazonaws.com/0/35159/e64eb69e-0efa-31f9-2069-97ed542ce0f1.png)
勝手に「折り返して全体を表示」とかになってしまう。
ダサい。
vagrant up するには、Visual Studio C++ 2010 の再頒布可能パッケージが必要

Windows 10 を再インストールしたので、[Scotch Box](https://box.scotch.io/) を再構築しようとしたら、以下のようなエラーが出て先に進めない。どうも、box ファイルがダウンロードできないようです。

```lang:vagrant1.8.1
>vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Box 'scotch/box' could not be found. Attempting to find and install...
    default: Box Provider: virtualbox
    default: Box Version: >= 0
The box 'scotch/box' could not be found or
could not be accessed in the remote catalog. If this is a private
box on HashiCorp's Atlas, please verify you're logged in via
`vagrant login`. Also, please double-check the name. The expanded
URL and error message are shown below:

URL: ["https://atlas.hashicorp.com/scotch/box"]
Error:
```

ログインが必要なのかと思い、Atlas account を作って、vagrant login しても、状況変わらず

調べていたら、vagrant up するには、Visual Studio C++ 2010 の再頒布可能パッケージが必要らしい。
インストールしたら、アッサリ動いたという話。

[Microsoft Visual C++ 2010 再頒布可能パッケージ (x86)](https://www.microsoft.com/ja-jp/download/details.aspx?id=5555)
RubyMine Keyboard Shortcut


## Code
|Key|Description|
|:---|---|
|⌥ ⌘ L|コードの再フォーマット|
|⌥ ↩|警告の出ている行で対応案を表示する|
|⇧ ⌥ Up/Down|行を移動|
|⇧ ⌘ V|コピー履歴を表示|
|⇧ #|式展開に変換|
|⌘ K|行コメント|
|⌥ ⌘ K|ブロックコメント|
|⌘ D|Duplicate lines|
|⇧ F6|Rename|
|⌥ ⌘ +|Expand all|
|⌃ O|Overide method|
|⌃ Up|Extend selection|
|⌃ Down|Shrink selection|
|⌘ N|Generate|
|⌘ J|Insert Live Template|
|`⌥ ⌘ J`|Surround with Live Template|
|`⌃ ⇧ J`|現在の行の下に一行追加しカーソルを追加した行の行頭に移動する|

## Navigate
|Key|Description|
|:---|---|
|⇧ ⌘ F|プロジェクト全体から文字列をインクリメンタルサーチ|
|⇧ ⌘ O|プロジェクト全体からファイルを開く|
|⌘ E|過去に開いたファイルを再度開く|
|⇧ ⇧|Search everywhere|
|⌘ B|定義に移動|
|⌃ ⌘ Up|Controller <-> View などを移動出来る|
|⌘ O|クラスを開く|
|⌘ Up|ナビゲーションバーにフォーカス|
|⇧ ⌘ A|RubyMindのコマンドを実行|


## Git
|Key|Description|
|:---|---|
|⌘ K|Commit changes|
|⇧ ⌘ K|Push|

## Run
|Key|Description|
|:---|---|
|⌃ R|Run|
|⌃ ⌥ R|Run ...|
|⌃ ⇧ R|Run current file (Need to push long)|


## Macの特殊記号一覧
http://penguinlab.jp/blog/post/2035
⌘
⇧
⌥
⌃
⌫
⏎
↩
⎋
⇪
↑↓←→
CoreData Error CoreData: error: -addPersistentStoreWithType:SQLite configuration:(null) 

CoreDataで下記のようなエラー

一度は動いたのにと思っていると原因は、
「1度エントリを作ってからCoreDataのModelを変えたこと」だった。

iPhoneを接続してテストをしていたのでデータがiPhone上のアプリに残り続けていた。
そこで新しいModelと不一致が起きていたよう。
一度アプリを削除してデータを消してから再度runすると問題なく動き出した。

Cleanではデータが消えないのでダメ



```
CoreData: error: -addPersistentStoreWithType:SQLite configuration:(null) URL:file:///Users/Patti/Library/Developer/CoreSimulator/Devices/A70306D7-76BE-489A-82B3-FBAA9390D5A4/data/Containers/Data/Application/FC51C1B7-416B-463E-B976-C175642A4B34/Documents/Note_App.sqlite options:(null) ... returned error Error Domain=NSCocoaErrorDomain Code=134100 "The operation couldn’t be completed. (Cocoa error 134100.)" UserInfo=0x7fa79add8080 {metadata={
NSPersistenceFrameworkVersion = 519;
NSStoreModelVersionHashes =     {
    Notes = <674765e4 00e077d5 e3b4d2ca 2795eee2 42850989 4a2a825a 0c289097 387aa3a5>;
};
NSStoreModelVersionHashesVersion = 3;
NSStoreModelVersionIdentifiers =     (
    ""
);
NSStoreType = SQLite;
NSStoreUUID = "8348BBED-7C75-4EF5-B73C-075E8719696E";
"_NSAutoVacuumLevel" = 2;
}, reason=The model used to open the store is incompatible with the one used to      create the store} with userInfo dictionary {
metadata =     {
    NSPersistenceFrameworkVersion = 519;
    NSStoreModelVersionHashes =         {
        Notes = <674765e4 00e077d5 e3b4d2ca 2795eee2 42850989 4a2a825a 0c289097 387aa3a5>;
    };
    NSStoreModelVersionHashesVersion = 3;
    NSStoreModelVersionIdentifiers =         (
        ""
    );
    NSStoreType = SQLite;
    NSStoreUUID = "8348BBED-7C75-4EF5-B73C-075E8719696E";
   
```
電子工作 > 基板類が届いた > 小さめの基板 / チップコンデンサ / ポリウレタン銅線 / カプトンテープ

発注していた基板類が届いた。

![DSC_0091.JPG](https://qiita-image-store.s3.amazonaws.com/0/32870/f46e9e67-8e7f-b327-92bd-0648c28ca8eb.jpeg)

上段左上から

- ダイセンの基板（入手済みのもの。サイズ比較のため）
- [１６ホールユニバーサル基板（２．５４ｍｍ）](http://akizukidenshi.com/catalog/g/gP-02515/)
  - 思ったよりも小さい
  - 手で割って使うタイプ
- [両面ＴＨ丸型ユニバーサル基板　２７ｍｍ （ペットボトル基板）](http://akizukidenshi.com/catalog/g/gP-09684/)
  - 何に使うか思案中
- [チップ積層セラミックコンデンサー　４．７μＦ５０Ｖ　２０１２　（２０個入）](http://akizukidenshi.com/catalog/g/gP-07548/)
  - 2012
  - ケースに容量記載もなく、15倍ルーペで見ても容量記載なし
  - 他の容量のものと混在したら終わる
  - 1uF, 0.1uF, 0.01uF, 4.7uF を購入してみた
  - HAKKO PRESTOというハンダコテではコテ先が大きいかもしれない。交換コテ先で小さいのはなかった模様
- [ポリウレタン銅線（０．２９ｍｍ　２０ｍ）](http://akizukidenshi.com/catalog/g/gP-09583/)
  - そのうち使う
- [耐熱テープ（ポリイミドテープ）　１５ｍｍ幅](http://akizukidenshi.com/catalog/g/gT-09380/)
  - 基板上に貼って、1.25mmピッチなどのICの実装に使う予定

下段

- ダイセンの基板
  - コーナンのソフトカードケース B7に収納
  - 基板類の整理にいい気がする
  - ケース自体のサイズがばらばらで数mm違うこともあるので購入時は要注意
  - こういうケースに長期間入れておくと、基板がケースにくっいてしまうかもしれない
電子工作 > AQM0802 > ユニバーサル基板実装

I2C接続のキャラクタディスプレイ AQM0802.

http://qiita.com/7of9/items/b3e1db76422280d47b7a
において一応動作はしたが、フラットケーブルなので固定しないと使いづらい。

関連情報を探している時に、ねむいさんのぶろぐにて以下のユニバーサル基板実装を見つけた。
http://nemuisan.blog.bai.ne.jp/?eid=204166

僕がよく使っているDAISENの細長いユニバーサル基板だ。

ピッチ変換をどうしているか考えながら、「曲げたらいいのか」という考えになりやってみた。

### 部品面とハンダ面

ねむいさんの方は横長での使い方だが、こちらは縦長で使いたいのでそのようにした。

![DSC_0083.JPG](https://qiita-image-store.s3.amazonaws.com/0/32870/73ff723c-6c8c-53df-9f0b-185068a6f015.jpeg)

ハンダ面は以下となる。基板上の実装なので随分楽になった。
青い線は昨日手に入れたジュンフロン線 ETFE 0.26mm L-50。

なお、プルアップ抵抗はESP8266の基板(上の写真の左の基板)上で実装しているので、今回はこちらの基板には実装していない。

![DSC_0084.JPG](https://qiita-image-store.s3.amazonaws.com/0/32870/0b78019b-b35e-9e55-c6ae-f8b1ea85b54b.jpeg)

### 実装

ピンを曲げた様子。
これが一番時間がかかった。
ラジオペンチでピンを曲げながら、2.54mmピッチに合わせていく。ピンの形状としては、竹ぼうきの先が広がった状態に近い。

両サイドのピンが一番頭が出にくく、スルーホールに少し入ったかどうか、という状態ではんだ付けした。

![DSC_0085.JPG](https://qiita-image-store.s3.amazonaws.com/0/32870/33eb2d71-e096-2663-f36b-f7b1abfbbb1b.jpeg)

ハンダ付けの方法としては、

1. ボビンに巻き付かれたハンダ線の先を蛇使いの蛇のように出して頭が下向き(または少し斜め)になった状態にしておく
2. AQM0802のピンがユニーバサル基板のスルーホールに入った状態にして、それを左手で抑える
3. 2のピンの部分を1のハンダ線先端に持って行き、右手ではんだごてを使って仮はんだする
4. 仮はんだを溶かして、位置調整をしながら溶かしたはんだの固定をまって本はんだとする
5. 他のピンを本はんだする


以下のようになった。
かっちりしていて使い勝手がいい。

![DSC_0089.JPG](https://qiita-image-store.s3.amazonaws.com/0/32870/15d3bd91-43d5-cf28-376f-c55d7653323e.jpeg)

### ユニーバサル基板実装の費用と考察

費用については

- ユニーバサル基板: ダイセン電子工業 PU26x44 > 125円くらい
- コンデンサ3つ: 60円くらい

[ピッチ変換基板](http://akizukidenshi.com/catalog/g/gP-06794/)は400円。手間と価格を考えるとピッチ変換基板を買うというのも手である。

一方でユニーバサル基板にしておけば、ピン配置を自分で変更できるのがいい。ピッチ変換基板を使った場合は、間にストレートピンヘッダとリード線を入れることでピン配置を変更は可能。

ピッチ変換キットを使った場合、横長画面に対してピン配置が縦になるので、今回のような基板につける場合はピン配置を９０度変更するものが必要になる。ESP8266基板のピンを縦配置にするというのも１つの手ではある。
技術英語 > A quick [recap] of the last two blogs / retrospect

@ Adam Taylor MicroZed Chronicles - Using the Zynq 101 [Kindle Edition]

No. 286/2129

> <font color=red>A quick recap</font> of the last two blogs shows we have defined our Zynq-based MicroZed system using Vivado and established the baseline within the Software Development Kit (SDK).

http://eow.alc.co.jp/search?q=recap
> recap briefly
> 簡単に要約する

...
> recap the main points of
...の要点を繰り返す

<hr>
関連して思い出したもの

http://eow.alc.co.jp/search?q=retrospect&ref=sp
> retrospect
> 回想、回顧、追想
DockerでError while pulling imageが出た時の対処

`docker-compose up`をしようとしたら以下のエラーが出ました。

```sh
Building test
Step 1 : FROM node:latest
Pulling repository docker.io/library/node
ERROR: Service 'test' failed to build: Error while pulling image: Get https://index.docker.io/v1/repositories/library/node/images: dial tcp: lookup index.docker.io on 133.20.16.1:53: server misbehaving
```

どうやらdocker imageの取得に失敗しているっぽいです。

単純にdocker-machineを再起動して解決しました。

```sh
$ docker-machine restart default
```


## 参考
[IBM Knowledge Center](http://www-01.ibm.com/support/knowledgecenter/SSHS8R_7.1.0/com.ibm.worklight.deploy.doc/deploy/r_ts_docker_error.html?lang=ja)
C# XmlSerialize TreeView

XML避けてましたが簡単ですね！(ちょっと省いてます)

階層テストクラス

```
public class Category {
  [System.Xml.Serialization.XmlElement ("name")]
  public String Name;
  [System.Xml.Serialization.XmlElement ("url")]
  public String Url;
}
```

```
public class LargeCategory {
  [System.Xml.Serialization.XmlElement ("name")]
  public String Name;
  [System.Xml.Serialization.XmlElement ("category")]
  public List<Category> Category;
}
```

```
[System.Xml.Serialization.XmlRoot ("categories")]
public class Categories {
  [System.Xml.Serialization.XmlElement ("largecategory")]
  public List<LargeCategory> LargeCategory;
}
```

適当にCategoriesを作成しておき

```
using (StreamWriter stream = new StreamWriter (filename, false, Encoding.UTF8)) {
  XmlSerializer serializer = new XmlSerializer (typeof (Categories));
  serializer.Serialize (stream, categories);
}
```
でSerialize終了。


読む時は

```
using (StreamReader stream = new StreamReader (fileName, Encoding.UTF8)) {
  XmlSerializer serializer = new XmlSerializer (typeof (Categories));
  categories = (Categories) serializer.Deserialize (stream);
}
```

で展開。簡単！

TreeNodeにUrlを格納しておくclass

```
public class GhoooTreeNode : TreeNode {
  public String Url;
  public GhoooTreeNode (String name, String url) : base (name) {Url = url;}
}
```

```
System.Windows.Forms.TreeView categoryTreeView;
```
TreeViewに展開

```
categoryTreeView.Nodes.Clear ();
foreach (LargeCategory largeCategory in categories.LargeCategory) {
  GhoooTreeNode parentNode = new GhoooTreeNode (largeCategory.Name, @"");
  categoryTreeView.Nodes.Add (parentNode);
  foreach (Category c in largeCategory.Category) {
    GhoooTreeNode node = new GhoooTreeNode (c.Name, c.Url);
    parentNode.Nodes.Add (node);
  }
}
```
pandas・numpy・python

##boolの数を数える
```
import numpy as np
np.count_nonzero({list|DataFrame|Series})
np.sum({DataFrame}) #× 行合計
```

##文字列要素の部分一致
```
df[xxx].str.contains("部分文字列")
```

##重複判定
```
df[xxx].duplicated()
```

##データに関数を使う
```
sr.apply(func)
```

##重複したindexを削除
重複しているグループの最後のデータを残す場合

```
dup_index = df.index.duplicated(take_last=True)
df[dup_index]
```
※take_lastではFutureWarningがでる、keep='last'

#python
##ソート

```
list.sort(key=func,reverse=True|False)

funcにはソートに使う値を返す関数を
list.sort(key=lambda a:a[1])
```

##可変長引数

```
def func(*args,**kwards)
def func(var=1,var=2,*args,**kwards)
~~ child_func(*args,**kwards)
```
※順番に注意

#BeautifulSoupとlxml
##BeautifulSoup

```
from bs4 import BeautifulSoup as bs
soup = bs(src)

#soup.find("タグ",{"要素":"文字列"})
#例
soup.find("div",{"class":"文字列"})
```

##lxml

```
from lxml import html
html.fromstring(src)

#検証ツールからxpathコピーとか
#見つかったのを配列で返してくるので
XPATH = "//*[@id=\"rfindex\"]/div[2]/div[1]/dl/dd/strong"
dom.xpath(XPATH)[0]
```

lxmlの方がソース元のせいでパースできない事が多い。
ページ遷移しながら使おうとする場合はlxmlよりbsの方が安定する。
5年ぶりに前線復帰して、Python Django をリファクタした話

# 背景
昨年からスタートアップに参画して、Python のフレームワーク Django で開発しています。5年近く開発のブランクがあったので、「今どきの開発はこうなのかー」と日和見を決めこんでいました。でも、いろいろなアンチパターンや突っ込みどころが満載だったのです。

前の前の担当者と前の担当者がやめて、そのつけがまわってきました。残されたコードを見て、頭をかかえたり、あきれかえったり。

そんな中でリファクタリングしたときの話、これからリファクタリングする話をまとめようと思います。

# やらかされていた問題

語り始めると止まらなくなりそうですが、アーキテクチャから見て残念なものが二つありました。

## スマートすぎるビュー

もともとバッチ処理で作成されたデータをビューが取得するだけのシンプルなアプリだったようです。しかし機能追加があって、ビューでいろいろ計算するようになりました。

※ よくわかっていなかったころの私は、ある時期にコピペ駆動開発でそれに加担してしまいました。
orz

## 散らかされたロジック

前の担当者が何とかしようとしたようなのですが、ビューにロジックが残ってたり、モデルにロジックがあったり。二つの異なるパッケージで循環参照を生じさせたり。ろくに動作確認もしてないし。もうひどいことになりました。

# 根本問題は…
時間が足りなかったとか、~~担当者がアホだったとか~~、状況や人に依存することは横に置きます。

そもそも Django はテーブルとモデルが1:1になっている、シンプルな構成を想定しています。本来の意味とは若干ずれるのですが、Active Record パターンに該当するでしょう。

この構成はアプリが複雑になってくると問題が出てきます。

* データ構造の問題

機能が複雑になってくると、テーブルが変更されます。当初想定していたモデルと合わなくなってくることがあります。

* 結合したデータの問題

Django だとビューからモデルを直接呼びがちになると思います。

複数のテーブルの情報を結合させるとビューでロジックを書くことになりがちです。複雑な計算をさせると「え？これってこのモデルが担当するの？」と責任の所在が分かりにくくなります。

* アーキテクチャの混乱

そもそも Model-View-Controller はプレゼン層のパターンです。それがモデルにデータソースのアーキテクチャパターンが混じっているようで、分かりにくくなっています。（単純に私が理解していないだけとも思いますが）

# 解決策

基本に立ち返ってレイヤー化することから始めてみました。その際、ドメイン駆動設計や、（訳がひどいと評判ですけど）エンタープライズアーキテクチャパターンを参考にしてみました。

個人的にはエンタープライズアーキテクチャパターンの内容が腹に落ちました。

http://www.amazon.co.jp/dp/4798121967
http://www.amazon.co.jp/dp/4798105538

## おさらい：基本的なアプリケーションレイヤー

いくつかパターンがありますが、4層にわける方法が分かりやすかったです。

* プレゼン層： View やデータローダー、外部連携
* サービス層: プレゼン層にたいして粗い API を提供、ドメイン層への Facade でもある。この層でリモート Facade にすることも。
* ドメイン層: データとビジネスロジックを持つ。細かい API を提供する。
* データ層: データソースと CRUD したり、オブジェクトに変換したり

繰り返しになりますが、個人的に Django が分かりにくかったのが、プレゼン層のモデルとドメイン層とデータ層がひとつにまとまっていたように見えたところです。このあたりを分割するのがキモになりました。

## サービス層の導入

* インターフェースと引数

一つのビューに対して一つのサービスを提供するようにしました。メソッドのパラメータが複雑化することがいやなので、Data Transfer Object っぽいパラメータをわたして処理させました。

* サービスの分類

サービスも二種類にわけました。

一つは基本的な CRUD を処理するもの。命名規則も XxxService。

もうひとつは複数のオブジェクトを結合して、複雑な計算・処理をするもの。命名規則も XxxEngine。

色々な解説をよんでもよくわからんかったので、以下のコードを参考にしました。
http://www.infoq.com/jp/news/2015/04/ddd-trading-example
https://github.com/archfirst/bullsfirst-server-java


* サービスの Singleton 化

サービスのインスタンスを都度作成するのも非効率なので Singleton 化しました。

http://code.activestate.com/recipes/579090-yet-another-singleton-pattern-in-python-using-clas/


* Strategy の導入

これは今後の課題ですけど。

XxxEngine の中に似たような処理がいくつかありました。これは Strategy パターンで分離すれば、もっと見通しがよくなるハズです。

## モデルの扱い

Django のモデルはデータ層と見なすことにしました。

## ドメイン層の導入

今後の予定ですが、ドメイン層を導入しようと考えています。Django のモデルを継承したクラスでドメインロジックを実装します。

> 昔、テーブルからオブジェクトに変換するときには、POJO(Plain Old Java Object)へマッピングしていました。ドメインモデルとしてロジックを実装するには POJO を継承したクラスで対応していました。
> それを参考に、POMO(私の造語w：Plain Old Model Object) を継承して、ドメインモデルにしよう考えているわけです。

# まとめ

まだ微妙な気がしますが、現状はこんなところです。

Rails でサービス層を導入した話をみかけて「同じことを考える人がいるものだなー」と思い、Django で考えたこと/対応したことをまとめました。

ただ、今回悩んだことはエンタープライズアプリケーションパターンで語られていた問題でした。今となってはフレームワークが隠蔽していて意識していないものが多くあります。しかしフレームワークの限界を超えようとするとき、基本をしっかり知っていることが大事だなー、と思ったのでした。
pythonで文字列の見た目幅の長さを調べる


等幅フォントでの縦揃えがしたくて書いてみた

## 文字コードで全角判定をしてみる

```Python
# -*- coding: utf-8 -*-

def width(s):
    return sum([_width(c) for c in s.decode('utf-8')])

def _width(c):
    return 2 if _isMultiByte(c) else 1

def _isMultiByte(c):
    return ord(c) > 255
```

### 動作確認

```Python
assert 0 == width('')

assert 1 == width('a')
assert 1 == width('A')
assert 1 == width('ｱ')
assert 1 == width('-')
assert 1 == width('+')
assert 1 == width(' ')
assert 1 == width('\\')
assert 1 == width('\n')
assert 1 == width('\t')

assert 2 == width('aa')
assert 2 == width('AA')
assert 2 == width('が')
assert 2 == width('っ')
assert 2 == width('ぽ')
assert 2 == width('い')
assert 2 == width('！')
assert 2 == width('Ｇ')
assert 2 == width('ア')
assert 2 == width('○')
assert 2 == width('■')
assert 2 == width('、')
assert 2 == width('。')
assert 2 == width('‐')
assert 2 == width('ー')
assert 2 == width('　')
assert 2 == width('\\\\')
assert 2 == width('\r\n')

assert 4 == width('ＹＹ')
assert 4 == width('0ｗ0')
assert 4 == width('OK！')
```

`ｱ`だけおかしい...全角だと判定されている...

## [East Asian Width](https://ja.wikipedia.org/wiki/%E6%9D%B1%E3%82%A2%E3%82%B8%E3%82%A2%E3%81%AE%E6%96%87%E5%AD%97%E5%B9%85)という規定があるとのこと
`_isMultiByte`だけ修正

```Python
# -*- coding: utf-8 -*-

def width(s):
    return sum([_width(c) for c in s.decode('utf-8')])

def _width(c):
    return 2 if _isMultiByte(c) else 1

def _isMultiByte(c):
    import unicodedata
    return unicodedata.east_asian_width(c) in ['F', 'W', 'A']
```

今度は全部問題なし！
これで良さそうかな？


### 補足
想定しているのは標準入力とか

```
$ echo ほわ〜ぁ | python width.py
8
```
```Python:width.py
# -*- coding: utf-8 -*-

import sys
s = sys.stdin.readlines()[0].strip()

print width(s)
```

コマンドライン引数とかです

```
$ python width.py ほわ〜ぁ
8
```
```Python:width.py
# -*- coding: utf-8 -*-

import sys
s = sys.argv[1]

print width(s)
```

あと、ギリシャ文字とかアラビア文字とかは動作保証対象外です
PEMからPFX形式に変換する時に参照するサイト

[OpenSSL] 証明書変換方法（PFX←→PEM変換） | Kung Noi Blog http://www.goodnai.com/blog/2013/11/01/openssl-%E8%A8%BC%E6%98%8E%E6%9B%B8%E5%A4%89%E6%8F%9B%E6%96%B9%E6%B3%95%EF%BC%88pfx%E2%86%90%E2%86%92pem%E5%A4%89%E6%8F%9B%EF%BC%89/