OmniAICreator/Qiita-1.07M huggingface dataset:
import AppKitでNo such module 'AppKit'とエラーが出る時の対処法

# はじめに
以下のように`import AppKit`をしてフレームワークであるAppKitを読み込もうとした際に、`No such module 'AppKit'`とエラーがでる原因と対処法について書いていきます。
<img width="803" alt="error.png" src="https://qiita-image-store.s3.amazonaws.com/0/190875/d951ff74-c344-25c6-fec3-b5ac942e2c22.png">

# 動作確認環境
- macOS Mojavaのバーション：10.14
- Xcodeのバーション：10.1
- Swiftのバーション：4.2.1

# エラーの対処法
まず、一番左にあるナビゲーターエリアのSampleProductをクリックします。
<img width="1094" alt="reference01.png" src="https://qiita-image-store.s3.amazonaws.com/0/190875/9e4da636-8617-9525-54f3-566eee9c0a21.png">

そして、Build SettingsのBase SDKをiOSからMacOSに変更します。
(プロジェクトを特に指定せずに作成するとBase SDKの初期値はiOSになっています)

変更前
<img width="1440" alt="reference02.png" src="https://qiita-image-store.s3.amazonaws.com/0/190875/8f3d5548-2ae3-4936-0abb-4bc790244d6b.png">

変更後
<img width="1439" alt="reference04.png" src="https://qiita-image-store.s3.amazonaws.com/0/190875/82706a6d-cf89-1087-8fb4-c170a93521fe.png">


すると、以下のように補完の候補としてAppKitが出てくるようになります。
<img width="457" alt="Completion.png" src="https://qiita-image-store.s3.amazonaws.com/0/190875/08d6a8e7-c928-f66e-b317-f46c161ba59d.png">



ちゃんと読み込まれているのがわかります。
　<img width="884" alt="OK.png" src="https://qiita-image-store.s3.amazonaws.com/0/190875/5c69af71-32ac-c39a-fe3e-380ca769bc29.png">


# AppKitとUIKitの違いについて
エラーが起きていた理由として、AppKitとUIKitを比較して説明していきます。

- AppKitはMacOSアプリケーションのユーザーインターフェースを構築・管理するフレームワーク
- UIKitはiOSまたは、tvOSアプリケーションのユーザーインターフェースを構築・管理するフレームワーク

よって、AppKitを使用する場合は、XcodeのSDKの設定をMacOSに合わせる必要があるといえます。


# 最後に
色々調べる中で、最初はドキュメントに目を通した方が回り道しないこともよくあります。
英語から逃げないようにしていきましょう！<font color="Silver">(自分への戒めも兼ねて)</font>

