OmniAICreator/Qiita-1.07M huggingface dataset:
gulpでSCSSの@importをできるだけ手抜きしたい [gulp-sass-glob]

#このプラグインを使います
gulp-sass-glob
https://www.npmjs.com/package/gulp-sass-glob

#事前準備

##ディレクトリ構成
 
```
/
├ dev
  ├ scss
    ├ 0_base
      └ インポートされる様々なscss
    ├ 1_layout
    ├ 2_component
    ├ 3_project
    └ style.scss
├ root
  └ css
    └ style.css（SCSS → CSSに変換されたもの）
├ package.json
└ gulpfile.js
```

##package.json

```javascript:package.json
{
    "name": "dev",
    "version": "1.0.0",
    "author": "",
    "main": "gulpfile.js",
    "license": "ISC",
    "devDependencies": {
        "gulp": "*",
        "gulp-sass": "*",
        "gulp-sass-glob": "*"
    }
}
```

##gulpfile.js

```javascript:gulpfile.js
// 環境変数
const setting = {
	scss: {
		src: "./dev/scss/*.scss",
		dest: "./root/css"
	}
};

const gulp = require("gulp");

// SCSSプラグインの読み込み
var sass = require("gulp-sass");
// SCSSをまとめて読み込むプラグインの読み込み
var sassGlob = require("gulp-sass-glob");

// SCSSをCSSに変換するタスクを作成
gulp.task("scss", () => {
	return (
		gulp
			// 変換対象のファイル
			.src(setting.scss.src)
			//SCSSをまとめ読み込むことを許可する
			.pipe(sassGlob())
			//SCSS → CSS変換
			.pipe(sass())
			//CSSを出力（保存）
			.pipe(gulp.dest(setting.scss.dest))
	);
});

// ファイルの変更を監視してタスク実行
gulp.task("watch", () => {
	gulp.watch(setting.scss.src, ["scss"]);
});

// gulp起動時に実行するタスク
gulp.task("default", ["watch"]);
```

#SCSS

gulp-sass-globを導入する前は、SCSSをこのようにしていました。

```CSS:style.scss
@charset 'utf-8';

//////////////////////////
// define
//////////////////////////
@import "0_base/vars";
@import "0_base/reset";
@import "0_base/mixin";
@import "0_base/develop";
@import "0_base/utility";

//////////////////////////
// Layout .l-
//////////////////////////
@import "1_layout/header";
@import "1_layout/footer";
@import "1_layout/side";
@import "1_layout/content";

//////////////////////////
// Component .c-
//////////////////////////
@import "2_component/title";
@import "2_component/btn";
@import "2_component/list";
@import "2_component/table";
@import "2_component/form";
@import "2_component/slide";
@import "2_component/card";

//////////////////////////
// Project .p-
//////////////////////////
@import "3_project/top";
@import "3_project/about";
@import "3_project/company";
@import "3_project/service";
```

インポートするSCSSを全部書いてました。
それがこうなりました！！ ↓↓↓

```CSS:style.scss
@charset 'utf-8';

//////////////////////////
// define
//////////////////////////
@import "0_base/vars";
@import "0_base/reset";
@import "0_base/mixin";
@import "0_base/develop";
@import "0_base/utility";

//////////////////////////
// Layout .l-
//////////////////////////
@import "1_layout/*";

//////////////////////////
// Component .c-
//////////////////////////
@import "2_component/*";

//////////////////////////
// Project .p-
//////////////////////////
@import "3_project/*";
```

##インポートする順番は指定できない

gulp-sass-globによって、まとめてインポートできるようになりましたが、その順番は指定できません。

###順番を守りたいものだけちゃんと書く

リセット系CSSは最初に読み込ませたいので
順番を守りたいものは、まとめ指定しないで記載します。

この部分がそれにあたります

```CSS
//////////////////////////
// define
//////////////////////////
@import "0_base/vars";
@import "0_base/reset";
@import "0_base/mixin";
@import "0_base/develop";
@import "0_base/utility";
```

以上です。
ありがとうございました。
自分用メモ: そもそものオブジェクト指向とは

## ある日ふと思った
オブジェクト指向とgofのデザインパターンとか、oopの原則はいつもセットで語られます。
ではそもそもの**オブジェクト指向**自体はなんなのでしょうか。


## オブジェクト指向とは
OOPのメリットは多態性ってよく言われますが、それはオブジェクト指向自身とは全然関係ないです。オブジェクト指向の言うオブジェクトとはなんでしょう、何を指向してるのでしょうか。


## 構造化プログラミング
OOPを語るには構造化プログラミングをサンプルにすると良いらしい。構造化プログラミングはしたことないのですが、データと処理(機能)単位で分解するらしい。
でもデータと処理を纏められたらいいよねってことで、オブジェクト指向がでてきました。


