OmniAICreator/Qiita-1.07M huggingface dataset:
Programming Paradigms

A programming paradigm is a style, or “way,” of programming.
<strong>some common paradigms:</strong>
<ul>
   <li><em><strong>Imperative:</strong></em> Programming with an explicit sequence of commands that update state.</li>
   <li><em><strong>Declarative:</strong></em> Programming by specifying the result you want, not how to get it.</li>
   <li><em><strong>Structured:</strong></em> Programming with clean, goto-free, nested control structures.</li>
   <li><em><strong>Procedural:</strong></em> Imperative programming with procedure calls.</li>
   <li><em><strong>Functional (Applicative):</strong></em> Programming with function calls that avoid any global state.</li>
   <li><em><strong>Function-Level (Combinator):</strong></em> Programming with no variables at all.</li>
   <li><em><strong>Object-Oriented:</strong></em> Programming by defining objects that send messages to each other. Objects have their own internal (encapsulated) state and public interfaces.
<ul>Object orientation can be:
   <li><em><strong>Class-based:</strong></em> Objects get state and behavior based on membership in a class.</li>
   <li><em><strong>Prototype-based:</strong></em> Objects get behavior from a prototype object.</li>
</ul></li>
   <li><em><strong>Event-Driven:</strong></em> Programming with emitters and listeners of asynchronous actions.</li>
   <li><em><strong>Flow-Driven:</strong></em> Programming processes communicating with each other over predefined channels.</li>
   <li><em><strong>Logic (Rule-based):</strong></em> Programming by specifying a set of facts and rules. An engine infers the answers to questions.</li>
   <li><em><strong>Constraint:</strong></em> Programming by specifying a set of constraints. An engine finds the values that meet the constraints.</li>
   <li><em><strong>Aspect-Oriented:</strong></em> Programming cross-cutting concerns applied transparently.</li>
   <li><em><strong>Reflective:</strong></em> Programming by manipulating the program elements themselves.</li>
   <li><em><strong>Array:</strong></em> Programming with powerful array operators that usually make loops unnecessary.</li>
</ul>
<p>Paradigms are not meant to be mutually exclusive; a single program can feature multiple paradigms!</p>
some observations:
<ul> 
  <li>Very few languages implement a paradigm 100%. When they do, they are pure. It is incredibly rare to have a “pure OOP” language or a “pure functional” language.</li>
   <li>A lot of languages will facilitate programming in one or more paradigms.</li> 
</ul>
main source used for this article : <a href="http://cs.lmu.edu/~ray/notes/paradigms/" target="_blank">Paradigms</a>.
Windows で強制的にディレクトリを削除する

# 免責
使い方次第では危険なコマンドが含まれています。
使い方には注意してください。
何か問題が発生しても当方では一切の責任を負いません。

# はじめに
まれに権限のおかしいフォルダ・ファイルがユーザーフォルダ下にも関わらずできてしまい、管理者ですら削除できないということがある。
そんなときの備忘録。

# 所有者の設定
`chown` 的な

```
> takeown /s <PCNAME> /u <USERNAME> /f .\TARGETPATH /r
```
- `/s` : PC の名前。設定->システム->バージョン情報->デバイスの仕様のデバイス名から確認できる
- `/u` : 設定するユーザーネーム
- `/f` : ファイルまたはフォルダを指定する
- `/r` : 再帰的に処理する

内容を読み取る権限すら無いとここで警告される。
そのアクセス許可もここで同時にできる。

# 権限の設定
`chmod` 的な

```
> icacls .\TARGETPATH /grant <USERNAME>:F /T
```

- `/grant` : 指定したユーザーにアクセス権を付与。`:` の後ろには以下のような(一部抜粋)許可マスクを使用できる

    ```
     N - アクセス権なし
     F - フル アクセス権
     M - 変更アクセス権
     RX - 読み取りと実行のアクセス権
     R - 読み取り専用アクセス権
     W - 書き込み専用アクセス権
     D - 削除アクセス権
    ```
- `/T` : 再帰的に処理する

# 削除の実行

```
> rd /s .\TARGETPATH
```

- `/s` :ファイルやサブディレクトリも含めて削除する
JSONを受ける -  Angular 6 メモ

# コレは何？
Angular&TypeScript初心者が、`@angular/common/http`を使ってレスポンスをJSONで受け取る部分でのコンパイルエラーに「えっ？型のエラー？どうするの？」と四苦八苦したときの解決メモです。（解決方法が正しくなかったらご指摘いただけると幸いです）

## エラーの内容
<font color="Red">ERROR in src/app/hoge/hoge.component.ts(xx,yy): error TS2339: Property 'data' does not exist on type 'Object'.</font>

「`data`と指定しているけど、その`Object`には`data`というプロパティ（属性、要素）は存在してないよ。」という内容。意訳すると「（あるかもしれないけど）`data`ってプロパティがあるよ、って指定されてない`Object`よね」っていう指摘です。

ちなみに、エラー時の`hogehoge()`はこうなっています。これを解決する修正方法を以下に2つ書きます。

````typescript:hoge.component.tsのhogehoge()を抜粋
  hogehoge() {
    this.http.get('/api/hogehoge').subscribe( res => {
      let response = res;
      this.test_data = response.data;  // <<<<< ココでエラー発生 <<<<<
    }, err => {
      if(err.status === 401) {
          this.router.navigate(['login']);
      }
    });
  }
````



# エラーを修正したコード
シナリオ：「APIエンドポイントの`/api/hogehoge`からデータ（JSON）を取得、取得データの要素`data`を`test_data`にセットする」

