OmniAICreator/Qiita-1.07M huggingface dataset:
devise_token_auth+omniauthで独自パラメータを付加したかった

facebook/twitter/googleなどでログイン/ログアウトが出来るようになったものの、ログイン時にグループID的なやつを付けないと色々と問題が発生することがわかったので試した内容のメモ。
グループIDについてはDBに登録されていることが前提としている。
つまり登録されていないIDはエラー扱い。モデル名はGroupInformationとする。

## 1. クライアント側

こういう風にすればOKという情報しかなかった。

```
http://localhost:3000/auth/:provider?group_id=1
```

devise_token_authというよりはdeviseでのやり方だったので、正直怪しかったけど結局クライアント側としてはこれで問題はなかった。

## 2. サーバ側

以下のようにして対応する。(変更箇所のみ抜粋)

```ruby:app/controllers/users/omniauth_callbacks_controller.rb
module Users
  class OmniauthCallbacksController < DeviseTokenAuth::OmniauthCallbacksController
    include Devise::Controllers::Rememberable
    before_action :group_id_valid?, only: [:omniauth_success]
    
    def redirect_callbacks
      session[:group_id] = request.env['omniauth.params']['group_id']
      super
    end

    def omniauth_success
      logger.debug(session[:group_id])
      # なんか処理
      session.delete(:group_id)
      super
    end
    # 省略

    private
    def group_id_valid?
      GroupInformation.find_by_id(session[:group_id]).nil?
    end
  end
end
```


最初はredirect_callbacksでparams['group_id']を使えば良いじゃんと思って試したけど、facebookやgoogleは無理だった。


## 3. 付加したグループIDのチェック

ミドルウェアで/auth/:providerにリクエストがきたときに、グループIDが付いていない場合は弾いたほうが良いんじゃないかなーとはおもっているんだけど、正直どのタイミングが良いのかわからん。

変にredirect_callbacksでグループIDを確認して弾く(認証処理を中断する)と
facebookでは「アカウントの安全確認」が発動してアカウントが一時的に凍結されてしまうことがある。
実際params['group_id']でグループIDが取れるのか試したときに、例外で認証処理が中断された結果、facebook側に不審なアクティビティ（だっけ？）と思われてしまい、アカウントが数日凍結された。~~おのれfacebook~~

なのでミドルウェアで弾いてしまうか、provider側の認証処理が終わってから確認するかどっちかになるんじゃないのかと。
どっちがいいんだろ？

上記の例では認証成功後に確認するようにしたけど、もしミドルウェアでチェックするならこんな感じ？


```ruby:lib/omniauth/custom_middleware.rb
require 'rack'
module Omniauth
  class CustomMiddleware
    def initialize(app)
      @app = app
    end

    def call(env)
      status, headers, body = @app.call(env)
      request = ActionDispatch::Request.new(env)
      if request.fullpath.include?('/auth') && !request.fullpath.include?('/callback')
        if request.params.has_key?('group_id')
          if group_id_valid?(request.params['group_id'])
            status, headers, body = error_response(status, headers, no_registered_error)
          end
        else
          status, headers, body = error_response(status, headers, no_query_error)
        end
      end
      response = Rack::Response.new body, status, headers
      response.finish
    end

    private
    def error_response(status, headers, body)
      content_length = body.inject(0) do |sum, content|
        sum + content.bytesize
      end
      headers["Content-Length"] = content_length.to_s
      headers.delete_if {|key, val| key == "Location" }
      status = 400
      [status, headers, body]
    end

    def no_query_error
      ["<html><body>Group ID is not found. </body></html>"]
    end

    def no_registered_error
      ["<html><body>Group ID is not registered. </body></html>"]
    end

    def group_id_valid?(group_id)
      GroupInformation.find_by_id(group_id).nil?
    end
  end
end
```

group_idがついていなかったり、存在しないgroup_idが付加されているなら、400エラーを返すようにレスポンスを書き換える。そうでなければ何もしない(そのまま処理を続行)。

ActionDispatch::Requestや@app.call(env)を使わずにenvから自分で取り出してやったほうがいいのかなー。
整数計画法での定式化

[<--目次へ](https://qiita.com/ki073/items/508b3c20eb03078703dd)

基本的な定式化を紹介します。

(2021.12.24 追記)
## 論理演算

バイナリ変数の場合には次の定式化が可能です。

| |制約条件  | バイナリ変数yに値を設定 |または|
|:----------:|:------------|:-----------|:-----------|
|**not**| 1-x        | x+y == 1    |
|**and**<br>(2変数)| x1+x2 == 2| x1+x2-1 <= y <br> x1+x2 >= 2*y| x1+x2-1 <= y <br> x1 >= y <br> x2 >= y|
|**and**<br>(3変数)| x1+x2+x3 == 3|x1+x2+x3-2 <= y <br> x1+x2+x3 >= 3*y|x1+x2+x3-2 <= y <br> x1 >= y <br> x2 >= y <br> x3 >= y|
|**and**<br>(配列)|sum{i in 1..n}x[i]==n|sum{i in 1..n}x[i]-n+1 <= y <br> sum{i in 1..n}x[i] >=n*y |sum{i in 1..n}x[i]-n+1 <= y <br> {i in 1..n}: x[i] >=y |
|**or**<br>(2変数)| x1+x2 >= 1 |x1+x2 >= y <br> x1+x2 <= 2*y|x1+x2 >= y <br> x1 <= y <br> x2 <= y|
|**or**<br>(3変数)| x1+x2+x3 >= 1 |x1+x2+x3 >= y<br>x1+x2+x3 <= 3*y|x1+x2+x3 >= y <br> x1 <= y <br> x2 <= y <br> x3 <= y|
|**or**<br>(配列)| sum{i in 1..n}x[i]>=1| sum{i in 1..n}x[i] >= y <br> sum{i in 1..n}x[i] <= n*y|sum{i in 1..n}x[i] >= y <br> {i in 1..n}: x[i] <= y|


目的関数でyの最小化や最大化をする時には、andやorの2式は一方だけを使うことで可能です。

例えばor(3変数)のときは
s.t. x1+x2+x3 <= 3*y;
minimize y;
片方の制約式で目的を達成できます。

## N以上・N未満の数
zがN以上の時にyが1になります

```GLPK:gte.mod
var z integer, >=0;
var y binary;
s.t. geN1: z-(N-1)<=M*y;
s.t. geN2: z>=N*y;
```

Mはz-(N-1)が取りうる最大の数あるいはそれ以上の任意の整数を与えます。
yを(1-y)に入れ替えると、否定の意味になりますので、N未満を検出できるようになります。

1以上の数の使用例が「生産現場で役に立つかもしれない最適化手法1【GLPK】」のpallet04.modにありますので参考に。

## 最大値・最小値

最大値をyに(最大値の最小化)

```GLPK:maximize.mod
var y;
s.t. max_x: max{i in 1..n}: x[i]<=y;
minimize max_y: y;
```

最小値をyに(最小値の最大化)

```GLPK:minimize.mod
var y;
s.t. max_x: max{i in 1..n}: x[i]>=y;
maximize min_y: y;
```

## 絶対値

xが-LからUの間(L,Uは正)にある場合には絶対値(y)が求められます。

```GLPK:abs1.mod
var x, >=-L, <=U;
var y, >=0;
var z binary;
s.t. abs1: x<=y;
s.t. abs2: x>=-y;
s.t. abs3: y<=-x+2*U*z;
s.t. abs4: y<=x+2*L*(1-z);
```

目的関数で絶対値の最小化をする場合には次のような簡単なプログラムでできます。

```GLPK:abs2.mod
var x;
var y ,>=0;
s.t. abs1: x<=y;
s.t. abs2: x>=-y;
minimize abs: y;
```

## 商と余り

xをNで割った時の値y

```GLPK:div1.mod
var x integer, >=0;
var y integer, >=0;
s.t. div1: y >= x*N;
s.t. div2: y <= x*N+N-1;
```

余りzはx-y*Nでも求められますが、次のようにすると商と余りを同時に求めることができます。

```GLPK:div2.mod
var x integer, >=0;
var y integer, >=0;
var z integer, >=0, <=N-1;
s.t. div1: y == x*N+z;
```



### Nで割り切れるか
(2021.12.24 追記)

```GLPK:div3.mod
var quotient integer, >=0; # 商　上限も設定する方が良い
var divisible binary; # Nで割り切れると1、余りがあると0になるバイナリ変数

s.t. div_1: x >= quotient*N;
s.t. div_2: x <= quotient*N+(N-1)*(1-divisible);
```

上式では、xがNで割り切れるときには、divisibleが1か0に、割り切れないときには0になります。
maximizeなどを使って目的関数にdivisibleを入れると割り切れるか判断することが可能です。
「生産現場で役に立つかもしれない最適化手法1【GLPK】」の pallet04_ext に使用例があります。

## 参考資料
[整数計画法による定式化入門](http://web.tuat.ac.jp/~miya/fujie_ORSJ.pdf)
Google App Maker ー Transformerを使いこなす

App Maker には [Binding Transformers](https://developers.google.com/appmaker/scripting/api/transformers)というバインディングのオプションのような仕組みがある。

これを使うことで表示の仕方を変えたりも出来るようになるし、スクリプトを書く行数を減らすことにも貢献してくるのでしっかり使いこなしていきたい。

本記事では、筆者がよく使うものを厳選して Transformer の解説をする。



## #formatDate
通常は Date 型をバインドすると `yyyy-mm-dd` の形式で表示されるが、これを変えることが出来る Transformer。

次の画像はバインドした時の式、と実際に表示される文字列。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/35595/85778be5-efe3-05cc-28e6-81df366d6357.png)

時分秒も表示できるし、`\x`で囲っておけば任意の文字列を埋め込むことも出来る。



## #formatNumber
通常は Number 型をバインドすると `#.0000000000000` の形式で表示されるが、これを変えることが出来る Transformer。

次の画像は`1234.5678901234567890`をバインドした時の式、と実際に表示される文字列。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/35595/c518f761-9d2f-4cc0-1671-2f7280c450de.png)

一番下の桁のひとつ下の桁で四捨五入される模様。



## #join
通常は Array 型をバインドすると `要素1,要素2,要素3` の形式で表示されるが、これを変えることが出来る Transformer。

次の画像は`['JavaScript', 'Angular', 'TypeScript']`をバインドした時の式、と実際に表示される文字列。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/35595/2811d8e8-e5da-2778-c1b1-e311ea66c4c7.png)



