OmniAICreator/Qiita-1.07M huggingface dataset:
geometry + Numpy > numpy_freeBoundary_171112 > v0.4  on GitHub

```txt:Environment
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04 LTS desktop amd64
TensorFlow v1.2.1
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
scipy v0.19.1
geopandas v0.3.0
MATLAB R2017b (Home Edition)
```

[v0.1 in Japanese](https://qiita.com/7of9/items/ff6ca65cdf9973fb6a16)

### GitHub repository
(MIT License)

[code @ GitHub](https://github.com/yasokada/numpy_freeBoundary_171112)
[v0.4 @ GitHub](https://github.com/yasokada/numpy_freeBoundary_171112/releases/tag/v0.4)

### README.md > numpy_freeBoundary_171112 (Nov. 18, 2017)

The code finds triangles not hidden by other triangles (defined herein as '**free triangles**'). 
The code reads triangle indices (indices of vertices) of tetrahedra, then outputs indices of free triangles.

The code uses:

- Python (tested on Python 3.5.2)
- Numpy (tested on Numpy v1.13.1)
- tested on Ubuntu 16.04 LTS desktop amd64

Test run can be executed as follows:

```bash
$ python3 freeBoundary_171112.py > log_171118.txt
``` 

See `log_17118.txt` in the repository.
ウィルスと闘ってみた。その5

#概要
開発用のXPが、どうにも調子が悪い。
ウィルスと闘ってみた。
salityを駆除したけど、プログラムが壊れたので復旧してみた。

#oeditの場合
Program filesのoeditフォルダを削除。
ダウンロードした、zipを解凍して、貼り付けでOK。

#ffftpの場合
ffftp-1.97bをダウンロード、解凍してffftp.exeをProgram files/ffftp-1.97bにコピペでOK。

以上。
raspberry pi 3 でstretch その15

#概要
raspberry pi 3 でstretchやってみた。
pythonでmidi再生やってみた。

#環境
Raspberry Pi 3 model B v1.2 element14
2017-09-07-raspbian-stretch

#インストール
sudo aptitude install python-pyaudio
sudo pip install softsynth

#サンプルコード

```
import sys
import argparse
from synth.synthesizer import Synthesizer
from synth.wave_writer import WaveWriter
from synth.options import Options
from synth import stream
from synth.instruments.OvertoneInstrument import OvertoneInstrument
from synth.note_envelopes import MidiTrackNoteEnvelope

def profile_call():
	opts = Options()
	instr = OvertoneInstrument(opts, ArpeggioNoteEnvelope())
	input = instr
	input.get_samples_in_byte_rate(44100)

def profile(opts):
	if opts.profile_application:
		import cProfile
		import pstats
		cProfile.run('profile_call()', 'restats')
		p = pstats.Stats('restats')
		p.strip_dirs().sort_stats('time').print_stats()
		sys.exit(0)

def get_args():
	parser = argparse.ArgumentParser(prog = 'synth', description = 'Programmable synth')
	parser.add_argument('input', metavar = 'INPUT', nargs=1, help = 'the input file path')
	parser.add_argument('output', metavar = 'OUTPUT', nargs='?', help = 'the optional output file path. Default is INPUT.wav')
	parser.add_argument('--bpm', '-b')
	parser.add_argument('-w', '--wave', action = 'store_true', help = 'Output wave file.')
	parser.add_argument('--profile', action = 'store_true', help = 'Profile the application to find hot spots.')
	parser.add_argument('--stdout', action = 'store_true', help = 'Also write PCM data to stdout. Only valid in conjunction with the --wave flag.')
	args = parser.parse_args()
	opts = Options(args.input[0], args.output, args.bpm)
	opts.write_wave = args.wave
	opts.write_wave_to_stdout = args.stdout
	opts.profile_application = args.profile
	return opts

def main():
	opts = get_args()
	synth = Synthesizer(opts).load_from_midi(opts.input)
	profile(opts)
	wave = None
	if stream.PYAUDIO and not opts.write_wave:
		stream.stream_to_pyaudio(opts, synth)
	else: 
		WaveWriter(opts).output(synth)

if __name__ == '__main__':
	main()

```

#実行
python synth.py -b 120 test1.mid

以上。
Numpy > fileIO > MATLAB saveコマンドによるasciiファイルを読込む > genfromtxt()使用

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04 LTS desktop amd64
TensorFlow v1.2.1
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
scipy v0.19.1
geopandas v0.3.0
MATLAB R2017b (Home Edition)
```

### 関連　

[MATLAB > 変数の内容をファイルに保存する > save('pi.txt', 'X', '-ascii')](https://qiita.com/7of9/items/a3d9f4fd8375ae5de427)

### 概要

MATLABのsaveによるファイルをNumpyで読込む。

### データ　

```tri_bef_171118.txt
   3.0000000e+00   2.0000000e+00   7.0000000e+00   1.0000000e+00
   2.0000000e+00   3.0000000e+00   6.0000000e+00   1.0000000e+00
   4.0000000e+00   3.0000000e+00   6.0000000e+00   2.0000000e+00
   3.0000000e+00   1.0000000e+01   6.0000000e+00   1.0000000e+00
   1.1000000e+01   7.0000000e+00   2.0000000e+00   5.0000000e+00
   7.0000000e+00   2.0000000e+00   5.0000000e+00   1.0000000e+00
   8.0000000e+00   1.2000000e+01   6.0000000e+00   1.0000000e+01
   4.0000000e+00   1.2000000e+01   6.0000000e+00   8.0000000e+00
   4.0000000e+00   8.0000000e+00   6.0000000e+00   3.0000000e+00
   8.0000000e+00   1.0000000e+01   6.0000000e+00   3.0000000e+00
   5.0000000e+00   2.0000000e+00   6.0000000e+00   1.0000000e+00
   3.0000000e+00   1.1000000e+01   9.0000000e+00   1.0000000e+00
   3.0000000e+00   7.0000000e+00   1.1000000e+01   1.0000000e+00
   7.0000000e+00   5.0000000e+00   1.1000000e+01   1.0000000e+00
   1.1000000e+01   5.0000000e+00   9.0000000e+00   1.0000000e+00
   6.0000000e+00   1.2000000e+01   4.0000000e+00   2.0000000e+00
   3.0000000e+00   4.0000000e+00   7.0000000e+00   2.0000000e+00
   8.0000000e+00   4.0000000e+00   7.0000000e+00   3.0000000e+00
   1.1000000e+01   4.0000000e+00   2.0000000e+00   7.0000000e+00
   3.0000000e+00   7.0000000e+00   9.0000000e+00   1.1000000e+01
```

### code v0.1

デリミタは空白３つ必要だった。

```test_read_matlab_output_171118.py
import numpy as np

tri = np.genfromtxt('tri_bef_171118.txt', delimiter='   ')

print(tri)
```

```bash
$ python3 test_read_matlab_output_171118.py 
[[  3.   2.   7.   1.]
 [  2.   3.   6.   1.]
 [  4.   3.   6.   2.]
 [  3.  10.   6.   1.]
 [ 11.   7.   2.   5.]
 [  7.   2.   5.   1.]
 [  8.  12.   6.  10.]
 [  4.  12.   6.   8.]
 [  4.   8.   6.   3.]
 [  8.  10.   6.   3.]
 [  5.   2.   6.   1.]
 [  3.  11.   9.   1.]
 [  3.   7.  11.   1.]
 [  7.   5.  11.   1.]
 [ 11.   5.   9.   1.]
 [  6.  12.   4.   2.]
 [  3.   4.   7.   2.]
 [  8.   4.   7.   3.]
 [ 11.   4.   2.   7.]
 [  3.   7.   9.  11.]]
```

### code v0.2

数値にマイナス符号があると、デリミタ空白３つでエラーになる。
空白２つに変更した。

```test_read_matlab_output_171118.py
import numpy as np

tri = np.genfromtxt('tri_bef_171118.txt', delimiter='  ')

print(tri)
```
redisを使ってみた

https://github.com/dockerfile/redis

## 起動

```rb:コンテナ起動
docker run \
 --name redis \
 -p 6379:6379 \
 redis:alpine \
 redis-server --appendonly yes
```

```sh:接続ツールインストール(ubuntuの場合)
apt install -y redis-tools
# もしくはdockerで接続する場合
docker run -it --rm --link redis:kvs redis:alpine \
 redis-cli -h kvs
```

```rb:redis-cli
$ redis-cli
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> set test abc
OK
127.0.0.1:6379> set room01 1000
OK
127.0.0.1:6379> keys *
1) "room01"
2) "test"
127.0.0.1:6379> get room01
"1000"
```

## 一旦停止して再開してみる

```
docker stop redis

docker start redis
```

```rb:コンテナ起動
$ redis-cli
127.0.0.1:6379> keys *
1) "room01"
2) "test"
127.0.0.1:6379> get room01
"1000"
```

## volume


`-v $(pwd)/data:/data` を追加

```rb:run.sh
docker run \
 --name redis \
 -p 6379:6379 \
 -v $(pwd)/data:/data \
 redis:alpine \
 redis-server --appendonly yes
