OmniAICreator/Qiita-1.07M huggingface dataset:
QtWebService の紹介

今年も Advent Calendar の季節になりました。今年も色々な人による Qt の色々な記事を楽しみにしています。

昨日は @hermit4 さんによる [Qtのマルチスレッド機構](https://qiita.com/hermit4/items/f4f03a4533e8c332241b) という記事でした。
個人的にはがっつりスレッドを使ったら負けだと思っていますが、そうは言っても使わざるを得ないことも多々あるわけで、こういう風に具体的な使い方や使い分けがまとまっていると非常にありがたいですね。

今日は趣味で開発をしている QtWebService というプロジェクトの紹介をしたいと思います。

# QtWebService とは？

[QtWebService](http://qtwebservice.io) とは、[QML](http://doc.qt.io/qt-5/qmlreference.html) という言語でアプリケーションを記述し実行するためのウェブサーバーです。
2012年頃から **silk** という名前で開発をしていましたが、いつのころから改名をしました。

## 特徴１：QML で様々なコンテンツの生成が可能

QML という言語は「エレメント」と呼ばれる様々な**部品**をツリー構造で記述し、それぞれのエレメントに対して「プロパティ」と呼ばれる**パラメータ**を指定することが可能です。
QML のエレメントは [QObject](http://doc.qt.io/qt-5/qobject.html) のサブクラスとして自由に作成でき、QML のプロパティは Qt が C++ を独自拡張して提供している [QObject のプロパティ](http://doc.qt.io/qt-5/properties.html) として自由に作成することができるようになっています。
この柔軟な言語と拡張性を最大限に活用し、QtWebService では様々なコンテンツを QML という一つの言語で記述できるようにしました。

### QML で HTML を記述する

```qml:index.qml
import QtWebService.HTML 5.0

Html {
    Head { ... }
    Body {
        H1 { text: 'title' }
        P { text: '...' }
    }
}
```

生の HTML で記載するよりも何となく見やすいですね？

### QML で CSS を記述する

```qml:css.qml
import QtWebService.CSS 3.0

Css {
    Rule {
        selector: 'body'
        background_color: '0'
    }
    ...
}
```

QML は CSS にとても似ているので混乱しますね？

### QML で JSON を記述する

```qml:api.qml
import QtWebService.JSON 1.0

Json {
    object: {
        'key': 'width'
        , 'value': 100
    }
}
```

QML って JSON に似てますね？

### その他様々なフォーマットに対応しています

単に文字列を返すことも可能ですし、XML の API を提供する事も可能です。

## 特徴２：JavaScript でロジックが書ける

### JavaScript でコンテンツを変化させる
```qml:fortune.qml
import QtWebService.HTML 5.0

Html {
    Head { title: 'Fortune' }
    Body {
        H1 { text: 'Fortune' }
        P {
            text: {
                var results = ['大吉', '中吉', '小吉', '吉', '末吉', '凶', '大凶']
                return results[Math.floor(results.length * Math.random())]
            }
        }
    }
}
```

### HTTP のヘッダや入力、クッキーの対応

[QtWebService の examples](http://qtwebservice.io/examples.qml#logic) で様々なサンプルを提供していますが、`http` という名前のグローバルオブジェクトが提供する API によりフォームからの入力の取得やクッキーなど HTTP プロトコルの様々な機能を利用することができるようになっています。

## QtWebService を使ってみよう

[Getting Started](http://qtwebservice.io/getting-started.qml) のページにセットアップの手順が記載されています。現在 Linux でのみ動作確認をしていますが、Qt の API のみで作られているので macOS でも Windows でも Android でも iOS でも QNX でも INTEGRITY でも動くはずです。

## 開発者募集中

現在 QtWebService ではみなさんのお手伝いを必要としています。
開発だけではなく、公式コンテンツの充実やテストの整備、ドキュメントの充実など QtWebService に足りてないところを手伝っていただける方がいましたら、[@task_jp](https://twitter/task_jp) まで是非連絡ください。

開発は主に [qt-users.jp の gerrit](http://codereview.qt-users.jp/#/admin/projects/qtwebservice) で行っています。気軽に github のアカウントでサインインしてパッチを送ってください！

実は [Qt ユーザー会のウェブサイト](http://qt-users.jp/) も QtWebService で動いています。こちらも情報が古かったり足りなかったりしているので、みなさんの力でもう少しコンテンツを充実させていけたらいいなぁと思っているので、ちょっとでも QtWebService に興味をもたれた方は、[このへん](http://codereview.qt-users.jp/gitweb?p=qt-users.jp/www.git;a=tree;f=frontend;hb=HEAD) を見ながら適当に git push してもらえるとうれしいなー。

というわけで、おしまいです。明日は現時点で未定です！
ローカルでCloud FunctionsのHTTPS関数を実行する

修正 > デプロイを繰り返すのはツライので、ローカルで実行できる環境を整えたときのメモ

# Firebase CLIインストール

参考
* [Testing Functions Locally with the Cloud Functions Shell](https://firebase.googleblog.com/2017/09/testing-functions-locally-with-cloud.html)
* [Firebase Documentation - ローカルでの関数の実行](https://firebase.google.com/docs/functions/local-emulator#invoke_https_functions)
* [npm - request](https://www.npmjs.com/package/request)

---

上記のブログなどを参考に、Firebase CLIのバージョンをv3.11.0に上げてコマンドを試した。

```bash
experimental:functions:shell [options]     launch full Node shell with emulated functions
```
　
実行したところエラー出たので言われるがままv6.9.1にして再実行

```bash
functions: Cannot start emulator. Please use Node version v6.9.1, you have v7.3.0
```
　
またエラーとりあえずv6.11.5にして試してみる…

```bash
Node.js v6.11.x or greater is required to run the Emulator!
```
　
やっとローカル実行できるようになった

```bash
$ sudo firebase experimental:functions:shell
i  functions: Preparing to emulate functions.
✔  functions: test
firebase >
```

# HTTPS関数の実行

実行したかったのはHTTPS関数だったので、こちらを参考に。
[Firebase Documentation - HTTPS 関数を呼び出す](https://firebase.google.com/docs/functions/local-emulator#invoke_https_functions)
　
なので、testというファンクションを実行する場合はこうなる。

```js
test.get()
```
　　
下記のようにGETパラメータだけ付けて実行したいのだが…例の一覧には記載はなく。

```js
https://us-central1-xxxxxxx.cloudfunctions.net/test?key=value
```
　

> シェルで HTTPS 関数を呼び出す場合、使用方法は request NPM モジュールと同じですが

と書いてあったので、次のように実行したら思ったように動作した。

```js
test.get({qs: {key: 'value'}})
```
PeerCast プログラミング配信 Advent Calendar 2017 ６日目

# PeerCast プログラミング配信 Advent Calendar 2017 ６日目 メモ

一つの画面上で複数のAI(外部プログラム？)で遊ぶゲームを作ろうとした。

まだどんなゲームにしようか決めてないが、案としては  
1,迷路マップでアイテムを拾い合って拾った数を競うゲーム
2,武器を拾って他のAIに突撃して倒すゲーム
3,迷路マップでゴールまで競争（壁壊したりできる）

こんなところ

複数の外部プログラムにデータの受け渡し部分要調整
vagrant up で Homestead settings file not found と表示される

Laravel プロジェクトで、`vagrant up` 実行後に環境が立ち上がりませんでした。

# vagrant up で settings file not found

```
vagrant up

Homestead settings file not found in /Users/pugiemonn/Documents/pugiemonn.com/vendor/laravel/homestead
```
`Homestead settings file` が無いと書いてあります。一体これは何のことかなと思いました。


# Homestead.yaml を生成する
ドキュメントを見ると、 composer で Homestead をインストールした後に、`Vagrantfile` と `Homestead.yaml` を生成せよとあります。

```
php vendor/bin/homestead make
Homestead Installed!
```
`Homestead.yaml`が生成されました。

# 再度 vagrant up

```
vagrant up
Bringing machine 'pugiemonn' up with 'virtualbox' provider...
==> pugiemonn: Importing base box 'laravel/homestead'...

略
```
今度は環境が立ち上がりました(☝ ՞ਊ ՞)



# 参考
https://github.com/laravel/homestead/issues/519
https://readouble.com/laravel/5.5/ja/homestead.html
形態素解析とマルコフ連鎖を使って新たな文を作る

#SP2LCとの関わり
2年生からSP2LCと全国高専プログラミングプロジェクトに入って，現在4年生です．
主に自然言語処理に手を出しています．
#はじめに
チャットボット（人工無脳）に使われる方法である，
__形態素解析__と__マルコフ連鎖__を使って新たな文を作るアルゴリズムについてまとめました．
今回の手法を使った有名なチャットボットとして[しゅうまい君](https://twitter.com/shuumai)などがあります．

#形態素解析とは
>形態素解析とは、文法的な情報の注記の無い自然言語のテキストデータ（文）から、対象言語の文法や、辞書と呼ばれる単語の品詞等の情報にもとづき、__形態素（おおまかにいえば、言語で意味を持つ最小単位）の列に分割__し、それぞれの形態素の品詞等を判別する作業である。（[Wikipedia](https://ja.wikipedia.org/wiki/%E5%BD%A2%E6%85%8B%E7%B4%A0%E8%A7%A3%E6%9E%90)より）

簡単にいうと，文を解析して単語ごとに区切ったり，品詞や読み等の情報を得ることです．
今回は__単語ごとに区切る__ために使用します．

#マルコフ連鎖とは
>マルコフ連鎖は、__未来の挙動が現在の値__だけで決定され、__過去の挙動と無関係__である。各時刻において起こる状態変化（遷移または推移）に関して、マルコフ連鎖は遷移確率が過去の状態によらず、現在の状態のみによる系列である（[Wikipedia](https://ja.wikipedia.org/wiki/マルコフ連鎖)より）

今回の現在の値とは__単語ごとに区切った１つの塊__を指し，
未来の挙動とは__その単語に続く単語ごとの塊__を示します．

#新たな文を作ってみる
それでは文生成の仕組みについて説明します．
  
以下の2つの文があるとします．
（１）私はラーメンが好きです。
（２）俺はラーメンが嫌いだ。
  
これらの文を，形態素解析によって単語ごとに区切ると，以下のようになります．
（１）私　は　ラーメン　が　好き　です　。
（２）俺　は　ラーメン　が　嫌い　です　。
  
ここから，共通の単語をまとめて有向グラフを生成すると以下のようになります．

![Untitled1.png](https://qiita-image-store.s3.amazonaws.com/0/218735/1a6dd78c-8c55-a24d-c95f-3d638586a841.png)

あとはこのグラフの全ての経路をたどっていけば，入力の2文とそれ以外の文が生成されます．
全て列挙すると，以下のようになります．
（１）私　は　ラーメン　が　好き　です　。
（２）俺　は　ラーメン　が　嫌い　です　。
__（３）私　は　ラーメン　が　嫌い　です　。(New)__
__（４）俺　は　ラーメン　が　好き　です　。(New)__
  
仕組みは以上です．

プログラム上の動きとしては，
まず，形態素解析によって分けた単語を数個の塊にします．今回は3単語で1つの塊としています．  

__（１）__
__(BOS)　私　は__
__私　は　ラーメン__
__は　ラーメン　が__
__ラーメン　が　好き__
__が　好き　です__
__好き　です　。__
__です　。（EOS）__
  
__（２）__
__(BOS)　俺　は__
__俺　は　ラーメン__
__は　ラーメン　が__
__ラーメン　が　嫌い__
__が　嫌い　です__
__嫌い　です　。__
__です　。（EOS）__
  
BOS（Begin of sentence）は文の始まり，
EOS(End of sentence)は文の終わりを示します．

あとは，
BOSを始点，EOSを終点として，
しりとりのように，各グループの最後の単語を探索していくことでグラフをたどることができます．

#おわりに
今回は2つの文を入力とした単純な例でした．
多くの違う構造の文を入力すればするほど，グラフのネットワークは複雑になり，探索時間は増大しますが，
その分面白い文も生成されるので，ぜひやってみてください！
KivyでOpenGLが2.0以上なのに認識せず Kivy Fatal Errorになるとき(Windowsのみ)

#環境
Pythonのバージョン: 3.6.2
Kivyのバージョン: 1.10.0
Windows 10

#内容
実行時に↓のようなメッセージが表示され、アプリケーションが終了する

>Kivy Fatal Error
>GL: Minimum required OpenGL version(2.0) NOT found!
>OpenGL Version detected: 1.1
>Version: b'1.1.0'
>Vendor: b'Microsoft Corporation'
>Renderer: b'GDI Generic'
>Try Upgrading your graphics drivers and/or your graphics hardware in case of
>problems.
>The application will leave now

#解決方法
(注意:この方法はWindowsで動作します。)
kivyで使用するOpenGLのバックエンドをangle_sdl2に変更します。
angle_sdl2を利用するにはkivy.deps.sdl2とkivy.deps.angleが必要なので、
pipでkivy.deps.sdl2とkivy.deps.angleをインストールします。
`python -m pip install kivy.deps.sdl2`
`python -m pip install kivy.deps.angle`

##方法#1
次に、コードの先頭に

```python:myapp.py
import os
os.environ ['KIVY_GL_BACKEND'] = 'angle_sdl2' 
```
と記述すれば実行できます。


##方法#2
環境変数 KIVY_GL_BACKEND を追加し、値をangle_sdl2に設定すれば実行できます。

参考元:
https://github.com/kivy/kivy/issues/3576
https://kivy.org/docs/api-kivy.graphics.cgl.html#module-kivy.graphics.cgl
ブロック要素の上下左右中央揃え

# ブロック要素の上下左右中央揃え

結構シンプルに実現できます。

```
.center {
  margin: auto;
  position: absolute;

  top: 0;
  left: 0;
  right: 0;
  bottom: 0;

  height: 10.0em; //要調整
}
```


以上です。
pukiwikiにランダムページ機能を実装する

pukiwiki内のページにランダムにアクセスできたら面白いよねって感じで、作ってみました。

# プラグインの作成
ページ一覧を取得し、その中からランダムに1つ選択
取得したページへのリンクを張る。

```php:randomlink.inc.php
<?php

function plugin_randomlink_convert()
{
    $pages = array();
    $i = 0;
 
    //すべてのページ一覧を取得
    $pages = get_existpages();

    //ページ数をカウント
    $size = count($pages);
    //ランダムで一つのページをとる
    $rand_page = array_rand($pages, 1);
    //.txt拡張子名削除
    $rand_page = substr($rand_page, 0, -4);
    //ページ名の整形(分割、2文字ごとに%を入れる)
    $randpage_array = str_split($rand_page, 2);

    while($i < count($randpage_array)){
        $randpage_array[$i] = "%".$randpage_array[$i]; 
        $i++;
    } 
    $rand_page = join('', $randpage_array);

    //htmlの形にする
    $href   = get_page_uri($rand_page);

    //%記号がなぜかエンコーディングされるので、とりあえず25の部分を消去
    $href = str_replace("25", "", $href);

    //終了
    $res = '<a href='.$href.'>ランダムページ</a>';
    return $res;
}

//ページのファイル名からURLに変更する関数
function get_page_uri($page, $query = '')
{
    if (function_exists('get_script_uri')) { // from pukiwiki 1.4
        $url = get_script_uri() . '?' . rawurlencode($page);
    } else {
        global $script;
        $url = $script . '?' . rawurlencode($page);
    }
    if ($query != '') {
        $url .= '&amp;' . $query;
    }
    return $url;
}

?>
```

これをpluginフォルダに保存。
Wiki内のランダムページへのリンクを張りたい部分に

```
#randomlink
```

を記述

# 課題
ランダムページへのリンクはリンクを張るページが生成された時点で作成される。
そんなわけで、「ランダムページに飛ぶ」→「戻る」→「ランダムページに飛ぶ」だと同じページに飛ぶ。
swift TCP/IP接続でパーミンションエラー


#問題

swiftのstreamを使ったTCP/IPクライアントでコネクションをオープンしようとすると、Operation not permittedとなり接続できない。

`2017-12-06 22:49:55.115031+0900 Game3D[1038:66476] [] nw_socket_connect connectx failed (fd 6, 192.168.1.23:8081 stream, pid: 1038): [1] Operation not permitted`

#解決策
xxx.entitlementsにcom.apple.security.network.clientを追加する。

<img width="961" alt="sandbox.png" src="https://qiita-image-store.s3.amazonaws.com/0/187104/bd4e5ce8-5c4b-5da3-166a-5ec75246cefa.png">
python3でPostgreSQLに接続する

# psycopq2を使用して接続する


## psyopq2をダウンロード
公式サイト：http://initd.org/psycopg/download/

↑にある通り、pipを使う

```
pip install -U pip # pip自体を最新のもの
pip install psycopg2
```
## python3からの接続

```py3
>>> import psycopq2
>>> connection = psycopg2.connect(host="localhost", database="＜データベース名＞", user="＜ユーザー名＞",password="＜パスワード＞")
```
何もエラーが出なければ接続OK
日本語で言語を作ろう 2 : ラムダ計算

好評だったので、(といってもtwitterで5,6人にリツイートされただけですが)
今回は、ラムダ計算を日本語で作ってみました。

```prolog
:- op(1200,xfx,ならば).
:- op(1000,xfy,かつ).
:- op(750,xfx,[の環境で]).
:- op(720,xf,[の要素]).
:- op(700,xfx,が).
:- op(700,xfx,[を評価すると,の型は]).
:- op(20,xf,[で関数適用,が変数,が整数]).
:- op(10,xfx,[を]).
term_expansion(A ならば B,B:-A).
A,B ならば A かつ B.
integer(A) ならば A が整数.
atom(A) ならば A が変数.
B is A ならば A が B.
A が (_,A) の要素.
A が E の要素 ならば A が (E,_) の要素.

% 評価規則

I が整数 ならば _ の環境で I を評価すると I.
E の環境で T1 を評価すると V1 かつ E の環境で T2 を評価すると V2 かつ V1+V2 が C
ならば E の環境で T1+T2 を評価すると C.
E の環境で T1 を評価すると V1 かつ E の環境で T2 を評価すると V2 かつ V1-V2 が C
ならば E の環境で T1-T2 を評価すると C.
E の環境で T1 を評価すると V1 かつ E の環境で T2 を評価すると V2 かつ V1*V2 が C
ならば E の環境で T1*T2 を評価すると C.
E の環境で T1 を評価すると V1 かつ E の環境で T2 を評価すると V2 かつ V1 div V2 が C
ならば E の環境で T1/T2 を評価すると C.
X が変数 かつ (X=V) が E の要素 ならば E の環境で X を評価すると V.
E の環境で 'ラムダ抽象'(X,T) を評価すると 'クロージャ'(E, X, T).
E の環境で T1 を評価すると 'クロージャ'(E1,X,T), E の環境で T2 を評価すると V2 かつ
(E1,X=V2) の環境で T を評価すると V
ならば E の環境で T1 を T2 で関数適用 を評価すると V.

:- '空' の環境で 'ラムダ抽象'(x,x+1) を評価すると 'クロージャ'('空',x,x+1).
:- '空' の環境で 1 を評価すると 1.
:- ('空',x=10) の環境で x を評価すると 10.
:- '空' の環境で 'ラムダ抽象'(x,x+1) を 1 で関数適用 を評価すると 2.
:- halt.
```

日本語でラムダ計算を実装して実行してみることが出来ます。

たしかに面白いけど、こんな、わけのわからないことをして何の意味があるのだとお思いかも知れません。しかしそう思うことこそが、日本のIT教育の敗北であるように思います。なぜならば、ここに書いてあるプログラムの内容は計算機科学の初歩の初歩であるからです。日本語で書けば読みやすいけれども、長くなるし、国際的に共有しづらいものであるからこそ、記号を使った式が有効であるのです。はじめに定義を書いておき、その定義を使って文章を書くということは、論理的に整合性の取れた文章を書くことにもつながるのですから。
簡単な動的コンテンツを data URL にしてブックマークに入れて使う

一発だけ簡単なタスクをこなす動的コンテンツを data URL の形にしてブックマークに入れておくと便利なことがあります。

# 簡単なページ遷移 HTML + JavaScript を data URL にする

例えば以下の HTML + JavaScript は、アクセスすると今日の日付（例えば「12月6日」など）の Wikipedia ページへ遷移するものです。

```html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript">
var now = new Date();
var url = "https://ja.wikipedia.org/wiki/"+(now.getMonth()+1)+"%E6%9C%88"+now.getDate()+"%E6%97%A5";
location.href = url;
</script>
</head>
<body></body>
```

このスクリプトを data URL にしてみましょう。

```html
data:text/html, <!DOCTYPE html><html><head><meta charset="UTF-8"><title></title><script type="text/javascript">var now = new Date();var url = "https://ja.wikipedia.org/wiki/" + (now.getMonth()+1)+"%E6%9C%88"+now.getDate()+"%E6%97%A5";location.href = url;</script></head><body></body>
```

画像などを data URL で表現するときには Base64 形式がよく使われますが、今回は単純なテキストのみなので、そのまま記載してあります。

この data URL をブラウザの URL 欄に入力すると、すぐさま Wikipedia の「MM月DD日」のページに遷移することでしょう。

# ブックマークレットとの違い

ブックマークレットとの違いが気になった方もいるかもしれません。

* ブックマークレットは現在表示しているページへの JavaScript コードの埋め込みなので、HTML以外の（DOM構造がない）画像ファイルなどを現在のブラウザ上で開いていた場合の動作や、そのブックマークレットを「新規ウィンドウで表示」といった操作はできない（ブラウザによってはできる場合もあり）
* 上記の例は描画にフォーカスを当てなかったものの、data URL であればボタンなどの描画も可能

画面を描画する例

```html
<!DOCTYPE html>
<html><head><meta charset="UTF-8"><title>今日のWikipedia</title>
<style type="text/css">
button { width: 100%; font-size: 2em; }
</style>
</head><body>
<button id="go_to_today">今日の記事</button>
<button id="go_to_yesterday">昨日の記事</button>
<script type="text/javascript">
var now = new Date();
var today_url = "https://ja.wikipedia.org/wiki/" + (now.getMonth()+1)+"%E6%9C%88"+now.getDate()+"%E6%97%A5";

var yesterday = new Date( now.getTime() - 86400 * 1000 );
var yesterday_url = "https://ja.wikipedia.org/wiki/" + (yesterday.getMonth()+1)+"%E6%9C%88"+yesterday.getDate()+"%E6%97%A5";

document.getElementById("go_to_today").addEventListener("click", ()=>{location.href=today_url;});
document.getElementById("go_to_yesterday").addEventListener("click", ()=>{location.href=yesterday_url;});
</script>
</body><html>
```

「今日の記事」「昨日の記事」という2つのボタンを表示して、どちらの記事を表示するか選ぶことができます。

```html
data:text/html, <!DOCTYPE html><html><head><meta charset="UTF-8"><title>今日のWikipedia</title><style type="text/css">button { width: 100%; font-size: 2em; }</style></head><body><button id="go_to_today">今日の記事</button><button id="go_to_yesterday">昨日の記事</button><script type="text/javascript">var now = new Date();var today_url = "https://ja.wikipedia.org/wiki/" + (now.getMonth()+1)+"%E6%9C%88"+now.getDate()+"%E6%97%A5";var yesterday = new Date( now.getTime() - 86400 * 1000 );var yesterday_url = "https://ja.wikipedia.org/wiki/" + (yesterday.getMonth()+1)+"%E6%9C%88"+yesterday.getDate()+"%E6%97%A5";document.getElementById("go_to_today").addEventListener("click", ()=>{location.href=today_url;});document.getElementById("go_to_yesterday").addEventListener("click", ()=>{location.href=yesterday_url;});</script></body><html>
```

今回の例は遷移前は完全にローカルのみで完結させましたが、http や https の URL を使って外部から画像や JavaScript ライブラリを取ってくることもできます。
electron-builderで作ったpkgをインストールする際に実行されるスクリプトを用意する

この記事は モバイルファクトリー Advent Calendar 2017 6日目の記事です。

## 概要

Macでpkg拡張子を持つインストーラでは、インストール時に実行されるシェルスクリプトを配置することができ、electron-builderでもサポートされている。

## Dependencies

``` package.json
{
  "electron-builder": "19.48.2"
}
```

## 何ができるのか

https://www.electron.build/configuration/pkg

electron-builderで作るpkgでは、`build/pkg-scripts`以下に`postinstall`または`preinstall`というコマンドスクリプトを配置することでインストール時にhookして実行してくれる。

実行タイミングはファイル名の通り、`preinstall`はインストール前。`postinstall`はインストール後。

具体的な用法についてelectron-builder自体のドキュメントに説明が無いので分かりにくいが、electronのドキュメント中で提示されている資料とかコミットログとか、あとmacのpkgについて調べてみると出てくる。

- 資料: http://macinstallers.blogspot.jp/2012/07/scripting-in-installer-packages.html
- 該当commit: https://github.com/electron-userland/electron-builder/commit/2eb12987ce1842a8291595ea9cdcf4db3e8fe298#diff-ca9a81b8204b29fbe42a0cf8168b0a04

## 使い方

package.jsonの設定は以下の通り

``` package.json
{
  "build": {
    ...
    "mac": {
      ...
      "target": {
        "target": "pkg",
        "arch": [
          "x64"
        ]
      }
    },
    "pkg": {
      "scripts": "pkg-scripts" // ここで明示的に配置場所を宣言できる
    },
    ...
  }
}
```

``` code:build/pkg-scripts/postinstall
#!/bin/sh

# インストール完了後、hogeが生成される

touch /Users/***/hoge
```

スクリプト内で使用できる変数は以下の通り

- `$1`: 実行しているpkgのフルパス
  - 例: /Volumes/Users/Vikrams/Desktop/TestPkg.pkg
- `$2`: インストール先のディレクトリのフルパス 例: /Applications
- `$3`: ペイロードを受け取るためのボリューム（またはマウントポイント）
  - 例: /Volumes/Tools
- `$4`: システムのルートディレクトリ
  - /
- `$SCRIPT_NAME`: 実行するファイル名
  - 例: preflight
- `$PACKAGE_PATH`: `$1`と同じ
- `$INSTALLER_TEMP`: インストール実行時に置かれるテンポラリファイル。 この領域を一時的な作業に使用することもできるが、インストーラファイルを上書きしてはいけない。 このファイルはインストール完了時に削除される。 
  - 例: /private/tmp/.vikrams.pkg.234.install


## 利用例

- アプリケーションインストール後に自身を起動する
- アプリケーションと一緒にcliもインストールする。
  - 例えばAtomだと`メニュー -> Atom -> Install Shell Commands`から`atom`コマンドがインストールできるが、`postinstall`コマンドを配置しておけばインストールと同時にcliコマンドを作ってしまえる。
  - Atomは`/Applications/Atom.app/Contents/Resources/app/atom.sh`にリンクを張っている

あまりインストール後にゴミが残ることは推奨できませんが、単純にappを生成するよりもアプリケーションの幅が広がるので、Mac向けビルドならば検討して良いと思います。
スマホサイトのランドスケープ対応(画面横向き対応)をする時間がなくてアイデアで乗り切った話

この記事は、[株式会社Y's アドベントカレンダー](https://qiita.com/advent-calendar/2017/ysinc)7日目の記事になります。

ディレクター出身の初心者エンジニアの私が自社コーポレートサイトを実装したときの経験談。
ディレクター時代に培った提案力が功を奏し、アイデアがたまたま採用されて乗り切れただけなので参考になるかはわかりませんが、あまり書かれていなさそうな方法だったのと、そこにたどり着いた経緯を忘れたくないので、備忘録的に残しておきます。
※方法のみを知りたいという方は、『[実際に使った手法②](https://qiita.com/The3rd_Ysinc/items/1b7bcbc4036aa97bb958#%E5%AE%9F%E9%9A%9B%E3%81%AB%E4%BD%BF%E3%81%A3%E3%81%9F%E6%89%8B%E6%B3%95-1)』から読むことをおすすめします。

# 普通のランドスケープ対応がしたかった
普段スマホでwebサイトを訪れた際に、端末を横向きにして見るケースは個人的にほとんどないし、自分の周りでもそうしている人はあまり見たことがありません。
それでも世の中に一定少数は居るらしく、その人達のために対応をしてあげる必要があります。
デザインにもよりますが、よくある対応方法としては、要素の幅や高さを`%` `vw` `vh`などのフレキシブルな単位で指定をするか、縦で見た際と同じ要素サイズ、同じレイアウトで組んであげて、両端の余白だけ大きくするといったものでしょうか。

しかし今回、一部実装を他のエンジニアに手伝ってもらった際に、下記が原因となり、ランドスケープ対応が非常にしづらいコードになってしまいました。

- 対応範囲等、要件定義の曖昧さ(私が悪い)
- コーディングルールのオリエンの不十分さ(私が悪い)
- コードレビュー分を開発工数に見積もっていなく、満足に実施できなかった(私が悪い)

# デザインのこだわり
そもそも前提としてですが、弊社はもともとデザイン会社で、デザイナーのこだわりが随所に光る作品が多いです。
横長の画面も作り込むことを当初から意識してマークアップの設計をしていないと、とてもじゃないけどこだわりを保つことができないということに、「いざランドスケープ用にスタイルを調整しよう」というタイミングで気づきました。

# アイデアで解決する方向に
先にも述べていますが、私は元々ディレクターで、課題解決のアイデア出しを生業としていた人間です。
今回もなんとかアイデアが出ないかと頭をひねった結果、こんなアイデアが浮かびました。

「***横向きで崩れるなら、横向きにさせなければいいんだ！***」

行き着いた先は非常にシンプルでした。
単純に、"横に向けることを禁止させる"というものです。

しかし禁止させると言っても、調べても調べても「画面の向きはプログラム側では制御できない」という記事しか見当たりません。さてどうしたものか。。

# 実際に使った手法①
考え方を変えて、横向きになっちゃった後に何かすることを考えます。
ここでまず頭に浮かぶのが、画面回転検知のイベントです。
検知イベントは`orientationchange`で取得できます。
これだけだとandroidではうまく動作しないことがあるそうなので、
`load`と`resize`も追加しておくといいそうです。

```sample.js
$(window).on('load orientationchange resize', function() {
    // 画面回転時の処理
});
```

そして、回転の検知のみではなく、それが縦向きか横向きかを判断する必要があります。

```sample.js
$(window).on('load orientationchange resize', function(){
    if (Math.abs(window.orientation) === 90) {
        // 横向きになったときの処理
    } else {
        // 縦向きになったときの処理
    }
});
```

次に思いついたのが、「回転を検知したらすぐに強制的に画面の向きを戻す」こと。
しかしこれをプログラムでやろうとするにはちょっとトリッキーだし
バグを生みそうなので断念。

発想の転換をして、なんとか手動で向きを戻させることを考えます。
このとき思いついたアイデアが最終形になりました。

# 実際に使った手法②
最終的にたどり着いたアイデアがこちら。
![IMG_3037.JPG](https://qiita-image-store.s3.amazonaws.com/0/190207/48929672-631c-870e-b2fd-dee1ed1fa45d.jpeg)

シンプル！！！！
「***画面を縦向きに戻してね***」と1枚の画像で伝えるだけです。

この提案がデザイナーにもとても気に入られ、デザインが30分後くらいには上がってきました。



↓出来上がったデザイン。
![IMG_3018.png](https://qiita-image-store.s3.amazonaws.com/0/190207/2c968a7d-1147-9672-5209-fe97b47a4c2f.png)

↓実際に実装したサイトはコチラ
[株式会社Y'sオフィシャルWebサイト](https://ysinc.co.jp/sp/)
(スマホで見てください)



# 実装方法

```sample.js
$(window).on('load orientationchange resize', function(){
    if (Math.abs(window.orientation) === 90) {
        // 横向きになったときの処理
        $(横向き時に表示させる画像).show();
    } else {
        // 縦向きになったときの処理
        $(横向き時に表示させる画像).hide();
    }
});
```
これだけです。
横向きになった際に画面全体を覆う上記アラート画像を表示して位置を固定し、縦向きに戻ったら画像を非表示にしています。
※画像が画面全体を覆うようにしたり、位置を固定するのはCSSで簡単にできますので割愛します。

# 伝えたかったこと
今回の一件で学んだことは以下の3つ。

- 必ずしも技術で解決する必要があるわけではないということ
- 使える時間と、要望・要件を正しく汲み取り判断した上で、最適な手段を選ぶ必要があるということ
- 人を巻き込むことが思った以上に大事だということ


でも最初から正しい設計ができていればこうはなっていなかったし、なったとしても私が思いついていないだけで他にも解決策はあったかもしれないので、結局実装においては技術力と正しい思考が一番大事だということは言うまでもありませんね。

現在私はまたディレクションやマーケティングの畑にいますが、引き続き技術系のインプットは続けていきたいと思っています。


次は 8日目 @Bong さんの記事です。お楽しみに！
RubyのProc#curry

Rubyのカリー化について個人的に調べたのでまとめます．

## カリー化
カリー化は関数型言語でよく使われているもので、複数の引数をとる関数を、引数を一つずつ受け取れるようにすることです．

たとえば、$f(x, y) = z$ という関数があったときに、$F(x) = g$ かつ $g(y) = z$ となるような $F$ がカリー化された $f$ にあたります．

下の数式はWikipediaの[Currying](https://en.wikipedia.org/wiki/Currying)にあった数式ですが、こちらの方がわかりやすいかもしれません．

```math
f: (X \times Y \times Z) \rightarrow N\\
\mathrm{curry}(f): X \rightarrow (Y \rightarrow (Z \rightarrow N))
```

このカリー化ですがRubyでも使うことができます．例を挙げていきます．

```rb
product = -> (a, b) { a * b }
curried_product = product.curry
```

これがカリー化です．`Proc#curry`を使うことで、Procオブジェクトをカリー化できます．カリー化された`lambda`とされていない`lambda`とで振る舞いを比べてみます．

```
[3] pry(main)> product.(2)
ArgumentError: wrong number of arguments (given 1, expected 2)
from (pry):1:in `block in __pry__'
[4] pry(main)> curried_product.(2)
=> #<Proc:0x00000000983960 (lambda)>
```

`product`では引数が足りないと`ArgumentError`が出ているのに対し、`curried_product`では`Proc`オブジェクトが返ってきていることがわかります．
さらに適用したい場合は以下のようにするだけです．

```rb
curried_product.(2).(3) # => 6
```

また、返り値が`Proc`オブジェクトなので、別の変数に代入して使うことも当然可能です．

```rb
double = curried_product.(2)
triple = curried_product.(3)

double.(4) # => 8
triple.(4) # => 12
```

また適用は一つずつに限らず、複数の値を同時に適用することも可能です．

```rb
double_triple = -> (a, b, c) { a * b * c }.curry.(2, 3)
double_triple.(4) # => 24
```

ラムダ式に可変長引数をとらせる際には少し注意が必要で、例えば次のような可変長引数をとるラムダ式があったときに、ただ`Proc#curry`をしてもうまくいきません．

```rb
multi_product = -> (*a) { a.inject(:*) }
multi_product.curry.(2) # => 2
multi_product.curry.() # => nil
```

考えてみれば当然で、引数の数としては0個でも十分なため値を返されてしまいます．引数の数を`Proc#curry`に引数として渡す必要があります．

```rb
multi_product.curry(2).(2) # => #

double = multi_product.curry(2).(2)
triple = multi_product.curry(2).(3)
double_triple = multi_product.curry(3).(2, 3)
```

### 注： カリー化と部分適用の違い

よく混同される二つの概念ですが、`curried_product = -> (a, b) { a * b }.curry`の部分がカリー化、`curried_product.(2)`の部分が部分適用と思えば、区別自体なんてことないと思います．
誤解の例としてよく挙げられるのが、Groovyというプログラミング言語ですが、`curry`というメソッド名なのに、その実、部分適用を行っています(カリー化だけを独立して行うことができません)．
その点、Rubyの`curry`は正しく実装されています．

## なにが便利か
やはり`Proc`オブジェクトなので、`map`のような高階関数に渡すことができるのが大きなメリットだと思います．
数の配列が与えられたとき、すべての数を2倍, 3倍, 100倍した`Array`をそれぞれ欲しいというときにどうするでしょうか．

```rb
(1..10).map { |i| i * 2 }
(1..10).map { |i| i * 3 }
(1..10).map { |i| i * 100 }
```
と書いても良いですが、カリー化を使えば、

```rb
product = -> (a, b) { a * b }.curry
(1..10).map(&product.(2))
(1..10).map(&product.(3))
(1..10).map(&product.(100))
```

と書けます．個人的には下の方が好みです．
もう一つくらい例を挙げてみます．与えられたスコアに対して、ある範囲外にある異常値を除くという処理があったとします．

```rb
is_irregular = -> (lower, upper, score) { score.nil? || score < lower || upper < score }.curry
arr.reject(&is_irregular.(0, 100)) # 100点満点のテスト
arr.reject(&is_irregular.(10, 990)) # TOEIC
arr.reject(&is_irregular.(0, 120)) # TOEFL
```

このように高階関数をすっきり書けるのが魅力だと思います．

## 物足りないところ

例えばHaskellだと`flip`という関数を使うと、引数の順番を入れ替えることができるため、任意の箇所に部分適用することができるようです．一方で、Rubyにはそのようなメソッドはないため、部分適用したい引数を先に書く必要があります．

上の`is_irregular`と名付けたラムダ式も個人的には`(score, lower, upper)`という順番の方が好みですが、その制約上仕方なく`(lower, upper, score)`という順番にしています．
DOMの基本

## はじめに
Webの世界に入って(?)１年ですが、DOMについてなんとなくしか理解してなかったので、まとめてみます。

## DOMとは
Document Object Model の略。ひとことでいうと、HTMLなどのマークアップ言語を、JavaScriptなどのプログラミング言語で操作するための、API(Aplication Programming Interface)といえます。Ajaxなどの技術も、DOMを用いて実現されています（たぶん）。

DOMでは、その名の通り、文書の要素をそれぞれオブジェクトとみなします。つまり、文章全体はオブジェクトの集合です。

## ドキュメントツリー
DOMにおいて、HTMLはツリー構造として扱われます。例えば、以下のHTMLは、次のようなツリー構造を持っています。

```html:index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>DOMの基本</title>
</head>
<body>
 <p id="identical">これが<strong>ドキュメントツリー</strong>だ！</p>
</body>
</html>
```

```
html
├── body
│   └── p
│       └── strong
└── head
    ├── meta
    └── title
```

このhtmlタグ一つ一つはノードと呼ばれ、ノードを指定するために、XPath、CSSセレクタなどの方法があったりします。

たとえば、pタグの「DOMの基本」を指定するXPathは、

```
/html/body/p[@id="identical"]
```

あるいは

```
//p[@id="identical"]
```

となります。
homestead の laravel プロジェクトを vagrant up したときに homestead.rb が無いと言われる

laravel プロジェクトを git clone してきて、 vagrant up したら立ち上がりませんでした。環境は Mac + Vagrant です。

# Homestead の立ち上げを試みる

```
vagrant up

There was an error loading a Vagrantfile. The file being loaded
and the error message are shown below. This is usually caused by
a syntax error.

Path: /Users/pugiemonn/Documents/pugiemonn.com/Vagrantfile
Line number: 0
Message: LoadError: cannot load such file -- /Users/pugiemonn/Documents/pugiemonn.com/vendor/laravel/homestead/scripts/homestead.rb
```

`This is usually caused by a syntax error.` と書いてありますが、ここは、vendor ディレクトリ内のファイルが無いことに注目します。

# composer update
vendor 以下のファイルが無いなら composer install をすると良さそうです。

```
composer update
```
もろもろファイルがインストールされました。

# 再度 vagrant up

```
vagrant up 
```
今度はエラーが出なくなりました(☝ ՞ਊ ՞)
僕とVimの1年間

## はじめに
この記事は[Vim Advent Calendar 2017](https://qiita.com/advent-calendar/2017/vim)の7日目の記事です。

この記事では、筆者とVimの出会いと日々、そしてこれからについて記しています。
まだ1年と少しという短いVimとの日々を振り返りながら、読者の皆さんにVimの魅力を伝えることをゴールとします。

ただの年末のテンションから生じた叙事詩的なテキストなので、お気軽にお楽しみください。

## 筆者
筆者のプロフィールはざっくりと以下の通りです。

* ソフトウェアエンジニア暦は1年3ヶ月
* 組み込みの業界で開発者として勤務
* 文系卒(歴史学)
* 前職ではアパレルの販売職を5年ほど務めた

## Vimとの出会い
僕とVimの出会いは、ソフトウェアエンジニアとしてデビューする、数ヶ月前(2016年、8月頃)でした。

ソフトウェアエンジニアへ転職するべく、半年弱の組み込みの開発の教育を受けていた時のことでした。
当時は、時間もたくさんあったので、`Raspberry Pi`に電子部品を組み合わせてよく遊んでいました。
その手の手順書には、「`vim xxx`で設定ファイルを開く」といった、内容のものが時々あり、
それが最初にVimを開いた瞬間だったと記憶しています。

そしてその時は、やはりというか、お決まりの、

「なんだこれ!!!!!!!!!!!!」
「入力できひん!!!!!!!!!!」
「終了できひん!!!!!!!!!!」

という状態へ陥り、第一印象は最悪でした。

「こんなんnanoで開いたらええやんけ」
当時はそう思ったりしていました。

## Vimとの再会
Vimの洗礼を受けてから2ヶ月後、教育のカリキュラムはLinux(CentOS, 組み込みLinux)を使用したものとなっていました。
そこでVimと再会することとなります。

そのカリキュラムのテキストでは、様々な編集は全てVimで行うようになっていました。
今思えばなかなか「いい」テキストだったと思います。

そこで筆者は幸いにも、じわじわとVimに馴れていくことができました。
ググると出てくる様々なコマンド。(`dd`で行削除とか、置換コマンド`substitute`とか)
偶然ながら、僕に「テキストエディタ」というものの強力さをはじめに教えてくれたのは、Vimでした。

## Vimとの意気投合
そして、その2ヶ月後、いよいよソフトウェアエンジニアとしてデビューを果たします。

その現場の上司は、エクストリームなVimmerでした。
これも僕にとっては幸運なことでした。

そして、その現場に入って、Vimを使う上でとんでもない誤りをしていたことをその上司に指摘されます。

「カーソル移動を十字キーで行っていた」 のです。
Vimにはノーマルモードとhjklキーによる移動という、素晴らしいカーソル移動手段があることの、
その重要性をないがしろにしていたのです。

これの修正には大いに苦労をしました。
そもそも、タッチタイプも満足にできなかったヒヨッコプログラマだった僕は、
必死でVim経由でタイピングの特訓を行いました。

その甲斐もあって、エンジニアになって一月が経つ頃には、
Vimでタイプすることが、とてもとても気持ちのいいことになっていました。

それにより、Vimといよいよ意気投合ができたと感じました。
そして、Vimと僕との毎日が始まっていきました。

## Vimとの1年
そして、Vimと働きだしてからの1年は、いつでもVim共にあったと振り返っています。

ソースコードを書くとき。
簡単なテキスト処理をするとき。
社内のイントラネットへ書き込む内容を編集するとき。
バイナリを開くとき。
ソースの差分をとるとき。
Gitのコマンドを実行するとき。
IDEのテキストオープンをリモートでジャックするとき
……

実質的にVimは僕にとってはIDEとして働いていてくれたと考えています。

そして、ソフトウェアの中でも、テキストエディタというものへ特別な興味を抱かせてくれたと感じています。

ちなみに、Vimの一番好きなところは、「小さなコマンドの組み合わせで多彩な機能を実現している」ことです。
Unix的で素敵。

## Vimとのこれから
僕はVimは世のテキストエディタ群において、文化的に以下のような位置づけと考えています。

「文化の黎明期から隆盛期にかけて登場する、最も文化的で格式性に富んだものごと」

まあ、スターウォーズでいう、ライトセーバーみたいなイメージです。笑

だから、今後Vimのような思想をもったエディタはきっと現れないと考えています。
そして、人間がテキストベースのインターフェースでコンピュータとコミュニケーションができる限り、
その思想は不変であり続けると考えています。

というわけで、今後は自分もVimが好きで、テキストエディタが好きな人間として、
微力ながらVimのコミュニティに貢献していきたいと考えています。

## まとめ
そんなこんなでダラダラと筆者とVimのあれこれをご紹介しました。
最後までお読みいただき、誠にありがとうございます。


この記事も、edited by Vim 100%でお送りしました。
indexedDB の基本をまとめてみた

---

## indexedDBとは

#### 値とオブジェクトをローカルデータベースに保持するウェブブラウザの標準インターフェース


---

## DBに接続


### open

```javascript
var request = window.indexedDB.open('MyTestDatabase')
```

第2引数にバージョンを指定することができる

---

## エラーハンドラを設定する

```javascript
var db;

// DB に接続
var request = indexedDB.open("MyDatabase");

// 接続失敗
request.onerror = function(event) {
 alert("接続に失敗しました");
};

// 接続成功
request.onsuccess = function() {
  db = event.target.result;
};
```

---

## スキーマを作成

#### openするとonupgradeneededイベントが呼び出されます

```javascript
var db
var request = indexedDB.open('MyDatabase', 1)
var index
var store
request.onupgradeneeded = function () {
    db = request.result

    // MyObjectStore　を作成　key は id
    store = db.createObjectStore('MyObjectStore', {keyPath: 'id'})

    // インデックスを作成 key は name.last, name.first 
    index = store.createIndex('NameIndex', ['name.last', 'name.first'])
}
```


---

## データの書き込み


```javascript
db = request.result

// 　readwrite : 読み書きを開始
var tx = db.transaction('MyObjectStore', 'readwrite')
store = tx.objectStore('MyObjectStore')
index = store.index('NameIndex')

// データの追加
store.put({id: 12345, name: {first: 'John', last: 'Doe'}, age: 42})
store.put({id: 67890, name: {first: 'Bob', last: 'Smith'}, age: 35})
```

---

## データの呼び出し

```javascript
// store からデータ取得 key は id
var getJohn = store.get(12345)
// => {id: 12345, name: {first: 'John', last: 'Doe'}, age: 42}

// index からデータ取得 key は [name.last, name.first]
var getBob = index.get(['Smith', 'Bob'])
// => {id: 67890, name: {first: 'Bob', last: 'Smith'}, age: 35}

getJohn.onsuccess = function () {
  console.log(getJohn.result.name.first)  // => "John"
}

getBob.onsuccess = function () {
  console.log(getBob.result.name.first)   // => "Bob"
}

// 読み書き終了
tx.oncomplete = function () {
  db.close()
}
```

---

#### 参考

[IndexedDB を使用する - Web API インターフェイス | MDN](https://developer.mozilla.org/ja/docs/Web/API/IndexedDB_API/Using_IndexedDB)
CentOS7で/tmpや/var/tmpに保存したファイルが見えなくて悩んだ

# 事象

WEBアプリケーションでファイルを`/tmp`に保存してダウンロードさせる機能を作ったのですがその際にサーバーに接続して`/tmp`の中身を確認しても保存したものが表示されないということがありました。
アプリケーションからはファイルの存在は確認できるが、サーバーに接続して`/tmp`を確認すると存在しないという感じです。

# 原因

インフラの方に聞いてみたところ、CentOS7からsystemdになった影響で`/tmp`はサービス毎に実体が異なるようになったということでした（PrivateTmpという機能らしいです（デフォルトで有効））。
WEBアプリケーションで`/tmp`に保存したものはWEBサーバーのサービスから保存したものになるのでそのサービスの`/tmp`に保存されるということでした。

更に確認すると`/tmp`ではなく以下に保存されていました。

```
/tmp/systemd-private-995039d4086a4e60b901dbfe2da2d4dd-php-fpm.service-XDbfC3/tmp/
```

# 対応

PrivateTmpを無効にするか、アプリケーション専用のtmpフォルダを作ってそこに保存する。
後者の場合は`/tmp`の自動削除が機能しないので自動削除を設定するか、基本一時保存のものなので使い終わったら削除することを忘れない等の対策が必要です。

# メモ

CentOS7からsystemdになったのでtempwatchがなくなってsystemd-tmpfiles-clean.timerになっています。

以下のコマンドでactiveかどうか確認できます。

```
systemctl status systemd-tmpfiles-clean.timer
```
KaoriYa Vim にMigemoを導入する

## Migemoとは

KoRoNさんが配布しているKaoriYaパッチを適用したWindows版Vimでは、C/Migemoを導入することでMigemoを利用できます。

Migemoとは、漢字や平仮名の検索をローマ字で素早くできるしくみです。
例えば「検索」という単語を検索したいとき、Migemoを導入していないと「kensaku」を入力して「スペース」で変換開始、「エンター」で候補を確定という手間がかかります。
加えて、検索前後で日本語入力の切り替えも必要です。
一方Migemoを用いると、日本語入力の切り替えをせずに「kensaku」と入力するだけでよいのです。

![無題.png](https://qiita-image-store.s3.amazonaws.com/0/105381/25ec0130-098d-0bf3-d3d4-384118caf136.png)

このアイデアは以下の文献で詳しく説明してあります。

- 高林 哲: 横着プログラミング 第2回: Migemo: 日本語のインクリメンタル検索, UNIX MAGAZINE, Vol. 17, No. 2, pp. 129-136, February, 2002.
- 高林 哲, 小松 弘幸, 増井 俊之: Migemo: 日本語のインクリメンタル検索, 情報処理学会論文誌, Vol. 43, No. 12, pp. 3698-3705, December, 2002.

## ドキュメント通りでは導入できない

さて、この便利なMigemoを導入しようとしても、C/Migemoに同梱のドキュメント通りにしたがってもうまくできません。
C/Migemoのドキュメントは3年以上更新されておらず、おそらくVimの仕様の変化に追従していないのでしょう。
Vimスクリプトを勉強し試行錯誤して、やっと解決できたので忘備録として残しておきます。

## 現在のインストール方法

Windows版Vimをダウンロードし起動できる状態にした直後を想定して説明していきます。

### 1. C/Migemoをダウンロード

[KoRoNさんのサイト](https://www.kaoriya.net/software/cmigemo/)でC/Migemoをダウンロードしてください。
32bit版と64bit版がありますが、あらかじめ導入済みのVimと同じ版を選んでください。

ダウンロードしたらアーカイブを展開してください。

### 2. migemo.dllをコピー

C/Migemoに含まれているmigemo.dllをgvim.exeがあるディレクトリにコピーします。

### 3. migemo.vimをコピー

同梱のドキュメントには、migemo.vimを `$VIM/runtime/plugin/` にコピーと書いてありますが、これではスクリプトが読み込まれません。
Vim上で `:set runtimepath?` コマンドを実行すると、現在有効なランタイムパスが表示され、このディレクトリ上のスクリプトが読み込まれます。
表示されたランタイムパスの中には `$VIM/runtime/plugin/` が含まれていないため、上記の方法では失敗するのです。

というわけで、gvim.exeがあるディレクトリを `$VIM$` とすると、 `$VIM/vimfiles/plugin/` にmigemo.vimをコピーするのが正解です。

### 4. 辞書ファイルをコピー

ドキュメントには `$VIM/dict` ディレクトリに4つのファイルをコピーするように書かれていますが、C/Migemoのdictディレクトリにはcp932とutf-8の2つの辞書ファイルが含まれており、どちらをコピーしたらよいのか迷います。

実際はdictディレクトリをそのまま `$VIM` にコピーすれば大丈夫です。

### インストール完了

以上でインストールは完了です。


## Migemoを使ってみる

`_vimrc` には以下の設定を追記しておいてください。

```vim:_vimrc
set incsearch
if has("migemo")
	set migemo
endif
```

Migemoはデフォルトで `g/` に割り当てられています。
ノーマルモードで `g/` を入力することで、Migemoによる前方検索が開始できます。

Enjoy Migemo!!
nbsphinx の紹介

# nbsphinx とは

[nbsphinx](https://github.com/spatialaudio/nbsphinx/) は Jupyter Notebook を Sphinx のドキュメントソースとして扱うための Sphinx拡張パッケージです。
ipynb ファイルを一度 reStructuredText に nbconvert してから Sphinx のビルドを実行されていた方もいらっしゃるのではないでしょうか。
nbsphinx を導入すると convert の必要が無くなり、ダイレクトに ipynb ファイルを Sphinx でビルドできるようになります。

# nbsphinx 活用の実例

nbsphinx の活用の実例として

- ipynb ファイルしか持たない既存の github repository を 
- nbshinx を用いて nbconvert をかませることなく Sphinx でビルドし
- その成果物を readthedocs で公開する

ことを行う repository
https://github.com/kozo2/biopython-notebook/tree/nbsphinx
を示します。

この repository (のnbsphinx branch) で行ったことは下記の5ステップだけです。
これだけで http://biopython-tutorial.readthedocs.io/en/latest/ のように Jupyter Notebook が Sphinx でビルドされたサイトを公開できます。

1. https://github.com/tiagoantao/biopython-notebook ([biopython](http://biopython.org)というバイオインフォマティクスのためのPythonパッケージのチュートリアルnotebook集) を fork
2. 下記の1行だけを書いた `requirements.txt` を追加 

    ```
    nbsphinx
    ```

3. `conf.py` を追加 (その内容は http://www.sphinx-doc.org/en/stable/config.html の **Example of configuration file** に 下記の1行だけを[追加したもの](https://github.com/kozo2/biopython-notebook/blob/nbsphinx/conf.py))

    ```
    extensions.append('nbsphinx')
    ```

4. 下記だけを書いた index.rst を追加 (notebooks directory 下には複数の ipynb ファイルがあります)

    ```
    Tutorials
    ---------

    .. toctree::
       :glob:
   
       notebooks/*
   
    ```

5. [readthedocs](http://readthedocs.org) で https://github.com/kozo2/biopython-notebook/tree/nbsphinx をビルドするように設定

# nbsphinx で得られるメリットとまとめ

Jupyter Notebook は GitHub がサボートしているので Sphinx でのビルド (とreadthedocsでの公開) にあまり興味を持たれないかもしれません。
ですが私は下記のようなメリットがあると思います。

1. アウトラインが把握しやすくなる。各ヘッダーへのジャンプが可能になる。
2. スマートフォン，タブレット端末での閲覧に適した見栄えが得られる。
3. 実行するのではなく，見たいだけの場合は静的なドキュメントサイトを見たくなる (気がする)。
4. 美しく整形された pdf や epub での export。
5. 1.2.3.4. に伴うさらなる Notebook 推敲のモチベーション喚起。

上記には特に興味が無くても
nbsphinx はとにかく便利と思うので是非試してその手軽さを体感していただきたいです。

以上 nbsphinx の紹介でした。
スライドのフォントや文字色をアニメの色合いにしてみるのは地味に大変だよ、という話。


[プレゼン研究会 Advent Calendar 2017](https://qiita.com/advent-calendar/2017/infrapre) 6日目の記事です。

今日は[第4回 エンジニアのためのプレゼン技術研究会「みんなの自由研究発表」と「前佛さんのスライドの作り方」](https://infrapre.connpass.com/event/20313/)に参加した時の話をしようと思います。

## プレゼン用の図を自動生成するお話

そのとき発表したスライドは「[プレゼン用の図を自動生成する話](https://www.slideshare.net/furandon_pig/ss-53761102)」というもので、以下のような感じのスライドです。
プレゼン用の図を自動生成ってどういうこと？という方は、[こちらのブログ](http://furandon-pig.hatenablog.com/entry/2015/10/13/002252)で解説していますのでご参照ください。

<img width="234" alt="img001.png" src="https://qiita-image-store.s3.amazonaws.com/0/61137/283cc18e-db68-39ab-b318-62769d22c69b.png">

## ひと目で尋常でないスライド作成になると見抜いたよ

このスライドですが、[ご注文はうさぎですか？](http://www.gochiusa.com/)風味で作成しました。アニメOPやサブタイトルに色合いを似せたスライドを作るの「それっぽい風味になってきた！」感があって楽しいのですが、色合いを合わせるのが地味に手間取るのです。

## RGB値を探す日常

色合いを合わせる作業は、録画したアニメのOP映像やサブタイ画像から「スポイト」ツール等で色を取り出し、フォントカラーに設定、のトライアンドエラーになり、これはこれで地味に大変なのですが、もっと大変なのが、「どれがどの色だっけ？」という色リストの管理です。テキストエディタとかに以下のような感じでメモしつつ、フォントカラーを変更する作業を黙々と進めるわけです...。

```
OPタイトル文字, #XXXXXX
OPタイトル背景色, #XXXXXX
...
```

これはだいぶ面倒な上に、発表内容の本質的な話ではないのでもっと楽にできるようにしたいものです。

## みんなでアニメのカラーコードを集めると捗る？

何か良い方法はないかなと考えているのですが、漠然と「みんなでアニメのカラーコードを集めると捗りそう...」という気がしています。
WebAPIとかでカラーコードの投稿、検索が行えるようにしたいのですが、まだ着手できていない＋わかりやすいカラーコードの項目名とかってどうするの？(「OPタイトル背景色」とかでみんなに通じるのかな？)とか、ちゃんとやろうとすると意外と検討すべきことは多そうです。

とはいえ、プレゼン研究会の懇親会でこの話をしたら同じように考えている方もおられて(アニメの)話題がはずんだりしたので、うまいこと発表ネタになるような成果物を作って次回のプレゼン研究会で発表したいですね。
Dockerコンテナ内でsendmailを使用する際のhostsの設定

# 目標

コンテナ内の/etc/hostsに設定を追加してもコンテナ再起動時にリセットされてしまうので何とかしたい。

追加する設定例

```
127.0.0.1 localhost ドメイン ホスト名
```

`domainname`が未設定の場合は`localhost.localdomain`

# 対応方法

コンテナ作成時に設定を追加してしまえば良い
runコマンドに以下のオプションを追加する


--hostname ホスト名 --add-host "localhost ドメイン ホスト名":127.0.0.1 

# 参考

http://jasani.org/2014/11/19/docker-now-supports-adding-host-mappings/
Chaliceを使ってみた

AWS+Lambda+Pythonでサーバレス開発をするためのAWS謹製フレームワーク
 
##インストール
```bash
pip install chalice
chalice new-project helloworld
cd helloworld
```

## ローカルで起動

```bash
chalie local
```

## getリクエスト、パラメータを受けて、jsonで返す
```.py
@app.route('/hello/{id}')
def index(id):
	return {'id':id}
```

## 画像を返す
```.py
@app.route('/hoge')
def image():
    image_bin = open("hoge.jpg", "rb").read()
    return Response(body=image_bin, headers={'Content-Type': 'image/*'})

```

## boto3でs3に保存
```.py
# pip instal boto3
import boto3
s3 = boto3.client('s3')
s3.put_object(Bucket=BUCKET_NAME, Key='s3_path_key', Body='hoge.png')
```

## sqlalchemyでMySQLにつなぐ
```bash
pip install SQLAlchemy
pip install PyMySQL
```

```app.py
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
import os

app = Chalice(app_name='helloworld')
app.debug = True
Base = declarative_base()

#Userモデル
class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(String(40))

#session取得
def getSession():
    #環境変数から接続文字列を取得
    engine = create_engine(os.environ["CONNECTION_STRING"], echo=True)
    session = sessionmaker(bind=engine)()
    return session

@app.route('/')
def index():
    session = getSession()
    user = session.query(User).one()
    return {'hello': user.name}
```

.chalice/config.json へ環境変数を定義
http://chalice.readthedocs.io/en/latest/topics/configfile.html

```.chalice/config.json

  "stages": {
    "dev": {
      "api_gateway_stage": "api",
      "environment_variables": {
        "CONNECTION_STRING": "mysql+pymysql://userid:passowrd@host/database?charset=utf8",
        "OTHER_CONFIG": "dev-value"
      }
    }
  
```

```bash
#デプロイしてみる
pip freeze > requirements.txt
chalice deploy

#依存関係をvendorに入れとけって怒られる
Could not install dependencies:
itsdangerous==0.24
typing==3.5.3.0
MarkupSafe==1.0
SQLAlchemy==1.1.15
You will have to build these yourself and vendor them in
the chalice vendor folder.

#入れる
pip install -U itsdangerous==0.24 -t ./vendor/
pip install -U SQLAlchemy==1.1.15 -t ./vendor/
pip install -U MarkupSafe==1.0 -t ./vendor/
pip install -U typing==3.5.3.0 -t ./vendor/

# installできない場合はtar.gzを取得して、wheelする
pip download enum-compat==0.0.2
pip wheel cryptography-1.9.tar.gz

chalice deploy

#接続を試す・・・成功!
curl https://xxxxxxx.execute-api.ap-northeast-1.amazonaws.com/api/
{"hello": "hirao"}
```

# AWS Lambdaの設定
## 同時実行の制限
https://aws.amazon.com/jp/about-aws/whats-new/2017/11/set-concurrency-limits-on-individual-aws-lambda-functions/

## コンフィグ
```config.json
{
  "version": "2.0",
  "app_name": "your_app_name",
  # メモリ設定
  "lambda_memory_size": 512,	
  "stages": {
    "dev": {
      "api_gateway_stage": "api"
    }
  }
}

```


RDBのコネクション数を超えないようにLambdaの同時実行を制限しましょう。
競技プログラミングについて紹介(初心者向け)

この記事は[高知工科大学 Advent Calendar 2017](https://adventar.org/calendars/2305)の7日目の記事です．
ここでは，競技プログラミングについて軽く紹介します．
いわゆるマラソン型には触れません．~~(知らないから解説できない)~~

私はAdvent CalenderどころかQiitaもMarkdownも初挑戦なので，所々おかしい表記があるかもしれません．
「ここはこう書いたほうが良いよー！」とかあったら教えてくれると幸いです．

##目次
1. 競技プログラミングとは
2. 簡単な問題をやってみる
3. 緑コーダーを目指す
4. おわりに

## 1.競技プログラミングとは
プログラミングの問題を短時間で沢山を解く競技です．
数学とかパズルが好きな人はハマると思います．

と言っても，その辺の面白いゲームより面白いかと言われたら微妙です．
なので，興味を持ってもらう為に，まず競プロの社会的有用性について語ります．

ざっくり言うと

1. プログラミング能力が上がる
2. 就活に役立つ

って所です．順番に解説します．

### 1.プログラミング能力が上がる

競プロは主に，考察力・発想力・実装力が身に付きます．
難しい問題になると，数学力も身に付つくらしいです
~~(僕はそんなレベルじゃ無いから分からない)~~

あと，ライブラリや言語仕様といった知識も身に付きますね．

### 2. 就活に役立つ

正直，こういう面で競プロが流行ってほしくは無いんですが，一番の魅力だと思っているので，あえて載せます．

大きなプログラミングコンテストの大会では，スポンサーさんから企業案内が沢山来ます．
また，成績によって開催企業への就職が有利になる企業コンテストも頻繁に開催されています．
以前は国内ではあまり見なかったのですが，今年の秋頃から頻繁に行われるようになりました．

あと，こんな記事もあります．
[プログラマー採用時や社員・学生のプログラミング教育に役立つ
プログラミング能力判定サービス「TOPSIC」発表](https://www.sint.co.jp/release/2017/release171124.pdf)

今後，競プロがどんどん就活に用いられるようになるかもしれません．

---

規模の大きいものを除いて，コンテストは基本的にオンライン上で行います．
日本では[Atcoder](https://atcoder.jp)という所が一番盛り上がっています．

この前にこんな記事を出していました．
[国内最大プログラミングコンテストサイト「AtCoder」の参加者が1万人突破！](http://atcoder.co.jp/news/release-20170924)
ここでは企業コンテストも頻繁に行っています．
日本語に対応しているだけでなく，終了後に解説pdf掲載+解説生配信をやってくれる良い所です．

他にも，Topcoder等色々ありますが，まずは日本人が一番とっかかりやすいAtcoderのみの紹介とします．

## 2.簡単な問題をやってみる
では，実際にコンテストの問題を解いてみます．
ここでは，AtcoderのABC(初心者向けコンテスト)のA問題(一番簡単な問題)を一問やります．

[ABC016](https://abc016.contest.atcoder.jp)のA問題を使用します．

#### 問題

> 12月6日は、月を日で割って割り切れる日です。日付が与えられるので月が日で割り切れるかを判定してください。

> 月が日で割り切れるなら YES 、割り切れないなら NO を出力せよ。出力の末尾には改行をつけること。

#### 自分なりの解答

```c++
#include <bits/stdc++.h>
using namespace std;

int main() {
    int m, d;
    cin >> m >> d;
    string ans = "NO";
    if (m % d == 0) ans = "YES";
    cout << ans << endl;
    return 0;
}
```

まず，整数を入れる箱を2つ用意します．次に，それに月と日の値を入れます．
最後に，剰余が0ならYES，そうじゃ無いならNOを出力します．

**めっちゃ簡単そうじゃないですか？**

このように，A問題というのは入出力と変数と条件分岐さえ分かれば解けるケースが多いです．

「コードそんなに書いた事無いし，コンテストなんて…」と心配する必要はありません．
じゃんじゃん出ちゃっておkです．

簡単な問題でも，提出して正解が出ると嬉しいものです．

## 3.緑コーダーを目指す

Atcoderに限らず，コンテストサイトではレーティングを色で表します．
ここでは，基本的なアルゴリズムを活用できるラインである緑色を目指すことにします．

### 1.AOJ本を読もう
プログラミング未経験・初心者の方は，[オンラインジャッジではじめるc/c++プログラミング入門](https://www.amazon.co.jp/dp/4839951101)
という本を読むことをオススメします．(KUTの図書館にはありますよ！)
競プロで使うc++の基礎と同時に，基礎の典型問題の解き方を学べます．

### 2.コンテストに参加しよう

ここからは主にアルゴリズムの勉強です．参考書としては，

- [蟻本(プログラミングコンテストチャレンジブック [第2版])](https://www.amazon.co.jp/dp/4839941068)
- [TLE本(プログラミングコンテスト攻略のためのアルゴリズムとデータ構造)](https://www.amazon.co.jp/dp/4839952957)

辺りがよく使われます．

しかし，範囲が広い上に，どれも実際に使えるようになるまでに時間が掛かります．
なので，パラシュート勉強法をオススメします．

**とりあえずコンテスト(ABC)に出て，分からなかった所を勉強する**

って感じです．コンテスト楽しいですよ．
分からない問題は，時間内の正解を諦めちゃっておkです．

コンテスト終了後は，解説pdfや解説放送を使って解けなかった問題の復習をしましょう．
蟻本・TLE本を使って，その範囲について詳しく勉強するとなお良しです．
解けた問題についても，解説pdfを読むと新たな発見があるかもしれません．

自分は，解けなかった問題が解説放送で流れるまでの間に，解説pdfと蟻本・TLE本で勉強するようにしています．

## 4.おわりに

競プロ勢を増やす記事を作りたいなと思い，この記事を書いました．
またこのような機会があれば，次はアルゴリズム面で何か書きたいと思います．

この記事を見て，競プロに興味を持ってくれる方が居たら嬉しいです．
BitVisor の vmmstaus の CLI 版クライアントを作ってみた

## はじめに
BitVisor には vmmstatus という機能があります．
その機能を使うための CLI 版クライアントアプリを作ったという話です．

## vmmstatus とは?
BitVisor には，vmmstatus という機能があります．
これを使うと，VMExit の数などの情報をゲスト OS から簡単に取得することができるます．

BitVisor Summit 3 で株式会社イーゲルの榮樂様の発表中で少し説明がありました．
https://www.bitvisor.org/summit3/slides/bitvisor-summit-3-02-eiraku.pdf

しかし現在，情報を取得して表示するためのクライアントが GUI 版 (Windows 版と GTK 版) しかないようです．
BitVisor 体験をするためには，GUI 版の方が見栄えがして良さそうなのですが，CLI 環境が大好きな僕としては CLI 版が欲しいなと思いました．
また，CLI に出力できると，テキストファイルに落としたり，出力をパイプで加工したりなどいろいろできて便利かなと思います．

そういった理由をつけて，とりあえず CLI 版を作ってみました．

## CLI 版
とは言っても，GUI 版よりも圧倒的に簡単です．
GUI 版の要らない部分を削って printf にして終わりです．

tools/ ディレクトリ以下に適当なディレクトリを作って，以下のページにある Makefile とvmmstatus-cui.c をおいてビルドしてすればよいはずです．

https://bitbucket.org/snippets/ftakaaki/ze4yXM/vmmstatus-cuic

## BitVisor 側の設定
CLI 版に限りませんが，vmmstatus を使う場合ときに注意する点があります．
BitVisor のビルド時の設定を変えないといけないのですが，make config で有効にする以外に，defconfig 内の vmm.status = 1 を追加しないとしないといけません．
(デフォルトの defconfig に vmm.status というフィールドがないですね...)

具体的は変更は，上記のページに diff がありますので，それを参考にしてください．

あとは，BitVisor 本体をビルド&インストールして，先ほどの CLI 版を起動してみましょう．

## 実際に使ってみる
こんな感じ

![image.png](https://qiita-image-store.s3.amazonaws.com/0/59503/c910e7e7-4c08-f08b-5ab0-85f69336fe53.png)

## ちなみに
GUI 版を使ったことないんですよね...
なんかビルド面倒そうなので，バイナリが配布されたりすると BitVisor 体験が簡単にできていいかもしれませんね．

## おわりに
vmmstatus の CLI 版を作った話でした．
時間があれば，vmmstatus の中身の話もそのうち書けるといいですね．
シスコ NeXt UI をカスタマイズしてみた

[シスコ NeXt UI を使ってトポロジを描画してみた](https://qiita.com/hiroactivity/items/9cc047baa9e277e949d3)では、シスコ NeXt UI のダウンロードからインストールまで紹介しました。ここではいろいろなカスタマイズについてまとめます。

## アイコンの変更
シスコ NeXt UI には、以下のように様々なアイコンが最初から含まれています（https://developer.cisco.com/site/neXt/discover/demo/ の Topology Icons から一部分のみ引用）。

![Screen Shot 2017-12-06 at 8.46.14 PM.png](https://qiita-image-store.s3.amazonaws.com/0/156216/122a730b-3181-3247-cbc0-dc6618367ec7.png "Screen Shot 2017-12-06 at 8.46.14 PM.png")


デフォルトではノードが unknown の ? マークになっていますので、これをルータに変更します。これだけであれば、Shell.js に一行追加するだけで実現できます。

```js
 16                     nodeConfig: {
 17                         // label display name from of node's model, could change to 'model.id' to show id
 18                         label: 'model.name',
 19                         iconType: 'router'  // 追加
 20 
 21                     },
```

これで無事にルータのアイコンになりました。

![Screen Shot 2017-12-06 at 8.56.29 PM.png](https://qiita-image-store.s3.amazonaws.com/0/156216/35931d6c-9799-dd48-bef2-349a388f5fc9.png "Screen Shot 2017-12-06 at 8.56.29 PM.png")




## リンクの変更
リンクタイプは curve と parallel が選べます。これまでのトポロジは curve でしたので、Shell.js を次のように変えて parallel にしてみます。

```js
 23                     linkConfig: {
 24                         // multiple link type is curve, could change to 'parallel' to use parallel link
 25                         linkType: 'parallel'  // parallel に変更
 26                     },
```

すると、下記のようにリンクが平行線になりました。

![Screen Shot 2017-12-06 at 9.03.33 PM.png](https://qiita-image-store.s3.amazonaws.com/0/156216/e0ed6090-6e7f-cda2-c41b-abb922b7b244.png "Screen Shot 2017-12-06 at 9.03.33 PM.png")


## テーマの変更
NeXt UI では blue, green, dark, slate および yellow の 5 つのテーマが用意されています。デフォルトは blue です。ブラウザで描画したときの設定ボタン（ギアのアイコン）を押しても変更できますが、コード上で変更する際には、下記のように nx.graphic.Topology クラスに theme プロパティを追加します。

```js
 13                     width: 580,
 14                     height: 580,
 15                     theme: "green",  // blue, green, dark, slate, yellow のいずれかを追加
 16                     // node config
 17                     nodeConfig: {
```

それぞれのテーマは以下のような感じです（デフォルトの blue はこれまでの画面なので省略します）。

### green
![Screen Shot 2017-12-06 at 9.09.35 PM.png](https://qiita-image-store.s3.amazonaws.com/0/156216/0af02d5c-bce8-2a4e-fb2d-4846eed04791.png "Screen Shot 2017-12-06 at 9.09.35 PM.png")


### dark
![Screen Shot 2017-12-06 at 9.10.03 PM.png](https://qiita-image-store.s3.amazonaws.com/0/156216/5f330bde-f667-207d-2732-36101a97d335.png "Screen Shot 2017-12-06 at 9.10.03 PM.png")


### slate
![Screen Shot 2017-12-06 at 9.10.19 PM.png](https://qiita-image-store.s3.amazonaws.com/0/156216/2c985ac1-1a6e-7412-9e9b-9fb450608099.png "Screen Shot 2017-12-06 at 9.10.19 PM.png")


### yellow

![Screen Shot 2017-12-06 at 9.10.33 PM.png](https://qiita-image-store.s3.amazonaws.com/0/156216/9110dc38-c0f5-d26e-649a-080e6a72f7b0.png "Screen Shot 2017-12-06 at 9.10.33 PM.png")
Elm初心者でもできるprintデバッグ

お前の`import Debug`を数えろ

Elm初めてでprint仕方が分からないって人をツイッターで二人ほど見かけたのでやりかたを書いておきます
式と文の違いが判らないって人もいるかもなんですけどとりあえず気にしない方針です

追記：2018/08/22
`0.19`が出ましたがここに書いてあることはそのまま動くのでよろしくお願いします

```hs
 import Debug
```
~~まず`import`する~~
importいらなかった。書かなくていいです（書いてもいいです


```hs
 update model msg =
   case msg ->
     NoOp ->
       Debug.log "modelをprintして、返り値はmodel" model
       
     InputName str ->
       { model | name = Debug.log "strをprint, model.nameにstrがセットされる" str }
       
     IgnoreNum num ->
       let
         _ = Debug.log "numをprint、numが返るんだけど使わないので _ に入れて捨てる" num
         -- アンダーバーは使いませんよーみたいな特殊な変数？
       in
         model
       -- こんなふうに式を並べることはできない
       -- Debug.log "numをprint、numが返るんだけど使わないので _ に入れて捨てる" num
       -- model
     UpdateUsers ->
       { model |
         users =
           model.users
             |> List.map enhanceUser
             |> Debug.log "enhanceされたuser listをprint"
             |> List.map killUser
             |> List.map (\user -> Debug.log "なぜかkillされたuserを1人ずつprint" user)
             -- pipeの途中でいくらでもはさみこめるんでよろしく
       }
```

大事なのは式（1行みたいな意味）を並べて書けないのと、`Debug.log`はlogしたものがそのまま返ってくること

ElmのviewはただのElmコードなのでview内でももちろん同じことができます

```hs
 view model =
   div [] [ text <| log "printします" <| model.message ]
```


何もわからないおれはElmの文法がよくわからないままコードを書いている
って人向けにたぶんどこでも動くprintも書いておきます

```hs
 let _ = Debug.log "このコード片は割とどこおいても大丈夫な気がする" something in
```
somethingに見たい変数を入れてください

ついでに２stepで学ぶDebug.log書いておきます

```hs
 view model =
    div [] [ text model.message ]
```
もとのコードがあります

```hs
 view model =
    div [] [ text (model.message) ]
```
step1. みたいものをかっこでかこむ

```hs
 view model =
    div [] [ text (Debug.log "log label" model.message) ]
```
step2. Debig.logを足す

ね、簡単でしたね