OmniAICreator/Qiita-1.07M huggingface dataset:
iOSをSwiftを使って開発するにあたって必要な項目まとめ

# 前提

iOSの知識やSwiftを触ったことないよ何から勉強したらよいの？という人向けです。
Swiftの言語使用というよりはiOS自体の知識 +α Swiftで学習すべきことです。

# 学習項目

* Swiftの構文
    * 変数、定数の宣言
        * var　と　let
        * 非オプショナル型、オプショナル型、暗黙的アンラップ型の違い
    * if let と guard let 構文(オプショナルバインディング)
    * クロージャの書き方(Objective-Cだとブロック)
    * デリゲートの利用

* メモリに関して
    * メモリリーク
    * 強参照、弱参照(ここを学習してデリゲートをweakで宣言しなければならない理由を理解する)
    * クロージャのキャプチャについて(weak self を利用する理由を理解する)
* Xcodeでメモリリークを検知する(Instrumentsの使い方)

* TableViewの利用（特別大事なのでUIの作り方から独立して切り出しました）
   * Cellの再利用
   * CustomCellの利用
   * UITableViewDelegate と UITableViewDatasource　の役割(デリゲートメソッドがどんな機能を持つか)
   * セルの高さを可変にする
   
* UIの作り方
    * Storyboardの利用
    * xibの利用
    * オートレイアウトで制約を付ける(画面回転や端末サイズに依存せず自動的にレイアウトが変化するようにする)
    * IBパーツをカスタムクラスにIBOutlet, IBActionとして紐づけてコードで処理できるようにする
    * 画像リソースをAssetsを利用して設定する
    * @1x, @2x @3x などのレティーナディスプレイ対応をする
    * スプラッシュ画面の設定
    * アプリアイコンの設定
    * UITabBarControllerの利用(よくある下にタブあって画面切り替えれるやつ)
    * UINavigationControllerの利用(タイトルの表示や左上の戻るボタンがデフォでついてる領域を提供するVC)

* 通信について
    * Alamofire + Codable で通信で取得したデータをEntityにマッピングする(アプリ内で扱えるようにパースする)
    * NSURLConnection, NSURLSessionについて
    * UIWebView, WKWebView, SafariView（それぞれどんな違いあるか）
    * 通信で取得したデータをTableViewやCollectionViewに表示させる
 
* MVCモデルについて
    * Model
        * Entity
        * Featcher
        * Manager
   * View
   * Controller

* UIViewControllerのライフサイクル
* GDC(非同期処理)
    * DispatchQueue

* 証明書の紐づきと役割
    * Developer証明書
    * Distribution証明書
    * プロビジョニングプロファイル
    * App IDs
    * APNs証明書
        * プッシュ通知の仕組みと実装

* iOSアプリの配布方法
    * Ad-Hoc
    * In-House
   

* 各種識別子
    * UDID
    * UUID

* テスト用に配布するツール
    * TestFlight
    * Deploygate

* ライブラリの導入ツール（以下どちらでも好きなほう）
    * Cocoapods
    * Carthage

* プリプロセッサマクロの利用
* デバッグ方法
    * ブレークポイントの付け方
    * po コマンドの利用
* 実機デバッグの仕方
* リリースの仕方
    * AppStoreConnectについて
        * App内課金のアイテム作成と実装
        * 申請時に必要なAppStoreメタデータ(説明分やスクリーンショット)
    * アプリ固有のBundle ID
    * ipa作成の仕方
    * XcodeからAppStoreConnectにipaをアップロード

# あとがき

まだまだいろんな項目あると思うのですが、ぱっと思いつかないので随時更新する可能性があります。
また、参考リンク等を追加したりチェックリスト式にしたりしたかったのですが余裕がなく一旦はこのままです

**編集リクエスト大歓迎ですので参考リンクいっぱいください。**
SwaggerのSpecのYAMLファイルをHTMLに変換する

