OmniAICreator/Qiita-1.07M huggingface dataset:
CData Data Sync

#CData Data Sync とは

CData Data Sync シリーズは、Salesforce、Dynamics CRM、SharePoint などのクラウド上の業務アプリケーションデータのレプリケーション（複製）をローカル DB およびクラウド DB に簡単に作成するサーバー製品です。
![00.png](https://qiita-image-store.s3.amazonaws.com/0/123181/8a708872-c771-00ae-a49f-1e03ee383375.png)

#利用シーン

CData Data Syncは次のようなシーンで利用すると便利です。

- オンプレミスの RDB にレプリケーションを作成して、定期的な帳票作成を実行。
- 通信でのパフォーマンス低下を気にせずに BI ツールやアナリティクスツールでデータ分析を実施。複雑なデータ加工を行ったりシナリオ分析を行ってもクラウドアプリケーションの本物のデータを誤って改ざんしたりするおそれがありません。
- データ処理をレプリケーション DB に対して行うことによりデータ通信量の低減とパフォーマンスの向上を実現。
- ディザスタリカバリ目的でのデータアーカイブ。

#CData Data Sync の機能

CData Data Sync は、エンタープライズ利用のための充実した機能を備えています。

- 幅広いデータソース対応（今後もラインアップ拡充予定）
第一弾のリリースでデータソースとして対応するサービスは、Salesforce、MicrosoftDynamics CRM、SharePoint、NetSuite（英語版）、SugarCRM（英語版）、Zoho CRM
（英語版）、Oracle Eloqua（英語版）、HubSpot（英語版）です。これらのサービスのレプリケーションデータベースをローカルおよびクラウド DB に作成できます。
- 豊富なレプリケーション先データベース
- エンタープライズエンジニアの扱い慣れた Oracle、MySQL、SQL Server、DB2、PostgreSQL、Amazon Redshift、Access、Cloud SQL、SQLite、SQL Azure をレプリケーション先に設定することが可能です。
- Windows 版と Cross-Platform Unix/Linux/Mac 版の 2 種類を準備。
- インクリメンタル（差分）アップデートでデータ通信量を低減。
- Point-and-click で簡単に設定、管理が可能。

#CData Data Sync の使い方 (Salesforce Data Sync)

1. 製品を[ダウンロード](http://www.cdata.com/jp/download/?f=sync)して、インストーラーに従いインストールを行います。
2. インストールされた製品を開き、［接続］タブからデータソースとなるサービスへの認証情報を入力し、接続を確立します。
![02.png](https://qiita-image-store.s3.amazonaws.com/0/123181/0e924e42-ae85-828e-d219-a61a007fa962.png)
3. 次に［データベース］タブから、レプリケーションしたデータを保管するデータベースを指定し、接続情報を設定します。この例では MySQL を設定します。
![03.png](https://qiita-image-store.s3.amazonaws.com/0/123181/d18b4322-c064-33df-e69b-9453d496418f.png)
4. ［スケジューラー］タブや［通知］タブで、レプリケーションサイクルや通知の設定を行います。
![04.png](https://qiita-image-store.s3.amazonaws.com/0/123181/2b17b3c2-ca6c-7d73-ea31-7b2c63eca897.png)
5. ［テーブルを追加］ボタンをクリックして、レプリケーションするテーブルを指定して変更を保存します。
![05.png](https://qiita-image-store.s3.amazonaws.com/0/123181/f719ab2d-f76c-3c6e-abbf-5a2bb432c0d2.png)
6. ［実行］ボタンをクリックして、クラウドサービスのレプリケーションデータベースを作成します。
7. 設定した MySQL に Salesforce データがレプリケーションされました。
![06.png](https://qiita-image-store.s3.amazonaws.com/0/123181/49d58dbe-f01b-d7d8-7ad9-484d325ef8aa.png)
ファイルのPOSTに立ちはだかる壁（PHP編）

PHPでファイルアップロードを行うこともありますが、あちこちの設定が「扱えるファイルの最大サイズ」に影響するので、抜けや漏れが発生しやすいかもしれません。

## 第一の壁 HTTPサーバ

まず、POSTリクエストはHTTPサーバに届きますが、このHTTPサーバの段階で「最大のリクエストサイズ」や「最大のPOSTサイズ」で容量を制限してあることがあります。

Apacheでは[デフォルト無制限](http://httpd.apache.org/docs/2.4/mod/core.html#limitrequestbody)なので、意図して設定していない限り問題にはなりませんが、nginxの場合はもともと「静的ファイルの配信」を意図して作られていた加減か、[最大1MBというかなり低めの設定](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size)がデフォルトになっています。PHP側をいくら設定しても、nginxで設定した場合には**PHPまで大きなデータが届かない**ので、注意が必要です。

## 第二の壁 PHPの最大POSTサイズ

そして、PHP側でも`post_max_size`として、POST可能なデータ量の最大値が決まっています。これは[デフォルトで8MB](http://php.net/manual/ja/ini.core.php#ini.post-max-size)という値になっていますので、本格的にファイルアップロードを運用するなら設定は必要です。なお、性質上`ini_set`での設定はできず、`php.ini`や`.htaccess`などで切り替える必要があります。

## 第三の壁 アップロードの最大ファイルサイズ
さらに、POSTでファイルを送る場合、1ファイルあたりの最大サイズも決まっています（[`upload_max_filesize`](http://php.net/manual/ja/ini.core.php#ini.upload-max-filesize)）。デフォルトが2MBなので、少し大きな画像でも超えてしまうレベルの設定となっています。これまた（PHPプログラムが動く前に走るものなので）`ini_set`は使えません。

また、「一度に受け取れるファイルの数」にも制限がありますが、デフォルトで20個となっているので、実用上問題となることはあまりないと思います。

## 第四の壁 最大メモリ容量

ここまででファイルのデータは通るようになりますが、それを「受け取った後」の処理も問題となります。具体的には、普通の処理をしていると、POSTデータをメモリに乗っける必要が出てくるということです。`memory_limit`はプログラムで調整もできますが、POSTデータが大きすぎる場合**ini_setに辿り着く前にメモリ不足で落ちてしまう**ので、`php.ini`などで設定しておく必要があります。
FileMaker API for PHP のドキュメントのまとめ

# FileMaker API for PHP
「FileMaker API for PHP」とは、PHP を用いて FileMaker のデータを扱うための仕組みです[^1]。「FileMaker Server」が必須ですが、この仕組みがあれば、極端な話、FileMaker のクライアント（「FileMaker Pro」など）を用いなくてもデータベースを操作することができます。

# 「カスタム Web 公開 with PHP」と「カスタム Web 公開 with XML」
「FileMaker API for PHP」は、「カスタム Web 公開 with PHP」という機能を用いています。FileMaker Server では、「カスタム Web 公開 with PHP」以外にも「カスタム Web 公開 with XML」という機能があり、どちらも http(s) 経由のアクセスによりデータベースを操作できます。詳しくは次項のドキュメントをご覧ください。

# 公式ドキュメント
「FileMaker API for PHP」の公式ドキュメント（というか説明）は以下のとおりです。

- [PHP Web 公開 | FileMaker](http://www.filemaker.com/jp/support/technologies/php.html)

公式ドキュメントに値するものは以下の PDF です（FileMaker Server 15 版）。「FileMaker API for PHP」だけでなく「カスタム Web 公開 with XML」についての詳しい記述もあります。必読です。

- [カスタム Web 公開ガイド（PDF ファイル）](https://fmhelp.filemaker.com/docs/15/ja/fms15_cwp_guide.pdf)

クラスやメソッドに関するドキュメントは以下のローカルの場所にあります。

- `\Program Files\FileMaker\FileMaker Server\Documentation\PHP API Documentation`

# 非公式ドキュメント

### マイナビニュース
非公式の「FileMaker API for PHP」のドキュメントとしては何といっても「マイナビニュース」の以下のサイトが有名でしょう。

- [FileMaker×PHPで作る、簡単・便利なWebアプリ | コラム | マイナビニュース](http://news.mynavi.jp/column/fmxphp/)

メソッドの中身をソースコードから解説したりしていて、手を動かしながら回を進めて読んでいけば、基本的な操作から発展的な操作まで問題なくできることでしょう[^2]。

「第1回」が書かれたのは実に7年以上前（2009/02/18）ですが、未だにこのサイトの内容は普遍的に通用します。書籍で言えば全部入りの分厚い解説書タイプであり、辞書的に用いるのにも有用でしょう。

### 「FX.php と FileMaker API for PHP」
もう一つ、非公式の個人ブログとして以下を挙げないわけにはいかないでしょう。

- [FX.php と FileMaker API for PHP - Yahoo!ブログ](http://blogs.yahoo.co.jp/nao_r1)

こちらは具体的な実装コードが豊富で[^3]、特定の操作がしたい際に特に参考になるのではないでしょうか。

### CodeZine
CodeZine にも少しだけ記事があります。ただ、いずれも基礎的な内容であり、上記の2つのサイトでまかなえる内容ではあります。

- [FileMaker API for PHPの利用連載一覧：CodeZine（コードジン）](https://codezine.jp/article/corner/70)

- [PHPとFileMaker ProによるWebアプリケーション構築（基礎編） (1/4)：CodeZine（コードジン）](https://codezine.jp/article/detail/5035)

- [PHPとFileMaker ProによるWebアプリケーション構築（実装編） (1/5)：CodeZine（コードジン）](https://codezine.jp/article/detail/5051)

後者2つの記事は[「『ITエンジニアのためのFileMaker講座』連載一覧」](https://codezine.jp/article/corner/263)という連載記事の中の一部の記事です。この連載記事は FileMaker 自体の理解に役立つので読んでみるのもいいでしょう。

[^1]: PHP ということで Web ブラウザ経由（Web アプリケーションなど）の操作を想像するかもしれませんが、コマンドラインからでももちろん処理できます
[^2]: 全部で116回ありますが……
[^3]: ただし Yahoo!ブログの仕様上、インデントなどが無く、大変読みづらいです
エバンジェリストの役割について考える

#エバンジェリストって？
##定義
エバンジェリスト(Evangelist)とは、キリスト教における伝道者のこと。エヴァンジェリスト、エヴァンゲリストとも。
ドイツの神学者ルターは、自らを福音主義者(エヴァンゲリストevagelist)と呼び、イエスの教えに回帰することを説いた。
また、IT業界では、技術的話題を社内外に解りやすく説明・布教する使命を持つ「テクニカルエヴァンジェリスト」という職業も存在している。

テクノロジー・エバンジェリスト（英: Technology evangelist）または テクニカル・エバンジェリスト（英: Technical evangelist）は、工業規格としてネットワーク外部性の存在する市場において、特定技術のサポートのクリティカル・マスを築こうとする人物を言う。エヴァンジェリストとは、宗教用語で伝道師のこと。
プロのテクノロジー・エバンジェリストの多くは、自らの専有技術をデファクトスタンダードとして確立するか、所有権の保持されていないオープン標準を確立しようとする企業によって雇用されている。ノンプロのテクノロジー・エバンジェリストは利他主義または利己心（例えば、ネットワーク外部性における早期参入の利益を得るために）から行動する例が多い。
（Wikipediaiより）

#どんなことやってる？
##概略
ある特定の、高度で複雑なIT環境やテクノロジーをユーザーに向けて分かりやすく解説し、啓蒙を図るのが主な任務である。

##登壇
システム開発者などITエンジニアを対象に開催される社内外のイベント等にて、製品・サービスのプレゼンテーションを行うことが多い。下記に上げる活動により、しばしばメディアへの露出も増え、技術者として開発のプロジェクトを現場で回している人から見ると、やや派手に映りがちである。

##書籍
自身の担当技術領域や担当製品・サービスの内容について、執筆活動を行う。

##Blog
技術情報発信や、ユーザーサイドとのコミュニケーションを強化するため、Blogやコミュニティサイトを自身で立ち上げたり、またはそのコミュニティにおいて中核を担うことも多い。

##イベント支援
ハッカソンでの技術サポート、チューターとしての活動、大規模セミナー／カンファレンス等での技術サポーターとして、イベントの支援などを行う。

#それって何のためだっけ？
前述の通り「ある特定の、高度で複雑なIT環境やテクノロジーをユーザーに向けて分かりやすく解説し、啓蒙を図る」のが目的なので、ともするとパブリックで派手な活動ばかりが目立ちがちなエバンジェリストは、実は見えないところではもっと地味なそして堅実な営業に極めて近い活動をしていることも多い。

#ステークホルダーとのつながり強化
いかにして、自身が担当する技術領域や、製品・サービスにおいて自分が技術サポートの中心となりその対象技術を「広めていく」「売れるようにする」かが大変重要な役割であると考える。
そのためには、営業セクションと密に連携し、各技術者または技術会社にその技術・製品・サービスを使ってもらうよう、プリセールスという位置づけで日々奔走している。

#経営者は昔からやっていること
実は、派手で特殊で楽しそうに見えるエバンジェリズム活動は、昔から個人事業主、スタートアップ企業の創業者、ベンチャー経営者などは、エバンジェリストという言葉・ロールなど意識せずに日々行っていることである。（自社の技術・製品・サービスを売りたい、啓蒙したいのだから当然であろう）

#まとめ
なんとなく流行り言葉になってしまった感のあるエバンジェリストという言葉に振り回されないでほしい。
自分が担当する技術・製品・サービスを広めたい、売りたい、使ってもらいたい、と思っているプリセールス／セールスエンジニア（場合によってはマーケッター、コンサルタントなども）の方は、すでにエバンジェリストであり、胸を張ってエバンジェリストを名乗って良いと思う。そして、今回のアドベントカレンダーの主題ともなっているDeveloper Relationsを盛り上げていって頂きたいと思う。

（乱文乱筆御容赦）
PHPのheader関数の前で出力しちゃダメ、本当？

2016年ニジボックス Advent Calendar 4日目の記事です。

# 回想
このようなシーンはたまにはあるでしょう。特に新人研修の時。

> 後輩：このPHPファイルの最後でPHPタグ閉じ（?>）はないっすね。大丈夫ですか？
> 先輩：フフ、PHPコードの次でHTMLなどはないから、閉じなくても大丈夫だよ。むしろない方がいいよ。
> 後輩：へぇぇ、なんでですか。
> 先輩：この状況で閉じを書かなくても自動で補完してくれるの。逆に閉じタグを書いちゃったら、もしその後改行でも入れたら、他のPHPファイルから「require」される時、呼び出したところで**改行を出力してしまう**。万が一その次で「header」を出力しようとしたら効かなくなる。知ってると思うけど、**headerの前にコンテンツ出力あっちゃいけない**のよ。あったらもheaderを変更できなくなっちゃう。
> 後輩：ほーほー、勉強になりますね！
> 先輩：こんぐらいは常識さ！　d(￣ ・￣)

# 本題
今時のPHP開発は大抵何かのフレームワークを使って行います。リダイレクトするのも一々header関数を呼び出したりをせず、フレームワークから提供してくれた使いやすい関数でやります。ただし、いざ素のPHPで何か小さい機能を作る時は、やはり上の会話で出た**常識**をちゃんと意識して、header出力を処理の一番先頭で書くようにしますね。

果たして、header出力は本当に一番先頭で書かなきゃいけないのか、今回これを検証していきたい、と思いまーす！

# 検証
```PHP
<?php
header('Location: https://google.co.jp');
exit;
```
いかにもシンプルなheader出力、予想どおりで実行したらGoogleさんへリダイレクトしました。
問題はこれからです！

```PHP
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    TEST
</body>
</html>
<?php
header('Location: https://google.co.jp');
exit;
```
ファイルの先頭でHTMLのタグが先に書かれました。
いざ実行したら、これもGoogleさん行きになりました。headerの前でHTML書かれても大丈夫のようですね。
さって次。

```PHP
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    TEST
</body>
</html>
<?php
echo 'TEST';

header('Location: https://google.co.jp');
exit;
```
あれれ、PHPの出力もheaderの前でやったのに、これもちゃんとリダイレクトしましたね。headerの前で出力はありなの？どういうことっすか先輩？

# 原因
header関数の前のクライアントまでコンテンツを出力したら、もちろんHTTPボディーの前にHTTPヘッダーが先行し、それ以降再度header関数でリダイレクトしようとしても実行できません。ただし処理実行中のコンテンツ出力すぐクライアントまで行くわけではなく、まずバッファーで溜め込んで、特別な処理をやらない限り、コンテンツはバッファーの設定上限までまたまたheader出力のチャンスがあります。

そのバッファーの上限はphp.iniでデフォルトの値が設定されています。

```ini
output_buffering = 4096
```

4Kですね、検証してみましょう。

```PHP
<?php

for ($i = 0 ; $i < 1024; $i++) {
    echo 'TEST';
}

header('Location: https://google.co.jp');
exit;
```
結果、4Kの「TEST」がheaderの前に出力されて、バッファーの上限を超え、リダイレクトがされなくなりました。

# まとめ
前述の「output_buffering」がPHP4.1までは「Off」で設定されています。もちろんそれでスペース一個の出力で、それ以降のheader関数をだめにしちゃいます。それで上の会話のような言い伝えが生まれた原因かもしれません。

またheader関数の前にflush関数を呼び出してバッファーを強制出力させたり、「output_buffering」をOffにされたりする可能があるため、やはりheaderをできるだけ先頭に置いとくほうが無難ですね。
Visual Studio CodeでMarkdownを書くときに覚えておきたいたった2つのショートカット 2016

　この投稿は「[Visual Studio Code Advent Calendar 2016](http://qiita.com/advent-calendar/2016/vscode)」の4日目の記事です。

# はじめに

　本投稿では、Visual Studio Codeを用いてMarkdownで執筆する際、覚えておきたい2つのショートカットを紹介します。

* Previewに表示切り替え
* ウィンドウ分割と同時にPreview表示

　です。

# ウィンドウ分割と同時にPreview表示

* Windows `Ctrl+K V`
* Mac `⌘K V`
* Linux `Ctrl+K V`

　上記のキーボードショートカットにより、ウィンドウを分割し、新たなMarkdown Previewのタブを生成・表示します。

![ss_whole_edit.PNG](https://qiita-image-store.s3.amazonaws.com/0/4125/dd98ffae-dd09-bae0-d0e4-80f2e9ae31f8.png)

　上の画像の状態から、キーボードショートカットにより

![ss_divided_with_preview.PNG](https://qiita-image-store.s3.amazonaws.com/0/4125/d863369a-5744-c14f-d982-332563dbaf21.png)

　こうなります。

# プレビュータブに表示切替


* Windows `Ctrl+Shift+V`
* Mac `⇧⌘V`
* Linux `Ctrl+Shift+V`

　上記のキーボードショートカットにより、新たにMarkdown Previewのタブを生成し、表示を切り替えます。


![ss_whole_edit.PNG](https://qiita-image-store.s3.amazonaws.com/0/4125/dd98ffae-dd09-bae0-d0e4-80f2e9ae31f8.png)

　上の画像の状態から、キーボードショートカットにより

![ss_whole_preview.PNG](https://qiita-image-store.s3.amazonaws.com/0/4125/088dc00d-2023-0dfc-e947-04ce6c716c61.png)

　こうなります。

　Preview タブを表示中に上記キーボードショートカットを入力すると、カレントタブを編集タブに切り替えます。

　編集タブを表示中ですでにPreview タブが存在する場面で、上記キーボードショートカットを入力すると、Preview タブに表示を切り替えます。


# さいごに

　2015年の「[Visual Studio / Visual Studio Code Advent Calendar 2015](http://qiita.com/advent-calendar/2015/vs)」にも、
『[Visual Studio CodeでMarkdownを書くときに覚えておきたい4個のショートカット](http://qiita.com/RyotaMurohoshi/items/a86a888cd0accf5d09b6)』というタイトルで参加しました。

　2016年のアドベントカレンダーである本投稿では、その当時はなかったMarkdownを書いているときに役立つ、2つのショートカットを紹介しました。

　どんどん進化を続けるVisual Studio Codeから、目が離せませんね！


* [Windowsキーボードショートカット一覧](https://code.visualstudio.com/shortcuts/keyboard-shortcuts-windows.pdf)
* [Macキーボードショートカット一覧](http://code.visualstudio.com/shortcuts/keyboard-shortcuts-macos.pdf)
* [Linuxキーボードショートカット一覧](https://code.visualstudio.com/shortcuts/keyboard-shortcuts-linux.pdf)
Fess フィールドを追加する

Fess 10.3でフィールドを追加してみます。

- Fessにフィールドを追加
- 追加フィールドにCSVファイルのセルのデータを投入
- 追加フィールドで検索

### CSVファイル

```text:
"Path","Track_No","Artist","Track","Remix"
"file:///Music/iTunes/iTunes Media/Music/Unknown Artist/Unknown Album/Cusp - Adam.mp3","","Cusp","Adam",""
"file:///Music/iTunes/iTunes Media/Music/Ruins/Shallows/05 Gradient (Beach Club & Relic Remix).mp3","05","Ruins","Grandient","Beach Club & Relic Remix"
"file:///Music/iTunes/iTunes Media/Music/Ruins/Shallows/04 Nu Guinea (Simpig Remix).mp3","04","Ruins","Nu Guinea","Simpig"
"file:///Music/iTunes/iTunes Media/Music/Ruins/Shallows/02 Gradient.mp3","02","Ruins","Gradient",""
"file:///Music/iTunes/iTunes Media/Music/Kozmo & Subduktion/Happy Hour/04 Kozmo & Subduktion - Gin & Tonic (A.Fruit Remix).mp3","","Kozmo & Subduktion","Gin & Tonic","A.Fruit"
"file:///Music/iTunes/iTunes Media/Music/Rattraps/Swan Dive/02 Vanilla Sky.mp3","02","Rattraps","Vanilla Sky",""
"file:///Music/iTunes/iTunes Media/Music/Rattraps/Swan Dive/01 Swan Dive.mp3","01","Rattraps","Swan Dive",""
"file:///Music/iTunes/iTunes Media/Music/Unknown Artist/Unknown Album/Lux Familiar - Risk Game.mp3","","Lux Familiar","Risk Game",""
"file:///Music/iTunes/iTunes Media/Music/broken haze/TRD - EP/01 Supra.m4a","01","Broken Haze","Supra",""
"file:///Music/iTunes/iTunes Media/Music/broken haze/TRD - EP/02 MR2.m4a","02","Broken Haze","MR2",""
```

# フィールド追加
`track,artist,remix,track_no`のフィールドを追加します。

app/WEB-INF/classes/fess_config.properties
1. response, search, facetに追加するフィールドを記述します。
2. **Fessを再起動します。**

```properties:fess_config.properties
query.additional.response.fields=track,artist,remix,track_no
query.additional.api.response.fields=
query.additional.cache.response.fields=
query.additional.highlighted.fields=
query.additional.search.fields=track,artist,remix,track_no
query.additional.facet.fields=track,artist,remix,track_no
query.additional.sort.fields=
query.additional.not.analyzed.fields=
```

# データストアクロール(CsvDataStore)
管理画面>クローラ>データストア>新規作成

```groovy:ハンドラ名
CsvDataStore
```

```groovy:パラメータ
directories=/opt/fileDir/csvlist (CSVファイルを配置したディレクトリを記述)
fileEncoding=UTF-8
hasHeaderLine=true
quoteDisabled=false
ignoreEmptyLines=true
escapeDisabled=false
```

```groovy:スクリプト
url=cell1
track_no=cell2
artist=cell3
track=cell4
remix=cell5
title=track_no+" "+artist+" - "+track+" "+remix
content=track_no+" "+artist+" - "+track+" "+remix+" "+url
digest=track_no+" "+artist+" - "+track+" "+remix
anchor=
content_length=crawlingContext.get("responseData").get("content_length")
last_modified=crawlingContext.get("responseData").get("last_modified")
created=crawlingContext.get("responseData")
```

# 追加したフィールドで検索

フィールド指定の検索は `追加フィールド名:検索語` で行います。
`track_no:01` と検索することでトラック番号が01のデータがヒットします。

<img width="682" alt="スクリーンショット 2016-11-22 17.36.17.png" src="https://qiita-image-store.s3.amazonaws.com/0/31616/3fbb7a9f-82f9-4e14-bd0b-0e7627a4e417.png">
Serializablitiyとは？ 3. Conflict Serializabilityについて

## 前回のまとめ

**VSR**を定義したけれどまだ実用性が足りない。

## Conflict Equivalence

スケジュールに対して以下の条件で集合confを定義する

1. 2つのトランザクション中の操作が同一の値に触れ、少なくともどちらかが`Write`である場合に*競合*と呼ぶ
2. スケジュールの中で*競合*している操作a,bについて操作a→操作bの順に触った場合にそれを*a→bの競合関係*と呼び、{a, b}と表記する
3. すべての*競合*に対してそれを行いすべての*競合関係*の集合をconfとする

2つのスケジュールについてそれぞれのconfが一致する場合に**Conflict Equivalent**（以下**競合等価**）と呼ぶ。

文章で読んでもピンとこないので、とあるスケジュール図Aを例に描いてみると例えばこのようになる。

![failconf.png](https://qiita-image-store.s3.amazonaws.com/0/1716/0591c0e2-fc26-44da-69d2-071fcd619fe4.png)

並行して実行されたTx1, Tx2の2つのトランザクションについて、同一の値に対して読み書きした操作のペア(*競合関係*)を赤い矢印で表現している。トランザクションaのnステップ目の操作をTxa_nと表記するとして、上の図からは以下の集合conf①が得られる。

```:↑から得られる競合関係の集合conf①
conf = ({Tx1_1, Tx2_1}, {Tx2_2, Tx1_2}, {Tx2_2, Tx1_3}) 
```

赤い矢印が3本あるので、集合の大きさも3となる。与えられた実行スケジュール2つについて、この集合が一致した場合に、2つのスケジュールは**Conflict Equivalent**であるという。そして何らかの順序で逐次実行したトランザクションと**Conflict Equivalent**であるスケジュールの事を**Conflict Serializable**(以下CSR)であると言う。

![succconf.png](https://qiita-image-store.s3.amazonaws.com/0/1716/85447376-f3c3-6803-519b-adc9af3204f3.png)

```:↑から得られる競合関係の集合conf②![csr_not_vsr.png](https://qiita-image-store.s3.amazonaws.com/0/1716/9f99f15a-d389-8657-d6ee-c01fbe6f51c4.png)

conf = ({Tx1_1, Tx2_1}, {Tx1_2, Tx2_2}, {Tx1_3, Tx2_2}) 
```

![succonf2.png](https://qiita-image-store.s3.amazonaws.com/0/1716/034b655d-b2fb-f96f-fa97-abe45a4f3fa6.png)

```:↑から得られる競合関係の集合conf③
conf = ({Tx2_1, Tx1_1}, {Tx2_2, Tx1_2}, {Tx2_2, Tx1_3}) 
```


conf②はTx1→Tx2の順で直列実行した場合のスケジュールであり、conf①とは内容が違う。
conf③はTx2→Tx1の順で直列実行した場合のスケジュールであり、conf①とは内容が違う。
そのためconf①を作る一番上のスケジュール図AはCSRではない。
というようにCSRであるかを検定できる。


![mono.png](https://qiita-image-store.s3.amazonaws.com/0/1716/fe1a54eb-05f6-3703-0c07-d8ba013cda14.png)

VSRが満たされるこのスケジュールは

![csr_not_vsr.png](https://qiita-image-store.s3.amazonaws.com/0/1716/a25d7c2b-8d88-8b83-5495-67cc6bada3e0.png)

```
conf = ({Tx1_1, Tx2_1}, {Tx1_1, Tx3_1}, {Tx2_1, Tx3_1}, {Tx2_2, Tx1_2}, {Tx2_2, Tx3_2}, {Tx1_2, Tx3_2})
```

このconfと同一になる逐次実行パターンが存在しないのでCSRとは呼べない。
また逆に、CSRなスケジュールは必ずVSRになる。エルブランセマンティクスがReadとWriteの関係しか表現していなかったのに対し、**競合関係**の矢印はReadとWriteの関係だけでなくWriteとWriteの関係も表現するからである。
なのでCSRはVSRよりもさらに厳しく狭いスケジュールの集合を表すクラスであり、CSRはVSRの部分集合である。図に表すと以下のようになる。

![benz2.png](https://qiita-image-store.s3.amazonaws.com/0/1716/393d039b-7193-9014-7e83-786886f8a85d.png)


**CSR**はFSRやVSRと違い、スケジュールからのCSRの判定が非常に容易である。その手順は以下である。
1. 任意のスケジュールが与えられた時、そこから競合集合confを算出する
2. confから**競合関係**を1つ取り出し、その中のTxの順序を逐次実行の順序として仮決めする
3. 2を繰り返し逐次実行の順序に矛盾（順序が円環になる）が起きたら**CSR**ではない
4. confから**競合関係**をすべて取り出し終えても矛盾が無ければ**CSR**
これは非常に高速に検定でき、理解しやすい。

さらにはCSRは*Monotone*であるという特性を満たす。*Monotone*とは「スケジュールから任意のトランザクションが消失してもスケジュールのクラスが変わらない特性であり、アボートや永続化を考える上で重要であるがそこの深追いは後の章にする。
Zapierを使ってBacklogのsvnのコミットをslackに通知しようとした話

# はじめに
- この記事は「[ポエム Advent Calendar 2016 \- Qiita](http://qiita.com/advent-calendar/2016/poet)」の 4 日目の記事です。
- ゆるふわです

# あわせてよみたい
- [backlog webhookを使ってpull\-requestをslackに通知してみる \- Qiita](http://qiita.com/shinderuman@github/items/2f7717c880091a271ab5)

# がいよう
## なんでやろうとおもったか
- 特定のファイル、ディレクトリがsvnにコミットされたらslackに通知したい
- 全部だとノイズすぎる

## どうやろうとおもったか
- Backlog使ってたのでWebHookを利用
- ZapierでWebHookをcatchしてFilter(特定のファイル、ディレクトリか)にmatchすればslackへ投稿

# かいはつ
## つくった
- ![image](https://qiita-image-store.s3.amazonaws.com/0/722/122b9da7-8542-fc74-ed6b-4e6366c8a7b1.png)

## だめだった
- そもそもjsonにファイル名、ディレクトリ名がなかった

```json
{
  "created": "2016-11-19T05:07:46Z",
  "project": {
    "archived": false,
    "projectKey": "TEST",
    "name": "TestProject",
    "chartEnabled": false,
    "id": 100,
    "subtaskingEnabled": false
  },
  "id": 10,
  "type": 11,
  "content": {
    "rev": 100,
    "comment": "test commit"
  },
  "notifications": [],
  "createdUser": {
    "nulabAccount": null,
    "name": "shinderuman",
    "mailAddress": null,
    "id": 11774,
    "roleType": 1,
    "userId": null
  }
}
```

# やりかたをかえてみた
- Filterをコミットコメントに特定のワードが含まれていたら、に変更

## filterのせってい
- ![image](https://qiita-image-store.s3.amazonaws.com/0/722/c7e10405-8f4b-cb4b-1cad-d6bc9268f2eb.png)

## templateのせってい
- ![image](https://qiita-image-store.s3.amazonaws.com/0/722/e0549db2-07ed-df03-6881-9e5f31910e76.png)

## うごかす
- ![image](https://qiita-image-store.s3.amazonaws.com/0/722/cf944350-b60d-1838-9203-26ebc0e88dee.png)
- うごいた! ((\\( ⁰⊖⁰)/) 

# とつぜんのまとめ
- 結局コミットコメントじゃ自動化になってない
- jsonにファイル名が含まれていない以上このままじゃ無理ぽ
- 大人しくCIとかから通知させるのが楽なのかなとおもた

# ((\\( ⁰⊖⁰)/) Happy Hacking!!
[PepperデモTips] デモの前後でPepperを迅速に設置＆撤収し、余計な音をできるだけ出さないための一手法

Pepperと一緒にプレゼンなどをするとき、迅速設置＆撤収し、他の人にできるだけ迷惑かけないためのアプリ作成のコツを書いてみました。
プレゼン中にPepperデモを行うときや、忘年会シーズンにPepperと一緒に宴会芸などやる際はぜひ参考にしてみてください。

#背景
本記事は以下のような状況を想定しています。

- 発表の冒頭にPepperに喋らせたり、人間の発表者とコントをする
- 自然な掛け合いをしたいので、Choregrapheは使わない。もしくは運営上自分のPCは発表時に使えない
- LT会のように、発表者入れ替え時間に余裕のないアジェンダで、他はPepperと関係ない発表だらけ。自分の番だけPepperの設置・撤収で時間をとる等の迷惑をかけられない

Pepperデモが中心の発表会では、発表者交代時のPepper設置＆撤収でかかる手間や時間を、最初から運営側が想定してくれていたり、聴衆もPepperの準備が整うまで、気長に待ってくれるというケースが多いと思います。
しかし、発表者の中で自分だけがPepperと一緒に登壇するときには、発表者が迅速に対応しないと他の発表者の迷惑になることもありえます。運搬に時間がかかったり、いきなり大声で「ねぇねぇ、なにしてるのぉー？」なんて叫んだり。。。

筆者はこんな方法で対応してみました。

#手順

### ◎アプリに入れておく処理
・アプリの冒頭にRestの処理を入れておく
・タッチセンサーでWake Upする処理を入れておく(筆者は手の甲センサーにしました)
・音声認識待ち状態の「ぴょこっ」という音を消す

### ◎発表前に待機場所から登壇場所へ移動するとき
待機場所や会場の外にいるうちに、アプリを再生(Choregrapheのロボットアプリケーション、もしくはタブレットから再生)
↓
PepperがRestの体勢になる
↓
発表場所までPepperを押して持っていく
↓
発表場所に着いたらタッチで起こす。
↓
アプリの本処理開始

### ◎発表後
すぐに、胸のボタンを二度押しして、Restにして運んでその場を去る
↓
元の待機場所に戻ったら、Choregrapheからつないで音量を下げる


#アプリに入れる処理詳細

## RestとWake Upの処理
Choregrapheボックスとして用意されているRestボックスとWakeUpボックスを入れるだけです。以下のようにボックスをつなぎました。
![rest_wakeup.png](https://qiita-image-store.s3.amazonaws.com/0/137766/e401a580-49cb-c3c5-d88e-39306347d716.png)

アプリ開始直後にPepperをRestの体勢にしてから運搬し、Pepperの右手の甲をタッチして起き上がらせる(WakeUp)ことができます。

## 音声認識時のあの音を消す
音声認識をトリガーにして、次のアクションを起こすように設計している場合、音声入力待ち状態のまま放置しておくと、発表者の声を聞き取るたびに何らかのキーワードとして認識し、「ぴょこっ」と音を出してしまうことがあります。プレゼンという状況でなくても、喋っている最中に邪魔になる事もあると思いますので、Pythonボックスで以下の処理を入れておきます。


```python:__init__内に以下を追加
        try:
            self.asr = ALProxy("ALSpeechRecognition")
        except Exception as e:
            self.asr = None
            self.logger.error(e)
        self.memory = ALProxy("ALMemory")
```

```python:onInput_onStart内に以下を追加
        if self.asr:
            self.asr.setAudioExpression(False)
        self.onStopped() 
```

もし、音声認識待ちの際に目が青く光る事も不要であれば、"if self.asr:"の中に"self.asr.setVisualExpression(False)"を追加して下さい。


# サンプル
以下に置きました。
https://github.com/yukanm/pepperdemotips


# まとめ
本記事では、Pepperと一緒にプレゼンなどをするとき、迅速設置＆撤収し、他の人にできるだけ迷惑かけないためのアプリ作成のコツを紹介しました。紹介した方法以外にも工夫の仕方はあると思いますが、一例として参考にして頂ければ幸いです。
FlowEditorをカスタマイズ (settings.jsで指定)

# 目的

Node-REDを自前で複数運用すると、いまどの環境で作業しているかがわからなくなることがあります。Flow Editorをカスタマイズすることで

- どの環境向けにFlowを書いているか分かる
- 自社のロゴによる自前感

というメリットがあります。 :smile: 

# カスタマイズ方法

Flow Editorは[Mustache.js](https://mustache.github.io/)が使われており、見た目は /usr/local/lib/node-red/editor/templates/indes.mst をさわれば変更可能ですが、簡単な方法としてsettings.jsのeditorThemeで指定することができます。

たとえば、Version 0.15.1 以降で使える「Manage palette」（Nodeのパレットを編集したり、Node-RED Libraryから新しいCustom Nodeをインストールする機能）を無効にするには

```js:settings.js
editorTheme: {
  menu: { 
    "menu-item-edit-palette": false,
  }
},
```

をsettings.jsに記載することで実現できます。

# カスタマイズできる項目
本家Node-REDのGithubのIssue #610
Editor Theming #610
https://github.com/node-red/node-red/issues/610
及び、Configuration
http://nodered.org/docs/configuration.html
の「Editor Themes」項に情報があります。

## FlowEditor
![FlowEditor変更可能項目](https://cloud.githubusercontent.com/assets/51083/7089838/87f01ab6-df96-11e4-9ba2-2259fc803894.png)

```js:settings.js
page: {
    title: "Node-RED",
    favicon: "/absolute/path/to/theme/icon",
    css: "/absolute/path/to/custom/css/file",
    scripts: [ "/absolute/path/to/custom/script/file", "/another/script/file"]
},
header: {
    title: "Node-RED",
    image: "/absolute/path/to/header/image", // or null to remove image
    url: "http://nodered.org" // optional url to make the header text/image a link to this url
},
deployButton: {
    type:"simple",
    label:"Save",
    icon: "/absolute/path/to/deploy/button/image" // or null to remove image
},
```

### MainMenu のカスタマイズ
MainMenu については、以下の項目を true / false で 表示 / 非表示 可能です。(1.0.6現在)

||
|:-----------|
|"menu-item-projects-menu"|
|"menu-item-projects-new"|
|"menu-item-projects-open"|
|"menu-item-projects-settings"|
|"menu-item-view-menu"|
|"menu-item-palette"|
|"menu-item-sidebar"|
|"menu-item-event-log"|
|"menu-item-action-list"|
|"menu-item-import-library"|
|"menu-item-export-library"|
|"menu-item-search"|
|"menu-item-config-nodes"|
|"menu-item-workspace"|
|"menu-item-workspace-add"|
|"menu-item-workspace-edit"|
|"menu-item-workspace-delete"|
|"menu-item-subflow"|
|"menu-item-subflow-create"|
|"menu-item-subflow-convert"|
|"menu-item-edit-palette"|
|"menu-item-user-settings"|
|"menu-item-keyboard-shortcuts"|
|"menu-item-help"|
|"menu-item-node-red-version"|

### MainMenu への追加
"menu-item-help"に"label"と"url"を追加することで、任意のWebページへのリンクを追加できます。

```js:settings.js
editorTheme: {
  menu: { 
    "menu-item-help": {
      label: "Node-RED Library",
      url: "https://flows.nodered.org/"
    }
  }
},
```

## Loginダイアログのカスタマイズ
![Loginダイアログ変更可能項目](https://cloud.githubusercontent.com/assets/51083/7090165/eb892f84-df98-11e4-852f-7b3b9c13d353.png)
ログイン画面のロゴは256x256pxで指定できます。イメージファイルのパスを以下のように指定します。

```js:settings.js
login: {
    image: "/absolute/path/to/login/page/big/image" // a 256x256 image
},
```

## Logout後にページ遷移
ログアウトした後に特定のページに遷移するには、logout:redirectに遷移先URLを記載します。

```js:settings.js
logout: {
    redirect: "http://example.com"
},
```
バナー作成の時短に役立つ！参考サイト

バナー作成は楽しいけど、できるだけ早く作成したいもの。
そこで、バナーを作成するときに、参考にしているサイトをまとめてみました。

# <i class="fa fa-check-square-o"></i> 前提条件
- 飛び先がある場合は、基本イメージや配色は飛び先に合わせます。
- 指定色がある場合は、指定色を必ず使用します。

# <i class="fa fa-bookmark"></i> レイアウト

要素を置いてみて、配置を悩んだときに眺めるサイトたちです。

## **1. BANNER LINKS**
![BANNER.png](https://qiita-image-store.s3.amazonaws.com/0/54595/689641c7-669c-dcac-1545-8e29acedf4bf.png)

http://nonamedesign.info/banner/

> 様々なバリエーションを集めたバナーまとめサイトです。
> バナーのレイアウト・見せ方のあしらいなどを参考にしています。

## **2.Dribbble**
![Dribbble.png](https://qiita-image-store.s3.amazonaws.com/0/54595/cccec52c-0049-d0c2-1959-01306d6ecf69.png)


https://dribbble.com/

> クオリティの高いサイトが多く登録されています。
> イメージを固めるためのインプット用にしています。

# <i class="fa fa-bookmark"></i> 配色サイト

飛び先のイメージがない場合や、メインカラーと合わせる色を探るときに利用するサイトたちです。

## **1.coolors**

![Coolor.png](https://qiita-image-store.s3.amazonaws.com/0/54595/2a46b40c-b479-17aa-5b33-e5f6a0ed75e4.png)

https://coolors.co/

> 最近の一番のお気に入りの配色サイトです。
> スペースキーで、どんどんカラーを変更し、気に入った色が見つかるとロックして、その他ほ配色を決めることができます。

## **2.Colourco.de**
![colourcode.png](https://qiita-image-store.s3.amazonaws.com/0/54595/33bb8237-73ae-b6d4-f0b9-c94172e23abd.png)

http://colourco.de/

> カラースキームを画面上をマウスで移動して作成できるツールです。
> 高度すぎるため、使い方に慣れが必要。


## **3.BrandColors**
![BrandColors – Official.png](https://qiita-image-store.s3.amazonaws.com/0/54595/77887115-3eb5-f18b-e94c-7de8de58d614.png)

https://brandcolors.net/

> 各ブランドサイトのカラーリングが必要な時に使ったりします。

## **4.HUE/360**
![hue.png](https://qiita-image-store.s3.amazonaws.com/0/54595/ebe672c0-464b-c37e-c187-76c212007ee2.png)

http://hue360.herokuapp.com/

> 明度・再度・色相の関係性を確認するときに使ったります。

## **5.ColorDrop**
![ColorDrop.png](https://qiita-image-store.s3.amazonaws.com/0/54595/03bb9e6e-9a5f-48e5-1265-35587b2d7e75.png)

https://colordrop.io/

> バナーの配色イメージがないとき、直感的に選びたい時に眺めるサイトです。
CakePHP3 のログをためす

この記事は、CakePHP3 Advent Calendar 2016の4日目の記事です。
CakePHP3.3のロギングを簡単に説明します。
CakePHP3.xのLogTraitを用いたものです。

# 環境

```
Welcome to CakePHP v3.3.7 Console
---------------------------------------------------------------
App : src
Path: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
PHP : 5.6.25
```


# ロギングさせる方法

## DB

`config/app.php` の `Datasources` 内の使用している設定(`default`)の、`log`を`true`にする。

## PHP

自分でPHPのコードに埋めたログを吐き出す。



``` app.php

    /**
     * Configures logging options
     */
    'Log' => [
        'debug' => [
            'className' => 'Cake\Log\Engine\FileLog',
            'path' => LOGS,
            'file' => 'debug',
            'levels' => ['notice', 'info', 'debug'],
            'url' => env('LOG_DEBUG_URL', null),
        ],
        'error' => [
            'className' => 'Cake\Log\Engine\FileLog',
            'path' => LOGS,
            'file' => 'error',
            'levels' => ['warning', 'error', 'critical', 'alert', 'emergency'],
            'url' => env('LOG_ERROR_URL', null),
        ],
    ],
```


### Controller / View(.ctp) 

※ `Component`も同じ

``` AppController.php
        $this->log("ʕ·ᴥ·ʔ I",'info');
        $this->log("ʕ·ᴥ·ʔ N",'notice');
        $this->log("ʕ·ᴥ·ʔ D",'debug');
        
        $this->log("（ ﾟᆸﾟ ）E",'error');
        $this->log("（ ﾟᆸﾟ ）W",'warning');
        $this->log("（ ﾟᆸﾟ ）C",'critical');
        $this->log("（ ﾟᆸﾟ ）A",'alert');
        $this->log("（ ﾟᆸﾟ ）E",'emergency');
```


```.log
$ tail -f *.log


==> debug.log <==
2016-12-03 07:06:29 Info: ʕ·ᴥ·ʔ I
2016-12-03 07:06:29 Notice: ʕ·ᴥ·ʔ N
2016-12-03 07:06:29 Debug: ʕ·ᴥ·ʔ D

==> error.log <==
2016-12-03 07:06:29 Error: （ ﾟᆸﾟ ）E
2016-12-03 07:06:29 Warning: （ ﾟᆸﾟ ）W
2016-12-03 07:06:29 Critical: （ ﾟᆸﾟ ）C
2016-12-03 07:06:29 Alert: （ ﾟᆸﾟ ）A
2016-12-03 07:06:29 Emergency: （ ﾟᆸﾟ ）E
```







# ログレベル使い分け

公式ドキュメントより。
上からヤバイ順。

* Emergency: システム異常
* Alert: 速攻対応必要あり
* Critical: 致命的な状況
* Error: 不具合
* Warning: 警告
* Notice: 通常、しかしメッセージを出したいとき
* Info: なんらかの情報
* Debug: デバッグメッセージ


以上。
RStudioのPaneを操作する

この記事は,[RStudio Advent Calendar 2016]()の4日目の記事です。

## RStudioのPaneについて

RStudioを起動させて目に飛び込んでくる4つのウィンドウ。これは**Pane**といいます。

![all_pane.png](https://qiita-image-store.s3.amazonaws.com/0/35118/9c98f928-b74c-4460-9a31-3d5148319928.png)

そのまま使っていってもいいのですが,いろいろとできます。今回はその基本をご紹介します。

## Paneの幅・高さを調整

Paneの幅を調整するには,**垂直仕切り線の中央**にハンドルがあります。ここをドラッグすると垂直仕切りを左右に動かせます。高さについても同様に,**水平仕切り線の中央**にハンドルがあるので,ここをドラッグすると水平仕切りを上下に動かせます。

両方とも,完全に端までドラックすることも可能です。その場合一部のpaneが非表示となりますが,また仕切り線をドラッグしてあげると出てきますので安心してください。

## Pane control(?)ボタン

RStudioのメニューバーのところに,以下のようなWorkspase Panesボタンがあります。これでいろいろできます。

![pane_control.png](https://qiita-image-store.s3.amazonaws.com/0/35118/7a44ebb2-b078-7d53-6e29-4f24387cd617.png)

<dl>
<dt>Show All Panes</dt>
<dd>4つのPaneをすべて表示させます。どれかを伏せていて,全部表示させたいときに使います。</dd>
<dt>Console on Left(Right)</dt>
<dd>Consoleを左側(あるいは右側)に配置するのを設定します。</dd>
<dt>Pane Layout...</dt>
<dd>RStudioの[Tools] - [Global Option...]内にあるPane Layoutを開きます。</dd>
<dt>Zoom ****</dt>
<dd>選択すると,選択した内容がウィンドウ全体に広がります。</dd>
</dl>

## Pane layout設定

RStudioのメニューから,[Tools] - [Global Option...]に進み,Pane Layoutを選択すると,以下のような設定画面が出てきます。

![pane_layout.png](https://qiita-image-store.s3.amazonaws.com/0/35118/b02daef4-3d72-0d24-8fea-541314a95ab8.png)

ここで,**自分好みにPane Layoutを設定できます**。人によってかなり好みが違いますし,普段Rでやる内容によっても変わるでしょうから,ぜひ自分にぴったりなものを探してみてください。

## ウィンドウの分離

実は,RStudioでは一部を**別ウィンドウとして切り離す**ことができます。例えばSource Paneでは,以下のようなボタンがあります:

![tear_button.png](https://qiita-image-store.s3.amazonaws.com/0/35118/d4efaa2d-14a9-64eb-1d4a-8e75911ea74a.png)

フロッピーディスクの保存ボタンの左にあるボタンがそれで,これをクリックすると別ウィンドウに切り離されます:

![teard_pane.png](https://qiita-image-store.s3.amazonaws.com/0/35118/f4599236-ec2e-a7e9-1981-8e72cf8d868c.png)

これを使うと,スクリプト編集に集中することもできます。またこれはタブ形式で,普段ブラウザでやっているように,タブ部分をドラック&ドロップすることで,RStudio本体や,切り離した別ウィンドウに他のファイルを持って行ったりすることも可能です。

個人的にはR Markdownですぐ下に出力結果を表示できるようにして作業したり,R Markdownでスライド作成している場面が多いので,このように画面を切り離して集中して作業できるようになりました。ぜひみなさんもご活用ください。

つぎはwakutekaさんです。楽しみにしております。**Enjoy!**
Cloud DataflowでBigQueryから取得したデータを加工してS3に出力する

# はじめに
この記事は、Google Cloud Platform(2) Advent Calendar 2016 4日目の記事です。
DataflowからS3へファイルを出力する方法について紹介します。

# 概要
Cloud　DataflowではGoogle Cloud StorageやBigQuery、Cloud PubSubなどに対してI/Oを行うライブラリが提供されているが、S3などAWS系のI/Oは現在のところ提供されていない。
そこで今回はS3へ出力するCustom Sink(S3Sink)の作成を行い、Dataflowを使ってBigQueryから取得したデータを加工して、その結果をS3へ出力するパイプラインを作成した。

今回作成するパイプラインの概要は下記の表のとおりである。

| デザイン | 備考 |
|:-:|:---|
| 入力データ  | BigQuery (マスタテーブルとマッピングテーブルの２つ) |
| 出力データ | S3  |
| ファイルフォーマット | csv  |
| 変換 | idの中でマッピングテーブルに該当するidを対応する値に変換する|
|開発環境| Dataflow Python SDK|

<img width="879" alt="スクリーンショット 2016-12-01 21.30.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/95399/7ba81259-d4c7-da23-7bea-dc8fb61b7fbd.png">

# S3Sinkの作成
S3Sinkは以下のような感じで作成した。

- FileSinkを継承　
- initialize_write: GCSの一時ディレクトリを設定
- write_record：　FileSinkのwrite_recordをコール
- write_encode_record: レコードを書き込み、改行を入れる
- open_writer：GCSにファイルを出力
- finalize_writeでGCSからファイルを取得し、一つのファイルにマージする。botoを使用してS3にマージしたファイルをアップロード

open_writerでS3に書き込んでいたが処理速度があまりに遅かったため、一度GCSに書き込んでからマージして、finalize_writeでアップロードするようにした。

# カスタムシンクを利用してDataflowを実行するのに必要な準備
以下のようなフォルダ構造でs3sink.pyを配置し、"python setup.py sdist"を実行して、s3sink.pyをパッケージングする。dataflowを実行するとき--extra_packageオプションでパッケージファイルを指定する。

```
s3_custom_lib
    |-dist
    |-s3package
         |-__init__.py
         |-s3sink.py
    |-setup.py
```

# Dataflow
1.BigQueryに対してクエリをかけて、その結果をPCollectionで受け取る

```
rows = p | 'readBigQuery' >> beam.io.Read(beam.io.BigQuerySource(query=custom_options.query))
```

2.Mappging用のテーブルに対してもクエリをかけてデータを取得する

```
mapping = p | 'readBigQuery(MappingTable)' >> beam.io.Read(beam.io.BigQuerySource(query=custom_options.mappingquery))
```

3.CoGroupByKeyで２つのテーブルをJoinする。BigQueryでクエリをかけた結果はdictなので、tupleに変換してからCoGroupByKeyにかける。

```
join_data = {'rows': convert_tuple_main(rows), 'mapping': convert_tuple_mapping(mapping)} | beam.CoGroupByKey()
```

4.ParDoでIDを変換する。
この段階では各要素は以下のような形式になっている。

```
{"id xxx",{{"row":""},{"mapping":"mapped_id xxx"}}}
```

mapped_idにある文字列が入ってるIDだけ変換する処理をDoFnで記載する。

```
result = join_data | 'Replace ID' >> beam.ParDo(IdReplaceFn())
```

5.処理結果をS3にアップロードする

```
awscredentialfile = gcsio.GcsIO().open(filename=segment_options.awscredential)
        awscredential = awscredentialfile.read()
        result | 'writeS3' >> beam.io.Write(s3sink.S3Sink(awscredential, custom_options))
```

6.パイプラインを実行する

```
python run_dataflow --project {PJ_NAME} --job_name {JOB_NAME} --runner BlockingDataflowPipelineRunner --staging_location gs://xxx/stagin g --temp_location gs://xxx/temp --extra_package s3_custom_lib/dist/s3package-1.0.tar.gz
```

実行するとGCPのWebコンソールで以下のような図が出力されることを確認できる。

<img width="501" alt="スクリーンショット 2016-12-01 21.32.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/95399/e8a07a81-dd1e-413d-df27-ddc1850dfc41.png">

360万件のデータを処理するのに16分程度要した。処理中3vcpuしか使用されてなかったので、もう少し検討が必要。

#最後に
Dataflow　のPython SDKはβ版なので現段階ではストリーミング処理機能が実装されてないなど、Prodocutionで利用するには推奨されてませんので、注意が必要です。
明日12/5はsoundTrickerによるGAEに関する発表です。
AWS re:Invent 2016に参加してみた 4日目

さて、４日目です。なんとか続けられてます。今までの軌跡はこちらから。昨日はre:Play参加などなどで結局日が空いてしまった。

[AWS re:Invent 2016に参加してみた 1日目](http://qiita.com/kojiisd/items/0b1c5ebe9118bd26147e)
[AWS re:Invent 2016に参加してみた 2日目](http://qiita.com/kojiisd/items/bd00afa24a515c58ddae)
[AWS re:Invent 2016に参加してみた 3日目](http://qiita.com/kojiisd/items/04d6d466444fca8be2a0)

# GA05 - Keynote Presented by Werner Vogels
また色々なサービスが追加されましたね。

# DCS205 - Workshop: Building Serverless Bots on AWS - Botathon
Amazon Lexを使ってのbotサービスを実際に作れるワークショップでした。サーバ側で動作するLambdaなどはすでに用意されている状態で、Amazon Lexを実際に触りながらこちらの質問に答えるbotの作成。

下手な説明を聞くよりもLex内のIntentとかUtterance、Slotsのことがわかったので、有意義な2.5時間でした。

この後は夕方のディナーまで、展示ブースを見て回りました。お付き合いある会社さんのブースに行ったりASK THE EXPERTでAmazon Athenaについて質問したり、時間がいくらあってもこれは足らなかったです。

Snowballの実物が見れたりかなり多くの会社がブースを構えていました。
![20161201_113106.jpg](https://qiita-image-store.s3.amazonaws.com/0/102769/b8daa6af-0967-1a1f-df38-daa57c286a27.jpeg)


# 資格保持者特別ディナー＠LAVO PALLAZZO
めっちゃ広かったですよ。非ツアー組の自分としては、ここでかなり多くの人と会話させてもらいましたので、ありがたいイベントでした。やっぱり資格保持しておいてよかった、と感じた瞬間でした。

ただ皆さん当たり前のようにプロフェッショナル持っててもうね、、、実力不足を痛感しました。

![20161201_174045.jpg](https://qiita-image-store.s3.amazonaws.com/0/102769/b20d2292-d83a-f7b6-b04d-d3054598701e.jpeg)


# re:Play
No1 DJのMartin Garrixによるライブ、さまざまなアトラクションがあったりと、かなり充実した時間でした。ただ会場までの道のりはどこかで明示しておくべきですね。こんなもん最初から行けた人の方が少ない気がする。この話はまたおいおい。

この雰囲気は他の参加者の方がいっぱい報告上げてくれると思いますのでそちらを参考に。
BaaSを使ってプロトタイピングする

昨日、BaaSでは何らかのブレークスルーが必要だという話をしました。
そのためには「潰しがきかない」リスクを排除する必要があると。
しかし、それでも爆発的に利用者が増えるかといえば、まだまだ不十分な気がします。

今日はその話をしたいと思います。

#成功のヒントはSaaSにある

クラウドでビジネス的に成功しているのはSaaSとIaaSです。
IaaSは標準化されたOSの世界で多くの人が理解できる一般的な環境を提供し、SaaSはエンドユーザがすぐに使えるパッケージを提供しています。

IaaSはまだしも、特殊な環境であるSaaSが流行るのはなぜでしょうか？
SaaSは「潰しがきかない」環境なのに、広く受け入れられているのは不思議です。

この辺りの話は、[APIに標準技術を押し付けるのはやめろ](http://blog.virtual-tech.net/2016/02/api.html
)で詳しく述べていますが、実はSaaSのこのビジネスモデルこそ見習うべき点があるように思います。

#エンドユーザに直接訴える

私はエンドユーザとの距離がポイントだと思っています。
SaaSがエンドユーザに直接訴える一方で、BaaSやPaaSはどちらかというと開発者やシステム管理者に訴えるものです。その分、エンドユーザとの距離が長くなります。

エンドユーザは、中身はあまり気にせず、便利ですぐに使えるものを好む傾向にありますが、開発者やシステム管理者は潰しがきかないものを避ける傾向にあります。

BaaSも、広く普及させるには、開発者やシステム管理者に訴えるのではなく、エンドユーザに直接訴えるようにしないといけません。

#BaaSの特長を生かして訴求力を引き出す

BaaSの仕組みをくどくど説明したところでお客様の心には響きません。
その点、具体的なパッケージを持っているSalesforceやKintoneなどのSaaSは強いと思います。
訴求力をもつには、完成形のイメージがエンドユーザから見てわかりやすく、具体的なソリューションであるべきです。これらは、いわゆるエンドユーザ・コンピューティングに近いモデルだと思います。

一方で、BaaSはSaaSよりも柔軟性があります。
スクラッチ開発のような柔軟性とSaaSのスピード感を併せ持つのがBaaSです。
SaaSでは制約があってできなかった機能でもBaaSだと実現できたりします。

このBaaSの特長を生かした開発手法の一つにプロトタイピングがあります。
プロトタイピングでは必ずしもエンドユーザ自身が開発するわけではありませんが、エンドユーザの目線でアプローチすることができます。

今年、あるお客様で、vte.cxを使ってプロトタイピングを行いました。
要件をまとめながら、２～３週間かけてモックを作成したのです。
モックとはいえ、実際にデータ入力もできるし、本番と同じように動作します。
実際に動くものを見たお客様は大変な衝撃を受けたようでした。
その後、次のフェーズも受注に至ったのはいうまでもありません。

#BaaSでプロタイピングするメリット

プロトタイピングなら別にわざわざBaaSを使うことはないと思われるかもしれませんが、本番と同じように入力でき、検索できるシステムはそう簡単には作れません。

しかし、vte.cxであればプロトタイピングで本番利用できるシステムをサクっと作ることができます。
というより、要件定義や外部設計を行いながら本番システムを実際に構築していく感じです。
プロトタイプと本番システムの明確な区別はありません。

プロトタイピングしながら、要件定義や外部設計を行なえ、かつ本番システムの実装も進む。
一石三鳥ぐらいの話です。

もちろん、将来的にはスケーラビリティや可用性が要求されるフェーズが来ることも想定しなければなりません。
その場合でも、可搬性の高いvte.cxであれば大丈夫です。
初めはBDB(KVS)で作り、将来的にはそれをRedisやRDBなどに移行することができます。また、オンプレミスを含む様々なプラットフォームで動作させることができます。

#新しい開発手法との組み合わせ

BaaSとエンドユーザ・コンピューティングとの組み合わせは新しい開発手法をもたらします。

例えば、ソニックガーデンさんが提唱する「[納品のない受託開発](https://www.sonicgarden.jp/32)」では、
「１〜２週間の単位で作りたいものを決めて、それが出来上がってきたものを見て、また次に作りたいものを決めていく」というアジャイル的なやり方で開発を進めていきますが、vte.cxを活用することで、このような短いスパンでもエンドユーザに具体的なソリューションを小刻みに示すことができます。

この手法は、特に、スタートアップや新規事業における開発ニーズにマッチすると思います。

以上、述べてきたように、エンドユーザに近い目線でアプローチすることで、BaaS活用のメリットは大きく広がるように思います。

それでは、また明日。
Rubyを評価するCLIツールはCRubyとmrubyのどちらで実装するべきか

最近[MItamae](https://github.com/k0kubun/mitamae)や[xkremap](https://github.com/k0kubun/xkremap)など、Rubyで設定ファイルを既述するCLIツールをCRubyではなくmrubyで実装することがあったのだが、そのようなCLIツールを作る際にCRubyではなくmrubyを使うことへの妥当性について考えていたことをダンプしておく。

以下、ハードウェアにmrubyを組み込む用途や、Ruby以外で書かれた既存のツールにmrubyを組み込む用途については(僕は特に経験してないので)除外して書きます。

# CLIツールの作成にmrubyを使うメリット
- CRubyやrubygemsの存在に依存しないバイナリとしてCLIツールを作ることができる
  - gem installする場合に比べ、rbenvに気を使わずバイナリを叩くだけで手軽に実行できる
     - gem installして入れたCLIツールは、rbenvが入っている環境ではrbenv globalや.ruby-versionが違ったりsudoでユーザーが変わると動かなかったりするので、rbenvに気を使って実行しないといけない
  - Ruby以外の依存も解決できれば、ダウンロードするだけで実行可能なバイナリにでき、配布が楽になる
     - CRubyで作ったツールは、CRubyが既に入った環境でgem installさせるか、[chef/omnibus](https://github.com/chef/omnibus)などを使って各OS/ディストリビューションごとにCRubyごとパッケージングする必要がある

# CLIツールの作成にmrubyを使うデメリット
- CLI関係なくmrubyを使う際のデメリットがある
  - 実装する時に一部の標準ライブラリやrubygemsが使えないので、自分で移植する必要がある
     - デフォルトでは require がないし、ほぼ確実にそのままでは動かない
         - mruby-requireを使うと、実行時にそのRubyのファイルが必要になってしまうので、mrubyが何らかのハードウェア/ソフトウェアに組み込む用途に使われる以上、極力使わない方が良い
     - 移植しても、本家に変更を追従させるのが大変
     - 移植する時にCのコードを書く機会が多い
         - 特に、CLIツールで使いそうなmruby-ioに必要なメソッドが足りなかったりする
     - RSpecが使えない
     - pryが使えない
  - mrubyはRubyの言語機能が一部実装されていない
     - キーワード引数とかない
  - CRubyに比べるとmrubyやサードパーティmrbgemの安定性が低い
     -  CRubyだとcoreに入っているような機能もmrubyだとサードパーティなので信頼性は低い
     - undefined methodの時にたまにSEGVするが再現が困難で報告しにくい
     - mruby-threadを使うとmruby-ioとかが壊れる
- mruby-cliを使っていても、Cのライブラリに依存したmrbgemを追加するとリンクやクロスコンパイル環境の準備が面倒
  - 例えばmruby-cli上でmruby-onig-regexpのWindows向けのクロスコンパイルがうまくいかない

# Rubyのスクリプトを評価するCLIツールはどんな時にmrubyで実装するべきなのか
これまでの話を総合すると、「mrubyを使ってCLIツールを実装すると、mrubyのエコシステムの成熟度的にメンテが大変になる代わりに、ツールを実行するまでのコストを下げることができる」という話になる。デメリットに上げた部分は **がんばれば** どれも解決可能な点が重要で、ツールを実装する時にがんばるのと、CLIツールを配布・実行する時にがんばるのとどちらが大変かで決めればよさそう。

で、技術選定の基準となりそうな事象のそれぞれにかかるコストを比べ、僕はmrubyで作るかどうかを以下のような基準で考えている。

![](https://i.gyazo.com/95307cf7f9e5b0ac21ce46990f98b73a.png)

<details>
例えば開発環境をMItamaeでセットアップする場合、まっさらなマシンでもセットアップしたいので「実行環境にCRubyを要求できる」が「いいえ」、僕の会社での用途だとhomebrew自体のセットアップもMItamaeのレシピでやっているので「パッケージングした方が実行が楽」が「いいえ」となり「mrubyで実装」になる。
xkremapの場合、僕のデスクトップマシンにはCRubyが入っているので「実行環境にCRubyを要求できる」は「はい」、実行するためにいちいちGemfileとか置きたくないので「Bundler管理下での実行を想定」が「いいえ」、僕のマシンにはrbenvが入っていて、rbenvで管理している特定のバージョンでxkremapが常に入っているようにしたりrbenvのコマンドを叩いて起動するのが面倒だし、かといってsystem rubyを使うとインストールに無駄にsudoが必要になるし、かつxkremapの実装コストのボトルネックになるXlibプログラミングではRubyのバインディングが用意されていてもさほど助からない(Cでの例やドキュメントが多いので、Cで書いた方が楽)のと、僕が既にMItamaeでmrubyに慣れているので、「mrubyで実装するよりrbenvについて考える方が面倒」が「はい」となり「mrubyで実装」になる。
</details>

まあrbenvについては大分細かい話な気もするが、rubygemでインストールしたツールの実行時にrbenvに悩まされたことがある人は普通にいるんじゃないだろうか。

# お気持ち
mrubyがもっと便利になれば、どんなCLIツールもmrubyで実装した方が手軽で便利、という日も来るかもしれない。

CRubyを使うかどうか迷わせるほどmrubyやそのエコシステムを便利にしてくださっているみなさま、いつもありがとうございます。
== と equals の不思議な関係

# 第一問

---

```java
public class Test {
    public static void main(String[] args){
        Integer i = new Integer(1);
        Integer j = new Integer(1);

        System.out.printf("%b, %b\n", i.equals(j), (i == j));
    }   
}
```

上記のプログラムの実行結果は次のうちのどれ？

1. true, true
2. true, false
3. false, true
4. false, false

---

# 正解

---

# 2. true, false

---

# 解説

---

ここで `"=="` は「参照等値演算子」であり、`i` と `j` はそれぞれ別のインスタンスの参照なので等値とはならない。
インスタンスの「値」が等しいかどうかを確かめたい場合は、`equals` メソッドを使用する。

---

まあこれは入門書や入門サイト的なものに必ずといいほど載っている、初心者のはまりポイント（最初は `==` を使いがち）である。

---

# 第二問

---

```java
public class Test {
    public static void main(String[] args){
        Integer x = 1;

        System.out.printf("%b, %b\n", x.equals(1.0), (x == 1.0));
    }   
}
```

上記のプログラムの実行結果は次のうちのどれ？

1. true, true
2. true, false
3. false, true
4. false, false

---

# 正解

---

# 3. false, true

---

# もしかして

---

# == と equals が

---

# 入れ替わってるー！？

---

# 解説

---

# x.equals(1.0) が false になるのは何故？

---

Integer#equals の仕様だから。

```java
public boolean equals(Object obj) {
    if (obj instanceof Integer) {
        return value == ((Integer)obj).intValue();
    }
    return false;
}
```

こんな感じの実装になっていて、型があっていないと無条件で `false` です。

---

# x == 1.0 が true になるのは何故？

---

x は Integer なのであるが、`==` による比較対象が数値リテラルなのでアンボクシングされてプリミティブな数値同士の比較になる。第一問の `==` とはそもそも別物なのである。
入れ替わってるのは `==` と `equals` じゃなくて、実は `==` と `==` なのでした。

---

# 終わり
今時のErlangプロジェクトの作り方(1/3)

# 言語のバージョン管理はkerl
kerlを使うと最新バージョンのErlangで開発しながら、古いErlangプログラムをメンテするなどができて便利。

## まずパスを通す
~/bin フォルダを作って、その中のプログラムをどのフォルダでも実行できるようにするbashの場合の設定例です。すでに設定済みに方はスキップして構いません。

```shell-session
mkdir -p ~/bin
echo "export PATH=$PATH:~/bin" >> ~/.bashrc
source ~/.bashrc
cd ~/bin/
```

## kerlを入手

```shell-session
wget https://raw.githubusercontent.com/kerl/kerl/master/kerl
chmod 0755 kerl
```

## 特定バージョンのErlangをインストール
~/bin/erlang フォルダ以下にErlangプログラムをインストールする例です。

```shell-session
mkdir -p ~/bin/erlang
```

どのようなバージョンがあるか確認します

```shell-session
% kerl list releases
R10B-0 R10B-10 R10B-1a R10B-2 R10B-3 R10B-4 R10B-5 R10B-6 R10B-7 R10B-8 R10B-9 R11B-0 R11B-1 R11B-2 R11B-3 R11B-4 R11B-5 R12B-0 R12B-1 R12B-2 R12B-3 R12B-4 R12B-5 R13A R13B01 R13B02-1 R13B02 R13B03 R13B04 R13B R14A R14B01 R14B02 R14B03 R14B04 R14B R14B_erts-5.8.1.1 R15B01 R15B02 R15B02_with_MSVCR100_installer_fix R15B03-1 R15B03 R15B R16A_RELEASE_CANDIDATE R16B01 R16B02 R16B03-1 R16B03 R16B 17.0-rc1 17.0-rc2 17.0 17.1 17.3 17.4 17.5 18.0 18.1 18.2 18.2.1 18.3 19.0 19.1
```

この時点で一番新しい19.1をインストールしてみます。
ダウンロードに約5分、ビルドに約8分かかりました。

```shell-session
kerl build 19.1 19.1
```

ビルドが終わったら ~/bin/erlang/ 以下にインストールします。

```shell-session
kerl install 19.1 ~/bin/erlang/19.1
```

最後にactivateする事で、どのフォルダでもErlangのコマンドが使えるようになります。

```shell-session
which erl # erlコマンドが見つからない
source ~/bin/erlang/19.1/activate # activateする
which erl # erlコマンドが見つかる！
```

## erlコマンドを使ってみる

```shell-session
erl
Erlang/OTP 19 [erts-8.1] [source] [64-bit] [smp:4:4] [async-threads:10] [kernel-poll:false]

Eshell V8.1  (abort with ^G)
1> 1 + 1.
2
2> io:format("hello world~n").
hello world
ok
3> 
User switch command
 --> q
```


## まとめ
お疲れ様でした。
これで様々なErlangのバージョンを切り替えながら使う事ができるようになりました。
次はビルドツールのrebar3を使ってみます。
[Xamarin.Forms] 新機能！ NativeのUIが xaml で使える！？

# はじめに
11月の下旬に Xamarin.Forms 2.3.3 がリリースされました。:tada:
内容は予定通り 新機能の **`Native View`** です。

その 2.3.3のリリースに合わせ、Xamarinの公式サイトでは
Xamarin.Forms の欄に２つの項目が追加されました。

今回はそれを読みつつ記事を書いていくつもりです。


# Native View
Native Viewは名前の通り 各プラットフォーム(iOS,Android,UWP)のAPIを
共通のプロジェクトである、 PCL の xaml で呼び出して使うことができます (Xamarinでは, 各プラットフォームのことをNativeといいます)。
iOSだったら UIKit 　Androidだったら widget 等々を呼び出してコーディングすることができます。
もちろん各プラットフォームごと呼び出されるので、お互いに影響することはできません。

例えば StackLayout で `ios:UILabel androidWidget:TextView win:TextBlock` と順番に宣言したとしても
StackLayout の Children は１つです。

## 使用方法
簡単です。
使いたい Xaml におまじないを書くだけです。[公式](https://developer.xamarin.com/guides/xamarin-forms/user-interface/native-views/#Consuming_Native_Views)の説明では画像のとおりです

<img width="873" alt="スクリーンショットXamlサンプル.png" src="https://qiita-image-store.s3.amazonaws.com/0/64093/7d3ced5c-0dba-ebc6-ac6b-9ca946025829.png">

ポイントとして
なぜ、各プラットフォームごとでコンパイルされるかというと
各宣言の末にある `targetPlatform=` でパッケージごとに分けてあげています。

この `targetPlatform` を見てくれてるわけです。
そして実際に宣言するときは

<img width="765" alt="スクリーンショットXamlサンプル2.png" src="https://qiita-image-store.s3.amazonaws.com/0/64093/18e18977-d8ae-b78e-64ca-a9231f39c537.png">

と宣言してあげれば、あとは自由に使えます。簡単ですね。

※　xmlnsでの宣言は使いたい assembly を指定します。
ある程度の Xamarin 独特の知識が必要ですが、大体各プロジェクトに入っているのでそれを見ればいいと思います。
例えば Android なら Widget だけなら問題ないのですが、 Graphics は別 assembly ですので忘れないよう注意が必要です。

## Yes バインディング 　No コードビハインド
じつは Native View には弱点があります。それはコードビハインドが現状使えないことです。
考えてみると納得ですが、そもそも assembly の指定を切り替えて実現しています。

UILabel に `x:Name` と付けてもこれが UILabel であるために
コーディングではどうしようもありません。そこで Binding です。
`Label.Text = "テキスト" `とやりたい気持ちを抑え、
xamlで `Text="{Binding Sample}"`とやりましょう。
あとは xaml.cs で `INotifyPropertyChanged` を実装してあげるなり好きにしましょう！

## それでも俺は コードビハインド がしたい
はい。できます。 流石ですね。
そんな人には　はい `Shared project` （PCLと別の方法）。
やってみるのは簡単ですが、 Native View ができてからはもう少しスマートにコーディングできると思います。
`Xamarin.Forms.Platform.Android.NativeViewWrapper`
`Xamarin.Forms.Platform.iOS.NativeViewWrapper`
を使いキャストしてあげることで、ちょっとしたコーディングが簡単にできます。

私的には この [ドキュメント](https://developer.xamarin.com/guides/xamarin-forms/user-interface/native-views/#Referring_to_Native_Views_from_Code) をみて、やりたくなりました（時間がないのでできない。つらい。）。

# まとめ

[Platform Specifics](https://developer.xamarin.com/guides/xamarin-forms/user-interface/platform-specifics/)
`Native View`は 公式ドキュメントで サンプルコードが載っています。
ここでは、 `Consuming Platform-Specifics` として Native View を使ったサンプルがあります。
他にも `PlatformConfiguration` を使っていたりと改めて読んでみて参考になりました。

`Consuming Platform-Specifics` はドキュメントからすると 
実行した時にプラットフォームごとの違いを分ける　としての立ち位置です。
（逆に、 `Creating Platform-Specifics` は、
先にプラットフォームごとの違いを分けて作る かなと思います。）

Xamarin.Forms にとって プラットフォームごとに作るのはあまり望ましくないですが、
昔に比べて少しの違いなら、 Xamarin.Forms の機能だけで簡単にコーディングできるようになりました。

昔からやっている人はすぐに `CustomRenderer` と言いますが、今では昔ほど頼ることはないと思います。

みなさんも是非 使ってみてください。
CSSでSan Franciscoを指定する(2017年版)

ちょっと前，San FranciscoをCSSで指定する方法がむずかしいという話を見聞きしたので，調べてみました。
話題としては2015年のものですが，当時から若干状況が変わったりしていますのでおさらいがてら眺めてみていただけますと幸いです。

# San Franciscoというフォント

iOS9やOS X El Cpitanからシステムフォントとして指定されているフォントです。
もともとはHelveticaが指定されていたのですが，小さいサイズのときに読みにくいという弱点があるらしく，
San Fransiscoがシステムフォントとして指定されたようです。

# San FranciscoをCSSで指定する

[demo1](http://jsdo.it/raryosu/Iyit)
demo1はCSSで以下のように指定しています。

```css
body {
    font-family: "San Francisco", Sans-Serif;
}
```

どうでしょうか，OS Xなみなさんも，macOSなみなさんも，iOSなみなさんも，Arialになっていることがわかると思います。
要するに，San Franciscoというやつは，単にCSSでSan Franciscoと指定しても無駄ということです。

ではどうやって指定するかというと，以下のようにします。

```css
body {
    font-family: -apple-system, Sans-Serif;
}
```

こんな感じの指定をすると次のようになります。

[demo2](http://jsdo.it/raryosu/UCJh)

あれ？上と変わらないじゃん，と思ったChrome on Macユーザの皆さん。そうなんです。Chromeでは `-apple-system` という指定ではSan Franciscoが指定されません。
Chromeにも対応させようと思うと，こんな感じになります。

```css
body {
  font-family: -apple-system, 'BlinkMacSystemFont', Sans-Serif;
}
```

`BlinkMacSystemFont` はChromeやOpera(レンダリングエンジンがBlinkのブラウザ)でSan Francisco(というよりMacのシステムフォント)を使うという指定です。

[demo3](http://jsdo.it/raryosu/IeT9)

めんどくさいですね。

ちなみに，weightを変えようと思ったら，普通に `font-weight` を指定すればいいです。

[demo4](http://jsdo.it/raryosu/yC7t)

# まとめ

San FranciscoをCSSで指定するときには，次のようにしましょう！！

```css
body {
  font-family: -apple-system, 'BlinkMacSystemFont',  Sans-Serif;
}
```

なんか，スマートじゃないなぁ…

# ちなみに

日本語の指定なんかは，この後ろに追記していくと良いです。例えば，

```css
body {
  font-family: -apple-system, 'BlinkMacSystemFont', 'Hiragino Kaku Gothic ProN', 'メイリオ', Sans-Serif;
}
```

などなど。

日本語といえば，日本語表示が最適化されたBootstrapテーマ，[Honoka](http://honokak.osaka)があります。

このHonokaのForkテーマであるところの「[Rin](https://rinhoshizo.la)」をForkして作りました。
ぜひ使ってみてください💕


# 参考

* https://medium.com/japan/apple-%E3%81%AE%E6%96%B0%E3%83%95%E3%82%A9%E3%83%B3%E3%83%88-san-francisco-%E3%81%AE%E7%A7%98%E5%AF%86-45becaae035a#.qkurbedw6

* https://developer.apple.com/fonts/

* http://stackoverflow.com/questions/32660748/how-to-use-apples-new-san-francisco-font-on-a-webpage