## オブジェクト指向では
オブジェクト指向ではオブジェクトとオブジェクトを連ならせてプログラムを書きます。
オブジェクトは0以上のオブジェクトを利用する事ができます。
つまり、オブジェクト指向言語を使ってプログラムをする際はそのプログラムは1つ以上のオブジェクトで構築されます。(entry pointのファイル自体もmoduleなので。


## オブジェクト指向の言うオブジェクトとは
思考の補助の為にあえて特定のプログラミング言語で例を出します。
オブジェクト指向の言うオブジェクトはpythonやjsで言う所のmoduleです。
つまりimportできる奴です。
また、moduleが提供している(exportとか)シングルトンインスタンスや、値、関数、クラスにいたるまでこの2つの言語の場合はオブジェクトとして扱えます。パッケージまでオブジェクトとして使えるのもあります。
逆にオブジェクトとして全然扱えない言語もあります。言語の実装次第ってことですね。


## サンプル図
[このリンクにある視点と結果項目の図](https://www.ogis-ri.co.jp/casestudy/docs/CaseStudy_ESEC2010_StructOO.pdf)がかなりわかりやすいですが、よそのサイトの画像勝手にもってくるのもと思いますので一応自分で書いた図を乗せておきます。

![Untitled (1).png](https://qiita-image-store.s3.amazonaws.com/0/141711/47b1c601-d3ca-2789-d05d-59c697eecae9.png)

パッケージもモジュールも何もかもがオブジェクトみたいなことを書いていますが、これは言語の実装によりけりです。


## つまり
オブジェクト指向の言うオブジェクトとは、値と処理を集合の事です。
なので、オブジェクト指向とは、値と処理を束ねた物で行こうぜ！って事ですね。
それに付随してじゃあどういうふうにオブジェクトを作れば良いのかって事で原則やらこう作るパターンもあるよ！って色々なものが周りにある感じです。


## コンポーネント指向についての余談
オブジェクト指向とコンポーネント指向の違いについては[こちらのリンク](https://ja.wikipedia.org/wiki/%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88#%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%81%A8%E3%81%AE%E9%81%95%E3%81%84)がとても参考になる。
フロントエンドで流行ってる、提唱しているコンポーネント指向は、上のリンクのコンポーネント指向と同一かどうかは甚だ疑問だが、しかしかなり近い概念であるのは間違いないだろう。

オブジェクトが文芸的プログラミングで作られるか、数学的プログラミングで作られるかの違いでオブジェクト指向かコンポーネント指向かの分類をしているように見受けられる。
フロントの場合は、オブジェクトに数学的な要素を詰め込んだってよりかは(極論言えば最終的にそうなのだが)、ビジュアル的プログラミングとでも言えば良いのか。フロントのオブジェクトはこのビジュアル要件を達成する各種要素が詰め込まれているような。このビジュアルには、ビジュアルの動作、アニメーション等も含まれており、コードとして表現すると中々に複雑だ。特にメンテが辛い。
なので、コンポーネントとしてパッケージングすることにより、再利用性だけではなく、修正コスト等を最小限に留められる。

自分の場合はコンポーネント指向とオブジェクト指向、関数型プログラミングを混在して適材適所で使っている。開発している上でこれが上手く行っているのはとても感じられていて間違いないのだが、しかし従来のこれだけで良いでしょ！と比べると要求スキルはとても上がっているのは間違いない。


## 最後に
まさかりはいつだって怖いのですが、まぁもし間違ったこととか言ってたらアドバイス頂けるとめっちゃ助かります！
高速でLPを作るために~①tips収集~

## INFO:

CSSを書くのってどこから、
どのように設計するの？という疑問があったので、

職場で先輩がたが工夫しているところ、
気をつけていることをコードから学び取っていこうという記事です。


今回の記事では、
あ、ここ良いなというsnippetを集めていき
次回で組み立ての順序をさらって、

最終的には3、4時間でLPを
作れるようになるのが目的です。



## WARNING:

■あくまでも自分のメモとして書いているので、
タイポ多いと思います。

■基本的に自分の知らないことだけメモってます。


## 備考:

■Bootstrap4とscss使います。


## 高速でlpを作るために~①tips収集~

## OOCSS
Object-oriented CSS

使い回しの効く設計を心がける。


```
**Separate container and content**
(コンテナとコンテンツを分離する)

.text-heading {
  font-wight: bold;
  color: red; 
}
```



```
**Separate structure and skin**
(構造とスキンを分離する)

.btn {
}

.btn-red {
  backgroud-color: red;
}

.btn-gray {
  backgroud-color: gray;
}

```

個人的に、


```
.text-
.btn-
.bg-
*バックグランド
```
などは別途ファイル作成して定義するのが
よいかんじだと思います。


>いい感じにまとまってるやつ
 [■すぐに実践できるCSS設計 OOCSSの基本を理解しよう | ブログ | SINAP ](https://sinap.jp/blog/2015/11/sinap-oocss.html)
[■CSS設計における3大メソッド[OOCSS][BEM][SMACSS]](http://www.risewill.co.jp/blog/archives/5652)



### ■最初にbodyとhtmlの設定をする
全体で使うフォントやテキストカラーなどを設定する。

メモ:
> ◯フォントサイズは
pcだと20px
タブレット端末だと18px
スマホだと16pxが良い感じ

## Bootstrapのカスタマイズ

#### 定数管理をしっかり行う。
[Bootstrap variable](https://github.com/twbs/bootstrap-sass/blob/master/assets/stylesheets/bootstrap/_variables.scss)
をダウンロードして、他に色など付け足す。

#### すべて読み込まないようにする。
[_bootstrap.scss]
(https://github.com/twbs/bootstrap-sass/blob/master/assets/stylesheets/_bootstrap.scss)

> ここが詳しい。
[RailsにBootstrapをカスタマイズ可能な形で導入する](https://qiita.com/iguchi1124/items/e8aca47b111bb52f94a5)



### ■sectionごとに切り分けるのが便利

```
section
  トップ画像
section
  導入
section
  特徴
```

メモ:
> ◯ブロック要素
padding top bottom をつけていいかんいじに。
margin right left autoに。


### ■breakpointの設定

よく見かける形は

```
@media (min-widht: 554px) {}
```
ただし、これだと毎回数値を書かないといけなくて面倒臭い。
よって変数管理できるように

```
@include media-breakpoint-down(sm)
```
とかく。

smはvariables.scssで別途に定義する。

### 自分の悪い習慣

学んで自分の良くなかった書き方をまとめます。



####■btnのwidth
```

***自分の悪いコード
(Rails表記あり)
slim:
= link_to 'hoge', #, class: 'btn btn-hoge'

css:
.btn-hoge {
  width: 220px;
}

***OOCSSを考慮した良いコード
slim:
.hoge
  = link_to 'hoge', #, class: 'btn'

css:
.hoge {
  width: 220px;
}

ブロック要素の中のインライン要素になるから、
.btnには.btn-blockを使って
margin: 0 auto;を使用。

```




## 終わりに:

また随時見つけたら更新していこうと思います。

ひとまず自分のしらないところは
抑えたので模写→見ないで作成。

そして手順のアウトプットして、

他のサイトで模写したいものを
2,3ピックアップ。

そしてまたアウトプットを繰り返そうと思います。

それでは、また。
3D facial animation + speech animation サーベイ

# 目的

* speech(audio, tts)と 3D facial animation を組み合わせる

## References

Dynamic Units of Visual Speech
https://www.disneyresearch.com/publication/dynamic-units-of-visual-speech/

SIGRAPH 2017 SPEECH AND FACIAL ANIMATION
http://s2017.siggraph.org/technical-papers/sessions/speech-and-facial-animation.html

VISEMENET: AUDIO-DRIVEN ANIMATOR-CENTRIC SPEECH ANIMATION
https://s2018.siggraph.org/presentation/?id=papers_171&sess=sess146

VOCA: Voice Operated Character Animation(CVPR 2019)
https://voca.is.tue.mpg.de/

Neural Voice Puppetry: Audio-driven Facial Reenactment
https://arxiv.org/abs/1912.05566

Realistic Speech-Driven Facial Animation with GANs
https://arxiv.org/abs/1906.06337
https://sites.google.com/view/facial-animation

## 2019/12 時点のまとめ

方向性として, 自動で自然な感じで喋る(e.g. text-to-speech) + 3D or フォトリアリスティックレンダリングな論文

* Neural Voice Puppetry : 2D neural rendering であるが, 画像の品質は高い. リアルタイム生成可
  * audio から感情も推定(DeepSpeech 利用) 
* VOCA : 3D 系だとこちらが State of the art か? ただし形状のみ. 
  * FLAME 4D キャプチャデータから形状学習 
    * http://flame.is.tue.mpg.de/
    * https://github.com/Rubikplayer/flame-fitting 
* Realistic Speech-Driven Facial Animation with GANs
  * 画像は荒いが, 音声とビジュアルはよくマッチしている 

## ツール　

DeepSpeech. ASR(音声認識)
https://github.com/mozilla/DeepSpeech

Montreal Forced Aligner. テキストと音声からアラインメント(phonemes とその位置など)を抽出する. 
https://montreal-forced-aligner.readthedocs.io/en/latest/

PRAAT

http://www.fon.hum.uva.nl/praat/

上記 MFA などで出力した alighment 情報から, phone の pitch と intensity mean/min/max を求める.
不要なPolyfillを削減する

[Node.js_2 Advent Calendar 2018](https://qiita.com/advent-calendar/2018/node2)に空きがあったので、飛び入り参加させてもらうことにしました。

## 必要だけど微妙なときもある

JavaScriptは、実行環境が多岐にわたる上に、開発者が**実行環境を選びづらい**という事情もあって、JavaScriptのコードを使って実装の差を補う、[PolyfillやPonyfill](https://qiita.com/jkr_2255/items/5378bf070aea62fe8a94)といったテクニックが存在します。

もちろん、汎用性を求められるライブラリであれば、このような方法で動かせる環境を増やすことは、もちろん有用です。ただ、そうでないプロジェクト作成の場合、「他のライブラリのバージョンが決まっている」あるいは「別なところで対応できる最低限のブラウザが決まってしまう」などの事情によって、Polyfillコードが動く機会がまったく訪れず、単なるバンドルの肥やしにしかならないシチュエーションも存在します。

## Webpackで差し替える

自分で呼び出しているものであれば呼ぶコードを書き換えればいいのですが、他のライブラリからの依存関係で参照しているものはそうも行きません。ただ、Webpackには`resolve.alias`という、読み込むモジュールを差し替える機能が存在します。これを使うことで、不要となったPolyfillライブラリをダミーのものに差し替えて、容量を節減することが可能となります。

### 今回のターゲット

今回対象とするライブラリは、[reactjs/react-lifecycles-compat](https://github.com/reactjs/react-lifecycles-compat)です。React 16.3で加わった`getDerivedStateFromProps`や`getSnapshotBeforeUpdate`を、それ以前のバージョンのReactでも動かせるようにするためのPolyfillライブラリです。

もちろん、React 16.3以上しか使わないプロジェクトであれば、これは無用の長物と化します。

### インターフェースの調査

とはいえ、単に「削除しました」だけではエラーとなりますので、「`react-lifecycles-compat`のインターフェースは再現して、実際の動作だけ削減する」コードにしないといけません。[ソースコード](https://github.com/reactjs/react-lifecycles-compat/blob/master/index.js)を確認すると、以下のことがわかりました。

* エクスポートしているのは、`polyfill`という関数1つ
* 引数は、クラスコンポーネント1つだけ
* そのコンポーネントを破壊的に変更して、同じコンポーネントを返す

ということで、インターフェースを守った最低限のコードは、以下のようになります。

```js
const polyfill = Component => Component;

export {polyfill};
```

### `alias`で差し替える

的確に当該のモジュールだけを差し替えるために、対象のモジュールは`require.resolve`で指定しましょう。

```js:webpack.config.js（一部）
{
  resolve: {
    alias: {
      [require.resolve('react-lifecycles-compat')]: require.resolve('./relative/path/to/mock')
    }
  }
}
```

このようにして、不要なPolyfillを追い出すことに成功しました。
WAI-ARIAをマークアップ以外の視点から考える

# はじめに

前から気になっていたWAI-ARIA（ウェイアリア）。
HTML5 Conference 2018に参加して、WAI-ARIAをマークアップ以外の視点から掘ってみたいと思ったので記事を書いてみようと思いました。

基本的内容からつらつら書いてみています。大まかな流れが頭の中に入りやすいように、細かい専門用語は控え目にしてみています。


## WAI-ARIAってなんですか？

* アクセシビリティ関連の技術
* セマンティクスを補強する

⇒ WAI-ARIAはHTMLタグだけでは表現できない。セマンティクスを補強してくれる。



## WAI-ARIAが気になってた理由

状態を表す属性とかあって、js, cssのセレクタとして利用できたら便利！
[is-selected]クラスを付与するより[aria-selected]属性を付与して状態を表現できたほうがコードが読みやすそう。
→やってみたーい！
が引き金

でも待てよ。
何だか「もやっと」する。
js, cssのセレクタとして利用できるってのはあくまで技術者にとってのメリットなんだよなぁ。

⇒ WAI-ARIAは誰のため、何のためのものなのだろうか？



## WAI-ARIAは誰のため、何のためのものなの？

誰のためというのは、健常者だけではなく支援技術が必要な人も含めたみんなのため。
何のためというのは、セマンティクスを補強し、検索エンジンの評価やSEO・アクセシビリティ・メンテナンス性を向上させるため。
支援技術とは、スクリーンリーダーだったり、点字キーボードだったりといったもの。

webを閲覧するうえで、健常者だけではなくみんなが使えるようになったらいいよね。という思想がもとになっている。

ではどのようなプロセスを経て支援技術が利用できるに至るのだろうか？



## 支援技術が利用できるまで

### 【ざっくりとした流れ】

* ブラウザはOSと情報のやり取りをする。
* OSは支援技術（デバイス）と情報のやり取りをする。  
  
ブラウザ　⇔　OS ⇔ 支援技術

### 【細かいところ】
* ブラウザはアクセシビリティツリーを作る。
* OSは自分のアクセシビリティAPIをつかって、アクセシビリティツリーを解釈する。
* 支援技術はアクセシビリティAPIを介してOSとやり取りをする。


アクセシビリティツリーはOSが支援技術とやり取りをするときに必要。
htmlタグのセマンティクスと、WAI-ARIAのセマンティクス情報を持ちあわせている。

⇒ アクセシビリティツリーがどうやってできるのかが気になる。


## アクセシビリティツリーがどうやってできるのかが気になります...

ブラウザがアクセシビリティツリーを生成するのですが、アクセサビリティツリーを説明するためには、レンダリングツリーとは何かを抑えておく必要がある。

レンダリングツリーの説明も含めて、ブラウザが画面を描画するまでの流れを追ってみます。
とはいえ、あんまり詳しく書くと本題からそれてしまいそうなので、大まかに。


* html構造から、DOMツリー・CSSOMツリーを生成する。
  * DOMツリー生成中にcssの読み込みが発生する。このタイミングで CSSOMツリーの生成も発生する。
  * 上記２つの生成が完了 
* DOMツリーと、CSSOMツリーのを組み合わせてレンダリングツリーを作る
  * DOMツリーのルートから処理していく。この時スタイルでdisplay:none;されている要素は処理から除外
  * DOMツリーのノードを処理するたびに、当てはまるCSSOMルールを適用させる
  * 全部終わったら出力。これがレンダリングツリー
* レイアウト処理を行う
  * レンダリングツリーのルートからノードの大きさの解釈をしていく。
* 描画する（ペインティング・ラスタライジングともいう）
  * 画面の大きさから、レンダリングツリーの大きさをピクセル変換する。
* 描画に至る。

⇒ アクセシビリティツリーは上記で作ったレンダリングツリーをWAI-ARIAで補強したもの。


## おわりに  

アクセシビリティツリーはChromeであれば、要素検証の「Elements」パネルから「Accessibility」ペインを開くことで確認することができます。

この記事を読んでWAI-ARIAについて「もやっと」していた方が少しでも「スッキリ」になりましたら幸いです。




## 参考URL

* [レンダリング ツリーの構築、レイアウト、ペイント](https://developers.google.com/web/fundamentals/performance/critical-rendering-path/render-tree-construction?hl=ja)
* [アクセシビリティオブジェクトについて](https://www.slideshare.net/takenspc/20140713-accessibility-object)
* [セマンティクスの作り方、これまで、今、そして未来](https://masup9.github.io/html5conf2018/#/)
* [アクセシビリティ ツリー](https://developers.google.com/web/fundamentals/accessibility/semantics-builtin/the-accessibility-tree?hl=ja)
* [Chrome 64, 65 の DevTools でアクセシビリティ関連の機能が進化](https://w0s.jp/diary/547)
Redux Formのハマりポイント

# 前書き

Advent Calendar 2018の21日目の記事です

`Redux Form`についてです。

Redux Formを使ってみて情報見つけるのに苦労したので
自分の備忘録の意味も込めて残しました。

`package.json`はこんな感じでやりました。最新版では確認してません。

```json:package.json
    "react-redux-form": "^1.14.0",
    "redux-form-material-ui": "^4.3.0",
```

Material-UIでのフォームはこのドキュメントのコンポーネントを参照するのがいいです。

https://v0.material-ui.com/#/home

# 準備

まずインポート

```javascript:
import { change } from 'redux-form';
```

こうすれば後のバリデーションやフィールド内の変更時に対応できる。

```javascript
  return {
    validate: validate,
    onChange: onChange,
  }
```

# バリデーション

先ほどの`validate: validate,`の部分の設定でリンクされてます。
こうすれば`requiredFields`にある

```javascript
const validate = values => {
  const errors = {};

  const requiredFields = [
    'hoge',
    'bar'
  ];

  requiredFields.forEach(field => {
    if (!values[field]) {
      errors[field] = field + 'が未入力です。';
    }
  });

  return errors;
}
```

`form`のボタンを押下した時にバリデーション
`this.props`に`handleSubmit`にある。

```javascript:
        const { handleSubmit } = this.props;

        return (
          <form style={wellStyles}>
            // 省略〜〜〜
            <RaisedButton
              type="button"
              label="ボタンだぜ"
              primary={true}
              onClick={handleSubmit(() => this.hoge())}
            />
          </form>
        );
```

`handleSubmit`からリンクされた
`hoge()`メソッドの返り値が`true`か`false`かでフォームを可能かどうかを決定させることができる。


# フォーム変更時にフォーム内を動的にテキスト入れたりするには？

先ほどの`onChange: onChange,`からリンクされてます
`hogeForm`と言うのは自分でつけたformの名前です。
こんな感じなら`hoge`と言うフィールドに変化があった時にだけ、`'bar'`と言う文字列を無理やり入れたりできます。

```javascript:
const onChange = (values, dispatch, _, previousValues) => {
  if (values['hoge'] !== previousValues['hoge']) {
    dispatch(change('hogeForm', 'hoge', 'bar'));
  }
}
```

細かい部分は色々端折りましたが、
参考になればと思います。
Kaggle/Titanicにおける、努力ごとの寄与比較 

# モチベーション
ネットでKaggle/Titanicで調べると、色々な人が色々な手法/操作を公開してくれている(感謝)。けれども、それらがどれくらいらの効果を発揮してくれるのかがいまいち分からなかった。そういうわけで、調べました。

# 結論
まず結論から。

- 前処理系だと、Nameから派生する特徴量は効果が高いように見える
- 機械学習手法系だと、XGBoostが強い
- でも、アンサンブルはもっと強い

今回試した手法/操作による精度への寄与は下記の通り。ちなみに、下記のものを全て適応/Submitすると、スコアは0.80861で960位(/10584位-20181216現在)でした。

## 前処理系
- 既存特徴量の削除
  - PassengerId: **+3.4pt**
  - Ticket: **+4.2pt**
- 新規特徴量の追加
  - Title: **+5.8pt**
  - Family_Name: **+5.1pt**
  - Is_Alone: **+2.6pt**
  - Family_Size: **+3.5pt**
- (参考)
  - 上記全部乗せ: **+7.1pt**

## 手法系
- ランダムフォレスト: **0.0pt(基準値)**
  - グリッドサーチ(n_estimatorsのみ): **+6.6pt**
- SVM: **-1.3pt**
  - グリッドサーチ: 未実施
- XGBoost: **+5.7pt**
  - グリッドサーチ(n_estimatorsのみ): **+6.1pt**
- NN: **+2.5pt**
  - グリッドサーチ(hidden_layer_sizesのみ): **+4.5pt**
- アンサンブル(SVM除く上記3つの多数決): **+4.6pt**
  - グリッドサーチ: **+6.3pt**

# 考察
①頭を使わずに機械学習手法を変えるだけで、あるいは②グリッドサーチを用いてパラメータを変えるだけで精度が大きく向上したように見える。そのため、EDAや前処理は後回しでも良いと考えられる。もちろん、前処理による精度向上も馬鹿にはならないけれども、時間効率からすると上記①②の方が優れている。
機械学習の理想として、「特に何も考えずにデータをブチ込めば、それっぽい結果が返ってくる」というものがあると思っている。前述の方針は、この考え方とも整合性が取れている。

# 付録
## 前提条件
- データを読み込みランダムフォレストに突っ込むだけのシンプルな機械学習を基本とし、そこから条件を1つ1つ変えていった際の値の変化を寄与と定義する。
  - ここでの値とは、3分割交差検証の平均値とする。
  - 複数条件を変えての確認は行わず、あくまで基本の形から1手法/1操作のみを変更し、それらを比較するものとする(組合せを全部調べるのはしんどいので)。
  - ただしここで、Cabinの値だけは事前に処理を加えて置くこととする(そうしないと、計算量が多くなりすぎ、時間がかかるので)。
  - RandomForest等のrandom_stateは1固定
- 新規特徴量を追加した際には、作成元となった特徴量は操作から除外することとする。
  - Title, Famili_Name: Nameを除外
  - IsAlone, Family_Number: SibSp, Parchを除外
- 欠損値は下記の方法で事前に埋めておくこととする(項目名後の括弧内は欠損値の数)。
  - Fare(1): 平均値(欠損値が少ない(全データの0.08%)のでテキトー)
  - Embarked(2): 最頻値(欠損値が少ない(全データの0.2%)のでテキトー)
  - Age(263): ランダムフォレストを用いて他の特徴料から穴埋め
  - Cabin(1014): ランダムフォレストを用いて他の特徴料から穴埋め
- Kaggle上のNotebook利用を前提とする
- メモ：SibSpはSiblings(兄弟姉妹)/Spouses(夫婦)の意味(つまりほぼ同年代)、ParchはParents/Childrenの意味(つまりそこそこ歳が離れている)。なぜParChでないのかは謎。

## TODO
- もっと色々な機械学習手法・グリッドサーチを試す
- 前処理が後工程の機械学習に与える影響の大きさを確かめる
- 精度を上げることに関して、前処理・機械学習手法以外に他の要素がないかを探す
- LightGBMを使えるようになる
- Jupyter NotebookがOneNote的な使い方をできるように頑張る
- (優先度低) EDA・前処理についてお勉強する
BigQueryで中間テーブルを設けて速度を出すための仕組み

## BigQueryで速度を出すための仕組み

園芸学部出身エンジニアの @harada_hi です。日本庭園好きです。
PLAID Advent Calendar 2018 の16日目を担当します。
今回はBigQueryをうまく利用するための仕組みの話をしたいと思います

### BigQueryの活用箇所と速度改善の必要性
弊社の製品、KARTEではサイト来訪者の行動データを取得しています。
製品の中ではこの行動データをレポーティングする部分などでBigQueryを活用しています。

行動データという特性上、非常に大量のデータがKARTEには存在しています。
BigQueryは大量データの集計も非常に高速に結果を返してくれるわけですが、
テラバイトを優に超えるデータに対して、複雑な集計をかけると流石に結果が返ってくるまでの時間が掛かります。

### BigQueryの速度改善について
これに対する解決策としては次の2点があげられます。

**1. 集計結果を事前に作りキャッシュとして保存しておく**
**2. 集計するデータの対象データを絞り込んだ中間テーブルを準備する**

基本的には1の方針で検討し、機能内容的に1が難しい場合に2での対応を検討しています。
今回は2の対応を実行した際の問題とその解決策に関してまとめています。

BigQueryはWHERE句やLIMITを考慮せずに最初に全件を読み込みします。
このためWHERE句を指定して処理するデータ量を減らしたと考えていても読み込むデータ量が多ければ速度は遅くなります。
テーブルの行数(データ量)を減らすこと、SELECTする列を減らすことが非常に重要です。

#### 中間テーブルを生成する上での問題点
中間テーブルを作成する上で、BigQueryの `同時実行レート制限 - 50 件の同時クエリ` という点が問題になりました。
BigQueryの制限に関してはGoogleの公式ドキュメントをご参照ください。
https://cloud.google.com/bigquery/quotas?authuser=2&hl=ja

同時実行レート制限が問題になった理由は、次の要因により中間テーブルを作成するクエリの数が多くなったためです。

* 元テーブルはプロジェクト毎に存在する
* 元テーブルは日付で分割されており、中間テーブルも同様の構成にしたい

中間テーブルを定時バッチなどで作成しようとする場合、作成する必要のあるテーブル数分のクエリを実行することになるため同時実行の制限にかからないよう制御する必要が出てきます。
そのため完了までの時間の予測が立てづらく、必要なタイミングに中間テーブルがないという問題が考えられました。
同時実行レート制限を回避するためにprioryをBATCHにして実行するということも選択肢にはありましたが、こちらは24時間以内に実行されることを保証するという仕様のため同様の問題が考えられた形です。

また定時に実行するとしても中間テーブルを用意しておきたい時間には他の処理も多々流れている状態であったため、該当の時間帯に処理を追加しにくい状況でもありました。

#### 問題点を解消する上での仕組み
最終的に次の2点の対応で上記の問題を解消しています。

1. ユーザーが中間テーブルを必要とするページに最初にアクセスしたタイミングで中間テーブルを生成する
2. その日の中間テーブルが作成されていなかった場合に、その日分の中間テーブルを作成するバッチを設ける 

`中間テーブルを生成する上での問題点` で記載した内容だけを考慮すると、1の選択肢だけ良いように感じるかと思います。
しかし日付ごとにテーブル分割されているためページアクセスをしていない日が長くなればなるほどアクセス時に作成するテーブル数が増えてしまいます。
これによりレスポンスが遅くなりUXが低下してしまうため、2の対応も併せて行うことでその問題に対応している形です。
また2の対応は、あくまでもテーブルが作られていない場合に処理を回せば良いため、他の処理が集中している時間帯を避けることにも繋がります。

### おわりに
今回はBigQueryでパフォーマンスを出すための中間テーブルをプロダクトでどうやって作っているのかという点を紹介しました。
速度改善という点では今回紹介したものは手段の一つであり、状況ごとにそれぞれ最適な手段は異なると考えています。
BigQueryの範囲ですと直近で @tmonoi が紹介している `Clustered Table` は活用しどころが多いのではないかと思っております。
https://qiita.com/tmonoi/items/7fab1ba2ef1c88a2fd71
Alexaで家電を操作するためのあれこれ(Raspi設定編)

Amazon Echoを用いて家電を操作するための手順をメモっておく．

####環境
Amazon Echo dot
Raspberry Pi 3 Model B
Nature remo mini

macOs 10.14
Raspbian OS Version October2018

以下のようなイメージで通信を行う．基本的にリモコン操作のできる家電であれば操作することができる．(ただしNature Remoに登録できないリモコンは不可)

<img width="506" alt="スクリーンショット 2018-12-16 午前11.51.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/249806/e7d8c757-e6d5-15a5-14c4-d9fbaa54b4d5.png">

---
本記事ではIPアドレスを固定するためには以下の記事を参考にしました．
[Raspberry Pi 3 (Raspbian Jessie)の無線LANに固定IPアドレスを設定する](https://qiita.com/momotaro98/items/fa94c0ed6e9e727fe15e)




# RaspberryPiの設定

####Raspbian OSのダウンロード
[こちら](https://www.raspberrypi.org/downloads/)をクリックしてRaspbianOSを選択．イメージをダウンロードし解凍しておく．本記事では，

####マイクロUSBカードのフォーマット
8GB 以上のマイクロUSBカードを用意する．Disk Utility を開き差し込んだSDカードを選択後Erase! を押すことによりフォーマットする．

<エラーが発生してフォーマットできない場合>
`diskutil list`
をターミナルに入力し，自分の消したいディスクを探す．
`diskutil unMountDisk /dev/disk?`
`diskutil eraseDisk HFS+ Untitled /dev/disk?`
アンマウントして，フォーマットする．その際にdisk?には必ずSDカードのディスクを指定する．間違うと大変なことになるので注意．

####解凍OSイメージをSDカードに焼く
`sudo dd if=name.img of=/dev/rdisk? bs=1m`

name.imgには先ほど解凍したイメージを指定する．この際も書き込むディスクを間違わないように注意！書き込み開始後，何も表示されないが「Ctrl + t」で動いているか確認できる．

ただし，進捗を確認したい人は，Etcher を使うべし．とても便利．

####RaspberryPi 起動！
 RaspberryPiをマイクロUSBケーブルで電源に，LANケーブルでMacに接続し，イメージを焼いたSDカードを差し込む．するとランプが点滅しRaspberryPiが起動する．

####ssh接続
起動後，RaspberryPi に IPアドレスが振り分けられる．RaspberryPiのMacアドレスは [b8:27:eb] から始まることを利用してIPアドレスを探しssh接続する．

`arp -a | grep "b8:27:eb"`
`ssh pi@ipアドレスs`
初期設定ではユーザ名: pi, パスワード raspberry

<「 WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! 」と怒られる場合>
前回接続した履歴が残っているらしいので，/Users/MacBookPro/.ssh に移動し known_hosts 内の接続しようとしたIPアドレスと同じアドレスの行を削除．

####RaspberryPi の設定
`sudo raspi-config`
で設定画面が表示される.
<img width="564" alt="スクリーンショット 2018-12-16 午後1.34.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/249806/354f0203-015e-fcbc-916e-fae78c92016f.png">

Interfacing Optinons よりVNCを有効化する．また，パスワードも変更しておく．

####VNC接続
VNC Viewer をダウンロードして起動
<img width="899" alt="スクリーンショット 2018-12-16 午後1.47.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/249806/0a9aa250-e9df-dd41-b97e-0d7622fbd8dd.png">
テキストボックスにホスト名+.localを入力すると，RaspberyyPiのデスクトップが表示される．
ホスト名ssh接続している状態で
`hostname`
で確認できる.

####Wi-fiの設定
CUIでも設定できるらしいがGUIを用いて行なった．右上にあるWifiっぽいボタンをクリックしSSID と暗号化キーを入力することでWi-fiに接続することができる．

####IPアドレスの固定化
/etc/dhcpcd.conf に以下を追記
`interface wlan0
static ip_address=固定ipアドレス/24
static routers=ルータipアドレス
static domain_name_servers=DNSサーバのipアドレス
`
これでラズパイを再起動してあげるとipアドレスが固定されているのが確認できる．

####RaspberryPi を最新状態にする
`sudo apt-get update
sudo apt-get upgrade
sudo apt-get sit-upgrade
sudo rpi-update
sudo reboot`

---
ここまでで，基本的な RaspberyPi の設定は終了!
Node-redの設定編は[こちら](https://qiita.com/polaris/items/ee4cb2c25cd3f239d008)
gulpで条件分岐する [gulp-if]

#このプラグインを使います

gulp-if
https://www.npmjs.com/package/gulp-if

#このgulp環境を使って試します

gulpでphpをhtmlに変換する [gulp-php2html]
https://qiita.com/bonsai3/items/c33dfc902aed41899708

#事前準備

## package.json

```javascript:package.json
{
	"name": "dev",
	"version": "1.0.0",
	"author": "",
	"main": "gulpfile.js",
	"license": "ISC",
	"devDependencies": {
		"gulp": "*",
		"gulp-php2html": "*",
		"gulp-if": "*"
	}
}
```

これを追加してあります

```javascript
"gulp-if": "*"
```

##gulpfile.js

```javascript:gulpfile.js
// 設定
const config = {
	htmlOut: true
};

// 環境変数
const setting = {
	html: {
		src: "./root/*.php",
		dest: "./html"
	}
};

const gulp = require("gulp");

// phpからhtmlに変換するプラグインの読み込み
const php2html = require("gulp-php2html");

// 条件分岐するプラグインの読み込み
const gulpIf = require("gulp-if");

// phpからhtmlに変換するタスクを作成
gulp.task("html", () => {
	return (
		gulp
			// 変換対象のファイル
			.src(setting.html.src)
			// php→html変換
			.pipe(gulpIf(config.htmlOut, php2html()))
			// htmlを保存
			.pipe(gulp.dest(setting.html.dest))
	);
});

// ファイルの変更を監視してタスク実行
gulp.task("watch", () => {
	gulp.watch(setting.html.src, ["html"]);
});

// gulp起動時に実行するタスク
gulp.task("default", ["watch"]);
```


#gulpfile.jsの変更点

「設定」を追加しました

```javascript
// 設定
const config = {
	htmlOut: true
};
```

gulp-ifのプラグインを読み込んで

```javascript
// 条件分岐するプラグインの読み込み
const gulpIf = require("gulp-if");
```

ここで分岐させてます

```javascript
// php→html変換
.pipe(gulpIf(config.htmlOut, php2html()))
```

これで、config.htmlOutの設定値によって
gulpの動作を分岐させることができます。

#普通にif文使えばいいのでは？

gulp-ifではなく、普通にJavascriptでif文使えばいいんじゃないの？
こういうことです↓

```javascript
// phpからhtmlに変換するタスクを作成
gulp.task("html", () => {

//ここで条件分岐してしまう
if(config.htmlOut){
	return (
		gulp
			// 変換対象のファイル
			.src(setting.html.src)
			// php→html変換
			.pipe(php2html())
			// htmlを保存
			.pipe(gulp.dest(setting.html.dest))
	);
}

});
```

gulp-ifプラグインは、
「gulpの処理中」に「if」を突っ込めるところが便利なプラグインです。

なのでこういう細かい分岐をするために使います。

```javascript
    return (
        gulp
            .src(setting.html.src)
            .pipe(gulpIf(何かのif分岐1,処理A)
            .pipe(gulpIf(何かのif分岐2,処理B)
            .pipe(gulpIf(何かのif分岐3,処理C)
            .pipe(gulpIf(何かのif分岐4,処理D)
            .pipe(処理)
            .pipe(gulp.dest(setting.html.dest))
    );
```


以上です。
ありがとうございました。
UWPアプリ開発メモ

# UWPアプリ開発メモ
---

UWPアプリを作ろうといろいろと試したときのメモです。

---
## UWPアプリでのClosedXMLの使用
UWPアプリでClosedXMLが使えない。System.Drawingがサポートされていないとか。
UWPアプリでExcelファイルの読み込みをしたいので、.NET Standard LibraryでClosedXMLを使用し、そのLibraryをUWPプロジェクトから参照したら動作しました。Visual Studioからのデバッグ実行でしか確かめていませんが。

以下は、UWPアプリ画面（MainPage.xaml.cs）に実装した内容

```csharp:MainPage.xaml.cs
var filePicker = new Windows.Storage.Pickers.FileOpenPicker();
filePicker.FileTypeFilter.Add(".xlsx");

StorageFile file = await filePicker.PickSingleFileAsync();
if (file != null)
{
    IBuffer buf = await FileIO.ReadBufferAsync(file);
    byte[] fileBinary = new byte[buf.Length];
    using (DataReader reader = DataReader.FromBuffer(buf))
    {
        reader.ReadBytes(fileBinary);

        using (MemoryStream ms = new MemoryStream(fileBinary))
        {
            List<string[]> lst = SampleExcelAccessor.ReadExcel(ms, );

            //～～ 取得したデータを処理 ～～
        }
    }
}
```

以下は、.NET Standard Libraryとして実装した内容

```csharp:SampleExcelAccessor.cs
public class SampleExcelAccessor
{
    public static List<string[]> ReadExcel(Stream fileStream, string sheetName)
    {
        List<string[]> retData = new List<string[]>();

        XLWorkbook workbook = new XLWorkbook(fileStream);

        IXLWorksheet worksheet = workbook.Worksheet(sheetName);
        int lastRow = worksheet.LastRowUsed().RowNumber();
        int lastCol = worksheet.LastColumnUsed().ColumnNumber();

        for (int i = 1; i <= lastRow; i++)
        {
            List<string> rowData = new List<string>();
            for (int j = 1; j <= lastCol; j++)
            {
                IXLCell cell = worksheet.Cell(i, j);
                rowData.Add(cell.Value.ToString());
            }
            retData.Add(rowData.ToArray());
        }

        return retData;
    }
}
```

---
## UWPアプリ画面のサイズ変更
こんな感じに実装すると画面サイズを設定できます。
下のサンプルは400×300の画面になります。

```csharp:MainPage.xaml.cs
namespace App1
{
    /// <summary>
    /// それ自体で使用できる空白ページまたはフレーム内に移動できる空白ページ。
    /// </summary>
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();

            ApplicationView.PreferredLaunchViewSize
              = new Size { Height = 300, Width = 400 };
            ApplicationView.PreferredLaunchWindowingMode
              = ApplicationViewWindowingMode.PreferredLaunchViewSize;
        }
    }
}
```
eosio.system の役割

EOS　の公式コントラクトとして、下記あります。

- [x] eosio.bios　紹介記事 [eosio.bios の役割 - Qiita](https://qiita.com/blueplanet/private/85fba0513fe2bd535909)
- [x] eosio.msig　紹介記事　[EOS のアカウント・ロール・権限　応用編 - Qiita](https://qiita.com/blueplanet/items/2e6148ab02f56d22c229)
- [ ] eosio.sudo
- [ ] eosio.system
- [x] eosio.token 紹介記事　[eosio.token コントラクトを解読してみる - Qiita](https://qiita.com/blueplanet/items/dad6ffce0e5d5f583f3f)

今回は、`eosio.system` を読んでみます。

## ソース
量が多いので、リンクとアクションリストだけにします。

[eos/eosio.system.hpp at master · EOSIO/eos](https://github.com/EOSIO/eos/blob/master/contracts/eosio.system/eosio.system.hpp)

```c++
EOSIO_ABI( eosiosystem::system_contract,
     // native.hpp (newaccount definition is actually in eosio.system.cpp)
     (newaccount)(updateauth)(deleteauth)(linkauth)(unlinkauth)(canceldelay)(onerror)
     // eosio.system.cpp
     (setram)(setparams)(setpriv)(rmvproducer)(bidname)
     // delegate_bandwidth.cpp
     (buyrambytes)(buyram)(sellram)(delegatebw)(undelegatebw)(refund)
     // voting.cpp
     (regproducer)(unregprod)(voteproducer)(regproxy)
     // producer_pay.cpp
     (onblock)(claimrewards)
)
```

コメントどおりに、実際の実装は複数ファイルに分けています。

下記のテーブルが定義されています。

- name_bid_table アカウント購入テーブル：項目は、購入うしたいアカウント名、購入したアカウント、価格
- global_state_singleton　グローバル情報：項目は、システム全体の使える RAM 量などの情報
- producer_info　BPの情報：項目は、アカウント名、投票数、URL、ロケーション、未払い報酬のブロック数など
- voters_table　投票情報：オーナー、投票したアカウントの配列など

メソッドは下記になってます。

// native.hpp (newaccount definition is actually in eosio.system.cpp)

- アカウント作成
- 権限更新、権限削除
- 権限リンク、権限リンク解除
- 遅延トランザクションの取り消し
- エラー処理

// eosio.system.cpp

- RAM設定
- ブロックチェーンパラメータ設定
- 特別権限更新
- BP 削除
- アカウント名購入

// delegate_bandwidth.cpp
- RAM購入
- 代理設定
- 代理解除
- 返金

// voting.cpp
- BP 登録
- BP　登録解除
- BP　投票
- 投票代理設定

// producer_pay.cpp
- ブロック生成を記録する
- BP　の報酬を付与する

## 関連しているシステムアカウント
契約の中、下記おｎアカウントも使っています。

- `eosio.saving` 報酬を計算するとき、80% の報酬を保持しているアカウント
- `eosio.bpay` ブロックの数によって計算れている報酬を保持しているアカウント
- `eosio.vpay` BPが持っている投票によって計算されている報酬を保持するアカウント
- `eosio.ram` アカウントが `RAM` を購入するとき払った料金を保持するアカウント
- `eosio.ramfee` アカウントが `RAM` を購入するとき払った手数料を保持するアカウント
- `eosio.stake` アカウントが `CPU / NET` を `stake` する料金を保持するアカウント
- `eosio.names` アカウントがオークションでアカウント名を売買するとき、代金を保管するアカウント

## EOS ネットワーク上の立ち位置
- `EOS` のメインネットでは、`eosio.bios` に代わりに、`eosio` アカウントにデプロイされています

## まとめ
`EOS` ブロックチェーン本体の動きとリソース制限やアカウント作成などの処理が、`eosio.system`で実装されていることになっています。
2Dゲーム制作に Go の複素数を使い倒そう

Goきってのドマイナー機能（主観）である複素数演算が、実は2Dゲーム制作ではちょっと便利というお話をしたいと思います。

# ベクトル演算をしよう

https://qiita.com/intelf___/items/039eccffd422321ec6dd
https://qiita.com/intelf___/items/f92f5c9ff2e515e16d47
基本的な使い方は上の記事をご覧ください（丸投げ）。

そして、ゲーム制作において主に役立つのは、 **複素数に虚数をかけると回転できる** という性質です。
実例をご覧ください。

```Go
// 発射元の位置
pos := complex(320, 240)
// 一発目のベクトル
vec := complex(100, 0)
// 9方向に発射
n := 9
// 9分の1回転するベクトル
rot := cmplx.Rect(1, 2*math.Pi/float64(n))
// 実際に発射してみる
for i := 0; i < n; i++ {
  bullet := pos + vec
  vec *= rot
  // 以下、いい感じに弾を描画
  x, y := real(bullet), imag(bullet)
  ox, oy := real(pos), imag(pos)
  ebitenutil.DrawLine(screen, ox, oy, x, y, color.White)
}
```

![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/70892/a0707a71-1c25-700d-96f6-bb1e3d2ed0f2.png)

はい。とてもシンプルなコードで9way弾（のつもり）が発射できました。実に綺麗ですね。僕はそう思います。
手元で動かしたい方は[こちらのリポジトリ](https://github.com/eihigh/cmpshoot/blob/master/main.go)をクローンして `go run .` してください。当然ebitenが必須です。

解説が要るのは回転ベクトルの辺りかなと思うので、ここを少し詳しく見てみます。

```Go
// 9分の1回転するベクトル
rot := cmplx.Rect(1, 2*math.Pi/float64(n))
```
`cmplx.Rect` は長さと角度を指定して1つの複素数値を得る関数です。
なので、 `rot` は長さ1、角度2π/n（つまり9分の1回転）のベクトルに相当します。

そして、これが複素数型の美味しい性質なのですが、ある複素数に長さ1[^1]の他の複素数を掛けると、 **長さを変えずに回転する** ことができます。
それが以下のコードです。

```Go
vec *= rot
```

この計算を一回行うごとに`vec`は9分の1回転します。これを9回行うので、丁度綺麗に一周できる寸法ですね。

他にも、

* 移動ベクトルに毎フレーム120分の1回転ベクトルを掛けて、曲がる弾にする。
* プレイヤーと敵の差のベクトルを正規化して掛けて、ホーミング弾にする。

など、いろいろと応用は効きますが、結局はこの **掛け算で回転できる** という性質を利用する形になります。
ライブラリに依存せず、ただの掛け算が活躍するのって、少し気持ちよくないですか？　僕は気持ち良いです。

というわけで、以上Goのマイナー機能である複素数型のご紹介でした。
3Dゲームでは使いまわせませんが、ebitenで2Dゲームを作るなら活用してみてはいかがでしょうか。
ご覧いただきありがとうございました。

[^1]: 絶対値とするべきですが、わかり易さ優先で。
SkyWay のビデオチャットに雑なクロマキー合成してみた

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

# はじめに

勢いでこのアドベント カレンダーに登録したので、慌ててアカウントを作って、アドベント カレンダー 8 日目の「[【爆速！】5分でビデオチャットを構築する](https://qiita.com/kolife/items/6b771676d7558254b3a6)」を一通り試してみました。
マジで爆速でビデオ チャットが実装できますね、これ。

さてビデオ チャットをする時、自室の様子が背景として映り込むのが気になりませんか？
私は少しだけ気になります。
なので、ビデオ チャットでも[クロマキー合成](https://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%83%9E%E3%82%AD%E3%83%BC)ができないかチャレンジしてみました。

# 雑なクロマキー合成

普通のクロマキー合成は、緑や青のシートを使って、そのシートの部分だけ他の映像と差し替えますが、当然自宅にあの緑や青のシートが自宅にあるわけではないので、少しだけ頑張ってみます。

処理は大まかに以下の通りです。

1. 人が映っていない背景だけをまず準備<br>
   video タグから、人が映っていない瞬間を選んで、背景画像用 canvas にフレームを転送しておきます。
2. 差し替えたい背景画像も準備<br>
   同じサーバー上に配置して、Image オブジェクトで読み込んだら、差し替え画像用 canvas に転送しておきます。
3. SkyWay の room オブジェクトに、配信用 canvas の `captureStream` で取得した stream を設定しておきます。
4. video タグからとれるフレームと、1. の canvas とピクセル単位で比較して、<br> **似てたら**その部分を 2. の canvas ピクセルに差し替え、3. の配信用 canvas に描画します。<br>
   これは、requestAnimationFrame で逐次処理を回します。<br>
   ピクセルが**似ているかどうか**の判定は、RGB の色空間でベクトルの内積を使ってます。

テスト用なので、canvas をふんだんに使っています。

# 結果

結果がこちらです。
上がクロマキー合成して SkyWay 経由で表示した映像、下が Web カメラで取得したオリジナル映像です。

表示しているページは
https://github.com/skyway/skyway-js-sdk/tree/master/examples/fullmesh-videochat

![image.png](https://qiita-image-store.s3.amazonaws.com/0/90361/32d85394-95a9-4dea-3dcb-eb742a7a415e.png)

念願のホワイトハウス前からビデオ チャットに参加することができました！
\# 噴水は動きませんけど。

# おわりに
天井と壁の境目が丸見えですし、カメラの露出が常時変化するので、ご覧の通り、めちゃくちゃノイズが乗ります。
ちなみに、一番映りがいい画像でこれなので、もっと真面目に処理しないといけないですね。。。
Git Bash で Permission denied (publickey) が毎回出る場合の原因と対策

##環境
* Windows 10
* Git 2.8.1

##現象
Git Bash を起動するたびに`ssh-add key`を実行しないと、Remoteにアクセスするコマンド（`git pull`など）を実行できない。
キーを登録しないと、以下のように怒られる。

```
Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
```

##原因
* 登録している ssh キーの名称がデフォルト(id_rsa)ではない[^1]

##対策
/etc/ssh/ssh_config
にキーを指定してやる

###設定手順
0. 普通にGit Bashを立ち上げる
1. タスクバー上のアイコンを`Ctrl-Shift-Click`する（管理者権限でGit Bashが立ち上がる）[^2]
2. `vim /etc/ssh/ssh_config`
3. 以下を追記する

```
Host bitbucket.org
    HostName bitbucket.org
    User git
    Port 22
    IdentityFile ~/.ssh/my_rsa
```
これは、↓と等価とのこと[^1]
`ssh git@bitbucket.org -p 22 -i ~/.ssh/my_rsa`



[^1]: 問題の原因および対策 [[メンチカツには醤油でしょ!!](http://ryoichi0102.hatenablog.com/entry/2017/02/03/232920)]
[^2]: Git Bashを管理者権限で実行する方法 [[@YamasakiKenta](https://qiita.com/YamasakiKenta/items/0ed5f2ba9bd8a5cd5e79)]
今こそStream API入門

JJUG CCC 2018 Fallに参加してきました。
@skrb さんの#ccc_g4の講演内容を個人的にまとめました。

# Streamってなに？
**Streamは単純なイテレータである**

* イテレータは２種類存在する。
    * 外部イテレータ
        * 繰り返しの制御を自分で記述
        * for 拡張for iteratorクラス
        * for文のループ部はもちろん、get(x)の部分も制御部分である。
        * 複雑
        * 記述力はそれほどでもない。
    * 内部イテレータ
        * 繰り返しはライブラリ任せ(Stream API)
        * シンプル
        * 記述力高い。

## ラムダ式の立ち位置
> 蝶のように舞い、鉢のように刺すのがモハメド・アリ
> 関数のように記述し、クラスのように振る舞うのがラムダ式

~~~
関数<============ラムダ式============>クラス
処理　　　　　　       関数のように記述し        状態＋処理
       　　　　　　　　クラスのように振る舞う
~~~

# Streamはなぜわからないのか？
一度試したけどわからなかった人多数

## 新しい技術があったら・・・

* まず使ってみるか？
* 完全に理解するまで使わないか？

例：オムレツを作るのに、タンパク質の熱変性は６０度で、メイラード反応というのがあって・・・
と知ってても、そんなこと気にせず作りますよね？？

**新しい概念だからこそ、習うより慣れよ。 かけるようになってから仕組みを理解すればよい。**

## Stream = データの流れ

ループより、加工して処理するものだと考える。
加工するのに、クラス作ったりしたくない。
→ ラムダ式 引数と返り値だけを決めた処理の記述法

~~~java
(引数)->{
	toDO
	return val;
}
~~~

# 結局Streamはなんなのか

**やりたいことをデータの加工という観点で組み立て直す。
工程をシンプル化し、1工程　-> シンプルな4工程にわける -> 最終的にtoList()などで箱詰め。
まずはfor eachからはじめて、徐々にmap->filter等やってみるのが吉**

## よく使われるラムダ式

[1引数 返り値あり Function<T,R>](https://docs.oracle.com/javase/jp/8/docs/api/java/util/function/Function.html)
[1引数 返り値boolean Predicate<T>](https://docs.oracle.com/javase/jp/8/docs/api/java/util/function/Predicate.html)
[1引数 返り値なし Consumer<T>](https://docs.oracle.com/javase/jp/8/docs/api/java/util/function/Consumer.html)
[引数なし 返り値あり Supplier<R>](https://docs.oracle.com/javase/jp/8/docs/api/java/util/function/Supplier.html)

## 基本的な書き方

~~~ java
// 基本的なやつ
(String s) -> { return s.length();
// 型は省略可能
(s) -> { return s.length();
// 1行なら returnも省略可能
(s) -> s.length();
// 1引数なら ()も省略可能
s -> s.length();
~~~

こんなの覚えなくてもIDEがやってくれる。

##  最低限覚えておけば良いパターン

* データを加工する中間の処理。
    * データを取捨選択する
        * filter
        * dropWhile ※1引数 返り値boolean
        * takeWhile
    * データを加工する。
        *  map ※1引数 返り値あり
        *  flatmap ※１引数 返り値 Stream  ←入れ子のstreamとか出てきたときに使う。１次元に変換
    *  データを纏める最後の処理。
        *  探す
            *  findFirst 単一データの返却
            *  findAny 単一データの返却 ※ラムダ式なし 
            *  anyMatch 正規表現探索
            *  allMatch 正規表現探索
            *  oneMatch 正規表現探索 ※1引数 返り値 boolean
        *  まとめる
            *  collect ※Collectors::staticメソッド
            *  toList ※ラムダ式なし
            *  groupingBy ※１引数 返り値あり(map)
        *  逐次処理
            *  for-each １引数 返り値なし
       		
例： Listから、小文字のaで始まる単語を抜き出す。
		
``` java:example.java
List<String> words = new ArrayList<>() {
    {
        add("apple");
        add("toast");
        add("about");
        add("sun");
    }
};
var results = words.stream()
    .map(word -> word.toLowerCase())
    .filter(word -> word.startsWith("a"))
    .collect(Collectors.toList());
System.out.println(results);
```	

StreamはNull保証されるので、アウトプットの配列のために、new ArrayList()しなくてよい。
Streamでかけないものもあるので無理はしない。

# Q&A
Q1. 変換処理部はメソッド参照できるとおもうのですが？
A1. 書けます。しかし、読む人に優しくないので、あまり好ましくない。
Q2. 例外がうまくかけない。ベストプラクティスはあるか
A2. 正解はない。eitherを使うと良い

# 補足
御本人が、既に[発表資料](https://www.slideshare.net/skrb/stream-api-125945709)を投稿されていたので、こちらの記事は参考程度に・・・。
6D.aiのサンプルを動かしてみた

## 6D.aiとは？

6Dが開発しているARのSDKです。
特徴として、「普通のスマホの単眼カメラ」で、空間情報を高速に解析して、その情報の保存や共有が非常に簡単にできるようになっています。

公式デモ動画
https://youtu.be/EWK2pKInCWU

空間情報を認識するのに、HoloLensやTangoは、赤外線を使った深度センサーを用いています。iPhone Xシリーズのフロントカメラで顔の凹凸を正確に認識できるのも深度センサーの恩恵です。

ただ、深度センサーはコストが高く、全てのスマートフォンに搭載するわけにはいきません。なので、普通のRGBカメラで空間認識を行う技術が増えてきました。ARKitやARCoreが代表的なものです。

ところが、ARKitもARCoreも、現状は部屋の形を正確に認識できるところまでは実現できておらず、「ここに垂直もしくは水平な平面がある」ところまでしかわかりません。

6D.aiは、同じく単眼カメラしか使わないのですが、ニューラルネットワークの力を使って、空間情報を正確かつ高速に把握することができるのが特徴です。

現状はiOSでしか動作しませんが、今後他のデバイスに向けても開発が行われているようです。

## 6D.aiのベータ版を申請する

6D.aiのベータ版のSDKを入手するには、申請をしてからしばらく待たないといけません。僕が申請したときには２週間程度かかりましたが、現状は不明なのでまずは申込みをしてみてください。費用などは発生しません。

## 対応機種

対応しているデバイスは、ARKitより少なくなっています。
iPhoneなら7以降、iPadなら第１世代のPro以降と、無印iPadの第６世代以降となっています。
相応のCPUパワーが要求されるためのようです。

## サンプルプロジェクトを動かす

6D.aiは、現状はUnity用とXcode用（SceneKit）のSDKとサンプルプロジェクトを提供しています。今回はUnity用ものを使用しました。
ベータ版の利用申請が通ったら、ログイン後にUnity用のプロジェクトをダウンロードして解凍します。また、APIのキーを設定する必要があります。
Downloads > Download Your API Keys を選択すると、「SixDegreesSDK.plist」がダウンロードされてきますので、サンプルプロジェクト内の下記に配置してください。

Assets/Plugins/iOS/SixDegreesSDK.plist

あとは、通常通りUnityからiOSプロジェクトを書き出してXcodeで実行する流れになります。

## サンプルシーン
https://dashboard.6d.ai/user/dashboard/?view=how_to_play

### Basic Sample scene
空間認識を行い、認識された空間の床にオブジェクトを配置するデモになります。クラウドへのセーブ／ロード機能がついています。

### Ball Pit Sample scene
空間認識を行い、そこにボールを放り投げて挙動を見ることができます。カメラで見回すとだんだんメッシュが作成されるのですが、作成されていない場所にボールを放り投げると奈落の底に落ちていきます。

少し改造して、カメラが近づくとボールが移動するようにしてみました。
BallBehaviour.csのUpdate()内に下記を追加します。

```CSharp
if (Vector3.Distance(this.transform.position,Camera.main.transform.position) < 0.5f)
{
    GetComponent<Rigidbody>().AddForce(Camera.main.transform.forward * 180);
}
```

動画
https://twitter.com/torikasyu/status/1073959003409924102

### Drawing Sample scene
空間にお絵かきができるサンプルです。
Drawing Sample Photon sceneでは、お絵かきをPhotonで共有しています。

## 感想
空間メッシュの生成速度が速くて正確で、HoloLensやTangoに遜色ない感じでした。空間への固定能力も優れていて、ARKitで起きるドリフトも比較的少ない感じがしました。

赤外線センサーを使用しないということは、HoloLensが苦手な直射日光下の屋外でも、赤外線が届かない広大な場所や遠くの場所でも使用できるということですので、かなり用途は広がるのではないかと思います。
BitVisorのMSR Bitmapについて

これは[BitVisor Advent Calendar 2018](https://qiita.com/advent-calendar/2018/bitvisor)の16日目の記事です．

@morimolymolyです．
研究でBitVisorを扱っています．よろしくおねがいします．
[Twitter](https://twitter.com/morimolymoly)や[ブログ](http://morimolymoly.hateblo.jp/)もやっています．

今日はBitVisorのMSR周り，特にMSR Bitmapのお話をします．

# MSR Bitmapとは
通常，MSRへのアクセスがあった場合，毎回VM Exitが起こりゲストからハイパーバイザへと制御が移ります．しかしVMExitなどのコンテキストスイッチはオーバーヘッドになるため，不要なVMExitは減らすべきです．そこで特定のMSRアクセスのみトラップして，ほかをパススルーするために，BitVisorではMSR Bitmapを導入しています．
Exception BitmapやPFEC_MASK(PageFault Error Code Match)やPFEC_MATCH(PageFault Error Code Match)も例外やページフォールトを選択的にトラップするための手段で，MSR Bitmapと似ていますね．

さて，MSR Bitmapには以下の4種類あります．

* Read bitmap for low MSRs: MSRのIndexが`00000000H` to `00001FFFH` 
* Read bitmap for high MSRs : MSRのIndexが`C0000000H` to `C0001FFFH`．MSR Bitmapのアドレスに`0x400`足したところ．
* Write bitmap for low MSRs : MSRのインデックスが`00000000H` to `00001FFFH`．MSR Bitmapのアドレスに`0x800`足したところ．
* Write bitmap for high MSRs: MSRのインデックスが`C0000000H` to `C0001FFFH`．MSR Bitmapのアドレスに`0xC00`足したところ．

# BitVisorでのMSR Bitmapの扱い
MSR Bitmapは`core/msr_pass.c`にて実装されています．
`static void msr_pass_init (void)`が初期化部分です．
基本的には`current->vmctl.msrpass`を引数をセットして呼び出しています．
vmctlはAMD-VとIntel VT-xを抽象化するレイヤです．
それぞれ，`core/svm.c`，`core/vt.c`にて`static struct vmctl_func func`に代入しているところが関数ポインタの初期化部分なので，追いかけるときはここを起点として読みます．
msrpassはそれぞれ，`core/svm_msr.c`，`core/vt_msr.c`に実装があります．
ここではIntel Vt-xの実装を読んでみましょう．

```c
void
vt_msrpass (u32 msrindex, bool wr, bool pass)
{
	u8 *p;

	switch (msrindex) {
	case MSR_IA32_SYSENTER_CS:
	case MSR_IA32_SYSENTER_ESP:
	case MSR_IA32_SYSENTER_EIP:
// 省略...
	case MSR_IA32_MTRR_PHYSMASK8:
	case MSR_IA32_MTRR_PHYSMASK9:
	case MSR_IA32_PAT:
		pass = false;
		break;
	case MSR_IA32_MTRRCAP:
	case MSR_IA32_FEATURE_CONTROL:
	case MSR_IA32_VMX_PROCBASED_CTLS2:
		if (!wr)
			pass = false;
		break;
	}
	p = current->u.vt.msrbmp->msrbmp;
	if (wr)
		p += 0x800;
	if (msrindex <= 0x1FFF)
		vt_setmsrbmp (p, msrindex, !pass);
	else if (msrindex >= 0xC0000000 && msrindex <= 0xC0001FFF)
		vt_setmsrbmp (p + 0x400, msrindex - 0xC0000000, !pass);
}
```
`msrindex`はMSRのインデックス，`wr`は書き込みならtrue，`pass`はpass-throughするならtrueです．トラップしたい場合は`pass`をfalseにします．


```c
static void
vt_setmsrbmp (u8 *p, u32 bitoffset, int bit)
{
	if (bit)
		p[bitoffset >> 3] |= 1 << (bitoffset & 7);
	else
		p[bitoffset >> 3] &= ~(1 << (bitoffset & 7));
}
```
ここが書き込み部分．


# 宣伝：仮想化技術slack HyperVillage
特に活動しているわけではないですが，仮想化技術関連のslackを立ち上げました．
[招待URL](http://bit.ly/2pn6ewY)
4人しか人がいないですが，ぜひ入ってくれるとうれしいです．(あわよくば実装の相談など……)
プログラムの引数にランダム数が欲しい時

プログラムの引数にランダムな数が欲しい時がありますよね．
そんなときは，shufを使えばOKです．

    shuf -i 0-128 -n 10

とやれば，0から128の数が10個出てきます．
ただ，これだと改行が入ってるんで，

    shuf -i 0-128 -n 10 | tr '\n' ' '

とやれば，改行がスペースになって，引数として渡しやすくなります．
アプリケーション開発の勉強について思うコト。

# はじめに

どうも。HAL東京IT学部WEB開発学科3年のYana氏です。
今回、初のHALアドベントカレンダーという事で、アプリケーション開発についての持論を語ろうかと思います。

まず、今から書くことについては、**あくまでも個人的見解**です。

一番ベストな方法は、
「**自分に合ったやり方で、学習を進めていく**」
のが、ベストです。

とは言っても、そう簡単に自分に合ったやり方は見つかるわけない。
なので、参考程度に聞いてください。

勿論、この記事読んで「いやぁ、無理だよ。俺には合わなそう....」とか思ったら、全然スルーしちゃってください。

# アプリを作るということ
まず、僕が初期に作ったiOSアプリ作品をいくつか載せておきます。

### 3D地球儀
<img width="344" alt="スクリーンショット 2018-11-03 13.39.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/154610/93410271-224f-144d-2132-9fa9e8822b0c.png">

SwiftのScenekitを使って、作ったアプリです。その名の通り、3Dの地球儀です。
正直これ、めちゃめちゃコード短いです。

```swift:earth.swift
let sv = SCNView(frame: CGRect(x: 0, y: 0, width: w, height: h))
sv.showsStatistics = false
sv.allowsCameraControl = true
sv.autoenablesDefaultLighting = true
sv.backgroundColor = .black
view.addSubview(sv)
        
let ss = SCNScene()
sv.scene = ss
        
let cn = SCNNode()
cn.camera = SCNCamera()
cn.position = SCNVector3(x: 0, y: 0, z: 10)
ss.rootNode.addChildNode(cn)
        
let gm = SCNSphere(radius: 2.0)
gm.firstMaterial?.diffuse.contents = UIImage(named: "earth.jpg")
ss.rootNode.addChildNode(SCNNode(geometry: gm))
```
これで、終了です。
このコードについて、詳しい解説すると長くなってしまうので、要約すると、

・**球体を生成して、3Dで作成されたメルカトル図法の世界地図の画像を貼り付けた**
だけです。

### 英単語1400
<img width="288" alt="スクリーンショット 2018-07-02 13.15.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/154610/f1e4c32b-a368-839d-08fb-37c5f65533a5.png">

英単語が1400語収録されているインプット英単語学習アプリ。
結構シンプルな機能(UIKitの部品のみ)を使って、構成しています。

2つ共通して言えることは、**そこまで深く作り込まれたアプリじゃない**ということです。

# アプリ開発を勉強するなら、まずゴールを決めるべき
アプリ開発の勉強に関してですが、
今の僕の考えとしては、**技術本の内容を全部写経してから、アプリ開発するのは結構効率が悪い**と思います。
(プログラミング言語に関しては、写経しながらじゃないと厳しいと思いますが。。)

まずは、**何を作るか決めること**が大事なのではないか、と思います。
アプリ開発の勉強のゴールが明確化されることで、モチベーションがかなりアップします。
とりあえず、**簡単なアプリを企画してみてください**。
後は、自分が作りたいものを作りながら、分からないことがあれば、技術本で調べるのがいいと思います。
結局、作っていくうちに、色々壁にぶつかって、技術本でインプットしていくので、自然と技術本の内容が入ってくるはずです。

# アプリをどんどん企画する
簡単なアプリが出来たら、「次何作るか？」みたいな感じで、どんどん企画してみてください。
とにかく、**自分の頭で、アプリ開発の勉強のゴールを作る**ことが大事です。
そして、もう一つ大事なことは、　**徐々に作品のレベルを上げていく**事です。
格段に、開発のレベルも向上すると思います。

# 楽しい開発ライフを送ろう！
やっぱりアプリケーション開発は、「**楽しさ**」あってこそだと思います。
楽しい、開発ライフを送ろう！
JavaScript Errorオブジェクト


##Errorオブジェクト
エラーをthrowさせたいときなどには、Errorオブジェクトを使うことができる。

```js
new Error("error message");
```

コンストラクタにエラーメッセージを渡すことができる。
Errorはインスタンスが作成されたときに、インスタンスが作成されたファイル名や行数を情報として持ち、スタックトレースに表示される。
throw構文ではあらゆるオブジェクトをthrowすることができるが、スタックトレースへ情報が表示されることから、Errorオブジェクトをnewしてthrowするほうがよい。



##よく投げられる組み込みエラー

###ReferenceError
存在しない変数が参照された場合にエラーが発生する。

###SyntaxError
構文的に不正なコードを解釈しようとした場合のエラーを表す。

###TypeError
値が期待される型でない場合のエラーを表す。
JIRA 3日間コーチ まとめ

# はじめに
どーもJIRA初心者です。
JIRAって便利そうですよね。何かイケてる感じしますよね。
社内業務の管理とか、開発チームの管理とか、顧客とのコミュニケーションとか、色々と出来て便利っぽいですよね。
活用したい想いとは裏腹に、やってみると難しく、心が折れそうだったところを[kajinari](https://qiita.com/kajinari)さんにご指導頂いたので、そこから得られたことを書いていきます。

たぶん誰かの役に立つと思います。

# 3日間コーチ概要
* カリキュラムは3日間
* 講師はAtlassianユーザグループ代表の[kajinari](https://qiita.com/kajinari)さん（AUGで会った際にお願いしました）
* 現在の業務に合わせたカスタマイズを行えることを目標に設定
* 習得度合いでカリキュラムを柔軟に変更

などなど

# 実際の学習内容
ざっくり以下のような流れになりました。

1日目：JIRAの使い方（課題タイプ、ワークフロー、画面、フィールドの基本的な使い方）
2日目：業務内容の整理、社内ワークフローの整理、ステータスの整理
3日目：実際の業務と照らし合わせてシミュレーション、その他JIRAのシステム設定の調整など

# 学習内容のまとめ

## JIRAのワークフローの整備手順

### １．ワークフロー、ステータスを整備する
業務内容にジャストフィットさせるためにも、先ずは業務内容とワークフローを整理する。
ワークフローはホワイトボードに書き出していくなど、手を動かしながら視覚的にディスカッションしていくと整理しやすい。
**バリューストリーミングマップ**のような形式でフローを整理した。

この時、ただワークフローを整理するだけでなく、各ステータスがどういう状態なのかを明確にしておくことが重要となる。
ステータスの整理におけるポイントは以下の通り。

* ステータスの意味（どういう状態か）を定義する
* ステータスに入る条件を定義する
* ステータスを出る条件を定義する（出る条件≒次の入る条件 だけど全部整理する）

この時はConfluenceで以下のようにステータスを定義していく。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/140133/693cfeef-21b1-5d25-74b3-9dd91e66ed08.png)


### ２．ステータスごとに設定されるべきフィールドを考える
ステータスを整理した後は、それぞれのステータスの時に何が解っているのか？何を入力させるのか？を整理していく。
実際の業務に照らし合わせて以下のように設定していく。
まずは思いつく限り書き出していき、以下のポイントを参考に整理していく。

* 内容が細かすぎないか？
* 過不足は無いか？
* 管理項目として必要か？
* 状況分析を行う際に必要な項目か？（フィルタリングなどの需要が無い情報はテキストエリアでまとめて書かせる）
* 添付ファイルの内容と2重管理になっていないか？

などなど

ステータス定義に列を追加して記録していく。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/140133/4e3fd4de-d74c-7fe6-826e-cad02843ba14.png)

一通り整理したらフィールドを追加しておく。


### ３．画面を作成する
新しい画面を作成してフィールドを配置する。

* とりあえず全部盛りの1画面を作る。
* 画面スキームを追加する（とりあえずDefaultだけで良い）

※課題タイプ画面スキームは課題タイプを作ってから設定する


### ４．ワークフローを作成する
あらかじめ適当なプロジェクトを作成しておき、自動で生成されるワークフローをコピーして、新しいワークフローを作成する。
ワークフローは以下の流れで編集していく。

1. 開始のワークフローをステータス定義の先頭ステータスに変更する
2. 終了のワークフローをステータス定義の終点ステータスに変更する
3. その他のステータスは削除し、ステータス定義に従って追加する

トランジション、ポストファンクション（事後操作）の細かい設定は割愛。



### ５．課題タイプを作成する
業務名を適当に決めて課題タイプを作成する。
課題タイプを作成後、以下の流れでスキームを設定する。

1. 課題タイプスキームを作成、設定する
2. 課題タイプ画面スキームを作成、設定する（作っておいた課題タイプと画面を紐づけする）
3. ワークフロースキームを作成、設定する（作っておいた課題タイプとワークフローを紐づけする）


## プロジェクトの作成・適用

ここまでで作成した課題タイプ、ワークフロー、画面は、それぞれ「スキーム」という単位で管理されています。
これらを使うためには、プロジェクトを作成して「プロジェクト設定」でそれぞれ利用するスキームを切り替えます。

たとえば、課題タイプのスキームは以下から変更できます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/140133/0e219beb-471f-b4b4-2bdb-aef607ea248c.png)

この他の各種スキームも同様に変更します。


## カンバンの設定
ワークフローを作成したらカンバンが出来ると思っていましたが、そんなことはなく、カンバンをワークフローに合わせて調整する必要があります。
※カンバンが無いプロジェクトテンプレートの場合は、フィルタを設定してからカンバンとして追加します（割愛）

### １．カンバンの設定は以下から行う
![image.png](https://qiita-image-store.s3.amazonaws.com/0/140133/9422950d-f00d-f0b4-265b-f96b768428c0.png)

### ２．列を追加したり、レーンにワークフローのステータスを割り当てる
![image.png](https://qiita-image-store.s3.amazonaws.com/0/140133/6dbcc827-29f0-72e1-547f-0f51ec24261d.png)




## テストと調整
ここまでで大体の設定は完了しているので、カンバンを使ってワークフローをシミュレーションしてみましょう。
やってみると「あーしたい」「こうしたい」と色々と出てくるので、それに合わせて整備するというのを繰り返していきます。


# おわりに
説明が尻すぼみになってすいません。気持ちが持ちませんでした。
ここではトランジション、ポストファンクションについて触れていませんが、これらを使いこなすことで、よりイケてるワークフローを構築することが出来ますので、どうぞ頑張ってください。（適当）
あと、ダッシュボードとかフィルタとか他にもイケイケな機能が盛りだくさんなので、業務効率でお困りの方は是非ご検討ください。（適当）
macで大量のcurlのPOSTリクエストを実行して結果をファイルに出力するNode.jsコード

## 大量のCurlのPOSTリクエストのレスポンスをデータ出力したい時があり、Node.jsで実装したので、メモ。

```js
var fs = require('fs');
const execSync = require('child_process').execSync;
const shellFile = 'curl.txt.';
const output = 'output.txt';

// sync
fs.readFileSync(shellFile).toString().split('\n').forEach(function (line) {
    var result = execSync(line).toString(); //buffa → string
    // console.log(result)
    fs.appendFileSync(output, result);
});

// async
// const exec = require('child_process').exec;
// fs.readFileSync(shellFile).toString().split('\n').forEach(function (line) {
// exec(line, (err, stdout, stderr) => {
//     if (err) { console.log(err); }
//     console.log(stdout);
//   });
    // var result = stdout.toString(); //buffa → string
    // fs.appendFileSync(output, result);
// });
```

curl.txtの中身はこんな感じ

```
curl -X POST https://※※※※　-H "Content-type: application/json" -d "{'question':'あ'}"
curl -X POST https://※※※※　-H "Content-type: application/json" -d "{'question':'ああ'}"
curl -X POST https://※※※※　-H "Content-type: application/json" -d "{'question':'あああ'}"
curl -X POST https://※※※※　-H "Content-type: application/json" -d "{'question':'あああ'}"
curl -X POST https://※※※※　-H "Content-type: application/json" -d "{'question':'ああああ'}"
```

ホントはシェルでやりたかったが、Mac初心者なので、うまくできなかったので、なれているNodeで実装した。