OmniAICreator/Qiita-1.07M huggingface dataset:
InSpecでchefのattributeを使う

#目的
Chefの実行時に利用したattributeを、InSpecでも同様に利用する方法を紹介します。
recipeでは、node objectのattributeを"node['apache']['dir']"といった表記で呼び出すことができます。
同様に、InSpecでも"node['apache']['dir']"といった表記でnode objectのattributeを呼び出せるようにします。


#構成
OSはRHEL7.3,ChefはServer Client方式。
利用したChef Clientは13.4.24-1.el7, Chef Serverは12.16.14-1.el7



#手順
1. 事前準備
2. ChefのRecipeでnode objectをJSONファイルに出力
3. InSpecでJSONファイルの読み込み、attributeを呼び出す


##1.事前準備
以下のコマンドで、Clientにgem 'deep_merge'をインストールします。

```
/opt/chef/embedded/bin/gem install deep_merge
```

##2.ChefのRecipeでnode objectをJSONファイルに出力
cookbookを作成し、以下のrecipeを追加します。

```
ruby_block 'Save node attributes' do
  block do
    require 'json'
    require 'deep_merge'

    new_node = JSON.parse(node.to_json)
    new_node = new_node.deep_merge!(new_node["default"])
    new_node = new_node.deep_merge!(new_node["force_default"])
    new_node = new_node.deep_merge!(new_node["normal"])
    new_node = new_node.deep_merge!(new_node["override"])
    new_node = new_node.deep_merge!(new_node["force_override"])
    new_node = new_node.deep_merge!(new_node["automatic"])
    new_node["default"] = nil
    new_node["force_default"] = nil
    new_node["normal"] = nil
    new_node["override"] = nil
    new_node["force_override"] = nil
    new_node["automatic"] = nil

    IO.write('/tmp/attributes.json', new_node.to_json)
  end
end
```


##3.InSpecでJSONファイルの読み込み、attributeを呼び出す
InSpecの最初に以下の2行を追加し、JSONファイルを読み込むようにします。

```
require 'json'
node = json('/tmp/attributes.json').params
```

これで、recipeと同様に"node['apache']['dir']"といった形式でattibuteを利用することができます。

以下、InSpecのテストファイルのサンプルです。

```
require 'json'
node = json('/tmp/attributes.json').params

apache_dir = node['apache']['dir']

control 'apache directory' do
  desc 'directory should exist'
  describe directory apache_dir.to_s do
    it { should be_directory }
  end
end
```

以上
mt_fileinfoをみるとわかること

