OmniAICreator/Qiita-1.07M huggingface dataset:
Native Extensions で Dart x SDL を利用してみる。Mac の 問題とか

Dart の Native Extensions を利用して、 SDL　を用いたマルチプラットフォームのゲーム開発環境を作れるか検証してみた。


結論からいくと、 「Mac　上で動作する SDL x Dart の アプリは動作させることが難しいよ」 と言うことです。 Windowsはできる。

ただ、時間をかければできるかなぁとも思いました。
※ Dartはゴリゴリ開発されているものなので、近い未来には、変わっているかもしれません。


# Dart とは
Serverサイド や SmartPhone で動作する VM　をもち、 Browser上で動作する JavaScriptを出力できる凄い奴です。
https://www.dartlang.org/


# Native Extensions とは
コマンドライン向けのVMから、 Shared Library と連携して、Nativeの機能をDartから叩くのに使用します。

https://www.dartlang.org/articles/dart-vm/native-extensions

# SDL とは
クロスプラットフォームの Low level のライブラリーです。 audio, keyboard, mouse, joystick, graphics hardware を扱うことができます。

ゲームを作成するのに必要な機能がサポートされており、スマフォの環境も含めて、ほとんどの環境で動作します。


# 試したこと

## Dart と SDLを組み合わせて、 Dartで書いたゲームをありとあらゆる PFで動作させることができないか?

Dart と SDLを組み合わせて、 Dartで書いたゲームをありとあらゆる PFで動作させることができないか?　と考えました。

Dartには、 async-await がサポートされていたりして、 ロジックが書きやすいです。ゲームスクリプトとか、 Dartがあればあればいらないじゃん。 Dartがゲーム用のスクリプトといって問題ないくらい。気軽にロジックがかけるではないか..


## Dart

#### MAC で
https://github.com/kyorohiro/dart.sdltest

```
git clone https://github.com/kyorohiro/dart.sdltest
cd dart.sdltest
cd doc_sdl2
ninja -f build.osx.ninja
cd ..
sh build.sh
dart main.dart 
```

#### Windows で

https://github.com/kyorohiro/dart.sdltest.vc

```
git clone https://github.com/kyorohiro/dart.sdltest.vc
cd dart.sdltest.vc
start Project3.sln
...
Debugモードでビルド.....
...
cd ..
git clone https://github.com/kyorohiro/dart.sdltest
cd dart.sdltest
copy {ビルドしたDLLとLib と SDL関連のDLL} ./
dart main.dart
```

# どうなったか?
Windowsでは、期待通りに動作します。
つまり、Dart で SDLアプリを作れます。

