OmniAICreator/Qiita-1.07M huggingface dataset:
unityで横スクロール2Dアクションを作る一連の流れを追ってみた　～準備編～

#冒頭の挨拶

こんにちは！
**こちらの記事は[高知工科大 Advent Calendar 2016](http://www.adventar.org/calendars/1872)の18日目の記事に当たります（たぶん）**
自分は機械が専門で、他の方は情報寄りのことをたくさんなさってるので、この記事が役に立ったという方は多分他の記事を見ると失禁するので、是非他の方の記事も御覧ください
ちなみにこの記事を書くに至った経緯を軽くご紹介しますと

同期「書かないか？」
自分「ウホッ！いい企画…」

というわけで、せっかくなので自分の中でずっとやってみたかったことのうちのひとつ、2D横スクロールアクションゲーム製作を行い記事にしようと思いました。どんなにクソゲーになってもいいのでこの際につくりあげてみようと思います
多分長くなりそうですがお付き合いください(たぶん記事を分けると思います)
あと関係ないですけどお付き合いくださる女性募集中です

#ここから本編
##目次(つくるまでの流れ)
1.製作ゲームの草案を作る
2.製作ゲームに必要なオブジェクトを全て書き出す
3.オブジェクトのグラフィックを用意する
4.主人公の動きを作る
5.ステージギミックを作る
6.量産、ステージ全体の流れを作る
7.テストプレイ、修正
8.ゲーム投稿（できればここまでしたい)

テストプレイ、修正については、最後にまとめてやるような書き方になっていますが、動きを作り始めたら、テストプレイは繰り返し行うことになると思います
ちなみに今回の記事は3までです（まさかのunity登場しません)

##１． 製作ゲームの草案を作る
まずはどのようなゲームを作るのかを考えましょう
僕自身、横スクロールアクションゲームを制作しようと奮闘したことはありますが、最後まで作り上げたことはないので、できるだけ簡単なものにしようかと思います
もちろん作りながらの変更も十分に有りえますが、とりあえずの方針を決めて動き出さないことには何も世界は変わりません

というわけで、草案というか、アイデアノートと爪切りです

