OmniAICreator/Qiita-1.07M huggingface dataset:
Schrödinger方程式と波動関数、そして粒子の存在確率

#はじめに
初めまして、ようこそお越しくださいました！

現象数理学科2年生の分際ながら初記事を書かせていただきます。
とは言ってもコードを書くわけではなく自然現象に関する「何か」を書きます。

今回はSchrödinger方程式を使い、波動関数を紹介いたします。

#そもそもSchrödinger方程式って
自然界には原子という存在があります。元素の最小単位です。
20世紀を迎えるまでは古典力学と言われるマクロな力学が主流でした。
ところがミクロな粒子の運動について考えようと思うと古典力学では説明できない事柄も現れたので、新しい分野である量子力学が登場しました。
量子力学はミクロな現象を研究することでマクロな現象も扱うことができます。


ではここで水素原子について取り上げてみます。
Bohrによって導かれた水素原子モデル

$
・2πr=nλ\\\
・rp=\frac{nh}{2π}　(角運動量)\\\
(r:電子が描く円軌道の半径, λ:波長, h:プランク定数, n:量子数)
$

を用いた水素原子のスペクトルの値はとびとびの値をとりますが、これが全ての原子に当てはまるのかというとそうではなく原子によって結果にズレが生じます。
そこで他の粒子にも対応できるようにSchrödinger方程式が生まれました。


では具体的にどのような式になるのか導出方法とともに見ていきましょう。
原子の物質波を定常波で考えると境界条件より両端が振幅0の節になっているので

$
A(x)=A_0sin(\frac{nπ}{L}x)\\
(A_0:振幅, L:波長)\\
$
という波の式になります。

この両辺を2回微分すると

$
\frac{d^2}{dx^2}A(x)=-(\frac{2π}{λ})^2 A(x)...(*)\\
$

ポテンシャル井戸の中に電子が伴うと考えると場所rにおける振幅をφ(r)とおくと、エネルギー保存則よりEを粒子の持つ全エネルギー、Vを粒子のポテンシャルエネルギーとして

$
E-V(r)=\frac{h^2}{2mλ^2}\\
$

が成り立つので

$
(*)⇔\frac{d^2}{dx^2}φ(x)=-(\frac{2π}{λ})^2 φ(x)$

つまり$(*)=-\frac{8mπ^2}{h^2}(E-V(x))φ(x)
$


これを整理して

```math
-\frac{h^2}{8mπ^2}\frac{d^2}{dx^2}φ(x)+V(x)φ(x)=Eφ(x)\\
```
これを1次元のSchrödinger方程式と呼ぶ。             
一般の3次元の場合は微分を3次元をのものに置き換え粒子の位置ベクトルをrとして

```math
-\frac{h^2}{8mπ^2}(\frac{∂^2}{∂x^2}+\frac{∂^2}{∂y^2}+\frac{∂^2}{∂z^2})φ(r)+V(r)φ(r)=Eφ(r)\\
```
というふうに表現できる。


この式からもわかるようにSchrödinger方程式というのは
ポテンシャルの形V(r)を波動関数φ(r)に変換する装置なのです！

#波動関数の構築
ある原子に対して波動関数を作るにはどんな要素が必要かを考えてみましょう。
原子核を中心として電子の極座標をγ(r,θ,φ)とおく。

