OmniAICreator/Qiita-1.07M huggingface dataset:
BoNeSi を ubuntu16.04 に install する

- 必要なパッケージのinstall

```
apt-get update
apt-get install build-essential libpcap0.8-dev libnet-dev automake
```

- automake-1.14, aclocal-1.14 が 必要なので linkを貼る

```
cd /usr/bin/
ln -s automake-1.15 automake-1.14
ln -s aclocal-1.15 aclocal-1.14
```

- bonesi を github から持ってくる

```
cd ~/
git clone https://github.com/Markus-Go/bonesi.git
cd ~/bonesi/
```

- install

```
./configure
automake --add-missing
make install
```

- 動作確認1 : helpを表示

```
# bonesi --help
Usage: bonesi [OPTION...] <dst_ip:port>

 Options:

  -i, --ips=FILENAME               filename with ip list
  -p, --protocol=PROTO             udp (default), icmp or tcp
  -r, --send_rate=NUM              packets per second, 0 = infinite (default)
  -s, --payload_size=SIZE          size of the paylod, (default: 32)
  -o, --stats_file=FILENAME        filename for the statistics, (default: 'stats')
  -c, --max_packets=NUM            maximum number of packets (requests at tcp/http), 0 = infinite (default)
      --integer                    IPs are integers in host byte order instead of in dotted notation
  -t, --max_bots=NUM               determine max_bots in the 24bit prefix randomly (1-256)
  -u, --url=URL                    the url (default: '/') (only for tcp/http)
  -l, --url_list=FILENAME          filename with url list (only for tcp/http)
  -b, --useragent_list=FILENAME    filename with useragent list (only for tcp/http)
  -d, --device=DEVICE              network listening device (only for tcp/http)
  -m, --mtu=NUM                    set MTU, (default 1500)
  -f, --frag=NUM                   set fragmentation mode (0=IP, 1=TCP, default: 0)
  -v, --verbose                    print additional debug messages
  -h, --help                       print this message and exit
```
- 動作確認2 :localhost 向けに実行してみる

```
# bonesi -p icmp 127.0.0.1:0
Warning: There is noch File with useragent names! The user-agent:
 Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.8.1.8) Gecko/20071004 Iceweasel/2.0.0.8 (Debian-2.0.0.6+2.0.0.8-Oetch1)
will be used.
dstIp:         127.0.0.1
dstPort:       0
protocol:      1
payloadSize:   32
rate:          infinite
ips:           (null)
urls:          (null)
useragents::   (null)
stats file:    stats
device:        (null)
maxPackets:    infinite
format:        dotted
toggle:        no
471596 packets in 1.000039 seconds
491407 packets in 1.000001 seconds
```
# 注意点
- BoNeSi は DDoS Botnet Simulatorなので、使用には気をつけてください
Pythonファイルをターミナルから実行し、自動化する

##やりたいこと
- PycharmProjects以下のファイルをターミナルから実行
- 6時間毎に自動化

##結論
以下のPythonファイルを実行したい

```ruby:test.py
print "グラッチェ"
```

```ruby:terminal
$ python test.py
```

結果

```ruby:terminal
グラッチェ
```

##自動化

watchコマンドを使用して、秒数を6H = 60 * 60 * 60 * 6 = 1296000sに設定

```ruby:terminal
$ watch -n 1296000 "python test.py"
```
Pixi.js v4で複数画像のロードを待つ

まあ画像以外もいけるんだけど、画像でしか今の所使ったことがない

```
const loader = PIXI.loader;

// key名と対象画像を設定していく
loader
      .add("img1" , "images/img1.jpg")
      .add("img2" , "images/img2.png")
      .add("img3" , "images/img3.gif");

loader.load((loader, resources) => {
    // ここが呼ばれたときはすでにロード完了なので取り出してつかう
    let img1 = new PIXI.extras.TilingSprite(resources.img1.texture);
    let img2 = new PIXI.extras.TilingSprite(resources.img2.texture);
    let img3 = new PIXI.extras.TilingSprite(resources.img3.texture);
});
```

よく使う。

ちなみにTilingSpriteスプライトが移動してて警告くらった

```
// old code
let img1 = new PIXI.TilingSprite(resources.img1.texture);

// new code
let img1 = new PIXI.extras.TilingSprite(resources.img1.texture);
```

公式のリファレンスも治ってないところがあるみたいね。
2018年1月5日現在は。
Angularプロジェクトでのbootstrap導入