```

## phpから使ってみる

* [Redis clients](https://redis.io/clients)からスターがついているものを選択するとよい。
    * ちなみに[ziogas/PHP-Redis-implementation: Raw wrapper for real Redis fans.](https://github.com/ziogas/PHP-Redis-implementation)は1ファイルでいいなと思ったが、なんでかredisに接続できなかった。

```
git clone https://github.com/nrk/predis
touch a.php
```

```php:a.php
<?php
require 'predis/autoload.php';
Predis\Autoloader::register();

$client = new Predis\Client();
$client->set('foo', 'bar');
$value = $client->get('foo');

echo $value;
```

bar が表示されることを確認。

## 冗長化(今度)

* 冗長化は[Redis マスターとスレーブサーバー間の自動フェールオーバーを行うための HAProxy と Redis Sentinel の設定方法](https://discuss.pivotal.io/hc/ja/articles/205309388-Redis-%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%BC%E3%81%A8%E3%82%B9%E3%83%AC%E3%83%BC%E3%83%96%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E9%96%93%E3%81%AE%E8%87%AA%E5%8B%95%E3%83%95%E3%82%A7%E3%83%BC%E3%83%AB%E3%82%AA%E3%83%BC%E3%83%90%E3%83%BC%E3%82%92%E8%A1%8C%E3%81%86%E3%81%9F%E3%82%81%E3%81%AE-HAProxy-%E3%81%A8-Redis-Sentinel-%E3%81%AE%E8%A8%AD%E5%AE%9A%E6%96%B9%E6%B3%95)が詳く書いてある。
resource fork, Finder information, or similar detritus not allowedと表示されてビルドエラーになったときの対処法

```
/Users/error_user/Library/Developer/Xcode/DerivedData/neet-abjggixtwqvtyealubfxjyuqqrbb/Build/Products/Debug-iphoneos/test.app: resource fork, Finder information, or similar detritus not allowed
Command /usr/bin/codesign failed with exit code 1
```
上記のようなエラーが出たときの対処法です。
「Command /usr/bin/codesign failed with exit code 1」のほうで検索をかけると、キーチェーンで古い証明書を消せ、的な回答がたくさん出てきますが、それでも対処できないときに試してみてください。
参考: [Technical Q&A QA1940: Code signing fails with error 'resource fork, Finder information, or similar detritus not allowed'](https://developer.apple.com/library/content/qa/qa1940/_index.html)

手順

```
$ cd /Users/a13945/Library/Developer/Xcode/DerivedData/neet-abjggixtwqvtyealubfxjyuqqrbb/Build/Products/Debug-iphoneos/
$ xattr -cr enh_dev.app/
```

これを試したあと、`xattr -lr enh_dev.app/`を叩いて何も表示されなければ、その後ビルドできるようになります。
MATLAB > IDE > ショートカットのキー追加 > コピーのCtrl+c割当 | 貼り付けのCtrl+vは割当できない

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04 LTS desktop amd64
TensorFlow v1.2.1
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
scipy v0.19.1
geopandas v0.3.0
MATLAB R2017b (Home Edition)
```

コピーのショートカットが２つの環境で異なる。

- MATLAB
    - Alt + w
- MATLAB online
    - Ctrl + c

貼り付けのショートカットも異なる。

両者の利用者は２つの環境を使うたびにショートカットを使い間違える。
悪いUIのperfect exampleだ。

ソフト開発の経緯により、MATLABのショートカットを一般的なショートカットに変更すると影響が多いのだろう。
あるいは、MATLAB Onlineを実装する時にMATLABと同じショートカットにしておけば、MATLAB間の混乱はなかったかと思う。
（MATLAB Onlineは一般的なショートカットキーにしたのだろう）。

### 設定

MATLABの方に一般的なショートカットキーを追加する。

1. ホーム > 設定
2. MATLAB > キーボード > ショートカット
3. コピーのショートカットにて"+"を押す
4. Ctrl+c を入力
5. 適用

(従来のAlt+Wも残しておく)

同様に「貼り付け」はCtrl+vを追加しようとしたら、「MATLABエディター、コマンドウィンドウ」の「次ページ」にて使用しているとのことで割当はできない。
(「次ページ」のキー割当を解除するまではしない)

### 備考

保存はCtrl+x, Ctrl+sである。
emacs系のキーに近いのかもしれない。

「一般的な」という用語は本当は一般的かどうかは厳密ではない。ここでは、ユーザ数が多いと思われるショートカットキーを意味する。
MATLAB > 変数の内容をファイルに保存する > save('pi.txt', 'X', '-ascii')

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04 LTS desktop amd64
TensorFlow v1.2.1
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
scipy v0.19.1
geopandas v0.3.0
MATLAB R2017b (Home Edition)
```

処理の流れを把握するため、変数の値をファイル出力したい。

save()というのがあるようだ。
https://jp.mathworks.com/help/matlab/ref/save.html

```matlab
>> X=[3 1 4; 1 5 9];
>> save("pi.txt", X)
エラー: save
string スカラーまたは文字ベクトルでなければなりません。
```

documentを見ると、変数を(')で囲う必要があるようだ。

```matlab
>> X=[3 1 4; 1 5 9];
>> save("pi.txt", 'X')
```

保存がされたが、読めない文字列になっていた。

```matlab
>> X=[3 1 4; 1 5 9];
>> save('pi.txt', 'X', '-ascii')
```

読めるようになった。

```bash
$ cat pi.txt 
   3.0000000e+00   1.0000000e+00   4.0000000e+00
   1.0000000e+00   5.0000000e+00   9.0000000e+00
```
iOSアップロードエラーについて その2

[iOSアップロードエラーについて](https://qiita.com/keeey/items/82d29c8582dc7ae383d0)で、[Monaca 提供のアップロード機能](https://docs.monaca.io/ja/monaca_ide/manual/deploy/appstore/app_submission/)を利用した際のエラーについて掲載しましたが、Monacaでビルドしたipaファイルは、Application Loaderを使用してもiTunes Connectへアップロードすることができます。

MonacaでビルドしたipaフィルをApplication Loaderを使用してiTunes Connectへアップロードした際にも、エラーが発生する場合があります。

その中で多いエラーが下記になります。

```
ERROR ITMS-90161: "Invalid Provisioning Profile. The provisioning profile included in the bundle com.example.xxx [Payload/xxx.app] is invalid. [Missing code-signing certificate]. A Distribution Provisioning profile should be used when submitting apps to the App Store. For more information, visit the iOS Developer Portal."
```

このエラーの原因はいろいろ考えられます。
その際の解決方法として、Xcodeで設定を変更するようなものもありますが、Monacaのプロジェクトは、Xcodeでは利用できません。

MonacaでビルドしたipaファイルをApplication Loaderを使用してiTunes Connectへアップロードした際に、このエラーが出た場合は、初めにビルドタイプを確認してください。

[Monaca 提供のアップロード機能](https://docs.monaca.io/ja/monaca_ide/manual/deploy/appstore/app_submission/)は、リリースビルド以外では利用することはできません。
しかし、Application Loaderでは、`デバッグビルド`で作成されたipaファイルでもアップロード処理を行います。

デバッグビルドで作成されたipaファイルをApplication Loaderでアップロードした際にも、上記のエラーが発生します。


MonacaでビルドをしたipaファイルをApplication Loaderでアップロードした際に、上記のエラーが発生した場合は、初めに `リリースビルド `で作成されたipaファイルかどうか確認してみてください。
will_paginateのurlを変更する

# 発生した問題
will_paginateをrailsアプリに組み込んでいるが、paramsを用いた検索を併用すると・・・2ページ目以降のurlがおかしい？

例えば、/search/myloversというページでparamsを用いたDB検索を行う。そのとき、発行されるurlは、
　/search/mylovers?age_gte=20&age_lte=25&occupation=model
といった感じになる。しかし、このとき、will_paginateを用いて複数ページに結果を分割していたとして、will_paginateが作成する「次へ」ボタンのurlは、
　/search/mylovers?age_gte=20&age_lte=25&occupation=model&page=2
とは**ならない**ときがある。

# 原因
url_forヘルパーがroute.rbの設定に依存すること

will_paginateはurl_forヘルパーを用いてurlを作成し、それをボタンに埋め込む。しかし、もしrails側のroutes.rbにおいて、
　get  search/mylovers/:occupation => search/index
みたいな設定をしていた場合（つまり、params[:occupation]をurl内に組み込んでいた場合）、url_forヘルパーは、
　/search/mylovers?age_gte=20&age_lte=25&occupation=model
のかわりに、
 　/search/mylovers/model?age_gte=20&age_lte=25
を返してくる。つまり、routes.rbでの設定を逆に解釈する。routes.rbでは、「もし、/search/myloversの後ろになんかひっついてきたら、それをparams[:occupation]として解釈してね」という指示を与えたつもりが、url_forヘルパーは気を回して「もし、params[:occupation]が渡ってきたら、search/mylovers/の後ろに引っ付けるようにしよう」としてしまう。

　基本的にはそれでも問題ない場合が多いが、例えば、params[:occupation]が配列形式である場合には、このurl_forヘルパーは壊れる。
　/search/mylovers？occupation=model&occupation=nurse
というurlを発行すると、url_forヘルパーは、
　/search/mylovers/modelnurse
を返してくる。もちろんこれは無効urlとなり、ページネーションが動作しないことになる。

# 解決策
　will_paginate内で作られるurlに問題があるので、gemのオーバーライドをする。オーバーライドとは、既存のメソッドの上書きのようなもの。オーバーライドのやり方は以下のステップ。

- 上書き用のファイルを用意
- 上書きするメソッドの位置を特定
- 上書き内容を書く

　今回は、app/helper内にファイルを用意した。次に、gem内部のどのメソッドを修正したいか（するべきか）を特定する。今回の場合、発行されるurlを変更したいので、urlを作成しているメソッドを探す。見つけたら、書き換えるメソッドのある場所を、module名::class名で指定する。今回はmoduleがネストしていたので、WillPaginate::ActionView::LinkRenderer。書き換えるメソッド名は「url(page)」。ここまでの段階で、上書きファイルの内容は下のようになる。

```ruby:paginatehelper.rb
module PaginationHelper
 class SearchPagination < WillPaginate::ActionView::LinkRenderer
  def url(page)#書き換えるメソッドと同じ名前に
    #処理
  end
 end
