OmniAICreator/Qiita-1.07M huggingface dataset:
Parse ServerをLocalにインストール

超超超久しぶりにParse Serverをローカルにインストールする必要？(ParseServerのデータをFirebaseにMigrationしたいためテスト用...)が出てきたので、忘れないようにメモ....。

OS: macOS High Sierra
Parse-Server:Ver.2.7.2
Parse-DashBoard:Ver.1.1.2

#Parse Serverをインストール

```
$ npm install -g parse-server mongodb-runner

$ mongodb-runner start

//Parse Server起動
$ parse-server --appId APPLICATION_ID --masterKey MASTER_KEY --databaseURI mongodb://localhost/test

```

**注意**
 APPLICATION_IDとMASTER_KEYは任意の文字列を入れます。
(例:$ parse-server --appId sampletestID --masterKey sampletestKEY --databaseURI mongodb://localhost/test)

(参)[https://github.com/parse-community/Parse-Server#getting-started](https://github.com/parse-community/Parse-Server#getting-started)

#DashBoardをインストール
Serverをインストールしただけではわかりにくいので、管理画面のDashBoardをインストールします。

```
git clone git@github.com:ParsePlatform/parse-dashboard.git

cd parse-dashboard

npm install
```

次に、ブラウザで「[http://localhost:4040](http://localhost:4040)」にアクセスすれば、DashBoardで見ることができるようになります。

(参)http://mushikago.com/i/?p=7144

#設定
次に、parse-dashboard-config.jsonを書き換えてアプリデータを表示できるようにします。

```
{
  "apps": [{
    "serverURL": "http://localhost:1337/parse",
    "appId": "<APPLICATION_ID>",
    "masterKey": "<MASTER_KEY>",
    "appName": "<App_Name>",
    "iconName": ""
  }],
  "iconsFolder": "icons"
}

```

【注意】
APPLICATION_ID、MASTER_KEYはServer起動時に設定した物を使用
App_Nameはなんでもいい

・parse-dashboard-config.json書き換え後、ブラウザでDashBoardをリロードして、設定したAppが表示されていればOK
・表示されなければ、一度、Parse-Dashboardを再起動すれば表示されるようになるはずです。
・複数アプリを登録する場合は以下のようにparse-dashboard-config.jsonを書き換えます。

```
{
  "apps": [{
    "serverURL": "http://localhost:1337/parse",
    "appId": "<APPLICATION_ID>",
    "masterKey": "<MASTER_KEY>",
    "appName": "<App_Name>",
    "iconName": ""
  },{
    "serverURL": "http://localhost:1337/parse",
    "appId": "<APPLICATION_ID>",
    "masterKey": "<MASTER_KEY>",
    "appName": "<別のApp_Name>",
    "iconName": ""
  }],
  "iconsFolder": "icons"
}
```
(参)http://mushikago.com/i/?p=7144

##(おまけ)DashBoardをGlobalにインストールする場合

・npmでインストールします。

```
npm install -g parse-dashboard
```

・DashBoard起動は以下のコマンドでOK

```
parse-dashboard --appId yourAppId --masterKey yourMasterKey --serverURL "https://example.com/parse" --appName optionalName
```

(参)https://github.com/parse-community/parse-dashboard
Annict GraphQL で視聴したアニメに対するコメントを取る

GraphQL の練習がてらです。特に Union Type について知ったのでメモ。

Annict GraphQL API についての本家の解説はこちら。
[AnnictのGraphQL APIを使ってアニメデータを取得しよう \- Qiita](https://qiita.com/shimbaco/items/e3f2f8650b08e1e060bd)

Annict API Doc: https://docs.annict.com/ja/api/graphql/overview.html

簡単に書くと

`myuser.records[].episode.records(hasComment==true)[].comment` が欲しいものです


GraphQL

```gql
{
  viewer {
    records(first: 2) {
      edges {
        node {
          episode {
            work {
              title
            }
            records(first: 2, hasComment: true) {
              edges {
                node {
                  user {
                    name
                  }
                  comment
                  likesCount
                  createdAt
                  ratingState
                }
              }
            }
          }
        }
      }
    }
  }
}
```

レスポンスの一部

```json
{
  "data": {
    "viewer": {
      "records": {
        "edges": [
          {
            "node": {
              "episode": {
                "work": {
                  "title": "ポプテピピック"
                },
                "records": {
                  "edges": [
                    {
                      "node": {
                        "user": {
                          "name": "うに"
                        },
                        "comment": "前半だけ",
                        "likesCount": 0,
                        "createdAt": "2018-02-18T05:09:28Z",
                        "ratingState": null
                      }
                    },
...
```

ActivityItemが4種類あるので今回欲しい Record を指定しています。

### 追記

[API が拡張された](https://github.com/annict/annict/issues/957)ので更新しました。
Webページのアーカイブにgitを使う場合の保存効率を調べてみた

## 概要
あるWebページを定期的にクロールして、HTMLにいつどんな変化があったのかを保存しておきたいニーズがあり、gitを使う場合と、生HTMLを保存しておく(後から`diff`コマンドで差分を見る)場合でどれぐらい保存効率に差があるのか知りたかったため、計測しました。

## 計測方法
https://github.com/showwin/git_benchmark/blob/master/git_disk_efficiency.py を使って検証しました。[ほぼ同じだが、一部が改変されているHTML10個](https://github.com/showwin/git_benchmark/tree/master/html_templates) を用意して、それらを5000ファイルに対してランダムで書き込み、10万回のコミットをしたときのディレクトリの容量を計測しました。(1ファイル当たり平均20回変更が発生していることになります)
生HTML方式は10種類のHTMLを10万回書き出した時のデータ容量を計測しました。

## 結果

```
git: 2.1GB
生HTML: 1.5GB
```

なんとgitで差分を管理する方が効率が悪いことが判明しました…
今回は1ファイルあたり12~13KBのHTMLで、変更部分は2文字〜4行ぐらいの小さな変更ばかりだったのですが、それでもこの結果になるんですね。。
独自で差分管理ファイルシステムを作ったほうが良いのかな… 差分の保存に特化したデータストアをご存知の方はぜひ教えてください…！

## 追記
`git gc` というコマンドの存在を知り([doc](https://git-scm.com/book/ja/v1/Git%E3%81%AE%E5%86%85%E5%81%B4-%E3%83%A1%E3%82%A4%E3%83%B3%E3%83%86%E3%83%8A%E3%83%B3%E3%82%B9%E3%81%A8%E3%83%87%E3%83%BC%E3%82%BF%E3%83%AA%E3%82%AB%E3%83%90%E3%83%AA))適用してみたところ、842MBまで軽量化できました🎉

```
git gc後: 842MB
生HTML: 1.5GB
```

なのでgc前と比べると1/3程度になり、生HTMLと比べても半分ぐらいまで減らせました。
レッツ！パーティション MYSQL。

#パーティションって何よ？

100万レコードとかになるとテーブルが重くなる。
そのテーブルを細かく分けるという技。
保存する時やデータを取得する時は、パーティションを指定して取得、保存が可能。

また、今まで通りの操作でも正常に動作する。


## 分割方法


パーティショニングしたいカラムが PRIMARY KEY に含まれている必要がある。
なので、インデックス張替え。

id だけのインデックスから
id , created の複合インデックスに 変更。

```mysql
ALTER TABLE yourtable DROP PRIMARY KEY, ADD PRIMARY KEY(id,created);
```



**複合にしても id での並び替え検索の時間は変わらない**


# パーティションを区切る


p201711 と TO_DAYSの中身は1ヶ月変えておく。
でないと、1ヶ月ずれてデータが入ってしまう。

```mysql
ALTER TABLE yourtable
PARTITION BY RANGE (TO_DAYS(created)) (
    PARTITION p201711 VALUES LESS THAN (TO_DAYS('2017/12/01 00:00:00')),
    PARTITION p201712 VALUES LESS THAN (TO_DAYS('2018/01/01 00:00:00')),
    PARTITION p201801 VALUES LESS THAN (TO_DAYS('2018/02/01 00:00:00')),
    PARTITION p201802 VALUES LESS THAN (TO_DAYS('2018/03/01 00:00:00'))
);
```

## php でパーティション名を一括取得

何十年先分もつくっておきたい。
そんな贅沢なあなたに。

```php
        $i = 1;

        while($i < 360){


            $p_tuki = $i-1;
            $p_name = date('Ym', strtotime('+'.$p_tuki.' month'));

            $raigetu = date('Y/m', strtotime('+'.$i.' month'));

echo "PARTITION p".$p_name." VALUES LESS THAN (TO_DAYS('".$raigetu."/01 00:00:00')),<br>";
            
            $i++;
        }

        die;
```


# パーティション区切れた？


```mysql
SELECT TABLE_SCHEMA, TABLE_NAME, PARTITION_NAME, PARTITION_ORDINAL_POSITION, TABLE_ROWS
FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_NAME =  'yourtable';
```


**パーティションがが区切れてますね**


# パーティションを指定して検索

```mysql
SELECT * FROM yourtable PARTITION (p201801, p201802) WHERE c < 5;
```




# パーティション張替え ( パーティションを一旦削除。データは消えない。 )

```mysql
ALTER TABLE yourtable REMOVE PARTITIONING;
```

# データの保存は？

新規保存時は、自動的に今年の日時が入るので何も考えなくて良い。
UPDATE時はパーティションを指定してupdateしたいので、日付も渡してパーティション名を取得。

#cakephp3 で使おう。

```php
//    パーティションを指定して保存
    public function pSave($data)
    {
        $con = ConnectionManager::get($this->getConnection()->config()['name']);

//        $last = $con->insert('mes PARTITION ('.$this->getPartitionName().')', [
//                'social_id' => s('id'),
//                'ip' => '111.222.333.444',
//                'body' => "%ここにテスト内容が入るよ%"
//            ]
//        );


//        update時は view から createdを送ってくること。
        if(!empty($data['id'])){

            $partition_name = "p".dtf($data['created'], "Ym");
            unset($data['created']);
            $last = $con->update($this->getTable().' PARTITION ('.$partition_name.')',$data,['id' => $data['id']]);

        } else {
            $last = $con->insert($this->getTable().' PARTITION ('.$this->getPartitionName().')',$data);
        }

        $last_id = $last->lastInsertId();

        return $last_id;

    }

//    インサートスべきパーティション名を返す
    public function getPartitionName()
    {
        return "p".date("Ym");
    }
```
初めてのre:dash on heroku


# 前提
herokuでre:dash を動かしたい！
でも、re:dashとはそもそも何？？
どうやってホスティングするの？　安く簡単にすませたい！
もうようわからん！

のような、現在の僕みたいな方向けの記事です・

# herokuでホスティング
調べてみると現在herokuではre:dashのホスティングをサポートしていないようです。
そして、調べてみるとdockerを使ってホスティングできるようです。

そして、今回はこのかたのをエントリーを存分に使わせてもらいたいと思います！m(_ _)m
http://memo.willnet.in/entry/2017/09/02/153224


```
# ブログから引用
$ git clone git@github.com:willnet/redash-on-heroku.git
$ cd redash-on-heroku
$ heroku create your_app_name
$ heroku container:push --recursive

#postgresをherokuに入れる
$ heroku addons:create heroku-postgresql:hobby-dev

#rediesをherokuに入れる
$ heroku addons:create rediscloud:30

```

以上で必要なモノがherokuにインストールされます。
そして次はpostgresDBとredisをつなげる作業です。

```
$ heroku config
```
を実行すると

```
DATABASE_URL:        postgres://xxxxxxxxxxx..
REDISCLOUD_URL:      redis://xxxxxxxxxxxx...
```

がでてくるので
これらをコピーし、`heroku config:set`　コマンドでredashとつなげます。


```
$　heroku config:set REDASH_DATABASE_URL＝postgres://xxxxxxxxxxx..
$　heroku config:set REDASH_REDIS_URL= redis://xxxxxxxxxxxx...

# DBを起動
$ heroku run /app/manage.py database create_tables
```
これで、re:dashの
これでセットアップは完了です！

```
$ heroku open 
```
で出るはずです！


# re:dashはどう使う？

re:dashの使い方をハンズオンで作成してくださったものがあるので、使わせてもらいましょう！

https://github.com/kakakakakku/redash-hands-on

# 現状の問題
現在、解析ようのDBとして、別のherokuで上がっているDBを設定しているのですが、恐ろしく実行がおそい！><
DBが大きすぎるのか、はたまたre:dashを上げているのが安いサーバーだからなのかは謎です。
自作のprometheus exporterを公式サイトに登録する

# はじめに
prometheusのexporterを作って公式サイトの[Third-party exporters](https://prometheus.io/docs/instrumenting/exporters/#third-party-exporters)に載せてもらえたので手順を書いておきます。
今回作ったのは[softether_exporter](https://github.com/dalance/softether_exporter)。[Softether VPN](https://ja.softether.org)サーバのメトリクスを取得するexporterです。

# 手順

## [WRITING EXPORTERS](https://prometheus.io/docs/instrumenting/writing_exporters/)を読む
作る前に一通り読んでおきましょう。メトリクスの命名規則などが書いてあります。

## デフォルトポート割り当て
[ここ](https://github.com/prometheus/prometheus/wiki/Default-port-allocations)に各exporterがデフォルトで使うポート番号のリストがあります。
特に強制力などがあるわけではないと思いますが、登録しておくといいでしょう。
登録した時点では9410まで埋まっていたので9411で登録しました。
公開前にポート番号だけ予約しておくのもOKのようです。

## exporterの配布サイトを準備
登録する際のリンク先です。githubで特に問題はないですが、
登録依頼したときにチェックされるようなので多少のREADMEはあったほうがいいです。

## githubでPR
公式サイトのソースを管理しているリポジトリ[prometheus/docs](https://github.com/prometheus/docs)にPRを出せば良いようです。
実際に出したPRは[こちら](https://github.com/prometheus/docs/pull/953)。

既存のexporterと被っていると、変更するにはいろいろ大変なようですが、
新規のexporterならすぐにマージしてもらえるようです。
pythonでQL分解とQR分解


numpyには（他のライブラリにも）QR分解あるけどQL分解がないので簡単に作る．


# 行列生成
```python:
import numpy as np

A = np.random.rand(4,4)
print(A)
```

```sh:output
[[ 0.79124883  0.99846239  0.68643175  0.62022478]
 [ 0.62550988  0.4907801   0.43422796  0.70191408]
 [ 0.55936063  0.31190068  0.77154881  0.08427772]
 [ 0.11253189  0.65420468  0.46686985  0.11447206]]
```

# QR分解

```python:QR分解
Q, R = np.linalg.qr(A)
print('Q\n', Q)
print('R\n', R)
print('Q @ R\n', Q @ R)
print('A == Q @ R ?', np.allclose(A, Q @ R))
print('Q @ Q^T == I ?', np.allclose(Q @ Q.transpose(), np.eye(4)))
print('Q^T @ Q == I ?', np.allclose(Q.transpose() @ Q, np.eye(4)))
```

```sh:output
Q
 [[-0.68280023  0.31934702  0.36684631 -0.54518356]
 [-0.53977747 -0.21055993  0.30305429  0.75661278]
 [-0.48269464 -0.38522751 -0.77364703 -0.14168954]
 [-0.09710826  0.83981055 -0.41839235  0.33201818]]
R
 [[-1.15882918 -1.16074386 -1.12084163 -0.85416362]
 [ 0.          0.64477264  0.22263932  0.1139407 ]
 [ 0.          0.         -0.40883161  0.32714981]
 [ 0.          0.          0.          0.21900634]]
Q @ R
 [[ 0.79124883  0.99846239  0.68643175  0.62022478]
 [ 0.62550988  0.4907801   0.43422796  0.70191408]
 [ 0.55936063  0.31190068  0.77154881  0.08427772]
 [ 0.11253189  0.65420468  0.46686985  0.11447206]]
A == Q @ R ? True
Q @ Q^T == I ? True
Q^T @ Q == I ? True
```

# QL分解

```python:QL分解
def QL(A):
    """
    QL factorization by using QR factorization
    """
    Q, L = np.linalg.qr(A[::-1,::-1])
    return Q[::-1,::-1], L[::-1,::-1]


Q, L = QL(A)
print('Q\n', Q)
print('L\n', L)
print('Q @ L\n', Q @ L)
print('A == Q @ L ?', np.allclose(A, Q @ L))
print('Q @ Q^T == I ?', np.allclose(Q @ Q.transpose(), np.eye(4)))
print('Q^T @ Q == I ?', np.allclose(Q.transpose() @ Q, np.eye(4)))
```

```sh:output
Q
 [[ 0.61195303  0.42670519 -0.1218915  -0.65465917]
 [-0.44726347 -0.4150739   0.28064256 -0.74088379]
 [ 0.09753892 -0.51781405 -0.84524639 -0.08895675]
 [-0.64494576  0.61441431 -0.43811043 -0.12082746]]
L
 [[ 0.18642187  0.          0.          0.        ]
 [-0.14250644  0.46278524  0.          0.        ]
 [-0.44300076 -0.53421711 -0.81849675  0.        ]
 [-1.04478428 -1.12405514 -0.89613647 -0.94740105]]
Q @ L
 [[ 0.79124883  0.99846239  0.68643175  0.62022478]
 [ 0.62550988  0.4907801   0.43422796  0.70191408]
 [ 0.55936063  0.31190068  0.77154881  0.08427772]
 [ 0.11253189  0.65420468  0.46686985  0.11447206]]
A == Q @ L ? True
Q @ Q^T == I ? True
Q^T @ Q == I ? True
```
月初の日曜 深夜1時にRAIDチェックが実行されてCPU高負荷になる

* メリット
    * [RAIDレベルの話: 1+0と6はどっちが安全か？ - たごもりすメモ](http://tagomoris.hatenablog.com/entry/20110419/1303181958)

## 参考

* [RAID1同期処理が実行されてる！？｜カラミティの適当なブログ♪](https://ameblo.jp/gx-9901xx/entry-11867446425.html)
* [RHELではraid-checkというスクリプトがあるけどDebianではcheckarrayがある - Humanity](http://tyru.hatenablog.com/entry/20120505/debian_checkarray)
* [RAID check on Ubuntu：びぼうろぐ：So-netブログ](http://bibo-log.blog.so-net.ne.jp/2012-04-03)

## 原因

/etc/cron.d/mdadm で 日曜日かつ1日〜7日の間の00:57 に
/usr/share/mdadm/checkarray が実行される様子。

### debian9の場合

```sh:/etc/cron.d/mdadm
57 0 * * 0 root if [ -x /usr/share/mdadm/checkarray ] && [ $(date +\%d) -le 7 ]; then /usr/share/mdadm/checkarray --cron --all --idle --quiet; fi
```

### CentOS6の場合

```sh:/etc/cron.d/raid-check
0 1 * * Sun root /usr/sbin/raid-check
```

### CentOS5の場合

```sh:/etc/crontab
22 4 * * 0 root run-parts /etc/cron.weekly
```

* /etc/cron.weekly/99-raid-check

* /etc/sysconfig/raid-check
    * ENABLED=yes

## 強制停止

```sh:強制停止
echo idle > /sys/block/md127/md/sync_action 
```

* すぐに実行したい場合は、

```sh:強制実行
echo check > /sys/block/md127/md/sync_action 
```

## 自動実行の無効化

```diff:/etc/default/mdadm
- AUTOCHECK=true
+ AUTOCHECK=false
```

もしくは /etc/cron.d/mdadm でコメントアウトして

```
service cron restart
```
Azure ML Studio でスクリプトを書かずに4層以上のニューラルネットワークを構築する

##はじめに
Azure Machine Learning Studio（Azure ML Studio）といえば、ブラウザ上で手軽に機械学習を構築することができるマイクロソフトのサービスです。

コードを書かずともドラッグ&ドロップで機械学習を構築できるので非常にとっつきやすいです。

とはいえ、Azure ML Studio上で、4層以上のニューラルネットワークを構築する場合、Net#という言語でカスタムスクリプトを書いて定義するのが一般的かもしれません。
たとえばAzure ML Studio 紹介のデモをするようなシチュエーションで、
肝心のディープラーニングにコードの記述が必要というのも、とっつきやすさが半減してしまいます。

実際はドラッグ&ドロップと設定値の変更だけで、4層以上のニューラルネットワークも定義できますが、設定方法があまり直感的ではないので以下に記載しておきます。

##内容

![amls_mnn.png](https://qiita-image-store.s3.amazonaws.com/0/50559/1aa6e180-00c1-f5d6-3a9c-09bb8b750a95.png)

もし、上図の青枠の[Hidden layer specification] に「Custom definition script」を指定している場合は、Net#スクリプトでニューラルネットを定義します。
図の通り「Fully-connected case」（通常の全結合）を指定している場合は、その下赤枠の[Number of hidden nodes]で隠れ層のユニット数を指定します。
ここは、数値を入力すべき欄のように見えます（私は最初そう思いました）。
単にひとつの数値を入れると、それはあくまでひとつの隠れ層内のユニット数になります。
でき上がるのは入力層を除いて2層のニューラルネットワークです。

しかし実は、この[Number of hidden nodes]は、層ごとにカンマ区切りで入力できます。
つまりカンマで区切るごとに隠れ層を定義できるので、4層以上のニューラルネットワークも定義できます。
たとえば「8,6,8」入力すると、隠れ層のユニット数がそれぞれ8個、6個、8個の３層、入力層を除いて全体で4層のニューラルネットワークになります。

##参考
[https://docs.microsoft.com/en-us/azure/machine-learning/studio-module-reference/neural-network-regression#parameters](https://docs.microsoft.com/en-us/azure/machine-learning/studio-module-reference/neural-network-regression#parameters "Neural Network Regression")

>Type the number of nodes in the hidden layer. For multiple hidden layers, type a comma-separated list.
1ヶ月でAWS 認定ソリューションアーキテクトに合格した話

昨年(2017年)の8月に[AWS 認定ソリューションアーキテクト – アソシエイト](https://aws.amazon.com/jp/certification/certified-solutions-architect-associate/)に合格しました。
ほぼゼロからの勉強でしたが、要点を抑えれば短期間でも合格できたので、やったことを紹介します。

# 1. 前提知識
趣味で触ったことがあるもの。※どれも軽く触った程度

- EC2
- ELB
- S3
- Lambda (試験には出ない)
- API Gateway (試験には出ない)

# 2. 対策内容

## 2-1. [AWS Summit Tokyo 2017 セッション資料・動画](https://aws.amazon.com/jp/summit2017-report/details/)
オススメ度: ★★★★★

一番オススメです。
「試験範囲の動画を見る → 実際にAWS上でやってみる」で大体雰囲気つかめました。
各サービスの「入門」だけで十分だと思います。
(話すペースがゆっくりなので、1.5倍速ぐらいで見ないと眠くなります。)

## 2-2. [AWS Black Belt](https://aws.amazon.com/jp/aws-jp-introduction/)
オススメ度: ★★★★☆

安定の公式資料集です。
そこそこボリュームあるので、自分は理解の浅いサービスに絞って読みました。
(試験範囲の資料は一通り目を通した方が良いのかも?)

## 2-3. 参考書
 - [合格対策 AWS認定ソリューションアーキテクト -アソシエイト](https://www.amazon.co.jp/gp/product/B01LZ2CBKB/ref=oh_aui_d_detailpage_o07_?ie=UTF8&psc=1)

オススメ度: ★★★☆☆

唯一の対策本なので、読んでおいて損はないと思います。
ただ情報量は少なめなので、概要をつかむ程度に使いました。

 - [Amazon Web Services実践入門](https://www.amazon.co.jp/Amazon-Web-Services%E5%AE%9F%E8%B7%B5%E5%85%A5%E9%96%80-PRESS-plus/dp/4774176737/ref=sr_1_1?s=digital-text&ie=UTF8&qid=1503445066&sr=8-1&keywords=aws+%E5%AE%9F%E8%B7%B5%E5%85%A5%E9%96%80)

オススメ度: ★★☆☆☆

ハンズオン形式で進めるので、イメージがつきやすいです。
ただこちらも情報量としては足りてないので、合わせて他の対策も必要です。

## 2-4. [AWS WEB問題集](https://aws.koiwaclub.com/)
オススメ度: ★★★☆☆

無料枠のみ解きました。
本番と似たような問題が出題されるので、そこそこ参考になります。
(何問かは本番とまったく同じ問題でした。運が良かっただけかも?)


## 3-5. それっぽい構成で作ってみる
オススメ度: ★★★★☆

ある程度理解が進んだら、サービスを複数組み合わせて何か作ってみるのがオススメです。
自分の場合は以下の構成で、Hello Worldをブラウザから表示する簡単なものを作りました。

```
 VPC + ELB + EC2 + AutoScaling + CloudWatch + Route53
```

# 3. 結果
正答率(模擬試験): 75%
正答率(実試験): 72%

試験当日は、そこそこ感触が良かったのですが、思ったより点数が伸びず^^;
何はともあれ、一発合格できて一安心でした。

# 4. 感想
- 実際に手を動かすことが一番タメになりました。やってみないとわからないことがけっこうあります。
- ある程度知識が付いた段階で、模擬試験を受けることがオススメです。雰囲気つかめます。
- セキュリティグループとネットワークACLに関する問題が多く出題された気がします。
- とにかく試験会場が暑かった。。。
clasp を SSH 接続して使っているゲストマシン上で使いはじめたときにハマりかけたこと

# これはなに
GoogleAppsScript をローカルで開発するための Google 様謹製 CLI ツール clasp を使いはじめたんだけど、VirtualBox 上のゲストマシンから login するのにハマりかけたので、誰かがハマらないために情報共有するためのもの。
まだ、こういう情報が出まわってなさげだったので。

# TL;DR
1. ホストマシンの localhost:2020 をゲストマシン 2020 にポートフォワーディング
1. ホストマシンのファイアウォールに穴あけ
1. ゲストマシンのファイアウォールに穴あけ

# 経緯
Windows10 をホストマシンとした VirtualBox 上の CentOS 7 機で GAS (Google Apps Script) の開発を始めて数年。今までも
 [gas-master](https://github.com/soundTricker/gas-manager) (やそれを利用して作った自前ツール) を使ってローカル開発をしてきたけれど、Google 先生が CLI ツール clasp を作ってくれたので、使ってみることにしました。ゲストマシンは、ネットワークアダプタを二つ持ち、一方は NAT ネットワーク、他方はホストオンリーアダプタとして接続してあります。

ゲストマシン上で clasp login したら、なにやら認可用の URL が表示されたので、ホストマシン上のブラウザでその URL に飛んでみたら、認証・認可のフローを経て、最終的に localhost:2020 にリダイレクトされました。ああ、clasp が 2020 番ポート開けて待っているのね、と思いました。
待ち受けのポート番号を変えるオプションか環境変数がないかと clasp login のマニュアルを見て探してみましたが、なさそうだったので、ホストマシンの 2020 をゲストマシンの 2020 にポートフォワードするしかないな、と思い至りました。
あとはホストマシンからゲストマシンにパケットが届くよう、ホストマシンのファイアウォールに穴を開け、ゲストマシンで clasp にパケットが届くようにゲストマシンのファイアウォールに穴を開けて解決しました。

clasp clone, clasp pull, clasp push なんかは問題なくできています。
clasp open もできると便利ですけどねぇ。
npmのorganizationアカウント運営 


npmのorganizationアカウントを作成するタイミングがあったので、調べた内容をメモとして残します。

## 0. organizationアカウントとは

企業やプロジェクトなどの組織として、npmのパッケージ管理を行うための仕組み。
組織名をスコープ（namespace）としたパッケージの作成や、有料プランを使用する場合の支払いの一元管理が可能となる。

> Googleのorganizationページ
> https://www.npmjs.com/org/google
>
> @googleをスコープにしたmapsパッケージ
> https://www.npmjs.com/package/@google/maps

## 1. organizationアカウント作成方法

### 1.1 個人アカウントの用意

organizationアカウントは個人アカウントをベースに作成する。
ということで、まず個人アカウントが必要となる。

> 個人アカウント登録ページ
> https://www.npmjs.com/signup

ベースとした個人アカウントが、organizationアカウントの最初のOwnerとなる。
Owner権限は後から別のアカウントに変更可能（それほど慎重に考えなくて良い）

### 1.2 organizationアカウント作成

組織名と料金プランを登録するだけでOK。
登録は個人アカウントページの右下、 [ create an organization ] から行う。

> 個人アカウントページ
> https://www.npmjs.com/~
>
> create an organization 直リンク
> https://www.npmjs.com/org/create

#### 1.2.1 組織名について

登録済みのorganizationアカウント、個人アカウントと重複しない名前のみ使用可能。
ベースの個人アカウント名を組織アカウント名としてコンバートすることも可能。（その場合、ベースの個人アカウント名を新たに付け直すフローになる）

組織名はorganizationページのURLとして使われる。

> 組織ページURLの例
> https://www.npmjs.com/org/組織名

#### 1.2.2 料金プランについて

publicなパッケージの管理なら無料プランでOK。
有料プランでは、privateなパッケージの管理が出来るようになる。

有料プランの月額 : 所属メンバー数 × $7

## 2. メンバーについて

組織メンバーとして個人アカウントを登録することができる。
組織パッケージの管理者は組織メンバーである必要がある。
メンバーの追加はOwner権限のあるアカウントで行う。
ベースとした個人アカウントがOwner権限のメンバーとしてあらかじめ登録されている。

### 2.1 メンバー追加方法

Owner権限のあるアカウントを使用し、organizationページのmembersタブから追加する。
各メンバーの権限もこの画面で設定できる。

### 2.2 権限について

メンバーの権限は3種類

 - Owner
 - Admin
 - Member

|出来ること|Owner|Admin|Member|
|:--|:--:|:--:|:--:|
|パッケージ管理|○|○|○|
|チーム管理|○|○| |
|メンバー管理|○| | |
|料金プラン管理|○| | |

## 3. チームについて

チームという単位で組織メンバーをグループ分けすることが出来る。
組織のパッケージは1つ以上のチームに割り当てられ、そのチームに所属するメンバーに管理権限が与えられる。
チーム作成やメンバー追加は、OwnerかAdmin権限のあるアカウントで行う。

### 3.1 チーム作成方法

OwnerかAdmin権限のあるアカウントで、organizationページのteamsタブから作成する。
チームへのメンバー追加やパッケージ追加もこの画面で行える。

## 4. 組織パッケージについて

組織スコープだけでなく、スコープなしや個人スコープのパッケージも組織管理にすることができる。
それぞれのパターンで手順が若干異なるので簡単にまとめる。

npmの公開手順自体がわからない方はこちらの記事が参考になります。
[3分でできるnpmモジュール](https://qiita.com/fnobi/items/f6b1574fb9f4518ed520)

### 組織スコープのパッケージ登録

 1. package.jsonのnameを`"@組織名/パッケージ名"`にする
 2. 組織メンバーのアカウントで`npm publish`する
    - 有料プランならprivateパッケージとして登録される
    - 無料プランはprivateが使えないので`npm publish --access public`とする
    - 初期チームはpublishしたメンバーの最初のチームになる（publish時に指定する方法が見当たらない・・・）
 3. OwnerかAdmin権限のあるアカウントで、organizationページのteamsタブから任意のチームに管理を移す

### スコープ無しのパッケージ登録
 
 1. package.jsonのnameを`"パッケージ名"`にする
 2. `npm publish`する
 3. publishしたアカウントにAdmin権限を与える
 4. publishしたアカウントで任意のチームにパッケージを登録する（パッケージ公開したアカウントでしか行えない）

### 個人スコープのパッケージ登録
 
 1. package.jsonのnameを`"@個人アカウント名/パッケージ名"`にする
 2. `npm publish`する
    - 個人アカウントが有料プランならprivateパッケージとして登録される
    - 無料プランはprivateが使えないので`npm publish --access public`とする
 3. publishしたアカウントにAdmin権限を与える
 4. publishしたアカウントで任意のチームにパッケージを登録する（パッケージ公開したアカウントでしか行えない）

## 5. 特殊な運用メモ

### Ownerアカウント変更

 1. Owner権限を与えるアカウントを、Owner権限でメンバーに追加する
 2. 追加したアカウントで、元のOwnerを別の権限に変更する

### メンバーの削除

 - Owner権限を与えるアカウントでチーム管理画面から削除できる
 - メンバーが作成したスコープ無しパッケージや個人スコープパッケージは組織に残る



### 組織パッケージの削除

 - スコープ無しパッケージや個人スコープパッケージはチーム管理から外すと作成した個人アカウントの管理に戻る（作成アカウントがメンバーにいないとパッケージが消失したが、バグかもしれない。）
 - 組織スコープのパッケージも個人パッケージと同様、公開から24時間以内は `npm unpublish --force パッケージ名` で物理削除することは可能（それ以降は問い合わせで対応）
[Angular] (EXCEPTION: Expression has changed after it was checked) の対応方法 (Angular2, 4, 5)

`ViewChildren` などを利用すると `ngAfterViewInit` などで変数に値を入れてそれをViewで利用することがある。
この場合、 `html` 内で　`*ngIf="component"` のようにその変数が生成されるまで待ちたいと考えるだろう。

このとき、こんなエラーが `Console` 上に表示される。

```
EXCEPTION: Expression has changed after it was checked
```

どうも、 `ngAfterViewInit()` などで変数を変更したら起きるらしい（Prod mode だと起きないとかなんとか）。
エラーが出るだけで特に問題なく動くのだが、Consoleにエラーが出るのがうざったいので対処方法を記載。

Component側の対処方法↓

```.ts
export class TestComponent {
  @ViewChildren(KoComponents): koComponents: QueryList<KoComponents>;
  ko1: KoComoponent;
  constructor(private changeDetectionRef: ChangeDetectorRef) {}

  ngViewInit(): void {
    this.ko1 = koComponents.toArrays()[0];
    this.changeDetectionRef.detectChanges();
  }
}
```

Viewの例↓

```.html
<div *ngIf="ko1">
  testです。
</div>
```

参考
https://github.com/angular/angular/issues/6005
Atomエディタ:BigQuery SQL シンタックスハイライト・スニペットを適用する

# はじめに
BigQueryのWebUIは、ある程度はSQLを快適に記述できるように実装されています。
しかしながら、エディタとしての使い勝手は決して十分とは言えません。

そこで、AtomエディタでBigQuery SQLのシンタックスハイライトと、スニペットによりコードを補完するパッケージ [`language-sql-bigquery`](https://atom.io/packages/language-sql-bigquery) を作成しました。

この記事では、パッケージの特徴とインストール方法、使い方を簡単に説明します。

# BigQuery SQL Atomパッケージ概要
## パッケージ名・URL
**language-sql-bigquery**
https://atom.io/packages/language-sql-bigquery

## 特徴
- Google BigQuery の SQL をシンタックスハイライトします。
- [標準SQL(スタンダートSQL)](https://cloud.google.com/bigquery/docs/reference/standard-sql/?hl=ja)、[レガシーSQL](https://cloud.google.com/bigquery/docs/reference/legacy-sql?hl=ja)の両方をサポートしています。
- レガシーSQLにしかない関数は、それが分かるように別のハイライトを組み込んでいます。
- コードスニペットは、クエリ(SQL)・DML・DDLの雛形、標準SQLの関数を実装しています。  

# インストール方法
1. Atom > Preferences > Install タブを開いてください。
2. `language-sql-bigquery` を検索してください。
3. Install ボタンをクリックすると、インストールが完了します。

# 使用方法
使い方は簡単です。Grammarを変更するだけで、 `language-sql-bigquery` を利用することができます。

1. メニューより、Edit > Select Grammar を選択してください。  
  - 他の方法
      - ショートカットキー `ctrl-shift-L` があります。
      - ステータスバーをクリックしても選択できます。(`SQL`, `PlainText`などと表示されている右下の箇所です)
2. パレット(入力エリア)から `SQL (BigQuery)` を選択してください。  
   ※`sql`, `bigquery`, `sql big`など一部の文字列を入力するだけで候補が絞り込まれます。
3. ステータスバーに `SQL (BigQuery)` と表示されていることを確認してください。
4. 以上で使用開始できるようになりました。

# 最後に
BigQueryは使い方さえ間違えなければ、安く、簡単にデータを集積し、高速に分析することができます。
データウェアハウス(DMP、最近はCDPなんて呼ばれますね)のプラットフォームでお悩みの方には、自信を持ってお勧めできるプロダクトです。
(もちろん、BigQueryが最善かは、ビジネス要件・技術要件などと照らし合わせて、決めるべきなのは承知の上!)

BigQueryをお使いの方は、是非、このAtomパッケージをお使いいただけるとうれしいです!
alpineのイメージでAWS Lambda用のgoバイナリをビルドしたらPathErrorになった話

タイトルままですが

[AWS Lambda での Go サポート開始](
https://aws.amazon.com/jp/about-aws/whats-new/2018/01/aws-lambda-supports-go/)
を見て、喜び勇んで、いままでapexでデプロイしていたツール系のlambdaを書き換えました。

いざデプロイして実行してみたところエラーが

```
fork/exec /var/task/bin/main: no such file or directory: PathError
```

デプロイに使ったzipの中を何回見てもそこにバイナリあるし、なんだろう。。。


早々に諦めて内村さまぁ〜ずの人間ドッグ2017を見ている時にふと気が付きました。

```
＿人人人人人人人人＿
＞　dynamic link　＜
￣Y^Y^Y^Y^Y^Y^Y￣
```

ビルドには[go-alpine](https://hub.docker.com/_/golang/)のイメージを利用していました。
これはnetパッケージ周りのアレだろうと思い下記のようにビルドコマンドを変更してデプロイ。。。！


```
GOOS=linux go build -x -ldflags '-s -w' -o ./bin/main main.go
```

```
GOOS=linux go build -x -ldflags '-d -s -w' -a -tags netgo -installsuffix netgo -o ./bin/main main.go
```

リクエスト実行。。。！

```
＿人人人人人＿
＞　200 OK　＜
￣Y^Y^Y^Y￣
```

ちょっと古いですが同じような感じの[issue](https://github.com/docker-library/golang/issues/152)が。

同僚がやっている`Rubber Duck Debugging`みたいなかんじで
僕は`内村さまぁ〜ずタイム`をもうけようとおもいました。

完
AngularのViewChildrenが動かない時に確認すべきこと (Angular2, 4, 5)

`ViewChildren` は、  `ViewChild` と違い、 `AfterViewInit` の前に作成される。
そのため、 `ngOnInit` で取得しようとしても動かない。
ハマりどころなので注意。

公式ドキュメントに書いてはあるんだけど、見逃す。
https://angular.io/api/core/ViewChildren


# 使い方
```
export class TestComponent implements OnInit, AfterViewInit {
  @ViewChildren(KoComponent) koComponents: QueryList<KoComponent>;

  ngOnInit(): void {
    const test = this.koComponents; // -> null
  }

  ngAfterViewInit(): void {
    const test = this.koComponents; // -> 値が入ってる
  }
}
```

注意しましょう。
DockerでPython3.6の環境構築！matplotlibインストールで詰まった話とかも

## DockerでPython3.6環境構築！

前使っていたMacのPython環境が行き当たりばったりのインストールで
よくわかんなくなってしまったので、最近はやりのDockerとやらを試してみた。

まずは本家サイトからダウンロード。僕はStableの方を入れました！
> https://docs.docker.com/docker-for-mac/install/

下記コマンドでダウンロードできたか確認。

```
$ docker --version
Docker version 17.12.0-ce, build c97c6d6
$ which docker
/usr/local/bin/docker
```

いーね。

## Docker Hubからイメージを入手

Dockerは実行環境や操作方法をまとめて1つのパッケージにし、それを「Dockerイメージ」として保存／配布している。
今回は公式がだしてる```library/python```を引っ張ってくる。```docker pull python:<バージョン>```で指定のPythonのイメージをもってこれる。僕は3.6が使いたかったので、下記を実行。新幹線の中だったからちょっと時間かかった。

```
$ sudo docker pull python:3.6
3.6: Pulling from library/python
f49cf87b52c1: Pull complete
7b491c575b06: Pull complete
b313b08bab3b: Pull complete
51d6678c3f0e: Pull complete
09f35bd58db2: Pull complete
0f9de702e222: Pull complete
73911d37fcde: Pull complete
99a87e214c92: Pull complete
Digest: sha256:98149ed5f37f48ea3fad26ae6c0042dd2b08228d58edc95ef0fce35f1b3d9e9f
Status: Downloaded newer image for python:3.6
```

成功したっぽい。```docker image ls```で確認できる

```
$ docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
python              3.6                 c1e459c00dc3        6 weeks ago         692MB
```

おお、サイズも。いつ作られたかも見れる。

## コンテナ起動

さっそくコンテナを起動する。```--name <コンテナ名前>```のオプションでコンテナに名前つけれます。

```
docker run -it --name pytest python:3.6 /bin/bash
```

はいれた！！pythonがちゃんと3.6使えるのか確認

```
# python --version
Python 3.6.2
```

おお、Python2.7系しか入ってなかったのに、3.6が使えるぞ！
今までpyenvでやらなんやらで行ってたので、これは楽かも。

```
# pip --version
pip 9.0.1 from /usr/local/lib/python3.6/site-packages (python 3.6)
```

ついでにpipもはいってた。ざす。
pipでnumpyやらなんやらいれてもホスト環境が汚れることはありません。

## Vimのインストール
Docker | docker コンテナの中で vim が使えない！ってなった。基本僕は簡単なコードならvimで編集してたので、入れとく。

```
# apt-get update
# apt-get install vim
```

これでvimが使える様になった。

## いざPython実行

早速、pythonのコードを書いて実行しよう。
/home/test.pyを作る。

```
# cd home
# vi test.py
```

コードは以下の通り
ちなみに```a```押すと入力モードに入り、ESCキー押して```:qw```で保存終了できる

```python:test.py
#-*- coding: utf-8 -*-
print("hello, python3.6")
```

これでいざ実行！

```
# python test.py
hello, python3.6
```
ログでた。よろしい。

## 終了するには
ホスト環境戻るには下記コマンド。

```
# exit
```

実際にPython3.6が本当にコンテナ上だけのものだったのかをホスト環境で確認してみた。

```
$ python --version
Python 2.7.10
```

戻ってる！俺たち、元の世界に戻ってきたんだ！！

## 再びコンテナ起動

再びコンテナに入りたいときは```docker exec```使います。

```
# docker exec -it pytest /bin/bash
```

## matplotlib インストールで "no display name and no $DISPLAY environment variable"
ちょっとつまづいたので、共有しとく。matplotlibを使ったスクリプトを実行したら下記のエラーが出た

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

matplotlibnの設定をいじる必要があるそう。以下で設定ファイルさがす。

```
# find / -name matplotlibrc
/usr/local/lib/python3.6/site-packages/matplotlib/mpl-data/matplotlibrc
```

でてきた。こいつの中身を開いて

```
backend : TKAgg
```

を

```
backend : Agg
```

に変えてあげる。僕は ```matplotlibrc```の41行目くらいにあった
これでエラーが消えました。

以上です。
偏差値の計算をプログラミング（js）で実装する。

前回 [Σ（シグマ）の計算をプログラミング（js）で実装する](https://qiita.com/k28/items/ca29b1fbb223ac684e8b)という記事をかいたのでそれを基に偏差値を求めてみる。

#偏差値の数式
```math
T_i= \frac{10(x_i - μ_x)}{σ_x} + 50
```

色々見慣れぬ記号が出てきましたがひとつづつ確認していきます。

#個々の値（標本値 / データ配列）
```math
x_i
```
xが求めたいデータ群（配列）になり、iはその対象データの指定を表しています。

この記事では例として下記のような10個のデータを準備します。

```javascript
var x = [10,35,60,0,100,90,45,50,20,80];
```


#平均
```math
μ_x
```
これが平均を表します。
(ミューと読みます。)

## 平均を求める数式
```math
μ_x=\frac{1}{n}\sum_{i=0}^nx_i
```
iが0から始まりn回繰り返されます。
ここでいうn回とはデータの個数となるので10回になります。
最終的に1/nで掛けます。
小難しく書いてありますがただの平均なので要は全部足して足した個数で割るだけです。

## 平均を求めるコード
```javascript
function average(x) {
	var n = x.length;
	var avg = 0;
	
	for(i=0; i<n; i++) {
		avg += x[i];
	}

	return avg / n; //  (1 / n * avg)
}

(function() {
	let x = [10,35,60,0,100,90,45,50,20,80];
	let avg = average(x);

	console.log(avg);
})()
```

#標準偏差

```math
σ_x
```
これが標準偏差を表します。
（シグマと読みます。小文字版です。）

##標準偏差を求める数式

```math
σ_x=\sqrt{\frac{1}{n}\sum_{i=0}^n(x_i-μ_x)^2}
```
今までの要領でシグマを求め最後に平方根を求める。

##標準偏差を求めるコード

```javascript
function average(x) {
	//↑にあるのでここでは省略
}

function standardDeviation(x, avg) {
	let n = x.length;
	let sum = 0;
	for (i=0; i<n; i++) {
		sum+=Math.pow(x[i] - avg, 2);
	}

	return Math.sqrt(sum / n);
}

(function() {
	let x = [10,35,60,0,100,90,45,50,20,80];
	let avg = average(x);
	let sd = standardDeviation(x, avg);

	console.log(sd);
})()
```

#偏差値を改めて求める
```math
T_i= \frac{10(x_i - μ_x)}{σ_x} + 50
```

ここで定義した「データ配列」、求めた「平均」、「標準偏差」をあてはめます。

##偏差値を求めるコード
```javascript
function average(x) {
	let n = x.length;
	let avg = 0;
	
	for(i=0; i<n; i++) {
		avg += x[i];
	}
	return avg / n; //  (1 / n * avg)
}

function standardDeviation(x, avg) {
	let n = x.length;
	let sum = 0;
	for (i=0; i<n; i++) {
		sum+=Math.pow(x[i] - avg, 2);
	}
	return Math.sqrt(sum / n);
}

function standardScore(x, avg, sd) {
	let ssArr = [];
	let n = x.length;
	for (i=0; i<n; i++) {
		let ti = (10 * (x[i] - avg) / sd) + 50;
		ssArr.push(ti);
	}
	
	return ssArr;
}

(function() {
	let x = [10,35,60,0,100,90,45,50,20,80];
	let avg = average(x);
	let sd = standardDeviation(x, avg);
	let ssArr = standardScore(x, avg, sd);

	console.log("平均: " + avg);
	console.log("標準偏差: " + sd);
	console.log("x[2]の偏差値: " + ssArr[2]);
})()
```

#参考
[Wikipedia: 偏差値](https://ja.wikipedia.org/wiki/偏差値)
BIG-IP ve Device Trustを確立しよう（失敗編）

# はじめに
前回の方法でAWS上にBIG-IP veを2台デプロイしました。ここからHAの設定をしていきたいのですが、そのためにはBIG-IP同士がお互いを認識する必要があります。そのために必要な設定をしていきます。

バージョンは13.1.0.2です。

# アドレスの確認
HAを構成したい個々のBIG-IPをDevice、Device同士がお互いを認識することを「Device Trustを確立する」と表現します。Trustを確立するためにはまずお互いのIPアドレスを知る必要があります。
Trustに使うIPアドレスは、アプライアンスでは実通信に利用しないManagement IPを、AWSでは適当なPrivate IPを指定することが推奨されています。

参考資料：https://support.f5.com/kb/en-us/products/big-ip_ltm/manuals/product/bigip-system-device-service-clustering-administration-13-1-0/3.html

今回はAWSですので、デプロイ時に作ったNICのIPアドレス10.0.4.11および10.0.4.12を使いましょう。

# NTP同期状態の確認
AWSではあまり意識する必要がありませんが、Deviceが正しい時刻を持っていないとTrustを確立できません。NTP同期状態は念のため確認しておきましょう。

```
[admin@ip-10-0-4-11:Active:Standalone] ~ # ntpq -np
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
*127.127.1.0     .LOCL.          10 l   53   64  377    0.000    0.000   0.000
[admin@ip-10-0-4-11:Active:Standalone] ~ # 
```

# コンフィグ同期用アドレスの設定……のはずだった
Trust確立の前提として、自分にコンフィグ同期用IPアドレスを設定しておく必要があります。このIPアドレスには適当なPrivateアドレスを使うことが推奨されています。

メニューから「Device Management」＞「Devices」＞自分のデバイスを選択します。続いて上のメニューで「ConfigSync」を選び、Local AddressのIPをドロップダウンから選択します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/126284/8036ec8f-33a8-e328-7a5d-c37ecc0032a0.png)

「Update」を押して完了です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/126284/dd44569f-59dc-364b-3137-891875801443.png)

あ、あれ……。駄目ですか。AWSならいけるかと思ったのですが、アプライアンスと同じManagement IPでは駄目なようです。

残念ながらここで時間切れになってしまったため、来週リベンジします。
【Drupal8】カスタムモジュールの作成手順

### 【概要】
Drupal8で簡単なカスタムモジュールを一つ作成します。

### 【目標】
画面に、「Hello!」と表示させること。

完成したときのモジュール構造は以下の通りです。

```html:モジュール構造
Drupal/　←　プロジェクト名
     ├ modules/
            └ hello/
                  ├ hello.info.yml
                  ├ hello.routing.yml
                  ├ hello.module
                  └ src/
                      ├ HelloController.php 
```

## 1. カスタムモジュール用のディレクトリを作成
モジュールのファイル一式を格納するディレクトリを作成します。

Drupalプロジェクトの`modules`ディレクトリ配下に、
カスタムモジュール用のディレクトリを新規作成します。
今回は`hello`を作成します。

```html:モジュール構造
Drupal/
     ├ modules/
            └ hello/
```
## 2. モジュールのメタ情報ファイルを作成
1で作成したディレクトリ内に、
モジュールのメタ情報を記述する「モジュール名.info.yml」ファイルを作成します。
今回のファイル名は`hello.info.yml`になります。

作成したファイル内に以下のように記述します。

```haml:hello.info.yml
name: my first custom module.
type: module
description: 'This is my first module.'
core: 8.x
```

このようにメタ情報ファイルを作成することで、
Drupalがこのモジュールの認識をしてくれるそうです。

## 3.モジュールの本体ファイルを作成
モジュールのコアとなる「モジュール名.module」ファイルを作成します。
今回のファイル名は`hello. module`になります。

今回は「Hello!」を表示するページを作成する上ではこのファイルは使用しないので、
中身は空のままで進めます。

## 4.コントローラーファイルを作成
今回は、`src`ディレクトリを新規作成し、
その配下に`HelloController.php`を作成します。

作成したファイルに以下のように記述します。

```php:HelloController.php
<?php

namespace Drupal\hello;

use Drupal\Core\Controller\ControllerBase;

/**
 * Hello!を表示するコントローラー
 */
class HelloController extends ControllerBase {

  public function content() {
    return array(
        '#markup' => '' . t('Hello!') . '',
    );
  }

}
```

## 5. モジュールのルーティング情報ファイルを作成
ルーティング情報ファイル用の「モジュール名.routing.yml」ファイルを作成します。
ルーティング情報ファイルは、特定のパスにアクセスした時に、
特定のコントローラーを利用させるように設定するファイルです。
今回は、`hello.routing.yml`になります。

作成したファイルに以下のように記述します。

```html:hello.routing.yml
hello:
  path: '/hello'
  defaults:
    _title: 'Hello Title'
    _controller: '\Drupal\hello\HelloController::content'
  requirements:
    _permission: 'access content'
```

ファイル内の説明

```html:
・ hello: そのルーティング設定の名前
・ path: 対象とする URL パスの指定
```

この設定により、そのDrupalサイトの`/hello`というパスにアクセスをすると、
4で作成した`HelloController.php`内の`HelloController::content`メソッドが対応するようになります。

## 6.モジュールをインストール
Drupalサイトにアクセスします。
管理画面からタブ「拡張機能」を選択すると、モジュールの一覧が表示されるので、
その画面から今回作成したカスタムモジュールをインストールします。

今回は、`my first custom module.`というモジュールを作成したので、
モジュールの横にあるチェックボックスにチェックを入れて、画面の一番下の「設定を保存」をクリックします。

以上で、有効化が完了になります。


最後に、ブラウザからパス`/hello`にアクセスして今回作成したページに「Hello!」と無事表示されるか確認をしましょう。

無事表示されれば、モジュール作成完了になります。
Processingで久しぶりにSimpleOpen NIを使った時の話

2018年，Processingでkinect使った作品を作ろうと思い，久しぶりにSimpleOpenNIを触ったら動かなぃ，，，

でも，なんやかんや動かせたので共有します．

# 環境
- MacOSX Sierra
- Processig3.3.5

# 結論
import Libraryから入れ直してみたり，.jarファイルを入れ替えてみたりしたけどだめだった．
けど，[totovr](https://github.com/totovr)さんがProcessing3.3.6ようにライブラリを作ってくれていました．(マジ感謝)

[SimpleOpenni](https://github.com/totovr/SimpleOpenni/tree/Processing_3.3.6)からダウンロードしてライブラリに入れれば動きました．

# 参考
[totovr/SimpleOpenni](https://github.com/totovr/SimpleOpenni/tree/Processing_3.3.6)
自分がよくつかうボードの環境設定

備忘録としてめも

##ArduinoIDEでArduino nano互換使うとき

「Arduino nano 互換 OSの名前 ドライバー」とかで検索すると親切なインターネット上の先輩方の情報がみつかるとおもいまっす！
ドライバのインストールが完了して、認識するようになったら
ArduinoIDE→ツール→ボード→Arduino Nano
をえらんで書き込み準備オッケー

Macの新しめの機種使っててうまく認識しない場合には、接続するUSBの口を変えてみるか
USB2.0対応のUSBハブを接続してハブにつなげると認識しやすくなるかも。

##ArduinoIDEでdigisparkのボード使うとき
大雑把にいうとWindowsの場合には
①ドライバをダウンロードしてインストールする
https://github.com/digistump/DigistumpArduino/tree/master/tools
②ArduinoIDEを起動し、ファイル→環境設定→「追加のボードマネージャのURL」に
http://digistump.com/package_digistump_index.json
をコピペで追加して「OK」ボタンで環境設定を閉じる
③ツール→ボード→ボードマネージャをクリック
④検索窓をクリックし、タイプの項目で「提供された」を選択
「Digistump AVR Boards」を検索し、検索結果をクリックして「インストール」をクリック
⑤インストール後、ツールから
ボード：Digispark(Default - 16.5mhz)
をクリックで選択して書き込み準備オッケー
android.media.Imageを別形式に変換する


## ImageからFile


```
fun run(image: android.media.Image, file: File) {
    val buffer = image.planes[0].buffer        
    val bytes = ByteArray(buffer.remaining())
    buffer.get(bytes)
    var output: FileOutputStream? = null
    try {
        output = FileOutputStream(file).apply {
            write(bytes)
        }
    } catch (e: IOException) {
        Log.e(TAG, e.toString())
    } finally {
        image.close()
        output?.let {
            try {
                it.close()
            } catch (e: IOException) {
                Log.e(TAG, e.toString())
            }
        }
    }
}
```

- imageはJPEGの場合
- `image.planes[0].buffer` でByteBufferを取得する。
- ByteArrayで必要なバイト列をとって、ファイルに書き出している。

## ImageからMat

```
Image image = reader.acquireLatestImage();

Mat buf = new Mat(image.getHeight(), image.getWidth(), CvType.CV_8UC1);

ByteBuffer buffer = image.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
buf.put(0, 0, bytes);

Mat mat = Imgcodecs.imdecode(buf, IMREAD_COLOR);

image.close();
```

- ImageはJPEG形式の想定
- imageのheight/widthでMatを初期化する。
- CV_8UC1は8bit,unsighed,1チャンネル（グレースケール）の画像
- IMREAD_COLORはデフォルト値と同じ指定

## ImageからMat（YUV）

https://gist.github.com/camdenfullmer/dfd83dfb0973663a7974
【勉強メモ】postgresql実行計画についてまとめ【随時更新】

実行計画を知ることで得られること
------
 * 発行するクエリがどれくらいの時間で処理されるかわかる
    * SQLのダメなところが見える
    * 発行対象のテーブルがばかでかいテーブル(レコード数や行サイズ)の場合の検知

実行計画とは
-------
postgresが算出した、一番時間がかからないクエリ実行手順のこと

一つのクエリ実行(結果)を出すための実現方法(手順)は多数存在する。postgres内部では対象のテーブルの状態(統計情報)を参照して、 **実行時点で一番時間のかからないクエリ実行になる実現方法はなにか**、という最適化問題を解いている。 このpostgresが算出した最適な実現方法(手段)をpostgresでは「実行計画」と呼んでいる。  

実行計画の仕組み
-------
 - 発行するクエリを「ノード」というサブ実行単位に分割され、ツリー構造で表現する
 - ツリーの葉から根に向かって順次実行

### ノードの種類は大きく三種類

 1. スキャンノード(テーブル内の情報を探索する)
 2. 結合ノード(文字通りテーブルの結合)
 3. 加工ノード(文字通り)


ノード
-------
### 1. スキャンノード(テーブル内の情報を探索する)
 - seq scan
 - index scan

シーケンススキャンの場合、テーブルのレコード1行1行を読み込んで、条件式(WHERE)などがあればそれを逐一実行する

インデックスが貼られていれば、条件式を評価する前に、indexでレコードを絞ってから、条件式を評価する。シーケンススキャンをしていれば、条件式の実行はレコード数分だが、インデックスが貼られていれば一回ですむ可能性もある。
つまり一般的には処理が早い。


### 2. 結合ノード(文字通りテーブルの結合)
三種類ある
 1. 入れ子ループ結合

    - 外側テーブルの1行に対して内側テーブルの全レコードをなめる素直な方法
    - みたからに時間はかかりそうだが、外側テーブルがレコード少ない＆内側テーブルにシーケンス貼ってある　場合はかなり高速らしい
 2. ハッシュ結合

    - まず内側テーブルの結合キーに対してハッシュを算出
    - 算出したハッシュはメモリ上に置かれる、そのためメモリがないと遅くなる
 
 3. マージ結合

    - 両方のテーブルを結合キーでソートしてその順番で評価する
    - 事前にソートするのでそのオーバーヘッドはある、が結合キーがそもそもソートしていたらうまく動いてくれる

### 3. 加工ノード(文字通り)
 - 文字通り、とかいたもののイメージはわいていない。。。


参考文献
------
 - 内部構造から学ぶPostgreSQL 設計・運用計画の鉄則
   - http://amzn.asia/0gSfg3V
MediatorLiveDataとカスタムTransformation

LiveDataのサブクラスにMediatorLiveDataというものがあります。
MediatorLiveDataは別のLiveDataを監視して自身の値を変更するLiveDataです。
[公式のサンプルリポジトリ](https://github.com/googlesamples/android-architecture-components)に幾つかの用例を見ることができます。

TransformationsはLiveDataの値の変形や別のLiveDataに変換することができるクラスです。Transformationsはその実装にMediatorLiveDataを使用していて、独自のトランスフォーメーションを作成したい場合、同じようにMediatorLiveDataを使って実装することができます。

```Sample.kt
fun <T1, T2, S> combineLatest(source1: LiveData<T1>, source2: LiveData<T2>,
                              func: (T1?, T2?) -> S?): LiveData<S> {
    val result = MediatorLiveData<S>()
    result.addSource(source1, {
        result.value = func.invoke(source1.value, source2.value)
    })
    result.addSource(source2, {
        result.value = func.invoke(source1.value, source2.value)
    })
    return result
}
```

- [MediatorLiveData | Android Developers](https://developer.android.com/reference/android/arch/lifecycle/MediatorLiveData.html)
- [Transformations | Android Developers](https://developer.android.com/reference/android/arch/lifecycle/Transformations.html)
Ubuntu 16.04 のインストール

Linux学習のために環境構築します。
USBメモリーを使って、Ubuntuをインストールするところまで

今回、使用する機器：インテル NUC / Model:DN2820FYK

---

# Windows上での用意
インストール用のUSBメモリーを用意する

1. USBメモリーにIOSイメージを保存するため、今回は[Rufus](http://rufus.akeo.ie/)を利用、[Rufus 2.18](http://rufus.akeo.ie/downloads/rufus-2.18.exe)をダウンロード
2. [Ubuntu Japanese Team](https://www.ubuntulinux.jp/)の Ubuntu Desktop 日本語 Remix を利用、[ubuntu-ja-16.04-desktop-amd64.iso（ISOイメージ）](http://cdimage.ubuntulinux.jp/releases/16.04/ubuntu-ja-16.04-desktop-amd64.iso)をダウンロード
3. rufus-2.18を起動
    1. IOSイメージで「ubuntu-ja-16.04-desktop-amd64」を選択<br>
    <img width="341" alt="Rufus.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/234144/cda9cd37-85d1-2d40-9b0f-cfe05c590f9b.png"><br>
    2. ポップアップで「はい(Y)」を選択<br>
    <img width="310" alt="Rufus_hopup.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/234144/6ce587f1-50b8-774c-b019-14e69af925a4.png"><br>
    3. ポップアップで「IOSイメージモードで書き込む(推奨)」を選択しOKをクリック<br>
    <img width="352" alt="Rufus_hopup2.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/234144/02f5360a-21d1-1e58-a8b4-06a03e25d6c8.png"><br>
    4. ポップアップの警告でOKをクリック<br>
    <img width="305" alt="Rufus_hopup3.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/234144/5d99645b-ecdb-b2f2-7d02-381b5a32ac11.png"><br>
    5. 準備完了となったら「閉じる」をクリック<br>
    <img width="341" alt="Rufus_hopup4.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/234144/68dbc4f9-8ef5-e961-2f4b-1d4b48b927b6.png"><br>
4. USBを取り外して終了

---

# 機器上での操作
USBメモリーをセットして電源を入れる

```ruby:BIOS
F2 to Enter Setup
F7 to Update BIOS
F10 to Enter Boot Menu
```

1. `F10`を押して、Boot Menu画面へ進む
2. ↑↓で「USB」を選んでEnter(Select)
3. 日本語を選び、「Ubuntuをインストール」をクリック
4. 「グラフィックス、Wi-Fi機器、Flash、MP3やその他のメディアに必要なサードパーティーソフトウェアをインストールする」を選択して「続ける」をクリック
5. 「ディスクを削除してUbuntuをインストール」を選択して「インストール」をクリック
6. 「ディスクに変更を書き込みますか？」の警告に「続ける」をクリック
7. 「どこに住んでいますか？」に「Tokyo」を選択して「続ける」をクリック
8. 「キーボードレイアウト」で「日本語 - 日本語(かな86)」を選択して「続ける」をクリック
9. 「あなたの情報を入力してください」

```
あなたの名前：haru
コンピューターの名前：haru-desktop
ユーザー名の入力：haru
パスワードの入力：*****
パスワードの確認：*****
```

「自動的にログインする」を選択して「続ける」をクリック(＊)
10. 「インストールが完了しました」で「今すぐ再起動する」をクリック

（＊：学習用途なので、利便性を求めてWi-Fi経由でSSHログインしたい。
デフォルトでは、ログイン前には Wi-Fi接続が されないため、自動ログインを選択します。
設定による回避策はあるようだが、学習がすすんだら 追々修正を考えよう。）

おしまい

---

参考にしたHP
[Ubuntu の日本語キーボード レイアウト](https://sites.google.com/site/tetsuroweb/home/software/ubuntu/tips/japanese-keyboard-layout)
Intel NUC の BIOSアップデート

Linuxの勉強を思い立ち、以前購入したIntel NUCを引っ張り出してきた。
折角なので、BIOSのアップデートから取りかかる。

今回、使用する機器：インテル NUC / Model:DN2820FYK

---

- Windows上での用意

1. [FY0061.BIO](https://downloadcenter.intel.com/downloads/eula/27468/BIOS-Update-FYBYT10H-86A-?httpDown=https%3A%2F%2Fdownloadmirror.intel.com%2F27468%2Feng%2FFY0061.bio)をダウンロード
2. 念のため、USBメモリーを一度フォーマット
3. USBメモリーに「FY0061.bio」をコピー
4. USBを取り外して終了

---

- 機器上での操作

USBメモリーをセットして電源を入れる

```ruby:BIOS
F2 to Enter Setup
F7 to Update BIOS
F10 to Enter Boot Menu
```

1. `F7`を押して、Bios Flash Update画面へ進む
2. 「Mass Storage Device」をEnter(Select)
3. 「FY0061.bio」をEnter(Select)
4. 「Are you sure you wish to update to BIOS with FY0061.bio?」をEnter(Yes)

再起動し、BIOSアップデートが自動進行する。

```ruby:BIOS
Flashing motherboard firmware:
Current revision: ***
Updating to revision: FYBYT10H.86A.0061.2018.0109.1107

*****
```

BIOSアップデートが終わると、再び再起動する。

おしまい

---

参考にしたHP
[インテル NUC の BIOS をアップデートする方法](https://www.intel.co.jp/content/www/jp/ja/support/articles/000005636/mini-pcs.html)
[Downloads for IntelR NUC Kit DN2820FYKH](https://downloadcenter.intel.com/product/78953/Intel-NUC-Kit-DN2820FYKH)
[BIOS Update [FYBYT10H.86A]](https://downloadcenter.intel.com/download/27468/NUCs-BIOS-Update-FYBYT10H-86A-?product=78953)
PowerShellでCSVを縦横変換する

#PowerShellでCSVを縦横変換する

データ分析の際に使用するので、備忘録として...

横に並んだ配列を...

```PowerShell
$csv = @(Get-Content in.csv )
$csv
a,b,c,d,e
1,2,3,4,5
```

縦に変換します

```PowerShell
for($i=0; $i -lt 5; $i++){$csv[0].Split(",")[$i] + "," + $csv[1].Split(",")[$i]}
a,1
b,2
c,3
d,4
e,5
```

CSVに出力します

```PowerShell
for($i=0; $i -lt 5; $i++){Add-Content –Path "out.csv" -Value ($csv[0].Split(",")[$i] + "," + $csv[1].Split(",")[$i])} 
```

職人的ではありませんが、素人でもわかるスクリプトだと思います
sedでxmlを処理する（<>を消したい)

#やりたいこと

owncloud使ってて、APIからPROPFINDしたときに返ってくるXMLから情報を引き出したい
<?xml version..>
などを消し去り、データだけを取り出したいのよ。うん。


#何故sed??
いやただ単になんとなく。
shellscriptからいじってるからです〜

#1.指定パターンの削除

これは簡単で、

```shell
$sed -e 's/消したい文字列//g' <ファイル名>
```

ってすればいい。

#2.パターンを書く

これが割とめんどくって。
パターンについて詳しく/一覧はこちらの「[sedでこういう時はどう書く？](https://qiita.com/hirohiro77/items/7fe2f68781c41777e507)」がわかりやすかったです。

また、これを書くにあたって一番参考にさせていただいたのがこちらの「[ワンライナーでお手軽実行可能なsed入門](https://qiita.com/muran001/items/472abcfc353d5df7b77a#最短マッチさせる)」の「最短マッチさせる」のトピック。

で、一応出来上がったのが

```shell
's/<[^>]*>//g'
```

これは、`<`と`>`で囲まれたものを全て消去する


# パターン解説

```shell
s/<[^>]*>//g
```

| パターン | 意味/役割 |
|:-:|:-:|
|  [] | 文字クラス？というらしい。`[a-z]`ならaからzまでの文字のどれか  |
| []内の ^  |  続く文字**以外の文字**を指定す流。`[^>]`は`>`以外の文字のこと |
|  * | 前のパターンの繰り返し。今回は `[^>]`を何度も評価する |

言葉で説明（ラフ）すると

`s/` -- 置換する設定にする
`s/<`  -- `<`で始まり、
`s/<[^>]...` -- `>`以外の文字のうちのどれか一つの
`s/<[^>]*` -- 0回以上の繰り返し
`s/<[^>]*>` -- の後ろが、`>`で閉じられているもの。
`s/<[^>]*>` -- つまり、`<`で始まり、`>`以外の文字のうちのどれか一つの0回以上の繰り返しの後ろが`>`で閉じられている、文字列にマッチするわけだ。
`s/<[^>]*>//` -- `//`で置換後の文字をなくすことによって、先のパターンにマッチするものを文字のないものに変換＝消す。
`s/<[^>]*>//g` -- `g`をつけて全てのパターンにマッチする部分を置換する。


...最後の方パターン解説ではない気もしたけどまあいいか


# まとめ

`<...>`を削除するには、

```shell
$ sed -e 's/<[^>]*>//g' <ファイル>
```
でおk！！

ちなみに`"..."`を消したければ

```shell
$ sed -e 's/"[^"]*"//g' <ファイル>
```
etc...


#参考にさせていただいた投稿

* sedのチートシート的な！ -> [sedでこういう時はどう書く？](https://qiita.com/hirohiro77/items/7fe2f68781c41777e507)
* 応用テク等が便利 -> [ワンライナーでお手軽実行可能なsed入門](https://qiita.com/muran001/items/472abcfc353d5df7b77a#最短マッチさせる)
python にとても長い式を食べさせると死ぬ

[整数を419378回インクリメントするとMacのg++が死ぬ](https://qiita.com/kaityo256/items/6b5715b213e955d44f55)
や
[C++でアスタリスクをつけすぎると端末が落ちる](https://qiita.com/kaityo256/items/d54439246edc1cc58121)
にインスパイアされて。

python で

`(((((1)))))`
`[[[[[1]]]]]`
`1+1-1+1-1+1-1+1-1+1-1`
`aaaaaaaaaaaaaaaa=1`

のような式を食べさせて、どれぐらいで死ぬのか調べてみた。

環境は macOS High Sierra。メモリ 16GB。
python は、Python 3.6.3。
測定には ruby 2.5.0 を使った。

ruby 自体については調査済み。[ruby にとても長い式を食べさせると死ぬ](https://qiita.com/Nabetani/items/5d62ff62ffaf4c556989) を参照のこと。

#`(((((1)))))`

```ruby:ruby2.5
a = [*1..20000]
p(a.bsearch do  |n|
  s="print"+"("*n+"1"+")"*n
  puts "#{n}"
  "1" != %x( python3.6 -c "#{s}" ).strip
end)
#=>93
```

100に届かないとは。意外と弱い。
出るエラーは
> `s_push: parser stack overflow`
> `MemoryError`

`s_push` の辺りに苦しみが表現されているのかも。

#`[[[[[1]]]]]`

```ruby:ruby2.5
a = [*1..20000]
p(a.bsearch do  |n|
  s="print("+"["*n+"1"+"]"*n+")"
  puts "#{n}"
  begin
    %x( python3.6 -c "#{s}" ).empty?
  rescue
    true
  end
end)
#=>92
```

先ほどのとは括弧の数え方が違うので、状況としては同じ。括弧の種類とは関係なく、100個弱で死ぬ模様。
出るエラーも同じ。

#`1+1-1+1-1+1-1+1-1+1-1`

```ruby:ruby2.5
a = [*1..20000]
p(a.bsearch do  |n|
  s="print(1+"+"-1+1"*n+")"
  puts "#{n}"
  begin
    %x( python3.6 -c "#{s}" ).empty?
  rescue
    true
  end
end)
#=>1499
```

括弧と比べてだいぶ頑張ったが、ruby と比べるとだいぶ少ない。
出るエラーは

> `RecursionError: maximum recursion depth exceeded during compilation`

コンパイルに失敗しているらしい。

# 長い変数名

```ruby:ruby2.5
a = [*1..100000000]
p(a.bsearch do  |n|
  File.open( "hoge.py", "w" ){ |f| f.puts( "a"*n+"=1" ) }
  puts "#{n}"
  begin
    %x( python3.6 hoge.py )
    false
  rescue
    true
  end
end)
#=> nil
```

1億文字まで試したけど、大丈夫だった。
所詮文字列いくらでも来い、という感じなんだろう。

# まとめ

括弧100個で死ぬというのは、機械が生成したコードだとわりと引っかかるんじゃないかと思ったけど、どうなんだろう。
まあ人間が書いたコードだと問題ないだろうけど。