# 参考サイト
- [AppKit](https://developer.apple.com/documentation/appkit)
- [UIKit](https://developer.apple.com/documentation/uikit)
うちのエンジニアが、400番のエラー画面の文言変えて遊んでやがる。仕事しろアホ。

この記事は[パーソルキャリア Advent Calendar 2018](https://qiita.com/advent-calendar/2018/pca)の9日目です。

## まず、Slackのやり取りを晒す

<img width="526" alt="ad1.png" src="https://qiita-image-store.s3.amazonaws.com/0/164563/7ad7937e-5541-813f-a81d-2e73de7ac39c.png">
<img width="543" alt="ad2.png" src="https://qiita-image-store.s3.amazonaws.com/0/164563/ed9523a3-2823-cee3-279e-de7b582f8bd4.png">
<img width="491" alt="ad3.png" src="https://qiita-image-store.s3.amazonaws.com/0/164563/be6c7c71-afe8-55ee-cb37-cbee5a7e4073.png">

## 彼は何故こんな作業をしているのか
[TECH PLAY](https://techplay.jp) では エラーページの出力に[CloudFrontのカスタムエラーページ](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/HTTPStatusCodes.html#HTTPStatusCodes-custom-error-pages)を利用しています。
CloudFrontのOriginが異常系HTTPステータスコードを返すと、S3上に置いてあるHTMLファイルにてエラー画面を表示する仕組みになってます。


↓こんな感じの質素なエラー画面

<img width="569" alt="ad7.png" src="https://qiita-image-store.s3.amazonaws.com/0/164563/c3ca3390-6ac2-bc46-24da-99124bffa7d8.png">

### カスタムエラーページの設定
* ALBのOriginとは別にS3のOriginを作成

<img width="1167" alt="ad6.png" src="https://qiita-image-store.s3.amazonaws.com/0/164563/36d2e373-5414-da10-a809-52d6bff4a3b4.png">

* S3用のBehaviorを作成

<img width="1166" alt="ad4.png" src="https://qiita-image-store.s3.amazonaws.com/0/164563/b1de629e-a79f-cc50-6a05-0a5d6a305c01.png">

* ErrorPageを作成

コード毎に設定する必要があります。

<img width="448" alt="スクリーンショット 2018-12-06 18.19.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/164563/133f4b59-f113-445e-68dd-9a3dccddd180.png">

<img width="1174" alt="ad5.png" src="https://qiita-image-store.s3.amazonaws.com/0/164563/527fb576-fd96-f54b-ab18-ea053dc00a3a.png">

* S3はこんな感じ

<img width="487" alt="ad8.png" src="https://qiita-image-store.s3.amazonaws.com/0/164563/4843929e-b9fc-cde7-9232-eb34cbccb9ad.png">


### 過ち
* CSRFトークンエラーの時にServer側でHTTPステータスコード500を返してたので、CloudFrontのカスタムエラーページが表示されてしまい、`Server Error サーバーで問題が発生しているためページを表示できません。 しばらく時間を置いてからやり直してください。` と表示されてしまっていた。

### 修正
* CSRFトークンエラーを500 Server Errorとして表示するのは如何なものか
* 400で返却しようぜ
* 文言考えようぜ
* 最初Slackに戻る
* 無事作業終了

### 作業を終えた彼の感想
<img width="833" alt="ad10.png" src="https://qiita-image-store.s3.amazonaws.com/0/164563/1e64a99f-2105-5f3f-fa7f-f358239d6eac.png">

ということで

### 仕事しろアホ。みんな真面目に仕事してるんだ！



パーソルキャリア Advent Calendar 2018 9日目を終わります。
RubyをCに変換する話の予告編　あるいは隙あらば自分語り

[言語実装 Advent Calendar](https://qiita.com/advent-calendar/2018/lang_dev)の13日目のRubyをCに変換する話という記事を書く予定です。これは今作っている[mrubyのJIT2(仮称)](https://github.com/miura1729/mruby-meta-circular)の説明なんですが、何を考えてこんなものを作ったのか理解に助かるだろうなという理由に見せかけて、自分語り欲求を満たすために、この10年強の間何を作って何を得て何を失ったか書いてみます。

# yarv2llvm
時は2007年ころにさかのぼります。その頃、離婚して強制的に時間がいっぱいできたとか、ケーブルテレビで常時接続のインターネットが使えたりとプログラムを書くための環境がとても整ってきました。そんな中、[llvmrby](https://github.com/tombagby/llvmruby)というとても面白いものを知りました。llvmrubyはRubyからllvmを使うためのライブラリでこれを使うと、高速なプログラムがつくれます(簡単とは言っていない)。
これを使って[正規表現エンジン](https://github.com/miura1729/regexpllvm/tree/master)とか作っていたのですが、やっぱりYARVのバイトコードを変換したいと思い、作成しました。そのころ、syoyoさんがpythonで型推論(型推定)の発表をされていてその方法を取り入れて静的に型を推定できるようにしました。具体的なアルゴリズムは[ここ](http://d.hatena.ne.jp/miura1729/20090123/1232707764)にあります。フィボナッチ級数のプログラムがRubyの40倍の速度だったり、SDLのバインディングを組み込んでグラフィックスも高速化出来たりいろいろ出来るようになりました。特筆すべき成果はao-benchのRuby版で、yarv2llvmの性能評価のために書いたのですが色々なところで使ってくれているようです。しかし、どうしても[bm_app_pentomino](https://github.com/sj26/ruby-1.9.3-p0/blob/master/benchmark/bm_app_pentomino.rb)が型推定できなかったり、llvmrubyが保守されなくなって新しいLLVMでは動かなくなったり、なによりLLVMを使うのに疲れたので、このプロジェクトは無くなりました。
## yarv2llvmの教訓
　このプロジェクトの教訓は一番大きいのはLLVMは辛いということです。何かあると何の説明もなくassertion errorって出るのも辛いですが、動的型付け言語には向かないという意味でも辛いです。
　また、このプロジェクトは紹介する3つのプロジェクトの中で一番完成度が低いも関わらず、githubのスターの数が一番多いのです。また、他のプロジェクトではない海外のサイトで紹介されていたりします[その1](http://webcache.googleusercontent.com/search?q=cache:hGwVHUxewdQJ:www.rubyinside.com/llvmruby-a-compiler-toolkit-available-to-rubyists-1362.html+&cd=9&hl=ja&ct=clnk&gl=jp), [その2](https://www.infoq.com/news/2008/10/llvmruby-roundup-yarv2llvm)
もちろん、小僧、自分の力で勝ったのではないぞ。そのLLVMとllvmrubyの名声のおかげだという事を忘れるな！　ってのは重々理解しているわけですが、OSSであっても必ずしも評価が技術を伴っているとは限らないってことを学習しました。
型推定の問題については同じメソッドに複数の型の引数が来ることがある多相性を扱うようにしないとRubyでは通用しないことが良くわかりました。

# ytljit
次に作ったプログラムが[ytljit](https://github.com/miura1729/ytljit/tree/master/lib/ytljit)です。yarv2llvmで問題になったbm_app_pentominoが型推定出来ない問題、BIGNUMなどはLLVMでは効率よく実装できない問題を解決ることを考えました。型推定についてはメソッドの引数の型の組の条件付きで推定するようにしました。よくわからないと思いますので[昔書いた記事](http://d.hatena.ne.jp/miura1729/20101114/1289738684)を読むと分かるかもしれないし、分からないかもしれないです。BIGNUMとかを効率よく実装するためにはアセンブラしかないと判断し、Rubyでアセンブラを作りました。あまり話題になっていないのですが、そこそこ順調に進み、こんなドヤ顔の[アナウンス](http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/48600)をruby-listメーリングリストに流すまでになりました。アナウンスを見て分かる通り何でも貪欲に機能を取り入れています。こういう流れになると失敗するのは世の常です。
そして、プログラムが複雑になり過ぎてバグがどうしても直せなくなってそのまま嫌になってプロジェクトは終わってしまいました。あのドヤ顔メールを出してすぐのことです。
## ytljitの教訓
　Simple is best

#mrubyのJIT
ytljitがポシャってしばらくして、新しいおもちゃとしてうってつけなmrubyが発表されました。しばらく、インラインキャッシュを付けたりして遊んでいたのですが、そうあれは某小学校で下水工事をしていた時、これってTracing JITが組み込めるんじゃね?って気づきました。やってみるとうまく行きそうです。
ytljitの教訓から出来る限りシンプルに元のmrubyを出来る限り生かしてと心がけました。アセンブラを自作するなんてとんでもないということで、[Xbyak](http://herumi.in.coocan.jp/soft/xbyak.html)を使わせてもらいました(これは大正解)。そうこうしているうちにmrubyのJITはとてもうまく行きました。
しかし、満足のいく性能が出ずだんだん汚いコード・早過ぎる最適化の誘惑に負け出してきました。プログラムはとても汚くなりましたが、なんとかデバッグは出来てmrubyの10倍くらいの速度が出るようになりました。でも、このアプローチではこれが限界。もっと速くするにはプログラム全体を見て、色々解析する必要があったのです。

## mrubyのJITの教訓
速くするにはそれなりに土台がいる。そうしないと限界が訪れる

#最後に
続きは13日に会いましょう
ASTERIA Warpを使って気軽にデータ連携

# 想定読者
- Salesforceシステム管理者
- 気軽にシステム間連携を開発したい方

# 自己紹介
Randstad Advent Calendar 9日目の記事です。
ランスタッドIT部門に所属し、Salesforceのシステム管理業務とシステム間のデータ連携業務に従事
しています。

# はじめに
ASTERIA Warpを使用して、短期間かつ安定したデータ連携処理を開発し、Salesforceにデータ連携する手順を紹介します。

# ノン・プログラミングデータ連携
## Asteria Warpとは
##### 企業向けのシステムを連携する基盤
- ASTERIA　WARPは、企業内外に点在するシステム間の連携、データやプロセスの統合を実現するためのミドルウェアです。IT技術者向けではなく、より多くの人に使って頂くことを念頭に置いて設計されており、ノン・プログラミング開発が可能です。
![asteriawarp.jpg](https://qiita-image-store.s3.amazonaws.com/0/311972/cd3a2137-5e19-3105-0557-93b85e941159.jpeg)

## Asteria Warpデータ連携開発手順
Asteria Warpでは、「フロー」という単位を用いて処理管理しており、その中に処理手順となる「コンポーネント」を配置してデータ処理を記述していきます。複数のフローをまとめて管理するものが「プロジェクト」です。ファイルはプロジェクト単位で保存されます。新しいプロジェクトを作成する際に、新しいフローが1つ作成されます。
![flowimage.PNG](https://qiita-image-store.s3.amazonaws.com/0/311972/033246e5-5a4f-0b22-e34a-f8a5d1f3456b.png)

## Salesforceへのデータ連携フローを作成する
- データ連携処理のフローの流れは以下の5つになります
    1. Salesforceログイン
    2. 基幹システムからデータ取得
    3. 取得データとSalesforceオブジェクトのマッピング
    4. データ投入
    5. Salesforceログアウト

- 各手順をフローの中にコンポーネントとして配置し、実行順序を設定します
![WS000033.JPG](https://qiita-image-store.s3.amazonaws.com/0/311972/f7d3801b-55f7-970a-8264-bc7b8abe4e01.jpeg)

- 作成したフローをコンパイルして、異常がなければ作成完了

- 後は任意のトリガを設定して、実行すれば、データ連携処理の完成です

# 最後に
上記の通り、Asteria Warpの連携開発は、下記の４つで完了になります

　1. フロー作成
　2. コンポーネント配置
　3. コンポーネント設定
　4. コンパイル
　
シンプルかつ短時間での実装が可能です。
私自身、スクラッチ開発データ連携処理の経験から、本ツールの、開発容易さ・安定感に感銘を受けています。この記事を通じて、その部分を感じていただければ幸いです。
vagrant 環境作成

### １、VirtualBoxインストール
略

### 2,Vagrantをインストールする
https://eng-entrance.com/linux-vagrant-install

### 3,インストール確認 　コマンド

    vagrant --version

### 4,Vagrantファイル作成　コマンド

     vagrant init scotch/box

※：起動するためのVirtualBoxの設定ファイル

例：
 E:\02_vagrant\02_test\Vagrantfile
 
### 5,vagrant起動　コマンド

     vagrant up

VirtualBoxに仮想OSを自動的に作成される。.vagrantフォルダも自動的に作られる
 例：
 E:\02_vagrant\02_test\.vagrant

### 6,ライブパスのコードを追加  コマンド

      git clone http://172.16.55.165/isp/livepass.git

### 7,vagrantの設定
##### 7.1 ssh起動

      vagrant ssh

##### 7.2 /var/www/public フォルダを作成

     mkdir public

##### 7.3 リンクを追加する

     cd /var/www/
     ln -s /vagrant/livepass/www public

### 8 databaseを追加する。
##### 8.1 テーブルなどを作る

略

##### 8.2　下記に格納する

 E:\02_vagrant\02_test\20181002.dump.pia_ent.sql

##### 8.3 mysql に入る(先にvagrant ssh)

     mysql -u root -p
     ps:root

##### 8.4 DBを作成する

     creat database livepass

##### 8.5 テーブル作成。

     source /vagrant/20181002.dump.pia_ent.sql

### 9環境確認

http://localhost:8080/beginners

### 10,vagrant終了　コマンド

     vagrant halt
FreeBSD で Prometheus & Grafana を動かしてみる

FreeBSD11.2でPrometheusとGrafanaを動かしてみます
（動かすだけです）


# 環境
| ソフトウェア | バージョン |
|---|---|---|
| FreeBSD    | 11.2 |
| Prometheus | 2.5.0 |
| Grafana    | 5.3.4 |

# pkgでprometheusのインストール

```
$ sudo pkg install -y prometheus grafana5
```
※prometheus1系の場合はprometheus1があるのでこちらをインストール
※grafanaは5以外にgrafana(1系)、grafana2、grafana3、grafana4があります

# Prometheus & Grafana を起動
```
$ sudo sysrc prometheus_enable="YES"
$ sudo sysrc grafana_enable="YES"
$ sudo /usr/local/etc/rc.d/prometheus start
$ sudo /usr/local/etc/rc.d/grafana start
```
Prometheusの設定ファイルは/usr/local/etc/prometheus.yml
Grafanaの設定ファイルは/usr/local/etc/grafana.conf


# Prometheusにブラウザからアクセス
http://サーバのIPアドレス:9090/
![prometheus](https://qiita-image-store.s3.amazonaws.com/0/153252/27e4e24b-1242-b973-1200-b1969af96755.png)


# Grafanaにブラウザからアクセス

http://サーバのIPアドレス:3000/
ID:admin, PASS: adminでログインできます
![prometheus](https://qiita-image-store.s3.amazonaws.com/0/153252/54d7f229-897e-d169-75c0-4f4fdd427394.png)
Rails でドメイン駆動開発 (DDD) をするときのディレクトリ構成案

Rails でドメイン駆動開発 (DDD) をしたいという時に、考えたディレクトリ構成案です。
開発をしながら改善をして、なるべく Rails と仲良く共存できる形になったのでメモとして残します。

## アーキテクチャ
- オニオンアーキテクチャ
  - 参考: https://qiita.com/little_hand_s/items/2040fba15d90b93fc124

## その他前提
- 複数のコンテキストは含めない
- なるべく Rails の機能を無効化しない (目標)

## ディレクトリ構成案

```
app/ # いつもの app ディレクトリ
┣ controllers/ # アダプターとしてみなす
┣ models/ # アダプターとしてみなす
┣ mailers/ # アダプターとしてみなす
┣ views/ # アダプターとしてみなす
┣ view_models/ # アダプターとしてみなす
┃
┣ services/ # アプリケーション
┃ ┗ users/ # `ユーザ` モジュール
┃   ┣ commands/
┃   ┃ ┗ register.rb # 登録コマンド
┃   ┃
┃   ┗ application_service.rb # アプリケーションサービス
┃
┣ domain_models/ # ドメインモデル
┃ ┣ common/ # `共通` モジュール
┃ ┃ ┣ entity.rb # エンティティ共通クラス
┃ ┃ ┣ value_object.rb # 値オブジェクト共通クラス
┃ ┃ ┗ domain_event.rb # ドメインイベント共通クラス
┃ ┃
┃ ┗ users/ # `ユーザ` モジュール
┃   ┣ user.rb # `ユーザ` 集約
┃   ┣ email.rb # `メールアドレス` 値オブジェクト
┃   ┗ repository.rb # リポジトリ (この中で Rails の機能を使用する。主に ActiveRecord。)
┃
┗ infrastructures/ # インフラ
  ┣ persistences/
  ┃ ┗ user_repository.rb
  ┃
  ┗ services/
    ┗ user_email_send_service.rb
```

## app/controllers
いつものコントローラーです。
私が開発をするときはコントローラーで `ViewModel` を使用して、アプリケーション層のサービスを呼びます。

## app/models
いつものモデルです。`ActiveRecord` のクラスと`集約`を同一にはしていません。
モデルには業務ロジック以外のロジックを実装します。(スコープ、エンティティへのシリアライズ、etc)

`ActiveRecord` と`集約`を同一にすることも出来ます。([composed_of について](https://api.rubyonrails.org/classes/ActiveRecord/Aggregations/ClassMethods.html))
ただし、インフラ層のインタフェースや知識がドメインモデル層に漏れてしまうのでトレードオフについて考えて、チームで決断するのが良いと思います。

## app/view_models
ユーザからの入力値 (params) を受け取り、ユースケースを実行する `ViewModel` で、一種のアダプターとして捉えています。
入力値のバリデーションが必要な場合にはここで行います。(`ActiveModel` を使用しています。)
また、ビュー層は `ViewModel` をもとに描画をすることで、ビュー層とドメインモデル層が直接やり取りをしないようにしています。

## app/services
アプリケーション層のサービスです。

### app/services/#{モジュール名}/commands
アプリケーション層のサービスへ渡すコマンドオブジェクトです。
Ruby のネームスペースを活かしてこのディレクトリ配下に配置します。

## app/domain_models
ドメインモデルです。
ドメインモデル内ではバリデーションは行いません。(ViewModel 内で行います。)
代わりにドメインモデル層ではアサーションを用意して、常に正しく存在し続けられるようにしています。

### app/domain_models/common
ドメインモデル内の共通モジュールです。
エンティティや、値オブジェクトの親クラスを定義して、
各ドメインモデルで継承して使用します。

## app/infrastructures
インフラ層の実装クラスをまとめます。

### app/infrastructures/persistences
永続化に関する実装クラスです。
この中で `ActiveRecord` や、`Rails.cache` などのインフラの力を使います。

### app/infrastructures/services
アプリケーション層のサービス、ドメインサービスの実装クラスです。
HTTP を使った外部への通信や、メール送信などを実装します。
メール送信をする際には、ここから `ActionMailer` を使用しています。

## まとめ
もっといい案があれば教えて下さいませ。
Windows API基本型

#### Win32型
BOOL
BOOLEAN
CHAR ...

##### ポインタ型
* 型識別子の先頭にPまたはLPを指定するとポインタ型になるという規則がある
* L(long) P(pointer)であるがLは16ビット時代からの名残なのでLPの接頭辞とPの接頭辞の型は同じ


#### 文字列型
TCHAR(UNICODEが定義されていればWCHAR、そうでなければCHAR)

###### 文字列型のポインタ
LPSTR, PSTR(NULL で終わるマルチバイト文字列へのポインタ)
LPWSTR,PCWSTR(NULL で終わるワイド文字列へのポインタ)
AWS: Amazon Route 53 をコマンドラインから更新して DDNS として使う


# Cluster,Inc. Advent Calendar 2018、6日目の記事です。

この記事では、aws-cli コマンドを利用して AWS Route 53 の DNS Entry を DDNS として利用した話を書きます。

# Motivation

クラスター株式会社は、リモートワーク可能・社内のリソースにアクセスする為に VPN が利用できるのですが、インターネット接続は通常のフレッツ光のため、たまに Office IP が変更になって困っている、という話がありました。

# 解決しましょう

IP を隠蔽する抽象化というと真っ先に `DNS` が思い浮かびます。特にダイナミックに変わる IP に追従するようにダイナミックに DNSレコードを変えていけばいいじゃないかという発想の元に

## ダイナミックドメインネームシステム とは

> IPアドレスを割り当てられたクライアントコンピュータの側から、自分のIPアドレスとホスト名をDNSサーバに登録することにより、IPアドレスを動的に割り当てながらもホスト名を一定に保つという発想が生まれた。これがダイナミックDNSである。
>
> https://ja.wikipedia.org/wiki/ダイナミックドメインネームシステム

これにより、 `*.example.com` ドメインを所有していれば、常に `office.example.com` = オフィス（のルーター）の IP ということが可能です。

# 実装

クラスター株式会社はサービスインフラおよび社内で利用される DNS の管理に AWS を利用しています。

（個人的な話で失礼しますが、転職経験としては4社目となるのですが、AWS便利で感動しました）

AWS の DNS 管理サービスは Route53 で、これをコマンドラインからレコードの修正をする aws-cli がありますので、こちらを利用します。

実装された手順としては以下の通りで、社内の Jenkins サーバーで動作しています。

1. オフィス内の Jenkins サーバー上から、Public IP として出て行く場合のIPを取得します
2. AWS Route53 更新テンプレートの IP 欄を、 1. で入手した IP に置き換えてリクエストボディを作成します
3. リクエストボディを元に AWS にリクエストします。

## 1. オフィス内の Jenkins サーバー上から、Public IP として出て行く場合のIPを取得します

自分のIPが知りたくなったら、確認君、、、が有名ですが。
今回は `IP API` で検索したなかでシンプルだった https://www.ipify.org/ を利用しました。

```bash
% curl -s https://api.ipify.org
114.164.185.104
```

末尾の `\n` が無い非常にシンプルなテキストでデータが返ってきます

## 2. AWS Route53 更新テンプレートの IP 欄を、 1. で入手した IP に置き換えてリクエストボディを作成します

準備したテンプレート

```json:template.json
{
  "Comment": "Update by update_office_ip.sh",
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "office.example.com",
        "Type": "A",
        "TTL": 60,
        "ResourceRecords": [
          {
            "Value": "<IP>"
          }
        ]
      }
    }
  ]
}
```

実際にはこんな流れで `<IP>` が現在のIPに置換された JSON が入手できます。

```bash
ip=$(curl -s https://api.ipify.org)
cat template.json | perl -pe"s/<IP>/$ip/"
```


## 3. リクエストボディを元に AWS にリクエストします。

```bash
aws --debug --output=table route53 change-resource-record-sets --hosted-zone-id ここがぞーんID --change-batch "$(cat template.json | perl -pe"s/<IP>/$ip/")"
```

`--debug` を付けておくことでリクエスト＆レスポンスの wire log が表示されます。
また、`--output=table`を追加すると、最終的な出力結果が表になります。

結果は以下の用になります。

```
----------------------------------------------------
|             ChangeResourceRecordSets             |
+--------------------------------------------------+
||                   ChangeInfo                   ||
|+--------------+---------------------------------+|
||  Comment     |  Update by update_office_ip.sh  ||
||  Id          |  /change/DEADBEEFV3RI3          ||
||  Status      |  PENDING                        ||
||  SubmittedAt |  2018-12-06T07:53:08.504Z       ||
|+--------------+---------------------------------+|
Notifying upstream projects of job completion
Finished: SUCCESS
```

これで次回から office.example.com で常に Office の Public IP が取得できるようになりました。

それでは、リモートワーク・VPNライフを、固定IP無しでお楽しみ下さい。
Terraform sliceの奇妙なふるまい

Terraformの効率化に欠かせないmap変数の一部を取り出すのに必須のslice関数ですが、なかなか他では見られないユニークな仕様なのではまらないようにメモ程度ですが投稿します。

## 関数の定義

#### slice（リスト、開始、終了）

#### 動作
リストから指定範囲を切り出して返します

#### パラメータ
リスト：元になるlist
開始：0から始まるリストの切り出し開始インデックス
終了：切り出しの終了位置

## どこが奇妙？

**終了：切り出しの終了位置**

この終了位置の**一つ前**のインデックスまでを切り出します。(ヲイ)


## 実例

##### 普通に一つ切り出す

```json
variable "list_01" {
  default = ["One", "Two", "Three", "Four"]
}

output "slice_01" {
  value = "${slice(var.list_01,0,1)}"
}
```
##### 結果
```
slice_01 = [
    One
]
```
----
##### 真ん中の二つを切り出す

```json
variable "list_01" {
  default = ["One", "Two", "Three", "Four"]
}

output "slice_02" {
  value = "${slice(var.list_01,1,3)}"
}
```
##### 結果

```
slice_02 = [
    Two,
    Three
]
```
----
##### 最後の一つを切り出す

```json
variable "list_01" {
  default = ["One", "Two", "Three", "Four"]
}

output "slice_03" {
  value = "${slice(var.list_01,3,4)}"
}
```
##### 結果

```
slice_03 = [
    Four
]
```

## 感想
きっと、よかれと思って実装したんだと思う............

きっと、そうだよ........................

でもね、**存在しないインデックス**を指定するのって、すげー気持ち悪いんだけど......
BubbleSort

ソートの復習がてら、BubbleSort（バブルソート）のプログラムを書いてみました。

バブルソートは、ソートのアルゴリズムの中で、1番理解しやすい簡単なアルゴリズムな気がします。

バブルソートは、リストの中の隣り合う要素を比較して、昇順または降順に並び替えるアルゴリズムで
す。

計算量はO(n^2)なので、早くはないですが、というよりソートの中でも遅い方ですが、やっていることが単純なので、比較的簡単で理解しやすいアルゴリズムだと思います。



```java:BubbleSort.java

import java.util.*;
public class BubbleSort {
    static int debug = 0;
    public static void main(String[] args) {
	if (args.length > 0 ){
	    if(args[0].equals("-d")) debug = 1;
	    else if (args[0].equals("-d2")) debug = 2;
	}
	Scanner sc = new Scanner(System.in);
	System.out.print("データの個数を入力して下さい：");
	int n = sc.nextInt();
	int[] a = new int[n];
	for (int i=0; i<n; i++) a[i] = sc.nextInt();
	sort(a);
	System.out.println(toString(a));
    }
    public static void sort(int[] a) {
	for(int i = 0; i < a.length-1; i++) {
	    boolean flag = false;
	    for(int j=a.length-1;j>i; j--) {
		if(a[j-1] > a[j]){
		    int tmp = a[j];
		    a[j] = a[j-1];
		    a[j-1] = tmp;
		    flag = true;
		}
		if(debug > 1)
		    System.out.println("i="+i+",j="+j+": "+toString(a));
	    }
	    if(debug>0)
		System.out.print("sorting: "+toString(a));
	    if(!flag)break;
	}    
    }
    public static String toString(int[] a) {
	    StringBuffer sb = new StringBuffer();
	    for (int i=0;i<a.length;i++)
		sb.append(a[i] + " ");
	    return sb.toString();
    }
}

```
Windows環境でmatplotlibを読み込もうとすると「指定されたモジュールが見つかりません」というエラーが出た時の対処法

初稿公開　2018年12月06日
　この記事では、Windows10にAnaconda3(32bit)を使ってPythonをインストールした後、Jupyter Notebook内でグラフ描画ライブラリであるmatplotlibをインポート

```
import matplotlib.pyplot as plt
```

しようとしたら、

```
File "C:\Users\admin\Anaconda3\lib\site-packages\matplotlib\font_manager.py", line 55, in <module>
    from matplotlib import afm, cbook, ft2font, rcParams, get_cachedir
ImportError: DLL load failed: 指定されたモジュールが見つかりません。
```

というエラーが出て、色々試しましたが失敗が続き、[Github](https://github.com/ContinuumIO/anaconda-issues/issues/6689)でようやく対処法を発見したのでシェアします。

## 「私の環境下で成功した対処法」
1.　Anaconda付属のパッケージ管理ツール"conda"でmatplotlibをアンインストール

```
conda uninstall matplotlib
```

2.　Pythonのパッケージ管理ツール"pip"でmatplotlibを再インストール

```
pip install matplotlib
```

これで無事エラーの回避に成功し、matplotlibでグラフ描画することが出来ました。
Python入門本にはAnacondaやmatplotlibを使うものが多くあると思います。私の様な、Python初学者の方の参考になればうれしいです。

##（追記） 「私の環境下で成功した対処法２」
上記で問題解決したかと思っていたら、時間が経ったら似たようなエラーが出るようになってしまいました。
これはmatplotlibのバージョンが古くなってしまったからのようです。

Pythonのパッケージ管理ツール"pip"でmatplotlibをアップデート

```
pip install -U matplotlib
```

これを行ったら、再びグラフ描画できるようになりました。
スクレイピングで最低価格を取得するには？

12月に入り、暖かい日もありつつ確実に冬に近付いています。
スキーやスノボなどウィンタースポーツをされる方にとっては交通費の次に宿泊費は大きな出費のひとつです。
空室情報や価格を比較できるサイトは数多ありますが、サイトから表示されるデータは実は選別されていることをご存知ですか？

![snowboardpic.jpg](https://qiita-image-store.s3.amazonaws.com/0/322458/cefb5f6d-7870-76ec-6fd7-d10482dfee23.jpeg)

これはクローキングと言われていて、ターゲットサイトがユーザーエージェントや IPアドレスにより実際の人が使っているブラウザなのか検索エンジンのロボットかを判別し、それぞれに別々のソースを参照させたりする行為の事です。

これを回避して、空室状況や正しい価格のデータを収集するにはプロキシが効果的です。
プロキシを利用して固定IPでIP分散を行うと、ターゲットサイトからはロボットではなく、
本物の人間がアクセスしているように見せかけることが可能となります。
paizaでアセンブラ その５


#概要

paizaでアセンブラ、やってみた。
gas調べたら、printf使えた。
fizzbuzzやってみた。

#サンプルコード


```
import subprocess
import os

def gcc():
    c_file = 'fizzbuzz.s'
    test_c = """
.code64
.text
.global main

main:
	sub 	$8, %rsp
	mov 	$1, %r8
loop:
	mov 	$0, %r10
	mov 	$0, %rdx
	mov 	%r8, %rax
	mov 	$3, %rsi
	div 	%esi
	cmp 	$0, %rdx
	jne 	skip1
	add 	$1, %r10
skip1:
	mov 	$0, %rdx
	mov 	%r8, %rax
	mov 	$5, %rsi
	div 	%esi
	cmp 	$0, %rdx
	jne 	skip2
	add 	$2, %r10
skip2:
	cmp 	$0, %r10
	je 		printNum
	cmp 	$2, %r10
	jb 		printFizz
	je 		printBuzz
	ja 		printFizzBuzz
printNum:
	lea 	num(%rip), %rdi
	jmp 	loope
printFizz:
	lea 	fizz(%rip), %rdi
	jmp 	loope
printBuzz:
	lea 	buzz(%rip), %rdi
	jmp 	loope
printFizzBuzz:
	lea 	fizzbuzz(%rip), %rdi
loope:
	mov 	$1, %rax
	mov 	%r8, %rsi
	push 	%r8
	push 	%r10
	call 	printf
	pop 	%r10
	pop 	%r8
	add 	$1, %r8
	cmp 	$101, %r8
	jne 	loop
	add 	$8, %rsp
	ret
.data
num:
	.asciz "%i "
fizz:
	.asciz "Fizz "
buzz:
	.asciz "Buzz "
fizzbuzz:
	.asciz "FizzBuzz "	
"""
    with open(c_file, 'w') as f:
        f.write(test_c)
    os.system("gcc -no-pie %s" % c_file)
    result = subprocess.Popen('./a.out', stdout = subprocess.PIPE).communicate()[0]
    for i, v in enumerate(result[ : -1].split('\n')):
        print v

if __name__ == '__main__':
  gcc()
  

```


#成果物

https://paiza.io/projects/cMCJMNKlAIoaLzIDSfdHsA

以上。
自分の使いたいコマンドを、CWLにするときのTIPS

追記:2019-01-31 一部更新(--helpの説明や、コメント追加、--make-templateについて)


# 自分の使いたいコマンドを、CWLにするときのTIPS

まずは、自分の使いたいコマンドを、 `CommandLineTool` に変換することｗ考える。

具体的な事例は、別の記事にする予定です

使いたいコマンドがコンテナになっていると便利である。
もし、biocondaのパッケージなら、
biocontainersで探してみると良い。

- 公式の、検索機能　[BioContainers Registry UI](http://biocontainers.pro/registry/#/)　が、うまく動かないときは
- [Quay Container Registry · Quay](https://quay.io/) で、 `biocontainers` と `ツールの名前` で検索するとみつかることがある。
  - Tags をみると、利用できるバージョン一覧が得られる。
  - [biocontainers/metavelvet · Quay](https://quay.io/repository/biocontainers/metavelvet?tab=tags)

まずは、バージョンを確認しておく。
のちのちの、再現性のために。



```

コマンド --version
```

つぎに、ヘルプやGettingスタートを見ながら、
コマンドを起こしていく。

```
コマンド --help
```

コマンドにわたす順番が問題になるならば、順番を指定しながら起こしていく。

サンプルは、このあと埋めます。


書いたCWLをバリデートしてくれる

```
cwltool --validate 今回作ったCWLファイル
```

書いたCWLのヘルプをだせる(docをかけば。 labelではでてこなかった)

```
cwltool --help 今回作ったCWLファイル
```

追記上の方法だと、ツールのヘルプがうまくでてこなかった
ただしくは

```
cwltool --tool-help 今回作ったCWLファイル
```

もしくは

```
cwltool 今回作ったCWLファイル --help 
```

順番依存であった。


書いたCWL用のテンプレートを作ってくれる
ここで、できたテンプレートに入力パラメータを書く。
もし入力パラメータが、変更になったら、このファイルを書き換えればよく、今回作ったCWLファイルを書き換える必要はない。

このファイルを使わずに、直接コマンドラインから入力パラメータを指定することも可能。（実例は別の記事にて）

```
cwltool --make-template 今回作ったCWLファイル
```

解析したものは、標準出力に出るので、それを保存するようにする

```
cwltool --make-template 今回作ったCWLファイル > template.yml
```


## キャッシュについて

キャッシュを使うと、ワークフローの作成時に

```
A->B->C
```

というフローだったときに、

```
A->B
```

まで動いていたら、そこまでのデータを、キャッシュしておける。

```
cwltool --cachedir cache
```

ツールの開発時によいかもしれない。

## 実際にテストデータを使って動かす。

このとき、実行するマシンが、サンプルデータを動かせるか（メモリの最低要求量など）を満たしているかわかっているとよい。
とにかく小さなデータを、用意すると、すぐに結果がえられてよい。
うまく動くことがわかってから、より大きなデータを実行したほうが効率的だろう。


## 注意点（どうしても、入力ファイルのあるディレクトリに出力をしたいとき）

CWLは使用上、基本的に入力データは、ReadOnlyで、コンテナにマウントされる。
これにより、不慮の事故でデータを失うことがない。

しかし、何かの理由で、入力データと同じディレクトリに、出力データを起きたいときに、以下の `InitialWorkDirRequirement` と `writable` オプションを使うと読み込み以外に書き込みもできるようになる。

追記2019-07-03 `entry` について書き足した
```cwl
requirements:
  InitialWorkDirRequirement:
    listing:
      - entry: ディレクトリ $(inputs.datadirとか) (なにかちょっとここにかかれる)
        writable: true
```

書き込みができるので、事故がおこる可能性がでてくる。
AWS CloudWatch でいつの間にかログを簡単に検索できるようになっていた件

### 概要
先ほどCloudWatchの画面をいつものようにログを漁ろうとみていたら、ロググループの中に「イベントの検索」というボタンがあり、押してみるとログ内容の検索ができるようになっていました。

今まではAthenaに取り込んだログでクエリを流すとか、Elasticsearch入れるとか、ちょっとめんどくさかったところが簡単にできそうです。
これ、知らなかったの私だけです？ Re:Inventでシェアされたりしたのだろうか。

### スクショ
`" 500 "` という検索ワードで500エラーだけが絞れているのがわかります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/144064/6b62269a-85c7-32f9-362c-a5d92f9c2832.png)



![image.png](https://qiita-image-store.s3.amazonaws.com/0/144064/ab89b30a-511a-4c91-330c-8347ddc229a5.png)
Aurora MySQL 5.7 で Mysql2::Error: MySQL client is not connected

# 問題
 - ステージングのデプロイ時に `db:migrate` でタイトルのエラーが出た

# 対処
 - 以下の記事通りに対処した。本当に感謝です。
   - [Aurora MySQL 5.7 で Mysql2::Error: MySQL client is not connected](http://blog.office-aship.info/aurora-mysql-5-7/) 

```yml:database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  ...
  # sql_modeの追加
  variables:
    sql_mode: TRADITIONAL
```


# おまけ
 - `amazon/aurora/mysql5.7` + `read replicaの複数台構成` + `rails` の database.yml 

```yml:database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: <%= ENV['DATABASE_USERNAME'] || 'root' %>
  password: <%= ENV['DATABASE_PASSWORD'] %>
  host: <%= ENV['DATABASE_HOST'] || 'localhost' %>
  database: <%= ENV['DATABASE_NAME'] || '<dev_database_name>' %>
  socket:  <%= ENV['DATABASE_SOCKET'] || '/tmp/mysql.sock' %>
  variables:
    sql_mode: TRADITIONAL

default_readonly: &default_readonly
  <<: *default
  host: <%= ENV['DATABASE_HOST_READONLY'] || 'localhost' %>

# dev or test 環境ではDB１台なのでreadonly設定はしてない
development:
  <<: *default

test:
  <<: *default
  database: '<test_database_name>'

staging:
  <<: *default

staging_readonly:
  <<: *default_readonly

production:
  <<: *default

production_readonly:
  <<: *default_readonly

```
paizaでアセンブラ その４

#概要

paizaでアセンブラ、やってみた。
gas調べたら、printf使えた。

#サンプルコード
１から１００を表示

```
import subprocess
import os

def gcc():
    c_file = 'test.s'
    test_c = """
.code64
.text
.global main

main:
	sub 	$8, %rsp
	mov 	$1, %r8
loop:
	mov 	$0, %r10
	mov 	$0, %rdx
	mov 	%r8, %rax
	lea 	mat(%rip), %rdi
	mov 	$1, %rax
	mov 	%r8, %rsi
	push 	%r8
	push 	%r10
	call 	printf
	pop 	%r10
	pop 	%r8
	add 	$1, %r8
	cmp 	$101, %r8
	jne 	loop
	add 	$8, %rsp
	ret
.data
mat:
	.asciz "%i "
"""
    with open(c_file, 'w') as f:
        f.write(test_c)
    os.system("gcc -no-pie %s" % c_file)
    result = subprocess.Popen('./a.out', stdout = subprocess.PIPE).communicate()[0]
    for i, v in enumerate(result[ : -1].split('\n')):
        print v

if __name__ == '__main__':
  gcc()
  

```


#成果物

https://paiza.io/projects/PzCEFvmgwG5C0C9ZdeW6Mw

以上。
【プログラミング質問方法のすゝめ】質問する事にためらいのあるすべての人へ


#もくじ
1. どんな記事？
2. 読んで得られること
3. 具体的な方法
4. 結論

##1.どんな記事？

人に聞くのは避けられない....
でも、原因がしょうもない事だったらどうしよう。
こんな事も分からないの？って言われたらどうしよう。
実際に質問してみたら、大した原因ではなかったらどうしよう。

人に質問する時に、色々考えてしまう人/質問する事が怖い人に読んでほしい記事です。

私自身、人に質問するのが怖いです！上記に書いたような事を考えてしまいます！
そのため、自己解決できる幅を広げよう！と考えていました。

しかし、学習初期は自己解決出来る幅も狭いので、質問相手がいるのなら「質問」はした方が効率良かったです。

なので、いかに不安要素を潰しつつ、相手に短時間で意思疎通を行い、求めていた回答を得るかを記事にしました。

##2. 得られること

質問しても、意図していない回答が返ってくることが減る。（質問の意図が伝わりやすくなる）

自己解決出来る幅が広がる。

質問力がつく。

##3. 具体的な方法

結論としては、以下の三点を意識して質問します。

- [ ]  1.実現したい事
- [ ]  2.問題点
- [ ]  3.試してみた事

なぜこの三点なのか？
私自身、人に質問した際の反省を生かした結果がこの3点でした。

###実現したい事を説明する必要性

一言で言うと、**意図が伝わりやすくなるからです！**無駄な意思疎通が減るので、心理負担が少し減りました！

プログラミング学習初期の私は、質問する際に問題点は必ず説明していました。
問題点を必死に説明して、説明して。。。。。
質問を説明し終わったと思ったところで、


質問相手「うん。それで。。。。。？」


と言われました。
ええ。つまり、実現してほしい事・解決してほしい事が伝わらなかった、もしくは言っていなかったのです。

問題点を説明したら、相手が「実現したい事」を理解してくれるだろう。と思っていました。
相手に理解を丸投げしていました。相手に理解してもらうための、努力をおろそかにしていました。

問題点を説明するだけで、実現したい事を悟ってくれる人もいるかもれません。
しかし、すべての人がそうだとは限りません。

そのため、**どの人に質問しても意図が伝わるために「実現したい事」は説明した方がハッピーになれます。**

###試してみた事を説明するメリット



この項目は、必要ないと思われるかもしれません。

しかし、

質問内容の自己解決の可能性の向上。
質問相手に、幻滅される可能性の削減。
質問相手に、試した事へのフィードバック得られることもあります！


**「何を試して、どのような結果が帰って来て、何が出来なかったか」　**

これを伝えるために脳内整理するだけでも、解決にいたる事があります！

さらに、「〜で検索して、〜を試してみました。しかし、〜となってしまいました。」

と質問するだけで「ググった？」と聞かれる事を回避できます！

質問する際に説明していて損はないです！

##4.まとめ

「〜をしたいのですが（行いたい事）〜で出来ませんでした（問題点）。〜と考えて、〜を実行してみました。しかしながら、〜となってしまいました（試した事）。」と聞くと分かりやすいかもしれないです！

色々試したにもかかわらず、分からなかったら聞いて良いです！

プログラミング学習の高速道路にのりましょ！！

最後まで読んでくださりありがとうございました。
paizaでアセンブラ その3

#概要

paizaでアセンブラ、やってみた。
gas調べたら、puts使えた。

#サンプルコード


```
import subprocess
import os

def gcc():
    c_file = 'test.s'
    test_c = """
.code64
.text
.global main

main:
	mov	 	$message, %rdi
	call	puts
	ret

.data	
message:
	.asciz "hello world!"
"""
    with open(c_file, 'w') as f:
        f.write(test_c)
    os.system("gcc -no-pie %s" % c_file)
    result = subprocess.Popen('./a.out', stdout = subprocess.PIPE).communicate()[0]
    for i, v in enumerate(result[ : -1].split('\n')):
        print v

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

#成果物

https://paiza.io/projects/9szX-ZBOIzn9BaQSq_-TZg

以上。
末尾再帰最適化について

# 概要
自分の中での整理用に書きました。
詳しくは参考記事を参照してください。
末尾再帰最適化について、再帰関数やスタックオーバーフローにも触れつつ書いていきます。

# キーワード
- 再帰関数
- スタックオーバーフロー
- 末尾再帰

# 再帰関数とは
関数の中でその関数自身を呼び出す関数のこと

例)階乗*n!*を求める関数 
6!=6*5*4*3*2*1=720
みたいに、その数字以降全ての積を表すのが階乗
これを関数にすると、

```javascript:factorial.js
function factorial(n){
  if (n === 1) return 1;
  else return n*factorial(n-1)
}
```

ただし、この関数には問題があり、nが非常に大きな数になった場合にスタックオーバーフローが起きてしまう

# スタックオーバーフロー
上記の階乗の計算を求める際、例えばn=10のとき、
factorial(10)=10*factorial(9)なので、factorial(9)の計算結果が必要となるためfactorial(9)を計算しにいく。
このとき、10*factorial(9)の10をどこかに記憶しておかないといけない。
同様にfactorial(9)では9*factorial(8)となるので9を記憶し、これがfactorial(1)=1と分かるまで繰り返される。
この記憶の積み重ねがメモリに溜まっていく。（このときに使われるデータ構造がスタック）
nが大きくなればなるほどメモリが必要になるが、メモリも無限ではないため、いつかはデータが多すぎて溢れてしまう。
これがスタックオーバーフロー。

これを回避するためには、ループでプログラムを記述するか、末尾再帰最適化を利用する。（実際は末尾再帰で書いたコードがループで書かれたものにコンパイルされるっぽい）

# 末尾再帰
返り値が再帰関数の呼び出しのみになっている場合に、それを末尾再帰(Tail Recursion, Tail Call)と呼ぶ。

上記の階乗を求めるコードを末尾再帰として書きなおすと下のようになる。

```javascript:factorialTailCall.js
function factorialTailCall(n, accumulator = 1){
  if (n === 1) return accumulator;
  else return factorialTailCall(n-1, n*accumulator)
}
```
factorialTailCall(4)のとき、
factorialTailCall(3,4*1)
factorialTailCall(2,3*4)
factorialTailCall(1,2*12)
という順番で関数が呼び出されていき、最終的に24が帰ってくる。

積を保存しておくaccumulatorを引数に追加することで、再帰関数の呼び出しのみを返り値にできている。
末尾再帰の条件を満たしているとき、コンパイラなんかが最適化してくれることを末尾再帰最適化と言う。
ただし、末尾再帰最適化に対応しているものとしていないものがある。

# 言語ごとの対応・非対応
| 言語 | 対応しているか | 補足 |
|:-:|:-:|:-:|
|Java|×||
|Scala|○|@tailrec|
|Kotlin|○|tailrec修飾子|
|JavaScript|△|※後述|

# JavaScriptの末尾再帰最適化
ES6の仕様には末尾再帰最適化があるみたいだが、それに対応しているブラウザがSafariくらいしかない模様([ES6対応表](http://kangax.github.io/compat-table/es6/#safari12))
Node.jsでは一時期`--harmony`オプションをつけることで末尾再帰最適化ができていたみたいだが、現在のバージョンでは非対応になってしまっている。([Node.js ES6対応表](https://node.green/#ES2015-optimisation-proper-tail-calls--tail-call-optimisation-))
babelについても、一時期対応していた時期もあったみたいだが、現在は非対応になっているようだ。

実際にNode.jsで前述のfactorialTail関数とfactorialTailCall関数を動かしたら、末尾再帰になっているはずの後者の方が早くスタックオーバーフローを起こしてしまった
悲しい

# おまけ フィボナッチ数列
フィボナッチ数列を通常の再帰と末尾再帰で書くと下記のような感じ

通常の再帰

```javascript:fibo.js
function fibo(n) {
  if (n === 0) return 0;
  else if (n === 1 || n === 2) return 1;
  else return fibo(n-1) + fibo(n-2);
}
```

末尾再帰

```javascript:fiboTailCall.js
function fiboTailCall(n, a = 1, b = 0) {
  if (n === 0) return 0;
  else if (n === 1) return a;
  else return fiboTailCall(n-1, a+b, a);
}
```

# 参考
[末尾再帰による最適化](https://qiita.com/pebblip/items/cf8d3230969b2f6b3132)
http://www.fos.kuis.kyoto-u.ac.jp/~igarashi/class/pl/09-rec-iter.html
【grpc-gateway】0, false, nullなどの値をJSON出力対象にする

# はじめに

例えばgRPCのメソッド、メッセージが以下だとして

```proto
syntax = "proto3";

import "google/protobuf/empty.proto";
import "google/api/annotations.proto";

package proto;

service TestService {
    rpc Test (google.protobuf.Empty) returns (TestMessage) {
        option (google.api.http) = {
            get: "/test"
        };
    }
}

message TestMessage {
    int32 a = 1;
    bool b = 2;
    string c = 3;
    repeated string d = 4;
}
```

サーバからクライアントに送るメッセージが(極端ですが)以下のような内容だったとします。

```go
TestMessage {
  a: 0,
  b: false,
  c: "",
  d: nil
}
```

`grpc-gateway`経由で上記のメッセージを受け取った場合、空のJSONがレスポンスとして返ってきてしまいます。しかし、本当は以下のようなレスポンスが返ってきて欲しいです。

```json
{ "a": 0, "b": false, "c": "", "d": [] }
```

ということでこのような設定にする方法を調べましたが、日本語の記事が見つからなかったのでQiitaに載せておきます。

# やりかた

`grpc-gateway`に、ゼロ値は省略せずにJSONの項目に含めてくれるオプションがありますので、それを指定して`grpc-gateway`のサーバを起動すれば万事解決です。

```go
opts := []runtime.ServeMuxOption{
	runtime.WithMarshalerOption(runtime.MIMEWildcard, &runtime.JSONPb{OrigName: true, EmitDefaults: true}),
}

mux := runtime.NewServeMux(opts...)
```

# 原因

そもそも、なぜJSONのレスポンスに0や空文字が含まれていないのかという話ですが、Protocol Bufferから作成されたGo用の構造体に`omitemptpy`が指定されているためです。

```go
type TestMessage struct {
	A                    int32    `protobuf:"varint,1,opt,name=a,proto3" json:"a,omitempty"`
	B                    bool     `protobuf:"varint,2,opt,name=b,proto3" json:"b,omitempty"`
	C                    string   `protobuf:"bytes,3,opt,name=c,proto3" json:"c,omitempty"`
	D                    []string `protobuf:"bytes,4,rep,name=d,proto3" json:"d,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}
```

しかも、この`omitempty`はハードコードで指定されているので`protoc`でコンパイルすときには必ず指定されてしまいます…

上記のような理由から、**構造体に指定されているomitemptyを無視してゼロ値を出力する**オプションが`grpc-gateway`側で作成されたようです。ありがとうphilipithomasさん！

# 参考リンク

[golang protobuf remove omitempty tag from generated json tags -Stack Overflow](https://stackoverflow.com/questions/34716238/golang-protobuf-remove-omitempty-tag-from-generated-json-tags)
[Support emitting default values in JSON #233](https://github.com/grpc-ecosystem/grpc-gateway/issues/233)
「スマートコントラクトを作るスマートコントラクト」の書き方

Qiita [BlockChain Advent Calendar 2018](https://qiita.com/advent-calendar/2018/blockchain) 6日目の記事です。今回はスマートコントラクトに関する小ネタとして「スマートコントラクトを作るスマートコントラクト」について書こうと思います。

## スマートコントラクトを作るスマートコントラクト

不特定多数の人が似たようなコントラクトを作りたいケースがあります。例えば「募金」のコントラクトなどは、募金によって必要となる property や function に大きな違いはなさそうです。
そのような場合、募金の**コントラクトを作るコントラクト**を用意しておけば、募金コントラクトを作りたい人は募金名・募金可能期間・関連URLなどその募金特有の情報だけを入力すれば、誰でも**同様の情報・機能をもつコントラクトを同じ仕組みで作ることができます**。

## スマートコントラクトを作るスマートコントラクトの書き方

ここでは「スマートコントラクトを作るスマートコントラクト」のことを**Factoryコントラクト**と呼ぶことにします。
Factoryコントラクトの中で`new [作成するコントラクト名]`することでコントラクトを作成できます。

```
pragma solidity ^0.4.25;

contract [Factoryコントラクト名] {

    // コントラクト作成function
    function createContract(/* 引数がある場合は引数を書く */) public returns (address) {
        address newContract = new [作成するコントラクト名](/* 引数がある場合は引数を書く */);
        return newContract;
    }
}


contract [作成するコントラクト名] {

    // do something...

}
```

## 備考

### 作成したコントラクトのオーナーについて
コントラクトのオーナーアドレスを設定する際、コントラクト内で`owner = msg.sender`すると思います。上記の[作成するコントラクト]内で`owner = msg.sender`とすると、作成したコントラクトのオーナーアドレスは**Factoryコントラクトのアドレス**になります。
createContract を実行したアドレスをオーナーアドレスとしたい場合は、createContract の中で`msg.sender`を取得しておいて、new する際に引数に渡しましょう。

```
contract [Factoryコントラクト名] {

    // コントラクト作成function
    function createContract(/* 引数がある場合は引数を書く */) public returns (address) {
        address ownerAddress = msg.sender;
        address newContract = new [作成するコントラクト名](ownerAddress);
        return newContract;
    }
}


contract [作成するコントラクト名] {

    constructor(address _ownerAddress) public {
        owner = _ownerAddress;
    }

    // do something...

}
```

### Style Guide
Solidityの綺麗な書き方については以下のStyle Guideを参考に。
- [Style Guide](https://solidity.readthedocs.io/en/latest/style-guide.html)
EC2 hibernation機能を試してみる

##はじめに
以前からSpotインスタンスでは利用できていたhibernation機能ですが、オンデマンド、RIでも利用できるようになりましたので試してみます。
https://aws.amazon.com/jp/blogs/aws/new-hibernate-your-ec2-instances/

##前提
Root VolumeがEBSであること(インスタンスストア不可)
Root VolumeがEBS暗号化されていること
サポートしているEC2インスタンスタイプ:M3, M4, M5, C3, C4, C5, R3, R4, R5

##手順
###暗号化したAMIの作成
AMIを作成する
![image.png](https://qiita-image-store.s3.amazonaws.com/0/78184/d3016ca3-d777-60b2-c225-bec117384ae8.png)

AMIをコピーして暗号化実施
![image.png](https://qiita-image-store.s3.amazonaws.com/0/78184/7db90b61-5d88-116e-2bb9-1aa05c09e441.png)

「Encrypt target EBS snapshots」にチェックをつける
![image.png](https://qiita-image-store.s3.amazonaws.com/0/78184/d510315c-2b24-c245-3f52-fc9bc07e4f1d.png)

AMIを選択しEC2インスタンスを起動
![image.png](https://qiita-image-store.s3.amazonaws.com/0/78184/8667d32a-1a42-05a8-ea6c-ef2d4fc7442d.png)

Nitro世代のインスタンスタイプを選択する。今回はc4.largeを選ぶ
「Enable hibernation as an additional stop behavior」を有効にする
※起動後に変更不可
![image.png](https://qiita-image-store.s3.amazonaws.com/0/78184/2f4a998e-db69-06ff-e90d-4671f5ce2885.png)

休止してみる
![image.png](https://qiita-image-store.s3.amazonaws.com/0/78184/bb7308ce-45ae-06e1-fd89-fb8af6ad72d5.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/78184/4513147d-1452-20d8-807c-8dc15ffbe681.png)

c4.large(メモリ 3.75 GiB)で10-15分程度で停止完了した

##約束
投稿内容は私個人の意見であり、所属企業・部門見解を代表するものではありません。
rails notesを使ってrailsプロジェクトにコメントを残す

# いつか直すぞ

railsで現ブランチではなくて、別ブランチで加筆・修正する場合にコメントアウトでメモを残す場合ありますよね？
※もしくは未来の誰かに託す場合...w
その際に、`“OPTIMIZE”, “FIXME”, “TODO”`で書いておくと良いよって話です。


# Railsガイドによると

> bin/rails notesは、コードのコメントからFIXME、OPTIMIZE、TODOで始まる行を探し出して表示します (訳注: [FIXME]のように[から始まるものはヒットしません)。検索対象となるファイルの拡張子は.builder、.rb、.rake、.yml、.yaml、.ruby、.css、.js、.erbで、デフォルトのアノテーション以外に独自のアノテーションも使用できます。

[Railsガイド](https://railsguides.jp/command_line.html#notes)より


```ruby:app/controllers/admin/users_controller.rb
# TODO: any other way to do this?
```

```console:console
$ bin/rails notes
(in /home/foobar/commandsapp)
app/controllers/admin/users_controller.rb:
  * [ 20] [TODO] any other way to do this?
  * [132] [FIXME] high priority for next deploy
 
app/models/school.rb:
  * [ 13] [OPTIMIZE] refactor this code to make it faster
  * [ 17] [FIXME]
```

# 実際の表示
![スクリーンショット 2018-12-06 16.46.00.png](https://qiita-image-store.s3.amazonaws.com/0/121435/223db2bb-891b-f881-dc21-53d6ef3b59f5.png)
Perception NeuronでレコードしたモーションデータをUnityの ヒューマノイドモデルに適応させる

# 目的
Perception NeuronでキャプチャしたモーションデータをUnity上の
Humanoidキャラクター(Humanoid SkeletonへのRigがついている)モデルに転写したい！

### 結果動画
![result.gif](https://qiita-image-store.s3.amazonaws.com/0/184790/db0de77d-8718-4865-9580-4cdbc13c4d5d.gif)





# PerceptionNeuronとは
PerceptionNeuronとは中国Noitom社によって開発された低価格(約$1,500)モーションキャプチャシステムです。キャプチャにはNeuronという加速度、ジャイロ、磁気計を持つIMU（慣性計測装置）32個と、それをコントロールする1つのハブで構成されています。
Axis Neuronという専用ソフトでモーションデータをレコードすることができ、BVH,FBX等のフォーマットでの書き出し、TCP/UDPを用いたリアルタイムでの送信も出来ます！ハブからpcへのwifi接続も出来ますが結構つながりにくいのでusb送信がおすすめです。

PerceptionNeuron:https://neuronmocap.com/ja
# Axis Neuron
ここからdownload出来ます→https://neuronmocap.com/ja/downloads

モーションのキャプチャが出来たら左上タブのfile/exportへ行き、FileTypeをFBX 6.0(*.fbx)を選択

# Unityでアニメーションの再生
ここで先ほど書き出したfbxデータをUnityに入れていきます。ここまでの過程でうまくいけば
終了ですが、うまくいかない場合があります。

### 失敗したやつ...これはこれで面白いですね笑
![Unity-2018.2.13f1-Personal-_64bit_-SampleScene.gif](https://qiita-image-store.s3.amazonaws.com/0/184790/b873bba9-540a-6e83-8a6a-8e11e86dd805.gif)


PerceptionNeuronを用いてモーションデータを受信する条件をモデルが満たしていないためです。制約としては以下の物が挙げられています。

1. モデルはHumanoid SkeletonへのRigがついていること
2. Rigの各ボーンはRotationが0で、軸の方向はUnityの座標軸と一致していること
3. モデルはTポーズの形でRigづけされてること

## 解決手段
自分は以下のようなモデルを使用しました。Tポーズは取れていますが、回転角が0ではなかったので挙動がおかしくなりました。
![Unity 2018.2.13f1 Personal (64bit) - SampleScene.unity - PerceptionNueron - PC, Mac & Linux Standalone _DX11_ 2018_12_06 15_54_46.png](https://qiita-image-store.s3.amazonaws.com/0/184790/715c5814-6512-2d2a-b2bf-e997ca8c0069.png)


### Rotationを0にする
先程のfbxデータのinspectorでAnimation TypeがHumanoidになっていることを確認した上でconfigureを選択。そのあとはモデルの各部位のRotationを0にするだけでおっけいです！
![Unity 2018.2.13f1 Personal (64bit) - Untitled - PerceptionNueron - PC, Mac & Linux Standalone_ _DX11_ 2018_12_06 16_25_54.png](https://qiita-image-store.s3.amazonaws.com/0/184790/577c575a-469b-9c9c-f4b1-399ca3518003.png)


##Success！
![result.gif](https://qiita-image-store.s3.amazonaws.com/0/184790/db0de77d-8718-4865-9580-4cdbc13c4d5d.gif )
# 補足
アニメーションのFoot IKはオンにしておいた方が動きがきれいに見えます
# 参考
http://dverse.me/enginnerblog/2016/08/08/perception-nueron01/
LAN-IRU01のカスタムファームを作ってみた

少し前の話になるのですが、投げ売りで500円で買って来たLogitecのLAN-IRU01をハックしてみました。

このモジュールはAndroidアプリからBluetoothで制御して赤外線リモコンの信号を出すためのモジュールです。

分解してみるとMSP430F5507やBC417など結構良い部品が使われてますし、何より赤外線LEDが10個もついています。

![9579667355_9af118a76b_z.jpg](https://qiita-image-store.s3.amazonaws.com/0/104066/72dd6fe0-219e-5ced-15fa-8d135a1ae71c.jpeg)


マニュアルには利用できないと書いてありますが、マイクロUSBの口があり接続してUSB proberで見てみます。

```
Full Speed device @ 7 (0x1D131000): .............................................   Composite device from unknown vendor
    Port Information:   0x0018
           Not Captive
           External Device
           Connected
           Enabled
    Device Descriptor   
        Descriptor Version Number:   0x0200
        Device Class:   0   (Composite)
        Device Subclass:   0
        Device Protocol:   0
        Device MaxPacketSize:   8
        Device VendorID/ProductID:   0x2047/0x0200   (unknown vendor)
        Device Version Number:   0x0104
        Number of Configurations:   1
        Manufacturer String:   0 (none)
        Product String:   0 (none)
        Serial Number String:   0 (none)
    Configuration Descriptor   

```

これって見る人が見れば分かりますよね。MPS430のISPが見えてしまっています。

このモジュールの不思議な事は製品ではISPは見えないようにするの普通です。またもし開発中にISPモードにしたい場合はボタンを押しながら、USBを接続するなどの仕様が一般的ですが、ボタンはあるものの特に操作しなくてもISPモードが見えてしまっています。

これに気を良くしてmspdebugにMacのHIDのパッチを作ってマージしてもらってますので、mspdebugで書き込めてしまいます。何故か一回目は失敗するのですが、もう一度やるとちゃんと書き込めます。Mac HID以外でも同じだったのでmsddebugの問題な気がします。

mspdebugで書き込むと元々あった機能が無くなりますので、注意してください。

[開発はPlatformIO](https://qiita.com/yamori813/items/25af074cc64a7f7cfcef)でおこないました。

CSRのBluetoothチップへはシリアル接続されていて、信号はコントロール用の送信とBluettothの受信で、オリジナルのフェームウエアでシリアル信号をモニターして確認しました。

CSRのBluetoothチップのファームウエアはいじりません。

赤外線LEDのポートは基板で追って、テストプログラムを書いて焼いて確認しました。

38Kの赤外線信号の作り方は[ここ](https://qiita.com/yamori813/items/f4423c566ea757ecf3be)に書きました。

そんなこんなで、どうにかモジュール用のコードは作れて、mspdebugで焼いてみました。

コントロール用のプログラムはMacのアプリで以前から作っていた[アルマジロのお使い](http://hp.vector.co.jp/authors/VA009278/ubsa-osx/armadillo.html)に入れてみました。

![Armadillo2.png](https://qiita-image-store.s3.amazonaws.com/0/104066/10f266a0-aa7a-c6c8-9271-1ee887cc856e.png)
![スクリーンショット（2018-12-06 15.52.58）.png](https://qiita-image-store.s3.amazonaws.com/0/104066/ddb9b920-faaf-5c55-7391-9a3842837f57.png)

久しぶりにパナソニックのシーリングを試してみましたが、ちゃんとON/OFFできました。

この製品の問題点は、

* コントロール用のAndroidアプリの出来が良くなかった
* iPhoneで使えない
* 制御できるリモコンの信号が少なかった
* 電池の持ちが1ヶ月くらいと悪かった
* ACアダプターも使えなかった
* Bluetoothの接続がうまくいかない事があった
* スマホでコントロールはあまり便利じゃ無かった

などが考えられます。

この製品は使っている部品も良いし、デザインも良いのに、500円はちょっと可哀想です。秋月でMSP430の評価ボードでも2000円くらいもするのに。

いろいろ考えて、USBがISPで立ち上がるのは、発光時にUSBの最大電流の500mAを越えるため電源として使えないためだったりするのでしょうか？
SASでいうWorkに保存されるデータ

**読み込んだデータはどこに行くのか。。**
--
SASの場合立ち上げるとCドライブ内にWorkというフォルダが作成され，
特に指定をしない限り作成したデータはWorkフォルダに格納される。

しかしPythonの場合，メモリ上に展開されるようだ。

**大きなデータを使用するときは，これが大問題に。**
32bitマシンを使用しているためメモリは4GB以上格納出来ない。
私の場合，大抵は2.3GB程度は使用されているので，2GBもメモリ内に展開することが出来ない。


**やりたい/知りたいこと**
--
①メモリでなくCドラとかに格納する方法
そもそも全データをメモリ展開しなくとも解析する際にバケツリレー的にメモリ展開して解析してくれたりするんですかね？

②メモリを開放する方法
SASプログラムだと，最初にlog消したりWork削除したりリセットしたりしてたのですが，
そんなようなことが出来ればと思っています。

**①メモリでなくCドラとかに格納する方法**
--
今のところ解決策を見つけられていません。
もし情報をお持ちの方がいたらご教示いただきたい。。

…やっぱりPythonの基礎本とかを読んでからのほうが良いんですかね。

**②メモリを開放する方法**
--
メモリを全部使うと他の作業が出来なくなるので，SASでいうWorkを全削除するみたいな作業を検討してみた。
ちなみにJupyter Labを使っているのですが，コマンドで開放する方法は今のところ知りません。
下記のどちらかの方法でリセットすることは出来るそうです。
![a.png](https://qiita-image-store.s3.amazonaws.com/0/281060/e558d631-00e6-a1d0-8c89-5942dbac3dc9.png)
![b.png](https://qiita-image-store.s3.amazonaws.com/0/281060/fedfa994-7fd6-ce24-5ee4-290f1a315f8a.png)

****

ネットを見る限り，SAS以外の他言語を学んだことがある人や素養がある人が分かるような説明はいっぱいあるようですが，
SASしかできない人はマイノリティなようで見つかりません。。

どなたかこうやって学んだほうが良いよと言う情報があれば合わせてコメントください。
CarbonPeriodを使って期間を指定して途中の日付を柔軟に補完する

CarbonPeriodを使って指定した期間の日付を楽に取得出来ます。

CarbonPeriodはCarbon 1.29から利用出来るようになっているようなので、現行バージョンのlaravelなら問題なく利用出来ると思います。

必要に駆られたら思い出して是非利用してみてください。

## 特定の期間を日単位で取得する

例えば任意の期間を日単位に配列で取得したい場合は、以下のように記載します。

```php
$period = CarbonPeriod::create('2018-12-01', '2019-12-31');

foreach ($period as $date) {
    echo $date->format('Y-m-d') . "\n";
}
```

結果

```
2018-12-01
2018-12-02
2018-12-03
2018-12-04
2018-12-05
　　　　　　　　・
　　　途中省略
　　　　　　　　・
2018-12-27
2018-12-28
2018-12-29
2018-12-30
2018-12-31
```

## 特定の期間を月単位で取得する

月毎の配列を取得する場合も、```months()```を呼ぶ事で簡単に月単位になります。
その他、years、weeks、hours、minutes、secondsと状況に応じて柔軟に期間も指定できます。

```php
$period = CarbonPeriod::create('2018-04-01', '2019-03-01')->months();

foreach ($period as $date) {
    echo $date->format('Y-m-d') . "\n";
}
```

```
2018-04-01
2018-05-01
2018-06-01
　　　　　　　　・
　　　途中省略
　　　　　　　　・
2019-01-01
2019-02-01
2019-03-01
```

## 配列に変換する

toArray()メソッドを使えば、そのまま配列として利用出来ます。

```php
$period = CarbonPeriod::create('2018-04-01', '2018-04-15')->toArray();

collect($period)->map(function ($date) {
    return $date->format('Y-m-d');
})->dd();
```

結果

```php
Illuminate\Support\Collection {#780
  #items: array:15 [
    0 => "2018-04-01"
    1 => "2018-04-02"
    2 => "2018-04-03"
    3 => "2018-04-04"
    4 => "2018-04-05"
    5 => "2018-04-06"
    6 => "2018-04-07"
    7 => "2018-04-08"
    8 => "2018-04-09"
    9 => "2018-04-10"
    10 => "2018-04-11"
    11 => "2018-04-12"
    12 => "2018-04-13"
    13 => "2018-04-14"
    14 => "2018-04-15"
  ]
}
```

それではごきげんよう！！
LaravelのルーティングのHTTPレスポンスをブラウザキャッシュさせる

タイトル通りですが、Laravelのレスポンスをブラウザにキャッシュさせたい場合などがあるかと思います。
この投稿ではその設定をした際の手順をメモします。

## 達成したいこと

- Laravel のルーティングでブラウザキャッシュを有効にしたい。(主にAPIなど)
- ルート個別に設定するのは手間なので Middleware を使って一括で設定したい。
- 処理中で例外が発生したりしたらキャッシュさせない。(特定のステータスコードの場合だけキャッシュさせたいなど)

## 手順

### 1. Middleware を作る

After Middleware として作り、レスポンスヘッダに `Cache-Control` を追加します。
`Cache-Control` で設定できるものはこちらの方の記事がまとまっていて見やすいです。 → [キャッシュについて整理 \- Qiita](https://qiita.com/anchoor/items/2dc6ab8347c940ea4648)
After Middleware (ルートの処理後に実施するMiddleware) を作るには `$next($request)` を実行し、それよりも後に実施したい処理を書きます。

`$next($request)` の戻り値 (`Illuminate\Http\Response`) からステータスコードを取り出して処理の成功/失敗を判断します。
`Response` のAPIは以下を参照してください。(以下のリンクはLaravel 5.7です)
[Illuminate\\Http\\Response \| Laravel API](https://laravel.com/api/5.7/Illuminate/Http/Response.html)	


ステータスコード `200` または `203` の場合だけキャッシュさせたい場合は以下のようになります。

```php:app/Http/Middleware/OhMyCache.php
<?php

namespace App\Http\Middleware;
use Closure;

class OhMyCache
{
    public function handle($request, Closure $next)
    {
        $response = $next($request);

        $statusCode = $response->status();
        $isValidResponse = $statusCode === 200 || $statusCode === 203;

        if ($isValidResponse) {
            $response->header('Cache-Control', 'max-age=60');
        }

        return $response;
    }
}
```


### 2. ルートに設定する

ルートで使えるよう `app/Http/Kernel.php` に登録します。

```php:app/Http/Kernel.php
protected $routeMiddleware = [
  // :
  'OhMyCache' => \App\Http\Middleware\OhMyCache::class,
  // :
];
```

任意のルーティングで使うよう設定して完了です。

```php:routes/api.php
Route::middleware(['OhMyCache'])->group(function () {
    Route::get('/foo', 'SomeController@foo');
    Route::get('/bar', 'SomeController@bar');
});
```
細菌叢解析ツールの共有〜Dockerコンテナで幸せになる方法②〜

#[細菌叢解析ツールの共有〜Dockerコンテナで幸せになる方法①〜からの続編です！](https://qiita.com/petadimensionlab/items/a51b4e42b2b886160b9b)

---
![つるおか_ページ_23.jpg](https://qiita-image-store.s3.amazonaws.com/0/241094/74a7f746-a980-9423-74cd-dd7b9a5cc86c.jpeg)
・そもそも使わんかったらどうなんの？

---
![つるおか_ページ_24.jpg](https://qiita-image-store.s3.amazonaws.com/0/241094/08e57b28-4633-0862-daf2-1434357f384d.jpeg)
・できた解析ツールを新PCに移そう！
・・・・うまいこと行きませんね〜・・・

---
![つるおか_ページ_26.jpg](https://qiita-image-store.s3.amazonaws.com/0/241094/c7837e1e-bebc-5e9e-2e3a-c4ed1fad8a26.jpeg)
・うまいこと行きませんね〜・・・（ちょっといらいら）

---
![つるおか_ページ_27.jpg](https://qiita-image-store.s3.amazonaws.com/0/241094/7df40443-854a-a1f8-98dd-0ee69a80ee6d.jpeg)
・はい、やっぱり幸せ！！

---
![つるおか_ページ_28.jpg](https://qiita-image-store.s3.amazonaws.com/0/241094/103821e5-c038-cbfc-d1a6-0e77f9653360.jpeg)
・気になる点&解決策をたらたら・・・（１）

---
![つるおか_ページ_29.jpg](https://qiita-image-store.s3.amazonaws.com/0/241094/69b52316-795f-ccda-2c6c-8223680ca0a1.jpeg)
・気になる点&解決策をたらたら・・・（２）

---
![つるおか_ページ_30.jpg](https://qiita-image-store.s3.amazonaws.com/0/241094/ee0b899c-d473-ba69-85b2-6484e10619fb.jpeg)
・[Galaxy](http://www.pitagora-galaxy.org/)
・[Google colaboratory](https://colab.research.google.com/notebooks/welcome.ipynb)
・[Rstudio.cloud](https://rstudio.cloud/)

---
![つるおか_ページ_32.jpg](https://qiita-image-store.s3.amazonaws.com/0/241094/da4ea818-594d-c353-4a49-c8aaa75b337a.jpeg)
以上です。ありがとうございました！

---
##参考URL
[効率的に安全な Dockerfile を作るには](https://qiita.com/pottava/items/452bf80e334bc1fee69a)

[大会スライドのフルバージョン（pitagora-galaxy公式Twitter）](
https://twitter.com/pitagora_meetup/status/1042608132344565762)

[細菌叢解析ツールの共有〜Dockerコンテナ〜](https://qiita.com/petadimensionlab/items/6393f07ef85f8b7a3743)
※本記事ですが、こちらをちょこっと変えただけだったりして・・・

・過去の記事リンク
[RstudioCloudの使い方](https://qiita.com/petadimensionlab/items/ea164445e455d2c52b66)
[Docker for Mac 勉強メモ〜インストール〜](https://qiita.com/petadimensionlab/items/76bb169723e57bdc0133)
[Docker for Mac 勉強メモ〜コマンド集〜](https://qiita.com/petadimensionlab/items/328c546b06fd073fe409)
[超新人プログラマー(見習)がまず手にした本と参考にしたWEBサイト〜Docker編〜](https://qiita.com/petadimensionlab/items/4963adf9fb882c05fc5e)