OmniAICreator/Qiita-1.07M huggingface dataset:
ラムダ式でもSFINAE

## 問題
ラムダ式をオーバーロード風に扱いたい場合など、ラムダ式でもSFINAEで呼び出しを制御したい場合がある
この際、どう書けばよいかについてまとめる

## 解決
通常の関数の場合から考えると
- 引数部
- 戻り値型部
- テンプレート引数部
の３種類が思いつく。これらについてひとつずつ考えていく


### 引数部でSFINAEする

引数の末尾にsfinaeするための部分を付ける
個人的にもっともおすすめ

```c++:例.cpp
std::visit(mylib::overload{
    [](std::string s){return s; },
    [](auto s, decltype(std::to_string(s))* =0){return std::to_string(s); }  //<--to_stringできる奴だけ
}, v);
```
https://wandbox.org/permlink/xPGBYzjpZBMdFMyz

`[](auto s, /*SFINAEしたい項目*/ * =0){/*略*/; } `
`*` `=` の2記号は間を開ける必要があることに注意(くっつけると `*=` に解釈されて文法ミスになる)


- 利点
  - 戻り値型を明記しなくて済む
     - 戻り値型部でやる場合、戻り値型の推論が効かなくなるため自分で書く必要が出てくる
- 欠点
  - 見た目が若干キモイ

### 戻り値部でSFINAEする

```c++:例.cpp
std::visit(mylib::overload{
    [](std::string s){return s; },
    [](auto s)->decltype(std::to_string(s)){return std::to_string(s); }  //<--to_stringできる奴だけ
}, v);
```
https://wandbox.org/permlink/Y3mDOysOYh2sMYZ7

`[](auto s)->/*SFINAEしたい項目+戻り値型*/{/*略*/ }`

- 利点
  - 上の例の様な「処理XができるかをSFINAEで調べて、できたら処理Xを呼ぶ」みたいなケース、その場合これの見た目が一番キモくない
     - ラムダ式でsfinaeを使う場合、このパターンは結構あると思われる
  - また、戻り値の型に興味がない場合でも
- 欠点
  -  戻り値の型推論が利かなくなるため、SFINAEの条件と戻り値の型が全然違う場合、見た目がキモくなるor辛くなる
     - 要するに「汎用でない」

### テンプレート引数部でSFINAEする

テンプレート引数部なんてものはラムダ式にない。したがってここでSFINAEする方法もない
少なくともC++17現在では

C++20ではラムダ式にもテンプレート引数部が存在するようになるといわれている
Pointcut Expression 複数指定したい

例えばとある`@Around`を、特定の**2クラス**に対して指定したい場合、  
` || `で見慣れた書き方ができるよ

```java
@Around("execution(* a.b.ClassName.*(..)) || execution(* x.y.ClassName.*(..))")
public void f() { ... }
```
ヘッドレスブラウザ Chrome + Chromy で操作した内容を録画する