![IMG_20161211_105124.jpg](https://qiita-image-store.s3.amazonaws.com/0/103256/e339a648-c17e-01d6-b122-c3974853315d.jpeg)

こんな感じで適当に書いてイメージをふくらませると楽しいですね(^o^)

##２．製作ゲームに必要なオブジェクトをすべて書き出す
ざっくりとでも草案が決まりましたら必要そうなオブジェクトを書き出しましょう
ここで書き出しておくと今後の作業量が目に見える形となるのでモチベーションの維持に役立つと本に書いてました！

- 主人公
- エネミー
- ビュレッド（主人公用）
- ビュレッド（エネミー用）
- ボスキャラ
- 床

的な感じですかね

##３．オブジェクトのグラフィックを用意する
では上に示したオブジェクトのうち、グラフィックが必要なものは用意していきましょう
ここで絵がかけないよ～って方が頓挫するポイントかなと思うんですが、無理に絵を書く必要はありません。
最強なものがこの世にはあるのです
それこそが**フリー素材**
フリー素材で作り上げれば技術力はつきます
そもそも絵を書く技術とゲームを制作する技術は全くの別物だと思いますので、あまり気張らずに今回はゲームを作り上げることだけ考えましょう
ちなみに、少しだけ注意ですが、フリー素材と書かれてはいますが、たぶん利用規約がついていると思います。利用規約はしっかり守って、フリー素材の提供に感謝しながら利用させていただきましょう
まあ今回は自分で書きますがね
ではそれぞれ書いていきましょう。絵のビジュアルはあまり重視しないことにしてください(；´∀｀)

使うソフトは[edge](http://takabosoft.com/edge)っていうソフトです
ドット絵を書くときはかなり重宝します
僕はあんまりうまくないですが、ドット絵の勉強には
[ドット絵描こうZ](http://blog.livedoor.jp/dotez/)
このサイトを参考にしました
今回つかう主人公は誰にでもかけます
あと主人公は歩く予定なので、何枚か用意しておきます
主人公
![qiita貼り付けよう.png](https://qiita-image-store.s3.amazonaws.com/0/103256/dcec46ea-3cac-2cd9-2026-289b6b0cb26e.png)
エネミー
![qiita貼り付けよう2.png](https://qiita-image-store.s3.amazonaws.com/0/103256/62d48806-9ad2-89b0-39b7-6b7d72ec5875.png)
ビュレッド（主人公用)
![qiita貼り付けよう3.png](https://qiita-image-store.s3.amazonaws.com/0/103256/f0cd0092-2d66-8682-6ecd-16199db4c859.png)
ビュレッド(エネミー用)
![qiita貼り付けよう4.png](https://qiita-image-store.s3.amazonaws.com/0/103256/308565af-5bba-7bcf-6266-00ec1bd14141.png)
床は茶色一色にします
ボスはシステムにも関わってきますので、あとで作りながら描いていこうと思います
ゲームの基本システムを作ることはできる程度の絵にはなったんじゃないかなと思います

##3.5　unityインストール
ついにunityの登場です
と、ここまできて自分のパソコンにunityがインストールされていないことに気づいてしまいました(；´Д｀)
忘れとった
以下のサイトからインストールできるはずですのでもししてなくて興味持たれた方はインストールしてみてください

[unity HP](http://japan.unity3d.com/)

インストールをしたことで作り出す大方の準備は整ったことになります。
記事が長くなったので、ここで一旦区切ります
次回の記事で実際にunityを使います

続きも18日に上げる予定でしたが、うまく行きませんでした(；´Д｀)
申し訳ありませんが、25日までには続きを仕上げますので、よろしくお願いします
Google Container Registryにログインする

今までずっと自前のレジストリを使っていましたが、色々と面倒なのでGCRを使うことにしました。
GCRを使う場合は、以下のようにoauth tokenで認証します。

```fish
x> docker login -u oauth2accesstoken \
  -p (gcloud auth print-access-token) \
  https://asia.gcr.io
```

簡単でいいですね :)
pwgen でランダムなパスワードを生成する

# はじめに

pwgen を使うと、ランダムなパスワードを生成することができます。
筆者は、 [1password](http://1password.com) と組み合わせて使ったりしています。

この記事は Mac で使うことを前提に書いています。 Linux でも pwgen をインストールすれば同様のことが出来ると思います。

# インストール

HomeBrew を使います。

```
$ brew install pwgen
```

# 使い方

## 16文字のランダムパスワードを1つ生成する

```
$ pwgen -s 16 1

kbtrIsNAONtQUtg9
```

``-s`` はなくても生成できますが、あった方がよりランダム性の高い、セキュアなパスワードが生成されます。
最後の ``1`` は作成する個数を表しています。

## 32文字の記号ありランダムパスワードを4つ生成する

```
$ pwgen -s -y 32 4

&(0Lw2>j"$k#"ou`{+$oRu}'_"??SI/N {Mufl3_{U8F&Y{:;m`vS5/yzP0O`K_YR
^-LW&S=~q-^Lpc,UC5zu.cd6`h[[.d5Z t#@ev{>6_p8P#TcXSBS>rLH-$@7,~|W?
```

``-y`` をつけると、記号を含めてランダム文字列を生成します。

# コマンドオプションの説明

### ``-c``, ``-A``

* ``-c`` 少なくとも 1 つの大文字を含めます
* ``-A`` 大文字を含めません

### ``-n``, ``-0``

* ``-n`` 少なくとも 1 つの数字を含めます
* ``-0`` 数字を含めません

### ``-y``

* 記号を含めて生成します

### ``-s``

* ランダム性の高いパスワードを生成します

### ``-B``

* あいまいな文字列 (``0`` と ``O`` など) を含めません
Dockerfile

## Dockerfileとは
>Docker は Dockerfile から命令を読み込み、自動的にイメージを構築できます。 Dockerfile はテキスト形式のドキュメントであり、コマンドライン上でイメージを作り上げる命令を全て記述します。ユーザは docker build を使い、複数のコマンド行の命令を順次実行し、イメージを自動構築します。

makeみたいなものかな？
イメージを作るための。

## ビルドについて
>docker build コマンドは Dockerfile と コンテクスト(context；イメージに含まれる「内容」の意味) に従ってイメージを構築します。構築用コンテクストとは、ファイルを示す PATH や URL の場所です。 PATH はローカルのファイルシステム上のディレクトリです。 URL は Git リポジトリの場所です。

Gitリポジトリを指定すればどの環境からもビルドできるということかな？便利かも。

## Dockerfileの記述
>命令 引数
（命令は大文字小文字を区別しない）

### コメント
 #をつける（文字列内はコメント扱いしない）

### パーサディレクティブ
\#に続く特定の文字列を指定すると
文字列により特殊な操作ができる
#### escape
エスケープ文字を変更する
```` docker:例
\# escape=`
````
これによりWindowsのバックスラッシュがエスケープされるのを防ぐことができる

## FROM
ベースイメージを指定する
パブリックリポジトリからイメージを取得するのが一般的

```` cocker:nodeの場合
FROM node:latest
````

[参考URL]http://docs.docker.jp/engine/reference/builder.html
RedmineからSVNのデータを自動で取得する設定

SVNのほうでコミット後にRedmineにデータを更新するように通知を行う必要がある。
具体的には、下記のファイルを作り、
`$ more /home/svn/repos/bio/nbb.ddca-job/hooks/post-commit`

```bash:post-commit
#!/bin/sh
REPOS="$1" 
REV="$2"
```

`/usr/bin/wget -q -O /dev/null http://192.168.1.47/redmine/sys/fetch_changesets?key=ZEOzxKhipA1uMOPGSlpZ`

あとは、実行権限を与える。
`chmod 755 /home/svn/repos/bio/nbb.ddca-job/hooks/post-commit`
vagrant upとvagrant sshを自動で行わせる方法

毎度仮想環境に入るためにGitBashにてvagrant upとvagrant sshするのが面倒だったので、メモとしてこの作業を自動で行わせるための方法を記しておきます。ちなみに手順はとても簡単です。


##以下手順
①ホームディレクトリにて.bash_profileファイルを作りましょう。
GitBash上にて以下のように打ち込むとファイルを作成できます。

```
touch .bash_profile
```

②エディタにて.bash_profileファイルを開き以下のようにコードを書き足します。

```
echo 
  cd ~/vagrant
  vagrant up
  vagrant ssh
fi

```

以上で終わりです。GitBashを開くとvagrantまで移動しvagrant up及びvagrant sshまで自動で行ってくれます。

しかし、毎回勝手に仮想環境に入られてしまっては不便なので今回は'v'と打ち込んだらvagrant sshまで行ってくれるようにカスタマイズしましょう。

③.bash_profileを下記のように更新する。

```
echo "please type 'v' and Enter if you want start vagrant"
read input
if [ $input = 'v' ]; then
  cd ~/vagrant
  vagrant up
  vagrant ssh
fi

```

これでGitBashを開くと最初にinput画面が表示されます。ここで'v'と打ち込めばvagrant sshまでの手順が自動で行われます。もし'v'以外のコマンドを打ち込むとvagrant up及びvagrant sshは行われずに通常時の画面に移ります。
プログラミングについて語るときに僕の語ること

<h1>自己紹介</h1>

はじめまして。
谷田ティムと申します。
ドイツから来た日本人・ドイツ人のハーフです。
Fusicでは10月からインターンシップが出来、とても運が良かったです。

この研修期間内でプログラミング技術に付いて何を習ったかに付き報告致します。
この3ヶ月で僕のプログラミングに対する見方・考え方が大きく変わりました。

<h1>今までのプログラミングの経験</h1>

僕は現在ミュンヘンの工科大学で機械工学を勉強をしています。
そのため、C言語以外は殆どプログラミングに関する知識を持っていませんでした。
素人の僕はプログラミングとは単純な作業だと考えていました。
プログラムの舞台裏にはどんな努力があって、どれ程細部への拘りがありまた綺麗なコードというものがどれ程重要なことか理解していませんでした。

<h1>研修の初めの数週間</h1>

研修の初めにはWebプログラミングの基本を習いました。
YouTubeで見つけたビデオチュートリアルを利用して素早くHTML, CSSやjQueryを習いました。
特にjQueryの様々なAPIを使って格好の良いサイトを作る事が出来て嬉しかったです。

その頃、やっとプログラミングでは一切のエラーが許されないということを理解することができました。
どれ程細かい細部に渡り間違いなく設定しなくてはならないという事です。

時々、コードが一つのバグで動かない事があり悔しく感じましたが、同時に僕は犯罪場所で事件を解くために一つの証拠を探している探偵みたいな気分になりました。

そしてそれを見付け出し、バグを外したコードが思い通りに動いた時はとても満足することが出来ました。

プログラミングではルールを守ってバグやエラーを排除する事が出来たら、自由になんでも作ることが出来る事を認識しました。

<h1>CakePHPとの経験</h1>

デ一タべ一スとSQLの知識を少し学んだ後はCakePHPに挑戦しました。
そこで初めて会社のために管理プログラムを作る仕事を与えられました。
最初は全てとても難しかったので会社の先輩に何度も質問をしなくてはならなかったです。

でも今は、CakePHPの使い方やフレームワークが段々明らかになり、同時にプログラミングが何であるかが分かりました。

プログラミングとは芸術である事。

CakePHPがフレームに囲まれた空のキャンバスとしたらプログラマーはそれを描く芸術家。
守らなくてはいけないルールや約束はあるけど、それ以外プログラムをどうやって作り上げるか全く自由。
プログラムが機能しても綺麗なコード(美しい絵画)とまずいコード(美しくない絵画)がある事。

<h1>まとめ</h1>

Fusic での研修を通じて簡単なプログラムを作成するのにも多くの作業と、想像力が必要とされる事が分かりました。

そして僕のプログラミングスキルはまだまだ高くないですが、この3ヶ月で問題解決能力や批判的思考が随分上がったと思います。

将来的には今回Fusicで学んだプログラミングスキルをいつか機械工学のエリアで利用したいです。
Node.jsでPerl CGI::Sessionで生成されたSessionIDからセッションを取得する

またアホな事を試してみる。

Windows 10 環境のPCでのテスト
Perl v5.20.1
Node v7.2.1

PerlのCGIが動く既存サーバー内でNode.jsのWebSocketを追加して共存させることを想定。
※もしCGI::Session::MySQLなどで動いているならファイルではなく直接MySQLを読み込んで同じことすればいいかな。

##とりあえずセッションファイルを読み込んでみる
とりあえず読み込むところから。
セッションファイルは``cgisess_`` + ``セッションID``のファイル名で、CGI::Sessionの使用時に指定したパスに保存されているので
後からファイル名部分を加工して読み取ろうと思う。

```javascript:test.js
var fs = require('fs');
fs.readFile('C:\\.session\\cgisess_0adf7392151ba60afcc05e65f398df23', 'utf8', function(err, text) {
	if(text){
		console.log(text);
	} else {
		console.log(err);
	}
});
```

```text:出力結果
$D = {'_SESSION_ETIME' => 7200,'_SESSION_ID' => '0adf7392151ba60afcc05e65f398df23','_SESSION_REMOTE_ADDR' => '::1','_SESSION_ATIME' => 1481824332,'_SESSION_CTIME' => 1481824330};;$D
```

セッションファイルの中はPerlのハッシュ定義みたいなのが書いてある。
##これをごにょごにょしてjson化してオブジェクト化してみる。

```javascript:test.js
var fs = require('fs');
fs.readFile('C:\\.session\\cgisess_0adf7392151ba60afcc05e65f398df23', 'utf8', function(err, text) {
	if(text){
		var m = text.match(/^\$D = (.+);;\$D$/);
		var data = m[1].replace(/=>/g, ':').replace(/'/g, '"');
		console.log(JSON.parse(data));
	} else {
		console.log(err);
	}
});
```

```text:出力結果
{ _SESSION_ETIME: 7200,
  _SESSION_ID: '0adf7392151ba60afcc05e65f398df23',
  _SESSION_REMOTE_ADDR: '::1',
  _SESSION_ATIME: 1481824332,
  _SESSION_CTIME: 1481824330 }
```

オブジェクト化もできた。
##CGI::Sessionの説明書きによると、各項目は以下の通り。

```
_SESSION_ID
そのデータに対するセッションidです。id()メソッドを通してアクセスできます。

_SESSION_CTIME
セッション作成時刻です。ctime()メソッドを通してアクセスできます。

_SESSION_ATIME
セッションの最終アクセス時刻です。atime()メソッドを通すことでアクセスできます。

_SESSION_ETIME
もしあれば、セッションの有効期限を示します。expire()メソッドを通してアクセス できます。

_SESSION_REMOTE_ADDR
そのセッションを作成したユーザーのIPアドレスです。remote_addr()メソッドを通して アクセスできます。

_SESSION_EXPIRE_LIST
もしあれば、それぞれの有効期限付き公開レコードに関する有効期限の情報を入れた もう一つの内部的なハッシュテーブルとなります。このテーブルは２つの引数を持つ 方のexpires()メソッドの文法を用いることによって更新されます。
```

Node.js側の現在時刻と比較する場合は``_SESSION_ETIME`` ``_SESSION_ATIME`` ``_SESSION_CTIME``をそれぞれ1000倍してミリ秒化してDate()に読み込ませれば、現在時刻との比較ができそう。

##関数化

```javascript:
function getSession(sid){
	var fs = require('fs');
	var text = fs.readFileSync('C:\\.session\\cgisess_' + sid, 'utf8');
	if(text){
			var m = text.match(/^\$D = (.+);;\$D$/);
			var data = m[1].replace(/=>/g, ':').replace(/'/g, '"');
			var session = JSON.parse(data);
			session._SESSION_CTIME *= 1000;
			session._SESSION_ATIME *= 1000;
			session._SESSION_ETIME *= 1000;
			//現在時刻
			var now = new Date();
			//制限時間
			var limit = new Date(session._SESSION_ATIME + session._SESSION_ETIME);
			//現在時刻が制限時間を超えていたらアウト
			if(now.getTime() >= limit.getTime()){
				return undefined;
			}
			return session;
	} else {
		return undefined;
	}
}
```

これでPerlのCGIとNode.jsで動かしているWebアプリケーションで同じセッションIDを共有できちゃうかもしれない。

わくわく

<span class='label label-default'>追記</span>
Perl側でSessionにSetしたユーザーの情報もこのファイルにハッシュとして保存されるているので、Node側で取得できるようオブジェクトで返しています。IPアドレスの比較をしたいときは_SESSION_REMOTE_ADDRを見てで自前でやる感じで（手抜き）
fsオブジェクトがreadFileSyncでファイルをopenする時にread onlyにするかどうかの情報が無かったのでロックの可能性の確認はできてないので、もし気になるなら、``fs.open(path, "r")``で開いて下さい。
技術英語 > If that is your intent. / That's not what I mean.

@ Star Trek Voyager > THE THAW

ある方法に関してのTuvokとJanewayのやりとり。
xxxという方法があります、の後に

Tuvok: **<font color=red>If that is your intent</font>**.
Janeway: It is.

<hr>

コードの意図(intent)を以下に後世に残すか。
記憶に依存しない方法にしておかないと。数年後に数多に増えた自分が関わったプロジェクトの中の１つの詳細を覚えている自信はない。

<hr>
関連して思い出したのは

> That's not what I mean.

http://ejje.weblio.jp/content/That's+not+what+I+meant.

weblioの方は「meant」で過去形。
`what I mean`の方は現在形。
bitFlyer APIを利用して自動的にマネーを次世代通貨にフォワードする

## ビットコイン買っとく?

去年くらいからビットコインを少しずつ買っています。
少しずつではありますが、世界で利用できるところも増えてきていて未来を感じるというのと、ギリシャがデフォルトしそうになったりしたし、元来の通貨も不安定だなと思ったので、金みたいな実物資産の感覚で、リスク分散のために保有することにしました。

ビットコインの価格は[今年1年で2倍に上昇する](http://jpbitcoin.com/markets)など、値動きが激しくて怖いですし、別に儲けようとしているわけでもないので、[ドルコスト平均法](http://www.sc.mufg.jp/products/stock/ruitou/cnst_d_plan.html)で積み立てていこうと思いました。

## 自動化した

毎月手で購入していたんですが、[bitFlyer](https://bitflyer.jp)なら[API](https://bitflyer.jp/ja/api)があることを知り、自動化しました。

最初はRubyで書いてみたんですが、AWS Lambdaの習作にでもするかと思いたってしまったのでやってみました。

### bitFlyer APIキーを取得

bitFlyerのAPIキーは以下のURLから取得できます。

https://lightning.bitflyer.jp/developer

「新規注文を出す」権限だけで大丈夫です。

![image](https://qiita-image-store.s3.amazonaws.com/0/882/6f446594-47fa-da90-b302-0a0bed215375.png)

### lambda functionを作る

https://github.com/makiton/bitflyer_buyer/blob/master/bitflyer_buyer.py

[yagays/pybitflyer](https://github.com/yagays/pybitflyer) を使わせてもらいました。

標準で入っていないモジュールをLambdaの環境で利用するには、ローカルでインストールしてzipに固めてアップロードする必要があります。

[デプロイパッケージの作成 (Python) - AWS Lambda](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/lambda-python-how-to-create-deployment-package.html)あたりを参考にしてください。

[AWS Lambda](https://ap-northeast-1.console.aws.amazon.com/lambda/home)のダッシュボードから`bitflyer_buyer.lambda_handler`をhandlerに設定してfunctionを作ります。
こんな感じ。

![image](https://qiita-image-store.s3.amazonaws.com/0/882/9c9a7483-83a7-bba5-8ab5-c0fdcb2f28b7.png)
![image](https://qiita-image-store.s3.amazonaws.com/0/882/777e409d-b564-ebaa-2622-8e82a129d8bd.png)

環境変数にはbitFlyerで取得したAPIキー、シークレットを入れてください。
今回はKMSに格納した鍵で暗号化しています。

### スケジュールの作成

動作確認できたら、[AWS CloudWatch](https://ap-northeast-1.console.aws.amazon.com/cloudwatch/home)から定期的にLambdaを実行するように設定します。

cron式で設定する際は、時刻がGMTなので気をつけてください。

![image](https://qiita-image-store.s3.amazonaws.com/0/882/e09a2e92-e8b0-4fa1-ab57-5755729b8aa6.png)

これで毎月自動的に日本円がビットコインに!

## さいごに

念のため、上記スクリプトの利用、投資はご自身の判断で、自己責任でお願いします。

残念ながら、現状日本円の振込は手でやる必要があります。
半年に1回くらい、まとまったお金を入れておくことにしています。

ビットコインの保管は、ひとつの取引所に置いておくとリスクが大きいので、別のアドレスに定期的に自動転送して、より安全な形で保管できるようにしたいなと思っています。

bitFlyerについては、[マネーフォワードも対応しています](https://moneyforward.com/accounts/new/drv_bitflyer)ので、アカウントをお持ちの方はぜひ連携もしてみてください。
タイムラプス動画の自動速度調整の試み（寄り道編）

タイムラプス動画の研究だと動画からってのが普通なのでしょうか。
５秒間隔の連続画像（動画？）とかはきっと需要が無さそうですね。

こんなブログを見つけました。

[超滑らかなタイムラプスを作る Hyperlapse を試してみた – PLAYGO.jp](http://playgo.jp/1410/)

Microsoft Research が 2015年の SIGGRAPH に出したものみたいです。

http://research.microsoft.com/en-us/um/redmond/projects/hyperlapseapps/
ここからMac版をダウンロードしました。

普通、カメラの位置が常に変動しているような動画とかを８倍速にする時使うのでしょうが
５秒間隔の連続画像を**そのままの長さで出力する**ような設定で使ってみました。

以下比較動画です。

https://youtu.be/r6x3OzrDjtg
[![](https://i.gyazo.com/026d74b6a7eb4c0be73a3c61b8d3f82b.gif)](https://youtu.be/r6x3OzrDjtg)

Youtubeのスタビライゼーション的な機能を試した時にも起きましたが
カメラが動いていない時には変な感じになりますね。

下のサービスエリアに止まっている時とかです。

<img width="862" alt="Screen Shot 2016-12-18 at 05.11.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/32636/6c95d218-1835-4f1b-9a1b-f5dcc19108ac.png">


終わりです。。
Githubのリポジトリのスター数の日ごとの遷移を見る

## やりたいこと

Github上の任意のPublicリポジトリで時系列でスター数の遷移をだしたい。

## やったこと

先に結果(？)です

データ取ってくるスクリプト
[get_repo_stars.sh（Gist）](https://gist.github.com/simeji/2d68d6fe2212934ad18068f5eedb34bb)

出したグラフ（スター数の遷移）

![スクリーンショット 2016-12-18 4.44.25.png](https://qiita-image-store.s3.amazonaws.com/0/30588/c9c06144-d422-9cc3-e100-dff4597386d1.png)


## やりかた

GithubのAPIで取ります。今回使うAPIは認証不要の機能です。

つかうAPIはこれです。
[List Stargazers](https://developer.github.com/v3/activity/starring/#list-stargazers) 

ドキュメントにも書いてありますが、スターがついた日時を出すのは、以下の `Accept` ヘッダーが必要です。

```bash
Accept: application/vnd.github.v3.star+json
```

たとえば、 [simeji/jid](https://github.com/simeji/jid) の各スターがつけられた日時を取りたいときは以下のようにします。

```bash
curl -s "https://api.github.com/repos/simeji/jid/stargazers?page=1&per_page=100" -H "Accept: application/vnd.github.v3.star+json" | jq -r '.[].starred_at'
```

ただ、このAPIは100件ごとしか取れないので、自動的にやろうと思ったら、
```
curl -s https://api.github.com/repos/simeji/jid | jq .stargazers_count
```
で取れた件数からページ数を算出してその分だけループさせます。

で、取れた日時の値を日と時間に分割して完了。
あとはそれを Googleのスプレッドシートやエクセルに貼り付けて、日毎にまとめたりしてグラフ作りたければつくります。

上記をまとめたシェルスクリプトが以下のスクリプト
[get_repo_stars.sh（Gist）](https://gist.github.com/simeji/2d68d6fe2212934ad18068f5eedb34bb)
です。

## さいごに

スター数がどのように遷移してきたかを見てみると少し面白いですね。
Amazon QuickSightを試してみる

　こんにちは！！　[CYBIRDエンジニア Advent Calendar 2016](http://qiita.com/advent-calendar/2016/cybird)、2年連続 18日目担当の@cy-hiroshi-chibaです。　16日目担当の@yuichi_komatsuと同じくデータ分析のエンジニアをしています。

　昨日は@cy-nana-obataさんの[新卒1年目ド文系女子が初めての社内アイデアソン・ハッカソンのファシリテーターをやってみたの巻](http://www.cybird.co.jp/recruit/engineer/blog/%E6%96%B0%E5%8D%921%E5%B9%B4%E7%9B%AE%E3%83%89%E6%96%87%E7%B3%BB%E5%A5%B3%E5%AD%90%E3%81%8C%E5%88%9D%E3%82%81%E3%81%A6%E3%81%AE%E7%A4%BE%E5%86%85%E3%82%A2%E3%82%A4%E3%83%87%E3%82%A2%E3%82%BD%E3%83%B3/)でした。　CCCの実行委員の他、つい最近まで社内イベントの企画運営も対応していて、時間がない中の投稿大変お疲れさまでした！！

　今日は現在絶賛お試し中の「Amazon QuickSight」について簡単に紹介します。

## [Amazon QuickSight](https://quicksight.aws/)とは

　昨年Amazonの「re:Invent 2015」で発表されたAWSのBIサービスです。　ファイルやAWS内のデータソース、外部のデータベースのデータを簡単に可視化することができます。また、SPICE（Super-fast, Parallel, In-memory Calculation Engine）というQuickSight専用のインメモリデータベースエンジンにより、大規模なデータであっても高速にロードし可視化できるという特徴があります。 　先月一般利用可能になりました。 

![quicksight_hp.jpg](https://qiita-image-store.s3.amazonaws.com/0/100287/f7207987-ce8a-a184-1f7b-e1d24a9e4c79.jpeg)

## 実際に使ってみる
### データソースを選択する
![image](https://qiita-image-store.s3.amazonaws.com/0/100287/be86bd80-3c32-1647-481e-b25fd67f9dba.png)

QuickSightのトップ画面から、左上にある「New Analysis」→「New data set」とクリックしていくと、分析で使用したいデータソースを設定する画面に遷移します。　

![quicksight_create_a_data_set.jpg](https://qiita-image-store.s3.amazonaws.com/0/100287/24f4a29f-7eaa-9dfa-0754-643d50830145.jpeg)

ファイルの場合は、「Upload a file」で分析で使用するファイルをアップロードします。


AWS内のデータソースや、外部のデータベースの場合はアイコンをクリック後、必要項目を入力することで接続できるようになります（QuickSightの[IPアドレスレンジを許可する](http://docs.aws.amazon.com/quicksight/latest/user/enabling-access-rds.html)必要があります）。
  

### 可視化するデータセットの準備をする 
データソースがファイルの場合は、表示するフィールドの選択、計算用フィールドの追加、カラムヘッダー名の変更、表示するデータのフィルタリング、データ形式の変更（文字列、数値、時間）操作ができます。
![image](https://qiita-image-store.s3.amazonaws.com/0/100287/9cd173d3-3ea2-d793-4824-89ef99f8057b.png)

データソースがデータベースの場合はファイルと同様の操作の他、GUI上でテーブルの結合やSQLを使ってデータセットを作成することができます。

![image](https://qiita-image-store.s3.amazonaws.com/0/100287/6fb0f946-9fac-1cd8-caa0-971021d4bc36.png)

### 可視化する
データセットの編集後「Save & Visualize」をクリックするとグラフが表示されます。
![image](https://qiita-image-store.s3.amazonaws.com/0/100287/d888eed3-9175-6066-baba-dd787025932f.png)

グラフに表示するフィールドの切り替えやフィルタリングについては、左側のメニューで操作することができ、グラフのカスタマイズもVisual typesからグラフの選択、グラフ上ではタイトルの編集、軸の設定、色・・・などかなり細かいカスタマイズができます。

![image](https://qiita-image-store.s3.amazonaws.com/0/100287/dbda57b6-d96d-f883-1805-b39b989b646c.png)

## その他
### 共有
分析結果や専用のダッシュボードを作り、他のユーザーに共有することができます。メールアドレスがあれば招待でき、権限管理も可能です。作ったダッシュボード上では細かな編集は出来ませんが、データのフィルタリングや拡大などの操作は可能です。

![image](https://qiita-image-store.s3.amazonaws.com/0/100287/0e83c9b4-9fb5-3242-285a-4cff8865fae5.png)

### ストーリー
Storyという機能では、表示しているグラフの位置をキャプチャーしてストーリーボードを作成することができます。作成したストーリーボードは再生すると、スライドショーのような画面に切り替わります。
![story.png](https://qiita-image-store.s3.amazonaws.com/0/100287/36c9803c-9690-961d-d6b1-6b6b464117b2.png)


## 今のところ
　今回初めて触った状態でも短時間で可視化、様々なカスタマイズも出来るので現在のところかなり印象がいいです。大規模なデータでも高速に集計分析できるため、ゲームログのアドホック分析でも使えるのではないかと思っています。分析結果の共有も安全かつ簡単にできるのもいいですね。　皆さんも是非使ってみてください！！

---
　明日の[CYBIRDエンジニア Advent Calendar 2016](http://qiita.com/advent-calendar/2016/cybird)は、2年連続19日目の@cy-katsuhiro-miuraさんのです！　どんな内容が出てくるのでしょうか？　お楽しみに！
SDカード書き込み速度比較


`/dev/diskX`のかわりに`/dev/rdiskX`に書き込みを行った結果。

# BSCR04U2 + SanDisk 16GB 48MB/s

```bash
$ sudo time dd if=2016-11-25-raspbian-jessie-lite.img of=/dev/rdisk2 bs=1m
1326+0 records in
1326+0 records out
1390411776 bytes transferred in 96.932175 secs (14344172 bytes/sec)
       96.95 real         0.00 user         0.82 sys
```

```bash
sudo time dd if=2016-11-25-raspbian-jessie-lite.img of=/dev/rdisk2 bs=2m
663+0 records in
663+0 records out
1390411776 bytes transferred in 97.694322 secs (14232268 bytes/sec)
       97.81 real         0.00 user         0.59 sys
```

```bash
$ sudo time dd if=2016-11-25-raspbian-jessie-lite.img of=/dev/rdisk2 bs=4m
331+1 records in
331+1 records out
1390411776 bytes transferred in 97.797548 secs (14217246 bytes/sec)
       97.81 real         0.00 user         0.58 sys
```


# BSCR04U2 + SanDisk 16GB 80MB/s

```bash
$ sudo time dd if=2016-11-25-raspbian-jessie-lite.img of=/dev/rdisk2 bs=1m
1326+0 records in
1326+0 records out
1390411776 bytes transferred in 96.677065 secs (14382023 bytes/sec)
       96.79 real         0.00 user         0.66 sys
```

```bash
sudo time dd if=2016-11-25-raspbian-jessie-lite.img of=/dev/rdisk2 bs=2m
Password:
663+0 records in
663+0 records out
1390411776 bytes transferred in 97.791985 secs (14218055 bytes/sec)
       97.93 real         0.00 user         0.61 sys
```

```bash
$ sudo time dd if=2016-11-25-raspbian-jessie-lite.img of=/dev/rdisk2 bs=4m
331+1 records in
331+1 records out
1390411776 bytes transferred in 97.870929 secs (14206586 bytes/sec)
       97.99 real         0.00 user         0.59 sys
```


# MacBook Pro 内蔵SDカードリーダ + SanDisk 16GB 80MB/s

```bash
$ sudo time dd if=2016-11-25-raspbian-jessie-lite.img of=/dev/rdisk2 bs=1m
Password:
1326+0 records in
1326+0 records out
1390411776 bytes transferred in 96.422072 secs (14420057 bytes/sec)
       96.54 real         0.00 user         0.67 sys
```

```bash
$ sudo time dd if=2016-11-25-raspbian-jessie-lite.img of=/dev/rdisk2 bs=2m
Password:
663+0 records in
663+0 records out
1390411776 bytes transferred in 96.097746 secs (14468724 bytes/sec)
       96.22 real         0.00 user         0.62 sys
```


# MR3-C008BK + SanDisk 16GB 80MB/s

1回目

```bash
$ sudo time dd if=2016-11-25-raspbian-jessie-lite.img of=/dev/rdisk3 bs=1m
1326+0 records in
1326+0 records out
1390411776 bytes transferred in 132.090613 secs (10526197 bytes/sec)
      132.11 real         0.00 user         1.02 sys
```

2回目

```bash
$ sudo time dd if=2016-11-25-raspbian-jessie-lite.img of=/dev/rdisk3 bs=1m
1326+0 records in
1326+0 records out
1390411776 bytes transferred in 130.144783 secs (10683577 bytes/sec)
      130.27 real         0.00 user         0.67 sys
```


# U3 2 in 1 Ultra SD 4.0 Mobile Phone / PC Card Reader for TF SD Card + SanDisk 16GB 80MB/s

```bash
$ sudo time dd if=2016-11-25-raspbian-jessie-lite.img of=/dev/rdisk3 bs=1m
Password:
1326+0 records in
1326+0 records out
1390411776 bytes transferred in 129.601942 secs (10728325 bytes/sec)
      129.72 real         0.00 user         0.73 sys
```
littlebitsでリモートハウスとさらにつながる- slackからlittlebitsでカメラを動かす-

###追記
**cloudbitは技適に対応していない、という指摘があったので運用を止めました。知らなかった:frowning2:日本国内の人はお気をつけください。**


----------

この記事は[littleBits Advent Calendar 2016](http://qiita.com/advent-calendar/2016/littlebits)の17日の記事です。

#はじめに
毎日家にいるのだが、咳をしても声をかけてくれる人がいないのは寂しい。し、人の目がないとついついだらだらしてしまう。なので、平日は友人数人とビデオチャット（appear.in）でつなぎっぱなしにしています。家が拡張された感じでけっこうよいです。しかし、ずっとPCの前にいるわけでもないので単に壁が映っている時間も結構あり、味気ない。なので、見ている人がネット越しにカメラを動かすことができるようにしました。専用UIを作るよりslackので動かす方が便利だろうということで、slackのbotを入力として使おうと思います。

まぁ普通の家でやるのは気持ち悪いという人が多いと思うんですが、会社にカメラをつないでおいてリモートワーク先の人が様子をわかりやすくする、とかシェアオフィスで誰が飽きているのか見てから行く、とかそういうのにも使えるのではないでしょうか。

#作ったもの

Slackのbotに話しかけるとカメラの角度を変えてくれる。角度は0～100の値をbotに言うと、90°を100として動いてくれます。

![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/39559/c42a26c3-740e-e50f-6312-0fad115d7a94.png)
https://www.youtube.com/watch?v=LJvZCmJn2qg

**Slack->hubot->littlebitsAPI->cloudbits->サーボモーター**、という感じで動きます。

IFTTTでの連携もやってみたが、遅延が大きく使いづらかったのでlittlebitsAPIを利用しました。IFTTTでやるだけなら10分の1くらいの手間でできます。

#作り方
##little bitsをセットする
###cloudbitsの設定
http://control.littlebitscloud.cc/ にアクセスして、案内の通りにやっていけば簡単に設定できます。PCのUSBからだと電力が足りなくて設定に失敗するので注意。
設定後、USBアダプタ->電源ユニット->cloudbits->サーボモーター、とlittlebitsをつなぎます。

##hubotとslackと連携させる
http://qiita.com/mochidamochiko/items/29c2d77715d8a1ff062a
上記の記事を参考にさせていただきました。細かいところでつまずきましたが、この辺についてはたくさん記事がある（＆自分がよくわからない）ので割愛します。

##hubotとcloudbitを連携させる
http://qiita.com/matsuoshi/items/319d271af7240fb59e8c
上記の記事を参考にさせていただきました。

cloudbitの設定画面からDevice ID と AccessTokenを取得。Heroku のダッシュボード > Settingsから環境変数に登録。

```js
_DEVICE_ID = process.env.DEVICE_ID　# 環境変数はherokuに登録したものを呼び出す
_ACCESS_TOKEN = process.env.ACCESS_TOKEN　# 環境変数はherokuに登録したものを呼び出す

module.exports = (robot) ->
  robot.respond /rotate camera to (.*)/i, (msg) ->
    voltageValue = msg.match[1]　
    data = JSON.stringify
      percent: voltageValue　# 電圧の高さ。0～100%で指定
      duration_ms: -1 # -1で電圧をあげっぱなしにする

    robot.http("https://api-http.littlebitscloud.cc/devices/#{_DEVICE_ID}/output")
    .header('Authorization', "Bearer #{_ACCESS_TOKEN}")
    .header('Accept', 'application/vnd.littlebits.v2+json')
    .header('Content-Type', 'application/json')
    .post(data) (err, res, body) ->
      msg.send 'OK, rotate it to ' + voltageValue　# チャットから動かす量を取得。
      console.error err
      console.log body
```

これで、@bot名 rotate it to 値（1～100）と話しかけるとその位置にモーターが動くようになりました。

##カメラを付ける

適当にあった重い缶の蓋をカットし、サーボモーターをボルトとナットで固定しました。
![20161218033040.jpg](https://qiita-image-store.s3.amazonaws.com/0/39559/5293d28b-7c6e-ae5a-561c-932a99bfe032.jpeg)

カメラはとりあえずガムテープでくっつけただけです。できることがわかったので3Dプリンターでアダプターでも作ろうかなと思っています。
![20161218033241.jpg](https://qiita-image-store.s3.amazonaws.com/0/39559/27caeb30-7284-bc25-dad5-0c714076fbf7.jpeg)



#これから

現状、細かい動き（5だけ動かすとか）ができないのが弱点。あと、エラーのときはbotがちゃんと喋るようにできると良いです。ハード面は、今はガムテープで止めてるのでちゃんとアダプタを作りたいなぁと思っています。

とりあえずしばらく運用してみて様子を見ます。

今回はid:htomineのちからをだいぶん借りました。ありがとう！
動的に生成される要素から特定のテキストだけを抽出しスタイルを当てる

■コード

```javascript
//要素内のテキストを取得
var str = $("element").text();

//テキストから数値部分のみを抽出
str2 = str.replace(/[^0-9^\.]/g,"");

if(str2){
  $("element").each(function(){
    var txt = $(this).html();
    //element内のstr2に該当する部分を<span>タグで囲んでスタイルを適用した要素で置き換える
    //replace()内の置換される要素に変数を用いる場合はRegExpオブジェクトを使う
    $(this).html(txt
      .replace(new RegExp(str2,"g"),"<span style='color:red;'>" + str2 + "</span>"))
  });
}

```

■RegExpオブジェクトについて
<リファレンス>
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/RegExp

RegExpはパターンに従ったテキストにマッチする正規表現オブジェクトを返す

```javascript
new RegExp(pattern,flag)
```

以下のようにすることで、RegExpで作った正規表現に該当する部分を"a"に置換することが出来る
正規表現に変数を用いる場合はこのRegExpを使うと出来るらしい

```javascript
$(this).html(
    txt.replace(new RegExp(str2,"g"),"a")
)
```

参考にしたサイト
http://mikaduki.info/webprogram/js/430/
[Unity][ADX2 LE]OBBでアプリを分割するとキューシートを読み込まない問題の対処

Google Playストアのアプリの容量制限は100MBであるため、100MBを超えるアプリはapkとOBBに分割しないといけない。
Unityにその分割機能があるため、面倒なことだと思っていなかったが、実機で動かすと音が鳴らないことに気づいた。
原因を探ると、ADX2 LEのキューシートが読み込めていないようだったので、その対処を行った。

#環境
・macOS Sierra 10.12.2
・Unity 5.5.0f3
・サウンド関係はCRI ADX2 LE使用
・キューシート等はStreamingAssets下に配置

#原因の特定経緯
症状は効果音やBGMが一切出ないというものだった。
また、分割しないビルドであれば問題なかった。(iOS版でももちろん問題ない)

はじめ、OBBに分割したことによって、OBBの方が読み込めていないのではと考えたが、OBBが読み込めていないとそもそもタイトルシーンでフリーズしてしまったため(環境によると思うが)、OBBの読み込みはできていると判断した。

```
adb logcat
```
でログを見ると、

```
CRIWARE ERROR[w2015111731] : file existence error occurred // 原文ママではない
```
というエラーが出ていたため、ADX2LEのキューシート等が読み込めていないと判断した。

#対処
ググった結果、似たような事例を見つけた。

[Android Split APK-OBB and StreamingAssets](http://answers.unity3d.com/questions/928421/android-split-apk-obb-and-streamingassets.html)
[Dataset does not exist error when using Unity 4 Android Splitter](https://developer.vuforia.com/forum/unity-extension-technical-discussion/dataset-does-not-exist-error-when-using-unity-4-android-splitter)

どうやら、```Application.streamingAssetsPath```内のファイルを```Application.persistentDataPath```にコピーすれば良さそうな感じがした。

上記サイトを参考に、タイトルシーンのスクリプトに以下のコードを加えた。

```
void Start(){
      StartCoroutine(ExtractObbDatasets()); // データのコピーを行うコルーチン開始
}

private IEnumerator ExtractObbDatasets () { // データのコピーを行う
        string[] filesInOBB = {"CueSheet_0.acb","CueSheet_1.acb","HogeHoge.acf"}; // .acbや.acfの指定(StreamingAssets下のファイル)
        foreach (var filename in filesInOBB) { // 指定したファイルの文だけ実行
            string uri = Application.streamingAssetsPath + "/" + filename; // コピー元のパス
            string outputFilePath = Application.persistentDataPath + "/" + filename; // コピー先のパス
            if(!Directory.Exists(Path.GetDirectoryName(outputFilePath))){ // ディレクトリが存在しなかったら作成(多分使わない)
                Directory.CreateDirectory(Path.GetDirectoryName(outputFilePath));
			}

            var www = new WWW(uri); // 内部的なコピーだが、wwwを使って擬似ダウンロードみたいなことをする
            yield return www;
             
            Save(www, outputFilePath);
            yield return new WaitForEndOfFrame();
        }
}

private void Save(WWW www, string outputPath) { // データのセーブを行う
		File.WriteAllBytes(outputPath, www.bytes); // セーブ
        if(File.Exists(outputPath)){ // もしセーブ先に書き込んだデータがあれば
            Debug.Log("File successfully saved at: " + outputPath); // 成功
		}else{
            Debug.Log("Failure!! - File does not exist at: " + outputPath);
		}
}
```

ここでのfilesInOBBには、StreamingAssets下のファイル名を入れる。
ADX2 LEであれば、.acb .awb .acfが対象となるだろう。

また、Assets/Plugins/CriWare内のCriWare.csの一部を次のように変更した。

```:CriWare.csの一部
public static string streamingAssetsPath
{
		get {
			if (Application.platform == RuntimePlatform.Android) {
				if (Application.dataPath.Contains(".obb")) { // obbのとき
					return Application.persistentDataPath; // このパスを返すようにする
				}else{
					return ""; // これがデフォになってるはず
				}
			} else {
				return Application.streamingAssetsPath;
			}
		}
}
```


さらっと書いてるが、7時間ぐらい無駄にした。
nginxで　font awesomeが『Failed to decode downloaded font』から始まるエラー

ここらへんの記事みて解決しました！！！

http://ts0818.hatenablog.com/entry/2016/04/01/225341

http://weboook.blog22.fc2.com/blog-entry-388.html

https://heartbeats.jp/hbblog/2012/02/nginx03.html

http://www.bunkei-programmer.net/entry/2013/10/14/140635
音ゲーの同期方法について考察した

この記事は [Akatsuki Advent Carender 2016 18日目](http://qiita.com/advent-calendar/2016/aktsk)の記事です。 

# はじめに

初投稿となります、[＠nom3nan](http://qiita.com/nom3nan)です。
[アカツキ](https://aktsk.jp/)で新卒エンジニアやってます。

普段から音ゲーが好きで、太鼓なやつとかポップなやつとか遊んでいたり、スマホでも色々と遊ばせてもらってます。
音ゲーを作るとなると、大切なところはやはり音楽との同期処理だと思います。
最近は音楽に合わせて演奏する以外にも、リズムに合わせて戦ったりパズルしたり、いろんな音ゲーが出てきました。
今回は、そんな様々ある音ゲーに合わせて、音楽とゲームの同期方法について考察しました。

# 同期処理の種類

一口に同期といってもいくつか方式が思いつきます。

- 音楽に合わせてゲームを同期する方式
- ゲームに合わせて音楽を同期する方式
- 時間軸に対して同期する方式

何れにせよ、一番大切なことは音楽に合わせてリズムゲームが進行することです。
何も障害が起きなければどの方式でも大丈夫なのですが、時には処理落ちが発生し描画が遅くなったり音楽が止まったりすることも考えられます。
よって、各ゲームにおいてどの方式が適切であるかを各方式のメリット・デメリットを考えながら考察していきます。

## 音楽に合わせてゲームを同期する方式

音楽の再生時間を取得し、リズムゲームの進行を同期させる方式です。
直球的でまさに音楽ゲーム、と言う感じの同期方法だと思います。

メリットとしては、音楽・ゲームどちらかに処理落ちが発生してもタイミングを合わせることが出来ます。
同期を取っているため当たり前ですね。

デメリットとしては、ゲームが処理落ちした場合、同期をとる瞬間に処理をスキップしなければいかず、ユーザにとって理不尽なスキップや早送りが発生してしまいます。

## ゲームに合わせて音楽を同期する方式

リズムゲームの進行に合わせて音楽の再生を同期させていきます。
これは先程の逆で、ゲームの進行を軸に音楽を同期させる方式です。

メリットとしては先程と同様、処理落ちが発生してもタイミングを合わせることが出来ます。
デメリットは、ゲームの処理落ちに合わせて音楽も止まってしまうため非常にリズムか取りづらくなります。

## 時間軸に対して同期する方式

3つ目は、時間軸に対して処理を同期させる方式です。
音楽は音楽、ゲームはゲームで時間に対して同期を取り、音楽とゲームのタイミングを合わせます。

メリットは、先ほどと異なりそれぞれが時間軸を持っており、処理落ちが発生してももう片方が引きづられてリズムが崩れることはありません。
デメリットは、音楽とゲームの間で直接的な同期を取っていないため、一度ズレるとゲームが終了するまでタイミングがズレたままになります。

## 各同期方法のまとめ

方式 | メリット | デメリット
--- | --- | ---
音楽に合わせゲームを同期 | 音楽とゲームがズレても修正できる | ゲームの早送りやスキップが発生
ゲームに合わせ音楽を同期 | 音楽とゲームがズレても修正できる | 音楽のテンポが狂う
それぞれが時間軸に同期 | フレームスキップが起きない | 音楽とゲームのズレを修正できない

# 結局どれが良いのか

先に結論を言えば、`音楽に合わせてゲームを同期する方式`もしくは`時間軸に対して同期する方式`の2択で、状況において使い分けだと思います。

一般に、音楽の再生とゲーム処理では、ゲーム処理のほうが処理落ちが発生しやすいです。
主に描画処理がネックになります。
そのため`ゲームに合わせて音楽を同期する手法`は、音楽は正常に再生できるはずなのに描画のせいでリズムを狂わせる回数がむやみに増えてしまうため、あまり良い手法とは言えません。

残りの2つに関しては、作るゲームや環境に合わせて適切な手法を選ぶことが大切かと思います。
例えば、音に合わせてパズルしたり戦ったりダンジョン入ったりするような、ゲーム部分が長時間続くような音ゲーはリズムの同期がズレることは致命的です。
ですので、`音楽に合わせてゲームを同期する方式`が適していると言えます。

音楽に合わせて演奏する様なゲームは処理落ちによるリスクが、「ゲームのリズム崩れ」と「ゲーム・音楽のズレ」との兼ね合いになるため判断に迷います。
別の観点で考えた時、「アーケードやコンシューマなど」と「スマホやPCなど」を比較すればスペックのばらつきを考慮することができます。

安定して動く環境があるのであれば、無理して同期させる必要はないため`時間軸に対して同期する方式`が良いかと思います。
逆に安定した環境でないのであれば、音楽とタイミングを合わせることが大切で`音楽に合わせてゲームを同期する方式`が良いかと思います。

ゲームの時間 | 動作環境 | おすすめの方式
--- | :-: | ---
長時間 | - | 音楽に合わせてゲームを同期する方式
短時間 | 安定 | 時間軸に対して同期する方式
短時間 | 不安定 | 音楽に合わせてゲームを同期する方式

# さいごに

どの同期方式が良いか、に関しては各方式の特徴と作りたいゲーム、環境などに合わせて適切に判断して選択する必要があると思います。
あくまで、自分が考えたおすすめを載せていますが参考にしていただければ幸いです。
oF製ビジュアライザでHappy FizzBuzzビジュアライズライフ

## Happy FizzBuzz!!

今年はこのあいさつを流行らせていきたいと思います。
残り少ないですがよろしくお願いします。

この記事はリブセンスアドベントカレンダー2016 18日目 C面です。
A面 [無限FizzBuzzリストでHappy FizzBuzzライフ](http://qiita.com/dkatsura/items/20a86d863ea4ed088e63)
B面 [Amazon PollyでHappy FizzBuzzオーディオライフ](http://qiita.com/dkatsura/items/aac7ec867f1ae0eb81a6)
もあわせてご覧ください。

## ビジュアライザ

みなさんの私生活は

* FizzBuzz映像をずっと眺めていたい
* 一日に一回はFizzBuzzを見ないとつらい
* FizzBuzzの映画化を楽しみにしている

という病に蝕まれていますか？

そう、そんなときに役立つのがoF製ビジュアライザです。

## FizzBuzzオーディオの準備

まずはFizzBuzzオーディオを用意します。

https://soundcloud.com/daisuke-katsura/joannafizzbuzz

今回は英語版(Joanna)を利用しました。

## ビジュアライザ

本当は「1」「2」「Fizz」とか文字が飛び出すのを作りたかったのですが、
来年もアドベントカレンダーがあるようなので、
今年はシンプルなものにしておきます。

openFrameworksでガチャガチャやります。

特に特別なことはやってないので解説は飛ばします。
ofxPostProcessing postだけアドオン使って定義してます。

```cpp
//--------------------------------------------------------------
void ofApp::setup(){
    ofBackground(0,0,0);
    ofSetVerticalSync(true);
    ofSetCircleResolution(64);
    ofEnableAlphaBlending();

    // Setup post-processing chain
    post.init(ofGetWidth(), ofGetHeight());
    post.createPass<PixelatePass>()->setEnabled(true);
    post.createPass<EdgePass>()->setEnabled(true);

    // Setup box positions
    for (unsigned i = 0; i < NUM_BOXES; ++i) {
        posns.push_back(ofVec3f(0, 0, 0));
    }
    boxMesh = ofMesh::box(20, 20, 20);
    
    sound.load("fizzbuzz.mp3");
    sound.setLoop(true);
    sound.play();
    
    vol = 0.0;
}

//--------------------------------------------------------------
void ofApp::update(){
    float *volume = ofSoundGetSpectrum(1);
    vol = volume[0]*800.0;
}

//--------------------------------------------------------------
void ofApp::draw(){
    glPushAttrib(GL_ENABLE_BIT);
    
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    
    post.begin(cam);
    
    for (unsigned i = 0; i < posns.size(); ++i) {
        ofPushMatrix();
        ofRotate(i * 10, 0, 5, 0);
        ofTranslate(posns[i] + ofVec3f(vol * i, 0, 0));
        boxMesh.draw();
        ofPopMatrix();
    }
    
    post.end();
    
    glPopAttrib();
    
}
```

### 完成品

こんな感じになりました。

<img width="344" alt="fizzbuzz.png" src="https://qiita-image-store.s3.amazonaws.com/0/47722/c27a7a87-f5cf-8451-edcf-71672f8f0fad.png">

https://drive.google.com/file/d/0B6l5wNYrO24XTWpWb0FFcEpqWEk/view?usp=sharing

作ってから思いましたが単調にしゃべり続けるので、
全然ビジュアライザに向いてないですね。

みなさまも、openFrameworksを使って、
HappyなFizzBuzzビジュアライズライフをお送りください。
Amazon PollyでHappy FizzBuzzオーディオライフ

## Happy FizzBuzz!!

今年はこのあいさつを流行らせていきたいと思います。
残り少ないですがよろしくお願いします。

この記事はリブセンスアドベントカレンダー2016 18日目 B面です。
A面 [無限FizzBuzzリストでHappy FizzBuzzライフ](http://qiita.com/dkatsura/items/20a86d863ea4ed088e63)
C面 [oF製ビジュアライザでHappy FizzBuzzビジュアライズライフ](http://qiita.com/dkatsura/items/02adfd2a5b19b49b595c)
もあわせてご覧ください。


## FizzBuzzオーディオ

さて、みなさんは私生活の中で

* 今度ドライブでかけるFizzBuzz何にしようかな
* たまにはお風呂の中でFizzBuzz聞きたいな
* でも自分の声で録音するのも恥ずかしい…///

ということが多々あります。

そう、そんなときに役立つのがAmazon Pollyです。

## まずはFizzBuzz配列を用意する

今回は同僚が作った「時をかけるFizzBuzz」の改造版を利用します。

```ruby
t = Time.new
fb = []
(1..100).each do |n|
  a = 20; b = 12
  fb << case (t + n * a + n * b).sec
  when t.sec; "FizzBuzz"
  when (t + n * a).sec; "Fizz"
  when (t + n * b).sec; "Buzz"
  else; n
  end
end
```

Timeインスタンスのsecが60の剰余になっていることを利用した技アリの作品で、
「除算と剰余禁止縛りFizzBuzz」の中でも珠玉の逸品だと思っています。


## Amazon Pollyで音声に変換

さて、準備はできました。
これをAmazon Pollyに依頼してMP3に変換します。

```ruby
require 'aws-sdk'
require 'yaml'

creds = YAML.load(File.read('./secrets'))
polly = Aws::Polly::Client.new(
  access_key_id: creds['access_key_id'],
  secret_access_key: creds['secret_access_key'],
  region: creds['region']
)

t = Time.new
fb = []
(1..100).each do |n|
  a = 20; b = 12
  fb << case (t + n * a + n * b).sec
  when t.sec; "FizzBuzz"
  when (t + n * a).sec; "Fizz"
  when (t + n * b).sec; "Buzz"
  else; n
  end
end

polly.synthesize_speech(
    response_target: './fizzbuzz.mp3',
    output_format: 'mp3',
    text: fb.join(" "),
    text_type: 'text',
    voice_id: 'Mizuki'
)
```

そして叩いてみると……

```
~/src/fizzbuzz/polly$ bundle exec ruby polly.rb
~/src/fizzbuzz/polly$ afplay fizzbuzz.mp3
```

流れました！
実際の音声は
https://soundcloud.com/daisuke-katsura/mizukifizzbuzz
からぜひお聞きください。

### 英語でも聞ける。そう、Pollyならね。

同じFizzBuzzばかりではやはり飽きが来てしまう。
そんなわがままFizzBuzzリスナーもPollyなら満足していただけるかと思います。

上のコードのvoice_idを他の名前に変えるだけで、
英語、ポルトガル語、ロシア語などなどなんと24言語、
そして同じ言語でも男性女性色んな人の声があります。

たとえばJoanna（英語・女性）。

https://soundcloud.com/daisuke-katsura/joannafizzbuzz

さすが、リズミカルです。

みなさまも、Amazon Polliyを使って、
HappyなFizzBuzzオーディオライフをお送りください。
無限FizzBuzzリストでHappy FizzBuzzライフ

## Happy FizzBuzz!!

今年はこのあいさつを流行らせていきたいと思います。
残り少ないですがよろしくお願いします。

この記事はリブセンスアドベントカレンダー2016 18日目 A面です。
B面 [Amazon PollyでHappy FizzBuzzオーディオライフ](http://qiita.com/dkatsura/items/aac7ec867f1ae0eb81a6)
C面 [oF製ビジュアライザでHappy FizzBuzzビジュアライズライフ](http://qiita.com/dkatsura/items/02adfd2a5b19b49b595c)
もあわせてご覧ください。

### 無限FizzBuzzリスト

さて、みなさんはプログラムの中で

* 長さ不定のFizzBuzzリストが必要になり
* しかし実際に評価されるかは定かでなく
* メモリに乗っけておきたくない

ということが多々ありますよね。

そう、そんなときに役立つのが遅延評価の無限FizzBuzzリストです。

### Rubyで実装してみる

さっそくお手持ちのRuby(>2.0)で実装してみましょう。

```ruby
fb = Array.new(1).cycle.lazy.zip((Array.new(2) << "Fizz").cycle, (Array.new(4) << "Buzz").cycle).with_index(1).map { |s, i| s.join.gsub(/^$/, i.to_s) }
```
なんと簡潔にできました！

クラスとサイズを見てみると

```ruby
irb(main):006:0> fb.class
=> Enumerator::Lazy
irb(main):007:0> fb.size
=> Infinity
```

きちんと遅延評価の無限リストになっています。

実行すると

```ruby
irb(main):019:0> fb.take(15).map(&:to_s).to_a.join(" ")
=> "1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz"
```

みごとFizzBuzzがあらわれました。

### コード

さきほどコード、改行を入れて見やすくするとこうなります。

```ruby
fb = Array.new(1).cycle.lazy.zip(
  (Array.new(2) << "Fizz").cycle,
  (Array.new(4) << "Buzz").cycle
).with_index(1).map { |s, i| s.join.gsub(/^$/, i.to_s) }
```

まずは一行目。
Array.newは引数Nを渡すとサイズNのnil配列ができあがるので、
Array.new(1)は[nil] となります。
これをcycleすると無限nil配列ができあがります。

ただしこれにzipをかけると永遠に処理が終わらないので、
lazyを挟むことによってEnumerator::Lazyに変換します。

あとは同じように作った無限Fizz配列、無限Buzz配列をzipし、
インデックスを付与してmapします。
map内が少し見苦しいのですが、文字列連結した後、空のときはインデックスに変換。
つまりFizzでもBuzzでもないときは数字が表示される、というわけです。

### 使用メモリ

もちろん気になるのはメモリですよね。
今回はObjectSpaceを使って計測してみます。

まずはふつうにFizzBuzz配列(サイズ100万)をつくった場合。

```ruby
irb(main):003:0> fb = []
=> []
irb(main):004:0> (1..1000000).each do |i|
irb(main):005:1*   s = ''
irb(main):006:1>   s << 'Fizz' if i % 3 == 0
irb(main):007:1>   s << 'Buzz' if i % 5 == 0
irb(main):008:1>   fb << (s == '' ? i.to_s : s)
irb(main):009:1> end
=> 1..1000000
irb(main):010:0> ObjectSpace.memsize_of(fb)
=> 11636272
```

とんでもないメモリ使用量ですね。

次に無限FizzBuzzリストの場合です。

```ruby
irb(main):012:0* lazy_fb = Array.new(1).cycle.lazy.zip((Array.new(2) << "Fizz").cycle, (Array.new(4) << "Buzz").cycle).with_index(1).map { |ss, i| ss.join.gsub(/^$/, i.to_s) }.take(1000000)
=> #<Enumerator::Lazy: #<Enumerator::Lazy: #<Enumerator::Lazy: #<Enumerator::Lazy: #<Enumerator::Lazy: #<Enumerator: [nil]:cycle>>:zip(#<Enumerator: [nil, nil, "Fizz"]:cycle>, #<Enumerator: [nil, nil, nil, nil, "Buzz"]:cycle>)>:with_index(1)>:map>:take(1000000)>
irb(main):013:0> ObjectSpace.memsize_of(lazy_fb)
=> 272
```

もちろんO(1)です。すばらしい。

まあ評価遅いとかそもそもランダムアクセスのスピード違うから配列と比べてもアレだとか色々難癖はありますが、冒頭に書いたような状況にはピッタリの代物かと思います。

みなさまも、遅延評価の無限FizzBuzzリストを使って、
HappyなFizzBuzzライフをお送りください。
SafariのkeyCodeで取得できるコードには要注意

HTMLとJavascriptで電卓を作るため、テキストボックスにカーソルがある状態で'+','-','Enter','ESC'キーを押したら電卓の'足し算','引き算','＝','AC'に相当する処理が行われるようチャレンジしました。

| タイプしたキー | 電卓での機能 |
|:----------:|:------------:|
|      +     |       +      |
|      -     |       -      |
|    Enter   |       =      |
|     ESC    |      AC      |


ところが、以下のコードで押されたキーを判定して処理しようとしたものの、Chromeでは動くのにSafariではテキストボックスに'+','-'が入力されるだけという状態になりました。

```javascript:calculator.js
$(document).on('keydown', '#InputNumber', function(e) {
  switch (e.keyCode) {
    case 107:
    case 187:
      $('#add').click(); #足し算の処理を実施
      break;
    case 109:
    case 189:
      $('#minus').click(); #引き算の処理を実施
      break;
    (以下省略)
    }
  });
```

デバッグする過程で、どうも`e.keyCode`に格納されるコードが怪しいと考えて、以下のコードで`e.keyCode`に格納される値を確認したところ、次の表の結果になりました。
（Sarafiはテキストボックスにカーソルがあるか否かで結果が変わりますが、Chromeは同じです。）

```javascript:debug.js
window.addEventListener("keydown", function(e) {
  return window.alert(e.keyCode);
});
```

|                             | + (テンキー) | - (テンキー) | + (キーボード) | - (キーボード) | Enter | ESC |
|-----------------------------|:------------:|:------------:|:--------------:|:--------------:|:-----:|:---:|
| Chrome                      | 107          | 109          | 187            | 189            | 13    | 27  |
| Safari (テキストボックス内) | 229          | 229          | 229            | 229            | 13    | 27  |
| Safari (テキストボックス外) | 107          | 109          | 187            | 189            | 13    | 27  |

結果は、Safariでは、テキストボックスにカーソルがあると'+'と'-'のどちらを押しても`e.keyCode`の値が同じになるということがわかりました。さらに、Safariでテキストボックスにカーソルがある状態でテンキーまたはキーボードから数字を入力すると、0〜9のいずれの数字を入力しても`e.keyCode`に格納される値は`229`になります。つまり、Safariでテキストボックスにカーソルがある状態で数字関係のキーを押した場合、`e.keyCode`の値でどのキーが押されたかを判断することはできません。
テキストボックスにカーソルが無ければ、Safariで0〜9を入力した際に`e.keyCode`に格納される値は、キーボードの場合は`48〜57`に、テンキーの場合は`96〜105`になりますので、`e.keyCode`で押されたキーを判断できます。

以上、長々と書いてきましたが、Javascriptを使ってキーボードのイベントを取得する際は、ブラウザ間の違いに注意する必要があるということが身に染みて分かりましたので、備忘録代わりに記事にしました。
ipaファイルに組み込んだ証明書の有効期限を確認する

## 概要
iOSアプリのipaファイルに組み込んだプロビジョニングプロファイル（証明書）の有効期限を確認する手順を記載します。

## 手順
1. ipaファイルの拡張子を.ipaから.zipに変更
2. .zipファイルを解凍する
3. Payloadフォルダを開く
4. Windowsの場合、"アプリ名.app"フォルダを開く  
MacOSの場合、"アプリ名.app"を右クリックし、"パッケージの内容を表示"をクリック
5. バイナリファイルを確認できるエディタ等で"embedded.mobileprovision"ファイルの内容を確認する  
`cat embedded.mobileprovision`でも可
6. 以下のように、"ExpirationDate"の部分に有効期限が記載されているので確認する

    ```xml:embedded.mobileprovision
	<key>ExpirationDate</key>
	<date>2017-12-17T15:11:36Z</date>
    ```
Webサイト運用を楽にしてくれるCDN

CDNと聞いて皆さんはどんなイメージを思い起こしますか？

> コンテンツデリバリーホゲホゲでしょ？　akamaiだかなんだかだよね・・

とか

> あぁ、画像が大量にある時に放り込んどくキャッシュね・・

とか

案外、人それぞれでイメージが異なってたりするんだと思います。

最近触る機会が多いJストリーム社の国産CDNサービス"CDNext"を参考にCDNサービスの現在の姿やWebサイト運用をぐっと楽にする為の活用法などについて紹介したいと思います。

# CDNのしくみ
ざくっと言ってしまうと、**地理的に分散配置されたリバースプロキシサーバー群**です。

![image](https://qiita-image-store.s3.amazonaws.com/0/4837/6cbe9e5f-f2a2-1a49-9d84-5bb173e14575.png)

**リバースプロキシ＋コンテンツキャッシュ＋最適ルーティング**、と言ってもいいのかもしれません。

# CDNを使うメリットは
基本的なメリットとしては以下あたりだと思います。

- Webコンテンツを高速に安定して配信することができる

大量の同時アクセスが発生するような場合でもCDNがプロキシしてくれるのでWebサーバーは楽ちんです
クライアントからネットワーク経路的に最も近いプロキシへ最適ルーティングされるのでWebサイトの応答速度が速くなります（といっても、日本国内ではさほどの差にはならないです、、）

- DDoS攻撃対策にもなる 

一般的にCDNネットワークではDDoS対策がとられており、WebサイトをDDoS攻撃から守ることができます

- HTTP/2対応、手っ取り早い常時SSL化

CDNにSSLサーバー証明書を登録することでHTTP/2対応が可能となりサイトが高速化したり、オリジンサーバーでの常時SSL化がいろいろと大変な場合は、クライアント－CDN間の通信のみ常時SSL化することもできたりします

# CDN活用法
Webサイト運用をコストも手間もかけずに改善するためのCDN活用法として、以下にいくつかあげてみたいと思います。

## CDN導入には手間をかけない
従来だと画像やJS,CSSといった更新頻度が低く、かつ比較的サイズの大きい静的ファイルのみCDNへオフロードするという導入方法が一般的でした。この導入法だとコンテンツの精査やリンクの書き換えなどコンテンツ側での手間が大きく発生してしまいますね。
CDNextなどの最近のCDNサービスではPHPやCGI等で動的に生成されるコンテンツについても問題なくキャッシュとして扱うことができます。なので、あまり細かい事は気にせず、Webサイト全体に対してCDNを適用し、コンテンツ側での制御はキャッシュさせたくない特定ディレクトリ下に.htaccessを設置するといったお手軽な導入方法がおススメです。

## Webサイトを冗長化する
ECサイトだけではなく、一般的な企業サイトでも今やWebサイトのダウンはビジネスに大きな影響を及ぼしてしまいます。
ですが、Webサーバーの冗長化には負荷分散（ロードバランサーなど）の導入や、コンテンツ同期、場合によってはデータベースの冗長化など技術的難易度が高い作業が必要となり、相応のコストがかかるため、なかなか踏み切れないといったケースは多いと思います。

CDNに複数のオリジンサーバーを設定することで簡易的なロードバランサーとして機能させることができます。
![image](https://qiita-image-store.s3.amazonaws.com/0/4837/d317321f-7ae8-d72f-f404-efec3ceb640f.png)
アクティブサーバーからスタンバイサーバーへ定期的にコンテンツを転送、同期させる処理は必要ですが、コストも手間もあまりかけずにWebサイトの可用性をグッと向上させることができます。

## いろいろと融通が利くコンテンツ管理
Webサイトが成長していくとコンテンツを管理する面においても様々な課題が発生します。

- 複数の制作会社が存在し、サーバー上のコンテンツ管理が難しくなってきた・・
- コンテンツを管理する複数の部署が存在し、サーバー上のコンテンツ管理が難しくなってきた・・

仮想パスといったURL配下の名前空間を制御できるCDNであれば、上記のような課題に対してかなり融通が利く楽な管理ができるようになります。
![image](https://qiita-image-store.s3.amazonaws.com/0/4837/7c2c5dc5-64f9-a89d-9536-5cd7c32a280e.png)

仮想パスを活用したコンテンツ管理の例として、

- www.example.jp/ir/ といったIR関連コンテンツは部署Aが管理するサーバーへ振り向ける
- サーバー管理もあわせて依頼しており、制作会社Aサーバー、制作会社BサーバーといったようにWeサーバーが分散してしまうようなケースでもCDNで集約、管理が手間なくできる

といった融通が利く管理が可能になり、Webサイト全体での運用がグッと楽になります。

# さいごに
CDNが登場した当初は一部の限られた大規模サイトが大きなコストをかけて利用するものというイメージが強かったですが、今や無料で使えるCDNサービスなども登場しており、CDNを活用する目的も多様化しているんだと思います。
付加機能なども各社それぞれで拡充されており、いろんな活用法が考えられるツールになってきていると感じてます。

Webサイト運用がもっと楽になれば・・とお悩みの方は是非いちど、CDN活用を検討してみてはいかがでしょうか。
Office-Saas 連携No.3 ~ Microsoft Word の差し込み文書にSaas データソースをODBC で使う

#Microsoft Word の差し込み文書機能概要#
Microsoft Word は、最も一般的に使われている文書作成ソフトウェアでしょう。レターやPDFの作成、宛名ラベルの作成機能もあります。そして便利な機能が「差し込み文章」機能です。ご存知の通り、一つのひな型を作成したら、ほかのデータベースに格納されている住所、社名などのデータを差し込んでくれるものです。難しいアプリケーションを組むことなく、コピー&ペースト要らずで、入り繰りのリスクのないレターやラベルが作成できます。差し込むデータは、SQL Server、ODBC DSN、Microsoft Access などから選択できます。

近頃顧客マスターがSalesforce などのクラウド上にあるというケースも多くなっています。本記事では、Salesforce のAccount（取引先）データを直接デスクトップのMicrosoft Word の差し込み印刷機能で使ってみます。
![9.png](https://qiita-image-store.s3.amazonaws.com/0/152422/0ba98b4a-7912-8908-1bdf-587aa5048cda.png)
同様に[CData ODBC Drivers](http://www.cdata.com/jp/odbc/) を使えば、70以上のSaas、NoSQL、Web API をプログラミング不要で差し込み文書のデータベースとすることが可能です。

#CData ODBC Driver for Salesforce のDSN 設定#
まずは、CData website から[CData ODBC Driver for Salesforce](http://www.cdata.com/jp/drivers/salesforce/odbc/)をダウンロードします。30日の無償版を使ってみましょう。

インストール実施後、DSN 設定画面が立ち上がります。
![ODBCDSNConfig.png](https://qiita-image-store.s3.amazonaws.com/0/116843/6b4e5a31-401e-d55e-88a2-74bcdc9ea830.png)
User: Salesforce のユーザーID です。
Password: Salesforce のパスワードです。
Security Token: Salesforce のSecurity token です。
Security Token の入手方法の詳細については、CData の[ヘルプ](http://cdn.cdata.com/help/GFB/odbc/pg_connectingtosalesforcexls.htm)を参照してください。

［テスト接続］を押して、問題が無ければ［OK］をクリックして、接続を確立します。

#Word 差し込み文章へのCData ODBC Driver の設定#
1. ［差し込み文章］のタブから［差し込み印刷の開始］を選択し、ウィザードを開きます。
![1.png](https://qiita-image-store.s3.amazonaws.com/0/152422/7572f44a-eafc-a4b6-291c-f564c56de0a7.png)

2. 右側に表示される差し込み印刷ウィザードで、作成する差し込み文章のタイプを選択して、次を押します。［宛先の選択］で［既存のリストを使用］を選択します。
「参照」を押して、データファイル選択画面で、［新しいデータソースへの接続.odc］を選択します。
![2.png](https://qiita-image-store.s3.amazonaws.com/0/152422/dadc90ed-de78-f530-4eb4-08b6d4ff011f.png)


3. ［データ接続ウィザード］で［ODBC DSN］を選択します。
![3.png](https://qiita-image-store.s3.amazonaws.com/0/152422/54347d3a-78d4-b24e-748d-e967b302a6c4.png)

4. 上で設定しCData ODBC ソースを選択します。今回は［CData Salesforce Source］を選択します。
![4.png](https://qiita-image-store.s3.amazonaws.com/0/152422/3b64bbdd-d637-84e8-6196-a31efe7d90e0.png)

#挿入するテーブルとカラム、およびレコードの設定#
5. データベースとテーブルの選択画面にて、差し込み文章で使用するテーブルを指定します。今回はSalesforce 内の顧客テーブルである［Account］テーブルを選択します。
データ接続ファイルを保存して終了します。
![5.png](https://qiita-image-store.s3.amazonaws.com/0/152422/36ffaa00-1cb7-5a56-92a2-cbaf6972091a.png)

6. 次にどのレコードを差し込み印刷の宛先とするかをチェックボックスで選択します。
![7.png](https://qiita-image-store.s3.amazonaws.com/0/152422/4fb86b45-d299-8c70-2616-b9cd436bc90b.png)
-30e4a18433a9.png)

#Word での差し込み文章のデザイン#
7. あとは、実際のWord 画面にて、［差し込みフィールドの挿入］を使って、挿入するフィールドを選択して、必要な住所や名前をWord 文章に挿入していきます。今回は、BillingStreet、BillingCity、BillingState、BillingPostalCode、BillingCountry を住所に、Name フィールドを会社名として宛先に挿入しています。
![8.png](https://qiita-image-store.s3.amazonaws.com/0/152422/bd8e28de-c2a0-1e26-f42a-75248c747dc2.png)

8. これで、Salesforce の顧客情報を使ったWord レターの作成ができました。リボンの［結果のプレビュー］から差し込まれた文章を確認できます。設定どおり、Salesforce 上の顧客住所、顧客名が挿入されていますね。
![9.png](https://qiita-image-store.s3.amazonaws.com/0/152422/4a79d536-aab6-d986-cb4b-1cea81552432.png)

このように、プログラミングを行わずに、Saas データをWord 文章に挿入することができました。皆さんも是非、お試しください。
GoでAESアルゴリズム(CBCモード)+PKCS7パディング+HMACを使った実装をする

[GoでAESアルゴリズム(CBCモード)+PKCS7パディング+HMACを使った実装をする](http://qiita.com/ken5scal/items/538febf69f9ac98ab292)の続きです。

さて、前回はAES+CBC+PKCSパディングを使った実装例を紹介した。パディングを使って、任意の平文をブロック型暗号で暗号化することが可能になったが、一方で脆弱性がうまれてしまった。暗号文+パディングを繰り返し送ることで平文を一部推測できてしまうような脆弱性だ。この脆弱性の根本原因は、誰もが復号できてしまう部分にある。従って、復号処理のための暗号文を入力するものを認証することで解決できる。その仕組がMAC(Message Authentication Code)であり、今回はHMAC(keyed-hash MAC)を使った実装例が今回のものになる。

# AES暗号化によるHMACとは
暗号文をHMAC用の共有鍵とハッシュ関数で導きだされるもの。復号をするまえにHMACを検証することで、共有鍵を持っているサブジェクトを認証することができる。

# GoにおけるHMACは？
標準パッケージ内のcrypt/hmacで実装されている。パディングは実装されていなかったのに、なぜなのか。謎である。実装自体はシンプルになる。

```暗号化.go
func EncryptByCBCMode(key []byte, plainText string) ([]byte, error) {
	block, err := aes.NewCipher(key); if err != nil {
		return nil, err
	}

	paddedPlaintext := PadByPkcs7([]byte(plainText))
	cipherText := make([]byte, len(paddedPlaintext)) // cipher text must be larger than plaintext
	iv := make([]byte, aes.BlockSize)// Unique iv is required
	_, err = rand.Read(iv); if err != nil {
		return nil, err
	}

	cbc := cipher.NewCBCEncrypter(block, iv)
	cbc.CryptBlocks(cipherText, paddedPlaintext)
	cipherText = append(iv, cipherText...)

        // MAC作成
	mac := hmac.New(sha256.New, []byte("12345678912345678912345678912345")) // sha256のhmac_key(32 byte)
	mac.Write(cipherText)
	cipherText = mac.Sum(cipherText)
	return []byte(cipherText), nil
```

```復号.go
func DecryptByCBCMode(key []byte, cipherText []byte) (string, error) {
	if len(cipherText) < aes.BlockSize + sha256.Size {
		panic("cipher text must be longer than blocksize")
	} else if len(cipherText) % aes.BlockSize != 0 {
		panic("cipher text must be multiple of blocksize(128bit)")
	}

　　　　// macの取り出し
	macSize := len(cipherText) - sha256.Size
	macMessage := cipherText[macSize:]

        // 暗号文から想定macを計算
	mac := hmac.New(sha256.New, []byte("12345678912345678912345678912345")) // sha256のhmac_key(32 byte)
	mac.Write(cipherText[:macSize])
	expectedMAC := mac.Sum(nil)

        // MACによる認証
	if !hmac.Equal(macMessage, expectedMAC) {
		return "", errors.New("Failed Decrypting")
	}

	iv := cipherText[:aes.BlockSize]
	plainText := make([]byte, len(cipherText[aes.BlockSize:macSize]))
	block, err := aes.NewCipher(key); if err != nil {
		return "", err
	}
	cbc := cipher.NewCBCDecrypter(block, iv)
	cbc.CryptBlocks(plainText, cipherText[aes.BlockSize:macSize])

	return string(UnPadByPkcs7(plainText)), nil
}

```

# その他
AES +CBC +パディング + hmacでためしたが、 AES +GCMで全てやりたかったことが出来るみたいなので、次回はそちらを試してみる.