OmniAICreator/Qiita-1.07M huggingface dataset:
リスクベーステストに関して

この記事は[ソフトウェアテスト Advent Calendar 2017 – Qiita](https://qiita.com/advent-calendar/2017/softwaretesting)の3日目です。
一つ前の記事は[@yoshikiito](https://twitter.com/yoshikiito)さんの [テスト自動化における集中と拡大](https://yoshikiito.net/blog/archives/1314)でした。


今年から生まれて始めてアドベントカレンダーに参加させていただきます。
freddiefujiwaraです　よろしくお願いします。

#1.全数テストは不可能
早速ですが、みさなん　"全数テストは不可能"という原則は聞いたことがあるけど
どのくらい膨大になるのかイマイチピントこないという事はありませんか？

有名な下記の問題があります。
"N×Nで区分された碁盤目状の道を、左上から右下まで遠回りを許しつつ同じ場所を通らない道順の数"
例えば
##2x2であれば

|||
|:--|--:|
|||

= 12通り:grinning:

5x5であれば。。。

||||||
|:--|---|---|---|--:|
|||||
|||||
|||||
|||||

=126,281通り :frowning2:

##では16x16 はどうでしょう

|||||||||||||||||
|:--|---|---|---|---|---|---|---|---|---|---|---|---|---|---|--:|
|||||||||||||||||
|||||||||||||||||
|||||||||||||||||
|||||||||||||||||
|||||||||||||||||
|||||||||||||||||
|||||||||||||||||
|||||||||||||||||
|||||||||||||||||
|||||||||||||||||
|||||||||||||||||
|||||||||||||||||
|||||||||||||||||
|||||||||||||||||
|||||||||||||||||

= 6.8*10^62通り　:confounded:

こちらのYouTubeを見るともっと実感がわきます。[フカシキの数え方](https://www.youtube.com/watch?v=Q4gTV4r0zRs)

同じようにアプリケーションの中でも、
各モジュールやクラスのユニットテストのステートメントカバレッジは100%は目指せても
その後の結合テストやシステムテストすべてのケースを網羅することは
テストケースを一つ一つ書き出すことはもちろん、実行となったら膨大な時間がかかることが予想されます。

#2.欠陥は偏在する

つくづく"バグ"という言葉はいい表現だなと改めて思うのですが。
ソフトウェア開発において、欠陥はまんべんなく存在しているのではなく
こんな感じで

|:ant:|:ant:|:ant:|:ant:|:ant:|
|:--|---|---|---|--:|
|:ant:|:ant:|:ant:|:ant:|:ant:|
|:ant:|:ant:|:ant:|:ant:|:ant:|
|:ant:|:ant:|:ant:|:ant:|:ant:|
|:ant:|:ant:|:ant:|:ant:|:ant:|

実際は偏在して存在していることが多いです
こんな感じでスイートスポットが存在します。

|:ant::ant::ant::ant::ant:||||
|:--|---|---|---|--:|
||||:ant::ant::ant::ant::ant:|
||:ant::ant::ant::ant::ant:|||
|||:ant::ant::ant::ant::ant:||
|:ant::ant::ant::ant::ant:||||

理由としては欠陥は人間のミスによって引き起こされ
複雑な箇所、変更を加えた箇所、新しい技術を適応した箇所や多くの人が関与している場所
欠陥が発生した箇所（なぜなら欠陥の修正は先述の変更にあたるからです)等
ミスを起こしやすいところというのは全体ではなく絞られてきます。

#3.リスクベーステスト
以上
1.全数テストは不可能
2.欠陥は偏在する
という２つの理由から

欠陥の発生によって起こりうる問題の大きさ x 欠陥の発生確率

この２つを駆使して、スイートスポットを見つけ
リスクの高いところからテストを行うというのが今日紹介する方法です

[PRISMAメソッド](http://www.erikvanveenendaal.nl/NL/files/e-book%20PRISMA.pdf)というのをネット上で見つけ　著者に英語から日本語への翻訳の許可をとりました
https://twitter.com/ErikvVeenendaal/status/922712650211053569

先日ようやく翻訳作業が終わりましたのでここで紹介させていただきます。
http://www.erikvanveenendaal.nl/site/wp-content/uploads/Practical-Risk-Based-Testing.pdf

#最後に
翻訳の内容をgithubにあげており、もし間違いや不適切な箇所がありましたら
こちらからpull requestいただけると幸いです。
https://github.com/freddiefujiwara/prisma

それでは皆様、寒くなってきたので風邪を引かぬようお気をつけください
つぎは @taikoheiさんの[TPI NEXT®を社内で1年半やってみて](https://qiita.com/taikohei/items/a1d1b59736cb34c7e5be)です。お楽しみに
Numpy: fliplr() > ValueError: Input must be >= 2-d. > １次元のarrayにはエラーを出す

[numpy.fliplr](https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.fliplr.html)
Flip array in the left/right direction.


### ValueError: Input must be >= 2-d.

https://ideone.com/xd3w1U (Python 3.5)

```py3
import numpy as np

xs = [[3, 1, 4], [1, 5, 9]]
res = np.fliplr(xs)
print(res)

xs = [3, 1, 4]
res = np.fliplr(xs)
print(res)
```

```txt:run
[[4 1 3]
 [9 5 1]]
```

```txt:stderr
Traceback (most recent call last):
  File "./prog.py", line 4, in <module>
  File "/usr/lib/python3/dist-packages/numpy/lib/twodim_base.py", line 81, in fliplr
    raise ValueError("Input must be >= 2-d.")
ValueError: Input must be >= 2-d.
```

### エラーの詳細

https://chromium.googlesource.com/external/github.com/numpy/numpy/+/maintenance/1.3.x/numpy/lib/twodim_base.py

153行あたり

```py
    if m.ndim < 2:
        raise ValueError, "Input must >= 2-d."
```

このエラーが出ているようだ。
MATLAB:fix() ゼロ方向への丸め > Numpy:実装 > 正: floor(), 負: ceil()

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04 LTS desktop amd64
TensorFlow v1.2.1
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
scipy v0.19.1
geopandas v0.3.0
MATLAB R2017b (Home Edition)
```

## MATLAB

https://jp.mathworks.com/help/matlab/ref/fix.html

```matlab
>> xs = [3.14 -2.718]

xs =

    3.1400   -2.7180

>> fix(xs)

ans =

     3    -2
```

## Numpy

上記に対して以下のように実装した。

### for実装

https://ideone.com/H8xPlf (Python3.5)

```py3
import numpy as np


def get_fix(xs):
    res = []
    for elem in xs:
        if elem >= 0.0:
            res += [np.floor(elem)]
        else:
            res += [np.ceil(elem)]
    return res

xs = [3.14, -2.718]
res = get_fix(xs)
print(res)
```

```txt:run
[3.0, -2.0]
```

### 内包表記実装

https://ideone.com/YjJwOh (Python3.5)

```py3
import numpy as np


def get_fix(xs):
    res = [np.floor(e) if e >= 0 else np.ceil(e) for e in xs]
    return res

xs = [3.14, -2.718]
res = get_fix(xs)
print(res)
```

```txt:run
[3.0, -2.0]
```
Numpy | MATLAB > Link: NumPy for Matlab users

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04 LTS desktop amd64
TensorFlow v1.2.1
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
scipy v0.19.1
geopandas v0.3.0
MATLAB R2017b (Home Edition)
```

NumPy for Matlab users
https://docs.scipy.org/doc/numpy-dev/user/numpy-for-matlab-users.html

Numpy (+ Scipy)とMATLABとの違いについてまとめられている。

探しているfix()については記載はなかった。
AWS S3にPythonで画像ファイルアップロードする方法

# はじめに
Pythonで画像ファイルをS３にアップロードしたくなったので、やってみました。
以下方法で簡単にできます。

# 環境
Python 3.5.1
Mac OS 10.11.4

#credentialの設定を忘れずに
AWS cliコマンドをまずは使えるようにしておきます。

```sh
$ pip install awscli
```

credentialを設定しておく

```
$ aws configure
```

aws configureコマンドを打つと、accesskey,secret key,regionの設定ができるので、AWSコンソール画面にログインし事前に確認しておき、ここで設定しておきます。
格納したいS3のリージョンを間違えないようにしましょう。

すると　.aws/credentialsにprofileが設定されるので、下準備はOKです。

#boto3をインストール
Amazonへの操作ができるようboto3モジュールをpipインストールします。

```
$ pip install boto3
```

以下のようにコードを記述します。
upload_file APIを使います。

```py3

import json
import boto3
 
bucket_name = "my-bucket-name"
s3 = boto3.resource('s3')

s3.Bucket(bucket_name).upload_file('/Users/tottu22/Downloads/local.jpg', 'server.jpg')
```
※ダウンロードフォルダにあるlocal.jpgファイルをS3のmy-bucket-nameフォルダにserver.jpgファイルとしてアップロードする例

これでファイルアップロードは完了

# 最後に
指定したバケットにファイルがアップロードされていることを確認してみてください。
「iOS 11 Programming」 が控えめに言って最高な件

読書の秋もおわり、冬の寒さを感じることが多くなって来ましたが、皆さんは最近何か本を読まれましたか？

僕はあまり読めてません!!!←
このままではまずい、、、と思い何かiOS関連で良い本ないかなーと探していたら最高の本に出会えたので紹介したいと思いますっ

それがこちらです↓

<div class="peaks_widget" style="overflow:hidden; padding:20px; border:1px solid #dedede;"><div class="peaks_widget__image" style="float:left; margin-right:15px; line-height:0;"><a target="_blank" id="purchase" href="https://peaks.cc/kafka0824/iOS11"><img alt="iOS 11 Programming" style="border:none; max-width:140px;" src="https://s3-ap-northeast-1.amazonaws.com/peaks-images/project002_cover.jpg"></a></div><div class="peaks_widget__info"><p style="margin:0 0 3px 0; font-size:110%; font-weight:bold;"><a target="_blank" id="purchase" href="http://peaks.cc/kafka0824/iOS11">iOS 11 Programming</a></p><ul style="margin:0; padding:0;"><li style="font-size:90%; list-style:none;"><span>著者：</span><span>堤 修一,</span><span>吉田 悠一,</span><span>池田 翔,</span><span>坂田 晃一,</span><span>加藤 尋樹,</span><span>川邉 雄介,</span><span>岸川克己,</span><span>所 友太,</span><span>永野 哲久,</span><span>加藤 寛人,</span></li><li style="font-size:90%; list-style:none;">発行日：2017年11月16日</li><li style="font-size:90%; list-style:none;">対応フォーマット：製本版,PDF</li><li style="font-size:90%; list-style:none;"><a target="_blank" id="purchase" style="text-decoration:underline; color:#1DA1F2;" href="http://peaks.cc/kafka0824/iOS11">PEAKSで購入する</a></li></ul></div></div>

見た目からしてかっこいい
インスタ映えする技術書です。買ったらすぐにインスタに投稿ですね:)


###なんで買ったの

・ARKitに興味があった
・iOS 11　になって色々変わったけど変更点追いきれていなくてやばいと思った

###誰が書いたの、何が書いてあるの

上の著書欄にもあるようにiOS界隈で有名な方々が書かれています。
各章の執筆者の欄にtwitterのアカウント名も載っているので、好きなトッピックを書いている人のアカウントはすぐにフォローしましょう。めっちゃ勉強になります。
iOS好きは全員フォローしましょう。

内容はARKit、Core ML、Swift4の変更点などiOS11に関することが網羅的に書かれています。

###読んでみてどうよ
全440P。
まだ途中ですが、一年目モバイルアプリエンジニアの自分でも読めるぐらい丁寧に書かれていると思います！多くのページにサンプルコードが載っていて、読み応えありです。

構成
各トピック約30ページほどでまとまっています

説明の分かりやすさ
★★★★★
Core MLは少し数学の知識必要かも。

サンプルコード量
★★★★★

応用性
★★★★☆

モチベーション向上度
★★★☆☆
技術書なので「うおおお開発するぞおおお」っていう感じにモチベーションが上がるわけではないですが、スムーズにそして体系的にiOS11を見渡せられるので、読めば開発して行く上での自信になると思います。


上のリンクから商品詳細に飛べますが、レビューも高評価ばかりです！
ぜひ手にとってみてください！
おためし Geant4

# Geant4 を仮想環境で試してみよう

ありがたいことに KEK の中の人が Geant4 インストール済み CentOS イメージを公開してくださっているので，[いますぐダウンロード](https://wiki.kek.jp/display/geant4/Geant4+Virtual+Machine)。

個人的には [VirtualBox](https://www.virtualbox.org/) でいいと思います。

## ターミナルわからない人向け

そもそも Linux どころかコマンドラインろくにさわったことないですという人向けの基本中の基本コマンド

### ls

list. いまいるディレクトリにあるファイルやフォルダを表示してくれる。

### pwd

print working directory. いまいるディレクトリがわかる。

### cd

change directories. 場所を変える。たとえば `ls` して `hoge` というディレクトリが直下にあったとして，`cd hoge` すれば `hoge` ディレクトリに移ることができる。

### cp

copy. `cp コピー元 コピー先` みたいに使う。`cp -R ...` と書くと再帰的
 (recursively) にディレクトリごとまるっとコピーしてくれる。

### mv

move. 移動の他にもリネーム目的でも使われる。`mv 移動元 移動先` と書く。

### rm

remove. 消す。特にエイリアスなどを設定していない場合，問答無用でゴミ箱などには行かずに消える。

## とりあえず Geant4 を触ってみる

配布されているイメージでは可視化ライブラリや環境変数等必要なものはすべて設定されていて，サンプルコードもビルド済みのものが入っているので，とりあえずサンプルを動かしてみましょう。

仮想イメージを起動したら，デスクトップから「端末」を起動して以下のコマンドでサンプル B1 がある場所に移動します。

```shell-session
$ cd ~g4user/work/basic/B1
```

行頭の `$` はその行がコマンドプロンプトであることを意味します（bash のデフォルト。zsh 等では異なる）。`$`とその直後の半角スペースは実際には入力しません。

`ls` すると `exampleB1` のような名前のバイナリファイルがあると思います。それを実行します。

```shell-session
$ ./exampleB1
```

なんで `./` を頭につけているかというと，「exampleB1 が今ここにあるファイルである」ことを示す必要があるからです。もし `./` を付けなかった場合，シェルは `exampleB1` という名前の実行ファイルを探しに行きます。このとき探しにいく場所は環境変数のひとつ `PATH` としてシェルに読み込まれていますが，いまいる `~g4user/work/basic/B1` はPATHにはデフォルトでは含まれていません。するとシェルは exampleB1 を見つけることができないので，「そのような名前のファイルはありません」というエラーを出力します。

無事実行できた場合，黒い背景にワイヤーフレームのようなものが描画された画面が出ると思います。そこでウィンドウ上部にある再生ボタンのようなものを押すと粒子が走ります。

他にも複数のサンプルプログラムがビルド済みで含まれていますので，お試しください。
PowerShellで例外を捕まえられない


[PowerShellでのエラー／例外処理について](https://qiita.com/bounoki/items/b371d1f91a9cb3aec8f4)にもうすこし突っ込んだことを書いたよ。（2018/11/30）


PowerShellで`try～catch`をしようとしても、うまくいかない、という事がある。
Cmdletが実行されたときに発生した問題（あえて例外とは書かないよ）は、コンソールに赤字で表示される（標準エラーではなさそう…）が、Cmdletを実行してるコンテキスト（例えば実装中のスクリプトとか）では例外としては扱われない[^1]。

## 例外をキャッチする
そんな時、`-ErrorAction Stop`をつけるか、`$ErrorActionPreference="Stop"`としておくと、Cmdletは例外を投げてくれる。

試す。

まず、以下だと例外投げてくれないので、赤文字が出る。

```text:取れない
PS C:\Users\bounoki> try {
    Get-LocalUser nosuchuser
} catch [Exception] {
}

Get-LocalUser : ユーザー nosuchuser が見つかりませんでした。
発生場所 行:2 文字:5
+     Get-LocalUser nosuchuser
+     ~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (nosuchuser:String) [Get-LocalUser], UserNotFoundException
    + FullyQualifiedErrorId : UserNotFound,Microsoft.PowerShell.Commands.GetLocalUserCommand

PS C:\Users\bounoki>
```

以下だと例外投げてくれるので赤文字が出ない。

```text:とれる
PS C:\Users\bounoki> try {
    Get-LocalUser nosuchuser -ErrorAction Stop
} catch [Exception] {
}

PS C:\Users\bounoki> 
```

```text:とれる
PS C:\Users\bounoki> $ErrorActionPreference = "Stop"
try {
    Get-LocalUser nosuchuser
} catch [Exception] {
}

PS C:\Users\bounoki> 
```

## 例外の種類を気にしながらキャッチする
上のやり方だと`Exception`で捕まえられるけど、もっと具体的な例外でキャッチするにはどうしたらよいか。
赤文字の内容見て「`UserNotFoundException`を捕まえよう」と考えて直そうとすると、うまくいかない。

これ、PowerShellの`ErrorAction`を`Stop`にしてスクリプトを止めようとすると、[`System.Management.Automation.ActionPreferenceStopException`](https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.actionpreferencestopexception?view=powershellsdk-1.1.0)がスローされるという仕様らしい。

```text:とれる
PS C:\Users\bounoki> try {
    Get-LocalUser nosuchuser -ErrorAction Stop
} catch [System.Management.Automation.ActionPreferenceStopException] {
}

PS C:\Users\bounoki> 
```

例外を特定して処理したい場合は、`ActionPreferenceStopException`を投げたきっかけの例外をif文で判断すればいいらしい、と[TechNetのフォーラムで見つけた](https://social.technet.microsoft.com/Forums/ja-JP/6fa69292-7725-4108-abc0-8c87b3b95bd0/powershell?forum=powershellja)。

```text:例外を特定して処理
PS C:\Users\bounoki> try {
    Get-LocalUser nosuchuser -ErrorAction Stop
} catch [System.Management.Automation.ActionPreferenceStopException] {
    if( $_.Exception -is [Microsoft.PowerShell.Commands.UserNotFoundException]) {
        Write-Host "ユーザーがみつからないよ"
    }
}
ユーザーがみつからないよ

PS C:\Users\bounoki> 
```

でも、**これだと`Exception`でcatchしたのとあまり変わらないじゃん！**

結局、catch句で条件分岐しなきゃいけないのかな。
だったら、例外吐きそうなのがCmdletくらいの場合`Exception`で取っても同じかなあ。
自分で例外をthrowするようなスクリプトを作ったときには役に立ちそう。

[^1]: たぶん内部的に発生した.NET側の例外などは、Cmdlet内でcatchするような実装になってるのではなかろうか。→ [PowerShellでのエラー／例外処理について](https://qiita.com/bounoki/items/b371d1f91a9cb3aec8f4)にもうすこし突っ込んだことを書いたよ。（2018/11/30）
ぼくの最近の開発環境

この記事は [Altplus Advent Calendar 2017](https://qiita.com/advent-calendar/2017/altplus)  の4日目のエントリです。

今日は私の最近Web開発に使っているお気に入りの開発環境について紹介したいと思います。

## どのような環境か？

普段Web開発をするのに使っているのが、以下のような感じです。

- IDE: 
    - IntelliJ IDEA
- Server side: 
    - Play Framework x Scala
- Client side: 
    - TypeScript with Vue.js & SCSS

では実際にそれぞれの特徴について簡単にご紹介します。

### IntelliJ IDEA

https://www.jetbrains.com/idea/

最近身の回りでも一大ブームメントを起こしつつあるIDEです。
JetBrainというIDEばかりを作り続けている会社が作った至極の一品です。
Scalaを嗜む身としては必需品です。
IntelliJ IDEA以外にもRiderとかCLionとか使ってます。超便利。

この記事を書いている時に利用しているのは 2017.2.6 というバージョンです。

### Play Framework

https://playframework.com/

Java/ScalaにおけるWeb Frameworkの決定版、といえる頼もしいやつです。
フレームワークで利用する言語をJavaかScalaで選べるので、どちらかが得意な方であればすぐに利用できます。
ちなみに私はScala版を利用しています。

この記事を書いている時に利用しているのは 2.6.7 というバージョンです。

### Scala

https://www.scala-lang.org/

Odersky教授によって生み出されたプログラミング言語です。
サーバーサイドの言語として利用しています。
Javaなんて要らなかったんや！という気持ちにさせてくれます。

この記事を書いている時に利用しているのは 2.11.11 というバージョンです。

### TypeScript

https://www.typescriptlang.org/

Microsoftが開発したJavaScriptに対して型付けを行えるAltJSの一つです。
TypsScriptで記述したプログラムをtscというコンパイラで生JSに変換して利用します。
私はこの変換はWebpackを使ってやってます。
もう型の無い言語は書けない体なので、生JSは恐ろしくて触れません。。。

### SCSS

http://sass-lang.com/

SCSS(サス)は、従来のCSSのイマイチなところをいろいろと改善してくれているものです。
基本的な構文としてはCSSのものをそのまま利用できるのですが、mixinができたりネストが
できたり、変数が使えたりととっても便利に利用できるのでベターCSSとして利用しています。

### Vue.js

https://jp.vuejs.org/index.html

Vue.jsは従来の(jQueryにありがちな)フロントエンド開発のつらみを取り去ってくれる
フロントエンド用フレームワークです。
もうDOM操作を自分で各必要はありません。すべて宣言的に記述することができ、
なおかつあらゆる変数がリアクティブに実装されていますので、jQuery時代とくらべてModel-View間の実装をかなり省略することができます。
DOMちまちま組み立てるの本当に辛いですよね。

このフレームワークの中で、TypeScriptとSCSSを合わせて利用しています。

## 実際のサンプル

それぞれどんな感じでどう使ってるのよ？というところですが、
実際のプロジェクトから抜粋してサンプルを作ってみたので興味のある人は御覧ください。

https://github.com/cimadai/play26_vue_ts_scss

cloneしたら `sbt run` だけで起動すると思います。


## まとめ

便利なものをどんどん使えるようになると楽しく仕事ができますね！

それではまた別の日に！
Geant4 概説

# Geant4 とは

[Geant4](http://www.geant4.org/geant4/) とは，粒子と物質の相互作用をシミュレートするための C++ ツールキットです。ここでいう粒子とは，素粒子，広い意味での放射線，可視光帯の光（光子）を指します。よくあるLHCの中でいろんな色の線が飛び散ってる画像を想像してもらえば大体合っていると思います。

## Geant4 は何であるか

Geant4 はあくまで C++ ツールキットにすぎないので，これを使ってユーザがアプリケーションをつくる必要があります。裏を返せば自由度が高いということでもあります。データをCUIやGUIで渡して，特定の形式の結果が得られるというシミュレーションソフトウェアもあると思いますが，一方 Geant4 を用いることでユーザーは望むままにアプリケーションを書くことができます。前者にも手軽で使い勝手がいいという利点がありますが，研究目的などで細かいところをいじりたい場合は自分でコードを書くほうが適切な手段でしょう。

自分でコードを書くと言っても，場合によっては非常に楽です。Physics List としてある程度の数の物理相互作用が実装されており，シミュレーションにおける物理過程すら自分で実装しなくて済むかもしれません。この場合，初期条件と情報の取得さえ実装すればよいです。

## Geant4 で何ができるか

抽象的な言い方をすれば，

1. 空間を定義
2. 物質を抽象的に定義
3. 空間内に物質を具体的に配置
4. 空間内に粒子を生成
5. 粒子が飛ぶので好きなように情報を取得する
6. 全粒子のエネルギーが0になったり空間の端に到達したら終了

となります。

具体的には，身近なところでは放射線に関する医療のシミュレーションソフトウェアの中身になっていたり，遠いところでは宇宙に飛ばす天体観測衛星の検出器のシミュレーションをしていたり，加速器のシミュレーションをしていたりします。

さらに詳しい情報を複数の記事にわけて書くつもりですが，[KEKの初心者講習会のページ](https://wiki.kek.jp/display/geant4/Geant4+Japanese+Tutorial+for+Detector+Simulation+2017) にある資料が参考になりますので，ぜひご参照ください。
Unicode Code Point の値を Google Spreadsheet 上で文字表現に変換

## 今回用いるサンプル文字
今回は Unicode 絵文字「😁」の各形式での記述方法を紹介します。

「😁」という絵文字は Unicode Code Point としては

```
U+1F601
```
と定義されています。

## HTML 上での表記
HTML が Unicode を扱えるエンコーディング形式 (UTF-8等) で管理されているのであれば、エディタでそのまま「😁」と打ち込めば「😁」がそのとおりに「😁」と表示されます。

これを Code Point を明示指定した形で HTML 記述したい場合には

```
&#x1F601;
```

とします。

## Google Spreadsheet 上での表記
Google Spreadsheet は Unicode 文字に対応しているので、セル内には直接「😁」と打ち込めば「😁」がそのとおりに「😁」と表示されます。

これを Code Point を明示指定した形で Google Spreadsheet 記述したい場合には

```
=CHAR(HEX2DEC("1F601"))
```

とします。

## おまけ：Excel 上での表記
Excel (2016) では CHAR 関数ではなく UNICHAR 関数を使うことになります。

```
=UNICHAR(HEX2DEC("1F601"))
```

　
今日はここまで。
はてなブックマークの「マイページ」，ウザいですよね．

と言うわけで，消す．

```javascript:KillHatena-Bookmark"Mymage"
try{
	document.getElementById("header-navigation").getElementsByTagName("a")[1].innerHTML = "";
}catch(e){
  document.getElementsByClassName("hotentry")[1].innerHTML = "";
}
```
これを私家版web extensionにしてfirefoxにアドオンしてます．
ページごとにDOM違ってるのは嫌がらせなのか．

追記：
http://b.hatena.ne.jp/entry/s/〜 のページだと上記スクリプトは
スクラッチパッドで試すと上手く行くが，webExtensionでは書き換えてくれない．
scriptタグ内でテンプレートエンジン使ってるからDOM書き換えてもscriptが
再実行されない為っぽいのだが，もうどうしたら良いかわかんない(´・ω・｀)
devpostから学ぶハッカソンの作り方

最近、ハッカソンもいたるところで行われるようになって、随分と浸透してきたと思います。

自分たちもやりたいけど、どうしたらいいのかよくわからない方は多いのではないでしょうか？

そんな人に参考にすべき**おすすめのサイト**があります。
「[devpost](https://devpost.com/)」というサイトです。

<img width="981" alt="スクリーンショット 2017-12-02 7.20.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/18114/9059e7ea-71db-a9cb-cde9-c8eb597eff42.png">
引用：https://devpost.com/


devpostとは、企業と開発者のマッチングを目的に、ハッカソンや仕事の情報をオープンにしているサイトです。

本記事は、**devpostに公開されているハッカソンから、ハッカソンについて学び、ハッカソンを開催するにあたって必要な情報をまとめます**。

また、ハッカソンの運営サイドの話は多岐に渡りすぎるのでココでは触れませんのでご承知ください。


では、行きます。


# ハッカソンを知る
具体例から入るとイメージし易いので、ひとつサンプルを見てみましょう。

以下は、今年のAWS re:Invent２０１７で開かれた、「Smart Cities Hackathon」という[ハッカソン](https://smartcities.devpost.com/?ref_content=default&ref_feature=challenge&ref_medium=discover)です。Alexaを用いて近代社会の問題を解決するようなアイデアを短時間で実装するというものでした。

<img width="966" alt="スクリーンショット 2017-12-02 9.30.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/18114/fc5777e1-b1f1-5ab3-3091-aafdf11a1eaa.png">
引用:https://smartcities.devpost.com/?ref_content=default&ref_feature=challenge&ref_medium=discover

詳細は[リンク](https://smartcities.devpost.com/?ref_content=default&ref_feature=challenge&ref_medium=discover)を確認していただきたいのですが、**ハッカソンの内容についてイメージが湧いてきた**でしょうか？

本記事の本題は骨組みなのでコンテンツには触れませんが、興味のある方は参加したつもりで考えてみるのも面白いと思います:grinning:

ハッカソン基本構成を確認していきます。

# ハッカソンの構成要素

ハッカソンの要素は、細かく見ると開催コンセプトに依存し多岐に渡りますが、**ある程度は抽象化できそうな要素で構成されています**。

下記、構成要素を抑えておけば大抵の抜け漏れを防げると思います。(たぶんきっと)

ひとつひとつ見ていきます。

## 内容
**最も重要な要素**です。内容には、コンセプトや動機、その先に実現したい世界を記述します。開催意図を明確にし、開発者が実装イメージを膨らませ、WhatとHowの部分に集中しやすくするための重要なパートです。

## 参加方法
どこから、どうやって申し込むのかを、わかりやすく説明します。
ここがめんどくさいと、参加率に影響します。

## 資格条件
このハッカソンへの参加資格を条件として書きます。
たとえば、年齢制限（20歳以下）や、参加スタイル（個人 or 何人以下のチーム)などなど。

ほかにも、自社の開発者は参加しては駄目など、NG条件もここに書きます。

## 要求事項
短い時間でアウトプットを出すためには、ある程度のスキルセットを持った人達でないと成り立たないケースがあります。ハッカソンが円滑に進むための要求を決めておきます。

事前準備などもここにいれます。

たとえば、「AmazonとGoogleにアカウントをもっていること」など。

また、事前準備での要求以外にも、**アウトプットの提出先・方法や締め切り**なども忘れずに書きます。

## 審査員
審査員は、ハッカソンのコンセプトに精通した方にお願いしましょう。
審査員は、一人よりは複数人のほうが納得感が出ます。また、各審査員のSNSのリンク、簡単なバイオグラフィがあると嬉しいですね。

## 審査基準
審査基準を明確にしオープンにします。

審査基準が適切に設定されていないと、目的から逸れる結果を引き起こしかねないので、達成したい目的とセットで考えることがおすすめです。

しっかりと吟味しましょう。

## 賞金・景品
入賞者がどのような賞金や景品がもらえるのかを明確にします。
入賞者のランクと景品が表になっているとわかりやすいと思います。

日本では、景品法に目を通しておくと万が一のトラブルを避けられるかもしれません。
http://www.caa.go.jp/representation/keihyo/keihin/keihingaiyo.html

## 賞金・景品の受け渡し方
たとえば、賞金が高額になった場合に、受け渡しは現金なのか、銀行振込なのか、受け渡すところまでしっかり考えておきます。

また、受け渡しの方法だけでなく、タイミングも一緒に明記します。
未発売のものを景品にした場合などに、すぐに渡せないことも明記するといいでしょう。

## 禁止事項
暗黙の良心で成り立つことも多いですが、明確にしておくと、トラブル時の保険になります。
たとえば、オープンソースとして公開するようなハッカソンで、著作権がある画像を使ったりしたらNGです。

## 免責事項
これも保険です。ハッカソン中の不慮の事故に関して一文入れておくといいと思います。

## サポートの連絡先
問い合わせ先って意外と書き忘れるんですよね。ML作って書いておけばいいですが、運営側での対応者は決めておきましょう。

## ハッカソン運営からのお知らせ方法
「会場が変わりました」など、全員に何かを知らせないといけないときに、運営サイドからの連絡手段を書いて置きます。メールとかSlackとかですね。

# まとめ
以上、つらつらと、ハッカソンの構成要素をまとめました。
自分は今年AWS re:Invent2017に出てハッカソンの楽しさを知りました。

devpostではいろいろなハッカソンの情報が見れるので、**自分のやりたいことと似たようなハッカソンを参考に広げていくのもあり**ですね！

ぜひ色んな所で開催されるハッカソンにチャレンジし、弊社でも開催していきたいと思います:smiley:
【ARKit入門】Xcodeに3Dファイルを入れてみる


#ARKit入門

前回の記事はこちら
・[【ARKit入門】　まずやること](https://qiita.com/yyokii/items/9f4ad47087fdc6136de7)


##3DモデルをXcodeにとりこんでみる

ARアプリを開発して行く上で、他の人が作ったモデルを使いたい時や、イケてるモデルとか使いたいな〜〜てなる時あると思います。そんなときに3DモデルファイルをXcodeに取り込む時のやり方をまとめました〜

無料の３Dモデルを探す時には以下のサイトがオススメですっ
[free3d](https://free3d.com/) 
[turbosquid](https://www.turbosquid.com/)

###1.daeファイルを用意する
使いたいモデルの.daeファイルを用意します。
そして、そのファイルをXcodeのプロジェクト内にドラッグ&ドロップします。


![daeファイル取り込み](https://qiita-image-store.s3.amazonaws.com/0/138735/2c38d793-4485-1b60-74eb-cf0f54811933.png)

![スクリーンショット 2017-12-03 1.28.18.png]()


なんで.daeなの？？という疑問に関しては以下の記事が参考になりました。
[SceneKitで扱える3Dモデルのフォーマット／アニメーションつき3DモデルをSceneKitで使う](https://qiita.com/shu223/items/0161f82d000d5cdf009c
)

>他のフォーマットがNGだった理由は以下の通り。
>.fbxは配布されているSDKを使うことでインポートできるが、頻繁にメンテされてるわけでもなさそうなので、そこに依存したくない
.objはSCNSceneSourceインポートできるが、そのファイル形式自体がアニメーションをサポートしていない
.3ds, .max はSceneKitにインポートできない（サードパーティ製ライブラリとかはあるかもしれない）
そしてこのCOLLADAの.daeファイルは大抵のモデリングツールでサポートされているらしい。


###2 .scnファイルへの変換

.daeファイルのままだと使えないので.scnファイルに変換します。.daeファイルを選択して、Editor>Convert...を選択すると.scnファイルが作成されます。

![.scnへの変換](https://qiita-image-store.s3.amazonaws.com/0/138735/0eb689d8-3e2c-c31d-424c-4cc38d8779ec.png)
)

このビューがある部分が検出対象！

###3.アセットカタログ作成

.scnファイルを入れるためのアセットフォルダ作成します。
名前は　フォルダ名+.scnassets

![スクリーンショット 2017-12-03 2.59.34.png](https://qiita-image-store.s3.amazonaws.com/0/138735/264652a2-48ae-0867-ce1b-bbad84cbd238.png)

そしてこのフォルダの中に.scnファイルを格納すれば完了です！

※ドラッグ&ドロップで.scnファイルを.scnassetsに移動させた場合に移動前の.scnファイルが残り続けることがあると思います。その際は、.scnassetsにいれた方のファイル名を編集し、移動前の.scnファイルを削除すれば.scnassetsにいれたファイルのみが残ります。


###おわり

以上のようにすることで自作したものや、他の人が作成した3Dモデルを使用した開発が可能になります！
→ サンプルアプリの作成編
[【ARKit入門】平面にアイテムを配置する](https://qiita.com/yyokii/items/ff5b69f7e2c7b93a68ce)
【Unity】SimpleAnimationについて

（24/10/16 17:28追記）

SimpleAnimationはアーカイブモードになってメンテナンスもされないので、使用しない事をおすすめします。
[Playable API](https://docs.unity3d.com/ja/2022.3/Manual/Playables.html)で同じような事を実現できますので、こちらを使用しましょう。

---



本記事は[サムザップ Advent Calendar 2017](https://qiita.com/advent-calendar/2017/sumzap)の3日目の記事です。
昨日は@yosizo@githubさんの「[Jenkinsパイプラインスクリプトで簡単！Unity＋iOSビルド環境構築](https://qiita.com/yosizo@github/items/72004f97fb27db3335ef)」でした

## SimpleAnimationとは何か？

`Animator`コンポーネントと`AnimatorController`は、少数のアニメーションをオブジェクトに適用するシンプルなケースにおいて、
しばしばいたずらに複雑であるというフィードバックを受けていたみたいです。
より複雑なPlayablesのサンプルが欲しいという声も沢山あり、今回、その2つを同時に解決するものとして、
Unity Technologies社が提供したものです。
全てC#で書かれ、Github上で公開されています。


## SimpleAnimationの使い方

[Unity-Technologies/SimpleAnimation](https://github.com/Unity-Technologies/SimpleAnimation)
上記で公開されている、SimpleAnimationを落としてきます。

![simple_animation_01.PNG](https://qiita-image-store.s3.amazonaws.com/0/6790/e07c136a-a33d-e3c7-6270-59c59c9c9334.png)

SimpleAnimation.csをアニメーションさせたいGameObjectにアタッチします。
すると`Animator`コンポーネントも自動的にアタッチされます。

![simple_animation_02.PNG](https://qiita-image-store.s3.amazonaws.com/0/6790/0150bc1a-cc21-0e78-466c-42226d974aaf.png)

今回は2つのアニメーションクリップを設定してみます。
まずはAnimationに1つ目のアニメーションクリップをセットします。
これがAnimationsにあるDefaultのアニメーションになるみたいです。(これは変更できない模様)
そして、Animationsに2つ目のアニメーションクリップをセットし、左のスペースに名前を設定します。(今回はscaling)


```PlaySimpleAnimation.cs
using UnityEngine;

public class PlaySimpleAnimation : MonoBehaviour
{
    [SerializeField]
    private SimpleAnimation _simpleAnimation;

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.A))
        {
            _simpleAnimation.Play("Default");
        }

        if (Input.GetKeyDown(KeyCode.S))
        {
            _simpleAnimation.Play("scaling");
        }
    }
}

```
次に、上記のスクリプトをGameObjectにアタッチして実際にアニメーションさせてみます。
`SimpleAnimation.Play`の引数には、先程付けた名前を指定します。
このように、インターフェースはlegacyのAnimationとよく似ています。

# 以下、ドキュメントから読み取れたもの
## 注意点
- SimpleAnimationで使えるアニメーションクリップは、legacyのアニメーションクリップとは互換性が無く、
GanericかHumanoidである必要がある。
- WrapModeがPingPongなものとは互換性はない。

## 安定性はどう？
SimpleAnimationコンポーネントがAnimationコンポーネントと同じ振る舞いをする事を実証するために100を超える比較テストをしてきた。

## パフォーマンスはどう？
SimpleAnimationは大抵のケースで`AnimatorController`よりも高速に動作するがAnimationコンポーネントよりは通常、若干遅い。

## これからの展望
- SimpleAnimationPlayableAssetを作る。
- SimpleAnimationコンポーネントとPlayableAssetｓまたはPlayableｓとの互換性を作る。
- 全てのWrapModeをサポートする。

## 使ってみての感想
これを待っていたという感じです。
`Animator`と`AnimatorController`を使っていてステートの二重管理に陥ってしまったり、シンプルなアニメーションをさせたいだけなのに、`AnimatorController`が必要であったりと中々に使いづらいと思っていた人は多かったんじゃないでしょうか。
過去にlegacyなAnimationも使った事があるので、特に問題もなく使う事ができました。
シンプルなケースではどんどん使っていけるような印象を受けました。

## 参考
[Introducing the Simple Animation Component](https://blogs.unity3d.com/jp/2017/11/28/introducing-the-simple-animation-component/)
[Simple Animation Component](https://github.com/Unity-Technologies/SimpleAnimation/wiki)
[【Unity】さよならステートマシン。旧AnimationっぽいAPIでアニメーションを再生する SimpleAnimation](http://tsubakit1.hateblo.jp/entry/2017/11/13/233334)

----
明日は、[tomoriaki](https://qiita.com/tomoriaki) さんの [ゲームエンジニアが紙ヒコーキワークショップをやってみた](https://qiita.com/tomoriaki/items/cc12a8c06be1fae1dcbc)です。
仮想通貨を変換した時の金額を求めるTwitterBOT作ったお話

# はじめに
気まぐれで作ったTwitter BOTです。
またこの記事は人畜無害のブログにて書いたものを更にQiita用にしたものです
[仮想通貨を変換した時の金額を求めるBOT作った[Twitter, BOT]](http://www.zinntikumugai.com/2017/12/02/-4130-/)

# 目的

* 選択した仮想通貨同士で計算してくれるサイトがなかった(Mona-BitZenyなど)
* BTCなどで計算するとめんどい(やたらと小数点以下が多いので)
* 変換サイトが重い
* タブ増やしたくない
* いつもTwitterは開いている
* いちいちめんどい
* めんどい

これらを解決するため楽するためにBOTを作成しました

# 使い方
TwitterにてBOTアカウントにリプライを飛ばすだけでできます

[ExCrypto - Twitter](https://twitter.com/MultiCryptoEx)

```text:ツイート
@MultiCryptoEx ex [金額] [変換前の通貨] [変換後の通貨] [コメントなど]
```

## 現時点で使用できる通貨

* BTC
* JPY
* MONA
* NEM/XEM
* BitZeny

例：

```text:ツイート
@MultiCryptoEx ex 100 mona zny
```

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">100 [MONA] を [MONA] から [ZNY] へ変換： 25,323.8866396761 [ZNY]<br> 2017-12-02 13:45:22</p>&mdash; ExCrypto (@MultiCryptoEx) <a href="https://twitter.com/MultiCryptoEx/status/936939356459167751?ref_src=twsrc%5Etfw">2017年12月2日</a></blockquote>

# 環境
稼働マシン ：Windows 10 Pro x64
PHP：7.1.7

# 仕組み
結構雑にできています

- Twitter Streaming APIにてBOTに対するリプライを取得
- リプライをスペースで区切り配列に変換
- 交換前の通貨の対応する取引所にAPIを飛ばし、交換前の通貨をBTCで換算
- 交換後の通貨の対応する取引所にAPIを飛ばし、BTCから交換後の通貨に換算
- リプライを返す

# 困ったこと
## 目的の通貨とBTCの変換
例としてZaifをあげますが公式で対応しているのが

- btc_jpy
- xem_jpy
- mona_jpy
- mona_btc

JPYが基準となっているようです
そこは置いておいてmona_btcでMonaをBTCに変換する場合は特に問題ありませんがBTCからMonaに変換する方法がなかなか思いつきませんでした
`1[Mona]:x[BTC] = 1/x[Mona]:1[BTC]`この計算式になるように適時対応させました


## 指数変換
非常に大きい値、小数点以下が非常に長い場合、指数変換されてしまいます
php の関数`number_format`を使用してカンマ区切りも同時に行っています

## リプライ
BOTのリプライに対して更にリプライをすると記法ミスとして扱ってしまいます
無視すればいいかもしれませんが、単に入力ミスの可能性もあるためBOTが行ったリプライ以降はすべて無視するようにしました

# 今後必要なこと
## Streaming APIの対応
Twitter APIはリプライ後すぐ返すためStreaming APIを使用していますがZaifもできればAPI制限にかからないよう、また負荷軽減のためにStreaming APIに対応したいです
ただ、複数のStreaming APIを同時に扱う方法がいまいちわかりません(というより情報がない)

## 実行環境の変更
現在ほぼ稼働しているメインPC(Windows)で動作させています
ただ、___家族が電子レンジを稼働させるとネットワークが切れてしまうため___(細かいことは[私のTwitter](https://twitter.com/uesitananame55)を察してください)早急にサーバーを用意する予定です
現在CloudAtCostでやろうか、有志の方のサーバー借りるか検討中です

# 使用したAPI・ライブラリ
## API
- [Twitter API](https://developer.twitter.com/en/docs)
- [Zaif Exchange API](https://corp.zaif.jp/api-docs/)
- [C-CEX API](https://c-cex.com/?id=api)

## ライブラリ
- [phirehose](https://github.com/fennb/phirehose) / PHP Twitter 
Streaming
- [cowitter](https://github.com/mpyw/cowitter) / PHP Twitter REST
- [Zaif4PHP](https://github.com/tk1024/Zaif4PHP/) / PHP Zaif REST, Streaming
- [PHP-ccex-api](https://github.com/Remdev/PHP-ccex-api) / PHP C-CEX REST

# 最後に
ライブラリを作成して下さった方々やデバック作業を自ら手伝ってくださった方、ありがとうございました
今後も機能追加、バグ潰し頑張ります☆(ちゝω・ぇ)v
systemd-nspawnでのtmpディレクトリの扱いについて

[systemd-nspawn Advent Calendar 2017](https://qiita.com/advent-calendar/2017/systemd-nspawn) 2日目の記事です。

systemd-nspawnで/tmpディレクトリはメモリ上に置かれます
なので/tmpディレクトリに沢山置くとメモリ不足になっちゃうよという話

あと、/var/lib/machines/container/tmp/a.txt
みたいなファイルがあったとしても、tmpfsで被せてしまうので見えない

# 確認

```bash
# df -h /tmp/
ファイルシス   サイズ  使用  残り 使用% マウント位置
tmpfs            1.9G     0  1.9G    0% /tmp
```

確かにtmpfsになってる

# 対策1

tmpマウントを止めてしまう

```bash
systemctl stop tmp.mount
````

起動時にこれを発動させたかったら、systemdのboot処理が全部終わった後に発動するrc.localとかcrontabの@rebootとかを遅延かけてやるしかないと思う
（というのも、なんかこれtmp.mountがdisableでもmaskされても発動されちゃうのでsystemdのサービス止めてもsystemd-nspawnが起動かけてるように思えるので・・・）

# 対策2

bindでつなげちゃう

```bash
systemd-nspawn --bind /var/lib/machines/hogecontainer/tmp:/tmp -D /var/lib/machines/hogecontainer
```

# 注意

--bootフラグを立てて、boot処理を行うとtmpの削除処理が走るので、注意すること
なので、ホスト側の/tmpとつなげちゃうとコンテナ上げるたびに/tmpがクリアされてしまう


# 参考にしたリンク

[systemd-nspawn: prevent guest from mounting /tmp as tmpfs](https://bbs.archlinux.org/viewtopic.php?id=226438)
Escrow,Conditionについてのメモ

#Escrowについて
ILP(Interledger Protocol)を語る上では，Escrowの理解は不可欠のようなのでGithubを読んで，備忘をここに記す。
Conditionという概念も重要な模様。

#読んだところメモ
https://github.com/ripple/rippled/tree/develop/src/ripple/conditions
https://github.com/ripple/rippled/blob/develop/src/ripple/conditions/impl/Condition.cpp
deserialized

## EscrowCreateなど
https://github.com/ripple/rippled/blob/develop/src/ripple/app/tx/impl/Escrow.cpp
checkCondition
https://github.com/ripple/rippled/blob/develop/src/ripple/app/tx/impl/Escrow.h


https://github.com/ripple/rippled/blob/develop/src/ripple/conditions/impl/utils.h
Preambleとは
`序文、序言、前文、前置き`
何らかのヘッダー的な概念か？
Heroku で Twitter bot を運用する

Heroku で運用している [Twitter bot](https://twitter.com/yonobot/) について書きます。

# どういう bot か

ソースコード: https://github.com/yono/yonobot

定期的に

* ランダムに生成した文章のポスト
* メンションへの返信

をします。

私のツイートのログを基にしてるので、ランダムとはいっても比較的日本語っぽい文章が出てきます。
特に実用性は無くて観葉植物みたいな感じです。

例
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">ちょっと何言ってみるつもりです</p>&mdash; yonobot (@yonobot) <a href="https://twitter.com/yonobot/status/936945812294262784?ref_src=twsrc%5Etfw">2017年12月2日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# Heroku での運用について

以下の構成で動いています。

- [heroku-buildpack-mecab](https://github.com/diasks2/heroku-buildpack-mecab)
- [Heroku Scheduler](https://devcenter.heroku.com/articles/scheduler)
- [mLab MongoDB](https://devcenter.heroku.com/articles/mongolab)

これで2年くらい動かしてますがノーメンテで元気に動いてくれてます。
その前は GAE/Python で動かしてましたが料金体系の変更により Ruby で作り直して Heroku に引っ越ししたという経緯があります。

## heroku-buildpack-mecab

デフォルトでは mecab gem がビルドできないため。
mecab は発言生成時でなく、発言の元となるツイートを形態素解析するのに使ってます。

（でもよく考えたら Heroku 上では解析処理してないので使わずに済むかもしれません……）

## Heroku Scheduler

定期的な発言と返信の実行に使ってます。
返信はもう少しこまめに実行したいですが、10分おきが最短なのでやむなくそうしています。

<img width="647" alt="herokuscheduler.jpeg" src="https://qiita-image-store.s3.amazonaws.com/0/14873/99ee7d4b-6827-78c1-482d-8a4083ef5a1d.jpeg">

## mLab MongoDB

発言の元データを置くのに使っています。
PostgreSQL でなく MongoDB を使っているのはレコード数が17万件くらいあって Heroku Postgres の Hobby Dev プランの制限にひっかかるからです。 

<img width="583" alt="mongodb.jpeg" src="https://qiita-image-store.s3.amazonaws.com/0/14873/92a0952d-041e-13c6-08ed-899e351e0965.jpeg">

# まとめ

Heroku で運用している Twitter bot の構成について紹介しました。
イレギュラーっぽいですがこういう使い方もあるということで。
JavaFXとHiDPI

この記事は、[JavaFX Advent Calendar 2017](https://qiita.com/advent-calendar/2017/javafx)の3日目です。2日目はHASUNUMA Kenjiさんの[afterburner.fx によるお手軽 JavaFX プログラミング (1)](http://www.coppermine.jp/docs/notepad/2017/12/afterburnerfx-1.html)です。

JavaFXのHiDPIに関する現状と設定についての簡単なメモです。

標準的なディスプレイは96DPI（Dots Per Inch：96DPIは、1インチに96画素）、1画素の大きさは0.264mmとなります。
一方、超高解像度なディスプレイは、例えば13.3インチで2560×1440画素の場合、220DPIで1画素の大きさは0.11mmとなります。

12ピクセルの文字は、標準的なディスプレイでは3.2mmの大きさとなりますが、超高解像度なディスプレイでは1.4mmの大きさとなります。

超高解像度なディスプレイではこのように画面に表示されるものの大きさが、標準ディスプレイでは半分未満に小さくなってしまい、不都合が生じます。この対処として、OSの機能で画面に表示されるものの大きさを拡大します。Windows 10 OSの場合は、ディスプレイの設定で「テキスト、アプリ、その他の項目のサイズを変更する」を150%、175%、200%などに変更可能です。

JavaFXでは、JDK 8の最新版、JDK 9において、Windows環境ではこのディスプレイのサイズ変更の拡大率をもとに表示の大きさを変えるようになっています。

例えば、AnchorPaneのPref WidthとPref Heightを320、200に、フォントの大きさを12pxに設定した画面を超高解像度ディスプレイに表示すると、OSの設定でサイズを変更するの値に応じて拡大して表示されます。

この拡大を抑制し、本来のディスプレイの物理的な解像度にJavaFXのピクセル設定を合わせるには、システムプロパティprism.allowhidpiをfalseに設定します。

以下に、システムプロパティprism.allowhidpiをtrue（デフォルト）とfalse に設定した場合の画面の大きさを並べて示します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/100353/68430cbf-ceed-cb9b-0dbc-1308db027680.png)

システムプロパティprism.allowhidpiの設定を変えたグラフィックス表示の場合の大きさを並べて示します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/100353/f9dcc9bd-94b3-a2e3-39eb-da6c749e0177.png)

## getDpi()によるDPI値の取得

JavaFXにはディスプレイのDPI値を取得するAPIが用意されています。
javafx.stage.ScreenクラスのgetDpi()メソッドです。

13.3インチで2560x1440の解像度のディスプレイ上で、Windows OSのディスプレイのサイズ変更が150%に設定されている環境で、このAPIを使ってDPI値を取得した結果の例が次となります。

| OSのディスプレイ設定のサイズ変更値 | prism.allowhidpiの値 | getDpi()の結果 |
|:-:|:-:|:-:|
| 150% | true  | 147.0 |
| 150% | false | 221.0 |
S3で拡張子に依らずgzip圧縮を有効化する

この記事は、株式会社ACCESS Advent Calendar 2017の10日目の記事です。

内容的には3日目の記事の続きです。

---

# あらまし

S3に割と大きなファイルをアップロードする必要がある。
幸いに圧縮が効くものだったので、gzip圧縮でダウンロードできるようにS3を設定する。

この[記事](https://qiita.com/katoken-0215/items/66dd67eb9596196f19f9)の一部を書き換える方法で説明する。

# ローカルファイルの圧縮

以下のようにすることで、圧縮がかかるようになります。

```diff
s3.putObject({
  Bucket: 'バケット名',
  Key: '/path/to/file',
-  Body: fs.readFileSync('/path/to/localFile')
+  Body: zlib.gzipSync(fs.readFileSync('/path/to/localFile'))
+  ContentEncoding = 'gzip';
}, (err, data) => {
  if (err) {
    console.error(err);
    return;
  }
  console.log(data);
});
```

読み込み時に`zlib.gzipSync()`で圧縮して、ダウンロード時に`content-encoding: gzip`でgzip圧縮されていることをHTTPクライアントに教えるイメージです。

----

明日は @akegashi です。お楽しみに！
書いたブログを多くの人に読んでもらうために気をつけたい３つのこと！

こんにちは！DMM.comラボで技術広報をしている木下です。
普段は勉強会の企画をしたり、登壇のサポートをしたり、DMMのオウンドメディア『[DMMinside](https://inside.dmm.com "DMMiniside")』で記事を書いたりしています。

Advent Calenderに私がエントリーしたのは、Slackでの盛り上がりを見ていて非常にワクワクしたから。
その様子は先日[DMMinside](https://inside.dmm.com/entry/2017/12/01-dmmlabotech-adventcalender "DMMiniside")にも公開しましたのでこちらもぜひ　 

ちなみにDMMのカレンダーは２つありますよ♩
[DMM.com #1 Advent Calendar 2017](https://qiita.com/advent-calendar/2017/dmm)
[DMM.com #2 Advent Calendar 2017](https://qiita.com/advent-calendar/2017/dmm2)

さてでは本題に入りましょう！
せっかくブログを書くならば、より多くの人に読んでもらいたくないですか？？
そのために気をつけた４つのことをご紹介します。

#◆ 大事なことは「誰に」「何を」「どのように」伝えるのか？
よく社内でエンジニアの方がブログの案を書きました！！って持って来てくれるのですが、読んで伝えることが多いのがこれなんです。
**① 一番伝えたいことって何？**
**② ターゲットってダレ？**
**③ どんな雰囲気で伝えたい？**

ただ書いただけの文章は、書くことが目的になってしまっていることが多いので、読み手に満足感を与えられるものになっているのか？というとそうでもないかもしれません。
せっかく書くのなら読ませたい！伝えたい！と思う方はまずこの３点を考えることからブログの執筆をスタートしてみるのがおすすめです。

例えば今回の私で言ったらこんな感じ。
①ブログの書き方について
②比較的書くことが初心者だけど読ませたいエンジニア・デザイナー向け
③上からすぎずかたすぎずラフに
一つ付け足すとすれば、目的は、これを書くことでもっとDMMの技術の話を外で見かける日が増えたらいいな
会社のブログ書きます！って手を上げてくれる人増えたらいいな、って感じです（笑）


では大事な３つが書けたら何をするのか？

#◆ 全体の流れを考える！まずは要点の洗い出し
３つのポイントが揃ったら、直ぐに書き出したくなるんです。
でもそうするとまたつまづきポイントがやってくるw

まずは伝えたいことの要点を３〜５項目くらいに整えてみましょう。
それがブログの見出しになっていきます。

現在DMMでは登壇資料の作成の前に、著作権など権利周りに気をつけましょうね！というレクチャーをさせてもらっているのですが
その時もまずは話のドラフト作成、紙芝居くらいでいいのでざっくりとしたストーリーを作ることから始めましょう！とお話ししているんです。
ストーリー展開が見えればあとは肉付けをするだけ。自分らしさを加えて肉付け、味付けをしていきます。

#◆ 自分だったらどうやって検索するか
技術ブログを読む時ってどんな時ですか？どんな風に検索していますか？

新しい知識を探している時、困っている時、焦っている時。
色々考えられると思います。
最初に挙げた「どんな人に伝えたい？」に通ずる話でもあるのですが、自分だったらどうやって似たような記事を探すかな？と引いた目で考えるのもひとつです。

引っかかりそうなワードを盛り込んで置くことで、探してもらいやすくなるかもしれません！
読み手の目線に立ってみることで、求められるものに近づくことができます。


ということで３つ挙げてみました！
でもまずネタがみつからないんですよ、って方がいるかもしれないので最後にネタの出し方について少しだけ。

|今使っている技術について|チームについて|自分の学習|
|:------|:------|:------|
|・　ハマったこと<br>・　新しい機能を使ったこと<br>・　便利だったこと<br><br>|・開発プロセスについて<br>・使用ツールについて<br>・MTGについて<br>・メンバーについて|・新しい技術での学び<br>・趣味で開発したもの<br>・趣味で描いたコード<br>・開発環境自慢|

ネタはなんでもいいんです。
みんなが書いているような内容だったら、１つだけでも自分らしい考えを入れてみることで新しいものになります。

なんやかんや書きましたが、一番大事なのは書きたいという気持ち！
気持ちがこもった文章は伝わります。

さて、長くなりましたが書いたブログを多くの人に読んでもらうために気をつけたい３つのこと！はこれで終了！
明日以降のDMM.com　Advent Calenderの更新をお楽しみに！

[DMM.com #1 Advent Calendar 2017](https://qiita.com/advent-calendar/2017/dmm)
[DMM.com #2 Advent Calendar 2017](https://qiita.com/advent-calendar/2017/dmm2)
node aws-sdk でS3へファイルアップロードをする

この記事は、株式会社ACCESS Advent Calendar 2017の3日目の記事です。

----

# あらまし

権限を持つ人だけがダウンロードできるURLを作る必要があったので、AWS S3とCloudFrontを使うことになりました。

自動化のため、AWS S3にファイルアップロードをしつつ、CloudFrontの署名生成をするプログラムをNode.js で実装しました。

# 準備

Node.js で`aws-sdk`をインストールします。

```
npm install --save aws-sdk
```

プログラム中で読み込み、CloudFrontでの公開期間を設定する。
**公開期間は秒単位であることに注意する。**

```js
const AWS = require('aws-sdk');

const EXPIRATION_DATE = new Date(2038, 0, 1).getTime() / 1000;
```

環境変数からAWSの各種アクセスキーとシークレットを読み込みます。

```js
if (!('AWS_ACCESS_KEY_ID' in process.env)) {
  console.error('ACCESS_KEY_ID is not set.');
}

if (!('AWS_SECRET_ACCESS_KEY' in process.env)) {
  console.error('SECRET_ACCESS_KEY is not set.');
}

if (!('CLOUDFRONT_ACCESS_KEY_ID' in process.env)) {
  console.error('CLOUDFRONT_ACCESS_KEY_ID is not set.');
}

if (!('CLOUDFRONT_SECRET_ACCESS_KEY_PATH' in process.env)) {
  console.error('CLOUDFRONT_SECRET_ACCESS_KEY_PATH is not set.');
}

const CLOUDFRONT_SECRET_ACCESS_KEY = fs.readFileSync(process.env.CLOUDFRONT_SECRET_ACCESS_KEY_PATH);
```

`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY` は、`aws-sdk`が内部的に使用するのでチェックだけ行います。


S3へアップロードするためのインスタンスと、CloudFrontへアップロードするためのインスタンスを作ります。

```js
const s3 = new AWS.S3({apiVersion: '2006-03-01'});
const signer = new AWS.CloudFront.Signer(process.env.CLOUDFRONT_ACCESS_KEY_ID, CLOUDFRONT_SECRET_ACCESS_KEY.toString());
```

S3へアップロードします。

```js
s3.putObject({
  Bucket: 'バケット名',
  Key: '/path/to/file',
  Body: fs.readFileSync('/path/to/localFile')
}, (err, data) => {
  if (err) {
    console.error(err);
    return;
  }
  console.log(data);
});
```

署名生成をします。

```js
const url = 'http://yourdomain.jp/path/to/file';
const signedUrl = signer.getSignedUrl({
    url: url,
    expires: EXPIRATION_DATE,
});
```

これで完成です。

----

明日は @diescake です。お楽しみに！
VAM2がMagento2.2に対応しました

Magento公式Dockerイメージのリリースが楽しみな@kzkiq2ndです。

[Magento Advent Calender 2017](https://adventar.org/calendars/2349) 2日目は、
Magento2をVagrantで構築するためのスクリプトセットVAM2をMagento 2.2.1に対応させました！

[Magento-Japan/VAM2](https://github.com/Magento-Japan/VAM2)

## サーバー情報
- CentOS 7.4（bento/centos74)
- httpd 2.4.6
- php 7.1.11 (ius)
- mysql 5.7.20

## 動作確認環境
- macOS 10.12.6 (Sierra)
- VirtualBox 5.1.30
- Vagrant 2.0.1
- Ansible 2.4.2.0

## セットアップ内容
Composer経由インストール、サンプルデータ込み、素のOSS版Magento2.2.1をローカルにセットアップします。
公式ドキュメント以上のチューニングは行っていません。商用では使わないで下さい。
利用するにあたってGithub API tokenとMagento2利用キーペアの登録が必要になります。
詳しくは[README.md](https://github.com/Magento-Japan/VAM2)を確認ください。

## こんな方にどうぞ
公式ドキュメントでのインストール手順ではカバーしきれていない躓き回避を含んでいますので、これから入門される方、または公式ドキュメントを見ながらのインストールで何かしら悩んでいる方も、VAM2のAnsibleレシピを解決のヒントにぜひご利用ください。

## 注意事項
仮想マシンにメモリを2GB割り当てますので実行マシンのリソースに注意してください。

## その他の簡単構築情報
1. Magento公式Dockerコンテナ（β版）：「[magento/magento2devbox-web](https://github.com/magento/magento2devbox-web)」
2. さくらクラウドスタートアップスクリプト：「[Magentoをインストールしてみよう | さくらのナレッジ](https://knowledge.sakura.ad.jp/8230/)」

---

< Magento Advent Calender 2017 1日目
「[ブログ - Hitch 1.4とVarnish 5.2でHTTP/2なMagento環境を作る | Magentoと越境ECの総合サポート Principleworks](https://principle-works.jp/blog/making-http-2-magento-environment-with-hitch-1-4-and-varnish-5-2)」

Magento Advent Calender 2017 3日目 > こうご期待！
Power BI 勉強会 #6 を開催しました

昨日、2017/12/02 品川にて Power BI 勉強会 #6 を開催しましたので、さっくりレポートです。
# Power BI 勉強会とはなんだ
[Power BI 勉強会 | connpass](https://powerbi.connpass.com/) 
Power BI と Modern Excel をみんなで勉強する ユーザーコミュニティ勉強会です。

# Power BI 勉強会 #6
2017-12-02 13:00 ~ 18:00
日本マイクロソフト株式会社(品川) セミナールーム C + D 

|#|Title|Speaker|
|:----:|:-------------------------|:----|:----|
|1|Power BI 勉強会について||
|2|Power BI - おさらい と あたらしいこと|かがた たけし|
|3|Power BI で地理的分析とこまでできる？|ますたに|
|4|ライトニングトーク / おしらせなど||
|5|Power BIで時系列データと上手く付き合う|小林 寿|
|6|アンケートを即可視化！～MS Forms ⇒ MS Flow ⇒ Power BI with Visio Visual～|清水 優吾|

## 資料
発表に使用された資料は、[Power BI 勉強会 #6 資料ページ | connpass](https://powerbi.connpass.com/event/69605/presentation/) からどうぞ

## 感想など
ユーザーコミュニティイベントとして足掛け2年ほど継続しているのですが、スタート当初と比べると少しレベルアップができたかなと思いました。ただ、いくつかの課題が明確になりつつあって次回以降になんとかみなさんと勉強できるようにしたいなと考えています。

- データの準備
- メジャー(DAX)

は、多くのひとが超えるべきハードルなのでしょう。実際に Power BI の キモ といえることで、どちらも欠かすことができないものです。本日のセッションのなかで、アンケート結果をレポートにしてもらったのですが、その確信に至った感じがしています。

# その他
- [Microsoft Community Ring](https://www.microsoft.com/ja-jp/comring)

当コミュニティ活動に対し会場の無償提供などご支援をいただいています。

- [togetter まとめ](https://togetter.com/li/1177535)

タグは #PowerBI #PBIJP です。
安物エアコンの温度制御を改善するハック

#はじめに

この記事は おうちハック Advent Calendar 2017 の、3日目の記事です。

おうちハックというわりにはエアコン単体でIoT感のない話なのですが、お許しください m(_ _)m

あと、自分がエアコンの暖房機能を使わない人なので、季節感を無視して冷房前提で話を進めます。（暖房時も応用可能です）

#エアコン付けっぱなしの方が安い話

エアコン付けっぱなしの方が安い件がたまに浮上します。「付けっぱなし」について解釈が2通りあるような気がしています。

1つ目は、**在宅時**に、「暑いからエアコンを入れる→寒くなったからエアコンを消す」というのを繰り返すよりも、「温度設定を適温にして自動運転で付けっぱなしにする」という解釈です。

当たり前だろコラ！と思います。

2つ目は、**不在時**にも付けっぱなしにしちゃうという解釈です。

不在なら消した方がいいだろと思うのですが、[ダイキンの調査](http://www.daikin.co.jp/press/2016/160812_2/)によると30分ぐらいまでの外出なら付けっぱなしの方が安いそうです。

#設定すべき適温が状況によって変わってしまう

不在時の話は深追いしません。**在宅時は付けっぱなし**が基本です。

で、**自動運転で27度とかの適温に維持してほしい**んですが、「最初はいい感じなのにだんだん暑くなってきてしまう」とか、「足元が寒すぎる」など、どうにも**一定温度になってくれないことが良くある**と思います。

**それをどうにかするハック**を考えていきたいと思います。

#エアコンが室温を一定にする仕組み

エアコンには温度センサーが内蔵されていて、その温度センサーの場所が設定温度に維持されるよう制御されてます。

真面目に話すと制御理論の話になってくるのですが、まあ「PID制御」「古典制御論」とか単語だけ覚えておくと知ったかできるかもしれません。

ポイントは、**温度センサーが重要ですよ**ということです。

業務用エアコンだと、エアコン室内機とは別に単体の温度センサーが設置されていたりします。会社の壁とかにあったりしますよね。

家庭向けでも高い機種になると、赤外線センサーで人の体感温度を見て制御するのとかあります。三菱のムーブアイなんかが有名だと思います。

この記事では、普通の温度センサーが室内機に内蔵されている安物エアコンについて考えます。

#安物エアコンの問題点

冷たい空気は下に行くので、足元が寒くなりがちです。上と下とで3度ぐらいは平気で違ったりします。

![air1.png](https://qiita-image-store.s3.amazonaws.com/0/104360/797e1ef6-7bfa-a5c8-497b-70e491cf4f0a.png)

また、エアコンによってはエアコン自身の冷たさをセンサーが拾ってしまい、全然冷やしてくれなくなる欠陥機種もあります。

![air2.png](https://qiita-image-store.s3.amazonaws.com/0/104360/bcb2b462-c825-e6da-d675-431fe2e5e2a8.png)


#改善策１ サーキュレーター

改善策として、サーキュレーターを使うことが良くあると思います。

2番目の問題がある場合でも、サーキュレーターの風が温度センサーに届けばいい感じになります。

ただそれだとこの記事の意味がありませんｗ

#改善策２ 電子工作

人間に近い場所に、なにか電子工作のブツを置いて、そこの温度センサーが適温になるようエアコンを制御する方法が考えられます。

うむ、これはハックだ！

でもシステムとして大げさすぎます。


#改善策３ センサー移設ハック

センサーの位置が悪いなら、いい感じの位置に移設してしまえばいいのです。

![air3.png](https://qiita-image-store.s3.amazonaws.com/0/104360/82514a6b-b242-23a9-4140-660a3232ddb4.png)

では早速やってみましょう。

エアコンのカバーを開けてフィルタを外すと、温度センサーが見えると思います。

![DSC_1062.jpg](https://qiita-image-store.s3.amazonaws.com/0/104360/075f58d1-df44-0e07-6ad7-a923943d16fa.jpeg)


見つからない場合は諦めるか、頑張って探してください m(_ _)m

配線を適当なところで切って延長して、センサーをいい感じの所に移動します。下の写真では古いカテ5のLANケーブルをバラしたもので配線しています。

![DSC_1063.jpg](https://qiita-image-store.s3.amazonaws.com/0/104360/ec1e7b58-155d-0820-014c-ac90af56a669.jpeg)

はい、これだけ！これぞハック！！

このハックをした後は、就寝時のエアコン付けっぱなしがすごく快適です。朝までずっと適温です。
また、サーキュレーターを使う場合に比べて天井付近が冷やされないので、その分電気代がオトクかもしれません。

#まとめ

安物エアコンの温度センサーを移設すると、温度制御がまともになるよ！
Windows Subsystem for Linuxにcronを。

（WSLインストール済みの想定です。）

initスクリプト的なバッチ書きました。
https://github.com/koginoadm/wsl/blob/master/service/cron.bat

以下な感じで使います。
```C:\> cron.bat start
C:\> cron.bat status
C:\> cron.bat stop
```

`.lnk`に引数`start`で登録しておいたりすると楽です。
標準出力のテスト

# はじめに
この記事はGo4 Advent Calendar 2017の3日目の記事です。  
標準出力のテストの方法について2つ紹介していきます。

# 標準出力のテスト
## 書き込み先の変更
標準出力の結果をテストする方法として、書き込み先を変更する方法があります。  
テスト実行時は普段と書き込み先を変更することで正常に出力されるかどうかをテストすることができるようになります。  
書き込み先の指定はfmt.Fprint関数で行います。  
この場合、以下のように出力先を指定できるように実装する必要があります。  
普段は明示的にos.Stdoutに書き込むように指定します。

```go
func Output(w io.Writer, output string) {
	fmt.Fprintln(w, output)
}

func Main() {
	Output(os.Stdout, "output")
}
```

テスト実行時には、書き込み先にbytes.Bufferを指定します。  
bytes.Bufferは書き込まれた文字列をメモリ上に保持してくれるため、保持された情報を取り出すことで予期した値が出力されたかどうかをテストすることができます。

```go
func TestOutput(t *testing.T) {
	buf := new(bytes.Buffer)
	Output(buf, "test")
	output := strings.Trim(string(buf.Bytes()), " \n\t ")
	if output != "test" {
		t.Error("unexpected value")
	}
}
```


## Examples
標準出力の結果をテストする方法としてExamplesを使う方法もあります。  
以下のサンプルコードをテストすることにします。

```go
func Main() {
	fmt.Println("test")
}
```
書き方としては、`` Output: `` で始め、続いて標準出力と比較したい文字列を指定します（`` Output: ``先頭のスペースと末尾のスーペースは無視される）。

```go
func ExampleOutput() {
	Main()
	// Output: test
}
```
`` Output: ``に指定する文字列をhogeに変更してテストをFAILさせてみます。
以下のように表示され、正しくFAILしていることがわかります。

```
--- FAIL: ExampleOutput (0.00s)
got:
test
want:
hoge
FAIL
FAIL    command-line-arguments  0.009s
```

詳しくは https://golang.org/pkg/testing/#hdr-Examples に書いてあります 。

# おわりに
Go初心者です...
内容が被ってしまった...
Protocol Buffers v3でフィールドのrequiredという仕様が削除された話

Microservices Advent Calendar 2017 3日目の記事です。
今日は、[2日目の記事](https://qiita.com/qsona/items/b13636fcdc4f8c6358db)で書いたロバストネス原則/Tolerant Readerに関連する話で、Protocol Buffersにあったフィールドのrequiredという仕様と、なぜそれが削除されたかについて書きます。

## Protocol Buffersとは

Protocol Buffersはメッセージフォーマットの1つです。JSONと大きく違うのは、バイナリ形式であることと、型定義があることの2点です。

Protocol Buffersの理解には、 @tayama0324 さんの歌舞伎座tech#12での[資料](http://tayama0324.github.io/slides/20161127-kbkz-tech.html#/) がおすすめです。(実はこの資料の中に、本稿で書いてある話も大体載っていました)

今回はマイクロサービスの話なので、Provider/Consumerで型定義ファイルを共有し、Providerがシリアライズ, Consumerがデシリアライズするようなケースについて書いています。
(あえて抽象的に書いていますが、その最も普通の例は gRPC です。昨年の @disc99 さんの[記事](https://qiita.com/disc99/items/cfca50a32240284578bb)が参考になります。)

## Protocol Buffers v2でのrequiredフィールド

v2の仕様では、フィールド定義にrequiredという修飾子をつけることが出来ました。
requiredが付いているフィールドは、そこに値が存在することが保証されます。型定義ファイルのあるフィールドにrequiredがついていると、そのフィールドの値が存在しないデータをシリアライズ/デシリアライズしようとすると失敗します。

アプリケーションでデータを扱うときは一般的に、そのフィールドの値がrequiredなのかoptionalなのかというのは有用な情報で、メッセージフォーマットに型があるならそこにその情報を含めたいというのは自然な発想だと思います。

## requiredフィールドの問題点

**既存のConsumerを壊さずに、requiredフィールドの追加/削除が出来ない** というのが問題点です。

そもそもrequiredが表すことが何なのかを、もう少していねいに考えてみましょう。
Protocol Buffers v2のrequired宣言は、ProviderにもConsumerにもそれを強制するものでした。
しかし、基本的にschemaは、まずProviderが提供するものです。
つまり、本来requiredは **Provider側からこのフィールドは必ず返すという宣言** であるべきであって、Consumerが必ず要求しているとは限りません。したがって、

- requiredフィールドの追加で、**既存のConsumerが壊れる**
- requiredフィールドの削除で、**そのフィールドを実際には使っていないConsumerが壊れる**

ということは、前日書いたロバストネス原則に反し、マイクロサービスの通信手段としては良くありません。

さらに、一般的にマイクロサービスでは「同時リリース」というのは出来ないので、Consumer側に何か手をいれるステップを踏んで段階的リリースできるならまだ良いのですが、そういう手段もありませんでした。

v2のドキュメントにもすでに、requiredフィールドを使わずにアプリケーションのレイヤでバリデーションをかけることを検討すべきという記述がありました。
そのような経緯があり、requiredフィールドはv3の仕様で削除されました。

## 代わりにどんな手段を用いるべきか

まず本来、requiredとして表現したかったことを、以下の2つに分割して考えましょう。

1. Providerが、requiredであることを保証する
2. Consumerから、requiredであることを要求する

1はメッセージフォーマットのレイヤでは行わず、**APIドキュメントなどに明示し、Provider側のコードでそれを保証**します。
そして、このような制約は未来に変わる可能性もあることを認識します。変わるとすると、requiredであることを要求しているConsumerがいたら壊れるので、先にConsumerを変更する必要があります。
したがって、2については、 **どのConsumerがrequiredであることを要求しているのかをProviderが知ることが出来る** とよいでしょう。前日の記事でも言及したように、これは契約の概念を持ち出して表すことができます。これについてはまた後日書きたいと思います。

## 参考文献
[Protocol Buffers (歌舞伎座tech#12)](http://tayama0324.github.io/slides/20161127-kbkz-tech.html#/) ( @tayama0324 )
[REST APIの設計で消耗している感じたときのgRPC入門](https://qiita.com/disc99/items/cfca50a32240284578bb) ( @disc99 )
[TolerantReader](https://martinfowler.com/bliki/TolerantReader.html) (Martin Fowler)
[Language Guide  |  Protocol Buffers (proto2)](https://developers.google.com/protocol-buffers/docs/proto) (Google Developers) Required Is Foreverの項
[why messge type remove 'required,optional'? · Issue #2497 · google/protobuf](https://github.com/google/protobuf/issues/2497#issuecomment-267422550)
WebRTCにおけるP2P

# WebRTCはP2Pでサーバーレスか

WebRTCを少しでも学んだ事のある人はご存じかと思いますが。インターネット越しで通信しようとするとWebRTCは完全にサーバレスと言うわけではありません。
WebRTCを構成しようとすると下記のように幾つかサーバーが必要になります。

## シグナリングサーバ

接続情報が含まれるSDPやCnadidateと呼称されるメッセージの交換に利用するサーバです。
これは双方のクライアントからアクセス可能なサーバである必要があります。

![TradeSDP.png](https://qiita-image-store.s3.amazonaws.com/0/59204/e8fde831-36fb-02e9-736c-c9b3c7eea8fb.png)


## STUNサーバ

NAT配下に存在する機器がNAT機器に割り当てられているIPと自分に割り当てられているPortを知るために必要になります。同じNAT機器の配下やグローバルIPをクライアントが持っているなどの例外を除き、ほとんどの場合でSTUNが無ければ繋がりません。

![STUN.png](https://qiita-image-store.s3.amazonaws.com/0/59204/2fc6b37b-04d0-c3f8-8d07-a25ed116ccb6.png)

## TURNサーバ

P2P接続が出来ない一部の環境において、通信を中継するために必要になります。グローバルIPを持っているTURNサーバがクライアントにIPとPortを貸し出すような仕組みです。個人向けの場合には必要になる事は少ないです。しかし、法人。特に日本の大企業の相手場合には高確率で必要になります。

![TURN.png](https://qiita-image-store.s3.amazonaws.com/0/59204/c546f9df-ffc2-9936-f04b-71ce097eb867.png)

# WebRTCでサーバレスにするには

隣接した端末がBluetoothやRFIDなどで接続情報を交換できて、かつ双方がIPアドレスで通信可能な場合においてはサーバーレスが実現可能です。実際にやっているのは時々見ます。

# ビデオチャットのサービスでP2Pを利用できるか

ビデオチャットの場合は数人であれば可能でしょう。これはクライアントPCの性能やクライアント間のネットワーク品質に依存します。現実的なラインとしては4-5人程度と個人的には考えています。
スマートフォンがクライアントの場合にはもっと少なく2-3人程度にする必要があると思います。

## 音声のみの場合

PCに対する要求性能やネットワークに対する要求速度が大きく下がります。必然的に処理可能な人数は増えます。

## ビジネスとして

正直言って難しいと思います。使えて1on1では無いでしょうか。
複数人の接続の場合は下記のようなフルメッシュ通信となります。

![P2P.png](https://qiita-image-store.s3.amazonaws.com/0/59204/593a07bd-9a53-9f8f-b173-16417365fa25.png)

この通信においては A<->B 間は繋がるのに B<->C 間が繋がらないという状況が発生するのですが、これら個々の通信経路は千差万別ですので問い合わせをうけても原因特定の難易度が非常に高くなります。

# 動画配信においてサーバ台数を減らせるか

これは一部の用途においては可能です。WebRTCのデータ通信であるDataChannelをつかい、HLSの動画セグメントをクライアント間で融通することでCDNのような状態とすることで送り元のサーバ転送量を減らすというテクニックがあります。

実際にこれを実現してビジネスにしている例としては

* [Mist Technologies](https://www.mist-t.co.jp/) 社の MistCDN
* [Peer5](https://www.peer5.com/)

が挙げられます。

## 問題点

しかし、ぱっと思いつく大きな問題点として下記が挙げられます

### クライアントの転送量が増加する

視聴しているクライアントはセグメントを融通するアップストリーム通信が必要になります。転送量に関わらず定額の回線であれば問題になりませんが、スマートフォンなどで転送量に制限のある携帯電話回線を利用している場合はユーザーが自分が視聴しているファイルサイズ以上の転送量が消費されるため、当然反感を買う可能性があります。

### 融通し合う相手がいなければ成立しない

同じタイミングで同じ動画を見ている人がいなければ、融通し合う事ができません。多くの人が同じ動画を同じタイミングで見ている場合には強力ですが。違うタイミングで見ていたり違う動画を見ている場合にはあまり効果は期待できません。ですので、Youtubeやニコニコ動画などの大量の動画から選択的に視聴するサイトには適用しにくい技術となります。

これ以外にも技術的に難しい問題点は複数あります。しかしながら、遅延が発生しても構わない形態のライブ放送であれば非常に有効な技術とも言えます。

# まとめ

結論としてWebRTCのP2Pをビジネスで利用できるのは一部の用途に限られることとなります。有償サービスとして提供しようとするとWebRTCのサポートコストはネットワーク環境の影響が大きい分、大変なものとなります。
1on1でP2P利用とする場合でも片側は自社の管轄ネットワークにするなど、可能な限り接続環境を限定したいところです。そう考えるとサーバ経由になるTURNのみやMCU/SFUは経路が限定しやすいためサポートコストを抑えるメリットがありますね。