## 結論
[ng-bootstrap](https://github.com/ng-bootstrap/ng-bootstrap)を使おう

## 準備
詳しくは[githubリポジトリのReadme](https://github.com/ng-bootstrap/ng-bootstrap)を参照

当然ながら`Angular`と`boootstrap4`に依存してる模様
`ng-bootstrap 1.0.0-beta.8`時点では`Angular 5.0.2`、`bootstrap 4.0.0-beta.2`で動作確認されている模様
(私の環境では`bootstrap 4.0.0-beta.3`で試したら動作しなかった)

```bash:terminal
npm install --save-dev bootstrap@4.0.0-beta.2 jquery@1.9.1 popper.js@^1.12.3
npm install --save-dev @ng-bootstrap/ng-bootstrap@^1.0.0-beta.8
```
ちなみに`jquery`と`popper`は`bootstrap4`の依存モジュールです。

## 導入

### NgModuleでのimport
top-levelの`NgModule`に対して`NgbModule.forRoot()`をimportする。
これをすることにより、`ngb-datepicker`などng-bootstrap特有のdirectivesなどを使用することができる。

```typescript:app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
// NgbModuleのimport
import {NgbModule} from '@ng-bootstrap/ng-bootstrap';


import { AppComponent } from './app.component';


@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    // Rootモジュールに対してNgbModule.forRoot()をimport
    NgbModule.forRoot(),
    BrowserModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
```

### cssでのimport
当然bootstrapの設定も必要
`.angular-cli.json`に記載する方法もあるのだが、おすすめは各コンポーネントorルートの`style.css`にてimportする方法。

```styleｓ.css
/* You can add global styles to this file, and also import other style files */
@import "~bootstrap/dist/css/bootstrap.css";
```

## 使ってみる

[デモサイト](https://ng-bootstrap.github.io/#/components/accordion/examples)から適当にとってきたサンプルを使う。
今回は一番単純な[Accordion](https://ng-bootstrap.github.io/#/components/accordion/examples)を使う。

```app.component.html
<!--The content below is only a placeholder and can be replaced.-->

<ngb-accordion #acc="ngbAccordion" activeIds="ngb-panel-0">
  <ngb-panel title="Simple">
    <ng-template ngbPanelContent>
      ABC
    </ng-template>
  </ngb-panel>
  <ngb-panel>
    <ng-template ngbPanelTitle>
      <span>&#9733; <b>Fancy</b> title &#9733;</span>
    </ng-template>
    <ng-template ngbPanelContent>
      DEF
    </ng-template>
  </ngb-panel>
  <ngb-panel title="Disabled" [disabled]="true">
    <ng-template ngbPanelContent>
      GHI
    </ng-template>
  </ngb-panel>
</ngb-accordion>
```

![result.png](https://qiita-image-store.s3.amazonaws.com/0/35276/f72b2e2e-bbc3-718c-4449-8028a6107fef.png)


その他の実装についてもデモサイトを参考にすればできそうです。
TITAN V で CryptoNight でマイニングする(2018 年 1 月 5 日時点 1241 H/s @ 72W)

漢なら TITAN V で CryptoNight(e.g. Monero) やりたいですね!

やりましょう!

## マイニングソフトウェア

ccminer-cryptonight を使いました.

https://github.com/KlausT/ccminer-cryptonight 

## 性能

<img width="778" alt="Screen Shot 2018-01-05 at 2.20.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/36275/0f6ab4c6-6a4e-cd5d-07ba-32fea49391f4.png">

1241 H/s 出ました. 消費電力は 72 W でした.

VEGA 64 が 1100 H/s で 75 ~ 80 W くらいなので, VEGA より電力効率良さそうですね.

## TODO

* xmr-stak など他のマイニングソフトを試す
社内会議の停止性問題

## 終わりの見えない会議
社内会議とは、ある議題に対して結論を導く手続きである。しかし、現実世界では様々な要因により結論を先送りにすることがある。今回の会議では結論を出すことができなかったので、次回も同じ議題で議論をし、次こそは結論を出しましょう、というのだ。勘のいいあなたはこんな不安を感じるはずだ。
次回の会議で結論が出るのか？それともまた先送りになるのか？
もしかすると、我々は100回繰り返しても、10000回繰り返しても結論の出ない議題について話し合っているのではないか？

## 結論はいつ出るのか。それとも、いつまで経っても出ないのか。
こんなプログラムを考えよう。
「ある議題に対して結論が出るならば__"この議題は意味あり"__を、結論が出ないならば__"この議題は意味なし"__を返す。」
なんて有益なプログラムなのか。__"この議題は意味なし"__と判定された会議には出なくて済むのだ。一生結論が出ない無駄な会議なのだから。

## 意地悪な上司現る
会議大好き上司はこのプログラムがインチキだと見破り、こんな議題を用意した。
「この会議は結論が出るか。」
そして、上司はこの議題に対して、先のプログラムで計算させて、結論づけることにしたのだ。
「この議題をプログラムに入力したとき、__"この議題は意味あり"__と返すならば結論を先送りにする。__"この議題は意味なし"__と返すならば議題に対して”Yes”と結論付ける。」

## 結論が出るか出ないか判定するプログラム
残念なことにある議題に対して結論が出るか出ないか判定するプログラムは存在しない。なぜなら、会議大好き上司の用意した議題に対して矛盾が発生するからである。
同様の問題は、[停止性問題](https://ja.wikipedia.org/wiki/%E5%81%9C%E6%AD%A2%E6%80%A7%E5%95%8F%E9%A1%8C)として知られている。
プロセッサの脆弱性。MeltdownとSpectre


という、気になる話が目に留まった。

[プロセッサ脆弱性「Meltdown」と「Spectre」のまとめサイト開設](http://www.itmedia.co.jp/news/articles/1801/04/news010.html)

ふーん、で終わろうかと思ったんだけども、[品川先生のtweet](https://twitter.com/utshina2/status/948809945327157253)

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">Meltdown の本質ってC言語で書くとこれだけだよね。<br><br>a = *kptr;<br>b = array[a&lt;&lt;12];<br><br>aにカーネルメモリの値が入って、arrayの対応する部分がキャッシュに乗る。もちろん例外を起こして実行は取り消されるけど、キャッシュはそのままなので、arrayのアクセス速度を測ればaの値がわかる。</p>&mdash; 品川 高廣 (@utshina2) <a href="https://twitter.com/utshina2/status/948809945327157253?ref_src=twsrc%5Etfw">2018年1月4日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


を見て、tweetだけでは理解できなかったので、ついつい論文2つを斜め読みしてみた。

理解内容は最後にして、まずは結論から。

# 結論

内容は、特にMeltdownの方はプロセッサの根本部分だし簡単に読み出せそうだし結構まずそう。対策は取れるだろうけど、いずれの方法にしてもプロセッサパフォーマンスをある程度犠牲にする必要があるのではないかしら。

# 感想

対策関係者は大変だろうけどちょっとそれは置いておいて、内容を理解できたし、μOPを身近に感じることができた初めての経験だった。うれしい。
μOPやOut Of Order(OoO)を説明するときの、ちょっとしたネタになりそうな予感。実験コードも簡単に書けそうだし。
新人研修向けのワンポイント小ネタとしてもおもしろいんじゃないかしら。

#自分の理解

さて。

```c
a = *kptr;
b = array[a<<12];
```

kptrにはカーネルのアドレスが入っていて、ユーザからは見ることができない場所。Windowsなら1行目で「このアプリは不正アクセスで落ちました」的なダイアログとともにアプリがお亡くなりになる。

C言語的に見れば、1行目を実行してから2行目を実行する。1行目で例外が発生すれば2行目は実行されない。
非常に当たり前な話だ。

しかし、C言語は機械語となり、さらにIntel CPUの中ではμOPコードというさらに細かい単位に分けられ、かつ、関連性のないものは複数同時に実行したり、実行順序を入れ替えたり(Out Of Order)、分岐に関しては予想で実行してしまったり(分岐予測)、ととんでもないことをしながら辻褄が合うようにしている。考えた人ほんと凄い。
（ちなみに、Spectreは分岐予測による投機実行を利用している。）

```
a = *kptr;
```

の行で何が起こっているかといえば、この行に来る前のすでにkptrの値が決まった時点で、メモリへのアクセスを開始してしまっている。なぜならメモリとのやりとりはプロセッサ動作に比べると亀のように遅いため、実行前にできるだけ早くキャッシュまでは持ってきておきたいから。
そして、それを変数aに入れるわけだが、CPUにはレジスタという入れ物があってそこに入れることになる。が、実はCPUの中には、見えているレジスタの裏に見えないレジスタがたくさんあって、実はそこに入る。変数aに割り当てられたレジスタにはまだ入らない。でも、実質aの内容は決まったので2行目のメモリも先読みできてしまうため、メモリへのアクセスを開始する。その頃、実は1行目のアドレスは不正アクセスですよーの例外処理が動きだす。
結果として、変数a,bに割り当てられたレジスタには値は入らないが、実はキャッシュにまではデータが来てしまっている。bの方はタイミング次第ということもあるようだけど。
あとは、そのキャッシュの内容を読み出せばよい。

どうやって読みだすのか。

array[]の要素を0から順番に読み出していきそれぞれの読み出しにかかる時間を計る。実行前にarray[]の内容を含んだキャッシュをすべてFlushしておけば、キャッシュに乗っている要素の呼び出しとそうでない呼び出しでは、読み出し時間に大きな差がでるため特定できる。いや、特定できるようにa<<12をしてpageを分けてキャッシュが被らないようにしている[^1]。つまり、飛び抜けて読み出しが早かった要素のインデックス値が、通常は読めるはずのないメモリの内容ということになる。つまり、どのアドレスでも読めてしまう、と。

細かい実装は、Spectreの方にコードがあってZero page確保の省略(Copy on Write)を避けたり、最適化を逃れたり、読み出し時間の判定とか泥臭くて面白い。

このおもしろさは、[Magic Ring Buffer](https://www.slideshare.net/urakarin/magic-ring-buffer)以来かも。

おわり。


# 参考
- [Meltdown](https://meltdownattack.com/meltdown.pdf)
- [Spectre](https://spectreattack.com/spectre.pdf)




[^1]: キャッシュライン単位でもよいような気もするけど、TLBやPTEあたりも関係するからということかしら。
Pixi.js v4で自前のcanvas使う

自分用メモ

公式みるとcanvas作るときにはこんな感じ

```
// Create the application
const app = new PIXI.Application();

// Add the view to the DOM
document.body.appendChild(app.view);

```
これでbodyにcanvasタグ追加してくれる。
でもcanvasにクラスとか振れない、optionにも直接それっぽいのがないので、
optionの中のviewを使った。

```html
<canvas class="any-class" id="js-canvas"></canvas>
```

それをnew の際のoptionに渡すと、クラスが振られたcanvasが生成される

```
// optionを渡す
const app = new PIXI.Application({
    view : document.getElementById("js-canvas")
});

// これは一緒
document.body.appendChild(app.view);
```

こんなんでいけた
GoogleHome+ChromeCastでYouTubeの動画をピンポイントに再生してみる 

Google Home + Chromecastを使ってYouTubeの再生を楽しんでいたのですが検索ワードだけだとピンポイントに見たい動画が見れないという状態が発生したのでその時に検証してみた内容をメモ

# 使用するデバイス
・Google Home
・Chromecast

# ひとまずサポートに問い合わせてみた

現状の仕様を確認したところ検索ワードに一番類似した動画を再生させるという回答をいただきました

上記の仕様に基づいて見たい動画を指定するには

**1. 見たい動画のタイトルをすべて話す必要がある**ので毎回再生させるのが大変(覚えれない)
**2. 同じタイトルの動画の場合はどうにもならない**

という問題があることに行き着いてしまいました。

# ショートカット機能を使用してそこそこ長いタイトルの動画であればピンポイント再生が可能

Goome Homeのアプリにショートカットを設定できる機能があることを発見
今回設定したショートカットを例に解説

タイトル：**トミカで「はたらくくるま」を再現してみた**

という動画がYouTubeにあったのでこの動画を「ねぇGoogle、はたらくくるま」とGoogleHomeに話しかけるだけでテレビに再生できるようにします


## 1. Google Homeアプリのショートカットを選択
![11.jpg](https://qiita-image-store.s3.amazonaws.com/0/223901/e774cc02-8a33-577b-53cb-bebc9518e7ba.jpeg)

## 2. 右下の+からショートカットを新規登録

![22.jpg](https://qiita-image-store.s3.amazonaws.com/0/223901/980a322d-2021-956b-66f1-93ced775225a.jpeg)

## 3. ショートカットの内容を設定
![33.jpg](https://qiita-image-store.s3.amazonaws.com/0/223901/fce5efe5-7078-dc8b-7a35-d23068e67b07.jpeg)

こう言ったときの項目についてはキーボドでの入力ではなく音声入力で設定を行ったほうがよいかもしれません
最初キーボードから登録を行ってみたのですがGoogleHomeが反応してくれなかったので音声で再度設定したところ正常に反応するようになりました

**youtubeでトミカで「はたらくくるま」を再現してみたの動画再生**

ここまで文章を設定しておくとChromecastを起動してYouTubeで再生してくるようになります

# まとめ

この動画がピンポイントで見たいということが意外と簡単そうで仕様上できないということがわかったのでショートカットを利用してしばらくは様子を見ようと思います。
この方法でも子供が見たいという動画ぐらいは登録ができると思うのでしばらくは問題なさそうです。

ショートカット登録にURLまたは何か動画のキーになるようなものが設定できるようになると精度がもう少し上がると思うのですが今後の更新に期待したいところです。

# Chromecast ヘルプ

Google Home を使ってテレビで YouTube 動画を再生する
https://support.google.com/chromecast/answer/7029380?hl=ja
ConcourseCIでチーム(team)作成時にGithub認証を設定する

多分何回もやると思うので備忘録

# 内容
ConcourseCIで新しいチーム作成時にGitHub認証(OAuth)を設定します。


# 前提

1. ConcourseCIのURLを http://192.168.0.2 とします。


# 手順

## GithubでOAuth Appを設定する
![image.png](https://qiita-image-store.s3.amazonaws.com/0/40692/ab6fd87b-c75e-6010-b67f-208b7dfd432c.png)

右上のドロップダウンメニューから`Settings`を選択します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/40692/a36c698b-e1d5-09c2-fd3c-d74f457ddd7f.png)

左側のメニューリストから`Developer settings`を選択します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/40692/a8927596-2eef-f87c-77ea-dc4f9c7e198b.png)

- （１）左側のメニューから`OAuth Apps`を選択します。
- （２）`New OAuth App`を選択します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/40692/64a9e3fe-1fda-2e03-2b06-5bdcdd81999d.png)

- （１）連携先のアプリケーション名(今回はPrivateConcourse)を設定します。
- （２）認証後のリダイレクト先を指定します。
    - http(s)://`ConcourseCIのDNS名`/auth/github/callback 
    - 今回は`192.168.0.2`が`ConcourseCIのDNS名`(IPアドレスじゃねえかというのは置いておきます)です。
- （３）`Register application`ボタンをクリックします。

登録された`OAuth Aps(PrivateConcourse)`の`Client ID`と`Client Secret`を後で使用します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/40692/63640268-a899-9ad5-a22d-9fa7696b344b.png)

## ConcourseCIで新しいチームを作る

```bash:
$ fly -t home set-team -n health_check \ ...(1)
     --github-auth-client-id $client_id\ ...(2)
     --github-auth-client-secret $client_secret \ ...(3)
     --github-auth-user Fufuhu ...(4)
```

- (1) 新しいチーム名としてここでは`health_check`を指定しています。
- (2) `$client_id`には先ほど確認したGithubのOAuth Appの`Client ID`を指定します。
- (3) `$client_secret`には先ほど確認したGithubのOAuth Appの`Client Secret`を指定します。
- (4) GitHubのユーザ名を指定します。今回は自分のアカウントを指定しています。
    - ここでは利用するオプションを変更することでteamやorganizationを指定することもできます。


## ConcourseCIでログインしてみる

ConcourseCIのURL(ここでは、http://192.168.0.2)にアクセスします。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/40692/582965ee-bc6f-602b-4d14-2182d049f29a.png)

（１）画面右上の`login`リンクをクリックします。
（２）ログイン先のチーム名(`health_check`)を選択します。

下のような画面に遷移するので、`login with GitHub`ボタンをクリックすると、
ログインできます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/40692/46cc27d2-29f2-ef19-e185-f10501b404c0.png)

※ まだGitHubでログインしていない場合は、GitHubのログイン画面が表示されるので、
そのまま画面表示にそってログインしてください。
ディジタル紫外線センサをWio LTEに繋げる

環境の計測用にいろんなセンサをWio LTEに繋げようとしてます。
Groveのモジュールに都合よいのがあればそれを繋げますが、今回使いたかったセンサがGroveになかったのでGrove化してみました。

#ディジタル紫外線センサ　VEML6070
日の光に含まれる紫外線はお肌に悪いと言われてます。その紫外線の強さを計測したくて紫外線センサを探したところ、I2Cで接続できる[VEML6070](https://www.vishay.com/docs/84277/veml6070.pdf)を見つけました。そのままだと扱いにくいので[ストロベリーリナックスのモジュール](https://strawberry-linux.com/catalog/items?code=16070)を使用します。
このセンサのインターフェースはI2Cで、電源も3.3Vで動作するので、そのままWio LTEに接続できます。

#Grove化
VEML6070のモジュールには、I2Cのプルアップ抵抗が取り付けられていないので付ける必要があります。

小型の基板にGroveコネクタ、VEML6070のモジュール、抵抗を半田付けします。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/109992/e2c230e6-fdea-0a4a-06b1-e6c0dc70e10e.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/109992/a57f7f74-45a7-8330-b574-e365090bf5a3.png)

#ライブラリ
Arduino用のライブラリを探したらあったので、それを使いました。

https://github.com/adafruit/Adafruit_VEML6070

ただライブラリに付属しているスケッチ例はWio LTEで使えないので、スケッチ例を元に以下の様にしました。

```Arduino
#include <WioLTEforArduino.h>
#include <Wire.h>
#include "Adafruit_VEML6070.h"

Adafruit_VEML6070 uv = Adafruit_VEML6070();
WioLTE Wio;

void setup() {
  Wio.Init();
  Wio.PowerSupplyGrove(true);
  SerialUSB.println("VEML6070 Test");
  uv.begin(VEML6070_1_T);  // pass in the integration time constant
}


void loop() {
  SerialUSB.print("UV light level: "); SerialUSB.println(uv.readUV());
  
  delay(1000);
}
```

#動作確認
動作させるとシリアルモニタに計測した結果が表示されます。センサを手で覆うと値が変化しました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/109992/e8efb527-e9c8-6c46-4cfb-d1f872e05f68.png)
ちょっとずつ読むドメイン駆動設計 第四部 戦略的設計 第十五章 蒸留3 汎用サブドメイン

# 前回までの第十五章

[コアドメイン1](https://qiita.com/YasuhiroKimesawa/items/899d1b3fd58ca91f525a)
[コアドメイン2](https://qiita.com/YasuhiroKimesawa/items/1aee3602d3aea1cb5b91)

# 汎用サブドメイン

補佐役を果たすもので、汎用的な役割だが、システムを機能させて、モデルを完全に表現するためには欠かせないものです。

ほとんどのビジネスで必要になる概念を抽象化したもの。

ただし、このようなモデルは専門的な知識をとらえることなく、複雑さを付け加えるだけの部分もあります。

汎用サブドメインの例としては、組織図や売掛金、経費元帳、財務などの会計モデル、タイムゾーンなどなど。

こうした、プロジェクトにとって動機になっていない、サブドメインをコアドメインと分けて考え、サブドメインの優先度を下げ、コアドメインに開発者を割り当てること。

## コアドメインの解決策

1. 既製品を使う・・・たとえば、認証、認可のモデルに[SpringSecurity](https://projects.spring.io/spring-security/)を使うとか。使うには事前に時間をかけて評価して、理解する必要がありますが、成熟度も高く、使わているので安定しています。
2. 公表されている設計やモデル・・・[アナリシスパターン](https://qiita.com/YasuhiroKimesawa/items/61c8a0452bb7d11e15b8)や[公表された言語](https://qiita.com/YasuhiroKimesawa/items/bfec2a083483d348dc9c)を使用する。
3. アウトソーシングする・・・ コアドメインを流出させずに発注することが大事ですが、コアドメインに集中できます。ただし、インターフェイスなどの重要な側面についてコアチームが時間を割く必要があります。
4. 自社で実装する・・・現状はこれが選択されるでしょうとEvansが言っています。**それでもコアドメインモデルから切り分けることには価値があります**

将来的には、多くの汎用的なモデルがフレームワークや、公表されたモデル・アナリシスパターンとして手に入るようになるでしょうとEvansは予言していますが、実際どうでしょうか？
SpringFrameworkは結構ここに力を入れている気がします。

SpringSecurityではモデルも公開されていますし、開発側が比較的自由にいじることもできますね。

## 汎用サブドメイン＝再利用可能ではない

ここは大事なところですね。再利用性を考慮していては、蒸留のコアドメインに集中するという動機から外れてしまいます。
ただし、

> **汎用的な概念の範囲内に収めるということに関しては厳格でなければならない**(第十五章 より)

ということは注意しておきたいですね。
node.js http-serverコマンドでwebサーバーを起動する

node.js を使って、最も簡単にwebサーバーを作る方法です。

# http-server コマンドのインストール

```
> npm install -g http-server
``` 

# コマンド起動

目的のフォルダをカレントにしてコマンドラインからコマンド起動するだけです。

```
> http-server
```

http://localhost:8080/

ここにアクセスするとそのフォルダのファイル一覧が表示されます。

止めたいときは、Ctrl+C (Windows) を押すといいでしょう。


# コマンドラインオプション指定

公式ページにのっています。

https://github.com/indexzero/http-server

例えば、ポートはデフォルトで8080なので、変更したい場合は -p オプションを指定します。

```
> http-server -p 8000
```

他にも多数のコマンドラインオプションがあります。

# 他のWebサーバーコマンド

node.js 系のシンプルなwebサーバーとしては、

* simple-http-server 
* simple-server
* superstatic

というものがあるようです。

# 参考サイト

* Node.jsのhttp-serverっていうコマンドラインのウェブサーバーが便利 | Firegoby
https://firegoby.jp/archives/5706

* Node.js のための HTTP サーバ - HAM MEDIA MEMO
https://h2ham.net/node-http-server

* 「紙芝居」用の簡単 HTTP サーバを立てる（その2） - Qiita
https://qiita.com/spiegel-im-spiegel/items/1a806ad8a9c38a0d7b70
asciidoc to markdown

asciidoc to markdown
====================

ググったけど結局いい感じのものが見つからなかったので、自分用のメモを兼ねて。
asciidocをmarkdownに変換しようとしてハマった話です。Linuxは参考にした記事を、Macはこの記事を参考にすることで解決の糸口になるかもしれませんが、Windowsは検証する環境が現在無いため、わかりません。。。あしからず。

TL;DR
-----

-   ココ見て[Convert asciidoc to
    markdown](https://tinyapps.org/blog/nix/201701240700_convert_asciidoc_to_markdown.html)

-   `pandoc`, `asciidoc` をインストールする

-   asciidocのコマンドでdocbookに変換したら、docbookをpandocでmarkdownに変換する

背景
----

少し周りで[asciidoc](http://asciidoc.org/)の話を聞いてみたので実際に試してみようと思い、ブログ記事をかき始めた。
ブログサービスではmarkdownをサポートしているため、変換する必要があった。

そこで[Pandoc](https://pandoc.org/)でサクッと変換してブログ記事の記載を完了…
する予定だったのだが、pandocではインプットするソースファイルにasciidocの形式のファイルが取れないことがわかった。[1]

そこで変換する方法を調べた…。

参考にした記事
--------------

-   [Convert asciidoc to markdown -
    tinyapps.org](https://tinyapps.org/blog/nix/201701240700_convert_asciidoc_to_markdown.html)

    -   最終的にココを見て解決しました

-   [Convert asciidoc to markdown -
    stackoverflow](https://stackoverflow.com/questions/26430433/convert-asciidoc-to-markdown)

    -   最初の方に見ていたページ。まさかこんなめんどくさいとは思わなかった…。

手順
----

上記、参考記事の手順2までとほぼ同様の操作になる。

`pandoc` と `asciidoc` をインストールする; Macの場合(brewを使う)  
`brew install pandoc asciidoc`

Linuxの場合  
`sudo apt install pandoc asciidoc`

asciidocでpandoc形式に変換する(ココで生成されるarticle.xmlがdocbook)  
`asciidoc -b docbook article.adoc`

pandocでmarkdown形式に変換する  
`pandoc -f docbook -t markdown_strict article.xml -o article.md`

大変すぎる！

shellにしとく
-------------

**convert.sh.**

    #!/bin/sh
    asciidoc -b docbook $1.adoc
    pandoc -f docbook -t markdown_strict $1.xml -o $1.md
    pandoc -f docbook -t html $1.xml > $1.html # 後述するHTML出力

これで `./convert.sh article` とかで叩けば良いのでは、と思いました。

余談
----

docbook に変換できれば他に変換するのは容易いっぽい。
例えば、htmlに変換する場合は下記のコマンドで一発。

**convert\_html.sh.**

    pandoc -f docbook -t html $1.xml > $1.html

参考記事：[Pandocを使ってMarkdownを整形されたHTMLに変換する](https://qiita.com/m_ohsumi/items/cea1243e106ababd15e7)

終わりに
--------

日本語の記事が少なくて苦しかったのでまとめてみた。
asciidoc、表現幅は広そうだなと思うのですが、まだまだ使いこなすには鍛錬が必要そう。

なお、この記事もasciidocを変換し、markdownにした記事になります。
参考までこんな感じの変換に。[2]

![asciidocばーじょん](https://github.com/yumechi/shitagaki/blob/master/qiita_article/20170104/images/asciidoc.png?raw=true)

![markdownへんかんごばーじょん](https://github.com/yumechi/shitagaki/blob/master/qiita_article/20170104/images/markdown.png?raw=true)

[1] pandoc公式ページに表示されている状態遷移図っぽいのがそれで、入力となる左側には確かにasciidocが存在していない

[2] 流石にqiitaに上げるときは画像リンクを差し替えていますがw


本当の感想
----

これ思いの外綺麗に変換がかからないので、やっぱりmarkdownに自動変換されるとはいえ、最後は自分自身でチェックして手直しする必要があるのかも。

[Githubにあげたもの](https://github.com/yumechi/shitagaki/blob/master/qiita_article/20170104/content.adoc)は綺麗に表示されているのですが、やっぱり変換は難しいみたいですね。。。変な部分での崩れや、余計のタブの挿入、ファイル拡張子の指定が上手く行ってないように見えます。同じような書き方がいくつかあるのですが、どれかなら対応しているとか何ですかね…。

Github、GitlabやPDF資料を作る場合にはasciidocが大きな効果を発揮する機会があるかと思うのですが、最終的にブログに貼り付けるためのmarkdownにする用途とするには無理があるかもしれません。


よくある[チートシート](https://powerman.name/doc/asciidoc)をテストケースとして変換したらどの程度の互換性を持って変換が可能なのか、時間があれば研究してみたいですね。（今後の課題）
mac OS 10.13(High Sierra) で Eclipse のデバッグに gdb を使う

[こちら](https://qiita.com/yuzu_afro/items/988020dd65fb4f43962a) の投稿で、mac OS 10.13(High Sierra) で gdb を使ったデバッグ環境を作成した。

* mac OS 10.13(High Sierra) で gdb を使う  
https://qiita.com/yuzu_afro/items/988020dd65fb4f43962a

今回はその続きで、Eclipse のデバッグに gdb を使おうとしてハマったのでメモ。

# Eclipse のバージョン

Eclipse -> Eclipse について メニューで確認。

```
Eclipse IDE for C/C++ Developers

Version: Oxygen.2 Release (4.7.2)
Build id: 20171218-0600
```

# gdb のバージョンとパス

ターミナルから確認。

```bash
$ gdb -v
GNU gdb (GDB) 8.0.1
...

$ which gdb
/usr/local/bin/gdb
```

# .gdbinit の作成

Eclipse から gdb でデバッグを実行させる際に設定が必要になるため、/Users/(username)/.gdbinit ファイルを作成する。

```bash
$ ls ~/.gdbinit
ls: /Users/(username)/.gdbinit: No such file or directory
```

```bash:.gdbinit
set startup-with-shell off
```

# Eclipse の設定

Eclipse の 環境設定 メニュー の GDB 項目を編集する。

* Eclipse -> 環境設定
  * C/C++ -> デバッグ -> GDB  
  gdb デバッガー: /usr/local/bin/gdb  
  GDB コマンド・ファイル: /Users/(username)/.gdbinit
  <img width="820" alt="Eclipse_setting_001.png" src="https://qiita-image-store.s3.amazonaws.com/0/153816/4033a170-04d7-c417-c625-d4fc3d559472.png">

「適用して閉じる」を選択する。

上記の設定で、これから作成するプロジェクトについては gdb のパス・コマンドが設定されているが、すでに開いているプロジェクトについては適用されていないことがあるので、手動で書き換える。

* プロジェクトを右クリック -> デバッグ -> デバッグ の構成...
  * C/C++ アプリケーション -> デバッガー  
  gdb デバッガー、GDB コマンド・ファイル の設定を確認する。
  <img width="849" alt="Eclipse_setting_002.png" src="https://qiita-image-store.s3.amazonaws.com/0/153816/6326441f-a24a-1774-46aa-fa3dfa5d0c18.png">

「デバッグ」を選択すると、デバッグが開始される。


## gdb の設定をしていない場合に発生するエラー

gdb の設定が正しく行われていない場合は、以下のようなエラーが発生していた。

### gdb デバッガーのパスが正しくない場合

gdb デバッガー のパスが正しくない場合は、"Error with command: gdb --version" が発生する。

<img width="300" alt="Eclipse_setting_003.png" src="https://qiita-image-store.s3.amazonaws.com/0/153816/5e618931-82fe-0a6e-92fd-3e5bc4ad6660.png">

### GDB コマンド・ファイル の設定が正しくない場合

GDB コマンド・ファイルの設定が正しくない場合は、"Error in final launch sequence" が発生する。

<img width="300" alt="Eclipse_setting_004.png" src="https://qiita-image-store.s3.amazonaws.com/0/153816/4f69e2e4-ae12-0012-7c1d-0e7b5d6d12bb.png">
Dart の PWA package を試して見た

自分のProject では、なるたけ Dart を 利用するようにしています。
Dart で オフラインアプリを作る方法について調べて見ました。

## code
[code](https://github.com/kyorohiro/memo_pwa/tree/master/dart_hello)

```html:index.html
<html>
<head>
    <meta charset="utf-8">
    <title>Dart PWA Hello</title>
    <script defer src="main.dart" type="application/dart"></script>
    <script defer src="packages/browser/dart.js"></script>
</head>

<body>
    Hello!!
</body>
</html>
```

```dart:maind.dart
import 'package:pwa/client.dart' as pwa;

void main() {
  pwa.Client client = new pwa.Client(scriptUrl: './pwa.dart.js');
}
```

```dart:pwa.dart
void main() {
  Worker worker = new Worker();

  worker.offlineUrls = <String>[
    "http://localhost:8000/",
    "http://localhost:8000/index.html",
    "http://localhost:8000/packages/browser/dart.js",
    "http://localhost:8000/main.dart.js",
  ];

  worker.run(version: "v0.0.1");
}
```

pub serve --port 8000

できました。
一度、読み込めば、オフラインでも動作するようになります。


# Dart だと、　pwa.dart を自動生成してくれる

Dart だと、　pwa.dart を自動生成してくれる
これは、すごい、

[code](https://github.com/kyorohiro/memo_pwa/tree/master/dart_hello_auto)

**pub run pwa**
pub serve --port 8000

おー、生成されました。

Dartなら、作成したWebアプリを、簡単にオフラインアプリ化できそうですね


# REF
https://pub.dartlang.org/packages/service_worker
https://github.com/isoos/pwa
https://news.dartlang.org/2017/03/making-dart-web-app-offline-capable-3.html

# 私のメモ
[Memo PWA (0)](https://medium.com/@kyorohiro_72753/memo-pwa-0-b236294426d3)
[Memo PWA (2) Dart PWA Package](https://medium.com/@kyorohiro_72753/memo-pwa-2-dart-pwa-package-9ac5a98b4b04)
API設計のポイント（Web API: The Good Parts）


# はじめに
WebAPIについて学ぼうと思い、学習を始めたのでメモ。
丸写しにならないよう、章ごとに個人的なポイントをまとめていく感じにしようと思います。

# 1章 Web APIとは何か
 - 現在はWebAPIを前提としたサービスが広く普及しています。
 - WebAPIは、公開する範囲によって、求められる設計も変わってきます。
   - 公開したAPIは、利用者のことを考えると簡単に変更できない場合もあるので、利用しやすい設計が重要になってきます。
 - RESTと呼ばれる考え方が存在します。
   - よいAPIを設計するための指針になりますが、必ずしも徹底する必要はないと考えています。
   - APIの公開範囲や、実現すべきユースケースを優先して設計をしていくことが重要です。

# 2章 エンドポイントの設計とリクエストの形式
 - エンドポイントは人間が理解でき、技術に依存しないように設計するべきです。
   - 単語が浮かばない場合は、APIとしてのデファクトを検索し、それに合わせるとよいです。
 - エンドポイントのスラッシュ内は、できるだけ1単語かつ小文字にすべきです。
   - 複数の単語を連結する場合、キャメルケースなのかスネークケースなのか、全大文字は許容するかなど、検討項目が増えます。
   - 結果として、利用しやすさに悪影響を与えてしまいます。
 - エンドポイントはリソースを指すようにし、操作方法はHTTPメソッドが担当するようにします。
 - エンドポイントにエンコード文字列などが入らないようにします。
   - エンコード文字列が含まれると、人間が読むために一苦労します。
 - 検索には、クエリパラメータを利用します。
   - IDを指定してのリソースの取得は、エンドポイントで行うよう区別するとよいと思います。
 - ページングや、limit/offsetなどを用いて、適当なデータ量を返却するようにします。
   - 一覧取得の場合に、大量のデータを返却するのは、トラフィックに影響を与えます。
 - 公開範囲によって、エンドポイント設計は粒度などが左右されることを理解します。
   - 内部用APIであれば、デファクトに必ず従うこともないです。利用者を意識したエンドポイントを意識しましょう。

# 3章 レスポンスデータの設計
 - レスポンスのデータ形式は、特に指定がなければデファクトであるJSONを指定するとよいと思います。
 - 返却したい情報は、適切な場所に格納して返却するように心がけます。（HTTPステータスコード、ヘッダ、ボディ etc.)
 - HTTPステータスは様々な種類があるので、結果の概要を表現できるものを選びます。
   - 例外として、結果を隠ぺいしたい場合もあると思います。その場合はどのステータスにするのかを検討しましょう。
 - ボディは、オブジェクトで包んだり、データ名を工夫して、何を表現しているのか誤解を生まないように設計すべきです。
 - エラーメッセージは、エラーコードを使う、開発者用のメッセージを持たせるなど、開発者がエラー原因を特定できるような仕組みを用意すべきです。
   - ユーザ向けメッセージと、開発者向けメッセージは違うと思いますので。
 - エラーの仕組みはAPI側では統一し、クライアント側でハンドリングしやすい状態を保ちます。
   - 404はhtmlで返却されちゃう　とかないように。

# 4章 HTTPの仕様を最大限利用する
 - 仕様はRFCを見る。
 - HTTPがエンベロープとしての役割を担っているので、レスポンスデータにエンベロープを用ない方が効率的。
 - 3章でも述べていますが、レスポンスのHTTPスタータスコードは適切に選択しましょう。
   - 適切なコードを返却することで、クライアント側が何をすればよいのかを分岐できるようになります。
 - レスポンスの効率を上げるために、キャッシュは有効利用しましょう。
   - キャッシュの範囲、有効期限などを考慮する必要があります。
 - キャッシュの有効期限の仕組みは、RFC 7234 では以下の２種類が定義されています。

| 仕組み                             | 内容                                                                      |
|:---------------------------------:| :-------------------------------------------------------------------------|
| Expiration Model (期限切れモデル)   | 予めキャッシュに有効期限を格納しておき、有効期限が過ぎていたら実データを再取得する仕組み |
| Validation Model (検証モデル)       | 今保持しているキャッシュが最新であるかを問い合わせする仕組み                        |

# 5章 設計変更をしやすいWeb APIを作る
 - APIはバージョンで管理し、後方互換性に注意して修正を行う必要があります。
   - セマンティックバージョニング(メジャーバージョン.マイナーバージョン.リビジョン)が一般的。
 - メジャーバージョンはURIに含めるのが一般的です。
   - クエリパラメータに含める方法もありますが、省略時の挙動を考慮する必要があります。
 - APIの公開終了は、利用者のことを考えて慎重に行う必要があります。
   - 並行稼働期間を設ける。
   - 告知をする。
   - 廃止後にどういった挙動にするかを考える(410を返却するのか、エラーメッセージを返すのかなど)

# 6章 堅牢な Web APIを作る
 - 本章の内容はセキュリティに関する一例なので、これを守れば100％オッケー！ではないです。
   - 参考にした上で、最新の動向に照らし合わせて、最適な対策を行うように心がけましょう。
 - 個人情報など、漏洩してはいかない情報を取り扱う場合は、HTTPS通信を利用する。
 - どんな攻撃が存在するのかを知った上で、防御策を知るとよいです。
   - XSSとか、XSRFとか。
 - ヘッダにはセキュリティ強化用の道具が多くあるので、活用していきましょう。
   - `X-Content-Type-Options` など。
 - 大量アクセスを防ぐ方法として、レートリミットを設ける方法があります。


# おわりに
 - URIの考え方は常日頃悩みどころだったので、今後の設計などに取り入れていけたらいいなーと思いました。
 - 困ったらデファクトスタンダードにしましょう　っていうのはその通りだなあと。。。
 - セキュリティに関してはまだ知識不足なところがあるので、実例調べつつもう少し深堀りしていきたいですね。

以上です。お疲れ様でしたー。
   
# 書籍
[Web API: The Good Parts](https://www.oreilly.co.jp/books/9784873116860/)
React SFCでもLifecycleフックを使う

React+Redux のスタックでアプリケーションを開発する際に、Presentational/Container でコンポーネントの責務分割をする設計手法[^1]をとっていると、できるだけビューとなるコンポーネントは **Stateless Functional Component (SFC)** で書きたいという気持ちがありますよね。

[^1]: https://redux.js.org/docs/basics/UsageWithReact.html#presentational-and-container-components

とはいえ、必ずしもすべてのビューコンポーネントを関数にできるかというとちょっと難しいです。例えば、`componentWillMount`のタイミングでAPIを叩いてデータを予めフェッチしておくなどの処理は、どうしてもその処理がビューのライフサイクルに依存するため、ここだけ仕方なくクラス構文を使ったコンポーネントにせざるを得ない...などのモヤモヤ感が生まれます。

# SFCにライフサイクルフックを提供するHOCを作る

このような場合には、特定のコンポーネントにライフサイクル・フックへのコールバックを登録できるような HOC[^2] ファクトリを作ってあげると、常にビューを SFC に維持することができます。 

[^2]: Higher Order Component

以下はTypeScriptで書いていますが、ジェネリクスがあるくらいでほぼほぼJSと同じです。

```ts:lifecycleHookRegister.tsx
import * as React from 'react';

export function withLifecycleHook<P>(
  Component: React.SFC<P>,
  hooks: {
    didMount?: (props: P) => void,
    willMount?: (props: P) => void
  }
) {
  return class StatefulComponent extends React.Component<P, {}> {
    componentDidMount() {
      if (hooks.didMount) {
        hooks.didMount(this.props);
      }
    }

    componentWillMount() {
      if (hooks.willMount) {
        hooks.willMount(this.props);
      }
    }

    render() {
      return (
        <div>
          {Component(this.props)}
        </div>
      );
    }
  };
}
```
この HOC ファクトリでやっていることは、引数として`componentDidMount`や`componentDidUpdate`のタイミングで実行する関数をコールバックで受け取り、動的に外部から設定できるようにしているだけの簡単なものです。

このような HOC ファクトリを作っておけば、ライフサイクルが必要な SFC なビュ―関数を必要に応じて食わせることで、ライフサイクルに応じた処理のあるコンポーネントを作ることができます。

```ts
const component: React.SFC<Props> = (props) => {
  return (
    <div>
      This is a stateless functional component!
    </div>
  );
};

export const YourComponent =
  withLifecycleHook<Props>
    (component, {
      willMount: (props: Props) => {
        props.callYourOwnAPI();
      }
    });
```
`component`が関数型コンポーネントとしてただ JSX を返すだけの Presentational な責務だけを持ち、ライフサイクルに関連した処理がうまく切り出せていることが分かりますね。
【問題解決】ファイルダウンロードのHTTPステータスコードが`201`だと、IE11/Edgeではダウンロードできない


# 環境
* Internet Explorer 11 (11.125.16299.0)
* Microsoft Edge 41.16299.15.0
* Firefox 57
* Chrome 63
* Servlet 3.1
* Java8
* Tomcat9
* Windows10


# やりたいこと
Java Servletでファイルのダウンロード


# 問題

以下のような、ファイルをダウンロードさせるコードを作成しました。
※HTTP Status Codeが`200`でなく`201`であることに注意

```java:DownloadServlet.java
@WebServlet("/download")
public class DownloadServlet extends HttpServlet {
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		response.setContentType("text/html");
		response.setHeader("Content-Disposition", "attachment");
		PrintWriter out = response.getWriter();
		out.write("Hello World");
		response.setStatus(201); //ステータスコードがCreated(OKではない）
	}
}
```

各ブラウザで、`localhost:8080/[ContextPath]/download`にアクセスしました。


## Internet Explorer 11の場合
「このファイルをダウンロードできませんでした。」というメッセージが表示され、ダウンロードできませんでした。


![image](https://qiita-image-store.s3.amazonaws.com/0/37903/5d3778f1-436c-63f1-e677-fe83c957218d.png)

![image](https://qiita-image-store.s3.amazonaws.com/0/37903/9f4e1d1a-8532-4f59-81c0-3d3dfa41666c.png)

## MIcrosoft Edgeの場合
「ダウンロードを待っています」という状態のままで、ダウンロードはできませんでした。

![image](https://qiita-image-store.s3.amazonaws.com/0/37903/aa2df5fa-60e4-33bb-667e-514f73f6d900.png)

![image](https://qiita-image-store.s3.amazonaws.com/0/37903/8d042282-41bd-09b4-ce85-d7a268faea87.png)

## Firefox, Chromeの場合
ダウンロードできました。



# 原因・解決策
HTTPステータスコードが`201`(Created)であることが問題でした。
私のポカミスです。。。
ステータスコードを`200`(OK)に変更したら、IE11/Edgeでもダウンロードできました。

```java
response.setStatus(200);
```


# 感想
GETメソッドの成功を表すコードは`200`なので、「ステータスコードが200でないからダウンロードできない」というIE11/Edgeの仕様は、特に問題ないと思います。
いつもなら「IEクソっ！」と思うところですが。。。

# 参考にしたサイト
* [HTTPステータスコードを適切に選ぶためのフローチャート : 難しく考えるのをやめよう](http://postd.cc/choosing-an-http-status-code/)
* [Status Code Definitions - W3C](https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html)
JupyterNotebookにVimの力を加えると、光と闇が両方そなわり最強に見える

前回まででMacにJupyter Notebookを入れ、そのExtensionも追加し、効率的に分析ができる環境を作りました。**今回は色やフォントなどの見た目変更、そしてVimで編集をできるようにします。**ちなみにタイトルの元ネタは[これ](https://dic.pixiv.net/a/%E5%85%89%E3%81%A8%E9%97%87%E3%81%8C%E4%B8%A1%E6%96%B9%E3%81%9D%E3%81%AA%E3%82%8F%E3%82%8A%E6%9C%80%E5%BC%B7%E3%81%AB%E8%A6%8B%E3%81%88%E3%82%8B)です。

(前回までの記事)
[僕がpyenv+anaconda3+jupyter notebookを選んだ理由と、その導入]
(https://qiita.com/_snow_narcissus/items/97d147dfa117f9a74936)
[Jupyter notebookのスニペット機能を使って機械学習案件の生産性をあげる]
(https://qiita.com/_snow_narcissus/items/647a6d3cec0a9bdb8980)

以下の順に沿って記していきます。

1. 見た目の変更
2. Vimの導入
3. cssの調整

前提となる環境として、自宅で使っているMacBooK Airを用います。

```text
2011 MacBook Air 3,1
1.4 GHz Intel Core 2 Duo
2 GB 1067 MHz DDR3
128 GB SSD
High Sierra 10.13.2
```

また`pyenv 1.1.5 + anaconda3-4.0.0`でpython3を入れています。

# 見た目の変更

デフォルトのテーマでは下記の感じになり、割合明るめなので、良い感じに闇に染めていきます。

![スクリーンショット 0030-01-04 22.42.01.png](https://qiita-image-store.s3.amazonaws.com/0/47559/5360669f-8a8c-05f4-b37b-8936addbe68d.png)

色やフォントの変更には[jupyterthemes](https://github.com/dunovank/jupyter-themes)を用います。JupyterNotebookのプロセスをいったん落としてから、下記コマンドを実行してください。

```bash
~$ pip install jupyterthemes
```

上記のようにpipパッケージを導入すると、`jt`コマンドが使えるようになりますので、下記のように色のテーマとフォントを指定します。(上記のサイトを見て自分なりにカスタマイズしてみてください)

```bash
~$ jt -t chesterish -T -f roboto -fs 9 -tf merriserif -tfs 11 -nf ptsans -nfs 11 -dfs 8 -ofs 8
```

ここでJupyterNotebookを起動してみましょう。良い感じに闇に染まりましたね。

![スクリーンショット 0030-01-04 23.12.41.png](https://qiita-image-store.s3.amazonaws.com/0/47559/3a3b561f-3d59-8b97-f82a-6d16f58c3e1e.png)

# Vimの導入

さらにVimの力を加えることにより、闇の力を深めていきます。前回記事にしましたが、既にnbextensionsは導入している前提です。Vimの導入には[jupyter-vim-binding](https://github.com/lambdalisue/jupyter-vim-binding)を用います。(**下記コマンドについてレポジトリのクローン先はコマンド`$ jupyter --path`で調べ、各自適切なパスに変更してください。**)


```bash
$ git clone https://github.com/lambdalisue/jupyter-vim-binding /Users/daiki_akimoto/.pyenv/versions/anaconda3-4.0.0/share/jupyter/nbextensions/vim_binding
```

すると、下記のようにVIM bindingのnbextensionが選べますので、これをチェックします。

![スクリーンショット 0030-01-04 23.37.18.png](https://qiita-image-store.s3.amazonaws.com/0/47559/72ac736c-226e-cf14-e9d2-184f77bd8a5a.png)

すると、下記のようにVimがJupyterNotebookの中でも使えるようになります。ちょっと見辛いので次の説でCSSをいじって調整してあげます。**(注:Safariで開きますと上手く動かないようです。GoogleChromeだと大丈夫でした。)**

![スクリーンショット 0030-01-04 23.41.05.png](https://qiita-image-store.s3.amazonaws.com/0/47559/e3e1cd28-0e3c-c829-096e-51a4aba4707d.png)

# cssの調整

上記のように闇に染まった背景にVimを導入すると、少し明るくなって見にくくなるので、これも塗りつぶしましょう。

`~/.jupyter/custom/custom.css`を編集します。`div.cell.edit_mode {`という一行がありますので、その直前に下記を挿入します。

```css
/* Jupyter cell is in normal mode when code mirror */
.edit_mode .cell.selected .CodeMirror-focused.cm-fat-cursor {
background-color: #000000 !important;
}
/* Jupyter cell is in insert mode when code mirror */
.edit_mode .cell.selected .CodeMirror-focused:not(.cm-fat-cursor) {
background-color: #000000 !important;
}
```

すると、下記のようにVimの編集範囲も闇に染めることができます。

![スクリーンショット 0030-01-04 23.54.47.png](https://qiita-image-store.s3.amazonaws.com/0/47559/3844f03f-c9a7-14dc-0a3e-651868934fb3.png)

# 最後に

以上、Jupyter　Notebookの色と見た目の変更とVimの導入でした。細かいところですが、毎日使っていくものでもあるので、紹介したサイトを参考になるべく使いやすく自分にあった環境を見つけて頂ければと思います。
sudo時の環境変数上書き / 引き継ぎについて

`sudo` 実行時、環境変数は変身ユーザーのもので基本的に上書きされると認識しているのだが、実際どう上書きされているのかとか、実行ユーザー側のものを引き継いで使いたい場合はどうしたらいいのかとか、よくわかってないので少し調べたメモ。

なお、以下では `sudo` で他のユーザーに成り替わることを「変身」と呼称する。日本語版のMan pageでも使われている用語であるため。また確認はCentOS 7で行なっている。

デフォルトの挙動
----

環境変数の扱いは基本的には `/etc/sudoers` で管理されている。デフォルトでは漠然と「変身ユーザーの環境変数が適用される」と考えていたが、具体的には `env_reset` が有効になっている。

### env_reset

* これを有効にしていると、変身後に「最小限の環境」が採用される。
* 最小限の環境とは、`/etc/environment` で初期化され、TERM, PATH, HOME, MAIL, SHELL, LOGNAME, USER, USERNAME, SUDO_*がセットされたもの。
* `sudo` の実行ユーザーからは `env_keep` と `env_check` にマッチするものが加わる。

というわけで、必ずしもすべての環境変数が上書きされているわけではない。 `env_keep` と `env_check` は以下の通り。

### env_keep

* `env_reset` **有効** 時に、実行ユーザーから継承される環境変数を定義する。

### env_check

* 「安全」だとみなされない場合に、実行ユーザーから継承されない環境変数を定義する。
* 「安全」とはTZ以外のすべての環境変数について、変数値に `%` や `/` を含まないこと。

ちなみに `env_reset` が無効な場合に適用されるオプションもある。

### env_delete

* `env_reset` **無効** 時に、実行ユーザーから継承されない（削除される）環境変数を定義する。

これらのオプションで定義されている変数は、 `sudoers` が権限的に見られない場合でも、 `sudo -V` で確認ができる。

env_resetの無効化
----

では実行ユーザーの環境変数を、変身後も引き継ぎたい場合はどうするか。 `Defaults    env_reset` をコメントアウトするなりして完全に無効化することもできなくはないが、それはセキュリティ的によろしくないので以下2パターンかと。

* 上述の `env_keep` を使う。
* `sudo -E` を使う。

`env_keep` を使う場合は全ユーザー共通の設定となってしまう。一方で `sudo -E` は、 `-E` オプションを指定した場合のみ `env_reset` が無効化されるため、選択権がある。というわけで後者が良さそう。

### setenv

しかしながらデフォルトだと `-E` は使えない。使えるようにするには `setenv` オプションを有効にする必要がある。

ただし、これについても全ユーザーに対して有効化することは、Man pageで明確に非推奨とされている。以下のようにタグで設定するのがベター。

```
%hoge        ALL=(ALL)       SETENV: /usr/bin/fuga
```

$HOMEについて
----

`sudo -E` を使っても、 `$HOME` は実行ユーザーのものを維持できない場合がある。

これは `always_set_home` オプションがデフォルト有効になっているためで、これは常にsudoの `-H` オプションが使用された状態になる（つまり変身ユーザーの `$HOME` が使われる）。 `$HOME` 含めて実行ユーザーの環境を使いたい場合は、これを無効にしておく必要がある。

似たようなオプションに `set_logname` なんかもあったりする。


結論
----

* `Defaults    env_reset` はそのまま有効にしておく。
* 必要な場合に限って `SETENV` タグを使い、 `-E` オプションを使えるようにする。
* `$HOME` の上書きが必要な場合は `Defaults always_set_home` も外す。
irMagicianをClojureで操作してみる。

大宮技研が販売する赤外線ブラスターであるirMagicianをClojureから扱えるようにするライブラリをつくってみました。

irMagicianは、LinuxだとCDC-ACMのドライバを使用するため、アプリからは/dev/ttyACM0といったデバイスファイルを通じてお話することができ、インターフェースも容易なため、すでに、たくさんの言語用のライブラリがつくられています。(Python, Javascript etc...)

仕様はこちら↓
http://www.omiya-giken.com/?page_id=889

しかし、Clojurianな自分としては、やっぱりClojureからさわりたいので、仕様を読みつつライブラリを書いてみました。
https://gitlab.com/myst3m/irmagician


## 準備
用意したもの:
- irMagician: (http://www.omiya-giken.com/?page_id=837)

環境:
- Debian GNU/Linux
  (RaspbianでもOK)


## 使い方

READMEに、使い方はある程度、細かく記載したのだけれども、基本操作としてはir-openでポートをオープンして、その後命令を実行する形式で、至って普通な実装だと思います。
with-ir-portというマクロを用いると、この中でclose処理をすますので、明示的にcloseする必要はありません。
例えば、赤外線データの学習をしたいときは以下のようにします。

```clojure
(with-ir-port (ir-open :path "/dev/ttyACM0")
 (ir-capture))
```
一々、マクロで包むのがめんどい場合は以下のようにすると、デフォルトで指定のデバイスを使用できます。ただし、最後にir-close!でクローズする必要があります。
ひととおり使い方を書くとこんな感じです。

### バージョン表示:

```clojure
(with-ir-port (ir-open :path "/dev/ttyACM0")
 (ir-version))
```

### 学習:

```clojure
(with-ir-port (ir-open :path "/dev/ttyACM0")
 (ir-capture))
```

### 実行:
上記で学習したデータを実行します

```clojure
(with-ir-port (ir-open :path "/dev/ttyACM0")
 (ir-play))
```

### デフォルトデバイスの指定:
REPLで使用する場合などは、一々マクロでくくるのが面倒なので、以下でデフォルトデバイスを設定して、あとは、(ir-capture)とか(ir-play)とかで実行できます

```clojure
(set-default-ir-port! (ir-open :host "localhost" :port 9999)
````

その他、ir-saveとかir-loadとかでJSONファイルをロードしたり、データを表示したりできるので、Clojureで遊んでみたい方はぜひつかってみてください。
REPLでテレビつけたりするとちょっとおもしろいですよ。
Reveal.jsのMarkdown記法で絵文字を使えるようにする

# Reveal.jsってなに
[Reveal.js](https://github.com/hakimel/reveal.js)とは、HTMLによるプレゼンテーションを簡単につくることができるフレームワークだよ。どんな雰囲気かは[公式のデモ](https://revealjs.com/#/)を見るのが一番だね。Qiitaにも紹介記事がいろいろあるよ（「[reveal.js+Markdown](https://qiita.com/siguremon/items/c717eca388070215712c)」など）。
Reveal.jsの真価は、プレゼンをMarkdown記法で書けることにあると思うんだ。Markdownで書くことで、HTMLタグを頑張って打つよりも圧倒的な速さを手に入れられるよ。

# 絵文字を使いたい:crayon:
でも。。Markdownで書くとプレゼンがシンプルになりがちで、ちょっと寂しいよね。そこで、僕は良く[emoji-awesome](http://zeeshanu.info/emoji-awesome/)をつかって絵文字をいれるんだ。でも、そのためには下のようにMarkdown中にHTMLタグを打つ必要があり、爆速のMarkdownの良さを損ねてしまうよね:disappointed_relieved:

```md
## Reveal.jsとは <i class="em em-heart"></i>
 * HTMLプレゼン <i class="em em-bell"></i>フレームワーク
 * Markdownが使えるよ <i class="em em-gift"></i>
```

理想としてはQiitaのMarkdownみたいにこんな風に書きたいよね。

```md
## Reveal.jsとは:heart:
 * HTMLプレゼン:bell:フレームワーク
 * Markdownが使えるよ:gift:
```

# やってみた！

そこで、QiitaのMarkdownみたいに絵文字を書けるようにしてみたよ。準備はとっても簡単だよ。Reveal.jsのインストールからやり方を書くよ。


## Reveal.jsインストール

GitとNode.jsがインストール済みだと想定するよ。gitとnpmで簡単インストールだ。

```
$ git clone https://github.com/hakimel/reveal.js
$ cd reveal.js/
$ npm install
```

## emoji-awesomeのインストール

絵文字を表示するライブラリは色々あると思うけど、今回は`emoji-awesome`を利用してみたよ。他の絵文字ライブラリでも考え方は一緒だよ。`emoji-awesome`のインストールはnpmでできるよ。

```
$ npm install emoji-awesome
```

`emoji-awesome`を使うにはCSSを読み込む必要があるよ。`index.html`に下記を追記してemoji-awsomeのCSSを読み込もう。

```html
<title>reveal.js</title>
<link rel="stylesheet" href="css/reveal.css">
<link rel="stylesheet" href="css/theme/black.css">
<!-- ★下の行を追加★ -->
<link rel="stylesheet" href="node_modules/emoji-awesome/dist/css/apple.min.css">

<!-- Theme used for syntax highlighting of code -->
```

`emoji-awesome`の絵文字のセットはAppleやTwitter、Facebook風など計６種類のセットから選べるようだ。上の例`apple.min.css`はApple風の絵文字セットで、他には`emojione.min.css`、`Facebook.min.css`、`google.min.css`、`messenger.min.css`、`twitter.min.css`があるようだ。

## markdownプラグインの修正(一行だけ）

`plugin/markdown/markdown.js`に一行だけ追加するよ。現在のコードでは358行目、`convertSlides()`関数内の以下の場所に追記だ。

```js
var notes = section.querySelector( 'aside.notes' );
var markdown = getMarkdownFromSlide( section );
/* ★ここから追記★ */
markdown = markdown.replace(/:([a-z0-9_-]+):/g, '<i class="em em-$1" style="font-size: 1em"></i>')
/* ここまで */
section.innerHTML = marked( markdown );
```

## つかいかた
これでreveal.jsのMarkdown記法内で絵文字が使えるようになったよ。たとえば`index.html`の`<div class="slide">`内に下記のようにかけばOKだ。

```html
<div class="slides">
 <section data-markdown>
## 絵文字を描くよ:bulb:
 * どこでも:heart:かけるよ
 </section>
</div>
```

これだけで、こんなふうに表示されるよ。(テーマは`solarized.css`に変えてます)

<img width="413" alt="スクリーンショット 2018-01-04 23.41.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/160451/18a730a3-a259-97e6-28a7-336d64682e87.png">


`<section data-markdown="./content.md" />`のようにMarkdownを別ファイルで書いても絵文字はちゃんと反映されるよ。

# 何をしているか

見ての通りとても単純で、文字列(Markdown記法)をHTMLに変換する処理の直前で、文字列中の`:絵文字:`を` <i class="em em-絵文字"></i>`に変換しているよ。
絵文字変換だけのプラグインを別途つくろうかと思ったけど、markdownプラグインと処理がだいぶかぶるので、markdownプラグインに追記しちゃいました。
iOSアプリをCircleCIにのせる

# ゴール

[Circle CI](https://circleci.com/)でiOSアプリのビルドを通すまで
（2018/01/04現在）

# はじめに

* この資料はCircleCI2.0をもとに記載しています
* CircleCIのドキュメントは[こちら](https://circleci.com/docs/2.0/ios-tutorial/)

## Github Marketplace

* [Github Marketplace](https://github.com/marketplace/circleci)から連携設定を行う
* iOSアプリのビルドはmacOSプランのみ
  * 料金は$39/月〜
     * https://circleci.com/gh/organizations/kazu14m1/settings#osx-pricing
  * 2週間無料トライアルあり

## Fastlaneの導入

* Fastlaneの導入が必要

### Gemfile

```
source "https://rubygems.org"

gem "fastlane"
```

### Fastfile

基本`fastlane init`でできるものでOK

## .circleci/config.yml

* Project > Add Project > macOS > Setup Project からプロジェクトの設定を行う
* `.circleci/config.yml`は基本sample.ymlでOK

```
# iOS CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/ios-migrating-from-1-2/ for more details
#
version: 2
jobs:
  build:

    # Specify the Xcode version to use
    macos:
      xcode: "9.0"

    steps:
      - checkout
      - run: bundle install

      # Install CocoaPods
      # Fastfileで指定しているなら不要
      - run:
          name: Install CocoaPods
          command: pod install

      # Build the app and run tests
      - run:
          name: Build and run tests
          command: bundle exec fastlane test

      # プロジェクトの設定に合わせて変える
      - store_test_results:
          path: test_output/report.xml  
      - store_artifacts:
          path: /tmp/test-results
          destination: scan-test-results
      - store_artifacts:
          path: ~/Library/Logs/scan
          destination: scan-logs
```

## はまりポイント

### rubyのバージョンが違う

fastlaneはchrubyとruby-installでバージョン管理されているので、バージョン指定が必要な場合は`.ruby-version`ファイルが必要

### iOS Simulatorが出ない

```
▸ xcodebuild: error: Unable to find a destination matching the provided destination specifier:
▸ { platform:iOS Simulator, id:91B6A3EF-A462-462C-BAD2-1F377D1A3B8A }
```
みたいなのが出るときは、`Deployment Target`を指定する。（２０１８/01/04現在）
SAP Cloud Platform Tools for Javaのセットアップ

#**はじめに**
SAP公式ブログを参考に、SAP Cloud Platform（SAP CP）のトライアルをいくつか行ってみたいと思います。
今回は、以下の記事をもとに開発ツールのセットアップを行います。

[触ってみよう！SAPのPaaS――第1回：ディベロッパー向けアカウントのセットアップ手順](https://www.sapjp.com/blog/archives/11485)
※上記リンク先の項番３を行います

この記事は2015年5月時点の情報のため、
記事との差分を中心に記述します(2018年1月時点)。

また、2017年2月にサービスの名称変更がありました。
旧：SAP HANA Cloud Platform
新：SAP Cloud Platform

以下、名称変更について
[SAP、「SAP Cloud Platform」にクラウドの名称変更。iOS用SDK、IoT対応、仮想マシン、API群など汎用PaaS型クラウドサービスとして訴求へ](http://www.publickey1.jp/blog/17/sapsap_cloud_platformiossdkiotapipaas.html)

#**環境**
Windows10 64bit
(記事のOSはWindows7)

#**手順**
*※ここからは、参照元の記事の項番とリンクした内容で記載します*

##**3　開発ツール（SAP HANA Cloud Platform Tools for Java）をセットアップ**

####**①HCP上のWeb開発環境（Web IDE）を利用して開発する。**
⇒今回は対象外

####**②ローカルPCにEclipseベースのツール（HCP Tools for Java）とSDK（Software Development Kits）をインストールし、ローカル開発環境で開発したものをHCP上に展開する。**

⇒今回のセットアップ対象はこちら

####**★差異あり**
まず、Eclipse IDE for Java EE Developerの新しいバージョンが出ていました(Oxygen)。
ダウンロードは[こちら](https://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/oxygen/2/eclipse-java-oxygen-2-win32-x86_64.zip)からできます。
ダウンロードしたZIPファイル名は「eclipse-java-oxygen-2-win32-x86_64.zip」となります。

#**3.1　JVMのシステム環境変数を設定**
####**★差異なし**

#**3.2　eclipse.iniファイルを編集**
####**★差異なし**

#**3.3　SAP HANA Cloud Platform tools for Javaをインストール**
Tipsとして、eclipse.iniファイルの先頭行に下記を追加し～とありますが、追加せずにインストールできました。

####**★差異あり**
Work withフィールドに入力する値が、以下の新バージョンのものとなります。
「https://tools.hana.ondemand.com/oxygen」

※今後ABAPに関してもEclipseを使用したいため、以下のプラグインの追加しました。
![20180104_01.jpg](https://qiita-image-store.s3.amazonaws.com/0/22526/5689c5a2-9a01-0865-dfd9-672b7ac838bc.jpeg)


#**3.4　SAP HANA Cloud Platform SDKをインストール**
####**★差異なし**
Java Web Tomcat 7はダウンロードしませんでした。

#**3.5　SDKを実行環境にセットアップ**
####**★差異なし**

#**おわりに**
待ち時間はありましたが、順調にインストールできました。
引き続き、SAP CPのトライアルを進めていきたいと思います。

※[はてなブログ](http://www.sapsumikko.jp/entry/2018/01/04/233325)で経緯などを追記
Elixirの静的型チェックの確認 - キーワードリストをつかった引数


キーワード引数をつかっている関数でもキーワードごとに型を指定したい。
指定できるか?

結論。
できるが構造的部分型だったとしてもエラーになる。
キーワードリストでなくて、Mapにしても同様。
なにか良い手はあるかもしれないが思いつかなかった。

# 確認

便宜上[Flow](https://flow.org/)と比較する

```javascript
// @flow
function sample(hoge_with_goro: {hoge?: number, goro?: number}) {}

sample({}) // Ok
sample({hoge: 1}) // Ok
sample({goro: 2})  // Ok
sample({mogu: 3}) // Ok
sample({hoge: 1, goro: 2})  // Ok
sample({goro: 2, hoge: 1})  // Ok
sample({hoge: 1, mogu: 3}) // Ok
sample({hoge: 1, hoge: 11}) // Ok ({hoge: 11}と同じ)
sample({hoge: 1, goro: 2, mogu: 3}) // Ok
```
* https://flow.org/try/#0PTAEAEDMBsHsHcBQkCuA7AxgFwJazaAM4CGAtgA7QCmAFABawDmVA+vDlnS47AE6wAuUAG8GzAPxC0KUgCMqvADSge-SaGlyFAXwCUI7YkQkK1GsL2gQoAPIBrY2Uq1RTKkICMl6-cemXqoKgAEyWVmC+Js7mpEwoQgDM3hEOUWauzJ7KgUKh+uG2qU7pOSHKYu6gXvk+Rf7mFVmgsYzxoEn6tX7RGZUe5W6e1QX2oA2DVV6AFgyAMCqAGgy63emNVdl8QcHKLW0dIw5AA

Elixirでやってみる。

```elixir
defmodule Sample do
  @spec sample([hoge: integer, goro: integer]) :: nil
  def sample(hoge_with_goro), do: nil

  def test(), do: sample([]) # Ok goroもhogeもなくてもOK
  def test2(), do: sample(hoge: 1) # Ok goroが足りないのはOK
  def test3(), do: sample(goro: 2) # Ok hogeが足りないのはOK
  def test4(), do: sample(mogu: 3) # Error 指定してないものがあるとダメ
  def test5(), do: sample(hoge: 1, goro: 2) # Ok
  def test6(), do: sample(goro: 2, hoge: 1) # Ok 順番は自由
  def test7(), do: sample(hoge: 1, mogu: 3) # Error moguがあるからやっぱりだめ
  def test8(), do: sample(hoge: 1, hoge: 11) # 複数あっても大丈夫 (JSとはちがって複数値がある)
  def test9(), do: sample(hoge: 1, goro: 2, mogu: 3) # Error moguがあるからだめ
end
```

Mapだとoptionalやrequiredを指定できるので、optionalをつかってみる。
キーワードリストのときと基本的に一緒

```elixir
defmodule SampleMap do
  @spec sample(%{optional(:hoge) => integer, optional(:goro) => integer}) :: nil
  def sample(hoge_with_goro), do: nil

  def test(), do: sample(%{}) # Ok
  def test2(), do: sample(%{hoge: 1}) # Ok
  def test3(), do: sample(%{goro: 2}) # Ok
  def test4(), do: sample(%{mogu: 3}) # Error
  def test5(), do: sample(%{hoge: 1, goro: 2}) # Ok
  def test6(), do: sample(%{goro: 2, hoge: 1}) # Ok
  def test7(), do: sample(%{hoge: 1, mogu: 3}) # Error
  def test8(), do: sample(%{hoge: 1, hoge: 11}) # Ok (%{hoge: 11}になってJSと同じ)
  def test9(), do: sample(%{hoge: 1, goro: 2, mogu: 3}) # Error
end
```

# 参考

* https://hexdocs.pm/elixir/typespecs.html#types-and-their-syntax

# 関連

* [Elixirの静的型チェックの確認 - リテラル型](https://qiita.com/eielh/items/5a676589d0a893e2f8a6)
「CSS Grid Layout Generator でレイアウト用CSSを生成する」をコピーしてみた

[出典 : CSS Grid Layout Generator でレイアウト用CSSを生成する](https://qiita.com/mizchi/items/c63ca1c6ed038f0bf8e4)

大体3日で目コピしたものの紹介です。

これが今回わたしがつくったやつ
https://miyamoen.github.io/elm-grid-generator/
こっちがコピー元のmizchiさんがつくったやつ
https://mizchi-sandbox.github.io/grid-generator/
(見た目を寄せてるので気を付けてください)

![](https://i.gyazo.com/b19fa21d97d45bd414dede2a7b64b3c8.gif)

# これは何

mizchiさんが作ってたCSS Grid GeneratorをElmで作りました
viewライブラリとして[style-elements](http://package.elm-lang.org/packages/mdgriffith/style-elements/latest)を使っています

mizchiさんがElmでやってみてくださいとか言ってて、ちょうどCSS Gridしてたしで作りました

見た目や機能をほぼそのまま再現しました
落としてる機能としてはcontainerのサイズ指定、オートセーブ（代わりにキーボードショートカットでセーブできます）、styled-components用の書き出しです

元のと同様にinvalidなarea name指定するとぐちゃっと壊れます
IEの話は知らん

# 使い方
[こっちみて](https://qiita.com/mizchi/items/c63ca1c6ed038f0bf8e4)

Ctrl-SでSave、Ctrl-LでLoad

# 中身の話
Elmです
Elmが何って人は[今年のAdvent Calendarまとめ](https://scrapbox.io/miyamoen/Elm_Advent_Calendar_2017_%E3%81%BE%E3%81%A8%E3%82%81)があるので見てください
[Discordでリモートもくもく会もやっている](https://qiita.com/ababup1192/items/329b9d16833095a0f887)のでちょっと覗いていってください

宣伝終わり

1日半くらいで見た目を目コピして、1日くらいでがーっと処理を書いていった感じで作りました

view部分には[style-elements](http://package.elm-lang.org/packages/mdgriffith/style-elements/latest)を使っています
gridもこれ使ってやってるんですが結果的にはcss-in-jsになる感じです

# 実装比較
ここでコードの比較をしようと思うんですが、いかんせんreduxとかいろいろ読めないので比較できません

比較してくれる人募集中です