## あわせ技
Transformer はつなげることが出来る。

次の画像はDateの形式を変えて、スペース区切りでArrayにして、スラッシュでつなげたときの式、と実際に表示される文字列。
※この式に意味はないです（良い例が思いつかなかった）
![image.png](https://qiita-image-store.s3.amazonaws.com/0/35595/e9ab4c46-d117-c44c-9fdc-1342da1ec914.png)


# 特殊な Transformer
特殊な使い方をする Transformer を紹介しておく。

## projection
projection は配列の中から指定したFiledsにマッチする配列を返す事ができる機能のこと。
`items..{Fields名}`のように使用する。[^1]
[^1]: ドットが２つになるのがポイント

projection で取得した配列の Transformer　には `#` ではなく `##` を指定する。

次の画像は レコード内のを Names を `-` でつなげて、複数レコードを `/` でつなげた例。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/35595/f1140162-6a4c-7651-e5b3-43c5eb19d5a7.png)


## #readonly
データソースのバインドを双方向から単方向（サーバー→クライアント）にするための Transformer。

たとえば、次のような場合に使う。

1. データソースが [Manual save mode](https://developers.google.com/appmaker/models/datasources#manual_save_mode) でなく Auto save mode
2. データソースから引っ張ってきたデータをテキストボックスにバインド
3. テキストボックスに入力した内容を変更する
4. 変更した内容を元にメール送信

この場合、3で入力した時点でサーバーに保存されているデータが更新されてしまう。
それを避けたいとき、テキストボックスにバインドするときに `#readonly` を指定する。

# おまけ
Transformer とはちょっと話がずれるが、関連があるのでついでに記載しておく。

## バインディングには式がかける
式がかけるので `+`を使って数字の加算や文字列の結合なんかも可能。

## Client の Function も呼べる
Client スクリプトに定義してある Function をそのまま呼ぶことが出来る。

そのため次のようなバインディングが可能。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/35595/cd0c5342-a82b-b8bd-4ab5-8fc14b013de4.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/35595/59a0ebf3-add5-e402-0b07-76b42145e9fd.png)



