OmniAICreator/Qiita-1.07M huggingface dataset:
chromeでのブレイクポイントのいろいろな設定方法

ここのところchromeを使ったデバッグをする機会が多いので便利なデバッグ方法をご紹介したいと思います。
chromeではさまざまなブレイクポイントの設定方法が用意されており、うまく使うと非常に効率的にデバッグできる場合があります。

# Break on
要素の変更時にブレイクする方法です。

Elementsパネルでブレイクさせたい要素を右クリックして「Break on...」よりブレイクタイミングを選択します。
値の変更時にはブレイクできないのが残念…

|選択肢|ブレイクタイミング|
|:-----:|:----------------:|
|subtree modifications|子要素の変更時|
|attribute modifications|該当要素の属性変更時|
|node removal|要素削除時|

![image.png](https://qiita-image-store.s3.amazonaws.com/0/171118/4118110e-a0e1-d58d-cfda-919f9f5a85fa.png)

# ソースの任意の行
ソースコードの任意の位置にブレイクする方法です。

Sourcesパネルでソースを開いてブレイクさせたい行の行番号をクリックします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/171118/49187886-ecf0-8085-9a88-5a898701473e.png)

## 条件付きブレイク
また、ブレイクの条件を指定することもできます。
ブレイクポイントを右クリックして「Edit breakpoint」を選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/171118/9ddf4a7a-d514-38e4-2899-6023e5560f22.png)

ブレイク条件を設定します。
以上で、条件に一致したときだけブレイクします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/171118/a5b60f11-14a6-253e-5471-3eb806fecc3d.png)

# Pause on exceptions
どこかで例外が発生した時にブレイクする方法です。
どこかしらで例外が発生しているけどどこか分からないときに便利です。

Sourcesパネルの赤丸のボタンを押します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/171118/640c6b86-3802-6b32-a68d-be9f87e5cbd1.png)

# XHR Breakpoints
指定したURLへのAjax通信が発生した時にブレイクする方法です。

SourcesパネルのXHR Breakpointsのアコーディオンを開いて、右クリックまたは右の＋ボタンで任意のURLを設定します。
URLを空で設定するとすべての通信時にブレイクする「Any HXR」が設定されます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/171118/ac844f0c-cacf-4ee0-13e3-37033dab2e08.png)

# Event Listender Breakpoints
どこかでイベントが発生した時にブレイクする方法です。
例えば、どこかの要素でクリックイベントが発生した時などに使用します。

SourcesパネルのEvent Listner Breakpointsのアコーディオンを開くとイベントが分類されて表示されます。
任意のイベントを選択状態にしておくとイベント発生時にブレイクします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/171118/49a2b9d2-fbe1-d558-ed7e-834dbca3dccf.png)

以上のようにchromeではいろいろなタイミングでブレイクできます。
ソース上のどこで発生しているかわからないタイミングで止めたい場合などに今回紹介した方法を使いこなせば非常に効率的にデバッグできると思います。
Slack API | Web API から Slack App 経由で チャンネル履歴を取得する

この例では `channel.history` を参照できる方法を紹介する。

# App の作成

https://api.slack.com/apps から App を作成する