![screenshot-1.png](https://qiita-image-store.s3.amazonaws.com/0/47327/79bef45f-b1cb-7e09-888a-7de8cc557bee.png)

# 変換

```bash
docker run -i yousan/swagger-yaml-to-html < petstore.yaml > petstore.html
```

# 経緯など

SwaggerHubで作成されるHTMLがいい感じだったんですが、ウェブでファイルを管理するのが大変だなと思っていて、Gitでyamlファイルを管理しつつ、HTMLに生成できないかなと思っていました。

調べてもなかなか情報が出てこなかったんですが、Pythonのスクリプトを発見しました。

https://github.com/yousan/swagger-yaml-to-html/blob/master/swagger-yaml-to-html.py

原理としてはすごく単純で、SwaggerHubのHTML＋JavaScriptを読ませていて、YAMLの実体をJSONに変換して読み込ませています。

これがPython環境だったので簡単なものですがDocker化してみました。

あとはこれでYAMLを管理しているGitで変換かけるスクリプトを置くと良いです。

## というか結構あった
それなりにググってたつもりだったんだけど、「swagger yaml html」だと結構あった…。
https://qiita.com/nmatsui/items/ed9ae462141eeadb6f6a
https://qiita.com/mokkos/items/3dc977b8b231adbbedf7
https://iktakahiro.hatenablog.com/entry/2016/11/23/100000

# オンラインでやりたい

というかこういう簡単な変換系でもPythonとかNodeが必要なものって結構あるじゃないですか。そういうのをオンラインでURLベースで変換できるサービス群作りたいですね。
/usr/libexec/java_home がいい子すぎる件

## ことのはじまり
MacBookProを新調しました。改めてOracleの公式dmgからJavaのいくつかのバージョンをインストール。`JAVA_HOME`を利用してパスを通そうとしたそのとき。。

**さっきインストしたやつらどこいった!?**

ちなみにこれは、下記ディレクトリに各バージョンがインストールされます。

```text:Javaのインストール場所
/Library/Java/JavaVirtualMachines/
```

## `/usr/libexec/java_home` 半端ないって  
以前は毎度あくせくググっていた(~~メモっとけ~~)が、とっても便利なコマンドがあることを知りました。
`/usr/libexec/java_home -V` でインストール済`Java`の場所リストを表示してくれます。

```shell:/usr/libexec/java_home
$ /usr/libexec/java_home -V
Matching Java Virtual Machines (4):
    10.0.2, x86_64:	"Java SE 10.0.2"	/Library/Java/JavaVirtualMachines/jdk-10.0.2.jdk/Contents/Home
    1.8.0_181, x86_64:	"Java SE 8"	/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home
    1.6.0_65-b14-468, x86_64:	"Java SE 6"	/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
    1.6.0_65-b14-468, i386:	"Java SE 6"	/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
```

## `JAVA_HOME`には小文字
お望みのversionのJavaを利用するには、パスを通す必要があります。見通しの良さのために`JAVA_HOME`をexportしてからパスに含めましょう。
だけどフルパス指定するの面倒。しかも切り替える可能性がある場合などは、もう毎度面倒。
そんなときは、`-v(小文字)`オプションを付けましょう。指定の`Java`バージョンのパスのみを表示してくれます。
単体でコマンド打つとこのように表示されます。

```shell:-v
$ /usr/libexec/java_home -v 1.8
/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home
```

## exportするときは
`.bash_profile`、`.zshrc`などで利用するときは、

```shell:.bash_profile
export JAVA_HOME=`/usr/libexec/java_home -v 10`
export PATH=$JAVA_HOME/bin:$PATH
```
のように記述することができます。これならバージョンを切り替えたいときもすごく簡単。
しかも、java10を指定したいときは、`-v 1.10`、`-v 10`どちらでも認識してくれるいい子っぷりで泣けます。

## Javaのパスを通すときまとめ
- インストール済の`Java`のインストール場所がわからなくなったら**V(大文字)**オプション

```shell
$ /usr/libexec/java_home -V(大文字)
```

- パス通すときは`JAVA_HOME`使う
- Javaのパスは**v(小文字)**オプション

```shell
export JAVA_HOME=`/usr/libexec/java_home -v 10`
export PATH=$JAVA_HOME/bin:$PATH
```

参照：https://qiita.com/ryo0301/items/3c9a02e03b4e9a41f576
django-axesの機能でログイン失敗した場合のロックアウトを無効化したい

Djangoでadminサイトを構築、django-axesを追加してログイン機能を実装していると
指定の回数ログインに失敗するとアカウントをロックアウトすることができます。

これ自体は全然構わないんですが、脆弱性診断を頼んでいるとかなんとかで
一時的にロックアウトされると困るなー……みたいなピンポイントな状況があったりなかったり。

django-axesの最新版 4.4.0 で書いています。

# Axesの制御について
まぁ大体は[ドキュメント](https://django-axes.readthedocs.io/en/latest/configuration.html#customizing-axes)に書いてあります。

https://django-axes.readthedocs.io/en/latest/configuration.html#customizing-axes

## AXES_FAILURE_LIMIT
ログイン失敗時にN回目でロックアウトさせます。
デフォルトは3回です。

## AXES_LOCK_OUT_AT_FAILURE
この項目がTrueの場合にAXES_FAILURE_LIMITの件数を超えるとロックが有効になります。
デフォルトはTrueです。

## ロックアウトを無効化するには
基本的に上記の項目を、djangoのsettings.pyに追加・設定してあげればOKです。
AXES_FAILURE_LIMITは物凄い大きい数にするか、AXES_LOCK_OUT_AT_FAILUREをFalseにすれば事足りるかと。
後はユーザ情報を管理するModelにnolockoutのattributeを追加してあげてもいい感じなんですが、ちょっとこっちはまだ未検証です:sob:

# 最後に

[株式会社ネコカリ](https://www.nekokari.co.jp/)では猫の手も借りたい🔥炎上中🔥なお仕事を募集しています！
一緒に働くメンバーも募集していますので、よかったら是非！
『増補改訂版Java言語で学ぶデザインパターン入門』をKotlinでやってみる（Template Method編）

## 【経緯】
[『増補改訂版Java言語で学ぶデザインパターン入門』をKotlinでやってみる](https://qiita.com/siroykht/items/f67b2c111e9b3b424f1e)の第三回目。
今回はTemplate Methodパターンです。

## 【コード】
Template Methodパターンは割とイメージしやすいですね。言葉のまんまですし。
スーパークラスで処理のテンプレートとなる枠組みを定義して、サブクラスでその具体的な内容を実装するデザインパターンです。
スーパークラス側で枠組みを定義するので、サブクラスから意識しなくてもロジックの共通化を行えるのが大きな利点かなと思います。

```kotlin:AbstractDisplay.kt
abstract class AbstractDisplay {
    // 抽象クラスメソッド
    abstract fun open()
    abstract fun print()
    abstract fun close()

    final fun display() {
        open()
        for (i in 0..4) {
            print()
        }
        close()
    }
}
```

```kotlin:CharDisplay.kt
abstract class AbstractDisplay {
class CharDisplay(char:String) : AbstractDisplay() {
    private var ch:String = char

    override fun open() {
        Log.d("CharDisp", "<<")
    }

    override fun print() {
        Log.d("CharDisp", ch)
    }

    override fun close() {
        Log.d("CharDisp", ">>")
    }
}
```

```kotlin:StringDisplay.kt
class StringDisplay(string:String) : AbstractDisplay() {
    private var str:String = string
    private var width:Int = str.toByteArray().size

    override fun open() {
        printLine()
    }

    override fun print() {
        Log.d("StringDis", "|" + str + "|")
    }

    override fun close() {
        printLine()
    }

    fun printLine() {
        Log.d("StringDis", "+")
        for (i in 1..width) {
            Log.d("StringDis", "-")
        }
        Log.d("StringDis", "+")
    }
}
```

```kotlin:MainActivity.kt
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        var chDisplay:AbstractDisplay = CharDisplay("H")
        var strDisplay:AbstractDisplay = StringDisplay("Hello, world.")
        var jStrDisplay:AbstractDisplay = StringDisplay("こんにちは。")

        chDisplay.display()
        strDisplay.display()
        jStrDisplay.display()
    }
}
```

```kotlin:MainActivity.kt
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        var chDisplay:AbstractDisplay = CharDisplay("H")
        var strDisplay:AbstractDisplay = StringDisplay("Hello, world.")
        var jStrDisplay:AbstractDisplay = StringDisplay("こんにちは。")

        chDisplay.display()
        strDisplay.display()
        jStrDisplay.display()
    }
}
```
Android Studioのログで確認しているので実際は改行入ってますが、クッソ見難いので省いています。

```:出力結果
<<HHHHH>>

+-------------+
|Hello, world.|
|Hello, world.|
|Hello, world.|
|Hello, world.|
|Hello, world.|
+-------------+

+------------------+
|こんにちは。|
|こんにちは。|
|こんにちは。|
|こんにちは。|
|こんにちは。|
+------------------+

```
laravel passportでルーティングを制限したりいじったりする。

laravelにおけるAPI認証で、passportを使うときのメモ。


Http/Providers/AuthServiceProviderに、```Passport::routes();```
を付け足すことで oauth/token　などのルーティングが追加されるが、その際引数で```$callback``` と ```$options```を渡すことができる。

これらは、vender/laravel/passport/Passport.phpのfunction routesを見ればわかる。

```$callback``` で登録するrouteを指定、
```$options```でnamespaceやprefixを指定できる。

```vender/laravel/passport/src/RouteRegister``` を見れば、```$callback```で指定できるエンドポイントもわかる。
Temporal Networks 入門 (2) still writing...

#確率論

###Question: 「ランダムさ」をモデル化するには

>　**確率論**（かくりつろん、英: probability theory )とは、**偶然現象**に対して数学的な模型(**モデル**)を与え、解析する


Philosophical Theories of Probability


##ちょっと歴史
![cicero.png](https://qiita-image-store.s3.amazonaws.com/0/196262/30426d59-dc46-e061-7c26-6bc56b6567f6.png) Marcus Tullius Cicero (B.C.106 - B.C.43)
Probability という語を用いた

十字軍がエジプトからさいころゲームを持ち帰った？？？
賭博ゲーム

確率論へ

![Jerôme_Cardan.jpg](https://qiita-image-store.s3.amazonaws.com/0/196262/8e22643c-2af0-4c97-4c57-eb494438babd.jpeg) Gerolamo Cardano (1501 - 1576) 
ジェロラモの母親は彼を中絶しようとして失敗した
**『さいころあそびについて』**（*Liber de ludo aleae*、発行されたのは彼の死後1663年）
「ギャンブラーにとっては、全くギャンブルをしないことが最大の利益となる。」
『偉大なる術（アルス・マグナ）』虚数の発見？
数学者→医者（腸チフスの発見など）
占星術で予言した死亡日に自殺する

![Blaise_pascal.jpg](https://qiita-image-store.s3.amazonaws.com/0/196262/6d4193ae-14ca-477d-18c7-5d8bb8b037a2.jpeg) Blaise Pascal  (1623 - 1662)
![Pierre_de_Fermat.jpg](https://qiita-image-store.s3.amazonaws.com/0/196262/25af3ccc-83fb-2c61-b126-68f5ac4ada10.jpeg) Pierre de Fermat (1607 - 1665)
文通友達

途中でゲームをやめたときの勝敗について
→「期待値」


![Christiaan_Huygens-painting.jpeg](https://qiita-image-store.s3.amazonaws.com/0/196262/06a7f0bb-24b5-2999-1f8d-452f3880e81a.jpeg) Christiaan Huygens (1629 - 1695)
自作の望遠鏡で土星の輪を発見
振り子時計
ホイヘンスの原理（球面波）

![Johann_Bernoulli2.jpg](https://qiita-image-store.s3.amazonaws.com/0/196262/be4147e9-bcc7-296e-84fa-cb9f6f42d65c.jpeg) Johann Bernoulli (1667 - 1748)

大数の法則(弱)
$$ \lim_{n \to \infty} P(\left| \bar{X_n} -\mu  \right| > \epsilon) = 0 \ (^\forall\epsilon > 0) $$
 Stiring's rule


![PE_77A.jpg](https://qiita-image-store.s3.amazonaws.com/0/196262/b0da9eeb-fabe-3ff1-5f6a-d216eee39386.jpeg) Abraham de Moivre (1667 - 1754)
中心極限定理


![Pierre-Simon_Laplace.jpg](https://qiita-image-store.s3.amazonaws.com/0/196262/adf597d7-74f5-9814-74df-76798daad362.jpeg) Pierre-Simon Laplace (1749 - 1827)
![Carl_Friedrich_Gauss_1840_by_Jensen.jpg](https://qiita-image-store.s3.amazonaws.com/0/196262/dd20f93f-92dc-de7c-000f-db4c8195017c.jpeg) Carl Friedrich Gauss (1777 - 1855)

熱・統計力学
![Boltzmann.jpg](https://qiita-image-store.s3.amazonaws.com/0/196262/09c23894-7390-f419-6c54-f234a0680058.jpeg) Ludwig Eduard Boltzmann (1844 - 1906)
![Josiah_Willard_Gibbs.jpg](https://qiita-image-store.s3.amazonaws.com/0/196262/2ac6e320-2b11-0889-56d9-4e96e174c203.jpeg) Willard Gibbs (1839 - 1903)

量子力学


そしてデータの時代へ


統計学
![R._A._Fischer.jpg](https://qiita-image-store.s3.amazonaws.com/0/196262/c9e4ecca-3f24-3707-a865-e9a32a05bc17.jpeg) Ronald Fisher (1890 - 1962)
![Neyman.jpg](https://qiita-image-store.s3.amazonaws.com/0/196262/d1f9903b-62dc-a0c4-ba1a-361e67334435.jpeg) Jerzy Neyman (1894 - 1981)
![Egon_Pearson.jpg](https://qiita-image-store.s3.amazonaws.com/0/196262/2ad03bef-7a04-bae5-ab28-f9186c409c69.jpeg) Egon Pearson (1895 - 1980)

ベイズ統計
Bayes

確率過程
Markov

測度論 measurement
measure 測度：集合の大きさを測る量
Kolmogorov




##確率分布
###ベルヌーイ分布
###二項分布
###幾何分布
###指数分布
Temporal Networks 入門 (1) still writing 

#これから読むもの
[A Guide to Temporal Networks](https://www.amazon.co.uk/Guide-Temporal-Networks-Complexity-Science-ebook/dp/B01KJCOMFW/)
![face-a-guide-to-temporal-networks.jpg](https://qiita-image-store.s3.amazonaws.com/0/196262/a7dac542-616f-f07a-0583-e01da852f2ae.jpeg)

#イントロ
#### サーベイ論文
- [Holme and Saramäki (2012)](https://arxiv.org/abs/1108.1780)
- [Aggarwal and Subbian (2014)](http://charuaggarwal.net/CSUR-2013-0157.pdf)
- [Holme (2015)](https://arxiv.org/abs/1508.01303)

#### 教科書
- [Holme and Saramäki (2013)](https://www.springer.com/gb/book/9783642364600)

#### adaptive networks（本書では扱わない(´・ω・)）自律ネットワーク
- [Gross and Blasius (2008)](https://arxiv.org/abs/0709.1858) paper
- [Gross and Sayama (2009)](https://www.springer.com/us/book/9783642012839) text book


##ざっと本書の流れを紹介

Chapter 2 確率論と線型代数など
Chapter 3 静的な（定常）ネットワーク
    -Newman (2010)
    -Barabasi (2016)
Watts-Strogatz model
Small-World 効果
degree correlation
centrality measures
parcolation
spatial networks
multi-layer networks

Chapter 4 Temporal Networksの2つの表現
Chapter 5 Temporal Networksの生成モデル
Chapter 6 いくつかモデルとダイナミクス解析の紹介



##Temporal Networksって何が面白いの？
###5つの楽しさ
1. mobilityと関係
2. metapopulation models
3. 時系列解析との関連
4. 因果との関連
5. 異なるタイムスケールの共存


因果そして情報量
起にくいこと（確率が小さい）が起こるとより大きな情報量を得る


###トノーニの意識の統合情報量
統合情報量 $\Phi$
![Slide1.jpg](https://qiita-image-store.s3.amazonaws.com/0/196262/bb0c55e3-1d4e-f731-4b02-4858478440c1.jpeg)

####相互情報量 (mutual information)
![Slide2.jpg](https://qiita-image-store.s3.amazonaws.com/0/196262/e8d3783b-9fc9-13ee-274f-1ccc65efcff2.jpeg)

$$I(A_t;B_t) = \sum_{y \in Y}\sum_{x \in X} P(x,y) \log \frac{P(x,y)}{P(x)P(y)} $$



####移動エントロピー(transfer entropy)
![Slide3.jpg](https://qiita-image-store.s3.amazonaws.com/0/196262/4c92f5e2-2bbd-365c-71d4-b52984fd0772.jpeg)

$$T_{B\rightarrow A} = \sum P(A_{t}, A_{t-1}, B_{t-1}) \log \frac{P(A_{t}|A_{t-1},B_{t-1})}{P(A_{t}|A_{t-1})} $$


###統合情報量
$$ T_{B\rightarrow A} \leq \Phi \leq I(A_t;B_t)　  $$
Javaでzipファイルを解凍する

Javaでzipファイルを解凍する機会があったため、そのときの技術メモになります(´・ω・｀) まずは次の手順でzipに格納する3つのファイル(`a.txt`, `dir1/b.txt`, `dir1/dir2/c.txt`)を作成します。

```bash
mkdir -p dir1/dir2
touch a.txt dir1/b.txt dir1/dir2/c.txt
echo "AAAAAAAAAA" > a.txt
echo "BBBBBBBBBB" > dir1/b.txt
echo "CCCCCCCCCC" > dir1/dir2/c.txt
```

作成した内容については次のようなコマンドで確認することができます。

```bash
find . -name "*.txt" | while read path; do
  echo "---> ${path} <---"
  cat ${path}
done
---> ./a.txt <---
AAAAAAAAAA
---> ./dir1/b.txt <---
BBBBBBBBBB
---> ./dir1/dir2/c.txt <---
CCCCCCCCCC
```

想定通りに3つのファイルが作成されていることが確認できたので、これを`text.zip`ファイルとして圧縮します。

```bash
$ zip "text.zip" $(find . -name "*.txt")
  adding: a.txt (deflated 45%)
  adding: dir1/b.txt (deflated 45%)
  adding: dir1/dir2/c.txt (deflated 45%)
```

最後に`text.zip`ファイルが正常に作成できたことを確認しておきましょう。

```bash
$ unzip -l text.zip
Archive:  text.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
       11  2018-08-24 23:17   a.txt
       11  2018-08-24 23:17   dir1/b.txt
       11  2018-08-24 23:17   dir1/dir2/c.txt
---------                     -------
       33                     3 files
```

前置きが長くなりましたが、`text.zip`ファイルを`text`ディレクトリに解凍したいという場合、それを実現するJavaコードは以下の通りになります。

```java
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class Main {
    public static void main(String[] args) throws IOException {
        var target = Paths.get("text");
        Files.createDirectories(target);
        
        var zipfile = Paths.get("text.zip");
        try (var in = new ZipInputStream(Files.newInputStream(zipfile))) {
            ZipEntry e;
            while ((e = in.getNextEntry()) != null) {
                var dst = Paths.get(target.toString(), e.getName());
                Files.createDirectories(dst.getParent());
                Files.write(dst, in.readAllBytes());
                System.out.printf("inflating: %s%n", dst);
            }
        }
    }
}
```

このJavaコードを実行すると、`text.zip`が`text`ディレクトリに解凍されると同時に、以下のようなログが標準出力に表示されるはずです。

```
inflating: text\a.txt
inflating: text\dir1\b.txt
inflating: text\dir1\dir2\c.txt
```

では本当に`text.zip`ファイルが`text`ディレクトリ配下に解凍されたのか。これについては以下のようなコマンドで確かめることができます。

```bash
$ find ./text -name "*.txt" | while read path; do
>   echo "---> ${path} <---"
>   cat ${path}
> done
---> ./text/a.txt <---
AAAAAAAAAA
---> ./text/dir1/b.txt <---
BBBBBBBBBB
---> ./text/dir1/dir2/c.txt <---
CCCCCCCCCC
```
Visual Studio Code インストール後に最低限入れたいプラグインなど


# プラグイン
以下のプラグインを入れる

- vim
- eslint
- prettier
- gitLens
- Debugger for Chrome
- erb

# 設定
- code コマンドを入れてコマンドラインから VSCode を起動できるようにする。
  - `cmd + shift + p` からの `shell` と入力して、一番上くらいに出ているはずなのでそれをクリックすればよい。

- ファイル保存時に自動でフォーマットしたい
  - `cmd + ,` で設定ファイルを開き、`"editor.formatOnSave": true` を追加

(随時更新予定、あくまで自分用)
Rustの所有権

よく分からないので調べたことをまとめた。スタック・ヒープに関しては正確に捉えられているかどうか怪しい。

\* 20180825 @scivola さん、@uasi さんから指摘をいただき、修正しました。

## 所有権

rust の変数束縛は束縛されている値の「所有権を持つ」。

これは「束縛がスコープから外れるとき、Rust は束縛されているリソースを解放する」ということ、この挙動は他の言語とあまり変わりない。

```rust
fn foo() {
    let v = vec![1, 2, 3];
    // ベクタがスタックに作成され、要素を格納するためにヒープに空間を割り当てられる(スタックアロケート)
}   // <- スコープから外れる時、ベクタに関連するものがスタックから削除される(スタックデアロケート)
```

## ムーブセマンティクス

Rust は与えられたリソースに対する束縛が`1つだけで`あることを保証する。
別の変数に束縛できるが、元々の変数が参照できなくなる。つまり、所有権が移動する。

```rust
let v = vec![1, 2, 3];

let v2 = v;// <- value moved here

println!("v[0] is: {}", v[0]);// <- Error!!! value used here after move
```

下記の例では 所有権が`main関数スコープのv`から`take関数のスコープのv`に移動するため、 同様にエラーが出力される。

```rust
fn main() {
    let v = vec![1, 2, 3];

    take(v);// <- value moved here

    println!("v[0] is: {}", v[0]);// <- Error!!! value used here after move
}

fn take(v: Vec<i32>) {
    println!("v[0] is: {}", v[0]);
}
```

## なぜ？

以下のコード例で説明する。

```rust
let v = vec![1, 2, 3];
let mut _v2 = v;// <-- value moved here
println!("v[0] is {}", v[0]);// <-- Error!!! value used here after move
```

1行目ではベクタオブジェクトvのために、スタック上にメモリを割り当てる。そして、先頭の要素`v[0]`のヒープ領域のアドレス`(2^30)-3`をポインタとして持つ。

| Address  | Name            | Value          | Note                           |
| -------- | --------------- | -------------- | ------------------------------ |
| (2^30)-1 |                 | 3              | v[2]の値                       |
| (2^30)-2 |                 | 2              | v[1]の値                       |
| (2^30)-3 |                 | 1              | v[0]の値                       |
| ...      | ...             | ...            | ...                            |
| 3        | v.len           | 3              | vのサイズ                      |
| 2        | v.buf.allocator | some allocator | 可変長のためバッファを持つ     |
| 1        | v.buf.capacity  | 3              | vの容量                        |
| 0        | v.buf.ptr       | ->(2^30)-3     | 先頭要素のヒープ領域のポインタ |

2行目では所有権が移動する。つまり、ベクタオブジェクトvの持つスタック領域の情報をベクタオブジェクト_v2にコピーする。よって同じヒープ領域を示すポインタが2つ存在することになる。

| Address  | Name   | Value      |
| -------- | ------ | ---------- |
| (2^30)-1 |        | 3          |
| (2^30)-2 |        | 2          |
| (2^30)-3 |        | 1          |
| ...      | ...    | ...        |
| \~\~     | \~\~   | \~\~       |
| 4        | _v2[0] | ->(2^30)-3 |
| \~\~     | \~\~   | \~\~       |
| 0        | v[0]   | ->(2^30)-3 |

例えば,`_v2.truncate(2)`といった処理を行い、要素を2つ切り詰めたとする。そうなると、ベクタオブジェクトvは存在しないヒープ領域をポインタに持つことになる。`このようなデータ競合を防ぐため、Rustではコピー元のベクタオブジェクトvの使用を禁止する`。

## プリミティブ型は違う

所有権が移動した時、元の変数は使用できない。しかし、`i32`などのプリミティブ型はその限りでない。これは`Copy トレイト`を実装しており、所有権の移動ではなく、完全なコピーを行なっているためである。

## なぜプリミティブ型は「完全なコピー」なのか

以下のコード例で説明する。

```rust
let x: i32 = 1;
let _y: i32 = x;
println!("x is {}", x); // x is 1
```

1行目のスタックアロケートは以下のようになる。

| Address | Name | Value |
| ------- | ---- | ----- |
| ...     | ...  | ...   |
| 0       | x    | 1     |

2行目では単純にxの値を参照して、_yへの代入が行われるため、以下のようになる。

| Address | Name | Value |
| ------- | ---- | ----- |
| ...     | ...  | ...   |
| 1       | _y   | 1     |
| 0       | x    | 1     |

プリミティブ型はベクタオブジェクトとは異なり、ヒープ領域を利用しない。つまり、別のアドレスへのポインタを持たない。よって、データ競合は起こりえないため、完全なコピーが許されている。
2018年8月第4週　今週気になった記事まとめ

# 今週気になった記事まとめ
##■「人間vsAI」のオンラインゲーム3番勝負の初戦は人間チームが勝利を収める
https://gigazine.net/news/20180824-human-defeat-ai-dota-2/
文中では「AIは瞬間瞬間の判断は上手でも広いレベルの決断は良くない」とあるが、これまで将棋などのAIで耳にした傾向は逆の「その瞬間での一手は無意味に見えても最終的に効果的な一手になってる」っていう印象だった。
対象にするテーマによるものなのか、作り手の違いによるものなのか。

##■SushiGAN 〜人工知能は寿司を握れるか？〜
https://qiita.com/shionhonda/items/1c43081a4c038667a694?utm_campaign=popular_items&utm_medium=feed&utm_source=popular_items
やってることの超ざっくりとしたイメージは分かるのだが、書かれてる仕組みがレベル高すぎて全く付いていけない・・・。

##■弱小スポーツチームを応援するIoT冷蔵庫、勝てばWi-Fi経由で解錠してビールを無料で大放出
https://www.gizmodo.jp/2018/08/iot-refrigerator.html
いざ勝ったときにエラーや障害起きたら笑えないので、ネタなのにエンジニアの精神すり減らしそう(笑)

##■スケジュールが一目で分かる“習慣時計”、キングジムが9月に発売
http://www.itmedia.co.jp/news/articles/1808/21/news094.html
完全デジタルなら欲しいかもしれない。

##■マストドン、再びTwitterトレンドに
http://www.itmedia.co.jp/news/articles/1808/16/news082.html
時折話題になって浮上してくるけど定着しないのは、複数インスタンスでやってるからなのだろうか。

##■プログラミング学習に「GitHubを使用すること」の効果とは？
https://gigazine.net/news/20180816-github-education-learner-outcome/
学生時代からGitHubを知っている・いないの差はいざ現場に出た時にものすごい差になりそう。
バージョン管理という習慣がもたらす効果は表面的なものよりもはるかに多そう。

##■幸福の科学「本日の格言」を分析してみた
https://qiita.com/Hiroyuki1993/items/cac5c199e464c0e95355?utm_campaign=popular_items&utm_medium=feed&utm_source=popular_items
テーマ自体はとても下らないのだけど、これくらい下らないほうが楽しそうで良い。

##■無料でスマホの写真から証明写真を作成可能＆コンビニで写真つき履歴書も印刷できる「履歴書カメラ」
https://gigazine.net/amp/20180819-rirekisho-camera
今時なかなか難しい、ありそうで無かったアイデアのアプリ。
こういうアイデアが出てきて実現できることが素晴らしい。

##■ChromebookでWindows 10を動かす「Campfire」　Googleが開発中か
http://www.itmedia.co.jp/pcuser/articles/1808/20/news079.html
Chromebookならではの爆速起動がWin10ブートにした時にどうなるのか・・・。
普通のWindowsとして使えるくらいだったらWindows買った方がいいんじゃッてなりそうな気もする。

##■Windows 10の「シャットダウン」と「再起動」は異なる　トラブル発生時は再起動を選ぶべき理由
http://www.itmedia.co.jp/pcuser/articles/1808/20/news095.html
高速スタートアップがこんなところでも弊害を生んでいるとは知らなかった。

##■iPhone＆Windowsの組み合わせは意外と悪くない
https://www.gizmodo.jp/2018/08/iphone_windows_user.html
「データはクラウド」が主流になった時点でハードの違いにこだわる意味はどんどん無くなっているのだろうなと。
そもそもどちらかが圧倒的なシェアを確保しているとかってわけじゃないので、使えるようにしとかないと逆にシェアが下がりそう。

##■ゴキブリを退治する最適（＆最悪）な方法
https://www.gizmodo.jp/amp/2018/08/best-way-to-kill-cockroaches.html
ちょっと閲覧注意。
うちのオフィスにもヤモリを放つか・・・。

##■コオロギを食べ続けて、どんなことが分かってきたのか 
http://www.itmedia.co.jp/business/articles/1808/08/news008.html
ちょっと閲覧注意。
テーマはさておいて、研究をしていく家庭での考え方が頭良すぎる。
芸大出身でデザイナーをされているそうだが、思考の仕方が超ロジカルかつ的確で面白い。


所感：
まとめた記事以外にも「AI使ってこんなことしてみた」的な記事が結構あって、AIという技術で遊び始めた人が増えてきている印象。
それだけAI技術自体が一般化してきているということなので、だんだんと分からないとだけ言ってるわけにはいかなくなっているのかもしれない。
【Veeam 9.5】vmdkファイルがサポートされていないためレプリケーションが失敗する

#環境
- Windows Server 2012 R2
- Veeam Backup & Replication 9.5
- vSphere Client 6.0
- VM OS：Windows 2012

#エラー内容
Veeamにて仮想マシンのレプリケーションジョブを作成し実行すると、仮想マシンのvmdkファイルがVeeamのサポート外であったため、warningとなりジョブが止まってしまった。

**出力されたエラーメッセージはこちら**
[Disk vmname.vmdk has been skipped due to unsupported type (independent)]

JOBの内容と見直すと、JOBに追加する仮想マシンを選択する画面にてVMの容量が0Bとなっており、仮想マシンのディスク容量が認識されていなかった。

#原因
仮想マシンの仮想ディスクモードが依存型ではなく、独立型になっていたことが原因であった。この独立モードに設定すると、VMwareの仕様上スナップショットの対象から外れるようになっている。Veeamは仮想マシンのスナップショットを取得してレプリケーションを行うので、仮想ディスクの独立型を選択しているとジョブが実行できずエラーが発生したと言える。

###仮想ディスクのモードとは
仮想マシンの仮想ディスクはデフォルトだと依存型になっているが、用途によっては独立型に変更することができる。独立型というのは、仮想ディスクだけが独立した状態になっていることを意味する。

- **依存型**：いつでもスナップショットを取れる。通常のディスクモード。
- **独立型-通常モード**：このディスクに書き込みを行うと、仮想マシンをパワーオフしたりある時点のスナップショットに戻してもその影響を受けない。
- **独立型-読み取り専用**：このディスクに書き込みを行なっても、仮想マシンをパワーオフまたはリセットするとその変更が破棄される。

※独立型はパワーオン状態だとスナップショットはとることができない。


#変更方法
####①対象VMにスナップショットがないか確認する。
スナップショットが取得されている状態だと仮想ディスクのモードを変更できないので、リストアポイントをスナップショットの管理から削除しておく必要がある。
**削除方法**
対象VM右クリック→スナップショット→スナップショットの管理
下図のようにレストアポイントが表示されているので削除する。(vSphere Web Clientで代用）
![pic](http://drive.google.com/uc?export=view&id=1-e5ZJUyzV_NL-SL4t4NUjj7I7yl-r90x)

####②対象VMをパワーオフする。
仮想ディスクモードはパワーオフ状態でないと変更項目が活性化しない。

####③仮想ディスクを選択し、独立型のチェックを外す。
チェックを外すと仮想ディスクが依存型に変更される。変更はvSphere Clientで対応できるがvSphere Web Clientではできないので注意。
変更方法
vSphere Clientにて対象VM右クリック→設定の編集→ハードディスク選択

####④変更を保存した後、対象VMをパワーオンする。

ディスクモードを変更することによって、VMのOSの調子がおかしくなったりファイルが消えたりなどの不具合はないと思うが、念のため検証してから変更することを推奨する。
Veeamを使用する予定のときは、このような変更作業が必要になりVMの通信断が生じるので、事前にVMのディスクはどちらを選択するのか検討事項として挙げると良い。
Unityで迷路ゲームを作るチュートリアル(ScratchC＃対応早見表)

引っ越しましたので[こちら](http://getabakoclub.com/2018/08/24/scratch-%E2%86%92-unity%E5%AF%BE%E5%BF%9C%E8%A1%A8%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E8%BF%B7%E8%B7%AF%E3%82%B2%E3%83%BC%E3%83%A0%E3%82%92%E4%BD%9C%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%88%E3%81%86/)で御覧ください。
ランダム化連鎖配列の本来の並び順を求める

こんにちは。
連鎖配列（例: ```[[0,1],[1,2],[2,3]]```）がランダムにシャッフルされているとして、それの本来の並び順を求めてみました。

```console
$ ./sequence_sort.py
 [[2, 3], [1, 2], [0, 1]] ==>
[0, 1]
[1, 2]
[2, 3]
```

```sequence_sort.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import random

SKIP = -1

def find_vacancy(seq):
    return list(set(range(len(seq))) - set(seq))[0]

def seq_nexts(arr):
    heads = [a[0] for a in arr]
    nexts = [heads.index(a[-1]) if a[-1] in heads else SKIP for a in arr]
    index_top = find_vacancy(nexts)
    return index_top, nexts

def sequence_sort(arr):
    i, nexts = seq_nexts(arr)
    indices = []
    while i is not SKIP:
        indices.append(i)
        i = nexts[i]
    return indices

N = 3
data = [[i,i+1] for i in range(N)]
random.shuffle(data)
print(data, '==>')

for i in sequence_sort(data):
    print(data[i])
exit(0)
```
【Androidアプリ】画像をグレーアウト表示する

# 前書き
Android版では2つあるボタンのうち片方は非表示にしていたのですが、iOS版では非活性にするという実装だったらしく。
iOS版でOK出たからiOS版に合わせてくれと言われ、突貫でAndroid版を修正しました。

非活性用の画像作るのめんどくさいな…ということで、「android 画像 グレーアウト」で検索、検索ぅ！

# 参考
[ImageButtonの画像をグレーアウト(不活性表示)する方法  |  mucchinのAndroid戦記](http://android.roof-balcony.com/view/disable_image/ "ImageButtonの画像をグレーアウト(不活性表示)する方法  |  mucchinのAndroid戦記")

# コード

```java:xxxActivity.java
final ImageView dailyButton = findViewById(R.id.dailyButton);
final ImageView weeklyButton = findViewById(R.id.weeklyButton);

dailyButton.setOnClickListener(new OnClickListener() {
    public void onClick(View v) {
        dailyButton.setEnabled(false);
        dailyButton.setColorFilter(0xaa808080);

        weeklyButton.setEnabled(true);
        weeklyButton.setColorFilter(null);
    }
});

weeklyButton.setOnClickListener(new OnClickListener() {
    public void onClick(View v) {
        weeklyButton.setEnabled(false);
        weeklyButton.setColorFilter(0xaa808080);

        dailyButton.setEnabled(true);
        dailyButton.setColorFilter(null);
    }
});

// 初回表示時
dailyButton.setEnabled(false);
dailyButton.setColorFilter(0xaa808080);
```

こういう時はImageViewよりImageButtonを使うべきなのだろうか？
flutterでTextFieldに変更が反映されない

TextFieldの変更が次のようになって反映されない問題にハマりました。

<img src="https://qiita-image-store.s3.amazonaws.com/0/18273/c4411fdb-3df4-cbed-5ffd-8f5c52e16754.gif" width="300px">

どうやらStatelessWidget内ではこのようになってしまうようです。
StatefullWidgetのサブクラスを利用することで正常に変更が反映されるようになりました。

<img src="https://qiita-image-store.s3.amazonaws.com/0/18273/87c0d973-b714-4690-9223-4312c7dd40cc.gif" width="300px">

コード例も載せておきます。

```dart
// StatelessWidgetを使用する
// TextFieldの変更が反映されない
class MyStatelessWidget extends StatelessWidget {
  TextEditingController controller;

  MyStatelessWidget() {
    controller = TextEditingController(text: "default");
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("MyStatelessWidget"),
      ),
      body: TextField(
        controller: controller,
      ),
    );
  }
}

// StatefullWidgetを使用する
// TextFieldの変更が反映される
class MyStatefullWidget extends StatefulWidget {
  @override
  State createState() {
    return MyStatefullWidgetState();
  }
}

class MyStatefullWidgetState extends State<MyStatefullWidget> {
  TextEditingController controller;

  MyStatefullWidget() {
    controller = TextEditingController(text: "default");
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("MyStatelessWidget"),
      ),
      body: TextField(
        controller: this.controller,
      ),
    );
  }
}
```
CI - Format Protocol Buffers


簡単に使えそうだった [uber/prototool](https://github.com/uber/prototool) を利用する （[利用例](https://github.com/nokamoto/webpush-101/pull/2)）。

```yaml
    steps:
      - checkout
      - run:
          name: Install prototool
          command:
            curl -sSL https://github.com/uber/prototool/releases/download/v1.0.0/prototool-$(uname -s)-$(uname -m) -o ./prototool &&
            chmod +x ./prototool
      - run:
          name: Format protobuf - write a diff instead
          command: ./prototool format -d protobuf
```

diff があれば失敗となる。

```bash
# -d, Write a diff instead of writing the formatted file to stdout.
$ prototool format -d ${directory}
--- protobuf/user.proto.orig	2018-08-24 21:46:11.000000000 +0900
+++ protobuf/user.proto	2018-08-24 21:46:11.000000000 +0900
@@ -1,5 +1,5 @@
 syntax = "proto3";

 message User {
-    string id = 1;
+  string id = 1;
 }
$ echo $?
255
```

上書きしてコミットすれば解決する。

```bash
# -w, Overwrite the existing file instead of writing the formatted file to stdout.
$ prototool format -w ${directory}
```
SageMakerのノートブックインスタンス環境にMecabをインストールする際に困ったこと

# モチベーション
Mecabを使って何かやりたい。が、ローカル環境を汚したくない。EC2を新しく建てるのも面倒だ。
→ そうだ。SageMakerのノートブックインスタンス環境にMecabを入れよう！

ということで下記のサイトを参考にやってみたが、なかなか上手く行かなかったので備忘として残しておく。
https://www.yoshiislandblog.net/2018/03/21/amazon-linux_mecab/

# Mecabが入らない

```shell-session
# sudo rpm -ivh http://packages.groonga.org/centos/groonga-release-1.1.0-1.noarch.rpm
# yum -y install mecab mecab-ipadic mecab-devel
```
上記を素直に実行すると下記のエラーが。そもそもなぜこんなURLにアクセスに行っているかがわからない。ブラウザで確認すると`centos/`配下には`2017.09`というディレクトリは無く、`latest`があるのみである。


```shell-session
failure: repodata/repomd.xml from groonga: [Errno 256] No more mirrors to try.
http://packages.groonga.org/centos/2017.09/x86_64/repodata/repomd.xml: [Errno 14] HTTP Error 404 - Not Found
```

もろもろGoogleを彷徨った結果、`/etc/yum.conf`の以下の部分の`releasever=2017.09`を`releasever=latest`に書き換えることによって処理が成功するようになった。

```shell-session
# by default the yum configuration will point to the latest release
# of Amazon Linux AMI. If you prefer not to automatically move to
# new releases, comment out this line.
releasever=2017.09
```

なぜこんなことをしなければならないのか、については正直わからない。ノートブックインスタンスの場合、Amazon Linuxのアップデートのポリシーが違うんだろうか。

# mecab-python3が入らない
`pip install mecab-python3`で簡単に入るはずが、手順通りにgccとgcc-c++をあらかじめ用意しているにも関わらず、コンパイル時にエラーが出てインストールできない。

https://stackoverflow.com/questions/36353302/gcc-cannot-find-cc1plus/36353331
上記サイトによると、なぜか`gcc-c++`がパスが通っていない場所に配置されてしまっている様子。
以下にて`gcc-c++`のパスを通してやると無事インストールできるようになった。

```shell-session
sudo ln -s /usr/libexec/gcc/x86_64-amazon-linux/4.8.5/cc1plus /usr/local/bin/
```

これについても、ぶっちゃけこんな場当たり的な対応でいいのかなぁー、という気持ちになる。

# そして
この記事を投稿してから以下のような記事が既にQiitaに存在していたことに気付いた。 
灯台下暮らし。最初にこれを読んでいれば1-2時間短縮できたな。

https://qiita.com/airtanker/items/fbbdd1176dae9b6719b8
「インデックス」ってなあに

またはRDBよくわかんないけど「パフォーマンス調べろ、悪かったらインデックス張るから」とか言われたある新卒への説明書き、あるいは「なんでインデックス張れば速くなるの？」に対する答え。
※ 内部的な事情とか歴史的なアレコレはガン無視してます。

# 意義
索引、目次、指標などなど。綴は index 。
大元は「指し示すもの」の意で、語源は「in (中) 」「dicare (宣言) 」らしい。
(目録もインデックスの一種である。某とあるのルビにもなんとなく納得がいくというもの)

ものすごく大雑把に言うと「検索を速くする」ために存在する。

# 検索は重労働
広範な知識を持った人間 (つまり司書さん) がやるならともかく、コンピュータが単なる文書に対して素直にやると殺人的な時間がかかる。

例えば、ある本Bの中に単語Nが存在するか見るとする。とりあえず頭から見て、1文字目からNの長さNl文字目までの文字列をBの先頭から取り出し、取り出したものとNを比較する。違ったら2文字目からNl+1文字目まで、それも違えば3文字目からNl+2文字目まで……
時間がかかるどころの騒ぎではない。

# RDBは制約である
ここに「テーブル, カラム, レコード」「データ型」「関係」といった様々な制約を持ち込み、検索しやすい状況を作ったのがRDBである。
1カラムには1つのデータだけが入る。文字列なら文字列、数値なら数値。変なものは入らない。
カラムがあつまるとレコードになる。レコードがあつまるとテーブルになり、1テーブルは同一構造のレコードだけが入っていることが保証されており、そのテーブルにどんなレコードが入るかはテーブルに書いてある。
非常に検索しやすい。何がどこに入っているか整理されているからだ。

しかし、そう喜んでもいられない。実際にはとんでもない量のレコードがぶち込まれるので、結局地獄の比較作業が始まるのだ。
今度は確かに1文字ずつずらす必要はない。単に全レコードの同じ1カラムを見て比較すればいいだけ。楽なもんだ。

そう、楽。ところで、それ1億回って言われてもまだ楽だって言える？

# すばやく検索する工夫
先程「様々な制約を持ち込み、検索しやすい状況を作ったのがRDB」と書いた。
この理屈に則れば、つまり制約を足せば検索を楽に……する余地が生まれる。

実際には検索する機構自体に工夫が必要だし、適切な制約でなければ意味がない。
使う側からして扱いづらくてもダメだ。それでは使われない。存在しないのと同じだ。

# 索引
そこで、頭のいいやつは名案を思いついた。

カラムを指定し、これの一覧表を作る。「一覧」はRDBにとって都合の良い順番に並べてあり、カラムに入っている情報たちと一緒に「これはここらへんにあるよ」とRDBにならわかる場所の情報がつけてある。
そのカラムを条件とする検索が要求された時、RDBはまずこの「一覧」を見る。なぜならこの「一覧」の順序ルールはRDB自身すでに知っているからだ。どのあたりに何があるかは簡単に見当がつく。

既に気がついているかもしれないが、これこそがインデックス。紙の辞書や技術書や教科書なんかの最後らへんについている索引と同じ発想で出来ているし、名前も同じだ。
英語ならアルファベット順、日本語のものなら50音順+アルファベット順で並んでいると我々は知っている。少なくとも「い」のあとに「あ」が来ないことぐらいは想像がつくだろう。
（このあたりの「順番がわかっているものから探す」アルゴリズムはいろいろあるが、調べたいと思ったらまず「二分探索木」がよい。まず使われないが、最もシンプルでわかりやすいだろう）

しかし、インデックスにも欠点がある。

# 欠点

「一覧」は一種の表 (のようなもの) である。ということはデータとして存在しなければいけない。でなければ見られないからだ。
しかし、存在するということは多少なりとも容量を使う。現在のストレージ容量・価格なら気にならないのは救いではあるが、設定をしくじると死活問題にもなりうる。

「一覧」はただの表ではない。「本物の表」に連動する表なのだ。ということは「本物の表」が更新されたら「一覧」も更新しなければならない。さもなくば「一覧」は陳腐化して使えなくなる。
こちらは大問題だ。これは「本物の表」の更新 (update) や新規データの挿入 (insert) に余計な手間がかかることにほかならない。
社内システムのようなのんびりしたものならまだしも、広く使われて大量に挿入・更新されるもの……例えばソシャゲのようなものではなかなか大変なことになる。10連ガチャを1000人が引いたら10000件になるのだ。洒落にならない。

そしてそもそも、「一覧」ですばやくなるのは「大量のデータから特定カラムを使って持ってくる」ものだけだ。
なにしろ「一覧」とは特定カラムの一覧とその「ありそうな場所」の対応表なわけであって、「対応表を見る」というワンアクションが増えている分、データ量が少ないと効果が出ない。
また、検索に「一覧」が見ているカラムが使われていなければそもそも使うことすら出来ず、変なところで抜け落ちることになりかねない。割とデリケートなのだ。

# まとめ
* インデックスは名前の通り、データベースという辞書の索引である。
* 索引なので使えないときは使えないし維持管理に手間がかかる。じゃけんちゃんと考えてはりましょうネ。
* Q. どう張ればいいの？ A. よく使う (or遅い) 検索の条件になってるカラムに張ればOK。でもレコードいっぱいあるんでもなければあんまり効かないぞ。大抵詳しい人がいるので教えてもらうとよい。
U-SQL でヒストグラムを作りたい時のラムダ式

U-SQLでヒストグラムを作ろうとする場合、データポイントをBINごとに仕分けて、集計ということになります。
これは直接サポートされていないので、色々ステップを踏む必要がありました。


BINに仕分ける部分は、U-SQLで書けなくは無いようにも思うのですが、SWITCHとか使うのは嫌ですし、使うたびにコードを埋め込まないといけないので、クエリーが醜くなりそう。

# ラムダ式をU-SQL変数に（名前付きラムダ）

今年出た機能のうち、U-SQL Spring 2018 Release Notes に書いてある、以下を使うと、C#関数を、変数に入れてインラインで手軽に使えるようになります。（コードビハインドやアセンブリ登録がいらない！！）

[U-SQL adds C# Func<>-typed variables in DECLARE statements (named lambdas)](https://github.com/Azure/AzureDataLake/blob/master/docs/Release_Notes/2018/2018_Spring/USQL_Release_Notes_2018_Spring.md)

TVFやPROCEDUREに比べて、引数も自由だし、単純なROW-wideな関数を定義するには楽です。本当にインラインにしちゃうと、再利用できないし。

``` SQL
DECLARE @cbin = new SQL.ARRAY<double>{0,1000,20000};

DECLARE @binning  Func<double,SqlArray<double>,double> =
         (n,bin) => { 
            if(n < bin[0]) return double.NegativeInfinity;
            if(n >= bin[2]) return double.PositiveInfinity;
            return ((Math.Floor((n - bin[0]) / bin[1]) + 1) * bin[1]);

@hoge2 =
    SELECT @binning(value, @bin) AS newValue
    FROM @a;
```

release note を読むと、以下のようにパッケージに登録して再利用も容易になるようです。

``` SQL
 DROP PACKAGE IF EXISTS MyFunctions;

 CREATE PACKAGE MyFunctions () AS
 BEGIN
   EXPORT @EnumerateToFloor Func<int,double,IEnumerable<int>> = 
          (x, y) => Enumerable.Range(x, (int) Math.Floor(y));

   EXPORT @TryParseDateTime Func<string, DateTime?> = 
          (d) => {
                   DateTime dt; 
                   var b = DateTime.TryParse(d, out dt); 
                   return b ? (DateTime?) dt : (DateTime?) null;
                 };
 END;
```

さらに、ラムダ同士で呼び合ったりすることも可能。

U-SQLでは、関数のようにパラメータ化された処理を使うことが難しかったのですが、これでインラインのROW-WIDEな処理は少なくともすっきりかけるようになりますね。
Firefoxのブックマークをシェルで分析する

ほんとうはタグクラウドのアドオンを自作したかったんですが、Firefoxのプラグインのつくりかたがよくわからなかったのでとりあえずシェルでやってみることにしました。

`ブックマーク > すべてのブックマークを表示 > ☆ > バックアップ` でJSONとしてブックマークをエクスポートできる。

# タグがそれぞれ何回ずつ使われているか集計する

```sh:tagcount.sh 
#!/bin/sh

#
# usage:
#   cat bookmarks-2018-08-24.json | ./tagcount.sh
#

jq .              |
grep '^ *"tags"'  |
sed 's/^ *//g'    |
cut -d ' ' -f 2-  |
sed 's/^"//'      |
sed 's/",$//'     |
tr ',' '\n'       |
sort              |
uniq -c           |
sort -rn
```

`jq`がはいっていなければいれます。

```sh:jqのインストール
brew update
brew install jq
```

ブックマークのJSONはパイプで渡します。

```shell-session:実行
cat bookmarks-2018-08-24.json | ./tagcount.sh | head -n 20
 353 hoge
 320 Web1.0
 292 読み物
 154 Raspberry Pi
 149 rails
 143 ruby
  95 android
  93 blog
  91 Arduino
  89 fashion
  88 design
  84 wifi
  84 old computer
  72 art
  72 OpenData
  69 マンガ
  68 ポケコン
  68 iOSアプリ開発
  65 IoT
  63 Akiba
```

`fashion` `design` `art` とかが上位にきてるのが意外でした。
Gradleで動かすKotlin版のSparkFrameworkのプロジェクトを1から作成

JVM言語でイチオシのKotlin版の、マイクロフレームワーク[SparkFramework](http://sparkjava.com/)のHelloWorldプロジェクトを作成します。

# 前提

- JVM 1.8
- Grade 4.9

# 手順

まず、プロジェクト用のディレクトリを作成し、`gradle init`で初期化します。

```bash
mkdir sparkjava_sample
cd sparkjava_sample
gradle init
```

`build.gradle`を編集します。

```groovy:build.gradle
plugins {
    id "org.jetbrains.kotlin.jvm" version "1.2.61"
}

apply plugin: 'application'

mainClassName = 'com.example.MainKt'

repositories {
    jcenter()
}

dependencies {
    compile "org.jetbrains.kotlin:kotlin-stdlib-jre8"
    compile "com.sparkjava:spark-kotlin:1.0.0-alpha"
}
```

メインクラスを作成します。

```bash
mkdir -p src/main/kotlin/com/example
touch !$/Main.kt
```

```kotlin:Main.kt
package com.example;

import spark.kotlin.*

fun main(args: Array<String>) {
    val http: Http = ignite()

    http.get("/hello") {
        "Hello Spark Kotlin!"
    }
}
```

サーバーを実行します。

```bash
./gradlew run
```

`> :run`と表示されたら http://localhost:4567/hello にアクセスし、`Hello Spark Kotlin!`と表示されれば :ok:


# 参考

- [Kotlin を Gradle でビルドする minimal サンプル - A Memorandum](http://etc9.hatenablog.com/entry/2017/08/03/190506)
- [Spark Framework: An expressive web framework for Kotlin and Java](http://sparkjava.com/)
新卒２年目がQiitaに投稿してよかったこと

# はじめに
* 私は2017年度からインフラ系SIerとして社会人デビューいたしました。それまでは基本的なコマンドも叩いたことが無く、完全に未経験者として入社いたしました。
* [先日社内研修の中で実施した内容を記事にした](https://qiita.com/FY0323/items/726268e2294a4c5d6cd6)ところ、様々な方からの「いいね」やtwitterでのコメントをいただけました。この時の出来事から、**社外に向けてアウトプットをすることでどんなメリットがあるか**、身をもって知ることができました。
* 「Qiitaやブログなどでアウトプットするのって、怖い。。。」「間違ったことを書いたら叩かれそう。。。」などの理由で、なかなかできない人も多いかと思います。今回は、**初めてアウトプットしてみた個人の観点から、どんなことをしたか、どんないいことがあったかを紹介したい**と思います。

# やったこと
* Qiitaで記事を投稿した
  * k8sの構築がなかなかうまくいかない。。。となったとき、[Rancher](https://rancher.com/)の存在を知りました。構築は[同僚の方がやってくださった](https://qiita.com/3364git/items/287fdf3685cebb4a7ce8)ので、デプロイのほうを私がやってみて、[その結果をQiitaに投稿しました。](https://qiita.com/FY0323/items/726268e2294a4c5d6cd6)
* twitterに質問の投稿をした
  * Rancherをいじってる中で出てきた疑問点について何気なく[twitterで投稿](https://twitter.com/FUTA_0203/status/1024694223205888001)しました。

# アウトプットした結果起こったこと
* 予想以上に反響があった
  * 「いいね」なんて1つもつかないだろうと思って投稿したのですが、[Qiitaに投稿した記事](https://qiita.com/FY0323/items/726268e2294a4c5d6cd6#_reference-9916517370aadf43d242)に対して、社内の人だけでなく、社外の方からも「いいね」を頂くことができました。完全に内向けの投稿のつもりだったのですが、**世界には自分の記事を参考にしてくれる方がいる**ことに気付かせていただきました。

* 疑問点について回答をいただけた
  * 記事を見てtwitterアカウントを見ていただいたのか、[twitterに投稿した疑問点について、回答していただけました。](https://twitter.com/FUTA_0203/status/1024694223205888001)**外向けにアウトプットをすることで、疑問点が解消されることがあることを知ることができました。**

# アウトプットしてよかったこと
* 反応があると単純に嬉しい
  * 「いいね」がつくのを見ただけでテンションが上がります。その結果として、**またアウトプットしたいという気持ちが出てきました。**

* 自分自身の勉強へのエネルギーになる
  * 前項とも関連しますが、アウトプットしようと思うと、自然とクオリティにこだわり始めます。その結果、**もっと勉強しよう！という前向きな気持ちになります。**

* 社外への心理的ハードルが下がる
  * それまでは社外の勉強会に参加するのに少し尻込みしていましたが、**一度何かしらアウトプットすることでその心理的ハードルがずいぶん下がりました。**[先日Rancherの社外勉強会にも参加させていただき](https://rancherjp.connpass.com/event/93510/)、新しい知識や最近の動向なども知ることができました。
 
# まとめ
* 自分で勉強していて何かアウトプットしたいと思っても、「こんな内容じゃ誰も見ないだろうな。。。」と思ってなかなかアウトプットできない方もいらっしゃるかと思います。私もそう思っていました。でも**自分のアウトプットが誰のためになるかは分からない**ものです。本当に基本的な内容でも初学者の人には参考になりますし、どんどんアウトプットした方がいいと思います。
* いきなり社外は難しい、という方は、**まずは社内向けにアウトプットするのがおススメです。**メールやslackなどどんなツールでもいいと思いますが、まずは一歩目を踏み出すのが大事だと思います。
GASでのSendMailについての考察


先日、Googleフォームの登録内容をメールで返信するツールを運用していたところ、email実行回数エラーが発生してしまいました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/278974/fd75c626-8936-5c5a-28d4-fb4f0a20b329.png)

無料版のアカウントを使っているので、メール送信回数に制限があるとは聞いていましたが20通くらいで上限に達してしまっており、これではツールを本格運用する事が出来ません。
MailApp.sendEmailについて、少し調べてみましたので、ここで共有します。

①一日何通まで送れるのか？

　WEBで調べた感じだと1日150通まで送れるという事らしいのですが、明らかに20通くらいでエラーが発生しています。

②CCを入れるとその分送信回数は減るのか？

　本ツールは発信してきた相手（ TO ）に返信しますが、送信内容をシステム管理者にBCCで転送しています。
　BCCには管理者（ツール動作用アカウント）と3名の責任者が含まれますので、1回の動作で5名にメール送信をしています。

　5人に送ることで5通とカウントしているのであれば、1日20回のメール送信で上限に達する計算になるので、この考え方は有力だと思います。

③上限に達した場合、何時にリセットされるのか？

　経験則から言うと、午前11時ごろが濃厚のようです。

＜検証＞

BCCを2名 日を改めてBCCを1名に変えてメール送信回数の上限が変わるか確認する。

1.BCC2名（計3名）→33通で上限
2.BCC1名（計2名）→50通で上限

やっぱりBCCの件数でメール送信可能回数は変わるみたいです。
おそらく上限は1日100通みたいです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/278974/7b5daf39-ed75-9e0b-481c-4af9164f1820.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/278974/af8265ca-deaf-e9ea-2613-572aa0eb4abe.png)

BCCをグループにする事で1日50通送信まではなんとかなりそうですが、50通かーーーー。
有料会員になる事も検討しないといけないかもしれません。
機械学習メモ

# 機械学習メモ

昨日縁があって調べたことを備忘録として.

## 精度について

1. 学習済の DNN を使って推論を実行する場合は INT8(or INT4) で OK
2. DNN の学習処理は FP16(or bfloat16) が必要

## FP16 と bfloat16 の違い

FP16 は IEEE754 の半精度浮動小数点で標準規格だが、Google TPU v2 はそれとは違う bfloat16 をサポートしている. Intel も Cooper Lake で対応するようなので、bfloat16 が事実上の標準になるのかもしれない.

https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/framework/bfloat16.h
> We don't use that format here because conversion to/from 32-bit floats is more complex for that format, and the conversion for this format is very simple.

本家を見るに、bfloat16 は変換が楽、それに尽きるよう.
FP32 の前 16bit を取る(= 後ろ16bit を捨てる)だけで bfloat16 に変換できるのでそりゃそうだではあるが.
NaN でない FP32 は必ず bfloat16 に変換できる(当然精度は落ちる)が、FP32 から FP16 への変換は必ずしも可能ではないことにも注意しておきたい.

## データ形式

NCHW とか NHWC とか表記されるデータ形式が存在する.
それぞれのアルファベットの意味は以下.

https://www.tensorflow.org/performance/performance_guide#data_formats

> * N refers to the number of images in a batch.
> * H refers to the number of pixels in the vertical (height) dimension.
> * W refers to the number of pixels in the horizontal (width) dimension.
> * C refers to the channels. For example, 1 for black and white or grayscale and 3 for RGB.
設計者のためのLGBT対応

# はじめに
LGBTが一般的になりつつありますが、LGBTに対応するシステムは日本では少ないと考えております。

そのため、この記事を通じて、LGBTに対応するため、設計段階から考慮する必要のある要素をまとめたいと思っております。

私の知識の及ばない箇所もあると思いますので、適宜編集リクエストをよろしくお願いします。

また、ここではLGBTのみ取り上げますが、実際の設計の際は、「地域化(L10n)」や「ユニバーサルデザイン（色、文書、フォント）」なども考慮が必要です。

# 設計の考慮事項

## 1.性の多様性
性と言うと、多くの方は戸籍上の性を思い浮かべると思いますが、性は多様です。
種類も多く、「男性」、「女性」に当てはまらない「その他」を考慮する必要があります。

性別を取得する必要性を十分に考慮し、取得の必要がある際は用途を明示するのが望ましいです。

主な性としては下記のようなものがあります。

* 戸籍上の性別
* 自認としての性別
* 社会的役割としての性別
* 肉体としての性別
* 恋愛対象としての性別

また、性別も「男性」「女性」以外にも多くのくくりがあります。

そのため、実際に性別を収集する必要が有る際は、これらに配慮した表記が必要です。

例示
「戸籍上の性別（法制上の処理のため必要）」など、具体的に掲示。
データベース設計の際、多値型、文字列型で処理。

参考
[性別は18種類　「LGBT」先進国タイの第一線で活躍する人たち](https://abematimes.com/posts/2582573)
[Facebookの性別欄は58種類！ 男性でも女性でもない性のこと](https://www.fnn.jp/posts/00312930HDK)

## 2.性別の変更
性別は、手続きにより変更可能で有り、性自認は時間とともに変わります。
システム上、性別は変わる前提に立ちシステムの設計が必要です。

例示
プロフィール変更などで、性別も変更可能とする。

参考
[性別の取扱いの変更](http://www.courts.go.jp/saiban/syurui_kazi/kazi_06_23/index.html)
[性自認は変わることもある 自分の性別はいつだって自分が決められるもの](http://lgbt-jp.com/gender-select-2907)


## 3.名前の変更に対する考慮
姓が、結婚や養子縁組などで変わることをご存じの方は多いと思いますが、名も手続きにより変更可能です。

名前、読みはプロフィール変更で変えられるシステムが多いですが、考慮が必要です。

参考
[名前を変えるには？！ 性同一性障害で改名する方法](http://joseika.jp/699)
[性同一性障害 改名の方法](http://lgbt-jp.com/name-change-779)

## 4.通名の使用について
3.にも該当しますが、LGBTを理由として法的な手続きのために通名を使用する場合があります。

名前を入力させる際には、必要な理由（本名を求める場合）または、ニックネームを合わせて入力するのが望ましいです。

本名が必須では無い場合、ニックネームとするのがなお良いと考えます。

# まとめ
LGBTへの対応は、地域化やユニバーサルデザインと合わせて、昨今のシステムでは必須と考えております。

LGBT対応に限りませんが、人をステレオタイプにはめずに、個人を認めて、個人に対応できるシステムの設計を考えるのが一番だと考えております。

また、昨今はビッグデータのために多数の情報を取得するシステムも多いですが、情報はリスクで有ることを理解し、「収集しない選択」を考慮するのが望ましいです。

本名は本当に必要なのか？
性別は本当に必要なのか？

システムを設計する際に考慮いただけると助かります。
最も簡単なDockerの公式セットアップ方法(CentOS/Ubuntu)

# 概要「覚えるのはget.docker.comだけ」

Docker が公式 https://get.docker.com/ で配布している便利なスクリプト(Convenience Script)を使うと、ディストリビューションを自動判別して（CentOS 7/Debian 8/Ubuntu/Fedora）自動的にリポジトリの設定と Docker Engine パッケージのセットアップを行う方法があります。

本番環境では非推奨ですが（作業にはroot権限が必要なためと、意図しないバージョンのセットアップの可能性）、 **新規環境** でテスト用途や検証で素早く Docker を使うには便利な方法です（稼働中の環境で実行すると、既存の設定を上書きする場合があります）。

以下、CentOS 7 と Ubuntu 18.04 で Docker CE(Community Edition) をセットアップする手順です。

## ポイント

https://get.docker.com にアクセスして出てくる内容が、セットアップ用スクリプトそのものです。そのため、この URL さえ覚えておけば、ブラウザからでも、あるいは `curl` や `wget` で簡単にセットアップできます。

![get-docker.png](https://qiita-image-store.s3.amazonaws.com/0/13002/dffc3a09-f03c-2eba-0f36-ce1208bffd2b.png)


## 手順

### CentOS 7 の場合

1. サーバにログインし、`root` または `sudo su -` などで同等の権限に切り替えます。
2. セットアップ用コマンドを実行します。

```
$ curl -fsSL get.docker.com -o get-docker.sh
# sh get-docker.sh
```
これは https://get.docker.com/ のファイルを `get-docker.sh` に保存します。ファイルはシェルスクリプトなので、 `sh get-docker.sh` でセットアップ用スクリプトを実行します。
3. Docker Engine を起動します。

```
# systemctl start docker
# systemctl enable docker
```

4.動作確認をします。

```
# docker version
Client:
 Version:           18.06.1-ce
 API version:       1.38
 Go version:        go1.10.3
 Git commit:        e68fc7a
 Built:             Tue Aug 21 17:23:03 2018
 OS/Arch:           linux/amd64
 Experimental:      false

Server:
 Engine:
  Version:          18.06.1-ce
  API version:      1.38 (minimum version 1.12)
  Go version:       go1.10.3
  Git commit:       e68fc7a
  Built:            Tue Aug 21 17:25:29 2018
  OS/Arch:          linux/amd64
  Experimental:     false
```

`Server:` の部分の応答があれば問題ありません。
5. Docker を楽しみましょう。`docker` コマンドが普通に使えます。
6. 後片付け
不要になったらパッケージとデータ用領域を消せます。

```
# yum remove docker-ce
# rm -rf /var/lib/docker
```

### Ubuntu 18.04 LTS の場合

1. セットアップ用のスクリプトをダウンロード＆実行します。

```
$ wget -O get-docker.sh https://get.docker.com
$ sudo sh ./get-docker.sh
```

2.動作確認をします。

```
# docker version
Client:
 Version:           18.06.1-ce
 API version:       1.38
 Go version:        go1.10.3
 Git commit:        e68fc7a
 Built:             Tue Aug 21 17:24:51 2018
 OS/Arch:           linux/amd64
 Experimental:      false

Server:
 Engine:
  Version:          18.06.1-ce
  API version:      1.38 (minimum version 1.12)
  Go version:       go1.10.3
  Git commit:       e68fc7a
  Built:            Tue Aug 21 17:23:15 2018
  OS/Arch:          linux/amd64
  Experimental:     false
```

`Server:` の部分の応答があれば問題ありません。
3. Docker を楽しみましょう。`docker` コマンドが普通に使えます。
4. 後片付け
不要になったらパッケージとデータ用領域を消せます。

```
# sudo apt-get purge docker-ce
# sudo rm -rf /var/lib/docker
```




## 参考

- Get Docker CE for CentOS | Docker Documentation
 - https://docs.docker.com/install/linux/docker-ce/centos/

- Get Docker CE for Ubuntu | Docker Documentation
 - https://docs.docker.com/install/linux/docker-ce/ubuntu/#install-using-the-convenience-script
ScriptPubKeyについて

#ScriptPubKeyとは #
Bitcoinではトランザクションの有効性を検証するためにScript言語というものを用いています。
Bitcoinのトランザクションにはinputとoutputが含まれますが、inputに用いるものがunlocking script（ScriptSig）で、トランザクションの鍵を解除するためのスクリプトです。
また、outputに用いられるものがlocking script（ScriptPubKey）と言います。
locking scriptはトランザクションのアウトプットに置かれる解除条件で、アウトプットを使用する際に満たさなければいけない条件を指定する、鍵をかけるためのスクリプトです。

# Script言語　#
script言語は、スタックベースの言語で左から右に向かって実行されます。
ここでいうスタックはデータ構造のスタックと同様のもので、先入れ後出しの形で命令が処理されていきます。
ビットコインのP2PKH（pay to public key hash)を使用したスクリプトでは
ScriptPubKeyは次のようなスクリプトになっています。

```
OP_DUP OP_HASH160 <PublicKey Hash A>  OP_EQUALVERIFY OP_CHECKSIG
```

OP_DUPはスタックのトップを複製して1番上に追加します。
OP_HASH160　スタックのトップをSHA-256でハッシュし、次にRIPEMD-160でハッシュします。
OP_EQUALVERIFYは2つの要素が等しければ1を、等しくなければ0を返すOP_EQUALを実行した後、OP_VERIFYを実行します。
OP_VERIFYはスタックのトップが1でなければトランザクションを無効とします。1の場合は何もしません。その後トップの要素が削除されます。
OP_CHECKSIGは署名の妥当性を検証して1（署名成功）または0（失敗）を返します。

一方で、ScriptSigは

```
<Signature A> <PublicKey A>
```
となっています。
ScriptSigとScriptPubKeyを組み合わせて以下のスクリプトを検証することでトランザクションに入っているビットコインを使用することができるようになります。

```
<Signature A> <PublicKey A> OP_DUP OP_HASH160 <PublicKey Hash A> OP_EQUALVERIFY OP_CHECKSIG
```

# P2PKHの流れ#

①　< Signature A> < PublicKey A>をスタックに積みます

```
<Signature A> <PublicKey A>
```
②OP_DUPでスタックのトップにある< PublicKey A>が複製され、追加されます

```
<Signature A> <PublicKey A>　<PublicKey A>
```
③OP_DUPでトップにある< PublicKey A>のハッシュを計算して< PublicKey Has A>としてスタックに追加します

```
<Signature A> <PublicKey A>　<PublicKey Hash A>
```
④< PublicKey Hash A>をスタックに追加します。

```
<Signature A> <PublicKey A>　<PublicKey Hash A>　<PublicKey Hash A>
```
⑤OP_EQUALVERIFYで上２つの<PublicKey Hash A>が等しいか検証し、正しければ1、そうでなければ0を積み、その後OP_VERIFYで1番上の要素を削除する

```
<Signature A> <PublicKey A>
```
⑥OP_CHECKSIGで署名をチェックする。1（署名成功）または0（失敗）を返す。
このような流れでトランザクションが検証されます。

# 参考　#
「BIP16 : P2SH の仕組み」https://developers.yenom.tech/entry/2018/08/18/143918

「ブロックチェーン・プログラミング　仮想通貨入門 」http://bookclub.kodansha.co.jp/product?item=0000148221


「Bitcoin wiki Script」https://en.bitcoin.it/wiki/Script
SPAからconsole.error() でBugsnagにエラー情報を送信する。

# 課題

　目下、ReactによるSPA(Single Page Application)の開発に関わっており、その途上で以下の課題

- [console.error()](https://developer.mozilla.org/ja/docs/Web/API/Console/error) に[Error](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Error)オブジェクトを渡すことで、 [Bugsnag](https://www.bugsnag.com/) にエラー情報が送られるようにしたい。

が発生したので取り急ぎ以下のように解決した。

# 解決策

　`console.error()`の先頭パラメーターが[Error](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Error)オブジェクトの場合、そのError情報がBugsnagに送信され、それ以外はデフォルトと同じ動作をするようにした。概略は以下。

```shell-session
yarn add bugsnag-js
```

```javascript
import bugsnag from 'bugsnag-js';

const origConsoleError = console.error;

console.error = (...args) => {
  if (args.length > 0 && /Error$/.test(args[0].constructor.name)) {
    bugsnag(BUGSNAG_API_KEY).notify(args[0]);
  }
  origConsoleError(...args); // 既存の console.error を呼ぶ
};
```

```javascript
console.error(new Error('This is an Error.'));  // sending Error info to Bugsnag
```

　なお上記で`BUGSNAG_API_KEY` には、環境変数から取得した API KEYが`webpack.DefinePlugin`経由で入ってくる想定。
　他によいやり方があれば教えてください。