![極座標系.png](https://qiita-image-store.s3.amazonaws.com/0/223549/c3ac30c4-4216-ddeb-d3e4-d6a2aa1679cf.png)


rの変化→電子が原子核に近づいたりと遠ざかったりする運動...(a)
(θ,φ)の変化→原子核まわりの回転運動...(b)

この3つの自由度に対して3つの量子数が決まる。


(1)原子核に対する遠近運動はrの変わらない円運動を考えると軌道面は傾いている。
この運動に対してSchrödinger方程式を解くと回転運動の角運動量は量子数lを用いて
$
\sqrt{l(l+1)}\frac{h}{2π}...(I)
$
と表現される。


![angular_momentum-1.gif](https://qiita-image-store.s3.amazonaws.com/0/223549/5da677d6-990e-be64-c31f-dc141a2c661f.gif)


(2)この回転運動をxy平面に投影してφによってのみ変わるz軸周りの運動を考える。
Bohrのモデルから角運動量のz軸への投影が整数mを用いて
$
\frac{mh}{2π}\\
$
とならなければならない。
この時、x,y成分によって角運動量は変化しないので(I)から$m=-l,-l+1,...,l-1,l$の値をとる。
この回転運動の波動関数を$Y_{lm}(θ,φ)$と表すことにする。



(3)次に原子核に近づいたり遠ざかったりする運動を考える。電子が回転している時の遠心力の大きさはlによって決まる。ここでlは非負整数である必要がある。それを解決するためにあるlが指定された時の遠近運動は量子数をj(自然数)としてn=j+lと表現するとn(自然数)に対してlは非負整数で考えることができる。
この表現の仕方を動径波動関数$R_{nl}$と言ったりする。


まとめとして回転運動と遠近運動の両方を含む波動関数を
$\psi_{nlm}(r)$=$R_{nl}・Y_{lm}(θ,φ)
$
と表す。


#電子の存在確率

最後に半径rの球上に電子が存在する確率を求めよう。
半径$r$の球と半径$r+dr$($dr$は微小距離)の球を考えると厚みは$dr$で、($θ,φ$)を中心に$dθ,dr$だけ変化すると考えると、この厚みでの動きは各々$rdθ$と$rsinθdφ$となる。
よって、規格化された$φ(r)$に対してこの厚みに電子が存在する確率は
$\int_{0}^{2π}\int_{0}^{π}|φ(r)|^2r^2drsinθdθdφ\\\
=r^2(R_{nl}(r))^2[\int_{0}^{2π}\int_{0}^{π}Y_{lm}(θ,φ)sinθdθdφ]^2dr\\\
=r^2(R_{nl}(r))^2dr\\\
=D_{nl}(r)dr$\\\
$D_{nl}(r)$は動径分布関数と呼ばれ、単位厚みあたりの粒子の存在確率に値する。そしてこの式からrの値として最も確率が大きい値はBohrの半径と一致することがわかる。
ReasonReact を使ってみる

Reason 気になった人はまず最初で使うであろう ReasonReact について解説する。

https://github.com/reasonml/reason-react

## 外部パッケージの使い方

npm経由で落として、bsconfig.json にバインディングがあるので、それを教えてやる。

```
yarn add reason-react
```

```bsconfig.json
{
  ...
  "bs-dependencies": ["reason-react"]
}
```

これで bucklescript が ReasonReact 名前空間にアクセスできる。

## Hello, ReasonReact

コンポーネントを定義して render する。

```ocaml:main.re
module App {
  let make = (_children) => {
    ...ReasonReact.statelessComponent("App"),
    render: (self) => <div> { ReasonReact.stringToElement("Hello") } </div>
  };
}

/* mount */
ReactDOMRe.renderToElementWithId(<App />, "root");
```

このコードを見る限り、ReasonReact は make という関数を見つけて React.createElement 相当の展開をする。
文字列は `ReasonReact.stringToElement("Hello")` という感じで埋める。多少面倒くさい。


## 名前空間の話

ここで、初歩っぽい話をするが(自分はocaml詳しくないので、こういうタイミングで新しいことを知る)、 ocamlのファイルスコープはファイル名が PascalCase に変換されて module 名になるが、自分自身で module を定義することも出来る。

なので、別ファイルに切り出すならこうなる

```ocaml:app.re
let make = (_children) => {
  ...ReasonReact.statelessComponent("App"),
  render: (self) => <div> { ReasonReact.stringToElement("Hello") } </div>
};
```

bucklescript 的には外部の名前空間へのアクセスを発見すると `require('./src/App')` 的な変換をする。

## reducerComponent

Reactのアプリを作るなら、 redux 相当のことをしたいよな、と思って、本当はここで reductive という redux クローンの解説をしようと思っていたが、 ドキュメントいわく、 You might not need this library, なぜなら ReasonReact が reducer 相当の機能を持ってるので、まずはそれを使え、という話。

https://github.com/reasonml-community/reductive は後日解説する。（こうやって記事を稼ぐ）

https://reasonml.github.io/reason-react/blog/2017/09/01/reducers.html を読みながらカウンターを実装してみた。

```ocaml
type action =
  | Increment
  | Decrement;

let counter = (action, state) =>
  switch action {
  | Increment => state + 1
  | Decrement => state - 1
  };

module App = {
  let make = (~value, ~onClickIncrement, ~onClickDecrement, _children) => {
    ...ReasonReact.statelessComponent("App"),
    render: (self) =>
      <div>
        <span> (ReasonReact.stringToElement(string_of_int(value))) </span>
        <button onClick=onClickIncrement>
          (ReasonReact.stringToElement("+1"))
        </button>
        <button onClick=onClickIncrement>
          (ReasonReact.stringToElement("-1"))
        </button>
      </div>
  };
};

let make = (_children) => {
  ...ReasonReact.reducerComponent("AppContainer"),
  initialState: () => 0,
  reducer: (action, state) => ReasonReact.Update(counter(action, state)),
  render: (self) =>
    <div>
      <App
        value=self.state
        onClickIncrement=(self.reduce((_) => Increment))
        onClickDecrement=(self.reduce((_) => Decrement))
      />
    </div>
};
```

counter が ピュアな reducer 定義、 App が View を持つComponent、 トップレベルの make がいわゆる ContainerComponent という感じの分担。ちょっとややこしいのが self.reduce が高階関数になっている。

JS でやるときの無理矢理な action 定義と違って、言語組み込みの機能で自然に表現できている。

## 次の記事の候補

- reductive さっと調べる限り connect 実装してないが、それはどうする？
- Reason から JS で定義した React Component を呼ぶ
- JS から Reason で定義した React Component を呼ぶ

まだ調べてない。わかったら書く。
Xorshift を作る

疑似乱数列生成法の1つである Xorshift を作ってみよう。今回は前置きなくいきなりプログラムだ。

```python:xorshift_func.py
import polyphony
from polyphony import module, pure
from polyphony import testbench
from polyphony.io import Port
from polyphony.typing import bit, bit32
from polyphony.timing import clksleep, clkfence, wait_rising, wait_falling

def xorshift(seed:bit32)->bit32:
    y:bit32 = seed

    y = y ^ ( y << 13 )
    y &= 0xFFFFFFFF
    y = y ^ ( y >> 17 )
    y &= 0xFFFFFFFF

    y = y ^ ( y << 5)
    y &= 0xFFFFFFFF
    return y

@testbench
def test():
    y:bit32 = 2463534242
    for i in range(10):
        rv:bit32 = xorshift(y)
        print(rv)
        y = rv

if __name__ == '__main__':
    test()
```

このソースは 32bit 版だ。64bit 版、128bit版というのもあるらしいのでいずれチャレンジしてみたいと思う。

ソースの中に bit32 というタイプヒントを入れている。これでPolyphony は 32bit の変数と解釈する。

プログラムの３か所に不思議ともいえる &(アンド) がある。bit32 と宣言しているので、そんなことをしなくてもよさそうなものだ。

```python:
    y &= 0xFFFFFFFF
```

この部分は Python でシミュレーションした時に効いてくる。Python ではタイプヒントはあくまでヒントであって、実行時には int である。シフトすればその分、大きな値になる。それを抑制するコードになっている。

Python で実行してみよう。

```text:
> python xorshift_func.py
723471715
2497366906
2064144800
2008045182
3532304609
374114282
1350636274
691148861
746858951
2653896249
```

実行結果が10進表示だが、c の結果と同じであることを確認した。
#class を使った Xorshift

先の Xorshift は関数版だった。Polyphony の現在は関数内に状態を持つことが出来ない(クロージャ的な事は出来ない)。そのため、関数の第一引数に seed を入れている。seed が毎回同じなら毎回同じ値を返す。これでは乱数とは言えない。Python の class をつかって書き直してみよう。

```python:xorshift_class.py
import polyphony
from polyphony import module, pure
from polyphony import testbench
from polyphony.io import Port
from polyphony.typing import bit, bit32
from polyphony.timing import clksleep, clkfence, wait_rising, wait_falling

from xorshift_func import xorshift

@module
class xorshift_module:
    def __init__(self, seed:bit32):
        self.seed = seed
        self.i_start  = Port(bit, 'in', protocol='ready_valid')
        self.o_data  = Port(bit32, 'out', protocol='ready_valid')
        self.append_worker(self.xorshift_worker)

    def xorshift_worker(self):
        seed:bit32 = self.seed
        while polyphony.is_worker_running():
            self.i_start.rd()
            rv:bit32 = xorshift(seed)
            self.o_data.wr(rv)
            seed = rv
            
m=xorshift_module(2463534242)

@testbench
def test(m):
    for i in range(10):
        rv = 0
        m.i_start.wr(1)
        rv:bit32 = m.o_data.rd()
        print(rv)
        y = rv

test(m)
```

先の関数がライブラリとして使えることがわかる。

#おまけ c 版のソース

```c:xorshift_c.c
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

uint32_t
xorshift(void)
{
    static uint32_t y = 2463534242;

    y = y ^ (y << 13);
    y = y ^ (y >> 17);

    y = y ^ (y << 5);
    return y;
}

int
main(int argc, char **argv)
{
    uint32_t a;
    int i;
    uint32_t n = (argc == 2)?atoi(argv[1]):1;
    for( i = 0 ; i < n ; i++ ) {
        a = xorshift();
        printf("%u\n", a);
    }
    return 0;
}
```
[新機能]: for 文の unroll

Python はコンパイラ側から見て非常によくできた言語だと思う。不必要に機能を入れ込んでいない点が何より素晴らしい。コンパイラを作るという視点から見ると普通の機能も別の意味があることに気が付く。

Python だけではないが、foreach のような構文を書ける言語はいくつもある。記述に便利なだけでなく、書き方によってはシリアライズが確定するのでコンパイラのオプティマイゼーションが効きやすくなるだろう。
どういうことか？簡単なリストの for 文を考える。

```python:
a_lst = [1, 2, 3, 4, 5]
for e in a_lst:
    print(e)
```

a_lst は必ず最初から順番にアクセスされる。一方、C で各 for 文では次のようになるだろう。

```c:
int a[] = {1, 2, 3, 4, 5};
for (int i = 0 ;i < sizeof(a)/sizeof(int); i++ ) {
    printf("%d\n", a[i]);
}
```

配列 a は何かに index される(この場合は変数 i)。配列 a がランダムアクセスされないことは、for の中を解析しないとわからない。配列をポインタに変えても本質は変わらない。

表記だけでそのアクセス方法がわかることはコンパイラにとって都合がよい。とりわけ HLS では最適化の可能性が広がる。

# unroll の実際
前置きが長くなったが for 文の unroll を使った例を示そう。unroll は for 文の中身をマクロのように展開する。

```python:unroll01.py
from polyphony import testbench
from polyphony import unroll, rule


def unroll01(xs, ys):
    s = 0
    with rule(unroll='full'):
        for i in range(8):
            x = xs[i] + 1
            if x < 0:
                s = s + x
            else:
                s = s - x
            ys[i] = x
            #print(x)
    return s


@testbench
def test():
    data = [1, 2, 3, 4, 5, 6, 7, 8]
    out_data = [0] * 8
    s = unroll01(data, out_data)
    print(s)
    assert -44 == s
    assert 2 == out_data[0]
    assert 3 == out_data[1]
    assert 4 == out_data[2]
    assert 5 == out_data[3]
    assert 6 == out_data[4]
    assert 7 == out_data[5]
    assert 8 == out_data[6]
    assert 9 == out_data[7]


test()
```

実際に unroll をした場合と、しない場合でのシミュレーション上の結果は 38 clock と 52 clock となった。

unroll の回数が決定できない場合は数字を指定することができる。回数は丁度良い必要はない。この例では 8 のループに対し 3 ずつの展開をする。あまりの 2 は逐次的に実行される。

```python:
    with rule(unroll='3'):
        for i in range(8):
            x = xs[i] + 1
            ...後略...
```

将来的には書き方が変わるかもしれない。最新のバージョンでは次の書き方もサポートされている。with 文を省きインデントの混乱が少なく書けるように設計されている。

```python:
def unroll04_a(xs:list):
    sum = 0
    for x in unroll(xs, 4):
        sum += x
    return sum
```
ちょっとずつ読むドメイン駆動設計 第四部 戦略的設計　序章 

# これまでのドメイン駆動設計
今日から第四部。第一部から第三部まで何を読んできたかちょっと復習

## 第一部：[ドメインモデルを機能させる](https://qiita.com/YasuhiroKimesawa/items/386b43d684518656fd10)
ドメイン駆動設計の基礎。その概念や設計・実装する上で必要なことを説明しています。

ドメイン駆動設計では慣れたこれまでの設計(トランザクションスクリプトな設計)の考え方から離れて、マインドから変えていかなくてはいけない。
モデルと実装を結びつけること。コミュニケーションを重視し、ユビキタス言語を構築すること、ドメインエキスパートとの会話から知識を噛み砕いてモデルにしていくことなどが説明されています。

## 第二部：[モデル駆動設計の構成要素](https://qiita.com/YasuhiroKimesawa/items/5801973f9e378ebf7e0d)
ドメインと技術的な要素を切り離すことから始まり、関連・エンティティ・値オブジェクト・モジュール・集約などの構成要素がテーマ。

## 第三部：[より深い洞察へ向かうリファクタリング](https://qiita.com/YasuhiroKimesawa/items/eb29387171d583144abc)
ドメインについての深い理解をとらえたモデルをいかに見つけ出すかがテーマ。

暗黙的な概念を明示的にするテクニックや、しなやかな設計にしていくためのリファクタリングなどが説明されています。

# 戦略的設計

最終第四部はモデリングプロセスをスケールアップさせるための原則がテーマ

三部までの違いは、複数のチーム・複数のシステムが関わったり、政治が入り組むことが多いところでの判断が必要になること。

サブシステムを含めたシステム全体でモデルを統一するということは夢のまた夢で非現実。
大きすぎ、扱いにくい、重複や矛盾が紛れ込む。

いかに統合してかつ、モジュール性を実現するか。その戦略が三部のテーマです。

モデルとしては、**概念的なコア(システムの「ビジョン」をとらえるモデル)**にいかに集中するかが大事なテーマになってきます。

これらを解決するための３つのキーワード。それが、**コンテキスト、蒸留、大規模な構造**です。

## コンテキスト
上記でいうモジュール性をどの範囲で適用するか、その境界を明示的にし、いかに整合性を維持していくかがテーマ。

## 蒸留
ドメインにおいて、周辺的な重要でない問題への努力を減らし、最も付加価値の高い箇所へ注力していく。
各サブシステムを含め、それぞれで適切な視点で、焦点を合わせ、システムで最も重大な部分に努力を向け、ビジョンを失わないようにしていく。

サブシステムが複数あるような大きなシステムでは、このコアンドメインの設計が役に立つものになっていきます。

## 大規模な構造
このキーワードは、システム全体にわたって、適用できる設計要素やパターンがテーマ。システム全体にわたる包括的なテーマとなる。



明日からはこれらを詳細に読んでいきます。
学び、今後知識をつけていきたいことについて

こんにちは！
アドベントカレンダー2記事目です！
今回は自身で悩んだこと、今後知識として強化していきたいことについて書かせていただきます。
今後さらに以下で書いていく内容について人に説明できるようにきちんと理解していきたいと思いました！

#悩んだこと
悩んだことはtableViewの更新とセルの再利用です・・・。
ボタンがタップされた時にTableViewの表示を更新しようとしたのですが、
更新の仕方がわからず、調べてみました。
#[tableView reloadData];

ボタンのタップイベントでreloadDataを記述するだけでセルの更新ができました！
reloadDataを記述する前はスクロールしないとセル内容の更新ができませんでした。
調べている時に「~でreloadDataを呼ぶだけ」などの記述をよくみたため惑わされました・・・・
reloadDataは固定のところで呼ぶのではないことを学びました。
当たり前ですが処理したいところで呼ぶことが大切でした。

#セルの再利用

セルの更新に関連するのはセルの再利用です・・・・
画面から見えなくなったセルをスクロールした時に次のセルとして使用することをセルの再利用と言うそうです。
セルを再利用せずに生成しまくっていると処理が重くなったりするため、
基本的にセルは再利用するものだそうです。
いくつか調べたのですが、もちろんセルを再利用せずに生成し続ける方法もあるようです。
しかし、大体の記事では再利用するようにと書かれていました。
セルの再利用がどの部分を意味するのか最初全く見当がつきませんでしたが、
おまじないのように書いていたセル生成の後の
cell==nil・・・・・あの部分が再利用の記述をしていることがわかりましたが詳しくは今後学んでいきたいと思います。
セルの再利用で気をつけなければいけないことは、前のセル状態が残ってしまったりっすることが多く、
そこでつまずく人が多いようです・・・(私もそのうちの一人です)
セルに表示する内容は配列などきちんと別で管理しておくことで対処できるようです。
#Notification

未だに苦手なものの一つです。最初「通知名」と「通知で呼び出されるメソッド名」の違いがわかりませんでした。
あとは何回も間違えてしまったaddObserverとremoveObserverです・・・・
addしてからremoveするまでの間でaddで指定したメソッドを呼ばなければいけない。

```objc
//通知の監視を始めます。
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notificationCallMethod) 
name:@"tutti" object:nil];
```

この例であれば通知名は@“tutii”
この通知名の通知があった時に呼ばれるのがここで指定しているメソッド名です。
メソッド間で行き来できるので便利な機能ではありますが
むやみやたらにNotificationを多用するとスパゲッティ状態になってしますので使用のしすぎに注意する。
[ios]firebaseを使用したデータ取得について

現在、開発でfirebaseを使用しているのですが、どうしてもデータの構造になれなくて、つまづくことが多かったので、メモ。
例えば、下記のようなデータの構造があるとする。
<img width="635" alt="スクリーンショット 2017-12-14 1.22.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/175906/50e9cbc2-c432-2032-d7dc-e92082e486f6.png">
この場合、「Group」以下を取り出すのは比較的簡単。

```swift:sample.swift
//この「ref」でこのツリー全体のrootを示す。
ref = Database.database().reference()
//refの下に「child()」で場所を示す。今回の場合は「Group」
ref.child("Gruop").observe(.value, with: { (snapshot) in
            中略・・・

```
私が今回、つまづいたのは「Group」の下にある一つブロックのその下にぶら下がっている（今回であれがusers）を取得する場合。

```swift:sample.swift
ref = Database.database().reference()
//refの下に「child()」で場所を示す。今回の場合は「Group」
ref.child("Gruop").observe(.value, with: { (snapshot) in
            
            for itemSnapShot in snapshot.children {
                //ここで取得したデータを自分で定義したデータ型に入れて、加工する
                let item = GroupData(snapshot: itemSnapShot as! DataSnapshot)
　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　・・・中略
                
                }
            }
```
で、自分で定義したデータ型がこちら。
let dict にfirebaseで取得したデータを入れて、あとは取り出したい項目ごとにデータを加工。

```swift:GroupData.swift
class GroupData {
    
    var ref: DatabaseReference?
    var groupid: String?
    var name: String?
    var founder: String?
    var memberofnumber: Int?
    var payment: Int?
    var period: String?
    var message: String?
    var publicnum: Int?
    var groupprofile: String?
    var users : Array? = []
    
    init? (snapshot: DataSnapshot) {
        ref = snapshot.ref
        guard let dict = snapshot.value as? [String:Any] else { return nil }
        guard let groupid  = ref?.key  else { return nil }
        guard let name  = dict["name"] as? String  else { return nil }
        guard let founder = dict["founder"]  as? String else { return nil }
        guard let memberofnumber = dict["memberofnumber"]  as? Int else { return nil }
        guard let payment = dict["payment"]  as? Int else { return nil }
        guard let period = dict["period"]  as? String else { return nil }
        guard let message = dict["message"] as? String else { return nil }
        guard let publicnum = dict["publicnum"] as? Int else { return nil }
        guard let groupprofile = dict["groupprofile"] as? String else { return nil }
         guard let users = dict["users"] as? [String:AnyObject] else { return nil }
        var newusers : Array? = []

        for i in users.keys {
            newusers?.append(i)
        }
        
        self.name = name
        self.groupid = groupid
        self.founder = founder
        self.memberofnumber = memberofnumber
        self.payment = payment
        self.period = period
        self.message = message
        self.publicnum = publicnum
        self.groupprofile = groupprofile
        self.users = newusers
       

    }
    
}

```

自分は「users（ツリー上ののぶら下がっているブロック）」を配列として取得したかったので、配列として取得したところ、うまくいかず・・
データの型を [String:AnyObject]で宣言することで、keysで一つ一つのkeyを取得できたので、あとは配列に入れておしまい。
言葉にして説明しようとすると、うまく伝えられない。。。。
kaggleで拾ってきたDatasetsをpythonで可視化する

アイスタイル  [Advent Calendar 2017](https://qiita.com/advent-calendar/2017/istyle) の 14 日目は、@tanit5699 が kaggleで拾ってきたDatasetsをpythonで可視化してみます。

##Kaggle
[Kaggle（カグル）](https://www.kaggle.com/)とは、データ解析のコンペサイトで、企業や研究者が投稿した課題に対して、世界中のデータサイエンティストがより精度の高い「予測」モデルを競い合う場所になっています。

参加者の提示したモデルは即時に採点され、順位が表示されます。コンペに参加し、上位入賞者には企業や研究者から賞金が用意されていたり、データサイエンティストとして実力をアピールすることができて求人の際に有利になったりします。

企業や研究者が投稿した課題の他、kaggleが用意したチュートリアルチャレンジ、個人が投稿するデータなど、膨大な量のデータが投稿されていますので、それらを用いて学習するのにも最適な場所になっています。

##Datasets

今回は、Kaggleが投稿した[機械学習エンジニア/データサイエンティストに対する2017年のアンケート](https://www.kaggle.com/kaggle/kaggle-survey-2017)のDatasetsを使用します。

##データを読み込む

```py3:dataVisualization.py
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.cm as cm

%matplotlib inline

data = pd.read_csv('../kaggle/DataScience2017/multipleChoiceResponses.csv', encoding='ISO-8859-1')
print(data.shape)
```

上記のソースコードを実行すると、下記の結果が返ってきます。

` (16716, 228)` 

読み込んだDatasetsは、16716人からの回答数があり、項目が228個が複数回答のアンケート結果になっています。
この中の項目から二つ選んで、データの可視化と軽い分析をしてみようと思います。

##年齢別に回答数をヒストグラムで描画

```py3:dataVisualization.py
plt.figure(figsize=(13, 10))
plt.hist(data['Age'].dropna(), bins=50,  edgecolor='white')
plt.title("age distribution", fontsize=15)
plt.tick_params(labelsize=15)
```



<img width="427" alt="age distribution.png" src="https://qiita-image-store.s3.amazonaws.com/0/211277/0422ab35-0fb3-57e1-a868-cd6f2cf7389f.png">


20代後半が一番多くなっており、kaggleを利用するデータサイエンティストは全体的に若い人が多いことがわかります。0歳や100歳の回答のような明らかに嘘の回答も混じっています。

##国別に回答数を棒グラフで描画

```py3:dataVisualization.py
countryData = data['Country'].value_counts()
x = np.arange(len(countryData))
y = countryData.values
plt.figure(figsize=(12, 6))
colors = cm.jet(y /max(y))
plt.xticks(x, countryData.index.values.astype('str'), rotation=90)
plt.ylabel('samples')
plt.bar(x, y, color=colors)
```

<img width="718" alt="country distribution.png" src="https://qiita-image-store.s3.amazonaws.com/0/211277/f8383b1d-de5c-b1cf-4ec0-a3a474f0ecfa.png">


USAとインドの回答者の数が圧倒的に多くなっています。日本は13番目に多いです。ただし、kaggleの利用者は、100万人以上いるそうなので、1万6千人のサンプルで、USAとインドの利用者が多いとは言い切るのはまだ早そうです。

##まとめ

今回はアンケートのDatasetsから年齢と国だけ可視化してみました。他にも、給料・使用しているツール・おすすめの言語など興味深い項目がありますので、見てみると面白いと思います。
pythonでは、簡単にデータを可視化できるので、今後、業務にも役立てていこうと思っています。

15日目はYuyaAboさんの「きっかけ」です！
iOS10だとUISearchControllerでメモリリークする

UISearchControllerを使って以下のような画面を作る時、
<img src="https://qiita-image-store.s3.amazonaws.com/0/14751/d7716d9c-9679-07f2-9cb5-81209c225bd8.png" width=160> <img src="https://qiita-image-store.s3.amazonaws.com/0/14751/3a7e61d9-d130-07fb-d4f9-ca125ba71257.png" width=160> <img src="https://qiita-image-store.s3.amazonaws.com/0/14751/a8b147c6-52fc-4b9a-1210-bcbd9f01ff8d.png" width=160>

なにも意識しないで実装すると画面遷移時に遷移した先でSearchBarが残ってしまうことがあります。
<img src="https://qiita-image-store.s3.amazonaws.com/0/14751/71edd1cc-c6e2-9bcb-f06e-e1faedee194d.png" width=160>


この対処法として、遷移元の `ViewController` の` viewDidLoad` で `definesPresentationContext = true` と書く方法をよく見かけます。
参考: 
https://qiita.com/color_box/items/d13b04a88587088019af
https://stackoverflow.com/questions/29472011/uisearchcontroller-persisting-after-segue

しかし、`definesPresentationContext = true`とするだけだと、iOS10では2番目のViewControllerから1番目のViewControllerへ戻るときにリークします。
Debug Memory Graphで見てみると、以下のように `TableViewController` が `_UISearchPresentationController` によって保持されているのがわかります。
<img width="1137" alt="スクリーンショット 2017-12-11 21.48.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/14751/2bf975a1-536b-5918-b578-cf919140cb25.png">

リークしないようにするには、遷移する前に `searchController.active = false` をするのを忘れないようにしましょう。

もしくは、SearchBarを `tableView.tableHeaderView` ではなく、ナビゲーションバーに置くと、`definesPresentationContext = true` を書かなくても遷移先でSearchBarが残ってしまったりUIが崩れたりしないのでUIを変えるというのも手かもしれません。

以上、UISearchControllerのTipsでした。

ちなみに上述のDebug Memory Graphは便利なので使ったことない人は使ってみるといいと思います。
以下の記事が詳しくまとまっています。
https://qiita.com/ikezzi/items/b6f9eaf4f093cda3a95d
Javaでお手軽に絵文字を使うライブラリ emoji-java の紹介

この記事はJava Advent Calendar 2017の14日目の記事です。
昨日は@Itinoiseさんの『[ふわっとStreamで試したいこと試してみた。](https://qiita.com/Itinoise/items/065d858100be491eadec)』でした。


# 概要
[emoji-java](https://github.com/vdurmont/emoji-java)というライブラリを利用してJavaでお手軽に絵文字を使用できるライブラリの紹介です。

emoji-javaにより、Slackを利用している方には馴染みのある記法をJavaアプリケーションでも使えるようになります。

# emoji-java
## ダウンロード
[README](https://github.com/vdurmont/emoji-java)にも書いてありますが、MavenやGradleでお手軽にダウンロードできます。

- Maven

```xml
<dependency>
  <groupId>com.vdurmont</groupId>
  <artifactId>emoji-java</artifactId>
  <version>4.0.0</version>
</dependency>
```

- Gradle

```groovy
compile 'com.vdurmont:emoji-java:4.0.0'
```

## 使ってみる
単一の絵文字は、 `EmojiManager` クラスで取得できます。
`Emoji` クラスはPOJOでaliasやunicode、HTML表現などの情報を持っています。

```java
EmojiManager.getForAlias("name_badge");
    // => Emoji{description='name badge', supportsFitzpatrick=false, aliases=[name_badge], tags=[], unicode='📛', htmlDec='&#128219;', htmlHex='&#x1f4db;'}
```

unicodeのみ欲しい場合は、`Emoji.getUnicode()` で取得できます。

```java
System.out.println(EmojiManager.getForAlias("name_badge").getUnicode());
    // => 📛
```

`EmojiPareser.parseToUnicode()` で文字列中に含まれるエイリアスを絵文字に変換することもできます。

```java
String str = "明日の朝までによろしくお願いします:pray:\n"
                + "定時後にゴメンネ:bow: @ほげほげ\n";
String parsed = EmojiParser.parseToUnicode(str);
System.out.println(parsed);
    // => 明日までによろしくお願いします🙏
    //    定時後にゴメンネ🙇 @ほげほげ
```

`EmojiParser` のメソッドで、絵文字の表現形式を変換できます。
例としては、以下のような変換が可能です

|Method|from|to|
|:---|:---|:---|
|parseToUnicode|alias|unicode|
|parseToHtmlHexadecimal|unicode|html hexadecimal|
|parseToAliases|unicode|aliases|

他にも、絵文字のみ削除したり、抽出したりすることもできます。

# まとめ

emoji-javaを使ってJavaで絵文字をお手軽に扱う方法を紹介しました。
基本的には `EmojiParser` クラスを利用して文章中の絵文字形式を変換できると良さそうかな、という気がします。

Java Advent Calendar 2017、15日目の明日は@cero_tさんです。
よろしくお願いします。
チームのリーダーを降ろされてから復帰するまで

# はじめに
社会人4年目になりました。
3年目までは何か若手って感じしますけど、4年目になったら中堅です。
時が経つのは早いなぁ・・・
20代も終盤です。まだまだ青春したいです。
忘年会シーズンなので幹事やることが多いです。

# 話すこと
実は1年くらい前まで小さい単位のチームリーダーやってました。
しかし、色々あってリーダー降ろされて・・・
最近またリーダーに復帰しました。
失敗して感じたこととか、これからのマインドとか話せればなと。

# リーダーになってから降ろされるまで
初めてリーダーになったのは1年半くらい前だったかな。
3年目に入った時くらいです。
小さい単位での「リーダー」というものが初めて導入された時でした。

当時のチームで若手が自分だけだったということもあり、経験のためにリーダーにして頂いた部分もあると思います。
学生の頃研究室の取りまとめとかしていたので、何となくそういうリーダーっぽいことは嫌いじゃなかったです。
（ま、その程度の気持ちが甘かったんですけど。）

何となくチームの窓口みたいなことはやってました。
けどまぁ、それ以上のことはあまりやらないし、やろうという気持ちもそんなにありませんでした。
別に特別悪いこともしていませんが、特別良いこともしていません。
自分の最低限の仕事だけを"こなす"感じです。

周りの人が頼もしかったので、大崩れするとは思っていませんでしたし、実際大崩れもしませんでした。

しかし、それはチームリーダーとしてどうなんだということで、区切りのいいところで降ろされました。
降ろされた際、特別これという理由はありませんが、"目指すリーダーの先輩像がないから"という感じでした。
確かに、初めてのリーダーの導入だったので、何をすれば良いか分かりませんでした。

自分でも何となく今のままじゃダメだとは思っていたので、降ろされたことに対する不満はありませんでした。
むしろ新しいリーダーを見習って、いつか返り咲ければと思っていました。

# リーダー降ろされてから復帰するまで
自分の代わりのリーダーを見たりしました。
今までの自分だったらやらないような調整をしたり。気遣いとかもそうですし。
基本的には勉強になることばかりでした。
大事だな〜と思ったこと箇条書きにします。後ほど一個一個詳しく書きます。

・定例業務の根本解決
・他部署との調整
・一つ上の世界を見れるか

あと、何よりも嬉しかったのは自分の悪いマインドを変えようとしてくれたこと。
これは特定の一人と言うより、自分に関わる人全体的にです。
少しずつ変わって、リーダー復帰しました。
自分のスキルは大きく変わってないかもしれませんが、マインドは変わったと思います。
4年目なんだから、周りに迷惑かけずに後輩を引っ張れるくらいの活躍をしたいです。
では、大事なことをまとめます。

## 定例業務の根本解決
今までは"こなしていた"仕事。
それはそれで仕事にはなりますが、ムダです。
思考停止でできることは大体自動化できます。
自分で自動化できなくても、ルーティーンをまとめるだけで誰かが自動化してくれるかもしれません。
ルーティーンをまとめるだけで、ほぼ自動化したも同然な気がします。

定例業務を自動化することによって、空いた時間が増えます。
早く帰るもよし、他の仕事をするもよし。自由に時間が使えるのはいいことですね。
至極当たり前のことなのですが、定例業務が根付いてしまうと感覚が麻痺して"こなす"ようになってしまいます。
そうなる前に根本潰したいです。

## 他部署との調整
部署が違うと考えや文化も違うかもしれません。
自分の常識は自分だけの常識かもしれません。
私の業務では他社ではなく、自社の他部署との繋がりが多いです。
同じ社内でくだらない争いをしても仕方ありません。
相手が何を欲しいのか、本当のところを考えれる気持ちが大切です。
それが分からなければ、頻繁に顔出すとか。それだけでも全然いいと思います。
とりあえず何か決定する前に相手の意見を聞く。それを鵜呑みにするわけではありませんが、大きく参考にします。

求められていない物を作っても、ムダです。
コミュニケーションロスを減らすことを考えましょう。
これは開発に限る話ではなく、人と人の付き合いだと思っています。

## 一つ上の世界を見れるか
自分の仕事をするのは当たり前。
その先のリーダーの気持ちになれるか。
リーダーだったらその上の上司？の事とか。
ちょっと先を見れた方が、案件の理解も早くなりますし、自分の仕事が何故必要なのか分かりやすいです。
目の前の仕事で手一杯の時もありますが、ちょっと意識するだけで違ってくるかなと。
偉そうなこと言って、自分が出来ているか不安ですが・・・
意識はします。意識はね。

# これから
チームに後輩も出来たので、あまり恥ずかしいところは見せたく無いです。
自分の失敗も生かし、注意するところは注意して、ちゃんと成長させられるようなリーダーになります。
自分のことだけをやる生活はもう終わりです。
ただ、やりすぎると自分の価値観の押し付けになりますので、そうはならないように。
チーム内の関係性も結局は人と人です。

# 最後に
マインドとかモチベとか、人によって全然違います。
私の言うことに共感する人もいれば、そうでない人もいると思います。
少しでも参考になる部分があれば嬉しいなと思います。

開発者である以前に皆人間です。
顧客の求めているもの。連携先の部署の求めているもの。
人の気持ちを考えて本質を見抜いて設計していきたいです。
ムダなことはしたくないので・・・
BitVisorのVLANタグの取り扱い

BitVisorのVLANタグの取り扱いについてです。

# BitVisorのVLANタグ対応部分

BitVisorのほとんどの部分はVLANタグなど気にしておらず、単なるパススルーがほとんどです。例えばTCP/IPスタックでVLANタグを使うとか、そんなことは、あ、それは設定だけでできるかも? VPNは無理だと思います。

# Broadcom GbEドライバー

少し前まで、VLANタグ付きパケットを受信すると黙って即捨てるという素敵な実装になっていましたが、10月頃に受信できるよう実装が入りました。

対応方法ですが、送信に関しては、そもそも特に何もしなくてもできていました。VLANタグに関するハードウェアの機能は使用していません。受信に関しては、ハードウェアが自動的に分離してくれているのを、ソフトウェアで挿入し直します。さすがにフレーム全体のメモリーコピーはあんまりなので、受信バッファーを4バイト後ろにずらしておき、タグを挿入する時には先頭の12バイトを4バイト手前にコピーする方法をとっています。受信に関してはハードウェアの機能を使用しない選択肢がありません。

本当は、タグを分離したままVMM内を引き回せるようにできているといいのですが、その前に非連続メモリーのバッファーやチェックサムなどのオフロードに対応したほうが良さそうです。

# Intel GbEドライバー

Virtio-netエミュレーション使用時には、何もしなくても送受信できているようです。VLANタグに関するハードウェアの機能は使用していません。

Para-passthroughモードでは未確認です。

# Virtio-netデバイスのエミュレーション

Virtioの仕様を見るとVLANフィルター機能に対応できるようになっていますが、BitVisorではその機能は提供していません。

# オペレーティングシステムからパススルーでの使い方

Linuxでは非常に簡単です。GNU/Linuxでは、iproute2に含まれるipというコマンドを用いて、VLANの設定ができます。Virtio-netエミュレーションでは、Broadcom・Intel GbEのどちらでも問題なく通信できました。

Windowsではオペレーティングシステム標準の機能はなさそうです。ネットワークインターフェイスのデバイスドライバーが対応していれば設定できる、みたいな感じのようです。残念ながらvirtio-netのドライバーだとうまくいかない様子でした。

macOSではオペレーティングシステム標準の機能がありますが、デバイスドライバーの何らかの機能をあてにしているのか、virtio-net-osxドライバーだと使えないようでした。
NonEmpty


# はじめに

遅くれてしまいましたが、今回は小ネタです。 `purescript-nonempty` ライブラリを共有したいと思います。

前回は [Parital制約](https://qiita.com/asua/items/fb20e45cf68eed9880c1) について書きました。Partial制約はあくまで注意を促すだけであり、ユーザが気を付けて使う必要があります。Parital関数を使うのは邪道でありよほどのことがない限りTotal関数を定義すべきです。前回の例では配列の先頭要素を取り出す `head` 関数を例に挙げました。この関数をTotal関数とする一つの方法には結果の型を Maybe で包むというのがありました。もう一つの取り上げなかった方法として引数の型を適切な型に変えるというものがあります。単なる「要素aの配列」ではなく、「空ではない要素aの配列」という型があれば、head 関数はMaybeで包まなくても必ず値を返すことができます。head に限らず、正確なモデリングを行なうには「空ではない要素aの配列」という型が欲しくなるケース多いと思います。

この「空ではない要素aの配列」を自前で定義してもいいのですが、既に`purescript-nonempty` ライブラリがこの型を表現する方法を提供しています。実際には配列に限らず、より汎用的に「空ではない要素aのコンテナ型」が表現できるようになっています。


<a id="org740b14b"></a>

# NonEmpty

`purescript-nonempty` ライブラリの [Data.NonEmpty](https://pursuit.purescript.org/packages/purescript-nonempty/4.0.0/docs/Data.NonEmpty) に以下の NonEmpty 型が定義されています。`f`がベースとなるコンテナ型、`a`が要素の型です。

```hs
data NonEmpty f a = NonEmpty a (f a)
```

例えば空でないInt配列の型は `NonEmpty Array Int` になります。NonEmpty コンスラクタのシノニムとして `(:|)` 演算子が定義されています。

```hs
foo :: NonEmpty Array Int
foo = 4 :| []               -- [4]

bar :: NonEmpty Array Int
bar = 1 :| [2,3]            -- [1,2,3]
```

NonEmpty f a に対して通常コンテナ型に求められる `Functor`, `Foldable`,`Traversable` 型クラスのインスタンスが定義されています。そのため他のコンテナ型と扱い方は基本的に同じになります。

「空ではない」という性質から独自の関数を提供しています。Maybe で包まなくても `head`, `tail` 関数はTotal関数です。

```hs
head :: forall f a. NonEmpty f a -> a
tail :: forall f a. NonEmpty f a -> f a
```

また必ず空でないことが保証されているので `foldl` 関数の初期値指定なしバージョンの `foldl1` 関数が使えます。

```hs
foldl1 :: forall f a. Foldable f => (a -> a -> a) -> NonEmpty f a -> a
```

便利ですね!


# まとめ

短くなりましたが、 `purescript-nonempty` ライブラリの共有でした。
横着して、空でないことが分かっているところでも通常のコンテナ型とか使っていましたが、NonEmpty を使えば簡単により正確な型が得られるのでこの先必要あれば使っていきたいと思っています。
Hiveでテーブルのパーティショニングや重複削除をするクエリをカラム名非依存に書く

# はじめに

この記事は[MicroAd Advent Calendar 2017](https://qiita.com/advent-calendar/2017/microad)の13日目の記事です。

Hive(hadoop)は大量データを効率的に捌くため、データの非正規化上等な世界です。
必然的に扱うデータのカラム数は肥大化する傾向があり、如何にして必要の無いカラムの名前を意識しないでデータを操作するか、というクエリが必要になってきます。

この記事ではETLの初期の段階で必要となってくる

- パーティショニング
- 重複削除

において、具体的なカラムを意識しないで操作する方法について紹介します。

結論だけ先に書いておくと、正規表現マッチングによるカラムの指定とrow_nuber関数使いましょうという話です。

# Hiveによるデータ変換の必要性と問題

生のログをHadoopに効率的に使うためにはETLの初期の段階で以下のような変換が必要になります。

- HDFS向けのデータへの変換
  - 列指向フォーマット(ORC|Parquent)への変換
  - 圧縮
  - 細分化されたファイルの結合
- パーティショニング
- 重複削除

これらの変換はデータ全体に対して行うため、基本的には`SELECT *`でガツッと書けそうですが`パーティションニング`と`重複削除`においては以下のような問題があり、具体的なカラム名について記述の必要が出てきます。

## パーティショニング

HDFSに突っ込むデータは大概は`date`とか`hour`とか時系列にパーティショニングする事が多いかと思います。
fluentdやflumeならtimestampに応じてHDFSの格納先を変更できるので、データを突っ込む際に時系列でのパーティショニングが可能です。
が、場合によってはあるキーをベースに追加でパーティションの階層を増やしたくるケースがあります。
ここで`dynamic partition insert`を使ってパーティションを増やしたテーブルにデータを突っ込み直そうとすると、ある問題に直面します。
それは`dynamic partition insert`でパーティションとして指定したいカラムはSELECTの末尾に順番を合わせて書くという制約があることです。
このままではSELECT句で末尾の順番を気にしながら全てのカラムを羅列しなければならなくなります。

## 重複削除を行う

もう一方の問題は重複削除のクエリをどう書くか？という点です。
データ収集のパイプラインを`Exactly once`に構築するのはかなり難しく、大概はデータパイプラインは`At least once`を保証して、データの終点（Hadoopなど）で`id`などのユニークなカラムを使って重複削除を行います。
重複削除のクエリで最もポピュラーな方法は`id`で`GROUP BY`してその他カラムは`MAX`で集約して`SELET`するというものがありますが、やはりカラム数が多いとクエリを書くのが辛くなります。

# 解決法

## Hiveカラムの正規表現マッチングを使用してパーティションキーのみ順番を指定する

HiveではSELECTするカラムを正規表現によりマッチングさせる便利機能があります。
この機能を使って、パーティションに使うカラムのみを除く正規表現を書くことで、パーティションキーの順番のみを意識したクエリがかけます。

具体的には以下のようなクエリです。以下の例では`date`,`hour`,`country`をパーティションキーとして使おうとしています。

```sql
SELECT `(date|hour|country)?+.+`, country, date, hour FROM json_log;
```

このクエリでは`` `(date|hour|country)?+.+` ``の正規表現マッチングの箇所で`country`、`date`、`hour`以外のカラムがマッチさせ、除外されたパーティションキーとして使うカラムは別途、明示的に順番を指定しています。

ちなみにこのカラム名の正規表現マッチングの機能を使おうとすると、`hive.support.quoted.identifiers`を`none`にする必要があります。

## idの重複削除にはrow_numbe関数を使う

HiveではWindow関数が使えるので、row_number関数が使えます。
以下のようなクエリでidカラムの重複に対して連番が振れるので、その１番目だけを使い重複を削除できます。

```sql
WITH with_order_num AS (
    SELECT 
        *, row_number()
            over(
                partition by id
            ) AS order_num
    FROM 
        json_log
)
SELECT
    *
FROM
    with_order_num
WHERE
    order_num = 1
;
```

# まとめ

上記のテクニックをまとめると以下のようなクエリになります。

```sql
WITH with_order_num AS (
    SELECT 
        *, row_number()
            over(
                partition by id
            ) AS order_num
    FROM 
        json_log
    WHERE
         WHERE date = '20171213'
         AND hour = '15'
)
FROM with_order_num
INSERT OVERWRITE TABLE orc_log partition(country, dt, hour)
SELECT 
    `(date|hour|country)?+.+`, 
    country, 
    date, 
    hour 
WHERE 
    order_num = 1
;
```

このように必要なカラム名以外を意識することなく、変換処理が書けました。
また、カラム名に非依存な変換クエリにしておくと、データ構造の変更にも強いですし、扱うログのカラム名の規則がちゃんと揃っていればほぼコピペのクエリで済みます。
（実際にはクエリをジョブで投げる際はtemplate化して都度レンダリングするケースが殆どだと思いますのでtemplateが使いまわせます。）

# 参考

- https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Select#LanguageManualSelect-REGEXColumnSpecification
- [ビッグデータ分析・活用のためのSQLレシピ](https://book.mynavi.jp/supportsite/detail/9784839961268.html)
Hyper-v で 仮想マシンの解像度の変更方法

## Fedora 26/27 （・RedHat系？）

下記をインストール＆再インストール。
（`grub2-efi-modules` 以外は始めからインストールされていた。）

```
sudo dnf install grub2-efi grub2-efi-modules shim
sudo dnf reinstall grub2-efi grub2-efi-modules shim
```

```
sudo vi /etc/default/grub
```

`GRUB_CMDLINE_LINUX` の行を探し末尾に `video=hyperv_fb:[変更したい解像度]` を追加する。
例えば 1920x1080 なら

```
GRUB_CMDLINE_LINUX="… quiet splash video=hyperv_fb:1920×1080"
```

その後

```
grub2-mkconfig -o /boot/efi/EFI/fedora/grub.cfg
grub2-mkconfig -o /boot/grub2/grub.cfg
```

（最近の Fedora だと上で、古いのだと下？Cent OS やRHEL だとどっちなのか未検証。
両方やっても問題無いはず。）

再起動

## debian/Ubuntu

Ubuntu 1710 と Kali Linux で確認

```
sudo vi /etc/default/grub
```

`GRUB_CMDLINE_LINUX_DEFAULT` の行を探して末尾に `video=hyperv_fb:[変更したい解像度]` を追記

```
sudo update-grub
```

再起動

## Windows 10

デスクトップを右クリックして[ディスプレイ設定]をクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/100313/849ce5fa-afb4-78d2-8353-96d4848a99d3.png)
[ディスプレイ]メニューの下の方にある[アダプターのプロパティを表示]をクリック
[モードの一覧(L)]をクリックして
![image.png](https://qiita-image-store.s3.amazonaws.com/0/100313/dc9d6050-c1a8-c7bd-719f-8b0c381b67bf.png)
指定したい解像度を選び適用。

## 参考

[Windows 8, Fedora 19 OS Hyper-V Virtual Machine](https://stackoverflow.com/questions/18172319/windows-8-fedora-19-os-hyper-v-virtual-machine)
[fedora WIKI - GRUB 2](https://fedoraproject.org/wiki/GRUB_2)
[Changing Ubuntu Screen Resolution in a Hyper-V VM](https://blogs.msdn.microsoft.com/virtual_pc_guy/2014/09/19/changing-ubuntu-screen-resolution-in-a-hyper-v-vm/)
[Configuring wide screen resolutions in a Hyper-V virtual machine](https://blogs.msdn.microsoft.com/virtual_pc_guy/2013/07/09/configuring-wide-screen-resolutions-in-a-hyper-v-virtual-machine/)
Milight/LimitlessLEDを有線LAN経由で操作する 1

# Milight/LimitlessLEDとは
専用のリモコンやスマートフォンで操作できる新しい電球。

- [公式](http://www.limitlessled.com/)
- [Gigazine](https://gigazine.net/news/20140322-limitlessled-color-wifi-bulbs/)

類似品で有名どころにPhilipsのhueがあるがあいつよりもずっと安い。

ここではMilight/LimitlessLEDそのものの話はしないのでこれについて知りたい場合は他の方の記事を探していただきたい。

# スマートフォン・PCからの操作
実際のところ[Wi-Fi Bridge](http://www.limitlessled.com/shop/wifi-bridge-v6/)なるものが必要であり、電球とLANが直接つながるわけではない。

LAN -- 2.4GHz(Wi-Fi) -- Wi-Fi Bridge -- 2.4GHz(プロトコル等不明) -- LED電球

といった形で接続される。

私はあるイベントに出展する展示物このLED電球を使用する予定なのだが会場は電波が飛び交い不安定になる恐れがあるので少しでも安定性を向上させたい。

そこで今回はこの2.4GHz(Wi-Fi)の部分を有線化し2.4GHzの電波を無駄に飛ばさないようにする改造を行う。

# 有線化
## とりあえず殻割
Bridgeを開けると中は結構スカスカになっている。

![01a6a5d8a78d161fa14a5d83f6a73cae84f6561632.jpg](https://qiita-image-store.s3.amazonaws.com/0/151628/7f523199-75f4-0b44-bdf4-56e1ce3715d3.jpeg)

大きい緑色の基板がLED電球に送信するボードで小さい黒い基板がWi-Fiモジュールになっている。

このWi-Fiモジュールが行っているであろう処理を有線LANに接続したRaspberryPiで置き換えていこうと思う。

次につづく
GCP で Gitlab Enterprise を動かす


今日、[Gitlab Enterprise Meetup](https://connpass.com/event/72558/)に行ってきました。ということでちょっと入れてみようと思ったのですがGCP見てたら普通にLauncherに登録されていたのでどんなものか起動してみました。

ちなみに、Gitlabですが IBM Cloudにアカウントがあると無料で使うことが出来ます。ただ少しVersionが古いので新しいものが使いたい人は自分で入れるのが良いでしょう。( https://git.ng.bluemix.net )

# 導入

まずは、LancherからGitlabを探してください

![Kobito.mkaO1X.png](https://qiita-image-store.s3.amazonaws.com/0/11540/d1698646-5e05-e179-da48-018ec7ab44f6.png "Kobito.mkaO1X.png")

* https://console.cloud.google.com/launcher/details/gitlab-public/gitlab-enterprise-edition?project=focused-code-188506&hl=ja
* `COMPUTE ENGINE上で起動` をクリックします。


![Kobito.HrGwvg.png](https://qiita-image-store.s3.amazonaws.com/0/11540/99a2128b-9370-9bd4-c43a-23c08cd6de69.png "Kobito.HrGwvg.png")

* 特に変更するオプションはないので「Development name」と Zoneを変更しておきます。
* 画面の一番下の`Deploy` をクリックします。

![Kobito.Cc73DM.png](https://qiita-image-store.s3.amazonaws.com/0/11540/035f333f-5759-d3e9-4570-e5680c50721a.png "Kobito.Cc73DM.png")

* しばらく待ちましょう。VMはGCPの場合にはあっという間に起動してきます
* 大体4,5分待てば `Visit the Site` をクリックすれば繋がります。
* 画面上にログインに必要な情報が出ています。

![Kobito.zuJMe8.png](https://qiita-image-store.s3.amazonaws.com/0/11540/e0dc7966-4871-323d-cfb3-5d0c9e28a7ba.png "Kobito.zuJMe8.png")



# 設定

## パスワードの変更

![Kobito.vynrUn.png](https://qiita-image-store.s3.amazonaws.com/0/11540/8206378f-d0ba-ce95-b653-41cd3e5b516d.png "Kobito.vynrUn.png")

* メニューの `admin area`のアイコンをクリックします

![Kobito.kohOtn.png](https://qiita-image-store.s3.amazonaws.com/0/11540/cc112443-ca8e-d7a6-4ace-936ccde2ded6.png "Kobito.kohOtn.png")

* `Overview` → `Users` を選択します

![Kobito.t4MW5K.png](https://qiita-image-store.s3.amazonaws.com/0/11540/25ad8c57-2fb2-d08c-8b5c-8741f02231fc.png "Kobito.t4MW5K.png")

* `Administrator` を選択肢右上の `edit`をクリックします

![Kobito.wwd5bz.png](https://qiita-image-store.s3.amazonaws.com/0/11540/2af0e06e-8594-4ce4-fa7d-a1d2b05e8d5e.png "Kobito.wwd5bz.png")


## メールの設定

* https://docs.gitlab.com/omnibus/settings/smtp.html#smtp-settings

こちらの内容に沿って実施すれば可能です。 `/etc/gitlab/gitlab.rb` のメールの設定を変更します。設定を変更したら `gitlab-ctl reconfigure` を実施します。

```
sudo gitlab-ctl reconfigure
```

* gmailを利用する場合には、セキュリティの設定が必要になります。![Kobito.Nrr43a.png](https://qiita-image-store.s3.amazonaws.com/0/11540/a80ac6b0-f3e2-bf50-3118-82d52823b4a1.png "Kobito.Nrr43a.png")

 

## 固定IPアドレスへの変更

VPCネットワーク→外部IPアドレスから、現在利用しているエフェメラルIPアドレスを静的IPアドレスに変更します。

![Kobito.9RgcGw.png](https://qiita-image-store.s3.amazonaws.com/0/11540/d6900c0a-f248-96b5-a951-d0634648c627.png "Kobito.9RgcGw.png")



## その他
* 実際に利用するには、ドメイン名も登録したいところですね。

## ライセンス
* ライセンスはBYOLとなっていましたので別途調達する必要があります。国内だと、クリエイションラインさん、ソフトバンク コマース&サービスさん辺りから購入できるみたいですね。
	* https://cas.softbank.jp/news/information/2017/devopswebdevops_hub.html


# 使ってみる

## アカウントの作成

![Kobito.bOjVwH.png](https://qiita-image-store.s3.amazonaws.com/0/11540/ce2610df-c74b-e516-ef0d-bd80d2939119.png "Kobito.bOjVwH.png")

* 普通にアカウントを作ることが出来ます
* 企業で使うにはLDAPなどを連携させて利用することになりそうなのでそのへんはまた今度調べてみます。



# まとめ

* https://docs.gitlab.com/ee/install/google_cloud_platform/index.html
* 今回は起動するところまでライセンス入れないと30日間なのかな？
ブラウザに立方体を表示させる。

## ご挨拶
どうも。社会人１年目の若輩者です。普段はC++でアプリ開発をしているガルパンおじさんです。最終章第一話を聖地立川で観てきましたが、控えめに言って最高でした。ちなみに冷泉さん推しです。

まあ前置きはこのくらいにして本題ですが、この記事では私が最近遊んでいるWebGLについて書きたいと思います。といってもWebGLを直接いじるのは大変なので、簡単に利用できるThree.jsというJavaScriptのフレームワークを使用してブラウザ上に立方体を表示させるところまで、やろうと思います。筆者はhtml,javascript 初心者なので、いろいろとご容赦ください。

### 成果物
こんなの
https://tarakokutibiru.github.io/AdventCalendar2017_TUS/

### Three.jsの入手
公式サイト(https://threejs.org) からdlしようとすると,とても重いのでGitHub(https://github.com/mrdoob/three.js/tree/master) からzipでdlするのがおすすめです。

### 実装

適当な場所に解凍したあと、htmlファイルを作りましょう。

シーンとカメラを作る。環境光とオブジェクトをつくってシーンに追加。最後に、レンダラーを作ってシーンを描画するっていう流れですね。適当なブラウザで作成したindex.htmlを開いてみてピンク色の立方体が表示されれば成功です。

```index.html
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>Cube</title>
</head>

<body>

  <script src="three.js/build/three.js"></script>
    <script>
        var main = function() {

            // シーンの作成
            var scene = new THREE.Scene();

            // カメラの作成
            var width = 600;
            var height = 600;
            var fov = 60;
            var aspect = width / height;
            var near = 1;
            var far = 1000;
            var camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
            camera.position.set(0, 0, 50);

            // レンダラー
            var renderer = new THREE.WebGLRenderer();
            renderer.setSize(width, height);
            document.body.appendChild(renderer.domElement);

            // ライトの作成
            var lightColor = new THREE.Color( 1, 1, 1 );
            var light = new THREE.DirectionalLight (lightColor); // 並行光
            light.position.set(0, 0.7, 0.7);
            scene.add(light);

            // 図形の作成
            var geometry = new THREE.CubeGeometry(20, 20, 20); // 四角形
            var cubeColor = new THREE.Color( 1, 0.5, 1 );
            var material = new THREE.MeshPhongMaterial({color: cubeColor}); // マテリアル
            var mesh = new THREE.Mesh(geometry, material);
            mesh.rotation.set(45,45,45);
            scene.add(mesh);

            // 描画
            renderer.render(scene, camera);
        };

        window.addEventListener('DOMContentLoaded', main, false);
    </script>

</body>

```

### 公開する

手軽に公開する方法はいくつかありますが、私はこちらを参考にGitHub上に公開してみました。
https://qiita.com/tonkotsuboy_com/items/f98667b89228b98bc096

### 最後に

本当は、「通常録音した音源をバイノーラル的に再生してみる」みたいなテーマを書こうと思ってたんですが、間に合わなかったので、Three.jsについての簡単な記事でお茶をにごしました。音をどういじると、どう聞こえるのか？みたいな実験記事を書こうと思ってたんですが、いろいろと下調べしてたら時間がなくなっちゃった感じです。これについてはまた何かの機会に記事にしたいと思います。では。ノシ
glslで疑似ディスプレイメントマップをプロシージャルにやってみる その3 パーティクル編

# はじめに
まずは、ディスプレイスメントマップにするパーティクルを作ります。

![particledis.png](https://qiita-image-store.s3.amazonaws.com/0/135381/1bc62314-29c4-54fe-9877-edfca68d3b28.png)
https://goo.gl/trmpQc

```glsl
precision mediump float;
uniform vec2  m;       // mouse
uniform float t;       // time
uniform vec2  r;       // resolution
uniform sampler2D smp; // prev scene

highp float rand(vec2 co){
   highp float a = 12.9898;
   highp float b = 78.233;
   highp float c = 43758.5453;
   highp float dt= dot(co.xy ,vec2(a,b));
   highp float sn= mod(dt,3.14);
   return fract(sin(sn) * c);
}

void main(void){
    vec2 p = (gl_FragCoord.xy * 2.0 - r) / min(r.x, r.y);
    float d;
    for(int i=0;i<20;i++){
    	vec2 q=p;
    	float pos = mod(t+float(i)*.3+rand(vec2(float(i),float(i))),2.0);
    	q.y+=1.;
    	q.y-=pos;
    	q.x+=sin(pos*5.+float(i))*.4;
    	d+=clamp(.2-length(q),0.,1.);
    }
    gl_FragColor = vec4(vec3(d), 1.0);
 }
```

# パーティクルでディスプレイスメントマップをしてみましょう

![particledisplacement.png](https://qiita-image-store.s3.amazonaws.com/0/135381/f1c386bc-7c2f-b540-6c96-e309d1928604.png)

https://goo.gl/XtCfiw

```glsl
precision mediump float;
uniform vec2  m;       // mouse
uniform float t;       // time
uniform vec2  r;       // resolution
uniform sampler2D smp; // prev scene

highp float rand(vec2 co){
   highp float a = 12.9898;
   highp float b = 78.233;
   highp float c = 43758.5453;
   highp float dt= dot(co.xy ,vec2(a,b));
   highp float sn= mod(dt,3.14);
   return fract(sin(sn) * c);
}

void main(void){
    vec2 p = (gl_FragCoord.xy * 2.0 - r) / min(r.x, r.y);
    float d;
    for(int i=0;i<20;i++){
    	vec2 q=p;
    	float pos = mod(t+float(i)*.3+rand(vec2(float(i),float(i))),2.0);
    	q.y+=1.;
    	q.y-=pos;
    	q.x+=sin(pos*5.+float(i))*.4;
    	d+=clamp(.2-length(q),0.,1.);
    }
    //gl_FragColor = vec4(vec3(d), 1.0);
    //return;
    p+=d*.1;
    p*=8.;
    float l = mod(floor(p.x)+floor(p.y),2.0);
    gl_FragColor = vec4(vec3(l), 1.0);
}
```
GPD PocketのためにDvorak配列を考え直す

[GPD Pocket Advent Calender 2017](https://adventar.org/calendars/2085) 16日目の記事となります。

## はてさて
[前回の記事](https://qiita.com/yamamo2/items/e6ce32fb92ef7a6a66a1)を書いたことで、久し振りにキー配列のことをじっくり考えました。振り返ってみると、Dvorak配列を使い始めてから何やかんやで約16年くらい経っていることに気がつき、Dvorakよりも優れた配列が提案されてないかなー？と調べてみることにしました。

## Qiitaにあった
どんなことにも先人はいるものでQiitaにとても[参考になる記事](https://qiita.com/ZeptByteS/items/6e6a3e46552dcb105948)を見つけました。[Keyboard Layout Analyzer](http://patorjk.com/keyboard-layout-analyzer/)というキー配列を解析するサイトを使い、Qwerty、Dvorakを含む12種類のキー配列の結果を比較しています。最近、ちょくちょく見かけるようになった[ErgoDox](https://www.ergodox.io)という左右分離タイプのキーボードにおける配列の考察ですが、非常に参考になります。

## BEAKLとやら
Colemakなど、Qwertyからの移行コストがDvorakに比べ低い配列は知っていましたが、今さらQwertyベースの配列に移行するのはDvorakが染みこんだ自分にとっては逆に移行コストが高くなってしまうし、面白くありません。Capewell-Dvorakは日本語のローマ字入力ではオリジナルのDvorakよりも劣ると感じました。そんな中で目にとまったのが、[BEAKL](https://deskthority.net/wiki/BEAKL)というキー配列です。基本的には格子状のキーボード向けに考えられた配列っぽいですが中々そそられます。

## とはいえ
BEAKLにそそられたとは言え、普段仕事でプログラム書いたりしていて、IDEや、Emacs、zshのキーバインドなどデフォルトからカスタムしているため、移行コストに怯んでしまいました。そこで、BEAKLを参考にしつつ、現状の問題点を改善する配列をDvorakベースで考えてみることにしました。  

## 左手
BEAKLで良いなと思ったのが、小指の使用率が低いこと。というか、Dvorakは打鍵が左右交互でリズミカルなのが利点ですが、小指の使用頻度が高いため、GPD Pocketの小さいキーボードでは小指の動きが窮屈になっているようで、一般的なサイズのキーボード以上に小指が疲れやすく感じます。そこでまず、CTRLで酷使する左手小指の使用頻度を下げるべく、BEAKLの母音の並びを取り入れ、次の画像のようにしてみました。

![GPD_Pocket_Mod_Dvorak.png](https://qiita-image-store.s3.amazonaws.com/0/213301/e36f8f79-97f0-6b67-22fd-5885116faa8c.png)

「W」と「Z」の間はタッチタイプ不可と判断し、下記のようにして押しても何も入力されないようにしました。

```
;; nothing <- .>
00,00,34,00,\
```

## 右手（12月14日追記）
まずは中段ホームポジションにメスを入れ、小指で打鍵していた「S」を人差し指に変更し、周辺のキー位置を調整して次のようにしました。右手下段の「V」と「Z」も入れ替えています。

![GPD_Pocket_Mod2_Dvorak.png](https://qiita-image-store.s3.amazonaws.com/0/213301/bf9dd1d1-3a5f-95a5-c35b-41a9c5bc2984.png)

## 右手の変更（12月17日追記）

数日試してみて、英文だと「th」、「wh」が打ちにくく、日本語だと、「～が」と言う助詞、が行のタイピングが多く「g」が小指だと、小指の使用頻度が多かったため、次のように「h」を薬指下段にし、「z」を中段小指にしました。

![GPD_Pocket_Pinkyless_Dvorak.png](https://qiita-image-store.s3.amazonaws.com/0/213301/2656775c-6a80-b94c-fd29-1aae893ca987.png)

## とは言え押しにくい左Ctrl（12月20日追記）
やはり左Ctrlキーが小さく、ここ以外のアルファベットキーでの小指使用率を下げたものの、Ctrlを押すだけでも小指の負担は大きいです。そこで、SandS（Space and Shift）の仕組みをこの配列で導入してみようと思います。今回の場合はSpaceとShiftではなく、EnterとCtrlになります。Enterを単独で押したときはEnterとして、Enterを押し続けて他のキーと組み合わせた時は右Ctrlキーとして働くようにします。  
この機能を実現するために、まず、Enterを割り当てたSpaceキーに右Ctrlキーを割り当てます。ここからはレジストリをいじるだけでは実現できないので、[AutoHotKey](https://autohotkey.com)を利用します。こちらもQiitaに[こんな記事](https://qiita.com/euxn23/items/90d37d3c14bde32c66c1)がありました。こちらを参考にして、作った.ahkファイルは[こちら](https://github.com/tkrworks/ExtendedDvorakLayout/blob/master/EandC.ahk)です。

## まとめ
Dvorakからの移行コストを抑えつつ、小指の使用頻度を抑えた配列なので「_**Pinky-less Dvorak**_」とでも言えましょうか。しばらくはこの配列で元のDvorak並にタッチタイプ出来るようになるか試してみたいと思います。

自己責任になりますが、この配列のための.regファイルも[github](https://github.com/tkrworks/ExtendedDvorakLayout/tree/master/GPD%20Pocket)で公開しています。
ansible vmware_guest_find モジュールを用いたVM存在確認と後続タスクの制御

# これは何
ansibleによるVMwareのVMインスタンス管理の話。
VMインスタンスをコマンド一つで作成して初期設定ができるようにAnsibleで管理している。すでに存在するVMについては、うっかりRebootしたりNW Restartなどが走らないように存在チェックをしてそれらのタスクをスキップしたい。

# vmware_guest シリーズの module について

* vmware_guest module 
    * VMを作るためのモジュール。ansible version 2.2 より使用可能。
* vmware_guest_find module 
    * VMが存在するディレクトリを教えてくれる。ansible version 2.4 より使用可能（なので、最初v2.3を使っていて数分ハマった）。
    * 今回の話題。
* vmware_guest_facts module
    * VMの設定値を取得できる
    * これはVMのリソース設定が正しく設定できているかの確認に使える（assetsモジュールと組み合わせる）。

# コードとハマリどころ

### コード　

```
# vmware_guest_findはすでにVMがいれば戻り値としてvm_folder.foldersにVMがいるディレクトリが入る（ここで、vm_folderはregisterで定義した変数）。居ない場合もしくは認証がうまく行かなかったなどの場合にはエラーになり、vm_folder.msgにその原因が書かれる。
# 後続のタスクは、VMがまだ居ない場合にのみ実行したい。
- name: check vm exists on vsphere
  vmware_guest_find:
    hostname: VMホスト名
    username: ユーザ名
    password: パスワード
    name: VMインスタンス名
    datacenter: データセンタ
  register: vm_folder
  ignore_errors: yes  # とりあえず ignore_errorsにしたけどfailed_whenで制御した方が綺麗だったかも。そのうちなおすかも。

- name: create and setting vm
  block:
    - name: create vm  # ここら辺の中身は今回は略
      include: create_vm.yml
      tags: create_vm
    - name: setting vm
      include: setting_vm.yml
      tags: setting_vm
  when: (not ("folders" in vm_folder)) and (vm_folder.msg | regex_search("Unable to find folders for VM"))
```

### 解説 
vmware_guest_find module の戻り値。
Debugで見てみる。

```
- name: debug
  debug:
    msg: "{{ vm_folder }}"
```

VMがいるとき

```
    "msg": {
        "changed": false,
        "failed": false,
        "folders": [   # これが帰ってくるのが特徴的
            "/vm/hoge/development"
        ]
    }
}
```

VMがいないとき

```
TASK [../ex_roles/vsphere_vmmaker : debug] ******************************************************
ok: [test-vmmaker] => {
    "msg": {
        "changed": false,
        "failed": true,
        "msg": "Unable to find folders for VM test-vmmaker"
    }  # msgが帰ってくる。他の原因でmodule実行が落ちると他のｍｓｇが帰ってくるのでそれを利用する。
}
```


* find と言う名前がついているので戻り値にBooleanが帰ってくるかと思ったらVM Folderが帰ってくるのだった
* ない時にはFalseが帰ってくるかと思ったらErrorになってしまうのだった
* 単に「find module実行が落ちたらVM設定する」にしてしまうと、なんらかの拍子にmoduleが落ちると意図せずcreate vm, setting vmが走ってしまって嫌だったので、それを念入りに回避するためにmsgを見ている
    * もっと綺麗にかければよかったけど安全策をとった形
    * find moduleはまだ安定していないので後方互換を取らないかもしれない、と言う注意文言があったのでmsgは変わるかもしれない（This module is flagged as preview which means that it is not guaranteed to have a backwards compatible interface. と書かれていた）
    * msgがマッチしている時にだけ設定が走るので、msg文言が変わっても実行しないという安全側に倒れるので良い

### コメント

* ちょっと美しくないが、とりあえず動くVM作成と、事故らない動きを実現した話。
* 社内ユーザの要望の声が大きければ enable_modify などのフラグを指定した時にはVMリソース設定や細かい設定を変えさせるのはやっても良いかもしれない。
WindowsでもDotty

この記事は[Scala Advent Calendar 2017](https://qiita.com/advent-calendar/2017/scala)の15日目の記事になります。

#概要

Scala次期バージョンとして順調にリリースが続いている[Dotty](http://dotty.epfl.ch/)。
今のうちに少し触ってみようと思い立ったものの、Windowsに対する公式サイトのサポートはあまり親切ではありません…。パッケージマネージャはhomebrewしか対応しておらず、zipをダウンロードしてみれば各種コマンドはbashで提供されているのみ。

というわけで、Windowsでお手軽にDottyを試してみるための方法をまとめました。

#前提

SBTがインストール済みでパスが通っているものとします。
Scalaを使用していれば自ずと満たしている条件かと思います。
SBTのバージョンは0.13系を使用しましたが、1.0系でも問題ないと思われます。

#Hello world
コマンドプロンプトで下記を実行します。

```cmd.exe
sbt new lampepfl/dotty.g8
```

プロジェクト名を聞かれるので入力すると、現在のフォルダ配下にプロジェクトが作成されます。
プロジェクトのフォルダに移動し、下記を実行。

```cmd.exe
sbt run
```

テンプレートプロジェクトの実行結果が表示されたと思います。めでたしめでたし。
sbtがDotty環境をお膳立てしてくれるので、別途インストールしたりする必要はないのでした。

#IDE

実行環境は整ったものの、静的型付け言語はIDEを使ってナンボ。
公式に推奨されているVisual Studio Codeに加え、IntelliJ IDEAでの対応方法を確認してみます。

##Visual Studio Code

Visual Studio Codeを[ダウンロード](https://code.visualstudio.com/)してインストール。
インストール時の設定は特に弄らなくても良さそうです。

インストール後、コマンドプロンプトで先ほど作成したプロジェクトのフォルダに移動し、下記コマンドを実行します。

```cmd.exe
sbt launchIDE
```

Visual Studio Codeで該当プロジェクトを開きつつ、Visual Studio Codeで必要なプラグインのインストールまでやってくれます。

##IntelliJ IDEA

WindowsでScalaを触っていればおそらくお世話になっているであろうIntelliJ IDEA。
調べてみると、LSP SupportというLanguage Server Protocol用のプラグインが存在しました。早速インストールして設定を行います。

設定はメニューのFile -> Settings -> Languages&Frameworks -> Language Server Protocolにあります。
Server Definitionsに下記を設定すればOKです。

<dl>
  <dt>Extension</dt>
  <dd>scala</dd>
  <dt>Artifact</dt>
  <dd>ch.epfl.lamp:dotty-language-server_0.5:0.5.0-RC1</dd>
  <dt>Main class</dt>
  <dd>dotty.tools.languageserver.Main</dd>
  <dt>Args</dt>
  <dd>-stdio</dd>
</dl>

上記設定に加え、scalaプラグインと処理が競合するのでscalaプラグインを無効にしておく必要があります。
IDEAの再起動後に設定が有効になります。
再起動後、ステータスバー右端に緑の丸が表示されていればOKです。
先のプロジェクトを開き、Main.classを表示すると、宣言へのジャンプやオートコンプリートが動作していることが確認できます。
ただし、自分の環境では頻繁にタイムアウトが発生しました。
また、コードの色分けができなかったりオートコンプリート等も若干残念な感じだったり、色々なところで難があります。
scalaプラグインと共存できないのが痛いので、しばらくは様子見となりそうです。

#Dottyを試す

テンプレートのMain.scalaだとDottyならではのコードが何一つ存在しないため、下記のように編集してみます。

```scala:Main.scala
object Main {
  case class User(name: String)

  case class Group(name: String, users: Seq[User])

  val users: Seq[User] = Seq(
    User("user1"),
    User("user2"),
    User("user3")
  )

  val groups: Seq[Group] = Seq(
    Group("group1", Seq(users(0))),
    Group("group2", Seq(users(1), users(2)))
  )

  def search(name: String): Option[User | Group] = {
    val user = users.find(_.name == name)
    val group = groups.find(_.name == name)
    user orElse group
  }

  def main(args: Array[String]): Unit = {
    println(search("user2"))
    println(search("group2"))
    println(search("group5"))
  }
}
```

Union typesを試してみました。もうちょっといい例はないものかと思いますが…。
実行結果は以下のようになります。

```:実行結果
Some(User(user2))
Some(Group(group2,List(User(user2), User(user3))))
None
```

#終わりに

言語仕様としては魅力的なDottyですが、Visual Studio Codeを使用してもIDEサポートはまだまだのように感じられました。
IntelliJ IDEAのScalaサポートが手厚いため、相対的にそう感じられるだけかもしれませんが…。
正式版がリリースされる頃にはこのあたりの問題も解決しているといいなあ、と思います。