end
```

あとは、処理の中で好きに書けば良い。今回はrequest.full_pathを使って現在のurlを取得し、お尻にparams[:page]をつける処理にした。

あとは、viewのwill_paginateのrendererオプションにオーバーライドしたいやつを指定。

```ruby:index.html.erb
<%= will_paginate @mylovers, renderer: PaginationHelper::SearchPagination
```

これで完了。will_paginateはrendererオプションでオーバーライドして色々カスタマイズができる。
自作FirefoxアドオンをWebExtensionsに書き直したのでポエム書く

#Firefox Quantum
Firefoxは量子的な跳躍によって、古典的なアドオンが使えなくなりました。

#自作Firefoxアドオン
タブのウィンドウ間の移動や切り替えを楽にしよう、というコンセプトのアドオンを作っています。
https://addons.mozilla.org/ja/firefox/addon/move-to-window/

欲しかったけど、なかったので。大した機能じゃないので作っちゃえってことで、以前に作りました。
なんと28ユーザもの方に使っていただいています(しかも、そのうち恐らく2人くらいは私)。

#移行作業
大した規模じゃない割には、なんだかんだで時間かかりました。

##自動的に移行できないか? APIの対応表ないか?
探した限り、楽な方法は見つかりませんでした。
APIも結構変わっていて、探し直しに近い状態です。

##初めてから始める
諦めて、これ読みました。

初めての WebExtension
https://developer.mozilla.org/ja/Add-ons/WebExtensions/Your_first_WebExtension
2 つめの WebExtension
https://developer.mozilla.org/ja/Add-ons/WebExtensions/Walkthrough

空っぽのディレクトリを作って、ここに書いてあるのをやりつつ、アイコンとか流用できそうなものは流用して、スクリプトやら何やらは、とりあえずコピペしながら手直しして、でやりました。
それができる規模の小さいアドオンだったのが幸いです。

私が作っていたのは、ボタンを押したらポップアップが出てくる(High Level APIのPanelと呼ばれていたもの)だったので、「初めての」は軽く流して「2つめの」を参考にしました。

一時的なインストールや、デバッグは、アドレスバーに `about:debugging` と打ち込んだら、それっぽいものが出てきます。以前より簡単ですね。

使いたいAPIは
https://developer.mozilla.org/ja/Add-ons/WebExtensions
を見ながら、泣きながら探しましょう。ないかもしれませんが、あると信じて探しましょう。
APIによっては、manifest.jsonの中にpermissionsの項目を追加しないとうまく動かないものもあります。

多くのAPIが、Promiseを返します。非同期処理とかいうやつです。
「javascript promise」でぐぐると、素晴らしい記事からポエムまで、多種多様な資料が出てきますが、とても雑に説明します。

`something` がPromiseだとします。
`something` は、もしかしたら、まだ処理中かもしれませんが、次の処理を書けます。
(既に処理が終わっているかもしれませんし、まだで、そのうち処理されるかもしれません)
慣れてないと気持ち悪いですが、気にせずに進めて大丈夫です。

とはいえ、 `something` が終わってからじゃないとできない処理や、 `something` の結果を使って行う処理だってあると思います。
そういうときは `something.then(f)` のように書きます。
`something` が無事終わったら、その結果が `f(somethingの結果)` のように呼び出されます。

`f` の部分は、ラムダ式でもいいです。

```js
something.then((result) => {
  anything(result);
});
```

##あとはがんばるだけですね。
最後にパッケージ化するプロセスが、zipに詰め込むだけ、という。
xpiだって所詮zipだったけど。もっとあからさまにzipになった。

#感想
移植するのは大変ですね。

ていうか、Firefoxって、Chromeにシェア奪われながらも、古いアドオンで持ちこたえていた部分が大いにあると思うので、今回のやつで民族大移動が起こらないか心配ではあります。
いいのか悪いのかは難しいですが、数年前から放ったらかしのアドオンも多いのも事実で、それらの利用者もそこそこ多いのも確かです。
それらを切り捨ててええんかいな。

あと、移行期間！開発版とかベータ版じゃない正式版でWebExtensionが動くようになってから、どれくらい期間あった？
(作業にそんなにかかるわけじゃあるまいし、締切が3日だろうと1年だろうと、始めるのは2日前、みたいな感じなのかもしれないけどね！)

一応、API自体は使いやすくはなっていると思います。
また、作り始めるのも簡単になっていると思います。
要するに、作るための敷居は下がってます。

作りたいものができたら、もう一個くらい、何か作ってもいいかな、とか思いました。

今後どうなるかは分からないですが、Firefox界隈が盛り上がってくれたらうれしいな。
cgoやってみた

## About
C/C++をやっているとgolangで書けたらいいのにと思うことがよくあります. C/C++で書いた`Hello()`をgolangから[cgo](https://golang.org/cmd/cgo/)で呼び出してみます.

### 試してみた環境
||version|
|:--|:--|
|Ubuntu|17.10|
|gcc|7.2.0|
|golang|1.8.3|

## C言語でHello World
```c:c_hello.h
#ifndef C_HELLO_H_
#define C_HELLO_H_

void Hello(const char*);

#endif
```
```c:c_hello.c
#include <stdio.h>
#include "c_hello.h"

void Hello(const char* name) {
  printf("hello %s\n", name);
};
```
```go:c_hello.go
package main

/*
#cgo LDFLAGS: ./chello.o
#include "chello.h"
*/
import "C"

func main() {
	C.Hello(C.CString("Qiita"))
}
```
コンパイル&実行
```bash
% gcc c_hello.c -c
% go run c_hello.go
% hello Qiita
```

## C++でHello World
```cpp:hello.hpp
#ifndef HELLO_H_
#define HELLO_H_

#ifdef __cplusplus
extern "C" {
#endif

void Hello(const char*);

#ifdef __cplusplus
}
#endif

#endif
```
```cpp:hello.cpp
#include <cstdio>
#include "hello.hpp"

void Hello(const char* name) {
  std::printf("hello %s\n", name);
};
```
```go:hello.go
package main

/*
#cgo LDFLAGS: ./hello.o
#include "hello.hpp"
*/
import "C"