![image](https://qiita-image-store.s3.amazonaws.com/0/89618/df7c3fc5-5c89-c4a6-c61c-519fefb7b467.png)

# App に チャンネルへのアクセス権を付与する


**OAuth & Permissions** > **Permission Scopes** で利用可能なスコープを追加する。

ここでは `Access user’s public channels. ( channels.history )` を選ぶ。

![image](https://qiita-image-store.s3.amazonaws.com/0/89618/e283f79f-b7f0-2804-d21a-9d7c709ef438.png)

# チームに App をインストールする

![image](https://qiita-image-store.s3.amazonaws.com/0/89618/cc60f256-774a-4aa4-bd9f-c2a0d59669e0.png)

![image](https://qiita-image-store.s3.amazonaws.com/0/89618/4e77d6d0-bacc-b5ed-04c7-92f771cd960a.png)

# App用のトークンが発行されるので控えておく

**注意: ここでは例として載せるが、通常はトークンは公開してはいけない**

![image](https://qiita-image-store.s3.amazonaws.com/0/89618/aca1be03-c66a-fb7d-245d-3bbcca863f2b.png)


# Web API でアクセスする

テスターを使うと、簡単に Web API 用のURLが発行できる。

https://api.slack.com/methods/channels.history/test

![image](https://qiita-image-store.s3.amazonaws.com/0/89618/8392c382-8a3e-b9b7-daba-46de41cc5f50.png)


# トークンを変更する

このテスターで生成されるURLは**「あなたのSlackアカウント」**に紐付いているので、Slack Appを通して取得しているわけではない。

なので 発行されたURLのトークンの部分だけを変更する。

## Before

`https://slack.com/api/channels.history?token=[TesterToken]&channel=C18TGD76Z&pretty=1`

## After

`https://slack.com/api/channels.history?token=[SlackAppToken]&channel=C18TGD76Z&pretty=1`

# 結果確認

ブラウザからアクセスして、情報が得られていたら成功だ。

![image](https://qiita-image-store.s3.amazonaws.com/0/89618/5e9b8a1c-2ffc-dad7-6cb8-6e21b6ceb345.png)

# それ本当に App 経由？

不安なら、あなたのSlackユーザー用トークンを再発行してみると良いだろう。(古いトークンは利用不可になる)

( https://api.slack.com/custom-integrations/legacy-tokens )

![image](https://qiita-image-store.s3.amazonaws.com/0/89618/81a8864b-2fa4-01ce-622e-529f6f746473.png)

## Testerで生成したURL

からは、エラーが返るようになる。

![image](https://qiita-image-store.s3.amazonaws.com/0/89618/8d031285-d6c2-069f-f8aa-c9d5b43894f5.png)

## App 経由の URL

は、引き続き利用できることが分かるだろう。

![image](https://qiita-image-store.s3.amazonaws.com/0/89618/5e9b8a1c-2ffc-dad7-6cb8-6e21b6ceb345.png)








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
EclipseでFindbugsプラグインを使う

# 前提条件
- MacOS Sierra 10.12.4 
- Eclipse Neon.2 Release (4.6.2)
- FindBugs Eclipse plugin 3.0.2

# FindBugsとは
ソースを解析して、潜在的な問題（バグ）を探し出してくれる静的解析ツールです。
Eclipse用のプラグインも用意されていて、eclipse上から実行及び実行結果の表示
が可能です。

# 使い方

・対象のプロジェクトを「右クリック」->「Find Bugs」->「Find Bugs」
　でソースの解析が実行されます。

【実行後】
潜在バグがあると判断されたファイル名の右に「(バグ数)」という形で表示がされます。
![スクリーンショット 2017-05-13 22.15.08.png](https://qiita-image-store.s3.amazonaws.com/0/83314/bbabec60-9223-312f-a8bc-c25e31f98ecb.png)

【該当ファイルを開く】
以下のように潜在バグがあると思われる箇所に虫アイコンが表示されている状態になります。
![スクリーンショット 2017-05-13 22.15.16.png](https://qiita-image-store.s3.amazonaws.com/0/83314/9fd983a8-30b6-ee21-3de9-90f6f8a115cd.png)

【虫アイコンをクリック】
Bug Info Viewに以下のような想定されるバグ内容が表示されます。
![スクリーンショット 2017-05-14 15.48.20.png](https://qiita-image-store.s3.amazonaws.com/0/83314/2b3c6b88-e5cc-d798-5fe6-536dc386131e.png)

# その他
プロジェクト単位の設定で「FindBugsを自動的に実行する」にチェックを入れておくとビルドされるタイミングで自動的に解析が実行されて、潜在バグを早期に退治することが可能です。
javascriptでobjectの中の配列を展開する書き方

書き方としては単純だったが、objectを展開するということで「for…in」を使わないとけないと思い、試行錯誤したので投稿します。

## objectの中身

配列になっています。

``` javascript:javascript
const obj = {
  name: [
    'name1',
    'name2',
  ],
  age: [
    'age1',
    'age2',
  ]
}
```

## 配列の取得方法

``` javascript:javascript
if (obj.name) {
  for (let i = 0; i < obj.name.length; i++) {
    console.log(obj.name[i]);
    console.log(obj.age[i]);
  }
}

/*
結果
"name1"
"age1"
"name2"
"age2"
*/
```

## 間違った書き方

始めobjectを展開するということで「for…in」を使わないといけないかと思ったが、そうすると2回繰り返される

``` javascript:javascript
for (let prop in obj) {
  if (obj.hasOwnProperty(prop)) {
    for (let i = 0; i < obj[prop].length; i++) {
      console.log(obj.name[i]);
      console.log(obj.age[i]);
    }
  }
}

/*
結果
"name1"
"age1"
"name2"
"age2"
"name1"
"age1"
"name2"
"age2"
*/
```
Cloud9上でクローラーを作るための環境構築

##概要
Cloud9上にクローラーを作る環境を構築しました。
作った環境は以下の通りです。
（2017/9/26時点）

 - Ubuntu 14.04（OSはCloud9で設定されます）
 - Python 3.5.2
 - Scrapy 1.3.3
 - Selenium 3.4.1
 - beautifulsoup 4.6.0
 - lxml 3.7.3
 - phantomjs 2.1.7

やったことを簡単に以下に記載します。

 - Cloud9のアカウント登録
 - Pythonのバージョンアップ
 - Scrapyインストール
 - Seleniumインストール
 - Beautiful Soupインストール
 - phantomjsインストール

##Cloud9のアカウント登録
詳しく解説しているサイトがあるので省略。
Workspaceを「Blank」で作ると、Python3系のバージョンが「3.4」だったので、
「Blank」ではなく「Python」としました。

##Pythonのバージョンアップ
まずはPythonのバージョンを2.7から3.5.2にします。
バージョンアップについては以下の記事を参考にしました。

https://teratail.com/questions/32152

若干、手順と違ったのは、権限関係で「sudo」つけないといけないくらいです。
「/usr/bin/」配下のファイルを見ると、Python3.6はないみたいですね。
（Cloud9の環境がUbuntu14.04なんだけど、Python3.6に対応してないのかな。）

##Scrapyのインストール
ここでハマりました。ハマることなんてないと思っていたので誤算でした。
pipでscrapyをインストールしようとすると正常に完了しませんでした。
その後、pipが壊れてしまい、pipコマンドを打つと以下のようなエラーが出るようになってしまいました。

```
Traceback (most recent call last):
  File "/usr/bin/pip", line 5, in <module>
    from pkg_resources import load_entry_point
  File "/usr/local/lib/python3.5/dist-packages/pkg_resources/__init__.py", line 72, in <module>
    import packaging.requirements
  File "/usr/local/lib/python3.5/dist-packages/packaging/requirements.py", line 59, in <module>
    MARKER_EXPR = originalTextFor(MARKER_EXPR())("marker")
TypeError: __call__() missing 1 required positional argument: 'name'
```
2個目のエラーの原因が「appdirsがないよ」ということだったので、
Scrapyのインストール前に「appdirs」をインストールしておきました。
なぜかそれだけでもダメで、事前に「lxml」も入れておくとうまくいきました。

```
$ sudo pip install appdirs
$ sudo pip install lxml
$ sudo pip install scrapy
```
上記の順番でコマンド打てば無事にインストールできました。

インストール済のパッケージをチェックしましたが、「appdirs」「lxml」しか増えなかったので、これらが影響してたと思います。
pipよりanacondaをオススメしている記事を見かけるので、anacondaについても調べておこうと思います。

##Seleniumのインストール

```
$ sudo pip install selenium
```
ちゃんとインストールされたか確認。

```
$ pip show selenium
```

上記のコマンドを打つと、以下のようになります。
ちゃんとpython3.5配下にインストールされているのでOK。

```
---
Name: selenium
Version: 3.4.1
Location: /usr/local/lib/python3.5/dist-packages
Requires: 
```

##Beautiful Soupのインストール

```
$ sudo pip install beautifulsoup4
```

こちらも同様に以下のコマンドを打ちます。

```
$ pip show beautifulsoup4
```

すると、

```
---
Name: beautifulsoup4
Version: 4.6.0
Location: /usr/local/lib/python3.5/dist-packages
Requires:
```

となり問題ないことが確認できました。


##phantomjsのインストール

```
$ sudo npm install -g phantomjs
```



以上
[golang]FCMの単一端末に通知を送る

手元で動かしただけなので特にGAEとかで検証はしてない。

```go
package main

import (
	"bytes"
	"encoding/json"
	"net/http"
)

func main() {
	PostToFCM(
		"##FIRInstanceID.instanceID().token()##",
		"hello",
	)
}

type FCMParams struct {
	To           string          `json:"to"`
	Notification FCMNotification `json:"notification"`
	Priority     int             `json:"priority"`
}
type FCMNotification struct {
	Body string `json:"body"`
}

func PostToFCM(to string, body string) error {
	n := FCMNotification{
		Body: body,
	}
	params := &FCMParams{
		To:           to,
		Notification: n,
		Priority:     10,
	}
	b, err := json.Marshal(params)
	jsonStr := string(b)

	req, err := http.NewRequest(
		"POST",
		"https://fcm.googleapis.com/fcm/send",
		bytes.NewBuffer([]byte(jsonStr)),
	)
	if err != nil {
		return err
	}

	// Content-Type 設定
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Authorization", "key=##FCMのサーバーキー##")

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	return err
}

```

とりまこんな感じ。
JavaScript全置換(正規表現使わない)の速度比較

2017年05月15日 記入

## プログラミングのテクニックサイトで全置換は正規表現とか書かないで欲しい

> JavaScriptのreplaceは、先頭文字だけしか置換でないので、全置換のやり方は、`replace(/文字/g)`みたいに、正規表現をつかいます。

というようにかかれている場合があります。[JavaScript 全置換]とかで検索すると多く出てくるので、ため息まじりになります。

プログラミングのテクニックとしてそれはよくないです。文字列置換と正規表現による一致をみて置換するのとは処理が違います。

正規表現はプログラミングでは複雑さがまし、また可読性も低いのであまり使わないようにしています。ただ、正規表現を使うようが望ましくなる場面では使います。使い所を選ぶプログラミングの機能です。

そして、単なる文字列置換に正規表現を使うのは実に望ましくありません。置換元の文字に正規表現が含まれていたら、困るでしょう。

例えば、「\*.co.jp」という文字列を「*.com」に純粋な文字として置換したいときに、正規表現文字列置換では簡単ではなくなるので応用が効かなくなるのでよくないのです。

## 全置換は、こんなコードがいいのかな

ということで、自分は次のようなコードを書いていました。

```JavaScript
  var replaceAll1 = function(str, before, after) {
    var result = str
    do {
      str = result;
      result = str.replace(before, after);
    } while (str !== result);
      return result;
  };
```

これは、replaceを文字が変換されなくなるまで繰り返すという実装です。行数はほどほど必要ですがロジックとしてはシンプルです。

正規表現置換の`replace(/文字/g)`よりは行数が必要ですが、関数の中身はカプセル化されているから数行程度の行数が増えてもよいのです。

## こっちのコードの方がいいのかな

ですが、正規表現とともによく掲載されているのは次のコードでした。

```JavaScript
  var replaceAll2 = function(str, before, after) {
    return str.split(before).join(after);
  };
```

え....splitしてjoinするんだ...

ということで、replaceAll1の方が順当と思ったんですが、replaceAll2も、いいのかな、どちらもいいけど、ロジック的にシンプルなreplaceApp1の方が速いんじゃないの。と思い、ベンチマークをとることにしました。

## HTML上でベンチマーク

ベンチマークのとり方は、こちらを参考にさせていただきました。
[JavaScript：処理時間計測方法 | 覚え書き.com](http://write-remember.com/program/javascript/console_time/)

```html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <script>

  var replaceAll1 = function(str, before, after) {
    var result = str
    do {
      str = result;
      result = str.replace(before, after);
    } while (str !== result);
      return result;
  };

  var replaceAll2 = function(str, before, after) {
    return str.split(before).join(after);
  };

var benchMark = function (replaceAll) {
  var startTime = new Date();

    for (var i = 1; i <= 10000; i++) {
      var result = replaceAll(
        new Array(10).join('abc123abc123abc'), 'abc', '123');
      if (result !== new Array(10).join('123123123123123')) {
        alert('error');
        break;
      }
    }

  var endTime = new Date();
  return endTime - startTime;
};

//startTime から endTime までの処理時間をミリ秒で出力。
alert(benchMark(replaceAll1) + "ms");
alert(benchMark(replaceAll2) + "ms");

    </script>
  </head>
  <body>
    <!-- page content -->
  </body>
</html>
```
これで測ると、圧倒的にreplaceAll2が速かったです。
実行速度にぶれはあるので掲載しませんが、確実に速いです。
やりたい人は、ループ数をご自分でいろいろ変えてみてください。

環境はChromeです。

そういうもんなんですね....知らなかった。

シンプルかつ、高速なのは、 split して join ですね。

ということで、
replaceAll2の書き方をおすすめします。

現場からは以上です。

## 追記 2021年07月15日 String.prototype.replaceAll

現在は主要なブラウザは次のメソッドが存在しているのでそちらを使うのがよいでしょう。

String.prototype.replaceAll() - JavaScript | MDN
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/replaceAll
pyenvのメモ

## pyenvのインストール

pyenvのインストール方法:

```
$ brew install pyenv
```

`.bashrc`に次を追記

```
export PYENV_ROOT=$HOME/.pyenv
export PATH=$PYENV_ROOT/bin:$PATH
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
```

Virtualenvのプラグインもインストールしておく:

```
$ brew install pyenv-virtualenv
```

## バージョンの確認

インストール可能なバージョンの一覧

```
$ pyenv install --list
Available versions:
  2.1.3
  2.2.3
  2.3.7
  2.4
  ...
```

標準的なPythonだけじゃなくて anacondaとかpypyとかもインストールできる.

インストールしてあるバージョンの一覧

```
$ pyenv versions
  system
  2.7.13
  3.6.1
* anaconda2-4.3.1 (set by /Users/yassu/.pyenv/version)
* anaconda3-4.3.1 (set by /Users/yassu/.pyenv/version)
```

最初はsystemだけがあって, systemがチェックされているはず.

## 新しいPythonのインストール

```
pyenv install {version}
```
この `{version}` は `pyenv install --list` で取得できるバージョン.

例えば, 最新のpythonのバージョンは3.6.1なので, これをインストールするには

```
$ pyenv install 3.6.1
```

## 環境の設定

グローバルな, pythonコマンドのバージョンを変更するには

```
$ pyenv global {version1} [version2]
```

`version2` を指定しなければ, 常にバージョンは`{version1}'で固定される.

`version2` を指定すれば, `python` コマンドでは `{version1}` が使用される.
`python{n}` コマンドでは それぞれに対応したバージョンが使用される.

例えば, `pyenv global 3.6.1 2.7.13` とすると, `python` コマンドでは バージョン
 3.6.1が使われるが, `python2` コマンドでバージョン `2.7.13` を使用することができる.

任意のディレクトリ以下でpythonのバージョンを指定するには そのディレクトリに移動してから

```
$ pyenv local {version}
```

`pyenv global` と同様に２つのバージョンを使用することもできる.

一時的にバージョンを指定する:

```
$ pyenv shell {version}
```

## 環境の作成

```
$ pyenv local {base-version} {version}
```

で, `{base-version}` をコピーして `{version}` を複製する.
pythonでgoの埋め込み(embedded)を模倣するときにやってること

## はじめに

pythonでgoの埋め込みを模倣するときにやってること、というか継承より委譲と言うやつです。

## 継承が辛いという話

継承が辛いという理由の１つは呼ばれたメソッドがどれによるものかがわからなくなる点です。

例えば、以下のような継承関係のあるCについて

```py
class A:
    def f(self):
        return "f"

    def g(self):
        return "g"


class B:
    def h(self):
        return "h"

    def i(self):
        return "i"


class C(A, B):
    def m(self):
        return (self.f(), self.i())
```

`C#m()` の処理の挙動を把握するのが面倒です。もちろん通常はもうすこし名前にこだわりを持つとは思うので、ここまでひどくはならないと思いますが。

一方で委譲になっている場合はまだマシです。

```py
class C:
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def m(self):
        return (self.a.f(), self.b.i())
```

内部的に抱えているインスタンス変数のどのメソッドがよばれているか明示されることになるからです。

## goの埋め込み

ここでgoの埋め込みです。これは委譲を半ば自動的にやってくれる機能と見る事もできます。

```go
type Reader interface {
    Read(p []byte) (n int, err error)
}

type Writer interface {
    Write(p []byte) (n int, err error)
}

type ReadWriter interface {
    Reader
    Writer
}
```

ReadeWriterはReaderとWriterの機能を持っていますが。実質的には内部に持っている値に委譲してあげているだけです。上の例はinterfaceの例でしたがstructの方でも同様です。

```go
type ReadWriter struct {
    *Reader  // *bufio.Reader
    *Writer  // *bufio.Writer
}
```

ここで `var rw *ReadWriter` となるような変数rwに対して、 `rw.Read()` などやると、 `rw.Reader.Read()` などが呼ばれます。

## pythonで埋め込みの模倣

pythonに戻ります。はじめの例で継承より委譲の方が良いということを言っていましたが。とは言え完全に委譲で解決したわけではありません。AやBのメソッドをCから直接呼び出したい場合があります。また、Cを使う箇所で直接 `c.a.f()` などのようにしてしまうと実質利用できる値がCのインスタンスに固定されてしまいます。

そんなわけで、`c.f()` と呼び出しつつも内部的には `c.a.f()` が呼ばれて欲しいということが起きます。とは言え、都度都度必要なメソッドの呼び出しを明示的に書くのは辛いです。自動でやってくれたらうれしいですね。つまりgoの埋め込みの模倣です。

ここからが本題なのですが、pythonでgoの埋め込みを模倣したい場合には、個人的には以下の様にしています。

```py
class C:
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def m(self):
        return (self.a.f(), self.b.i())

    def __getattr__(self, name):
        return getattr(self.a, name)
```

これで、 `c.f` が自動的に `c.a.f` になります。これは完全にgoの埋め込みを模倣しているわけではないですし。存在しない属性が指定された場合に全てself.aに委譲されてしまいます。メタプログラミングなどを使えばもう少し明示的にあるいはもっと限定的にできるようになりますが。今のところはこれで十分だと思っています。

### 複数の継承元が存在する場合について

元々の例では複数の継承元が存在していました。先程の例では継承元が1つの場合にしか対応できていません。複数の場合についても対応して見ることにしましょう。注意点はgetattrの使い方です。getattrの第３引数にdefault値を指定する事ができますが。Noneではなく何らかの特殊な値を返してあげるようにしましょう。もし仮にNoneが設定されていた場合にも次の探索先を探してしまうからです(逆にNoneがあったら別の候補を探すということにしたいならそうやっても良いのですが。挙動を把握するのが難しくなるのでオススメはしません)。

```py
missing = object()


class C:
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def m(self):
        return (self.a.f(), self.b.i())

    def __getattr__(self, name):
        v = getattr(self.a, name, missing)
        if v is not missing:
            return v
        return getattr(self.b, name)
```

これで `c.i()` で `c.b.i()` を、 `c.f()` で `c.a.f()` が呼ばれる様になります。

### ところで

ところで元々の例ではA,Bを複数継承した値を最後の例では複数の移譲先に対応する例を書きましたが。実際のコードではこのように複数の移譲先に対する暗黙的な移譲を行うことはオススメしません。パット見て挙動を把握するのが難しくなるからです。なのでなるべく移譲先は一つだけに限定するというようにしたほうが良いです。
Bash on Ubuntu on WindowsでSingle-cell RNA sequence解析　⑤番外編：コードのブラッシュアップ

#※記事を読んでくださるみなさまへ
・対象は**プログラミングもバイオインフォ解析も全く未経験のバイオ研究者**です
・筆者は基礎研究を初めて約1年3ヶ月の大学院生です
・いわゆる”DRY”な研究を始めたのは約5ヶ月前からです
・そのため記事の内容にはとんでもない間違いやずっと良い別の方法が存在するかもしれません
・また、筆者と同じレベルの人が0から始めるときの参考になるよう、説明は結構まだるっこいです
・ご指摘の度に記事をブラッシュアップしていきたいです、よろしくお願いします

過去記事一覧
[①環境構築まで](http://qiita.com/rouninnomi/items/d92d9fb65d52ed4353e4)
[②NGSデータのダウンロードとクオリティチェック](http://qiita.com/rouninnomi/items/88a24ad1eb454e78e99d)
[③NGSデータのトリミング](http://qiita.com/rouninnomi/items/9244e54785ab58b0f114)
[④Pipeline (hisat2, samtools, stringtie)](http://qiita.com/rouninnomi/items/5441bef2f50780035127)
[⑤番外編：コードのブラッシュアップ](http://qiita.com/rouninnomi/items/f8328ece9388b7870138)
[⑥Rによる発現解析](http://qiita.com/rouninnomi/items/439bdced092cffbc3c36)

#コードのブラッシュアップ
シェルスクリプトの勉強を進めた結果、今までの処理をもう少し自動化、簡略化できることがわかったため、今回の番外編で追記します。for文というのを利用するとよさそうです。その他前回からの変更点としては、

・出力結果のファイルを準備して、そこに書き込まれるようにした
・一つのfastqファイルをgtfファイルまで連続的に処理し、必要無くなったファイルを自動削除、ハードディスクの容量がsamファイルなどで埋め尽くされないようにした

という感じです。改行処理によりうまくいかない場合は\（環境によっては¥）を削除して一行にしてください。do, doneのところは改行をいじらないでください。

```
for f in *.fastq.gz
do 
java -jar ~/miniconda2/share/trimmomatic-0.36-3/trimmomatic.jar SE\
 -threads 8 ${f} ${f/.fastq.gz/_trimmed.fastq.gz}\
 ILLUMINACLIP:NexteraPE-PE.fa:2:30:10 LEADING:3 TRAILING:3\
 SLIDINGWINDOW:4:15 MINLEN:36 >>result.txt\
 && fastqc ${f/.fastq.gz/_trimmed.fastq.gz} >>result.txt\
 && hisat2 -p 8 --dta -x (indexファイルのパス)/(.ht2の頭部分)\
 -U (fastqファイルのパス)/${f/.fastq.gz/_trimmed.fastq.gz}\
 -S ${f/.fastq.gz/.sam} >>result.txt\
 && samtools sort -@ 8 -o ${f/.fastq.gz/.bam}\
 ${f/.fastq.gz/.sam} >>result.txt\
 && stringtie -p 8 -G (referenceファイルのパス)/(reference.gtf)\
 -o ${f/.fastq.gz/.gtf} -l ${f/.fastq.gz/}\
 ${f/.fastq.gz/.bam} >>result.txt\
 && rm ${f}  ${f/.fastq.gz/_trimmed.fastq.gz} ${f/.fastq.gz/.sam}
done
```
ごちゃごちゃしていてわかりにくいですが、実は簡単です。for文は

```
for (変数を示すアルファベット:f,x,iなど) in (変数一覧：直接記載、'ls'、*.fastqなど)
do
(コマンド) (引数)
done

ただし、引数の中身で変数が登場するところを${f}のように記載。
変数の拡張子や名称の一部を変更したいとき${f/(変えたい部分)/(変えたいパーツ)}のようにする。
```
というふうな感じで、全ての候補に対して処理を行うことができます。また、&&という記号は、

```
(コード１) && (コード２) && ...
```
というふうに無限に処理をつなげて連続させることができます。また、>>は

```
(コード) >>〇〇.txt
```
でコードの出力内容をテキストファイルに追記保存していくことができます。>なら上書き保存です。

```
\
```
を入れると右隣の文字から改行をして見やすくすることができます。幾つかテストしてみたのですが、&&のような意味をもつ記号に接触する形では使わないほうが良さそうです。mkd\irみたいなのはいけます。

マージ以下は[前回](http://qiita.com/rouninnomi/items/5441bef2f50780035127)までと同様に処理してください。以上で番外編終了です。

（5/16追記）
どうやら今回の環境では&&をつけなくても、改行しておけば連続してコードが実行されるようです。

```
for f in *.fastq.gz
do 
java -jar ~/miniconda2/share/trimmomatic-0.36-3/trimmomatic.jar SE -threads 8 ${f} ${f/.fastq.gz/_trimmed.fastq.gz} ILLUMINACLIP:NexteraPE-PE.fa:2:30:10 LEADING:3 TRAILING:3 SLIDINGWINDOW:4:15 MINLEN:36 >>result.txt
fastqc ${f/.fastq.gz/_trimmed.fastq.gz} >>result.txt
hisat2 -p 8 --dta -x (indexファイルのパス)/(.ht2の頭部分) -U (fastqファイルのパス)/${f/.fastq.gz/_trimmed.fastq.gz} -S ${f/.fastq.gz/.sam} >>result.txt
samtools sort -@ 8 -o ${f/.fastq.gz/.bam} ${f/.fastq.gz/.sam} >>result.txt
stringtie -p 8 -G (referenceファイルのパス)/(reference.gtf) -o ${f/.fastq.gz/.gtf} -l ${f/.fastq.gz/} ${f/.fastq.gz/.bam} >>result.txt
rm ${f}  ${f/.fastq.gz/_trimmed.fastq.gz} ${f/.fastq.gz/.sam}
done
```
rippleの入金確認手順


# 準備

事前に20xrp入金してアクティベートを済ませたリップルアドレス(address)を用意
入金の確認に秘密鍵は必要なし

リップルアドレスの入金を開始する台帳番号を取得して保存する(since_ledger)

```
const since_ledger = await api.getAccountInfo(address).then(res => res.previousAffectingTransactionLedgerVersion)
```

# 手順

* 現在の最新台帳番号を取得する（current_ledger）

```
const current_ledger = await api.getLedger().then(res => res.ledgerVersion)
```

* DBのトランザクションを開始する
* DBをロックする
* DBから入金を開始する台帳番号を取得する(since_ledger)

* 台帳番号で範囲を指定してアドレスからトランザクション一覧を取得する

```
const transactions = await api.getTransactions(address, {
  minLedgerVersion:since_ledger,
  maxLedgerVersion:current_ledger,
})
```

* トランザクションがリストで取得できるのでチェックして入金処理を行う（destination_tagやpartialpaymentあたり）

* 現在の台帳番号を次の入金開始する台帳番号(since_ledger)としてDBに保存する

* DBのトランザクションをコミットする



# 関連事項

* [destination tagとは](http://qiita.com/you21979@github/items/63d554dfd5a589e27624)
* [partial paymentとは](http://qiita.com/you21979@github/items/176db26559ab32205079)
Node.js で Twitter をサーチ

あるユーザーのタイムラインを取得します。

必要なライブラリーのインストール

```bash
sudo npm install -g twitter
```

```js:twitter_search.js
#! /usr/bin/node
//
//	twitter_search.js
//
//						Apr/26/2019
//
//  npm install twitter
//
// ---------------------------------------------------------------
console.error ("*** 開始 ***")
var Twitter = require('twitter')
const dotenv = require('dotenv')

dotenv.config()

var client = new Twitter({
	consumer_key: `${process.env.CONSUMER_KEY}`,
	consumer_secret: `${process.env.CONSUMER_SECRET}`,
	access_token_key: `${process.env.ACCESS_TOKEN}`,
	access_token_secret: `${process.env.ACCESS_TOKEN_SECRET}`
})

var params = {screen_name: '@ekzemplaro',count: 5}
client.get('statuses/user_timeline', params, function(error, tweets, response)
	{
	if (!error) {
		console.log(tweets)
		for (var it in tweets)
			{
			const tweet = tweets[it]
			console.log (tweet.created_at)
			console.log (tweet.text)
			}
	}
	else
		{
		console.log(error)
		}
})

console.error ("*** 終了 ***")
// ---------------------------------------------------------------
```

```text:.env
CONSUMER_KEY = '******'
CONSUMER_SECRET = '******'
ACCESS_TOKEN = '******'
ACCESS_TOKEN_SECRET = '******'
```

実行方法

```bash
export NODE_PATH=/usr/lib/node_modules
./twitter_search.js > out01.txt
```

次の環境で動作を確認しました。

```text
$ uname -a
Linux iwata 5.6.13-arch1-1 #1 SMP PREEMPT Thu, 14 May 2020 06:52:53 +0000 x86_64 GNU/Linux

$ node --version
v14.3.0
```
インストール直後のCentOS7(ゲストOS)を最短の手順でネットワーク接続する

##環境
- CentOS7
- OSインストール時にネットワーク設定をしていない状態
- ゲストマシン

##手順

nmcli deviceコマンドでインターフェースを確認。

```
# nmcli device
[root@localhost ~]# nmcli device
DEVICE  TYPE      STATE         CONNECTION         
eth0    ethernet  disconnected  --                 
lo      loopback  unmanaged     -
```

nmcli connection コマンドでインターフェースをネットワークに接続する。

```
[root@localhost ~]# nmcli connection up eth0
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/1)
[root@localhost ~]# nmcli device
```

成功すれば、インターフェースの状態がconnectedに。

```
[root@localhost ~]# nmcli device
DEVICE  TYPE      STATE      CONNECTION 
eth0    ethernet  connected  eth0       
lo      loopback  unmanaged  --         
```

pingで通信を確認。

```
[root@localhost ~]# ping google.com
PING google.com (216.58.220.238) 56(84) bytes of data.
64 bytes from nrt13s37-in-f14.1e100.net (216.58.220.238): icmp_seq=1 ttl=53 time=101 ms
64 bytes from nrt13s37-in-f14.1e100.net (216.58.220.238): icmp_seq=2 ttl=53 time=21.7 ms
64 bytes from nrt13s37-in-f14.1e100.net (216.58.220.238): icmp_seq=3 ttl=53 time=44.4 ms
^C
--- google.com ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 21.740/56.003/101.828/33.702 ms
```
スプレッドシートのセル指定リンクの作成方法

## 概要
スプレッドシートを頻繁に利用する方は、他の方に入力をお願いするときにリンクとセル番号を伝えていると思います。

入力する側は指定されたセルに移動するのが手間です。
そんなときにリンクをクリックしただけで飛べると便利ではないですか？

最近スプレッドシートにセル指定リンクが追加されました。
この記事はセル指定リンクについて説明します。

## セル指定リンク取得
スプレッドシートでセル指定リンクを作成したいセルで右クリックしてリンクを取得します。


1. リンクを作成したいセルにカーソルを合わせる
2. 右クリックをする
3. このセルへのリンクを取得
4. 表示されるリンクをコピー

コピーしたリンクの末尾に``&range=C5``とパラメータが付与されました。
``range``パラメータを指定することでセル指定リンクを作成することができます。

## パラメータ一覧
セル指定以外にも行指定、列指定、範囲指定のリンクを作成できます。
スプレッドシートの末尾にパラメータを付けるかセルを選択して右クリックで作成できます。

|用途|パラメータ|
|:--|:--|
|セル指定|&range=C5|
|範囲指定|range=C2:D7|
|列指定|range=C:C|
|行指定|range=7:7|
任意のカラムの配列を取得する　pluckメソッド

##指定したカラムの配列を取得したい場合
　
**pluckメソッド**
**引数にカラム名を指定すると、そのカラムの値が配列で返してくれる**　

```
user.pluck(:name)
#=> ["satoshi", "kei", "yumi"]
```

またRails4からは、複数のカラムの指定もできる

```
user.pluck(:id, :name)
#=> [[1, "satoshi"], [2, "kei"], [3, "yumi"]]
```

　
ActiveRecordのオブジェクトの生成コストは大きい。
pluckメソッドはActiveRecordオブジェクトを生成せず要素を返すため動作が早い。
DBから値を取ってくる時はmapよりpluckの方がおすすめ。

##参考サイト
[Railsドキュメント](http://railsdoc.com/references/pluck)
c++ メモリ使われ方 簡易メモ

#自作GC作るぞー
という事でちょろっと書いたプログラムでメモリの使われ方を検証メモ

#使用クラスの解説

- GCはガベージコレクション(になる予定 現在は適当なサイズのメモリを確保してそこからGC_OBJにメモリを割り当てるだけ)
- GC_OBJはint[12]を持ちnew,deleteをオーバーライド 確保したメモリサイズを出力
- GC_OBJ_EXはGC_OBJを継承し、int[12]を持つ
- GC_OBJ_EX2はGC_OBJ_EXを継承し、int[12]を持つ


GC_OBJのデストラクタはvirtualを付ける つけない場合継承したクラスのdelete時に渡されるsizeが基底クラスのサイズで渡されるためうまく解放されない(ガベージコレクションによるメモリ開放処理だと継承先がポインタで何か指していた場合メモリリークが起きる?(未検証))

#以下コード

```ruby:main.cpp
//メモリ確保 メモリ開放をするテストアプリ 確保したメモリサイズを表示
//本来メモリ開放部分はガベージコレクションが行うようにするがテスト段階なので
int main() {
	srand(time(NULL));
    //ガベージコレクション用メモリ確保
	GC::GetInstance()->SetMemorySize(1024 * 1024 * 8);
    //ガベージコレクションからメモリを確保
	GC_OBJ* hoge = new GC_OBJ();
	GC_OBJ* piyo = new GC_OBJ_EX();
	GC_OBJ* foo = new GC_OBJ_EX2();
    //ガベージコレクションからメモリを確保
	GC_OBJ* hogeArr = new GC_OBJ[2]();
	GC_OBJ* piyoArr = new GC_OBJ_EX[2]();
	GC_OBJ* fooArr = new GC_OBJ_EX2[2]();
    //メモリ開放 この処理は本来ガベージコレクションにやらせるが未実装のため
	delete hoge;
	delete piyo;
	delete foo;
    //メモリ開放 この処理は本来ガベージコレクションにやらせるが未実装のため
	delete[] hogeArr;
	delete[] piyoArr;
	delete[] fooArr;

	return 0;
}
```

#出力結果

GC_OBJ52byte確保
GC_OBJ100byte確保
GC_OBJ148byte確保
GC_OBJ108byte確保
GC_OBJ204byte確保
GC_OBJ300byte確保
GC_OBJ52byte開放
GC_OBJ100byte開放
GC_OBJ148byte開放
GC_OBJ108byte開放
GC_OBJ204byte開放
GC_OBJ300byte開放

##GC_OBJのデストラクタにvirtualがない場合

GC_OBJ48byte確保
GC_OBJ96byte確保
GC_OBJ144byte確保
GC_OBJ100byte確保
GC_OBJ196byte確保
GC_OBJ292byte確保
GC_OBJ48byte開放
GC_OBJ48byte開放
GC_OBJ48byte開放
GC_OBJ100byte開放
GC_OBJ100byte開放
GC_OBJ100byte開放

#結果からの考察

デストラクタをvirtualにすることで現在どのクラスであるかを記憶する領域が4byte
配列情報を記憶する領域が4byte確保されてるっぽい

GC_OBJのデストラクタにvirtualがない場合開放時すべてGC_OBJであると解釈される

以上車輪の再発明のためのメモでした

#参考
これだけ読めば全部がわかるC++のoperator new/deleteオーバーロードの注意点
http://cflat-inc.hatenablog.com/entry/2014/01/28/214820
GCアルゴリズム詳細解説
http://seesaawiki.jp/w/author_nari/
Gitでの作業手順

Gitで作業履歴を記録する際に、自分がやっている手順をまとめました。

## 前提
~~変更内容は、GUIツール（SourceTree）で確認してからコマンドを叩いています（GUIの方が差分が見やすいため）。~~
git diffで確認するようになりました。

## 通常フロー

|手順|コマンド|ステータス（更新ファイルの場所）|なぜそれをするのか|
|:---|:---|:---|:---|
|作業ブランチ確認|git branch|-|正しいブランチで作業をするため。特にブランチを新規に作成する場合、元となるブランチを間違えると後々面倒になる。|
|（必要に応じて）ブランチ切り替え|git checkout (-b) [ブランチ名]|-|上に同じ。|
|（必要に応じて）リモートから取得|git pull origin|-|他の人の変更をローカルリポジトリに取り込み、競合を防ぐため。|
|ファイル編集（追加、削除含む）|-|作業ディレクトリ|-|
|ファイルステータス確認|git status|作業ディレクトリ|変更したファイル名を確認するため。カレントブランチも確認できる。|
|変更点確認|git diff|作業ディレクトリ|変更した内容を確認するため。間違って不要な箇所を変更していないか、など。|
|コミットにまとめたいファイルをステージングエリアへ|git add [ファイル名/ディレクトリ名/--all/-A]|ステージングエリア|コミットの対象にするものとしないものとを分けるため。|
|ファイルステータス確認|git status|ステージングエリア|ファイルが過不足なくコミットの対象になっているかを確認するため。|
|コミット|git commit -m "[コミットコメント]"|Gitディレクトリ|変更を履歴に残すため。|
|コミット確認|git log --oneline|-|コミットログを確認。コメントが間違っていないかなど。間違っていたら、git commit --amendやgit resetでやり直せる（今なら）。|
|リモートにプッシュ|git push origin [ブランチ名]|-|他の人が変更を取り込めるようにするため。|

* add, commit, pushで、ステータスが切り替わる。



### マージについて
ローカルとリモートのどちらでマージするかによって、手順が変わる。

#### A) ローカルでマージをする場合
1. プッシュする前にマージ先のブランチに移動（=git checkout [ブランチ名]）。
2. 取り込みたいブランチをマージする（=git merge [取り込みたいブランチ名]）。
3. マージ先、マージ元両方のブランチをプッシュする（=git push origin [ブランチ名]）。

#### B) リモートでマージする場合
1. 変更したブランチをプッシュ後、リモートでマージしたいブランチに対してプルリクエストを作成する。
2. リモートでマージする。
3. ローカルでマージ先のブランチに切り替え（=git checkout [ブランチ名]）、プルする（=git pull）。

### コンフリクトの解決について
どちらかのファイルを正とする場合（ファイル内の差分を見て１つずつ反映させる必要がない場合）は、以下のコマンドで対応できる。
git checkout --theirs [fileName] ・・・ 相手のブランチ（マージした側）を正とする
git checkout --ours [fileName] ・・・ 自分のブランチ（マージされた側）を正とする


## やり直したい場合

|目的|コマンド|どうなるか|意味|
|:---|:---|:---|:---|
|マージ、プルをなかったことにしたい|git reset --hard ORIG_HEAD|マージ前の状態に戻る|git merge, git pullの取り消し|
|特定のファイルの修正を取りやめたい|git checkout [ファイル名]|指定ファイルだけ最後のコミットの状態に戻る|変更内容の破棄|
|すべてのファイルの修正を取りやめたい|git reset --hard HEAD|最後のコミットの状態に戻る|変更内容の破棄|
|新規に追加したファイルを削除したい|git clean -f|削除される|追跡対象外のファイルの削除|
|特定のファイルを特定のコミットの状態に戻したい|git checkout [コミットID] [ファイル名]|指定ファイルだけ指定したコミットの状態に戻る|ファイルの置き換え|
|すべてのファイルを特定のコミットの状態に戻したい|git checkout [コミットID]|指定したコミットの状態に戻る|ファイルの置き換え|
|ステージ済みファイルを戻したい|git reset HEAD|変更内容が作業ディレクトリに戻る|git addの取り消し|
|コミットをなかったことにしたい（変更内容は残す）|git reset HEAD^|コミットがなくなる、変更内容は作業ディレクトリに残る|git commitの取り消し|
|コミットをなかったことにしたい（変更内容も破棄する）|git reset --hard HEAD^|1つ前のコミットの状態に戻る|git commitの取り消し、変更内容の破棄|
|コミットの内容を変更したい|変更したい内容をgit add して、git commit --amend|直前のコミットに変更内容が追加される|git commitの変更|
|コミットコメントを変更したい|git commit --amend "コミットコメント"|直前のコミットコメントが変更される|git commitの変更|
|プッシュをなかったことにしたい|git revert [打ち消したいコミットID], git push origin [ブランチ名]|指定したコミットを打ち消す内容のコミットが作成され、リモートに反映される|git commitの打ち消し|
|ブランチを削除したい|git branch -d(-D) [ブランチ名]|ブランチがなくなる|git branchの取り消し|

* git reset＝**HEADの位置を指定したコミットに移動させる**ことで、変更をなかったことにできる
* Windowsのコマンドラインでは、```git reset HEAD^```が認識されない。```git reset "HEAD^"```のように、HEAD^をダブルクォーテーションで囲うと認識される。
* pushの取り消しは、**resetで履歴を消すのではなく、revertで打ち消した履歴を残す**方が推奨されている。一人プロジェクトの場合は、```git reset --hard HEAD^```で取り消した内容を、```git push -f origin [ブランチ名]```で強制的にpushする方法もある。
* 上記例では、1つ前のコミットに戻すことを想定し、HEAD^と指定している。状況に応じて、コミットIDを指定したり、HEAD^^（2つ前のコミット）といった指定が必要。
goでhttp clientを利用したrequest数をカウント(transportとcontextを使ってごまかす)

## はじめに

特定のバッチの特定の区間で行われるreuest数をカウントしたいということがあった。
内部的には、paginationされた処理を繰り返しrequestし辿る部分などもあり、明示的にカウントする処理を入れていくのは大変そうだった。

方針として以下２つなどが考えられた

- proxyを別途立てて、何らかのmarkerと一緒にrequestする(proxy側でカウント)
- contextにrequest数のカウンターを詰めて、カウントする処理を行うtransportを挟む

今回は後者の話。

## transport

httpClientのTransportに `http.RoundTripper` のinterfaceを実装した値を渡すとmiddlewareのようにして使える。例えば以下の様なstructの定義を行うことでrequest数のカウントが実現できる。

```go
// Transport :
type Transport struct {
	Base http.RoundTripper
}

// RoundTrip :
func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
	if sc := GetCollectorFromContext(req.Context()); sc != nil {
		sc.Collect(req)
	}
	return t.Base.RoundTrip(req)
}

// GetCollectorFromContext :
func GetCollectorFromContext(ctx context.Context) *StatCollector {
	switch sc := ctx.Value(K).(type) {
	case *StatCollector:
		return sc
	default:
		return nil
	}
}

// K :
var K struct{}
```

名前はてきとう。requestのcontextからcollector(request数カウンター)を取り出してカウントしている。

## collector

collectorの定義は以下のようなもの。柔軟にしたければinterfaceにするべきかもしれないけれど。特に今回はそこまでする必要がなかったのでただのstructの定義。

```go
// StatCollector :
type StatCollector struct {
	Stat map[string]int
}

// NewStatCollector :
func NewStatCollector() *StatCollector {
	return &StatCollector{Stat: map[string]int{}}
}

// Collect :
func (sc *StatCollector) Collect(req *http.Request) {
	sc.Stat[req.Host]++
}
```

真面目にやるならlockなどを追加する必要もあるかもしれない。

## client

http.ClientにはTransportという引数を取る事ができる。ここに作ったTransportを渡す。



```go
func tick(ctx context.Context, client *http.Client, url string) error {
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return err
	}
	req = req.WithContext(ctx)
	response, err := client.Do(req)
	if err != nil {
		return err
	}
	defer response.Body.Close()
	io.Copy(os.Stdout, response.Body)
	return nil
}

func main() {
	client := &http.Client{Transport: &Transport{Base: http.DefaultTransport}}
	sc := NewStatCollector()
	ctx := context.Background()
	ctx = context.WithValue(ctx, K, sc)
	if err := tick(ctx, client, "http://localhost:54321/foo"); err != nil {
		log.Fatal(err)
	}
	if err := tick(ctx, client, "http://localhost:54321/foo"); err != nil {
		log.Fatal(err)
	}
	if err := tick(ctx, client, "http://localhost:54321/bar"); err != nil {
		log.Fatal(err)
	}
	pp.Print(sc.Stat)
}
```

リクエスト数のカウントができた。

```
{
  "localhost:54321": 3,
}
```
MongoDBで変数でlike検索の実行



findメソッドで検索対象に変数を使う方法についてつまづいたのでメモ。


単純にやりがちだがこれではエラー。
"/"と/が異なるので。

```
var word = "テスト"
var query = ({test: "/" + word + "/"})
testDB.find(query).function(err, item) {
 //hogehoge
}
```


RegExpを使うことで解決

```
var word = "テスト"
var query = ({test: new RegExp(".*" + word + ".*" , "i")})
testDB.find(query).function(err, item) {
 //hogehoge
}
```
PythonでTkinterがimportできなかった

pythonでtkinterがimportできない問題に遭遇したけど、日本語で解決方法が見つからなかったから書く。

#環境
Ubuntu16.04 LTS
pyenv 1.0.10-12-gda80a3d
python 3.6.1 (2.7系でも多分同じ)
IPython 6.0.0

# 原因
pyenvでpythonをインストールしたときに、tk-devがないのが原因だった。

# 解決方法
```shell-session
> sudo apt-get install tk-dev
> pyenv install x.x.x
```

`python -m tkinter`でtkinterのウィンドウが表示されればオッケー。

# 発生した障害
ipythonで%pasteが使えなくてあれ?となる。
エラーメッセージにtkinterがないと言われる。

調べてみたらこんな感じになった。

```py3
import tkinter
```

```py3tb
---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
<ipython-input-4-13f92e9c9d24> in <module>()
----> 1 import _tkinter

ModuleNotFoundError: No module named '_tkinter'
```

調べたら[ここ](http://stackoverflow.com/questions/26357567/cannot-import-tkinter-after-installing-python-3-with-pyenv#26358646)にたどりついた。
【GAS】QUERY関数を使って複数の情報を横に結合する

　今まで縦に結合するのはよく使っていたのですがこの度横に結合することもできることが分かったのでここに残しておこうと思います。

　といってもとても簡単で、範囲を{}の中で,（カンマ）で区切るだけです。具体的には、下の画像のように列が離れているものが横に結合されています。縦に結合するときは;（セミコロン）でしたが。

![スクリーンショット 2017-05-14 8.50.57.png](https://qiita-image-store.s3.amazonaws.com/0/139134/36209898-1525-94d9-1460-28202567118e.png)


　A8には以下の式が入っています（書かなくても分かるだろうけど）。<font color="red">注意すべきは行数を揃えることです。行数が揃ってないとエラーになります。</font>

```

=QUERY({A2:A4,E2:E4,H2:H4})

```

　で、応用してもう少し洒落たことをやってみます。たとえば料理の分類名のリストと料理名のリストがあって、料理名のリストには料理の分類IDが入っており、この分類IDから分類名を引っ張ってきて結合しつつ、洋食を除外するというのをやってみます。

![スクリーンショット 2017-05-14 9.12.57.png](https://qiita-image-store.s3.amazonaws.com/0/139134/20f5e64d-4501-39a5-233f-cbc2ce1989b8.png)


```

=QUERY({D3:E,IFERROR(ARRAYFORMULA(VLOOKUP(F3:F,A3:B,2,FALSE)))},"where Col3 != '"&"洋食"&"'")

```

　<font color="red">行数が揃っていさえすれば何でも横に結合できるので、このように他の関数の結果をも横に結合することができるわけです。</font>けっこう便利だと思うんですけど伝わりにくかったらすみません。。。

　（この例、加工後を同じシートの同じ行に持ってきているので横結合の恩恵が分かりにくかったかもしれないか・・・）
WordPressの絵文字出力のJavaScript,CSSを非表示にする

WordPressのheadタグ内にデフォルトで出力される絵文字出力のjs,cssを削除するには functions.php に以下を追記する。

```php:functions.php
remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
remove_action( 'admin_print_scripts', 'print_emoji_detection_script' );
remove_action( 'wp_print_styles', 'print_emoji_styles' );
remove_action( 'admin_print_styles', 'print_emoji_styles' );
```
Laravel 5.4にlaravel/duskを導入する


## 導入手順

* 公式マニュアルを参照
  * https://readouble.com/laravel/5.4/ja/dusk.html

### laravel/duskパッケージを取得

* composer requireでパッケージを取得する。

	``` bash:console
	cd (/your/laravel/project/path)
	composer require laravel/dusk
	```

* app/Providers/AppServiceProvider.phpを編集する
	
	> <マニュアルより引用>
	>
	> Duskをインストールしたら、Laravel\Dusk\DuskServiceProviderサービスプロバイダを登録してください。Duskは他のユーザとしてのログイン機能を可能にしてしまうので、利用可能な環境を限定するため、AppServiceProviderのregisterメソッド中でプロバイダーを登録します。


	``` app/Providers/AppServiceProvider.php
	use Laravel\Dusk\DuskServiceProvider;
	
	public function register()
	{
	    if ($this->app->environment('local', 'testing')) {
	        $this->app->register(DuskServiceProvider::class);
	    }
	}
	```

### インストール

* artisanコマンドを実行してインストール
		
	``` bash:console
	cd (/your/laravel/project/path)
	php artisan dusk:install
	```
今更ながらLocalStorageのメモ


特に難しいことはないけど、メモ。基本的にJavaScriptからの操作です。

### 基本的な性質

* 5 ~ 10MBの容量が入る（ちなみにcookieは4K程度）
* cookieと同様？ドメイン制約はある（当然）
* 消さなければ半永久的に残る

### 使えるか使えないか

まあ、2017年だと普通に使えるけど。念のため。

```js
if(window.localStorage) alert("使える");
```

### 書込み

基本はsetItem()。

```js
localStorage.setItem("name","hoge");
localStorage.email = "foo@foo.com"; //setItem("email","foo")と同義
```

### 取得

基本はgetItem()。

```js
localStorage.getItem("name");
console.log(localStorage.email);
```

>もちろんcosole.log()は必須じゃないです。念のため。

### 一覧取得

いろいろな取得方法ありますが、誰が見てもわかりやすいやつ。

```js
for(key in localStorage){
	console.log(key);
}
```

>このループを回すとweblioObjeFlgというkeyでデータが作られてしまうようです。。。Google先生に聞いてもよくわからない。なんだろう。

### keyの数の取得

いくつのkeyが存在しているか。

```js
console.log(localStorage.length)
```

>上記の通り、勝手に作られるものもあるので注意。

### 消去（個別）

keyを指定して削除。

```js
localStorage.removeItem("name");
```

### 消去（全部）

全クリア。

```js
localStorage.clear();
```
NSView の背景色を直接指定できるようにする IBInspectable

```swift
import Cocoa

extension NSView {
	
	@IBInspectable var backgroundColor: NSColor? {
		get {
			guard let layer = layer, let backgroundColor = layer.backgroundColor else {return nil}
			return NSColor(cgColor: backgroundColor)
		}
		set {
			wantsLayer = true
			layer?.backgroundColor = newValue?.cgColor
		}
	}
	
}
```

Background Color 項目が属性インスペクターに現れる。

![](https://qiita-image-store.s3.amazonaws.com/0/3603/ccaa77af-0097-4e1a-dab3-fd6d70a39a01.png)
Ubuntuで最新のカーネル以外をアンインストールする

# 目的
Ubuntuカーネルを自動で最新バージョン以外をアンインストールしたい。

# 検証環境
Ubuntu 16.04.2

# 手順
## インストールされているカーネルを調べる
```sh:
dpkg --list | grep -E -o "linux-image-[0-9]+\.[0-9]+\.[0-9]+-[0-9]+-generic"
```

これにより、以下のような結果が得られる。

```
$ dpkg --list | grep -E -o "linux-image-[0-9]+\.[0-9]+\.[0-9]+-[0-9]+-generic"
linux-image-4.8.0-36-generic
linux-image-4.8.0-51-generic
```

## バージョンのみを抽出する
```sh:
dpkg --list | grep -E -o "linux-image-[0-9]+\.[0-9]+\.[0-9]+-[0-9]+-generic" | grep -o -E "[0-9]+\.[0-9]+\.[0-9]+-[0-9]+" | uniq
```

```
$ dpkg --list | grep -E -o "linux-image-[0-9]+\.[0-9]+\.[0-9]+-[0-9]+-generic" | grep -o -E "[0-9]+\.[0-9]+\.[0-9]+-[0-9]+" | uniq
4.8.0-36
4.8.0-51
```

## 最新のバージョンを抽出する
自然数化して降順ソートした結果の先頭を取得する。

```sh:
dpkg --list | grep -E -o "linux-image-[0-9]+\.[0-9]+\.[0-9]+-[0-9]+-generic" | grep -o -E "[0-9]+\.[0-9]+\.[0-9]+-[0-9]+" | uniq | sort -n -r | head -1
```

以下のような結果となる。

```
$ dpkg --list | grep -E -o "linux-image-[0-9]+\.[0-9]+\.[0-9]+-[0-9]+-generic" | grep -o -E "[0-9]+\.[0-9]+\.[0-9]+-[0-9]+" | uniq | sort -n -r | head -1
4.8.0-51
```

## 最新以外のカーネルバージョンを抽出する
`grep` の `-v` オプションに最新のバージョンを指定して除外する。

```
dpkg --list | grep -E -o "linux-image-[0-9]+\.[0-9]+\.[0-9]+-[0-9]+-generic" | grep -o -E "[0-9]+\.[0-9]+\.[0-9]+-[0-9]+" | uniq |
$(dpkg --list | grep -E -o "linux-image-[0-9]+\.[0-9]+\.[0-9]+-[0-9]+-generic" | grep -o -E "[0-9]+\.[0-9]+\.[0-9]+-[0-9]+" | uniq | sort -n -r | head -1)
```

## 抽出した最新以外のカーネルバージョンに関連するパッケージを削除する
`linux-headers-` と `linux-image-` から始まるパッケージを `autoremove --purge` オプションを付けて `apt` (apt-getでもaptitudeでも可) コマンドで削除する

```
apt autoremove --purge -y linux-headers-<上記までで抽出した最新以外のバージョン>*
apt autoremove --purge -y linux-image-<上記までで抽出した最新以外のバージョン>*
```

## シェルスクリプト化してみる

```sh:
USER=$(whoami)

if [ ! ${USER} = "root" ]
then
  echo "Please use with sudo"
  exit 1
fi

LATEST=$(dpkg --list | grep -E -o "linux-image-[0-9]+\.[0-9]+\.[0-9]+-[0-9]+-generic" | grep -o -E "[0-9]+\.[0-9]+\.[0-9]+-[0-9]+" | uniq | sort -n -r | head -1)

TARGETS=$(dpkg --list | grep -E -o "linux-image-[0-9]+\.[0-9]+\.[0-9]+-[0-9]+-generic" | grep -o -E "[0-9]+\.[0-9]+\.[0-9]+-[0-9]+" | uniq | grep -E -v ${LATEST})

for pkg_ver in ${TARGETS}
do
  for pkg_prefix in linux-headers- linux-image-
  do
    apt autoremove --purge -y ${pkg_prefix}${pkg_ver}*
  done
done

update-grub
```

`dpkg --list | grep -E -o "linux-image-[0-9]+\.[0-9]+\.[0-9]+-[0-9]+-generic" | grep -o -E "[0-9]+\.[0-9]+\.[0-9]+-[0-9]+" | uniq` を先に実行して共通化したい。。。
OpenPoseを動かす (Docker)


# はじめに
OpenPoseは，CVPR2017で発表された1枚のカラー画像から人物の骨格を推定する手法です．最近DNN界隈で話題になっているということで，手法の詳細はとりあえず置いておくとして，公開されているコードを動かしてみました．

# Dockerfile
caffeとopenPoseのinstallは``install_caffe_and_openpose.sh``を実行するだけで入ります．学習済みのモデルも自動でダウンロードしてきてくれます(逆に言うとイメージの中にモデルも入ってしまっています)．とりあえず動けばいいのでapt-getも適当です(モデルのダウンロードに``wget``は必須でした．)

```Dockerfile
FROM nvidia/cuda:8.0-cudnn5-devel-ubuntu14.04

RUN apt-get update && apt-get install -y build-essential cmake libatlas-base-dev git vim python-dev python-pip python-numpy libopencv-dev python-opencv wget

WORKDIR /root
RUN git clone https://github.com/CMU-Perceptual-Computing-Lab/openpose.git
WORKDIR /root/openpose
RUN chmod u+x install_caffe_and_openpose.sh
RUN ./install_caffe_and_openpose.sh
```

# デモを実行してみる
デモを実行してみます．
(https://github.com/CMU-Perceptual-Computing-Lab/openpose/blob/master/doc/demo_overview.md) 

以下のように``--no_display``のオプションを使うとGUIなしで動きます．動画として出力するととりあえず結果を確認できます．
``./build/examples/openpose/openpose.bin --video ./examples/media/video.avi --no_display --write_video PATH/TO/OUTPUT.avi``
Rantly gemでランダムにテストデータを大量に生成する

Rubyの property-based testing 向けライブラリの rantly gem で
ランダムなテストデータを大量に作成します。

## <i class='fa fa-question-circle'></i> 関連記事
[tbpgr の rantly 関連記事](http://qiita.com/search?utf8=%E2%9C%93&q=user%3Atbpgr%20tag%3Arantly)

## <i class='fa fa-flask'></i> サンプル
```ruby
require "rantly"
require "pp"

module Languages
  NAMES = %w(c Java Ruby Perl PHP Python Scala Brainfuck)
end

Programmer = Struct.new("Programmer", :name, :age, :languages, :love_programming, :love_numbers)

def generate_programmer
  name = Rantly{choose('tanaka', 'suzuki', 'sato', 'honda', 'noda')}
  age = Rantly{range(10, 80)}
  languages = ::Languages::NAMES.sample(rand(4))
  love_programming = Rantly{boolean}
  love_numbers = Rantly{array(5){range(1, 100)}}
  Programmer.new(name, age, languages, love_programming, love_numbers)
end

# ループ数を大きくすればもっと大量のデータを生成できます
10.times {
  programmer = generate_programmer
  pp programmer
}
```

* 出力

```sh
#<struct Struct::Programmer
 name="tanaka",
 age=54,
 languages=[],
 love_programming=false,
 love_numbers=[45, 57, 42, 35, 99]>
#<struct Struct::Programmer
 name="noda",
 age=11,
 languages=["PHP", "Perl", "Brainfuck"],
 love_programming=false,
 love_numbers=[79, 62, 93, 17, 33]>
#<struct Struct::Programmer
 name="sato",
 age=55,
 languages=["Ruby"],
 love_programming=true,
 love_numbers=[2, 17, 43, 89, 78]>
#<struct Struct::Programmer
 name="honda",
 age=39,
 languages=["Scala", "Java", "PHP"],
 love_programming=true,
 love_numbers=[97, 62, 19, 86, 57]>
#<struct Struct::Programmer
 name="sato",
 age=55,
 languages=[],
 love_programming=true,
 love_numbers=[87, 19, 24, 35, 24]>
#<struct Struct::Programmer
 name="noda",
 age=54,
 languages=[],
 love_programming=true,
 love_numbers=[60, 11, 40, 46, 19]>
#<struct Struct::Programmer
 name="tanaka",
 age=78,
 languages=["Brainfuck"],
 love_programming=false,
 love_numbers=[55, 5, 42, 71, 52]>
#<struct Struct::Programmer
 name="honda",
 age=49,
 languages=["Java"],
 love_programming=true,
 love_numbers=[81, 10, 22, 95, 58]>
#<struct Struct::Programmer
 name="tanaka",
 age=47,
 languages=[],
 love_programming=false,
 love_numbers=[84, 88, 49, 19, 33]>
#<struct Struct::Programmer
 name="tanaka",
 age=13,
 languages=["Ruby", "c"],
 love_programming=false,
 love_numbers=[44, 50, 47, 58, 11]>
```

## <i class="fa fa-book" style="font-size:1em;"></i> 外部資料
* [abargnesi/rantly](https://github.com/abargnesi/rantly)
Microsoft AzureでMySQLが利用できるようになった

# 概要
Microsoft Build 2017のキーノートでMySQLのフルマネージドサービスの発表がありました。
2017/5/13現在preview版ですが、一通り触ってみた所感と利用時の注意事項などについて書いていきたいと思います。

# メリット
## 🍣 フルマネージドでサイジングが簡単
Azureでは今までMySQLのマネージドサービスは提供されてきませんでした。
そのため、インスタンスを立ててMySQLをインストールして利用するしかありません。
もちろんクラスターやレプリケーション、シャーディングといった冗長化や負荷分散には自前でその台数分のインスタンスを作成し、
それらを自分でプロビジョニング・管理する必要があります。

発表されたAzure Database for MySQLでは、コンピューティングユニットと、ストレージの容量がダウンタイムを(ほぼ)挟むことなく操作できます。
これにより、サイジングを簡単に行うことができます。
![Kobito.ElZ3Bi.png](https://qiita-image-store.s3.amazonaws.com/0/125051/fbefac88-498d-7ae7-ca68-771c371702e0.png "Kobito.ElZ3Bi.png")

## 🍺 自動バックアップ
現在利用可能なBasicプランでは過去7日間のバックアップを自動で保管します。
ただし、復元の際には、新規でリソースを作成する必要があります。
![Kobito.XtO3OF.png](https://qiita-image-store.s3.amazonaws.com/0/125051/d9e229f3-914f-385c-e77b-bbeaa726098f.png "Kobito.XtO3OF.png")

# デメリット
## 💀 フルマネージドなので細かいチューニングは不可能
フルマネージドサービスに共通して言えることですが、細かいチューニングはできません。
チューニングできる項目(後述)は限られるので、注意する必要があります。

## 😈 ポータルからのレプリケーションはできない
現在、ポータルからのレプリケーション設定はできないようです(間違っていたらごめんなさい)。
Azure SQL Databaseではactive geoレプリケーションでプライマリ/セカンダリとレプリケーションが可能ですが、MySQLにはまだ存在しないようです。
自分でレプリケーションを組む他なさそうです。

# Azure Database for MySQLでできること
## 使用可能なMySQLバージョン
開始時にMySQL 5.6 または 5.7の選択が可能です。

## 設定可能な項目
現在、以下の項目をポータルにて管理/設定できます。

| パラメーター名 | 初期値 |
|:------------|:----|
| binlog_group_commit_sync_delay | 1000 |
| binlog_group_commit_sync_no_delay_count | 0|
| character_set_server | LATIN1 |
| div_precision_increment | 4 |
| group_concat_max_len | 1024 |
| innodb_adaptive_hash_index | ON |
| innodb_lock_wait_timeout | 50 |
| interactive_timeout | 1800 |
| log_bin_trust_function_creators | OFF |
| log_queries_not_using_indexes | OFF |
| log_slow_admin_statements | OFF |
| log_throttle_queries_not_using_indexes | 0 |
| long_query_time | 10 |
| max_allowed_packet | 536870912 |
| min_examined_row_limit | 0 |
| server_id | 1000 |
| slave_net_timeout | 60 |
| slow_query_log | OFF |
| sql_mode | 0 項目が選択されました |
| time_zone | SYSTEM |
| wait_timeout | 120 |

# おわりに
検証が不十分な箇所が散見し申し訳ないです。
所感として、正直まだproductionに投入できるほどのものではありません(preview版だし、basicしかないので当然だが)。
しかし今までインスタンスの管理コストがあったものが丸投げできるのは大きな魅力です。
またAzure SQL DatebaseではAWS RGSに比べても遜色のない様々な機能が提供されているので、GAまでにはよりAzureならではのフルマネージドdatabaseになっていくのではないかと思います。
これからどんどん機能が追加されていく(といいな)ので、どんどん検証していきたいと思います。
boost::function は int 型の右辺値参照型では初期化出来ない

`std::function` は `nullptr` を渡す事で, 空の関数オブジェクトを構築する事が出来る. また, 同様に代入演算子に対して `nullptr` を渡す事でもまた, 空の関数オブジェクトとなる.

```cpp
#include <utility>
#include <functional>
int main()
{
    using namespace std;
    using f = function< void() >;
    f x( nullptr );
    x = nullptr;
}
```

また `boost::function` は同様の機能を `0` を引数として渡す事で実装している.

```
#include <utility>
#include <boost/function.hpp>
int main()
{
    using namespace std;
    using f = boost::function< void() >;
    f x( 0 );
    x = 0;
}
```

`std::functional` は `std::nullptr&&` 型の値を渡した場合も同様である.

```cpp
#include <utility>
#include <functional>
int main()
{
    using namespace std;
    using f = function< void() >;
    f x( move( nullptr ) );
    x = move( nullptr );
}
```

ところが `boost::function` は `int&&` を渡した場合ビルドエラーとなる. 以下のコードはビルドエラーとなる.

```cpp
#include <utility>
#include <boost/function.hpp>
int main()
{
    using namespace std;
    using f = boost::function< void() >;
    f x( move( 0 ) );
    x = move( 0 );
}
```

これは `boost::function` のコンストラクタ及び代入演算子において, 0 による初期化を行う引数の型が実際には `int` ではないために, オーバーロード解決に失敗するためである.

`boost::function` のコンストラクタに `0` が渡された時, 以下のコンストラクタでコンパイラはテンプレート引数 `Functor` を `int` に推論する. [^1]

[^1]: 実際のコードはもう少し複雑である.

```cpp
template<typename Functor>
function(
    Functor f
    , typename boost::enable_if_c<
        !( is_integral<Functor>::value ), int>::type = 0
);
```

引数の型が `Functor const&` でも `Functor&&` でもなく `Functor` である事に注目して欲しい.

上記の疑似コードでは省略したが, `Functor` の型が整数型であった場合, SFINAE によって上記のコンストラクタはオーバーロードの候補から除外され, メンバ型 `clear_type` のポインタ型を引数としたコンストラクタが呼ばれる. そして注目すべき事に, コンパイラは `clear_type*` への暗黙の型変換について `0` のみを通し `1` や `std::move( 0 )` は通さない [^2] のである. これがコンパイラがオーバーロード解決に失敗する理由である.

[^2]: この部分について,規格上の参照箇所が分かる型がいらっしゃったらご指摘願います.

Boost.Functon が `nullptr` ではなく `0` によって空にする仕様になっている理由はまず, 設計された当初に `nullptr` が無かったためと思われる.

次に, `0` で空になる事を明示している [^3] にも関わらず, `clear_type*` を引数としている理由だが, これは前述の様に `1` 等のリテラルを渡した時, 実行時ではなくコンパイル時にエラーにするためであろう.

[^3]: [Boost.Function Tutorial Basic Usage](http://www.boost.org/doc/libs/1_64_0/doc/html/function/tutorial.html#idp247873024)

この分岐先の関数は, マクロ `BOOST_NO_SFINAE` が定義されている時, 引数の型が `int` の関数に置き換えられる. そしてこの関数は内部で `0` である事を条件としてアサートを行っている. この事からも `0` 以外の値を受け取った時, エラーにしようという意図が読み取れる.

態々 `BOOST_NO_SFINAE` の有無によって分岐している理由は, `0` を引数として受け取った時, SFINAE の無い処理系において `clear_type*` 型と関数ポインタとの分岐が不可能であるためと思われる.

よって, この問題を修正するためには「 `0` で初期化する方法の他に `nullptr` でも初期化可能とする仕様を追加する」か「 `0` 以外の `int` 型のリテラルが渡された時コンパイル時エラーにする事を諦め, `int` 型のコンストラクタを用意し, 実行時アサートで妥協する」かの二者択一となる.

一応「ユーザ側で `clear_type*` を渡す」という手段もあるが, やや冗長である. この方法は Boost.Optional における `boost::none` 等が採用している.