![unnamed.png](https://qiita-image-store.s3.amazonaws.com/0/54192/198c0754-3ca6-b81c-4758-ca6d06c9d862.png)

しかし、MACでは以下のようなエラーがでます。

とすると、 WARNING: nextEventMatchingMask should only be called from the Main Thread! This will throw an exception in the future.
と警告がでてそれ以上何もできません。

Mac では　UI　関連のイベントは、 MainThreadで処理しなくてはならないからです。



# もしも macで Dart x SDLを実現したいなら
DartVM に手を入れて MainThread を、制御できるようにする。
DartVM と プロセスを分けて、MainThreadを描画ように利用する。
などなど。

Flutter のコードを見ると、 DartVM を組み込んで　アレコレしているので、
参考にしたり、 そのまま利用したりすると良いかもしれません

 
# PS 
以下でも、あれこれ書いてます。

[About Dart x SDL on Mac](http://kyorohiro.blogspot.jp/2017/12/about-dart-x-sdl-on-mac.html)
https://github.com/kyorohiro/dart.sdltest.vc
https://github.com/kyorohiro/dart.sdltest
https://github.com/kyorohiro/cgame
https://github.com/kyorohiro/doc_sdl2
CloudSQLの自動フェイルオーバーはマスターインスタンス障害時には発火しない

[GCP Advent Calendar](https://qiita.com/advent-calendar/2017/gcp)の5日目です。
勢いで申し込んでちょっと後悔してます。

内容はタイトルのとおりです。
先日、マスターインスタンスが不調なことがあったのですが、全然フェイルオーバーせずに焦りました。
知らなかった方もいるかもなので、簡単にまとめておきます。

## どんなときに自動フェイルオーバーするの？
- マスターインスタンスがあるゾーンが停止状態になったとき
  - ちゃんと[ドキュメント](https://cloud.google.com/sql/docs/high-availability?hl=ja#when_failover_is_triggered)にも書いてありました。。
- なので、マスターインスタンスの障害時や、インスタンスタイプ変更時の再起動はフェイルオーバーしません
- ちなみにRDSは[このあたりの基準](https://aws.amazon.com/jp/rds/faqs/#43)でフェイルオーバーするみたい
  - RDSとは勝手が違うのでご注意を

## 自動フェイルーバーってどのくらいダウンタイムあるの？
- `db-n1-standard-1`の10GBのからっぽなDBのフェイルオーバーで3分くらいかかりました
- あと、リードレプリカがある場合、フェイルーバー時にリードレプリカもダウンタイム発生するらしいのでご注意を
  - 参考: [Google Cloud Platform（GCP）の Cloud SQL がフェイルオーバー際の挙動](https://qiita.com/e_tei/items/4a703943afb283a4227c)

## その他フェイルオーバー仕様
- フェイルーバー後のIPは変わらないので、アプリ設定はそのままでいい
- マスタのインスタンスタイプを変えると、レプリのインスタンスタイプも変わる
- 詳細は[公式ドキュメント](https://cloud.google.com/sql/docs/mysql/configure-ha?hl=ja)を

## さいごに
- マスターインタンスの障害起こると長いことDB接続できなくなるので、別途監視とフェイルオーバーの自動化が必要だなと思いました
dictの作成は「{}」より「dict()」のほうが簡潔に書ける

この記事は [Pythonのコードを短く簡潔に書くテクニック Advent Calendar 2017](https://qiita.com/advent-calendar/2017/python-short-code) の5日目です。

# はじめに

Pythonでdictを作成するときは通常`{}`を使うことが多いですが、キーを`''`または`""`で囲う必要があるので若干面倒です。

`dict()`で書くとキー名を囲う必要がないので若干短く書くことができます。
文字数はそれほど変わらないですが、入力がとても楽になります。

# `{}`で書いた場合

```py3
d = {'title': 'title1', 'user': 'user1', 'body': 'body'}
```

# `dict()`で書いた場合

```py3
d = dict(title='title1', user='user1', body='body1')
```

# 参考

- Python3 ドキュメント
    - Python チュートリアル
        - [辞書型 (dictionary)](https://docs.python.jp/3/tutorial/datastructures.html#dictionaries)
オブジェクトを全部配列に変換する再起プログラムを振り返る。


# そもそも
テンプレートエンジンにPHPから値を渡す際に
以下の２通りの書き方をコーディングする方に説明するのが大変で
> オブジェクトでデータを渡す場合：`{$aaa->name}`
> 配列でデータを渡す場合：`{$aaa.name}`

いっそのことオブジェクトを配列に変換してしまい
コーディングする方には
`{$aaa.name}`
で統一してもらおうという事で作り始めました。

自分で作ったものの、再起プログラムは少し苦手意識がありましたが
知らない所で別のプロジェクトで関数を使われていたのを知ったでこれを気に見直して見る。


# 参考プログラム
https://github.com/tecokimura/funcToArray

# toArray()
自分の中から「GitHubだけ見たら分かるようにしとこうよ」という声が聞こえますが・・・
あえてコメントを書きまくる！！


```php
/**
 * @param var $var オブジェクトから配列にするデータ
 * @param int $count 関数を呼び出した回数
 * @return array toArray()を呼び出した結果データ
 **/
static function toArray($var, $count=0) {

	// オブジェクトじゃない場合は何もしないので戻り値にしまう
	$ret = $var;

        // 再起の最大呼び出し回数を超えていない時処理をする
	if( $count <= self::TO_ARRAY_LOOP_MAX ) {
		// toArray()が実装されているのなら
		if( self::methodExists($var,'toArray') ) {
                        // toArray()を再起にかける
			$ret = self::toArray($var->toArray(), $count+1);
		}else {
			// オブジェクトであってもstdClassの場合は配列にして返す
			if(is_object($var) && get_class($var) == 'stdClass'){
				$var = (array)$var;
			}

			// 配列の場合はそれぞれを再起させる
			if( is_array($var) ) {
				foreach($var as $key => $value) {
					$ret[$key] = self::toArray($value, $count+1);
				}
			} else {
				$ret = $var;
			}
		}
	}

	return $ret;
}
```

# まとめ
class 定義時にtoArrayで変換できるようにしておいて
配列などのデータにまとまったデータを再帰的にtoArray()を呼び出して変換していきます。
countでreturnする処理は念のためです。

# 改善
クラス内の変数を取得する方法があった気がしますそれを使えばtoArray()がもう少し汎用的に作れそうです。
C#のSQLの書き方

# はじめに
C#でお仕事していて、SQLでDB操作する際の書き方について、
最近初めて知った方法もあったのでメモしておこうと思います。
![Screen Shot 2017-12-04 at 21.12.12.png](https://qiita-image-store.s3.amazonaws.com/0/99869/d4b1efad-6ca9-ecfb-e9a9-f7d30e1d7774.png)
# まとめ
プログラム内でSQL書く際に、可読性、保守性と全体のスタイルを考慮してどのように書くべきか
未だに悩むことがありますが、いろいろ調べてみると今まで知らなかったことを発見できるので
それはそれで面白いですね。
Rails：今すぐrails consoleからboolean型でdefaultが未設定のカラムが無いか確認しよう

# コード

```ruby
  ActiveRecord::Base.connection.tables.map{ |table| table.classify.safe_constantize }.compact.
      map{|table| table.columns.map{|col| { "#{table.table_name}": "#{col.name}"} if col.type == :boolean && col.default == nil}.compact }.flatten

=> [{:users=>"is_xxx"},
 {:users=>"is_yyy"},
 {:posts=>"is_zzz"}]

```

書きかえればboolean以外の条件/組み合わせでも探せます。

migrationファイルから今どんなデータモデルになっているのかを確認するのは、ファイル数が少ないうちは良いですがすぐに増えてきつくなってきます。

自分の場合、後述するような画面側の挙動に遭遇したのがきっかけになり、consoleから調べられないかなぁと試してみて上手くいったのでこの記事を書いていますが、[他の方の記事でも未設定のリスクが指摘](https://qiita.com/jnchito/items/a342b64cd998e5c4ef3d)されていたりするので再確認して損は無いと思います（ちなみに確認した結果7個も出てきました。。）

<b>未設定は色々と良くないことが多い</b>ということの参考になればと思います。



# 画面側でこんなことが
とあるboolean型の項目を登録することができるUIパーツにて起きた話です。
※再現用に用意した画像なのでところどころ実際とは異なっています。


#### 初期状態  valueには<b>`null`</b>が入っている

![default.png](https://qiita-image-store.s3.amazonaws.com/0/107536/9ea1e74c-b34d-1af2-9979-a06555dd11e2.png)




#### チェック入れる  valueに<b>`true`</b>が入る
![checking.png](https://qiita-image-store.s3.amazonaws.com/0/107536/f440e6ab-1ef1-88de-b488-78f45433676c.png)


#### チェック解除後  valueに<b>`false`</b>が入る
![after.png](https://qiita-image-store.s3.amazonaws.com/0/107536/de031e97-2f3c-98c0-e886-6447d555c1fb.png)


初期状態とチェック解除後では見た目的には同じですがサーバーに送られるデータが異なります。
ユーザーからすると<b>「ある時は空、ある時はfalseとして登録されるんだけど、なんでなの？」</b>ということになってしまいます（実際これで問い合わせがありました。。）

該当のフィールドがたまたま処理に使われていなかったからdefault値が設定されていなかった＆問題にならなかったのだと思いますが、ユーザーを不安にさせるのは良くないので極力設定した方が良いですね。

# まとめ
* boolean型のdefault値未設定は色々と良くないことが多いので設定しておく
* スクリプトで楽に確認できる
Node.jsで書いたWebサーバでJSやCSSを読み込む

Node.jsでWebサーバを書く必要があってHTMLからJSやCSSのファイルが読み込めなかったのでその解決策
まずはindex.htmlを返すサーバを書いてみる  

 ```js:server.js
var http = require('http');
var fs = require('fs');

http.createServer(function(req,res){
  fs.readFile('./index.html',function(err,data){
    res.writeHead(200,{"Content-Type":"text/html"});
    res.end(data,'utf-8');
  });
}).listen(8888); 
 ```

index.htmlでは./js/index.jsを読み込んでいる  

``` html:index.html
<html>
  <head>
    <script type="text/javascript" src="./js/index.js"></script>
  </head>
  <body onload="hello()">
    <h1>Hello!</h1>
  </body>
</html>
```  

index.jsの中身は今回単純にアラートを出すだけにしておく  

```js:js/index.js   
function hello(){
  alert("Hello!!");
}
```  

この状態でサーバを起動させるとjs/index.jsは読み込まれずに  
その内容はindex.htmlとして扱われる  
![スクリーンショット 2017-12-04 20.27.25.png](https://qiita-image-store.s3.amazonaws.com/0/98200/3504ebfa-e468-4578-c6e7-a5a5a1a16f72.png)

# 修正  
server.jsを編集してjs/index.jsを読み込むようにする  

``` js:server.js
var http = require('http');
var fs = require('fs');

http.createServer(function(req,res){
  var url = req.url; //リクエストからURLを取得
  var tmp = url.split('.'); //splitで . で区切られた配列にする 
  var ext = tmp[tmp.length - 1]; //tmp配列の最後の要素(外部ファイルの拡張子)を取得
  var path = '.' + url; //リクエストされたURLをサーバの相対パスへ変換する
  switch(ext){
    case 'js': //拡張子がjsならContent-Typeをtext/javascriptにする
       fs.readFile(path,function(err,data){
         res.writeHead(200,{"Content-Type":"text/javascript"});
         res.end(data,'utf-8');
       });
       break;
     case '/': //拡張子が/(index.html)だった場合はindex.htmlを返す
       fs.readFile('./index.html',function(err,data){
         res.writeHead(200,{"Content-Type":"text/html"});
         res.end(data,'utf-8');
       })
       break;
  }
}).listen(8888);
```  

とするとサーバ内においてあるjsファイルやcssファイルを読み込める 
![スクリーンショット 2017-12-04 21.02.56.png](https://qiita-image-store.s3.amazonaws.com/0/98200/9b42d2d7-018a-a969-515b-4faf47cdfa45.png)

ちょっと悩んだので覚書程度に
Systems Manager パラメータをCloudFormationで使う

# 概要
CloudFormationのパラメータをSystems Manager パラメータから取得する方法の解説

# やってみる
## コマンド
従来通り `ParameterKey` と `ParameterValue` を渡せばOK
この時 `ParameterValue` にSystems Manager パラメータのキー名を指定する

```console
$ aws cloudformation update-stack \
    --stack-name <スタック名> \
    --template-url <テンプレートURL> \
    --parameters \
      ParameterKey=<CFnパラメーターキー>,ParameterValue=<Systems Manager パラメータキー>\
    --capabilities CAPABILITY_IAM
```

## テンプレート
`Type` を `AWS::SSM::Parameter::Value<String>` 型にする。
コマンドとテンプレートを修正するだけでSystems Manager パラメータからの呼び出しが可能に！

```yaml
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
  <CFnパラメーターキー>:
    # コマンドの引数で指定した、<Systems Manager パラメータキー>からパラメータを取得してくれる
    Type: AWS::SSM::Parameter::Value<String>
```


# 試す
MySQLを構築するテンプレートを例にする

## Systems Manager パラメータ(EC2 パラメータストア)
以下のキーで、DBユーザー名とパスワードをSystems Manager パラメータに保管してあるとする。
SecureStringだとCloudFormationから呼び出せないので注意。

| key | value |
|---|---|
|MySQLUsername|mysqluser|
|MySQLPassword|mypassword|


## テンプレート
```rds.yaml
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
  Username:
    NoEcho: true
    Type: AWS::SSM::Parameter::Value<String>
    
  Password:
    NoEcho: true
    Type: AWS::SSM::Parameter::Value<String>

  StorageSize:
    Type: Number

Resources:
  DB: 
    Type: AWS::RDS::DBInstance
    Properties: 
      DBInstanceClass: "db.t2.medium"
      Engine: "MySQL"
      EngineVersion: "5.7"
      Iops: "1000"
      AllocatedStorage: !Ref StorageSize
      MasterUsername: !Ref: Username
      MasterUserPassword: !Ref Password
```

## コマンド
`ParameterValue` を呼び出したいSystems Manager パラメータのキー名にすることで呼び出せる

```console
$ aws cloudformation update-stack \
    --stack-name rds-stack \
    --template-url file://rds.yaml \
    --parameters \
      ParameterKey=Username,ParameterValue=MySQLUsername \
      ParameterKey=Password,ParameterValue=MySQLPassword \
      ParameterKey=StorageSize,ParameterValue=100 \
    --capabilities CAPABILITY_IAM
```

# まとめ
機微情報の管理をSystems Manager パラメータで一元管理できるのはとても良いですね


# 参考
* [AWS CloudFormation で StackSets パラメータの上書きと EC2 Systems Manager パラメータストアのパラメータ化設定をサポート](https://aws.amazon.com/jp/about-aws/whats-new/2017/11/aws-cloudformation-supports-parameterizing-configurations-with-stacksets-parameter-overrides-and-ec2-systems-manager-parameter-store/)
* [Parameters - AWS CloudFormation](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html#aws-ssm-parameter-types)
     - `AWS::SSM::Parameter` 型の一覧。執筆時点でドキュメントは **英語のみ**
hot reloadを自前のexpressサーバーに組み込む

こんにちは。明治大学総合数理学部現象数理学科の鈴木です。2016年度からWeb Engineerはじめて、現在はPlaid, incでインターン中です！明治大学総合数理アドベントカレンダーを[@ryunryunryun](https://qiita.com/ryunryunryun)を巻き込んで作ってみたのですが、カレンダーはスッカスカです！（ネタも思いつかないし）

最近のwebpackだと、`webpack-dev-server`をインストールすれば、簡単にhot reload開発ができるようになります。しかし、既にサーバー側のコードを書いていて、そちらにhot reloadを組み込みたい場合もあると思います。今回は、Expressサーバーにhot reloadを組み込む方法を記事にしてみました。

# Hot reloadとは
`Hot reload`とはコードを変更したときマニュアルでリロードしなくとも、自動でリロードしてくれることを言います。ただ単にブラウザで開いているページをリロードするのではなく、VueやReactであれば、そのコンポーネントの状態をリロードしてくれるという代物です。

ここを読んでみてください！

- [Vue hot reload](https://vue-loader.vuejs.org/ja/features/hot-reload.html)


# Getting Started

## 必要なモジュールのインストール
hot reloadに必要なモジュール

```
npm i --save-dev express webpack webpack-dev-middleware webpack-hot-middleware
```
なんとなくpugがほしいので

```
npm i --save-dev pug
```

## webpackの設定を書く
- entrypointの設定は配列の形式すること
- output先のフォルダをoutput.publicPathにも設定すること
- HotModuleReplacementPluginをpluginsに入れること
- 開発時にのみhot reloadを設定すること

```./webpack.config.js
const path = require('path')
const webpack = require('webpack')
const isProd = process.env.NODE_ENV === 'production'

const webpackConfig = {
  // webpack config
  entry: {
    app: [path.resolve(__dirname, 'client.js')]
  },
  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, 'dist'),
    publicPath: '/dist/'
  },
  plugins: []
  // ...
}

if (isProd) {
  // ...
} else {
  // dev
  webpackConfig.entry.app.unshift('webpack-hot-middleware/client')
  webpackConfig.plugins.push(
    new webpack.HotModuleReplacementPlugin()
  )
}

module.exports = webpackConfig

```


## Express Server
これをserverに追加するだけで終わりです。

```js
const webpack = require('webpack')
const webpackConfig = require('./webpack.config.js')
const compiler = webpack(webpackConfig)
app.use(require('webpack-dev-middleware')(compiler, {
  noInfo: true, publicPath: webpackConfig.output.publicPath
}))
app.use(require("webpack-hot-middleware")(compiler))
```

### 例
例では、開発時のみhot reloadを有効にするようにしています。また、リクエストが来たらhot reload付きで`./index.pug`をrenderするようにしています。

```./server.js
const express = require('express')
const app = express()
const isProd = process.env.NODE_ENV === 'production'

if (!isProd) {
  const webpack = require('webpack')
  const webpackConfig = require('./webpack.config.js')
  const compiler = webpack(webpackConfig)
  app.use(require('webpack-dev-middleware')(compiler, {
    noInfo: true, publicPath: webpackConfig.output.publicPath
  }))
  app.use(require("webpack-hot-middleware")(compiler))
  }
}

app.set('view engine', 'pug')

app.use((req, res, next) => {
  res.render('index')
})

const server = setup(app)

server.listen(8080)
```

## Client Side
```./client.js
// any js code. eg vue/react/...
```

```./index.pug
html
  header
    title hot reload
  body
    #app
    script(src="/dist/app.js")
```

## DONE
これで終わりです。後は、server.jsを実行するだけです。また、server.js内でwebpackのcompileをしているため、webpack watchをする必要はありません。コードを書いたら直ぐにブラウザ上に反映されるはずです！最後に、webpackにvue-loaderなりなんなりを入れてSPAをhot reloadで開発してみましょう！

ただ、大規模開発のときはどうなるんでしょうか？？ 重そう。
Scalaを知るために参加した勉強会【2017/12/4　メモ】

#Scala勉強会参加してみた！
注目されている言語である「Scala」に初心者でも参加できる機会をいただけたので、今日の勉強会の知識を残していこうと思います！

※興味だけで参加しているので、知識は凄く浅いです。
##PHPエンジニアが始めるScala
”型安全”
PHPとの違いListに対して何が入っているか一目瞭然
型エイリアス
引数/返り値　一目瞭然

”ライブラリ”
CakePHPでドン！！　→　選ぶ姿勢が生まれた

”不変”
immutableで安心

match/case　を使用してしまえばifを使わなくてい良い

flatMap ... ここまで来ると分からない
Either Rigthはright! 回すの便利

登壇者も言ってましたが、私もチンプンカンプンでした。

「使わなくてもプロダクトのコードは書ける！」


##"cats" in practice 関数ライブラリcatsの紹介とアドテクシステムにおける使用例

関数型ライブラリのデファクトスタンダード
以下のような関数型色の強いライブラリが内部でcatsに依存している。

syntax.option._
syntax.either._
面白い事ができる

NonEmptyList
-空でないことが保証されているList

sequence,traverse
-２重に包まれたMonadの順番をひっくり返す。

OptionT,EitherT
-2重Monadoのボイラープレートを減らす

登壇者：感想
まずは使ってみることも大事
使ってる内にだんだん理解してくる

※理解するには難しい領域だと感じた。

##ScalaのDIパターンについて

DIとは何か？
コンポーネント間の依存関係をプログラムのソースコードから排除し、外部の設定ファイルなどで注入できるようにするソフトウェアパターンである。

何が嬉しいのか？
・結合度の低下・コンポーネント化の促進
・単体テストがしやすくなる

###Manual DI
・コンストラクタ引数を使って手作業で配線
・一番簡単にDIする方法

Pros
一番手軽に始められる方法
Compile-time DI
Pure Scala

Cons
依存関係が多いと配線作業がつらい

小規模のプロジェクトならManual DI

###Cake Pattern
コンストラクタ引数を使用しない面白いアプローチ
説明するのが難しい

Pros
Compile-time DI
Pure Scala

Cons
大量のボイラープレート
柔軟性が低い
パフォーマンス・コンパイルに難あり

###MacWire
・Scala用ライブラリ
・マクロで配線してくれる
Manual DIの上位互換

Pros
・ボイラープレートが少ない
・ Compile-time DI
Cons
・マクロ（強いて言えば）

###Guice
・Javaようフレームワーク
・ランタイム？

Pros
・ボイラープレートが少ない
・ 高機能で柔軟性が高い
・実行時に配線をコントロールできる
・javaで使ってた人は馴染みやすい
Cons
・Runtime DI
・学習コストが高い

何を使えばいいか？　→　お好きなのどうぞ

オススメ
・最初はMAnual DI　から始めるのがオススメ
・Compile-time DI を使うと安全


##感想
知らない用語も数多く存在し、学習コストも高く感じた。
未来の自分これを見て納得できるようになっていますように頑張っていきたいな思いました。
また、登壇トークをメモ書きしている程度なので、聞き取れない部分も多々ありました。
話を追っていくのが難しかった。
素のRでdata.frameにlistを含める

## 追記@2017/12/05

`I()`を使うと楽というかヘルプによると勝手に変換してほしくなければ`I()`を使えということのようです。

- cf. [完璧なdata.frameなどといったものは存在しない。完璧な絶望が存在しないようにね。 - Technically, technophobic.](http://notchained.hatenablog.com/entry/2017/12/05/004406)

```r:入力
> data.frame(
+   x = I(list("a", TRUE, 0)),
+   y = 1:3
+ )
```

```r:出力
     x y
1    a 1
2 TRUE 2
3    0 3
```

## 以下原文

最初そんなことできたっけと思ってしまったけど、できる。data.frameはlistなので。

```r:入力
df <- data.frame(x = 1:3)
class(df)
typeof(df)
```

```r:出力
> class(df)
[1] "data.frame"
> typeof(df)
[1] "list"
```

data.frameは列のlist、したがって要素としてlistを含めそうなものだが`data.frame()`にlistを与えても展開されてしまう。

```r:入力
data.frame(
  x = list("a", TRUE, 0),
  y = 1:3
  )
```

```r:出力
  x..a. x.TRUE x.0 y
1     a   TRUE   0 1
2     a   TRUE   0 2
3     a   TRUE   0 3
```

しかし後から列にlistを与えることはできる。

```r:入力
df$y = list(1, FALSE, mean)
df
```

```r:出力
  x                                     y
1 1                                     1
2 2                                 FALSE
3 3 function (x, ...) , UseMethod("mean")
```

data.frameもlistなので、nested data.frameも作れる。

```r:入力
df <- data.frame(x = 1:3)

df_list <- list(
  df_a = data.frame(l = rnorm(3)),
  df_b = data.frame(l = rnorm(3), m = rnorm(3)),
  df_c = data.frame(l = rnorm(3), m = rnorm(3), n = rnorm(3))
)

df$y <- df_list

str(df)
```

```r:出力
'data.frame':	3 obs. of  2 variables:
 $ x: int  1 2 3
 $ y:List of 3
  ..$ df_a:'data.frame':	3 obs. of  1 variable:
  .. ..$ l: num  0.5879 0.0696 -0.8323
  ..$ df_b:'data.frame':	3 obs. of  2 variables:
  .. ..$ l: num  -0.723 1.752 -0.724
  .. ..$ m: num  0.98 0.833 -0.111
  ..$ df_c:'data.frame':	3 obs. of  3 variables:
  .. ..$ l: num  0.102 -0.264 1.623
  .. ..$ m: num  2.563 0.428 0.106
  .. ..$ n: num  2.086 0.249 -0.538
```

参照も普通に。

```r:入力
df$y$df_a$l
```

```r:出力
[1]  0.58786320  0.06962387 -0.83226396
```

listのlistなので`rapply()`が活きるぞ。

```r:入力
rapply(df, mean)
```

```r:出力
          x    y.df_a.l    y.df_b.l    y.df_b.m    y.df_c.l    y.df_c.m 
 2.00000000 -0.05825896  0.10152878  0.56755911  0.48687462  1.03224899 
   y.df_c.n 
 0.59883656 
```
特になにもしないHerokuスケジューラを2年くらい動かしてる話

# はじめに

Heroku Scheduler つかってますか？そういえば私は、仕事ではつかったことありません（ジョブ実行は、違う仕組みで実現している）。この投稿は、そんな Heroku Scheduler での本番運用を検討するにあたり、どのくらい安定的に稼働するものなのか、調べた記録です（というか、なんとなく始めたから放置していたの思い出しただけだけど）。


# Heroku Scheduler とは
こいつです
https://elements.heroku.com/addons/scheduler

# 検証したいこと

- Heroku Scheduler がジョブ起動に成功/失敗する頻度はどの程度か


# 検証方法
- 任意のタイミングでジョブが起動するように Heroku Scheduler を設定する。
- ジョブの内容は、死活監視サービスへのチェックインとする。ほかは何もしない。
- 一定期間に死活監視サービスにチェックインがあったら、ジョブが起動成功したと判断する

## 死活監視サービス
Dead Man's Snitch をつかいました。Pingdom みたいなやつです。無料から使える。監視対象が落ちてるとアラートをくれます。
https://elements.heroku.com/addons/deadmanssnitch

## ジョブ
Ruby の rake task を書いてそれを Heroku Scheduler で定期的に実行しているだけです。["snitcher"](https://github.com/deadmanssnitch/snitcher) は、Dead Man's Snitch
が 配布しているgemです。

```rb
require 'snitcher'

task :snitching do
  Snitcher.snitch(ENV['DEADMANSSNITCH_TOKEN'], message: "snitched with a rake command.")
  puts "just snitched!"
end
```

# 検証結果

## 1日1回のスケジュールの場合

1日1回ジョブを実行するスケジュールです。わりとあるケースじゃないでしょうか。Dead Man's Snitch の監視インターバルを「Daily」に設定して、Heroku Scheduler のスケジュールも「Daily」に設定します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/7046/c95b4da3-5503-78db-1251-0af0f7e0fa22.png)

このジョブスケジュールは、2016年7月23日に開始してます。こちらは、現在（2017年12月5日）まで1度もジョブ起動が失敗したことないです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/7046/ddf25669-6a28-ff74-bb46-b1518964ada4.png)


## 1時間に1回の場合

![image.png](https://qiita-image-store.s3.amazonaws.com/0/7046/99f1339c-8488-f7fe-097f-85f0bd64bf27.png)

1時間に1回、チェックインするスケジュールです。上記の24倍ですね。いきなりハードルがあがります。Dead Man's Snitch の監視インターバルを「Hourly」に設定して、Heroku Scheduler のスケジュールも「Hourly」に設定します。このジョブスケジュールは、2016年4月14日から開始してます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/7046/8ddfffde-aff8-2299-a495-3e8622adae73.png)



2016年4月14日に初回のアラートがきて以来、アラートは累計62回です（長時間起動失敗している場合は、1時間に1度メールがくる）。2016年4月14日〜2017年12月5日まで600日間、14,400回の実行のうち、ジョブ起動失敗は62回ということになります。0.995694の確率でジョブ起動が成功、といったところでしょうか。10/31に何通もメールがきているのは、Herokuがまるごと1日落ちてた障害のときですね。だいたいの場合、1回起動に失敗したあとでも、次の1時間後のスケジュールでは正常に起動しているようです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/7046/79843955-6de6-e4eb-2358-304f608dffc6.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/7046/86a55028-11ef-5eb9-fdfa-704ae27e867b.png)

取り急ぎ、なにかの参考になれば幸いです。以上です。
ドットファイル（設定ファイル）を直接Gitで管理する —— リンクを作成したりは面倒

## 📁 📁 📁 📁
Gitに慣れてくると、ホームディレクトリ以下の設定ファイルたち、いわゆるドットファイルもGitで管理したくなります。
よく紹介されている方法は、ドットファイルを置く専用のディレクトリを用意して、そのディレクトリをGitの管理下に置き、そこからホームディレクトリ以下にシンボリックリンクを張る方法です。

しかし、これは面倒なので私はホームディレクトリを直接Gitの管理下に置いています。
乱暴かも知れませんが、とりあえず今まで問題を感じたことはありませんので、方法を簡単に紹介します。


## 初期化

当然、ホームディレクトリで行なうことになります。

```bash
cd
git init
```

`~/.git/` が作られます。
このリポジトリの設定である `~/.git/config` と、全体の設定である `~/.gitconfig` を混同しないよう注意します。


## 除外

まず、`~/.gitignore` で全てのファイルを除外します。

```text:~/.gitignore
*
```

こうしないと、ホームディレクトリ以下のファイルが全て `Untracked file` として報告されてしまいます。
Gitで管理したいファイルだけ対象になるような `~/.gitignore` を作ってもいいのですが、面倒なので `*` でよいでしょう。


## ファイルを管理対象に加える

`git add` で好きなファイルを指定します。
全てが `.gitignore` で除外されていますので、`-f, --force` オプションが必要です。

```bash
cd
git add -f .vimrc
```


## 管理しているファイルの一覧

現在どのファイルがGitで管理されているかが解りにくいですが、`git ls-files` で確認できます。

```bash
cd
# 全て
git ls-files
# ディレクトリを指定
git ls-files .config/
```


## 新しい環境で

例えばリモートリポジトリを使用しているならば、そこからホームディレクトリに直接もって来れますね。

```bash
cd
git clone https://example.com/foo/home.git ./
```

GitHubなどの公開リポジトリでドットファイルを公開している方々もいますが、ちょっと恐いですね。
私は色々と熟練するまでは止めて置きます。


## この記事のライセンス
[![クリエイティブ・コモンズ・ライセンス](https://i.creativecommons.org/l/by/4.0/88x31.png)](http://creativecommons.org/licenses/by/4.0/deed.ja)
この記事は[CC BY 4.0（クリエイティブ・コモンズ 表示 4.0 国際 ライセンス）](http://creativecommons.org/licenses/by/4.0/deed.ja)の元で公開します。
人類fish shell化計画

こんにちは、株式会社スマートドライブでフロントエンドエンジニアをしているオオキです。
今回は、僕のお気に入りのシェルである`fish`を紹介したいと思います。

## fish?
`fish`とはシェルの一種で`zsh`と同じようなものです。
https://fishshell.com/

インストールの方法とかは検索してみてください。
[zshからfish-shellへ体験入門](https://qiita.com/pfavill/items/354c246267b8ffd03bdf)
[fish shell を使いたい人生だった](https://dev.classmethod.jp/etc/fish-shell-life)

ドキュメントの全訳もあります。とても素晴らしい。
[全訳！fishシェル普及計画](http://fish.rubikitch.com/)

## fishのメリット
### 軽い
一番のメリットはこれ。とても軽いです。
具体的に比較したわけではないですが、起動時間は`zsh`の半分、いやもっと速いかもしれません。

### 設定ファイルがシンプル
`bash`と同じくらいシンプルな記述で`zsh`と同じくらい便利な機能を使うことができます。
履歴と補完機能が標準で搭載されているので、基本的な機能を使うだけであれば設定を追加しなくても良いかもしれません。

### プラグインマネージャーが優秀
fishでは[fisherman](https://github.com/fisherman/fisherman)というプラグインマネージャーを使います。
難しい設定やコマンドがなくシンプルでわかりやすいのが特徴です。
また、起動が早くfish自体の起動を邪魔することもありません。

### シンプルでクリーンなスクリプト構文
モダンな構文でシンプルに設定を記述することができます。

```zsh
set -x PATH $PATH /Users/hogehoge/.rbenv/shims
rbenv rehash >/dev/null ^&1
rbenv init - | source
```

### 日本語ドキュメントがある
[全訳！fishシェル普及計画](http://fish.rubikitch.com/)というドキュメントサイトがあり、すべて日本語で書かれています。
ドキュメントが日本語になっているというだけで、十分`fish`を使う理由になると思います。

### エラーがメッセージが親切
エラーの解消方法を具体的に示してくれます。これはとても素晴らしいことです。

# 結論
**fish shellを使いましょう。**
Homebrew で upgrade する時に cleanup してスッキリ

[Homebrew](https://brew.sh/) で気軽に `upgrade` していると、キャッシュとか過去のパッケージが残っていて気づいたら意外とディスク容量食っていたりしますよね。

```bash
brew upgrade --cleanup
```

コマンド一発で `upgrade` と `cleanup` 出来ます。
三種の OSM ベクトルタイルの比較

# OSM系ベクトルタイル3種のレイヤ構成比較
同じ OpenStreetMap のデータから生まれたバイナリベクトルタイルでも、その構成は異なります。今回は、以下の代表的なバイナリベクトルタイルの仕様を確認し、レイヤ構造を比較してみました。

1. [mapbox-streets-v7](https://www.mapbox.com/vector-tiles/mapbox-streets-v7/#layer-reference)
2. [OpenMapTiles](https://openmaptiles.org/schema/)
3. [Mapzen Vector Tile service](https://mapzen.com/documentation/vector-tiles/layers/)

# 構造の比較
|mapbox-streets-v7|OpenMapTiles|Mapzen Vector Tile Service|
--- | --- | ---
|(1)aeroway|(1)aeroway|-|
|(2)airport_label|-|-|
|(3)admin|(2)boundary|(1)boundaries|
|(4)barrier_line|-|-|
|(5)building|(3)building|(2)buildings|
|(6)country_label|-|-|
|-|-|(3)earth|
|(7)housenum_label|(4)housenumber|-|
|(8)landuse|(6)landuse|(4)landuse|
|(9)landuse_overlay|-|-|
|(10)marine_label|-|-|
|(11)motorway_junction|-|-|
|(12)mountain_peak_label|(7)mountain_peak|-|
|-|(8)park|-|
|(13)place_label|(9)place|(5)places|
|(14)poi_label|(10)poi|(6)pois|
|(15)rail_station_label|-|-|
|(16)road|-|(7)roads|
|(17)road_label|-|-|
|(18)state_label|-|-|
|-|-|(8)transit|
|-|(11)transportation|-|
|-|(12)transportation_name|-|
|(19)water|(13)water|(9)water|
|(20)water_label|(14)water_name|-|
|(21)waterway|(15)waterway|-|
|(22)waterway_label|-|-|
【PHPUnit】privateプロパティの値をテスト用に書き換えてテストする

そもそもprivateなもののテストを行うこと自体賛否両論あるらしいですけど、
テストは書いておいた方がいいような気がします。（小並感）
そういう場合は標準クラスの**ReflectionClass**を使用する方法があるらしいです。

- [PHP: リフレクション - Manual](http://jp2.php.net/manual/ja/book.reflection.php)

自分がよく遭遇するパターンとしては、**privateプロパティをテスト用の値に書き換えたい**とき。
例として以下に記します。
  

**例）**
**プロパティに設定してあるファイル名が正しい場合は** `TRUE` **、誤ってる場合は** `FALSE` **を返すメソッドのテストを行う場合**

- **Registerクラス**

```Register.php
<?php
class Register
{
    /**
    * 登録するファイル名
    * @see  __construct()
    */
    private $registerFile;

    public function __construct()
    {
        $this->registerFile = 'AAA.csv';
    }

    public function check()
    {
        if ($this->registerFile === 'AAA.csv') {
            return true;
        }

        return false;
    }
  
/** 略 **/
  
}

```

以下のような感じでprivateプロパティを上書きしてやればテストが可能みたいです。(PHPUnit)

- **RegisterTestクラス**


```RegisterTest.php
<?php

use App\Register;

class RegisterTest extends TestCase
{
    public function test_ファイル名が適切でない場合はFALSEが返ること()
    {
        // テスト対象のクラスをインスタンス化
        $register = new Register();

        // Reflectionクラスをインスタンス化
        $reflectionClass = new ReflectionClass($register);

        // プロパティの値を取得
        $property = $reflectionClass->getProperty('registerFile');

        // privateプロパティのアクセス範囲を設定（trueを指定でアクセスできるようになる）
        $property->setAccessible(true);

        // 取得したプロパティをテスト用に上書き
        $property->setValue($register, 'AAA_test.csv');

        // 上書きしたプロパティでテストを実行
        $this->assertFalse($register->check());
    }

}

```

  
### 参考
- [【PHP】リフレクションクラスでprivate変数、privateメソッドをテストする｜リスティング広告の運用代行ならカルテットコミュニケーションズ](https://quartet-communications.com/info/topics/15144)
- [PHPUnitでReflectionClassを使ったprotectedメソッドのテスト | チャットワーククリエーターズブログ](http://c-note.chatwork.com/post/105055836713/phpunit-reflection)
- [ReflectionClassについて調べる - 新人Webエンジニアの記録。](http://blog.fagai.net/2014/02/09/reflectionclass%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E8%AA%BF%E3%81%B9%E3%82%8B/)
環境変数に日時情報を取得する方法


; 年月日
SET YYYYMMDD=%date%

; 西暦
SET YYYY=%YYYYMMDD:~0,4%

; 月
SET MM=%YYYYMMDD:~5,2%

; 日
SET DD=%YYYYMMDD:~8,2%

; 時刻
SET HHMISS=%time: =0%

; 時(24時間)
SET HH=%HHMISS:~0,2%

; 分
SET MI=%HHMISS:~3,2%

; 秒
SET SS=%HHMISS:~6,2%
Rubyでスクレイピングをする際に調べたこと


##基本的なライブラリ
######Open-URI
        * http/ftpに簡単にアクセスするためのライブラリ
        * Kernel#openを定義
        * ファイルのopenと同様にURLを扱える
######Nokogiri（静的なものに限る）
        * HTML/XMLの構文解析器（パーサー）
        * ほぼデファクトスタンダード
        * XPath or CSSセレクタでHTML中の要素を選択
        * UTF-8以外の文字コードを扱う場合は注意
######Mecanize（動的・ステートフルなクローラ）
        * 対話型の為、ログインしてデータをクローリングするなどに使用出来るが、javascriptには対応していない。
##クローラーフレームワーク
######Anemone（静的・ステートレスなクローラ、イマイチ感あり）
        * Ruby製のフレームワーク
        * データ収集/解析/保存のすべての機能がある
        * 6年ほどメンテされていない
        * ScrapyのあるRubyが羨ましい今日このごろ
######Selenium（jsを使った動的なページの取得の際に使う）
        * ログインページへのログイン（http://iwathi3.hatenablog.com/entry/web_scraping_Ruby_Selenium）
        * Seleniumの弱点（https://qiita.com/justin999/items/55fbfd5d4f9fc8e5e77d）
            * 手軽だが遅い
            * ページを一回一回レンダリングするので時間がかかる。
                * Headress Chromeを使えばあまり関係ない？
            * ローカルで動かすのとサーバー上で動かすのに環境が違う
            * chrome driverのインストールが面倒
######Capybara（javascriptが必要なページのクローラ）+Selenium
        * 基本的にはUIテストツール
        * ブラウザを使うのでjsにも対応可能
        * スクレイピング部分はNokogirを使用
        * CapybaraをラッパーにしたMasqueというクローラー
        * ブラウザ代わりに、PhantomJSを使うのもあり
######cosmiccrawler
        * 並列処理を得意とするクローラー
        * 並列処理の実装は、EventMachine
        * EventMachineのめんどくさい処理を隠蔽してくれる
##補助的なライブラリ
######CocProxy
        * ほぼピュアRubyで実装されたプロキシサーバ
        * 開発用途でクローラー作成時に便利
        * 訪問済みサイトをキャッシュしてくれる
        * 訪問先サイトに無駄に負荷をかけずに試行錯誤できる


##参考：
https://www.slideshare.net/takurosasaki/ruby-crawler
【Unity】 アナリティクスのカスタムイベントを使ってみる

## はじめに
Analytics導入後の話になります
導入の仕方は、[ここ](https://docs.unity3d.com/jp/current/Manual/SettingUpProjectServices.html)とか[ここ](http://tsubakit1.hateblo.jp/entry/2015/10/31/232933)を参考にしてみてください

ユーザーの細かなデータが見られればバランス調整で便利です

## 使った環境
- unity 2017.1.1f1
- Analyticsセットアップ済み
- C#

## カスタムイベントを仕込んでみる

```C#:PlayerAnalyticsSender.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Analytics; //追加

namespace TestGame.Script
{
    /// <summary>
    /// 主人公のステータスを送信するクラス
    /// </summary>
    public class PlayerAnalyticsSender : MonoBehaviour
    {
        [SerializeField] Player _player //主人公のステータスを見るための参照
        
        private Dictionary<string, object> dictionary = new Dictionary<string, object>();

        /// <summary>
        /// 主人公のステータスを送信
        /// </summary>
        public void SendStatus() 
        {
            dictionary["Lv"] = _player.Lv;
            dictionary["HP"] = _player.Hp;
            dictionary["Attack"] = _player.Attack;
            dictionary["Defense"] = _player.Defense;
            dictionary["日本語もOK"] = "hogehoge"

            Analytics.CustomEvent("主人公のステータス", dictionary);
        }
    }
}
```

例として主人公のステータスを送信してみました
シーン内の適当なゲームオブジェクトにアタッチして、SendStatusをお好きなタイミングで呼ぶようにしておけば準備完了です

## 確認してみる
UnityEditorのメニューの 「window」→「Services」→「Analytics」
Build&Runして実機でゲームを実行すると「Validato」の項に
先程仕込んだカスタムイベントが表示されます（表示されるまでちょっと時間がかかります）

## グラフを確認する
UnityEditorのメニューの 「window」→「Services」→「Analytics」→「Go To Dashboard」
ブラウザが開いたら 「データエクスプローラ」→「+カスタムイベント」

ドロップダウンメニューのなかに送信したイベントがあるので
後はセグメントやパラメータをお好みで設定してください
（ない場合は集計が終わるまで待ってみてください 4~6時間ほどかかるそうです）

お疲れ様でした。
Rails s するとCould not find a JavaScript runtimeって怒られる問題

##問題

``rails s``すると下記のエラーが出てYou're on Railsできない。

```
Gem Load Error is: Could not find a JavaScript runtime. 
See https://github.com/rails/execjs for a list of available runtimes.
```

要するにJavaScriptのランタイムが無いよってことらしい。

##解決策

```:Gemifile
# gem 'therubyracer', platforms: :ruby
```

これのコメントアウトを外す。
もしくは何かしらのJsエンジンをインストールする。

## 解説
therubyracerはJavascriptのエンジンであるV8 JavaScript EngineをRubyから使えるようにするgem。
（更にそのままでは使えない環境の場合は、環境に合ったバイナリファイルを持ってきてくれるスグレモノ）
ただ既にnode.jsとかがインストールされている環境では不要なため、デフォルトではコメントアウトされているらしい。
Rubyでsleniumを使ったときにハマったところ

簡単に、ハマった箇所をまとめていく。

###■ リンクを新規タブで開きたい（target_blankではない）
```
@driver.action.send_keys(:command).click(element).perform
```

動作としてはactionクラスに動作を覚えさせながら、
「command + クリック」と同じ動作を実現させている。

###■ Action Chains（actionクラスを使って複数動作を実現する）
```
driver.action.send_keys(:command).click(element).perform
```

actionに対して、させたい動作を付け足していって、最後にperformで実行する。
これはactionクラスを使うと複数動作を実現できるもの。（shift押しながら〜とか、command押しながら〜とか）
設定するkeyは、MacやWindowsのキーボードに依存するみたい。

###■ 画面のハンドルの移動
```
window = driver.window_handles.last # 最後に開いたタブのwindowハンドルを取得
driver.switch_to.window(window) # windowのハンドルを切り替える
```

新規で開いたタブは開かれても操作自体は元の画面に残っている。
操作したい画面に対してハンドルを移してやる必要がある。

###■ 新規タブを閉じて元の画面にハンドルを戻す
```
driver.close
```

タブを閉じれば、元の画面に勝手にハンドルが戻る。（2タブしか開いていない場合）

###■ seleniumのelement情報

ページ遷移すると取得したelement情報は変わってしまうため、複数のelementを繰り返し使う場合は都度取得し直すか、処理するページを新規タブで開くなどしておく必要があった。
イーサリアムのブロック構造と合意するアルゴリズム

## ブロックデータ構造
- header: ヘッダー部
    - prevhash: 親ブロックのハッシュ値
    - ommers_hash: 競合が出ているブロックの情報を要約するハッシュ値
    - beneficiary: マイナーのアドレス（マイニングの報酬をもらうアドレス）
    - state_root: ステートのルートハッシュ値
    - transactions_root: ブロックに含めているトランザクションに対するルートハッシュ値
    - receipts_root: ???
    - logs_bloom: ???
    - difficulty: ブロックの難易度
    - number: このブロックの番号
    - gas_limit: ガスの制限値
    - gas_used: 実際使ったガス値
    - timestamp: タイムスタンプ
    - extra_data: 関連データ???
    - mixhash: nonce と組み合わせて、十分な量の計算を行ったことの証明
    - nonce: mixhash と組み合わせて、十分な量の計算を行ったことの証明
- transactions: トランザクションのリスト
- ommer_block_headers: 競合しているブロックのヘッダーのリスト

## チェーンの競合を解決する方法
- イーサリアムのブロック生成間隔が15秒ので、ビットコインの10分間と比べると、異なるマイナーが同時に新しいブロックを作成する確率が多くなってしまう
- 同時に複数のチェーンが出てしまう場合は、基本の方針はビットコインと同じく、「最も長いチェーンが正しいとみなす」ですが、この **最も長い** の定義は少し異なっている。
- ビットコインの場合単に、ブロックの数で判定されますが、イーサリアムはそうではなく、**最も計算量が蓄積された** ほうがメインチェーンとみなす
- ここでの計算量がそのチェーンだけではなく、そのチェーンから派生したチェーンの計算量も合計している。ここで使うために、競合しているブロックのヘッダーの関連情報を持っているわけ。

## 疑問
- [ ] `transactions_root` はデータ部のトランザクションリストから算出されているのは理解できていますが、`state_root`と`receipts_root`はどのデータから計算するだろう

## 参考記事
- [【図解】ブロックチェーンレベルでのイーサリアムの理解](https://zoom-blc.com/ethereum-blockchain)
[Azure Stream Analytics] TRY_CAST の利用

<br>Azure Stream Analytics のジョブを実行中、SQL Database への出力が行われず、以下のようにデータ型変換の警告が表示される場合があります。

<img width="50%" alt="cve11 (002).jpg" src="https://qiita-image-store.s3.amazonaws.com/0/163237/5583f272-1e8d-89b4-6605-c5a6aeb02257.jpeg"> ![cve10 (002).jpg](https://qiita-image-store.s3.amazonaws.com/0/163237/049ef61d-3fdf-2137-fea6-9f1afa9852d0.jpeg)

Warning の抜粋
_Encountered error trying to write 1 event(s): Cannot convert from property 'c2' of type 'System.String' to column 'c2' of type 'System.DateTime_
<br>

Azure Stream Analytics では、”Error Policy” が既定の “Retry” に設定されている場合、出力になんらかのエラーがでると、job をリトライし続けます。その結果、何度も入力のデータを参照することになり Input Events は上昇し、リソースの利用状況を表す SU % Utilization もそれに伴い上昇します。最終的にリソースを使い切り、ジョブが停止することがあります。

不正な入力データが発生しない対処を行うのが一番ですが、このデータ型変換エラーが発生するような入力が来た場合もエラーを回避し出力を行うために、以下のように Azure Stream Analytics のクエリに TRY_CAST の関数を追加する対応をとることができます。

TRY_CAST() を利用することで、CAST のエラーをハンドリングすることができます。TRY_CAST() では、キャストが成功した場合は指定されたデータ型にキャスト値を返します。それ以外の場合は NULL を返します。

（例）
<pre>SELECT
    c1,
    <b>TRY_CAST(c2 as datetime) as c2</b>
INTO
    [sqldbout]
FROM 
  [blobin]
</pre>
### + 参考情報
TRY_CAST (Azure Stream Analytics)
“https://msdn.microsoft.com/library/en-us/Mt643735.aspx”

##### 本内容は、2017年12月時点の情報です。
Microsoft SQL Server Japan Support Team blog で公開した内容をこちらでも紹介しています。
>https://blogs.msdn.microsoft.com/jpsql/2017/12/04/azure-stream-analytics-try_cast/
巨大なリポジトリを GitHub に移行した話

社内のサーバーにホスティングしていた巨大な Git リポジトリを GitHub に移行する機会があったので、そのときにやったことを備忘録代わりとして書きます。

## リポジトリの概要
ちょっと、巨大というと誇張しすぎですが、対象のリポジトリは以下のようになっています。

- Unity プロジェクト
- コミットの数は、9,000 弱
- リポジトリのサイズは 5 GB 程度
- プロジェクトの期間は 3 年ほど
- 所々 で 100 MB 超えのファイルがコミットされている
- 一部のアセットは既に GitHub のリポジトリとなっていて、 LFS で管理されている

## 要望
- このリポジトリを、ひとつの GitHub リポジトリとして統合したい
- また、そのときにアセット類は LFS で管理したい

この要望に対応するため、スクリプトを書いてゴニョゴニョします。

やるべきことは、以下の 2 点です。

1. 社内サーバーにホスティングされている Git リポジトリを GitHub に移行する
2. アセット類のリポジトリ統合する

## 社内サーバーにホスティングされている Git リポジトリを GitHub に移行する
通常であれば、社内サーバーのリポジトリをローカルにクローンして、リモートリポジトリとして GitHub を追加し、 Push で OK なのですが、100 MB 超えのファイルのコミットがあると GitHub が受け付けてくれず、 Push が失敗してしまいます。

そこで、伝家の宝刀 `git filter-branch` コマンドを使ってリポジトリの履歴を書き換えてしまいます。

### すべてのブランチをチェックアウトする
`master` と `develop` ブランチのみ、であれば単純なのですが、 `master-XXX` など、大量のブランチが残っていて、どのブランチが必要で、どのブランチが不要なのかが分からない。という状況だったので、とにかく全てのブランチをチェックアウトすることにしました。

以下のようなスクリプトを書いて実行します。

``` bash
#!/bin/bash

branches=$(git branch -r --no-merged | grep -v HEAD | sed -e "s/origin\///")

for branch in ${branches}; do
    echo ${branch}

    git checkout -b ${branch} origin/${branch}
done
```

### 過去のコミットに Git LFS を対応させる
過去のコミットのバイナリファイルなどを LFS で管理するために `git filter-branch` で履歴を書き換えていきます。
LFS 化するファイルの拡張子は予め決めておきます。

``` bash
#!/bin/bash

# LFS 化するファイル拡張子を列挙しておく
extensions='
png
jpg
mp3
'

# 列挙した拡張子からコマンドを作成する
tree_filter_command="git lfs track "
for extension in ${extensions}; do
    tree_filter_command=${tree_filter_command}\"*.${extension}\"" "
done

# git filter-branch を適用する
git filter-branch \
    --tree-filter "${tree_filter_command} >/dev/null" \
    --index-filter "rm .gitattributes" \
    --tag-name-filter cat -- \
    --all

```
このスクリプトを実行して、全てのブランチを書き換えていきます。
この処理に一晩くらいかかりました。

あとは、通常どおり、リモートブランチを切り替えて、プッシュすれば移行は完了です。

### リモートブランチを切り替える
``` bash
$ git remote remove origin
$ git remote add origin git@github.com:foo/bar.git
```

### プッシュ
``` bash
$ git push -u origin master
$ git push --all origin
```

### 掃除
最後にローカルリポジトリを掃除します。

``` bash
$ rm -rf .git/refs/original/
$ git reflog expire --expire=now --all
$ git gc --aggressive --prune=now
```

## アセット類のリポジトリを統合する

まずは、リソースのリモートリポジトリを登録します。

``` bash
$ git remote add resource git@github.com:foo/bar-resource.git
```

リソースの `master` ブランチをチェックアウト（名前は本流のブランチとは別にします）

``` bash
$ git fetch resource
$ git checkout -b feature/resource-master resource/master
```

リソースのブランチを本流のブランチにマージします。
この時、 `--allow-unrelated-histories` を付けることで別のリポジトリを統合することができます。
いきなり `master` にマージするのは怖いので `feature/merge-resource` というマージ用のブランチを用意して作業しました。

``` bash
$ git checkout master
$ git checkout -b feature/merge-resource
$ git merge --allow-unrelated-histories feature/resource-master
```

最後にリソースディレクトリの移動などを行って完了です。

## まとめ
- 履歴の書き換えには、 `git filter-branch` を使う
- 別のリポジトリを統合するには、 `--allow-unrelated-histories` を使う

Git はローカルで作業して失敗してもリモートには影響がないので、こういった作業も比較的気軽に行えて便利ですね。
openmaptiles を使うための細かなノウハウ

planet.osm.gz 形式のデータおよび Natural Earth のデータからバイナリベクトルタイルを生産するツールである [OpenMapTiles](https://github.com/openmaptiles/openmaptiles) を使うにあたっての細かなノウハウを紹介します。

# gh:openmaptiles/openmaptiles との付き合い方
このソフトウェアの一番大きな特徴は、バイナリベクトルタイルを作成するための既存・新規の様々なツールを Docker (docker-compose) を使って構成管理しているところですね。このおかげで、かなり複雑な生産体系を数コマンドで新規環境に移すことができます。これが、最も大きな強みかと思います。

他方で、Docker の技術は動いてきていることと、gh:openmaptiles/openmaptiles の構成がやや特殊なことから、お使いになる環境に合わせる作業が必要になることが多いです。

このソフトを使うにあたっての考え方は、次のようになると私は思います。

1. 環境と合わせ込むために、いくら泥臭い設定をしてでも、まずは何とか動かすことができるようにすることを追求する。
2. 使い方が安定してきたら、それに安住せず、gh:openmaptiles/openmaptiles の進展に追従できるように、github レポジトリそのままの内容から最小の変更で動かすことができるようにする。

泥臭い設定をすることによって、Docker の仕組みを学ぶことができますし、その作業は無駄にはならないと信じて quickstart.sh や Makefile、.env をいじっていくことが必要です。どうしてもうまく動かない場合には、もしかすると違う OS 環境で試してみるのも良いかもしれません。別の OS 環境で得た知見が、もとのターゲット OS での設定に役立つかもしれません。

# gh:openmaptiles/openmaptiles の技術的特殊さ
gh:openmaptiles/openmaptiles を使うにあたって技術的な難しさが発生する要因を知っておくことは、それぞれの環境で解決をお考えになるにあたって役に立つかもしれません。私は、次の２点が要因であると思います。

1. データを扱うためのボリューム（ストレージ）について、Docker が古くから使っているが、必ずしも環境によっては安定していない[バインドマウント](https://docs.docker.com/engine/admin/volumes/bind-mounts/)によって確保している。
2. ホスト側で make や gawk, bc などの基礎的なツールを実行するように組んである。

これらの要因が、それぞれのホスト環境で問題を起こします。
# Windows 7 の場合
Windows 7 の場合、Docker も virtualization 環境前提の新しい実装ではなく、VirtualBox を用いる [Docker Toolbox on Windows](https://docs.docker.com/toolbox/toolbox_install_windows/) を使うことになります。この場合、難しさの本質は次の２点になります。

1. ボリュームのバインドマウントのためのパスの指定が、VirtualBox 上のホスト（docker-machine）からの指定になる。加えて、Windows 7 上で docker を扱うために用意されている MINGW が、パス指定を調整してしまうことがある。これをキャンセルするために、パスの最初の / を // と書くことが有効である場合がある。

2. make は MINGW に用意されていない。

私の場合には、quickstart.sh から本質的に重要なところを抜き出し、make を呼んでいるところをコマンド直書きに展開したシェルスクリプトファイル openmaptiles.sh を作成し、バインドマウントされているフォルダを [ボリューム](https://docs.docker.com/engine/admin/volumes/volumes/) によって差し替えることによって、動かすことができるようにしました。

ただし、この方法だと必ずしも最新の gh:openmaptiles/openmaptiles に追従するのに便利ではないので、gh:openmaptiles/openmaptiles を呼び出すための兄弟 docker container を用意する方法に移ることができないかと悩んでいます。

# macOS の場合
macOS はより UNIX ベースなので、比較的困難は少ないと思っています。私は現在、ポータビリティを確保するために、homebrew なしで動かす方法を確立しようと思っていて、ここでもボリュームの扱いで悩んだりしています。

いずれも、より洗練された方法を確立できれば、あらためて共有したいと考えています。
新米パパママ向けIoTハンズオンを設計した話

[ヴァル研究所 Advent Calendar 2017](https://qiita.com/advent-calendar/2017/val)の7日目は、下記のIoTハンズオンを設計したときの裏話を書こうと思います。

>IoTで母乳育児？ MESHボタンで授乳をカウント＆シェアするイベントレポート
https://comodo.life/everyday/article-374.html

##忙しい方向け[今北産業](http://dic.nicovideo.jp/a/%E4%BB%8A%E5%8C%97%E7%94%A3%E6%A5%AD) 
- LINEとIFTTTの認証時には「LINEに設定してあるメールアドレスとパスワード」が必要
- 日常的には必要性が無いためか、LINEユーザーの3割(体感値です)はメールアドレスを設定していない
- LINEを使うハンズオンの参加者には「メールアドレスは設定してあるか？」「パスワードは覚えているか？」を事前に確認すること

##きっかけ
[昨年のアドベントカレンダー](https://qiita.com/advent-calendar/2016/val)に書いたような一連の活動で、何故か社内の一部で「MESHとIFTTTに詳しい人」のイメージが付いていました。
そんな折で、とあるクライアントより「IoTハンズオンイベントを企画したい」との依頼が舞い込み、ハンズオンの設計、ファシリテーター(進行役)を担当することになりました。

まず設計としてやったことは下記の2つでした。

- クライアントの考える「IoTでやりたい事」をどうやって実現するかという**IoTの仕組みの設計**
- エンジニアではない「一般的なリテラシー」の参加者でもできる**IoTハンズオンイベントの設計**


##IoTの仕組みの設計
クライアントは「パパの授乳」を促進するきっかけとしてIoTを活用したいと考えていました。

必要なのは、

- パパ、ママお互いの授乳の様子（授乳したこと)が離れていても分かる**「コミュニケーション手段としてのIoT」**
- 10日間のチャレンジ期間中、各家庭での状況が分かるようにする**「可視化手段としてのIoT」**

と考えたので、MESHの「ボタンタグ」を使って

- 1回押すと「ママが授乳したよ」という内容のLINEメッセージをパパママお互いのスマホに送信
- カチカチと2回押すと「パパが授乳してくれたよ。ありがとう」という内容のLINEメッセージをパパママお互いのスマホに送信＆Google Drive上のデータベースにも記録
- データベースに記録された「パパが授乳した回数」は特設サイトで各家庭ごとに可視化される

という仕組みを考えました。
メッセージの送信先はいろいろと選択肢があったのですが、

- パパが仕事で不在でもメッセージを受け取れる(MESHからの通知を受けられるのはBluetoothの届く範囲内のみ)
- このメッセージのやりとりを専用グループに送ることにすれば、あとからタイムラインを遡って振り返ったりできる
- 普段から夫婦がコミュニケーションに使っているツールをそのまま使える方がいい

などの観点からLINEメッセージを使うことにしました(この選択が後の悲劇を招くのですがｗ)

![alt](https://comodo.life/rsc/ID374/04.png)
※画像はイベントレポートより拝借

![1.Google Driveタグを配置、ボタンタグと線でつなぐ.png](https://qiita-image-store.s3.amazonaws.com/0/152460/a706c5e3-2de9-8e50-1c8d-97e164a12327.png)
※MESHアプリ上ではこのような構成に

##IoTハンズオンイベントの設計
ハンズオン前に最も警戒していたのは「リテラシーの差によって各参加者間の足並みが揃わないこと」だったので、対策として手順を一つ一つ解説しながら進めて進行側で作業ペースをコントロールすることを考えました。

スクショを撮っては貼り撮っては貼りで全ての手順を載せた資料は50ページ超にもなり、リハーサルも実施して準備は万全かに見えました。

<img width="500" alt="スクリーンショット_2017-12-04_17_49_49.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/152460/54a6ab80-e25e-e749-ba28-0306be4ca250.jpeg">
※手順を一つ一つキャプチャして進行資料を作成

##ハンズオン当日に潜む悪魔
[当日のイベントレポート](https://comodo.life/everyday/article-374.html)には和気あいあいと進めた様子が書かれていますが実際はかなり大変でした。

一番問題になったのは**「LINEとIFTTTの認証に手間取る参加者が出たこと」**で、この認証時にLINEに紐付けたメールアドレスとパスワードでログインすることが必要だったのですがここが盲点でした。

LINEアカウントにメールアドレスを紐付けている参加者ばかりではなかったことと、LINEを利用する中ではほとんど使わないためかパスワードを覚えてない参加者がいた事で、進行に大きな影響が出てしまいました。

![Screenshot_2017-12-04-16-21-21.jpg](https://qiita-image-store.s3.amazonaws.com/0/152460/bc80a5eb-7369-cd62-0570-577966fa7aa7.jpeg)
※メールアドレスとパスワードの設定がないとここで詰みます

確かに、LINEは電話番号やSNS連携で利用登録ができるため、機種変更時にアカウントを引き継ぐ目的以外ではメールアドレスを設定する必要性はないので、LINEを使ったハンズオン参加者にはメールアドレス設定を事前にお願いしておく必要がありそうです。

##まとめ
- LINEユーザーはメルアドとパスワードを設定しているものだと思いこんでいたせいで、イベント当日に詰みました
- 「ノンプログラミングで誰でもできる」というツールの場合でも、前提がエンジニア目線であることに意外と気付けない
- エンジニアではないユーザーの参加するハンズオンは、前提が合ってないことがあるので特に気をつけよう
ngx_mrubyの裏(不人気)機能(1)

ngx_mrubyには実は裏機能があります。

```nginx
location ~ \.rb$ {
    mruby_add_handler on;
}
```

こんな風にかくと、アクセスのあったRubyスクリプトがmruby上で実行されて、レスポンスを返します。レスポンスデータは、

```ruby
Nginx.rputs "fuga"
Nginx.echo "hoge"
```

あたりで作ると良いでしょう。これで、mrubyでWebアプリが書けるよ！
【Laravel】DB登録値取得時のfind()、get()、first()の返り値早見表

よく忘れるのでメモ

# find()

`App\Model::find(1)` の返り値は**Modelのオブジェクト**
  
# get()

`App\Model::where('id',1)->get()` の返り値は**Collectionクラス**
（中身はModelのオブジェクト。ゆえに`foreach()`で回せば各々の値を取得できる。）
  
# first()

`App\Model::where('id',1)->first()` の返り値は**Modelのオブジェクト**
  
※もしなかった場合は`NULL`を返す

以下[tinker](https://github.com/laravel/tinker)(laravel用REPL)で実行した際の様子


```
$ php artisan tinker
New version is available (current: v0.8.14, latest: v0.8.15)
>>> App\Model::find(1)
=> App\Model{#458
     id: 1,
     name: "モデル1",
     created_at: "2017-11-30 07:32:29",
     updated_at: "2017-11-30 07:32:29",
   }

>>> App\Model::where('id',1)->get()
=> Illuminate\Database\Eloquent\Collection {#449
     all: [
       App\Model{#448
         id: 1,
         name: "モデル1",
         created_at: "2017-11-30 07:32:29",
         updated_at: "2017-11-30 07:32:29",
       },
     ],
   }

>>> App\Model::where('id',1)->first()
=> App\Model{#470
     id: 1,
     name: "モデル1",
     created_at: "2017-11-30 07:32:29",
     updated_at: "2017-11-30 07:32:29",
   }

>>>

```

# ちなみに：where()

ちなみに

`App\Model::where('id',1) `の返り値は**Builderクラス**

```
>>> App\Model::where('id',1)
=> Illuminate\Database\Eloquent\Builder {#462}
>>>

```

# そんで：all()

そんで`App\Model::all()` の返り値は**Collectionクラス**

```
>>> App\Model::all()
=> Illuminate\Database\Eloquent\Collection
```
  
  
# もっとくわしく
- [Namespaces | Laravel API](https://laravel.com/api/5.4/index.html)

# おわり

以下もどうぞ

- [【Laravel】Laravelでよく使うroute()とview()とredirect()まとめ](https://qiita.com/sola-msr/items/4f92686d474118d1cceb)
- [【Laravel】わりとよく使うArtisanコマンド集](https://qiita.com/sola-msr/items/a09b857c5e7f7c88d01d)
- [【Laravel】Viewのbladeの書き方](https://qiita.com/sola-msr/items/a128f4e0900f3541690c)
ハッカソン初心者に贈る、少しでも受賞に近づくポイント3つ。

#普通に社会人してるとなかなか社外実績が作れないという事実
根っからの社畜サラリーマンほさかです。
普段は地域活性事業部というところで仕事をしてるんですが
毎日のルーティン作業してても、なかなか査定が上がらない（当たり前＆下世話）
クックパッドも転職面談の時に社外活動内容が聞かれるらしい、このご時世です。
社外実績作るの大切！

まずは<b>「ハッカソンに出てみよう」</b>

ということで昇進もしたいし社外で何かしら実績を残せないかな〜と思っていた矢先の
のびすけさんの投稿↓に釣られました。

![スクリーンショット 2017-12-04 17.44.03.png](https://qiita-image-store.s3.amazonaws.com/0/112144/6ea95834-8cba-ac0e-34db-05cb159ea57f.png)

うん、テーマも地域活性ですし。なんか実績になりそう。

#人は見た目が８割ならぬ、ハッカソンは事前準備が８割。
今回の<a href="https://connpass.com/event/67436/" target="_blank">ハッカソン</a>は<a href="https://resas.go.jp" target="_blank">RESAS</a>という地域情報が見れるシステムとIoT縛り。

当日まで1ヶ月ぐらい時間があったのでプランナーでエントリーしてましたが
せめてフロントでなんか下準備して行こうと思いbootstrap触ってました。
最終的にハッカソンでは使わなかったけど…。

今回のハッカソンは個人応募の方が多く、チームで参加したのはうちのチームだけだったのですがチームビルディングで各自何ができるかを明確にしておくとアイデア出てからスムーズに作業に取り掛かることができ作業が早かったです。
多分、これは個人で参加した際にも応用できそうなハッカソン知識ですね。

ここでの学び

<b>⑴チームビルディングまじ大事</b>
・チームリーダー・・・ちょっと抜けててもいいから愛される人がいい。空中分解を避けるためにも。
・エンジニア・・・今回の場合要件定義と書くのは別でした。みんなかけたら進みが早いかも。
・プランナー・・・金とかニーズ（市場調査）とか、資料作成とか。システムのことわかると話が早いなと自分では感じました。わからないと無理なこと言いがち。

<b>⑵時間の有限さを知る</b>
小タイトルが哲学的ですが…。
ついやりがちな「あれこれやりたくなっちゃう病」を最初から排除するのは大切だと思いました。時間の制限を決めていたからかパートを三つぐらいに分けて、追加開発、追加開発で最後までたどり着いた感じです。

<b>⑶なるべく事前準備をする</b>
今回はテーマがあらかじめ発表されていたので課題になりそうなことの情報収集をできたのは大きかった気がします。ゼロベースで情報収集して、開発して資料作ってってなると厳しいですし、ハッカソンをやってる途中でアイデアの方向性が変わったりすることがないように確たる根拠のある情報を提示してアイデア固めておくと完成に近づく気がします。

#あとは粛々と進めるだけ
当日はもうずっと作業でした。
個人的に作業用BGMはamazonmusicがオススメです、垂れ流しで作業できました。

ということで作ったプロダクトがこちら↓

![23772427_1677587378971010_1919458144_n.jpg](https://qiita-image-store.s3.amazonaws.com/0/112144/83b3ce5e-3909-4304-2655-664763c04c7c.jpeg)

LINEbeaconを利用した「駅構内の出口案内」です。
ユーザーは駅ホームに降り立った瞬間にLINEからプッシュで通知がきます。
行き先をLINEに記入すると、最寄出口までの案内をしてくれるというものです。

ビジネスモデルとしては出口付近に関する広告を入れたり、その周辺領域の広告モデルで収益化しましょうというイメージです。

英語・日本語音声でインバウンドと障害を持つ人向けのプロダクト。
仕様も載せたいのですが、コンテストがあるので企業秘密としてます、ごめんなさい。

<b><font size="7" color="red">結果、狙っていた賞を頂戴しました！</font></b>

![23760225_1675876972475384_815895693_o.jpg](https://qiita-image-store.s3.amazonaws.com/0/112144/1894b880-3161-93d7-dd1a-2cf393045891.jpeg)

初ハッカソンでしたが、結果として社外活動の実績値も上がりいい学びになりました、今度LINEさんでランチしてきます〜、楽しみ！
Goで「決定的なサブセット選択」を実装してみた。

SRE本によれば、Googleはデータセンター内のロードバランシングに「決定的なサブセット選択」アルゴリズムを採用しているとのこと。

疑似コードが載っていたので、これをGoで実装してみました。

```go
package main

import (
	"fmt"
	"math/rand"
	"reflect"
)

type Backend struct {
	ID int
}

type Client struct {
	ID int
}

func Subset(backends []Backend, clientID int, subsetSize int) []Backend {
	subsetCount := len(backends) / subsetSize

	round := clientID / subsetCount
	rand.Seed(int64(round))
	shuffled := Shuffle(backends, round)

	subsetID := clientID % subsetCount
	start := subsetID * subsetSize

	return shuffled[start : start+subsetSize]
}

func Shuffle(backends []Backend, round int) []Backend {
	shuffled := make([]Backend, len(backends))
	copy(shuffled, backends)

	for i := 0; i < len(shuffled); i++ {
		j := rand.Intn(i + 1)
		shuffled[i], shuffled[j] = shuffled[j], shuffled[i]
	}

	return shuffled
}

func main() {
	backendSize := 300
	clientSize := 300
	subsetSize := 10

	backends := []Backend{}
	for i := 0; i < backendSize; i++ {
		backends = append(backends, Backend{ID: i})
	}

	clients := []Client{}
	for i := 0; i < clientSize; i++ {
		clients = append(clients, Client{ID: i})
	}

	selected := [][]Backend{}
	for _, c := range clients {
		s := Subset(backends, c.ID, subsetSize)
		selected = append(selected, s)
	}

	// display
	for i, b := range selected {
		fmt.Printf("ClientID:%d -> %v\n", i, b)
	}

	// check dup
	for i := 0; i < len(selected); i++ {
		for j := 0; j < len(selected); j++ {
			if i == j {
				continue
			}

			if reflect.DeepEqual(selected[i], selected[j]) {
				fmt.Println("error")
				fmt.Println(selected[i])
				fmt.Println(selected[j])
			}
		}
	}

	// count by backendID
	flat := []Backend{}
	for _, b := range selected {
		flat = append(flat, b...)
	}

	stats := make(map[int]int)
	for _, backend := range flat {
		stats[backend.ID] = stats[backend.ID] + 1
	}

	for i, count := range stats {
		if count == subsetSize {
			continue
		}
		fmt.Println(stats[i])
	}
}
```

300台のクライアントが、300個のバックエンドサーバから10個を選択する場合、[このようになります](https://go.dev/play/p/6CaCYh0lr8)

一見ランダムに選択されているように見えますが、各バックエンドは正確に10回のみ選択されていることがわかります。
ランダムにバックエンドサーバを選択するアルゴリズムでは、このように均一にならず偏りが生じます。

アルゴリズムの詳細はSRE本のChapter20を参照してください。

## 参考
 1. [Site Reliability Engineering](https://landing.google.com/sre/book.html) Chapter20 Load Balancing in the Datacenter
Rails Girls Tokyoにスポンサーをしてみて

過去３回、スポンサーとして参加させていただいた感想を書いてみたいと思います。

http://railsgirls.com/tokyo-2015-09-12.html

http://railsgirls.com/tokyo-2016-07-23

http://railsgirls.com/tokyo-2017-03-25.html

# 感想その１
会場が毎回キレイ（COOKPADさんとか）

# 感想その２
オーガナイザーやコーチの人がとても親切で話しやすい

# 感想その３
運営がちゃんと設計されている（参加者とスポンサー両方に目が向いている）

# 感想その４
懇親会メニューが豪華（特にお酒のラインナップが良い。運営にお酒好きが多いから？）

# 感想その５
これら諸々が理由で、結果的に現場の雰囲気が良い

# 感想その６
スポンサー的にはお得（高くないスポンサー費用でLTさせてくれて懇親会まで参加させてくれる）

# 感想その７
これら諸々の理由で、スポンサー的には継続的に参加したくなる

# まとめ
**なので、どんどん参加しようー！**


・・・全くテッキーなこと書いてないですが、以上です。

これからもさらに活発に開催されることを期待しております。