OmniAICreator/Qiita-1.07M huggingface dataset:
超高速仮想ルーター/仮想スイッチ FD.io vppでDHCPを使ってインターフェースにアドレスを付与する

# モチベーション
DHCPは一時的利用のため動的なIPアドレスを付与するものでしたが、openstackやcloudstackのようなクラウドソフトウェアでは、DHCPは固定IPアドレスを割り当てるためのIPAMの役割をもっています。
そのため、openstackのテンプレートとしてFD.io vppを用意するには、インターフェースのアドレスをDHCPで付与できなければなりません。

# FD.io vppでインターフェースアドレスをDHCPで割り当てる
以下のようにする事で、vppでもDHCPでインターフェースを割り当てる事ができます。

```shell-session
# vi /etc/vpp/interface_dhcp
# cat /etc/vpp/interface_dhcp
set int state GigabitEthernet0/3/0  up
set int state GigabitEthernet0/4/0  up
set dhcp client  intfc GigabitEthernet0/3/0
set dhcp client  intfc GigabitEthernet0/4/0
# vppctl
vpp# exec /etc/vpp/interface_dhcp
```

テンプレート化するときは、/etc/vpp/startup.confに以下のように書けば良いですね。

```shell-session
unix {
  nodaemon
  log /tmp/vpp.log
  full-coredump
  exec /home/ubuntu/set-interfaces
}
```
Windows10にkeras, tensorflow with GPU環境作成の備忘録

普通にSteamで使っていたPCなので、ドライバ等は入っている前提です。
あと、Kerasで学習したモデルは、iOS11CoreMLで使うことを前提にKeras 2.0.4を使用します。
が、Tensorflow 1.0.x, 1.1.xがなかったので 1.2.1 をインストしました。動くのかわかりません...

## Environment
- Windows10 64bit
- GTX960 with 4GB
- Driver 381.65

ドライバやSpecは、NVIDIAコントロールパネルのシステム情報から確認できます。

## Installation

### 1. CUDA Toolkit 8.0
https://developer.nvidia.com/cuda-downloads
からインストーラをDL後、ダイアログに従う。

### 2. cuDNN 5.1
https://developer.nvidia.com/cudnn
からDL後、 `cudnn-8.0-windows10-x64-v5.1.zip\cuda\*` を
`C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0` へコピーする。

[tensorflow_self_check](https://gist.github.com/mrry/ee5dbcfdd045fa48a27d56664411d41c)
TensorFlow 1.2.1 or earlier requires cuDNN 5.1. ('cudnn64_5.dll')
TensorFlow 1.3 or later requires cuDNN 6. ('cudnn64_6.dll')

### 3. Visual C++ 2015 Build Tools
※ numpyインストール時にエラーが出て、↓のURLが吐かれました。
http://landinghub.visualstudio.com/visual-cpp-build-tools
からインストールする。

※ Visual Studioが入っている場合は、バッティングしてインストール出来ませんでした。
http://qiita.com/84zume/items/72bed23914c671b61fba
を参考に、Programming Languages -> Visual C++ -> Common Tools for Visual C++ 2015をインストールしました。

### 4. tensorflow-gpu

```
> pip install h5py matplotlib "tensorflow-gpu==1.2.1"
```

kerasのインストールで以下のエラーが出たので、[stack overflow](https://stackoverflow.com/a/40247857)で対策する。

```:error
...
  File "scipy\linalg\setup.py", line 20, in configuration
        raise NotFoundError('no lapack/blas resources found')
    numpy.distutils.system_info.NotFoundError: no lapack/blas resources found
```

```:stack-overflow
> pip install .\scipy-0.19.1-cp36-cp36m-win_amd64.whl
```

```
> pip install "keras==2.0.4"
```


## Reference
https://www.tensorflow.org/install/install_windows
rubyで繰り返し処理を行う（while,times,for,each）

# 繰り返しの処理

何回か同じ処理を繰り返したい時に

* while
* times
* for
* each

を使うと便利です。

* while
* times

は回数を指定して使いたい場合。例えば〜回処理をするなどの時に便利。

* for
* each

は配列などを参照して、要素がある分だけ繰り返し処理を行いたい場合便利です。


# while書き方

```ruby:test

i = 0

while i <10 do

puts "#{i}:hello"
i += 1

end

```

* whileの条件分に入れている変数はwhile内で使える。
* forとwhileは制御構造のため
    * doは省略可
    * スコープを作らない

# times書き方

```ruby:test

10.times do |i|

puts "#{i}:hello"

end

```

* 10が繰り返す回数
* iはtimes内で変数として使いたい時に設定

# for書き方

```ruby:test

for i in 15..20 do

  p i

end

for 変数 in 範囲 do

  p i

end

# 変数がinの範囲内で何回も処理を行う。timesなどと違い、変数がinの範囲内に変化する。

for colors in ["red","white"] do

  p colors

end

```


# each書き方

```ruby:test

colors = ["red","white"]

colors.each do |i|

 puts i

end

# 下記でも記入可能

["red","white"].each do |i|

 puts i

end

```

注意点

* times や each はメソッドのためdo〜end でブロックをなす
【備忘録】Angular CLI インライン設定の違い

# コンポーネントのデフォルト設定

Angular CLI 設定ファイル。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/103139/1e4e3161-f914-0027-6a5c-0951bee50905.png)

コンポーネントのデフォルト設定が無い様子。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/103139/0af4adae-baaa-effa-cf80-a2f6e60d83b4.png)

コンポーネントのデフォルト設定を変更して、インライン・スタイルとインライン・テンプレートを指定している様子。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/103139/4a0157c2-1025-49b9-bf3d-ec6d2667f641.png)

`ng generate component`コマンドを「デフォルト設定変更無し」と「デフォルト設定変更あり」で実行した場合に出力されるファイルの違い。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/103139/6ac525ca-7e1d-d819-44bb-426219f7c642.png)

インライン・スタイルとインライン・テンプレートを指定している場合にのみ、css、html、spec.ts ファイルの出力がないことが確認できる。
[windows][python3] windows上のpython3 venv Activate方法

venvのactivate方法が、mac/linuxと違ったので、メモっておきます。

python3のインストール方法は割愛します。

# Activate
**PowerShell** 上で以下のコマンドを実行します。

```
$ python -m venv ml
$ cd ml

$ ./Scripts/activate

$ which pip
/path/to/ml/Scripts/pip
```
VS2015対応のopenFrameWorksをVS2017で動かすには

久しぶりにopenFrameworks動かそうと思ったら、最新Verの0.98はVisualStudio2015対応のまま止まっています。

