OmniAICreator/Qiita-1.07M huggingface dataset:
外部エディタ(Atom)を使ったPOV-Rayの環境構築

# はじめに
これは [POV-Rayによる数学お絵かき入門 Advent Calendar 2017](https://qiita.com/advent-calendar/2017/povray4math) の1日目の記事です.
今日から25日間に亘ってPOV-Rayの基本的な使い方について書いていきます.


## POV-Rayとは
POV-Rayは無料で使えるレイトレーシングソフトです.
早い話が, POV-Rayを使えば例えば次のような画像が作成可能です.

![](https://media.giphy.com/media/3o6gbfG53hwEAAmgvK/giphy.gif)

筆者の他の作品は例えば https://giphy.com/channel/hyrodium を参照して下さい.

かの有名なJos LeysさんらによるDimensions(http://www.dimensions-math.org/Dim_JP.htm), Chaos(http://www.chaos-math.org/ja) にもPOV-Rayが使われています.
Jos LeysさんのYouTube Channel(https://www.youtube.com/user/josleys) も必見です.

## 方針
POV-Rayのドキュメントは公式/非公式に関わらず, ある程度充実しているように思います.
しかし実際の所, これらは網羅的に書かれた公式ドキュメントと単発的に書かれた非公式ドキュメントが大部分であり, 実際のコードの解説はあまり見掛けません.
そこで本連載ではそれらの間を取って

* 網羅的には書かず, 幾つかの項目を取り上げて解説
* 5日毎に作例の提示
* 独自のパッケージなどの紹介

を基本的な方針とします.

第一回では環境構築からHello Worldまでを書きます.

# 環境構築
ここでは筆者の用意できる環境(Ubuntu16.04, Windows10)について記述します.
他の環境でも同様に環境構築が可能な筈です.

## POV-Ray本体
### Ubuntu
次でインストールします.

```
sudo apt install povray
```

自分でコンパイルしてインストールする場合は次を参照して下さい:
https://github.com/POV-Ray/povray/blob/master/unix/README.md

あるいは次の記事が参考になるかもしれません:
https://qiita.com/oshimaryo/items/ab5b3253c1591e8eafbf

### Windows
ここからダウンロードしてインストールします.
http://www.povray.org/download/
Windows版ではPOV-Rayにエディタが付属していますが, 付属エディタはお世辞にも使い易いとは言い難いです.
別のエディタを導入するのが良いでしょう. (後述)

付属エディタを使わない場合はpathを通す必要があります.
標準ではインストール先が`C:\Program Files\POV-Ray\v3.7\bin`になっているので, これをpathに通します.

![](https://i.imgur.com/deo18hY.png)

## エディタ(Atom)
エディタは各自の好みで構いませんが, ここではAtomを使う事にします.
https://atom.io/

POV-Rayを使うに当って必要なパッケージは以下です.

* atom-language-povray
	POV-Rayのシンタックスハイライトをするためのパッケージ.
	https://atom.io/packages/atom-language-povray
* script
	Atom上からPOV-Rayのレンダリングを回すためのパッケージ.
	https://atom.io/packages/script


#### 注意点など

* scriptパッケージの代わりにtools-povrayを使う事も可能のようです. (筆者は使っていません): https://atom.io/packages/tools-povray

## 画像ビューア
LaTeX on Windowsで生成したpdfのビューアーにSumatra pdfが便利だったように, POV-Rayを使う際にも標準とは別の画像ビューアをインストールする方が便利です.

画像ビューアの要件は次です.

* ビューアで開いた際にファイルをロックしない
* 画像の更新を監視して自動で再読み込みする

### Ubuntu
Ubuntuの標準の画像ビューアは上要件を満たさないため, 別のアプリケーションをインストールする方が良いです.
お勧めはgThumbです.
次でインストールできます:

```
sudo apt install gthumb
```

### Windows
OS標準のもので可能かはまだ試していません.
(分かる方居ればコメントに書いてもらえると有り難いです)

以上で環境構築は完了です.

# Hello World
## 実行
次のように書かれたファイル`HelloWorld.pov`を用意します.

```Povray:HelloWorld.pov
background{rgb<1,1,1>}
sphere{<0,0,1>,0.2}
```

あとは`Ctrl+Shift+B`で実行すれば, 以下のような画像が同ディレクトリ内に`HelloWorld.png`として出力されている筈です.

![](https://i.imgur.com/nlqCLyu.png)

## 解説
`background{rgb 1}`は背景の色を白色に指定します.
`sphere{<0,0,1>,0.2}`は座標$(0,0,1)$を中心とする半径$0.2$の球面を配置する命令です.

POV-Rayにはカメラの位置を指定するための命令が存在しますが, ここではその命令を省略しています.
そのため, デフォルトとして座標$(0,0,0)$に置かれたカメラが$(0,0,1)$方向を向いて配置されています.
カメラの設定については第3回でより詳しく解説する予定です.

# 参考文献
幾つか参考になりそうな文献を挙げます.

* POV-Ray 公式ドキュメント
	http://www.povray.org/documentation/3.7.0/
* POV-Wiki
	POV-Rayが公式に運営しているwiki.
	http://wiki.povray.org/content/Main_Page	
* POV-Ray 3.5 利用参考マニュアル
	バージョン3.5の公式マニュアルの日本語訳.
	http://www.arch.oita-u.ac.jp/a-kse/povjp/povjp/
* POV-Ray for Geometry
	本連載の内容と比較的近いと思われるテキスト.
	http://math.uni.lodz.pl/~maczar/cagir/5.php
* POV-Ray実習マニュアル
	大黒学さんによるテキスト. 筆者はちゃんと読んでませんが, 130ページに亘って詳しく記述されています.
	http://tutorial.jp/graph
SlickのDatabaseConfigProviderでdefault以外の設定を使ってDBに接続するのでハマった

PlayFramework を 2.5.x から 2.6.x にバージョンアップした時に play-slick も 2.0.0 から 3.0.0 にバージョンアップしたところ deprecated の警告が出てしまいました。
その警告の修正にハマったので残しておきます。

## play-slick 2.0.0の場合
Scala Object で DatabaseConfigProvider を使っていたので、DI ではなくDatabaseConfigProvider の `get` メソッドを使って DB にアクセスするインスタンスを取得していました。

```scala:main.scala
object Main extends App {
  val app = new GuiceApplicationBuilder().build
  val db = DatabaseConfigProvider.get[JdbcProfile]("hoge")(app).db
  // 以下省略
}
```

Slick は 通常 `default` の設定を使用しますが、この処理では `hoge` の設定にある DB に接続していました。

```conf:application.conf
slick.dbs {
  default {
    # 省略
  }
  hoge {
    # 省略
  }
}
```

play-slick 2.0.0 を使用しているときは上記のコードで `hoge` の設定にある DB に接続していました。

## play-slick 3.0.0の場合
play-slick 2.0.0 のコードだと、以下の警告が出ました。
`Use DatabaseConfigProvider#get[P] or SlickApi#dbConfig[P]("default") on injected instances`

`get` を使わず、インジェクションして使用してくださいとあったので、以下のコードに変更しました。

```scala:Main.scala
object Main extends App {
  val app = new GuiceApplicationBuilder().build
  val dbConfig = app.injector.instanceOf[DatabaseConfigProvider]
  @NamedDatabase("hoge") val db = dbConfig.get[JdbcProfile].db
  // 以下省略
}
```

この場合、`hoge` の設定にあるDBに接続される想定でしたが、実際には `default` の設定にある　DB に接続されてしまい、存在しないテーブルにクエリを発行しようとして例外がスローされました。

`@NamedDatabase("hoge")` が効いてなかったので、以下のコードに変更して動作を確認したところ `hoge` の設定にある　DB にアクセスするようになりました。

```scala:Main.scala
object Main extends App {
  val app = new GuiceApplicationBuilder().build
  val executer = app.injector.instanceOf[Exetuter]
  executer.execute
  // 以下省略
}

class Exetuter @Inject() (@NamedDatabase("hoge") protected val dbConfigProvider: DatabaseConfigProvider) extends HasDatabaseConfigProvider[JdbcProfile] {
  def execute = {
    // 省略
  }
}
```

## 参考
[play-slick DatabaseConfigProvider github](https://github.com/playframework/play-slick/blob/master/src/core/src/main/scala/play/api/db/slick/DatabaseConfigProvider.scala)
[PlaySlick 2.6.x 公式ドキュメント](https://www.playframework.com/documentation/2.6.x/PlaySlick)
[play.api.inject.Injecter apiドキュメント](https://www.playframework.com/documentation/2.6.x/api/scala/index.html#play.api.inject.Injector)
【iOS】端末ごとのスクリーンサイズまとめ（iPhone & iPad）

# スクリーンサイズのまとめ
端末ごとのサイズを調べる時に複数サイト回って探していたので、まとめました。（随時更新予定ですっ）


＜iPhone＞

| iOSの端末サイズ | width | height |
|:-----------|------------:|:------------:|
| iPhone 2G, 3G, 3GS | <font color="Orchid">320</font> | <font color="LimeGreen">480</font> |
| iPhone 4, 4s | <font color="Orchid">320</font>  | <font color="LimeGreen">480</font> |
| iPhone 5, 5s, 5c, SE | <font color="Orchid">320</font>  | 568 |
| iPhone 6, 6s, 7, 8 | <font color="SandyBrown">375</font> | 667 |
| iPhone 6+, 6s+, 7+, 8+ | 414 | 736 |
| iPhone X | <font color="SandyBrown">375</font> | 812 |


＜iPad＞

| iOSの端末サイズ | width | height |
|:-----------|------------:|:------------:|
| iPad Mini | <font color="FireBrick">768</font> | <font color="Fuchsia">1024</font> |
| iPad Air & Small Pro | <font color="FireBrick">768</font>  | <font color="Fuchsia">1024</font> |
| Large iPad Pro | <font color="Fuchsia">1024</font> | 1366 |

（※数字はステータスバー領域を含む場合の画面サイズです。＝スクリーン全体のサイズ）

##サイズ取得方法

```swift
let boundSize: CGSize = UIScreen.main.bounds.size
let width = boundSize.width 
let height = boundSize.height
```
モブプログラミングを振り返りまとめてみる

モブプログラミングの情報を噂に聞いて現場で取り組んでみて半年経過したので参考までにまとめておきます。

##モブプログラミングとは(以下モブプロ)
- 簡単にまとめると「チーム全員でペアプロする」みたいなことです。
2014年にWoody Zuill氏がAgile Allianceで発表されたMob Programming A Whole Team Approachが原著になると思います。

- https://www.agilealliance.org/resources/experience-reports/mob-programming-whole-team-approach-woody-zuill/


##モブプロを取り入れた経緯
- 設計の背景や意図を伝えるのに時間がかかる
    - ドキュメントを作成してみたが作成に時間がかかり、かつ保守が大変
- コードレビューやレビューの取り込みにやたら時間がかかる
- スキルやナレッジが偏ることでタスク担当者に偏りがでる
    - バス因子のようなもの…
- 開発チームで決定したことを顧客に合意を得るまでに時間がかかる

他にも挙げればキリがないのですが、特にプロジェクトでボトルネックになっていたのが上記の課題でした。
そこでコミュニケーションのムダやナレッジ共有に効果があると噂のモブプロを取り入れてみました。

##環境
- 人数：3～6人
- 場所：比較的大きなモニターがある部屋、スペースなど
- PC：作業用のPC1台
- 内容：要件定義、設計、開発(TDD)、運用手順定義 など
- ツール：
    - mobster
        - モブプロ用のタイマーです。(ペアプロでも効果あり)
        - 一部動作しないPCもあったのでその場合は下記のサイトを利用していました。
        - http://oss.jahed.io/agility/timer.html
  
##結果
###設計編
- 全員で合意しながら設計が行えたので、その後の情報共有も不要になった
- 各システムや言語の有識者が集まっているので、より洗練された設計ができた
- チーム全員で設計を共有できているのでドキュメントコストを削減できた

###レビュー編
- そもそも全員でレビューを行いながら開発しているのでこれまでのレビューがなくなった
- gitのwork branchも使わなくなり、trunk base開発に移行
    - マージもなくなり幸せになった

###スキル編
- 有識者：スキル共有することで理解を深める
- 初心者：スキル共有され且つ実際に手を動かしていくので理解を深める
- win-winな関係に

###合意を得るまでのリードタイム編
- その場で合意が得られるのでリードタイムは0です

##これからモブをやってみようという方へ課題共有
###モブプロでぶつかった課題と解決策
- ナレッジ差によって発言しなくなってしまう人が出る
    - ドライバー、ナビゲーター、モバーの役割を明確に分けて徹底する
    - ドライバー、ナビゲーターは発言せざるを得ないので意図的に割り当てる
- 議論がヒートアップしてムードが悪くなることがある
    - 意見が分かれた場合、プランニングポーカーのような形式で方針を決定する
    - ファシリテータを明確に立てて場をクールダウンさせるようにする
    - 時間を決めて作業に取り組む(予定時間になったら一旦落ち着く)
- 参加者1人1人のゴールがばらばらになっていることがある
    - ホワイトボードに書くなどして常に見えるところにゴールを配置する
    - 定期的に現在の目的を再確認する
- 顧客へのレビューに時間がかかる
    - 意思決定が必要な場合は、顧客に参加してもらいその場で決定する
- ファシリテータによって進行に差がある
    - ファシリテータでない参加者も気づいた時点で積極的にファシリテーションする

###やっておいた方が良いこと
- 毎回ふりかえりを実施する(モブ開始前に前回の振り返りからtryを選んでもok)
- no blameの精神を…
    - あまり否定的だと発言が消極的になるので 

##総括
- 結果の部分からもわかるようにモブプロを取り入れて得られた効能は非常に大きなものでした。
特に心理的安全性が確立されたことから、これまで発言が消極的だったメンバーも積極的に発言するようになったので、より良い設計や実装ができるようになりました。
- 他にも新しい情報があれば積極的に試していこうと思います!
[TensorFlow]Machine Learning Developer Meetup Tokyo

<p>Machine Learning Developer Meetup に参加してきた。このイベントは、<a href="https://tfug-tokyo.connpass.com">TensorFlow User Group Tokyo</a>との共催ということのようだ。</p>

<p>TensorFlow。日本では、数学と物理の教科書で、Tensorをテンソルと訳しているため、テンソル・フローと呼ばれているが、英語ではテンソー・フローということになるようだ。</p>

<p>Googleが開発し、Googleで利用されている機械学習のライブラリで、先日、TensorFlow Liteというモバイル環境に最適かされた実行環境もリリースされて話題となっている。iOSの世界では、CoreMLのモデルを生成するライブラリの一つとして認識されているということになると思う。</p>

<p>本イベントでは、どちらかというと、学習関連の話題が多く取り上げられ、分散化やボトル・ネックの解消などの話題が多かった。</p>

<p>全然ノーマークだったのだが、まずは、ユーザ・グループに参加してみようと思っている。</p>

関連情報
<a href="https://events.withgoogle.com/ml-developer-meetup/">Machine Learning Developer Meetup Tokyo</a><br />
<a href="https://qiita.com/advent-calendar/2017/cocoa">Cocoa Advent Calendar 2017</a><br />
<a href="https://cocoa-kanto.connpass.com">Cocoa勉強会 BUKURO.swift (connpass)</a><br />
<a href="https://atnd.org/groups/cocoa-study">Cocoa勉強会 BUKURO.swift (ATND)</a><br />
<a href="http://cocoa-study.peatix.com">Cocoa勉強会 BUKURO.swift (Peatix)</a><br />

【Cocoa練習帳】
<a href="http://www.bitz.co.jp/weblog/">http://www.bitz.co.jp/weblog/</a><br />
<a href="http://ameblo.jp/bitz/">http://ameblo.jp/bitz/</a>（ミラー・サイト）<br />
<a href="https://t.co/6P3h2jtbRk>note</a><br />
<a href="https://qiita.com/m_yukio>Qiita</a><br />
AirStationの定期再起動をmacOSで自動化する

# つくったもの

[yewton/reboot\-airstation](https://github.com/yewton/reboot-airstation)

# 背景

なんだか無線の調子が悪くてプチプチ切れるようになったので AirStation ルーターを再起動してみたら症状が収まったので、自動で定期的に再起動してほしくなった。

# 使ったもの

## AppleScript

前提として、 AirStation には Web API のような便利なものは備わっていないため、再起動させるにはブラウザから管理画面に入って操作するしかない。

この操作を `curl` でエミュレートするなども考えたが、今回は常に稼働しているmacOSから出来ればそれでよかったので、一番かんたんに出来そうなAppleScriptを使うことにした。

## launchd

AppleScriptで自動再起動できるようになったので、これを定期的に実行するためにlaunchdを使った。

# ハマったところ

## ページロードを待ちたい

ブラウザを自動で操作するだけなので、ページのロードが完了していないと意図通りに動作しない。

[`applescript wait for page to load` で検索すると](https://www.google.com/search?q=applescript+wait+for+page+to+load) 色々やり方はあるようだったが、デファクトなやり方がなさそうだったのと、今回は厳密さをそこまで要求しないので、単に `delay` を各所に挟むだけにした。

## アカウント情報を外から与えたい

アカウント情報をスクリプトにハードコードしたくなかったので、環境変数から与えることにした。

AppleScript では `system attribute "HOGE"` で環境変数を取得できる。

LaunchAgentで環境変数を与えるには、`EnvironmentVariables` を使って以下のように指定する:

```xml
    <key>EnvironmentVariables</key>
    <dict>
        <key>HOGE</key>
        <string>hoge</string>
    </dict>
```

## LaunchAgent は `~` や `$HOME` を展開できない

[bash を噛ますなどの回避方法もある](https://github.com/yewton/.dotfiles/blob/9a6931f8bc66522856f54cb2710ec567f0e79d66/Library/LaunchAgents/net.yewton.sshadd.plist#L9-L11) のだけれど、今回はこの他にアカウント情報なども埋め込む必要があったので、 plist のテンプレートを元に環境変数の値を埋め込んだファイルを生成して配置するスクリプトを作った。
この配置スクリプトを実行した環境の `$HOME` の値を埋め込んでフルパスに直したものを使用することで回避した。


# 参考にしたもの
- [Baffaloルータの自動再起動スクリプト \- hishidoの日記 temp](http://d.hatena.ne.jp/hishido/20100825/1282698461)
- [cygnan/reboot\-airstation: An ash script to reboot a Buffalo AirStation router](https://github.com/cygnan/reboot-airstation)
- [How to Open a Website with Applescript – CubeMG](http://www.cubemg.com/how-to-make-safari-open-a-website-with-applescript/)
- [applescript \- How to wait for webpage to fully load before proceeding script? \- Stack Overflow](https://stackoverflow.com/questions/24500011/how-to-wait-for-webpage-to-fully-load-before-proceeding-script)
- [AS Hole（AppleScriptの穴） By Piyomaru Software » AppleScriptでwaitを入れる » Blog Archive](http://piyocast.com/as/archives/948)
- [how do I get the value of an environment variable in Applescript? \- Stack Overflow](https://stackoverflow.com/questions/42079388/how-do-i-get-the-value-of-an-environment-variable-in-applescript)
- [launchdで定期的にスクリプトを実行 \- Qiita](https://qiita.com/rsahara/items/7d37a4cb6c73329d4683)
- [launchd/launchctl に困った時 \- ばかもりだし](http://baqamore.hatenablog.com/entry/2014/01/29/222428)
.htaccessを有効にするにはメモ

# http.conf
`<Directory></Directory>`内に
`AllowOverride All`
を書来ましょう。
`AllowOverride None`
だと.htaccessが有効にならない

[参考](http://web.just4fun.biz/?Apache/.htaccess%E3%81%AB%E3%82%88%E3%82%8B%E8%A8%AD%E5%AE%9A%E3%81%8C%E5%8F%8D%E6%98%A0%E3%81%99%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E3%81%99%E3%82%8B#sfb1c448)
CWL User Guide 16: File Formats をやってみた

# CWL User Guide 16: File Formats

今回は、入力、出力に使うファイルの形式の指定について書かれています

サンプルでは、[BAM](https://www.ebi.ac.uk/ols/ontologies/edam/terms?iri=http%3A%2F%2Fedamontology.org%2Fformat_2572)を入力にして、テキストファイル[plain text format \(unformatted\)](https://www.ebi.ac.uk/ols/ontologies/edam/terms?iri=http%3A%2F%2Fedamontology.org%2Fformat_1964)が、出力されるということが、EDAMを参照して書かれています。

Key Points から
* 入力と出力の `File` について、ファイル形式をドキュメントすることができる
* 十分にツールが熟成したら、EDAMのようなすでに存在するオントロジーをリファレンスに、フォーマットを記述することをおすすめします。


# この回にでてくる主なキーワード
* File

# CWLファイル、metadata_example.cwl

```metadata_example.cwl
#!/usr/bin/env cwl-runner
cwlVersion: v1.0
class: CommandLineTool

label: An example tool demonstrating metadata.

inputs:
  aligned_sequences:
    type: File
    label: Aligned sequences in BAM format
    format: edam:format_2572
    inputBinding:
      position: 1

baseCommand: [ wc, -l ]

stdout: output.txt

outputs:
  report:
    type: stdout
    format: edam:format_1964
    label: A text file that contains a line count

$namespaces:
  edam: http://edamontology.org/
$schemas:
  - http://edamontology.org/EDAM_1.18.owl
```

# パラメータファイル

```sample.json
aligned_sequences:
    class: File
    format: http://edamontology.org/format_2572
    path: file-formats.bam
bamstats_report:
    class: File
    path: /tmp/bamstats_report.zip
```

# 必要なファイル

`file-formats.bam` が必要

ダウンロードの仕方はドキュメントに書かれている

```
wget https://github.com/common-workflow-language/user_guide/raw/gh-pages/_includes/cwl/file-formats.bam
```

# 実行

## 実行方法

```
cwltool metadata_example.cwl sample.yml
```

## 実行結果

```
$ cwltool metadata_example.cwl sample.yml
/usr/local/bin/cwltool 1.0.20171107133715
Resolved 'metadata_example.cwl' to 'file:///home/vagrant/cwl_user_guide_work/16-file-formats/metadata_example.cwl'
[job metadata_example.cwl] /tmp/tmpXlxfjy$ wc \
    -l \
    /tmp/tmp7YTE26/stgffbb819a-9b83-497b-b2f9-d95d3931993f/file-formats.bam > /tmp/tmpXlxfjy/output.txt
[job metadata_example.cwl] completed success
{
    "report": {
        "format": "http://edamontology.org/format_1964",
        "checksum": "sha1$2b6fc3fa866a2e30043aed460ea44603faad18a8",
        "basename": "output.txt",
        "location": "file:///home/vagrant/cwl_user_guide_work/16-file-formats/output.txt",
        "path": "/home/vagrant/cwl_user_guide_work/16-file-formats/output.txt",
        "class": "File",
        "size": 78
    }
}
Final process status is success
```

## 実行結果確認

```
$ cat output.txt
13698 /tmp/tmp7YTE26/stgffbb819a-9b83-497b-b2f9-d95d3931993f/file-formats.bam
```

# 今回使ったファイル

[cwl\_user\_guide\_work/16\-file\-formats at master · manabuishii/cwl\_user\_guide\_work](https://github.com/manabuishii/cwl_user_guide_work/tree/master/16-file-formats)
CWL User Guide 15: Staging Input Files をやってみた

# CWL User Guide 15: Staging Input Files

[Common Workflow Language User Guide: Staging Input Files](http://www.commonwl.org/user_guide/15-staging/)

今回は、実行時に必要なファイルをステージングする方法、について書かれています

# この回にでてくる主なキーワード


# CWLファイル、linkfile.cwl

```linkfile.cwl
#!/usr/bin/env cwl-runner

cwlVersion: v1.0
class: CommandLineTool
hints:
  DockerRequirement:
    dockerPull: java:7
baseCommand: javac

requirements:
  - class: InlineJavascriptRequirement
  - class: InitialWorkDirRequirement
    listing:
      - $(inputs.src)

inputs:
  src:
    type: File
    inputBinding:
      position: 1
      valueFrom: $(self.basename)

outputs:
  classfile:
    type: File
    outputBinding:
      glob: "*.class"
```

# パラメータファイルarguments-job.yml

```arguments-job.yml
src:
  class: File
  path: Hello.java
```
# 必要なファイル

第８回で作った `Hello.java` が必要になります

```
public class Hello {}
```

# 実行


## 実行方法

```
cwltool linkfile.cwl arguments-job.yml
```

## 実行結果

```
$ cwltool linkfile.cwl arguments-job.yml
/usr/local/bin/cwltool 1.0.20171107133715
Resolved 'linkfile.cwl' to 'file:///home/vagrant/cwl_user_guide_work/15-staging/linkfile.cwl'
['docker', 'pull', 'java:7']
7: Pulling from library/java
Digest: sha256:c0b61b62639124aa838dc755c5a9d57c072f762b71b170281927399a14db4652
Status: Downloaded newer image for java:7
[job linkfile.cwl] /tmp/tmpNjfe1r$ docker \
    run \
    -i \
    --volume=/tmp/tmpNjfe1r:/var/spool/cwl:rw \
    --volume=/tmp/tmpwc5RxS:/tmp:rw \
    --volume=/home/vagrant/cwl_user_guide_work/15-staging/Hello.java:/var/spool/cwl/Hello.java:ro \
    --workdir=/var/spool/cwl \
    --read-only=true \
    --user=1000:1000 \
    --rm \
    --env=TMPDIR=/tmp \
    --env=HOME=/var/spool/cwl \
    java:7 \
    javac \
    Hello.java
[job linkfile.cwl] completed success
{
    "classfile": {
        "checksum": "sha1$e68df795c0686e9aa1a1195536bd900f5f417b18",
        "basename": "Hello.class",
        "location": "file:///home/vagrant/cwl_user_guide_work/15-staging/Hello.class",
        "path": "/home/vagrant/cwl_user_guide_work/15-staging/Hello.class",
        "class": "File",
        "size": 184
    }
}
Final process status is success
```

## 実行結果確認

`Hello.class` ができていることが確認できます

```
$ ls
arguments-job.yml  Hello.class  Hello.java  linkfile.cwl
```

# 今回使ったファイル

[cwl\_user\_guide\_work/15\-staging at master · manabuishii/cwl\_user\_guide\_work](https://github.com/manabuishii/cwl_user_guide_work/tree/master/15-staging)
Raspberry Pi 3 Model B のセットアップ


# インストール
以下の記事の「ラズパイ起動！」の節まで実施する。
http://xayataka.hatenablog.com/entry/2017/02/25/225418

参考
https://qiita.com/cuminseed/items/8693b4fe8fb7db45f14b

# Wi-Fi接続（マウス無しで実施）
ターミナルを起動して以下を入力。

```
$ sudo sh -c 'wpa_passphrase SSID PASSPHRASE >> /etc/wpa_supplicant/wpa_supplicant.conf'
$ sudo reboot
```

再起動後、再度ターミナルを開き、wlan0の箇所でIPアドレスが取得できているか確認。

```
$ ip addr
(一部略)
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether b8:27:eb:dd:62:ab brd ff:ff:ff:ff:ff:ff
    inet 192.168.11.12/24 brd 192.168.11.255 scope global wlan0
       valid_lft forever preferred_lft forever
    inet6 fe80::ba27:ebff:fedd:62ab/64 scope link
       valid_lft forever preferred_lft forever
```

上記だと「inet 192.168.11.12」が設定されているIPアドレス。
※ただし、今は固定されていない。（固定方法は後述）

参考
https://qiita.com/toshihirock/items/8e7f0887b565defe7989

# ssh接続
デスクトップの上部のメニューから、「設定」→「Raspberry Piの設定」を開く。
インターフェイスタブからSSHを有効に変更してOKをクリック。

少し待つとsshdが起動するはずなので、手元のPCからログインする。
初期パスワードは「raspberry」が設定されている。

```
$ ssh pi@192.168.11.12
```

参考
https://qiita.com/toshihirock/items/8e7f0887b565defe7989

# IPアドレスを固定する

`/etc/dhcpcd.conf` の末尾に以下を追記する。
`ip_address` は↑で取得したものにしておくと間違いがない。

```/etc/dhcpcd.conf
interface wlan0
static ip_address=192.168.11.12/24
static routers=192.168.0.1
static domain_name_servers=192.168.0.1 8.8.8.8
```

`routers` と `domain_name_servers` は Wi-Fi の環境によって異なるので注意。

その後、再起動する。

```
$ sudo reboot
```

再起動後、sshログインできれば成功。

```
$ ssh pi@192.168.11.12
```

参考
https://qiita.com/tukiyo3/items/f125739311d6d2e16023

# OSアップデート

```
$ sudo apt-get update -y
$ sudo apt-get upgrade -y
$ sudo rpi-update
$ sudo reboot
```

参考
http://xayataka.hatenablog.com/entry/2017/02/25/225418

# タイムゾーンを日本に設定する

以下の記事の「タイムゾーンを設定する」の通りに実施する。
https://iotdiyclub.net/raspberry-pi-introduction-step-3/

# 自分の環境を設定する（dotfiles）
zsh, vimをインストールし、デフォルトシェルをzshに変更。

```
$ sudo apt-get install zsh vim -y
$ chsh
```

dotfilesをcloneしてインストールする。

ssh鍵の設定を行う。

# 困ったときは？

## 無線LANに接続したけどネットに繋がらない

http://densikousaku.com/archives/865
電車の中で一目惚れしたあの子(Webサイト)の秘密(ページソース)を知るためのテクニック(iPhoneでの表示方法)

良いデザインのあの子(Webサイト)や
いつも気の利く情報をくれるあの子(Webサイト)のことを、もっと知りたい…
そう思って意中の人の秘密(ページソース)を知りたいと思うことはよくある話だと思います。

そしてそんな出会いは、いつも電車の中…
一目惚れしてしまった、君のことをもっと知りたい、だからページソースを見てみたい…
けど**iPhoneでのソース表示どうすればいいの**


この記事はそんな疑問にぶち当たった人のためのまとめです。
(決して恋愛ポエムや恋愛小説ではありません)


#ブックマークレットを使って知る
## Snoopy
http://snoopy.allmarkedup.com

ブックマークレット使った場合だとこれが有名どころかもしれませんね。
ページに書いてある手順に沿ってブクマに登録し、気になるサイトを開いた状態でSnoopyのブクマをタップすると表示してくれます。
ただし、どうも触ってみた感じだとhttpsページでは反応してくれない模様。。。


# Appを使って知る
## iSource
https://itunes.apple.com/jp/app/isource-browser/id370764473

HTMLソースはもちろん、コンソールやHTTPヘッダーの中身まで見ることができる無料のアプリ。
URL欄にキーワードを入れて検索することも可能です。シンプルで使いやすい。
サッと確認する程度ならこれくらいで十分ですね。


## ScriptBrowserPlus
https://itunes.apple.com/jp/app/scriptbrowserplus/id475185328

無料でおすすめしたいのはこのアプリです。
ソース表示以外にも色々な機能がありアレコレ知りたい試したい人には便利（ソースコードテストもできるのは素晴らしい）
ただし残念ながらiOS11では動作対応していない模様。。。残念（；；）


## View Source
https://itunes.apple.com/jp/app/view-source-html-javascript-and-css/id917660039

有料ですが個人的に一番使いやすいのがこれです。
Safariの共有メニューからこのアプリを呼び出せるのはめちゃくちゃ大きい。
DOM階層やページに含まれるアセットを見れるのも便利です。


#最後に
謎のテンションで一気に調べて一気に検証して一気に書き上げた記事なので、誤りや間違いがあったり「こんな秘密兵器もあるんだぜ。。。」というのがあればコメント等頂けると幸いですm(_ _)m
CWL User Guide 14: Creating Files at Runtime をやってみた

# CWL User Guide 14: Creating Files at Runtime

[Common Workflow Language User Guide: Creating Files at Runtime](http://www.commonwl.org/user_guide/14-runtime/)

今回は、実行時点でファイルを作る方法、について書かれています

# この回にでてくる主なキーワード

* InitialWorkDirRequirement

# CWLファイル、createfile.cwl

```createfile.cwl
#!/usr/bin/env cwl-runner

class: CommandLineTool
cwlVersion: v1.0
baseCommand: ["cat", "example.conf"]

requirements:
  InitialWorkDirRequirement:
    listing:
      - entryname: example.conf
        entry: |
          CONFIGVAR=$(inputs.message)

inputs:
  message: string
outputs: []
```

# パラメータファイル echo-job.yml

```echo-job.yml
message: Hello world!
```


# 実行


## 実行方法

```
cwltool createfile.cwl echo-job.yml
```

## 実行結果

```console
$ cwltool createfile.cwl echo-job.yml
/usr/local/bin/cwltool 1.0.20171107133715
Resolved 'createfile.cwl' to 'file:///home/vagrant/cwl_user_guide_work/14-runtime/createfile.cwl'
[job createfile.cwl] /tmp/tmp1eoDtO$ cat \
    example.conf
CONFIGVAR=Hello world![job createfile.cwl] completed success
{}
Final process status is success
```

# 今回使ったファイル

[cwl\_user\_guide\_work/14\-runtime at master · manabuishii/cwl\_user\_guide\_work](https://github.com/manabuishii/cwl_user_guide_work/tree/master/14-runtime)
CWL User Guide 13: JavaScript Expressions をやってみた

# CWL User Guide 13: JavaScript Expressions

[Common Workflow Language User Guide: JavaScript Expressions](http://www.commonwl.org/user_guide/13-expressions/)

今回は、JavaScript で、入力パラメータを、操作(manipulate)することができるということ、について書かれています

このあたり、JavaScriptで、どのあたりまでできるのか？
JavaScript あれば解決できるなということがこのあたりに合致するかを確認してみると良いと思います。

Key Points から

* `InlineJavascriptRequirement` が指定された場合、 JavaScript は、 CWL runner により解釈される
* `expression` 形式が使えるフィールドは限られている。
* `expression` は、他に解決策がないときのみ使われるべき



# この回にでてくる主なキーワード
* InlineJavascriptRequirement
* valueFrom

# CWLファイル、expression.cwl

```expression.cwl
#!/usr/bin/env cwl-runner

cwlVersion: v1.0
class: CommandLineTool
baseCommand: echo

requirements:
  - class: InlineJavascriptRequirement

inputs: []
outputs: []
arguments:
  - prefix: -A
    valueFrom: $(1+1)
  - prefix: -B
    valueFrom: $("/foo/bar/baz".split('/').slice(-1)[0])
  - prefix: -C
    valueFrom: |
      ${
        var r = [];
        for (var i = 10; i >= 1; i--) {
          r.push(i);
        }
        return r;
      }
```

# パラメータファイル

```empty.yml
{}
```

# 実行

## 実行方法

```
cwltool expression.cwl empty.yml
```

## 実行結果

```console
$ cwltool expression.cwl empty.yml
/usr/local/bin/cwltool 1.0.20171107133715
Resolved 'expression.cwl' to 'file:///home/vagrant/cwl_user_guide_work/13-expressions/expression.cwl'
[job expression.cwl] /tmp/tmpMRy2L5$ echo \
    -A \
    2 \
    -B \
    baz \
    -C \
    10 \
    9 \
    8 \
    7 \
    6 \
    5 \
    4 \
    3 \
    2 \
    1
-A 2 -B baz -C 10 9 8 7 6 5 4 3 2 1
[job expression.cwl] completed success
{}
Final process status is success
```

# 今回使ったファイル

[cwl\_user\_guide\_work/13\-expressions at master · manabuishii/cwl\_user\_guide\_work](https://github.com/manabuishii/cwl_user_guide_work/tree/master/13-expressions)
MacBook Pro 環境構築

## 前段 :skull::money_with_wings: 
MacBook Pro 13（2016）の液晶が割れたため、MacBook Pro 13（2017）を新調した。

CPUとメモリを上げたものを購入しようと思い、銀座Appleストアに行ったものの、カスタマイズになるからネットでしか購入できないんだとか。まじか。

なのでビックカメラに行きました。ポイントありがたや。

以前のパソコンは結婚式のムービー編集用（という嫁に対する建前）で購入したが、今回は開発マシンとして堂々と購入。

開発マシンと言っても大したことはしません。堂々と言います。
Vue.js最高。直近はreact-nativeとreduxを趣味でいじってます。
仕事でも開発してみたいものです。

最近はサーバーサイドから離れてるのでnodeさえ入ってれば後は使い勝手さえ良ければ正直なんでもいい。

ということで、以下が初日に行った環境構築の内容。

## アプリ :man:
- [Google 日本語入力](https://www.google.co.jp/ime/)
- ~~[Alfred](https://www.alfredapp.com/)~~
- [Chrome](https://www.google.co.jp/chrome/browser/desktop/index.html)
- [Firefox](https://www.mozilla.org/ja/firefox/new/)
- [IntelliJ](https://www.jetbrains.com/idea/download/#section=mac)
- Xcode
- [AppCleaner](http://freemacsoft.net/appcleaner/)

Alfredはずっと使い続けていたので無いと死ぬと思ってたけど実はSpotlightで十分なのでは、と今更ながら気づいてしまって少し震えている。
Powerpack購入しないと入れる動機が愛着以外ない、、

ということで、AppCleanerを入れて二日目にして削除しました。
Spotlightと少し浮気してきます。

## zsh :kiss_mm:
```bash:Terminal
chsh -s /usr/local/bin/zsh
```

```text:~./zprofile
# Command
PROMPT='
%d
$ '

# Command History
HISTFILE=~/.zsh_history
HISTSIZE=1000000
SAVEHIST=1000000
setopt hist_ignore_all_dups

# Auto Completion
zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}'

# Disable Ctrl+D
setopt ignore_eof

# Alias
alias ls='ls -aG'
```
本当はコマンドを太字にしたい。けどやり方がわからない。
他人の設定とか気になるなぁ〜

### node.js :family_mwgb:
```bash:Terminal
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```

```bash:Terminal
brew install node
```
nodebrewは入れていない。

## 終わりに :wave:
とくに語ることはない。
アホみたいなWeb MIDI APIラッパーを更新してたらいろいろと気づいた

## メリークリスマース！

![midi.jpg](https://qiita-image-store.s3.amazonaws.com/0/31758/7d88762f-9e1d-c4ba-44ff-04215ec48a41.jpeg)

> ↑謎のMIDI楽器たち

## 前ふり

普段 Web MIDI APIでは主に「リアル金属音を鳴らす」という偏った活動をしてる @tadfmacです。

[アホなスライド](https://www.slideshare.net/tadfmac/web-music-demo-party-1-lt)

勢いでアドベントカレンダーに登録してしまった！
どうしよう！ネタはない！時間もない！

というわけで、やってみて起こったことをつらつらと書きます。すいません...

## やってみたこと。 poormidi.js -> pomidi.js 

[アホみたいなWeb MIDI APIの Wrapper](https://github.com/tadfmac/poormidi) ですが、さすがにいろいろアレなので、さらにアホみたいに書けるように進化（！？）させようと企んでいます。

まだ githubにはpushしてませんけど、こちらに置いてあります。

https://mz4u.net/libs/posnd/pomidi.js

### 使い方

こんな感じで書けるようになります。

```main.js
(async ()=>{
  var midi = await new pomidi();
  midi.sendNoteOn(30);
  await midi.wait(100);
  midi.sendNoteOn(40);
  await midi.wait(100);
  midi.sendNoteOn(50);
})();
```
かんたん！
アホみたいなケースにしか使えなさそうな気もしますが遊んでください！

## 気づいたこと 1. Chrome 63から Cross-Origin iframes で MIDIの利用が制限される?

[jsFiddle](https://jsfiddle.net/) 便利ですね！
さきほどの pomidi.js もjsfiddleでテストしてました。

こんな感じのスクリプト書いてWindow 2つ開いて遊ぶ感じです。

- [MIDI送る方](https://jsfiddle.net/x91fqerb/)
- [MIDI受ける方](https://jsfiddle.net/xtp8j9a9/)

> MacでIACを有効にしておくと Window間でMIDI渡せるよー

しかし！
コンソールにこんなメッセージが！

<img width="829" alt="warnning.png" src="https://qiita-image-store.s3.amazonaws.com/0/31758/56666b50-d6c9-7b76-5562-ae7372368161.png">

ええ！？どういうこと！？
Web MIDI APIなんか怒られてる！？ 

なんか見覚えあるような....と思ったら、ここ↓に書いてありました。

https://groups.google.com/forum/#!topic/web-music-developers-jp/zj3EEFQQTx0

MIDIだけでなく、getUserMedia も同じように制限されるようになる模様。

https://sites.google.com/a/chromium.org/dev/Home/chromium-security/deprecating-permissions-in-cross-origin-iframes

まぁ、iframe 経由で Web MIDI API 使うなんてのは普通はやらないので影響ないわけですが、`jsfiddle` で外部jsファイルを読み込むように書いたら、たまたまそういう構造になっていてひっかかった。という話でした。`jsfiddle` 使ってなかったら気づかなかった気がする。

## 気づいたこと 2. なんかエラー?

というか、`requestMIDIAccess()`で見慣れないエラーもでるようになってるぞ。Chrome 62。
`InvalidStateError: Platform dependent initialization failed.`

なんだ？これ。
ちょっとしらべてみると、issueで報告されているようです。

https://bugs.chromium.org/p/chromium/issues/detail?id=718140

どうやら、`chrome://flags/#enable-midi-manager-dynamic-instantiation` が `default` になってると、起こることがある? という雰囲気。(ちゃんと読んでないw)

悩まず `disable` に。→なんとなく起こらなくなった模様。ノープロブレム。

## まとめ。

やはり Web MIDI APIおもしろい。

Chromeでは`WebUSB`も実装されたので、USB経由でいろいろやれる可能性は広がったけど今のところMIDIに合わせこんでいろいろやる方が自分にはちょうどいい。

というわけで、他のブラウザでも早く使いたいので、Edgeに Web MIDI API実装してもらえるようお願いしよう！

https://wpdev.uservoice.com/forums/257854-microsoft-edge-developer/suggestions/6508429-web-midi-api
iPhoneXの画面サイズについて考えてみた。後編！

#実際に作ってみた

[前編](https://qiita.com/ryo-ta/items/b556331411c58dc8b5f0)の続きとなっておりますので、まだみてないよという方は是非・・・。

さて、[初回](https://qiita.com/ryo-ta/items/1dff68458776c0baa193)でAutoLayoutの勉強に使ったアプリを立ち上げてみました！！

...

......

.........


![スクリーンショット 2017-11-29 22.46.59.png](https://qiita-image-store.s3.amazonaws.com/0/206492/2a07ee4c-3f77-f750-320a-a8dfe55ca104.png)

iPhoneXの画面サイズに対応してた。。。

これ、何もソースコードを変更せずビルドを行っただけです。

はい、**AutoLayout**の利点ですね。

まあ若干そうだろうなと予想は付いていましたがｗ
AppleがAutoLayoutを勧める理由もわかりますね。

AutoLayoutは相対的な位置関係を指定し、動的な画面サイズに柔軟に対応させることができます。
そのため、画面比率が大きく変わったiPhoneXでも「いいかんじ」に表示してくれます。

なのでもともとAutoLayoutでデザインされていたアプリはすぐ対応できたんですね！

#じゃあ全部AutoLayoutにしようよ！

と言いたいところですが、世の中そううまくはいかないようで。。。

今回使用したアプリがとてもシンプルな画面でした。
このような場合は制約の指定がしやすく、AutoLayoutに向いていると言えます。

ですが、複雑な画面構成となると多数の要素が密に並びあい、
画面サイズによっては入りきらない、理想の大きさで表示できないなどの問題が発生してきます。

そうなってしまうと、結局コード側で動的に制約を変更する必要があったり、
この場合はこれを表示しないなどの処理が必要となってしまい、
AutoLayoutいらね。
となってしまうみたいですね。。。

#まとめ
要は用途によるってことですね。。。
ちゃんと作りたい物を想定して選別していけるように頑張ろうと思います！
iPhoneX、開発機としても使っていきますよ〜！！

最後までご覧いただき、ありがとうございました！！
【ぶっちゃけiOSアプリ開発】手っ取り早くObjective-cを理解する | その2 クラスの初期化

細かいことや例外的なことは後回しでいいので、手っ取り早くobjective-cを理解して使い始めたいという人向けです。他言語を経験していることが前提です。
その2はクラスの初期化方法です。

#サンプルクラスQiitaTest
コンソールにメッセージ出力するだけのメソッドを実装したクラス。

```objectivec:QiitaTest.h
#import <Foundation/Foundation.h>

@interface QiitaTest : NSObject

- (void)consoleWrite;

@end
```

```objectivec:QiitaTest.m
#import "QiitaTest.h"

@implementation QiitaTest

- (void)consoleWrite {
    NSLog(@"Good Morning!"); // コンソールにメッセージ出力する
}

@end
```
>※NSLog
c言語のprintfみたいなもの。「NS～」という独特のクラスについては別の記事で書く

#クラスを初期化してメソッドを呼び出す
ViewControllerを使った場合。

```objectivec:ViewController.m
#import "ViewController.h"
#import "QiitaTest.h"

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    QiitaTest *test = [[QiitaTest alloc] init]; // クラスを初期化する
    [test consoleWrite]; // メソッドを呼び出す
}

@end
```
実行すると、Xcodeのログに以下のメッセージが出力される。

```
2017-11-29 23:02:10.599 QiitaTest[1186:37521] Good Morning!
```

クラスの初期化は以下の行で行っている。

```objectivec
QiitaTest *test = [[QiitaTest alloc] init];
```
とりあえずクラスを初期化するためには、おまじないのように書いておけば良い。
#クラスの初期化をもっと知りたい人
```objectivec
QiitaTest *test = [[QiitaTest alloc] init];
```
この行は以下のように書き換えられる。

```objectivec
QiitaTest *test = [QiitaTest alloc];
test = [test init];
```
1行目でQiitaTestクラスのallocというクラスメソッドを呼び出し、インスタンス化してtestオブジェクトをメモリ上に確保。
2行目でtestオブジェクトのinitというインスタンスメソッドを呼び出して初期化。
この2行を1行にまとめたもの。

---
ぶっちゃけiOSアプリ開発は、アプリ開発にあたってとりあえず知っておくべきことをズバリ書きます。例外はありますのでご了承ください。
ブロックの構造

今回はブロックチェーンの**ブロックの構造**について紹介します。
できる限り「Short & Simple」を心がけます。
なお、私もブロックチェーン初学者なので、内容に誤り等ありましたらご指摘いただけると幸いです。

## ブロックの構造
ブロックは、大きく分けて２種類のデータで構成されている。

1. そのブロックに関する情報（メタデータ）を含む**ブロックヘッダ**
2. そのブロックに含まれる**トランザクションのリスト**

Bitcoinにおけるブロック構造は以下のとおり。

| サイズ       | フィールド名          | 説明                                                       |
|:------------|:--------------------|:----------------------------------------------------------|
| 4バイト      | Block Size          | この次のフィールドからブロックの最後までのデータサイズ（単位はバイト）|
| 80バイト     | Block Header        | nonceなどブロック自身に関するいくつかの情報                      |
| 1-9バイト    | Transaction Counter | ブロックに含まれるトランザクションの数                           |
| 可変         | Transactions        | ブロックに記録されるトランザクションのリスト                      |

## ブロックヘッダ
３種類のメタデータが含まれる。

1. １つ前のブロックのハッシュ値
2. マイニング競争に関係するメタデータ（difficulty、タイムスタンプ、nonce）
3. ブロック内の全トランザクションを要約した情報（マークルツリーのルートハッシュ）

（「マイニング」や「マークルツリー」については別途記事を書こうと思います。）

Bitcoinにおけるブロックヘッダ構造は以下のとおり。

| サイズ       | フィールド名          | 説明                                                    |
|:------------|:--------------------|:-------------------------------------------------------|
| 4バイト      | Version             | ソフトウェア／プロトコルのバージョン番号                      |
| 32バイト     | Previous Block Hash | 親ブロック（１つ前のブロック）のハッシュ値                     |
| 32バイト     | Merkle Root         | ブロック内の全トランザクションに対するマークルツリーのルートハッシュ |
| 4バイト      | Timestamp           | ブロックの生成時刻                      |
| 4バイト      | Difficulty Target   | ブロック生成時のproof of workのdifficulty |
| 4バイト      | Nonce               | proof of workで用いるカウンタ|

## ブロックのハッシュ値
ブロックに関する情報の中で最も重要なものの一つとして**ブロックハッシュ**がある。
これは、ブロックヘッダに対してSHA-256（ハッシュ関数）アルゴリズムを用いて２回ハッシュ化して得られる32バイトの値であり、各ブロックにユニークに与えられる識別子である。
*※ハッシュ値の計算のインプットには「ブロックヘッダのみ」が利用される*


なお、Bitcoinにおける最初のブロック「genesisブロック」のハッシュ値は以下である。

```
000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
```

## 参考文献

- [Mastering Bitcoin](https://www.amazon.co.jp/ビットコインとブロックチェーン-アンドレアス・Ｍ・アントノプロス-ebook/dp/B072JJL66R/ref=sr_1_2?s=digital-text&ie=UTF8&qid=1511787188&sr=1-2&keywords=mastering+bitcoin)
パブリックチェーンとプライベートチェーン

今回はブロックチェーンのパブリック型とプライベート型（おまけ程度にコンソーシアム型も）について紹介します。
できる限り「Short & Simple」を心がけます。
なお、私もブロックチェーン初学者なので、内容に誤り等ありましたらご指摘いただけると幸いです。

## パブリックチェーンとプライベートチェーンの違い
一言で言うと**「ネットワークに参加しているノードの数を把握できるか否か」**。

- パブリックチェーンは**把握できない**

- プライベートチェーンは**把握できる**

この違いにより生まれる差は「合意形成の方法」、特に**「誰が」合意形成するか**。

- パブリックチェーンは**不特定多数のノード** *（→中央管理者が存在しない）*

- プライベートチェーンは**特定のノード** *（→中央管理者が存在する）*

（「合意形成」に関しては別途記事を書こうと思います）

## パブリックチェーン
### パブリックチェーンのメリット

- **不特定多数がネットワークに参加しても合意形成が実現**できる（ビザンチン将軍問題を解決できる）
- **公共性、真正性**を備えている

### パブリックチェーンのデメリット

- 合意形成にあたり、膨大な計算を行うための**「時間」「マシンパワー」「電力」が必要**

### パブリックチェーンの例
- Bitcoin
- Ethereum
- nem


## プライベートチェーン
### プライベートチェーンのメリット

- **迅速な合意形成**が可能（信頼できる限られたノードで合意形成を行うため）
- マイニング報酬などの**インセンティブが不要**

### プライベートチェーンのデメリット

- **ネットワークが拡大するほど性能低下**に陥りやすい
- ネットワーク規模を拡大できないことにより、**「ゼロダウンタイム」性能が多少犠牲**となる

### プライベートチェーンの例
- Ethereum
- Hyperledger Fabric
- Corda
- mijin

## コンソーシアムチェーン
中央管理者が存在するという点でプライベートチェーンの仲間と言えるが、
プライベートチェーンは１つの企業や単一組織内など、単一の管理主体で運用するのに対し、
コンソーシアムチェーンは複数の企業や組織など、**複数の管理主体で運用**するブロックチェーン。
プライベートチェーンに比べ、データの改ざん難易度が高く検閲耐性が高いと言える。

### コンソーシアムチェーンの例
- Hyperledger Fabric
- Hyperledger Iroha


## 参考文献
- [いちばんやさしいブロックチェーンの教本](https://www.amazon.co.jp/いちばんやさしいブロックチェーンの教本-人気講師が教えるビットコインを支える仕組み-「いちばんやさしい教本」シリーズ-杉井靖典-ebook/dp/B075CFG2TY/ref=sr_1_1?ie=UTF8&qid=1511787155&sr=8-1&keywords=いちばんやさしいブロックチェーンの教本)
- [パブリックチェーンとプライベートチェーンの違いとは？](http://businessblockchain.org/differenece-between-public-chain-and-private-chain)
- [複数の管理主体により共同で運用されるブロックチェーン「コンソーシアムチェーン」](http://gaiax-blockchain.com/consortium-chain#i-2)
React-navigationで２重遷移を防ぐ (with Redux)

### はじめに

Reduxで管理するまでは↓の方法で2重遷移を防いでいましたが、reduxを入れた時にエラーになってしまったのでその時の対応
https://qiita.com/kuniiskywalker/items/dc26acc97e6009c92a3f
https://qiita.com/ozaki25/items/ec9ec9459b12453339cc

### 結論

`return null` ではなく `return state`で期待した動作になった。

動作としてはnavigationが連打されいているが、stateが同じなので1画面しか進まない、、よう
若干不安なのでつっこみお待ちしています
![image.png](https://qiita-image-store.s3.amazonaws.com/0/206623/cb6a42c5-f0f5-725a-fc47-8326146fe1ad.png)


全文

```js

const original = AppNavigator.router.getStateForAction
AppNavigator.router.getStateForAction = (action, state) => {
  if (state && action.routeName === state.routes[state.index].routeName) {
    return state
  }

  return original(action, state)
}
```



##### APPENDIX:
https://github.com/react-community/react-navigation/issues/271
【Python】OpenCVでウィンドウ位置変更

OpenCVで表示したウィンドウの位置変更方法。
ちょいちょい忘れるため、投稿。。。

ソースコードは以下。

```py
    cv2.imshow('window name', frame)
    
    # Window位置の変更　第1引数：Windowの名前　第2引数：x 第3引数：y
    cv2.moveWindow('window name', 100, 200)
```

以上。
[Unity]BGMをシームレスに切り替える

【マリオカート８】スカイガーデン　切り替わりBGM
http://www.nicovideo.jp/watch/sm24324337

こーいうのやるとき用のメモ。
マリカーでは雲の中に入った時に曲がスッと切り替わってました。カッチョイイ

# 再生デモ

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">BGM切り替え。マリカのスカイガーデンBGMでやってみた<br>AudioSource２つ再生させてるのってぶっちゃけ負荷的に良くない気がしてるけどとりあえず <a href="https://t.co/CvSTOUsBxc">pic.twitter.com/CvSTOUsBxc</a></p>&mdash; 白金バーガー (@flankids) <a href="https://twitter.com/flankids/status/935858983809589248?ref_src=twsrc%5Etfw">2017年11月29日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

こんな感じで、MixRateという変数で管理。実際にはゲーム内の状況を監視して切り替える別なマネージャーから操作するようにすべきかと。


# 実装

```csharp:FrontBoundsObject.cs
using UnityEngine;

public class SwitchAudio : MonoBehaviour {
	[SerializeField]
	private AudioSource[] _audios;

	/// <summary>
	/// BGMの混ぜ具合。0ならSound1、1ならSound2になる
	/// </summary>
	[Range(0, 1)]
	public float _mixRate = 0;

	public void Play() {
		_audios[0].Play();
		_audios[1].Play();
	}

	private void Update () {
		_audios[0].volume = 1f - _mixRate;
		_audios[1].volume = _mixRate;
	}
}
```

　
▼コンポーネント設定はこんな感じ

![キャプチャ.JPG](https://qiita-image-store.s3.amazonaws.com/0/184294/3744da7e-16b7-83c4-e9de-ab92937ec654.jpeg)

Sound1、Sound2にそれぞれAudioSouceコンポーネントを設定し、再生したいサウンドファイルを入れてます。
AudioSouceコンポーネントの取得方法や、AudioClipの設定方法は適宜カスタムという感じで（直接入れるのはダサいので）

※注意点１
AudioSouceコンポーネントはInspector上でどちらも「Play On Awake」を false にしてます。
Playメソッドを使って再生開始。Play On Awakeに任せると、読み込みで再生タイミングがズレそう。

# 課題点
#### １．負荷
２つのAudioSourceが常時再生されてるのは負荷的にアレだと思うので、せめてMixRateが 0 or 1 のときはもう一方のAudioSourceの再生を止めるべきかと
0 < MixRate < 1 のときは、再生中のAudioSourceの再生時間（time）を止めていたほうに反映して、すぐに同期を取るようにすれば大丈夫そう

#### ２．３つ以上のAudio管理
AudioClipの参照を持たせておけば、AudioSouce２つのままで実現できそう。ただし、同時再生は２曲までで、切り替え対象を３つ以上、という仕様に限る。
実装する場合、1 or 0 のときに再生されてない方のAudioSourceに遷移対象のClipを設定する感じになるかと

# こぼれ話
ストリートファイターVのBGM切り替え表現もやってみたい

ステージごとに６種類の曲が用意されていて、

・１ラウンド目
・１ラウンド目 - どちらかの体力が一定以下
・１ラウンド目終了（ME）
・２、３ラウンド目
・２、３ラウンド目 - どちらかの体力が一定以下
・決着（ME）

という感じで構成されてます。
それぞれ、記載してる状況になると自動的に曲が切り替わるんですが、クロスフェードではなく、曲の拍（テンポ）を見て良きタイミングで切り替わっていて、対戦開始～終わりまで一つの長い曲に錯覚するような仕組みになってます。

この動画の１試合目の滝ステージの曲が好き
https://youtu.be/v4MhhIMZKEo?t=25s

バラして並べてある動画上がってました
https://www.youtube.com/watch?v=u0-Szhv5B40

こういうのってCRIWAREとかにサクッと実装できる機能があったりするのかな・・・？
お手製でやるとしたらBPMをサウンドクリエイターから聞いて、条件を満たしていて、かつBPMから計算した"切り替えしてよい拍"でパッと切り替えるようにする感じになるかな
【Python】OpenCVで疑似カラー(Pseudo color)

グレースケール画像に疑似的な色を付けることを疑似カラーと言います。
以下のようなデータがあった場合に、視覚的に分かりやすい表現が出来ます
　・深度センサー（KinectやRealSenseやXtion等のDepthカメラ)
　・サーモグラフィー
　・照明ムラ
　　など

OpenCVに疑似カラーを付けるAPI（applyColorMap()）があったため、本投稿にメモ。

動画は以下。
https://www.youtube.com/watch?v=iOeULBjR7Jk
[![【Python】OpenCVで疑似カラー(Pseudo color)
](https://img.youtube.com/vi/iOeULBjR7Jk/0.jpg)](https://www.youtube.com/watch?v=iOeULBjR7Jk&feature=youtu.be)



ソースコードは以下。
本来ならサーモグラフィー等の画像を取り込みたいところですが、
Webカメラしかなかったので、グレースケール画像を取り込んで疑似カラーを付けてます。
色々なパターンがあるため、N押下で切り替えれるようにサンプルを作成。

```py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import numpy as np
import cv2
import copy

colormap_table_count = 0
colormap_table = [
    ['COLORMAP_AUTUMN',  cv2.COLORMAP_AUTUMN ],
    ['COLORMAP_JET',     cv2.COLORMAP_JET    ],
    ['COLORMAP_WINTER',  cv2.COLORMAP_WINTER ],
    ['COLORMAP_RAINBOW', cv2.COLORMAP_RAINBOW],
    ['COLORMAP_OCEAN',   cv2.COLORMAP_OCEAN  ],
    ['COLORMAP_SUMMER',  cv2.COLORMAP_SUMMER ],
    ['COLORMAP_SPRING',  cv2.COLORMAP_SPRING ],
    ['COLORMAP_COOL',    cv2.COLORMAP_COOL   ],
    ['COLORMAP_HSV',     cv2.COLORMAP_HSV    ],
    ['COLORMAP_PINK',    cv2.COLORMAP_PINK   ],
    ['COLORMAP_HOT',     cv2.COLORMAP_HOT    ]
]

video_input = cv2.VideoCapture(0)

while(1):
    ret, frame = video_input.read()

    # グレースケール化
    grayscale_image = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    
    # 疑似カラーを付与
    apply_color_map_image = cv2.applyColorMap(grayscale_image, colormap_table[colormap_table_count % len(colormap_table)][1])

    cv2.putText(apply_color_map_image, colormap_table[colormap_table_count % len(colormap_table)][0], (20, 40), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0,0,0),2);
    cv2.imshow('apply_color_map_image',apply_color_map_image)

    k = cv2.waitKey(50) & 0xff
    if k == 110: # N
        colormap_table_count = colormap_table_count + 1
    if k == 27:  # ESC
        break

video_input.release()
cv2.destroyAllWindows()

```

以上。
No storyboard with Swift(Storyboard無しの場合)

#An App Delegate class with no storyboard
[AppDelegate.swift](以下のように修正）

```
import UIKit
@UIApplicationMain
class AppDelegate : UIResponder, UIApplicationDelegate {
 var window : UIWindow?
 func application(application: UIApplication, 
      didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?)
      -> Bool {
           self.window = UIWindow()
           self.window!.rootViewController = UIViewController() // 適用したいViewController
           self.window!.backgroundColor = .white
           self.window!.makeKeyAndVisible()
           return true
   }
}


#Subview and Superview
  func application(application: UIApplication,
            didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?)
            -> Bool {
                self.window = UIWindow()
                self.window!.rootViewController = UIViewController()
                // subviewsの追加ができる
                let mainview = self.window!.rootViewController!.view
                let v = UIView(frame:CGRectMake(100,100,50,50))
                v.backgroundColor = .red // 小さい四角
                mainview.addSubview(v) // main viewに追加
                self.window!.backgroundColor = .white
                self.window!.makeKeyAndVisible()
                return true
}
```
PHPでディレクトリを削除

scandirやopendirを使う方法等もありますが、globが見易そうでしたのでglobを使って行う方法です。

フレームワーク側に実装されていることもあるので確認することをお勧めします。


```php
/**
 * 指定したディレクトリを削除する
 *
 * @param string $directory_path
 * @return boolean
 */
public function remove_directory(string $directory_path): bool
{
    if ( ! is_dir($directory_path))
    {
        return false;
    }

    foreach (glob($directory_path . '/{*,.[!.]*,..?*}', GLOB_BRACE) as $path)// .と..以外の隠しファイルも対象とする
    {
        if (is_file($path))
        {
            if ( ! unlink($path))
            {
                return false;
            }
        }
        elseif (is_dir($path))
        {
            if ($this->remove_directory($path) === false)
            {
                return false;
            }
        }
    }

    return rmdir($directory_path);
}
```

globはファイルを検索する際に重宝します。

```php
$txt_file_list = glob('document/*.txt');
```

http://php.net/manual/ja/function.glob.php

`exec()`でrmコマンドを使った方がワンライナーで実現できるので楽だと思います。コピーに関してもcpコマンドを使った方が同様に楽だと思います。

```
# 削除
rm -rf name

# コピー
cp -arf source dest
```

http://php.net/manual/ja/function.exec.php
Ghost Version 1での日本語入力の不具合で困ってます

Ghostのユーザーはご存知だと思いますが、Ghostは2017年7月か8月にVersion 1にメジャーアップデートしました。

私のブログ [https://www.kosukemaeda.com/](https://www.kosukemaeda.com/) はGhost.org（有料のGhostホスティング）を使っています。

最近、GhostをVersion 1.18.0にアップデートしたら、次のようなIMEの位置がおかしい不具合が出るようになりました。

![weird-ime-behavior.gif](https://qiita-image-store.s3.amazonaws.com/0/197109/908caa7c-0028-9994-de83-aaa1eaf4dba4.gif)

日本語を入力すると現れる「変換リスト」が書いている文字の真上に現れてしまうので、文章がすごい書きづらいです（泣）。

環境はChrome / Windows 10です。

サポートとメールでやりとりしても解決できないし、GitHubにIssueを開きました。

[Incorrect Japanese IME popup position · Issue \#9289 · TryGhost/Ghost - GitHub](https://github.com/TryGhost/Ghost/issues/9289)

Google日本語入力とChrome、Google日本語入力とEdge、Microsoft IMEとChromeでの組み合わせでも同じ不具合があります。
Ghost.orgのサポートがMacで試すと正常だったとのことです。
GhostのエディタはCodeMirrorを使っていて、CodeMirror単体では問題ありませんでした。

[Web技術と親しむ : Ghostで少しだけ日本語を打ちやすくする](http://il-sus-web.net/archives/63385949.html)に似たようなトラブルを解決した話があるのですが、私の手に負えません…

GitHubにIssueを開いてすぐに返信くれた方によるとCSS周りに問題があるそうです。でも、IMEでテストできる環境がないからよくわからないとか言っています。IMEを使う言語圏のコントリビューターがGhostにはいないみたい。

あと、Ghost.orgはVersion 1にメジャーアップデートしたら、メジャーバージョンのダウングレードはできないとサポートに言われました（悲）。

誰か直せますかー？？

インターネットにこの情報がまるでないんですが、日本人はGhost使っている人少ないんですか…？私以外に誰も困っていないの？Macだと問題ないみたいだからかなぁ。

### その後の進展について（2018年1月5日）

@tamurashingo@github さんがGitHubにプルリクエストを開いてくれました。

[Fixed Japanese IME popup position by tamurashingo · Pull Request \#940 · TryGhost/Ghost\-Admin · GitHub](https://github.com/TryGhost/Ghost-Admin/pull/940)

すごいと思います。私にはできないことです。感激しました。ありがとう！
curry化と部分適用の違いを自分なりにまとめてみる

関数型プログラミングでおなじみのcurry化。
部分適用と何が違うの？　とずーっと悩んできて、やっとなんとか整理がついたような気がするので自分用にまとめみてみます。
言語はjavascriptをチョイスしましたが、言語に特別依存する概念ではありません。

# お題: 2つの値を掛け算する関数multiply

```js
var multiply = function(x, y){
    return x * y;
};

console.log(multiply(4, 5));
20
```

涙が出るくらい簡単ですね。これをcurry化します。

curry化とは、複数引数の関数を**1引数**の関数の**組み合わせ（合成関数）**に書き直すことです。
`multiply` の場合こんな感じになります。

```js
var multiply = function(x){
    return function(y) {
        return x * y;
    }
};
```

curry化された `multiply` は　直接的には1引数の関数になりました。更に返り値が（1引数の）関数になっています。
このcurry化された `multiple` を使用するときには引数を**1つずつ**渡す必要があります。

```js
console.log(multiply(4)(5));
20

console.log(multiply(4, 5));    // multiple()は1引数の関数になったので、5が無視されていることに注意。
ƒ (y) {
    return x * y;
}
```

# curry化のメリットは？
関数の部分適用（複数引数の関数の一部を固定化して引数を減らした関数を作ること）がしやすくなります。

curry化した `multiply` では第1引数を `4` に固定（部分適用）して、与えられた値を4倍する `multiple4` が簡単につくれます。

```js
var multiply4 = multiply(4);
```
自分で新しく関数を定義しなくても良いのがポイントです。 `multiply` は関数を返す関数なんだから当然ですね。

curry化されていない場合に部分適用するには、自分で新しい関数を定義しなければいけません。

```js
var multiply4 = function(y){
    return multiply(4, y);
}
```

結果はどちらも同じです。

```js
console.log(multiply4(5));
20
```

# 関数型プログラミングで currey化が重要なのは？
関数型プログラミングでは関数を組み合わせて目的とする合成関数を作っておいて、そこに値を流し込んで求める結果を得るということを重視します。
unixシェルプログラミングでコマンド（フィルタ）をパイプでつないでパイプラインを作るのと似てますね。

これが可能なのは、各コマンドが1つの標準入力から値を受けて、1つの標準出力に結果を流すというインターフェイスが決まっているからです。
関数型プログラミングも同じで、引数（入力）が複数あると前の関数の戻り値（出力）が受け取りにくくなります。そこで、1引数の関数に分解（curry化）するとインターフェイスが単純になって合成関数が簡単に組めるようになるのです。

# まとめ
- 部分適用とは、複数引数の関数の一部を固定化した関数をつくること。
- curry化とは、複数引数の関数を1引数の関数に分解すること。
- curry化すると部分適用が瞬殺で作れるよ。
- curry化すると関数の合成が簡単になるよ。


…間違いがあったらすまん。
iPhoneXの画面サイズについて考えてみた。前編！

#動機

iPhoneXが発売されてからもうすぐ1ヶ月ですね！

赤外線による深度センサーや有機ELディスプレイ、
そして今までとは画面サイズが異なり、ベゼルレスデザインとなりました。

かく言う私も発売日に無事、iPhoneXをゲットしたので、
1ヶ月弱使用して疑問に思ったことを解いてみたいと思います。

後半では実際にコーディングで違いを体験してみようかと！

#気になったこと。
画面のアスペクト比が従来の16:9ではなく、縦に1.2倍ほど長くなっています。

なんとアスペクト比は812:375らしい…。（よくわからん）

2:1よりちょっと縦に長いぐらいですね。
それによって従来のiPhoneよりも情報を表示できる領域がかなり増えました。

ですが、非対応アプリでは上下に黒い帯が表示されてしまうんですね。

＊非対応アプリ例
<img width="375" alt="BF395331-736A-4BE1-8F69-FB5D052282E2.jpeg" src="https://qiita-image-store.s3.amazonaws.com/0/206492/7f254903-2b93-5a2b-c2b0-0ff48d29077b.jpeg">

こうみると表示できていない部分ってかなりあります。
私も対応していないアプリを使うと、もったいないなと思ってしまいます。
せっかくなら全画面有効に使いたい！と思いますしね。


次に対応アプリの例です。
＊対応アプリ例
<img width="375" alt="2C95A1D9-5FB1-433E-934E-77E3BF0B9E32.jpeg" src="https://qiita-image-store.s3.amazonaws.com/0/206492/844d3c38-d9ef-c98c-3d54-7a13ebeb241d.jpeg">
上下しっかり表示されていますね。
一度にたくさんの情報を表示できるので、非常にありがたく感じました。

#自分でやるよ。
冒頭にも申し上げたようにもうすぐ1ヶ月です。

対応していたアプリは初日から対応していました。
ですが、今現在メジャーなアプリなのにまだ対応していないアプリもちらほらと…。

iOSの知識がないので間違っているかもしれませんが、
デザイン方法によって自動、もしくは簡単に対応できる場合と、
なかなかてこずってしまうパターンがあるのかなと。。。

まぁ文句言うなら自分で試してみよう！

ということで自分のiPhoneXで試してみたいと思います！！



〜後編に続く〜
RSpecの１対多をスッキリ書く方法

# はじめに
RSpecを書く時に、１対多や多対多のリレーションのテストコードを書かないといけないことがあるかと思うのですが、Qiitaや日本語のサイトにスッキリとしたいいものが掲載されていなかった（少なくともすぐには出てこなかった。たぶん。）ので今回書くことにしました。
**今回は親子の親のmodelやcontrollerに記述する方法です。**
子の方に記述する場合はassociationを使う方法で問題ないかと思います。
# よくある書き方
 ```rb
before do
        create_list(:(親子の子に当たるオブジェクト))
      end
 ```
```rb
after(:create) do |hoge|
      create_list(:hoge, 3, hoges: [hoge])
    end
```
のようなbeforeやafterで子を呼び出して書く方法がよく見受けられました。それでやってもなんか上手くいかなかった。(これに関しては自分に原因があると考えている)

# 今回書く書き方
 ```ruby:(親に当たるオブジェクト).rb
describe 'Relations' do
    let!(:(親に当たるオブジェクト)) {FactoryGirl.create(:(親に当たるオブジェクト))}
    before { FactoryGirl.create(:(子に当たるオブジェクト), date: '2017-11-22', （親に当たるオブジェクト): (親に当たるオブジェクト))}

it 'should have (親に当たるオブジェクト) with (子に当たるオブジェクト)' do
  hoge = (親に当たるオブジェクト).(子に当たるオブジェクト).first
      expect(hoge.date.to_s).to eq '2017-11-22'
    end
  end
 ```
これの方が書く分量もいらなくてシンプルです。また今回はcreateの前にFactoryGirlと書いていますが、

 ```ruby:spec_helper.rb
config.include FactoryGirl::Syntax::Methods
```
で書く必要がなくなるので合わせて知っておくといいかと思います。
SQLが変われば、フロントも変わる

バックエンドにRDBMSを使うアプリケーションにとって、SQLのチューニングは重要だけど放置されることが多いものだったりもします。その理由としては、

* そもそも、SQLを使いこなせるレベルの知識・能力がない
* （特に、フレームワークの中から使う場合）ORMオブジェクト⇔SQL⇔DBアクセスと変換が入るので、やりたいことを制御しづらい

などがあります。とはいえ、画像処理などを除けばWebアプリの大きな時間を占めるのはデータベースアクセスですし、ときに僅かなチューニングが、数十倍の速度差になるなど劇的な効果をもたらすこともありますので、やはり重要となります。

# 遅い箇所を洗い出す

データベースの速度を調べるにはいくつか方法があります。

まずは、「実際にSQLを投げてみる」というのが簡潔な手段です。何も仕掛けていない本番サーバで速度を知りたい場合、このような原始的な手段が必要となることがあります。

そして、1秒以上かかるような、絶対的に長時間のクエリに対しては、スロークエリログを仕掛ける、という方法があります。バッチで長時間のクエリが必ず発生する、という条件だとそれがじゃまになることもありますが、どこで発生しても取れる、というのはいいところです。

あと、本番環境では難しいのですが、フレームワーク内で使えるプロファイラが存在する例も多いです。Railsでも、`rack-mini-profiler`のような、各SQLの時間まで取れるプロファイラがあります（[参考](https://qiita.com/TakakiSato/items/e0b2a215247eacd06d7a)）。

# 実際に高速化した例

いま進行中のプロジェクトから抜き出した例ですが、やはり検索画面で一覧生成となると、書き方を間違えればあっという間に0.5秒を突破するような長時間クエリとなります。

* スロークエリを見ていたところ、検索画面に使われているクエリに数十秒、なんていう凄まじい時間がかかっていてまずい状況となっていまいた。調べてみたところ、Eager Loadのために行っていたJOINで、STIのためにJOINする側のテーブルに条件がかかっていたのに引きずられて、必要以上の列を一時テーブルで生成してしまっていることが判明しました。このテーブルをJOINせず、eager loadを`preload`で行うようにした結果、クエリ時間が0.2秒まで改善しました。
* これまた同じ画面で、ページのリクエストタイムが1秒弱になっていたので追いかけてみたところ、`DISTINCT`のための結果生成に時間がかかって、クエリの処理が0.4秒以上かかっていることに気づきました。調べれば、`DISTINCT`をかける前から1件しかありえなかったので外したところ、それだけでクエリ実行は0.1秒を切るようになりました。

# クエリ自体を削る
`FOREIGN KEY`などの関係上で、マスターもDBに持たせることが多いですが、このあたりはかんたんに変わらないので、（更新時にキャッシュクリアするフックをつけて）長期キャッシュにしておけば、そもそも最初以外はDBを叩く必要もなくなります。