これは [Movable Type Advent Calendar 2017](https://adventar.org/calendars/2203) 24日目の記事です。
Data API にはじまり、MTAppjQuery に終わるという、今年も Movable Type 一筋の一年でしたが、みなさんはいかがでしたか。来年は MT7 への移行が熱くなりそうですね。

## はじめに
最近、以下のことを相談されることがあったので、解決策につながる方法を紹介したいと思います。

1. ブログ記事のベース名を変更した際に、古いベース名のファイルが残っているので探したい。
2. 公開しているコンテンツの中で、Movable Type で出力しているものと、そうでないものを整理したい。

(1) はよく聞く話です。ブログ記事やウェブページのベース名は、タイトル欄に入力された文字列を元に自動生成されます。このベース名を、理解しやすい URL にするために変更する際、対象を公開したまま実行するため、元のベース名のファイルが残ってしまうというものです。

(2) は (1) の現象の他に、期間限定のプロモーションサイトやランディングページを FTP 等でアップロードしているサイトではよくある話ですね。

これらを解決するには、 `Movable Type で出力したファイル` と `実際のファイル` を比較することになります。これを手助けしてくれるのが `mt_fileinfo` というテーブルです。

## mt_fileinfo テーブルとは
mt_fileinfo テーブルは、Movable Type をインストールした際に生成されるテーブルの一つで、Movable Type が出力したファイルの情報を管理します。以下は、その代表的なものです。()内は、mt_fileinfo テーブル内のカラム名です。

- 出力先のファイルパス（fileinfo_file_path）
- 出力先の URL からウェブサイト・ブログのサイト URL 部を除いたもの（fileinfo_url）
- ブログ ID（fileinfo_blog_id）
- テンプレート ID（fileinfo_template_id）
- エントリー ID（fileinfo_entry_id）
- カテゴリー ID（fileinfo_category_id）
- アーカイブ種別（fileinfo_archive_type）

## mt_fileinfo テーブルの情報を取得する
私の環境では phpMyAdmin とか入れていないので、mysql コマンドの出力結果を、テキストファイルに保存しています。
mysql のシェル内で、以下を実行すると、ファイルの一覧を出力できそうです。

```
SELECT fileinfo_file_path FROM mt_fileinfo;
```

ですが、これでは不十分です。理由は、mt_fileinfo テーブルには `未公開・下書き` のものもあるからです。



## 記事やウェブページの公開状態の確認
記事やウェブページの公開状態は、mt_entry テーブルの entry_status カラムの値で確認できます。entry_status の値は、以下のようになっています。

| 値 | 解説 |
| :----: | :----: |
| 1 | 未公開(原稿) |
| 2 | 公開 |
| 3 | 未公開(承認待ち) |
| 4 | 日時指定 |
| 5 | 未公開(スパム) |
| 6 | 非公開（公開終了） |

現在、公開されているものは、entry_status の値が `2` のものになります。

## インデックス・テンプレートや他のアーカイブの公開状態の確認
インデックス・テンプレートや他のアーカイブの公開状態は、mt_template テーブルの template_build_type カラムの値で確認できます。

| 値 | 解説 |
| :----: | :----: |
| 0 | 公開しない |
| 1 | スタティック(既定) |
| 2 | 手動 |
| 3 | ダイナミック |
| 4 | 公開キュー経由 |

現在、公開されているものは、template_build_type の値が `0` のものになります。

## Movable Type が出力しているファイルの一覧の取得するには
整理すると、以下のようになります。

- mt_fileinfo テーブルの fileinfo_file_path の値で、出力しているファイルの一覧ができる。
- 記事やウェブページの公開状態を反映するには、mt_fileinfo テーブル内の fileinfo_entry_id の値と mt_entry テーブルの entry_id を連携させて、 **entry_status の値が 2 のもの** のみを抽出する。
- インデックス・テンプレートや他のアーカイブの公開状態を反映するには、mt_fileinfo テーブル内の fileinfo_template_id の値と mt_template テーブルの template_id を連携させて、 **template_build_type の値が 0 以外のもの** のみを抽出する。

ここまでわかれば、あとは頑張るだけです。今回は、SQL 文で INNER JOIN や条件を指定せず、以下の SQL で出力された結果を EXCEL で VLOOKUP してマスターを作成しました。

```
SELECT fileinfo_file_path,fileinfo_blog_id,fileinfo_template_id,fileinfo_archive_type,fileinfo_entry_id FROM mt_fileinfo;
SELECT entry_id,entry_blog_id,entry_status FROM mt_entry;
SELECT template_id,template_blog_id,template_build_type FROM mt_template;
```

最後に、作成したマスターとウェブサーバーに直接アクセスして得たファイルの一覧を比較することで、欲しい結果が得られました。

## まとめ
- mt_fileinfo テーブルをはじめに幾つかのテーブルの情報を連携させると、Movable Type が出力したファイルの一覧ができる。
- ウェブサーバーに直接アクセスして得たファイルの一覧と、VLOOKUP することで Movable Type が過去に生成したファイルの一覧ができる。
- 作業を楽にするためには、プログラムが必要ですね。MT7 のリリースに間に合うように開発したいな。
GithubへPRするまで

今回はちょっとしたGitの話です。
未だにGitを積極的に使ってなかったこともあり、一人で使う場面がほとんどだったためGitの良さが分かりませんでした。最近、現場でGithubと連携し、本格的に使っているので日々勉強中です。メモ書きレベルですが、ご参考まで。

##レポジトリの命名について分かったこと

###upstream
ターゲットリモートリポジトリ。このレポジトリに対してPR(Pull Request)をしたりフォーク(Fork)したりする。

###origin
自分リモートリポジトリ。フォーク(Fork)するとターゲットリポジトリソースを持ってくる。

この命名は決まりではないが、一般的らしい。

##PR(Pull Request)したソースを取得する

git fetch upstream pull/PR番号/head:ブランチ名

```sh
git fetch upstream pull/PR番号/head:ブランチ名

//例
git fetch upstream pull/457/head:feature/hoge
```

##PRしたのがconflictになっている時はRebase

GithubのWeb上で確認できる（PRのところにびっくりマークが表示される。）

1.まず、リポジトリ状態を最新化する。
upstreamからpullし、自分のoriginへpushする。そうすることでupstream/master, origin/master, ローカルのmasterが最新化される。

```sh
git fetch --all
git pull upstream master
git push origin
```

2.作業branchになっているのか確認します。

```sh
git branch
```

3.Rebase実行

```sh
git rebase [もともとForkしたブレンチ名]

例) 作業ローカルブランチがhogeで最初Forkしたブランチが[master]の場合
git rebase master
```

4.conflictした場合はソースファイルを確認する。

```sh
git status
```
5.conflictを修正し、問題なかったら追加　***絶対commitはしない***

```sh
git add .
```

6.再びrebase実行

```sh
git rebase --continue
```

もし、分からなくなった場合や、ミスった場合はrebaseをやめたい時は、

```sh
git rebase --abort
```

7.4-6を繰り返す
完了したらApplying…のログが出力される。。。

8.完了したらorigin/workbranchに強制pushする。

例）workbranchがfeature/hogeの場合

```sh
git push -f origin feature/hoge
```

9. Githubのweb上でpull requestを確認

びっくりマークが消えたのを確認。(conflictがないこと)


##その他
最新のコミットに追加してコミットする場合、
（コメント変更でも）

```sh
git commit --amend -m "hogehoge..."
```

##補足
ケースによって色々方法があるのであんまり役に立たないかもしれません。
SourceTreeではできないことが多く、改めてコマンドになれる必要があると思った。
Jasmine-nodeでテスト実行までの手順メモ

npmのインストールからJasmine-nodeでJavaScriptのテストを実行するまでのメモ

1.npmのインストール
下記のURLよりNode.jsをダウンロード、インストールしてください
https://nodejs.org/en/

2.Jasmine-nodeのインストール

```java

npm install jasmine-node -g

```

3.テストを作成
テスト対象JS（"Hello Jasmine-node"の文字列を返すfunctionをもつJS）
![スクリーンショット 2017-12-24 8.29.44.png](https://qiita-image-store.s3.amazonaws.com/0/192949/742110e6-8006-31bf-d52f-e6376181b23f.png)

テストコード（testFunctionが存在していることと、返り値が期待値と同じであることを確認）
![スクリーンショット 2017-12-24 8.30.20.png](https://qiita-image-store.s3.amazonaws.com/0/192949/598acf0a-623c-5ed6-5486-1dbc9a38087b.png)

フォルダ階層
テストコード(test.jsの一つ下の階層として"spec"フォルダを作成し、その下にテストコードtesSpec.jsを作成)
![スクリーンショット 2017-12-24 8.30.35.png](https://qiita-image-store.s3.amazonaws.com/0/192949/ddb7810f-8abb-88a3-6bb2-2135ec5c3cad.png)

4.テスト実行
下記のコマンド実行（specフォルダ内でテストスクリプトを指定して実行する）

```
jasmine-node tesSpec.js

```
成功の場合
![スクリーンショット 2017-12-24 8.38.19.png](https://qiita-image-store.s3.amazonaws.com/0/192949/16aeb058-8322-cbcd-9600-cee299e7c337.png)

失敗の場合
![スクリーンショット 2017-12-24 8.40.42.png](https://qiita-image-store.s3.amazonaws.com/0/192949/e4189418-ec27-6ca4-2c59-efc66f478af0.png)


メモ
成功時についてはどのテストケースが成功したかのメッセージがないため、
Jasmine-runner等で出力を改善した方が良いと思います

環境
OS : Mac
エディタ：Visual Studio Code
子供と一緒にPCNこどもプロコン

##応募した作品
- 作品名：「Step On(音) the piano」
- 結果　：[最優秀賞（小学生の部）](http://pcn.club/contest/contest07.html)
- 動画　：[YouTube](https://youtu.be/cKk1jiC8lkk)

作品の細かい紹介は先にYouTube動画を見てもらうと助かります。

##やろうと思ったきっかけ
- 子どもがIchigoJamを触ったことがあった
- 私がIchigoJamを地域の子供たちに教えたことがあった
- IchigoJamのコンテストがあるらしいことは知ってた

IchigoJamで工作して、PCNコンテストまで出すようになったのは、いろいろな背景がありましたが、割と決定的だったのが、子供が先生から言われた以下の言葉。
**「夏休みの工作は是非お父さんと一緒にやったらいいです」**

- 親が手伝っていいの？
- って言うか何作るの？
- ってかそのリクエスト。微妙に大人としてプレッシャーを感じるのだが。。。

最初、聞いた時は結構戸惑いました。いろいろな思いが頭をめぐり、どうしたらいいものかと葛藤の日々。ただ、いま思うとこの言葉がなかったら一緒にやってなかったと思います。

##テーマ決め
複雑な心境ながら「やる」と決めて、テーマを考えます。何しようかなぁと思いながら、自分の工作じゃないし、自分が決めても違うしなって思ったり、子どもに「何作りたい？」って色々聞いてみたり。そして、急に何作りたいって言われても？？？な顔してるし。そうこうしながら、時間が数日過ぎたのですが、ある日、子どもが学校から自分が書いた絵を持ってきて、そのテーマが「将来こんなものがあったらいいな」。**これだ！**って内心でガッツポーズしてました。親が勝手に決めるんじゃなくて、子どもが欲しいと思ったものをそっと手伝ってあげる。そういった訳で、足で踏むピアノの工作が始まりました。「想い」を持って作る、ものづくりの第一歩は子どもが自分で答えを持ってきてくれました。
ちなみに、後で知ったのですが、子どもが書いてきた絵は発明協会がやっている[未来の科学の夢絵画展](http://koueki.jiii.or.jp/hyosho/kaiga/kaiga_yoko.html)のコンクール用だったみたいです。

##一緒に作りながら
まだまだ小学生なので、全部を一人で考えることは出来ないですが、**「お父さんと一緒にやったらいい」**という先生の言葉を信じて？、一緒にやることにしました。ただ、この時の注意点も、決して大人の工作にならないこと！どうやって作ろうかって話をしながら、ダンボールを切ったり、アルミテープが電気を通すことを実験してたり、必要な材料を100円ショップに買いに行ったり、IchigoJamを触ったり。とにかく、子ども主体で失敗してもいいからやってみることを大切にしました。まぁ、この時点で、作るもののアイデアは子どもが考えてたので、工作(実装)は何とでもなると思ってたので、自由にさせてました。ワイヤーストリッパーで導線の被膜はがしたり、グルーガンで止めたり、ブレッドボードに導線を刺してみたり、色々させてみましたが、楽しそうにやってたと思います。子どもの工作なので、紙・のり・ハサミなどベーシックな道具を大切にやりました。そうこうしながら、作品完成。

##PCNこどもプロコンへの応募
これは大人から仕掛けてますね。「ねぇねぇ、こんなコンテストあるみたいよ」って子どもに話して、その時点で工作の出来に十分満足しているので、もちろん乗り気です！そして、最近友達とYouTuberごっこしながら、将来YouTuberになりたいとか言ってるので、動画作成も一緒にやることにします。将来の夢「YouTuber」を頭ごなしに否定するつもりはないですが、本当になりたいなら今すぐやれ！って優しい？愛情を持ってして、動画も作って、PCNこどもプロコンに応募しました。

##先生から宿題
先生のいう通りに一緒にやったし、子どもの「作りたい想い」も大切にできた良い作品だなぁって思いながら、夏休みの宿題に提出。PCNこどもプロコンもあるけど、「想い」を形にして、やりたいことをやれる！って経験をさせれたので、良かったなぁってボーッとしてました。しばらくしたら、先生から夏休みの工作の県の発明くふう展に出したいって言われて、「まぁ、どうぞどうぞ」と思ってました。その時、すでに達成感があったので。ただ、子どもが持って帰ってきたプリントにまさかのリクエスト。**「音がもう少し大きいといいですね by 先生」**。
これは、自分も分かってました。IchigoJam単体の限界ですよね。そして、敢えてやらなかったんです。トランジスタを使って、回路組んで、半田ごて使って、明らかに大人の工作になるので止めてました。ただ、先生のリクエストもあるので、ほっとくわけにもいかず、ただ子どもの工作だしなぁって葛藤もあって。そこで思いついたのが、100円ショップ作戦。最近は売ってないですが、昔買った100円アンプが手元にあったので、あとはスピーカーを100円ショップに子どもと一緒に買いに行き、基本的な原理と音が大きくなることを子どもと確認して、最終的に分解して使うことに。これならなんとか大人の工作にならない範囲で収まったような。それにしても、提出した夏休みの工作に追試みたいなリクエストがあるとは。県のコンクールに出すので、先生が事前アドバイスを他の作品にもしているそうですが、なかなかびっくりしました。

## 感想
大人がどこまで関わっていいのか？を考えながら、試行錯誤しながらやりましたが、結果としては子どもにとって良かったのかと思います。結果もそうですが、やったことに対して自信もつくし、いろんな大人と直接話しすることもいい経験になったと思います。
あとは、やりたいことはできる！作りたいものは作れる！って体験を子どもが出来たことが１番良かったと思っています。子どものアイデアって本当に面白いのですが、道具やツールが使いこなせなくて上手くいかないと、アイデア自体を使える道具やツールで制限を掛けるようになっていくと思います、自然と。なので、そこはある程度知っている人（大人とか）がフォローしてあげれば、更にアイデアが加速して拡がっていく、そういった循環ができると、流れに流されるのではなくて、自分の意思をしっかり持てるようになるのかと。

##おまけ
この前、[NT加賀](http://kaga-iotac.org/ntkaga2017/)に子どもの作品と自分が作っている作品を展示しに行きましたが、圧倒的に子どもの作品が人気でしたね。インパクト強すぎ。子どもの作品で人が集まってきて、ついでに[自分の作ったもの](https://youtu.be/2Db_57aJLpY)を見てもらうという構図。知り合いに「子どもの作品の方が、人気です」って言ったら、「当たり前でしょ！」って言われました。子どもの作品見ながら、まだまだ自分が勉強することが多いなって思いました。大人もまだまだ頑張らないと。
bash > x!2594 > historyからコマンド履歴を取得する (一部を変更して実行するため)

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04 LTS desktop amd64
TensorFlow v1.2.1
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
scipy v0.19.1
geopandas v0.3.0
MATLAB R2017b (Home Edition)
ADDA v.1.3b6
```

### 概要

```bash
$history
...
...
 2594  ../adda -orient avg CODE_171216_Euler/avg_params_beta_4_6_gamme_3_5.dat -shape chebyshev 0.7 12 -size 10
 2595  ../adda -orient avg CODE_171216_Euler/avg_params_beta_4_6_gamma_4_6.dat -shape chebyshev 0.7 12 -size 10
...
```

上記のようなコマンド履歴があるとする。
2594で実行したコマンドを別ファイルで実行したい。

### 手順

- `x!2594`を実行
    - ここでは実行されない (失敗する)
- カーソル上キー入力
    - 2594のコマンドになる
    - ただし最初に「x」が付いているので取り除いて使う
        - Ctrl+Aで行頭に移動、を使って取り除く
    - あとは変更したい部分を変更して使う

「ｘ」の部分は「#」と「!」以外の文字列であれば有効だと思われる。

```bash
$ x!2594
x../adda -orient avg CODE_171216_Euler/avg_params_beta_4_6_gamme_3_5.dat -shape chebyshev 0.7 12 -size 10
-bash: x../adda: そのようなファイルやディレクトリはありません
```

マウスでコマンド履歴をcopy, pasteするよりは早い。
[tvOS] テレビのリモコンのことも忘れないで！


## AppleTVで使えるリモコンって？

### Siriリモート

<img src="https://qiita-image-store.s3.amazonaws.com/0/7883/330f9bdc-86fe-97b5-2dca-a2259c525739.jpeg" height=200>

tvOS/AppleTVのリモコンといえばSiriリモートですよね。
皆様におかれましても日々のAppleTV生活ではSiriリモートを使われているかと思います。

### テレビのリモコン

<img src="https://qiita-image-store.s3.amazonaws.com/0/7883/dfe71005-eb5e-bc17-b112-1e0ffdd150ad.jpeg" height=200>


そしてもちろん普通のテレビのリモコンもAppleTVの操作に使えます！

AppleTVを利用しているということは当然テレビを利用しているわけで、AppleTVを使っている人のほとんどがテレビのリモコンを所持している、かつ普段使いしていることでしょう（AppleTVの操作をするかどうかは置いておいて）。
そのため、AppleTVの操作という意味ではSiriリモートに次いで利用するチャンスが多くなるリモコンかと思います。

### ゲームコントローラ/ゲームパッド

Nimbusなどのゲームコントローラも利用できますが、今回の主役は普通のテレビのリモコンのため、省略させていただきます。

## テレビのリモコンでどこまで操作できる？

### Apple純正のアプリ

全て確認したわけではないですが、ホーム画面はもちろん、純正アプリならテレビのリモコンだけでも一通りの操作ができるようになっているようです。

### サードパーティのアプリ

ゲームアプリ以外なら操作できることが多いようです。
ただしTouchサーフェス前提で組まれているアプリは操作不能です。

### 自分が開発するアプリはどうすべき？

タイトルには「忘れないで！」と書いたものの、実際のところそんなに気にしなくても良いのでは。
また、UIKitをシンプルに使って作ったアプリなら何も処置しなくてもテレビのリモコンで操作できるようになっています（後述します）。

## テレビのリモコンのボタンに対応するUIPressType

うちのテレビ（REGZA）のリモコンではこんな感じになっていました。他のテレビのリモコンも概ね同じじゃないかと思います。

|REGZAのリモコン|UIPressType|
|---|---|
|決定|.select|
|戻る|.menu|
|再生|.playPause|
|停止|-|
|上|.upArrow|
|下|.downArrow |
|左|.leftArrow |
|右|.rightArrow |

## UIKitの各コントロールの挙動

### フォーカス移動

テレビのリモコンの上下左右キーが有効ですので、上下左右を押すことで普通にフォーカスが移動可能です。そのためシンプルにフォーカスが当たるコントロール（UIButtonなど）が配置されただけの画面なら何もしなくても操作可能になっています。

### UITableView/UICollectionView

UITableViewやUICollectionViewを使った画面もテレビのリモコンで操作可能です。
デフォルトで各Cellにフォーカスが当たるので、Cellのフォーカスを移動していくと自動的にスクロールしていく挙動になります。

### UIPageViewController

これは意外だったのですが、UIPageViewControllerもデフォルトでテレビのリモコンでの操作が可能でした。

ただし条件があり、transitionStyleプロパティに`UIPageViewControllerTransitionStyle.scroll`を設定している場合のみ操作可能です。`.pageCurl`だと（デフォルトでは）操作不能でした。

`.scroll`の場合には、`navigationOrientation`プロパティが`.horizontal`なら左右ボタンで、`.vertical`なら上下ボタンでそれぞれページ移動が可能です。

### UIScrollView

UIScrollViewも特に意識しないでも操作可能になっています。

上下左右で直接スクロール可能というわけではなく、UIScrollView上に配置された要素を上下左右ボタンでフォーカス移動することで、結果としてスクロールされるという挙動になります（フォーカスが当たった要素が画面内に収まるように）。

### UITextView

UITextViewはデフォルトでは上下左右ボタンでの操作ができませんでした。

## テレビのリモコンで操作できない画面をなんとかする

一例ですが、UIPanGestureRecognizerを使って独自のページ移動をさせるような実装をした画面でもテレビのリモコンで操作させたい場合には、`UITapGestureRecognizer`を使って対処するのが簡単そうです。

```swift
let leftTap = UITapGestureRecognizer(target: self, action: #selector(self.leftArrowDidPress(sender:)))
leftTap.allowedPressTypes = [NSNumber(value: UIPressType.leftArrow.rawValue)]
view.addGestureRecognizer(leftTap)

let rightTap = UITapGestureRecognizer(target: self, action: #selector(self.rightArrowDidPress(sender:)))
rightTap.allowedPressTypes = [NSNumber(value: UIPressType.rightArrow.rawValue)]
view.addGestureRecognizer(rightTap)

// func leftArrowDidPress(sender:) と func rightArrowDidPress(sender:) にそれぞれ左右への移動のための実装をする
```

単にUIGestureRecognizerの`allowedPressTypes`プロパティでハンドリングしたいUIPressTypeを指定してそれに応じたコードを書くだけです！

※ブログ用にコードで例示しましたが、普段UITapGestureRegognizerの追加はInterface Builderでやってます

## まとめ

- シンプルに作ればtvOSアプリはテレビのリモコンで操作できるようになっている
- 利用できるボタンは決定、戻る、再生、上下左右
- 凝った実装でデフォルトではテレビのリモコンで操作できない場合でも、各ボタンに対応したUIPressTypeをハンドリングしてあげれば対応可能
VirtualBox Ver5.2.4 CentOS7 NAT＋HostOnly接続するためのネットワーク設定

#ホストOS側の設定
##Host Network Mangaeの起動
1. VitualBoxを起動します。
2. GlobaltoolsのHost Network Mangaerをクリックします。
![スクリーンショット 2017-12-23 22.42.25.png](https://qiita-image-store.s3.amazonaws.com/0/225872/e8ceb69e-6fc5-8d1f-237b-80a2eda22cc3.png)

## ネットワークアダプターの追加
1.Host Network Managerが表示されます。
2.作成をクリックします。
3.ネットワークアダブターが追加されます。
4.Host Network Managerを閉じます。
![スクリーンショット 2017-12-23 22.45.15.png](https://qiita-image-store.s3.amazonaws.com/0/225872/9aa973d9-71d8-a815-58b4-87d1f341da41.png)

##設定画面の起動
設定をクリックします。
![スクリーンショット 2017-12-23 22.46.58.png](https://qiita-image-store.s3.amazonaws.com/0/225872/46da06ec-d90a-ceea-35f9-e23062f04aac.png)

## ホストオンリーアダプターの作成
設定画面が表示されます。
1.ネットワークをクリックしてください。
2.アダプター2をクリックしてください。
3.ネットワークアダプターを有効化をチェックしてください。
4.割り当てにホストオンリーアダプターを選択してください。
5.名前に先ほど追加したネットワークアダブターを選択してください。
![スクリーンショット 2017-12-23 22.48.24.png](https://qiita-image-store.s3.amazonaws.com/0/225872/25dd50d8-dbd8-c05e-4b99-38b0fc5ef062.png)


#ゲストマシンのネットワーク設定
##NetworkManageの起動
1.端末を起動します。
2.ルートユーザーで、nmtuiを入力し、Enterキーを押します。
![スクリーンショット 2017-12-24 6.18.11.png](https://qiita-image-store.s3.amazonaws.com/0/225872/3af57105-eb5a-8e02-ea6d-312bbf5ce7af.png)


##IPアドレス設定
1.接続の編集を選択し、Enterキーを押します。
![スクリーンショット 2017-12-24 6.20.19.png](https://qiita-image-store.s3.amazonaws.com/0/225872/1db12f3e-1375-7b73-7a78-c332249c920c.png)

2.ホストオンリーアダプターの作成で作成したネットワークアダプターを選択し、Enterキーを押します。
![スクリーンショット 2017-12-24 6.22.58.png](https://qiita-image-store.s3.amazonaws.com/0/225872/8d5a5508-e16e-cd2d-0594-e79efd439279.png)

3.アドレスに、192.168.56.101/24と入力します。
4.このネットワーク・・・、自動的に・・・、この接続には・・・をチェックします。
![スクリーンショット 2017-12-24 6.25.37.png](https://qiita-image-store.s3.amazonaws.com/0/225872/5d0f63af-6dbe-6ebb-912a-e3693b3cdd34.png)

5.IPv6設定で、無視するを選択します。
6.自動的に・・・、全ユーザーに・・・をチェックします。
7.OKを選択し、Enterキーを押します。
![スクリーンショット 2017-12-24 6.25.56.png](https://qiita-image-store.s3.amazonaws.com/0/225872/8bb7ef0e-cdcd-d62e-3f02-21b523973001.png)

##ネットワークの再起動
以下のコマンドを入力し、Enterキーを押します。
![スクリーンショット 2017-12-24 6.30.13.png](https://qiita-image-store.s3.amazonaws.com/0/225872/e557ad72-841f-0443-e969-ec3a8318a79f.png)

##ホストOS側からの接続
1.ターミナルを起動します。
2.ssh userId@192.168.56.101を入力し、Enterキーを押します。
3.パスワードを入力します。
Agdaで挿入ソートの正当性を証明する

# 証明したこと
挿入ソートによってソートされることと挿入ソートによって要素が変わらないことを証明しました．

# ソースコード
ソースコードは[リポジトリ](https://github.com/karrym/AgdaSort)にあります．
agda-stdlibのバージョンが0.14以前では`≤-total`がなくて動かないので注意してください．

# 挿入ソートの定義
以下によって挿入ソートを定義しました．

```agda
insert : ℕ → List ℕ → List ℕ
insert x [] = x ∷ []
insert x (y ∷ ys) with x ≤? y
... | yes _ = x ∷ y ∷ ys
... | no _  = y ∷ insert x ys

isort : List ℕ → List ℕ
isort [] = []
isort (x ∷ xs) = insert x (isort xs)
```

`x ≤? y`の型は`Dec (x ≤ y)`でコンストラクタは`yes : x ≤ y → Dec (x ≤ y)`と`no : ¬ (x ≤ y) → Dec (x ≤ y)`なのでパターンマッチすると証明つきで真偽がわかるようになってます．
`insert`の定義では証明を捨ててますが，正当性の証明では必要になります．

# 正当性の定義
正当性を証明するにあたってソート済みであることと要素が同じであることを定義する必要があります．
定義はCoqからパクってきました．

```agda
data Sorted : List ℕ → Set where
    snull : Sorted []
    scons1 : {x : ℕ} → Sorted (x ∷ [])
    scons : {x y : ℕ} {ys : List ℕ} → x ≤ y → Sorted (y ∷ ys) → Sorted (x ∷ y ∷ ys)

data Permutation {A} : List A → List A → Set where
    pnull : Permutation [] []
    pskip : {x : A} {xs ys : List A} → Permutation xs ys → Permutation (x ∷ xs) (x ∷ ys)
    pswap : {x y : A} {xs : List A} → Permutation (x ∷ y ∷ xs) (y ∷ x ∷ xs)
    ptrans : {xs ys zs : List A} → Permutation xs ys → Permutation ys zs → Permutation xs zs
```

`Sorted`の定義における`_≤_`は一般の述語`A → A → Set`に置き換えても問題ないですが，今回は`ℕ`の通常の順序しか扱わないので`_≤_`に限定しました．

# 証明
証明は`Sorted`と`Permutation`の`insert`に関する補題を示して，そこから目的の命題を証明するという風に行ないました．
補題の証明はいい感じになるまで帰納法を適用すればいけます．
補題の証明ができれば本題は楽に示せます．

```agda
step-insert : {x y : ℕ}{ys : List ℕ} → ¬ (x ≤ y) → insert x (y ∷ ys) ≡ y ∷ insert x ys
step-insert {x} {y} {ys} x≰y with x ≤? y
... | yes x≤y = ⊥-elim (x≰y x≤y)
... | no x≰y₁ = refl

lem-isorted : (x : ℕ) → (xs : List ℕ) → Sorted xs → Sorted (insert x xs)
lem-isorted x [] s = scons1
lem-isorted x (y ∷ ys) s with x ≤? y
... | yes x≤y = scons x≤y s
lem-isorted x (y ∷ []) scons1 | no x≰y = scons (lem-≤ x≰y) scons1
lem-isorted x (y ∷ (z ∷ zs)) (scons y≤z s) | no x≰y with x ≤? z
...     | yes x≤z = scons (lem-≤ x≰y) (scons x≤z s)
...     | no x≰z  = scons y≤z (subst Sorted (step-insert x≰z) (lem-isorted x (z ∷ zs) s))

iSorted : (xs : List ℕ) → Sorted (isort xs)
iSorted [] = snull
iSorted (x ∷ xs) = lem-isorted x (isort xs) (iSorted xs)

lem-iperm : (x : ℕ) (xs : List ℕ) → Permutation (x ∷ xs) (insert x xs)
lem-iperm x [] = pskip pnull
lem-iperm x (y ∷ []) with x ≤? y
... | yes x≤y = pskip (pskip pnull)
... | no x≰y  = pswap
lem-iperm x (y ∷ z ∷ zs) with x ≤? y
... | yes x≤y = ptrans pswap pswap
... | no x≰y with x ≤? z
...     | yes x≤z = pswap
...     | no x≰z  = ptrans pswap (pskip (subst (Permutation (x ∷ z ∷ zs)) (step-insert x≰z) (lem-iperm x (z ∷ zs))))

perm-isort : (xs : List ℕ) → Permutation xs (isort xs)
perm-isort [] = pnull
perm-isort (x ∷ xs) = ptrans (pskip (perm-isort xs)) (lem-iperm x (isort xs))
```

# 感想
Agdaの型システムが結構バカなので計算を進められるのに進めてくれない場面があって，そういった場面は`subst`を使って明示的に変形しなければいけないのが面倒．
あと`with`でパターンマッチするときに対象の型がimportされていないとエラーになるが，エラーコードが`yes _`の左辺がパースできないとかでシンタックスエラーなのかと1時間ほど唸ってしまった．
時間とやる気があればマージソートやクイックソートなどの他のアルゴリズムでも同様のことを証明したり，安定ソートであることを示したりなどしたい．

# 参考文献
+ [証明駆動開発入門 (1)](http://www.iij-ii.co.jp/lab/techdoc/coqt/coqt8.html)
+ [agda-stdlib](https://github.com/agda/agda-stdlib)
Lisp(Scheme)超絶入門備忘録2

#はじめに
　
[前回](https://qiita.com/Wt0909/items/bce1e5a0351e3e48e9e7)に引き続き、scheme入門(備忘録)です。
相変わらずLisp経験者は読むだけ無駄です、早速やっていきます。



#シンボル
　
シンボルとは？
文字列をロケーションで管理するデータ型とのこと。 
シンボル同士を比較するときは、eq?などでロケーションを比較が使用可能で、高速に比較処理ができるとか・・・

端的に言うとバリューじゃなくてロケーションだけ見るよ！ってことかな。
詳しくは改めて学習しようと思います。。。。


#リスト
　
ようやくリスト、一旦触ってみます。
　
リストの構成要素であるペア(コンスセル)については後述、なにはともあれ簡単に動かしてみます。
リストの定義は、値を並べて括弧で囲って書きます。python等の言語とは異なり、カンマで区切る必要はないです。
しかし(3 4)のような形式だと3が手続きと認識されてエラーとなります。　

インタプリタからしたら(print 1)　これと同じ扱い。　3 なんて手続きねーよってこと。

よってシンボル、またはlist関数、make-list関数を使う必要があります。
加えて簡単なリスト操作系の関数も使用してみました。

```Lisp

  (print '(1 2 3)          ; (1 2 3)

  (print (list 1 2 3))     ; (1 2 3)

  (print (make-list 3 1))  ; (1 1 1)

 
  (define x (list 2 4 3 1 5))
  (define y (list 6 7 8 9 0))
  
  ;　listかどうか
  (print (list? x))        ; #t
  
  ;　listの長さ
  (print (length x))       ; 5

  ;指定位置要素の抽出
  (print (list-ref x 3))   ; 1
  
  ;　反転
  (print (reverse x))      ;(5 1 3 4 2)

  ;listの連結
  (print (append x y))     ; (2 4 3 1 5 6 7 8 9 0)

  
```
　
　


シンボルでのリスト定義をした場合に　x がバリューではなくシンボルとして格納されてしまうので注意が必要です。


```Lisp

(define x 4)

(print(list 1 2 3 x)) ;(1 2 3 4)

(print'(1 2 3 x))     ;(1 2 3 x)

```
　

#コンスセル
　
では改めて、ペア(コンスセル)についてちょっと確認していきます。

'(1 2 3 4 5)について

1,2,3,4,5と一見それぞれのバリューがキーに格納される様なイメージが持てますが、
その脳みそは捨ててください。
リストは全てペア(carとcdr)の集まりから構成されいる、といった感じです。
　

左側をcar（カー）、右側をcdr（クダー）、この纏りをペア（コンスセル）と呼びます。
いや、どこまでがcar？cdr？ペア？ってなりますよね・・・・




説明が下手くそなのでさっさと動かして確認していきましょ。

```Lisp

(define x '(1 2 3 4 5))

(print (car x)) ; 1

(print (cdr x)) ; (2 3 4 5)
```



xのcar、cdrの出力結果は上記です。

carはペア(x)の最初の要素
cdrはリストの残りの部分となります。
carとcdrを箱と捉え、その2つの箱の組み合わせがペア

こんな感じですかね！！

次にxから 2 を出力してみます。
前述の通りxのcdrが (2 3 4 5) ということは
このcdrはリスト、ペアとなるから、そのcarが 2 になるはずだ！！
ついでにそのcdrが(3 4 5) のはずだ！！
　
　

```Lisp

(define x '(1 2 3 4 5))

(print (car(cdr x))) ; 2

(print (cdr(cdr x))) ; (3 4 5)


```

はい、おk。
なるほど、こんな感じでコンスセルの構成が理解できました、やったぜ。
　
　

もちろんリストのペアには終点があります。
そしてcarとcdrは常に1対1でペアとして存在する為、　x　のcarが5になるとき、cdrとなる要素は空リストとなります。
再帰的な処理とかに便利な構成ですね。

```Lisp

(define x '(1 2 3 4 5))

(print (cdr x))                     ;(2 3 4 5)

(print (cdr(cdr x)))                ;(3 4 5)

(print (cdr(cdr(cdr x))))           ;(4 5)

(print (cdr(cdr(cdr(cdr x)))))      ;(5)

(print (cdr(cdr(cdr(cdr(cdr x)))))) ;()

```

続いてcons関数でリストにペアを追加してみます。

```Lisp

(define x '(1 2 3 4 5))

(define y (cons 7 x))

(print y)       ;(7 1 2 3 4 5)

(print (car y)) ; 7

```

#まとめ
今回はリストの構造やら何やらをメインに学習してみました。
二分木構造ってやつですかね。ちょっとこれを活かして何かしら書いてみたいと思います。
そして次回こそlambdaやらmapやら・・・ごめんなさい。
放物線を描いて目標地点まで剛体を飛ばす


コーナーキックのスクリプトを実装

こちらのコードをベースに実装
https://forum.unity.com/threads/throw-an-object-along-a-parabola.158855/#post-1087673

```csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CornerKick : MonoBehaviour {

	[SerializeField] Transform m_Target; // 目標地点
	[SerializeField] Transform m_KickerTransform; // コーナーキックの位置
	[SerializeField] GameObject m_ProjectilePrefab; // ボールのプレファブ
	public float gravity = 9.8f;
	public float firingAngle = 45.0f;

	void Awake() {
		m_KickerTransform = transform;
	}

	void Update () {
        if(Input.GetKeyDown(KeyCode.R)) {
            RightShoot();
        }
        if(Input.GetKeyDown(KeyCode.L)) {
            LeftShoot();
        }
	}

	void RightShoot() {
		m_KickerTransform.position = new Vector3(17f, 0, 32f);
		StartCoroutine ("Shoot");
	}
	void LeftShoot() {
		m_KickerTransform.position = new Vector3(-17f, 0, 32f);
		StartCoroutine ("Shoot");
	}

	IEnumerator Shoot() {
		Transform m_ProjectileTransform = Instantiate (
			m_ProjectilePrefab,
			m_KickerTransform.position + new Vector3 (0f,0f,0f),
			Quaternion.identity
		).transform;

		float target_distance = Vector3.Distance (m_ProjectileTransform.position, m_Target.position);
		float projectile_velocity = target_distance / (Mathf.Sin(2 * firingAngle * Mathf.Deg2Rad) / gravity);

		float vx = Mathf.Sqrt (projectile_velocity) * Mathf.Cos (firingAngle * Mathf.Deg2Rad);
		float vy = Mathf.Sqrt (projectile_velocity) * Mathf.Sin (firingAngle * Mathf.Deg2Rad);

		float flight_duration = target_distance / vx;

		m_ProjectileTransform.rotation = Quaternion.LookRotation (m_Target.position - m_ProjectileTransform.position);

		float elapsed_time = 0;

		while(elapsed_time < flight_duration){
			m_ProjectileTransform.Translate (
				0f,
				(vy - (gravity * elapsed_time)) * Time.deltaTime,
				vx * Time.deltaTime
			);
			elapsed_time += Time.deltaTime;
			yield return null;
		}
        
        // 到達した後の処理はこの下に
	}
}
```
【PUN】ログイン


Photon Unity Networkの基本機能メモ

[【PUN】ログイン](https://qiita.com/mo4_9/items/4aba4601feb3e6440826)
[【PUN】アバター生成・同期](https://qiita.com/mo4_9/items/75324cc31709ec329d26)
[【PUN】ゲーム終了判定](https://qiita.com/mo4_9/items/87b969da060c975736cf)

---

公式
https://www.photonengine.com/ja-JP/Photon

基本説明
http://doc-api.photonengine.com/ja-jp/pun/current/general.html

Class List
https://doc-api.photonengine.com/ja-jp/pun/current/annotated.html


[201 1 PhotonEngineとは](https://github.com/yumemi-inc/vr-studies/wiki/201-1-PhotonEngine%E3%81%A8%E3%81%AF)
こちらの資料をベースに進める


[【Unity】僕もPhotonを使いたい - うら干物書き](http://www.urablog.xyz/archive/category/PUN)
こちらのシリーズも勉強になる

---

## ログイン

- ロビーに接続
- ロビーに入室
- ルームを作成
- ルームに入室

`Alt + P`で[PUN Wizard]を表示
[Locate PhotonServerSettings]から
[Auto-Join Lobby]にチェックを入れてロビーまで自動で入室

以下スクリプトを、シーン中の任意のゲームオブジェクトにアタッチする

```csharp:PhotonLogin.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PhotonLogin : MonoBehaviour {

	private const string ROOM_NAME = "VR-Room";
	private const string GAME_VERSION = "v1.0";

	void Start () {
		Debug.Log ("PhotonManager: ロビーに接続");
		PhotonNetwork.ConnectUsingSettings (GAME_VERSION);
	}

	void OnJoinedLobby() {
		Debug.Log ("PhotonManager: ロビーに入室成功");
		RoomOptions roomOptions = new RoomOptions () {
			MaxPlayers = 20,
			IsOpen = true,
			IsVisible = true,
		};
		PhotonNetwork.JoinOrCreateRoom (ROOM_NAME, roomOptions, null);
	}
	
	void OnJoinedRoom() {
		Room room = PhotonNetwork.room;
		PhotonPlayer player = PhotonNetwork.player;
		Debug.Log ("PhotonManager: ルーム入室成功　部屋名:" + room.Name + ", プレイヤーID:" + player.ID);
		Debug.Log ("PhotonManager: 部屋情報:" + room + ", ルームマスター？:" + player.IsMasterClient);
	}

	void OnPhotonJoinRoomFailed() {
		Debug.Log("PhotonManager: ルーム入室失敗");
	}

	void OnPhotonCreateRoomFailed() {
		Debug.Log("PhotonManager: ルーム作成失敗");
	}
}
```

## 詳細情報を表示

PhotonNetwork.connectionStateDetailed

以下スクリプトを、シーン中の任意のゲームオブジェクトにアタッチする

```csharp:PhotonStatus.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PhotonStatus : MonoBehaviour {

	void OnGUI() {
		string status = "Photon: " + PhotonNetwork.connectionStateDetailed.ToString() + "\n";
		if(PhotonNetwork.inRoom){
			status += "---------------------------------------------------";
			status += "Room Name: " + PhotonNetwork.room.Name + "\n";
			status += "Player Num: " + PhotonNetwork.room.PlayerCount + "\n";
			status += "---------------------------------------------------";
			status += "Player Id: " + PhotonNetwork.player.ID + "\n";
			status += "IsMasterClient: " + PhotonNetwork.isMasterClient + "\n";
		}
		GUI.TextField (new Rect (10, 10, 220, 120), status);
	}

}
```
Railsチュートリアルで「No application seems to be running here!」が表示された時の対処法

Railsチュートリアル(Ver5.1)第一章のメモです。

#現象

第一章でRailsサーバ起動時以下のコマンドを打つように記述されていますが、なぜかRails5.1の版から説明が不足しており、Cloud9でそのまま打ち込むとローカルサーバーが立ち上がらないため、対処法を記載しておきます。
Rails初心者の人はここで躓くかもしれません。

```sh
$ rails server
```

上記コマンドをそのまま打ち込んでブラウザを表示すると、以下のエラーが表示されRailsの起動が確認できません。
`No application seems to be running here!`

#対策
**Cloud9の場合、外からサーバーにアクセスするためにIPアドレスとポート番号を指定する必要があります。**
具体的には、サーバー起動時のコマンドを以下のように変更してください。

```sh
$ rails server -b $IP -p $PORT
```

-bでIPアドレスを、-pでポート番号を指定しています。
これで再度ブラウザにアクセスすると正しく表示されるはずです。

#補足
Railsチュートリアルの5.0まではチュートリアル上に上記の内容が記載されていたのですが、5.1の版から説明が無くなっているようです。
最初は戸惑うかもしれませんね。

Good Luck!
homebrewからインストールできるemacsの違い

# はじめに
いつもはCotEditorとかIDE使ってるんですが、ターミナル上で少しだけ編集する場合はemacsかvimがいい。
でも、MacOS付属のemacsのバージョンは22.1.1で古すぎる！
ということで、homebrewでemacsをインストールしようとしたのですが、インストールできるemacsがいくつかあり、調べてもあまり情報が得られなくて困りました。
そこで、それぞれインストールしてみてわかった違いを紹介。
（細かい違いはわかりません。）

2019/01/03 *TL;DRの追加とcaskに関する部分を修正*
2022/03/26 *cask版emacsのインストールコマンドを修正*

# TL;DR

```sh
# インストール方法と違い
brew install emacs              # ターミナルで使える普通のemacs
brew install emacs --with-cocoa # OSXウィンドウで開けるemacs
brew install --cask emacs         # OSXウィンドウで開ける、Launchpadにアイコンが追加される(/Applicationに追加されているので)
```

# いろいろなemacs
## 普通のemacs

```sh
brew install emacs
```
でインストールする普通のemacs。
この記事の更新時点でのバージョンは26.1。
ターミナルから`emacs`と打てばおなじみのemacsが起動します。
ターミナルでしかemacsを使わない方は他のemacsは不要。

## cocoa emacs
まずは、`brew info emacs`でemacsの情報を見ると、

```
--with-cocoa
	Build a Cocoa version of emacs
```
というインストールオプションが表示されます。
このオプションを使って、

```sh
brew install emacs --with-cocoa
```
でインストールすると、cocoa版emacsがインストールされます。
ターミナルから`emacs`で起動させると、以下のように別ウィンドウでemacsが開きます。

<img width="925" alt="スクリーンショット 2017-12-24 3.16.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/106956/67227613-61e6-ccf8-1774-83f6fd68b987.png">

Cocoaとは、macOS用のアプリケーションを構築するためのフレームワークであり、それを使って作られているcocoa版emacsはのmacOSのウィンドウ環境でも動作します。
ターミナル上のemacsでは、マウスで入力カーソルを動かすことはできないけれど、これだと可能。
ウィンドウ上部のアイコンからファイルを開いたり、保存したりすることが可能。

このように別ウィンドウで起動できるのが強みですが、`-nw`オプションを使えば、普通のemacsと同じようにターミナル上で起動することもできます。

## cask emacs

```sh
brew install --cask emacs
```
でインストールできるcask[^1][^2]版emacs。
caskとは、Google ChromeやAtomなど、今までインストーラを公式ページからダウンロードしてきてインストールしていたようなアプリケーションを、ターミナル上からインストールできるようになる、homebrewの拡張です。
したがって、cask版emacsとは、インストーラを使ってインストールされるものと同一のものです。

このcask版emacsは、cocoa emacsと同様に、ターミナルで`emacs`と打ったときには別ウィンドウでemacsが開きます。
そして、cask版の大きな違いはLaunchpadの一覧にemacsのアイコンが追加されること。
ターミナルからでなくても実行できるので、emacsを普段使いのテキストエディタにしたい場合にはcask版emacsをインストールしましょう。

# おわりに
macでインストールできるemacsはいろいろあります。
それぞれの目的に合わせてインストールすればいいと思います。
ちなみに私はターミナルでしかemacsを使わないので、普通のemacsを使っています。

[^1]: 以前はcaskを使うときに`brew tap caskroom/cask`でcaskをインストールする必要がありましたが、現在はcask自体がbrewに同梱されているので、特にtapする必要はありません。
[^2]: 以前は`brew cask install`でcaskのパッケージをインストールしていましたが、現在はcaskコマンドが廃止され、`brew install --cask`でインストールするようになりました。
middleman-iepab 公開しました

# middleman-iepab 公開しました

この記事は，下記の記事の転載です。

* [middleman-iepab 公開しました。(実験室 〜 Lab in ZACKY's Laboratory)](https://zacky1972.github.io/tech/2017/12/24/middleman-iepab.html)

middleman v4 では external pipeline を呼び出すのがビルドより前にしかできないのですが，たまにビルドより後に呼び出したい時があります。

たとえば，asset_hash 相当の処理を rev と rev-replace を実行する gulp タスクの external pipeline で行いたい場合，rev-replace による \*.html の書き換えはビルドより後でしか行えないので，既存の external pipeline ではうまく実現できませんでした。

そこで，middleman-iepab (invoke external pipeline after build) を開発しました。

* [rubygems の公開ページ](https://rubygems.org/gems/middleman-iepab)
* [ソースコード(GitHub)](https://github.com/zacky1972/middleman-iepab)

はじめて middleman のカスタム拡張を作ったので，いろいろ不手際があるかもしれません。

インストール方法:

Middleman の Gemfile に `gem "middleman-iepab"` を追加して `bundle install` を実行する

設定方法:

config.rb を次のように設定すると，ビルド終了後に `hello` と表示されます。

```ruby
activate :iepab, {
  name: :echo,
  command: "echo hello",
  source: "./source",
  latency: 1
}
```

この記法と機能は，external pipeline と同じです。違いは，**ビルド後に** external pipeline を呼び出すという点です。
GoとElixir 並行処理の処理間のデータ共有の比較

# tl;dr

ElixirのProcessとGo routineのデータの共有ポリシー, データの送受信のコードも似ているが, Elixirの全てのコードはProcessで動くため ProcessとGo routineの意味合いは違う。

# 比較するきっかけ 

並行処理間のデータの共有のポリシーがElixirとGoで似ていると感じたため。
ElixirはProcess, Goには Go Routines 並行処理に適している仕組みがある。

他の言語では主にシェアメモリを利用して並行処理を実装すると, レースハザードがおきないようにメモリへのアクセス, 書き込みを制限しなければならず実装が難しい。
が Go, Elixir, Erlang(他の言語もあるはず)ではシェアメモリを使わずプロセス間でデータの送受信を行うため並行処理を実装しやすい。


# Goの場合

[参照リンク](https://blog.golang.org/share-memory-by-communicating)
GoではRoutine間のデータの共有はChannelを使用しプロセスにデータの参照を送る。


## Goroutine とはなんぞや

+ ThreadではなくGoランタイムで管理される軽量プロセスである。
+ 関数が終わる, returnで処理を抜ける, runtime.Goexit() を実行したタイミングでGo Routineが終了する。

## Channelとはなんぞや

+ goroutine 間で値の送受信のために使用するもの。
+ send => `channel<-value`, receive => `<-channel`

## 実装例


```Go
package main

import "fmt"

func main() {

    messages := make(chan string)

    go func() { messages <- "ping" }()

    msg := <-messages
    fmt.Println(msg)
}
```

### 処理の流れ
1. `make (chan string)` channelを作成。
2. `go func() { messages <- "ping" }()` Go routineを起動し, channelに "ping"を送信します。
3. `<-messages` でchannelからデータを受け取る。


# Elixirの場合

ElixirはProcess間のデータの共有はプロセスのid(PID)を指定して `send`, データを受け取るプロセスは `recieve`で受け取る。


## Processってなんぞや

Go Routineと違いElixirの全てのコードはProcess上で動く。
Process同士は独立，並行して動き，メッセージパッシングでやり取りする。
OSのプロセスとは違い, とても軽量なものである。

```Elixir
defmodule Spawn1 do
  def greet do
    receive do
      {sender, msg} -> 
        send sender, { :ok, "Hello, #{msg}" }
    end
  end
end
```

```Elixir
pid = spawn(Spawn1, :greet, [])
send pid, {self, "World!"}
receive do
  {:ok, message} ->
    IO.puts message
end
```

1 `pid = spawn(Spawn1, :greet, [])`

`spawn`関数は新しいプロセスを開始し, プロセスを一意に識別できるPID(プロセスID)を返す。
Spawn1モジュールのgreedメソッドを走らせる新しいプロセスを生成する。

2 `send pid, {self, "World!"}`

`send` 関数でメッセージを送る。引数としてPID, 送信するメッセージを指定する。

3 `receive`  

receive を使ってメッセージを待つ。

# これからやりたいこと

ベンチマークとったり, 並行処理モデルの違いについてまとめたい。

# :pencil: 

Go Routine, Channelについて参考にさせていただきました :bow: 

http://jxck.hatenablog.com/entry/20130414/1365960707
ざっくばらんメモ_17：自動パラメータチューニングの良し悪し

###自動パラメータチューニングの良し悪し
kaggleなどでxgboostなどのチューニングを行うことを考えたとき、
何も考えずに広いパラメータグリッド内で最適化しようとすると
当然ながら非常に時間がかかる。
しかもそうしてやって得られた結果が割と大した改善にもなっていない事が多い。
そのためパラメータチューニングをする際にはある程度human in the loopをした
方がまだ効率的である。
つまり、序盤の事前知識がない状態においてはなるべく粗く、でも広くパラメータグリッドを取り、
まずはどのあたりのパラメータで性能が出そうか人手で当たりを付ける。
続いて当たりを付けたあたりのより狭い範囲で、しかしグリッドの粒度を上げた形で
さらなる探索を行っていく形である。
だがこれはグリッドサーチに限った形で、例えばランダム探索やbayesian optimisationと比較した
場合にどちらが効率が良いかは気になる。
tmuxの基本コマンド

とりあえず使えるようになりたいtmuxコマンド備忘録。
プレフィックスキーのデフォルトは`Control-b`。以降`C-b`と表記。

##コマンド一覧

|コマンド|機能|
|:--:|:--|
|tmux / tmux new-session -s < name >|新規セッション|
|C-b + $|セッション名変更|
|C-b + ,|ウィンドウ名変更|
|C-b + d|セッションのデタッチ|
|tmux a / tmux a -t < session-name >|セッションにアタッチ|
|tmux ls|セッション一覧|
|tmux kill-session -t < session-name >|セッションを削除|
|C-b + c|ウィンドウ作成|
|C-b + n|ウィンドウ移動（next）|
|C-b + p|ウィンドウ移動（pre）|
|C-b + w|ウィンドウ一覧表示で移動|
|C-b + &|ウィンドウ強制終了|
|C-b + “|ペイン横分割|
|C-b + %|ペイン縦分割|
|C-b + o|ペインの移動|
|C-b + q + < number >|ペインのインジケータ表示・移動|
|C-b + x|ペイン強制終了|

##参考情報
- [tmuxの基本的な使い方とコマンドのまとめ](http://www.task-notes.com/entry/20150711/1436583600)
ちょっとずつ読むドメイン駆動設計 第四部 戦略的設計 第十四章 モデルの整合性を維持する8 腐敗防止層

# これまでの十四章
- [第四部 戦略的設計 第一四章 モデルの整合性を維持する](https://qiita.com/YasuhiroKimesawa/items/6e8e5503a05ce9515a79)
- [境界づけられたコンテキスト](https://qiita.com/YasuhiroKimesawa/items/901ac764340275b93d61)
- [継続的な統合](https://qiita.com/YasuhiroKimesawa/items/6a58743c90c5b707c29d)
- [コンテキストマップ](https://qiita.com/YasuhiroKimesawa/items/626384c84145870ec5af)

##  
- [共有カーネル](https://qiita.com/YasuhiroKimesawa/items/7895d8c28137bd34008a) 
- [顧客/供給者の開発チーム](https://qiita.com/YasuhiroKimesawa/items/c9668a437499897fa9d5)
- [順応者](https://qiita.com/YasuhiroKimesawa/items/ab4782d5e727075e2d87)


# 腐敗防止層
## 動機
[前回](https://qiita.com/YasuhiroKimesawa/items/ab4782d5e727075e2d87)、腐敗防止層を採用する動機として、上流のモデルを下流で扱うのが困難な場合とありました。

相手がレガシーの場合は特に、モデルが貧弱であるのが普通ですし、今回のプロジェクトとの要求に合わないことも。

エンジニアの心情としては、なんでそのレガシーを作り変えないんだ！と文句が出るところですが、予算的・政治的なところもありなかなか実現はしないものです。

## プリミティブなデータに曖昧なところがないという幻想

システム間のデータのやり取りは大体プリミティブなデータだと思います。
intやbooleanなどに曖昧なところはないので、そのデータがどういうデータなのか間違うことはないと考えてしまうことは多いと思います。

大体こういう想定は間違いであるとEvansは言っています。
データの意味を取り違って、エラーが起きたり、データベースのデータに矛盾が出てきたりということはよくあることです。

> 必要なのは、別のモデルと接している部品の間で変換できるようにすることにより、異質なモデルの要素を消化しきれずにモデルが崩壊しないようにすることである(第四部 第十四章より)

## 腐敗防止層

この解決策として、隔離するためのレイヤを作成して、2つのモデル間の変換を両方向に対して行う機能を提供することです。

注意すべき点としては、この腐敗防止層は、メッセージを送受信する仕組みではなく、ある**モデルを別のものに変換する仕組み**ということです。

腐敗防止層は、それ自体で複雑なソフトウェアになりえるので、[コンテキストマップ](https://qiita.com/YasuhiroKimesawa/items/626384c84145870ec5af)で読んだように、テストは必須です。

## 腐敗防止層のインタフェース

> 腐敗防止層の持つ公開インタフェースは、通常、サービスの集合として現れるが、まれにエンティティのかたちをとることがある。

サービスになるのはわかるのですが、エンティティになる場合ってどういうときですかね？

# 腐敗防止層の実装

腐敗防止層の構成例が１つ挙げられてますね。
ファサード(FACADE)・アダプタ(ADAPTER)と変換サービスを組み合わせるというものですね。ファサード・アダプタはGOFのデザインパターンです。

腐敗防止層は、モデルの変換をするサービスではありますが、統合するシステムへのインターフェイス(APIとか）が巨大で複雑であることも多いですよね。
　
引数が多すぎとか、条件が複雑とか・・・それだけで、十分複雑です。

ファサードはそのために用意します。

## ファサード
ファサードは、サブシステムのための代替インターフェイスです。サブシステムへのアクセスを簡略化して使いやすくし、複雑な箇所は隠蔽するものです。

ファサード内では、他システムのモデルに厳密に従って実装する必要があります。

## アダプタ
アダプタの役割はクライアントから来たものを変換して別システムへ送信をすること、別システムから受信したものを変換して返すこと（変換自体は変換サービス、送受信自体はファサードで行う)です。

## 変換サービス
単純に変換するための機能を提供します。変換自体が複雑な作業なので、独自のオブジェクトを用意します。

![腐敗防止層.png](https://qiita-image-store.s3.amazonaws.com/0/150455/60bccad4-cd47-a15f-74a4-bef09d3a93ae.png)

これらの構成は図にするとわかりやすいですね。

# 落ち葉拾い
## 他システムがこちらに通知や要求をする場合

基本はこちらから腐敗防止層にアクセルするのですが、他システムがこちら側に通知してくる場合、他システムに腐敗防止層のサービスを呼び出せるための変更が必要になることもあります。

## モデルの整合性で妥協しない

変換が難しくて、ある程度他システムのモデルに合わせなければと思うことがあるかもしれませんが、やはりそれは最終手段。モデルの整合性でまずは妥協しないことです。

## ファサードが必要ないことも

他システムがシンプルであるとか、APIなどのインターフェイスが整理されている場合は、ファサードが必要ないかもしれません。
この場合は、変換サービスで全部やるってことですかね。

## 他システムに関する特有な機能

他システムに対する監視証跡やデバックロジックなど、特有な機能を腐敗防止層に追加してもよいでしょう。

## 自分で作った他システム

自分で設計したサブシステムでも、別々のモデルに基づいている場合、腐敗防止層でつなぐことに意味があります。
Atom Teletypeをやってみた


# そもそも
なかなか特別な機会に新人と2人で行く事があったので
前々から興味のあったペアプロをやってみようと思いました。

もともとは隣の席で画面見ながら
Atom、Visual Studioを使ってやろうかと思ってましたが

席は背向かいでVisual Studioの共有作業は発表のみでまだできませんでした。。。
調査不足・・・w

なのでAtomで試しにやってみた結果です。

# Atom Teletype導入
かなり簡単で導入の方法はこの記事を参考にやりました
https://qiita.com/k-waragai/items/a372800c262f56fe688a
まだβのようですが面白いです。

# 何をするのに使用したのか？
手順書をまず箇条書きで作る必要があったのでmarkdownで書きながら
そのファイルを共有してもらい一緒に編集しました。

# 良かったところ：

### 導入が簡単
AtomをインストールしてTeletypeの認証を入れれば自分の編集しているファイルをすぐ共有できます。
相手に共有できるのは１ファイルですが2人で１つづつ共有することで
自分の共有と相手からの共有で2ファイル同時にできます。

### レビューする側からみて
- 相手のカーソルの移動や選択範囲をしているところまでわかるので相手の迷いや理解が追い付いていない点
- もっと簡単なストロークでできる操作を手間をかけてやっていたりすることが分かる。
- 同期が早いのでタイピングしている速度もなんとなくわかるw
- 面白かったのは想像もしない所で選択範囲をしていてペーストされないな？と思ったらググってるとかw

### レビューされる側
毎回毎回、席に呼ばなくてよい
画面に直接文字が入ってくるので
Window A見て
Window B見て
Window A見て
とやらなくて良いので指示者からの「ここを見てほしい」が伝わりやすい

自分が入力していると突然？上や下の行に
「そこじゃなくてこう！」
みたいにタイピングされて出てくるｗ これが意外と直接的でわかりやすい。

### 微妙な所：
- お互いのカーソルがどこにあるのかわからなくなることがたまにある
- 相手に共有できているのか切断されているのかがわかりにくい
- 同じ行を編集するとやはり微妙にぶつかることがある
特に最終行など、一回だけ自分と相手の文書が合体してしまったがかなりよく出きていて稀なことだった
- 同じところを書いてることもお互いに気が付くのでもなんとなくシンパシーで回避できるｗ
しかし最終行に追加するはどうしても何度もぶつかってしまう
- 相手の変換をこちらで確定するや改行を相手のバックスペースで消すなどが起きてた気がする

- １ファイルしか共有できず他のファイルに切り替える、エディタを落とした場合には再度Joinしなおさないといけないのが面倒（方法はあるようだが不明だった）

- ２人でソースをがっつり編集し始めると上の人のカットやペーストで下の人の対象行の位置が上下してしまい困るｗ


# 結果どうだったの？
- ペアプロいいなと思いました。もっと導入していきたい
- 直観的で相手にわかりやすいしやってみて「え？何やってんの？え？そこ？」ってことが1回やっただけでもわかる
- 選択範囲やカーソルの移動の仕方で相手が何がわからないのかが一目瞭然になるし考え方も見えやすい
- レビュー用途にとても便利でしたし、なかなか新鮮で楽しいｗ

# おまけ
プログラム実装も共有しましたが行数が多いととたんにどこにカーソルがいったのか全くわからなくなるのであくまで特定の関数や補助じゃないとソースコードによっては厳しそうです。

# 期待
Visual Studio Live Share にもかなり期待　＆　Atomでのバージョンアップも期待！

:dancer: :dancer_tone1: :dancer_tone2: :dancer_tone3:  :dancer_tone4:  :dancer_tone5:
Laravel に Nuxt.js プロジェクトを入れたい


Laravel に Nuxt.js プロジェクトを入れたい。

Nuxt.js の SSR は使わないものの、 Laravel の機能を API のみに閉じ込めて、完全に静的なクライアントで運用したいときなど。

生 Vue.js でも良いのだけど、置くだけ認識の Router/Vuex はかなり楽。

## 環境構築

````
$ laravel new myProject 
$ cd myProject 
$ vue init ~~~~~ myNuxt
$ mv myNuxt resouces/nuxt.js
$ rm package.json
$ mv resources/nuxt.js/package.json package.json
$ mv resources/nuxt.config.js nuxt.config.js
````

`nuxt.config.js` に次のような変更を

````
module.exports = {
  ....
  srcDir: "resources/nuxt.js/",
  ....
}
````

ひとまずコレで Nuxt が動くようになる。

## Laravel APIを Proxy する

`@nuxtjs/proxy` を使って、 Laravel のAPIをProxy する。

````
$ npm i @nuxtjs/proxy
````

`nuxt.config.js` に次のような変更を

````
module.exports = {
  modules: [
    '@nuxtjs/proxy'
  ],
  proxy:{
    '/api' : "http://localhost:8000"
  }
}
````

`php artisan serve`で立てたサーバが `/api` パスのリクエストを受け取れるようになる。

## ビルド設定

このままではビルドしても Nuxtアプリケーションしか立ち上がらない。

まずは、nuxt.js のstatic フォルダの中に Laravel の public フォルダの中身を全部ぶち込む

これでとりあえず、 Laravel のファイルが generate 時に dist の中に生成されるようになる。

server 側での公開パスも dist を設定してやると良い。

あとは apatch の設定。 generate するので問題ないかもしれないが 404 系を Laravel が受け取るような設定になっているはずなので、 そのへんは API でよしなにする。
(単純に index.html側に向けるとAPIが動かなくなるので注意)

index.html が index.php より優先されるように設定しないと、Laravel の Welcome page が表示されるのでそのへんも注意。

サブディレクトリでのホストが可能であれば、 generate を public/app の中に…みたいなことも出来るが、多分画像とかのパスの設定とかおかしくなりそう。
Yocto でパッケージにパッチをあてる方法

この記事は SmartDrive Advent Calendar 2017 の 23 日目の記事です。

SmartDrive でバックエンドエンジニアをしている @ahoki  です。
弊社では、デバイスのファームウェアの開発をしており、一部のデバイスでは Yocto を使用してカスタマイズして組込 Linux の環境を構築しています。 

Yocto ではいろいろなパッケージを自分で簡単に追加することができますが、パッケージをそのまま使うのではなくて、ソースコードに手を入れて使用したいということが度々起こりえます。
本記事では NXP 社の i.MX7 の Yocto Linux を例としてパッチを当てる方法を紹介したいと思います。

## パッチをあてるところ

今回は例として、i.MX7 のプロセッサのクロックをデフォルト設定よりも低くできるようにします。
具体的にはソースコード (Device Tree Source) の下記になります。

*
<build dir>/tmp/work/imx7dsabresd-poky-linux-gnueabi/linux-imx/4.1.15-r0/git/arch/arm/boot/dts/imx7d.dtsi*

```
cpu0: cpu@0 {
        compatible = "arm,cortex-a7";
        device_type = "cpu";
        reg = <0>;
        operating-points = <
                /* KHz  uV */
                1200000 1225000
                996000  1075000
                792000  975000
                396000  975000 ★追記
                198000  975000 ★追記
        >;
        clock-latency = <61036>; /* two CLK32 periods */
        clocks = <&clks IMX7D_ARM_A7_ROOT_CLK>, <&clks IMX7D_ARM_A7_ROOT_SRC>,
                 <&clks IMX7D_PLL_ARM_MAIN_CLK>, <&clks IMX7D_PLL_SYS_MAIN_CLK>;
        clock-names = "arm", "arm_root_src", "pll_arm", "pll_sys_main";
};
```

## 安直にパッチを当てる方法

一番単純な方法はダウンロードして展開先のファイルを直接書き換えてビルドし直す方法です。

下では `DISTRO="X11"`, `MACHINE="sato"`のケースを例としています。

```
vi tmp/work-shared/imx7dsabresd/kernel-source/arch/arm/boot/dts/imx7d-sdb.dts ★ファイルを編集
bitbake linux-imx -c compile -f
bitbake core-image-sato
```

`${YOCTO_ROOTDIR}` 直下の `tmp/work` または `tmp/work-shared` に展開されたソースコードがあるのでそれを直接編集しています。
その後、`bitbake` コマンドに `-f` をつけることで強制的に指定したパッケージに対してコンパイルし直しています。

ただし、この方法はちょっとしたお試しでやるにはいいですが、新たにビルドする度にファイルを編集する必要があるため、継続的に使用する環境では現実的ではありません。

## レシピを使ったパッチの当てる方法

パッチの適用を構成管理できるようにするためにはレシピを作成する必要があります。

###  Gitフォーマットパッチの作成

まず、下記のようにパッチファイルを作成します。

```
cd tmp/work-shared/imx7dsabresd/kernel-source
vi arch/arm/boot/dts/imx7d-sdb.dts ★ファイルを編集
git add arch/arm/boot/dts/imx7d-sdb.dts
git commit -s -m "Add cpu clock down options"
git format-patch -1
```

### レシピファイルの作成

次に作成したパッチファイルをあてるためのレシピを作成します。
レシピファイルは `<パッケージ名>_<バージョン>.bbappend` という形式のファイル名にするのが習わしです。 (今回は `linux-imx_4.1.15.bbappend` )
また、パッチファイルは `<パッケージ名>-<バージョン>/` ディレクトリ以下に置きます。 

```
mkdir -p meta-example/recipe-kernel/linux/linux-<version>
cd meta-example/recipe-kernel/linux/
cp <patch file> linux-imx-4.1.15
vi linux-imx_4.1.15.bbappend
```

`<version>` の部分については適宜自分が使っている Linux の Kernel バージョンに合わせて記載します。

`linux_<version>.bbappend` は下記のように記載します。

```
FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}-${PV}:"

SRC_URI += " \
    file://0001-Add-cpu-clock-down-options.patch \ |
"
```

先頭一行目はパッチファイルを置いたディレクトリを指定しています。
また、 `SRC_URI` はパッチファイル名を指定しています。

### Yocto ビルドにレシピファイルの置き場を指定する

このままでは Bitbake でレシピファイルが見つけられないので、ありかを教えてあげる必要があります。
そのためには、`conf/bblayers.conf` に下記を追記します。

```
BBLAYERS += " ${BSPDIR}/meta-example "
```


### 構成管理

本例では `meta-example` 以下および `conf/bblayers.conf` を構成管理しておけばパッチを適用済みの環境を繰り返し構築することができます。


## まとめ

手順を示したようにレシピを使ってパッチを適用するのは結構面倒です。
まずはソースコードを直接書き換えてビルドすることで、パッチの効果を確認した上でレシピを作成して管理することをおすすめします。
Qiita が少しでも見やすければ良いなと思ってStylishで色変えてみた。


どうしても明るいトップページが苦手で、
StylishというChrome, Firefoxで使えるCSSカスタマイズの拡張機能を使って
自分の見やすい感じに軽く仕上げました。

# Stylishのインストールはこちら

* [Chrome拡張「Stylish」でユーザースタイルシートを設定する](http://pixadversaria.web.fc2.com/htuao/stylish-ch.htm)

# コード

* LINK : [Dark Qiita | Userstyles.org] (https://userstyles.org/styles/152632/dark-qiita)

``` css
@-moz-document domain("qiita.com")
{
/* HOME background */
  .p-home
  {
    background: #232323;
    background-color: #232323;
  }

  .p-home_aside > .ra-UserList
  {
    background-color: #434343;
  }

  .p-home_aside > .ra-TagList
  {
    background-color: #434343;
  }

/* MAIN background */
  .p-home_main
  {
    background: #434343;
  }

  .tr-ItemList_label, .ra-User_name, .ra-User_screenname, .ra-User_contribCount, .ra-Tag_name, .ra-Tag_postCount
  {
    color: white;
  }

  .ra-UserList_tabItem.is-active, .ra-TagList_tabItem.is-active
  {
    color: #ccc;
  }

  .tr-Item_title, .ra-UserList_label, .ra-TagList_label
  {
    color: #dcdcdc;
  }

  .p-items_wrapper
  {
    background: #D8D8D8;
  }

  .p-items_wrapper .p-items_article
  {
    background: #BBB;
  }

  .p-items_container
  {
    background: #D5D5D5;
  }

  .footer
  {
    background: #333;
  }
}
```

# あとがき

CSSを好きにいじくるの楽しいですよね。
明るすぎるページは見てて疲れてしまうのでよくこの方法を使います。
良かったら皆様も使ってみてください。
bitflyerのAPIを使ってTwitterに板情報に投稿する

久しぶりの投稿はAPIを叩いてその結果をツイートする
という方法を忘れないために書いておく


# 環境

* abraham/twitteroauth を利用
* 参考→[abraham/twitteroauthを使う Qiita] (https://qiita.com/kino0104/items/9f9e6f75d58b40663673)
* composer のインストールを済ませておく（入れた記憶無いけど）
* php は 7.0で動いてるはず

# サンプル

``` php
 
$settings = array(
    'oauth_access_token' => "xxxxxxxxxxxxxxxxxx",
    'oauth_access_token_secret' => "ooooooooooo",
    'consumer_key' => "xxxxxxxxxxxxxxxxxxxxxxxx",
    'consumer_secret' => "ooooooooooooooooooooo"
);
 
// OAuthライブラリの読み込み
require "twitteroauth/autoload.php";
use Abraham\TwitterOAuth\TwitterOAuth;
 
//認証情報４つ
$consumerKey = $settings['consumer_key'];
$consumerSecret = $settings['consumer_secret'];
$accessToken = $settings['oauth_access_token'];
$accessTokenSecret = $settings['oauth_access_token_secret'];
 
$base_url = 'http://api.bitflyer.jp';
 
$tag = 'PHP';
$query = ['product_code'=>'FX_BTC_JPY'];
 
$response = file_get_contents(
                  $base_url.'/v1/getboard?' .
                  http_build_query($query)
            );
 
// 結果はjson形式で返されるので
$result = json_decode($response,true);
 
$mid_price = $result["mid_price"];
 
$message = "現在のbitflyerのFX_BTC_JPYは " . $mid_price . "円 です。";

//接続
$connection = new TwitterOAuth($consumerKey, $consumerSecret, $accessToken, $accessTokenSecret);
 
//ツイート
$res = $connection->post("statuses/update", array("status" => $message));
 
//レスポンス確認
var_dump($res);
```

今回、速さを優先してPHPでの取得にしてしまいました。
単純に価格を取得するだけなので、
おそらくAPIの回数規制にも引っかからないはず。

次はRubyで書いてみようかな。
Pythonで別のPythonファイルを作って実行結果を得る

変数の書き換えでどうにもならないときに使った方法である．
具体的には，Sympyで立てた計算式をSciPyで計算したいときに使った（もしかしたら別記事に書くかもしれない）．

# 環境
- Python 3.6.1

# コード

外部ファイルに1+1の計算をするコードを書き，その結果を得て出力するプログラムである．

```python:
import subprocess

def main():
    content = "def main():\n    print(1+1)\n\nif __name__=='__main__':\n  main()" # 外部ファイルの内容
    f = open("./tmp.py","w") # 今いるディレクトリのtmp.pyを開く (存在しなければ作成される)
    f.write(content) # contentをtmp.pyに書き込む
    f.close()
    # tmp.pyを実行する
    try:
        res = subprocess.check_output(["python tmp.py"],shell=True)
        res = res.decode("utf-8") # resはバイナリ形式なのでデコードする
        print(res) # ここでは2を得る
    except:
        print("エラー")

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

`subprocess`を用いて指定したコマンド(`python tmp.py`)を実行する．
結果のresは`<class 'bytes'>`なので，デコードして使いたい形式に変換する必要がある．
ここでのデコードした後のresは`<class 'str'>`である．

作成されたtmp.pyは以下のようになる．

```python:tmp.py
def main():
    print(1+1)

if __name__=='__main__'
  main()
```
PythonのListに含まれる全ての要素がもう一つのListに含まれるかの検証方法


# はじめに
```python3
list1 = [0, 1, 2]
list2 = [4, 2, 5, 6, 12, 1, 9, 0]
```
上記のようにlist1の要素全てがlist2に含まれるかを検証して真偽値を返す必要があったのでやってみます。

# 方法１
最初に以下のような関数を思いつきました。

```python3
def list_check1(list1, list2):
    count = 0
    for element in list1:
        if element in list2:
            count += 1
        if len(list1) == count:
            return True
    return False
```

これでいいのですが、list1の要素数が増えるとすごく遅くなってしまいます。

```python3:list_check1.py
import time

def list_check1(list1, list2):
    count = 0
    for element in list1:
        if element in list2:
            count += 1
        if len(list1) == count:
            return True
    return False

start = time.time()
list1 = [i for i in range(10000)]
list2 = [i for i in range(100000)]
print(list_check1(list1, list2))
print(time.time()-start)
```

```console
$ python list_check1.py
True
0.7270619869232178
```

# 方法２
Setオブジェクトにはsetの全ての要素がotherに含まれるか判定するissubset(other)メソッドがあるので、一度ListをSetに変換して判定してみます。

```python3:list_check2.py
import time

def list_check2(list1, list2):
    return set(list1).issubset(list2)

start = time.time()
list1 = [i for i in range(10000)]
list2 = [i for i in range(100000)]
print(list_check2(list1, list2))
print(time.time()-start)
```

```console
$ python list_check2.py
True
0.012912750244140625
```
list_check1と比べてかなり速くなりました。