OmniAICreator/Qiita-1.07M huggingface dataset:
Tween.jsでカメラ移動


Three.jsのカメラを[Tween.js](https://github.com/tweenjs/tween.js/)で移動させてみた

## ダブルクリックした位置から対象にズームインする

デモ：http://codepen.io/mo4_9/pen/amoKrW

```javascript:ES6のClass内から一部抜粋

animateCameraPos(50,20,0);

・・・

animateCameraPos(x,y,z) {
  const that = this;
  const coords = this.camera.position; // 現在地点
  const destinationVector = new THREE.Vector3(x, y, z); // 終着地点
  const DURATION = 1000;
  let loop;
  
  const tween = new TWEEN.Tween(coords)
    .to(destinationVector, DURATION)
    .easing(TWEEN.Easing.Cubic.Out) // 最後で減速する
    .onUpdate(update) // TWEEN.update()の度に呼び出される
    .onComplete(complete)
    .start();
  
  renderCamera();
  
  function renderCamera() {
    loop = requestAnimationFrame(renderCamera);
    TWEEN.update();
  }
  function update() {
    that.camera.lookAt(that.zeroVector); // 向きを変えながら移動
    console.log(coords);
  }
  // 終着地点に着き次第、requestAnimationFrameをストップ
  function complete() {
    cancelAnimationFrame(loop);
  }
}
```

## カメラをエンドレスにゆらゆらさせる

### chain

行きと帰りのアニメーションが違う、3点以上のアニメーションを繋げるときなどに使える

デモ：http://codepen.io/mo4_9/pen/xExxKL

```javascript:ES6のClass内から一部抜粋
swayCamera() {
  const posSrc = {pos:1};
  const DURATION = 3000;
  const that = this;
  
  // 行き
  const tween = new TWEEN.Tween(posSrc)
    .delay(500)
    .to({pos:0}, DURATION)
    .easing(TWEEN.Easing.Quadratic.Out)
    .onUpdate(update)
  
  // 帰り
  const tweenBack = new TWEEN.Tween(posSrc)
    .delay(500)
    .to({pos:1}, DURATION)
    .easing(TWEEN.Easing.Elastic.In)
    .onUpdate(update)
  
  // ループさせる | chain() 連結
  tween.chain(tweenBack);
  tweenBack.chain(tween);
  
  tween.start();
  
  function update() {
  	// thisはトゥイーンによって与えられる座標
  	// new TWEEN.Tween(posSrc)のposSrcを指す
  	// つまりthis == {pos: 1}
    const pos = this.pos;
    const RANGE = 10;
    
    const newX = that.initialCameraPosX + ((RANGE * pos) * 2 - RANGE); // 90 ~ 110
    that.camera.position.x = newX;
  }
}
```

### yoyo

行きと帰りの動きが同じの場合、yoyoで書いた方が簡単

デモ：http://codepen.io/mo4_9/pen/bwNraw

```javascript:ES6のClass内から一部抜粋
const tween = new TWEEN.Tween(posSrc)
  .delay(500)
  .to({pos:0}, DURATION)
  .easing(TWEEN.Easing.Quadratic.Out)
  .yoyo(true)
  .repeat(Infinity)
  .onUpdate(update)
  .start();
```

> 参考
[Tween.js × Three.js](http://qiita.com/mo4_9/items/738f0a94dd83fab318e2)
配列が特定の長さになるまでにパディングする

[Array#fill](http://docs.ruby-lang.org/ja/2.3.0/method/Array/i/fill.html) を使います。

```rb
girls = %w(まどか さやか)
#=> ["まどか", "さやか"]

girls.dup.fill(girls.length...5) { '杏子' }
#=> ["まどか", "さやか", "杏子", "杏子", "杏子"]
```

`dup` を外せば、レシーバを直接書き換えます。
boto3でS3の期限付きURLを発行する（ファイルの存在確認付き）


`generate_presigned_url`で期限付きURLを発行できるのですが、オブジェクトが存在しないキーに対しても作れちゃう問題があります。
なのでget_objectでオブジェクトが実在するか否かを確認してから、期限付きURLを発行するようにしてみました。

```
import boto3
import botocore
import logging
logger = logging.getLogger()

def create_presigned_url( bucket_name, key ):
	s3 = boto3.client('s3')
	try:
		s3.get_object(
			Bucket = bucket_name,
			Key = key
		)
		url = s3.generate_presigned_url(
			ClientMethod = 'get_object',
			Params = {
				Bucket = bucket_name,
				Key = key
			},
			ExpiresIn = 3600,
			HttpMethod = 'GET'
		)
		return url
	except botocore.exceptions.ClientError as e:
		logger.warning(e)
		return 'File ' + bucket_name + '/' + key + 'not found'
		

bucket_name = 'BUCKET_NAME'
key = 'S3_OBJECT_KEY'
create_presigned_url( bucket_name, key )
	
```

存在しないオブジェクトに対してget_objectを実行すると、`ClientError`が返ってきます。
なのでそれを利用して`try ~ except`でオブジェクトが存在しない場合は、generate_presigned_urlを実行せずに処理を終了させます。
CSSで画像のサイズ調整

### 親要素の大きさに依存してサイズ変更
259 x 194 pxの画像を180x180のdivと同じサイズにする

デモ https://jsfiddle.net/yangchuntao/oepgynre/

参考ページ: [【CSS3】親要素の大きさに依存して画像の表示方法を変える［object-fit］プロパティの使い方。](http://on-ze.com/archives/2296)
Firebase Test Lab上でアプリが実行中であることをコードから確認する


# 概要

Firebase Test Lab上でアプリが起動していることをコードから確認する方法のメモです。

# System Propertyでの判別

`Settings.System.getString`メソッドで`firebase.test.lab`を参照することでFirebase Test Labでアプリが実行中かを判別できます。

```java
String testLabSetting =
  Settings.System.getString(context.getContentResolver(), "firebase.test.lab");
  if ("true".equals(testLabSetting)) {
    // Test Labでの実行中に行う処理
  }
```

このコードで判別できるので[Roboテスト](https://firebase.google.com/docs/test-lab/robo-ux-test)がログイン画面を突破できない問題を解決できそうです。

# 参考
- https://firebase.google.com/docs/test-lab/android-studio
チェックボックスをすべてチェックする

以下をブラウザのソールに入力することにより、ブラウザの画面上に表示されているチェックボックスを無条件で一括チェックすることができます。

```js
$("input[type=checkbox]").each(function(index){
var setval = $(this).val();
$(this).val([setval]);
});
```

勤怠の承認とかで大量のチェックボックスをチェックする場合に便利です。
Intrinsicsを使ってもっと早く演算やってみよう！

#始めます。

こんにちは。Dreamwalkerです。
intrinsicを使って基本的な演算やってみました。
これを使ったら、基本Serial演算より早いです。

#開発環境
- **XCODE 7.3.1** (　Visual Studio 2013をお勧めします。。）
- **C/C++**
- OS : **macos**
- Data Unit : **16bit Short**

#使ったHeader ..
MMXを始め今はAVX2まで、開発進めています。
私はSSE2を基本のSIMDで使いました。

#まずHeaderから。。
intrinsicを使うためにはHeaderが必要です。

```ruby:C/C++
#include <emmintrin.h>　//SSE2
```
###他のHeaderはこれを参考してください。
*普通Ver upしていくと、下のversionを含めています。*
*例えば、AVX Headerを使ったらMMX~SSE4.2までの命令を使えます。*


| Header | intrinsic |
|:-:|:-:|
| mmintrin.h  | MMX  |
| xmmintrin.h  | SSE2  |
| emmintrin.h  |  SSE3 |
| pmmintrin.h  | SSE3  |
| tmmintrin.h  |  SSSE3 |
| smmintrin.h  |  SSE4.1 |
| nmmintrin.h  |  SSE4.2 |
| ammintrin.h  |  SSE4A |
| wmmintrin.h  |  AES |
| immintrin.h  |  AVX |
| zmmintrin.h  |  AVX512 |

#メイン関数の中で、配列を作ろう！
SSEからのレジスターは128Bitです。
shortを使ったら128bit中で8個のデータを使えます。

```ruby:C/C++
 short aData[8] = {2,3,4,5,6,7,5,3};
 short bData[8] = {1,2,3,4,5,6,7,8};
 short Result[8] = {0};
```
#配列をXMMレジスターへLoadしよう。
###**この過程しなければならないです。**
XmmレジスターはCPU中(Coreの中)で、あるSIMDレジスターで128bit Sizeです。
Xmm0~Xmm7まで、Core別々8個持っています。


```ruby:C/C++
__m128i xmmA = _mm_load_si128((__m128i*)aData);
__m128i xmmB = _mm_load_si128((__m128i*)bData);
```
#足し算と引き算やってみよう！

上まで、問題なかったですか？ :laughing: 
もし、問題あったらこの内容は進めません。
さあ。。本格的な基本演算始めます。

-**足し算。**

```ruby:C/C++

__m128i xmmR = _mm_add_epi16(xmmA, xmmB); // xmmA + xmmB
_mm_store_si128((__m128i*)Result, xmmR);

printf("ADD: %d,%d,%d,%d,%d,%d,%d,%d\n",Result[7],Result[6],
Result[5],Result[4],Result[3],Result[2],Result[1],Result[0]);


```
-**引き算。**

```ruby:C/C++

xmmR = _mm_sub_epi16(xmmA, xmmB);   // xmmA - xmmB
_mm_store_si128((__m128i*)R, xmmR); 

printf("SUB: %d,%d,%d,%d,%d,%d,%d,%d\n",Result[7],Result[6],
Result[5],Result[4],Result[3],Result[2],Result[1],Result[0]);


```

**Xcodeで Command + R を押しと結果が出ます。 :tada:**

#掛け算やってみよう！
あれ？掛け算しかない？割り算は？と思いましたか？
**はい！Intrinsicは割り算の命令語ないです。 :sob: **

残念ですね。。でも、**方法はあります。**次のPOSTで載せてみます。

-**掛け算**

```ruby:C/C++

xmmR = _mm_mullo_epi16(xmmA, xmmB);  // xmmA  * xmmB
_mm_store_si128((__m128i*)R, xmmR); 

printf("MUL: %d,%d,%d,%d,%d,%d,%d,%d\n",Result[7],Result[6],
Result[5],Result[4],Result[3],Result[2],Result[1],Result[0]);


```

mulloはlow 16bitだけ生き残します。
天才な皆様はmulhiもあるでしょ！と思えます。

**Xcodeで Command + R を押しと結果が出ます。 :tada:**


#結果

まず、今日は割り算を除外した、足し算、引き算、
最後に掛け算までやってみました。
どうでしたか？　Intrinsicは基本Serial演算より1.5~2倍は早くなります。

読みいただきありがとうございました。
次のPostで会いましょう！

**Dreamwalker。**
sqlserver遠程連接設置

#打開Sqlserver Config manager
![image](https://qiita-image-store.s3.amazonaws.com/0/136263/43ee1b2e-658b-c364-27d6-f4d6c8815df3.png)

把tcp/ip和name pipes設置為Enabled

#設置端口1433
![image](https://qiita-image-store.s3.amazonaws.com/0/136263/bb19efed-e991-3ee4-2960-7220f421204a.png)

#防火牆開啟1433端口
必要な要素が出来た時点で処理を実行したい（DOMContentLoadedまで待てない）

とあるサイトを高速化したいという依頼を受けた。

# 構造
そのサイトは静的ページなんだけど、記事本文部分が以下の様なHTML構造になっていて、

```html
<div>冒頭ぶった切り</div>
<div class="MoreBtn hide">続きを読むボタン</div>
<div class="MoreBody hide">記事の後半全文</div>
```

Javascript で `DOMContentLoaded` のタイミングでクエリをチェックして `mode=all` が付いてるかどうかを見て `hide` クラスの除去を行っていた。

```javascript:readmore.js（明用簡略ソースです）
$(function(){
  if(/mode=all/.test(location.search)) {
    $(".MoreBtn").removeClass("hide");
  } else {
    $(".MoreBody").removeClass("hide");
  }
});
```

一応これで表示非表示の制御自体は期待通りの動作は実現できていました。

# 問題点

- このページにはサイドバーやサードパーティ製の広告タグがわんさか入っていました。
- そのため __`DOMContentLoaded` が発火するのが非常に遅い__ 時がありました。
- するとヘタしたら続きを読むボタンや本文表示自体が冒頭文章が表示された後1分ぐらいしてからボタンや本文が唐突に現れるといった具合です。
- __広告タグや `readmore.js` を埋める場所を動かすのも難しい事情__があるようです。
- 色々突っ込みどころはありますが現状は大きく変えずに__小手先の修正で改善したい__というのが要件です。

# 解決策

実はDOM内に記事部分が出現するタイミング自体は結構早いです。
問題の元凶は `DOMContentLoaded` が発火するのが非常に遅い事で、またそれを早くするのも難しそうというという事です。
なので `DOMConentLoaded` を待たずに `.MoreBtn` や `.MoreBody` の要素が出現したタイミングで JS 処理を実行すればいいんじゃね？
ってことでそれを発火するタイミングを早くする為に readmore.js を以下のような書き換えてみました。

```javascript:
!function(){
  // selectors で指定された要素の出現、またはDOMContentLoadedの早い方のタイミングで handler を実行する、
  function waitElementOrReady(selectors, handler) {
    var loop = setInterval(function(){
      if(selectors.every(function(v){return document.querySelector(v)})) {
        onReady();
      }
    }, 500);
    document.addEventListener('DOMContentLoaded', onReady);
    function onReady() {
      clearInterval(loop);
      handler();
    }
  }

  // $(...) の代わりに waitElementOrReady 関数経由で発火タイミングを指定する。
  waitElementOrReady([".MoreBtn", ".MoreBody"], function(){
    if(/mode=all/.test(location.search)) {
      $(".MoreBtn").removeClass("hide");
    } else {
      $(".MoreBody").removeClass("hide");
    }
  });

}();
```

こんな感じの改造で、コンテンツ全体の読み込みが終わらなくても続きボタンや続きの本文が即座に表示できるようになりました。
案外簡単に出来てよかった。めでたしめでたし。
scapy IPv6

備忘録的な。

Router solicit

```py
# いつもの投げっぱなし
>>> sendp(Ether()/IPv6()/ICMPv6ND_RS())
# 応答が欲しい
>>> sr1(IPv6()/ICMPv6ND_RS())
```

DHCPv6 solicit には client-id が必須(RFC 3351)

```
>>> client_id=DUID_LLT(lladdr=get_if_hwaddr(conf.iface6))
>>> a=sr1(IPv6(dst="ff02::1:2")/UDP()/DHCP6_Solicit()/DHCP6OptClientId(duid=client_id))
>>> client_id=a[DHCP6OptClientId].duid
>>> server_id=a[DHCP6OptServerId].duid
```

DHCPv6 solicit, advertise, request, reply とつなげるとこんな感じ。dnsmasq はとりあえず応答してくれる。

```
a=sr1(IPv6(dst="ff02::1:2")/UDP()/DHCP6_Solicit()
 /DHCP6OptClientId(duid=DUID_LLT(lladdr=get_if_hwaddr(conf.iface6))))
b=sr1(IPv6(src=a[IPv6].dst, dst=a[IPv6].src)/UDP()/DHCP6_Request()
 /DHCP6OptServerId(duid=a[DHCP6OptServerId].duid)
 /DHCP6OptClientId(duid=a[DHCP6OptClientId].duid))
```

Cisco は DHCPv6_Solicit に DHCP6OptIA_NA が無いと、応答しない。RFC 3351 の記述をそのまま実行すると付くことになる（いちおう validation では要求されていない）。

```
a=sr1(IPv6(dst="ff02::1:2")/UDP()/DHCP6_Solicit()
 /DHCP6OptClientId(duid=DUID_LLT(lladdr=get_if_hwaddr(conf.iface6)))
 /DHCP6OptIA_NA(iaid=1)
)
b=sr1(IPv6(dst="ff02::1:2")/UDP()/DHCP6_Request()
 /DHCP6OptServerId(duid=a[DHCP6OptServerId].duid)
 /DHCP6OptClientId(duid=a[DHCP6OptClientId].duid)
 /DHCP6OptIA_NA(iaid=1)
)
```

さらに DHCPv6-RelayForward, RelayReply をする。下の例の src アドレスは stateful に割り当てられた時の値を抜き出している。slaac 使ってる場合は、手元で計算していれるべし。

```
c=sr1(IPv6(dst="ff05::1:3", src=b[DHCP6OptIA_NA].ianaopts[0].addr)
 /UDP(sport=547, dport=547)
 /DHCP6_RelayForward(linkaddr="fd00::152", peeraddr="fe80::2000:1")
 /DHCP6OptRelayMsg()/DHCP6_Solicit()
  /DHCP6OptClientId(duid=DUID_LLT(lladdr="00:11:22:33:44:55"))/DHCP6OptIA_NA(iaid=2)
)
```
[Emacs] magitで範囲選択からのCherry Pick(+ コンフリクトの解消)


magitならログで範囲選択してCherry Pickができる

![rebase_onto1.png](https://qiita-image-store.s3.amazonaws.com/0/39647/c48940d1-a747-e986-d66a-757518f9f402.png)

masterに`E-F`をCherry Pickする。

masterをcheckout後に<kbd>l</kbd> <kbd>b</kbd>で上記ログ画面をだし、`E-F`を選択(<kbd>Ctrl</kbd>+<kbd>Space</kbd>で選択できる)

![cherry_pick1.png](https://qiita-image-store.s3.amazonaws.com/0/39647/46c37c76-c566-d17a-83d9-d95ec2df4a31.png)

`A`でCherry Pickモードにして

![cherrypick2.png](https://qiita-image-store.s3.amazonaws.com/0/39647/71557f53-e33a-d174-f55b-a01ce9fd604c.png)

<kbd>Shift</kbd> + <kbd>a</kbd>でCherry Pick実行。

Eのコミットがコンフリクトしてしまった。

![cherrypick6.png](https://qiita-image-store.s3.amazonaws.com/0/39647/6fe31bca-7311-285c-50c8-2cb032b38241.png)

ファイルを編集してコンフリクトを解消し、Stagingした後、magit内で<kbd>Shift</kbd> + <kbd>a</kbd>を押すとCherry Pickを継続するか来てくる

![cherrypick7.png](https://qiita-image-store.s3.amazonaws.com/0/39647/e9124509-49ae-6c01-aa58-5bbd10e21a79.png)

<kbd>Shift</kbd> + <kbd>a</kbd>で続行する。
(なお、<kbd>a</kbd>を選択するとCherry pickの取り消しができる)

コミットメッセージを聞いてくるので通常はそのまま`C-c C-c`でコミット実行

![cherrypick8.png](https://qiita-image-store.s3.amazonaws.com/0/39647/073c67df-caec-5731-2ad8-28e899c12e8e.png)

Cherry Pickが完了した。

![cherrypick9.png](https://qiita-image-store.s3.amazonaws.com/0/39647/4ddab5ac-d431-9d60-8d1d-0f2a1207e92d.png)
select + map するならinject / reduceよりもeach_with_object

## 要約
コレクションに対して

1. 絞り込みと
2. データ処理

をしたいときはeach_with_objectを使うと良いという話です。

## 詳細

[Effective Ruby](http://amzn.to/2bDBZNP)を読む中で、よく書きがちな以下のコードに対して**inject / reduceを用いよ**という教えが書かれていました。

```rb

# こんなデータがあるとする。
User = Struct.new(:name, :age)
users = [
  User.new('user1', 21),
  User.new('user2', 19),
  User.new('user3', 23),
  User.new('user4', 35),
  User.new('user5', 10),
  User.new('user6', 18),
  User.new('user7', 24),
  User.new('user8', 15),
  User.new('user9', 21),
]

# 成人だけを絞り込んで、その名前リストが欲しい。そんなときは...

# これよりも
users.select { |u| u.age >= 20 }.map(&:name)

# これがいい(パフォーマンス的に。)
users.inject([]) do |result, user|
  result << user.name if user.age > 20
  result # injectのブロックは必ずnil以外を返そう。
end
```

「お、なるほど」「injectの引数に空配列か〜」と勉強になったなと思いながら、そのようなコードを書いたところ、rubocopが**``Use `each_with_object` instead of `inject`.``**とメッセージを発していました。


何だこれと思い調べてみると、[リファレンス](http://ref.xaio.jp/ruby/classes/enumerable/each_with_object)には以下のように説明が。

>each_with_indexメソッドは、要素を使って何らかのオブジェクトを操作するのに使います。要素の数だけブロックを繰り返し実行し、繰り返しごとにブロック引数itemには各要素を、memoには引数objectで指定したオブジェクトを入れます。戻り値は、objectのオブジェクトです。

- **each_with_objectの引数をブロック引数に持ち**
- その引数をメモとして更新しつつ、各要素ごとにブロックを回す
- なので、ブロックの返り値を明示的に書かなくていい
    - 返り値を次のブロック引数として渡すわけではないので

といった使い方で、**select + map目的であればeach_with_objectを使ったほうが用途に適切**なコードになるとのこと。

書き換え後がこちら

```rb
users.each_with_object([]) do |user, result|
  result << user.name if user.age > 20
end
```


冒頭の目的であればeach_with_objectを使うべきというtipsでした。
SELinuxの操作

# SELinuxの操作

## 確認環境
「さくらのVPS」 http://vps.sakura.ad.jp/
カスタムOSインストール:CentOS7
での確認となります。

## 前提
「SELinuxが原因でうまくいかない？」と原因を切り分けるために停止が必要な場合もあるかと思いますが、SELinux停止のリスクをご理解した上での操作をお願いします。

## SELinux動作確認
```shell-session
# getenforce
Enforcing
```

getenforceコマンドでSELinuxの状況を確認できます。

| 状況 | 意味 |
|:-:|:-:|
| Enforcing  | 有効 |
| Permissive  | 無効（ただし警告あり） |
| Disabled  | 無効 |

## 一時的な無効化/有効化

### 一時的な無効化
```shell-session
# setenforce 0
```
実行後、すぐにSELinuxは無効になります。
### 一時的な有効化
```shell-session
# setenforce 1
```
実行後、すぐにSELinuxは有効になります。

## 起動時のSELinux有効・無効設定
/etc/selinux/config を直接編集します。

```text
SELINUX=enforcing ※disableにすると無効
```
再起動後に有効となります。

## 謝辞
以下を参考にしました。ありがとうございます。

selinuxの無効化
http://www.server-memo.net/centos-settings/selinux/deiabled-selinux.html
SELinuxの設定
http://rfs.jp/server/security/selinux01.html
C node を rust で書いてみた

[「ElixirからRustの関数をつかう → はやい」][1] では Erlang/Elixir からネイティブプログラムを呼び出す方法として以下の３つが紹介されています。

1. [Port Driver][2]
1. [Port Linked-In Driver][3]
1. [NIF][4] (Native Implemented Function)

ざっくり VM の外（1）か内（2, 3）かという事ですが、実は外も2種類：プロセスが親子になる場合（1）とならない場合があります。詳細は[こちら][5]。

今回はそのならない場合：[C Node][6] を rust で[書いてみました][0]。
お題は元記事のものをコピペで使わせて頂きます。

## 0. 環境
os: darwin-15.6.0 ／ MacBook Air（Mid 2011）

erlang: 19.0（erl_interface: 3.9）／ [kerl][7] で野良ビルド
rust: 1.11.0 ／ homebrew版

src は https://github.com/tomaon/ei にあります。

## 1. [epmd][8]（Erlang Port Mapper Daemon）の起動
```bash
$ epmd -daemon
$ epmd -names
epmd: up and running on port 4369 with data:
```
erl が上げてくれますが、先に上げておきます。

## 2. C node の起動
```bash
$ cargo run --example cnode
local: V6([::1]:3456)
epmd : (3456, 5)
```
ノード名は "r1@localhost"、ポートは 3456 です（決め打ち）。
一応 epmd に登録されていることを確認します。

```bash
$ epmd -names
epmd: up and running on port 4369 with data:
name r1 at port 3456
```

## 3. calc_pi の実行
```erlang
-module(cnode).

-export([calc_pi/2]).

calc_pi(N, NumThreads) ->
    {any, 'r1@localhost'} ! {N, NumThreads},
    receive
        Any ->
            Any
    end.
```
クライアント側も決め打ちです。

```bash
$ cd examples
$ erl -sname e1 -proto_dist inet6_tcp
```
C node が IPv6 で上がっているのであわせます（重要）。

``` erlang
Eshell V8.0  (abort with ^G)
(e1@x)1> c(cnode).
{ok,pi}
(e1@x)2> timer:tc(cnode, calc_pi, [1000000000,10]).
{16735480,{ok,3.141592655589816}}
```
はや、くはないですね。なんせ非力なマシンなので。。

## まとめ
C node はやるべき事が多すぎて辛いです（全然やれてないですが）。
Port Driver の方が幸せになれます、たぶん。

初めての rust、とにかく動いて良かった。

[0]: https://crates.io/crates/ei
[1]: http://qiita.com/tatsuya6502/items/52c2817b5ccae6d51197
[2]: http://erlang.org/doc/tutorial/c_port.html
[3]: http://erlang.org/doc/tutorial/c_portdriver.html
[4]: http://erlang.org/doc/tutorial/nif.html
[5]: http://erlang.org/doc/tutorial/users_guide.html
[6]: http://erlang.org/doc/tutorial/cnode.html
[7]: https://github.com/kerl/kerl
[8]: http://erlang.org/doc/man/epmd.html
[Emacs] magitでrebase --onto


magitでの`rebase --onto`がちょっとわかりにくかったのでメモ

magitのバージョンは2.7

![rebase_onto1.png](https://qiita-image-store.s3.amazonaws.com/0/39647/fe5f0a75-02f0-bf9a-b0c1-afed29bdbd28.png)

このようなツリーになっていて`E-F`をmasterに繋げたいとする。
Fのコミットにいる状態でmagitに入って<kbd>r</kbd>でrebaseモードに入る。

![rebase_onto2.png](https://qiita-image-store.s3.amazonaws.com/0/39647/14470847-55d6-7333-bc48-dbf73f940b21.png)

ここで<kbd>e</kbd>(elsewhere)ではなく<kbd>s</kbd>(subset)を選択。

ミニバッファにつなげる先（ここではmaster）を入力。

![rebase_onto4.png](https://qiita-image-store.s3.amazonaws.com/0/39647/5b596a9b-fb4e-d032-76e6-8ff220e7acd0.png)

以下の画面となるので移動する先頭(ここではE)を選択し`C-c C-c`

![rebase_onto3.png](https://qiita-image-store.s3.amazonaws.com/0/39647/994eaaaf-68c4-5a65-a9a8-41aa6f2c1d40.png)

コンフリクト等が起きた場合は通常のrebaseと同じように処理して、最終的に求めていた形となった。

![rebase_onto5.png](https://qiita-image-store.s3.amazonaws.com/0/39647/484a3b85-7875-912c-b5e6-edb818cf720b.png)
PostgreSQLのロック


## ロックとは
ロックとは、あるトランザクションがレコードにアクセスしているときに，別のトランザクションからそのレコードにアクセスできないようにする仕組みのことです。

PostgreSQLの場合、トランザクションからの同時実行を確実にするために、テーブル・行に対して明示的なロックを獲得することができます。
また、ほとんどのPostgreSQLコマンドでは、参照されるテーブルがそのコマンドの実行中に別の方法で削除もしくは変更されていないことを確実にするために、SQLの実行の裏で、適切なモードのロックを自動的に獲得します。 

## テーブル単位のロック
テーブル単位のロックは、LOCK文を使用します。

```
LOCK [TABLE] table_name [IN lock_mode MODE] [NOWAIT]
```

ターミナルを2つ開いて試してみます。

```
transaction_a=# BEGIN;
transaction_a=# LOCK TABLE hoge_table IN EXCLUSIVE MODE;

transaction_b=# BEGIN;
transaction_b=# UPDATE hoge_table SET hoge_column = 'fuga';
-- トランザクションaでロック中のテーブルにUPDATEをかけているため、waitになる

transaction_a=# COMMIT;
transaction_b=# UPDATE num -- UPDATE分が実行される
```

※ NOWAIT：ロックが取得でないとき、待たずにエラーを返す

### ロックモード
ロックモードは色々あるので、[公式ドキュメント](https://www.postgresql.jp/document/9.5/html/explicit-locking.html)をご参照ください。

## 行単位のロック
行単位のロックは、SELECT文のオプションとして`SELECT FOR UPDATE`または`SELECT FOR SHARE`を使用します。

ターミナルを2つ開いて試してみます。

```
transaction_a=# BEGIN;
transaction_b=# BEGIN;

transaction_a=# UPDATE hoge_table SET hoge_column = 'fuga' where id = 1;
transaction_b=# SELECT * FROM hoge_table WHERE id = 1;
-- ロックしようとしている行の変更がトランザクションaでコミットされてないため、ここでwaitになる

transaction_a=# COMMIT;

transaction_b=# -- SELECT文の結果が表示される
```


## デッドロック
デッドロックとは、二つのトランザクションが，互いに相手の所有するロックが解除されるのを待機して処理が進まなくなる状態のことです。

例えば次のような例を考えてみます。

```
transaction_a=# BEGIN;
transaction_b=# BEGIN;

transaction_a=# UPDATE hoge_table SET hoge_column = 'fuga' where id = 1;

transaction_b=# UPDATE hoge_table SET hoge_column = 'fuga' where id = 2;
transaction_b=# UPDATE hoge_table SET hoge_column = 'fuga' where id = 1;
-- トランザクションaでコミットされていないためwaitになる。トランザクションbはトランザクションaが完了するのを待つ

transaction_a=# UPDATE hoge_table SET hoge_column = 'fuga' where id = 2;
-- トランザクションbでコミットされていないためwaitになる。トランザクションaはトランザクションbが完了するのを待つ
-- トランザクションaもトランザクションbも、お互いのトランザクションが完了するのを待っているため、これ以上進まない。そのため、デッドロックが発生する
ERROR:  deadlock detected
DETAIL:  Process 93169 waits for ShareLock on transaction 112598; blocked by process 93173.
Process 93173 waits for ShareLock on transaction 112596; blocked by process 93169.

transaction_a=# SELECT * FROM hoge_table;
-- トランザクションがアボートされているのでエラーになる
ERROR:  current transaction is aborted, commands ignored until end of transaction block
```

上記の場合、トランザクションaもトランザクションbも、お互いのトランザクションが完了するのを待っているため、これ以上処理を進めることができません。これがデッドロックであり、そうなると片方のトランザクションを強制終了することで、もう片方の処理を完了させます。

## 勧告的ロック
SQL文による自動ロックや明示的ロックの他に、アプリケーション固有の排他的制御を行いたい場合、勧告的ロックを使用します。勧告的ロックは、MVCC方式に合わせづらいロック戦略で有用に使用することができます。例えば、トランザクションをまたいで排他的制御を行い場合、セッションレベルでのロックを使用することができます。

## 参考
* [13.3. 明示的ロック](https://www.postgresql.jp/document/9.5/html/explicit-locking.html)
* 内部構造から学ぶPostgreSQL 設計・運用計画の鉄則 4.5
RepoForge(rpmforge)は入れてはいけない

# はじめに
理由については以下２つのURLを参考にしていただければ。

CentOSでは、epelとrpmforgeリポジトリを加えるのが、(remiを使う場合を除けば)これまでの定番（？）であったと思いますが、今後はrepoforgeを追加されないようご注意ください。

## CentOS Wiki

https://wiki.centos.org/AdditionalResources/Repositories/RPMForge

> RPMForge/RepoForge is a dead project. It is not maintained. DO NOT USE.

## RepoForge

http://repoforge.org/

> RepoForge might be outdated. We have no updates since very long time.
jQueryで選択されているセレクトボックスの属性の値の取り方

選択されているセレクトボックスからdata属性の値を取得しようとしたら、
調べないとわからなかった。。。

```html:sampleSelecbox.html
<select id="selectBox">
	<option data-type="A">1</option>
	<option data-type="A">2</option>
	<option data-type="B">3</option>
	<option data-type="B">4</option>
	<option data-type="C">5</option>
</select>
```
上記のような、セレクトボックスがあった状態で、
valueを取るのはよく行うのでお馴染みのアレでさっと書ける。

```js:getValueBySelected.js
$("#selectBox").val();
```
valueを取るだけなら上ので一発。
ただ、選択されているセレクトボックスのdata-typeの値を取得するのにはちょっと工夫が必要。

```js:getAttrBySelected.js
$("#selectBox option:selected").data("type");
```
とは言っても、上記のように書くだけで取得可能。
OSXで突然Apacheが起動しなくなった時

ある朝、いつも通りMacbookを起動したのですが、ローカルPCのApache(localhost:80)につながりません。
いろいろなWebアプリをインストールして、ローカルで作業しているので、致命的に困った事態発生です。
そういえば、寝る前に・・・何かのアップデートがあったような気がするのですが・・・。寝ぼけていて覚えていません。
そのため、原因なのか分かりません。

というわけで、原因を調査していきましょう。その様子をここにメモします。たぶん、他の方もそんな状態になることがあるかもしれません。

## Apacheを再起動

大抵は、再起動すると直ります。

```bash
$ sudo apachectl restart
```

問題があれば、ここでエラーが表示されるはずなのですが・・・しかし、今回エラーも何も表示されません。

## エラーログを確認しよう

大抵の問題は、エラーログに何かしらのメッセージが記録されます。

以下のパスにどこかにある、エラーログを確認してみましょう。

```
/var/log/apache2/error_log
/private/var/log/apache2/error_log
/var/log/httpd/error_log
```

今回私の症状ですが、なんと、エラーログにも何も記録されていません。昨夜に寝る前にアプリをデバッグした痕跡は残っているのですが、今朝、この瞬間のログは何も記録されていませんでした。

## ポートが占有されてないか確認

それでは、本腰入れてトラブルシューティングしようと思いました。

まず、試したのは、ポートスキャンして、他にポート80を占有しているアプリがないかを確認することからです。以下のアプリで、Portscanのタブを開いて、localhostのポート80番を調べます。

OS X：ネットワークユーティリティについて
https://support.apple.com/ja-jp/HT202790

あるいは、男らしくコマンドを打って確認しましょう。

```bash
$ sudo lsof -i -P | grep "LISTEN"
```

そういえば、何かアプリをインストールした気がする・・・と思ったら、そのアプリがポート80番を占有していないでしょうか。

私の今回の症状では、ポート80番には何も表示されません。

## 設定ファイルが壊れていないか確認

希に、インストールしたアプリが、勝手に、Apacheの設定ファイルを書き換えることがあります。そこで、設定ファイルが正しいかどうか調べましょう。

```bash
$ apachectl configtest
```

と、ここでエラーが出ました。

```
Syntax error on line 170 of /private/etc/apache2/httpd.conf: Cannot load /usr/local/opt/php56/libexec/apache2/libphp5.so into server: dlopen(/usr/local/opt/php56/libexec/apache2/libphp5.so, 10): Symbol not found: _ldap_control_find\n  Referenced from: /usr/local/opt/php56/libexec/apache2/libphp5.so\n  Expected in: /System/Library/Frameworks/LDAP.framework/Versions/A/LDAP\n in /usr/local/opt/php56/libexec/apache2/libphp5.so

```

どうやら、PHPのApacheモジュールの読み込みで死んでいるようです。ここまで分かれば何とかなりそうです。

エラーメッセージでググってみると・・・

https://github.com/Homebrew/homebrew-php/issues/3074

ありました。全く同じエラーメッセージが出ています。

どうやら、ApacheとPHPの相性の問題です。そういえば、先日、brew updateをかけた気がする・・・

このスレッドに解決策も書かれていました。

```bash
$ brew uninstall php56
$ brew cleanup
$ brew install php56
```

ただ、これをやっても解決しません。。。それで、さらいスレッドの下の方を読んでいくと、やはりこれでも解決できないという書き込みがあり、以下のようにした直ったという話がありました。

```bash
brew uninstall php56
brew cleanup
brew update
brew install php56 --without-ldap
```

なるほど、LDAP関係のエラーなので、LDAPをオプションから外してコンパイルするのでしょう。

試してみると、無事解決しました。

最初、エラーを見つけたときに、Homebrewのphp56が問題だと思ったので、最新のphp71を試したのですが、それでも直らなかったので、どうしようかと思っていたのですが、なんとかなって良かったです。

## 結論

ある日、突然、Apacheが動かなくなることもありますが、一つずつ、落ち着いて対処していけばなんとかなるようです。

Apacheが動かなかったので、とりあえず、PHPの簡易サーバーを使ったのですが、ちょっとしたWebアプリをテストするにはそれでも十分ですね。
Ubuntu16.04(さくらVPS)で１からcronの設定をし、pythonプログラムを定期実行する

# 目的
Ubuntu上にあるpythonのプログラムを定期的に自動実行したいです。
cronを１から設定しました。

# 環境
OS     : Ubuntu16.04 (さくらVPS）
python : Version 3.5

# CRONの初期設定
## <b>操作１) CRONの動作確認 </b>

```
sudo service cron status
```

色々CRONの状態が表示されていますが、
「Active: active(running)」と表示されていればOKでしょう。

動いていない場合は、

```
service crond start
```

で起動します。

## <b>操作２) cronの設定ファイルにジョブを登録 </b>

cronの設定ファイルであるcrontabは以下のコマンドで実行できます。

```
crontab -e
```

ただし、キーボード上でeの隣にあるrを誤って押すと、「crontab -r」がcrontabの設定を全て初期化してしまいますので、「crontab -e」を頻繁に使うのは危険です。

crontab -eを使わない方法は複数ありますが、私は以下の手順でバックアップを取りながら別で編集をしています。

```
crontab -l > ~/crontab #バックアップ
vim ~/crontab        #バックアップを編集
crontab < ~/crontab  #本体に上書き
```

crontabの書き方については、他のサイトで詳細書いてありますので、そちらを参考にすると良いでしょう。例えば[こちら](http://www.server-memo.net/tips/crontab.html)なんかが分かりやすかったです。

なおpythonプログラムを実行する時は、プログラムの前に、pythonが格納されているパスを書かなければいけません。

例えば、毎分ごとにtest.pyを実行したい場合は、

```
* * * * * /<path_to_python>/python3 /<path_to_file>/test.py 
```

となります。

pythonへのパスが分からなければ、

``` 
which python3
```

で調べられます。

ログを出力したい場合は、

```
* * * * * <path_to_python>/python3 /<path_to_file/test.py >> /<path_to_log>/test.log 2>>&1
```

で良いでしょう。

## <b>操作3) ファイルの権限を変更する </b>

基本的には操作２までの設定で良いのですが、私の場合はPermission Deniedのエラーが出ていました。CRONの実行権限がrootでファイルの所有者が別のユーザだったため、権限設定の関係でPermissionがおりなかったという状態です。

とりあえず、「所有者：root, 権限700」に変更します。

```
chmod 700 test.py
chown root:root test.py
```

以上で、test.pyは定期的に自動実行されるようになりました。
swift2.0で2つの日付の差分を調べる


例えば、2000/10/09と2000/11/09の差分を調べたい場合。

```swift
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy/MM/dd"

let start = "2000/10/09"
let end = "2000/11/09"
let startDate:NSDate? = dateFormatter.dateFromString(start)
let endDate:NSDate? = dateFormatter.dateFromString(end)
let cal = NSCalendar.currentCalendar()
let calUnit:NSCalendarUnit = [.Day]
let components = cal.components(calUnit, fromDate: startDate!, toDate: endDate!, options: NSCalendarOptions())

print(components.day)
```

こうすると差分日数は「31」だとでてきます。

上の例は差分の日数のみ取得していますが、年や月まで知りたい時はNSCalendarUnitでその旨、指定してあげるといいです。
let calUnit:NSCalendarUnit = [.Year, .Month, .Day]
のように。
Qiitaに初投稿するモチベが湧かない人へ贈る 2つの投稿結果のグラフ

## この記事の目的
Facebookのいいね依存症の例ではありませんが、
記事を投稿する以上は、たくさんの人に見て欲しいと思ってしまうのは当然の欲求かと思います。

乱暴な認識ですが、「Facebookのいいね」＝「Qiitaのストック数」と考えると
いいねの伸び率が悪い投稿は積極的に投稿する気になれない人が一定数いるはずです。

今回の記事はそのような理由で投稿をためらっている人に知って欲しいQiitaの機能についての投稿です。

# 投稿をすると閲覧数が見れる！
この記事の画面右上にも「0ストック | 0コメント」といった
ストック数とコメント件数が表示されているかと思います。
<img width="292" alt="スクリーンショット 2016-08-30 12.51.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/130316/5fb37d1b-f1f3-e3b4-f627-1a5e268df14e.png">

投稿する前は私も知らなかったのですが、
自分の投稿には閲覧数が追加で表示されるようになります。
<img width="298" alt="スクリーンショット 2016-08-29 12.42.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/130316/edcb08c2-f55b-ea18-29e7-698f1a931333.png">

これによって、たとえストック数が0であろうと**閲覧数**を知ることができるのです！

## 反論：閲覧数が見えても俺の記事は誰も見ねぇよ
「いや、以外と多くの人が見てるンスよ」と言うだけでは説得力が無いので、
次のような実験をしました。

> 次の二つを記事を書いてその閲覧数を比較する
> ・ストック数が1桁になるような記事
> ・ストック数が2桁になるような記事

(ストック数が0件の記事は、誰がストックしないとも限りませんし、空ページなどのゴミ投稿するのもアウトなので諦めました。ストック数が3桁の記事は、そもそも狙ってそのような記事を書けるならノウハウとして投稿できるレベルなので無理でした)

## ストック数1桁を目指した書いた記事

記事はこちらです → [Enum の「equals」vs「==」(右の勝ち)](http://qiita.com/hcl/items/8e554df74332a6b79bcc)

まずは、ストック数1桁を目指して書いた記事のグラフ
![enum_1week.png](https://qiita-image-store.s3.amazonaws.com/0/130316/2a2b650f-f948-7bfa-2499-707f1b7891ea.png)
図1 - ストック1桁の投稿後1週間のグラフ

![enum_1month.png](https://qiita-image-store.s3.amazonaws.com/0/130316/3e82df15-f41c-b980-3066-d56821b5385d.png)
図2 - ストック1桁の投稿後約1ヶ月間のグラフ


## ストック数2桁を目指して書いた記事
記事はこちらです → [Java9で追加されたメソッド一覧とその使い方](http://qiita.com/hcl/items/c684aa1b85d2425f0151)

次に、ストック数2桁を目指して書いた記事のグラフ

![Java9_1week.png](https://qiita-image-store.s3.amazonaws.com/0/130316/fa1d81a2-601c-db2e-729f-6c85b7fd89f7.png)
図3 - ストック2桁の投稿後1週間のグラフ

![java9_month2.png](https://qiita-image-store.s3.amazonaws.com/0/130316/ddb359df-501a-4c83-22ef-92f79caae894.png)
図4 - ストック2桁の投稿後約1ヶ月間のグラフ

# 結果・考察
> 1. 当然ながら、ストック数が多いほど閲覧数は多い
> 2. ストック数が約6.7倍の差があるにもかかわらず最終的な閲覧数は約3.0倍しか違わない
> 3. 悲観して想定するよりも多くの人に閲覧される可能性を秘めている！！！

### 付録:ストック数と閲覧数の表の抜粋

ストック数1桁の記事の結果抜粋

|経過時間|ストック数|閲覧数|ストック率|
|------:|------:|---:|------:|
|   1時間|     2|   79|2.53%|
|    1日|     16| 460|3.48%|
|   1週間|     19| 691|2.75%|
|   1ヶ月|     20|  814|2.46%|

ストック数2桁の記事の結果抜粋

|経過時間|ストック数|閲覧数|ストック率|
|------:|------:|---:|------:|
|   1時間|     0|   66|0%|
|    1日|     1| 171|0.58%|
|   1週間|     3| 232|1.29%|
|   1ヶ月|     3|  273|1.10%|
sshでコマンド実行の際、&を付けてバックグラウンドで実行してもsshが終わらない。


※CentOS7環境下で確認しています。

journalctl -f -o json | ncat localhost 1111 &
を普通に実行したらプロンプトに戻るのに
ssh経由で
ssh server "journalctl -f -o json | ncat localhost 1111 &"
を実行した場合、sshが終了しなくなってしまう。

標準出力、エラー出力を/dev/nullもしくはLogに保存するようにすると返ってくる。
ssh server "journalctl -f -o json | ncat localhost 1111 >/dev/null 2>&1 &"

おそらくsshはプロセスから標準出力が切断されるまで待つがjournaldを
-fで動かしたときは標準出力を繋ぎ続けるため終了しなくなると思われる。
Ruby on rails params について

#Paramsについて

paramsはビューファイルから何か値をコントローラに送信するときに用いる。

ビューから値を送信する方法は以下の2つしかない。
①URLに値を載せる、②フォームで送信する

```ruby:routes.rb
post '/like/:note_id' => 'likes#like', as: 'like'
```

```ruby:top.html.erb
<%= link_to '保存', notes_path(@note)%>
```
Atom インストール（プロキシ環境）メモ

# インストールする環境
* Windows 8.1 Enterprise 64bit
* プロキシ利用環境下
* 本記事執筆時の ATOM のバージョンは **1.10.0**

# いざインストール
## 1. ATOM のダウンロード
[ATOM](https://atom.io/) のサイトから [Download Windows Installer] ボタンを押下して、インストーラーをダウンロードする。

![image](https://qiita-image-store.s3.amazonaws.com/0/81548/bfd54a30-a214-9693-a197-8eb2364addef.png)

## 2. ATOM のインストール
ダウンロードした AtomSetup.exe を実行して、インストーラーを起動する。

![image](https://qiita-image-store.s3.amazonaws.com/0/81548/35c0d1fa-9a38-c980-3750-662beeeebd2b.png)

## 3. ATOM の起動
インストール完了後、ATOM が起動する。

![image](https://qiita-image-store.s3.amazonaws.com/0/81548/56f2d069-6114-b339-e17a-b0544604ae51.png)

> なんかエラーでてるけど……

## 4. プロキシ設定
前にインストールしたときにプロキシ設定していたみたいで、すんなり動いてしまった。
本来なら「」の .apmrc ファイルにプロキシ設定をする必要があるはず。

```:.apmrc
proxy = http://username:password@server:port/
https-proxy = http://username:password@server:port/
strict-ssl = false
```

> こんなだったと思う。

## 5. minimap のアップデート
ATOM は一旦閉じて、コマンドプロンプトを開く。
下記コマンドを実行して、minimap をアップデートする。

```
apm update minimap
```

途中で、インストールしてよいか？と聞かれたら、『yes』を入力して [Enter] キーを押下する。

```
C:\>apm update minimap
Package Updates Available (1)
└── minimap 4.19.0 -> 4.24.7

Would you like to install these updates? (yes) yes
```

完了メッセージが表示されたら、アップデート完了。

```
C:\>apm update minimap
Package Updates Available (1)
└── minimap 4.19.0 -> 4.24.7

Would you like to install these updates? (yes) yes

Installing minimap@4.24.7 to C:\xxxxx\.atom\packages done
```

再度、ATOM を起動して、minimap に関するエラーが出ていないことを確認する。
ちなみに、コマンドプロンプトから `atom` で起動できる。

> すべてのプログラムに追加されていた ATOM のショートカットは Update.exe してから起動するもの。
> 「%LOCALAPPDATA%\atom\bin」あたりに atom.cmd や、「%LOCALAPPDATA%\atom\app-1.10.0」あたりに atom.exe が存在する。

> minimap のエラーは tokenizedLinesForScreenRows という関数が無いため。アップデートによるものみたい。
> 詳細については、[atom-minimap / minimap](https://github.com/atom-minimap/minimap/commit/fc2622f561fc9508e3da12fe4e874b06ea28039b) にて。

## 6. その他パッケージのアップデート
いくつか使いそうなパッケージをアップデートする。お好み。

[ファイル]-[環境設定]-[Updates]

* japanese-menu
* color-picker
* pigments
* seti-ui

> インストール直後にアップデートが存在したものをとりあえずアップデートしてみた。

## 7. その他パッケージのインストール
いくつか使いそうなパッケージをインストールする。お好み。

[ファイル]-[環境設定]-[Install]

* monokai
* project-manager

## 8. その他環境設定

[ファイル]-[環境設定]-[Themes]

* Seti
    * Compact Mode

[ファイル]-[環境設定]-[Packages]

* wrap-guide 無効化
ゲーム品質を上げるための自動化、オートプレイ


CEDEC 2016 で[『ベヨネッタ2』におけるゲーム品質を上げる為の自動化](http://cedec.cesa.or.jp/2016/session/PRD/1660.html)が大変割りきった設計のテストで、その割り切りっぷりが気持ちよかったので紹介します。



## オートプレイの概要
- ニューゲームからエンディングへ行くまで繰り返しプレイ
- 3ヶ月程度で実装、最初は兼業で作り2～3週間で動くように
- 同じ行動を繰り返してバグを発見・再現したいので、ランダム性は排除

本業の傍ら2～3ヶ月で動くようになったという事で少ない工数の中で実装されている点が興味深いです。続く実装方法にその秘密がありました。



## オートプレイの実装
基本的には「パッド入力の再現」のみ。なんという割り切り。
延々とパッド入力を設定し続け、それを再生するだけという事です。もちろん「アイテム入手結果画面が出てきたらボタンを固定回数連打してパッド入力を再開」など場面に応じて操作を変える点はあるものの、とてもシンプルにまとめられています。
ちなみに、開発初期の頃はナビゲーションメッシュを使っていましたが、再現性が落ちるなどの理由から結局は使われなくなったそうです。



## オートプレイの設定方法
実機で設定するのでゲームパッドを使いオートプレイのパッド入力を設定するそうです。

![cone.png](https://qiita-image-store.s3.amazonaws.com/0/39587/d676007c-8340-b570-f7b8-4f6dc6c2b3b3.png)

具体的には、ゲーム内ツールから3D空間にコーンを次々と設置します。コーンにはボタン操作などのアクションが設定できます。オートプレイを開始するとキャラクター（ベヨネッタ）がコーンまで移動し、コーンに到着すると設定されたアクションを実行するというもの。
延々と設定するのは大変そうですが、特に難しい事はないなという印象です。



## パフォーマンス計測の可視化
- ブラウザでオートプレイ中のパフォーマンスを可視化
- データは1日毎にxmlファイルへ保存
- 作っても大抵の人は見ないため、自分には関係ないと思っているのでページの作り方を工夫
  => ワクワクするページを作ろう
  => 改善した後にみんなで喜んでもらえるページを作ろう
  => 毎日開いてもらえるようなページを作ろう

データがxmlに保存されているのはDBを採用して障害対応をしたくないとのこと。セッションの冒頭で「プログラムを書きたくない、書かずにゲームを作りたい」と言われていた言葉が思い起こされました。



## 所感
やりたい事を実現するために必要最小限の設計と実装で済むよう一貫して割り切っている点が大変印象的でした。
プログラムの設計はともすると複雑に考えてしまいがちですので、講演者の森田さんのようにシンプルに小さく実装する事を心がけたいです。
MySQLのテーブル定義をマークダウン（Qiita用）で出力する

`php echo_mysql_table_structure.php database table` で単一テーブルの定義を出力できます。
`table` の部分を `all` に変更してやると全てのテーブル定義を出力します。

Qiita:Teamでテーブル定義とか共有することが多いのでつくりました。

# 動作確認環境
PHP: 5.5.36
MySQL: 5.6.23

# スクリプト

`$host` `$user` `$pass` はいい感じに入れてください。

```php:echo_mysql_table_structure.php

<?php

// 引数がアレな場合はusage表示
if (count($argv) !== 3) {
    echo "usage: php ./{$argv[0]} database_name table_name|all \n";
    exit();
}

// 引数取得 1:データベース 2:テーブル名
$database = $argv[1];
$table_names = [];

// データベース接続設定
$host = '';
$user = '';
$pass = '';
$dsn  = "mysql:dbname={$database};host={$host};charset=utf8";

// データベースオプション：Exception吐く、フェッチの結果はカラム名のみ
$options = [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC];
try {
    $pdo = new PDO($dsn, $user, $pass, $options);
}
catch (PDOException $e) {
    exit($e->getMessage() . "\n");
}

if ($argv[2] === 'all') {
    $list_table_stmt = $pdo->query("SHOW TABLES FROM {$database}");
    $list_table_stmt->execute();
    while ($row = $list_table_stmt->fetch()) {
        $table_names[] = $row["Tables_in_{$database}"];
    }
}
else {
    $table_names[] = $argv[2];
}

// 表示するshow full columnsの結果
$outputColumns = ['Field', 'Type', 'Null', 'Key', 'Default', 'Extra', 'Comment'];

ob_start();

$table_stmt = $pdo->prepare("SHOW TABLE STATUS LIKE :table_name");
foreach ($table_names as $table_name) {
    // テーブルコメント出力
    $table_stmt->bindValue(':table_name', $table_name);
    $table_stmt->execute();
    while ($row = $table_stmt->fetch()) {
        echo "# {$table_name}\n";
        echo "{$row['Comment']}\n";
    }

    echo "## {$table_name} Fields\n\n";
    echo '|' . implode('|', $outputColumns) . "|\n";
    echo '|';
    foreach ($outputColumns as $dummny) {
        echo ':--|';
    }
    echo "\n";

    // カラムの定義出力
    try {
        $stmt = $pdo->query("SHOW FULL COLUMNS FROM {$table_name}");
        $stmt->execute();
    }
    catch (PDOException $e) {
        ob_clean();
        exit($e->getMessage() . "\n");
    }

    while ($row = $stmt->fetch()) {
        echo '|';
        foreach ($outputColumns as $column_name) {
            echo "{$row[$column_name]}|";
        }
        echo "\n";
    }
    echo "\n";
}
```
Ubuntu16.04にMongoDBをインストールして、python経由で操作する

# 環境
OS      : Ubuntu16.04 (さくらVPS)
MongoDB : 2.6.10
python  : 3.5

# MongoDBのインストール

```bash:MongoDBのインストール

1) 公開鍵の設定
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10

2)　mongodb.listの作成
echo 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen' | sudo tee /etc/apt/sources.list.d/mongodb.list

3) 実際にインストールする
sudo apt-get update
#sudo apt-get install mongodb-10gen

4) mongod.serviceの作成
sudo vim /lib/systemd/system/mongod.service

　▼mongod.serviceの中身

　[Unit]
　Description=MongoDB Database Service
　Wants=network.target
　After=network.target

　[Service]
　ExecStart=/usr/bin/mongod --config /etc/mongod.conf
　ExecReload=/bin/kill -HUP $MAINPID
　Restart=always
　User=mongodb
　Group=mongodb
　StandardOutput=syslog
　StandardError=syslog

　[Install]
　WantedBy=multi-user.target

```

（参考URL）　http://qiita.com/pelican/items/bb9b5290bb73acedc282

# pymongoのインストール
pythonからMongoDBを操作するpymongoパッケージをインストールする

```
pip3 install pymongo
````

# mongoDBの起動

```
sudo systemctl start mongod
```

# 実際にpythonから操作してみる

```
from pymongo import MongoClient

if __name__ == "__main__":

#MongoDBへの接続
mongo = MongoClient('localhost:27017')
#データベースの選択
db = mongo_client['test']
db['test'].insert_one({ "name" : "A", "age": 30 })
```

より詳細な操作などは、以下URLを参照しました。
http://goo.gl/xVmzuI
UserAgentの設定をとても簡単にカスタムする方法


``2016/0901 この記事は環境：Xcode7.3.1です。``


## 目的
WebViewで表示する際サーバにRequestするUser-Agentヘッダーにアプリバージョンを付与させたい。

## AppDelegateを編集する(UIWebView)
WebViewを使って通信を行う前に設定をしないと反映されないので、AppDelegateの ``didFinishLaunchingWithOptions``に記述します。



```objc
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

// デフォルトのUserAgentを取得するために、サイズゾロのUIWebViewインスタンスを生成
    UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectZero];

    // デフォルトのUserAgentを取得
    NSString *userAgent = [webView stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"];

    NSString *appVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"];

    // デフォルトのUserAgent文字列後尾にアプリバージョンを追加した文字列を作成
    NSString *customUserAgent = [userAgent stringByAppendingString:[NSString stringWithFormat:@" AppVersion/%@",appVersion]];

    // UserAgentをkyeとし,customUserAgentをvalueとした辞書型変数を作成
    NSDictionary *userAgentDict = [[NSDictionary alloc] initWithObjectsAndKeys:customUserAgent, @"UserAgent", nil];

    // ユーザーデフォルトにカスタムUserAgentを設定
    [[NSUserDefaults standardUserDefaults] registerDefaults:userAgentDict];

 }
```

デフォルトUserAgentを使用しない場合の記述はとても少なく、上記``didFinishLaunchingWithOptions``において2行で設定できます :smile: 


```objc

   // UserAgentをkyeとし,customUserAgentをvalueとした辞書型変数を作成
    NSDictionary *userAgentDict = [[NSDictionary alloc] initWithObjectsAndKeys:@"InsertCustomUserAgent!!", @"UserAgent", nil];

    // ユーザーデフォルトにカスタムUserAgentを設定
    [[NSUserDefaults standardUserDefaults] registerDefaults:userAgentDict];

```



## AppDelegateを編集する(WKWebView)
同じくWebViewを使って通信を行う前に設定をしないと反映されないので、AppDelegateの ``didFinishLaunchingWithOptions``に記述します。WKWebViewはUserAgentプロパティが用意されているので代入するだけで設定可能です。

```objc
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    WKWebView *webView = [[WKWebView alloc] init];
    webView.customUserAgent = @"InsertCustomUserAgent!!";
}
```
RubyでPEG使ってCのパーサ(のようなもの)書いてみた


RubyでCパーサのようなもの書いてみたという記事です。  
Cパーサを書いたといってもPythonで実装されたpycparserのような厳密で完成度の高いCパーサではなく、実装も3日程度で済ませた雑実装なのであしからず。

リポジトリ: [github.com/hsssnow23/Captain](https://github.com/hsssnow23/Captain)

サンプル
input:

```c
typedef struct {
    unsigned int id;
    float x;
    float y;
} Actor;
```
output:

```
#<CTypedef:0x000000037809a8
 @from=
  #<CStruct:0x0000000376a068
   @body=
    [#<CVariable:0x000000034f0350
      @name="id",
      @type=
       #<CType:0x000000034f3780
        @const=false,
        @name="int",
        @pointer=false,
        @prefix="unsigned">,
      @value=nil>,
     #<CVariable:0x000000035b6ca8
      @name="x",
      @type=
       #<CType:0x000000035ad950
        @const=false,
        @name="float",
        @pointer=false,
        @prefix=nil>,
      @value=nil>,
     #<CVariable:0x000000036a0df8
      @name="y",
      @type=
       #<CType:0x000000036a3a30
        @const=false,
        @name="float",
        @pointer=false,
        @prefix=nil>,
      @value=nil>],
   @name=nil>,
 @to="Actor">
```

もともとCにアノテーションなどで付加情報を付け、コードの自動生成を行うツールのために作ったパーサなのですが、どうにも遅い。おそらく実装に使用したPEGパーサがおれおれ実装でPackrat Parsingしてないのが主な原因だと思います。なのでこの記事ではPEGパーサを実際に使ってみてどうだったかということを書きたいと思います。

## 先にざっくりまとめ

### PEGのメリット

- Rubyのような演算子オーバーロードができる言語ではDSLのように書けるのでわかりやすい。(lex yaccなどのパーサジェネレータはお作法が多いので若干とっつきづらいと思います)
- 速度を度外視する単純なものならPEGパーサ自体の実装が楽。（最終的にPEGパーサ自体の実装は269行。）
- 字句解析と構文解析を同時に行えるので手間がはぶける。よって正規表現のように手軽に使える。
- 正規表現と違い括弧の対応付けなどのパースができる。

### PEGのデメリット
- 単純な実装だとO(n)で実行できない。
- 左再帰ができない。

## 感想

楽。圧倒的に楽です。なにが楽かというと思い立ったらすぐに書き始められるというところが他のパーサに比べた大きなメリットかと思います。  
字句解析すっ飛ばしてパーサ書いていきなり構文木作れるので、簡単なパーサだけど正規表現よりはリッチにやりたいなんてときには一番向いていると思います。  
しかし、Cのパーサのようなすでに仕様としてあるもののパーサをPEGで書くのは少し大変かなと思いました。既存のプログラミング言語の多くはlexやyaccなどのパーサジェネレータで作られており、それらとの整合性を確保するのが大変だということと、PEGはまだ歴史が浅く、どこまでパースできるかがあまりわかっていないらしいです。（正直、隅をつつくようなC言語のソースだとパースできる自信薄い）

ただし、パースした内容によってパーサ自体が変化するようなパーサは書きやすそうと感じました。（それが必要になる場面は少ないとは思いますが）

## まとめ
自分の最終的な結論としてPEGは最高におすすめのパーサです。  
しかし、自分で仕様を決めることができる小さいフォーマットのパーサは間違いなく向いていると思いますが、その他に使用するのは微妙かもしれないと思いました。

参考記事：
http://kmizu.hatenablog.com/entry/20100203/1265183754
Unity Androidのストレージ残量を取得(Android4.4.2、5.1.1、6.0.0による確認済み)

下記URLを参考にしました。
http://qiita.com/snaka/items/35a6389d35447c2db272

ボタンを押すとプラグイン内のメソッドを呼ぶようにサンプルプログラムを作る。
![容量チェック.png](https://qiita-image-store.s3.amazonaws.com/0/17904/cf206e95-0708-876d-9bcd-698436316625.png)


## ■クリックが押されると計算用処理を呼ぶ

```
using UnityEngine;
using System.Collections;

public class testClick : MonoBehaviour {

    public void OnClick()
    {
        CallPlugIn.test();
    }

}
```

## **■各サイズを取得**

```
using UnityEngine;
using System.Collections;


public class CallPlugIn : MonoBehaviour {

    public static void test()
    {
        Debug.Log("1");
        var statFs = new AndroidJavaObject("android.os.StatFs", Application.temporaryCachePath);
        Debug.Log("2");
        // 指定したファイルシステムでアプリケーションが利用できる領域のブロックサイズを返します。
        var availableBlocks = statFs.Call<long>("getAvailableBlocksLong");
        Debug.Log("3");
        // 指定したファイルシステムで利用できる領域のブロックサイズを返します。返されるブロックにはアプリケーションから利用できない領域を含みます。
        var freeBlocks = statFs.Call<long>("getFreeBlocksLong");
        Debug.Log("4");
        // ファイルシステムのブロックサイズを返します。単位はByte。
        var blockSize = statFs.Call<long>("getBlockSizeLong");
        Debug.Log("5");
        // ファイルシステムの総ブロック数を返します。
        var blockCount = statFs.Call<long>("getBlockCountLong");

        Debug.Log("■getAvailableBlocks=" + availableBlocks.ToString());
        Debug.Log("■getFreeBlocks=" + freeBlocks.ToString());
        Debug.Log("■getBlockSize=" + blockSize.ToString());
        Debug.Log("■getBlockCount=" + blockCount.ToString());
    }
}

```

## **■空き容量を求める**

 **availableBlocks**と**blockSize**掛け合わせると空き容量の合計バイト数が計算できる。

メガバイトに変換するには

　availableBlocks*blockSize/(1024*1024)　とする。
衝撃な発見。原因不明

$$\frac{n+1}{n}\=(n+1)*n^{-1}$$
普通に成り立つ等式で、何も違和感がないです。

```
> n <- 1:100
> which( (n+1)/n != (n+1)*n**(-1) )
 [1]  5  6 13 21 24 28 30 37 38 40 45 46 52 54 77 83 91 96

> n <- 1:1000
> which( (n+1)/n != (n+1)*n**(-1) )
  [1]    5    6   13   21   24   28   30   37   38   40   45   46   52   54   77   83   91   96  105  106  109  117  122  123  133  135  137  149  150  167
 [31]  181  189  191  198  200  211  214  220  224  234  235  248  249  281  288  296  297  301  304  328  342  343  347  371  383  384  391  392  394  412
 [61]  425  432  436  438  439  454  456  459  463  474  475  477  480  486  492  497  498  501  515  524  534  540  542  544  548  552  569  578  579  587
 [91]  590  598  609  613  618  629  637  640  653  672  691  695  698  701  702  705  724  725  734  735  737  746  754  756  767  774  782  783  791  808
[121]  809  810  817  823  826  829  830  839  841  842  847  850  862  880  883  886  887  889  890  895  908  927  942  945  946  957  961  966  977  978
[151]  980  984  987  998 1000
```
なんで？
$$\frac{6}{5}\neq6*5^{-1}$$

さらに、

```
> n <- 1:100
> which( n/5 != n*5**(-1) )
 [1]  3  6  7 12 14 17 19 23 24 28 29 33 34 38 39 41 46 48 51 53 56 58 61 63 66 68 71 73 76 78 82 87 92 96 97
```
$$\frac{3}{5}\neq3*5^{-1}?$$

さらに、

```
> n <- 1:100
> a <- seq(0.2, 20, by =0.2)
> which( n/5 != a )
 [1]  3  7 12 13 14 15 17 18 19 23 24 25 28 29 30 33 34 35 38 39 44 97
> which( n*5**(-1) != a )
 [1]  6 13 15 18 25 30 35 41 44 46 48 51 53 56 58 61 63 66 68 71 73 76 78 82 87 92 96
```
$$\frac{3}{5}\neq0.6?$$

Rはダメですか？では、Pythonで試してみましょう。

```
>>> 6/5 == 6*5**(-1)
False
>>> (81/20-4)*20 == (81/16-5)*16
False
```

困りますね。原因を知りたいです。
ご存じの方、ぜひ教えてください。
Hyper-VのCentOS7にLAMP環境を構築する

##前提となる環境
CentOS7をHyper-Vの仮想マシンにインストールしてインターネットに接続する
http://qiita.com/como96/items/5eead1679f339fc954b9

##インストールするもの
- Apache 2.4.6
- MySQL 14.14
- PHP7.0.9

##作業環境
- Windows10 Enterprise 2015
- Hyper-Vマネージャー 10.0
- CentOS 7.2.1511

##Apache
1. インストール  
```sudo yum install -y httpd```<br>
（sudo使えなければrootでログインしてください）<br>
```-y```は、インストール前の確認を省略するオプション。お好みで。
<br>  
2. 状態を確認  
```sudo systemctl status httpd```<br>
（```service```でなく```systemctl```）
<br>  
3. ポート80が使われていないことを確認  
```ss -nat```<br>
（```netstat```でなく```ss```）<br>
もし80が使われていたら、/etc/httpd/conf/httpd.confを編集してポートを変更してください。  
（参考）https://www.server-world.info/query?os=CentOS_7&p=httpd
<br>  
4. 起動<br>
```sudo systemctl start httpd.service```<br>
うまく起動しなかったらfirewall関係の可能性もあるようです。<br>
私は問題なく動いてしまいました。<br>
（参考）http://qiita.com/sky_y/items/b92fa6ba57d926f25370
<br>  
5. OS起動時に自動でApacheを立ち上げる  
```sudo systemctl enable httpd.service```<br>
確認<br>
```sudo systemctl list-unit-files | grep httpd```

##MySQL
1. mariaDBと競合してしまうので、消しておく。  
どんなのがあるか確認<br>
```yum list installed | grep maria```<br><br>
mariadb関係は消す。<br>
初回起動なら3つめは必要ないかも。<br>
```sudo yum remove mariadb-libs```<br>
```sudo yum remove mariadb-libs.x86_64```<br>
```sudo rm -rf /var/lib/mysql```
<br>  
2. MySQLをインストール  
```sudo yum install -y mysql```
<br>  
3. yumリポジトリをインストール<br>
MySQL公式の「Download MySQL Yum Repository」<br>
「Red Hat Enterprise Linux 7」の「Download」へ進み、「No thanks, just start my download.」のURLをコピーしておく。<br>
http://dev.mysql.com/downloads/repo/yum/<br>
```sudo yum install -y コピーしたURL(http://dev.mysql.～)```
<br>  
4. MySQLインストールの続き<br>
```sudo yum install -y mysql-community-server```
<br>  
5. インストールされたかどうか確認<br>
```mysqld -v```
<br>  
6. 起動<br>
```sudo systemctl start mysqld.service```<br>
確認<br>
```sudo systemctl status mysqld.service```
<br>  
7. OS起動時に自動でMySQLを立ち上げる<br>
```sudo systemctl enable mysqld.service```

##PHP7
標準リポジトリのPHPバージョンは5.4なので、7を入れるときはEPELとRemiが必要。
こちらの通りに作業したのでリンク貼っておきます。
http://qiita.com/ozawan/items/caf6e7ddec7c6b31f01e
1. EPELを追加
2. Remiを追加
3. インストール
4. インストール確認
5. php.iniを編集
6. Composerはインストールしてません
Custom Viewを作成して使用すると、Warning が表示される環境がある

この Warning 自体は誤表示だと思われるため、実機で正常動作する場合は無視するのが最善だと思われます。

■ Warning メッセージ

要素 'LinearLayout' には無効な子要素 'examplemynamespace.ExampleMyView' が含まれています。必要とされる要素は 'GLSurfaceView, AdapterView, (中略), ZoomControls' です。

■ XSD ファイルパス

[PROGRAM_FILES_FOLDER]\Microsoft Visual Studio 14.0\Common7\IDE\Extensions\Xamarin\Xamarin\4.1.2.18\schemas\android-layout-xml.xsd

■ Example XSD

	<?xml version="1.0" encoding="utf-8"?>
	<xs:schema xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xs="http://www.w3.org/2001/XMLSchema">
		<xs:import schemaLocation="schemas.android.com.apk.res.android.xsd" namespace="http://schemas.android.com/apk/res/android" />
		<xs:group name="any-view">
			<xs:choice>

					…
	
				<xs:element ref="ExampleMyView" />
			</xs:choice>
		</xs:group>
	
		…
	
		<xs:element name="ExampleMyView" type="ExampleMyView">
			<xs:annotation>
				<xs:documentation>Runtime Type: ExampleMyNamespace.ExampleMyView</xs:documentation>
			</xs:annotation>
		</xs:element>
		<xs:complexType name="ExampleMyView">
			<xs:complexContent mixed="false">
				<xs:extension base="LinearLayout" />
			</xs:complexContent>
		</xs:complexType>
	</xs:schema>

■ Example XML or AXML

	<?xml version="1.0" encoding="utf-8"?>
	<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
		android:orientation="vertical"
		android:layout_width="match_parent"
		android:layout_height="match_parent">
		<ExampleMyView
			android:id="@+id/exampleMyView1"
			android:layout_height="match_parent"
			android:layout_width="match_parent" />
	</LinearLayout>
else ifにも代入文が書ける #golang


今回は小ネタです。
Goのif文には、以下のように代入文が書けることは有名です。

```go

if err := f(); err != nil {
    // error handling
}
```

[言語仕様](https://golang.org/ref/spec#If_statements)を見てみると、以下のように`Expression`の前に、オプションで`SimpleStmt`が書けるようになっています。

```go
IfStmt = "if" [ SimpleStmt ";" ] Expression Block [ "else" ( IfStmt | Block ) ] .
```

`SimpleStmt`についても、[言語仕様](https://golang.org/ref/spec#SimpleStmt)を確認すると、以下の様な定義になっています。
このうちの`ShortVarDecl`が`err := f()`にあたります。

```go
SimpleStmt = EmptyStmt | ExpressionStmt | SendStmt | IncDecStmt | Assignment | ShortVarDecl .
```

`SendSmt`とかもあるので、使いみちはわかりませんが、以下のように書けます。

[Go Playgroundで見る](https://play.golang.org/p/v5BZHkVH_J)

```go
package main

import (
	"fmt"
)

func main() {
	ch := make(chan struct{})

	go func() {
		if ch <- struct{}{}; true {
			fmt.Println("send")
		}
	}()
	<-ch
}
```

さて本題ですが、`IfStmt`の定義を見ると、`else`の後にさらに`IfStmt`が書けます。
つまり、同じようにオプションで`else if`の後に、`SimpleStmt`が書けるということです。
言語仕様をみると、なんだか当たり前なんですが、割りと便利なのではないかなと思います。

例えば、以下のように書けます。
`b`は最初の`else if`より下の`else`でも使えます。
`else if`の`SimpleStmt`で`a`を使っているのがポイントです。

[Go Playgroundで見る](https://play.golang.org/p/4kIEnfQLBE)

```go
package main

import (
	"fmt"
)

func f() interface{} {
	return "hi"
}

func g(a interface{}) interface{} {
	return "hello"
}

func main() {
	if a := f(); a == nil {
		fmt.Println("a is nil")
	} else if b := g(a); b == nil {
		fmt.Println("b is nil")
	} else {
		fmt.Println(a, b)
	}
}
```

上記と同じことを`switch - case`で実現するのは難しいです。
以下のように[言語仕様](https://golang.org/ref/spec#ExprSwitchCase)を見ると、`switch`の隣には`SimpleStmt`が書けますが、`case`に書けるのは`ExpressionList`だからです。

```go
ExprSwitchStmt = "switch" [ SimpleStmt ";" ] [ Expression ] "{" { ExprCaseClause } "}" .
ExprCaseClause = ExprSwitchCase ":" StatementList .
ExprSwitchCase = "case" ExpressionList | "default" .
```

案外知らない人もいるかもしれないので、ぜひ試してみてください。