OmniAICreator/Qiita-1.07M huggingface dataset:
【UNITY】007っぽいスポットライト演出作ってみた【Shader】【PostProcess】

初投稿です。
# 作ったもの
まずはこちらをご覧ください。
<blockquote class="twitter-video" data-lang="ja"><p lang="ja" dir="ltr">Shader とPostProcess でスポットライト風エフェクト作ってみた（モバイルでも動くよ） <a href="https://t.co/L0grnsx0a2">pic.twitter.com/L0grnsx0a2</a></p>&mdash; 人生＼(^o^)／ (@8bitdots) <a href="https://twitter.com/8bitdots/status/976004182283993088?ref_src=twsrc%5Etfw">2018年3月20日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 実装について
PostProcess による、現在カメラ写している絵を取得＆加工　することで実装しました。
手順としては
1. カメラコンポーネントにアタッチしているC# スクリプトでOnRenderImage　でカメラで写している絵をTexture として取得
2. そのTexture を事前に専用Shader を設定したMaterial に適応
3. Shader 内で表示/非表示を判定

## C# コードについて
[こちら](http://nn-hokuson.hatenablog.com/entry/2016/11/17/204831)にある通り、OnRenderImage 関数無いでBilt しているだけです。
~~コピペでいけますね~~

## Shader について
基本的にはピクセルシェーダー(フラグメントシェーダー)で行います。
※ポイント
- if文は並列演算を行うGPUにとって処理が重いので
条件分岐はif文ではなく Clamp やlerp を用いて表現
- 2乗は関数ではなくそのまま A x A みたいに書いてしまう
- 平方根を計算するのが重いので2乗した値で比較する

実際のコードは以下の通りです。

```Cg
fixed4 frag (v2f i) : SV_Target
{
	fixed4 col = tex2D(_MainTex, i.uv);
	fixed4 black = float4(0.0, 0.0, 0.0, 1.0);

	// Elipse equation
	// ((x-p)/a)^2 + ((y-q)/b)^2 = 1
	//
	float r = (i.uv.x - _Param.x)*(i.uv.x - _Param.x)/_Param.z/_Param.z+
	(i.uv.y - _Param.y)*(i.uv.y - _Param.y)/_Param.w/_Param.w;

	// r^2 < 1 ? Original : Black
	return lerp(col, black, floor(r) );
}
```
以下解説
- L1:ピクセルシェーダーの関数定義
- L3: 受け取った画像(OnRenderImage で得た画像)のあるピクセルの色情報を取得
- L4: 非表示用の黒色
- L９~10: 楕円の方程式を計算しています。
- L13: 楕円の方程式の計算結果が1以上なら黒, 1未満ならオリジナルの画像を描画

### 楕円の方程式について
高校数学の復習ですね。
中心座標(p,q) でx軸の長さをa, y軸の長さをb とすると下記のような方程式になりますね。
![スクリーンショット 2018-03-20 17.17.03.png](https://qiita-image-store.s3.amazonaws.com/0/65257/871175d3-c61a-7e62-c85b-fa5c9447a34b.png)

左辺が1以下なら楕円内に存在することがわかるので、各ピクセルに対して上記楕円の方程式を解いて楕円内にいるか判定しています。

# 動作確認
動作確認のため、Unity ちゃんを置いてみます。
Unity ちゃんのDL 先は[こちら](http://unity-chan.com/contents/guideline/)
利用規約的にも大丈夫そうですね。

あ、ライセンス、ライセンス
![Light_Frame.png](https://qiita-image-store.s3.amazonaws.com/0/65257/ebbe3621-1dc5-7c90-6ae8-5f7f4a317d7a.png)
これで大丈夫かな。

# 最終的に
冒頭の動画の通り、Shader のパラメータをいじることで指定位置に指定サイズ,形状の円領域のみ表示することができました。
あとは、モーションを右から歩かせてそれに合わせてスポット位置を調整すればいけそうですね。

[ 再掲 ]
<blockquote class="twitter-video" data-lang="ja"><p lang="ja" dir="ltr">Shader とPostProcess でスポットライト風エフェクト作ってみた（モバイルでも動くよ） <a href="https://t.co/L0grnsx0a2">pic.twitter.com/L0grnsx0a2</a></p>&mdash; 人生＼(^o^)／ (@8bitdots) <a href="https://twitter.com/8bitdots/status/976004182283993088?ref_src=twsrc%5Etfw">2018年3月20日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## GitHub
今回作ったShaderとかのコードはGitHub で公開しています。
https://github.com/Cova8bitdots/SpotLightShader


# 参考
【Unityシェーダ入門】Unityのポストエフェクトでモノクロ画面を作る
http://nn-hokuson.hatenablog.com/entry/2016/11/17/204831

Unityちゃん利用ガイドライン
http://unity-chan.com/contents/guideline/

手書き数式認識
https://webdemo.myscript.com/views/math.html#
pk8 と pem から keystore ファイルつくる

- apk に署名しないといけない。
- Unity 上でつくるのが簡単なんだけど、事情があって他から pk8 と pem がきてしまった。

というときのやり方メモ。

```
$ openssl pkcs8 -in platform.pk8 -inform DER -outform PEM -out platform.priv.pem -nocrypt
$ openssl pkcs12 -export -in platform.x509.pem -inkey platform.priv.pem -out platform.pk12 -name hoge
$ keytool -importkeystore -srckeystore platform.pk12 -srcstoretype pkcs12 -destkeystore hoge.keystore -deststoretype pkcs12 -alias hoge
```

あとは Edit → Project Settings → Player の Publishing Settings のとこで、Use Existing Keystore チェックして、Browse Keystore で↑でつくった `hoge.keystore` 選んで、Keystore password いれて、Key のとこの Alias で `hoge` 選んで、Password いれるだけ。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/2595/5d0e33c7-ee16-a05f-0eb6-754c52a4e067.png)
Ubuntuで発生するmatplotlibのエラーの対処

# はじめに
Windowsで書いていたpyファイルをUbuntu上で動かそうとしたらエラーが出た。その対処法のメモ。

# 実行環境
Ubuntu 16.04 LTS
Python 3.6.3
matplotlib 2.2.2

# 事象
plt.showしていたWindowsで動かしていたpyファイルをUbuntu上(正確にはコンテナ上)で動かそうとしたら以下のエラーが発生。

>_tkinter.TclError: no display name and no $DISPLAY environment variable

# 対処法
plt.showではなくplt.savefigにしてファイル保存しますがそれだけではダメで、
以下の手順が必要みたいです。

設定ファイル「matplotlibrc」を修正します。
まずpythonを起動してmatplotlibの設定ファイルの場所を確認。

```python
import matplotlib as mpl
print(mpl.get_configdir())
```

>/root/.config/matplotlib

ただし、おそらく上記の場所に「matplotlibrc」は存在しません。

>/etc/matplotlibrc

があるため、vimで以下を修正する
>backend : TkAgg
>↓
>backend : Agg

その上で、「matplotlibrc」をコピー

```
cp /etc/matplotlibrc /root/.config/matplotlib/matplotlibrc 
```

これでOK。

# 参考
[matplotlibで$DISPLAYが未定義の際に怒られた場合の対応](http://nc30mtd.oops.jp/blog/2016/08/matplotlibdisplay.html)
[Matplotlibのグラフのスタイルを設定ファイル・スタイルシートで変更](https://note.nkmk.me/python-matplotlib-matplotlibrc-stylesheet/)
Laravel5.6のルーティング基礎

# URLとコントローラ（メソッド）の関連付け

コントローラ

    app\Http\Controllers\Japan\Tokyo\ShibuyaController.php

を作ったとする。

```php

<?php

namespace App\Http\Controllers\Japan\Tokyo;
use App\Http\Controllers\Controller;

class ShibuyaController extends Controller
{
    public function __construct()
    {

    }

    public function shopAndStation()
    {
        echo 'Recommendation store of Shibuya.';
    }
}


```

このとき、下記のようにルート設定をする。routes\web.php

    Route::get('/hoge/piyo/foo/bar/', 'Japan\Tokyo\ShibuyaController@shopAndStation');

そして、

    http://localhost/hoge/piyo/foo/bar

にアクセスすると、ブラウザに

    Recommendation store of Shibuya.

と表示される。

# URLとコントローラ（メソッド）の関連付け（GETパラメータの渡し方）

メソッドが

```php

    public function shopAndStation($name)
    {
        echo 'Recommendation store of Shibuya.' . $name;
    }

```

のように、引数で $name を受け取るようになっている場合。
ルートを下記のように設定する。

    Route::get('/hoge/piyo/foo/bar/{name}', 'Japan\Tokyo\ShibuyaController@shopAndStation');

そして、

    http://localhost/hoge/piyo/foo/bar/yoshinoya

にアクセスすると、ブラウザには

    Recommendation store of Shibuya.yoshinoya

と表示される。

# URLとコントローラ（メソッド）の関連付け（GETパラメータを2つ渡す場合）

下記のようにすれば、2つ以上のGETパラメータを渡すことも可能。

```php

    public function shopAndStation($name, $date)
    {
        echo 'Recommendation store of Shibuya.' . $name . ' : ' . $date;
    }

```

ルートは

    Route::get('/hoge/piyo/foo/bar/n/{name}/d/{date}', 'Japan\Tokyo\ShibuyaController@shopAndStation');

とする。

    http://localhost/hoge/piyo/foo/bar/n/yoshinoya/d/20180320

にアクセスすると、ブラウザには

    Recommendation store of Shibuya.yoshinoya : 20180320

と表示される。
Windows10にWSLをインストールする

# はじめに

Windows10にWSL（Windows Subsystem for Linux）をインストールしてみた。その備忘録。
さて、WSLってなんでしょう？Windows上で動くLinux環境の事みたいだ。だが、どうも仮想環境という訳ではなさげ。どうもマイクロソフトもOSSの路線に流れつつある印象は持ってはいたが、どうも本気みたいだ。WindowsでCGIでコマンドを打ちたければ、今まで通り、MS-DOSやPower Shellを利用すればいい。しかし遂に、LinuxコマンドでWindowsの各種設定をできるようにしたのだ。アンチMSだが、仕方なくWindowsOSを利用し続けていた開発者には嬉しいに違いない。勉強のために、仮想環境でLinuxを利用していた人にとっても嬉しいだろう。これで本番環境に近い緊張感でコマンドを打って勉強する事ができる。Linux vs Windowsの戦いは、遂に相手陣地に足を踏み入れた形となった。

# インストール

1.コントロールパネルから「プログラムと機能」を選択
2.左上にある「Windowsの機能の有効化または無効化」を選択

![image.png](https://qiita-image-store.s3.amazonaws.com/0/94029/a7444f55-665c-2c2c-5b21-87d3ff91a8a8.png)

3.「Windows Subsystem for Linux」の左側にチェックしてOKをクリック
4.完了しましたのメッセージが出てきたら再起動
5.「Microsoft Store」を起動
6.「linux」で検索

![image.png](https://qiita-image-store.s3.amazonaws.com/0/94029/6cce1edc-bba2-f31b-8dc7-395c976f6e14.png)

7.「アプリを入手する」をクリック

![image.png](https://qiita-image-store.s3.amazonaws.com/0/94029/9744e389-fa82-b50f-5dc7-2df079a98e85.png)

8.今回インストールするディストリビューションはUbuntuなので、「Ubuntu」をクリック

![image.png](https://qiita-image-store.s3.amazonaws.com/0/94029/94f39b51-17e6-4952-d350-53b4abdb556e.png)

9.「入手」をクリック
10.「サインイン　or　必要ありません」を聞いてくるメッセージが表示されるが、自分の場合は「必要ありません」選択して続行

![image.png](https://qiita-image-store.s3.amazonaws.com/0/94029/1d4da012-de53-bdf7-e170-0622ee40ecd6.png)

11.インストールが完了するとこのように表示
12.「スタートにピン留めする」をクリックして留めておいた
13.Windows Store の画面は閉じる

# Ubuntuの起動

1.Windowsのピン留めから「Ubuntu」を起動

![image.png](https://qiita-image-store.s3.amazonaws.com/0/94029/3cbacca5-07b8-e1d0-364c-104afe970d96.png)

2.このように表示されるが暫く待つ　（Linuxのファイル環境などをユーザーフォルダの下に展開するための作業が行われているそうで、初回起動時のみ時間がかかるみたいだ）

![image.png](https://qiita-image-store.s3.amazonaws.com/0/94029/4284e6ea-9400-e848-6548-c7b3c3bdce85.png)

3.ユーザー名とパスワードが聞かれる　（Windowsにログインする時にユーザー名とパスワードとは別に、WSLの中だけの閉じた環境でユーザー管理をするためのアカウントの登録になるようだ）

![image.png](https://qiita-image-store.s3.amazonaws.com/0/94029/45a6b886-84d5-454c-8522-e3c44c2838bb.png)

4.プロンプトが表示される
5.Ubuntsを終了させる時はlogoutコマンド

はい、お疲れさまでした
【Swift】NotificationCenterを扱いやすくする

# オブザーバーの登録/解除するカスタムクラス
```swift:NotificationObserver.swift
import Foundation

final class NotificationObserver {
    
    typealias Action = (_ notification: Notification) -> Void
    
    private let center = NotificationCenter.default
    let name: NSNotification.Name
    private var token: NSObjectProtocol?
    let action: Action
    
    init(name: NSNotification.Name, action: @escaping Action) {
        self.name = name
        self.action = action
    }
    
    func addObserver() {
        token = center.addObserver(forName: name, object: nil, queue: nil, using: { (notification) in
            self.action(notification)
        })
    }
    
    func removeObserver() {
        guard let token = token else { return }
        center.removeObserver(token)
        self.token = nil
    }
    
}
```

# 使い方

```swift
import UIKit

var applicationWillEnterForegroundObserver = NotificationObserver(name: .UIApplicationWillEnterForeground) { (_) in
    print("例として、UIApplicationWillEnterForegroundをハンドリングする")
}

// viewWillAppear(_:) などで登録する
applicationWillEnterForegroundObserver.addObserver()

// viewWillDisappear(_:) などで解除する
applicationWillEnterForegroundObserver.removeObserver()
```

# オススメな使い方

用途・種類に応じて、オブザーバーインスタンスを配列に入れておくと、スッキリして見やすくなります。

```swift
import UIKit

var applicationWillEnterForegroundObserver = NotificationObserver(name: .UIApplicationWillEnterForeground) { (_) in
    print("例として、UIApplicationWillEnterForegroundをハンドリングする")
}

// オブザーバーを配列にする
func applicationObservers() -> [NotificationObserver] { return [applicationWillEnterForegroundObserver] }

// viewWillAppear(_:) などで一括登録する
applicationObservers().forEach { $0.addObserver() }

// viewWillDisappear(_:) などで一括解除する
applicationObservers().forEach { $0.removeObserver() }
```
[IoT×AWS] AWSIoTにMQTTでPublishしてるけどデータの欠損を無くしたいって言われた時は…

# はじめに

IoT関連の案件に携わっていて、お客様が強い関心をお持ちになる事の一つに **データの欠損** があります。
センサーが取得したデータが欠損してしまうということは、お客様から見ると **データをDBに格納する処理のバグ** という認識をされてしまう可能性があります。
もちろん100%データの欠損しないというのは難しい話になりますが、限りなくデータの欠損を0%に近づけていきたいですよね。
今回はそんな要望に対して一人の開発者が奮闘した記録となります。

## あんた誰よ？

はい、私は[こういうサービス](https://iot.kyoto)を展開しているチームの一員です。
IoT関連の案件に携わっており、基本的にAWSの環境上にシステムを構築しています。
他にも通信回線にはSORACOM様のサービスを利用しています。(というかほとんどSORACOM様のサービスを使っている)

## では本題です

デバイスからAWSIoTにPublishしてLambdaでデータを加工、そのあとDynamoDBにデータをPUTするという処理フローがありました。
こんな感じです。

![スクリーンショット 2018-03-20 16.24.08.png](https://qiita-image-store.s3.amazonaws.com/0/95875/fab95de7-355e-d29a-afe6-1da8ca664798.png)

上記のような処理フローの中で、どのような場合にデータ欠損する可能性があるでしょうか？
※決してこれだ！という答えがあるわけではありません。

## 体験記

先ほどの画像と同じ構成でDeviceからデータを受け取っていたところ、データが欠損していました。
Deviceの数が増えるなどして、送信されてくるデータ量が著しく増加した際に、DynamoDBのスループットに十分なキャパシティが適用されていないがために、LambdaからのPUT時にDynamoDBが「もうスループットに余裕がないから受け入れられないンゴ」といって、LambdaがPUTできずにエラーを吐いていたのです。スケールしたときの対処がなされていなかったということですね。

AWSIoTは基本的にデータを横流しにするだけなので、Lambdaをinvokeすればデータは削除されてしまいます。
Lambdaも性質上、一度実行が完了すればそのときのデータを保持することはありません。
なので、「DynamoDBのスループット不足でLambdaがPUTできない」 = 「データの欠損！」となるわけです。

「それならDynamoDBのスループットを十分に確保すれば問題解決するやん」と思うのですが、そうすると当然のごとく金額が上がってしまいます。要するに運用費が上がります。できるだけ避けたいですよね。
DynamoDBのスループット課金は時間単位での課金となるので、データがきていないときもその時のスループット分は課金されてしまいます。

DynamoDBにはスループットをオートスケールさせる機能があるので、
「オートスケールが適用されるまでなんとか待てへんものか？」
と考えていたときでした…
「そうか！KinesisDataStreamsを間に用意してやればええやん！」
と閃いたわけです。

## どうしたか？

結論。こうしました。

![スクリーンショット 2018-03-20 16.44.16.png](https://qiita-image-store.s3.amazonaws.com/0/95875/30a8d7f7-a146-c54a-c399-07832447ef1f.png)

AWSIoTとLambdaの間にKinesisDataStreamsを用意しました。
KinesisDataStreamsはストリームデータを処理するために弊社でもよく使っているサービスで、一定時間(24~168h)データを保持してくれます。
そのあとのLambdaでエラーが発生した時にちゃんとエラーをcallback()で返せば、Lambdaの再invokeをしてくれます。
要するに、 **Lambdaがエラーで死んでも(一定時間は)データが欠損することがない** ということです。
（Kinesis StreamsのようなストリームベースのイベントソースがトリガのLambdaは、エラー時にデータの有効期限が切れるまで処理を再実行してくれますが、その代わりに、エラーが発生した以降のデータは処理されずに、いわゆる「詰まった状態」になってしまいます。詰まった状態のまま有効期限が過ぎると、そのデータは愚か、それ以降のデータまで実行すること無くロストしていってしまうので、DynamoDBのAutoScaleが確実に有効である事を確認する必要があります）

# さいごに

もちろんKinesisDataStreamsもシャードという単位で金額がかかってきます。(約$20/month)
実際にDynamoDBのスループットを十分に確保するための金額と比較すると半額程度ですみましたので、この構成を採用しました。
DynamoDBのスループットを確保する方が安く済むのであっても、KinesisDataStreamsを用意しておけば、AWSIoTのみの構成よりもデータの欠損を防ぐことができるのでおすすめです。

今回は **データ欠損を防ぐ(減らす)** という観点で考えた時に、私一個人としては「KinesisDataSteamsにデータを保持させる」という答えにたどり着きました。もちろん他にも答えがあると思います。

この記事は **個人的に考えついたベストプラクティス** を書いています。他にもこんな方法あるよ！などご教授いただければ嬉しいです。

ではまた！
CircleCI 2 で Oracle Java 8を入れる

swagger-genを動かすためにJavaが必要だったので
CircleCI2にJava8を入れたときのメモ

```
# Javascript Node CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-javascript/ for more details
#
version: 2
jobs:
  build:
    docker:
      # specify the version you desire here
      - image: circleci/node:6.11.2

    working_directory: ~/repo

    steps:
      # install java 8
      - run: echo "oracle-java8-installer shared/accepted-oracle-license-v1-1 boolean true" > debconf.txt
      - run: sudo debconf-set-selections debconf.txt
      - run: sudo apt-get install software-properties-common
      - run: sudo add-apt-repository "deb http://ppa.launchpad.net/webupd8team/java/ubuntu xenial main"
      - run: sudo apt-get update
      - run: sudo apt-get install oracle-java8-installer
```
bash > fileIO > ファイル存在のチェック (existのe) | regular fileの定義 | testの-hと-Lはsymbolic linkの元ファイルをチェックする


FeeBSD2.2.6?からの練達である(話半分)7of9であるが、「bashのファイル存在チェックはどう書くのだっけ？」という日々を過ごす。

man bashでCONDITIONAL EXPRESSIONSにて様々な選択肢がある。

```
       -a file
              True if file exists.
       -b file
              True if file exists and is a block special file.
       -c file
              True if file exists and is a character special file.
       -d file
              True if file exists and is a directory.
       -e file
              True if file exists.
       -f file
              True if file exists and is a regular file.
       -g file
              True if file exists and is set-group-id.

(以下略)
```

記憶の宮殿にコマンドオプションを格納する案として、「**e**xistの`-e`」と覚えればいいだろう (こじつけ)。

一方で、`-f`オプションを使う例もある。

> True if file exists and is a regular file.

regular fileとは何か?

https://stackoverflow.com/questions/10204562/difference-between-if-e-and-if-f

> answered Apr 18 '12 at 7:10
jman

> A regular file is something that isn't a directory / symlink / socket / device, etc.

つまり、symbolic linkしたファイルはregular fileでないため、`-f` testは失敗する、と推測した。

man bashにはregular fileの定義はない。

と思ったが、以下を見つけた。

https://stackoverflow.com/questions/10204562/difference-between-if-e-and-if-f
> Strange, on Ubuntu 14.04, using `-f`, it evaluates to true even for symlinks... – Garrett May 15 '15 at 18:28


### CentOS 6.9

```txt:動作環境
Xeon E5-2620 v4 (8コア) x 2
32GB RAM
GeForce GT 730 1GB GDDR5
CentOS 6.9 (64bit)
NCAR Command Language Version 6.3.0
for WRF3.7.1, WPS3.7.1
  openmpi-1.8.x86_64 とその-devel
  mpich.x86_64 3.1-5.el6とその-devel
  gcc version 4.4.7 (とgfortran)
for WRF3.9, WPS3.9
  Open MPI v2.1.1
  gcc version 4.9.2 (とgfortran; devtoolset-3使用)
　NetCDF v4.4.1.1, NetCDF (Fortran API) v4.4.4
Python 2.6.6 (r266:84292, Aug 18 2016, 15:13:37) 
Python 3.6.0 on virtualenv
GNU bash, version 4.1.2(2)-release (x86_64-redhat-linux-gnu)
date (GNU coreutils) 8.4 
tmux 1.6-3.el6
```

```bash:check_file_exist_180320_exec
#!/usr/bin/env bash

set -eu  # just in case 

if [ -e LN-file ]
then
	echo "file exists [-e]"
fi

if [ -f LN-file ]
then
	echo "file exists [-f]"
fi
```

```bash
$ touch afile
$ ln -fs afile LN-file
$ bash check_file_exist_180320_exec 
file exists [-e]
file exists [-f]
```

CentOSでは`-f`のregular fileの結果でsymlinkは含まれるようだ。


### Stackoverflow

質問しておいた。
https://stackoverflow.com/questions/49380068/what-is-the-regular-file-on-centos-and-ubuntu

nos氏による回答によると、`-h`と`-L`オプションではsymbolic linkはなく、その元ファイルのチェックになるようだ。
ヒューマンピクトグラム2.0の画像で遊んでみた

知人からヒューマンピクトグラム2.0というサイトを教えてもらったので、
お遊びで5つほど作ってみた。

ヒューマンピクトグラム2.0
http://pictogram2.com/

1
<img width="489" alt="スクリーンショット 2018-03-20 16.29.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/42969/64c58e6b-a077-bc56-5d33-67ddb55c22ba.png">

2
<img width="456" alt="スクリーンショット 2018-03-20 16.30.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/42969/a94fbc1c-77c3-5b07-4d62-381b7f081582.png">

3
<img width="404" alt="スクリーンショット 2018-03-20 16.32.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/42969/b5a08323-51c2-9957-2a0f-1ce42a0c1e99.png">

4
<img width="1014" alt="スクリーンショット 2018-03-20 16.41.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/42969/745558c4-a15a-bb5b-a7b0-d0385f314c76.png">

5
<img width="1069" alt="スクリーンショット 2018-03-20 17.07.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/42969/38f688ed-39b9-ea2c-0ff5-a5921d5422ba.png">

以上っす。
FileMakerのボタンバーとスライドコントロールで疑似タブコントロール化


今回はFileMaker14から追加されたボタンバーとスライドコントロールを利用してタブコントロールの代替機能を実現する方法です。
標準のタブコントロールがあるのに何故こんなことをするかというと、標準の機能だとタブ部分のデザインなどの変更が柔軟に出来ないため使っています。

スライドコントロール側でのパネル切替を抑止してして、ボタンからだけ制御できるようにします。

方法を簡単に説明すると、ボタン数とスライド数を同数用意して、各スライドに名前を付け、ボタンが押された時に対応したスライド名のオブジェクトに移動させます。

設定方法を順に説明します。
## 設定手順
１．ボタンコントロールとスライドコントロールをレイアウトに載せます
![スライダーによるタブ1.png](https://qiita-image-store.s3.amazonaws.com/0/68589/e022a4b4-6f2a-db27-9412-914f1ea2129a.png "スライダーによるタブ1.png")

その時、スライドコントロールの設定で以下の2つのチェックを外します。
- 「スワイプジェスチャを有効にする」
- 「ナビゲーションドットを表示」
![スライダーによるタブ2.png](https://qiita-image-store.s3.amazonaws.com/0/68589/5b3b0216-3432-7138-09b0-f0d2dc86ae5c.png "スライダーによるタブ2.png")

２．各スライドに名前を付けます
![スライダーによるタブ3.png](https://qiita-image-store.s3.amazonaws.com/0/68589/94e04d26-842e-78d8-938c-399a32430acd.png "スライダーによるタブ3.png")

３．各ボタンのクリック時にスライドを切り替える設定をします。
![スライダーによるタブ4.png](https://qiita-image-store.s3.amazonaws.com/0/68589/70621df7-7759-60f3-57f8-2f840626c814.png "スライダーによるタブ4.png")


以上です。
オブジェクトの名称とボタンに設定した名称が正しければこれで動作するはずです。
応用としてｓスライドコントロールは、ステップダイアログなどにも使用できますので、是非活用してみてください。
udacityとudemy

udacityはプログラミング中心か？英語の動画のレクチャーを見て勉強していくタイプで、１講座１万円台から？１講座あたりの量はそこそこ。

udemyはベネッセと提携している？
今キャンペーンだかで大半の講座が１４００円になってる。
プログラミングに限らず様々な講座がある模様。
Firebase User Propertiesの検証

FirebaseのUserPropertiesを使ってできることのまとめと
ユーザプロパティを変更した場合の挙動についての検証

# ユーザプロパティを使ってできること
- イベントデータをプロパティでフィルタする：PVイベントをフィルタして、通知をONにしている人のPVイベントを見る
- プロパティでユーザを分類、グループ化する: 通知をONにしているユーザ、通知をOFFにしているユーザで分類する
- 分類したユーザリストを使って特定のユーザに何かする： 購入歴ありのユーザリストにのみに通知を送る。

# ユーザプロパティを設定すると具体的にどうなるのか
- 自動的にユーザプロパティで分類したユーザリストが作られる
- アナリティクスのイベントデータに設定したユーザプロパティ情報が含まれる

# ユーザプロパティを変更した場合の挙動を検証
アイテムの購入歴を表すユーザプロパティ`"have_purchased"`を定義
購入経験が「ない」から「ある」に変わった場合にどうなるのか。
`"have_purchased" = false`を`"have_purchased" = true`とする

## アナリティクスイベント

PVイベントなどイベントデータに含まれるユーザプロパティは過去に遡って変更されることはない： (DebugView上の表示での確認。TODO:反映されたら生データを確認する)

過去のイベントには`"have_purchased" = false` 、変更後のイベントには`"have_purchased" = true`が設定されている

`"have_purchased" = false`から`"have_purchased" = true`に変更して変更前後のイベント情報を確認する

下のように`"have_purchased" = true`とした後のプロパティは当然`"have_purchased" = true`となる
![スクリーンショット 2018-03-20 15.58.39.png](https://qiita-image-store.s3.amazonaws.com/0/230408/36f23f6a-47ac-a0f3-3793-c6e34f96a205.png)

`"have_purchased" = true`とする前のプロパティは falseとなっているので
過去のイベント分はプロパティを変更してもそのまま
![スクリーンショット 2018-03-20 15.58.28.png](https://qiita-image-store.s3.amazonaws.com/0/230408/c92f16c7-4cd2-657c-6121-9d097d9e0bf6.png)



## ユーザリスト
- プロパティを変更すると最新のプロパティに基づいて分類される
- 以前は購入したことがなかったが、その後購入したという時。購入したことがないユーザかつ、購入したことがあるユーザというように二重にリストに参加することにはならない。


### 検証した内容
`"have_purchased" = false`　に設定。通知を送る


|未購入ユーザリストへ通知する|購入ユーザリストへ通知する|
|:--|:--|
|届く|届かない|

プロパティを変更する
`"have_purchased" = true`　に設定を変更


| 未購入ユーザリストへ通知する | 購入ユーザリストへ通知する |
|:-- |:-- |
| 届かない | 届く |

最新のユーザプロパティで正しく分類され通知が送られている。

# memo
DebugView上でUserPropertyの変更の反映が少し遅い。
プロパティを変更しても表示上は古い情報のままだったりする。
通知では正しく分類されているので表示の問題のみで、ユーザリストの更新は即時にされている様子。
AWSのcloud9に接続できない問題の解決法

##起こった問題
前まで普通にcloud9に接続できていたのですが、急に以下の画像のようなエラーが出て接続不可能になりました。ブラウザはChromeを使っていました。
エラー文はこれです。
`This is taking longer than expected. If you think there might be an issue, contact AWS Support.
It might be caused by VPC configuration issues. Please check documentation.`

<img width="1280" alt="スクリーンショット 2018-03-20 16.25.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/237856/c2a5d68e-7a81-48d5-fc0f-f7c9a50cb4de.png">

##解決方法
ブラウザをChromeからsafariに変更する。
これでなんの問題もなく接続することができました。
どうやらChromeだとブラウザの問題でたまにこのエラーが起こってしまうようです。
詳しい原因は探ってみたもののわからず終いでした。

##終わりに
もし原因を知っていたり、Chrome上でアクセスさせるための方法をご存知の方がいましたらぜひコメントで教えていただけると幸いです。
Heroku上のLaravel AppにIP制限をかける


# 手順

- `\App\Http\Middleware\IPAuthMiddleware` を作成
- `\App\Http\Kernel` に登録
- Herokuの Config Variables にIPアドレスをカンマ区切りで追加

## ポイント

- Heroku上のAppではIPアドレスを取得するときは先に `setTrustedProxies` を通す

## 


```php:IPAuthMiddleware.php
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Response;

class IPAuthMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $isPrd = !$this->isDebug();
        $isDenied = !$this->whetherThisIpAccepted();
        if ($isPrd && $isDenied) {
            return Response::create(view("errors.403"), 403);
        }
        return $next($request);
    }

    protected function isDebug()
    {
        if (env('APP_DEBUG') !==  true) {
            return false;
        }
        return true;
    }

    protected function whetherThisIpAccepted()
    {
        $ipArr = explode(',', env("APP_IP_chatbox", ""));
        \Request::setTrustedProxies([\Request::ip()]);

        if ($ipArr && !in_array(\Request::ip(), $ipArr)) {
            return false;
        }
        return true;
    }
}

```

# 参考
https://www.messiahworks.com/archives/14930
http://pdo99.hatenablog.com/entry/2017/06/27/175316

## その他の手法
https://stackoverflow.com/questions/18264304/get-clients-real-ip-address-on-heroku/18517550#18517550
[AWS] Lambda Function の CodeSha256 をPythonで計算する

# やりたいこと
AWSに登録済みのLambda Functionのコードと、これから更新しようとしているコードが同一かどうか判断するには、`CodeSha256`を比較します。… よね？
わざわざコードを落としてきて比較とかしないですよね？

登録済みのコードの`CodeSha256`はAWS側で勝手に計算されていますが、手元にあるコードの`CodeSha256`は自力で計算する必要があります。そういうことをやってくれるツールを使っていなければ。

というわけで、Pythonで`CodeSha256`を計算する方法です。
名前は`CodeSha256`ですが、単純に`SHA256`の計算だけすればいいというわけでもなかったりします。

# CodeSha256 計算

## 計算方法
* zipファイルのバイナリの
* `SHA256`を計算し
* base64エンコードする。

以上。


## サンプルコード

### 前提
* Python 3.6

### コード
```Python:python3.6
# coding: utf-8

# required
import hashlib
import base64

# for sample
import json

if __name__ == '__main__':

    # zipファイルをバイナリモードで読み込み
    function_zip_path   = "/path/to/lambda_function.zip"
    f = open(function_zip_path, 'br')
    function_zip_bynary = f.read()
    f.close()

    # sha256算出
    sha256               = hashlib.sha256(function_zip_bynary).digest()
    sha256_base64        = base64.b64encode(sha256)
    sha256_base64_str    = sha256_base64.decode()

    # 表示
    print(json.dumps(sha256_base64_str, indent=2))

```

`base64.b64encode()`は bytes を返しますので、最後に`.decode()`でstrに変換してます。
FaceRigで録画できない人のための対処法

![facerig_recording_error.PNG](https://qiita-image-store.s3.amazonaws.com/0/242611/7c65840c-830b-a4aa-9224-549218c1698d.png)

FaceRigで撮影を試みたものの、上のようにムービーエクスポートエラーが発生してしまいました。


>ムービーはエクスポートできませんでした。確認できるアプリケーションの前提条件を再インストールしてください

と書いてあります。

FaceRigを入れたときに、前提条件も同時にインストールされるものだと思っていたんですが、これらは個別に、手動で再インストールする必要があるそうです。

参考記事:http://steamcommunity.com/app/274920/discussions/2/451848854993041115/

##前提条件を再インストールする


C:\Program Files\Steam\steamapps\common\FaceRig\Bin\prerequisitesに移動してください。

**install_webmdshow** と, **opencodes_0.85.17777**があるかと思うので、
opencodes_0.85.17777 →　install_webmdshowの順番でインストールします。
![facerig_recording_option.PNG](https://qiita-image-store.s3.amazonaws.com/0/242611/066e4ee9-173c-77af-e19c-543293d8fe19.png)


そしたらFaceRigを再起動し、録画をしてみましょう。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/242611/323376b4-fb1b-dea0-ea95-a08493faa52b.png)


録画ができたらWEBMファイルとして保存されます。
![facerig_recording_storage.PNG](https://qiita-image-store.s3.amazonaws.com/0/242611/a67daaa5-01a5-b421-c593-fa618947fa94.png)

お疲れ様でした。

##それでもできなかったら、、

それでもできないといった場合には、FaceRig自体をアンインストールすると解決するかもしれません。

いずれにせよ、prerequisitesファイルにある、install_webmdshow,opencodes_0.85.17777がないと録画はできないので、もしそれらが見つからなければ再度インストールする必要がありそうです。
GitLab上で巨大なファイルのdiffが表示できない問題

# 背景
仕事でGitLabを使っていますが、しばしばファイルのサイズが大きくて差分が見れない状況に陥る事があります。その際にはgit diffで凌いだりしてますが、レビューのコメントを書き込んだりできず不便な思いを強いられています。

いい加減うんざりしてきたので、
- この問題は既に修正されていないか？　
- Walkaroundは用意されていないか？ 

少し調べてみました。

#調査結果
ほどなく、このバグを報告している[ページ](https://gitlab.com/gitlab-org/gitlab-ce/issues/30061)を見つけました。

この問題はおよそ1年前（2017年2月）にバグとして報告されていますが、驚いた事に「残念ながら、差分の上限値の設定は変更できるようにはなっていないんだよー。」と言ってMark Fletcherという方がサクッとバグをクローズしています。

#炎上
誠意を見せないMark Fletcherさんに、バグの報告者であるkrisnilもあきらめかけた(?)頃、他の開発者達の猛反発がはじまります（翻訳は私の独断と偏見でおこなってますので悪しからず）。

「何のアクションもとらずにこのバグをクローズするなんて信じられない。このバグのせいで我々はGitLab上でコードレビューができないというのに・・・。」

「俺もそう思う。これは重大な問題だ。修正方法もWalkaroundについても何も知らせてこない。」

「そうだー。このバグはオープンし直すか、上限値を変更できるよう新機能としてリクエストされるべきだ。そもそもなぜこんな問題が存在するのか理解に苦しむ。ファイルの中身は見る事ができるのに、差分がみれないなんて・・・。」

「マジで頼みますよ。」

#鎮火
解決方法や問題の重要性に関して議論が加熱し大炎上になりましたが、開発マネージャーのSean McGivernさんがコメントして、ようやく少し落ち着きます。

「皆さんの声は届いています。我々もこのバグが問題なのは理解してますし、我々にとっても問題です。問題を根本から正しく解決するには、それなりの時間を使い慎重に考え抜かなければなりません。そのため我々としては他の優先度の高いタスクとうまくバランスをとっていく必要があります。」

GitHubではこの問題は起きていないとか、このバグが修正されない限り、GitLabへの移行はできないなど不満の声もありましたが、開発の責任者が正式に前向きなコメントした事で、ようやく事態は収拾したようです。




#現状（2018年3月上旬）
バージョン10.7の一部として、この問題に関する更なる調査と解決法が模索されている。さしあたり、以下の３つに取り掛かっていくみたいです。

1. 全てのソースから、差分の中身とは別に差分に関する情報 (stats)をロードできるようにする。
2. 差分に対し、無限スクロールを実装する。
3. １つのファイルに対し、現在のExpand / Collapse よりも良い差分の表示を可能にする。


仕事上、結構不便なので一日も早く修正版がリリースされる事を願います。

[参照]
https://gitlab.com/gitlab-org/gitlab-ce/issues/30061
yolov2で学習させるための自分用メモ

とりあえず自分がわかればokなので本当にメモ

`cfg/~.data`ファイルにトレーニングファイルの場所とか記載
`~.names`ファイルにクラス名を記載(置く場所は↑で記載)
学習用画像を`train_images`ディレクトリ(名前、場所は↑で記載)に入れる
アノテーション情報が記載されたtxtファイルは`train_labels`に入れる(`train_images`ディレクトリの`images`部分を`labels`に変更したディレクトリ)

`train.txt`と`test.txt`には学習用画像の相対pathを記載する↓
(darknetから見た相対パス `data/~/train_images/~.jpg`)

↓これとかで`train.txt`と`test.txt`は画像から簡単に作れる([参考](https://timebutt.github.io/static/how-to-train-yolov2-to-detect-custom-objects/))

```
import glob
import os

image_dir = './images/'
path_data = 'data/train_images/'

# testに使う割合
percentage_test = 2

file_train = open('train.txt', 'w')
file_test = open('test.txt', 'w')

counter = 1
index_test = round(100 / percentage_test)
for pathAndFilename in glob.iglob(os.path.join(image_dir, "*.jpg")):
    title, ext = os.path.splitext(os.path.basename(pathAndFilename))

    if counter == index_test:
        counter = 1
        file_test.write(path_data + title + '.jpg' + "\n")
    else:
        file_train.write(path_data + title + '.jpg' + "\n")
        counter = counter + 1
```

cfgファイルのclassesの数を変更
filtersも↓の式で変更
*filters = num * (classes + coords + 1)*

学習(-i 0 は使うGPUを指定するやつ)
`./darknet -i 0 detector train cfg/~.data cfg/~.cfg darknet19_448.conv.23`

途中から学習し直し
`./darknet -i 0 detector train cfg/~.data cfg/~.cfg backup/~.weights`
Project Euler 59「XOR暗号解読」

暗号解読よりも先に問の読解力が試される。
暗号化鍵の3文字は一文字ずつ繰り返し使用するってことなんですね。
意味が分からず小一時間右往左往しました。

下記リンクによると最も使用頻度の高い英単語は「the」らしいです。
https://gakumado.mynavi.jp/gmd/articles/17855

# Problem 59 「XOR暗号解読」
(訳者注: 文字コードの説明は適当です) 各文字はそれぞれ一意のコードに割り当てられている. よく使われる標準としてASCII (American Standard Code for Information Interchange) がある. ASCIIでは, 大文字A = 65, アスタリスク (*) = 42, 小文字k = 107というふうに割り当てられている.

モダンな暗号化の方法として, テキストファイルの各バイトをASCIIに変換し, 秘密鍵から計算された値とXORを取るという手法がある. XOR関数の良い点は, 暗号化に用いたのと同じ暗号化鍵でXORを取ると平文を復号できる点である. 65 XOR 42 = 107であり, 107 XOR 42 = 65である.

破られない暗号化のためには, 鍵は平文と同じ長さのランダムなバイト列でなければならない. ユーザーは暗号文と暗号化鍵を別々の場所に保存する必要がある. また, もし一方が失われると, 暗号文を復号することは不可能になる.

悲しいかな, この手法はほとんどのユーザーにとって非現実的である. そこで, 鍵の変わりにパスワードを用いる手法が用いられる. パスワードが平文より短ければ (よくあることだが), パスワードは鍵として繰り返し用いられる. この手法では, 安全性を保つために十分長いパスワードを用いる必要があるが, 記憶するためにはある程度短くないといけない.

この問題での課題は簡単になっている. 暗号化鍵は3文字の小文字である. cipher1.txtは暗号化されたASCIIのコードを含んでいる. また, 平文はよく用いられる英単語を含んでいる. この暗号文を復号し, 平文のASCIIでの値の和を求めよ.


```python
from itertools import product

def hoge(path):
    cipher = [ int(x) for x in open(path).read().split(',') ]
    m = len(cipher) // 3 + 1
    for p in product(( chr(97+i) for i in range(26) ), repeat=3):
        decrypted = [ a ^ b for a, b in zip( cipher, [ ord(x) for x in p ] * m ) ]
        text = ''.join( chr(x) for x in decrypted ) 
        if text.find(' The ') != -1 or text.find(' the ') != -1:
            #print(p, text)
            return sum(decrypted)

print(hoge('p059_cipher.txt'))
```

うーむ、解答も若干難解になってしまったか。
AnsibleでAWSのリージョン間VPCピアリングを構築する（Inter-Region VPC Peering）

先月の2月22日、待ちにまったInter-Region VPC Peeringが東京リージョンにもやってきました :tada: 

https://aws.amazon.com/jp/blogs/news/inter-region-vpc-peering-is-now-available-in-nine-additional-aws-regions/

Inter-Region VPC Peeringは世界中の（対応している）リージョンとVPC Peerを張れる機能です。
これで、今まで東京リージョンに来ていなかったAWSサービスを使う事が可能となります。
EC2 C5シリーズとか、ECS Fargateとか、Amazon EFSとか！

それでは、早速導入していきましょう。
Webコンソールからはボタン3つぐらいで出来るのですが
今回はAnsibleを使って構築していきます。

# 概要

Ansible2.5のec2_vpc_peerモジュールでpeer先のリージョンが指定できるようになります。
https://github.com/ansible/ansible/blob/stable-2.5/lib/ansible/modules/cloud/amazon/ec2_vpc_peer.py#L30-L34
Ansible2.5を待てない人や、何かしらの理由でアップデート出来ない人は
ライブラリに追加する事で利用ができます。

# 手順

## Ansible2.5のモジュールをコピー

Ansible2.5にアップデート出来る人はこの対応が不要です。

ライブラリパスの通る場所に
上記ec2_vpc_peer.pyファイルを置いてしまいましょう。
ライブラリとAnsible本体に同盟のモジュールがある場合は
ライブラリのモジュールが優先されます。
一部機能だけ先に使いたい場合はダウンロードする事で
古いバージョンのまま新しいモジュールを使うことができます。

もちろん、依存関係があるモジュールなどは依存を気にする必要はありますが。

私の場合は以下のようなファイル構成にして利用しました。

```bash:vpc-create-role
user@my-serv:~/ansible-setup-repository/aws-vpc$ tree -a
.
├── library
│   ├── ec2_vpc_peer.py
│   ├── .gitignore
│   └── README.md
└── tasks
    └── main.yml
```

私はgitignoreで除外設定をしてREADME.mdに説明を書いていましたが
git submoduleなどで管理してもいいですね。

## 2つのリージョンのVPCを用意

VPC Peerを貼るVPCを用意します。

VPCを作る手順は省略します。
Qiitaにもいくつか記事がありますので、参考までにリンクを記載します。
https://qiita.com/search?q=VPC+ansible

この時、Peerを張る先のリージョンをきちんと確認しておきましょう。
（当然ですが…）。
東京リージョンに来ていないFargateやC5インスタンスはus-east-1リージョンで利用可能ですが
過去の障害実績や利用サービス、料金などを見てリージョンを選びましょう。

リージョンごとに利用できるサービス一覧は以下のページが参考になります。
https://aws.amazon.com/jp/about-aws/global-infrastructure/regional-product-services/
過去のリージョンごとの障害は以下の記事を見ておくと安心できます。
https://qiita.com/saitotak/items/07931343bcb703b101f8

## Ansibleでピア設定

Ansible TaskでPeerの設定をします。
以下は参考までに私が記載したTaskです。

```yaml:aws-vpc/tasks/main.yml
- name: Create Connection vpc-a_vpc-b
  ec2_vpc_peer:
    profile: "{{ vpc-a_profile }}"
    vpc_id: "{{ vpc-a_vpc_id }}"
    region: "{{ vpc-a_region }}"
    peer_owner_id: "{{ vpc-b_account_id }}"
    peer_vpc_id: "{{ vpc-b_vpc_id }}"
    peer_region: "{{ vpc-b_region }}"
    tags:
      Name: "{{ peer_name }}"
    state: present
  register: _vpc_peer
```

明確に変更があったのはpeer_regionパラメータだけですね。
その他には、ap-northeast-1固定だったリージョンを変数化していたります。

その後、Route Tableの設定なども必要ですが
これは普通のVPC Peer設定と変わらないですね。

# 最後に

これで東京リージョンに来ていないAWSサービスが利用しやすくなりました！

リージョン間の通信費など、考えないといけない事は残っていますが
別リージョンのサービスをVPC内で完結して利用できるので
導入のハードルがだいぶ下がったのではないでしょうか。
RxSwift 用語 Observable

Observable入門
- 監視できる / イベントを流すもの

Observable
- onNext : 通常のイベントを通知する。複数回送ることが可能
- onError : エラーの発生を通知する。発生後はイベントが一切発生がない
- onCompleted : 終了の通知する。発生後はイベントが一切発生がない

それぞれ、onNextは「値が更新された」, onCompletedは「処理が完了した」, onErrorは「エラーが発生した」というイベントを表します。

subscribe（購読）
この登録された処理のことを observerと呼びます。名前はObservableと似ていますが、意味は逆なので注意してください！

※subscribeにはもう一つ大きな意味がありますが、HOT/COLDの章で書きます。

dispose（購読解除）
subscribe処理をいつまでも続ける訳にはいきません。これを止めることをdisposeと呼びます。クロージャなどがメモリ解放されます。

onCompletedやonErrorが発生するとObservableはもうイベントを発行できないので、自動的にdisposeされます。よって、明示的にdisposeする必要はありません。

DisposeBag
DisposeBagを使うと半自動的に解放をしてくれるのでよく使います。

disposeBagは、disposeBagオブジェクト自身が開放されるタイミングで、登録されたsubscriptionをdisposeします。

用語
---

bind() : バインド
action() : アクション
subscribe() : サブクライブ
fetch()　: フェッチ

---


## 関連記事

【About】(http://qiita.com/sunstripe) - サンストライプ

---

## 制作チーム：サンストライプ

[![sunstripe_logo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80600/322f2d60-f19d-af9e-2b6f-7290ca546848.png)](http://sunstripe.main.jp/)
http://sunstripe.main.jp/

(月１WEBコンテンツをリリースして便利な世の中を作っていくぞ！！ボランティアプログラマー/デザイナー/イラストレーター/その他クリエイター声優募集中！!)

### 地域情報 THEメディア
THE メディア 地域活性化をテーマに様々なリリース情報も含め、記事をお届けしてます！！
https://the.themedia.jp/

### ゼロからはじめる演劇ワークショップ
多様化の時代に向けて他者理解を鍛える

https://workshop.themedia.jp/

### プログラミングワークショップ・ウェブ塾の開講！！！
様々なテーマでプログラミングに囚われずに取り組んでいきます。
詳しくはこちら　↓　↓　↓　↓　↓　↓　↓　↓
[プログラミングサロン 月１だけのプログラミング学習塾](https://workshop.themedia.jp/posts/7057553?fbclid=IwAR32CfRQ7RvDOhvuogoSwqxDLMOU7Jvuzljlnx-TMc27qBPX1BnWsfLcBR8
)

### 協力応援 / 支援者の集い
## チーム：サンストライプ
#### プログラミングラボ
https://twitter.com/sunstripe2011

一緒にポートフォリオを作りませんか？現場の体験やそれぞれの立場から年齢関係なく作品を作りたい方々と一緒にチームを作って、作品を作っています。現場に行きたい人には、職場紹介や職場の体験や悩み相談なども受けております。
様々な職種からプログラミングの知識を得たい、デザインの知識を得たい、データーベースの知識を得たいという人が集まっております。
週１のミーティングにそれぞれの近況と作業報告して、たまにリモート飲み会などをしております！！

興味がある方は、DMに話しかけてみてください。

## トラストヒューマン
http://trusthuman.co.jp/
私たちは何よりも信頼､人と考えてます｡

｢コンサルティング｣と｢クリエイティブ｣の両角度から｢人材戦略パートナー｣としてトータル的にサポートします！！

キャリア教育事業
広域学習支援プラットフォーム『のびのび日和』
https://slc-lab.amebaownd.com/

#スポンサー募集
MultiProducer-MultiConsumer (MPMC) channel using crossbeam-channel

Rustにはcrossbeamという低レベルの並列処理を実装するためのライブラリ群があります

Crossbeam: support for concurrent programming
https://github.com/crossbeam-rs/crossbeam

[tokio][]や[rayon][]のような高次のライブラリもこれらを使用しています。今回は特に[crossbeam-channel][]を使用してみたいと思います。

std::sync::mpsc
---------------
[crossbeam-channel][]は標準ライブラリにある[std::sync::mpsc][mpsc]を意識して作られたAPIです。Multi-Producer Single-Consumer (MPSC)の名前通り、`mpsc`は複数の送信者と一人の受信者の間のチャンネルを構築するためのライブラリです。

```rust
use std::thread;
use std::sync::mpsc::channel;

// Create a simple streaming channel
let (tx, rx) = channel();
thread::spawn(move|| {
    tx.send(10).unwrap();
});
assert_eq!(rx.recv().unwrap(), 10);
```

(stdのドキュメントより) `channel()`関数によって`Sender<T>`と`Receiver<T>`の組を作り、これらを使って送信・受信を行います。送られたデータ `tx.send(10)` は無制限でキューに積まれ、受信者が順番に取り出します `rx.recv()`。送受信される型`T`はチャンネル毎に固定で、この例では型推論から`usize`になっています。

crossbeam-channel
-----------------
これだけでも使いどころによっては十分便利なのですが、受信者が一人しか居ないという状況は大きな制約です。また、`Sender<T>`, `Receiver<T>`が`Sync`を持たないのでスレッド間で安全に受け渡すことができません。これを改善し、Multi-Producer Multi-Consumer (MPMC)としたのが[crossbeam-channel][]です。

単純なサンプルを書いてみました：

```rust
extern crate crossbeam_channel;

use crossbeam_channel::unbounded;

use std::thread;
use std::time::Duration;

fn main() {
    // 1. create unbounded channel
    let (tx, rx) = unbounded();

    // 2. start worker (consumer) threads
    let th_cs: Vec<_> = (0..3)
        .map(|n| {
            let rx = rx.clone();
            thread::spawn(move || loop {
                match rx.recv() {
                    Ok(i) => println!("Get {} on thread {}", i, n),
                    Err(_) => break,
                };
                thread::sleep(Duration::from_secs(1));
            })
        })
        .collect();

    // 3. push tasks
    for i in 0..10 {
        tx.send(i).unwrap();
    }
    drop(tx); // close sender
    
    // 4. wait workers
    for t in th_cs {
        t.join().unwrap();
    }
}
```



1. `crossbeam-channel::unbounded()` によりMPMCチャンネルを作成
    - 上限個数を指定する場合は`bounded()`で作成
    - 送受信するデータは同じく`usize`
2. ワーカースレッドを起動
    - ワーカーは `rx`のコピーを保持して、そこからデータを読み出す
    - チャンネルが閉じられてたら `rx.recv()` がエラー(`RecvError`)を投げるので、それをもってスレッドを終了する
3. メインスレッドでタスクをチャンネルに投入
    - `drop(tx)`で明示的にチャンネルを閉じてる
4. ワーカースレッドの終了を待機

最後に
------
channelによる並行処理の記述はメモリを共有して行う処理よりも分かりやすくて良いですね(/・ω・)/

[tokio]: https://tokio.rs/
[rayon]: https://github.com/rayon-rs/rayon
[crossbeam-channel]: https://github.com/crossbeam-rs/crossbeam-channel
[mpsc]: https://doc.rust-lang.org/std/sync/mpsc/
dockerコンテナ　日本語文字化け対応

ニュース記事の分類の学習をしていて、ちょこっとvimで内容を確認したいときがある。
dockerコンテナを立ててデフォルトの状態だと言語の設定はまったくないので、
普通に開くと文字化けして読めない。
（必須ではないが）

そこで入れる日本語の設定

```
export LANG=C.UTF-8
export LANGUAGE=en_US:
```

反映の確認

```
# env |grep LANG
LANG=C.UTF-8
LANGUAGE=en_US:
```

これでだいたいオッケーだと思う。
teratermの設定で文字化けする可能性もあるので、まずここを参照する
http://www.j-oosk.com/teraterm/mojibake/563/
UTCとJSTの対応表

## JST 0時基準

JST | UTC
---|-----
0  | 15
1  | 16
2  | 17
3  | 18
4  | 19
5  | 20
6  | 21
7  | 22
8  | 23
9  | 0
10 | 1
11 | 2
12 | 3
13 | 4
14 | 5
15 | 6
16 | 7
17 | 8
18 | 9
19 | 10
20 | 11
21 | 12
22 | 13
23 | 14

## UTC 0時基準

JST | UTC
---|-----
9  | 0
10 | 1
11 | 2
12 | 3
13 | 4
14 | 5
15 | 6
16 | 7
17 | 8
18 | 9
19 | 10
20 | 11
21 | 12
22 | 13
23 | 14
0  | 15
1  | 16
2  | 17
3  | 18
4  | 19
5  | 20
6  | 21
7  | 22
8  | 23
Android - Proguardで難読化して、リバースエンジニアリングして確認してみるまで

# Proguardで難読化する

### Proguardを有効にする

`app/build.gradle`に`minifyEnabled true`を追加する

```app/build.gradle
buildTypes {
    release {
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}
```

### とりえあずやってみる

`Build > Generate Signed APK ...` を実行して、難読化を実行してみる

### エラーが出たら

```
Warning: okio.DeflaterSink: can't find referenced class org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
Warning: okio.Okio: can't find referenced class org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
Warning: okio.Okio: can't find referenced class org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
```

`-dontwarn xx.yy.**` してwarningを消す

基本的には以上で完了。

### リバースエンジニアリングしてみる

### apk取り出し

#### Android 7.0以前

```shell
$ adb shell pm path <pkg_name>
# => package:/data/app/com.xxx.yyy-1/base.apk
$ adb pull /data/app/com.xxx.yyy-1/base.apk
```

#### Android 7.0以降

```shell
$ adb shell pm path <pkg_name>
# => package:/data/app/com.xxx.yyy-1/base.apk
$ adb shell cp/data/app/com.xxx.yyy-1/base.apk /storage/emulated/0/Download
$ adb pull /storage/emulated/0/Download/base.apk
```

または、 APK抽出アプリを入れて取り出したapkファイルを使う。
例えば ... [ApkExtractor](https://play.google.com/store/apps/details?id=com.ext.ui&hl=ja)

### dexファイル取り出し

`unzip xxx.apk`

たくさんファイルできるので注意。どこかフォルダに入れてからunzipコマンドを実行するのがいいかも。

### dex → jar

[dex2jar](https://github.com/pxb1988/dex2jar)を任意のフォルダにダウンロードし、実行権限がない場合は与える。 (GithubからDownloadして解凍したフォルダ内のファイル)

`chmod +x *`


次に、`jar`ファイルへの変換を行う

```
sh d2j-dex2jar.sh -f target.dex
```

dex2jarと同じフォルダに `classes-dex2jar.jar` ができていれば成功。

## デコンパイルツールを入れて確認。

[JD-GUI](http://jd.benow.ca/)をダウンロードする。先程のjarファイルをDrag&Drop。


## 参考

[ProGuardによるクラッシュ・不具合を正しく回避する](https://qiita.com/yuya_presto/items/ca528258d382ac82d9f3)
pytorchで書いたモデルを保存するときの落とし穴

Deep Learningのフレームワークとして最近伸びてきている[pytorch](http://pytorch.org/)を触ってみたら、モデルの保存で思いがけない落とし穴があったのでメモ。

## 概要

```python
torch.save(the_model, PATH)
```
この方法で保存したモデルはGPUの情報を含んでいて、ロードのときに自動的に保存時のGPUに乗る。

## 公式ドキュメント

pytorchのモデルの保存について公式でまとめてあるサイト。
http://pytorch.org/docs/master/notes/serialization.html

モデルの保存方法には以下の２つの方法がある。

### 方法1

```python:保存時
torch.save(the_model.state_dict(), PATH)
```

```python:ロード時
the_model = TheModelClass(*args, **kwargs)
the_model.load_state_dict(torch.load(PATH))
```

### 方法2

```python:保存時
torch.save(the_model, PATH)
```

```python:ロード時
the_model = torch.load(PATH)
```

問題なのは2つめの方法

## 実際にやってみる

まず適当にモデルを組む。

```python:model.py
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.autograd import Variable

class DummyModel(nn.Module):
    def __init__(self):
        super(DummyModel, self).__init__()

        self.l1 = nn.Linear(100, 10)
        self.l2 = nn.Linear(10, 10)

    def forward(self, x):
        h1 = F.tanh(self.l1(x))
        return self.l2(h1)
```

モデルを作って、GPUに送って学習はせずに保存する。

```python:create_model.py
import torch
import model

def main():
    # モデルの作成
    m = model.DummyModel()

    # GPUに転送
    m = m.cuda()

    # 保存
    torch.save(m, 'model')


if __name__ == '__main__':
    main()
```

ロードしてみる。

```python:load_model.py
import torch
import model

def main():
    m = torch.load('model')

    for param in m.parameters():
        # 型を調べるとCPUかGPUかわかる。
        # CPU: torch.FloatTensor
        # GPU: torch.cuda.FloatTensor
        print(type(param.data))

if __name__ == '__main__':
    main()
```

結果:

```bash
% python load_model.py 
<class 'torch.cuda.FloatTensor'>
<class 'torch.cuda.FloatTensor'>
<class 'torch.cuda.FloatTensor'>
<class 'torch.cuda.FloatTensor'>
```

がっつりGPUに乗ってる。（CPUなら`'torch.FloatTensor'`なはず）

## 何が問題なのか。

1. 学習時に使っていたGPUが他の人に使われているとロードすらできなくなる。
2. 学習の途中でGPUを変えるのが非常にめんどくさい。

## 結論

公式ドキュメントでもおすすめされている１つ目の方法を使って、モデルは保存しましょう。

```python:保存時
torch.save(the_model.state_dict(), PATH)
```

```python:ロード時
the_model = TheModelClass(*args, **kwargs)
the_model.load_state_dict(torch.load(PATH))
```
Cordova for Mac

# 概要

環境構築から動作確認までの流れをまとめます。
また、構築中につまずいたところも合わせてまとめました。

# 前提

- 下記がインストール済みであること
    - node
    - Android Studio
    - Gradle
    - Java JDK

# 環境構築手順

## `Cordova`をインストールする

`npm`でインストールを行う

```bash:cmd
cd /your/develop/path/
npm install cordova
```

`package.json`の`script`に`cordova`を追加する

```json:package.json
"scripts": {
  "cordova": "cordova"
}
```

## `Cordova`プロジェクトの作成

```bash:create
npm run cordova create dir_name jp.co.domain project_name
```

- 引数についてまとめておきます

|      |説明            |
|:----:|:-------------:|
|第1引数|ディレクトリ名   |
|第2引数|ドメイン（逆引き）|
|第3引数|プロジェクト名   |


## ビルドしたいplatformを追加する

### Android

```bash:Android
npm run cordova platform add android
```

### iOS

```bash:iOS
npm run cordova platform add iso
```

### その他

```bash:other
npm run cordova platform add amazon-fireos
npm run cordova platform add blackberry10
npm run cordova platform add firefoxos

etc.
```

## platformが追加されたことを確認する

```
npm run cordova platforms ls
```

installedに含まれていればOK

```
Installed platforms:
  android 7.0.0
Available platforms:
  browser ~5.0.1
  ios ~4.5.4
  osx ~4.0.1
  windows ~5.0.0
  www ^3.12.0
```

## ビルドしてみよう

### ビルドの前に

インストールされていないものがあるか確認しておく！

```bash:cmd
npm run cordova requirements
```

`No android targets (SDKs) installed!`などが、表示されたらインストールされていないので
足りないものをインストールしてください。

```text:こんな感じのエラー
Java JDK: installed 1.8.0
Android SDK: installed true
Android target: not installed
No android targets (SDKs) installed!
Gradle: installed /usr/local/Cellar/gradle/4.6/bin/gradle
(node:89454) UnhandledPromiseRejectionWarning: CordovaError: Some of requirements check failed
  at ~
  at ~
  ...
(node:89454) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:89454) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
```


### platformごとにbuildしてみる

#### Android

```bash:Android
npm run cordova build android
```

## エミュレター上で動かす

### Android

```bash:Android
npm run cordova emulate android
```

# 困った時のまとめ

## platformを削除したい

### Android

```bash:Android
npm run cordova platform rm android
```

### iOS

```bash:iOS
npm run cordova platform rm iOS
```

### Other

```bash:other
npm run cordova platform rm amazon-fireos
npm run cordova platform rm blackberry10
npm run cordova platform rm firefoxos

etc.
```

## Android Emulatorが起動しない

```
No emulator specified, defaulting to Nexus_5_API_21_x86
Waiting for emulator to start...
emulator: ERROR: unknown skin name 'nexus_5' <- ここから動かない
```

このエラーに悩まされました。。。
これは、ADV Managerのemulatorが古いようなので
新しいemulatorをインストールしましょう！！

android studioを起動し、ADV Managerからemulatorを最新にしてください。
【MarkLogic Server】Red Hat Linux7におけるOSパラメータの設定

はじめに
===
今回は、MarkLogicがインストールされているサーバのOSパラメータについて見てきましょう。ここではMarkLogicのver9、OSはRed Hat Linux7を前提にお話しを進めますが、他のバージョンでもほぼ同じようなOSパラメータの調整があるようです。他のバージョンについては[こちら](https://docs.marklogic.com/guide/installation/intro)を参照ください。
なお、こういったパラメータの調整はOracleなど他のDBでもあるようなので、経験のある人にはピンとくるかもです。

背景
===
試しにMarkLogicを扱ってみるとき、MarkLogicのDBの作成や、クエリなどアプリケーション作成などを試みると思います。これはこれで結構なのですが、パフォーマンスを最大限に生かすために、OSのパラメータ調整も欠かせません。
実際、パラメータ調整の前後で性能が20%ほど変わることもありましたので、システムを組む場合は忘れずに行って頂きたいものです。

I/O scheduler
===
複数のディスクI/O要求を並び替えてディスクのシーク量を減らすためのアルゴリズムの選択です。
noopまたはdeadlineが推奨値とされています。デフォルトはcfqとなっていることが多いようです。両者のどちらが良いかは以下の通りです。

| 設定値 | 説明 |
|---|---|
| noop | ディスクがSSDまたは、高度なIOコントローラ(つまりRAID構成)を持っている |
| deadline | 上記以外の場合 |

設定の変更方法については、以前に書いた[記事](https://qiita.com/JucoML/items/16ac9923324d3485f4d7 "記事")を参考にして頂ければと思います。ver8のものですが[こちら](https://help.marklogic.com/knowledgebase/article/View/8/0/notes-on-io-schedulers "こちら")もご参照ください。

Huge Pages
===
頻繁にアクセスされる可能性のあるリソースのためにメモリ領域を確保する設定です。
物理メモリの3/8だけ設定するのが推奨とされています。例えば、物理メモリ64GB、Huge Page Size 2048KB(x86システムでのデフォルト)であれば、以下のような計算を行います。

```
64GB × 3/8 ÷ 2048KB
= 64 × 1024 × 1024 × 3/8 ÷ 2048 
= 12288 
```

つまり、Huge Pagesは12288が推奨値ということになります。

Huge Page Sizeが分からないといった場合ですが、MarkLogic自身もOS上の/var/opt/MarkLogic/LogsにあるErrorLog.txtに以下のようなHuge Pagesの推奨値を提示してくれるので、取り敢えずインストールしてみて判断するという手もあります。

```
2018-03-01 19:00:14.567 Info: Linux Huge Pages: detected 0, recommend 11360 to 15413
```

INFOレベルのメッセージなので見落とさないようにしましょう。

設定変更は、/etc/sysctl.confに以下の一文を加える、もしくは修正します。

```
vm.nr_hugepages = 12288
```

Transparent Huge Pages
===
Transparent Huge Pagesの設定をoffにすることが推奨されています。Red Hat Linuxではデフォルトでonになっているので必ず設定変更してください。onにしているとリソースを無駄に消費するようであり、並列処理など負荷をかけた時に大きな影響を受けるようです。
設定変更は、/etc/grub.confに以下の一文を加えます。

```
transparent_hugepage=never
```
　
　
ここまで、各パラメータの修正が完了したらOSを再起動しましょう。
Transparent Huge Pagesについては、[こちら](https://help.marklogic.com/knowledgebase/article/View/16/0/linux-huge-pages-and-transparent-huge-pages こちら) もご参照ください。

注意点
===
☆バージョンによる違い
MarkLogicでは、バージョンアップで推奨値が変わることがあるかもしれません。新規導入時は[公式サイト](https://docs.marklogic.com/guide/installation/intro 公式サイト)で確認ください。

☆Huge Pagesと物理メモリの増設
Huge Pagesは物理メモリサイズに比例します。このため途中で物理メモリを増設した際にはHuge Pagesがより大きく設定できることになりますので、パラメータの修正を忘れずに行いましょう。

おわりに
===
OSのパラメータ調整はそれほど難しくはないようですね。LinuxでMarkLogicを試すときは挑戦してみてください。
また調整はなるべく早めに行いましょう。未調整のまま動かすとリソースを無駄に消費する原因となったり、試験がやり直しになって基盤チームに負担をかけることになります。


```math
\def\textsmall#1{%
  {\rm\scriptsize #1}
}
```

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

**免責事項**

​​​​​$\textsmall{当ユーザ会は本文書及びその内容に関して、いかなる保証もするものではありません。}$
​​​​​$\textsmall{万一、本文書の内容に誤りがあった場合でも当ユーザ会は一切責任を負いかねます。}$
​​​​​$\textsmall{また、本文書に記載されている事項は予告なしに変更または削除されることがありますので、予めご了承ください。}$
RFC を自分の好きにフォーマットして読む (未完)

RFC は読みづらい。いまどき横幅固定出しタイプライタみたいなフォントだし携帯で読むと字が小さすぎる。どう考えても理想的な表示では無いので原稿を入手して自分でフォーマットしたいと思った。

目標: https://tools.ietf.org/html/rfc6749 を携帯で読みやすく。

仮定: RFC の HTML フォーマットにはリンクも付いている事だし、なにかの原稿を元に作られているに違いない。整形前の原稿が手に入れば携帯で読めるよう好きにフォーマットし直せるのではないか?

この整形前の原稿を手に入れるためには、RFC がどのように書かれるのかを調べれば良い。[Publication Process](https://www.rfc-editor.org/pubprocess/) から辿ってゆくと次の事が分かった。

* 著者は RFC として公開する前にまず Internet-Draft を投稿する。
* 投稿は [Internet-Draft submission](https://datatracker.ietf.org/submit/) のフォームを使う。
* 投稿フォーマットとして最低限 xml か txt を選ぶ。片方だけを投稿するともう片方はツールで生成される。
    * [xml2rfc](https://xml2rfc.tools.ietf.org/): xml -> txt 変換
        * [The "xml2rfc" Version 2 Vocabulary](https://xml2rfc.tools.ietf.org/rfc7749.html): XML フォーマット
        * 例えば [OAuth2.xml](https://github.com/davidrecordon/OAuth-2.0/blob/master/OAuth2.xml)
    * [id2xml](https://pypi.python.org/pypi/id2xml/1.4.0): txt -> xml 変換
    * その他 [Tools for Creating Internet-Drafts](https://www.rfc-editor.org/pubprocess/tools/) に色々なツールがある。
        * [kramdown-rfc2629](https://github.com/cabo/kramdown-rfc2629) 最近よく使われるらしい。

ということで、RFC の xml ソースコードがあればもうちょっとましに整形出来る事が分かった。

実際、ietf のサイトでも読みやすく整形されたドラフト版の XML は見つかった。。https://tools.ietf.org/id/draft-ietf-oauth-v2-31.xml
不思議な事に RFC の xml は見当たらなかった。見つかったら続きを書きます。

参考

* [RFC/Internet-Draftの書き方](https://www.isoc.jp/wiki.cgi?page=PreIETF93#p5) 
    * [発表資料(藤原)](https://www.isoc.jp/wiki.cgi?file=20150701ietf93pre%2Dfujiwara%5F01%2Epdf&page=PreIETF93&action=ATTACH) が分かりやすい。
jupyter notebookのconfigの設定

機械学習の実装で、tensorflow/tensorflowなどのDocker Imageを使って、コンテナを立てまくっているのですが、
jupyter notebookのポートの設定などよく忘れるので備忘ログ

・足りていないモジュールを入れる and vimを入れる
```
apt-get update
apt-get install vim
```

・configファイルを開く
```
vim ~/.jupyter//jupyter_notebook_config.py
```

・configファイルの中身

```
import os
from IPython.lib import passwd

c.NotebookApp.ip = '*'
# PORTの設定。dockerコンテナのポートと合わせる
c.NotebookApp.port = int(os.getenv('PORT', 8888))
c.NotebookApp.open_browser = False
# c.MultiKernelManager.default_kernel_name = 'python2' # 起動するpythonのバージョンを切り替えたいとき。
# --allow-rootの設定
c.NotebookApp.allow_root = True

# sets a password if PASSWORD is set in the environment
if 'PASSWORD' in os.environ:
  c.NotebookApp.password = passwd(os.environ['PASSWORD'])
  del os.environ['PASSWORD']

```