OmniAICreator/Qiita-1.07M huggingface dataset:
Qiita検索を作ってみた


これは [Supership株式会社 Advent Calendar 2018の24日目の記事](https://qiita.com/advent-calendar/2018/supership)です。

メリークリスマス🎄
Supership株式会社の池田です、S4/S4Adsの開発に携わっております。

一応、業務で検索サービスを開発しておりますので、今回は
Qiitaの記事検索を作ってみました。

# Qiita検索を作ってみた

これです↓
http://qiita-search.ap-northeast-1.elasticbeanstalk.com/
~~来月前半くらいまでの期間限定で稼働予定です。~~ (2019年1月17日 停止しました）

基本的には直近1年くらいのQiitaの記事を[Qiita API v2](https://qiita.com/api/v2/docs)より取得しております。(30分毎更新)

突貫で作ったのでだいぶ雑ですが、
本家の検索よりも直近盛り上がったものを重視しておりますのでAdvent Calendarの記事を漁るのに役立つのではないでしょうか。 
是非、年末年始暇な時のAdvent Calendar漁り活用してください。

今回使った技術、システムの解説等は いいね! がいっぱい付いたら別途記事にしますw
気になった方は いいね! お願いします!


[Supershipでは一緒に働く仲間を募集しています](https://supership.jp/recruit/)
[Supership Search Solution（S4） - サイト内検索ソリューション](https://www.s4p.jp/)
「除雪ありがとう」の気持ちを感謝ボタンで伝えよう

はじめに
---
毎年冬になると億劫なのは冬将軍の到来です。大雪による生活への影響は大きく、とりわけ除雪はかなりの負担になります。そんな中でも朝早くから道路インフラの除雪を頑張っている皆さんや、除雪ボランティアの皆さんに感謝の気持ちを伝えたい、と思いこのシステムを考えてみました。本当は感謝の気持ちを直接伝えられたらいいんですが、なかなかできない事情もあるのでSNSへの投稿にしてみました。今回はtwitterへの投稿にしてみました。

こんな感じ
---

<img src="https://qiita-image-store.s3.amazonaws.com/0/63318/b64bd42e-02aa-96d6-e4b2-fedb375ea9e3.png">


感謝ボタン:除雪ありがとう
---

**除雪している皆さんに感謝するとき使います。**
IFTTTの「Button widget」を押すと、Twitterに「除雪ありがとう」、日時、マップ、ハッシュタグをつぶやきます。

|:one:<img src="https://qiita-image-store.s3.amazonaws.com/0/63318/3557877a-81b1-5306-c3a0-df41f655137e.png">|:two:<img src="https://qiita-image-store.s3.amazonaws.com/0/63318/d17a154b-b78f-341c-834b-ea3103665831.png">|:three:<img src="https://qiita-image-store.s3.amazonaws.com/0/63318/711e08be-191d-8dae-0852-064d99f95102.png">|
|:--:|:--:|:--:|
|:four:<img src="https://qiita-image-store.s3.amazonaws.com/0/63318/30d3c3e5-d227-5b6a-2b59-8bc76d75583b.png">|:five:<img src="https://qiita-image-store.s3.amazonaws.com/0/63318/20b33c59-47c0-2fab-a1bb-d983f3b7079d.png">|:six:<img src="https://qiita-image-store.s3.amazonaws.com/0/63318/08e4f7a6-9bb7-974a-b640-44e88c8ceaf9.png">|

応援ボタン:大雪で大変です
---

**ついでに大雪で困った時のバージョンも考えました。大変さが伝わるようカメラで撮影した画像もアップします。**
**応援ボタン**というより、**応援して欲しいボタン**ですが...
IFTTTの「Camera widget」を押し、先にカメラで画像を撮影した後、Twitterに「大雪で大変です」、日時、画像、マップ、ハッシュタグをつぶやきます。
**おそらくハッシュタグに市町村名を入れると効果的だと思われます。**


|:one:<img src="https://qiita-image-store.s3.amazonaws.com/0/63318/ee8c7fc7-8578-b9cf-e7dc-8f90f891cc52.png">|:two:<img src="https://qiita-image-store.s3.amazonaws.com/0/63318/0fb1b9ce-2978-6388-357e-f60602a29406.png">|:three:<img src="https://qiita-image-store.s3.amazonaws.com/0/63318/637cad02-ca24-3085-b0dc-8570fffb2a72.png">|
|:--:|:--:|:--:|
|:four:<img src="https://qiita-image-store.s3.amazonaws.com/0/63318/63779715-6676-f436-4314-a0804e94c9ef.png">|:five:<img src="https://qiita-image-store.s3.amazonaws.com/0/63318/2fb8b299-af62-f2ec-cc0c-c6f0cd411a9b.png">|:six:<img src="https://qiita-image-store.s3.amazonaws.com/0/63318/8f103946-a604-cc54-eb7a-4fe529e022cd.png">|

ウィジェット・ボタンとつぶやき結果
---

|<img src="https://qiita-image-store.s3.amazonaws.com/0/63318/8cbc5257-d3bd-0083-2051-e584674d88a4.png">|<img src="https://qiita-image-store.s3.amazonaws.com/0/63318/e7a2c48b-9fa7-44fe-1dca-e1e33b79bf05.png">|
|:--:|:--:|


残念ながら
---

クルマに乗ってるとき、Googleアシスタントに「OK Google、除雪ありがとう」と話すと同様にできたらいいと思ったのですが、twitterに一部データを引き渡すことができず断念しました。

さいごに
---
除雪に限らず「ありがとう」の気持ち、世界中に広げましょう(=^・^=)
EKS上でfluentd-cloudwatchをhelmでinstallする

[charts/incubator/fluentd-cloudwatch at master · helm/charts](https://github.com/helm/charts/tree/master/incubator/fluentd-cloudwatch)をEKS上にinstallして使った話。最後にログインサイト使ってみたけど、AWS便利すぎかよ、、、

# IAMの設定
- WorkerNodeのIAMロールにCloudWatchFullAccessポリシーをアタッチ

# values.yaml
- awsRegion: ログを送るcloudwatchのリージョン
- rbac.create: trueにするとKubernetes APIを利用するためのRBACを自動生成する
- extraVars: Fluentdコンテナのenvを設定する
    - 以下のようにroot権限を持つように実行しないとうまく動作しなかった

```values.yaml
awsRegion: us-west-2
rbac:
  create: true
extraVars:
  - "{ name: FLUENT_UID, value: '0' }"
```

# install
```bash
⇒ helm install --name fluentd --namespace fluentd --values ./values.yaml --debug incubator/fluentd-cloudwatch
[debug] Created tunnel using local port: '55876'

[debug] SERVER: "127.0.0.1:55876"

[debug] Original chart version: ""
[debug] Fetched incubator/fluentd-cloudwatch to /Users/paper2/.helm/cache/archive/fluentd-cloudwatch-0.6.3.tgz

[debug] CHART PATH: /Users/paper2/.helm/cache/archive/fluentd-cloudwatch-0.6.3.tgz

NAME:   fluentd
REVISION: 1
RELEASED: Fri Dec 21 21:27:28 2018
CHART: fluentd-cloudwatch-0.6.3
USER-SUPPLIED VALUES:
awsRegion: us-west-2
extraVars:
- '{ name: FLUENT_UID, value: ''0'' }'
rbac:
  create: true
...
```

# 確認
- kubernetesロググループに以下のようにコンテナのログが出力されていれば成功です
![スクリーンショット 2018-12-21 21.41.52.png](https://qiita-image-store.s3.amazonaws.com/0/230552/adaaac22-748e-0394-9f2c-8ba5b6fac4a8.png)

# CWのインサイト機能を使ってセベリティ検索してみる
ESじゃないと検索面倒だなあと思ったらこんな機能が、、、。
便利すぎる、、、、。これで複雑なクエリも投げれるし、ESつくるよりログ保存ならCWの方が楽そう。
以下の例ではログのinfoだけ抽出している。クエリをERRORとかにすればエラーも探せる。

![スクリーンショット 2018-12-21 22.04.33.png](https://qiita-image-store.s3.amazonaws.com/0/230552/ffad1aab-89c2-c742-ff9e-30f0717925a3.png)
順列と組み合わせの公式について

# 順列と組み合わせの公式について

* 問題提起
   * 順列と、組み合わせの公式がよくわからない。
   * 順列の公式 $_nP_r=\displaystyle \frac{n!}{(n-r)!}$ ← まだわかる。
   * 組み合わせの公式$_nC_r=\displaystyle \frac{n!}{r!(n-r)!} = \frac{_nP_r}{r!}$ ← わからない($r!$ がどっから出てきたっけ？ って毎回なる)

* そもそも順列と、組み合わせとは何か？
   * 組み合わせ
      * グループから、いくつかを取り出すパターンの数
         * 例: 5人から3人を取り出すパターンの数
         * $_nC_r$と表現される。
         * 上記例の場合 n=5, r=3であるため、$_5C_3$

   * 順列
      * グループから、いくつかを取り出して並べたパターンの数
         * 例: 5人から3人を取り出して並べるパターンの数
         * $_nP_r$と表現される。
         * 上記例の場合 n=5, r=3であるため、$_5P_3$

* 順列と組み合わせの関係
   * 組み合わせのパターン数に、要素の数の並び方のパターン数を乗ずれば、順列のパターン数が得られる。
      * `組み合わせのパターン(グループからいくつかを取り出す際のパターン)`のひとつひとつに対して、並び方で区別するようにした場合が、順列のパターン数。
      * `組み合わせのパターン数`に、`その組み合わせにおいて可能な並び方のパターン数`を乗ずれば、順列のパターン数が出る。
      * 例: 5人から3人を取り出して並べるパターンの数
         * 5人から3人を取り出すパターンの数がある。
         * その一つ一つのパターンに対して、3人の並べ方がある(3 × 2 の6通り)。
         * `5人から3人を取り出すパターンの数`に`3人の並べ方のパターンの数`を乗ずれば、5人から3人を取り出して並べるパターン数(順列)が出る。
   * 数式での説明
      * n人からr人取り出して並べたときの並び方のパターン数 $_nP_r$ は、n人からr人取り出すパターン数 $_nC_r$ にr人の並び方のパターン数 $r!$を乗じたもの。つまり、
      * $_nP_r = _nC_r \times r!$
      * となる。これを$_nC_r$
      について解けば、組み合わせの公式が得られる。
      * $_nC_r = _nP_r \div r! =\displaystyle \frac{n!}{(n-r)!} \div r! = \displaystyle \frac{n!}{r!(n-r)!}$

* 順列の公式
   * 順列の公式 $_nP_r =\displaystyle \frac{n!}{(n-r)!}$(n個から、r個を取り出して並べたときのパターン数) はどこから出てくる？
   * 前提
      * 5人の並び方のパターン数: 5! = 5 * 4 * 3 * 2 *1 となる。(これは感覚的にわかるだろう)
      * 2人の並び方のパターン数: 2! = 2 *1
      * 5人から3人取り出して並べたパターンの数: とりあえず $_{5}P_{3}$ とおく
   * ここで、`5人から3人取り出して並べたパターンの数` × `2人の並び方のパターン数` = `5人の並び方のパターン数` となることも、感覚的にわかるだろう。
   * これを数式で表すと、以下になる。
   * $5! = _5P_3 \times 2!$
   * $_5P_3$について解く。
   * $_5P_3 =\displaystyle \frac{5!}{2!} = \frac{5!}{(5-3)!}$
   * n=5, r=3である。上の式一般化すると以下となり、順列の公式となる。
   * $_nP_r = \displaystyle \frac{n!}{(n-r)!}$
cで関数ポインタ

#概要

cで関数ポインタやってみた。


#サンプルコード


```
#include <stdio.h>

void number(int i)
{
    printf ("%d\n", i);
}
void fizz(int i)
{
    printf ("fizz\n");
}
void buzz(int i)
{
    printf ("buzz\n");
}
void fizzbuzz(int i)
{
    printf ("fizzbuzz\n");
}
int main()
{
	int i;
	void (* funcp[]) (int) = {
	    number,
	    fizz,
        buzz, 
        fizzbuzz
    };
	for (i = 1; i < 100; i++) 
	{
	    (* funcp[!(i % 3) + !(i % 5) * 2]) (i);
	}
    return 0;
}

```


#成果物

https://paiza.io/projects/kylC3EPb2Mch4vXCpUChvg


以上。
QA現場におけるチームビルディング例

# 前置き
私は複数の会社でQAチームのリーダーポジションに就いた経験があり、現在も同様か一歩下がってチームを支えるようなことをやっております。
チームビルディングの手法は調べればすぐに色々な記事が出てくるので、大半の内容はそちらを参考にした方が早いと思いますが、立場上チームビルディングについて考えることが多いので、経験を基にQA現場でどんな手法がチームビルディングに役立っているか、紹介と考察をしてみました。
この記事はマネージャーやリーダーなど主導的にチームビルディングを行える立場を前提に考えて書いています。また、この記事では5人前後のまとめ役についてもリーダーという言葉で扱うことにしています。
「チームビルディング」は、その言葉通りチームを作るということなので、良いチームを目指すことを前提として進めます。風通しが悪いよりは良い方がよいですし、対応が遅いよりは早い方がよい、精度が低いよりは高い方がよい、バグが多いよりは少ないほうがよい。ですよね。

# よくあるチームと問題点
大抵の組織ではトップダウンで進めた方が意思決定が早く推進力が高いと思います。QAチームも同様で、リーダーが細かく指示を出す方が効率が良い場合が多く、特にテスト業務ではリーダーが担当範囲を決めて動くことが場合が多いことと思います。
ゲーム系QAなどは人数が多くなり、チームを細分化することが多く、経験の浅い人、纏めるのが不得意な人、適切な判断を下せない人がリーダーをやるという悲惨な現場をよく見かけます。また役割の固定化は縦割り組織になりやすくボトルネックによって意思決定に時間が掛かったり、個々の問題が表面化し辛かったりします。

# 状況のまとめ
前項を踏まえると、QAチームはトップダウンで動ける方が効率が良いが、人数が増えてくるとリーダーの人手不足問題が出てきます。12年ほど複数のQA組織に属していた経験則ですが、良いチームの共通点を1つだけ上げるなら、リーダー（マネージャー）が良いことです。これは属人化を認めるというよりはリーダーの意向がチームに反映されるという理由からです。このリーダーの意向、判断と言い換えても良いですが、ここが不安定だととたんにチーム内から不協和音が聞こえてきます。
次項ではどのようなことに意識してリーダー不足やチームメンバーの不満を取り除きながらチームビルディングを行っているかをご紹介します。

# 意識していること
- チーム（グループ）の指針はマインド重視で示す
- リーダー未経験者を積極的に抜擢しても滞りなく業務が回る体制を目指す
- QA現場に必要なスキルセットを提示して教育と共通させる
- 有能なリーダーを引っ張ってくる

# 実践したことの詳細
### チーム（グループ）の指針はマインド重視で示す
- 心理的安全性を感じるわかりやすい言葉を選ぶと良い
- 現在所属している組織では「 **機嫌よく働く**」という標語を掲げていて、この標語は自身と他者の機嫌のどちらも適用することを前提に考えるように伝えています。このことでチーム内のみならず関係各所と良好な関係を築くべきであるということを伝えられます。
- マインド以外のこと、目標、成果といった業務履行上当然必要なことを前面に推し出すと、そちらを優先するあまり人間関係に悪影響が出て結果としてチームのパフォーマンスが落ちてしまうので注意した方が良いでしょう。
- メンバー各々が意識出来ているかを定期的に確認
  - 1on1などを取り入れてチーム指針について話し合い、マインドがズレた方向を向いていないかを定期的に話し合う
  - 各々が経験を基に不満を溜めている事が多いので、マインドと合う経験の活かし方を一緒に考える

### リーダー未経験者を積極的に抜擢しても滞りなく業務が回る体制を目指す
- 役割としてのリーダーを意識してもらう
   - スケジュール、工数管理、折衝などに集中してもらう
   - リーダー側の苦労を理解していただくことも目的のひとつ
- 性格分析を行い、その結果を公開して紹介し合う
   - お互いの性格を意識して相手を理解しやすい
   - 自身の弱点を把握できる
   - 性格をタイプで捉えることで個人攻撃に繋がり辛い
   - ※診断は **エニアグラム** と **コーチング式タイプ分け** を使ってます
- リーダーより能力のある人を補佐に付ける
   - 性格的に反目しないレベルでお互いを補える組み合わせが良い
   - 補佐の方が能力が高いことをリーダー本人、補佐共に理解してもらう
- 技術的なフォローを選任で行う人を用意する
   - 複数のチームを跨って管理やテスト技術をフォローする
   - 進捗管理の補佐や相談窓口

### QA現場に必要なスキルセットを提示して教育と共通させる
   - 以下のカテゴライズでそれぞれ5～10項目程度のチェック項目を設けました
       - 管理
       - テスト技術
       - コミュニケーション
       - IT知識 / プログラム知識
       - プロダクト知識
       - 改善活動
       - リーダーシップ
   - テスト技術以外もスキルとして捉えることで総合的な評価につなげる
   - 定期的に評価とフィードバックを行うことでスキル向上に意識が向く
   - 詳細なチェック項目は提示せず求めている方向性を伝えられれば良い

### 有能なリーダーを引っ張ってくる
   - 採用は妥協せずに作りたいチームマインドに合致した人を選ぶ
   - 過去の人脈から良い人材を連れてくる
 
※最後に持ってきているのは、ゼロから立ち上げるより立て直しとして入る状況が多いので、まずは既存のメンバーで構築し、難しい場合に使う切り札としたい

# まとめ
実践していることで、満足できない結果が出る場合もあり日々試行錯誤していますが、ゴール（QAの理想やチームの理想）を見据えて何が足りないか、今の状態はどうかを考え、改善していこうという行為自体が有意義で、チームが成長していくのを感じるのは非常に楽しいです。
フォームブリッジから企業微信にメッセージを配信する

この記事は [kintone Advent Calendar 2018](https://qiita.com/advent-calendar/2018/kintone) の 21日目の記事です。

# 作るもの
フォームブリッジで、メッセージをkintoneに書き込んで、企業微信に配信します。
１．フォームブリッジからkintoneにレコード追加
２．WebHookをMicrosoft Flowのkintoneコネクタで受ける
３．内容を企業微信に配信
４．配信結果ログをkintoneの元レコードに書き込む


# 企業微信（Wechat）とは
微信(wechat)の企業版です。
[企業微信の公式サイト](http://work.weixin.qq.com)

# 作る
## kintone側にアプリを作成します。
touserには配信したい相手の企業微信IDをいれます。配信結果は、企業微信配信ログに書き込む想定。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/79724/147bf233-c686-1dd5-9f49-a3d6ff215cf1.png)

## フォームブリッジでフォームを作ります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/79724/4b7e6c58-d2f3-bb97-b5f3-7dda087a7193.png)

## 企業微信に配信用アプリを作成します。
AgentIDとSecretはあとから使うので控えておきましょう。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/79724/c0f32acc-bc13-e264-fd1c-338f7f15827f.png)

## Microsoft Flowでフローを作成します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/79724/498e11b8-ef91-43a6-e344-7ad196ea59fd.png)
レコード追加はkintoneコネクタで受けられます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/79724/4daa33ac-8fde-4ea4-991a-6abdd8b64a99.png)
企業微信のAccessTokenを取得しています。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/79724/4be5ab3f-f02f-42b3-fb2d-c64ef995924a.png)
Messageを配信します。配信先ユーザーや配信内容はkintoneコネクタからそのまま参照できます。超便利。kintoneコネクタ。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/79724/bb874911-c570-d83a-3c25-dc28c23b3bdc.png)
配信結果のログを、元レコードに書き込みます。
更新対象のレコード番号も、kintoneコネクタから参照可能。やっぱり便利。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/79724/5ac0ebde-884d-65d8-b0a7-9ff8f4dc14da.png)

#動作確認
フォームブリッジでレコード投稿
![image.png](https://qiita-image-store.s3.amazonaws.com/0/79724/fd188252-3a61-6ef9-86cb-566838f23336.png)
微信に配信
![image.png](https://qiita-image-store.s3.amazonaws.com/0/79724/dfc8e943-da56-6d6a-ca81-00e9ee98cd60.png)
kintoneにログ
![image.png](https://qiita-image-store.s3.amazonaws.com/0/79724/48c44938-6842-a61a-ebff-40d4299e6bfd.png)

成功しました。

もう少しきちんと作れば、別アプリに格納されている情報を、フォームブリッジから能動的に企業微信に引き出す。という事ができますね。

 圣诞节快乐！（メリクリ！）
EspressoテストをKotlin化したらThe @Rule 'mActivityRule' must be public.エラーが出るのでその対策

# やりたいこと
EspressoテストのKotlin化

Convert Java File To Kotlin Fileを実行した

# 困ったこと
テストを実行すると以下の例外が発生する

```
org.junit.internal.runners.rules.ValidationError: The @Rule 'mActivityRule' must be public.

```
# 原因
Kotlinで宣言したプロパティはJava側から見るとgetterとsetterがあるのみで、publicなフィールドとしてアクセスできないからである。

# 解決方法
Kotlinで書いたクラスのフィールドにJavaからアクセスしたい場合は以下のように＠JvmFieldアノテーションをつける

```kotlin
@Rule @JvmField
var mActivityRule = ActivityTestRule(HogeActivity::class.java)
```

# 終わりに
Kotlinの言語仕様を知らないからこんなことになるので、基本的なところは学習する必要がある。
何かの参考になれば幸いです。


# 参考になったサイト
https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html
https://proandroiddev.com/fix-kotlin-and-new-activitytestrule-the-rule-must-be-public-f0c5c583a865
AWSでGitLFS環境構築して、Unity開発で使うのを完全に理解した

## Why

LFSを避けて生きてきたけど、さすがにリポジトリがしんどすぎたので、腹をくくりました。

元々、CodeCommitで管理していたので、LFSもAWSで完結すると良いなーとおもってたところ、いい方法が見つかったので、それで構築 & 以降をキメた。Σ(´□｀;)

## 構築方法

- [Amazon S3 に Git LFS サーバを超簡単に立てる](https://qiita.com/kanemu@github/items/d66bfd174a011d8dffdf)
    - メモしておくべきなのは、途中で設定する ユーザ名 + パスワード
    - URLはあとから、APIGatewayからでも確認できるので大丈夫

## セットアップ

- 初期設定はこちらを参考に
    - [macOS で Git LFS (Large File Storage) を使ってみる](https://blog.amedama.jp/entry/2017/11/19/091626)

その上で、各マシンで、

```
git config --global --add lfs.url "https://{user}:{password}@*********.execute-api.ap-northeast-1.amazonaws.com/lfs"
```

と設定することで、LFS関係諸々でAWSで構築したスタックをりようするようになる。

#### Unity側の設定

- [nemotoo/.gitattributes](https://gist.github.com/nemotoo/b8a1c3a0f1225bb9231979f389fd4f3f)

あたりを入れておきましょう。
Node.jsでスクレイピング(cheerio-httpcli)

##はじめに
この記事は [SLP KBIT Advent Calender 2018](https://qiita.com/advent-calendar/2018/slp_kbit) 22日目の記事です。

前々からスクレイピングに興味があったので、Node.jsを使ってスクレイピングをしてみることにしました。
今回は、Node.js用Webスクレイピングモジュールであるcheerio-httpcliを使用してみます。
完全に初心者なので、間違っているところがありましたら教えていただけると嬉しいです。

##cheerio-httpcliについて
cheerio-httpcliとは、Node.jsを使ってWebページをスクレイピングする際に必要となる文字コードの変換、そして、cheerioによってパースされたHTMLをjQueryのように操作することが出来るモジュールです。

ここで注意しなければならないのは、静的ページにしか対応していないので、Javascriptなどによってコンテンツを取得するページには使えないことです。
なので、動的ページをスクレイピングする時は、別のモジュールを使用するようにしましょう。(調べたらCasperJSなどがありました)

##使ってみた
Googleで私が所属しているSLP KBITのホームページを検索をしてみます。
今回は、SLP KBITを検索ワードとして検索しました。


```javascript
const client = require('cheerio-httpcli');

var word = 'SLP KBIT';

client.fetch('http://www.google.com/search', { q: word })
    .then((result) => {
        console.log(result.$('title').text());
        result.$('a').each(function (idx) {
            var $h3text = result.$(this).find('h3').text();
            var $url = result.$(this).attr('href');
            if ($h3text.includes('slp-kbit')) {
                console.log($h3text + '  '  + $url);
            }
        });
    })
    .catch((err) => {
        console.log(err);
    })
    .finally(() => {
        console.log('終了');
    });
```

プロミス形式でも書けるとあったので、今回はそちらで書いてみました。(悪くない)

使用する時はcheerio-httpcliのインストールを忘れずに。

```
npm install cheerio-httpcli
```

実行結果はこんな感じです。

```:実行結果
SLP KBIT - Google 検索
slp-kbit - 香川大学  https://poulenc.eng.kagawa-u.ac.jp/Pub/KBIT/
終了
```
成功です。(やったね)

##少し解説(fetchメソッドについて)
今回書いたコードでcheerio-httpcliのメソッドであるfetchメソッドについて説明していきたいと思います。

```javascript
client.fetch('http://www.google.com/search', { q: word })
```
この部分ですね。
これは、cheerio-httpcliのfetchメソッドを使用しています。
fetchメソッドとは、urlで指定したページをgetメソッドで取得します。その後、文字コードの変換やHTMLパースを行っているのですが、要はurlを指定してそのソースの解析をし、情報を取っているという事ですね。

今回私はプロミス形式で呼び出しましたが、callback関数に返すことも出来ます。(サンプルではcallback関数を使用してました)
callbackを使用する時は以下のように書きます。

```javascript
client.fetch('url', {q: word}, function (err, $, res, body) {
    //やりたい処理
});
```

引数のcallback関数を省略すると、自動的にPromiseオブジェクトが返るようになっています。
なので、プロミス形式で書くときは、callback関数を省略するだけでOKです。
ただし、プロミス形式でthenに渡されるパラメータは1つの引数にまとめられているという点には注意が必要です。(callbackでは引数が4つ)

```javascript:titleタグのテキストを呼び出すときの違い
    $('title').text();  //callback関数の場合
    result.$('title').text();  //プロミス形式の場合(thenの引数をresultとしている)
```
このように呼び出すときには間違えないように注意しましょう。

##おわりに
「cheerio-httpcliを使ってこんなことが出来る!」という事を書きたかったのですが、ちょこっと触った程度なのでいい案が出ませんでした。(アイディア力の無さ)
cheerio-httpcli自体はjQueryチックにコードを書けるので、比較的楽にスクレイピングすることが出来たと思います。(問題は静的ページのみなところ)
今回は静的ページをスクレイピングしたので、今度は動的ページのスクレイピングに挑戦したいです。

##参考

- [cheerio-httpcli - npm](https://www.npmjs.com/package/cheerio-httpcli)
テスト環境のマイグレーションに失敗した場合にコミッターを吊るし上げる

# やりたいこと
ソースのビルドでこけた場合はjenkinsが自動でよしなにしてくれるが、
内製ツールで社内のテスト環境のDBのマイグレーションをしているのでそれがこけた場合には自動では開発者に正しく通知できない
社内のテスト環境とはいえ、マイグレーションがこけるとごみデータができたりテストをブロックしたりするので、迅速に通知したい

# やったこと
DBのマイグレーションツールは結果をログに吐く
そこから対象ファイルを特定し、前回の成功したジョブ時点でのコミット以降にそのファイルに変更を加えた人にslackでメンションする

# 使ったもの

```shell
git rev-list --format=%cE ${GIT_PREVIOUS_SUCCESSFUL_COMMIT}..HEAD $line | grep 弊社のメールアドレスの＠以降 | perl -pe 's/\@弊社のメールアドレスの＠以降//g'| sort | uniq
| perl -pe 's/^(.*)$/\@$1/g' 
```

- git rev-listで特定のファイルのあるコミットから現在までのコミッターのメールアドレスを抽出する
- そのうち@以前を抽出してslackのIDにする

# スクリプト

```shell
cat migration.log | grep ERROR! | perl -pe なんかごちゃごちゃやって対象ファイルのパスを抽出する | xargs -I {} find . -name {} | perl -pe 's/\.\/(.*)/$1/g'> ERRORS

while read line
do
        echo $line >> suspects
        git rev-list --format=%cE ${GIT_PREVIOUS_SUCCESSFUL_COMMIT}..HEAD $line | grep 弊社のメールアドレスの＠以降 | perl -pe 's/\@弊社のメールアドレスの＠以降//g'| sort | uniq
| perl -pe 's/^(.*)$/\@$1/g' >> suspects
 done < ERRORS
```

# jenkinsのslack notification pluginの設定

「高度な設定」（Advanced Settings）の
「Include Custom Message」にチェックを入れ、以下のイメージでメッセージを設定した

```
$ENV へのDBスクリプトの適用が完了しました。
コミット$GIT_COMMIT まで適用されています。

やらかしたかもしれない人リスト↓
${FILE, path="suspects"}
```
2018年12月第3週　今週気になった記事まとめ

# 今週気になった記事まとめ
##■リアル写真と判別不能なレベルの偽画像をAIが生成可能になるGANs向けアーキテクチャをNVIDIAが作成
https://gigazine.net/news/20181219-nvidia-style-based-generator-architecture-gans/
かなり詳しく内容を説明してくれているのだけれど、それでも結局原理がどうなっているのかイメージが付かないな・・・。
ソースの顔の組み合わせがハズレなパターンがちらほらあるのが面白い。

##■あのホーム・アローンが大人になってスマート家電で華麗に泥棒を追い払うムービーが公開
https://gigazine.net/news/20181220-home-alone-again/
昔の人気映画をネタに今の技術を披露してくるあたりがセンス良いですね！

今週はピンとくる記事が少なかった気がする・・・。
Qiita上に書かずとも気になってチェックする記事も今回は少なかった。

年末、ということが関係していたりするんだろうか。
転職したらゲームQAだった件

# はじめに
元組み込みQA、現ゲームQAの私が、これまでの経験を踏まえて、
組み込み開発のどういう良いところを持ってくれば
ゲーム開発がもっとハッピーになるのかとかを考えながらまとめてみます。
ちなみに、ここでのゲーム開発は主にスマホ向けアプリゲームの運用フェーズを指していますのでご承知おきください。
# 組み込み開発とゲーム開発の違い
主観になりますが、一番大きいなと思ったのは、**「スケジュール感」** です。
組み込み開発では、いったんリリースしてしまえばデータ更新の頻度はそこまで多くなく、更新版でも開発期間は数か月かけることもあります(不具合修正のアップデートではなく、機能更新のようなものを想定しています)。
一方ゲーム開発は、毎週のようにデータ更新が入り、開発期間はQA含めて1週間というのもあります。![スケジュール.png](https://qiita-image-store.s3.amazonaws.com/0/321152/33b95724-1b72-82ae-9bd4-9483590edfc2.png)
スケジュールが変われば、関連するプロセスやドキュメントの類も特徴が変わってきます。
運用中のゲーム開発では、ウォーターフォール型の開発はほぼないのでは、とか思っています(アジャイルっぽいとか、スクラムで、とかは聞いたことありますが)。
企画も大枠は決まっていますが、細かい部分は日ごとに変化したりしますし、
予期せぬ影響範囲が見つかって、急遽実装に変更が入ることだってあります。
組み込みでももちろん発生したりしましたが、QA期間が多くて4日のゲームタイトルで発生すると結構修羅場になったりします。
そのため、ドキュメント類の構成管理はそこまで厳密ではなかったりします。
([過去のアドベントカレンダー](https://qiita.com/gomez_te/items/0db755dc32b3696c7552)で、仕様書の件も少し触れているので、
興味ある方は御覧いただけますと幸いです。)
あとは、品質の定義もけっこう違うと思いました。
組み込み製品では、リリース前にしっかりと品質を保証し、万が一にも不具合が発生しないよう高いカバレッジのテストを複数サイクル実施します(製品にもよりますが)。機能更新のようなリリース後のアップデートも同様です。
ゲームでもカバレッジは意識しますが、開発期間自体が短く、開発中の仕様や実装の変動も多いので、
基本機能のカバレッジがどうしても低くなりがちです(特に条件の組み合わせを網羅したような設計が困難)。
その分、探索的なテストだったりでカバーすることが多いと思います。
ちょっとまとめてみると、以下の表のようなイメージです(会社さんによって、違うとは思います)。
![違い.png](https://qiita-image-store.s3.amazonaws.com/0/321152/0a667229-2094-a8e5-6b74-e9d743e2d09a.png)
# どうしたらゲーム開発がハッピーになるか考える
ではQAの側面で組み込み開発から見習うと良さそうな点を考えてみます。
見習う点の一例として上述したような組み込み開発の高いトレーサビリティと、カバレッジ基準に沿ったテストをつくる方法とは・・・
## トレーサビリティを確保してみる
ゲームQAで特におさえるべきポイントとしては、**「変更点」** です。
最低限、ここだけは変更したときに追えるようにしたいところになります。
テストでも、変更点については新たにテストケース化しておかないとテスト漏れのリスクが高まります。
(実装に手を入れた箇所には不具合が入り込む可能性がある)
こっそり変更されてしまうと、QAでも検知が難しくなる(過去のテストも無意味になる)ので、更新したかを追える仕組みを入れてみると良さそうです。
とはいえ、仕様書を更新するたびにバージョン〇〇、更新日mm/dd、更新者〇〇、更新内容ほげほげ、というのを
毎回やっていると、工数がいくらあっても足りないので、実装に影響するような変更点の仕様変更に対してのみ適用するなど、
範囲をある程度決めておくのが良いと思います。

例)
・テストケースに、「参照仕様書」と「仕様書最終更新日」の欄を設ける
・仕様書に、変更点に関する「最終更新日」と「更新内容」の欄を設ける
コンフルみたいな共有ツールを使用している場合は、コメントを利用するのも手だと思います。

トレーサビリティを確保できているか、と問われると悩ましいところではありますが、
少なくとも更新漏れを検知するための1つのシステムとしては機能しそうです。
## カバレッジを考えてみる
変更点をちゃんとテストできているのか。ここについても課題がありそうです。
ゲームの定常機能更新の場合、変更の多くはデータ設定部分になると思います。
一方で、機能的な改修も少し入れたりもします(ゲーム自体に変化が少ないと飽きちゃいますよね)。
全機能のカバレッジとなると大変ですが、機能改修箇所に焦点を当ててカバレッジを考えるだけなら、なんとかなるかもしれません。
こんなフォーマットを考えてみます。
![変更点.png](https://qiita-image-store.s3.amazonaws.com/0/321152/cb4ba35e-994c-b182-0f78-7b24876270b0.png)
変更内容は、仕様書のコピペでも大丈夫です。
大事なのはすべての変更点がリストアップされ、それぞれに対してどんなテストをするかが明示されていることです。
変更内容部分を詳細化する余裕があれば、もう少し細かく書いた方が、よりテスト観点を洗い出せると思います。
開発担当者と、このレベルで認識あわせができれば、大枠での漏れが発生しにくくなります。
## 結局何がハッピーなのか
ゲーム開発で不具合になりやすいところは、**変更点とその影響範囲**です。
変更点に対するトレーサビリティとカバレッジを意識することで、QAで拾える可能性も上がります。
リリース前に不具合を検知し修正できれば、リリース後に検知されるよりも少ないコストで対応ができます。
原因の調査や、再発防止策の検討に時間を費やすことも少なくなります。
結果として、モノづくりに集中する時間を確保でき、より良い品質のゲームを世の中に出せるわけです。
こうなれば開発もQAもハッピーになりそうですね。
# さいごに
組み込みQAの(おそらく)堅牢なテストケースの仕組みを、全て導入するのは限られた工数の中では困難です。
が、一部の仕組みをうまく流用できれば、ゲームQAのテストケースも堅牢にできるかもしれません。
少なくとも、経験者による探索的テストに頼るしかない状況を打破できるかもしれません。

本エントリーでは、組み込みQAの一部分だけ切り出してみましたが、
他にも参考になる仕組みはたくさんあります。
別の機会で、うまくいったこととか、ダメだったこととか触れてみようかなと思います。

それでは、良いクリスマスを。
Ubuntu 16.04 LTS とUSB-Wifi

Ubuntu 16.04 LTSとUSBWifiをつなぐための備忘録

⇒2019/3/30確認したところ、この方法ではなぜかできなくなりましたので削除します。
https://blogs.yahoo.co.jp/gajesuki/28497221.html
上記のサイト様の方法で可能でした。

Ubuntuに挑戦しています。
LANケーブルは見栄えが悪いため、無線子機を購入しました。
しかし、BUFFALO　WI-U2-433DMについての記事はたくさんありましたが、WI-U2-433DMSについては記事が見当たらず、困りました。

そのため投稿します。


１．Windowsにて、USB子機のチップを確認

デバイスマネージャー→詳細
Realtekのバージョンが1030.11.503.2016であることを確認。
<img width="389" alt="キャプチャ.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/284528/3b061c0f-0a2b-8635-d42a-eeca2430dded.png">


検索をかけるとWI-U2-433DMSはrtl8821auであることが判明。
（WI-U2-433DMはrtl8812auのようです。）
https://drivers.softpedia.com/get/NETWORK-CARD/REALTEK/Realtek-RTL8821AU-Wireless-USB-Adapter-Driver-1030115032016-for-Windows-10-Anniversary-Update-64-bit.shtml

２．下記サイトを参考にインストール作業。
https://dmaiorino.com/?p=83

$ sudo apt-get install linux-headers-generic build-essential git

$ git clone https://github.com/scrivy/rtl8812AU_8821AU_linux.git

$ cd rtl8812AU_8821AU_linux
$ make

最後の
4. ドライバーをインストールのところで
$ sudo make install
$ sudo modprobe 8821au

無事にWifi 接続されました。
Pythonで線形回帰を実装

「精度」と「モデルの複雑さ」に注力しながら、線形回帰をpythonで実装。

## 目次
- 線形モデル
- 線形モデルによる回帰
- 線形回帰(通常最小二乗法)
- 一次元データに対しての線形回帰
- 高次元データに対しての線形回帰

## 参考文献
- [Pythonではじめる機械学習](https://www.oreilly.co.jp/books/9784873117980/)

## 線形モデル
線形モデルは、入力特徴量の線形関数(Linear function)を用いて予測を行う。

## 線形モデルによる回帰
回帰問題で使われる線形モデルの予測式は、以下のようになる。

$$y = w(0)  \times x(0) + w(1)  \times x(1) + w(2)  \times x(2) + ・・・　+ w(p)  \times x(p)$$

ここでの$x(0)~x(p)$は、ある1サンプルの特徴量を示す。また、$w$と$b$は、学習されたモデルのパラメータであり、$y$はモデルからの予測である。

特徴量が1つの場合、傾き$w(0)$、切片が$b$の直線になる。

回帰における線形モデルにおいての予測は、特徴量が1つの場合は直線に、特徴量が2つの場合は平面に、高次元の場合は超平面になる。

回帰モデルを用いた回帰には、様々なアルゴリズムが存在する。
それらの異なる点は2つ。

- パラメータwとbを訓練データから学習する方法
- モデルの複雑さを制御する方法

## 線形回帰(通常最小二乗法)
線形回帰(または、通常最小二乗法 ordinary least squares: OLS)は、最も単純な線形回帰手法である。

線形回帰は、訓練データにおいて、予測と真の回帰ターゲットyとの平均二乗誤差(mean squared error: MSE)が最小になるような$w$と$b$を求める。

平均二乗誤差は、
$$MSE = \frac{1}{n} \sum_{n=0}^{p} (y − \hat{y})^2$$
誤差をイメージできない人もいると思います(僕は頭に描けなかった)。なので、誤差を図示してみました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/185039/10c67d17-b84f-ee5b-ccaf-106b92d0e3fe.png)

線形回帰は、ハイパーパラメータがない。よって、モデルの複雑さを制御できない。

### 下準備

```
$ pip install scikit-learn
$ pip install mglearn
```


## 一次元データに対しての線形回帰

```python
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
import mglearn

X, y = mglearn.datasets.make_wave(n_samples=60)
print("(サンプル数, 特徴量数): ", X.shape)
# => (サンプル数, 特徴量数):  (60, 1)
```

```python
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)
lr = LinearRegression().fit(X_train, y_train)

print(f"training dataに対しての精度: {lr.score(X_train, y_train):.2}")
print(f"test dataに対しての精度: {lr.score(X_test, y_test):.2}")
# => training dataに対しての精度: 0.67
# => test dataに対しての精度: 0.66
```

### 考察:
training dataに対しても、test dataに対しても、精度は低い。よって、過剰適合はなく、適合不足である可能性が高い。
下の「精度とモデルの複雑さ」の図でいうと、スイートスポット左側に位置しているのだろう。

![width=70](https://qiita-image-store.s3.amazonaws.com/0/185039/f889a769-6e6c-a3b8-27a9-5da761d929ae.png)

線形回帰は、一次元データに対しては、モデルの複雑さが低く、適合不足に陥りやすい。

## 高次元データに対しての線形回帰

```python
X, y = mglearn.datasets.load_extended_boston()
print("(サンプル数, 特徴量数): ", X.shape)
# => (サンプル数, 特徴量数):  (506, 104)
```

```python
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
lr = LinearRegression().fit(X_train, y_train)
print(f"training dataに対しての精度: {lr.score(X_train, y_train):.2}")
print(f"test dataに対しての精度: {lr.score(X_test, y_test):.2}")
# => training dataに対しての精度: 0.95
# => test dataに対しての精度: 0.61
```

### 考察:
training dataに対しての精度は非常に良いが、test dataに対しての精度は良くない。これは、過剰適合の可能性が高い。

上記の「精度とモデルの複雑さ」の図でいうと、スイートスポットの右側に来ているのだろう。

よって、汎化性能(test dataに対しての精度)を上げるためには、モデルの複雑度を制御する必要がある。
その手法に、**リッジ回帰**と**Lasso**がある。

### おまけ
次の記事で、モデルの複雑さを制御する手法である**リッジ回帰**と**Lasso**についての記事を書く予定です。
[C++] ダブルクォーテーションで囲った文字列を関数に渡すことで警告が出るときの理由と対処

# 環境
- BeagleBone Black Rev.C 
    - BeagleBoard.org Debian Image 2016-11-06（/etc/dogtag）
    - Debian8.6（2016.11.6）
- コンパイラ
   - gcc (Debian 4.9.2-10+deb8u2) 4.9.2

# 概要
fopen() にファイルポインタをオープンできたかを確認する機能を追加した関数，Myfopen() を呼び出した際に警告が出た．

```sample.c
#include <stdio.h>
#include <stdlib.h>

FILE *Myfopen(char Path[], char Mode[])
{
    FILE *fp = fopen(Path, Mode);
    if(fp == NULL)
    {
        printf("OpenError.[%s](%d)\n", Path, Mode);
        exit(1);
    }
    return fp;
}

int main(void)
{
    FILE *fp = Myfopen("sample.txt", "r");
    return 0;
}
```

これをコンパイルすると，以下のような警告が出る．

```
debian@beaglebone:~/share/program/src$ g++ sample.cpp
sample.cpp: In function 'int main()':
sample.cpp:17:41: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
     FILE *fp = Myfopen("sample.txt", "r");
                                         ^
sample.cpp:17:41: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
```

この警告が出る理由と対処について説明する．

# 警告が出る理由
C++では文字列リテラル（ダブルクォーテーションで囲われた文字列）は、const char 配列として扱われる．したがって~~**関数（Myfopen）に渡される文字列は const char [] であるのに関わらず，関数の仮引数の型は char []**~~
**関数（Myfopen）に渡される文字列は const char* であるのに関わらず，関数の仮引数の型は char []（char*）**である．これが理由である．
（2018/12/22 訂正）

# 対処
関数へ渡す引数が const char* であるため，関数の仮引数の型も const char []（const char*） にすればよい．

```sample.c
/* 変更後 */
FILE *Myfopen(const char Path[], const char Mode[])
{
    FILE *fp = fopen(Path, Mode);
    if(fp == NULL)
    {
        printf("OpenError.[%s](%d)\n", Path, Mode);
        exit(1);
    }
    return fp;
}
```

これによって警告を出すことなくコンパイルすることができる．


# 参考
C++において，文字列リテラルから 'char*型' への変換が非推奨？ エラーメッセージ
https://teratail.com/questions/9652
GoogleCloudFunctionでFortniteのLINEbot作った

[BrainPad Advent Calendar 2018](https://qiita.com/advent-calendar/2018/brainpad) 21日目の記事です！

# はじめに
最近Fortniteにハマってます。（めちゃくちゃ下手ですが）
このアドベントカレンダーのネタを考えているとき、ふと「Fortnite関連で何かしたいな～」と思い調べてみたところ、なんとAPIがありました。
https://fortnitetracker.com/site-api

しかもPythonのラッパーまであって、驚愕です。
みんな面白いこと考えるなぁと思いました。
https://pypi.org/project/fortnite-python/

# つくったもの
そこで今回は、
「アイテム教えて」と送ると売られているアイテムの画像を返してくれるbotを作りました。
<img src="https://qiita-image-store.s3.amazonaws.com/0/177134/405f6562-7c91-8674-577b-8c88a350707f.png" width=50%>


こちらから友達追加できます。
<a href="https://line.me/R/ti/p/%40wsk9147y"><img height="36" border="0" alt="友だち追加" src="https://scdn.line-apps.com/n/line_add_friends/btn/ja.png"></a>

codeは[こちら](https://github.com/rio-kurihara/FortineLINEBot)においてます。

# CloudFunctionとは
完全サーバーレスでアプリケーションを実行できるサービスです。
実行環境としてはNode.js v6とNode.js v8、さらにPythonが追加でサポートされました。
使い方は私が書くよりググればたくさん出てくるのでそちらをご参考ください・・・
~~（まとめる時間がなかった）~~

# おわりに
平日はゲームしてる暇なくても、LINEでサクッとアイテムだけ確認して、もし良さそうなアイテムがあったらPS4の電源つけて購入する、が出来たらいいな～と思ってCloudFunctionの勉強がてら作ってみました。
過去にLINEbotを作ったときはherokuとFlaskで開発しましたが、サーバーレスだと開発も楽だな～と思いました。
APIで過去の戦歴とかも取れるので、ユーザー名を送ったら戦歴返してくれる機能とかも追加したいなと思います。
Lambdaの多重起動は同期呼び出しで防げる

Lambdaの二重起動、多重起動、冪等性…で数時間ググりまくった結論です。

# Lambdaが多重起動するかもしれないときっていつ？
答えは
非同期呼び出しされたときです。
同期呼び出しされたときは、一回だけ呼び出されます。

つまり、**同期呼び出し時には多重起動は発生しません。**
>RequestResponse（同期）呼び出しオプションを使用すると、その関数は1回だけ呼び出されます。
>Event（非同期）呼び出しオプションを使用する場合、関数はイベントに応答して少なくとも1回呼び出され、関数はこれを処理するためには冪等でなければなりません。
>https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/API_Invoke.html

### 同期呼び出し、いいじゃん！でも失敗時リトライが必要
非同期呼び出しは失敗時にリトライしてくれます。それ故に（？）多重起動することがあるようです。
同期呼び出しは1回しか呼び出さないため、リトライ処理を自前で用意する必要があります。

### そもそもなんで呼び出しに失敗するの？
[ドキュメント](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/retries-on-errors.html)にはこうあります。


>Lambda 関数は、次のいずれかが原因で失敗する場合があります。
>- 関数がエンドポイントに到達する前にタイムアウトになった。
>- 関数が入力データを正しく解析できなかった。
>- 関数にメモリ不足エラーまたは他タイムアウトなどのリソース制約が発生した。



## 失敗時はどういう挙動するの？
[ドキュメント](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/retries-on-errors.html)にはこうあります。
>同期呼び出し – 呼び出し元アプリケーションが 429 エラーを受け取り、再試行が必要となります。
>非同期呼び出し – 非同期イベントは Lambda 関数の呼び出しに使用される前にキューされます。AWS Lambda がイベントを完全に処理できない場合、呼び出しが 2 回自動的に再試行されます (再試行間には遅延があります)。

ほ〜。
Lambdaのリトライについては↑のドキュメントに詳しく書かれてそうですね。


# 【本題】同期呼び出しってどうやんのよ？
- コンソールで手動で呼ぶときは同期/非同期を指定することができる
- サービスがトリガーのときは、__サービスごとに同期か非同期か決まっている。__

つまり、
_・S3がトリガー　→　非同期呼び出し
・StepFunctionsがトリガー　→　同期呼び出し_
みたいな感じで最初から決まってるんですね。

>呼び出しタイプを制御できるのは、ユーザー自身が Lambda 関数を呼び出すときのみです。
>トリガーとして AWS サービスを使用する場合、呼び出しタイプはサービスごとに事前に定義されています。
>https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/invocation-options.html

## 同期か非同期かわかるサービス一覧表はないの？
あるよ（声色）

こちらです。
サービスごとに同期/非同期が日本語で書いてございます。
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/invoking-lambda-function.html

# 非同期呼び出しのときはどうやって多重起動を防げばいいの？
非同期呼び出しの場合は[DynamoDBに状態書いて頑張る](https://dev.classmethod.jp/cloud/aws/lambda-dynamodb/)みたいなことが巷では書かれています。
ちょっとしたサービス作るにはつらいですね…。

# おわり✨🍰✨
うーん、結局、AWS公式ドキュメントを読み込めばわかることばかりですね。
でも読むのがしんどい日本語なんだよなあ…。翻訳文だからですか…？
Raspberry Pi Sense HATをNode-REDで遊んだよ

この記事は[Node-RED Advent Calendar 2018](https://qiita.com/advent-calendar/2018/nodered) 21日目の記事です。

# Raspberry Pi Sense HATとは
ラズベリーパイ公式サイトにもあるラズベリーパイ専用のアドオンボードです。
Sense HATは、「Astro Pi」という、宇宙ステーションでラズベリーパイを動かそうというプロジェクトのために作られたアドオンボードです。8×8フルカラーLEDディスプレイ、ジョイスティックの他に、6種類ものセンサが組み込まれています。

![49037977_311993916082382_5957419810521350144_n.jpg](https://qiita-image-store.s3.amazonaws.com/0/171737/1b4c28fe-22b8-b8e4-e34c-3802d6d3446f.jpeg)
[amazonで販売しています。Raspberry Pi Sense HAT - 6 センサー、8x8 LEDマトリックス、ジョイスティック](https://www.amazon.co.jp/Raspberry-Pi-Sense-HAT-LEDマトリックス、ジョイスティック/dp/B014N3RAUC)

# 遊ぶまえに
Raspberry Pi3のOSであるRaspbianにはNode-REDに、Sense HAT用のノードが標準に登録されています。これはいいですね。

今回は、IBM developerWorks Recipesを利用して遊んでみようと思います。
ゲームの内容は、
**「Sense HATの傾斜センサーとLEDディスプレイを使用した単純な大理石の迷路ゲームを作成します」**
です。
参考の[URL](https://developer.ibm.com/recipes/tutorials/connecting-a-sense-hat-to-watson-iot-using-node-red/)はこちら。

# Node-REDの設定
非常に簡単な構成です。

![スクリーンショット 2018-12-20 22.42.05.png](https://qiita-image-store.s3.amazonaws.com/0/171737/42d1b244-a22a-dae1-edf6-30423c99f320.png)

## Sense HATのノードはここにあります。
<p><img alt="repo" src="https://qiita-image-store.s3.amazonaws.com/0/171737/d87019a9-6d24-fdcc-083a-d6e317f65d4d.png" style="display:block;margin-left:auto;margin-right:auto;" /></p>

1. Sense HAT入力ノードを追加して、 Motion eventsのみを送信するように設定します。
2. 読み込みダイアログを開き、[ここ](https://gist.githubusercontent.com/knolleary/da4fc4348e44dcf81744eb4e042e8635/raw/b5e811fb83c931262d23fcd099e2db570f281bf3/Step%25203%2520-%2520Marble%2520Maze%2520Function%2520Node%2520v1.json)からJSONを貼り付けます。モーションイベントを処理するためのFunctionノードが追加されます。
3. Sense HAT出力ノードを追加します。

デプロイしたら、ラズベリーパイを傾けると、赤い点である「大理石」をディスプレイの周りに移動できます。
目的は、大理石を青い点、「目標」に当てることです。
緑色の点は、壁です。
大理石がゴールに当たったら、新しい壁を作り、ゴール場所が変わります。

# こんな感じで遊べます。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">Raspberry Pi Sense HATをNode-REDで遊んでみました。 <a href="https://t.co/3Ekfj0Ap2b">pic.twitter.com/3Ekfj0Ap2b</a></p>&mdash; t_kobanyn (@kobanyn) <a href="https://twitter.com/kobanyn/status/1076071384701255680?ref_src=twsrc%5Etfw">2018年12月21日</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 

# 終わりに
あそべるように自動起動設定を行いましょう。
次のコマンドを実行します。

```
$ sudo systemctl enable nodered.service
```

再起動して、起動しているのを確認して下さいね。

それでは、Node-REDでEnjoyしましょう！！
Unity ML-Agents 前提知識まとめ

## **概要**
Unity ML-Agentsを使い始める前に知っておくといい前提知識をまとめてみました。

**※2018/12/21現在**　強化学習のみ対応

## **用語解説**

- **機械学習**

大量の情報の中から**規則性**を見つけ、予測や判断を行うためのルールを機械に生成させる手法のこと。

機械学習にもいくつか種類があり、代表的なものには「教師あり学習」「教師なし学習」「強化学習」があります。

- **推論**

与えられた情報を**推論モデル**(人間でいう頭脳)に判断させ、その結果を導き出すこと。

例えば囲碁の場合、推論モデルに現在の盤面情報を与え、「これが最善手だ！」と判断すれば、その最善手の座標を出力する、というのが推論の一例です。

- **強化学習**

ある環境に置かれた**エージェント(Agent)** が**環境(Enviroment)** に対して**行動(Action)** した結果得られる**報酬(Reward)** が最大化されるような**推論モデル** を生成する手法です。

例えばサッカーの場合、ゴールしたら **+1.0** ゴールされたら **-1.0** の報酬を与えるとしましょう。

エージェントは、学習していく過程の中で偶然でもゴールすると報酬が与えられるため、**今の行動は良い行動**であると認識して少しずつ賢くなっていく、というのが強化学習の一例です。
Docker for windowsでtimeout errorしたときの処理

#はじめに

Windows 10 home にてdocker toolboxを使いDockerFileからbuildしようしたらこのようなエラーが出ました。

```
docker build -t <name>/nginx:1.0 .
Sending build context to Docker daemon  3.072kB
Step 1/3 : FROM nginx
Get https://registry-1.docker.io/v2/: dial tcp: lookup registry-1.docker.io on 10.0.2.3:53: read udp 10.0.2.15:48321->10.0.2.3:53: i/o timeout
```
#原因
調べたところDockerホストのDNSが問題らしいです。
#解決法

```
$ docker-machine ssh default
$ sudo vi /etc/resolv.conf
```
でvm内部に入ります。

```
$ sudo vi /etc/resolv.conf
```
そしてresolv.confを編集します.

```conf:resolv.conf
nameserver 10.0.2.3
```
となっているので

```conf:resolv.conf
nameserver 8.8.8.8
```
と変更します
あとは>exitでvmから抜け出しbuildすると無事成功しました。
routes.rbにおけるresourcesの意味

これまでGETやPOSTをそれぞれ書いていたが、resourceというものでまとめられるらしいので、そのルーティングをメモ。


```
resources :posts
```
- get "/posts" => posts#index

- get "/posts/new" => posts#new

- post "/posts" => posts#create

- get "/posts/:id" => posts#show

- get "/posts/:id/edit" => posts#edit

- put(patch) "/posts/:id" => posts#update

- derete "/photos/:id" => photos#destroy


超基礎的なことだろうが、メモ。
変更があるところはresouresよりも上に書くらしい。

参考
[Rails のルーティング](https://railsguides.jp/routing.html)
AIの金融分析の記事の統計情報の専門用語が、わからなかったから、しらべてみた

# 概要

自分、統計にかんしてまったくの素人なんですが、

パソコン雑誌に、「リッジ回帰」という単語がでてきて、

なんのことやら、さっぱりわからなかったので、wikiとかで、しらべて、

みると、その解説も、さっぱり。。。というわけで、わかるまで、

しらべてみた結果をまとめた記事です。


### 記事について
パソコン雑誌、日経ソフトウェア2019年01月号 082page


# 回帰分析とは
回帰分析とは、説明変数 によって目的変数 の変動を y = f ( x ) の形でどの程度説明できるかを分析する手法です。

# 重回帰分析
* 重回帰分析は、多変量解析の一つです。
* 回帰分析において独立変数が2つ以上のものです。
* 独立変数が1つのものを単回帰分析といいます。 

# 直線回帰とは
直線回帰は重回帰分析の最も単純な場合です。

# ノルムとは

ノルムとはいろいろなものの「大きさ」を表す量です。

## L2 ノルム
高校数学でも扱う「普通の意味での長さ」です。ユークリッドノルムとも言います。

二乗して、ルートをとるやつです。

## L1 ノルム
|x1|+|x2|+⋯+|xn|

各成分の絶対値の和です。

# 最小二乗法とは(英: least squares method)
最小二乗法は、測定で得られた数値の組を、適当なモデルから想定される1次関数、対数曲線など特定の関数を用いて近似するときに、想定する関数が測定値に対してよい近似となるように、残差の二乗和を最小とするような係数を決定する方法、あるいはそのような方法によって近似を行うことです。

# リッジ回帰とは
直線回帰に正則化項の概念を加えた回帰分析。

最小二乗法の式に正則化項（L2ノルム）を加え、その最小を求めることでモデル関数を発見することにつかいます。

#　感想

リッジ回帰の説明を理解するには、たくさんの統計用語をしらないといけなくて、びっくりしました。
したらば掲示板のAAをずれなく表示するChrome Extensionを作る

本記事はしたらば掲示板のAAにAA表示用日本語フォントを適用するChrome拡張機能を作る内容です。

## あらすじ
まず下の画像をみてください。
![Screen Shot 2018-12-21 at 19.41.48.png](https://qiita-image-store.s3.amazonaws.com/0/165335/d86d6972-dfc2-be74-ad26-1e7e975ce7e0.png)

こちらは我がMacBookProのChromeから「したらば掲示板」を見た時の状態です。ご覧の通りずれてますね。このままだと非常に読みづらいですね。

というわけで今回はこちらのサイトにAA表示用日本語フォントを適用するChrome拡張機能を作りたいと思います。


## 作ったもの
現在、Chromeウェブストアに並んでいます。
[AAHub-Extension](https://chrome.google.com/webstore/detail/aahub-extension/ccelihcopcojkkljbedblojdlkfdjaei)

こちらをお使いのChromeブラウザに追加すると右クリックで「AAHubフォント適用」というメニューが現れるようになります。
![Screen Shot 2018-12-21 at 19.46.07.png](https://qiita-image-store.s3.amazonaws.com/0/165335/86fbdc8f-cba2-4b4f-a12d-c783079af921.png)

そして、「AAHubフォント適用」を選択すると...
![Screen Shot 2018-12-21 at 19.46.17.png](https://qiita-image-store.s3.amazonaws.com/0/165335/5afa9a8d-530e-af0f-013a-aa11275ea862.png)

ご覧の通り、やる夫がずれずに表示されるようになります。クール！！

## 作り方
作り方といってもこれだけだと非常に短いソースコードで完成します。必要なファイルはmanifest.json、base.js、background.jsのみ

```json:manifest.json
{
  "name": "AAHub-Extension",
  "version": "0.1",
  "description": "したらば掲示板にAAHubフォントに変更します。Mac等でアスキーアートが崩れずに表示されるようになります。",
  "manifest_version": 2,
  "icons": {
    "16": "images/icon16.png",
    "32": "images/icon32.png",
    "48": "images/icon48.png",
    "128": "images/icon128.png"
  },
  "background": {
    "scripts": ["js/background.js"],
    "persistent": false
  },
  "permissions": ["tabs","https://jbbs.shitaraba.net/", "contextMenus"]
}
```

```javascript:js/background.js
var parentId = chrome.contextMenus.create({
  "id": "parent",
  "title" : "AAHubフォント適用",
  "type": "normal",
  "contexts": ["all"]
});
chrome.contextMenus.onClicked.addListener( function(info, tab)　{
  chrome.tabs.executeScript(tab.id, { file: "js/base.js" });
});
```

```javascript:js/base.js
var fa = document.createElement('style');
fa.type = 'text/css';
fa.textContent = '@font-face { font-family: "aahub"; src: url("https://storage.aahub.org/fonts/aahub_light.woff2") format("woff2"), url("https://storage.aahub.org/fonts/aahub_light.woff2") format("woff");}';
document.head.appendChild(fa);
var authorNode = document.querySelector(
  "dl"
);
if (authorNode) {
  authorNode.style.fontFamily = "aahub";
}
```

これだけで完成です。
ソースコードはGitHubにあります。興味あったら見てみてください(そしてスターを...)
[AAHub/AAHub-extension](https://github.com/AAHub/AAHub-extension)

## まとめ
Chrome拡張機能、意外と簡単に作成可能なのでもし、普段困ってることがあったら自分の問題の解決のために作ってみましょう。僕はいずれまた何か作るかもしれません。
それでは。
obniz対応スマートスピーカースキルの作り方

# はじめに
LINE BOOT AWARDS 2018のハッカソンにてチームで開発した「心の音」というスキルがあり、現在Clova、Alexaにてリリースされています。
obnizと心拍センサーと合わせて使うスキルとなっており、現在の心拍数に応じてオススメの曲をレコメンドしてくれるスキルとなっています。

[心の音（Alexa）](https://www.amazon.co.jp/%E7%94%B0%E4%B8%AD%E3%81%BF%E3%81%9D-%E5%BF%83%E3%81%AE%E9%9F%B3/dp/B07K32CK1Q)

![image](https://camo.qiitausercontent.com/aee44b1d27ada51b7579810f36fd9129e1265a12/68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f3230373130392f66333665346130392d303931392d303432332d613536662d6636663637666635333265342e706e67)

このスキルのように、obnizと連携するスマートスピーカースキルの開発ノウハウについて書いていこうと思います。



# obniz IDの音声登録
obniz IDは8桁の数値で構成されるので、そのぐらいの情報量であれば音声で登録してもらう仕組みが良いでしょう。

このとき8桁を1度に伝えるか、4桁を2度に分けて伝えるかという判断が出てきますが、ベストは両方の方法を実装することでしょう。
どちらか一方を実装する場合は4桁を2度に分けた実装のほうがユーザーに優しいと思いますが、一番ラクな実装は8桁を一度に伝える方法かと思います。

ちなみにアカウントリンクを使用してGUIからobniz IDを入力する方法もありますが、こちらは中々手間ですし折角の音声スキルなら音声で登録させたほうがいいかなと思います。

## スロットの実装
obniz IDの読み上げは例えば「1234-5678」というIDだった場合、ユーザーは「せんにひゃくさんじゅうよん の ごせんろっぴゃくななじゅうはち」と読み上げはせず、「いちにーさんよん の ごーろくななはち」と読み上げるでしょう。
ClovaやAlexaにはビルトインスロットとして「CLOVA.NUMBER」や「AMAZON.NUMBER」が用意されていますが、どちらも前者のような読み上げ方にしか対応していません。
そのためID読み上げの拾い方について考える必要があります。

Alexaには「AMAZON.FOUR_DIGIT_NUMBER」という、まさにうってつけなビルトインスロットがあります。
ただ、FOURと名前についているものの4桁以外も認識してしまうため、桁数チェックをあわせて実装しておきましょう。

ClovaのほうではAlexaのようなビルトインスロットがなく、以下のようなスロットを独自に登録し、インテントに1桁づつ割り振りす必要があります。

[ スロット ]
![image.png](https://qiita-image-store.s3.amazonaws.com/0/207109/06f84ef2-2c56-6e48-fee7-165f2e304976.png)

[ インテント ]
![image.png](https://qiita-image-store.s3.amazonaws.com/0/207109/00a01f12-d32c-bdc4-e12c-318688e06505.png)

このようにユーザーのobniz IDを取得し、ユーザーIDをキーとしてDBに格納しておきます。



# バックエンド実装の注意点
バックエンド実装で注意すべき点として、タイムアウトがあります。
Clova、Alexaに話しかけてから応答を返すまでの処理の時間です。
現在、Clova、Alexaとも8秒ほどあるので、センサーデータの取得等には十分な時間です。

ただしこのあたりの仕様は変更される可能性もあるため注意が必要です。
※Clovaは一時期8秒→3秒→8秒と変化していました。

8秒を超える処理を行うときには工夫が必要で、バックエンドからスキルのプロセスとは別のプロセスを起動したりと、色々と方法は考えられます。
このあたりの話は文量が多くなってしまうのでまた別の機会にまとめたいと思います。



# スキルリリースにあたっての注意点
Clova、Alexaそれぞれでobniz連携スキルのリリースにあたり、色々と注意点があります。

## 共通
### obnizとの接続方法を分かりすく説明したページを用意する
obnizとパーツの接続方法を写真を使って分かりやすく説明したり、必要になるパーツの購入先（秋月等）のリンクを掲載したり、スキルの使い方やプライバシーポリシー等を記載したページを作成し、スキル説明欄にそのページのリンクを掲載しました。

参考までに説明ページのリンクです。
[心の音 説明ページ（Clova版）](https://qiita.com/miso_develop/private/c3dd542eaae857f37350)
[心の音 説明ページ（Alexa版）](https://qiita.com/miso_develop/private/c0ff6a89b9f7163f1174)

## Clova
### スキル無効化時にユーザーデータをクリアすること
他の音声アシスタントには無い実装なのですが、Clovaはスキル無効化時にイベントが発生します。
このイベントを適切にハンドリングし、その中でobniz IDといったユーザーデータをDBへ格納している場合はクリアする必要があります。

## Alexa
### プライバシーポリシーへの明記
これはobnizというよりかは、「心の音」というスキルの特徴にもよる部分かと思います。
心拍数というセンシティブな情報を取得することをプライバシーポリシーへ明記しなさいと指摘がありました。
心拍数に限らず、センサーデータを取得する場合も同様にプライバシーポリシーへの明記は必要になるかもしれません。

プライバシーポリシーってどんな感じに書けばいいんだって方もいらっしゃると思いますので、「心の音」のプライバシーポリシーの文面を以下にご紹介致します。

> # プライバシーポリシー
> ## 個人情報の利用目的
> 本スキルでは、ユーザーのobnizのIDおよび心拍数を取得し保管致します。
> obnizのIDおよび心拍数はおすすめの音楽とのマッチングのために利用致します。
> この目的以外にユーザー情報を利用することはありません。



# さいごに
obnizというマイコンに対応したスキルがリリースできるのか半信半疑のままスキル開発を進めていましたが、Clova、Alexaともに無事リリースすることが出来ました。
Google Assistantへのリリースにもそのうち挑戦してみようと思います。

スマートスピーカーはそれ自体がIoTな機器ですので、obnizや様々な電子パーツと組み合わせることでIoTガジェットとしての幅が一気に広がると思います。
本記事がobnizと連携したユニークなスキルリリースの助けとなりましたら幸いです。
【備忘録】Ubuntu18.04のCUDA10&Python3&PyTorch環境構築


研究室のPCの環境構築を頼まれたので，また構築を頼まれた時に楽ができるようにメモしておきます．

# 環境

* OS : Ubuntu 18.04.1 LTS 64bit
* CPU : Intel core i3 @ 4.00GHz x 4
* GPU : GeForce GTX 1080 Ti

# CUDA 10.0

[CUDA Toolkit 10.0 Download \| NVIDIA Developer](https://developer.nvidia.com/cuda-downloads)
Installer Type で deb(network) を選択する場合

```
$ sudo apt update
$ sudo apt upgrade

$ sudo apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub

$ wget http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-repo-ubuntu1804_10.0.130-1_amd64.deb
$ sudo dpkg -i cuda-repo-ubuntu1804_10.0.130-1_amd64.deb
$ sudo apt update

$ sudo apt install cuda cuda-drivers  # cuda-10-0でver指定も可能
$ sudo reboot  # 再起動
```

```
$ rm cuda-repo-ubuntu1804_10.0.130-1_amd64.deb

$ export PATH="/usr/local/cuda/bin:$PATH"
$ export LD_LIBRARY_PATH="/usr/local/cuda/lib64:$LD_LIBRARY_PATH"

$ exit  # 端末を起動しなおす
```

```
$ nvidia-smi  # 確認

$ sudo apt autoremove
$ sudo apt clean
```

~~間違えてUbuntu16.04向けのものをダウンロードしたらaptの依存関係エラーで大変なことになった...~~

# Anaconda

下記サイトからインストーラーをダウンロード
[Downloads - Anaconda](https://www.anaconda.com/download/#linux)

2系を使う予定がなかったので Python 3.7 version を選択（2系なら2.7）

```
$ bash ./Anaconda3-5.3.1-Linux-x86_64.sh  # .shファイルが保存されているディレクトリで実行
```

ラインセンスを読んで同意し，インストール場所を設定（デフォルトはEnter）するとインストールが開始

```
$ conda -V  # 確認
conda 4.5.11
```

### 仮想環境構築

環境名とPythonのバージョン，インストールしたいパッケージを羅列して実行

```
$ conda create -n 環境名 Python=x.x パッケージ
```

例）

```
$ conda create -n py37 python=3.7 anaconda
Proceed ([y]|n)? y
```

### アクティブ

```
$ conda activate 環境名
```

### 確認

```
$ conda info -e
# conda environments:
#
base               * /home/.../anaconda3
py37                 /home/.../anaconda3/envs/py37

$ conda activate 環境名
$ python -V
Python 3.7.1
```

### 非アクティブ

```
$ conda deactivate
```


### 仮想環境の削除

```
$ conda remove -n 環境名 --all
```

# PyTorch

[PyTorch 公式HP](https://pytorch.org/)
Get Start から自分の環境を指定するとインストールコマンドが出力される．

```
$ conda install pytorch torchvision cuda100 -c pytorch
```

# GPU動作確認

### その１

```
$ python
>>> import torch
>>> nums = torch.randn(2,2)
>>> nums.cuda()  # 結果が出ればおｋ
```

### その2

```
$ git clone https://github.com/pytorch/examples.git
$ cd examples/vae/
$ python main.py  # 結果がでればおｋ
```

[
A repository showcasing examples of using PyTorch](https://github.com/pytorch/examples.git)

実行中に `$ nvidia-smi -l` を実行して確認する．

# メモ
### VisualStudioCodeのインストール

[Visual Studio Code - Code Editing. Redefined](https://code.visualstudio.com/)

### Gitのインストール

```
$ sudo apt-get install git
```

# 参考にしました
[Ubuntu 18.04へのCUDAインストール方法 - Qiita](https://qiita.com/yukoba/items/4733e8602fa4acabcc35)
[Ubuntuを初めて触るド素人がAnacondaを入れてみた - Qiita](https://qiita.com/m0p1nt/items/b55b175c78ecfa42eeea)
[Markdown記法 チートシート - Qiita](https://qiita.com/Qiita/items/c686397e4a0f4f11683d)
[WindowsでCUDA+PyTorchのサンプル実行するまでのメモ - Qiita](https://qiita.com/stkdev/items/91b12610dcb9782f3b63)
Ionicでピンチイン・アウトでフォントサイズを変更してみる(iOS safari対応)

私が個人開発しているAAまとめzip配信のサービス(AAHub)にて要望があった内容です。スマホでピンチイン・アウトの操作をした時にフォントサイズの変更を行えるようにしました。
![fontchange.gif](https://qiita-image-store.s3.amazonaws.com/0/165335/425bbdd8-a942-7302-31ad-48fe844457d1.gif)

本記事ではその時の実装を振り返ってみます。

## ピンチイン・アウトによるFontSize変更
基本的に、ピンチイン・アウトをした時にフォントサイズを変更するには以下の手順があります。

1. ピンチイン・アウトをリスティングするDirectiveを作る
2. 開き具合、閉じ具合の移動量を測定する
3. 移動量に合わせてfontSizeを変更する
4. ピンチイン・アウトによる画面全体の拡大縮小を無効化する(iOS safari用)

さて、このうち1、2、3についてはすでに同様の物を作成している方がいます。なので、今回はこちらを使用しました。
[https://github.com/ionicrun/using-the-pinch-gesture-in-ionic-2](https://github.com/ionicrun/using-the-pinch-gesture-in-ionic-2)



## 4. ピンチイン・アウトによる画面全体の拡大縮小を無効化する(iOS safari用)
1〜３の実装だけですとピンチイン・アウトをしたときに画面全体が拡大・縮小されてしまいます.
![error.gif](https://qiita-image-store.s3.amazonaws.com/0/165335/96128112-6888-b7e5-460e-0cef9c859761.gif)

というわけで、こちらを無効化する必要があります。今回は以下のソースコードを`index.html`に追加しました。

```html:index.html
    <script>
document.documentElement.addEventListener('touchstart', function (e) {
  if (e.touches.length >= 2) {e.preventDefault();}
}, {passive: false});
/* ダブルタップによる拡大を禁止 */
var t = 0;
document.documentElement.addEventListener('touchend', function (e) {
  var now = new Date().getTime();
  if ((now - t) < 350){
    e.preventDefault();
  }
  t = now;
}, false);
    </script>
```

こちらのソースコードを追加するとiOS Safariでも文字の拡大・縮小のみが動作するようになります。

## ソースコード
[https://github.com/scrpgil/pinch-fontsize-change/tree/master](https://github.com/scrpgil/pinch-fontsize-change/tree/master)


## まとめ
もし、ピンチイン・アウトによる処理を行う＆Webにも同様の機能を実装するという方は善行にしてみてください。
ntpのlogを出力しようとしたらPermission deniedって言われたときの話

# 1. 経緯
そもそもntpのログなんてものはほとんどの場合で不要なのだが、やんごと無き理由により出力する必要に迫られた。

まぁこんなものはntp.confに適当に書けば動くだろうと踏んでいたんだが、唐突にSyslogにPermission deniedとか吐いてきやがったのでその対処を。

# 2. 環境

```
kernel:
linux-image-4.4.0-130-generic 4.4.0-130.156 (amd64 binary) in ubuntu xenial

ntp:
1:4.2.8p4+dfsg-3ubuntu5.9
``` 

# 3. 出力されたエラー

```
# /var/log/ntpstats/ntpd.log はログの出力先に指定していた奴
Cannot open logfile /var/log/ntpstats/ntpd.log: No such file or directory
```

# 4. 解決策

以下のようなスクリプトで動くはず。詳細は後述。

```bash

# ntp.conf

# 省略

# 末尾にこれを書く
logfile /var/log/ntpstats/ntpd.log
```


```bash
# setup.sh

#!/bin/bash

sudo bash -c "cat ntp.conf > /etc/ntp.conf"

sudo mkdir -p /var/log/ntpstats/

sudo apt-get install apparmor-utils -y
sudo aa-complain /usr/sbin/ntpd

sudo /etc/init.d/ntp restart
```

# 5. 解説

ポイントは以下

```bash
sudo apt-get install apparmor-utils -y
sudo aa-complain /usr/sbin/ntpd
```

筆者の環境の場合、ntpdはデフォルトでAppArmorというセキュリティ制限をかけるシステムに支配されていた。

AppArmorは例えばプロセスが読み込めるファイルに制限をかけたりするのだが、その動作には以下のようなモードがある

- Enforceモード
    - プロファイルで許可された操作以外は絶対に許可しない
- Complainモード
    - プロファイルで許可された操作以外もできるが、ログに記録される

今回のntpdはこのEnforceモードになってしまっていたため、新しく作るログファイルに記録できなくなっていた。

そのため ```aa-complain``` コマンドでこれをComplainモードに書き換えている。

正直ntpはEnforceモードで無くても良いなと思ったのでこうしているが、もし超厳密にセキュリティを意識するならプロファイルに記述する形になると思う。
Node.js環境の構築とUNIXドメインソケットによるNginxとの連携

# 意外に解説のないUNIXドメインソケット

　今更、これを記事にしなくてもと思う人が大半だろう。Node.jsとNginxの連携など、いくらでも情報がある。しかし意外なことに、UNIXドメインソケットを使って連携する方法はQiitaの記事に存在しなかった。何故かTCPのlocalhost:3000を使用しているものばかりだ。

　パフォーマンス的にはUNIXドメインソケットを使う方が優れているので、同じサーバ上で動いているのなら、わざわざTCPを使う必要性は無い。


# Node.jsのインストール

Node.jsの10系統をインストールする(デフォルトだと現時点では8系統)
CentOS系だとaptをyumに置き換えるだけ

```
curl -sL https://deb.nodesource.com/setup_10.x | sudo bash -
sudo apt -y install nodejs
```

# インストール結果の確認

```
nodejs -v
```

#テストアプリケーションの作成
プログラムをホームディレクトリに置くのを前提条件として以下のような構成を作る

```
~/node_app/       Node.jsアプリ作成用親ディレクトリ
           app/   Node.jsのプログラム置き場
           sock/  UNIXドメインソケット置き場
```

テストプログラムの作成

```app/indes.js
const SOCK_PATH = 'sock/app.sock' //ドメインソケット用パス 
var fs = require('fs') 
var http = require('http') 

var server = http.createServer() 
server.on('request',function(req,res) { 
    res.writeHead(200) 
    res.write('<html><body>Hello world</body></html>\n') 
    res.end() 
}) 
try{fs.unlinkSync(SOCK_PATH)}catch(e){} //ソケットファイルの削除 
server.listen(SOCK_PATH)                //ソケットの待ち受け設定 
fs.chmodSync(SOCK_PATH, '666')          //アクセス権の変更
```

UNIXドメインソケットを使用する場合いくつかの注意事項がある
・UNIXドメインソケットは通信を行うのにファイルが生成されるのだが、プログラムが終了しても自動的に削除されない
　ファイルが存在した場合ソケットの生成に失敗するので、事前に削除
・実行ユーザとNginxのIDが異なると、アクセス権の問題で接続できない
　その場合はOtherに書き込み権限を与える必要がある
　Otherにアクセス権を与えたくない場合は、実行ユーザのグループにnginxのID(www-data)を追加する
　　usermod -Ga ユーザ名 www-data
　ちなみにCentOSではnginxのIDはnginxだ
　グループへの追加コマンドを実行したらnginxの再起動を行わないと、アクセス権が更新されないので注意すること

#Nginxの設定
/etc/nginx/sites-enabled/default に以下の設定を追加
サイトの設定を別のファイルに行っている場合は、適宜内容を読み替えて欲しい

```
upstream nodesock{ 
     server unix:/対象ディレクトリ/node_app/sock/app.sock; 
}

server { 
        listen 80 default_server; 
        listen [::]:80 default_server;
　　　　・
　　　　・
　　　　・
        location = /nodejs/ { 
            proxy_pass http://nodesock/; 
        }
}
```

#結果の確認
node_appフォルダをカレントディレクトリに設定し、以下のコマンドを実行

```
nodejs app/index.js 
```

確認

```
http://アドレス/nodejs/
```


ログアウトしても動作させたい場合は、コマンドを以下のようにする

```
nohup nodejs app/index.js &
```

ただしこの方法をテスト以外の目的で使用するのはお勧めしない
daemon化するならpm2辺りを使うと幸せになれる

#まとめ

　UNIXドメインソケットはNode.jsだけでなく、その他のアプリケーションサーバやDBなどでも利用できる。通信対象が同じインスタンス内であるのならlocalhost:xxxxは無駄にパフォーマンスを下げるだけなので、それをやってしまっているのなら切り替えていくことをおすすめする。