## anyを使う
その名の通りで`any`は「何でもOK型」です。せっかくの`TypeScript`なn....(ry。
実装時は最も速く簡単な指定方法です。

````typescript:hoge.component.ts
import { Component, OnInit } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
.
.
@Component({
.
.
})
export class HogeComponent implements OnInit {

  private test_data: String[];

  constructor(private http: HttpClient) { }

  ngOnInit() { }

  hogehoge() {
    this.http.get('/api/hogehoge').subscribe( res => {
      let response:any = res;  // <<<<< 違いはココ <<<<<
      this.test_data = response.data;
    }, err => {
      if(err.status === 401) {
          this.router.navigate(['login']);
      }
    });
  }

}
````

## Interfaceを使う
APIからのレスポンスが固定されている場合は恩恵を受けやすい。「あれっ、ここってどんな形でレスポンス返ってくるんだっけ？」というのも起きづらくなるでしょう。

````typescript:hoge.component.ts
import { Component, OnInit } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
.
.
interface ResJSON {
    success: boolean;  // <<<<< 区切りはコンマ(,)ではなくセミコロン(;) <<<<<
    data: any;  // <<<<< 区切りはコンマ(,)ではなくセミコロン(;) <<<<<
}
.
.
@Component({
.
.
})

export class HogeComponent implements OnInit {

  private test_data: String[];

  constructor(private http: HttpClient) { }

  ngOnInit() { }

  hogehoge() {
    this.http.get('/api/hogehoge').subscribe( res => {
      let response = <ResJSON>res;  // <<<<< 違いはココ <<<<<
        this.test_data = response.data;
      }, err => {
        if(err.status === 401) {
          this.router.navigate(['login']);
      }
    });
  }

}
````
# 参考

- [TypeScriptの型入門](http://bit.ly/2uneuiL)


# お礼
@takustaqu さん、ありがとうございました！
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">Interfaceで帰ってくるJSONの通りに型定義しておくか、any型で逃げるかのどちらかで。</p>&mdash; Harada Yayane &quot;Moses&quot; Kiyohide (@takustaqu) <a href="https://twitter.com/takustaqu/status/1019098509675380736?ref_src=twsrc%5Etfw">July 17, 2018</a></blockquote>

<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">とはいえちゃんとInterfaceで定義してると後々楽ではあるので。是非。</p>&mdash; Harada Yayane &quot;Moses&quot; Kiyohide (@takustaqu) <a href="https://twitter.com/takustaqu/status/1019107821420285952?ref_src=twsrc%5Etfw">July 17, 2018</a></blockquote>
MacでVLCを使って1時間に1回slackに画面録画をアップロードする

ゲーム開発とかしてるときに、100時間くらい放置すると発生するバグってありますよね(僕だけだったら悲しい)。そういうバグを検証するために、人間が労力を使うのは面倒です。起動しっぱなしにして、画面を定期的に録画しましょう。ついでにslackにうｐしましょう。

こちらが今回の完成コードです

```bash
while :
do
    filename=/tmp/$(hostname).mp4
    vlc screen:// --no-interact --sout "#transcode{vcodec=h264,vb=3072}:standard{access=file,mux=mp4,dst=${filename}}" &
    pid=$!
    sleep 30
    kill -SIGINT ${pid}
    sleep 10
    kill -SIGINT ${pid}
    sleep 10
    ./slack file upload $filename $CHANNNEL_NAME
    sleep 3600
done

```

### コマンドラインから画面録画する

VLCを使います。インストールは `brew cask install vlc`。
MacならQuicktimeで画面録画するのが普通だろう、という声がありそうですが、調べてみても、コマンドラインから叩くにはapplescriptを使わなきゃいけなそうで、正直面倒でした。その点VLCは最初っからcliツールがついてくるので素敵。

この辺( https://stackoverflow.com/questions/22084098/vlc-screen-capture-using-terminal )の議論を参考にして、なるほど、コマンドラインから画面録画を起動して、適当にSIGINT送ればエンコードして保存してくれるんだな、と。

ということで上記のコマンドの `vlc~~~dst=${filename}` で起動して、 `pid=$!` でpid記録しておいて、 `kill -SIGINT ${pid}` でうまくいきました。ただ、SIGINT送った時点ではエンコード始まるだけっぽくて、その後適当にsleepしてます。pidがpsからなくなるまで待つ、ってやったほうが綺麗かと思います。

ちなみに僕は、複数台で再現実験を同時にやるために、ファイル名にhostnameをつけてます。

### slackに動画を投稿する

この機能はおまけですが。slackに動画投稿しておけば、自分以外の誰かがこの実験確認したいときにも便利かな、と。

slack-cli( https://github.com/rockymadden/slack-cli )を使います。
インストールは `curl -O https://raw.githubusercontent.com/rockymadden/slack-cli/master/src/slack`。

いくつかあるslackのcliの中でもコマンドが整理されてて使いやすいです。 `slack file upload ファイル名 チャンネル名` でサクッと投稿できました。
Raspberry Piでbluetoothシリアル通信

RaspberryPiにbluetooth機器を接続してpythonで通信させようとしたけど，うまくいかなかった記録．
とりあえず動くまではいきましたが，まだ不安定な部分があるので日々加筆します．


# 環境
PC:aRaspberry Pi 3
OS:Ubuntu MATE 16.04

# 手順
[参考１](http://netlog.jpn.org/r271-635/2016/01/ubuntu_bluetooth_serial.html)
[参考２](https://qiita.com/shskwmt/items/fffabf521201f5835214)

## デバイスのスキャン
まずはデバイスが認識されているかスキャンしておく<br>
デバイス名の前についてるのはMACアドレス

```shell-session:scan
$ sudo hcitool scan
[sudo] password for pi:
Scanning ...
	00:07:80:3C:xx:xx	device1
	90:CD:B6:37:xx:xx	device2
```

一応確認のためping飛ばしとく

```shell-session:ping
$ sudo l2ping -c 2 00:07:80:3C:8E:F2
Ping: 00:07:80:3C:xx:xx from B8:27:EB:E3:yy:yy (data size 44) ...
4 bytes from 00:07:80:3C:xx:xx id 0 time 70.46ms
4 bytes from 00:07:80:3C:xx:xx id 1 time 64.60ms
2 sent, 2 received, 0% loss
```

## シリアルポートにバインドする
/dev/rfcommX　にバインドすることで，bluetoothで仮想シリアル通信できるようになる．

```shell-session:bind
$ sudo rfcomm bind 1 00:07:80:3C:xx:xx
```

番号は0から何番かまで使える．

### 自動設定する
rfcommは再起動すると設定が失われる．
そのため，再起動しても設定を継続したい場合はrfcomm.confを作成する必要がある．

```config:/etc/bluetooth/rfcomm.conf
rfcomm0 {
        # Automatically bind the device at startup
        bind yes;

        # Bluetooth address of the device
        device 00:07:80:3C:xx:xx;

        # RFCOMM channel for the connection
        channel 1;

        # Description of the connection
        comment "IMU config";
}
```
**この方法うまくいかなかったんで誰か教えてください**

## bluetoothctlからペアリング
bluetoothctlがない人はインストールしてください．

```shell-session:install
# $ sudo apt install bluez bluez-utils

#起動
$ bluetoothctl
```

対話モードで設定

```shell-session:config
# コントローラ起動
$ power on

#デバイスのMACアドレスを検索
$ devices

# デバイスがないときはスキャン
$ scan on

# ペアリング
$ pair [MAC]
```


これで接続できる．（はず）
Reactを貫く概念 - single source of truth

いろいろあって、他の仮想DOMライブラリからReactも使おうと入門してみたのですが、仮想DOM以外のところの概念に少し感心してしまいました。

# 入門の経緯

もともと、複雑化するビュー内の制御にjQueryだけで行き詰まっていたところで、Riot.jsを使い始めました。

これはCSSまで1モジュールになっている、呼び出す側にはHTMLでタグを埋め込むだけなど、比較的使いやすかったのですが、もともとの制御がDOMベースとなっていることもあって、[動的に`<table>`を構築するには限界がある](https://qiita.com/jkr_2255/items/ddb00e04a7328f30829e)、そしてHTML断片を変数に入れて制御することができないので、1タグの中でしか使い回さない要素などの細かなレベルでの使い回しが難しい、というような問題を抱えていました。

そして、シンプルな仮想DOMライブラリとしてPicodomを導入したのですが、シンプルすぎてモジュール分けがうまく行かなかったこと、そしてライブラリの名前すらpicodom→ultradom→superfineと転々とするように、ライブラリとして安定しない状態が続いたこともあって、使い続けるのに困難さを覚えるようになっていました。

そこで、「一定のユーザー層があって、ライブラリとしてある程度安定していること」も加味したところ、Reactというところにたどり着いた次第です。

# フォーム要素の4つの役割

何気なく使っている、`<input>`などのフォーム要素には、大きく分けると4つの役割があります（もちろん、設定やフォームの性質上、特定の役割を持たないこともあります）。

1. ユーザーからの値の入力
2. 設定した状態の保存
3. 状態の表示
4. フォーム送信時に値を伝える

JavaScriptでフォームを制御する場合、2の「状態の保存」が厄介になる要因の1つで、JavaScriptで持っている値とフォーム側の値が一致しなくなって混沌としたりもします。

ここでReactは、「フォームには、実質的に値を保存させない」（仮に変更しようとしても、何も設定しなければReact内で持っている値から変わらない）という方法で問題を解決しています[^1]。フォーム自体ではない、JavaScriptで管理できる1箇所（single source of truth）で値を管理する構造を取るためのビルディングブロックです。

# 値の流れ
## 1階層のコンポーネントの場合

あるコンポーネントの内部にある`<input>`で、それを変化させても外部に伝える必要のない場合、Reactでは以下のように構築します。

* `<input>`の`value`には、`state`のプロパティをセットする
* `onChange`にセットしたイベントハンドラで、`this.setState`を行って、`state`内を書き換える

ここでは、値が変化するのは`state`内のたった1つだけ、という形でsingle source of truthを実現しています。

## 多層のコンポーネントの場合

ここでは、Reactのコンポーネントが持つ2つの属性である`state`と`props`について考えてみましょう。

* `state`…コンポーネントが内部状態として持つ値、基本的に外部から設定・参照すべきものではない
* `props`…コンポーネントに外部から設定する値、コンポーネント内で書き換えてはいけない

となれば、子コンポーネントから親コンポーネントの値を変更したい場合の手段がないようにも見えます。じつは、ここでもネイティブのDOM要素と同様に、`props`の一部としてイベントハンドラをセットする方法が推奨されています。「DOM要素でイベントが起きる」→「子コンポーネントでも`props`にセットされたイベントを呼ぶ」→「親コンポーネントが自らの`state`を更新する、あるいは更に上にイベントを伝える」→「それを`props`として子コンポーネントに伝える」→「子コンポーネントから`props`としてDOM要素に値を流す」という形で、親コンポーネントより上にsingle source of truthを集約する形となります。

# まとめ

「値を自分で管理するコンポーネント」と「外部から来た値とイベントだけを管理するコンポーネント」をきちんと峻別しないと混沌とする、と感じました。

[^1]: プログラム的に値を書き込めない`<input type="file">`を筆頭に、Reactで値を管理しないで使うという手段も、なくはないです。
Amazon echoで流れた曲をスプレッドシートへ記録しつつPrimeMusicへのリンクを貼る

# 前置き
GoogleHome mini 3台買っただけで飽き足らず、Primeデーの半額セールで echo dot まで買ってしまったので、ちょっと遊んでみました。

基本的にやってることは、以下の記事でされていること＋αです。スプレッドシートに記録されるのはいいけれど、この曲いいなーと思った時に調べるのが面倒だったから、リンクまで自動で生成しておけばいいんじゃないのと思った次第。

[参考] [IFTTTを使ってAmazon echoで流れた音楽のタイトルと歌手名をslackとspreadsheetに連携する](https://qiita.com/hideno0110/items/71b713332075cc6120cc)

# IFTTTでの設定
基本設定は上記参考記事をご覧いただくとして……追加で設定するところだけ書いておきます。
Formatted Row の欄を以下のように設定します。

```
{{PlayDateTime}} ||| =HYPERLINK("https://music.amazon.co.jp/search/{{SongName}}+{{ArtistName}}","{{SongName}}") ||| {{ArtistName}} ||| {{AlbumName}}
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/37739/0d249a26-0596-28af-cecb-b2c9d2abcc1c.png)


||| っていうのはセル列の区切りになります。

私は曲名をリンク化しましたが、他でも構いませんし、URLとかいうセル列を追加しても良いと思います。
あと、アーティスト名のところにGoogleリンクを貼るようにするとか。GETパラメータ渡すだけなので簡単に色々できそうですね。


# 結果
スプレッドシートで途中からリンクがつくようになってます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/37739/6acded78-5180-615a-cf4c-d2b6ec2f8b34.png)

リンク先に飛んで見ると、ほらこの通り。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/37739/a52261a6-7b28-ae46-67b4-47904204e8c3.png)

ね、簡単でしょう？

ちなみに、ランダムで再生された PrimeMusic のリストの命名と選曲とがちょっと頭オカシイ感じで、「夜のランニング用ヘヴィメタル～ミドルテンポ 」なのに、何故か、チルボドやメガデスやソナタアークティカが入って思いっきり高速に疾走しているっていう……
階層的クラスタリングとk平均法

# クラスタリングのそもそも
まずはクラスタリングのそもそもの説明から入っていく。

クラスタリングは、機械学習のなかでもいわゆる教師なし学習に含まれる。
つまり、模範解答によって訓練し規則性を見つけ出す（分類、回帰）教師あり学習とは目的が異なる。

**クラスタリングの目的とは、データセットのなかでグループを見つけ出すことである。**

例えば、顧客データのクラスタリングによって、顧客の購買傾向をグループ化してそれぞれに最適なレコメンドを行うことができる。

ちなみに、犬と猫の画像データにそれぞれ「犬」「猫」とラベルをつけて判断させるのが**分類(Classification）**で、
同じ画像データでも正解を教えず、分類器が自ずと犬と猫の違いを導くのが**クラスタリング(Clustering)**である。

# 階層的クラスタリング
クラスタリングには階層的手法と非階層的手法がある。
階層的クラスタリングでは、もっとも類似度の高い組み合わせをまとめていくことを繰り返し、グループの階層を作っていく。

ノードがツリー構造になるのを想像してもらうとわかりやすい。これがいわゆる**デンドログラム**である。
このデンドログラムは、アイテム同士の距離も表すことができるので、クラスタ内のアイテムがどの程度似ているのかを知る助けにもなる。

ところが、階層的クラスタリングのツリー構造には、いくつか欠点もある。
まず、そのままでははっきりとしたグループに分けられない。
そして、**計算量が非常に大きい**。
アイテムの全ての組みに対して計算を行う上に、アイテムがマージされると再計算が必要になる。
（階層の高さによってクラスの数を決める）
つまり、大きなデータセットを扱う場合には不向きである。

# k平均法
そこで、非階層的手法の中にk平均法という手法がある。
k平均法では、あらかじめ決めておいた数のクラスターにアイテムを振り分けていく。
階層的手法と違って、ビッグデータ分析にも用いることができる。

### アルゴリズム
1. アイテムから、クラスタの重心をk個決める
2. 全てのアイテムと重心の距離を計算。各アイテムはもっとも近い重心のクラスになる
3. 2で求められたクラス内で、アイテムのノードの平均をとり、重心を再度割り当てる
4. 2と同じ要領でクラスが求められる
5. 3と4を、重心の割り当てに変化が生じなくなるまで繰り返す

### 問題点
k平均法では注意すべき点がある。
それが、**あらかじめ決めるクラスターの数**である。
重心の決め方によって、クラスタリングが正確にならない恐れがある。
いくつのクラスターに分けるのかに直接的な正解はないので、分析するときに頭を悩ませるポイント。

# クラスタリングで注意するポイント
なお、このような問題はk平均法だけの問題ではない。
クラスタリングは教師なし学習なので、分析結果に対して妥当かどうか考える必要がある。
また、あくまでデータの傾向を知るものなので、その分類結果を絶対的な答えとして用いるのは誤りである。
大きなデータに対して、アイテム同士にどのようなデータの傾向があるのかを見てみる手法として、クラスタリングは用いたい。
SQLのJOINが分からない？ じゃあ逆から考えてみよう (親子関係を例にしたりして) 

# 親子関係

Alice には二人の子供がいる。
Carol と David だ。

Bob にも二人の子供がいる。
Eric と Frank だ。

これをデータベースの「1個のテーブル」で表すと、こんな感じになるだろう。

|Parent|Child|
|:--|:--|
|Alice|Carol|
|Alice|David|
|Bob|Eric|
|Bob|Frank|

AliceもBobも行が重複しているが、1個のテーブルで表現しようとすると仕方がないのだ。


# 分割してみよう

このテーブルを二個に分割したらどうなる？


|Parent|
|:--|:--|
|Alice|
|Bob|

|Child|
|:--|:--|
|Carol|
|David|
|Eric|
|Frank|

やった、データが綺麗になったぞ！

だけどちょっと待てよ。
誰が誰の子供か分からなくなってしまった。

# IDを付けてみよう

親にIDを付ける。
あくまでも親だけだ。子供になんてとんでもない。

Aliceは1でBobは2。

|Id|Parent|
|:--|:--|:--|
|1|Alice|
|2|Bob|

そして子には親のIDを教えるのだ。
忘れるなよ。君たちの親だぞ。

|Child|ParentID|
|:--|:--|
|Carol|1|
|David|1|
|Eric|2|
|Frank|2|

# 合流だ！

*JOINしよう!*

これで親子は再び出会えました。
もう離れることはありません。

めでたしめでたし。

|Id|Parent|Child|
|:--|:--|:--|
|1|Alice|Carol|
|1|Alice|David|
|2|Bob|Eric|
|2|Bob|Frank|

いずれ子供が増えた時も、子が親元を離れる時も、テーブルも分割されているし、きっとうまくいくことでしょう。

# 具体的なSQLは？

心の眼で見るのです。

このQiitaはあなたの脳に直接語りかけました。









<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
なぜなぜ分析心得

#心得
1. 人間は間違いを犯すと心得よ
2. すべての間違いを発見することは不可能と心得よ
3. 用語の意味を理解せよ
4. なぜなぜ分析の最終目標は予防システムの綻びを直すことと心得よ
5. 危険予知訓練も予防システムの一つと心得よ
6. 危険個所は変換する工程にありと心得よ

#意味
1. だから、誰かが、何かが、フォローして、不良を起こしにくく、発見しやすく、影響を最小限にする仕組みが必要
2. テストカバレッジ100%の組み合わせは数億通り・・非現実的<br>
人間のすべての行動をシステムに盛り込むのは不可能<br>
作りこみをコントロールするコストは発見するコストの何倍も小さい
3. 真因と根本的原因<br>
真因とは車を止める（事象の連鎖）に至った最初の部品を特定すること<br>
根本的原因は部品が不良となった作業上の不備、環境上の不備、管理上の不備
4. 予防システムとは、作業**環境**の中で不良を起こしにくく、発見しやすく、影響を最小限にするための仕組み
5. 予防システムとは、作業**手順**の中で不良を起こしにくく、発見しやすく、影響を最小限にするための仕組み<br>
6. 変換工程＝人から人、知識からドキュメント、設計書からソース・・・
だから変換工程が少ないオブジェクト指向はバグが少なくなるはず
OculusGoのホームボタン(Oculusボタン)長押しを取得する方法

ホームメニューやブラウザなどでコントローラーのホームボタン(Oculusボタン)長押しをするとVR空間の方向がリセットされますが、これをunityで検出するには「OVRInput.GetControllerWasRecentered()」を使います。

環境: Unity 2018.1.5f1 (64-bit) / OculusUtilities(1.26.0 2018/06/20)

## コード
``` C#
if (OVRInput.GetControllerWasRecentered(OVRInput.GetActiveController())) {
    Debug.Log("reCenter!");
}
```
書籍「インフラCI実践ガイド Ansible/GitLabを使ったインフラ改善サイクルの実現」の環境構築メモ

この本の環境として、CentOS7が求められていたので、Ubuntuの入ったマシンにCentOS7を上書きインストールした。
CentOSのインストール前後の設定でつまづいたので、対処法をメモ。

# CentOSのインストール時
## インストールするソフトウェア
デフォルトは最小構成になっており、ユーティリティやGUIはインストールされない。
Linuxの習熟度がそこまで高くもないので、ユーティリティとGNOME Desktop環境はインストールするように指定。

## パーティション
以前は無駄に細かく設定していたが(後述の問題の原因にもなっているので良いこと特になかった)、
大した用途に使うわけでもないので下記のように設定。

| マウントポイント | サイズ |
|:--|--:|:--:|
| /boot | 500 MB |
| swap | 8 GiB |
| / | 50 GB以上の適当な値 |
| /home | Ubuntuそのまま |

「/」と「/home」のサイズは適当。
「/boot」と「swap」のサイズは以下のページを参考に決定。「/boot」は300 MBもあれば十分らしいが、一応500 MBに設定。
https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/6/html/installation_guide/s2-diskpartrecommend-x86

蛇足だが1 GiB = 2^30 B。1 GB　＝10^9 Bらしい。GiBを使うと正確に2の累乗が表現できるということ。

## パーティションサイズが指定できない問題への対処
CentOSの/bootのパーティションのサイズを指定した時、サイズが94MBから変えられない問題に遭遇(/boot以外のマウントポイントでも類似の問題発生)。
元のUbuntuの/bootパーティションのサイズが94MBであり、それがそのまま使われてしまうらしい。
インストール作業を開始する前に、GPartedでいらないマウントポイントを事前に削除することで解決(GPartedはLive CDのLinuxから利用)。

# CentOSのインストール後
## ネットワークつながらない問題への対処
デフォルト(自分がインストールの流れで設定を飛ばしただけかも)で自動接続になっていないことが原因。
手動で接続  & 自動接続すれば解決。
「アプリケーション」→「システム・ツール」→「設定」→「ネットワーク」→「有線」のトグルをオンに切り替えることで手動接続。
そこから、有線の設定ボタンを押し、「自動接続する」にチェックを入れて適用すれば、次回から自動接続するようになる。

## LANドライバが誤って選択される問題への対処
PCのLANがRealtek 8111Cなのだが、本来R8168のドライバが必要な所、R8169のドライバが使われてしまう問題。
通信は一応できるが、通信が不安定になるらしいので対処。
基本的に、以下のページの手順で解決。
http://pt326.hatenablog.com/entry/2015/10/07/233756

ただし、ELRepoのURLが古そうだったので、上記のページから最新のURLを調べて設定。
http://elrepo.org/tiki/tiki-index.php

## 他のPCからGitLabにアクセスできない問題への対処
本では、GitLabのURLが「http://<CI環境ホストのIPアドレス>:8080」となっているが、CI環境ホスト以外のPCのブラウザからアクセスしてもつながらない。
原因は、httpサービスを公開していないから。以下のURLに記述した手順を実施して対処。
https://qiita.com/zigenin/items/875931dc83a62a1ddbd4
Rustのライフタイムの記法がわからなかった

以下のようなコードの意味がわからなくて困りました。

```rust
/// 指定された参照の指す値を二倍し、参照をそのまま返す。
fn hoge<'a>(n: &'a mut usize) -> &'a usize {
    *n *= 2;
    n
}
```

`hoge`の横の`<'a>`を見て、関数のライフタイムって何だ？と思いました。

# 答え

この`<'a>`は単にこれから`'a`というライフタイムを表す変数を使うという宣言です。
普通のジェネリクスの型変数と同じです。

つまり上のコードにおいては「返り値のライフタイムは引数の`n`のライフタイムに一致する」ということなのでした。

[プログラミング言語Rust](https://rust-lang-ja.github.io/the-rust-programming-language-ja/1.6/book/)にもちゃんとそう書いてあるのですが、自分は誤読してしまいました。[第二版](https://doc.rust-lang.org/book/second-edition/index.html) ([和訳](https://qiita.com/yyu/items/18df35988f3ea3b12af0)) ではそのような誤解がしづらくなっているようなので、これから学ぶ人はそちらをおすすめします。
Rubyからgitする

GitHubはしない。するなら[octokit](https://github.com/octokit/octokit.rb)というgemがわりと多機能（ただし癖は強い）。

その名もズバリ[git](https://github.com/ruby-git/ruby-git)という名前のgemがあるので、これを使う。
`system`でゴリ押しでもできない事はない。

## gemをインストール

```bash
sudo gem install git
```

## 使ってみる

```rb
require "git"

local_repo_path = "/path/to/repo".freeze

git_client = Git.open(local_repo_path)

# masterブランチに切り替え
git_client.checkout("master")
# 最新をpull
git_client.pull

# 新しいブランチを作ってチェックアウト
branch_name = "hoge"
git_client.branch(branch_name).create
git_client.checkout(branch_name)

# ファイルを追加してコミット
filename = "test.html"
git_client.add(filename)
git_client.commit("test")

# push
git_client.push("origin", branch_name)

# コミット間の差分があるファイルの一覧を取得
start_commit = "1234567890"
end_commit = "0987654321"
# D: 削除、R: 名前変更（古い名前）
diff_files = git_client.diff(start_commit, end_commit).name_status.select {|_f, s| s != "D" && !s.start_with?("R") }.keys
# ファイル名変更は逆向けでないと新しいファイル名が得られない
diff_files += git_client.diff(end_commit, start_commit).name_status.select {|_f, s| s.start_with?("R") }.keys
diff_files.uniq!
```
IBM i (AS/400)のPASE環境でnode.jsを動かす方法 [IBM i Native Objectアクセス編]　(4/4)

![nodejsi.png](https://qiita-image-store.s3.amazonaws.com/0/16875/4fd1be23-2e45-12ae-e16f-a1f196ba9392.png)


#１．JavaScriptの準備
##IBM i Native ObjectをアクセスするJavaScriptを作成して動作確認
###【Javaスクリプトの編集】
テキストエディターでJavaScriptを編集後、UTF-8で「sample2.js」と名前を付けて保存

```javascript:hello.js
var http = require('http');
var db = require('/QOpenSys/QIBM/ProdData/Node/os400/db2i/lib/db2');
var xt = require('/QOpenSys/QIBM/ProdData/Node/os400/xstoolkit/lib/itoolkit');
var pd = require('/QOpenSys/QIBM/ProdData/Node/os400/xstoolkit/lib/iprod');
var prod = new pd.iProd(new xt.iConn("S6515E9A"));
var prodInfo = prod.getProductInfo("5770DG1");
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
db.init();
db.conn("S6515E9A");
db.exec("SELECT LSTNAM, STATE FROM QIWS.QCUSTCDT", function(rs) {
res.write("Product ID:" + prodInfo["Product_ID"] + "\n");
res.write("Release level:" + prodInfo["Release_level"] + "\n");
res.write("Load State:" + prodInfo["Symbolic_load_state"] + "\n");
res.end(JSON.stringify(rs));
});
db.close();
}).listen(8082, '192.168.1.7');
console.log('Server running at http://192.168.1.7:8082/');
```

###【FTP転送】
先にIBM iに作成済みの/home/nodeフォルダーへ「sample2.js」をFTP転送
![nodejs04_02.png](https://qiita-image-store.s3.amazonaws.com/0/16875/6aad070b-3722-bc1b-8295-b92606d95266.png)

#２．JavaScriptの実行
##「sample2.js」JavaScriptを実行して動作確認
###【実行コマンド】
>*CALL QP2TERM
>cd /QOpenSys/QIBM/ProdData/Node/bin
>node /home/node/sample2.js*

![nodejs04_05.png](https://qiita-image-store.s3.amazonaws.com/0/16875/4402abca-598d-ddfc-8f6a-0ae03a49f35f.png)

###【実行結果】
ソース上で指定したIPアドレスとポートでWebブラウザからアクセスした物理ファイルから意図する結果が得られたことから正しく動作しているといえます。
![nodejs04_06.png](https://qiita-image-store.s3.amazonaws.com/0/16875/720efb6b-356f-cf6b-c801-d9bf9f1d9e40.png)



この記事を読んでいただいてありがとうございます！
IBM i (AS/400)のPASE環境でnode.jsを動かす方法 [DB2接続編]　(3/4)

![nodejsi.png](https://qiita-image-store.s3.amazonaws.com/0/16875/d236f13a-832c-cd80-a93f-f4ed8ca095bc.png)

#１．DB2接続の準備
Node.jsのDB2iアドオンは、IBM iでDB2データベース操作に設定されるJavaScript APIです。それは、DB2 CLI APIに基づきます。次のパスにそのアドオンが存在します。

>*パス：/QOpenSys/QIBM/ProdData/Node/os400/db2i*

DB2アドオンには、上記フォルダーに含まれるdb2.jsが必要です。

###【スクリプトセットの確認】
DB2アドオンに必要なdb2.jsが存在していることを確認
![nodejs03_01.png](https://qiita-image-store.s3.amazonaws.com/0/16875/55c4dabc-cbd9-f91f-e7e7-a490490fcb83.png)

###【IBM i設定の確認】
接続するRDBディレクトリ項目名を確認します。必要であれば、RDBディレクトリ項目の設定を行います。Nodejsを実行するIBM i上のDB2にアクセスする場合は、NodejsのコーディングでDB名に*LOCALを指定して接続が可能です。
![nodejs03_02.png](https://qiita-image-store.s3.amazonaws.com/0/16875/7dca83a2-0576-7f06-5898-951b4825bade.png)

#２．Javaスクリプトの準備
##物理ファイルQIWS/QCUSTCDTのデータを参照・表示するJavaScriptを作成
###【JavaScriptの編集】
テキストエディターでJavaScriptを編集後、UTF-8で「sample.js」と名前を付けて保存

```javascript:hello.js
var http = require('http');
var db = require('/QOpenSys/QIBM/ProdData/Node/os400/db2i/lib/db2');
http.createServer(function (req, res) {
     db.init();
     db.conn("*LOCAL");
     db.exec("SELECT LSTNAM, STATE FROM QIWS.QCUSTCDT", function(rs) {
                 res.writeHead(200, {'Content-Type': 'text/plain'});
                 res.end(JSON.stringify(rs));
     });
     db.close();
}).listen(8082, '192.168.1.7');
console.log('Server running at http://192.168.1.7:8082/');
```

###【FTP転送】
先にIBM iに作成済みの/home/nodeフォルダーへ「sample.js」をFTP転送
![nodejs03_04.png](https://qiita-image-store.s3.amazonaws.com/0/16875/9f1af25e-35c2-ac2e-92c6-015ba6582344.png)

#３．JavaScriptの実行
##「sample.js」JavaScriptを実行して動作確認
###【実行コマンド】

>*CALL QP2TERM
>cd /QOpenSys/QIBM/ProdData/Node/bin
>node /home/node/sample.js*

![nodejs03_07.png](https://qiita-image-store.s3.amazonaws.com/0/16875/113fd43d-22d3-c6af-071f-e6116176b53a.png)

###【実行結果】
ソース上で指定したIPアドレスとポートでWebブラウザからアクセスした物理ファイルから意図する結果が得られたことから正しく動作しているといえます。
![nodejs03_08.png](https://qiita-image-store.s3.amazonaws.com/0/16875/445df2a9-cb7e-d2b4-cdc1-2cab75cf21ca.png)


この記事を読んでいただいてありがとうございます！
Nginxの機能一覧


Nginxにはどのような機能が疑問に思い調べた際の記事。
調べたとは言いつつも、[Nginxのabout](http://nginx.org/en/)に記載されていた。
機能は以下の通り。

・機能一覧
Basic HTTP server features
　[リバプロ設定](https://qiita.com/ashbrain/items/4de51ff33e4bddf1278b)
　負荷分散
　モジュラアーキテクチャ フィルタ
　キャッシングによる加速サポート
　SSL、TLS　SNIサポート
　HTTP/2サポート
Other HTTP server features
　ホスト名、IPアドレスでの仮想サーバ
　キープアライブ、パイプライン接続のサポート
　ログ形式、出力
　正規表現を利用したURIの変更
　ソースIPにもとづくアクセス処理
Mail proxy server features
　外部HTTP認証サーバーを使用してIMAPまたはPOP3サーバーにユーザーをリダイレクトする。
　外部HTTP認証サーバーを使用したユーザー認証と内部SMTPサーバーへの接続リダイレクト。
　SSLサポート
TCP/UDP proxy server features
　TCP、UDPでのプロキシ機能
Architecture and scalability
　1つのマスタープロセスと複数のワーカープロセス。権限のないユーザーの下で実行されるワーカープロセス。
　クライアントのサービスを中断することなく実行可能ファイルの再構成とアップグレード。

・その他
　[導入手順](https://qiita.com/ashbrain/items/4de51ff33e4bddf1278b)
gRPCとRuby gemを使ったすでにモノリシックになってしまったRailsにbundle可能なマイクロサービスの構築

# 概要
https://speakerdeck.com/cnosuke/fintechtorailstogrpcto?slide=1
https://github.com/cnosuke/bank_sample
http://kotaroito.hatenablog.com/entry/2017/10/25/095333
https://github.com/square/rough
https://magazine.rubyist.net/articles/0056/0056-hanami.html
https://github.com/treasure-data/serverengine
https://8thlight.com/blog/uncle-bob/2012/08/13/the-clean-architecture.html
http://engineer.crowdworks.jp/entry/2018/03/26/140018
https://github.com/bigcommerce/gruf
https://employment.en-japan.com/engineerhub/entry/2017/04/07/110000
IBM i (AS/400)のPASE環境でnode.jsを動かす方法 [動作確認編]　(2/4)

![nodejsi.png](https://qiita-image-store.s3.amazonaws.com/0/16875/326bc4f6-4099-bd78-b7c5-e7d73014e281.png)

#１．インストール環境の確認

第１回でインストールしたNode.jsが動作するか確認
[IBM i (AS/400)のPASE環境でnode.jsを動かす方法 [準備編]　(1/4)](https://qiita.com/kagesta/items/29220d57a2fec50a8674)

###【フォルダーの確認】
次のフォルダーが作成されている事を確認
作成されるフォルダー：/QOpenSys/QIBM/ProdData/Node
![nodejs02_01.png](https://qiita-image-store.s3.amazonaws.com/0/16875/af5cf863-aaf8-e456-5495-72cdbefc41f8.png)

###【Node.jsの稼働確認】
確認コマンド：node -v、npm -v

>*CALL QP2TERM
>cd /QOpenSys/QIBM/ProdData/Node/bin
>node -v
>npm -v*

次のように正しく実行されました。
![nodejs02_02.png](https://qiita-image-store.s3.amazonaws.com/0/16875/faf92faa-d834-225c-b5bf-1baf251df607.png)
今回の動作確認では特に発生しませんでしたが、参照した資料には以下のような事が書かれていました。類似のエラーの場合、参考にして頂けたらと思います。
シグナル 5 エラーメッセージが表示される場合はスレッドに関するエラーになります。
環境変数でマルチスレッドを有効にすれば、スレッドに関するエラーは解消される可能性があります。
\>>> ADDENVVAR ENVVAR(QIBM_MULTI_THREADED) VALUE(‘Y’)
環境変数の変更は、PASEアプリケーションに影響を及ぼします。

#２．JavaScriptの準備
###【JavaScriptの編集】
テキストエディターでJavaScriptを編集後、UTF-8で「hello.js」と名前を付けて保存

```javascript:hello.js
var sys = require('sys');
var http = require('http');
var server = http.createServer(
function (request, response) {
response.writeHead(200, {'Content-Type': 'text/plain'});
response.write('Hello World!!\n');
response.end();
}
).listen(8124);
sys.log('Server running at http://192.168.1.7:8124/');
```
![nodejs02_04.png](https://qiita-image-store.s3.amazonaws.com/0/16875/9114395c-fbcb-eae5-9364-2f75cc3b9b51.png)

###【FTP転送】
IBM i側の保管先フォルダーをmdコマンドで作成して「hello.js」をFTP転送
フォルダー作成コマンド：md /home/node
![nodejs02_06.png](https://qiita-image-store.s3.amazonaws.com/0/16875/4916c824-5fd0-56f0-a21a-476224d2cee8.png)

#３．JavaScriptの実行
##転送した「hello.js」JavaScriptを実行して動作するか確認
###【実行コマンド】

>*CALL QP2TERM
>cd /QOpenSys/QIBM/ProdData/Node/bin
>node /home/node/hello.js*

![nodejs02_10.png](https://qiita-image-store.s3.amazonaws.com/0/16875/76e04338-ae6a-4ef2-38d7-2aba8ea92509.png)

###【実行結果】
ソース上で指定したIPアドレスとポートでWebブラウザからアクセスすると次のように正しく表示されました。
![nodejs02_11.png](https://qiita-image-store.s3.amazonaws.com/0/16875/dcdcc44d-41e3-f3fb-0061-0cf2410c36bd.png)


この記事を読んでいただいてありがとうございます！
Vue.jsを使ってそれっぽいTodoリストを作ってみる

　プログラミングを学び始めて気が付いたら半年経ったので、今の理解度を確認するために最近触れ始めたVue.jsを使ってシンプルなTodoリストを作ってみました。

　・[デモページ](https://kou3akina.github.io/todo_list/)
　・[コードはこちら](https://github.com/kou3Akina/todo_list)

　コード自体は改良できそうな気はしていますが、現在の自分では思いつかなかったので諦めました……。

◆改良するべき点
　・ページに入力した内容の保存を出来るようにする。
　・Todoを入力する部分とボタンの見た目を良くする。案は色々ありそうなので略。
　・もう少しデザイン頑張る。

◆自分への課題
　・「でもこれどうせあるでしょ」と思わずとりあえず色々作ってみよう
JPmobileを使用している時にresponseとしてjsを返す場合の注意点

## 背景
jpmobileのgemを使用して、hogehoge_smart_phoneみたいなファイル名にしたら、
使用デバイスに応じて、viewを表示してくれる便利なgem
(partialまでsmart_phone化するからちょっと好きではないw)

## コード
```ruby
respond_to do |format|
  format.html
  format.js
end
```

* remote: trueでgetしているのに、HTMLが返却されていた。
* action.js.erbはちゃんと用意してあって、アプリケーションサーバーも再起動済み


## 原因
* action.html.erb, action_smart_phone.html.erbが存在する場合は、action.js.erbもデバイスに応じて作らないといけなかった
* 例) pc: action.js.erb, sp: action_smart_phone.js.erb


トホホ :sob:
<図解>ブラウザがページを表示するまでの流れ

[書籍：Webフロントエンド ハイパフォーマンス チューニング](http://gihyo.jp/book/2017/978-4-7741-8967-3)を参考にさせていただきました。
![全体の流れ.png](https://qiita-image-store.s3.amazonaws.com/0/263830/fb1fbdbe-a030-82bb-feb4-8934586c752e.png)

![ブラウザ仕組み.png](https://qiita-image-store.s3.amazonaws.com/0/263830/59e58d3e-b6c9-ba06-12bb-719274e6e247.png)

![Loading.png](https://qiita-image-store.s3.amazonaws.com/0/263830/73c07952-dca0-1e61-d16d-d8ddf9018ac3.png)
![Scripting.png](https://qiita-image-store.s3.amazonaws.com/0/263830/64eae71a-f7b3-611b-e695-58fc77126291.png)
![rendring.png](https://qiita-image-store.s3.amazonaws.com/0/263830/c6349bc0-7daf-38e4-1641-0c95fb540026.png)
![painting.png](https://qiita-image-store.s3.amazonaws.com/0/263830/d08084f3-d59f-cb1d-939e-c6b1ae2058b4.png)
IBM i (AS/400)のPASE環境でnode.jsを動かす方法 [準備編]　(1/4)

![nodejsi.png](https://qiita-image-store.s3.amazonaws.com/0/16875/98a80f12-823f-313e-cb46-4a244b29fa76.png)

#１．5733-OPS導入の前提条件のインストール
次のライセンスPGMが前提条件として必要になります。
GO LICPGM コマンドで上記ライセンスPGMが導入されていることを確認します。

>【5770-SS1】 option33－Portable Application Solutions Environment (PASE)
>【5733-SC1】 option1－OpenSSH, OpenSSL, zlib functions, IBM Portable Utilities for i
>【5770-DG1】 *BASE – IBM HTTP Server for i

###【5770-SS1】opt33 がインストール済
![nodejs01_01.png](https://qiita-image-store.s3.amazonaws.com/0/16875/7a31c8ab-89f9-10f7-2b90-680669d3995e.png)

###【5733-SC1】*BASEとopt1がインストール済
![nodejs01_02.png](https://qiita-image-store.s3.amazonaws.com/0/16875/fb162209-6f29-0ef0-3859-5a5f08af1469.png)

###【5770-DG1】がインストール済
![nodejs01_03.png](https://qiita-image-store.s3.amazonaws.com/0/16875/7eb7cbc0-6669-ec0b-d2a5-fca82fdfe75c.png)

#２．5733-OPSのインストール
インストールコマンド
>RSTLICPGM LICPGM(5733OPS) DEV(OPTVRT01) OPTION(*BASE) LNG(2924) RLS(V1R1M0)

###【5733-OPS】がインストール済
![nodejs01_04.png](https://qiita-image-store.s3.amazonaws.com/0/16875/6a25ccb2-ec2a-5363-0d97-2565a3195971.png)

#３．PTFの適用
HTTP Serverのグループ PTF SF99368 LVL31以上を適用
5733OPSをインストールした後にHTTP ServerのグループPTFの適用が必要になります。
既に以下スクリーンショットのように適用済が確認されたが、5733OPSのインストール後に適用されたものか不明であったため念のため、「Re-IPL=No」でグループ適用を実施しました。

###【SF99368 LVL33】が適用済
![nodejs01_05.png](https://qiita-image-store.s3.amazonaws.com/0/16875/336171ea-1739-0a46-cb8e-a6c05a7f927d.png)



この記事を読んでいただいてありがとうございます！
Ruby の module を使って特定のインスタンスにのみ 特定のインスタンス変数をもたせた

## インスタンスにだけmoduleをインクルードすることで実現する.

~~ruby の include を使ってみることにしました。~~
~~[ruby2.5.0 instance method Module#include]
(https://docs.ruby-lang.org/ja/latest/method/Module/i/include.html)~~

extendを使います。
[ruby リファレンス extend](https://ref.xaio.jp/ruby/classes/object/extend)

[参考資料:Qiita::いつも忘れるRubyの include, prepend, extend の意味。そしてActiveSupport::Concernについても。](https://qiita.com/leon-joel/items/f7c4643023f44def5ebd)

```ruby

# 今回の例では人間を使います。
class Human
  def initialize(name)
    @name = name
  end
end

# 人間は別名をいろいろ持っているのでこちらのmoduleでそれを設定できるようにしようと思います。
module OtherNames
  attr_reader :nickname, :pseudonym, :twitter_name # アクセサはなくても平気です。
  def set_nickname(nickname)
    # 宣言するときにチェインできるようにtapを使います。
    tap { @nickname = nickname }
  end

  # pseudonym は ペンネームのことだそうです。
  def set_pseudonym(pseudonym)
    tap { @pseudonym = pseudonym }
  end

  def set_twitter_name(twitter_name)
    tap { @twitter_name = twitter_name }
  end
end

# taroを用意します。
taro = Human.new('taro')
            .extend(OtherNames)
            .set_nickname('tarohiko')
            .set_pseudonym('taronosuke')
            .set_twitter_name('卍とんかつDJほげ☆太郎卍')
# 対照実験用にhanakoも用意しました。
hanako = Human.new('hanako')

# 同じクラスが生成元です
taro.class #=> Human
hanako.class #=> Human

# インスタンス変数を比較すると以下のようになっていました。
taro.instance_variables #=> @name, @nickname, @pseudonym, @twitter_name
hanako.instance_variables #=> @name
```

これで特定のインスタンスにのみ特定のインスタンス変数を持たせることができました。

extendの新境地に達しました。

## 追記(2018/07/18)

もともとincludeにしていたんですが、クラスをレシーバにしてincludeを利用するとクラスに対してのincludeとなっており、狙いである特定のインスタンスへのmoduleの追加ができていませんでした。
こちらはextendで実装可能でしたので修正しました。m(_ _)m
ローカルでGAE GoをDocker Composeで動かす

ローカルでGAE(Standard Environment) GoをDocker Composeで動かすメモ。

Docker Hubに[google/cloud-sdk](https://hub.docker.com/r/google/cloud-sdk/)があり、これにも`dev_appserver.py`コマンドなど入ってるけど、depが効かないので、[golang](https://hub.docker.com/_/golang/)をベースに`gcloud` SDKを入れるDockerfileを作った。

なお、GoのバージョンはGAEのStandard Environmentで使えるものを確認して使う（2018年7月17日現在は`1.9`）
https://cloud.google.com/appengine/docs/standard/go/release-notes

まずは`Dockerfile`を作る

```dockerfile:Dockerfile
FROM golang:1.9.7

RUN export CLOUD_SDK_REPO="cloud-sdk-stretch" && \
    echo "deb http://packages.cloud.google.com/apt $CLOUD_SDK_REPO main" | tee -a /etc/apt/sources.list.d/google-cloud-sdk.list && \
    curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add - && \
    apt-get update -y && apt-get install google-cloud-sdk google-cloud-sdk-app-engine-go -y

WORKDIR /go/src/path/to/project
EXPOSE 8080 8000
```

`docker-compose.yaml`はこんな感じ
ポイントは`--host`と`--admin_host`を`0.0.0.0`してあげること


```yaml:docker-compose.yaml
version: "3.6"

services:
  api:
    build:
      context: .
    volumes:
      - .:/go/src/path/to/project
    ports:
      - 8080:8080
      - 8000:8000
    command: dev_appserver.py ./app/app.yaml --host 0.0.0.0 --admin_host 0.0.0.0 --datastore_path .datastore
```
Zend Server 5.1 から Zend Server 7 へ移行する方法

![zendi.png](https://qiita-image-store.s3.amazonaws.com/0/16875/f08db304-9bb6-ed12-9508-52dc2dff30a4.png)
#環境
新旧バージョンは暫く並行稼働を行いました。
（Zend Server 5.1 と ZendServer 7 の共存)

**■移行前環境**
ZendServer 5.1.0
PHP 5.3
Easycom For PHP Toolkit for IBM i
Zend Framework Version : 1.11.3

**■移行後環境**
ZendServer 7.0.1
PHP 5.5
XML Toolkit
Zend Framework Version : 1.12.7

**■移行対象PHPソース数**
PHPソース数：200本（Controller,Model,Viewそれぞれ）

#作業内容
##PHPの移行
「PHP 5.3 → PHP 5.5」 のバージョンアップに伴う、下位互換がない変更点の
機能（関数）の使用調査と修正
http://php.net/manual/ja/migration54.php
http://php.net/manual/ja/migration55.php
上記、PHP マニュアル を参照
→ 特にソース修正の必要はなかった

##IBM i資源の利用法の変更
i5関数(Easycom For PHP Toolkit for IBM i)から XML Toolkit への変更に伴う影響調査と修正
コンパチビリティーラッパーの利用
Bootstrap.phpにrequire_once(‘CW/cw.php’)の1行を追加
→ 1ファイルのみの修正
利用していたi5関数は以下であった為、すべてラッパー機能で動作可能であった
i5_connect
i5_program_prepare
i5_program_call
i5_close

##稼働確認時に発生した問題点と解決手段
特になし

##工数
移行工数：2人日 ※稼働確認含む

 

 

この記事を読んでいただいてありがとうございます！
個人的にphpの摩訶不思議だと思う挙動

## 個人的にphpの摩訶不思議だと思う挙動


```php:
// こういう連想配列がある。。
$rec = ['0' => 1, 'item_type1' => [100,200,300], 'item_type2', 'd'];

foreach($rec as $key => $col){

    echo '[ '.$key.' ] -> ';

    if($key == 'item_type1'){
        echo 'キー名は item_type1 だよ';
    }else{
        echo 'キー名は item_type1 じゃないよ';
    }
}

```

結果↓

```shell:
[ 0 ] -> キー名は item_type1 だよ
[ item_type1 ] -> キー名は item_type1 だよ
[ 1 ] -> キー名は item_type1 じゃないよ
[ 2 ] -> キー名は item_type1 じゃないよ
```


**これ、$keyが```[item_type1]```でも、```[0]```でも通る**

```php:

$rec = ['0' => 1, 'item_type1' => [100,200,300], 'item_type2', 'd'];

foreach($rec as $key => $col){
    echo '[ '.$key.' ] -> ';
    if($key === 'item_type1'){
        echo 'キー名は item_type1 だよ';
    }else{
        echo 'キー名は item_type1 じゃないよ';
    }
}
```

```=== ```で無事意図通りの動きに。
この挙動ははじめて知りました。。汗

null,false,"",0の比較はさすがに```===```を使っていましたが、、
まさかこの挙動は想定外。


### おまけ

ためしに他の配列も

```php:

$rec = [0 => 1, 'item_type1' => [100,200,300], 'item_type2', 'd'];
```

```
[ 0 ] -> キー名は item_type1 だよ
[ item_type1 ] -> キー名は item_type1 だよ
[ 1 ] -> キー名は item_type1 じゃないよ
[ 2 ] -> キー名は item_type1 じゃないよ
```
。。。汗

```php:
$rec = [null => 0, 'item_type1' => [100,200,300], 'item_type2', 'd'];
$rec = [null => false, 'item_type1' => [100,200,300], 'item_type2', 'd'];
$rec = ['' => false, 'item_type1' => [100,200,300], 'item_type2', 'd'];
```
```
[  ] -> キー名は item_type1 じゃないよ
[ item_type1 ] -> キー名は item_type1 だよ
[ 0 ] -> キー名は item_type1 だよ
[ 1 ] -> キー名は item_type1 じゃないよ
```
これは意図通り、、汗

```php:
$rec = array('0' => 1, 'test' => 2 , '100' => 1000);
```
```
[ 0 ] -> キー名は item_type1 だよ
[ test ] -> キー名は item_type1 じゃないよ
[ 100 ] -> キー名は item_type1 じゃないよ
```

ちゃんと```===```を使う事にします汗

## この挙動の正体

```php:
$rec = ['0' => 1, 'item_type1' => [100,200,300], 'item_type2', 'd'];
```

> [配列のドキュメントより](http://php.net/manual/ja/language.types.array.php)
10 進数の integer として妥当な形式の String は、 数値の前に + 記号がついていない限り、 integer 型にキャストされます。

```'0'=>1``` はinteger型にキャストされ ```0=>1```　となり


```php:
if($key == 'item_type1'){
```
> [比較演算子のドキュメントより](http://php.net/manual/ja/language.operators.comparison.php)
整数値を文字列と比較したり、比較に数値形式の文字が含まれる場合は、文字列が 数値に変換され、 数値としての比較を行います

$keyが整数の```０```で、
'item_type1'が文字列の```item_type1```ですが、
整数と文字列を比較しているため、文字列のitem_type1がinteger型にキャストされ整数```0```に。

そのため、

```php:
if('0' == 'item_type1'){
```

のつもりが、

```php:
if(0 == 0){
```
となり、

比較が成立するようです。


@pickles さん　解説、ご丁寧にありがとうございました!!（泣）


### ためした環境
PHP 7.0.3
RealSense メモ

# ubuntu 17.10 -> 18.04
## 再起動後にD435をディテクトしなくなる現象
rebootするとlsusbでD435が見つからなくなる現象が発生している。
電源投入後ではdetectしているのだが。
dmesgで見ると、reboot時にusbの切り離しがerrorになっていて、電源投入時にD435に割り当てられたDevice番号が使えなくなる為であろう。一旦、USBコネクタを外し再び接続するとディテクトするのだが、Device番号が1つ増えている事から以上のことが言えると思う。
対処としてubuntuのバージョンを17.10から18.04に上げてみることにした。
```
$ do-release-upgrade
```
途中、止まってしまったのでrebootした。その後に以下のコマンドで継続。
```
$ sudo dpkg --configure -a
```
その後、insecure modeにするためのパスワード設定し、再起動してそのパスワードを使ってinsecure modeに設定した。
バージョンを18.04にしてからD435のディテクトは電源投入後でもリブート後でもうまく行っていますので、RealSense D435 や D415 を使う場合は18.04でやりましょう！

# examples/capture コンパイル
## opengl インストール
```
$ sudo apt-get install freeglut3-dev libglew-dev mesa-utils
```
## コンパイル
```
$ g++ -std=c++11 -o capture -I../ rs-capture.cpp -lrealsense2 -lglfw -lGLU -lGL
```

# wrappers/opencv/imshow コンパイル
```
$ g++ -std=c++11 -o imshow rs-imshow.cpp `pkg-config --cflags opencv` -lrealsense2 `pkg-config --libs opencv`
```

# wrappers/python/examples
## 環境作成（librealsenseディレクトリにて）
```
$ mkdir build
$ cd build
$ cmake ../ -DBUILD_PYTHON_BINDINGS=bool:true
$ make -j4
$ sudo make install
```
## python環境（.zshenv等に追加）
```
export PYTHONPATH=$PYTHONPATH:/usr/local/lib
```
## サンプル実行（librealsense/wrappers/python/examplesで）
```
$ python opencv_viewer_example.py
```
予測モデルの構築

自分用の学習のメモ書きですが、予測モデルの構築について、ざっと勉強してみたことをまとめてみました。

クロスバリデーションのスキーム
・K分割クロスバリデーション(Kfold関数)
・層別K分割クロスバリデーション(StratifiedKfold関数)
・一つ抜きクロスバリデーション(LOOCV関数)
・ランダムサンプリング(RandomSub関数)
・層別ランダムサンプリング(StratifiedRandomSum関数)

Juliaを使用した予測モデルの構築
参考ページ
[WindowsへのJuliaインストール] (https://qiita.com/JKirisaka/items/c0736a9e2838710e8aaa)

必要パッケージのインストール
DataFrames.jl・・データフレームの扱いに使用
MLBase.jl・・機械学習の予測モデルの構築に必要な様々な機能を提供(pythonのscikit-learnのようなもの)
DecisionTree.jl・・ランダムフォレストの実行に使用

```
Pkg.add("DataFrames")
Pkg.add("MLBase")
Pkg.add("DecisionTree")
```

訓練データとテストデータに使用するデータの取得
*下記の例ではkaggleの参加ページから取得したcsvをtargetdata.csvという名称に置き換えて、カレントディレクトリのdataフォルダ内に配置し、データをインポートしています

```
using DataFrames
srand(123)
cd("~/data")
getData = readtable("targetdata.csv", separator=';')
*ファイル配置先、csvファイル名は適宜読み替えてください。
N=Size(test,1)
inds_train = rand(1:N, Int(0.7*N))
*Int(0.7*N)がerrorとなる場合は、Int64(0.7*N)を単独計算し、四捨五入した値をInt(0.7*N)の箇所に置き換えます。
X_train = convert(Array, test[inds_train, 1:16])
y_train = convert(Array, test[inds_train, :y])
```

ランダムフォレストによる予測モデルの構築

```
using DecisionTree
srand(123)
fit_rf = build_forest(y_train, X_train, 10, 100, 0.7)
fit_rf

inds_test = setdiff(1:N, inds_train)
X_test = convert(Array, bank[inds_test, 1:16])
y_test = convert(Array, bank[inds_test, :y])
pred = apply_forest(fit_rf, X_test)
conf_mat = confusion_matrix(pred, y_test)
conf_mat
conf_mat = conf_mat.matrix
prec = conf_mat[2,2]/sum(conf_mat[2,:])
prec
rec = conf_mat[2,2]/sum(conf_mat[:,2])
rec
#f値
f_value = 2 * prec * rec / (prec + rec)
f_value
acc = sum(diag(conf_mat))/sum(conf_mat)
```
Zend Core から Zend Server 7 へ移行する方法

![zendi.png](https://qiita-image-store.s3.amazonaws.com/0/16875/71e8a4d0-5136-7adc-a1fc-b2a5a7b644eb.png)
#環境
マシンリプレイスに伴う、Zend Sever 7 日本語へのバージョンアップ

**■移行前環境**
OSバージョン V5R4
Zend Core 2.6.1
PHP 5.2
Easycom For PHP Toolkit for IBM i

**■移行後環境**
OSバージョン V7R1
Zend Server 7.0.1
PHP 5.4
XML Toolkit

**■移行対象PHPソース数**
PHPソース数：70本


#PHPの移行作業内容
##PHPの移行
PHP 5.2 → PHP 5.4 のバージョンアップに伴う、下位互換がない変更点の機能（関数）の使用調査と修正
http://php.net/manual/ja/migration53.php
http://php.net/manual/ja/migration54.php
上記、PHP マニュアル を参照
→ 特にソース修正の必要はなかった

##IBM i資源の利用法の変更
i5関数(Easycom For PHP Toolkit for IBM i)から XML Toolkit への変更に伴う影響調査と修正

1. コンパチビリティーラッパーの利用
i5関数を利用しているPHPソースの先頭にrequire_once(‘CW/cw.php’)の組み込みを行った。
修正PHPソース数：約60本
→ 修正作業自体は単純作業であったが、元々のアプリケーションの作りとして、共通ファイルをincludeしていたなら、１ファイルの修正で済んだはずである

2. 下記のi5関数については、XML Toolkitでは未対応だった為、db2関数に置き換えを行った。
i5_query
i5_fetch_row
i5_free_query
修正PHPソース数：約20本
→ こちらも、i5関数自体を内包したユーザー関数を作成して共通化していたなら、１ファイルの修正で済んだはずである

##稼働確認時に発生した問題点と解決手段
i5_commandで実行したCL内で作成したスプールについて、同CL内でSPLNBR(\*LAST)で取得できない。（MRGAPW、DLTSPLF等）
→ OSのバージョンによる、Toolkit実行ジョブ制御の違いであり、SPLNBR(*LAST)ではなく、APIで直前スプールの情報を取得するようにCLを修正して解決。

##工数
移行工数：5人日 ※稼働確認含む

 

この記事を読んでいただいてありがとうございます！
PHPテンプレートエンジンTwigのTips

最近Twigを使うようになったので今後のための備忘録として書きます。

[公式ドキュメント](https://twig.symfony.com/doc/2.x/)

## インスタンス生成

```php
require_once '/path/to/vendor/autoload.php';

$loader = new Twig_Loader_Filesystem('/path/to/templates');
$loader->addPath('/path/to/additional_templates');
$twig = new Twig_Environment($loader, [
    'cache'            => '/path/to/cache_dir',
    'auto_reload'      => TRUE,
    'strict_variables' => TRUE,
]);
```

### テンプレートの読込
共有テンプレートなどは`addPath`などで一気に読み込むと良い。

### キャッシュ
`cache`に書いたパスにコンパイルしたPHPキャッシュファイルを置く。`auto_reload`オプションはPHPファイルに変更があったらキャッシュファイルを置き換えてくれるので開発環境では`TRUE`、本番環境では`FALSE`にする。また、キャッシュがある限りそれを読み続けるので、本番環境にデプロイするときは一度全てキャッシュを消した方が良い。

### 変数名やメソッド名の厳密性
`strict_variables`はデフォルトで`FALSE`だが、もしここで存在しない変数名やメソッド名を呼ぶとエラーが出ずにスルーされる。それはとても困るので`TRUE`にする。

## 文法

### デバッグ

#### var_dump的に

```twig
{{ dump(var) }}
```

#### print_r的に

```twig
{{- var|json_encode(constant('JSON_PRETTY_PRINT') b-or constant('JSON_UNESCAPED_UNICODE')) -}}
```

#### テンプレート内に読み込まれた全変数のキー

```twig
{% for k, v in _context  %}
  {{ k }}
{% endfor %}
```

### include

```twig
{{ include('hoge.twig'[, with_context = false]) }}
```

include先に変数がそのまま引き渡される。引き渡したくなかったら`with_context = false`。

### block

```twig
{% block BlockName %}{{ var }}{% endblock %}
{% block BlockName var %}
```

これらは等価。

### 比較

厳密な比較`===`は使えない。同じことは`same as()`構文で実現できる。

```twig
{{ 0 is same as("0") ? "0 === '0'" : "0 !== '0'" }} // 0 !== '0'
```

ゆるい比較`==`は可能。ただしPHP本家よりもゆるいので留意する。

```twig
{{ "aa" == null ? "'aa' == null" : "'aa' != null" }}
{# 'aa' != null #}

{{    0 == null ? "0 == null" : "0 != null" }}
{# 0 == null #}

{{   "" == null ?　"'' == null" : "'' != null" }}
{# '' == null #}

{{   [] == null ? "[] == null" : "[] != null" }}
{# [] == null #}

{{ hoge == null ? "undefined == null" : "undefined != null" }}
{# undefined == null #}
```

1-4はわかる。5つめが怖い。

### foreach

```twig
{% for k, v in array　%}
    {{ k }}:{{ v }}
{% endfor %}
```

### 三項演算子

```twig
{{ foo ? 'yes' : 'no' }}

{# これらは等価 #}
{{ foo ?: 'no' }}
{{ foo ? foo : 'no' }}

{# これらは等価 #}
{{ foo ? 'yes' }}
{{ foo ? 'yes' : '' }}
```
Android:「Androidのライフサイクルにいてまとめてみました。」

Androidのライフサイクルは以下の通りです。

| メソッド名 | 内容 |
|:-----------:|:------------:|
| onCreate | Activityが生成された時に1回だけ呼び出される |
| onStart | Activityが画面に表示される時に呼び出される |
| onResume | Activityがフォアグランドになる時に呼び出される |
| onPause | Activityがバックグラウンドに移行する時に呼び出される |
| onStop | Activityが画面から見えなくなる時に呼び出される |
| onDestroy | Activityが破棄される時に呼び出される |
| onRestart | onStopの後、復帰する時に呼び出される |

アップデートの際に忘れがちなため、備忘録としてまとめました。

ご参考になれば幸いです。
コンソールログインしたら日本語キーボードで俺のMacはUS配列でコロン（:）が打てなくて死んだ

そういう事件がつい最近起きたんです。

コロンを打とうとしても `*` とか `;` とか `7` とか出ちゃって一向に `:` （コロン） が打てない。悲しいし、URLが作れない。死んだ。

そんなときは printf で解決できました。

```
$ printf "\x$(printf %x 58)\n"
:
```

例えば `https://example.com/` を curl で叩きたければ

```
$ curl -I $(printf "https\x$(printf %x 58)//example.com/")
```

こんな感じで。

無事解決できたので先ほど生き返りました。
Tomcatセットアップ

# インストール
# su - opuser
$ cd /home/opuser
$ tar zxvf /var/tmp/apache-tomcat-8.5.32.tar.gz
[opuser@test01 ~]$ ls -l
total 0
drwxrwxr-x 9 opuser opuser 160 Jul 17 19:22 apache-tomcat-8.5.32
[opuser@test01 ~]$

$ cd apache-tomcat-8.5.32/
[opuser@test01 apache-tomcat-8.5.32]$ cd webapps/
[opuser@test01 webapps]$
[opuser@test01 webapps]$ ls -l
total 4
drwxr-x--- 14 opuser opuser 4096 Jul 17 19:22 docs
drwxr-x---  6 opuser opuser   83 Jul 17 19:22 examples
drwxr-x---  5 opuser opuser   87 Jul 17 19:22 host-manager
drwxr-x---  5 opuser opuser  103 Jul 17 19:22 manager
drwxr-x---  3 opuser opuser  306 Jul 17 19:22 ROOT
[opuser@test01 webapps]$

rm -fr docs examples host-manager manager ROOT
cd /home/opuser/apache-tomcat-8.5.32/conf

[opuser@test01 conf]$ ls -l
total 224
-rw------- 1 opuser opuser  13548 Jun 21 04:53 catalina.policy
-rw------- 1 opuser opuser   7576 Jun 21 04:53 catalina.properties
-rw------- 1 opuser opuser   1338 Jun 21 04:53 context.xml
-rw------- 1 opuser opuser   1149 Jun 21 04:53 jaspic-providers.xml
-rw------- 1 opuser opuser   2313 Jun 21 04:53 jaspic-providers.xsd
-rw------- 1 opuser opuser   3622 Jun 21 04:53 logging.properties
-rw------- 1 opuser opuser   7511 Jun 21 04:53 server.xml
-rw------- 1 opuser opuser   2164 Jun 21 04:53 tomcat-users.xml
-rw------- 1 opuser opuser   2633 Jun 21 04:53 tomcat-users.xsd
-rw------- 1 opuser opuser 169322 Jun 21 04:53 web.xml
[opuser@test01 conf]$


# 初期設定
Kotlinまとめ - 文法詳解 - クラスとそのメンバ

# クラスの定義
```Kotlin
class MyClass

val myClass = MyClass() // デフォルトのコンストラクタが生える
```
Kotlinでは`new`キーワードを付ける必要はない
`new`は予約語ではない

# メソッド
* 定義方法は関数と同じ
* 呼び出しは`インスタンス.メソッド名`

```Kotlin
class Greeter {
    fun greet(name: String) {
        println("Hello, $name")
    }
}

val greeter = Greeter()
greeter.greet("Kotlin")
```

# プロパティ
* 定義方法は変数と同じ
* オブジェクトの特性や性質を表すデータをやり取りするための窓口

```Kotlin
class Person {
    var name: String = ""
    var age: Int = 0
}

val hanako = Person()
println(hanako.name) // ""
println(hanako.age)  // 0

hanako.name = "hanako"
hanako.age = 25

println(hanako.name) // "hanako"
println(hanako.age)  // 25
```

## バッキングフィールド
* 上記の例のような`Person`クラスの`name`や`age`には自動的にバッキングフィールドが生成される
* 例えば、`name`として保持する文字列オブジェクトへの参照をバッキングフィールドが持っている
* バッキングフィールドを持たないプロパティを定義することも可能

```Kotlin:バッキングフィールドを持たない`nameLength`追加
class Person {
    var name: String = ""
    var age: Int = 0
    val nameLength: Int
        get(): Int {
            return this.name.length
        }
}
```
これはSwiftでいうコンピューテッドプロパティに似ている

カスタムセッターを定義することも可能

```Kotlin
class Person {
    var name: String = ""
        set(value) {
            println("${value}がセットされました")
            field = value
        }
    var age: Int = 0
    val nameLength: Int
        get(): Int {
            return this.name.length
        }
}
```
* fieldはバッキングフィールドを表す暗黙の変数
    * `name = value`とすると無限にカスタムセッターが呼ばれてクラッシュする

# 遅い初期化
* バッキングフィールドをもつプロパティは初期化が必須
* どうしても初期化を遅らせたい場面がある
    * DIやUnitテストのときとか…
* `var`のみ可能
* 初期化前に`lateinit`の変数にアクセスすると`kotlin.UninitializedPropertyAccessException`をスローする

```Kotlin
class MyClass {
    lateinit var foo: String
}
```

# `this`
* メソッドやプロパティをまとめてメンバと呼ぶ
* メンバへのアクセスは`目的のオブジェクトへの参照.メンバ名`
* `this.メンバ名`とすることで、自身のオブジェクトのメンバにアクセスできる
* `this`は省略可能

# コンストラクタとイニシャライザ
* 分数クラス`Rational`の初期化に分子`numerator`と分母`denominator`を受け取る例

```Kotlin
class Rational constructor(n: Int, d: Int) {
    val numerator: Int = n
    val denominator: Int = d
}

val half = Rational(1, 2)
println(half.numerator)
println(half.denominator)
```

コンストラクタの引数をそのままプロパティにしたい場合は、引数に`val`や`var`をつける

```Kotlin
class Rational(val numerator: Int, val denominator: Int)
```

## セカンダリコンストラクタ
* 今までのコンストラクタはプライマリコンストラクタ
* 分母の指定がない場合はデフォルトで1になるセカンダリコンストラクタを定義

```Kotlin
class Rational(val numerator: Int, val denominator: Int) {
    constructor(numerator: Int): this(numerator, 1)
}

// 今回の場合だとデフォルト引数のほうが早い
class Rational(val numerator: Int, val denominator: Int = 1)
```

## イニシャライザ
* インスタンス生成の際に実施しておきたい処理

```Kotlin
class Rational(val numerator: Int, val denominator: Int = 1) {
    init {
        // 要求に反した場合、例外をスローする標準ライブラリの関数
        // ∴分母が0になった場合、IllegalArgumentExceptionをスローする
        require(denominator != 0)
    }
}
```

# エクステンション
既存クラスに対して、その定義に手を入れずにメソッドを追加できる→拡張関数

```Kotlin
fun String.countWords(): Int = this.split("""\s+""".toRegex()).size

"I like  Kotlin".countWords() // 3
```

拡張プロパティもOK
`this`は省略可能

```Kotlin
val String.wordsCount: Int
    get() = split("""\s+""".toRegex()).size
```

---

[← 文法詳解 - オブジェクトからクラスへ](https://qiita.com/hicka04/items/d39dbce6095c369d95bc) || [文法詳解 - 継承と抽象クラス →](https://qiita.com/hicka04/items/e00a9d9896f7017a932b)