## 参考サイト
[Binding Transformers Reference  |  App Maker  |  Google Developers](https://developers.google.com/appmaker/scripting/api/transformers)
特定の値を区切って出力する

業務中に思いついたツールを作成したので、
記事に残しておきます。値は例として物理メモリの使用量を
取得していますが、なんでも入れることができます。

```memory.sh
#!/bin/bash
#物理メモリの使用量を出力するツール

#各種変数の設定
OUTPUT_DIR="/home/ToolAdmin/memory"
FILENAME="Memory.log"

#日付レコード関数の設定
writinglog() {
echo "[`date +%Y/%m/%d\ %H:%M:%S`]" $1
}

#メモリデータの出力
writinglog `free | grep Mem | awk '{print $3}'` >> $OUTPUT_DIR/$FILENAME
```
出力結果は以下の通りです。

```MemoryResult.log
[2017/12/26 21:50:37] 467832
```
writinglog関数の部分は、
処理ログっぽくしたくてこうしましたが、
のちのちデータ可視化のために表形式にすることも考慮するならば、
[]は不要だと思うので、以下の構文もいいのかなと思いました。

```writinglog関数別案.sh
#日付レコード関数の設定
writinglog() {
echo `date +%Y/%m/%d\ %H:%M:%S` $1
}
```
上記の通りであれば、EXCELなどの表計算ソフトに、
日付・時刻・取得したい値の3列に成形することも簡単になります。
また＄1の横に$2...と比較したい値をつけ足していくこともできるので、
わりかし色々と応用して使えれそうです。

あとはcronに5分毎に出力設定にするとよいと思います。

```5分毎.log
[2017/12/26 21:50:37] 467832
[2017/12/26 21:55:01] 466260
[2017/12/26 22:00:01] 470524
[2017/12/26 22:05:01] 467840
```

おやすみなさい。
allclose and array_equal in numpy

```python
for n in range(1,10):
 print n
 A = np.random.rand(5)/(10**n)
 B = np.random.rand(5)/(10**n)
 print(A)
 print(B)
 equal = np.allclose(A,B)
 print("n:"+str(equal))

equal = np.array_equal(A,B)
print(equal)
A = np.round(A)
B = np.round(B)
print(A)
print(B)
print(np.array_equal(A,B))
```
* e.g.

```
1
[ 0.0298082   0.04003474  0.02872756  0.09176077  0.01331635]
[ 0.06857003  0.06778863  0.07607786  0.05847496  0.006106  ]
n:False
2
[ 0.00317924  0.00509297  0.00045694  0.00244269  0.00191481]
[ 0.00082808  0.00936693  0.00762758  0.00880452  0.00209532]
n:False
3
[ 0.00078644  0.00079482  0.00026717  0.00028053  0.00044964]
[ 0.000313    0.00065483  0.00062208  0.00059468  0.00081469]
n:False
4
[  9.87031921e-06   7.62342923e-05   6.06185184e-05   9.00550070e-05
   8.71136572e-05]
[  5.77593038e-05   7.66163969e-05   7.80444868e-05   5.64477615e-05
   6.99759484e-05]
n:False
5
[  6.63956353e-07   4.40127691e-06   9.97819333e-06   2.70879250e-06
   5.98758872e-06]
[  5.22982428e-06   6.15193585e-06   1.62380013e-06   2.57664136e-06
   7.77403213e-06]
n:False
6
[  7.22618800e-07   4.24174705e-07   3.47110656e-07   5.50610346e-07
   3.83744762e-07]
[  2.26714831e-07   9.61289002e-07   2.78650787e-07   4.55959437e-07
   4.72961207e-07]
n:False
7
[  5.42295914e-08   4.11724669e-08   1.14244412e-08   3.47335529e-08
   7.96313319e-08]
[  6.78021955e-08   6.98691048e-08   8.07975635e-08   6.35369128e-08
   1.27262232e-09]
n:False
8
[  3.96133085e-09   2.43976101e-09   6.30000295e-09   4.95797726e-09
   5.80549571e-09]
[  2.39773425e-09   5.42822671e-09   9.81844991e-09   5.63585558e-09
   1.94575074e-09]
n:True
9
[  7.14517368e-10   6.73306783e-10   8.78720148e-10   8.43871868e-10
   2.78854396e-10]
[  2.85450974e-10   9.63295584e-10   9.56901702e-10   1.88261275e-10
   5.27516301e-10]
n:True
False
[ 0.  0.  0.  0.  0.]
[ 0.  0.  0.  0.  0.]
True
```
# Refs.
* [numpyで配列の等価・不等価を判定](https://python.dogrow.net/blog60/)
* [2つのarrayが近似的に同じか比べる](http://oppython.hatenablog.com/entry/2015/05/29/020902)
結果が得られないときには【GLPK】

[<--目次へ](https://qiita.com/ki073/items/508b3c20eb03078703dd)

##すぐに止まってしまう

PROBLEM HAS NO PRIMAL FEASIBLE SOLUTION
とメッセージが出て停止した時には、条件を満たす答えがないということです。まず制約条件を外して試してください。どこかに全ての制約条件を満たさない条件があるです。


##結果が収束しない
####minisatが使えるとき
--minisatをオプションで指定すると早く収束することがあります。
[GLPKのプログラムをMiniSatで動かす](https://qiita.com/ki073/items/b920a4fe490be790df01)
を参考に

####結果が収束しないとき
```
+ 31902: mip =     not found yet >=  -8.812395258e-15        (449; 28)
+ 36342: mip =     not found yet >=  -8.812395258e-15        (497; 29)
+ 40006: >>>>>   3.840489845e+01 >=  -8.812395258e-15 100.0% (603; 29)
+ 42602: mip =   3.840489845e+01 >=  -8.812395258e-15 100.0% (637; 38)
+ 45360: mip =   3.840489845e+01 >=  -8.812395258e-15 100.0% (674; 40)
```

のように上限がnot found yetではなく、 3.840489845e+01のように数字が表示されるようになるのであれば、--tmlim 120のように実行時間の上限をoptionで設定することで、途中で打ち切って許容解を返してくれます。
I Need jQuery

**[『You Don't Need jQuery』](https://github.com/nefe/You-Dont-Need-jQuery)**と言われて久しいですが、なんだかんだでユーザースクリプトなどでDOM操作を行なうには便利です。[^1]

## 要素の取得
ネイティブの要素取得メソッドは、種類も文字数も多すぎます。
jQueryでは、`$()`がすべてです。

### セレクタで取得（1つ）
#### ネイティブ
```js
const viewport = document.querySelector('meta[name=viewport]');
```

#### jQuery
```js
const $viewport = $('meta[name=viewport]');
```

### セレクタで取得（複数）
#### ネイティブ
```js
const externalLinks = document.querySelectorAll('a[target=_blank]');
```

#### jQuery
```js
const $externalLinks = $('a[target=_blank]');
```

### classで取得
#### ネイティブ
```js
const articles = document.getElementsByClassName('article');
```

#### jQuery
```js
const $articles = $('.article');
```

### idで取得
#### ネイティブ
```js
const main = document.getElementById('main');
```

#### jQuery
```js
const $main = $('#main');
```

### nameで取得
#### ネイティブ
```js
const buttons = document.getElementsByName('button');
```

#### jQuery
```js
const $buttons = $('[name=button]');
```

### タグ名で取得
#### ネイティブ
```js
const links = document.getElementsByTagName('a');
```

#### jQuery
```js
const $links = $('a');
```

## 複数のスタイルの設定
ネイティブでは、要素に対して複数のスタイルをまとめて設定することはできません。
jQueryなら、`jQuery.css()`で可能です。

### ネイティブ
```js
element.style['background-color'] = '#000000';
element.style['color'] = '#ffffff';
```

### jQuery
```js
$element.css({
  'background-color': '#000000',
  'color': '#ffffff'
});
```

## HTML文字列からの要素の作成
ネイティブでは、HTML文字列から要素を作成するために長い呪文を唱える必要があります。
jQueryなら、`$()`で可能です。

### ネイティブ
```js
const foo = document.createRange().createContextualFragment(`<div id="foo">Foo</div>`);
```

### jQuery
```js
const $foo = $(`<div id="foo">Foo</div>`);
```

## 表示状態の設定
ネイティブで要素の表示状態を切り替えるには、displayプロパティの値を書き換える必要があります。
jQueryには、いくつかの直感的なメソッドがあります。

### 表示
#### ネイティブ
```js
element.style.display = 'block';  //or 'inline', 'inline-block', 'inline-table'...
```

#### jQuery
```js
$element.show();
```

### 非表示
#### ネイティブ
```js
element.style.display = 'none';
```

#### jQuery
```js
$element.hide();
```

### 切り替え
#### ネイティブ
```js
const elementIsShowing = element.ownerDocument.defaultView.getComputedStyle(element, null).display !== 'none';
element.style.display = elementIsShowing ? 'none' : 'block';  //or 'inline', 'inline-block', 'inline-table'...
```

#### jQuery
```js
$element.toggle();
```

## 他言語版
- [English](https://dev.to/munieru_jp/i-need-jquery-51dj)

[^1]: 自分のアプリケーションでは、Vue.jsなどを使います。
kotoのプールを作成

#はじめに

kotoのプールの作成方法です。

[kotod](https://qiita.com/hideki8/items/3c768eff9335a9c28b53)はインストールされているとして

https://github.com/yoshuki43/k-nomp
https://github.com/kpooljp/k-nomp


#事前準備

`apt-get install redis-server`
`apt-get install build-essential libsodium-dev`

`apt-get install -y nodejs npm`
`npm cache clean`
`npm install n -g`
~~`n stable`~~
`n v9`

`ln -sf /usr/local/bin/node /usr/bin/node`
`apt-get purge -y nodejs npm`

#k-nompのインストール


`cd /usr/local`
`git clone https://github.com/kpooljp/k-nomp`
`cd k-nomp/`
`npm update`

`npm install bignum`

`npm install`

`cd pool_configs/`
`cp koto_example.json koto.json`

* address = koto-cli getnewaddress
* zAddress = koto-cli z_getnewaddress
* taddress = koto-cli getnewaddress
* daemon = koto.conf のユーザ名とパスワード

```koto.json

適宜修正

```

`cd ..`
`cp config_example.json config.json`

```config.json

適宜修正

```


#プールの運営

## crontab
`*/10 * * * * /root/k-nomp.sh >> /var/log/k-nomp-restart.log 2>&1`
payoutが止まった時に自動再起動します

## スタート
`k-nomp.sh start`

## ストップ
`k-nomp.sh stop`


#TODO

残高の確認
`koto-cli z_gettotalbalance`

マイニングしたコインをプライベートアドレスへ移動
`koto-cli z_shieldcoinbase "*" "zアドレス"`

プライベートアドレスからtアドレスへ移動
`z_sendmany "zアドレス" '[{"address": "tアドレス" ,"amount": 180}]'`

通常の送金
koto-cli sendmany "" "{\"tアドレス\":100}"


公開しているプール
http://jp.kpool.jp/

MPOS版
http://koto.jpool.jp/
【LaTeX】制御文字が原因のタイプセットエラーについて

先日 LaTeX のタイプセット中によくわからないエラーがあってタイプセットできなかったことがあったので, メモとして残しておきます.

ある日, bib ファイルの中身をいじってから tex ファイルでタイプセットした時のこと,

You're missing an entry type

と怒られました...

bib ファイルいじっちゃったからなあ...と, bib ファイルでエラーが起こってそうな箇所を見にいったのですが,
どうも変なところはなさそうでした.

実際, うまく動いていた時の bib ファイルからエラーの該当箇所と対応するところをコピーして, 今のファイルのエラー箇所に貼り付けてみるとうまく動きました.
でも見た目は全く一緒なので, どこがおかしいかわかりませんでした.
その時そのエラーを一緒に見てもらった人が言うには
もしかしたら変な制御文字が入っちゃったんじゃない？
と.
制御文字とは普通は見えない, いわゆる不可視文字というやつのようです.

Mac だとターミナルから vi コマンドを用いてファイルを開くと不可視文字も見られると聞き
vi を使って bib ファイルを見てみることになりました.
するとエラーの該当箇所に ^P の文字．
これがいわゆる制御文字というものだそうです．

ちなみに制御文字は
ctrl + Q
の後に
ctrl +  (何か)
を打つと制御文字が入力できるらしいです (詳しくはhttps://blog.fenrir-inc.com/jp/2016/11/input-control-characters.html).

わたしは caps lock に ctrl キーを割り当てていたので
shit + 2 を打って @ を入力したかった時に
ctrl + Q を打ってしまっていたのかもしれません...(ひどいタイプミス...)

もしタイプセットでエラーが出たときは制御文字の可能性も考えてみるといいかもしれません．
RxJS5で始めるRx入門

2年前に[RxJSで始めるRx\(Reactive Extensions\)入門1 \- Qiita](https://qiita.com/erukiti/items/6a82dfd3506e9773d592)という記事を書いたのですが、当時のRxJSのバージョンがもう古いもの(4系)で、それが残り続けてるのも申し訳ないので、[RxJS5](https://github.com/ReactiveX/rxjs)に関しての記事を書き直してみました。

## RxJS (Observable) は何がうれしいのか？

非同期処理、イベント処理などをすべて、統一したストリームというもので扱える。RubyのEnumerationやScalaのそれみたいな、コレクション操作のライブラリっぽく扱えます。

ES2015になってPromiseというとても強力な環境がJavaScriptで使えるようになりましたが、Promiseは1回処理が完了してしまうとそこでおしまいです。たとえば、EventEmitterのように何回も処理するような目的には使えません。

## 使い方

```sh
$ npm i rxjs -S
$ yarn add rxjs
```

npmでもyarnでもお好きな方でインストールしてください。

```js
const Rx = require('rxjs')

Rx.Observable.interval(1000)
  .subscribe(msg => console.log(msg, new Date().toLocaleTimeString()))
// 0 '20:37:32'
// 1 '20:37:33'
// 2 '20:37:34'
// ...
```

setIntervalの使いやすくなったヤツです。`Rx.Observable.interval(1000)`で1000ms(1秒)ごとに0からカウントアップする数字を流すストリームを作ります。

subscribeは言ってみればストリームの終着点です。`interval`であれば設定した時間ごとにsubscribeに登録した関数が呼び出されますし、Promiseベースであれば、Promiseのthenの代わりに呼び出されます。

## ストリームを生成する

`interval`の他にも、Eventから生成する、Promiseから生成する、固定値から生成するなど色々な手段でストリームは生成できます。[Creation · learn\-rxjs](https://www.learnrxjs.io/operators/creation/)を読むのが手っ取り早いでしょう。

地味に便利なのがrangeです。

```js
const Rx = require('rxjs')

Rx.Observable.range(0, 10)
  .subscribe(msg => console.log(msg))
// 0
// 1
// ...
```

どうしてもJSでレンジを扱うにはRubyと比べて面倒な感じがありました。generatorを作る、あるいはObject.keys(Array(10))みたいなトリッキーなコードを書く羽目になりましたが、`Rx.Observable.range`ならストリームとして簡単に使えます。

## オペレータで加工する

```js
const Rx = require('rxjs')

Rx.Observable.range(0, 10)
  .map(n => n * 2)
  .subscribe(msg => console.log(msg))
```

さっきの`range`の出力を加工するオペレータです。JSでも配列などのIterableではmapメソッドを便利に皆さん使っていると思いますが、同じことがRxJSでも可能です。

```js
const Rx = require('rxjs')

const source = Rx.Observable.of(0, 0, 1, 2, 1, 2, 2)

source.subscribe(n => process.stdout.write(`${n} `))
// 0 0 1 2 1 2 2
console.log('\n')

source
.distinctUntilChanged()
.subscribe(n => process.stdout.write(`${n} `))
// 0 1 2 1 2 
console.log('')
```

mapだけだととても寂しいですが、様々なオペレータがあるのがRxJS (というかRx)の特徴です。`distinctUntilChanged`というオペレータを使えば、連続する同じ値を間引く事ができます。

Rxとしての強みとしては、ストリームで時間軸を取り扱える点です。

```js
const Rx = require('rxjs')

Rx.Observable.interval(10)
  .throttleTime(2000)
  .subscribe(n => console.log(n, new Date().toLocaleTimeString()))

//   0 '21:11:56'
// 176 '21:11:58'
// 353 '21:12:00'
```

intervalのソースは10msですが、2000ms(2秒)経つまでのメッセージを破棄するのが`throttleTime`です。

## エラーハンドリング

```js
const Rx = require('rxjs')

Rx.Observable.throw(new Error('hoge'))
  .subscribe(
    () => console.log('waai'), 
    err => console.log(`handling!: ${err.toString()}`)
  )
// handling!: Error: hoge
```

subscribeに第二引数を渡すとエラーをキャッチできます。もちろんオペレータをいくつはさんでも大丈夫です。
Promiseを使っている人ならこの利点は理解していただけると思います。

## まとめ

非同期処理をいい感じにコレクションライブラリっぽく扱えるのがRxJSです。
[Swift] Processを使おう！(1)

### Processってなに？
ちょっと前までNSTaskと呼ばれていた、主にコマンドラインツールを実行してデータのやり取りを行うためのクラスです。
SwiftでできることはSwiftでやってしまえばいいのですが、swiftcを呼びたいとかそういう時に使います。

[第２回](https://qiita.com/masakihori/items/a85d1667b0af86d6f6e7)
[第３回](https://qiita.com/masakihori/items/fe094ca1f66d56f38d92)
[第４回](https://qiita.com/masakihori/items/3d6a2c083182076f2e0f)

### ちょっと使ってみよう
では早速使ってみよう。

```swift
let echo = Process()
echo.executableURL = URL(fileURLWithPath: "/bin/echo")
echo.arguments = ["Hello, World."]

let pipe = Pipe()
echo.standardOutput = pipe

echo.launch()

let readHandle = pipe.fileHandleForReading
let data = readHandle.readDataToEndOfFile()

if let output = String(data: data, encoding: .utf8) {

    print(output)
}
```


**長いわ――！！！！**

`Hello, World.`をechoコマンドで出力してその出力をprintする。
ただそれだけでこの長さです。
まあ、これではあんまり使おうとは思いませんね。

ということで、これを短くしていきます。
そのままでは無理なのでカスタムオペレーションなどをどんどん書いていきます。

## Processのセッティングを簡単に

では、どんどん行きます。
コマンドのパスと引数列を簡単に設定できるようにします。

```swift
precedencegroup ArgumentPrecedence {
    associativity: left
    higherThan: AdditionPrecedence
}
func <<< (lhs: Process, rhs: String) -> Process {
    
    lhs.executableURL = URL(fileURLWithPath: rhs)
    return lhs
}

func <<< (lhs: Process, rhs: [String]) -> Process {
    
    lhs.arguments = rhs
    return lhs
}
```

### 使用法

```swift
// original
let echo = Process()
echo.executableURL = URL(fileURLWithPath: "/bin/echo")
echo.arguments = ["Hello, World."]

// New!
let echo = Process() <<< "/bin/echo" <<< ["Hello, World."]
```

短い！　わかりやすい！


## 問題点

存在しないパスを渡すとURLが作れないので動かないよ！
文字列だしね！！
演算子の中に隠れちゃってるしね！！

じゃあまた次回！！（たぶん

[第２回](https://qiita.com/masakihori/items/a85d1667b0af86d6f6e7)
[第３回](https://qiita.com/masakihori/items/fe094ca1f66d56f38d92)
[第４回](https://qiita.com/masakihori/items/3d6a2c083182076f2e0f)
ちょっとずつ読むドメイン駆動設計 第四部 戦略的設計 第十四章 モデルの整合性を維持する10 公開ホストサービス/公表された言語

# これまでの十四章
- [第四部 戦略的設計 第一四章 モデルの整合性を維持する](https://qiita.com/YasuhiroKimesawa/items/6e8e5503a05ce9515a79)
- [境界づけられたコンテキスト](https://qiita.com/YasuhiroKimesawa/items/901ac764340275b93d61)
- [継続的な統合](https://qiita.com/YasuhiroKimesawa/items/6a58743c90c5b707c29d)
- [コンテキストマップ](https://qiita.com/YasuhiroKimesawa/items/626384c84145870ec5af)

##  
- [共有カーネル](https://qiita.com/YasuhiroKimesawa/items/7895d8c28137bd34008a) 
- [顧客/供給者の開発チーム](https://qiita.com/YasuhiroKimesawa/items/c9668a437499897fa9d5)
- [順応者](https://qiita.com/YasuhiroKimesawa/items/ab4782d5e727075e2d87)
- [腐敗防止層](https://qiita.com/YasuhiroKimesawa/items/bf22f7a970d5ee29a111)
- [別々の道](https://qiita.com/YasuhiroKimesawa/items/259cff6e393d5d03e274)

ここからは、統合を拡大、つまり、多くのサブシステムと統合する必要がある場合のパターンです。

# 公開ホストサービス

公開ホストサービスは、プロトコル(RestAPIなど）を公開し、統合する必要がある人が全員使用できるようにするパターンです。
あるチームにだけに特有の要求などは、プロトコルを拡張し対応します。共有のプロトコルは一貫性のある状態を保つのがよいでしょう。

# 公表された言語

公表された言語は、２つの境界づけられたコンテキスト間のモデルの変換で共通する言語を利用します。
業界やコミュニティで既に広く公表されていたり、標準化されている言語を使うというものです。

XML形式で公表されているものや、APIが公開されているものもあるでしょう。

書籍の例では、化学のための化学マークアップ言語を利用する例が挙げられています。

なかなか、こういう言語ってないような気もしますし、こちらのドメインモデルに合わないこともあります。
もし見つけることができたなら、参考になりますし、ドメインの深い理解に役に立つことが多々あるかと思います。

APIやXMLだけでなく、業界の資格試験の参考書や用語集なども役に立つと思います。
自分の今のドメインであるEC業界でもネットショップ検定なるものがあり、この参考書が結構役に立ったりします。
CygwinのEmacsをタスクバーからいい感じに起動

# 課題

WindowsでEmacsを動かす方法はいくつかありますが、Cygwinを使っている場合は親和性の観点から、CygwinのEmacsが使いたくなります。しかし、emacs-w32.exeはコンソールプログラム（コンソールアプリケーション）として作成されているので、単純にタスクバーにピン留めしてこれをクリックして起動すると、真っ黒のコンソールウィンドウが余分に表示され、いい感じじゃありません。

# コンソールウィンドウの隠蔽

Cygwinはベースシステムにrun.exeというコマンドが用意されており、これに目的のプログラムを与えると、コンソールウィンドウを隠蔽してくれます。emacs-w32.exeのコンソールウィンドウを隠蔽するには、run.exeのショートカットを作成して適当な名前（run-emacsとか）に変え、プロパティの「リンク先」としてEmacsのコマンド名emacs-w32を引数として付け、`C:\cygwin64\bin\run.exe emacs-w32`のようにしておきます。あと、アイコンをemacs-w32.exeのものに変更し、作業フォルダを`C:\cygwin64\home\%USERNAME%`などとしておくとよいでしょう。

これをタスクバーにピン留めしておくと、起動しても、コンソールウィンドウが一瞬現れますが、すぐ消えるので、まあいい感じとしておきましょう。

ところがタスクバーをよく見ると、Emacsのアイコンがもう一つ表示されてしまいます。これはいい感じじゃありません。

# タスクバーのグループ化制御

Windows 7以降では、プログラムはアプリケーションID（AppId）でグループ化されてタスクバーに表示されます。ところが、ショートカットにはデフォルトではAppIdが設定されていないため、起動されたプログラムそのものは別のグループとして扱われてしまうのです。

プログラムのAppIdは、[7+ Taskbar Tweaker](http://rammichael.com/7-taskbar-tweaker)により調べることができます。これをインストール・起動すると、ウィンドウ右下にある「Taskbar Inspector」ボタンにより、現在のタスクバーの各AppIdが表示されます。これによると、CygwinのEmacsのAppIDは`GNU.Emacs`です（GNU純正のMinGW32バイナリも同様のようです）。

次に、ショートカットのAppIdを設定するには、[Win7AppId](https://code.google.com/archive/p/win7appid/downloads)が利用できます。`Win7AppId1.1.exe`をダウンロードして適当な場所に置き、次のように実行すると、それまでのAppIdが表示され、新しいAppIdが設定されます。（引数の先頭の/はスイッチとして扱われるので、Cygwinからはショートカットを絶対パスで指定でできないので注意）

```
$ Win7AppId1.1 run-emacs.lnk GNU.Emacs
```

# 完成

以上の作業の後、いったんタスクバーのピン留めをはずし、再度run-emacsをピン留めします。以降は、これをクリックすると、コンソールウィンドウは出ず、タスクバーのグループ化もうまくいき、いい感じです。

もちろん他のGUI付きコンソールアプリケーションにも応用できます。
Win10にVirtualBox+Vagrantを用いた環境構築する為の下準備

windows10 home環境にVirtualBox+Vagrant+CentOSの環境構築を行ったのですが、
手こずったので記述しておきます。


# **1.各ツールバージョン**
| 各種ツール      |       バージョン |
|:-----------------:|:------------------:|
|VirtualBox|5.1.30     |
|Vagrant|2.0.1      |
|CentOS|6.5|



# **2.各種ツールのダウンロード・インストール**
下記記載のツールをインストールしてください。
## 2.1 Virtualbox
https://www.virtualbox.org/wiki/Downloads
使用しているPC上に仮想的なPCを作成し、他のOSをインストールして実行可能にします。
## 2.2 Vagrant
https://www.vagrantup.com/
開発環境を簡単に構築・管理、配布出来るツールです。詳しくは下記サイトを参照。
>VirtualBoxが「野球場」でVagrantが、チームごとの「マネジャー」
https://qiita.com/kenju/items/00050972fdf74e37e71f

# **3.Windows環境構築の下準備**
そのまま構築すると[vagrant up]を実行した後にブルースクリーンが発生したり問題が起きるので回避する設定を行います。

## 3.1 BIOS設定で仮想化支援機構(VT-x/AMD-V)を有効にする
VisualBoxは仮想化支援機構が有効である必要があるので、BIOS設定を変更し有効にしてください。


**BIOSへのアクセス方法**
1.[Shift]を押しながらシャットダウン
2.[F2]を押しながら起動
※端末により異なる場合があります。

## 3.2 Hyper-Vの無効化
Hyper-Vの無効化はいくつか方法がありますが、実際に無効化出来た方法は下記となります。
Windows10 homeでも、Hyper-V無効化は必要です。
1.管理者権限でコマンドプロンプトを起動
2.下記コマンド1を実行

```bat:コマンド1
bcdedit /copy {current} /d "Disable Hyper-V"
>エントリは {ここに文字列} に正常にコピーされました。
```
```bat:コマンド1_結果
エントリは {ここに文字列} に正常にコピーされました。
```
3.上記結果のカッコ内文字列を下記コマンドに当てはめ実行。

```bat:コマンド2
bcdedit /set {先ほどの文字列} hypervisorlaunchtype off
```
4.[Shift]を押しながらWindowsを再起動
5.再起動すると[Disable Hyper-V]ボタンが表示されるので押下する
これで、Hyper-Vが無効化が完了しました。
>参考エントリ
>http://variedtastefinder.jp/blog/?p=3145

尚、下記の方法ではHyper-V出来ませんでした。
1. 「Windowsの機能の有効化または無効化」からHyper-Vの項目を無効化
　問題：Hyper-Vの項目が見つからない。Homeだから？
2. 管理者権限でcmdを起動、「bcdedit /set hypervisorlaunchtype off」を実行する
　問題：実行してもHyper-Vが無効化されない

## 3.3 Vagrantのホームディレクトリの変更(任意)
デフォルトではCドライブに保存されるようになっているので、
容量が少なく任意の場所に変更したい場合は下記動作を行ってください。

1.環境変数設定画面を開く(タスクバーの「○」から「環境」と検索)
2.[環境変数]ウィンドウの[システム環境変数]に下記変数を追加する

| 変数名 | 値 |
|:-:|:-:|
| VAGRANT_HOME  | 任意のディレクトリ  |


## 3.4 VirtualBoxの仮想マシンフォルダ変更(任意)
上記と同じでデフォルトではCドライブなっているので必要があれば設定してください。
1.VirtualBox起動
2.[ファイル]-[環境設定]を開く
3.[一般]-[デフォルトの仮想マシンフォルダー]へ任意のディレクトリを設定
![image.png](https://qiita-image-store.s3.amazonaws.com/0/226435/20999cb6-a4bb-110a-b9e9-fd5959dde653.png)

>参考エントリ
>http://memories.zal.jp/WP/blog/20160214_2707.html



# 4. 下準備完了
これでWindows10 Homeでの環境構築の下準備は完了です。
後は、下記の素晴らしいエントリがありますので参照ください。
Web表示確認まで行けるはずです。

・Windows上でVirtualBox+Vagrant+CentOSによる仮想環境構築
https://qiita.com/hiroyasu55/items/11a4c996b0c62450940f

# 追記
filezillaでvagrantの仮想環境へアクセスする参考エントリ
http://motomichi-works.hatenablog.com/entry/2015/06/14/151822
Androidの画像ファイルをdp解像度毎にディレクトリに分ける処理

#はじめに
svgで作れば、こんなものは必要ありません。
お勉強です。

###sketchで書き出すとき

<img width="220" alt="6f688d72-245f-55c5-71f5-abac9878a7b1.png" src="https://qiita-image-store.s3.amazonaws.com/0/70283/e8dddecc-cc7e-bfef-2f79-20e1c7d434d7.png">

こんな感じでexportすると、まだディレクトリに振り分けられていない。
大量に書き出したときに、コンソール叩いて一気に振り分ける方法が以下。

#書き出し方法

作る場所はどこでも良いです。
###解像度毎のディレクトリを作成

```
cd Desktop/res/
mkdir drawable-xxxhdpi; drawable-xxhdpi; mkdir drawable-xhdpi; mkdir drawable-hdpi; mkdir drawable-mdpi
```

###書き出す。

```
for file in $(find . -type f -iname '*@4x*'); do
  mv "$file" "drawable-xxxhdpi/${file/@4x/}"
done
for file in $(find . -type f -iname '*@3x*'); do
  mv "$file" "drawable-xxhdpi/${file/@3x/}"
done
for file in $(find . -type f -iname '*@2x*'); do
  mv "$file" "drawable-xhdpi/${file/@2x/}"
done
for file in $(find . -type f -iname '*@1.5x*'); do
  mv "$file" "drawable-hdpi/${file/@1.5x/}"
done
for file in $(find ./ -type f -maxdepth 1 -iname '*.png' | grep -v "@"); do
  mv "$file" "drawable-mdpi/${file}"
done
```

これで、それぞれのディレクトリに画像が振り分けられたはず。
おわり。

#良さげなプラグインがあった・・・
https://github.com/nickstamas/Sketch-Better-Android-Export
https://github.com/GeertWille/sketch-export-assets
エンジニアのキャリア

##エンジニアのランチェスター戦略
https://qiita.com/kopug/items/2e6821de0d0fefb29e0f
https://ferret-plus.com/534

##学び続けるために
https://qiita.com/sakaizay/items/e4ae74bfecd026925e3b
https://qiita.com/YudaiTsukamoto/items/42a8df22ca4c6b327dfd
numpyの配列を一定の確率で反転される


numpyを使ってて、まれによく0,1で構成される配列の要素を一定の確率で反転させたいときがあると思います。
numpyに慣れてないと、パッとコードに落とし込むの大変なのでメモしときます。

```python
#p : 反転させる確率
#matrix : 0,1で構成されるnumpy配列

def random_inverts(p,matrix):
     matrix = matrix.astype(bool)
     random_mask = np.random.binomial(1,p,size = matrix.size).astype(bool)
     matrix = np.where(random_mask == 1,~matrix,matrix).astype(np.int32)
     print(matrix)
     return matrix
```
VSCode で TypeScript 書いてるときに aws-sdk が cannot find module になる件

最近 Flowtype から TypeScript に乗り換えました。

主に VSCode で書いてるんですが、

![2017-12-26 (3).png](https://qiita-image-store.s3.amazonaws.com/0/71785/b755b15b-c9d9-b828-2201-7a4765a37490.png)

こういうエラーが出る件について。

TypeScript のコンパイラは通るので、たぶん VSCode の問題なのかなと思ってます。

VSCode と TypeScript とで依存解決の仕組みが違うんでしょうか。

とりあえず `tsconfig.json` にこのように書くと直りました。

```json
{
    ...
    "files": [
        "node_modules/aws-sdk/index.d.ts",
        "index.ts"
    ],
    ...
}
```

TypeScript サーバーを再起動するか VSCode を再起動することで反映されます。

`index.ts` はアプリケーションのメインなので適宜変えてください。

## TSLint と両立しない問題

で、先のように変えると今度は TSLint を `tslint --fix --project tsconfig.json 'index.ts' 'src/**/*'` みたいに実行している場合に `src/**/*` が `tsconfig.json` の `files` に存在しないため正常にリントできません。

`files` ではなく `include` で設定すれば TSLint は問題ないのですが、また aws-sdk が cannot find module になるというループに陥ります。（なぜ `files` でなければならないのか :rage:）

ツラいですが、TypeScript のための `tsconfig.json` と、TSLint のための `tsconfig.lint.json` を作って、TSLint の実行を `tslint --fix --project tsconfig.lint.json 'index.ts' 'src/**/*'` のようにすることで解決しています。

`tsconfig.json` には先のように `files` 指定を含み、`tsconfig.lint.json` にはそれを含めず CLI オプションを使います。

---

[@types](https://github.com/DefinitelyTyped/DefinitelyTyped) に登録のあるライブラリでも、ライブラリ自体が declaration を提供している場合でも、同様の問題は起きていないのでなぜ aws-sdk だけなのかは分かりません。`index.d.ts` ではなく `aws-sdk.d.ts` じゃないと解決できないとかそんな感じでしょうか。

もっとスマートな対応方法があればどなたか教えてください。

アップデートで直ることを期待してます。
AOM AV1コーデックと特許管理

[Alliance for Open Media(AOM)][aom] により開発されているロイヤリティ・フリー(Royalty-Free)な動画像コーデック「AV1」と、同コーデックにおける特許(Patent)の考え方についての情報収集メモ。


超要約：

- **コーデック仕様** と **エンコーダ/デコーダ実装** の ロイヤリティ・フリーを保証する。
- この保証が **現在から将来に渡って担保される** よう最大限配慮されている。特に **防御的解除** 条件により特許訴訟への対抗策が明示されている。
- 防御的解除＝(発端の)訴訟を起こした団体/個人に対して、即時のライセンス解除を発動する。

旧来のMPEG系コーデックとの違い：

- AV1では **特許ライセンス許諾範囲がエンコード処理を包含する**。MPEG系ではデコード処理の必須特許のみが許諾範囲であり、エンコーダ実装には別途での考慮が必要であった。
- AV1では **特許ライセンス許諾範囲がエンコーダ／デコーダ実装を包含する**。MPEG系では参照エンコーダ／デコーダ実装のソフトウェア・ライセンスは特に統一されていない。
- AV1では **コーデックの初期策定段階から** ロイヤリティフリー実現にむけてた合意を行っている。MPEG系では[妥当で公平なライセンス(RAND)][rand]条件への同意のみであり、具体的な特許使用料の議論は仕様策定の後で行われている。

[rand]: https://ja.wikipedia.org/wiki/RAND%E3%83%A9%E3%82%A4%E3%82%BB%E3%83%B3%E3%82%B9


# Alliance for Open Media Patent License 1.0
https://aomedia.org/license/patent-license/

（下記の日本語抄訳は部分的な意訳であり無保証の参考情報にすぎません。）

- 各ライセンサー(_Licensor_)は、本ライセンスにある条項および条件に従うことを前提に、自己および承継人と譲受人を代理して、あらゆる実装(_Implementation_)を製造、使用、販売、販売の申し出、輸入または頒布するための必要請求項(_Necessary Claims_)を、譲渡不能で(non-sublicensable)、永久的に(perpetual)、全世界で(worldwide)、非排他的に(non-exclusive)、無償で(no-charge)、ロイヤリティー・フリーの(royalty-free)、（本ライセンスで明確に記述されるものを除いて）解除不能な(irrevocable)特許ライセンスを、ライセンシー(_Licensee_)に対して付与する。
- 防御的解除(Defensive Termination): 万一、いずれかのライセンシー(_Licensee_)、その関係者(_Affiliates_)または代理人が、特許訴訟を開始ないし提出、支持した、もしくは他団体や個人に対し任意の実装(_Implementation_)の必要請求項(_Necessary Claims_)侵害を主張する訴訟へ加わった場合、本ラインセンスの下でライセンシー(_Licensee_)に付与された特許ライセンスは、1)その訴訟が開始団体による実装(_Implementation_)に関する最初の訴訟提起へ応えるものである、または 2)その訴訟が本ライセンスの解除を強制する提起（ライセンシー(_Licensee_)による第三者行動の参加を含む）である場合を除き、行動の開始日をもって即時解除される。
- 必要請求項(_Necessary Claims_)とは、(a)現在および将来の任意時点でライセンサー(_Licensor_)に保有ないし管理され、(b) (i)仕様(_Specification_)をW3C勧告とみなして[W3C Policy as of February 5, 2004][w3c-patent]で定義される必須請求項(Essential Claim)、または (ii)参照実装(_Reference Implementation_)により侵害される、あらゆる特許の請求項を意味する。
- 関係者(_Affiliate_)とは、契約当事者を直接的または間接的に支配する(_Controls_)、支配される(_Controlled by_)、ないし共通の支配(_Control_)下にある団体を意味する。
- 支配(_Control_)とは、対象法人の役員選出投票権の50%以上を直接支配または間接支配、もしくは任意の他団体に対する、該当団体の直接経営権を意味する。
- 実装(_Implementation_)とは、参照実装(_Reference Implementation_)を含む、エンコーダ(_Encoder_)かつ／またはデコーダ(_Decoder_)を意味する。
- 参照実装(_Reference Implementation_)とは、Alliance for Open Mediaから最終成果(_Final Deliverable_)としてリリースされるエンコーダ(_Encoder_)かつ／またはデコーダ(_Decoder_)を意味する。

[aom]: http://aomedia.org/
[w3c-patent]: https://www.w3.org/Consortium/Patent-Policy-20040205/#def-essential


# 参考
- (PDF) [Progress in the Alliance for Open Media](https://people.xiph.org/~tterribe/pubs/lca2017/aom.pdf), 2017 linux.conf.au
- (PDF) [解説 ITU-T/ITU-R/ISO/IEC 共通特許ポリシーの実施ガイドライン](http://www.jisc.go.jp/policy/kenkyuukai/ipr/pdf/PatentPolicy_kaisetsu.pdf)
OSSをtake overした話

# はじめに

少し前の話ですが、[会社](https://supership.jp/)が「スポンサーやるので誰かチケットあげるよー」ということだったので[builderscon tokyo 2017](https://builderscon.io/tokyo/2017)に参加させていただきました。

なかでも@hsbtさんが発表されていた「How to take over OSS project」はとても印象深くて、帰りの電車のなかでいくつかの言葉が頭のなかをぐるぐる回っていたのを覚えています。

https://speakerdeck.com/hsbt/how-to-take-over-oss-project

その後いろいろあって本当にOSSをtake overすることになったので経緯を残しておきます。

## ひょんなことからCrystalをやってみることに

ビルダーズコン開催と同じ月である2017年8月に入社していた@maihaさんの布教によって[Crystal](http://ja.crystal-lang.org/)を触りはじめました。

「型があるRuby」みたいな書き心地がなんとも良いです。

## 放置されているプロジェクトを発見

練習も兼ねてRubyで書いた簡単なCLIをいくつかCrystalでリプレイスして遊んでいました。

そんななかオレオレTwitterクライアントをCrystalで書き直そうとしていたとき、[twitter-crystal](https://github.com/sferik/twitter-crystal)という使えそうなライブラリを発見。

Rubyでは[twitter](https://github.com/sferik/twitter)というGemを使っていたんですが、作者が同じだということに気づいて期待に胸踊りました。

さっそくソースコードを読んでみるとどうやらエンドポイントとオプションを引数で渡して使ってくれ、ということらしい。

こんなイメージですね :point_down: 

```crystal
client.post("/1.1/statuses/update.json", {"status" => "こんにちは世界"})
```

Ruby版のように 

```crystal
client.update("こんにちは世界")
```
みたいに、URLを意識せずに使えることを期待してた僕としてはちょっと残念。。。

他に良いライブラリがないか探してみたものの、めぼしいものは見つからず。

残念ながら開発は止まっているようだったので「フォークしてつかうかー、、、」なんて思いましたが、

**もしかして、こういうときのための「How to take over OSS project」なんじゃあないか？**

と思い立って、ダメもとで連絡してみることにしました。


## オーナーにメール

僕
「はじめまして、 @kenta-s といいます。このプロジェクト、メンテしたいのでよかったら権限もらえませんか？」

〜 数分後 〜

sferikさん
「done. ありがとう！」

まじすか、こんなにあっさり...?

https://speakerdeck.com/hsbt/how-to-take-over-oss-project　
の

>２. Request to take over via E-Mail/DM/Slack...

のパターンですね。

そういえば、@hsbtさんは「世界的には連絡手段としてemailを利用している人が多い」といったこともおっしゃっていました。

## というわけで

欲しかった機能をバンバン付けてバンバン使ってます。
インターフェースはRuby版のそれを意識して実装していったので、sferikさんの意志に大きく反するような形にはなっていない、、、と思いたい。

これまではOSSについては「使う」「Issueを立てる」「PRを出す」くらいの選択肢しか持っていなかったんですが、ここに「引き継ぐ」が追加された瞬間でした。

メンテナになると責任を伴ってしまうので、引き継ぎは最終手段にしておきたいというのが正直なところ（実際精神的に少しキツい瞬間ありました）ですが、
それでも可能性が広がったのは間違いなくて、@hsbtさんと、良い機会をくれた会社には感謝です。

タイミングよくCrystalを紹介してくれた@maihaさんにも圧倒的感謝です:pray:
AppleWatchでボタンのタッチ開始と終了タイミングを検知する方法

# はじめに

スマートウォッチで色々楽しいことができるといいなとワクワクしながらAppleWatchを買った筆者であったが、あまりの制限の多さに絶望...
ボタンのタッチ開始、終了のタイミングもわからないじゃないか...
いや待て、できるかもしれない。ヤツを使えば...。

# 解決方法概要

Long Press Gesture Recognizerを本来とは間違った方法で使う。
このジェスチャイベントはなぜかわからないが、longPressの認識開始タイミングと終了のタイミングの二回にイベントハンドラを発動させる。そこで、longPressの認識開始タイミングをキーをタッチしてから0秒後にすることで、キーをタッチした瞬間とキーを離した瞬間の2回イベントハンドラを発動させることができるようになる。

# 実装方法

1.まずはButtonをInterface.storyboardに追加する。
2.続いてLong Press Gesture RecognizerをButtonの配下に追加する。
![longpress.png](https://qiita-image-store.s3.amazonaws.com/0/67153/3997dea4-6624-7a53-318a-cc44a345b3dd.png)
3.Long Press Gesture Recognizerをインスペクターで編集
Min Durationを0にする
4.Long Press Gesture RecognizerとInterfaceControllerをIBActionにて関連付けする
5.コーディング（タッチ開始と終了に分岐させて処理）

```swift
@IBAction func press(_ sender: Any) {
    let recognizer = sender as! WKLongPressGestureRecognizer
    if recognizer.state == .began {
        //タッチ開始の処理
    } else if recognizer.state == .ended || recognizer.state == .cancelled {
        //タッチ終了の処理   
    }
}
```

# 終わりに

AppleWatchは開発上の制限が非常に多く、思いついたことを実装するにはあまりにも環境が悪い。なぜ売れないのか、なぜ専用アプリが少ないのかは開発してみて初めて理解できた。
画像とボタンとラベルしか置けないのでは、ちょっとしたアニメーションやインタラクションを実装することも困難だ。BLEでHIDキーボードとして認識させることもできない。もっとデベロッパに自由を与えてほしい。切実にそう思う。
VulsをDockerで構築したけどHostKeyを登録しろと永遠言われる問題

# 前提
公式の手順を元にDockerをセットアップした。
https://github.com/future-architect/vuls/tree/master/setup/docker

# 問題
Dockerのホストからサーバに接続はできる。
しかし、HostKeyを登録しろと怒られる。それは100年前に登録してある。

```
[Dec 26 09:28:48] ERROR [localhost] (5/5) Failed: SERVER, err: [Failed to detect OS: Unable to connect via SSH. Check SSH settings. If you have never SSH to the host to be scanned, SSH to the host before scanning in order to add the HostKey. user@172.17.2.62 port: 22
execResult: servername: SERVER
  cmd: /usr/bin/ssh -tt -o StrictHostKeyChecking=yes -o LogLevel=quiet -o ConnectionAttempts=3 -o ConnectTimeout=10 -o ControlMaster=no -o ControlPath=none user@172.17.2.62 -p 22 -i /root/.ssh/id_rsa_vuls -o PasswordAuthentication=no stty cols 1000; ls /etc/debian_version
  exitstatus: 255
  stdout: 
  stderr: 
  err: %!s(<nil>)]
```

# 原因
接続先のセグメントが、
Docker　bridgeのデフォルトのIPとバッティングしていた。


# 調査結果
debugモードで実施すると、
getsockopt: no route to hostというエラーが大量に吐かれていた。

```
$ docker run --rm -it    -v ~/.ssh:/root/.ssh:ro     -v $PWD:/vuls     -v $PWD/vuls-log:/var/log/vuls     vuls/vuls configtest     -config=./config.toml --debug
(略)
o SERVER, err: dial tcp 172.17.2.62:22: getsockopt: no route to host, Retrying in 3.749548963s...
[Dec 26 09:37:36] DEBUG [localhost] Failed to Dial to SERVER, err: dial tcp 172.17.2.61:22: getsockopt: no route to host, Retrying in 5.535907099s... 
```

コンテナ内に入り、対象のサーバへping/sshを実施。繋がらない。
他のセグメントや他のサーバには繋がる。
恥ずかしながらここで初めてDocker内のネットワークを疑う。


# 対応方法
Docker　bridge のIPを使っていないセグメント帯に変更

まずはdockerのネットワーク一覧を表示

```
# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
ae5bb0c38a2c        bridge              bridge              local
dd1c38f5429e        host                host                local
6519945407d0        none                null                local
#
```

bridgeが怪しいので中身を調査

```
$ docker network inspect ae5bb0c38a2c
[
    {
        "Name": "bridge",
 (略)
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },

```

ビンゴ。

Docker bridgeのセグメントを変更。

```
# vi /usr/lib/systemd/system/docker.service 
（略）
[Service]
（略）
#ExecStart=/usr/bin/dockerd
ExecStart=/usr/bin/dockerd --bip=10.0.0.1/8
```
docker再起動。。。
と思ったけど、OS再起動しても構わないサーバだったので
念のためOS再起動

```
# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         GATEWAY         0.0.0.0         UG    100    0        0 eth0
10.0.0.0        0.0.0.0         255.0.0.0       U     0      0        0 docker0
```

docker0のセグメントが変更された。


# Vulsを起動

```
$ docker run --rm -it    -v ~/.ssh:/root/.ssh:ro     -v $PWD:/vuls     -v $PWD/vuls-log:/var/log/vuls     vuls/vuls scan   -config=./config.toml
(略)
 (5/5) Detected: SERVER: centos 7.4
```
成功！


# 参考情報
Dockerのbridgeのセグメントを変更する方法
http://tigertaizo.hatenablog.com/entry/2016/08/06/173101#1-Docker%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E7%8F%BE%E7%8A%B6%E7%A2%BA%E8%AA%8D

#
ルータの設定画面をブラウザで開けなかった恥ずかしい話

# はじめに
ルータのLANの設定をするためには、ルータをLANケーブルでPCに繋いで、ブラウザのURL欄に192.168.11.1とか入力してログインして設定するのが一般的だけど、以下の恥ずかしい原因で入れなったので、戒めにメモっておく。

# 恥ずかしい原因2例
- LANケーブルをルータのWANポートにつないでいた。→LANポートに繋ぎ直そう
- 繋いだPCのホストOSの上にvirtualboxでVM立てたりしてたんだけど、ルータのIPがVirtualbox用のホストOSのIPと被っていた。→virtualbox止めたり設定したり、別のPC使おう。

# ちなみに
久しぶりにルータの設定とかすると、IPアドレスとかアカウントとか忘れていることが多い。以下のサイトにデフォルトの設定値がメーカ毎にまとまってたので載せておく。
https://pctrouble.net/network/router_ip.html
Nodeがなくてもvueファイルを使いたい

**追記**

getlibsというのが良さそうらしいです。

[レガシィシステムでVueとPHPの連携を考える](https://qiita.com/dozo/items/1116892fb6cb110265e4)

***

私が求めていたものが見つかったかもしれないのでメモ

[http-vue-loader](https://github.com/FranckFreiburger/http-vue-loader)

まだ試していませんが期待は大きいです。というのも[ブラウザだけでvue.jsは使える](https://qiita.com/horikeso/items/91db9b1ed24f8fe33fb5)のですが、ララベルみたいにコンポーネント毎にファイル管理をしたいなと思っていましたが、それにはNode.jsでビルドしないといけませんでした。更に個人的にはララベルでNode.jsを使いたくなかったこともあります。Node.js使えるならサーバーサイドもnode.jsで良いではないかという考えに至ってしまうからです。今度ララベルのapp.jsを使わないでvue.jsでvueファイルを使ってみようと思います。

とりあえず試してみたところ問題なく動作しました。
Homebridgeで対応できない家電をGoogle Homeで操作する（IRKit使用）

# 概要

Google Homeへの呼びかけでシーリングライトのリモコンボタン押下と同様の操作を行う。
事情に興味ない方は本題へ→[赤外線信号の取得](#赤外線信号の取得)

# 背景

[エアコンをHomebridge対応させたり](https://qiita.com/tkms0106/items/eba7d233981b0293b78d)、Philips Hueを買って玄関等に配置し、自宅IoT化の恩恵を享受する中、部屋に元々備え付けられていたシーリングライトが取り残されていた…。

## 取り残された理由

シーリングライトの仕様とHomebridgeの設定ファイルのフォーマットが合わない。

## Homebridgeの設定ファイル

オンとオフの2状態を想定し、「オンにする信号」「オフにする信号」を記述する。

## シーリングライトの仕様

* 状態は4つ
  * 蛍光灯2本点灯
  * 蛍光灯1本点灯
  * 常夜灯
  * 完全消灯
* リモコン信号は1つ

オンにする / オフにする で信号が分かれていないため、2本点灯と完全消灯の2状態だけを抜き出して設定ファイルに書く、ということができない。
信号は1つだからとむりやり設定ファイルを書いても、「ホーム」アプリ上の表示が気持ち悪いことになる。
（例えば、2本点灯：オン、1本点灯：オフ、常夜灯：オン、完全消灯：オフのようになる）

# Homebridgeを使うまでもなかった？

* 状態を考慮せず信号が送りつけられればそれでよい
* IRKitにはWeb APIがある

→GoogleHomeとIFTTTで操作できる

# 赤外線信号の取得

http://getirkit.com より

IRKitに向けてリモコンを操作し、赤外線信号を読み取らせてから以下のコマンドを実行

```
% curl -i "http://[IRKitのIPアドレス]/messages" -H "X-Requested-With: curl"
HTTP/1.0 200 OK
Access-Control-Allow-Origin: *
Server: IRKit/2.1.3.13.gbe33d36
Content-Type: text/plain

{"format":"raw","freq":38,"data":[18031,8755,1190,1190,1190,3341,1190,3341,1190,3341,1190,1190,1190,3341,1190,3341,1190,3341,1190,3341,1190,3341,1190,3341,1190,1190,1190,1190,1190,1190,1190,1190,1190,3341,1190,3341,1190,1190,1190,3341,1190,1190,1190,1190,1190,1190,1190,1190,1190,1190,1190,1190,1190,1190,1190,1190,1190,3341,1190,3341,1190,3341,1190,3341,1190,3341,1190,65535,0,9379,18031,4400,1190]}
```

# clientkeyとdeviceidの取得

まずclienttokenを取得

```
% curl -i "http://[IRKitのIPアドレス]/keys" -d '' -H "X-Requested-With: curl"
HTTP/1.0 200 OK
Access-Control-Allow-Origin: *
Server: IRKit/2.1.3.13.gbe33d36
Content-Type: text/plain

{"clienttoken":"XXXXXXXXXXXXXXXXXXXXXXXXXXXXX"}
```

取得したclienttokenを使いclientkeyとdeviceidを取得
ここはURLがローカルIPアドレスでない点に注意

```
curl -i -d "clienttoken=XXXXXXXXXXXXXXXXXXXXX" "https://api.getirkit.com/1/keys"
HTTP/1.1 200 OK
Server: ngx_openresty
Date: Tue, 07 Jan 2014 08:46:06 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 94
Connection: keep-alive
X-Content-Type-Options: nosniff

{"deviceid":"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX","clientkey":"XXXXXXXXXXXXXXXXXXXXXXX"}
```

# IFTTTアプレットの作成

## This部

設定はお好みで
画像の例だと、「照明」より「明かり」の方が理解してもらいやすい（気がする）。

![323b06f9-7cf5-418b-9be9-67bf3528a72e.png](https://qiita-image-store.s3.amazonaws.com/0/195900/4199dd5c-299d-ecff-2d09-e2af34ef2258.png)

## Then部

Content Typeが見切れているが`x-www-form-urlencoded`を選択

![07abea43-383a-42d2-8aef-61e258a6fbdb.png](https://qiita-image-store.s3.amazonaws.com/0/195900/8699beb8-e3a3-47a0-888a-64fab0a26764.png)

Body(optional)欄に書く内容

```
clientkey=取得した文字列に置き換え&deviceid=取得した文字列に置き換え&message=取得した赤外線信号JSONに置き換え
```

これで、呪文を唱えると照明を操作できるようになる。

# 問題

全点灯から消灯に一気に遷移したいときなどに繰り返し唱えるのが面倒。
C++ Builder XE4, 10.2 Tokyo > モニタ解像度 > Bug > Screen->Monitors[0]のWidthとHeightがおかしくなる

```txt:動作環境
C++ Builder XE4
Rad Studio 10.2 Tokyo Update 2
```

[c++ builder > form > モニタ解像度の取得 > Screen->Monitors[0]->Width; / ->Height; // Screen->PrimaryMonitor->](https://qiita.com/7of9/items/228a65f799f5181e916e)
を10.2 Tokyoで試していて気付いた不具合。

### code 

```Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
// 1. Monitors[]使用
    int width = Screen->Monitors[0]->Width;
    int height = Screen->Monitors[0]->Height;

	String msg = String().sprintf(L"Monitors[0]: W%d x H%d", width, height);
	Memo1->Lines->Add(msg);

// 2. PrimaryMonitor使用
	width = Screen->PrimaryMonitor->Width;
	height = Screen->PrimaryMonitor->Height;
	msg = String().sprintf(L"Primary: W%d x H%d", width, height);
	Memo1->Lines->Add(msg);
}
//---------------------------------------------------------------------------
```

### 結果

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/ac4f8703-e5d7-9bc7-cd24-207935cad7a8.png)

Monitors[0]の値がおかしくなる条件がある。
上記では二回Button1を押下しているが、二回目の値がおかしい。

## 不具合発生条件

### 1. VMware上での再現

VMware上のWindows 7(や10など)で「モニタを循環」によりモニタ数を1から2に変更した時に発生する。

### 2. マルチモニタでの再現

1つのモニタと接続している状況から2つ目のモニタを接続後に発生する。

### 想定される状況

モニタが故障直後にMonitors[0]のHeight, Widthにおかしな値が入り、それをもとに位置計算する処理がすべて失敗する。

ソフトを起動した状態でモニタを1台から2台に増やす場合も失敗するかもしれない。

コードでは、値がおかしくならないPrimaryMonitor使用を検討すると良いだろうか。
Cognos Analytics 11.0.9 新機能紹介

#概要
Cognos Analytics 11.0.9が2017/12/22にリリースされました。
11.0.8から一ヶ月半の高速リリースになります。

**What’s New in Cognos Analytics Release 9 (11.0.9)**
https://www.ibm.com/communities/analytics/cognos-analytics-blog/whats-new-in-cognos-analytics-release-9-11-0-9/

新機能をまとめましたので、目を通して頂ければと思います。

#地図機能の拡張
11.0.8ではレポートの機能のみで使用できた、地図で緯度・経度が使える拡張が、ダッシュボードにも広がりました。
こんな感じで、ダッシュボードでも緯度・経度指定できます。
![002.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/e35916d2-3bcf-72f0-24fb-ffbd8e5ab030.png)

レポートの地図機能と少しだけ違う点としては、ツールチップに緯度・経度が表示される点です。
ここは将来のバージョンで、レポートの機能でも表示されるようになるようです。
![003.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/fba564f3-33bf-08f4-83a8-6c707141ae91.png)

また、以下のように「緯度/経度」だけでなく、「領域」に対してもデータアイテムを置いて、赤枠のチェックボックスにより、「緯度/経度」セットを表示するか、「領域」セットを表示するか、分けれるようです。
![004.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/ee094e92-efa2-9155-35da-6bfade2f5f2a.png)

**Dashboard Maps Enhancements in Cognos Analytics 11.0.9**
https://www.ibm.com/communities/analytics/cognos-analytics-blog/dashboard-maps-enhancements-in-cognos-analytics-11-0-9/

#Planning Analyticsのサブセットのサポート
データソースとしてPlanning Analyticsを指定した場合に、サブセットがレポートの機能及びダッシュボードで使用可能になりました。※データソースとしてTM1を指定した場合は使用できません。
![005.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/33e93a48-8519-0f7c-cc6d-6582a607913d.png)

サブセットはフィルター領域に配置して、フィルターとして使用する事が可能です。
![006.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/f7bedaa0-624e-62c9-fd8d-9f44b82b61e2.png)

**Cognos Analytics 11.0.9 supports Planning Analytics’ Subsets**
https://www.ibm.com/communities/analytics/cognos-analytics-blog/cognos-analytics-11-0-9-supports-planning-analytics-subsets/

#ダッシュボード機能の拡張
軸ラベルの方向を指定可能になりました。
下記は、「Rotate 45 degree」を選択した表示です。
![007.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/96b74a59-956e-696b-0b9a-672237a1a16e.png)

ダッシュボード参照画面では、このサイドバーが常に細い状態で表示されるようになり、キャンバス部分の広さが最大化されるように考慮されました。
![008.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/aed3ff54-0240-a5c8-030e-07f0d397960b.png)

また、ダッシュボードをフルスクリーン表示可能になりました。
![009.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/1dd9994d-71ce-ee75-8d47-492834321674.png)

フルスクリーン表示のイメージは、文字通りフルスクリーンで、バーの表示も一切ない表示です。
Escキーで戻れます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/147246/e5716480-85f7-4cd3-e340-9855da14054d.png)

**What’s new in Cognos Analytics Dashboards 11.0.9**
https://www.ibm.com/communities/analytics/cognos-analytics-blog/whats-new-in-cognos-analytics-dashboards-11-0-9/