![image002.png](https://qiita-image-store.s3.amazonaws.com/0/68563/f028bc37-101a-e5e4-880a-a43b3489666a.png)

VisualStudio2017でサンプル動かそうとおもったのですが「ctype.hが見つからない」とエラー。

![image006.png](https://qiita-image-store.s3.amazonaws.com/0/68563/08a6134a-220b-8b53-d8c6-ae3cace82914.png)

解決方法としては下記のstackoverflowの記事を参考にしました。
https://stackoverflow.com/questions/42258311/cannot-open-include-file-ctype-h-no-such-file-or-directory

![image003.png](https://qiita-image-store.s3.amazonaws.com/0/68563/001dbfca-9d41-4c8a-bdbc-5390475c6d37.png)

Windows Universal CRT SDKにctype.h等々が含まれているようなのでインストールして解決。

Visual Studio 2017がリリースされてから早5か月くらい経つので、そろそろ対応してほしいところ。。。
【備忘録】 Azure CLI でローカルGitレポジトリからデプロイする手順

#目的
HTML5アプリケーションなどをローカルGitレポジトリからAzure上のWebAppにデプロイする手順。元記事から自分用に要点だけ抜粋したものです。

元記事
https://docs.microsoft.com/en-us/azure/app-service-web/app-service-web-get-started-html

# １．デプロイメント用のユーザー・クレデンシャルを設定する
デプロイメントの目的のみのためにユーザー・クレデンシャルを設定しなくてはならない。もちろん、一旦設定すれば次回からは同じクレデンシャルを使える。
`az webapp deployment user set --user-name <username> --password <password>`

ユーザ名とパスワードは後で必要なので保管しておく。
# ２．ローカルGitレポジトリをWeb Appのソースとして設定する
実質的には、Azure側にGitレポジトリを作る作業。AzureのSubscriptionを正しく選択していることが前提（`az account set --subscription <subscription_name>`を使用する）。

`az webapp deployment source config-local-git --name <app_name> --resource-group myResourceGroup --query url --output tsv`

返される値は以下のようなフォーマットになっているはず。
`https://<username>@<app_name>.scm.azurewebsites.net:443/<app_name>.git`
この値は次のステップで使う。

# ３．ローカルGitレポジトリにリモートを新規設定する
これは純粋なGit操作です。前ステップで作成したAzure側のGitレポジトリをローカルGit側の「リモート」として設定します。

`git remote add azure <URI from previous step>`

この段階でローカルGitレポジトリには`azure`と`origin`のふたつのリモートあることを確認します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/103139/1b31f638-f1eb-c14e-e994-781324efe8c8.png)

# ４．ローカルGitレポジトリのブランチをリモートレポジトリにPushする
ブランチのイメージがデプロイできる状態なら、通常のGit pushコマンドでPushします。

`git push azure master`

実質的にはこれがデプロイメントステップとなります。

完了。指定したWeb AppをブラウザでロードするとローカルGitレポジトリのブランチの内容が反映されているはず。
AWS上でjupyterを行う(メモ)

#参考にしたサイト一覧


http://qiita.com/Salinger/items/c7b87d7000e48be6ebe2#ssh-%E3%81%AE%E8%A8%AD%E5%AE%9A

http://linuxbrew.sh/

http://qiita.com/taka4sato/items/2c3397ff34c440044978

http://qiita.com/Salinger/items/c7b87d7000e48be6ebe2#ssh-%E3%81%AE%E8%A8%AD%E5%AE%9A
Heroku の AddOn、PointDNS を設定しました

Heroku の DNS がかなり前に動かなくなっていました。そういえば、だいぶ前に　Zerigo DNS が使えなくなるよとメール📩が来ていて忘れていました。

以下メール📩抜粋

>Zerigo DNS is no longer a supported add-on and its service may stop working at any time. If you are actively using the add-on for DNS resolution and it stops working, your app will go down.

>Please take action immediately to switch to a new DNS provider if you have not done so already. This is the final email communication regarding this add-on shutdown and continued use of this service will be at your own risk.

>We recommend the PointDNS add-on for your app's DNS management needs and have created this knowledge base article with detailed instructions on how to migrate from Zerigo DNS to PointDNS.

つまり Zerigo DNS 廃止するから PointDNS を勧めるよみたいな内容ですね。

# Heroku で DNS を振りたい人向け
この記事は ValueDomain + Heroku でドメイン設定を行いたい方が対象です。

# Heroku の Addons から PointDNS へ
Heroku に Addons という機能があるので、そちらから PointDNS で　Install PointDNS します。
https://elements.heroku.com/addons/pointdns

こんなモーダルがでました。
<img width="40%" src="https://qiita-image-store.s3.amazonaws.com/0/1624/bfb65e70-926f-ec4d-e5de-37ce60e652af.png">
**Provision** を押します。

## PointDNS の設定
Provision を押すと resources の画面に飛ばされました。
Add-onsに PointDNS が表示されています。

<img width="40%" alt="Heroku AddOn PointDNS" src="https://qiita-image-store.s3.amazonaws.com/0/1624/db0dfdea-55ab-9f60-23b0-b3e5a49b69d3.png">

My domains に pugiemonn.com があったので、そのリンクを進みます。

<img width="50%" alt="PointDNS" src="https://qiita-image-store.s3.amazonaws.com/0/1624/5dc3d60d-9950-fcd4-fcf4-a1cc024050e2.png">

こんな感じで pogiemonn.com が勝手に振られていました。

## ValueDomain に PointDNS のネームサーバーを指定
先程 PointDNS の画面で表示されたネームサーバーを ValueDomain のネームサーバーに書いておきます。
<img width="552" alt="ValueDomainにPointDNSのネームサーバーを指定" src="https://qiita-image-store.s3.amazonaws.com/0/1624/f996e1b5-567f-8d7f-68a2-afe550b23910.png">

# 動作
しばらく経ってから http://pugiemonn.com/ にアクセスしたら表示されました。

# 次にやること
さくらレンタルサーバーへサブドメイン（blog.pugiemonn.com）でアクセスできるようにします。
Rails twitter みたいにフォームでgif画像取得方法

##実装
[ブログにて](https://ryu-nishida.blogspot.jp/2017/07/span-display-block-overflow-hidden_99.html)
##結果
![images](https://i.gyazo.com/bfad06cd39ac567505f6b4d5e415efe7.png)
Windows派の私がMacを使い始めてタスクバーを求めてuBarに出会った話

#Macに移行したけどタスクバーが恋しい話
かれこれもう15年以上Windowsを使っていたのですが、
開発者的にはWindowsつらくね？ということで、この度ついにMacを購入して全面的に移行しました。

当然なのですが、細かいところであれこれ気になります。
そのうちにMac風のスタイルに慣れるとか、カスタマイズしてWindows風に寄せるとかして、徐々に順応してきました。

しかし、どうしても我慢できなかったことがひとつ。
Windowsのタスクバーです。

Macのそれにあたるものといえば、これは当然Dockですが、
**これが納得できません。**

*ひとつのアプリを複数ウィンドウ開いてウィンドウが隠れると、
どこいったかわからなくないですか？*


ということで、何かいいものはないものか半年間に渡って、
たまに調べては見つからず諦めて、を繰り返して……**ついに見つけました！**

***[uBar](https://brawersoftware.com/products/ubar)です！***

##ubarのご紹介

![スクリーンショット 2017-07-29 02.17.38.png](https://qiita-image-store.s3.amazonaws.com/0/122390/71ab6c57-2e02-8fcf-27d4-7b5c960735b8.png)

![スクリーンショット 2017-07-29 02.42.27.png](https://qiita-image-store.s3.amazonaws.com/0/122390/efa0da12-9fd3-7fce-6a30-7a36e8834243.png)

![スクリーンショット 2017-07-29 02.33.43.png](https://qiita-image-store.s3.amazonaws.com/0/122390/ebfcef2b-2645-99b4-ef49-04b6c65447c0.png)

このアプリを導入することによって概ねWindowsのタスクバーと同じようなことができます。

![スクリーンショット 2017-07-29 02.37.30.png](https://qiita-image-store.s3.amazonaws.com/0/122390/710e6a78-4c3a-872c-99ab-78ee2c779d77.png)
並び順は起動した順・アルファベット順・マニュアル指定順のいずれかを指定すると、
それ以外の順番にできませんが、その代わりタスクバーに表示しないアプリを設定することもできます。

##でも、お高いんでしょう？
ちなみにこのアプリ、~~20$です。~~30$になってました。
有料アプリですが、買い切りでこの値段なら、Windowsに~~飼い~~慣らされてしまった私には
大満足の体験でした。
naoqi2.5.5でALAutonomousLife::SwitchFocus に失敗しました。となるエラー

# naoqi2.5.5にアップデートしたら・・・
先日、naoqi2.5.5がPepper for dev向けにも配布されました。
この機にnaoqi2.5.5にアップデートしたときにタイトルのエラーが発生したので、その解決法をご紹介します。

# 実行環境
macOS Sierra 10.12.6
Choregraphe 2.4.3
PepperのNaoqi 2.5.5

# ALAutonomousLife::SwitchFocus に失敗しました。
naoqi2.5.5にアップデート後、Choregrapheから作成したアプリを実行しようとすると、以下のようなエラーが。
<img width="735" alt="ALAutonomousLifeError.png" src="https://qiita-image-store.s3.amazonaws.com/0/164020/6091de06-de0d-be68-e99a-27aa0d337d6a.png">

来週にはプログラムが完成しないといけないのに・・・かなり焦りました

# 解決方法
どうしたものかと思っていましたが、以下のサイトで解決策が見つかりました。
http://wanttobenya-n.hatenadiary.jp/entry/2017/07/22/132532

どうやら、言語設定関連のエラーのようです。
プロジェクトのプロパティから、言語設定「English」から「Japanese」にを変更すれば解決です。
（ただし、プロジェクト単位で各々変更する必要があります）

<img width="725" alt="ALAutonomousLifeError2.png" src="https://qiita-image-store.s3.amazonaws.com/0/164020/c1f82a5f-0735-8a45-77a1-4941ddabba31.png">

ここから・・・

<img width="897" alt="ALAutonomousLifeErrorBefore.png" src="https://qiita-image-store.s3.amazonaws.com/0/164020/39e0115f-b358-6e42-c50b-7d612ae73b50.png">

赤枠を変更します

<img width="898" alt="ALAutonomousLifeErrorAfter.png" src="https://qiita-image-store.s3.amazonaws.com/0/164020/6d0b8f48-6097-c870-3dc8-d4c52110ca22.png">

最終的にこうなればOKです
文字列の配列をfor文で回す(Python3)



こういう基本的なことが意外と見つからなかったのでメモ


```Python
data = ["hoge", "fuga"]

for i in range(len(data)):
    print(data[i])
```

追記
こちらの方が一般的だそうです＞＜
HigashinoSolaさんありがとうございます

```Python
data = ["hoge", "fuga"]

for s in data:
    print(s)
```
帰ってきたrubyクイズ　文字列の「+=」と「<<」

#問題

##第1問

```rb
s = "123"
ss = s
s += "456"
puts s  #=> ?
puts ss #=> ?
```

##第2問

```rb
s = "123"
ss = s
s << "456"
puts s  #=> ?
puts ss #=> ?
```


:mouse:
:cow:
:tiger:
:rabbit:
:dragon_face:
:snake:
:horse:
:sheep:
:monkey_face:
:bird:
:dog:
:boar:
:mouse:
:cow:
:tiger:
:rabbit:
:dragon_face:
:snake:
:horse:
:sheep:
:monkey_face:
:bird:
:dog:
:boar:


#答え

##第1問

```rb
s = "123"
ss = s
s += "456"
puts s  #=> "123456"
puts ss #=> "123"
```

##第2問

```rb
s = "123"
ss = s
s << "456"
puts s  #=> "123456"
puts ss #=> "123456"
```

`+=`は代入演算子で、
`<<`はビット演算子なため、
起きる違いでした:hugging_face:
今まで楽天で買い物した総額を算出する

Amazonのそれが再度熱を帯びているので、楽天市場の方も。

参考にしたサイト
http://blog.kantan-life.com/article/412662083.html

このサイトに記載しているコードでも充分に動くが、肝心の総額は計算されない。またChromeだと動作しない。
そこで、このサイトに掲載されているコードを改良し、ブックマークレット化した。
ブックマークレット化には「Closure Compiler」を用いている。
http://closure-compiler.appspot.com/home

```javascript:ブックマークレット
javascript:(function(){function c(a){a="number"!==typeof a?0:a;if(0===a&&($("<div/>").css({position:"fixed",left:0,top:0,width:"100%",height:"100%",zIndex:1E3,backgroundColor:"rgba(0,0,0,.7)",color:"#fff",fontSize:30,textAlign:"center",paddingTop:"15em"}).attr("id","___overlay").text("\u697d\u5929\u5e02\u5834\u3044\u304f\u3089\u4f7f\u3063\u305f\uff1f").appendTo("body"),e=2012,!/^[0-9]+$/.test(e)))return alert("\u6b63\u3057\u3044\u6570\u5024\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044"),$("#___overlay").remove(),
!1;var b=h(a+1);$("#___overlay").text("\u96c6\u8a08\u4e2d\u2026  / "+(a+1)+"\u30da\u30fc\u30b8\u76ee");b.done(function(k){f+=k;c(a+1)}).fail(function(){for(var a=alert,b=(new String(f)).replace(/,/g,"");b!=(b=b.replace(/^(-?\d+)(\d{3})/,"$1,$2")););a("\u3042\u306a\u305f\u306f\u5408\u8a08"+b+"\u5186\u5206\u306e\u8cb7\u3044\u7269\u3092\u697d\u5929\u5e02\u5834\u3067\u3057\u307e\u3057\u305f\uff01");$("#___overlay").remove()})}function h(a){var b=$.Deferred();l(a).done(function(a){a=$.parseHTML(a);var c=
0;$(a).find(".price").each(function(){var a=$(this).text().match(/[0-9]/g),b=0;null!=a&&(b=Number(a.join("")));c+=b});0===c?b.reject():b.resolve(c)});return b.promise()}function l(a){var b=$.Deferred();$.ajax({url:"https://order.my.rakuten.co.jp/?page=myorder&fidomy=1&display_month=0&search_item=&page_num="+a+"&search_sender=&search_shop=",success:function(a){b.resolve(a)}});return b.promise()}var f=0,e="2012";if("function"!==typeof $){var g=document,d=g.createElement("script");d.src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js";
d.onload=c;g.body.appendChild(d)}else c()})();﻿
```
あとは楽天の購入履歴のサイトへ移動し、
https://order.my.rakuten.co.jp
上記ブックマークレットをURL欄にペースト、頭にjavascript:を追加して実行するだけで計算される。
ちなみに私は300万弱と計算された。怖い。


Amazonの方もそうだが、案外この手のものは既存のものを少し改良（クラス名を変更するだけなど）することにより、様々なものを計算することが出来る。
いろんなサイト向けのものを作ってみよう。
Juliaでアニメーションgif生成

# とにかくデータをアニメーションさせたい

線が流れる様子はとてもいいものだ．

# とにかくJuliaつかってみたい

なんだかよさそうなのでつかってみたい．
https://juliaplots.github.io/animations/ を動かしてみた．

# 動かした

![anim_fps30.gif](https://qiita-image-store.s3.amazonaws.com/0/131710/2f4d33ee-9111-61ca-998a-9038c09a1de3.gif)

```Julia:
using Reactive, Interact, Plots

x = linspace(0, 2*pi, 100)
dt, nsteps = 0.1, 10

anim = @animate for i in x[2:end]
    plot(x, sin.(x - i))
end

gif(anim, "/tmp/anim_fps15.gif", fps = 15)
gif(anim, "/tmp/anim_fps30.gif", fps = 30)

```

# 感想

pythonよりアニメーションさせやすい気がする．
ノイズが走るの気になる．
HoloLensではじめるMRDesignLabs - MRDesignLabs_Unity_LunarModuleの遊び方

# MRDesignLabsの新作アプリは楽しいですよ！
MRDesignLabsから新しいサンプルアプリがリリースされました。LunaModuleというゲームです。内容はいたって簡単。月面に宇宙船を操作してうまく着陸させるというものです。昔2Dのゲームで燃料を消費しながら噴射を駆使して宇宙船を着陸させるゲームがあったかと思うのですが、あれのHoloLens版です。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">MRDesignLabsの新しいサンプルアプリ「MRDesignLabs_Unity_LunarModule」面白いけどかなり難しい。&#13;興味深い機能が多いのでまた勉強しよう。 <a href="https://t.co/xwJCdvsGIY">pic.twitter.com/xwJCdvsGIY</a></p>&mdash; takabrz (@takabrz1) <a href="https://twitter.com/takabrz1/status/890561923518939141">2017年7月27日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

動画のものは１時間くらい苦戦して無事着陸にこじつけられた記念すべき映像です。単純なのですがかなり時間を忘れて遊べてしまうのでHoloLensあれば簡単に動かせるのでお試しあれ。少し操作方法に癖があるのでせっかくなのでコツを紹介します。また、面白いだけではなく非常に気になる機能が色々導入されているので次回以降でいくつかピックアップして説明をしたいと思います。本日のメニューはこちら。

1. 実行手順
2. 操作方法
3. 新しく導入された機能

## 1. 実行手順

実行までの手順は特に難しくありません。Gitからソースを取得してビルドすれ動かせます。今回の開発環境は以下の通りです。

* Visual Studio 2015 update 3
* Unity 5.6.1f1
* Windows 10 Pro (Creators Update)

まず初めにGitからソースコードを取得します。
[https://github.com/Microsoft/MRDesignLabs_Unity_LunarModule](https://github.com/Microsoft/MRDesignLabs_Unity_LunarModule)

任意の場所にクローンしてください。
次にUnityを起動してLunarModuleを開きます。
LunarModuleはMRDesignLabsライブラリを利用しているので、フォントの設定が必要になります。設定方法については[こちら](http://qiita.com/miyaura/items/cf0ebc41733a4b31e137#1-mrdesignlabs%E3%82%92%E4%BD%BF%E3%81%88%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E6%BA%96%E5%82%99%E3%81%99%E3%82%8B)から。

Unityからのビルドは通常のHoloLensのビルドと同じです。
ビルド後はVisual Studioでソリューションを開き「Release」-「x86」でビルドしてHoloLensにデプロイしてください。なお、Debugではとても重く遊べないですよ！

## 2. 操作方法

起動するとレトロなメニューが表示されます。
![image](https://qiita-image-store.s3.amazonaws.com/0/152548/d032d3a5-a6fc-8afd-3878-510b55f3c87c.png)

スタートを選択するとチュートリアルから始まってゲームの開始になります。
操作はゲーム内で「Hands」「GamePad」が選択可能です。HoloLensですので迷わず「Hands」を選択してください。（本気で高得点狙うならGamePadがいいとおもいます）

![image](https://qiita-image-store.s3.amazonaws.com/0/152548/a9aa0df3-48fd-6988-4ae0-53a1193b10a8.png)

HoloLensであればジェスチャーでの操作になりますが、うまく両手が認識できている状態でないとうまく操作できません。
コツとしてはゲームスタート時に両手の人差し指を立てた状態で少し待つと機体左の方にゲージが表示されます（エンジン出力ゲージ）。これが出ている状態からホールドを行い指を動かせば機体の操作ができます。機体の操作は以下の表のとおりです。

|使う手|操作内容|操作方法|
|:-:|:-:|:--|
|左手|エンジンの出力調整|ホールド：上 - エンジンの出力を上げる<br/>ホールド：下 - エンジンの出力を下げる|
|右手|宇宙船の姿勢制御|ホールド：上 - ヨーイング（宇宙船の向きを右に回転)<br/>ホールド：下 - ヨーイング（宇宙船の向きを左に回転）<br/>ホールド：手前-ローリング（宇宙線を左に傾ける）<br/>ホールド：奥 - ローリング（宇宙船を右に傾ける）<br/>ホールド：左 - ピッチング（宇宙船の機首を下げる）<br/>ホールド：右 - （宇宙船の機種を上げる）|

ホールドの操作はおおよそ10㎝も動かす必要ないくらい小さい操作で動きます。
うまく操作してゴールに着陸させましょう！

## 3. 新しく導入された機能

Lunar ModuleにはMRDesignLabsとは別に新しい機能が追加されています。これらの機能自体は[README.md](https://github.com/Microsoft/MRDesignLabs_Unity_LunarModule/blob/master/README.md)でも紹介されています。
主に以下の３点が追加されています。次回はこれらの機能について紹介したいと思います。
特にHnad Coachはデモやサンプルではかなり重宝しそうです。

* Local Hnad Input - タップ地点を起点にホールド操作に応じて指の移動量や速度を取得する機能
* Simple Menu Collection - 簡単なメニューを作成するためのコレクション
* Hand Coach - ジェスチャーの操作方法を見える化。チュートリアルなどを作成するための機能
サーバー起動時に非rootユーザーでsystemdを使ってサービスを立ち上げる

ハマりどころしかなくてなかなかうまくいかなかったのでハマったポイントを全てメモしておく。

## 設定ファイルはhome以下に置く必要がある
/etc/systemd 以下とかに置いてもダメ。~/.config/systemd/user/*.service を使わないと--userではうまくいかない。

## [Install]を必ず書く
```
[Install]
WantedBy=default.target
```

がないとenableしても意味ない

### --userモードにはmulti-user.targetが存在しない
普通、rootで起動するサービスはmulti-user.targetにしておくのが良いようだが、--userで使う場合はdefault.targetじゃないと起動してくれない。

### [Install]をいじったら `systemctl --user enable`を叩き直す
WantedByが変わるとsymlink先も変わる。その場合enableもやり直さないと当然ダメ。
その前に`systemctl --user daemon-reload`が必要かもしれないがこれはちゃんと確認してない。

~/.config/systemd/user/default.target.wants/*.service がなかったらまず動かない。

## systemのunitは参照できない
https://wiki.archlinux.org/index.php/Systemd/User

> `systemd --user` runs as a separate process from the `systemd --system` process. User units can not reference or depend on system units.

ということなので、`After=mysql.service`みたいなのを書いてしまうと逆に動かなそう。これが原因で動かなかったのかは確認してないが、とにかく外した状態で動いている。

## デフォルトではログインした時に立ち上がる
まず、ログインしたら立ち上がる状態には持っていく必要がある。その後、以下のようなコマンドを実行することでサーバーの起動時にサービスが立ち上がるようになる。

```
sudo loginctl enable-linger username
```
Anconda4.2.0-Python3環境構築(Windows)

#Pythonとは
プログラミング言語にはたくさんの種類があります。代表的なものではC言語、Java、html、Pythonなどが挙げられます。この中で比較されるのがC言語とPythonです。それぞれの違いについて見ていきます。

|  | C言語、Java | Python | 
|:-----------|------------:|:------------:|
| 長所       |     実行速度が早い    |※インタプリタのため※コンパイルが必要ない コード量が比較的少ない|     
| 短所     | コンパイルが必要　コード量が多い　etc... |    実行速度が遅い    |

※コンパイルとはプログラムを機械語に変換すること
※インタプリタとはプログラムをソフト上で実行するプログラムのこと

#anacondaとは
Continuum Analytics 社によって提供されているPythonでよく用いられるライブラリを一括にインストールすることができるパッケージのことです。
anacondaの中にこんなライブラリが入っています。

pandas
numpy
jupyter notebook

今回はanaconda4.2.0をインストールしていきます。
最新バージョンは4.4.0となっています。なぜ古いバージョンをインストールするのか。
それは、現在人工知能開発で主流となりつつあるライブラリ「Keras」に非対応であるためです。
もっと詳しく説明するとanaconda4.2.0のPythonのバージョンは3.5で4.4.0はPython3.6です。しかしKerasはPython2.7~3.5にしか対応していないのです。
Pythonではそのライブラリが最新のバージョンに対応していないことが稀にあります。もっとも最新のバージョンを使用すると、エラー等の報告記事が以前のバージョンに比べて少なくなるため対応が難しくなる可能性もあります。
ですので安易に最新バージョンをインストールするのではなく、ライブラリ等の対応を確認することが重要です。
#【実践】環境構築
anacondaソフト置き場
<a href="https://repo.continuum.io/archive/">anacondaソフト</a>

今回は時間短縮のため事前にUSBに用意したanacondaをインストールします。

インストール画面
![win anaconda1.png](https://qiita-image-store.s3.amazonaws.com/0/176377/d83a6487-0405-9fc8-e893-b8191de5f400.png)

ユーザーの選択
![anaconda3.png](https://qiita-image-store.s3.amazonaws.com/0/176377/05b2c1f5-848a-fdd0-e2ff-9b384cfed95a.png)
All Usersを選択します。

インストールが終了したら、anacondaがインストールされているかを確認します。windowsキー+Rキー同時押しで「ファイル名を指定して実行」が出てくるので、「cmd」と入力します。
![anaconda4.png](https://qiita-image-store.s3.amazonaws.com/0/176377/77130d36-13cd-c084-49a7-78bf6b491f50.png)

コマンドプロンプトが出てくると思います。「python」と入力してEnterキーで実行します。
![anconda5.png](https://qiita-image-store.s3.amazonaws.com/0/176377/83e0be23-eb31-21ff-13df-d2b6629dfffd.png)

このようにpythonの実行入力画面が出てくれば成功です。
![anaconda6.png](https://qiita-image-store.s3.amazonaws.com/0/176377/a25862e6-72af-2bc1-ed9d-7579ae7bc950.png)

「quit()」と入力してpythonを一旦止めます。

#ライブラリのインストール
pythonには「pip」コマンドが実装されています。
「pip freeze」と入力するとインストールされているライブラリの一覧が出て来ます。
![anaconda7.png](https://qiita-image-store.s3.amazonaws.com/0/176377/69282b68-1e59-02ce-3ee6-3f1c5bcf9642.png)

今回は一つの例としてtensorflowとkerasをインストールします。
tensorflowを入れましょう。

```py
pip install tensorflow
```

と入力します。
次にkerasです。こちらも同様に

```py
pip install keras
```
と入力します。




#JupyterNotebook
コマンドプロンプトで「jupyter notebook」と入力します。
![jupyter.png](https://qiita-image-store.s3.amazonaws.com/0/176377/764b5817-781b-e5cc-a64e-0656aeba994e.png)

するとこのようにブラウザが勝手に立ち上がります。
![win jupyter1.png](https://qiita-image-store.s3.amazonaws.com/0/176377/96898d02-fb98-019e-d20f-bd5b18b0ea04.png)

今回はここでpythonを使っていきます。


はじめに右上のNewをクリックします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/176377/e71fad8a-4104-75c6-2025-e51dd45c54d7.png)

次にconda root をクリックします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/176377/288e0041-916a-b7c8-b4e7-5f3815712d78.png)

このようになれば成功です。
![jupyter2.png](https://qiita-image-store.s3.amazonaws.com/0/176377/da0c0dd5-6ca6-4508-1632-c81ac5e80564.png)

以上でPythonを扱う上での必要なものが全て整いました。

寄付していただければ幸いです！
仮想通貨
BTC 18c58m54Lf5AKFqSqhEDU548heoTcUJZk
ETH 0x291d860d920c68fb5387d8949a138ee95c8d3f03
ZEC t1KtTRKy9w1Sv5zqi3MYnxZ3zugo54G4gXn
REP 0x291d860d920c68fb5387d8949a138ee95c8d3f03
DockerでTAIGAのインストールに成功するが、エラーでトップページ以降に進めない。


## 状況
VPSにDockerでTAIGAをインストール。
トップページは表示されるが、何かが起こりました的なメッセージが出て先に進めない。

![スクリーンショット 2017-07-29 0.18.15.png](https://qiita-image-store.s3.amazonaws.com/0/28850/2f703833-0d4f-3713-b0bd-90a124fda3df.png "スクリーンショット 2017-07-29 0.18.15.png")


手順は下記コマンドを実行したのち、ブラウザでVPSのドメインにアクセス。

- TAIGAインストール

```
docker run -d -p 80:80 -t -i -h taiga --name taiga accon/taiga
```


## Ajaxでエラーになっているのが原因か？
ChromeのDevToolsでNetworkを覗いてみると
127.0.0.1に対してAjax通信しようとしてエラーになっているJSがいる。

![スクリーンショット 2017-07-29 0.17.46.png](https://qiita-image-store.s3.amazonaws.com/0/28850/da1f94bc-3d51-53a6-f384-49f8ae10e434.png "スクリーンショット 2017-07-29 0.17.46.png")


## 127.0.0.1が記述されているファイルを修正
とりあえずコンテナに入ってそれっぽいファイルに手を加える。

- コンテナにログイン

```
docker exec -it taiga bash
```

- 修正前のファイル

```json:/develop/www/conf.json
"api": "http://127.0.0.1/api/v1/",
"eventsUrl": "ws://127.0.0.1/events",
```

- 修正後のファイル

```json:/develop/www/conf.json
"api": "http://＜VPSのドメイン＞/api/v1/",
"eventsUrl": "ws://＜VPSのドメイン＞/events",
```

これでエラーはなくなり、サインアップしてプロジェクト作成までいき、今のところは正常に動いている。


## 参考記事
[Love Your Project： TAIGA簡単インストール (アジャイル・プロジェクト管理ツール)](http://qiita.com/maemori/items/4bd1b985774d17888e29)
[UE4]マテリアルブループリント内でクォータニオンでオブジェクトを回す

マテリアルブループリント(以下 マテリアルBP)内でオブジェクト回転させたい時に便利なノードに
RotateAboutAxisというノードがあります。
回転の中心位置とAxisとAngleを渡せば回転させる事ができる便利なノードなのですが、
使い方についてはヒストリアさんのこちらの記事が大変参考になります。

[UE4] RotateAboutAxisでオブジェクトを回転する
http://historia.co.jp/archives/6261


このノード、x, y, z軸の3軸の回転が組み合わさると少し面倒な事になりました。
まず、2軸以上で回す際には僕はNormalizeを忘れていたので思った様に回せなくて困りましたが、
UE4のAnswerHubの方で教えて頂きました。ありがとうございます！


マテリアルブループリント内で2軸以上での回転の方法
https://answers.unrealengine.com/questions/675115/%E3%83%9E%E3%83%86%E3%83%AA%E3%82%A2%E3%83%AB%E3%83%95%E3%83%AB%E3%83%BC%E3%83%95%E3%83%AA%E3%83%B3%E3%83%88%E5%86%85%E3%81%A62%E8%BB%B8%E4%BB%A5%E4%B8%8A%E3%81%A6%E3%81%AE%E5%9B%9E%E8%BB%A2%E3%81%AE%E6%96%B9%E6%B3%95.html


たとえば、x軸を45度、y軸を105度、z軸を15度の回転をさせたい！となった場合には上記だけでは
なすすべがありません、、

この様な場合、x, y, z軸それぞれのクォータニオンを作って掛け合わせることで最終的なAxisとAngleを求めれば
いいのですが、残念な事にマテリアルBP内にはクォータニオンにまつわるノードは用意されていません。
クォータニオンの計算をBPで全て用意すればいいのですが、面倒なのでカスタムノード内でクォータニオンの計算
をする事で実現する事ができましたので方法を以下にまとめておきます。


マテリアルBP内のノードの繋ぎは以下の様な感じです。

![2.PNG](https://qiita-image-store.s3.amazonaws.com/0/21126/8a834743-e25d-39d2-c6c6-cee8fe82d5f1.png)


それぞれのカスタムノード内の設定はこんな感じ

[MakeQuaternionByAxisAngle]
AxisとAngleを指定してクォータニオンを生成するカスタムノードです
![3.PNG](https://qiita-image-store.s3.amazonaws.com/0/21126/7586bc31-3090-908b-6334-9812cd64861a.png)


[MultiplayQuaternions]
２つのクォータニオンを掛け合わせるカスタムノードです。
![4.PNG](https://qiita-image-store.s3.amazonaws.com/0/21126/1df173af-612a-59ee-af88-bfc630a65a78.png)


[GetAxisAndAngleByQuaternion]
クォータニオンからAxisとAngleを取得します。(x,y,zがAxisで, wにAngleを書き込んでます)
![4.PNG](https://qiita-image-store.s3.amazonaws.com/0/21126/e5ace1b6-f76a-1194-59fe-2c5ea315c60c.png)


注意点としてはRotateAboutAxisのAngleに指定する値はDegreesでもRadiansでもなく、0~1の値です。
90度なら0.25, 180度なら0.5, 360度回したいなら1.0を指定するといった感じで、僕はここで
挙動が読めなくてかなり躓きました、、 
あと、PivotPositionで0, 0, 50を指定しているのはUE4のデフォルトのキューブをレベルに配置して
試しているのですが、このキューブのピボット位置がキューブの中心じゃないのと、キューブのサイズが100なので
z座標を半分だけ中心にズラしているという理由です。

こちらが完成動画
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">マテリアルBP内だけで3軸をクォータニオンで計算して回転させるのできた！ これで大量のインスタンシングされた各オブジェクトを個別に自由に回転させれるはず <a href="https://twitter.com/hashtag/UE4?src=hash">#UE4</a> <a href="https://t.co/atM9k7sOy1">pic.twitter.com/atM9k7sOy1</a></p>&mdash; selflash (@selflash) <a href="https://twitter.com/selflash/status/890895166407450624">2017年7月28日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>



[追記 2017/7/29] 
法線も回さないとライティングがおかしな事になるという事を忘れてました。
ヒストリアさんの記事を見るにこれでいいのかなと思います。
が、上手くいっているのかどうか複雑なオブジェクトで試してはないのでもしかしたら間違っているかもしれません。その際は上記で述べたヒストリアさんの良記事をご参考ください。

![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/21126/44b6a55b-899f-d601-aee8-810eee23969d.png)
ハフ変換を使った円形の物体認識


円形の物体を認識して切り取る方法があることを知ったので、メモ。

# 準備編
## OpenCVの準備

まずは、PythonからOpenCVを使えるようにする。

最近のAnaconda環境では、Python 3.6がインストールされるんだけれど、Python 3.6にインストールできるosx-64環境用のOpenCV3のconda パッケージが公開されていないので、Python 3.5環境を用意する。

とりあえず、condaで仮想環境を作っておいた。

	conda create -n py35 python=3.5 anaconda

その後、`source ~/.pyenv/versions/anaconda3-4.4.0/bin/activate py35` した後に、`conda install --channel https://conda.anaconda.org/menpo opencv3` しておく。

## サンプル画像の用意
ちょうど良い画像が手元になかったので、ImageJのサンプルをダウンロードして使う。

- https://imagej.nih.gov/ij/images/embryos.jpg

![embryos_mini.jpg](https://qiita-image-store.s3.amazonaws.com/0/15553/85e37819-ebfe-b8d3-4a7c-580c6f1f1149.jpeg "embryos_mini.jpg")

# 実装する

http://docs.opencv.org/3.1.0/da/d53/tutorial_py_houghcircles.html を参照しながら、実装してみる。

```houghcircles_sample.py
import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('img/embryos.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blur = cv2.medianBlur(gray, 5)

circles = cv2.HoughCircles(blur, cv2.HOUGH_GRADIENT,
								dp=1, minDist=20, param1=50, param2=30,
								minRadius=10, maxRadius=100)
circles = np.uint16(np.around(circles))
for (x, y, r) in circles[0]:
	cv2.circle(img, (x, y), r, (0, 255, 0), 2)
	cv2.circle(img, (x, y), 2, (0, 0, 255), 3)

plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
```

## 実行結果

![result.png](https://qiita-image-store.s3.amazonaws.com/0/15553/f579465b-5306-ad01-c999-61cf92f97a61.png "result.png")

なかなか悪くない。`param1`と`param2`の調整次第では、ちゃんと細胞をカウントできそうだ。

----

# 本日のコード
- https://github.com/fukuit/Python_SelfLearning/blob/master/hough/houghcircles_sample.py
Jupyter Notebookを起動する時に新しいウィンドウで開く(Windows)

Jupyter Notebookを起動するとき、新しいウィンドウを開くときの設定です。
Windows版が意外に無かったので、書きました。

[Jupyter Notebookを起動する時に自動で新しいウィンドウで開く]
(http://qiita.com/irs/items/e39378206fb48e374806)
を参考にしました。Mac版です。

## 実行環境
Windows 10 (64bit)
Anaconda 4.4.0 (64bit)

## 準備
設定ファイルの作成。

```
 > jupyter notebook --generate-config
```
Anacondaをインストールした場所に <ユーザー>/.jupyter/jupyter_notebook_config.py等に生成されます。


## 設定変更
jupyter_notebook_config.pyからc.NotebookApp.browserを探して、以下に変更。

```
c.NotebookApp.browser = '\"C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe\" %s --new-window'
```

%sがURLで、--new-windowが新しいウィンドウで開くことを意味しています。

exeを「"」を囲んでから、オプションを指定するなんて、思いつきません。
Rails5.1に移行後のmigrationファイルの注意

Rails5.1後に作成するmigrationファイルはデフォルトでidカラムにbigint型を使う(Mysqlの場合)
規模が大きいアプリケーションなら良いが、これによって不都合が出る人も割りといるのではないか。

そもそもintで十分なところをbigintにすると、1レコード辺りのデータ容量を余計に使ってしまう。

解決するには、create_tableメソッドのオプションでidの型を指定する。

```ruby
create_table :cards_tags, id: :integer do |t|
# ...
end
```

bigintによって既存テーブルとの関係でエラーの原因になることも。以下で詳しく述べる。

## referencesのエラー

例えば、既存テーブルを参照するmigrationファイルを生成して実行してみると、以下エラーになることがある。

以下のように既存のcardsとtagsを紐付ける中間テーブルを作成

```ruby:cards_tagsの生成
class CreateCardsTags < ActiveRecord::Migration[5.1]
  def change
    create_table :cards_tags do |t|
      t.references :card, foreign_key: true
      t.references :tag, foreign_key: true

      t.timestamps
    end
  end
end
```

実行後、

> Mysql2::Error: Table 'copylog_development.cards_tags' doesn't exist: SHOW FULL FIELDS FROM `cards_tags`

とでる。

referencesで作ろうとしている`card_id`, `tag_id`はbigint型。
対して外部キーで参照したいcardsテーブルのidがinteger型なので、型が合わずエラーになるようだ。

## 解決策
[mysql - Migration to create table raises Mysql2::Error: Table doesn't exist - Stack Overflow](https://stackoverflow.com/questions/44550062/migration-to-create-table-raises-mysql2error-table-doesnt-exist)
こちらが参考になったが、migrationの[5.1]の指定を5.0に戻すか、次のようにreferencesを使用しない形式に変える。

```ruby:cards_tagsの生成(5.1版)
class CreateCardsTags < ActiveRecord::Migration[5.1]
  def change
    create_table :cards_tags, id: :integer do |t|
      t.integer :card_id, foreign_key: true
      t.integer :tag_id, foreign_key: true

      t.timestamps
    end
  end
end
```
arXiv APIのPythonでの取得

# arXiv API

なんかtwitter@astro_ph_EPは止まってしまったし，指定カテゴリだけながすbotさんとか欲しいかなー，みたいな感じでちょっとarXiv APIでも見てみましたが．

しかし公式( https://arxiv.org/help/api/user-manual )の記述そのままでは動作しないのでした… 


# 公式の修正

エラーは以下で発生．

```python
data = urllib.urlopen(url).read()
```

urllibが古い?
公式の記述なら下記のように書き換えれば動作します！

```python3
import urllib.request
url = 'http://export.arxiv.org/api/query?search_query=all:electron&start=0&max_results=1'
data = urllib.request.urlopen(url).read()
```

# 取得例

```python3
import urllib.request
import datetime as dt
import re


def main():
	basedate = dt.date.today()+dt.timedelta(days=-1)
	previousdate = basedate +dt.timedelta(days=-1)

	url_q = 'http://export.arxiv.org/api/query?search_query=submittedDate:['+previousdate.strftime('%Y%m%d')+'1400+TO+'+basedate.strftime('%Y%m%d')+'1400]+AND+(cat:astro-ph.EP)&start=0&sortBy=submittedDate&sortOrder=ascending'
	data = urllib.request.urlopen(url_q).read().decode('utf-8')
	#
	parse = lambda a,b: re.findall("<" + b + ">([\s\S]*?)<\/" + b + ">", a)
	#
	entries = parse(str(data), "entry")
	for entry in entries:
		url = parse(entry, "id")[0]
		title = parse(entry, "title")[0]
		author = ', '.join(parse(entry, "name") )
		summary = parse(entry, "summary")[0]
		print( '%s\n%s\n%s\n%s' % (url, title, author, summary) )

if __name__ == '__main__':
	main()
```

微妙にNew submissionsと件数が合わない…
米祝日はholidays.US()を使えば回避可能．
SPAかつSEO意識したサイトを作る時のスタック

※ 本記事はポエムです。もし鉞を投げてくれる心優しい方がいたらコメントしてもらえると嬉しいです ><

一からWebサービスを作るにあたり、できる限りモダンな環境を作ろうとしている。
リリースはできる限り早くしたいので、個人的に分からない領域であまり思い切ったことはしない。NoSQL使うとか、サーバーレスとか、Docker本番運用とか。
スタックの構成を考えている時が一番楽しいので、思いついたものを羅列していく。

# インフラ・DevOps


- Elastic Beanstalk (AWS)
    - ELB
    - EC2 with Autoscaling
- RDS
- ElastiCache(Redis)
- S3
- Route53
- CircleCI
    - GitHubと連携して、 `master` ブランチにリリースしたら自動テスト → 自動デプロイ
- GitHub
    - 開発スピードを速めたいので `GitHub Flow` で。
- `.ebextension` 構成管理

AWSは鉄板。
EBはデプロイとオートスケールの設定が楽なので、これにした。
CloudFrontで世界中に Content Delivery したいけど、初期は国内サービスだしな・・・
CircleCIも使い慣れているし、設定が楽で対応プラットフォームも多いのでこれで

# 言語/フレームワーク

- Node.js
    - Express （APIサーバー）
    - Bookshelf.js または Sequelise.js （ORM）
    - node_redis
    - socket.io
- Vue.js
- PostCSS
- テスト
    - Karma + Mocha 使ったこと無いので要検討 Jasmine とか Chai とか色々ある
    - GoogleChrome/lighthouse Chrome59 からの Headless 機能を利用したい
    - ESLint Standard rule で
- UIフレームワーク
    - 全体は `Skeleton.css`
    - コンポーネントは `keen ui` or `element-ui`
- Webpack
    - postcss-loader
    - vue-loader
    - pug-loader
    - babel-es6
    - babel-polifill

Node.jsを選択。JS好きだし、パフォーマンスが良いのと、サーバーとクライアントで言語を共通化できるっていうのがどのくらい恩恵があるのか試してみたいので

- LaravelとかRailsとか鉄板MVCフレームワーク使ってもいいけど、今更やっても正直面白くはない
- Rust, Elixir, Golang, Swift とかやりたいけど、やる理由が無い

# 設計

- CSSドキュメント Materialize.cssみたいな実例付き
- Vue.js コンポーネントドキュメント element-ui みたいな感じにしたい
    - `props`, `event`, `slot` をドキュメント化して、コード見なくても使えるようにしたい
- APIドキュメント
    - REST原則。リソース単位。
- 当たり前かもしれないが、ビジネスロジックはサーバーサイドで全てやる。Vue.jsは描画に専念する。 `methods:` でごちゃごちゃやるのは最悪。
- SEOが必要なページは、Pugで静的なページを返す
- SEOが不要なページ（ログイン後の画面）は、フルSPA

nuxt.jsでSSRとか、BFFとかやりたいけど、どこかで事故りそうなので

# 開発環境

- Vagrant
    - `yarn run watch` でホットリロード

Docker 使いたいんだけど、 Macでトラブったので敬遠
みんなLinux使いにならないかなー Systemd nspawn + Ansible でやりたい

# その他

- JSライブラリ 絶対他にもあるけど
    - [moment.js](https://momentjs.com/)
    - axios
    - lodash
    - cropper.js 及び vue-cropper
    - [Faker.js](https://github.com/marak/Faker.js/)
- Slackに通知を集約
- KPI管理のために、 `re:dash` 入れるのも有り superset でも良いかも？
- Vim, Vim, Vim...
has_many :throughの結合モデルの属性を関連先モデルの属性として取得する


# やること

あるユーザが画像群の中から複数枚を選んでプロフィール画像として設定できるような、次のテーブルがあるとします。特徴としては、結合モデル `profile_images` に外部キー以外の属性 `order` があることが挙げられます。

![relations.png](https://qiita-image-store.s3.amazonaws.com/0/62097/f97b1dec-1ab6-013e-0835-ecc76f2a3cfc.png "relations.png")

これをActive Recordで書くと次のようになります。

```ruby
class User < ApplicationRecord
  has_many :profile_images
  has_many :images, through: :profile_images
end

class ProfileImage < ApplicationRecord
  belongs_to :users
  belongs_to :images
end

# Image は省略
```


このとき、結合モデル `ProfileImage` の属性 `order` を取得する場合と、関連先のモデル `Image` の属性 `src` を取得する場合とで、次のように書き分けなければなりません。

```ruby
user.profile_images.first.order
user.images.first.src
```

記述を統一させるために、`User` のレコードから関連先 `Image` をたどる場合は、次のように `ProfileImage` の属性も `Image` の属性も統一した形で取得できるようにします。

```ruby
user.ordered_images.first.order # User からたどると Image から ProfileImage#order を参照できる
user.ordered_images.first.src
```

# やりかた

`has_many` の第2引数 (`scope`) に次のようなラムダ式を渡します。この引数は関連先を取得するときに使うクエリををカスタマイズするために使います。

```ruby
class User < ApplicationController
  has_many :ordered_images,
           ->{ select("#{Image.table_name}.*", "#{ProfileImage.table_name}.order AS order") },
           through: :profile_images,
           class_name: 'Image'
end
```

**※注意**: ここでは普通の関連と区別するために `ordered_images` という名前にしています。また、この方法を使うと、`user.ordered_images.count` のような集約操作はクエリをうまく生成できずエラーになります。

ここでは、テーブル `users`, `profile_images`, `images` をJOINしたテーブルをもとに関連先 `Image` のオブジェクト群を取得するときに、ラムダ式内の [`select`](http://api.rubyonrails.org/v5.1.2/classes/ActiveRecord/QueryMethods.html#method-i-select) で `Image` の属性に加えて `ProfileImage.order` を合わせてSELECTするようにしています。

これで `user.ordered_images.first.order` のように、`User` レコードから関連をたどったときは関連先モデルが結合モデルの属性を持つかのように取り扱うことができます。

# 参考資料

- [ActiveRecord::Associations::ClassMethods](http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many)
  - `has_many` の説明の "Scopes" を参照のこと
CentOSにPostgreSQLをインストールしてRailsと連携させる

# はじめに
久しぶりにCentOSへRailsをインストールする機会があったので、PostgreSQLのインストールからRails連携までの手順をメモしました。

**環境**
CentOS 7.3.1611
Rails 5.1.2
PostgreSQL 9.2.18

**もくじ**
1. インストール
2. 事前準備
3. DBユーザ作成
4. データベース作成
補足. postgresユーザのパスワード設定
5. 認証設定
6. Rails
7. 自動起動設定

# 1. インストール

```
# インストール
$ sudo yum install -y postgresql-server

# バージョン確認
$ psql --version
```

# 2. 事前準備

初期化（データベースクラスタを作成）

```
# 初期化
$ sudo service postgresql initdb
```

PostgreSQLをサービス起動

```
# サービス起動
$ service postgresql start
```

PostgreSQLをインストールするとシステムに追加される`postgres`ユーザのパスワードを変更する

```
$ sudo passwd postgres
```

# 3. DBユーザ作成

```
# postgresユーザに切り替え
$ su - postgres
```

```
# DBユーザを追加
-bash-4.2$ createuser -P DBユーザー名

# psql接続
-bash-4.2$ psql

# ユーザ一覧の確認
postgres=# \du

# PostgreSQLから抜ける
postgres=# \q
```

# 4. データベース作成

※postgresユーザに切り替えた状態で実施

```
# psql接続
-bash-4.2$ psql

# データベースの作成
postgres=# create database データベース名;

# データベース一覧の確認
postgres=# \l

# PostgreSQLから抜ける
postgres=# \q
```

# 補足. postgreユーザのパスワード設定

※postgresユーザに切り替えた状態で実施

md5認証が有効でもpostgresユーザでpsqlを利用できるようにパスワードを設定しておく

```
# psql接続
-bash-4.2$ psql

# パスワード設定
postgres=# \password

# PostgreSQLから抜ける
postgres=# \q
```

# 5. 認証設定

PostgreSQL接続時の認証方式をmd5に変更する

```
# 認証設定を変更
$ sudo vi /var/lib/pgsql/data/pg_hba.conf
```

```text:/var/lib/pgsql/data/pg_hba.conf
# "local" is for Unix domain socket connections only
local   all　　　　postgres        md5
```

PostgreSQLを再起動する

```
$ sudo service postgresql stop
$ sudo service postgresql start
```

# 6. Rails

`pq`をbundle installする

```
$ sudo yum install -y postgresql-devel
$ vi Gemfile
```

```ruby:Gemfile
gem 'pg'
```

```
$ bundle install
```

`database.yml`に作成したDB情報を設定する

```yaml:database.yml
development:
  adapter: postgresql
  encoding: utf8
  pool: 5
  username: DBユーザ名
  password: DBユーザパスワード
  database: データベース名
```

モデル作成

```
$ cd ~/hello-app
$ rails g scaffold User name:string age:integer
$ rake db:migrate
```

アクセス確認

```
$ rails s 
```

ブラウザアクセスしてデータ追加/変更/削除を実施
http://xxx.xxx.xxx.xxx/users

![PostgreSQL.png](https://qiita-image-store.s3.amazonaws.com/0/141934/a7d06d2f-4e5d-d8d6-f5f6-02fe6149f6f6.png)

# 7. 自動起動設定

アクセス確認して問題なければ自動起動設定をする

```
# 自動起動ON
$ sudo systemctl enable postgresql

# 状態確認
$ sudo systemctl status postgresql
```
Ruby on rails controllerからmodelのモジュールを呼び出す

#始めに
Ruby On Railsでcontrollerからmodelフォルダにあるモジュールを呼び出してみる
ARは使いません。
だって、DB周りでうまくいかなくなるのが目に見えているし！
まずは簡単なモジュールから実行してみます

#序章
一般的なRailsのサイトでmodelクラスの話になると

- 意味は分からないけれど、何かコマンド打ってファイル作って
- DBをマイグレーションして
- ARのサブクラスを使って
- DBに接続してなんか表示させる

となると思うが、ここではそんなことをはしない
絶対、DB周りでトラブることは目に見えている
むしろ、railsの何か自動生成するコマンドは一切使わずに、自前で作ったアプリケーションをModelに配置してそれをcotrollerから呼び出してみたい

#サンプルアプリケーションの実行
##ARの解説をしているサイトのサンプルプログラムをもとにロジックを実装してみる
まずはmodelフォルダに

```word_dictironary.rb
class WORD_DICTIONARY 
  def getworld()
    return "test"
  end
end
```
とめっちゃシンプルなrbクラスを配置する
で、このクラスをARを実装しているサイトのサンプルソースをまねしてcontrollから呼んでみる

```sample_controller.rb

class SampleController< ApplicationController
protect_from_forgery :expect  => ["create"]
def sayhello
     @msgToNikkyusan = '２９３、hello!';
     @msgToPerorisan = 'ペロリさん、hello!';
  end
  #初期表示で呼ばれるメソッド
  def sayhelloToNyukkyusan
     @msgToNikkyusan = '２９３、hello!';
  end
    
  #Ajaxから呼ばれるメソッド
  def sayhelloasynpost
    render text:"こんにちは！#{ WORD_DICTIONARY.new().getworld()}さん"
  end
end
```
ぱっとみ、WORD_DICTIONARYが名前解決できていないような気がしますが、気にしないでブラウザからリクエストを飛ばしてみます

##案の定エラーが出る
ブラウザからリクエストを飛ばしてみると

```
Started POST "/nikkyuusanpostasyn/" for 0:0:0:0:0:0:0:1 at 2017-07-28 22:16:52 +0900
Processing by SampleController#sayhelloasynpost as */*
  Parameters: {"name"=>"triple"}
Can't verify CSRF token authenticity
Completed 500 Internal Server Error in 43ms (ActiveRecord: 0.0ms)

NameError (uninitialized constant SampleController::WORD_DICTIONARY):
  app/controllers/sample_controller.rb:21:in `sayhelloasynpost'
```
案の定、自前で作ったクラス「WORD_DICTIONARY」の名前が解決できていない
まぁ、これは想定内だったので気を取り直して、railsがロードしているパスをコンソールに表示させてみる
railsがロードしているパスはグローバル変数$:から参照できるらしい
自分のrailsのロードパスを一部抜粋してみる

```
C:/jrubyrails/sample9/lib
C:/jrubyrails/sample9/vendor
C:/jrubyrails/sample9/app/assets
C:/jrubyrails/sample9/app/controllers
C:/jrubyrails/sample9/app/helpers
C:/jrubyrails/sample9/app/mailers
C:/jrubyrails/sample9/app/models
C:/jrubyrails/sample9/app/controllers/concerns
C:/jrubyrails/sample9/app/models/concerns
C:/jruby-9.1.12.0/lib/ruby/gems/
C:/jruby-9.1.12.0/lib/ruby/2.3/site_ruby
C:/jruby-9.1.12.0/lib/ruby/stdlib
```
ロードされたパスを見るとどうやら、app/models配下はロードされているようだ

##修正したモジュールを実行する
app/models配下がロードされているなら、自作クラスがあるrbをcotroller側からrequireしてあげれば見えるはず
controllerを

```sample_controller.rb
require "word_dictironary.rb"

class SampleController< ApplicationController
protect_from_forgery :expect  => ["create"]
def sayhello
     @msgToNikkyusan = '２９３、hello!';
     @msgToPerorisan = 'ペロリさん、hello!';
  end
  #初期表示で呼ばれるメソッド
  def sayhelloToNyukkyusan
     @msgToNikkyusan = '２９３、hello!';
  end
    
  #Ajaxから呼ばれるメソッド
  def sayhelloasynpost
    render text:"こんにちは！#{ WORD_DICTIONARY.new().getworld()}さん"
  end
end
```
のように修正し、リクエストを飛ばすと
![image.png](https://qiita-image-store.s3.amazonaws.com/0/136860/89946d4b-3516-c3aa-a959-97a23a6c001f.png)

ちゃんと、WORD_DICTIONARY#getworld()が実行されたことがわかる

#結論
おまじないコマンドを打たずにmodelに自前クラスをおいても、railsはその自前クラスを自動的にロードしてくれるわけではない、というごく当たり前のことがわかった
世間一般のARのサンプルプログラムがrequireなしにモデルクラスのクラスをがりがりかけるのは、きっとおまじないコマンドが自動的にrequireしてくれるよう、設定ファイルか何かを書き換えているのだと思う
fishermanでrbenvプラグインを入れてるのにrailsのコマンドが使えなくなった時

fish、rbenv の不具合
fishermanのプラグインのrbenvを入れても、突然railsのコマンド(例えばbundle installなど)が使えなくなることがある。
そんな時はfisher upをすると何故か直る
一時的に直るだけまたfisher upしなくてはならない。
原因がわかったらここに追記する。
【Android】Androidアプリ内のデータベースファイルの取り出し方

アンドロイドアプリ内のデータベースをスマホ端末からPC内に移動する方法
ここでは、アプリから端末のSDカードにデータベースファイルをコピーし、取り出す方法を紹介します。

１．USBケーブルでPCとスマホ端末を接続する
２．lsコマンドでアプリ内のデータベースファイル名を確認する

```
adb −d shell "run−as 【パッケージ名】 ls /data/data/【パッケージ名】/databases/"
```

３．アプリ内のデータベースファイルをスマホ端末のストレージにコピーする

```
adb −d shell "run−as 【パッケージ名】 cp /data/data/【パッケージ名】/databases/【データべース名】 /sdcard/【データべース名】"
```

４．スマホ端末内のデータベースを端末のストレージにコピーする

```
adb pull /sdcard/【データべース名】
```
PRを検証環境を用意する方法を考える


wamw Friday I/O 初日です。
株式会社ワムウでは、毎週金曜日は **興味がある事柄に取り組み、その成果を何らかの形でアウトプットする日** としています。

そんな **Friday I/O** の初日、私は下記の問題解決に取り組みます。

## 課題

弊社にてコーディングを行う、もしくはコードクオリティを管理する業務を行う際に、コードレビューを通して品質管理を行うのだが、PRベースだとコードの確認はできても挙動・画面の確認ができない。

リモートサーバ上で開発を行っている人の確認などは簡単にできるのだが、ローカルで開発しPRを出す場合この挙動確認のコストがなかなか高い。

コードを確認すると同時に簡単に画面も確認できるようになっているととても助かる。

ググると「自社のプロジェクト用」にこのようなツールを作っている記事はチラホラとあるのですが「みんなが」「汎用的に」使えるようなものは見当たらなかった。


## 解決の方向性

ざっくりイメージとして

1. PRを出した製作者が、そのタイミングで魔法を唱える
2. そのブランチのコードがどこかのサーバで起動し、ドメインが割り振られる
3. レビュワーはそのURIをWebブラウザで開き、挙動的に問題がないかを確認する

のような形です。

また、レビュイーはエンジニアとは限らずデザイナーやコンテンツ編集者もいることを想定して **CUI** ではなく **GUI** で魔法を用意する。


## 解決アプローチ

* AWS 上で起動することとする
* アクセスキーなどの情報を保持する必要があるため、信頼性向上のため Web ツールではなく Electron を用いたローカルアプリケーションとする
* アプリ上で **リポジトリURL** **ドメイン** を設定し、起動ボタンを押すと ECS で環境を立ち上げる


## 要は?

https://www.slideshare.net/AtsushiYoshinari1/ecs-pr-72456169

この辺りを汎用化したいよね、というお話です。

## 今日の成果

![スクリーンショット 2017-07-28 22.22.44.png](https://qiita-image-store.s3.amazonaws.com/0/97820/cc15b175-7e91-afa5-5f28-2429c6531295.png "スクリーンショット 2017-07-28 22.22.44.png")

どんな画面にしようかな、と考えてました。
fishからbashのletを呼び出してちょっと計算する

## はじめに
fishでは，計算は基本的に`math`コマンドにやってもらうことになっています．
なので`while`ループ時のインクリメント等は

```sh
set i 0
while true
    # do something
    set i (math $i + 1)
end
```

と書きます．ループカウンターみたいに短い名前の変数なら問題ないのですが，変数名が長いと

```sh
set __my_function_search_count (math $__my_function_search_count + 1)
```

みたいになってつらい．ただのインクリメントなので短く書きたいです．

## 解決
インクリメントをする方法，[bashだと色々ある](http://qiita.com/b4b4r07/items/cb02bbfd6df58df06ea8)らしいのですが，bashビルトインの`let`コマンドを使う方法だと

```sh
let __my_function_search_count++
```

でインクリメントでできるようです．

これをfishでも利用すべく，`let`コマンドのラッパーを書いてみました．

```sh:let.fish
function let --no-scope-shadowing
    if not string match -qr '^\w+' -- "$argv" # 変数名が与えられていないとき
        bash -c "let $argv[1]" # エラーメッセージを吐かせて終了 `let --help`もここで処理
        return $status
    end
    
    if string match -qr '^argv\W' -- "$argv" # 変数がargvのとき
        set -l expr (string match -r '(\w+)(.*)' -- "$argv")
        set -e argv # これで呼び出し側のargvが見える
        set argv (bash -c "v=$$expr[2]; let v$expr[3]; echo \$v")
    else # それ以外の変数のとき
        set argv (string match -r '(\w+)(.*)' -- "$argv")
        set $argv[2] (bash -c "v=$$argv[2]; let v$argv[3]; echo \$v")
    end
end
```

これを使うと，fishでも次のような書き方ができます．

```sh
set -l foo 0   # setで変数を定義して...
let foo++      # インクリメント
let foo+=3     # 増分指定
let foo=$foo%3 # 剰余

set -l __long_long_long_name 0
let __long_long_long_name++ # 長い名前でも比較的見やすい!...かも？
```

[プラグイン化](https://github.com/ryotako/fish-let)もしたので，他のプラグインを書くときにも利用可能です．

## 終わりに
bashを使ってfishのローカル変数の書き換え...できるのか？ といろいろ試した結果，できました．ポイントは

- `--no-scope-shadowing`オプションで関数外のローカル変数を書き換える．
- 任意の変数名に対応するため，極力`argv`以外のローカル変数を定義しない．
- 書き換えるのが`argv`である場合は，`let`関数内の`argv`を消して一段階外側を参照する．

です．[ブレース展開](http://qiita.com/ryotako/items/70827643a20fa60b2547)に続き，bashの力でfishを便利にするシリーズでした．bash便利．
GCPベンチマーク#1 GCE インスタンス間の通信

GCPのインスタンス間のネットワーク速度を計測するために、PerfkitBenchmarkerを使用する。PerfKitbenchmarkerにはiperfなどのベンチマークツールが含まれており、各クラウドに対応しているので、クラウド同士の比較なども簡単にできる。
https://github.com/GoogleCloudPlatform/PerfKitBenchmarker

クラウド上でプロビジョニングするモードでは以下のコマンドを実行するだけで、ノードが２台とネットワークが作成され、ベンチマークを行なった後、ノードが削除されるので、クラウドの性能を計測するのに便利である。
また既に立ち上げているノードを利用することも当然できる。

今回は実行環境としてCloudShellを使用し、プロビジョニングモードでPerfKitBenchmarkerを実行。

```
git clone https://github.com/GoogleCloudPlatform/PerfKitBenchmarker.git
cd PerfKitBenchmarker
pip install -r requirements.txt -t lib
export PYTHONPATH=~/PerfKitBenchmarker/lib:$PYTHONPATH

```

n1-standard-8:thread_count:1, us-central1-aで計測

```
$ ./pkb.py --cloud=GCP --machine_type=n1-standard-8 --benchmarks=iperf --ip_addresses=INTERNAL --zones=asia-east1-c --iperf_sending_thread_count=8
```

```
-------------------------PerfKitBenchmarker Results Summary-------------------------
IPERF:
  receiving_machine_type="n1-standard-8" receiving_zone="us-central1-a" runtime_in_seconds="60" sending_machine_type="n1-standard-8" sending_thread_count="1" sending_zone="us-central1-a"
  Throughput                         1204.000000 Mbits/sec                      (ip_type="external")
  Throughput                         8565.000000 Mbits/sec                      (ip_type="internal")
  Throughput                         1672.000000 Mbits/sec                      (ip_type="external")
  Throughput                         8522.000000 Mbits/sec                      (ip_type="internal")
  End to End Runtime                  747.215729 seconds

-------------------------
```

n1-standard-8:thread_count:8, us-central1-aで計測

```
-------------------------PerfKitBenchmarker Results Summary-------------------------
IPERF:
  ip_type="internal" receiving_machine_type="n1-standard-8" receiving_zone="us-central1-a" runtime_in_seconds="60" sending_machine_type="n1-standard-8" sending_thread_count="8" sending_zone="us-central1-a"
  Throughput                        12139.000000 Mbits/sec
  Throughput                        13228.000000 Mbits/sec
  End to End Runtime                  583.234252 seconds

-------------------------
```

n1-standard-8:thread_count:8, asia-east1-cで計測
1coreあたり2Gbps、1node辺りの最大スループットは16Gbpsなので、理論値の98.6%でている。

```
-------------------------PerfKitBenchmarker Results Summary-------------------------
IPERF:
  ip_type="internal" receiving_machine_type="n1-standard-8" receiving_zone="asia-east1-c" runtime_in_seconds="60" sending_machine_type="n1-standard-8" sending_thread_count="8" sending_zone="asia-east1-c"
  Throughput                        15200.000000 Mbits/sec
  Throughput                        15785.000000 Mbits/sec
  End to End Runtime                  531.351110 seconds

-------------------------
```
GCPサービスアカウントの鍵を安全に管理する

以下の記事のメモ。
https://cloudplatform.googleblog.com/2017/07/help-keep-your-Google-Cloud-service-account-keys-safe.html

GCPは堅牢なサービスアカウントの鍵管理機能を提供している。それは認可された適切なエンティティのみが稼働中のGCPリソースにアクセスできるようにする。
アプリ全体がGCP上で稼働している場合、サービスアカウントの鍵管理はGCP側で自動で鍵ローテーションなどを行ってくれるため容易である。しかし多くのアプリは様々な環境で実行されているので、鍵を安全に管理することが必要である。

#GCPの外にあるサービスアカウントを保護する
サービスアカウントを作成する時、最小権限の規則に従っているか確認する。これはGCP外に置く置かないに関わらず全てのケースで有効な手段である。
サービスアカウントのキーはダウンロードされると、GCPのコントロール外になるので、セキュリティリスクは高くなる。そのため鍵のローテーションなどをして管理しないといけない。

#ベスト・プラクティス

1. ローカル環境に鍵をダウロードするなら、その鍵はプロダクションリソースへのアクセス権が与えられてないことを確認してください
2. 以下のメソッドを使って鍵をローテートする。
   - ServiceAccounts.keys.create()
   - Replace old key with new key
   - ServiceAccounts.keys.delete()
3. 毎日の鍵ローテーション処理の実装し、開発者がCloudStorageから鍵ファイルをダウンロードできるようにする。
4. serviceAccount.keys.list()もしくはLogs Viewerページを使って、サービスアカウントと鍵を監査する。
5. Service Account ActorとService Account Userロールの権限を持つユーザを制限する。
6. ローカルの開発環境のために、GOOGLE_APPLICATION_CREDENTIALSを設定する。
7. 開発者が外部のソースコードリポジトリから鍵を取得するのを防ぐ。
8. 定期的に外部リポジトリをスキャンし、鍵が置かれてたら是正処置を行う。

##鍵のローテーション
Keyrotator(https://github.com/Googlecloudplatform/keyrotator)　
はシンプルなCLIツールでPythonで記述されている。adminインスタンス上でcronジョブとして実行し、夜中に新しい鍵をCloudStorageに配置し、開発者が朝方にその鍵をダウンロードして使用する。
鍵を含むバケットのアクセスコントロールは必須である。

1. リソースをシェアするためのプロジェクトを作成
2. バケットを作成
3. 開発者用のグループを作成
4. storage.objectViewerロールを開発者グループに割り当て、バケットを読めるようにする。

※より強いコントロールするときはCloud KMSを使用する。

## 外部のソースコードリポジトリに鍵がコミットされるのを防ぐ
外部のソースコードリポジトリに鍵を置く代わりの手段として、GCPではプライベートなGitリポジトリを提供している。
もしくはgit-secretsを使うことによって、鍵が外部リポジトリにアップロードされるのを防ぐことができる。

## 外部リポジトリをスキャンする
git-secretsを補完するツールとしてtrufflehogを使用する。trufflehogはリポジトリの履歴を検索し、鍵がアップロードされたか調べることができる。