func main() {
	C.Hello(C.CString("Qiita"))
}
```
コンパイル&実行
```bash
% gcc -lstdc++ hello.cpp -c
% go run hello.go
% hello Qiita
```

## 所感
+ `#cgo`で結構エラーで詰まったが, LDFLAGSにオブジェクトファイルを指定するだけでよかった.
+ `import "C"の上のコメントアウトしているCコードとの間に空行があるとエラーになる.
HTML,CSSで乃木坂46のロゴを描く

#HTML,CSSで乃木坂46のロゴを描く
```html
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>乃木坂ロゴ</title>
  <style>
  .nogilogo {
    background: linear-gradient(to bottom right, #fff 50%, #812990 50.3%) no-repeat bottom right/100% 100%;
    width: 200px;
    height: 200px;
    position: relative;
  }
  .nogilogo::after {
    content: "46";
    font: 60px/1em -webkit-pictograph;
    color: #fff;
    right: 4px;
    bottom: 0;
    position: absolute;
  }
  </style>
</head>
<body>
  <div class="nogilogo"></div>
</body>
</html>
```
##結果
![image.png](https://qiita-image-store.s3.amazonaws.com/0/163837/86534989-a7cc-0502-2227-8687e7b672c6.png)
こんな感じになる。
##メモ
コメントで教えて頂いたスタイルに修正した。

```css
background: linear-gradient(to bottom right, #fff 50%, #812990 50.3%) no-repeat bottom right/100% 100%;
```
ボーダーをトリッキーな使い方をしていたため、余計な空白が空いたりしたけど、`linear-gradient`だととてもスマート。

```css
font: 60px/1em -webkit-pictograph;
```
`font`のおかげで簡略化された。 :clap: 
###旧スタイル

```html
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>乃木坂ロゴ</title>
  <style>
  .nogilogo {
    display: inline-block;
    position: relative;
    border-style: solid;
    border-width: 0 0 200px 200px;
    border-color: transparent transparent #812990 transparent;
  }
  .nogilogo::after {
    content: "46";
    width: max-content;
    position: absolute;
    bottom: -210px;
    right: 2px;
    color: white;
    font-size: 64px;
    font-family: -webkit-pictograph;
  }
  </style>
</head>
<body>
  <span class="nogilogo"></span>
</body>
</html>
```
```css
  border-style: solid;
  border-width: 0 0 200px 200px;
  border-color: transparent transparent #812990 transparent;
```
cssで三角形を作るときには定番のボーダー

```css
  display: inline-block;
```
inline-blockでないと謎の空間が上に出てくる。

```css
.nogilogo::after {
  content: "46";
  width: max-content;
  position: absolute;
  bottom: -210px;
  right: 2px;
  color: white;
  font-size: 64px;
  font-family: -webkit-pictograph;
}
```
もっと簡略化できそうな気がする。
《JavaScript》配列かどうか知りたい。


## IE9＋

ES5 ではネイティブメソッドの　`Array.isArray()` を使います。

```js

Array.isArray([]);  // true
Array.isArray({});  // false

```

## IE8-

IE8以下は文字列で判定します。

```js

function isArray( obj ) {
  return Object.prototype.toString.call( obj ) === "[object Array]"
}

isArray([]);  // true
isArray({});  // false

```
Eclipseのインストールとコード補完の補強設定(Java開発用 mac)

#Eclipseのパッケージをダウンロード
Eclipse公式サイトからダウンロードパッケージをダウンロード。64bitです。

#インストールするパッケージを選ぶ
ダウンロードしたインストーラーを展開するとパッケージを選べと言ってきます。
<img width="589" alt="スクリーンショット 2017-11-17 23.24.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/147926/2263c426-4737-ae7e-bbae-6d9752159889.png">

ふぁっ( 'ω')！？←知らなかった

ここで慌てて違いを調べます。
今回インストールしたいのはJava用IDEなので
Eclipse IDE for Java DevelopersかEclipse IDE for Java EE Developers のどちらかです。

公式サイトによると、
<img width="534" alt="スクリーンショット 2017-11-17 23.38.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/147926/f1383efa-c415-147e-c4ac-2b933cd43458.png">
が入ってて、
Eclipse IDE for Java EE Developersは
<img width="531" alt="スクリーンショット 2017-11-17 23.41.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/147926/99d2b009-7251-04b5-73d8-57b3c23a3f06.png">
(https://www.eclipse.org/downloads/packages/　
より引用)
が入ってるようですね。
なんかEEの方はJavaScriptとか入ってるあたりWebアプリ開発者向けなんでしょう。
まあでもWebアプリ開発の予定もあるし、EEの方はEEじゃない方に入ってるのも全部入ってるので。（入ってるはず？）そっちを入れましょう。まあ別にEEでなくても十分JavaのIDEとして使えると思いますし、後で追加もできるらしいのでメモリ節約したい方とかは最低限の方でも良いかもしれませんね。
( ･ㅂ･)و!

というわけで
インストールしたいパッケージを選んでインストールします。
(ちなみにインストールしてる間ネット接続が切れるとエラー出るので注意。色々ダウンロードしてるためで筆者は一回やり直しました。)

#立ち上げて見ましょう
<img width="452" alt="スクリーンショット 2017-11-17 23.49.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/147926/f3d9d904-5a25-dd55-7f81-e4c4b4410b95.png">

インストールは終わったので早速Launchして見ましょう。
最初にWorkSpaceの場所をどこにするか聞いてくるので設定してください。
後でもここから切り替えられます。
<img width="327" alt="スクリーンショット 2017-11-17 23.57.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/147926/b99784fb-b07b-77a5-0213-3ce315b7153d.png">

立ち上げてみるとこんな感じ。Tutorialも付いてて親切ですね！
<img width="1136" alt="スクリーンショット 2017-11-17 23.52.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/147926/43b76a04-ee05-4d90-3559-af5c6ce27ce5.png">
ただEEだからでしょうか...Welcome画面にCreate Java Projectはないのね。

でも安心、File→New→OtherからJava Projectもちゃんと選べます。
こんな深いとこにwww
<img width="1108" alt="スクリーンショット 2017-11-17 23.58.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/147926/9dab4ed8-adb9-8c7f-2c75-cc79cf07ae3d.png">

#コード補完機能の補強
Eclipseは他のIDEに比べるとちょっとコード補完がびみょいと聞きました。
とりあえず補強しておきましょう。

やるのは、
1. コンテンツアシストの自動有効化遅延を短くする。
2. コンテンツアシストの自動有効化トリガーの文字の追加。
...要はコード補完のスピードアップといろんな文字に対してコード補完してくれってことですね。

設定→Java→Editor→Contents Assistに行きます。
<img width="744" alt="スクリーンショット 2017-11-18 0.17.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/147926/25727d2a-8796-114c-80de-8c6def2c1284.png">
字ちっちゃい...(^^;)

Auto activation Delayを80にします。（お好みの数字をどうぞ）
次にAuto activation triggersに文字を追加。デフォルトだと　.　を入力した時しか発動しないっぽいですね...(´・ω・｀)
で、どうするかというと...
.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_
って入力するとまあほぼ大体のものに対して補完しますね！(^^;
この辺他サイトさんを参考にさせていただいのですがなんというマニュアルな設定方法笑

で、どうなったかというと...
<img width="667" alt="スクリーンショット 2017-11-18 0.24.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/147926/4205d3c2-b770-58ac-ef46-aed81c9763b9.png">

おお！圧倒的違い！（｀・ω・´）
どのくらい違うというとスクショ撮り忘れたんですがさっきfやらwやら押した時は何もでなかったんですよ。何も笑
というわけでJetBrainとかと同じくらいになるのかはわかりませんが設定をオススメします。

それでは~
apipie で api リファレンスドキュメントの作成練習をしてみた


apipie をつかって, rails （api モード) の scaffold でつくった API に対して、ドキュメント作成をしてみた。
See https://github.com/katoy/rails5-sql/blob/master/Using-Apipie.md

API ドキュメントには、レスポンスの json 例を記載することは必須であるが、
apipie では、テストコードを走らせたときの json レスポンスをドキュメントに埋め込むことが可能。

次のような記載を追加してからテスト走らせたせれば、こんなリファレンスページができる。

    api :GET, '/memos/:id', 'Show memos'
    param :id, Fixnum, :desc => "User ID", :required => true
    error 404, "Missing"
    error 500, "Server crashed for some <%= reason %>", :meta => {:anything => "you can think of"}
    meta :author => {:name => 'John', :surname => 'Doe'}
    
    def show
     # Nothing here, it's just a stub
    end

![apipie-006.png](https://qiita-image-store.s3.amazonaws.com/0/14958/e737d2ad-e444-3c9a-0311-a67cf58e52e0.png)
![apipie-007.png](https://qiita-image-store.s3.amazonaws.com/0/14958/72a31196-3beb-38e9-f1b5-9b696e1b92b9.png)
DB2DBA: 診断ログファイル


# 診断ログファイルとは
トラブルシューティングのために必要なイベントやエラーに関する情報が記録されるファイルです。IBMサポートが主に利用するものと位置づけられていますが、管理通知ログファイルよりも詳細な情報が記録されており、検索のためのコマンドインターフェースも提供されているため、DBAにとっても有用なログです。

ここでは診断ログファイルの参照方法や設定について解説します。

# 診断ログファイルの参照
以下のコマンドで診断ログファイルの内容を参照できます。

```
$ db2diag
```

db2diagコマンドのオプションにより検索条件を指定することもできます。以下によく使うオプションとその使用例を挙げておきます。各オプションは組み合わせて使用することが出来ます（AND検索）。

|オプション|機能|例|
|:--|:--|:--|
|-l|重大度の指定（複数指定可）|db2diag -l Info,Warning,Error,Severe,Critical,Event|
|-e|エラーコードの指定（複数指定可）|db2diag -e 911,913|
|-t|開始時刻・終了時刻の指定（一方のみでも可）|db2diag -t 2017-11-10:2017-11-10-20.30.00.000000|
|||db2diag -t 2017-11-10:|
|||db2diag -t :2017-11-10-20.30.00.000000|
|-H|指定範囲での最新のログの出力|db2diag -H 1M|
|||db2diag -H 2d|
|||db2diag -H 6h|
|||db2diag -H 15m|
|-g|各種項目でのフィルタリング|db2diag -g AUTHID=SVC34|
|||db2diag -g DB=SAMPLE,MESSAGE:=ADM1823E|

-gオプションでのフィルタリングには様々なパターンが用意されているので、マニュアルを確認してみてください。

- [db2diag - db2diag ログ分析ツール・コマンド](https://www.ibm.com/support/knowledgecenter/ja/SSEPGG_11.1.0/com.ibm.db2.luw.admin.cmd.doc/doc/r0011728.html)

出力されるログの各項目の解説はについては、こちらを参考に。

- [診断ログ・ファイル項目の解釈](https://www.ibm.com/support/knowledgecenter/ja/SSEPGG_11.1.0/com.ibm.db2.luw.admin.trb.doc/doc/c0020815.html)

# 診断ログファイルのアーカイブ
診断ログファイルは放っておくとサイズが増え続けていくため、定期的なアーカイブが必要です。

```
$ db2diag -A パス名
```

アーカイブされたログファイルの内容は、以下のようにdb2diagコマンドの入力に指定することで検索出来ます。

```
$ db2diag アーカイブファイル名 各種オプション
```



# 診断ログファイルの出力先
診断ログの出力先は、DBマネージャ構成パラメータDIAGPATHにより設定されます。したがって、インスタンスレベルでの設定となります。また、DIAGPATHに出力できなかった場合の代わりの出力先をALT_DIAGPATHに設定することもできます。

## 出力先の確認
```
$ db2 "get dbm cfg" | grep DIAGPATH
```

デフォルトでは```$INSTHOME/sqllib/db2dump```が指定されています。

## 出力先の変更

```
$ db2 "update dbm cfg using DIAGPATH パス名"
```

# 通知レベル
診断ログの通知レベルは、DBマネージャ構成パラメータDIAGLEVELにより設定されます。DIAGLEVELには0から4までの値を設定可能で、数字が大きいほど詳細な情報が記録されるようになります。

## 通知レベルの確認
```
$ db2 "get dbm cfg" | grep DIAGLEVEL
```

デフォルトは3となっています。


## 通知レベルの変更
```
$ db2 "update dbm cfg using DIAGLEVEL 3"
```


# 参考資料
- IBM Knowledge Center
    - DB2 for Linux UNIX and Windows 11.1.0 
        - [db2diag - db2diag ログ分析ツール・コマンド](https://www.ibm.com/support/knowledgecenter/ja/SSEPGG_11.1.0/com.ibm.db2.luw.admin.cmd.doc/doc/r0011728.html)
        - [診断ログ・ファイル項目の解釈](https://www.ibm.com/support/knowledgecenter/ja/SSEPGG_11.1.0/com.ibm.db2.luw.admin.trb.doc/doc/c0020815.html)
        - [diagpath - 診断データ・ディレクトリー・パス構成パラメーター](https://www.ibm.com/support/knowledgecenter/ja/SSEPGG_11.1.0/com.ibm.db2.luw.admin.config.doc/doc/r0000299.html)
        - [alt_diagpath - 代替診断データ・ディレクトリー・パス構成パラメーター](https://www.ibm.com/support/knowledgecenter/ja/SSEPGG_11.1.0/com.ibm.db2.luw.admin.config.doc/doc/r0058822.html)
[diaglevel - 診断エラー・キャプチャー・レベル構成パラメーター](https://www.ibm.com/support/knowledgecenter/ja/SSEPGG_11.1.0/com.ibm.db2.luw.admin.config.doc/doc/r0000298.html)
阿部寛のサイトを高速化する

ちまたで[阿部寛のサイト](http://abehiroshi.la.coocan.jp/)が早いと話題になってます。

[dev.toと阿部寛のホームページどっちが速いですか？](http://kuxumarin.hatenablog.com/entry/2017/11/15/dev.to%E3%81%A8%E9%98%BF%E9%83%A8%E5%AF%9B%E3%81%AE%E3%83%9B%E3%83%BC%E3%83%A0%E3%83%9A%E3%83%BC%E3%82%B8%E3%81%A9%E3%81%A3%E3%81%A1%E3%81%8C%E9%80%9F%E3%81%84%E3%81%A7%E3%81%99%E3%81%8B%EF%BC%9F)
[dev.toと阿部寛のホームページについてちゃんと計測させてくれ](https://qiita.com/naru0504/items/7d652681d698f6d88c4f)

阿部寛のサイトはベストを尽くしてるのか？
それを調べるために、阿部寛のサイトを高速化させてみたいと思います。

## 目指すべきスピード
最速はローカルのファイルへのアクセスだと思うのでこれを目指したいと思います。
file:///C:/abe_hiroshi/index.html

![9baae75ad17a694cadc9a83081cd4df4.gif](https://qiita-image-store.s3.amazonaws.com/0/152303/cecd158c-f83f-00f2-c72e-97017f31e529.gif)

ChromeのDeveloper Toolでレンダリング完了が「173ms」でした。
まぁここまでは無理だな…

## 阿部寛のサイトはどんなもん？
速度は[webpagetest.org](http://webpagetest.org)で測ってみます。

![nama.png](https://qiita-image-store.s3.amazonaws.com/0/152303/f455b02c-6653-f7b0-125e-452b8503b974.png)
レンダリング完了時間は「359ms」です。はえーな

## S3でホスティングしてみる
サーバーを立てるほどでもないので、S3でWebホスティングしてそこにhtmlと画像を置いてみます。

![s3_1.png](https://qiita-image-store.s3.amazonaws.com/0/152303/4542d94b-cab8-4f20-4f65-951a6e0bd5b9.png)
![s3_2.png](https://qiita-image-store.s3.amazonaws.com/0/152303/d533e8ed-7c16-5f5b-26b4-065e102f79b4.png)

レンダリング完了時間が「698ms」なんで、まだまだ遅いです。

## CDN(CloudFront)でキャッシュする
続いてS3のオブジェクトをCloudFrontでキャッシュしてみる。

![cf_1.png](https://qiita-image-store.s3.amazonaws.com/0/152303/5977425f-1a97-33a4-704f-b30dcabf08da.png)
![cf_2.png](https://qiita-image-store.s3.amazonaws.com/0/152303/d7b52463-517d-6cb1-1a3f-184cff979bad.png)

レンダリング完了時間が「379ms」になりました。
やはりCDNは効果絶大です。

## Webpを使ってみる
[dev.to](https://dev.to)では[Cloudinary](https://cloudinary.com/)という画像ホスティングサイトを使用しており
画像をアップロードすると様々なフォーマットで利用できるようになります。

dev.toでも使用している「Webp」というJPG/PNGよりも圧縮に優れたフォーマットで
大幅なサイズ削減を実現してくれます。
サイズ削減できれば高速化できるはず。早速試してみます。

画像の変換作業は、Cloudinaryでこんな感じの画面で行えます。
![webp.png](https://qiita-image-store.s3.amazonaws.com/0/152303/dd483669-ae9b-fc97-fde9-b962a3c3bf6b.png)


普通の画像サイズ
http://abehiroshi.s3-website-ap-northeast-1.amazonaws.com/image/abe-top2-4.jpg
64KB

cloudinaryでwebpに変更してみると
https://res.cloudinary.com/morix1500/image/upload/v1510926252/abe-top2-4_n99mu2.webp
18.9KB

cloudinaryのURLをhtmlに埋め込んで計測してみます。
![webp_1.png](https://qiita-image-store.s3.amazonaws.com/0/152303/73d2bf9b-23b1-4818-1f23-05a9492e225e.png)
![webp_2.png](https://qiita-image-store.s3.amazonaws.com/0/152303/50ec90bf-fa31-841e-ad33-af5cfc8195fe.png)

はい、全部Aになりました。
しかし、レンダリング完了時間が「1.337s」と遅くなった…なぜでしょう？

このページではHTTP2が有効になってます。
同一ドメインでないと余計なコネクションが発生してしまうのではないかと推測し、
同一ドメインに画像を置いてみることにします。（間違えてたらご指摘おねがいします）

ということでCloudinaryから直接画像を読み込むのではなく、WebpをダウンロードしてS3に配置してみます。
![webp_3.png](https://qiita-image-store.s3.amazonaws.com/0/152303/5c18809f-1e50-6c5a-ca10-4a5cd890cb34.png)

お、「328ms」になりました。
また読み込みバイト数も「70KB」から「18KB」になりました。
これはいい感じですね。

これで阿部寛サイトを超えることができました！

## 結論
以下の技術を使用すれば既存の阿部寛サイトを凌駕することが出来ました。

* S3でホスティング
* CDN（CloudFront)でキャッシュ
* HTTP2
* Webp

ここまでしないと超えられない既存サイト…恐ろしい。
Service Workerも使ってみたかったですが、それは今度の機会に。

では！
Haskell(stack)のEmacs環境 on NixOS

# Haskell 環境
Emacsでhaskell-modeを準備する際にinteroが非常に便利だったのだけど
NixOSでは躓くこともしばしばあったためメモ

- NixOS
  - Stack (--nix)
     - hlint
     - ghc-mod
     - hoogle
  - Emacs
     - intero

## Stack (--nix)

nixpkgsでインストールする

```bash
$ nix-env -i stack
```

stackのsetupを行う

```bash
$ stack --nix setup
```

interoやその他のツール(ghc-mod,hlint,hoogle)で
依存してるライブラリを **~/.stack/config.yaml** に追記する
(NixOSでない場合はそれっぽいパッケージを各自インストール)

```yaml
略
....

nix:
  enable: true
  packages:
    - gcc      #
    - ncurses  # interoで必要
    - libcxx   #
    - icu      #
    - zlib     # hoogleで必要
```

stackから使うツールをインストールする

```bash
$ stack --nix install hlint ghc-mod hoogle
```

## Emacs

[Intero for Emacs](http://commercialhaskell.github.io/intero/) の通り **intero** をインストール
個人的に **package.el** をそのまま使っているためインストール後 **init.el**に

```el
(require 'haskell-mode)
(require 'intero)
(add-hook 'haskell-mode-hook 'intero-mode)
```

# 実行

stackで適当なプロジェクトを作成する

```bash
$ stack --nix new myhs
```

emacsで **myhs/src/Lib.hs** を開くと **intero** のビルドが自動的に走り 環境構築終了

| Key | Function | Description |
|:-- |:-- |:--|
| C-c C-c | intero-repl-eval-region| 範囲選択している箇所の実行 |
| C-c C-e | intero-expand-splice-at-point| |
| C-c TAB | intero-info | 定義情報を別バッファに表示 |
| C-c C-l | intero-repl-load | REPLに編集中の.hsファイルを読み込む |
| C-c C-r | intero-apply-suggestions | import等で不足しているものがあったりする場合読み込んでくれる |
| C-c C-t | intero-type-at | 関数や変数の型をminiバッファに表示 |
| C-c C-z | intero-repl | REPLのバッファに移動する |
| M-.| intero-goto-definition | 定義箇所にジャンプする |
CloudFrontの署名付きURLをRubyで発行する

## 概要
画像コンテンツを扱うアプリのバックエンドをRails/EC2/S3/CloudFrontで作った。
コンテンツ保護のためCloudFrontの署名付きURLを使ったが、何やらAWSのSDKとやらが必要だったのでそのメモ。

## 前提
S3/CloudFrontの設定と署名用のキーペアの作成が終わっていること。
下記を参考にさせてもらったらバッチリできた。

> CloudFront+S3で署名付きURLでプライベートコンテンツを配信する
> https://dev.classmethod.jp/cloud/aws/cf-s3-deliveries-use-signurl/

しかし、肝心の署名付きURLの発行しようとしたらRubyのサンプルがなくて詰んだ。
泣きながら初心者なりに試行錯誤して見ると一応動いた。

## やったこと
AWS SDK をGemで追加して

```ruby:Gemfile
gem 'aws-sdk-cloudfront'
```
キーペアのIDとダウンロードした秘密鍵を指定し、署名付きURLを発行する。

```ruby:url_signer.rb
signer = Aws::CloudFront::UrlSigner.new(
  key_pair_id:      "APKA9ONS7QCOWEXAMPLE", # 鍵ID
  private_key_path: "tmp/pk-cloudfront.pem" # 鍵ファイル
)
# 5分間有効な署名付きURLを発行
signed_url = signer.signed_url(
  "https://d111111abcdef8.cloudfront.net/images/image.jpg",
  expires: Time.now.getutc + 5.minute
)

# 発行された署名付きURL
# signed_url = https://d111111abcdef8.cloudfront.net/images/image.jpg?Expires=123456789&Signature=nitfHRCrtziwO2HwPfWw~yYDhUF5EwRunQA-j19DzZrvDh6hQ73lDx~-ar3UocvvRQVw6EkC~GdpGQyyOSKQim-TxAnW7d8F5Kkai9HVx0FIu-5jcQb0UEmatEXAMPLE3ReXySpLSMj0yCd3ZAB4UcBCAqEijkytL6f3fVYNGQI6&Key-Pair-Id=APKA9ONS7QCOWEXAMPLE
```
これだけだ。

発行したURLでアクセスするとちゃんとコンテンツにアクセスできたし、有効期間（5分）が過ぎた後はちゃんとアクセスが拒否された。
ちなみにexpiresではなくpolicyも指定できるので、もっと複雑な条件も指定できるらしい。

# 参考
- [Amazon CloudFront 開発者ガイド - 署名付き URL の使用](http://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/private-content-signed-urls.html)
- [AWS SDK for Ruby - Class: Aws::CloudFront::UrlSigner](http://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/CloudFront/UrlSigner.html)
Spring Bootでweb.xmlのcontext-param経由でspring.profiles.activeを指定

とりあえず適当な```pom.xml```をつくる。

```xml:pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>kagamihoge</groupId>
	<artifactId>asdasdf</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>

	<name>asdasdf</name>
	<description>Add project description here</description>

	<properties>
		<maven.war.filteringDeploymentDescriptors>true</maven.war.filteringDeploymentDescriptors>
	</properties>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.8.RELEASE</version>
	</parent>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
		</dependency>
	</dependencies>

	<profiles>
		<profile>
			<id>hoge</id>
			<properties>
				<spring_profile_value>hoge_profile</spring_profile_value>
			</properties>
		</profile>
	</profiles>
</project>
```

上記のうち```<maven.war.filteringDeploymentDescriptors>...</maven.war.filteringDeploymentDescriptors>```とすることで```maven-war-plugin```で```web.xml```のプレースホルダを置換するようになる。

```xml:src/main/webapp/WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                             http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
	version="3.1">

	<context-param>
		<param-name>spring.profiles.active</param-name>
		<param-value>@spring_profile_value@</param-value>
	</context-param>

</web-app>
```

mavenのprofileで指定されるspring.profiles.activeをweb.xmlのcontext-paramに指定する。spring-bootではmavenのプレースホルダの参照は```${...}```ではなく```@...@```になっている。

あとは```mvn package -P hoge```とかすれば生成されるwarの中のweb.xmlはこんな感じになる。

```xml:web.xml
<context-param>
	<param-name>spring.profiles.active</param-name>
	<param-value>hoge_profile</param-value>
</context-param>
```

ただし、参考にした[How to set spring active profiles with maven profiles](https://stackoverflow.com/questions/25420745/how-to-set-spring-active-profiles-with-maven-profiles)でも書かれてるけど、この方法でアクティブプロファイルを切り替えるのはあまり美しいとは言えない。というのも、各環境ごとに異なる内容のwarが出来てしまうためで、最終的なバイナリが一つの方が何かとトラブルが少ない。

ただまぁそうはいっても現実世界は色んなケースがあるので、一概にweb.xml経由の指定が悪いとは言い切れないだろうけど。

### 参考URL
* https://stackoverflow.com/questions/25420745/how-to-set-spring-active-profiles-with-maven-profiles
* https://stackoverflow.com/questions/15355708/how-to-replace-a-value-in-web-xml-with-a-maven-property
* https://memorynotfound.com/servlet-3-web-xml-example-configuration/
Google Cloud Platformでハロワする


#GCPでハロワ
##登録
なんかGitHubとかTwitterとかで登録。
クレカ情報とか求められるので適当に入力。

###個人かビジネスか？と聞かれる
注釈に「変更できません」とか書かれているので少しビビる。
まあどうでもいいかなと思ってとりあえず個人にした。 

よく考えると現時点では登録すべき法人もないし。


##ホーム画面
![スクリーンショット 2017-11-15 10.21.19.jpg](https://qiita-image-store.s3.amazonaws.com/0/214031/34124271-6c09-6722-203a-ba3c7f13ecdc.jpeg "スクリーンショット 2017-11-15 10.21.19.jpg")


詰んだ。

ので調べる。

> [Google Cloud Platform での PHP の使用  |  PHP  |  Google Cloud Platform](https://cloud.google.com/php/?hl=ja)


まさに、なチュートリアルが存在していた。

> [PHP で Hello World を実行する方法  |  PHP  |  Google Cloud Platform](https://cloud.google.com/php/getting-started/hello-world?hl=ja)


##チュートリアル

###事前準備
やることは以下。

- Google Cloud Platform Consoleでプロジェクトを作成。
これはすでにしている。
 - App Engineの設定
ハンバーガーメニューからコンピューティング > App Engine > ダッシュボードを選択。

1. 初めてのアプリへようこそ > 言語を選択
2. リージョンを選択 > asiaのやつを選択
3. App Engineのチュートリアルを選択
4. プロジェクトを指定 > 作成したプロジェクトを選択
5. Google Cloud Shellを使用する > 画面下部に開発者ツールみたいな感じでコンソールが出てくる
6. サンプルが表示されるのでそれを順に入力 > 変数にプロジェクト名を入れて、その場所にgitからサンプルプロジェクトのクローンを取得して配置、そのブランチに移動。そんな感じ。
7. phpとyamlをcat　ただの確認なので次に進む。
8. アプリをテストする > コンソールから起動、プレビューでポート8080に接続して確認する
9. Hello, World!が見れた
10. Shell上で Ctrl+C で、アプリケーションを落とす
11. アプリケーションをデプロイする
12. 確認。[http://macro-storm-186100.appspot.com/](http://macro-storm-186100.appspot.com/)
13. アプリのステータスを確認。App Engine > ダッシュボードから。

- プロジェクトの課金を有効にする。
これは最初にクレカを登録しているので大丈夫っぽい。

- Google Cloud SDKをインストール。
これはさっきの手順にもあったやつなので、DLしてやってみる。

1. 適当な場所に解凍する。
2. インストールスクリプトを実行する。省略はできる。
3. なんかばばっと出る。途中でヘルプがどうこうとか言われる。なんとなくYes。
4. gcloud initでSDKの初期化。途中でGoogleアカウントのログインを求められる（ブラウザが突然開く。怖い）。
5. [Google Cloud SDK の認証が完了しました  |  Cloud SDK のドキュメント  |  Google Cloud Platform](https://cloud.google.com/sdk/auth_success)　とかに飛ばされる。

###GAEフレキシブル環境でのPHPアプリの実行
アプリケーションをアップロードして実行できるよ。
連携はapp.yamlファイルでやるからそれさえ正しければ動かせるよ。

みたいなことを説明される。
だからなに。

###アプリをダウンロードして実行する
1. サンプルアプリを適当なフォルダにclone
2. 1-hello-worldに移動
3. ローカルでアプリを実行

これでlocalhost:8000にアクセスするとHello World、localhost:8000/goodbyeにアクセスするとGoodbye Worldと表示されるようになった。

とりあえずできたはできただろうか。

このテンプレートはSilexとかいうフレームワークで動いているらしい。

> [Silex - Wikipedia](https://ja.wikipedia.org/wiki/Silex)

当初の予定ではLaravelでやりたいなーと思っていたのだけど、別にLaravelの経験があるわけでもない。
どうしようかなほんと。

とりあえず引き続きいじくってみる。
Spring Bootでcontext-paramを設定

web.xmlで下みたいに設定するやつ。

```web.xml
<context-param>
  <param-name>p-name</param-name>
  <param-value>-value</param-value>
</context-param>
```

プロパティファイルに以下のように記述する。

```application.yaml
server:
  context_parameters:
    p-name: hogehoge
    p-name2: foobar
```

以下は動作確認用のコード。

```java
@RestController
@SpringBootApplication
public class App {

	@Autowired
	ServletContext ctx;
	
	@RequestMapping("/home")
	public String hoge() {
		System.out.println(ctx.getInitParameter("p-name"));
		System.out.println(ctx.getInitParameter("p-name2"));
		
		return "hoge";
	}
	
	public static void main(String[] args) {
		SpringApplication.run(App.class, args);
	}

}
```

ただし[How to set context-param in spring-boot](https://stackoverflow.com/questions/26639475/how-to-set-context-param-in-spring-boot)によるとspring-boot 1.2以降の機能とのこと。

ちなみに、ここに```spring.profiles.active```を入れても何も起きなかった。少なくとも起動ログでは``` No active profile set ...```となる。

```application.yaml
server:
  context_parameters:
    spring.profiles.active: profile_ctx
```
書籍「Designing Concurrent, Distributed, and Real-Time Applications with UML」 のオブジェクト構成基準

Designing Concurrent, Distributed, and Real-Time Applications with UML (Addison-Wesley Object Technology Series)

のオブジェクト構成基準です。オブジェクトデザインステレオロールタイプとは違います。組み込み向けですが、他の分野でも参考になるでしょう。

#### インタフェースオブジェクト
ここでいうインタフェースはステレオロールタイプのインタフェースとは違い、外部環境との接続をさしています。

* デバイスインタフェースオブジェクト
* ユーザーインタフェースオブジェクト
* システムユーザーインタフェースオブジェクト

外部環境（サーバー）とのインタフェースになります。

#### エンティティオブジェクト

#### コントロールオブジェクト
* コーディネータオブジェクト
* ステートマシンオブジェクト
責務駆動設計のステレオロールタイプでいう制御役っぽいです。
* タイマーオブジェクト

#### アプリケーション ロジックオブジェクト
責務駆動設計のステレオロールタイプでいうサービス役ですね。
* ビジネスロジックオブジェクト
* アルゴリズムオブジェクト
機械学習の理論を理解しようとしてから オセロ AI を作ってみた 〜再始動‼〜


#シリーズ目次
- [機械学習の理論を理解せずに tensorflow で オセロ AI を作ってみた ～導入編～](http://qiita.com/sasaco/items/3b0b8565d6aa2a640caf)
- [機械学習の理論を理解せずに tensorflow で オセロ AI を作ってみた ～実装編～](http://qiita.com/sasaco/items/fdb9771c146cb877b183)
- [機械学習の理論を理解せずに tensorflow で オセロ AI を作ってみた ～いざ対戦編～]
(http://qiita.com/sasaco/items/f9aa608860eebb3026c1)
- 機械学習の理論を理解しようとしてから オセロ AI を作ってみた 〜再始動‼〜
- [機械学習の理論を理解しようとしてから オセロ AI を作ってみた 〜何これ Alpha Zero 編〜](https://qiita.com/sasaco/items/d249ee3493b5b85c6eb5)
- [機械学習の理論を理解しようと エクセルでニュートラルネットワークを作ってみた 〜画像認識 mnist 編〜](https://qiita.com/sasaco/items/a70ea2940380f7f8e1a1)


#[前回](http://qiita.com/sasaco/items/f9aa608860eebb3026c1)の反省...
この分野では門外漢の私が、「機械学習の理論」をまったく勉強せずに
オセロのAI を作ってみましたが、結果惨敗でした。強くならない

しかたがないので、機械学習の勉強しようと思います。


#勉強する教材
オセロAIに関して私が理解できる本は唯一これだけでした
<a href = "http://shop.ohmsha.co.jp/shopdetail/000000004775/">
<img src="https://qiita-image-store.s3.amazonaws.com/0/142847/8454f7c0-443d-16bd-dad7-5e6d3b1a38bb.jpeg" width=40%> </a>
この本の **第６章 強化学習ー三目並べに強いコンピューターを育てる**
を元にオセロAIを作成します。

この他に参考になる書籍をご存知の方ご教示ください


#まずは教科書通り...と言いたいところですが

この本の **第６章 強化学習ー三目並べに強いコンピューターを育てる**
では下記の点を改良したものを 再始動の初期状態とします。

## 1. **RL-Glue** という仕組みは、削除する

この本の 例では **RL-Glue** という仕組みを使って学習しているのですが
私には難しく使いこなせなそうなので、削除してみました

はじめにソースコードをダウンロードします。
[`$ git clone -b "#1" https://github.com/sasaco/train-chainerai.git`](https://github.com/sasaco/train-chainerai/tree/%231)

環境が整ったら、ソースコードのディレクトリに移動して、experiment.pyを叩くと学習が始まります。

```text:
$ cd train-chainerai
$ python experiment.py
```
<img src="https://qiita-image-store.s3.amazonaws.com/0/142847/f813c231-f848-51b2-8b7f-17fbfb4a5d76.png" width=70%>

どうやら **改造 RL-Glue なしバージョン** も正常に学習できるようです。


## 2. ゲームが 三目ならべなので**オセロ**に変更する

とりあえず今回は、中間層の数とか細かいところは この本のままで、下記の修正をしました
- 入力層と出力層を 3×3 → 8×8 に変更しました。
- オセロは空白でも置けないマスがある
- 置けない場合パスする動作を追加
- 対戦相手は、完全なランダム

### まずは動かしてみよう

はじめにソースコードをダウンロードします。
ソースはここにおいておきます。
[`$ git clone -b "#2" https://github.com/sasaco/train-chainerai.git`](https://github.com/sasaco/train-chainerai/tree/%232)


### 学習

環境が整ったら、ソースコードのディレクトリに移動して、experiment.pyを叩くと学習が始まります。

```text:
$ cd train-chainerai
$ python experiment.py
```

![実施中.png](https://qiita-image-store.s3.amazonaws.com/0/142847/edb42b9f-c6ec-ac0a-6047-c49be919e7ff.png)



### 結果

ランダム相手に 5000 エピソード学習させても効果見えず
少し勝率が上がっているかな？っといったところ
![othe.png](https://qiita-image-store.s3.amazonaws.com/0/142847/40c880a4-c35a-2062-76c8-8dc948bca88c.png)

 50000 エピソード に変更して再トライアルした結果
![Screenshot from 2017-11-24 18-51-04.png](https://qiita-image-store.s3.amazonaws.com/0/142847/e1b8b06f-54ee-6058-5b24-24f1ea09cea9.png)

150000 エピソードを超えたあたりで Loss nan になってしまった!!

![image.png](https://qiita-image-store.s3.amazonaws.com/0/142847/efef55ea-196a-5981-af2c-8f068674d22d.png)

勝率も上がらず...失敗です。

[次回](https://qiita.com/sasaco/items/a70ea2940380f7f8e1a1)、機械学習の理論を理解しようとします
iOSクラス探訪　〜Item編

辞書で調べると事項、項目、品目です。まあ、これだと抽象的ですが、一覧にしたり、リスティングしたり、ひとまとめに使うものの中の一品目という感じのクラスになるクラス名です。

### MKMapItem
パス

### MPMediaItem
楽曲の事です。

### NSMenuItem
メニューの一項目です。

### UIBarItem
ツールバー、ナビゲーションバーのボタンになります。
Ubuntu 16.04 ServerでWi-Fiに接続したいのにwpa_supplicantが動かないとき

# 環境

* PC: Panasonic Let's Note CF-NX2
* OS: Ubuntu 16.04 Server

`wpa_supplicant`でWi-Fiに接続するよう設定したかったのだが、接続できなかった。`iwlist`でもなぜかscanできず。

Ubuntu DesktopをLive USBで起動すると問題なく接続できるので、ハードウェアの問題ではなさそう。
ということで、Ubuntu ServerでもおとなしくNetwork Managerを使って設定する。

~~~bash
apt-get install network-manager
~~~

## 公開SSID + DHCP

~~~bash
nmcli device wifi connect [SSID] password [PASSWORD]
~~~

## ステルスSSID + DHCP

~~~bash
nmcli connection add type wifi con-name [CONNECTNAME] ifname [IFNAME] \
  ssid [SSID] wifi-sec.key-mgmt wpa-psk wifi-sec.psk [PASSWORD]
~~~

`[CONNECTNAME]`は任意の名前、`[IFNAME]`は`wlp2s0`や`wlan0`などを指定する。

参考) [CentOS7でステルスSSIDへ接続する方法
](https://qiita.com/n7aka/items/64e8fdd11e3f7ceaa49c)

## ステルスSSID + 固定IP

~~~bash
nmcli connection add type wifi con-name [CONNECTNAME] ifname [IFNAME] \
  ssid [SSID] wifi-sec.key-mgmt wpa-psk wifi-sec.psk [PASSWORD]
nmcli connection modify [CONNECTNAME] ipv4.method manual \
  ipv4.address [IPADDR] ipv4.gateway [GATEWAY] ipv4.dns [DNS]
~~~

`[IPADDR]`に割り当てたいIPアドレス、`[GATEWAY]`にはゲートウェイ(通常はルータ)のIPアドレス、
`[DNS]`にはDNSサーバのIPアドレスを指定する。

参考) [CentOS 7.1.1503ではnmcliでIPアドレスを固定する方法が変更された](https://qiita.com/yunano/items/88a6e46b412d3be1d3ec)

# 余談

テスト中のUbuntu Desktop 17.10でステルスSSIDのWi-Fiに接続しようと思ったが、GUIでの設定方法がわからない。設定画面どこに行ったの？

そんなときも上記コマンドで接続できる。
Unix系の隠しファイルの仕組みは開発者のポカから生まれた悪習だった

### hidden file
今となってはLinuxでのvimやtmuxのコンフィグファイルなど、基本的にユーザーに見せる必要のないファイルを
隠しファイルとしてホームディレクトリに置くという作法がよくつかわれます。

.tmuxや.vimrc、.sshなど枚挙にいとまがありませんが
その起源はプログラマが作り出したバグとコピペとこじつけの３連コンボクリティカルによるものでした。

### 成り立ち
lsコマンドといえば定番のファイル一覧表示コマンドですが
オプション無しではUnixの実装上存在するカレントディレクトリ、親ディレクトリを指す、.と..を表示しません。
特殊で常在するディレクトリなので当然ですがその実装はちょっとだけ、短かったのです。
実際はアセンブラですが

```c
//実際にできたもの
if (name[0] == '.') continue;
//本当に必要だったもの
if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) continue;
//営業が提案したもの
// ʕ◔ϖ◔ʔ 
```
このバグ自体は簡単なものでしたが、２つの結果を引き起こしました。

まず初めに、lsという先例ができたことによって他のいくつかのプログラマが真似をしました。
そのため初めに.が含まれるファイルがスキップされることがよくあります。

第二に、隠しファイル、ドットファイルというアイデアが生まれてしまったことです。
結果としてさらに怠惰なプログラマは隠しファイルをホームディレクトリにぶちこみまくりました。
おかげでホームディレクトリを通過するファイルの評価をするたびこのゴミカスウンチをご自慢のチンポで確認しないといけなくなりました。

### 代替の方法
とはいってもhidden fileはよく使われています。
設定ファイルのような、不慣れなユーザには余分なファイルの隠蔽は非常に役立つからです。
ですがそもそもホームディレクトリに設定ファイルをそのまま置くことが問題なので
本来であればlib/やcfg/などを作ってそこに放り込む慣習にするべきでした。

### というわけで
というわけでPlan9では隠しファイルのアイデアは実装されていません。
詳しくはUnix開発者の人のこちらのブログを見てください。
https://plus.google.com/+RobPikeTheHuman/posts/R58WgWwN9jp

しかしこの記事を見るまでまるで疑問にも思いませんでした。
設計を重視しているUnixですから多少古くがたついたところがあるとはいえまさかこんな・・・いやそんな・・・常識を覆されました。
いわれてみればもっともな話ですが、なかなか気づかないものですね。
vim ~/.vimrcよりも
vim ~/cfg/vimrc の方が見た目にも設定ファイルであることが明示的でいいと思います。

ちなみにls -aコマンドではちゃんとカレントディレクトリなどが表示されます。
iOSクラス探訪　〜Request系クラス編

　iOSは今では巨大なプラットホームでいろんなジャンルの色々なクラスがある。そこでクラス名の観点からそのクラスがどんな特徴、役割を持つのか調べてみた。

まずは、〜Request系クラス編。文字通り要求を表すクラス。とはいってもクラスの性格や役割は各々ので全く異なる。

##### NSURLRequest
言わずと知れた有名なクラス。文字通りURLをロードするための各種通信パラメータを持っている。通信パラメータを保持しているだけでこのクラス自身は送信処理をしない。

iOSとクラス設計に長けた人が考察すれば分かる通り、iOSでは様々な方法でHTTP通信できるためこいつに通信処理を持たすと責務超過でクラス自身が肥大化するから情報保持の責務に特化しているだと思う。後でパラメータを変更できるNSMutableURLRequestというのがある。

##### SLRequest
ソーシャルサービスへの送信パラメータを保持する。

TwitterやFacebook等、iOSで直接管理しているサービスのみ扱える。外に対しては抽象的なインタフェースを提供し、内部で各サービスに特化したパラメータに変換している。キャンセル不可能なコールバックベースの非同期通信インタフェースを持っており送信が可能。

NSURLRequestへの変換メソッドも用意しており、好きな方法で送信処理やパラメータの追加を行える。

##### SKRequest
 IAPサービスの各種送信処理を行う。

こいつもNSURLRequstと違って送信処理も行え、キャンセルも行える。応答メッセージはSKReqeustDelegateプロトコルとその派生プロトコルで拾えるようになっている。

 SKRequest自体は抽象クラスでサブクラスに商品情報の詳細を引っ張ってくるSKProductsRequestと、レシートの更新を行うSKReceiptRefreshRequestがある。それぞれのコンストラクターで送信パラメータを設定する。

##### NSFetchRequest
 言わずとしれたCore Dataのクラスで、NSManagedObjectのフェッチを行うためのパラメータを保持している。

主にNSManagedObjectContextのexecuteFetchRequestメソッドの引数に指定して使う。

他にもNSFetchedResultControllerやNSFetchedPropertyDescriptionクラスのプロパティとして、Core Dataの各問い合わせ関連の処理を裏から支えている。

上記以外については調べしだい随時追加いこうと思います。
iOS クラス探訪、〜Object、〜Entityクラス編

##### はじめに

モデル系フレームワークのエンティティ系オブジェクトの基底クラスを表す。NSManagedObjectが有名。

内部で使っているであろう永続化機構(SQLite or Core Data?)に関連したメソッドを提供している事が多い。各属性の列挙アクセス、変更した属性値を破棄する。変更状態を保持するとか。このクラスを基点に各々のクラスへ派生する。

##### NSManagedObject
言わずと知れたCore Dataのオブジェクトを表す。挿入された/削除された/フォルト等のCore Data独特のオブジェクトライフサイクルの把握、属性や関連オブジェクトへのアクセス手段、自身の編集状態の把握等のタスクを請け負っている。

カスタムのサブクラスを作れる様に状態変化をフックするためのトリガーメソッドを提供している。

##### EKObject
Event Kitのエンティティ系クラスの基底クラス。
　
NSManagedObjectと同じような位置づけだが、Event Kitでの使用に特化しているためか、編集状態の把握ぐらいしが外部に公開していない。

イベント関係のモデル構築に特化している関係上、当然の事ながらカスタムのサブクラスは作成できない。

##### MPMediaEntity
　楽曲、アルバム、プレイリストを構成するクラスの基底クラス、プロパティへの列挙アクセス。フィルター可能なプロパティか否かの判定手段のみ提供している。

　個人的には、MPMediaEntityからMPMediaItemとMPMediaItemCollectionを派生される必要があったのかは謎？抽象的に使い回したいというニーズはないと思う。

Home Kit、Health Kit、iCloud Kit関係とかにも類似のオブジェクトがあるがまあ後で。。。
[vim] 置換コマンド `:%s` の `g`　オプションが効かない？


## 環境
* PC　： MacBook Air OS X EI Capitan バージョン 10.11.6 
* Vim ： MacVim Custom Version 8.0.1272 (KaoriYa 20171105)

## データ

```DATA
aaa bbb aaa ccc 
aaa bbb aaa ccc 
``` 

## やりたいこと
全ての `aaa` を `111` に置換したい。

## やったこと

```
:%s/aaa/111/g 
```

## 結果

```
111 bbb aaa ccc 
111 bbb aaa ccc 
```

各行の最初の `aaa` しか置換されてなかった。
今までは `g` オプションをつければ、全部を置換してくれていたのに。

## 原因

いろいろと調べたところ、`gdefault`　というコマンドで `g` オプションの動きを設定できるそうです。

>  `:help gdefault` 

| コマンド | 'gdefault' がオン |'gdefault' がオフ |
|--------|--------|--------|
| `:s///`       |  全て置換      | 最初だけ置換 |
| `:s///g`      |	 最初だけ置換 |	  全て置換 |
| `:s///gg`	  |  全て置換 |		  最初だけ置換 |

 
既定ではオフのはずなので、
`:e ~/.vimrc` vim設定ファイルを確認したら、
`set gdefault`　という設定が混ざっていました。
削除することでデフォルト設定に戻りました。


## 参考になったリンク

http://vim.wikia.com/wiki/Search_and_replace