[Chromeのブラウザ内（もしくはデスクトップ）操作をJavaScriptで録画する](https://qiita.com/zaru/items/4b766dc3cdee90a2faf8)に続いて、今度はヘッドレスブラウザ (Chrome) で操作した内容をビデオ録画する方法を紹介します。今回は [Chromy](https://github.com/OnetapInc/chromy) というライブラリを利用します。

機能的には Chrome DevTool に用意されている [startScreencast](https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-startScreencast) を利用します。Chrome ヘッドレスブラウザのライブラリといえば [puppeteer](https://github.com/GoogleChrome/puppeteer) という感じがあるのですが、 Chromy は `startScreencast` のラッパーを用意してくれているので、サクッと使えるのが良いところです。

## サンプルコード

指定のページを開いて `startScreencast` をした後、なんらかの操作をします。その後、 `stopScreencast` で処理を終了すると `startScreencast` コールバックで受け取ったキャプチャデータを画像ファイルとして保存してあげているだけです。この時点では単なる画像ファイルです。

```javascript
const Chromy = require('chromy')
const fs = require('fs')

let chromy = new Chromy()
let frameNum = 0
chromy.chain()
      .goto('https://noco.fun/b/vjhqmkzFIDjJNLuLDGrj/e/vgCqD11cYntd173Y4JvB/?scene=0')
      .startScreencast(async (payload) => {
        frameNum++
        fs.writeFileSync(
          `./frame${String(frameNum).padStart(5, '0')}.png`,
          payload.data, { encoding: 'base64' })
      }, {format: 'png'})
      .sleep(5000)
      .evaluate(_ => {
        document.querySelector('.episode-player__goto-nextframe-button').click()
      })
      .sleep(1000)
      .evaluate(_ => {
        document.querySelector('.episode-player__goto-nextframe-button').click()
      })
      .sleep(1000)
      .evaluate(_ => {
        document.querySelector('.episode-player__goto-nextframe-button').click()
      })
      .sleep(1000)
      .evaluate(_ => {
        document.querySelector('.episode-player__goto-nextframe-button').click()
      })
      .sleep(1000)
      .stopScreencast()
      .sleep(3000)
      .end()
      .then(_ => chromy.close())
      .catch(_ => { console.log(_); chromy.close() })
```

### ffmpeg で動画へ結合

このままだと単なるパラパラマンガになってしまうので `ffmpeg` コマンドで結合します。フレームレートは適当です。

```
ffmpeg -r 6 -i frame%05d.png -pix_fmt yuv420p -r 10 output.mp4
```

これで晴れて mp4 ファイルになって操作の様子を動画に録画することができました。ヘッドレスブラウザなので裏で何かの処理を再現したりするのに使えそうです。

## デモ


さすがに 60fps のようなヌルヌル感はないですが、ぎりぎり使えるくらいの感じにはなってるかなと思います。ただクオリティ重視の場合はちょっと厳しいかな。

![output.gif](https://qiita-image-store.s3.amazonaws.com/0/2152/aa42105b-d892-a589-5793-0406d2ddab93.gif "output.gif")

mp4 をアニメーション GIF に変換したので画質はあれですが再生感はこんな感じです。
Nuxt.jsでSassの変数やMixinsを管理する（resources-loader）

> **10/31追記**
>
> `node-sass-glob-importer`を使用すると記載していましたが、`nuxt-sass-resources-loader`のみで同等のことが可能だったため書き直しました。

# Sassの変数やMixinsを使う

Nuxt.jsでは `nuxt-sass-resources-loader` を使うことで、変数やMixinsなどを各コンポーネントで使えるようになります。

> [nuxt-sass-resources-loader](https://github.com/anteriovieira/nuxt-sass-resources-loader)

```js
{
  modules: [
    ['node-sass-resources-loader', '@/assets/styles/resources.sass']
  ]
}
```

```sass:@/assets/styles/resources.sass
=button($width: auto, $height: auto)
  width: $width
  height: $height
  color: #333
  border: 1px solid #ccc

  &:disabled
    background: #ccc
```

```vue:@/pages/login.vue
<style lang="sass" scoped>
.submit
  +button(320px, 60px)
</style>
```

# Globを使ってファイルを指定する

`nuxt-sass-resources-loader`ではGlobを使ってファイルを指定することもできます。

```js:nuxt.config.js
{
  modules: [
    ['nuxt-sass-resources-loader', '@/assets/styles/resources/**/*.sass']
  ]
}
```

これで、`styles/resources`以下のすべてのSassファイルを使用できるようになります。

# 読み込む順序を指定する

変数など、読み込む順番を気にしなければならない場合は、配列で指定します。

```js:nuxt.config.js
{
  modules: [
    ['nuxt-sass-resources-loader', [
      '@/assets/styles/variables/**/*.sass',
      '@/assets/styles/utilities/**/*.sass',
      '@/assets/styles/components/**/*.sass'
    ]
  ]
}
```

# Links

* [nuxt-sass-resources-loader](https://github.com/anteriovieira/nuxt-sass-resources-loader)
vue.js+Firebase+vue.draggableな連携　

vue.draggableとFirebaseを組み合わせてみました。
みなさまvue.draggable紹介してくれているんですけど、DBに保存するところまで書いてくれていないんですよね。。。決まったデータに要素追加してそこでの動きだけ見て終わり。な記事はたくさんあるんですけど、やりたいのはオンラインに保存するところ。

というわけで、ちょちょいとかいてみました。

      import draggable from 'vuedraggable'

してスタート。


あとは、ボードの内容が変わったタイミングで、Firebaseのaddかupdateを実行するだけ。以上です。watchとかにぶち込んでおきましょう。いかのような感じで。

      <draggable class="list-group" element="ul" v-model="list" 
       :options="dragOptions" :move="onMove" @start="isDragging=true" 
       @end="isDragging=false">


      watch: {
         isDragging(newValue) {


localstorageに保存してもいいんですが、まぁ、処理はどっちかに絞りたい。。。のでFirebaseによせましょう。ちなみに条件分岐がけっこう手間かかる。。。

はまった個所：
・firebaseに登録するときは、ボードの情報をまるっと文字列で保存するべし。Jsonstringify便利。
・文字列をJSON.parseし、arrayとして<draggable>に流し込む。
・firebaseにデータがあるかないかでupdateを実行したいがタイミングを間違うと、ドキュメントが重複登録される。ここはconsole.logを打ちまくってどのタイミングでどう動いているのかを把握すべし。

それでは良きVueライフを～ ^o^
社会人が片手間で取る統計検定2級

# 概要
* 通勤時間の本読みと公式過去問3周とWebでなんとか合格までは到達できる。
* 主に使用した教材は下記
 1. [まずはこの一冊から 意味がわかる統計学 (BERET SCIENCE)](https://www.amazon.co.jp/gp/product/4860643046/)
 2. [日本統計学会公式認定 統計検定 2級 公式問題集[2015〜2017年] ](https://www.amazon.co.jp/%E6%97%A5%E6%9C%AC%E7%B5%B1%E8%A8%88%E5%AD%A6%E4%BC%9A%E5%85%AC%E5%BC%8F%E8%AA%8D%E5%AE%9A-%E7%B5%B1%E8%A8%88%E6%A4%9C%E5%AE%9A-2%E7%B4%9A-%E5%85%AC%E5%BC%8F%E5%95%8F%E9%A1%8C%E9%9B%86-2015%E3%80%9C2017%E5%B9%B4/dp/4788925451/)
 3. [改訂版 日本統計学会公式認定 統計検定2級対応 統計学基礎](https://www.amazon.co.jp/改訂版-日本統計学会公式認定-統計検定2級対応-統計学基礎-田中豊/dp/4489022271/)
 4. [統計検定2級　模擬問題集1](https://www.amazon.co.jp/gp/product/B07DNW5S5J/)
 5. [統計学の時間](https://bellcurve.jp/statistics/course/)

# 使用電卓
* 電卓はルート計算できるものは必須。僕は[これ](https://www.amazon.co.jp/%E3%82%AB%E3%82%B7%E3%82%AA-%E3%82%B8%E3%83%A3%E3%82%B9%E3%83%88%E3%82%BF%E3%82%A4%E3%83%97-12%E6%A1%81-%E3%83%AC%E3%83%83%E3%83%89-JF-Z200RD-N/dp/B0090UNLDE)を使いました。

# 前提条件
* 理系私立大学卒・数学が嫌い・統計は勉強したことがない社会人です。
* 統計の知識がないままstatsmodelsを使ってシステムを組んでいましたが、根拠をもった説明を行いたくなったため統計検定をうけることを決意
* 頑張れば割となんとかなる。

# 勉強方法
* 通勤時間(往復1時間弱)は、[統計学の時間](https://bellcurve.jp/statistics/course/)をひたすら閲覧。
    * 「なぜこの式を使うのか。なぜこうなるのか。」を意識することが大切
    * 誤植があるので疑いながらじっくり読むといいと思う。
  
* 腰を据えての勉強は最後の1週間
    1. 公式の問題集を解く。間違えたところはすべてチェックし、理解できないところは飛ばす。
        * GoogleKeepで間違えたところをメモして、チェックリストにしてました。
    2. Webサイトを見つつ、2週目スタート。2周目も間違えたところは公式テキストで確認。
        * GoogleKeepで一度チェックを付けたところも、間違えたら元に戻して再度確認をしました。
    3. 3周目で7~8割くらいとれれば、模擬問題集解いて試験へ。
        * このあたりで、解ける問題は勝手に手が動くので、手が動かない＝確認対象として補強しました。

こんな感じで本番では、7割程度で合格しました。ギリギリですね。

# おすすめ
* はじめは式を丸暗記して、問題を解くことに集中。
* 式を全部丸暗記できて、記号の意味が説明出来たらもうほぼ合格できると思う。
* 検定はたくさん種類があるので、樹形図みたいに体系的に整理すると覚えやすい。
* 僕の感覚では、公式問題集よりCBTのほうが難しく感じたため、模擬問題集はやったほうがいい。（模擬問題集のほうが難しい）
* [統計WEB様](https://bellcurve.jp/statistics/)のおかげで合格できたようなもの。

JOBチェンジしてデータ分析者として覚醒するため、次の勉強（機械学習？データベース？）を開始します。
【Kotlin】Spring DevTools におけるホットデプロイの設定

##　概要
* Spring Boot を用いた開発をするときに毎回と言っていいほどホットデプロイの設定でつまづくので備忘録として設定の手順を残しておこうと思います。Spring Bootのバージョンは 2.0.6, ビルドシステムは gradle を使用します。

## 1. SPRING INITIALIZR で Devtools の Dependency を追加
![スクリーンショット 2018-10-23 9.49.55.png](https://qiita-image-store.s3.amazonaws.com/0/221568/2c338dcd-955d-31f2-bd44-f59066fa0707.png)

## 2. 自動ビルドの設定を有効にする
ここからはIntelliJでの作業になります。

* shift * 2 でなんでも検索を起動（私はなんでも検索を使わないと設定箇所を特定できなかったのでこの方法をとっています。）
* 「settings」 とタイプし、下の方の「Default Settings」 を選択する
<img width="400" alt="スクリーンショット 2018-10-22 23.43.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/221568/0ccbde60-4836-c988-50db-504b6a4a5a07.png">

* 「Build, Execution, Deployment」 -> 「Compiler」 の 「Build project automatically」にチェックを入れる
<img width="400" alt="スクリーンショット 2018-10-22 23.49.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/221568/c9a74719-60b9-8657-4d59-bc6d39dcafba.png">

* 再びなんでも検索を起動し、「registry」 とタイプし、一番下の「Registry」 を選択
<img width="400" alt="スクリーンショット 2018-10-22 23.56.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/221568/a998806e-abad-c41e-0cc3-4783dca76817.png">
* 「compiler.automake.allow.when.app.running」 にチェックを入れる。
<img width="400" alt="スクリーンショット 2018-10-22 23.57.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/221568/a85c97c0-d78f-d856-e667-cfb91db70149.png">

## 3. build.gradle の設定
* build.gradle に以下を追加

```gradle:build.gradle
apply plugin: 'idea'
idea {
	module {
		inheritOutputDirs = false
		outputDir = file("$buildDir/classes/kotlin/main")
	}
}
```
以上の設定をするとファイルが更新された時点で自動的に変更が反映されるようになります。

## 参考文献
[Spring Boot (Kotlin) はじめの一歩](https://qiita.com/Yuki10/items/aef152f300a500b85725)
[Spring Boot — Hot Swapping a Gradle project in IntelliJ with Kotlin support](https://medium.com/@bojanbelic/spring-boot-hot-swapping-a-gradle-project-in-intellij-with-kotlin-support-3559996dfafd)
systemd で Phoenix を管理する

Phoenix をサービス化して systemd で管理できないかと思い、試してみました。
環境は、CentOS 7 の Docker コンテナを利用しています。

### ユニットファイルの作成

ユニットファイルを以下のように作成してみました。
どのタイミングで参照するのかわかりませんが、環境変数 HOME を定義しないと起動に失敗しました。

<pre>
[root@phoenix ~]# vim /etc/systemd/system/phoenix.service
[Unit]
Description=Phoenix web service
After=syslog.target
After=network.target
After=nginx.target

[Service]
WorkingDirectory=/apl/test
Environment=MIX_ENV=prod PORT=4001 HOME=/home/homulilly
ExecStartPre=/bin/mix ecto.migrate
ExecStartPre=/bin/mix clean
ExecStartPre=/bin/mix compile
ExecStartPre=/apl/test/compile-assets
ExecStartPre=/bin/mix phx.digest
ExecStart=/bin/mix phx.server
User=homulilly
Group=homulilly
StandardError=syslog
SyslogIdentifier=phoenix

[Install]
WantedBy=multi-user.target
</pre>

### assets のコンパイルのためのスクリプト作成

ユニットファイルの中で `ExecStartPre` に指定している `compile-assets` によって assets をコンパイルしています。

<pre>
[homulilly@phoenix test]$ vim compile-assets
#!/bin/sh

LANG=en_US.UTF-8
NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"

# clean
/bin/rm -f ./priv/static/css/*

# compile
cd ./assets
node node_modules/brunch/bin/brunch build
</pre>

### syslogd の設定ファイル作成

ログは syslogd で収集します。

<pre>
[root@phoenix ~]# vim /etc/rsyslog.d/phoenix.conf
if $programname == 'phoenix' then /var/log/phoenix/phoenix.log
</pre>

### syslogd 再起動と Phoenix 起動

<pre>
[root@phoenix ~]# systemctl restart rsyslog
[root@phoenix ~]# systemctl start phoenix
</pre>

以上で、ソースコード変更がサービス再起動で反映されるようになりました。
scikit-learnの使用例

#はじめに
こんばんは、supercellです。ここでは、機械学習ライブラリの一つであるscikit-learnの使用例を解説していきます。
※ここで紹介するコードは以下のリンクから参照することができます。
[python-machine-learning-book-2nd-edition](https://github.com/rasbt/python-machine-learning-book-2nd-edition/tree/master/code/ch03)

#scikit-learnとは？
**scikit-learn**は機械学習のライブラリの一つで、様々なアルゴリズムのほかに、データの前処理や、モデルの調整や評価を行うための便利な関数を取り揃えています。

#実装例
今回は、パーセプトロンのモデルを用います。データセットは、Irisデータセットの特徴量を2つ使用します。Irisデータセットは、scikit-learnにすでに用意されているため、簡単に取り込むことができます。

では、実装していきます。

```python
from sklearn import as datesets
import numpy as np
#Irisデータセットをロード
iris = datasets.load_iris()
#3,4列目の特徴量を抽出
X = iris.data[:, [2,3]]
#クラスラベルを取得
y = iris.target
#一意なクラスラベルを出力
print('Class labels:', np.unique(y))
```

Irisデータセットをダウンロードした後、特徴行列**X**に代入し、ベクトルyにクラスラベルを代入しています。
np.unique(y)によって一意なクラスラベルを返しています。ここでは、Iris-setosa、Iris-versicolor、Iris-virginicaがすでに整数(0，1，2)として収納されていることがわかります。

```python
from sklearn.model_selection import train_test_split
#トレーニングデータとテストデータに分割
#全体の30％をテストデータにする
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, 
                                                    random_state=1, stratify=y)
```
train_test_split関数を用いて、X配列とy配列の30％のテストデータと70％のトレーニングデータに分割しています。また、ランダムなクラスラベルに分割するために、データはシャッフルされます。
stratify=yを指定することで、トレーニングデータとテストデータのクラスラベルの比率を等しくすることができます。比率を確認するには、Numpyのbincount関数を用います。

```python

>>>print('Labels counts in y:', np.bincount(y))
Labels counts in y: [50, 50,50]
```
機械学習では、最適化の際、**標準化**という特徴量のスケーリングを行う。scikit-learnのStandardScalerクラスを使って特徴量の標準化をおこなうことができる。

```python
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
#トレーニングデータの平均と標準偏差を計算
sc.fit(X_train)
#平均と標準偏差を用いて標準化
X_train_std = sc.transform(X_train)
X_test_std = sc.transform(X_test)
```
テストデータの標準化の際に、トレーニングデータの標準偏差と平均を用いていることに注意です。これは、トレーニングデータとテストデータの値を比較することができるようにするためです。

scikit-learnのほとんどのアルゴリズムは一対他手法が使用されるため、3つ以上のクラスラベルを比較することができます。実際にパーセプトロンのモデルをトレーニングしてみましょう。

```python
from sklearn.linear_model import Perceptron
#エポック数40、学習率0.1でパーセプトロンのインスタンスを生成
ppn = Perceptron(n_iter=40, eta0=0.1, random_state=1)
#トレーニングデータをモデルに適合させる
ppn.fit(X_train_std, y_train)
```
[前回](https://qiita.com/undermountainaf/items/3ebabec53b5d1279fe80)パーセプトロンを学習させた際の変数の定義と同じです。

次に、トレーニングの後に予測を行うことができます。

```python
y_pred = ppn.predict(X_test_std)
#誤分類のサンプルの個数を表示
print('Misclassified samples: %d' % (y_test != y_pred).sum())
```
このコードにより、誤分類する確率を出すことができます。

また、scikit-learnでは、性能指標を計算する機能も備えています。具体的に、正解率をみてみます。

```python 
>>>from sklearn.metrics import accuracy_score
>>>#分類の正解率を表示
>>>print('Accuracy: %.2f' % accuracy_score(y_test, y_pred))
Accuracy: 0.93
```

以上がscikit-learnの実装例となります。

#おわりに
scikit-learnを用いると、はるかに楽にモデルを作成することができることがわかりました。
次回は、ロジスティック回帰について説明する予定です。お楽しみに。

#参考文献
[Python機械学習プログラミング](https://www.amazon.co.jp/Python-%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-%E9%81%94%E4%BA%BA%E3%83%87%E3%83%BC%E3%82%BF%E3%82%B5%E3%82%A4%E3%82%A8%E3%83%B3%E3%83%86%E3%82%A3%E3%82%B9%E3%83%88%E3%81%AB%E3%82%88%E3%82%8B%E7%90%86%E8%AB%96%E3%81%A8%E5%AE%9F%E8%B7%B5-impress-gear/dp/4295003379/ref=pd_lpo_sbs_14_t_0?_encoding=UTF8&psc=1&refRID=AN9DSEQNY55GPHV725TN)
Windows10とMacとLinuxの使い分けと思う所

以下の記事が古くなって今とは若干違う状況になってきたのではないかと思うので投稿


[Linux, Mac, Windows 3つのOSの使いどころ比較](http://mollifier.hatenablog.com/entry/2015/03/13/222033) by mollifier

## 前提
私の使用環境は以下
- 自作デスクトップマシンでWindows10
- MacBookPro 2011 LateでMac
- Linux（Ubuntu）はサーバー用

Windows、Mac、Linux(UbuntuとCentOS)はどれも使っていますが私が一番使っているのはWindowsです。
Linux触りたては「Linux意外と色々できるやんけ！」と思って一時的にメインとなりましたが、再度Windowsメインになっています。
Mac触りたては「Macキレイだし、Linuxの様な操作もできるやんけ！」と思ってこれも一時的にメインになりました。

## Linux

### 長所
- 開発環境の構築が簡単
- apt-getが便利
- コマンドが便利
- OSの仕組み等、ソースレベルで勉強になる

### 短所
- ~~ない~~
- WindowsやMacでメジャーな製品は動かない事が多い
- 使用した事ない人にとっては敷居が高い
- 種類が多くてわかりにくい
- Microsoft Office使えない
    - Libre Office等代わりになり得る物はいくつかあります。

種類が多くてどれが良いかわからない場合は、Ubuntu Desktopから使用してみると良いかもしれません、色々な物があるのも醍醐味です。

## Mac

### 長所
- 開発環境の構築が簡単
- Xcodeが使えるのでiOSアプリやMac OS様のアプリも作成できる
- コマンドが便利
- Linuxで出来る事もWindowsで出来る事も大体出来る（使用感は異なるが）

### 短所
- Linuxほどコマンドが使いやすくない
- Linuxほどパッケージマネージャも使いやすくない

iOSアプリを作成する際に必要となります。
2011 Lateは最新OSが使用できなくなったため、iTunesが使えなくなってしまいました。

## Windows10

### 長所
- 皆が知ってるソフトとデバイスは大抵Windowsで使える様に作られている
- Windows用のゲームで遊べる（Direct Xを使用した物等）
- WSLがあるためWindowsに親和性の高い、ピュアッピュアなLinuxが使える
    - WindowsにX Serverを入れればGUIアプリも使用できます。
- 皆使える
- なんとFTPやVPSのクライアントも実は搭載されている

### 短所
- 自動アップデートで予期していない時に時間を取られる事がある
- コントロールパネルと設定アプリがあってカオスな事になってる
- Shift-JISがある事でテキストファイルが扱いにくい場合がある

## 思う所

Linuxのコマンドがだんだんと使える様になってきたら、Linuxのコマンドがないと不便だなと感じる様になります。
しかし、昨今のWindowsではWSLやFTPクライアント、VPSクライアントが標準搭載されています。
そのため、外部ツールをインストールする事なくSSHもファイルサーバーへの接続も簡単に行う事が出来ます。
Windows+WSLでも都合良い場合がほとんどで、今に至ります。

Macの良い所はLinuxの知識がちょっと使える事と、Macにしかない高品質なツールが使える事だと思っています。
Laravelを勉強していて学んだことを書いていく 20181022

## has one結合
2つのテーブルを「1対1」の関係で関連づけられることをいう。

Person.phpに下記を追記する。

```php5:Person.php
public function board()
{
    return $this->hasOne('App\Board');
}
```

関連テーブルの情報を表示するようにテンプレートを修正する。
Person/index.blade.phpを修正する。

```php5:index.blade.php
@section('content')
    <table>
        <tr><th>Person</th><th>Board</th></tr>
        @foreach ($items as $item)
            <tr>
                <td>{{$item->getData()}}</td>
                <td>
                    @if ($item->board != null)
                        {{$item->board->getData()}}
                    @endif
                </td>
            </tr>
        @endforeach
    </table>
@endsection
```

上記を修正すると下図のようにboardsテーブルと紐づいて表示される。

<img width="1440" alt="スクリーンショット 2018-10-21 22.02.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/268048/cfca3d05-f721-5e92-01ae-b669d10ee901.png">

##has Many結合
Personモデルのboardメソッドを修正する。

```php5:Person.php
public function boards()
{
    return $this->hasMany('App\Board');
}
```

/Person/index.blade.phpを修正する。

```php5:oinde.blade.php
@section('content')
    <table>
        <tr><th>Person</th><th>Board</th></tr>
        @foreach ($items as $item)
            <tr>
                <td>{{$item->getData()}}</td>
                <td>
                    @if ($item->boards != null)
                        <table width="100%">
                            @foreach ($item->boards as $obj)
                                <tr><td>{{$obj->getData()}}</td></tr>
                            @endforeach
                        </table>
                    @endif
                </td>
            </tr>
        @endforeach
    </table>
@endsection
```

修正すると下図のように全ての利用者の投稿が表示される。

<img width="1440" alt="スクリーンショット 2018-10-22 7.29.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/268048/127b32b4-acbb-750d-4367-a8c2ecd2209f.png">

## belongsTo結合
belongsToとは、従テーブル（boards）から、関連づいている主テーブル(people)のレコードを取り出すこと。

Boardモデルクラスを修正する。

```php5:Board.php
public function person()
{
    return $this->belongsTo('App\Person');
}

public function getData()
{
    return $this->id . ': ' . $this->title . ' (' . $this->person->name . ')';
}
```
しかしこのコードを書いても/boardにアクセスするとエラーが発生してしまう。
Trying to get property of non-objectということはプロパティのオブジェクトを取得できないらしい。

[Laravel belongsToでリレーションした主テーブルのプロパティが取得できない]
(https://teratail.com/questions/119544)

この記事によると　personからの値を取得するには連想配列にするとうまくいくみたい。

```php5:Board.php

public function getData()
{
    return $this->id . ': ' . $this->title . ' (' . $this->person['name'] . ')';
}
```

出力確認したらこれでOKそう。苦労した。

<img width="1440" alt="スクリーンショット 2018-10-23 0.14.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/268048/8dae78f8-b913-85df-2739-b9dcfcf65c77.png">
contentのidを取得したい

初めまして。
初歩的な質問ですが教えていただきたいことがあります。

状況

簡単な説明ですがさせていただきます。

クラス
content　→　message
１　　対　　N　の関係を作成してます。
現状だとmessage/1..Nといったようにパラメーターごとのメッセージボックスに入れる状態で、そのページ内にcreate_formを作成してます。

希望としてはcontentに紐づいたメッセージを作成したいのですが、content_idを取得できていない状態です。
もしお分かりになるようであればアドバイスをいただきたいと思います。
よろしくお願いいたします。

controller

def show
    @content = Content.find(params[:id])
    @message = Message.new
    @messages = Message.where(content_id: @content.id)
  end
  
  # .find_by(id: @content.id)
  # select ... where id = @content.id
  
  def create
    @content = Content.where(content_id: @content.id)
    @message = @content.messages.build(message_params)
    if @message.save
      redirect_back(fallback_location: @content) 
    else
      render "/contents/show"
    end
  end

＊＊showアクションの中にcreateアクションがある

**Content.find(params[:id])
nilclassとなる
**Content.find_by(params[:id])
content_id 1しか取得できない

view

　　<div class="message_form">
　　<%= form_for(@message) do |f| %>
　　<%= f.label :喋ってみよう %>
　　　<%= f.text_area :talk, class: 'form-control'%>
　　　<%= f.submit "送信", class: "btn btn-success btn-sm" %>
　　　<% end %>
　　　</div>

routes

post "/created", to:"messages#create"


上記がコードとなります。
Chromeのブラウザ内（もしくはデスクトップ）操作をJavaScriptで録画する


ブラウザ内の操作をビデオに録画したくなったので調べていたら `getDisplayMedia` という面白そうなものを見つけたので試しに使ってみました。

- [Chrome Canary M70 でScreen Capture API 利用できるようになった](https://medium.com/@voluntas/chrome-canary-m70-%E3%81%A7screen-capture-api-%E5%88%A9%E7%94%A8%E3%81%A7%E3%81%8D%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E3%81%AA%E3%81%A3%E3%81%9F-d57c44cce398)
- [MediaStream.getDisplayMedia()](https://www.chromestatus.com/feature/6744724455030784)

2018/10/23時点の Chrome 70.0.3538.67 ではまだ使えないみたいです。使うためには Canary で試してください。他のブラウザの対応としては Firefox / Edge が対応しているようです。ただし Firefox は呼び出し方が違いました。

- [参考: WebRTC API コトハジメ](https://gist.github.com/voluntas/a31de1837f733933e587bb144c4d50a5)

なおヘッドレスブラウザで録画する方法はこちら

- [ヘッドレスブラウザ Chrome + Chromy で操作した内容を録画する](https://qiita.com/zaru/items/d4de5c2654044db25795)

## サンプルコード

Canary の DevTool コンソールに下記のコードを入力してください。共有確認ダイアログが表示され、選択後３秒間の操作を録画してくれます。その後、webm ファイルがダウンロードされます。面白いです。

```javascript
navigator.getDisplayMedia({audio: false, video: true}).then(stream => {
  const tracks = [...stream.getTracks()]
  const mediaStream = new MediaStream(tracks)
  const rec = new MediaRecorder(mediaStream, {mimeType: 'video/webm; codecs=vp9'})
  const chunks = []
  
  rec.ondataavailable = ev => chunks.push(ev.data)
  rec.start()
  rec.onstop = () => {
    const webm = new Blob(chunks, { 'type' : 'video/webm' });
    const url = window.URL.createObjectURL(webm)
    const a = document.createElement('a')
    a.setAttribute('href', url)
    a.setAttribute('download', 'rec.webm')
    a.click()
  }

  setTimeout(()=>{
    rec.stop();
  }, 3000);
})
```

## デモの様子

![webm.gif](https://qiita-image-store.s3.amazonaws.com/0/2152/f6f2e5de-3114-2c20-874a-e9b8c4715cbf.gif "webm.gif")

今回は Canary のタブを録画しましたが、デスクトップを選択すればデスクトップ全体の録画もできます。
modeule 

＃＃ 初めての module

```ruby

module MyMethods

  def food(name) 
    name
  end
end


class MyClass
 include MyMethods


end

my = MyClass.new
puts my.food("pasta")

→ pasta
```

## できること
- 変数を渡せる
- includeで繋げる


## モジュール関数

```ruby
module MyMethods

  def food
    "food"
  end

  module_function :food
end

puts MyMethods.food


→food

```
クラウド開発をしたことがない人向けのAWS導入解説

# 主旨
今日は、クラウド開発（サーバレス）をしたことがない！！という人向けに、
ザクっと、AmazonのAWSクラウドサービスを紹介するぞ。
サーバーありきの開発とは大きく異なるクラウド開発が、どのようなものか伝わると良きかな。

# Web公開に使うサービス
## S3
これはストレージサービス。DropboxやGoogleDriveのイメージに近い。
しかし、後述するサービスと連携することで静的なWeb資材を配置できるぞ。
すなわち、HTMLやJavaScriptを置くところだ。
※S3自体にも外部公開機能は存在するが、推奨されていない。

## CloudFront
これはコンテンツデリバリーサービス。
S3上のHTMLファイルを外部公開できるようにしてくれるぞ。
404などのエラーごとにもバラバラのHTMLを設定できる。

### Lambda@Edge
後述するLambdaプログラムをHTML表示前に使うことができる機能。
URLの変更や、認証などに使える。ただし、制限が多いサービスなので注意。
使いたい場合は公式マニュアルを先に読んだ方が良い。

## WAF
これはファイアウォール。
一般的な攻撃パターンをブロックするのはもちろん、IP制限などを行うことができる。
とりあえず、開発期間中は特定のIPアドレスだけ設定しておけばOK。
作成した後に、CloudFrontに張り付ける。

## Route53
これはドメインネームシステム。自分で買ったドメインはここに登録しておく。
ちなみにドメインは持っていなくても、CloudFrontでランダムなものが使用可能。


# 動的Webサービス
## Lambda
これは、サーバレスなコード実行環境。10年前にはない新しい概念。
サーバーなしで関数の実行をマネージドにしたサービス。
アクセスが多ければ、大量に並列実行できたりする。
Node.jsやPython、Javaなどが使える。後述する方法でHTMLと連携もできる。
実行時間制限15分などを設定する。

## API Gateway
これは、アプリケーションの「玄関」。
Lambdaに張り付けると、HTMLから呼べるようになる鍵を発行できる。

### CORS
コアーズ（クロスオリジンリソースシェアリング機能）により、
外部ドメインでもAjax通信ができるようになるぞ。


# 全体
## CloudWatch
これはログサービス。
LambdaやらURL監視やら、Webサービスの公開に関するログはここに出る。
メール通知機能などもあるぞ。

## IAM
これは権限管理。これも独特な概念。
基本的に各サービスはバラバラに独立している。
なので、どのサービスがどのサービスを呼ぶのかの権利を設定する必要があるのだ。
また、IP制限やストレージのアクセス権利なども設定できるぞ。
Nuxt.jsのOnsenUIのfont-familyの変え方

## 環境
* Windows 7
* Nuxt.js
* onsenui: 2.10.5

## はじめに  
Nuxt.js×OnsenUI×VuetifyでPWAアプリを作ってるのですが、カスタムフォントを適用しようとしてハマったので
やり方をメモしておきます。
ちなみにフォントは[あんずもじ](http://www8.plala.or.jp/p_dolce/)さんを利用させて頂きました。
文字感はこんな感じ
![image.png](https://qiita-image-store.s3.amazonaws.com/0/230651/6bc6c872-0762-9017-7595-d8bf84afd6dd.png)
よき！

## フォントを設定
まずは使いたいフォントをダウンロードしたら、それをassets/cssディレクトリに置きます。
※cssフォルダがなければ作成します
※この記事ではAPJapanesefont.woff2という名前のフォントファイルを置きました。

次にfont-familyとして利用するためにstyles.scssを以下のように作成しassets/cssディレクトリに置きます。

```scss:styles.scss
@font-face {
  font-family: 'MyFont';
  src: url('./APJapanesefont.woff2') format("woff2");
}
```

最後にstyles.scssファイルを読み込むための設定をnuxt.config.jsに追記します。

```js:nuxt.config.js
  css: [
    { src: '~assets/css/styles.scss' }
  ],
```

これでカスタムフォントをMyFontという名前でfont-familyの一員として利用できるようになりました！

## フォントの適用  
利用できるようになったMyFontを実際にサイトに適用してみます。

まずnode_modules/nuxt-onsenui-module/plugin.jsを開き、OnsenUIが現在利用しているcssファイルを特定します。

```
import 'onsenui/css/onsen-css-components.css'`
```

次に上記のファイルを開き、font-familyを以下の通り修正します。

修正前：

```
.page {
  font-family: -apple-system, 'Helvetica Neue', 'Helvetica', 'Arial', 'Lucida Grande', sans-serif;
```

修正後：

```
.page {
  font-family: -apple-system, 'MyFont','Helvetica Neue', 'Helvetica', 'Arial', 'Lucida Grande', sans-serif;
```

これでサイトにMyFontが適用されました！

## おわりに  
一応これで適用できたものの、node_modulesをいじるのはかなりイケてないですよね。。
できればassetsフォルダ内だけで完結させたかったですが、やり方が分かりませんでした。。
良い方法をご存知の方がいらっしゃればぜひコメントで教えて頂ければ幸いです。

## 余談  
ちなみにハマったポイントとしては、ずっとOnsenUIじゃなくてVuetifyで検索しちゃってたところですね。。
だって見た目の話といえばVuetifyって思うじゃんかよー。
VLAN のお勉強【理論編】

## Virtual LAN, VLAN とは

- **L2 スイッチの物制約を超えて、論理的なセグメントを構築する** 技術のこと。
- L2 スイッチの **物理ポートごとに、論理的な番号を割り当てる** ことで実現する。
- 論理的とはいえセグメントは分離されるため、たとえば一方の論理セグメントで流れるブロードキャストパケットは、もう一方の論理セグメントには到達しない。
- VLAN の技術には以下の二つがある。
   - 一つの物理ポートに VLAN ID を一つだけ指定できる **ポート VLAN**
   - 一つの物理ポートに、複数の VLAN ID を指定できる **タグ VLAN**

## ポート VLAN

- **一つの物理ポートに、一つだけ VLAN ID を指定** する技術。
- 一つの物理 L2 スイッチに接続されていたとしても、VLAN によって生成されたセグメント間は仮想的に分離される。
- そのためこれらのセグメント間で通信を行うためには、物理セグメントと同様にレイヤ3 を経由する必要がある。
- それゆえ、この物理スイッチが L3 スイッチ（ルーティング機能を持つ L2 スイッチ）であれば、これらの論理セグメント間は他のネットワーク機器がなくても通信できる。

![vlan1.png](https://qiita-image-store.s3.amazonaws.com/0/288168/90582835-1d15-9083-3c15-75279aacc393.png)

- 一方ルーティング機能を持たない、単純な（？） L2 スイッチから複数の論理セグメントを生成する場合、これらのセグメント間で通信を行うためにはもちろんルータが必要。

![vlan2.png](https://qiita-image-store.s3.amazonaws.com/0/288168/2f56caee-0721-0ecc-d222-6c484316e41a.png)

- 2 台以上の物理スイッチで VLAN を構築することも可能。
- しかしこの場合、 **全ての物理スイッチについて、論理セグメントの数だけポートが占有される** 。

![vlan3.png](https://qiita-image-store.s3.amazonaws.com/0/288168/5c8840ee-9bdb-0f92-a280-476df6c97982.png)

## タグ VLAN

- **一つの物理ポートに、複数の VLAN ID を指定できる** 技術。
- ポート VLAN 特有の、**「 VLAN の数だけポートが占有される問題」を解決できる** 。
- どのように解決できるかというと...
   - 物理スイッチ間を接続するポート（トランクポート）を対象に、全ての VLAN ID を割り当てる。
   - 異なる VLAN 間で通信を行うとき、送信側スイッチのトランクポートにて送信元の VLAN ID に対応するタグをイーサネットフレームに埋め込む。
   - 受信側スイッチのトランクポートでにて、上記タグで指定された論理セグメントに（ブロードキャストパケットなどを）流す。同時に、イーサネットフレームからタグを除去する。

![vlan4.png](https://qiita-image-store.s3.amazonaws.com/0/288168/99382e47-18b4-7cbe-3d82-c027539f9f71.png)



## 参考文献

- 竹下隆史・村山公保・荒井透・苅田幸雄 (2012) 『マスタリングTCP/IP 入門編』 オーム社
- みやた ひろし (2013) 『インフラ/ネットワークエンジニアのためのネットワーク技術&設計入門』 SBクリエイティブ
- 佐野裕 (2016) 『インフラエンジニアの教科書2 スキルアップに効く技術と知識』 シーアンドアール研究所
Vue.js の computed, method, watch の使い所

#　はじめに
Vue.js を勉強していて、最初に使い方の違いがよく分からなかった `computed`, `methods`, `watch` を忘れないようにメモしていきます。

3つともできることはほとんど同じですが、使い所やパフォーマンスに違うがあります。

## computed と methods の違い
どちらも関数を使って、計算した値を返すという点では同じです。

- `computed`: 計算した結果を新たにプロパティとして公開する仕組み
- `methods`: C++ や Java の関数のように、計算した値を返す仕組み

`computed` と `methods` の違いは、計算結果がキャッシュされるかどうかです。`computed` は計算がキャッシュされ、必要なときのみ再計算をする優れた機能です。しかし、Vue が管理していない値の変化は検知できないので注意が必要です。

## computed と watch の違い
`computed` は、計算した結果が新たにプロパティに加えられます。例えば、プロパティに `price: [100, 200, 300]` とあり、この合計を表す `total` をプロパティに加えたい場合に使用します。
対して `watch` は、特定のプロパティの変更を監視するために使います。例えば、`total` の合計金額が1000円を超えたら `flag` プロパティを `true` にするような処理をするために使用します。
オプショナル型とnil

🌟随時更新🌟
## nil
扱うべき値が存在しないことを表す値。
変数や定数、関数の返り値、式の評価結果が通常の値だけでなく、未設定やエラーなどの状態がある場合、その値をnilで表現する。
## オプショナル型
- 通常の型だけでなく、特殊な場合にnilを値として持つことがある変数や式
- nilを通常の値と誤って使うことを防ぐ

整数の場合、変数や式の型はInt型だが、nilを値として持つことがある変数や式はInt型ではなく、**Int?**という形で扱う。
EX.

````swift
var a: Int = 10
var b: Int? = 10
a = nil
b = nil  
````
この場合、aはInt型のため整数以外の値を保持することができないが、bはオプショナルInt型となる。
また、オプショナル型nilを通常の値と誤って使うことを防止する目的もあるため、aはエラーになる。
pip + virtualenvユーザ向けpipenv導入メモ


2018年においてpipenvがされに便利と聞いたので、
Windowsでの開発環境での使い方についてまとめてみる。

[2018年のPythonプロジェクトのはじめかた](https://qiita.com/sl2/items/1e503952b9506a0539ea)

# pipenvの理解

- pipenv
 - python仮想環境、実行環境のインストール

と覚えています。

つまり、pipenv=pip+virtualenvですね

※似たような名前で「pyenv」もありますが、別物です。こちらはpython本体のパッケージ管理

# 使用例

pip+virtualenvの場合

```
mkdir work
cd work
virtualenv env
.env\Script\activate.bat
(env)pip install pylint
(env)pip freeze > requirements.txt
```

pipenvの場合

```
mkdir work
cd work
pipenv install
pipenv shell
(work)pipenv install pylint
```

VSCodeでもちゃんと仮想環境を認識してくれる。
また、わざわざ「pip freeze」を実行しなくても、インストールしたパッケージは
Pipfileに記録される。

このPipfileがある状態で「pipenv install」をすると、パッケージインストールまでしてくれる

## virtualenvと同じようにプロジェクトディレクトリ以下に仮想環境をインストールしたい

環境変数「PIPENV_VENV_IN_PROJECT」を追加し、値に「true」を設定する。

https://dackdive.hateblo.jp/entry/2018/05/16/100000

## VSCodeでPowerShellにて仮想環境をアクティベートするときにエラーがでる

パーミッションの問題の可能性。
PowerShellを起動して「Get-ExecutionPolicy」を実行して「Restricted」がでたらギルティ。
セキュリティ上問題がないのであれば「RemoteSigned」に変更する
変更するときはPowerShellで「Set-ExecutionPolicy -Scope CurrentUser RemoteSigned」（権限があれば実行できる）

http://totech.hateblo.jp/entry/2017/09/29/162411
CentOS7 ログ

CentOS7において、syslogからjournaldへとログ管理の仕組みが変更となった

#syslog⇒journald
変更となった理由は以下のようらしい。
・eコマースなどのWebシステムを利用する顧客のログ集計のために、システムのログやセンサーのログなど、様々なログが収集されるようになった
・従来のsysylogでは複数のシステムのログをネットワーク経由で一括して管理できる機能などを備えていることから、多くの管理ソフトウェアと連携が可能であった
・しかし、膨大なログの中から目的の情報を抽出するために、様々なコマンドやツール、スクリプト類を駆使する必要があった
・その負荷を軽減するために、目的の情報を抽出しやすい新たな仕組みを搭載したのがjournald

#journaldログの保存
ログファイルは、デフォルト設定では「/run/log/journal」ディレクトリ配下に格納される
そして、そのディレクトリはtempfsでマウントされているため、OS再起動で配下に格納されているログファイルは削除されてしまう
そのため、ログが削除されないように設定ファイルを以下のように修正

```ruby:/etc/systemd/journald.conf
#Storage=auto
↓
Storage=persistent
```
修正したら、再起動
`systemctl restart systemd-journald`
すると、「/var/log/jounal」ディレクトリ配下にログが移動している
※Storage=autoでは、「/var/log/jounal」ディレクトリが無い場合は「/run/log/journal」ディレクトリ配下にログが作成される

ログファイルは、デフォルトではファイルシステムの10%がログの容量として割り当てられている
最大サイズを明示的に指定する場合は以下のように記載

```ruby:/etc/systemd/journald.conf
SystemMaxUse=100M
```

ログデータの転送には、journald以外にrsyslogを利用可能
また、ログファイルの完全性を保証するために、キーペアの作成と検証がかのうである
キーペア作成
`journalctl --setup-keys --force`
赤文字で「533f6d-399531-b17d48-325afc/1a247b-35a4e900」といった鍵が表示される
検証
`journalctl --verify-key 533f6d-399531-b17d48-325afc/1a247b-35a4e900`
完全性が認められた場合、「PASS」と表示される

###<コマンド例>
・時系列フィルタ
`journalctl --since="2018-11-10 00:00:00" --until="2018-11-11 22:00:00"`
・特定サービスの出力
`journalctl --since="2018-11-10 00:00:00" --until="2018-11-11 22:00:00" -u httpd`
・リアルタイム出力
`journalctl -f`
・緊急度フィルタ
`journalctl --since=today -p warning`
※プライオリティの値で指定も可能
emerg   : `journalctl -p 0`
alert   : `journalctl -p 1`
crit    : `journalctl -p 2`
err     : `journalctl -p 3`
warning : `journalctl -p 4`
notice  : `journalctl -p 5`
debug   : `journalctl -p 6`
・テストログ出力(例:emerg)
`logger -p daemon.emerg "TEST LOG"`
・ブートログ出力
`journalctl -b`
・カーネルログ出力
`journalctl -k`
・特定プロセスの出力
`journalctl _PID=100`
・実行ファイルのパス指定による出力
`jounalctl /usr/sbin/crond`
・現在ログファイルの容量確認
`journalctl --disk-usage`

#sosreport
システム全体のログと設定ファイルを簡単に一括取得できるコマンド
`sosreport -a`
以下のように質問2つがされ、システム全体のログと設定ファイルを固めたファイルが出力される

```
Please enter your first initial and last name [localhost.localdomain]:
Please enter the case id that you are generating this report for []:
中略
Creating compressed archive...
Your sosreport has been generated and saved in:
  /var/tmp/sosreport-localhost.localdomain-20181112000402.tar.xz
```

```ruby:tarファイルの中身
boot/       etc/             java@         lsof@     ps@      run/           sys/     version.txt
chkconfig@  free@            last@         lspci@    pstree@  sos_commands/  uname@   vgdisplay@
date@       hostname@        lib/          mount@    root/    sos_logs/      uptime@
df@         installed-rpms@  lsb-release@  netstat@  route@   sos_reports/   usr/
dmidecode@  ip_addr@         lsmod@        proc/     rpm-Va@  sos_strings/   var/
```
tarファイルの中には、「sos.html」といったhtmlファイルが作成されており、作成されたtarファイルを解凍し、Apache管理下に配置すればWebブラウザからログや設定ファイルが確認可能となる
例：http://192.168.11.233/sosreport-localhost.localdomain-20181112000402/sos_reports/sos.html
※「sosreport-localhost.localdomain-20181112000402」ディレクトリへのパーミッション付与のみではSELINUXによりアクセスできませんでした


※参考：CentOS7 実践ガイド
webpack-dev-serverで起動したアプリが「Invalid Host header」と表示される場合の対処法

# 事象

以下のコマンドを実行し、アプリケーションを起動した際に

```
npm run dev
```

以下のコードが出て、アプリケーションが起動できない

```
Invalid Host header
```

# 対応

webpack.config.jsに「disableHostCheck: true」を追記

```webpack.config.js
module.exports = {
  devServer: {
    disableHostCheck: true
  }
}
```
tf.matmulとtf.tensordotの違い

#はじめに
それぞれnumpy.matmulとnumpy.tensordotと同じです。

いずれも行列をベースに内積を計算する関数ですが、
ブロードキャストへの対応が異なります。

ブロードキャストについては下記など。
https://qiita.com/capybara/items/2d5f387996a5bd275fbf

numpyやtensorflowに慣れた方には常識かもしれませんが、
tf.matmulやtf.tensordotで検索する方のために投稿します。

#tf.matmul
https://www.tensorflow.org/api_docs/python/tf/linalg/matmul

a: shape=[x, y, z, i, k]
b: shape=[x, y, z, k, j]

```
tf.matmul(a,b)
# shape=[x, y, z, i, j]
```

もし, b: shape=[x,y,z, j, i]なら、
```
tf.matmul(a,b, transpose_b=True)
```

shapeからも分かるように、
tf.matmulはブロードキャストしません。
最後の二階部分以外はテンソルの形がそろっていることが必要です。

また、trasnpose_a, transpose_bでは、最後の二階部分のみが転置されます。

#tf.tensordot
https://www.tensorflow.org/api_docs/python/tf/tensordot

a: shape=[x, y, z, i, k]
b: shape=[j, k]

```
tf.tensordot(a,b, axis=[4,1])
# shape=[x, y, z, i, j]
```

このようにブロードキャストされた内積が計算できます。
なお、axisの指定の仕方はいくつかあって、

- axis=p
aの最後のp階部分と、bの最初のp階部分についてのdot

- axis=[p, l]
aのp+1階部分とbのl+1階部分のdot

- axis=[[p,q,r],[l,m,n]]
aのp+1階部分とbのl+1階部分、
aのq+1階部分とbのm+1階部分、
aのr+1階部分とbのn+1階部分、のdot

となっています。

axisで指定されなかった部分に関してbroadcastされ、
最終的なテンソルの形は残った階をa,bの順に並べた形になります。

#おまけ
tf.einsumという関数がさらに自由度の高いものとして用意されているようです。。


# 実例：バッチ処理でマルチラベル分類
最終隠れ層を受け取って、最終的にマルチラベル分類を行うlayerは以下のようになります。
output_layer: shape=[batch_size, hidden_size]
weight: shape=[num_labels, num_classes, hidden_size]
bias: shape[num_labels, num_classes]

```
logits=tf.tensordot(output_layer, weight, axis=[1,2])
tf.shape(logits) #[batch_size, num_labels, num_classes]

logits=tf.add(logits, bias)
tf.shape(logits) #[batch_size, num_labels, num_classes]

probs=tf.nn.softmax(logits, axis=-1)
tf.shape(probs) #[batch_size, num_tasks, num_labels]
```
これで、適当な損失関数に渡せます。

#参考
公式doc
https://www.tensorflow.org/api_docs/python/tf/linalg/matmul
https://www.tensorflow.org/api_docs/python/tf/tensordot
stackoverflow
https://stackoverflow.com/questions/38051143/no-broadcasting-for-tf-matmul-in-tensorflow/38056381
numpyやchainerでのベクトル、行列、テンソルの積関連演算まとめ
http://segafreder.hatenablog.com/entry/2017/01/09/203811
puppeteer でターミナルから google 翻訳

鶴田謙二さんイラストの puppeteer 入門(ヴェネチア冒険団團/三崎 薫/小原 亮一/酒井 一成 著)
面白かったです。

参考にして試しによく使ってる google 翻訳をコマンドラインから叩けるスクリプト作ってみました。

``` js
const puppeteer = require('puppeteer')
const URL = 'https://translate.google.co.jp/?hl=ja'
;(async () => {
  const browser = await puppeteer.launch({
    headless: false,
    slowMo: 50
  })
  const page = await browser.newPage()
  await page.setViewport({ width: 1500, height: 800 })
  await page.goto(URL)
  if (process.argv.length > 2) {
    process.argv.splice(0,2)
    word = process.argv.join(" ")
    console.log(word)
    await page.click('#sugg-item-en')
    await page.type('textarea#source', word)
    await page.click("input#gt-submit[type='submit']")
  }
  // browser.close()
})()
```

例えば、

``` bash
$ node googleTrans.js I am a boy.
```
![スクリーンショット 2018-11-11 23.10.06.png](https://qiita-image-store.s3.amazonaws.com/0/3657/5f218681-fe4f-bdef-741f-40698a41e774.png)
論文まとめ：Training Deep Networks with Synthetic Data: Bridging the Reality Gap by Domain Randomization

# はじめに  
CVPR2018から以下の論文
[1] J. Tremblay, et. al. "Training Deep Networks with Synthetic Data: Bridging the Reality Gap by Domain Randomization"
のまとめ。

arXivのリンク
https://arxiv.org/pdf/1804.06516.pdf

# 概要

1. 自動的に合成して作ったデータが、object detectionタスクにおいても有効であることを初めて実証した
2. domain randomizationというデータ拡張のテクニックを使ってデータを生成した
3. この合成データセットのみで学習したモデルは、virtualなKITTIの合成データで学習したモデルを上回った
4. この合成データセットで学習したモデルを人がアノーテーションしたデーセットでの学習に転移させることで、後者のみによる学習の精度を上回った


# 背景 
deep neural networkの学習には膨大なアノーテーションが欠かせないが、これはなかなか入手しにくい。

そこで幾つかのタスクでは合成したデータを用いて学習する手法が用いられてきた。

しかし、合成したデータは photorealism に欠ける。

そこで、合成したデータを用いる場合はランダムなテクスチャーを加える事で、この問題を回避した。（domain randomization）

本手法はこの domain randomization（以下DR）をobject detect用に拡張して利用する。

# 拡張した Domain Randomization（DR） 
以下の図（[1] Figure 1）で説明すると・・・

<img width="844" alt="SD_DR_01.png" src="https://qiita-image-store.s3.amazonaws.com/0/116706/ad40d64f-2631-4965-429a-f33cb2073cbd.png">

まず図の中央上側は合成した複数の車の3D モデル。

一方、図の左側はそれぞれの背景。この背景に車を置く。

この時、図の中央左寄りにある三角錐とか球などの幾何学的な形状（flying distractors）を加える。

また撮影するカメラは任意の位置にし、ライトも任意の形状のものを任意の位置に配置する。

これにより生成された画像は図の右側。同時にアノーテーションも取得する。

具体的に生成された画像は以下の図[1]Figure2

<img width="859" alt="SD_DR_02.png" src="https://qiita-image-store.s3.amazonaws.com/0/116706/26895b41-3cea-00cf-f5b3-2c1a598786dc.png">

上側は virtual KITTI というKITTIに似せて作ったデータセット、下側が本手法で合成した画像。

# 本手法と virtual KITTI との比較実験 
###設定 

本手法で合成したデータで学習したモデルと、virtual KITTIで学習したモデルとを精度で比較した。

比較に用いたモデルは、1)Faster-RCNN、2)R-FCN、3)SSD。

メトリクスは、IoUが0.5を超えてるバウンディングボックスに対して true/falseを計算。

### 比較の結果

結果は以下の[1]Table 1。

<img width="427" alt="SD_DR_04.png" src="https://qiita-image-store.s3.amazonaws.com/0/116706/58a5ab50-5464-ca7e-160b-f4a696980cf6.png">

おおよそ本手法の方がよさげ。

### bounding boxの出力例
bounding boxの出力例は以下。

<img width="851" alt="SD_DR_05.png" src="https://qiita-image-store.s3.amazonaws.com/0/116706/238e76f7-f2da-47e2-043f-f8e017a4cf71.png">

### precision-recall curve 
precision-recall curve は以下。

<img width="419" alt="SD_DR_06.png" src="https://qiita-image-store.s3.amazonaws.com/0/116706/c5f43fbd-f637-933e-6669-fbab0c25e438.png">

recallが低いところでは本手法の方がprecisionが高いが、逆にrecallを上げるとprecisionで劣る。

# 実際のKITTIデータで転移学習した時の結果　
実際のKITTIデータで転移学習した時の結果は以下。

<img width="418" alt="SD_DR_07.png" src="https://qiita-image-store.s3.amazonaws.com/0/116706/b645a8e9-62b1-ce63-6d89-a8ef8a01e5b4.png">

本手法で事前学習してから転移させた方が性能がいい。

# ablation study  
本手法におけるそれぞれのテクニックのどれが効いてるかを知るため、各テクニックの１つを落として学習させた結果は以下。

<img width="430" alt="SD_DR_08.png" src="https://qiita-image-store.s3.amazonaws.com/0/116706/d18f2441-e576-dad8-23a5-3db0de5a90bd.png">

ライトの位置を固定させたものが一番性能が悪い。つまりライトの位置をランダムにすることが一番効いている。

# Reference  
[2] J. Tobin, et. al. "Domain Randomization for Transferring Deep Neural Networks from Simulation to the Real World"
iOSでキーボードショートカットに対応する

# やりたいこと

iPad Pro 11インチとキーボードフォリオとApple Pencilを購入して、色々なアプリをキーボードで操作できることに気がつきました（遅い？）。やっぱりできるアプリはキーボードショートカットが充実しています。macOSでの経験則がそのまま活かせる訳で、どうやっているのかなと調べてみました。

## 仕組み

以下のUIResponderのkeyCommandsをオーバーライドします。

```objc
@interface UIResponder (UIResponderKeyCommands)
@property (nullable,nonatomic,readonly) NSArray<UIKeyCommand *> *keyCommands NS_AVAILABLE_IOS(7_0); // returns an array of UIKeyCommand objects<
@end
```

適当なViewControllerを用意してショートカットを登録します。

```swift
override var keyCommands: [UIKeyCommand]? {
	let commands = [
		// コマンド＋Oが押された時の定義
		UIKeyCommand(input: "O", modifierFlags: .command, action: #selector(handleShortcutCommand(command:)), discoverabilityTitle: "開く")
	]
	
	return commands
}

@objc func handleShortcutCommand(command: UIKeyCommand) {
	if command.input == "O" {
		print("開くコマンド実行")
	}
}
```

ビルドしてコマンド＋Oを実行するとログに開くコマンド実行と表示されました。コマンドキーを長押しすることで操作可能なショートカット一覧が表示されます。定義した開くコマンドが表示されるはずです。

要は各ViewControllerにこれらを仕込んであげることでキーボード操作が実現できます。便利便利。


## もう一歩踏み込んで

例えば、あるビューからモーダルで別のビューに遷移するアプリを考えてみましょう。最初のビューからコマンド＋Oでモーダルを開き、モーダルはコマンド＋Wで閉じたいです。

それぞれのViewControllerに開くコマンドと閉じるコマンドを定義すれば良さそうですが、実際にやってみると、モーダル表示中にコマンドキーを長押しすると**開く**と**閉じる**が二つ出てきてしまいます。

これを回避するために、以下のようにモーダルが表示されている時は`keyCommands`でnilを返してやりましょう。

```swift
override var keyCommands: [UIKeyCommand]? {
	// モーダルが表示されてたらnilを返す
	if self.presentedViewController != nil {
		return nil
	}
	
	let commands = [
		// コマンド＋Oが押された時の定義
		UIKeyCommand(input: "O", modifierFlags: .command, action: #selector(handleShortcutCommand(command:)), discoverabilityTitle: "開く")
	]
	
	return commands
}

@objc func handleShortcutCommand(command: UIKeyCommand) {
	if command.input == "O" {
		print("開くコマンド")
	}
}
```
awkで空白が含まれる任意のフィールドを抽出する方法

# awkにおける空白やタブの扱いと問題
- awkでは連続する空白やタブは1つのフィールドとして扱われる。
- 本来なんの問題もなく、これによりデータが扱いやすいのだが、空白が含まれるフィールドをそのまま抽出しようとした際にハマったのでメモ。
- 具体的には、以下のようなデータについて、空白フィールドが含まれる列を指定して抽出すると、空白フォールドの次のフィールドのデータが出力され、空白をそのまま出すことはできない。

``` bash
$ cat aaa.txt
aaa bbb ccc
ddd     fff
ggg hhh iii

$ cat aaa.txt | awk '{print $2}'
$ bbb
  fff
  hhh
```
# 解決策
- 一度タブを他の文字に変換して、デリミタとして指定する方法がある。

```bash
$ cat aaa.txt
aaa bbb ccc
ddd     fff
ggg hhh iii

$ cat aaa.txt | tr "¥t" "," | awk -F ',' {print $2}
$ bbb
     
  hhh
```
# もっと良い解決策あるはず
上記はまあ、スマートではない。
ググってもいい方法全然でてこないので、そもそもawkの使い方として間違ってるのかも。。
備忘録として。

# 参考
[AWKのこういう時はどう書く?](https://qiita.com/hirohiro77/items/713d5bcf60fef7e88dfa)（本稿には活かされてないのですが、awkで悩むかゆいところに手が届くめちゃめちゃ参考になった）
[awkコマンドの基本](https://qiita.com/yamazon/items/563af1b485ff413d381f)
PRAISE-NETの医薬品関連の通知PDFをダウンロードする

##背景
製薬会社は医薬品の研究開発において、多くの法律や規制に縛られています。その発信元は、厚生労働省や医薬品医療機器総合機構（PMDA）など多岐にわたります。日々大小の通知が発信されていて、通知のPDFは[PRAISE-NET](https://www.praise-net.jp/)がサービスとして配信しています。配信はメール媒体で、PDFが添付されているわけではなく、PDFのリンクが張り付けられているのみの簡素なものです。それをもとにPDFをダウンロードする必要が出てきたので、作りました。使いたい人は、勝手に使ってください。

##コード
```python

import requests
from bs4 import BeautifulSoup
import os

# セッションを開始
session = requests.Session()

# payload : ログイン情報
#user_login_idとpassword書き換える
#doInputはたぶんいらないけど、残しておいた。要らなければ消してもOK。

payload = {
    "user_login_id":"各自のメールアドレス",
    "password" :"各自のパスワード",
    "doInput":"ログイン"
}

#PRAISE-NETにログインするのにTWORDというデータが必要。
#このデータをpayloadに加える。
r = session.get("https://www.praise-net.jp/pn/m/login.asp")
soup = BeautifulSoup(r.text,"lxml")
auth_token = soup.find(attrs={'name': 'TWORD'}).get('value')
payload['TWORD'] = auth_token

#ログインする
url_login = "https://www.praise-net.jp/pn/m/login.asp?path="
p = session.post(url_login, data=payload)

#エラーが出れば、ここで弾かれる。
p.raise_for_status()

#PDFをダウンロードする。
#https://www.praise-net.jp/pn/m/p.asp?i=p/20181430.pdf ← 試しにこれをダウンロードしてみるとよい。
res = session.get("PDFのURL",stream=True,data=payload)

#PDFの保存
#ファイル名はURLの末尾の数字になる。

with open(os.path.basename("PDFのURL"),"wb") as file:
    for chunk in res.iter_content(chunk_size=1024):
        file.write(chunk)

#forで回すなら、処理が終わったら一秒待つコードを追加するべき？
#import time
#time.sleep(1)
```

このコードだけだとファイルは当然一つだけしかダウンロードされないので、for文で回してください。今後、praise-netのホームページが改修されて、HTMLのinputのnameが変更されていたら、payloadのkeyを変更してください。
DockerでELK(Elasticsearch Logstash Kibana) を構築してみました

# はじめに
Docker上に、Logstashを使って、アプリケーション（NGINX）のログをElasticsearchに転送し、Kibanaで表示するまでやってみました。メモとして手順を残しておきます。

# 環境
|--|バージョン|
|:--|:--|
|OS|CentOS Linux release 7.5.1804 (Core)|
|Docker|18.06.1-ce|
|Elasticsearch|6.4.3|
|Logstash|6.4.3|
|Kibana|6.4.3|
|nginx|1.10|

# 手順
## 準備
```
#Dockerに共有するフォルダを作成
sudo mkdir -p /data/elk
sudo chown user:user /data/elk
#elasticsearch用共有フォルダ作成
mkdir /data/elk/elasticsearch
#logstash用共有フォルダ作成
mkdir -p /data/elk/logstash/pipeline
#nginx用共有フォルダ作成
mkdir -p /data/elk/log/nginx
```

## nginx起動
```
docker run -d --restart always -v /data/elk/log/nginx:/var/log/nginx -p 80:80 nginx:1.10
```
起動後、http://${hostip}にアクセスして確認します。

## elasticsearch起動
```
docker run -d --restart always -v /data/elk/elasticsearch:/usr/share/elasticsearch/data -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node"  --name elasticsearch docker.elastic.co/elasticsearch/elasticsearch-oss:6.4.3
```
起動後、http://${hostip}:9200にアクセスして確認します。

## logstash設定ファイル配置
```/data/elk/logstash/pipeline/logstash.conf
input {
  file {
    path => "/var/log/nginx/access.log"
    start_position => beginning
  }
}

filter {
  grok {
    match => { "message" => ["%{IPORHOST:[nginx][access][remote_ip]} - %{DATA:[nginx][access][user_name]} \[%{HTTPDATE:[nginx][access][time]}\] \"%{WORD:[nginx][access][method]} %{DATA:[nginx][access][url]} HTTP/%{NUMBER:[nginx][access][http_version]}\" %{NUMBER:[nginx][access][response_code]} %{NUMBER:[nginx][access][body_sent][bytes]} \"%{DATA:[nginx][access][referrer]}\" \"%{DATA:[nginx][access][agent]}\""] }
    remove_field => "message"
  }
  mutate {
    add_field => { "read_timestamp" => "%{@timestamp}" }
  }
  date {
    match => [ "[nginx][access][time]", "dd/MMM/YYYY:H:m:s Z" ]
    remove_field => "[nginx][access][time]"
  }
  useragent {
    source => "[nginx][access][agent]"
    target => "[nginx][access][user_agent]"
    remove_field => "[nginx][access][agent]"
  }
  geoip {
    source => "[nginx][access][remote_ip]"
    target => "[nginx][access][geoip]"
  }
}

output {
  elasticsearch {
    hosts => [ 'elasticsearch' ]
    index => "access_log1"
  }
}
```
## logstash起動
```
docker run -d --restart always -v /data/elk/logstash/pipeline:/usr/share/logstash/pipeline -v /data/elk/log:/var/log --link elasticsearch:elasticsearch  --name logstash docker.elastic.co/logstash/logstash-oss:6.4.3
```
起動後、http://{hostip}:9200/_cat/count/access_log1をアクセスして、ログ転送を開始したことを確認します。

## kibana起動
```
docker run -d --restart always -p 5601:5601 --link elasticsearch:elasticsearch -e ELASTICSEARCH_URL=http://elasticsearch:9200 --name kibana docker.elastic.co/kibana/kibana-oss:6.4.3
```
起動後、http://{hostip}:5601にアクセスすると、kibana画面が表示されます。
左側の「Dev Tools」を開いて、「Console」に「GET /access_log1/_search?pretty=true」を入力、緑色の「▶」をクリックすると、右側にnginxのアクセスログが表示されます。

# 参考資料
https://qiita.com/va034600/items/b4b96faa36949b04d103
https://blog.manabusakai.com/2018/05/analyze-elb-logs-with-elk-stack/
https://www.elastic.co/guide/en/elasticsearch/reference/current/docker.html
Amazon Elasticsearch Service

## Amazon Elasticsearch Serviceについて構築時のパラメータ整理
* 論理設計に関わるところは、詳細設定のところか
* VPC内に配置可能でSGも適用できる

## クラスターの設定
### 1.ノード設定
* インスタンス数
 * インスタンス数=データノードの数
* インスタンスタイプ
 * データノードのインスタンスタイプ
* 専用マスターの有効化
 * クラスターの管理を行う専用マスターノードを利用するか否か
 * 専用マスターノードを利用する場合最低3台必要 
* ゾーン対応の有効化
 * クラスターを同一リージョン内の複数AZに分散
 * このオプションを利用する場合最低でも2台データノードが必要

### 2.ストレージ設定
* ストレージタイプ
* EBS ボリュームタイプ
 * gp2(SSD),piops,standard(磁気ディスク) 
* EBS ボリュームサイズ
 * ディスクサイズ、投入するデータに合わせて設定 
* 保存時の暗号化の有効化
 * KMSでの暗号化の有効化 

### 3.スナップショットの設定
* 自動スナップショットの開始時間
 * 自動スナップショット取得タイミングを設定(UTC) 

### 4.詳細設定
* rest.action.multi.allow_explicit_index
* indices.fielddata.cache.size
* indices.query.bool.max_clause_count

### 5.ネットワーク設定
* VPC or PublicAccess
 * VPC内のリソースとして扱うか否か
 * ここではVPC前提で以降の設定は記載
* VPC
 * 配置するVPCを選択
* サブネット
 * 同じく配置するサブネットを選択する
 * ゾーン対応を有効化する場合、2つ以上サブネットを選択する 
* セキュリティグループ
 * 適用するセキュリティグループを選択
* IAM Role
 * デフォルトロールAWSServiceRoleForAmazonElasticsearchService 
 * 権限の内容はENIの付け外しとSG周り

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1480452973134",
            "Action": [
                "ec2:CreateNetworkInterface",
                "ec2:DeleteNetworkInterface",
                "ec2:DescribeNetworkInterfaces",
                "ec2:ModifyNetworkInterfaceAttribute",
                "ec2:DescribeSecurityGroups",
                "ec2:DescribeSubnets",
                "ec2:DescribeVpcs"
            ],
            "Effect": "Allow",
            "Resource": "*"
        }
    ]
}
``` 
* ノード間の有効化
 * ノード間の通信を暗号化(TLS)する
 * 特に鍵情報等の指定はない
* Kibana認証
 * ESドメインにくっついてくるKibanaには認証がない
 * Kibanaアクセスに対し、Cognitoを利用するか否かを選択する

### 6.アクセスポリシー
* Amazon Elasticsearch Serviceに対するアクセス制御を設定
* IAM使うかどうか、SGでの制御のみとするかどうか