OmniAICreator/Qiita-1.07M huggingface dataset:
『増補改訂版Java言語で学ぶデザインパターン入門』をKotlinでやってみる（Factory Method編）

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

## 【コード】
Factory MethodパターンはTemplate Methodパターンのインスタンス生成の場面に適用したもの、らしいです。
Template Methodパターンの発展形？亜種？みたいなイメージでしょうか。
結局やりたいのはスーパークラスでインスタンスの生成の仕方を決めてしまって、具体的な処理はサブクラスで行う物です。
今回は問題がサンプルの発展形なので、まとめます。

```Kotlin:Factory.kt
abstract class Factory {
    final fun create(owner:String) : Product {

        var p:Product = createProduct(owner)
        registerProduct(p)
        return p
    }

    protected abstract fun createProduct(owner: String) : Product
    protected abstract fun registerProduct(product: Product)
}
``````
```Kotlin:Product.kt
abstract class Product {
    abstract fun use()
}
``````

```Kotlin:IDCard.kt
class IDCard(owner: String, number:Int) : Product() {
    private var own:String = owner
    private var num:Int = number

    init {
        Log.d("IDCard", own + "(" + num + ")" + "のカードを作ります。")
    }

    override fun use() {
        Log.d("IDCard", own + "(" + num + ")" + "のカードを使います。")
    }

    fun getOwner():String {
        return own
    }

    fun getNumber():Int {
        return num
    }
}
``````

```Kotlin:IDCardFactory.kt
class IDCardFactory : Factory() {
    private var owners = HashMap<Int, String>();
    private var num:Int = 0

    protected override fun createProduct(owner: String): Product {
        num++
        return IDCard(owner, num)
    }

    override fun registerProduct(product: Product) {
        product as IDCard
        owners.put(product.getNumber(), product.getOwner())
    }

    fun getOwner():HashMap<Int, String> {
        return  owners
    }

}
```

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

        var factory:Factory = IDCardFactory()
        var card1:Product = factory.create("とむら")
        var card2:Product = factory.create("結城浩")
        var card3:Product = factory.create("佐藤花子")

        card1.use()
        card2.use()
        card3.use()
    }
```
```:出力結果
とむら(1)のカードを作ります。
結城浩(2)のカードを作ります。
佐藤花子(3)のカードを作ります。
とむら(1)のカードを使います。
結城浩(2)のカードを使います。
佐藤花子(3)のカードを使います。
```
第四回までやってきて思いましたがこれ通常業務の実装の中で活かせる気がしないぞ。
Linux カーネルのソースコードを読む方法

# ■ はじめに

本稿では、Linux カーネル (アップストリーム[^1]) のソースコードを読む方法についてご紹介します。**初学者向けの内容**であり、カーネルソースを**読み解くテクニックと言った類のものではありません。**

[^1]: アップストリームとは、Linux カーネルの本家本元のソースツリーを指します。実は Ubuntu、RHEL や CentOS などのディストリビューションに含まれるカーネルソースは、このアップストリームのカーネルとは別物です (完全に同じでない)。またディストリビューション間でも差分があります。そのため、たとえば RHEL で発生したバグについて、厳密な調査をしたいなどの場合はアップストリームカーネルではなく、RHEL カーネルのソースコードで調査する必要があります。

# ■ ソースコードを読む方法

Linux カーネルは、オープンソースであるため、ソースコードが公開されており自由に読むことができます。読む方法としては、主に次の二通りです。

- ローカルマシンにソースコードを落として読む
- ブラウザ上から読む

## 1. ローカルマシンに落としてから読む

ローカルマシンにソースコードを落とす方法は、色々考えられますが、本稿では、git コマンドからソースコードを落とす方法をご紹介します。git を使用することで、カーネルバージョンのタグ切り替えや、コミットログの確認ができて便利です。次の何れかを実行すれば OK。

```
$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
```

```
$ git clone https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
```
```
$ git clone https://kernel.googlesource.com/pub/scm/linux/kernel/git/torvalds/linux.git
```

## 2. ブラウザ上から読む

ブラウザ上から読むには、次の何れかを開くだけです。

- [index : kernel/git/torvalds/linux.git (Linux kernel source tree)](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/)

- [torvalds/linux (上記のミラー)](https://github.com/torvalds/linux/tree/master)
- [Bootlin Embedded Linux Experts (LXR)](https://elixir.bootlin.com/linux/latest/source)

# ■ おわりに

ソースコードを読む方法についての紹介は以上ですが、参考までにということで、次のリンクをご紹介します。カーネルソースを読む際にどこから読めば良いのか分からない時に参考になります。たとえば、mm ディレクトリならメモリ管理関連のコードが含まれていると言った、ディレクトリ構造の説明が記載されています。

- [The Linux Kernel JF Project(15.2 カーネルソースの構造)](https://linuxjf.osdn.jp/JFdocs/The-Linux-Kernel-15.html#ss15.2)

# ■ あわせて読みたい

- [Vim で Linux カーネルソースを快適に読むための設定](https://qiita.com/Kernel_OGSun/items/6354d265c5b7ac6b3ce5)
すぐ始められるテスト駆動開発（RSpec）

テスト駆動開発の書籍を読みながらテスト駆動開発に挑戦。
まだ書籍を完読していないので、自分なりに着手しやすい方法を記載しておきます。

環境はRubyOnRailsなのでRSpecを活用します。

## TODOリストを作成する

必要になりそうなテストをリストアップしておく。
最初は思いつく限りでいよいので、テスト項目を明確にしておく。

- [ ] 報酬計算
    - [ ] A評価の報酬
        - [ ] 支払い対象がXXであること
        - [ ] XXXXXXの場合
            - [ ] 報酬を支払うこと
        - [ ] XXXXXXの場合
            - [ ] 支払い総額が正しいこと



## テストコードを先に書く（テストファースト）

実装を進めたくなると思うが、ここは我慢をしてテストコードから書く。
先に実装を進めると、何かと理由をつけて後でテストコードを書かない可能性があるので。

describe,context,itにテストの仕様がわかるような記載にする。
TODOリストをそのまま転記する感じだと楽だと思います。

`describe`　テスト対象
`context` 特定の条件
`it`　期待するアウトプット

```rb:fee_spec.rb

describe '報酬計算' do

  describe 'A評価の報酬' do
    before do
    end

    it '支払い対象がXXであること' do 
       ...テスト処理...
    end

    context 'XXXXXXの場合' do
      it '報酬を支払うこと' do
       ...テスト処理...
      end
    end
    context 'XXXXXXの場合' do
      it '報酬を支払わないこと' do
       ...テスト処理...
      end
    end

    it '支払い総額が正しいこと' do
       ...テスト処理...
    end
  end

```

テストコードができたら、実装を進める。
適宜テストコードを修正して、とにかくテストをグリーンにする。

```
rspec spec/fee_spec.rb

Finished in 15.67 seconds
6 examples, 0 failures, 0 pending
```

## リファクタリング

コードが汚い状態になっているので、リファクタリングをする。
まめにテストを実行しレッドの状態なら、テストコードor実装を直して、グリーンの状態にする。
実装中に必要なテストを思いついたら、TODOリストに加え、テストコードの実装を追加する。

リファクタリングを終えてテストがグリーンになればそのテストのTODOリストにチェックを入れておく。

## 完了条件

TODOリストが全てチェックがはいえれば、完了。

## まとめ

テストコードと一緒に実装をすすめると工数は多くなりますが、以下メリットがあると思います。

- テストコードを見れば、その機能の仕様が把握しやすい（describeに書いてるあるため）
- CIの自動テスト環境と組み合わせれば、他の開発時によって引き起こされたデグレに気づける
- いつでもリファクタリングしやすくなる
- 自信を持って開発できる

`自信を持って開発できる`というのがいいですね。
この先長いので活き活きと仕事をしたいもんです。

今後もテスト駆動開発を極めていきたいと思います。
書籍の内容をだいぶ省略していますので、間違っていたらご指摘頂ければと思います。

# 参考

[テスト駆動開発](https://www.amazon.co.jp/%E3%83%86%E3%82%B9%E3%83%88%E9%A7%86%E5%8B%95%E9%96%8B%E7%99%BA-Kent-Beck/dp/4274217884)
Firebase Realtime Database をブラウザから使う

実装
====

```html
<script src="https://www.gstatic.com/firebasejs/4.12.1/firebase.js"></script>
<script>
    let config = {
        apiKey: "xxxxx",
        authDomain: "xxxxx.firebaseapp.com",
        databaseURL: "https://xxxxx-xxxxx.firebaseio.com",
        projectId: "xxxxx",
        storageBucket: "xxxxx.appspot.com",
        messagingSenderId: "xxxxx"
    };
    firebase.initializeApp(config);
    let abcRef = firebase.database().ref('abc');
    abcRef.on('child_added', function(data) {
        console.log('child_added', data.val());
    });
</script>
```

注意点
=====

- コンフィグ部分は Firebase の管理コンソールの「ウェブアプリにFirebaseを追加」リンクからコピーする。
- 上記のconfigはただの接続情報なのでgitに入れてよいが、認証を設けていないなら一般への流出は避けなければならない。（誰でもアクセスできるので最悪、すごい課金が発生することになる。）
- databaseURL はデフォルトのものを使わず、作成したほうがセキュア（URLが予想しにくくなるので）。
Firebase Hosting で html を簡単にホスティングできる(メモ)

### 使いどころ

- https のドメインありの URL ですぐに動かしたい。

### メリット

- ローカルで動くものを firebase deploy コマンドで簡単に配布できる。
- ネットワークやら、デプロイやらの設計が一切いらない。
- https の URL が発行される。

### 利用メモ

- cmd で `firebase init` で hosting を有効にする。
その際、`? What do you want to use as your public directory? (public)` で配信したいディレクトリ指定
- `firebase deploy` で配布
Amazon Linux WorkSpaces US イメージでシステムの起動時に日本語入力を有効化する

このトピックに関する新しい記事はこちら: [続・Amazon Linux WorkSpaces US イメージでシステムの起動時に日本語入力を有効化する](https://qiita.com/mosop/items/d1b301c9b9fd23fa4c83)

Amazon Linux WorkSpaces の US イメージで日本語の入力環境をセットアップしました。

US 言語でもはじめから iBus Kana Kanji がインストールされているので比較的セットアップは楽なのですが、追加で多少の設定が必要です。

私の設定手順は以下のとおりです。

1. `~/.xprofile` に環境変数の設定を書く

    ```:~/.xprofile
    #!/bin/sh
    export XMODIFIERS=”@im=ibus”
    export GTK_IM_MODULE=”ibus”
    export QT_IM_MODULE=”xim”
    ```

1. Startup Applications に iBus デーモンの起動コマンドを追加する[^1]<br/>コマンド: `ibus-daemon -drx`<br/>![ibusdaemon.png](https://qiita-image-store.s3.amazonaws.com/0/63688/e5b46676-1781-5ab7-08cb-4f19040214e9.png)


1. ターミナルから `ibus-setup` コマンドを実行して、 iBus の Preferences を開く

1. Input Method に "Japanese - Kana Kanji" を追加する

    ![スクリーンショット 2018-08-27 17.57.44.png](https://qiita-image-store.s3.amazonaws.com/0/63688/300f1a5b-c053-3880-7446-53982896443f.png)

システムを再起動すると、無事に日本語入力が有効化されました:tada:

![ibusok.png](https://qiita-image-store.s3.amazonaws.com/0/63688/10fcd10b-ef95-1f11-5a00-25cccde5584d.png)

[^1]: 理由は分かりませんが、iBus デーモンの起動を ~/.xprofile の中で行うと、GUI アプリケーションでインプットメソッドを有効化するキー (Zenkaku_Hankaku) が効かないことがあります。代わりに Starup Applications にコマンドを登録したところ、うまくいっているようです。
Windows の Node.js で音声データを再生する

Windows + Node.js なら node-wav-player が簡単。
Windows の場合、.Net のプレイヤー使うらしい。

```js
const player = require('node-wav-player');

class Player {
    /**
     * @return {Promise<ReadableStream>}
     */
    static play(path) {
        return new Promise((resolve, reject) => {
            player.play({path: path}).then(() => {
                resolve();
            }).catch((error) => {
                console.error(error);
                reject(error);
            });
        });
    }
}

module.exports = Player;
```

```js
const Player = require('./Player');
await Player.play(wavPath);
```
フィボナッチ数を出力する関数を作る

再帰関数を書いた事がなかったので、とりあえずフィボナッチ数が適しているだろうと思って書いてみました。
再帰関数という名前に身構えてしまいましたが、意外とシンプルですね。

```javascript
function F (n) {
  if ( n === 0 || n === 1 ) {
    return 1;
  } else {
    return F(n-1) + F(n-2);
  }
}
```

ワンライナー

```javascript
F = (n) => n === 0 || n === 1 ? 1 : F(n-1) + F(n-2);
```

こんな感じの書き方は冗長な感じがしているので、よりよい書き方を知っている方は是非コメントをよろしくお願いします:pray:

> [追記]
> コメントでより短いやり方を教えていただきました。
> `const fib = n => n > 2 ? fib(n - 1) + fib(n - 2) : 1;`
> 基底部のところを後回しにするのがポイントですね。

## 参考

[JavaScript-階乗でみる、初めての再帰関数](https://qiita.com/aboutuser/items/4538813947b9ddcff53b)
SESで入った先でやる事備忘録

# mac環境構築

Macの個人環境で抜けていたり、不明確だった部分について記載します。

# CodeCommitを使うにあたってIAMへのKeyの登録。
できればroot権限で。

自分で
以下のコマンド
mkdir -m 700 ~/.ssh
で、SSH鍵保存場所のディレクトリを作成します。
下のコマンドでキーを発行。

ssh-keygen -t rsa
chmod 600 ~/.ssh/id_rsa

これをIAM上で登録する。

SSH鍵の作り方について
詳しくは
http://cameong.hatenablog.com/entry/2017/02/17/011429

IAM、CodeCommitについて詳しくは
https://docs.aws.amazon.com/ja_jp/codecommit/latest/userguide/setting-up-ssh-unixes.html

# Homebrewのインストール
バージョン管理が楽なのでHomebrewを使ってました。
詳しくは
https://qiita.com/saken649/items/b5830de62211b600f7ee

ここでcomposerがインストールできるので、
composerからFuelをインストールできます。
詳しくは
https://qiita.com/saltyshiomix/items/4dcf99b59dee4e0db93d

またnode.jsのインストールもcomposerからやれます。
詳しくは
https://qiita.com/akakuro43/items/600e7e4695588ab2958d

リモートリポジトリの取得については
https://qiita.com/L_e_k_o/items/956bd92645769dece5e7

# PPKをpemに
※Homebrewのインストールがされていることが前提となります。

ターミナルで
brew info putty
を実行してください。

特にエラーが出なければ
brew install putty
を実行してください。

以上でputtyのインストールは完了です。

その後、
puttygen hoge1.ppk -O private-openssh -o hoge2.pem
パーミッション変更。
chmod 600 hoge2.pem
を実行すればhoge2.pemの完成です。

ssh -i　hoge2.pem アカウント@IPアドレス
でアクセスできるか確かめる。

ターミナルでPPKが使えなかったので自分で変換して使いました。

詳しくは
https://qiita.com/ryok/items/be260e6df4ecfb5d5f1d

ちなみにNetbeansはPPKでアクセスができます。

# hostsの設定
場所はここ
/private/etc/hosts

ルート権限で編集
sudo -i
vi /private/etc/hosts

# gitlabのSSHkeyの登録
参考にしたところはここ
https://qiita.com/redamoon/items/07e445d1fce360cb5fa3

# そういえば隠しファイル見えるようにするのどうするんだっけ

defaults write com.apple.finder AppleShowAllFiles TRUE
killall Finder
でした。
ubloxのGPSモジュールの測位間隔を変更するコマンドをgolangで作った

![IMG_0989.jpg](https://qiita-image-store.s3.amazonaws.com/0/13271/c74f6f8f-0a4b-9da0-81d0-fe5bf0904826.jpeg)

USBで接続するGPSモジュールを入手しました。
ubloxのチップセットを使用しているものです。
デフォルトで1秒間に1回の間隔で測位を行うようになっています。通常の用途ならばこのままでよいのですが、これを変更するコマンドを調べて、それを送り込むコマンドをgolangで作りました

ubloxの拡張コマンドを使っているので、ublox社製のチップのものでのみ使用できます。

# 使い方

```
$ ./gps_ublox
Usage: ./gps_ublox /dev/ttyACM0 rate
rate is in msec. (100 <= rate <= 65535)
```
500ms 間隔で測位するには、以下のようにします。( /dev/ttyACM0はGPSモジュールのデバイスファイル)

```
$ ./gps_ublox /dev/ttyACM0 500
$ cat /dev/ttyACM0 > gps.nmea
```

# ビルド方法

```
$ go get .
$ go build
```

`GOARCH=arm go build` としてクロスビルドすればラズパイでも使えます。

# ソースコード

```golang:gps_ublox.go

package main

import (
	"bufio"
	"fmt"
	"github.com/tarm/serial"
	"io"
	"log"
	"os"
	"strconv"
)

// Refer "u-blox 7 Receiver Description Including Protocol Specification V14"

func main() {
	if len(os.Args) < 3 {
		fmt.Fprintf(os.Stderr, "Usage: %s /dev/ttyACM0 rate\nrate is in msec. (100 <= rate <= 65535)\n", os.Args[0])
		os.Exit(1)
	}

	c := &serial.Config{Name: os.Args[1], Baud: 115200}
	s, err := serial.OpenPort(c)
	if err != nil {
		log.Fatal(err)
	}
	defer s.Close()

	rate, err := strconv.Atoi(os.Args[2])
	if err != nil {
		log.Fatal(err)
	}
	if rate < 100 {
		rate = 100
	}	
	if rate > 0xffff {
		rate = 0xffff
	}
	cmd := []byte{0x06, 0x08,
		0x06, 0x00, /* len */
		byte(rate & 0xff),
		byte((rate >> 8) & 0xff),
		0x01, 0x00, 0x00, 0x00}
	sendCmd(s, cmd)
	os.Exit(0)
}

func sendCmd(s io.ReadWriter, cmd []byte) {
	cmdbuf := []byte{0xb5, 0x62}
	cmdbuf = append(cmdbuf, cmd...)
	ck_a, ck_b := chksum(cmd)
	cmdbuf = append(cmdbuf, ck_a, ck_b)

	//fmt.Printf("cmdbuf = %x\n", cmdbuf)
	n, err := s.Write(cmdbuf)
	if err != nil {
		log.Fatal(err)
	}
	if n != len(cmdbuf) {
		log.Fatal(err)
	}

	waitAck(s, cmd[0], cmd[1])
}

func chksum(payload []byte) (ck_a, ck_b byte) {
	ck_a = 0
	ck_b = 0
	for _, b := range payload {
		ck_a += b
		ck_b += ck_a
	}
	return
}

func waitAck(s io.Reader, class_id, msg_id byte) {
	ack := []byte{0xb5, 0x62, 0x05, 0x01, 0x02, 0x00, class_id, msg_id}

	reader := bufio.NewReaderSize(s, 128)
loop:
	for {
		_, err := reader.ReadBytes(0xb5)
		if err != nil {
			log.Fatal(err)
		}
		for _, a := range ack[1:] {
			b, err := reader.ReadByte()
			if err != nil {
				log.Fatal(err)
			}
			//fmt.Printf("b = %x\n", b)
			if b != a {
				continue loop
			}
		}
		/* TODO: check check sum */
		//fmt.Printf("ack ok\n")
		return
	}
}
```
JavaScript ES6で関数の戻り値が複数の場合のスッキリした実装

関数の戻り値が複数の場合のスッキリした実装。

# 実装

関数の戻り値をオブジェクトにすると、複数の戻り値を返すことができる

```JavaScript:
function func(){
  let x = 1;
  let y = 2;
  return {x: x, y: y}
}
```

オブジェクトでキーと値が同じ場合は省略できる

```JavaScript:  
let x = 1;
let y = 2;
let xy = {x, y};
```

オブジェクトを分割代入すると楽

```JavaScript: 
let xy = {x: 1, y: 2};
let {x, y} = xy;
```

これらを合わせると

```JavaScript: 
function func(){
  let x = 1;
  let y = 2;
  return {x, y}
}

let {x, y} = func();
```

スッキリ
MySQL : 『DBサイズ』と『Tableサイズ』を確認するコマンドシート

データストアリプレイスの際に、既存のDBテーブルのサイズ確認をして見積もりを行う際のコマンドをよく忘れるので記載します。


###『DBサイズ確認』
まずは、DBのサイズから見ていきます。
**MB単位**

```sql
SELECT
    table_schema, sum(data_length+index_length) /1024 /1024 AS MB
FROM
    information_schema.tables
GROUP BY
    table_schema
ORDER BY
    sum(data_length+index_length) DESC;

+--------------------------+----------+
| table_schema             | MB       |
+--------------------------+----------+
| sample_database1         | 5,243.14 | 
| sample_database2         | 6,443.14 | 
+--------------------------+----------+
```

**GB単位** ※MBをさらに1024で割る。

```sql
SELECT
    table_schema, sum(data_length+index_length) /1024 /1024/1024 as GB
FROM
    information_schema.tables
GROUP BY
    table_schema
ORDER BY
    sum(data_length+index_length) DESC;

+--------------------------+----------+
| table_schema             | MB       |
+--------------------------+----------+
| sample_database1         | 5.12     | 
| sample_database2         | 6.2      | 
+--------------------------+----------+
```


####補足
DBを指定してサイズを見たい場合は、上記のクエリの中で`GROUP_BY`, `ORDER BY`を消して、`where` 句でDBNAMEをつけてあげればよいです。

```sql:sample_database1を指定
SELECT
    table_schema, sum(data_length+index_length) /1024 /1024 AS MB
FROM
    information_schema.tables
WHERE 
    table_schema = 'sample_database1 ';

+--------------------------+----------+
| table_schema             | MB       |
+--------------------------+----------+
| sample_database1         | 5,243.14 | 
+--------------------------+----------+
```

###『Tableサイズ確認』
つぎは、テーブルのサイズを確認していきます。

```sql
SELECT  
    table_name, engine, table_rows AS tbl_rows,
    avg_row_length AS rlen,  
    floor((data_length+index_length)/1024/1024) AS all_mb,
    floor((data_length)/1024/1024) AS data_mb,
    floor((index_length)/1024/1024) AS index_mb
FROM 
    information_schema.tables  
WHERE
    table_schema=database()  
ORDER BY
    (data_length+index_length) DESC;  

+------------------------+--------+----------+------+--------+---------+----------+
| table_name             | engine | tbl_rows | rlen | all_mb | data_mb | index_mb |
+------------------------+--------+----------+------+--------+---------+----------+
| table1                 | MyISAM |  576382  | 454  | 2334   |    2322 |  12      | 
| table2                 | MyISAM |  785480  | 245  | 55666  |   73633 |  12     | 
+------------------------+--------+----------+------+--------+---------+----------+
```
GBの場合は、DBサイズ同様に1024で割ってください。

| column       |            意味 |   
|:-------------|---------------:|
| tbl_rows     |       レコード数 |
| rlen         |        平均行長 |     
| all_mb       |          総容量 |      
| data_mb      |       データ容量 |       
| index_mb     |  インデックス容量 |    
 
 
参考 : http://d.hatena.ne.jp/sho-yamasaki/20120405/1333640589
python構文編

xを1から100までのランダムな整数として取得し、
xが80以上の場合にaと、xが60以上の場合はbと、それ以下の場合はcと出力するコードを書け

```python
from random import randint
x = randint(1, 100)

if x >= 80 :
    print("a")
elif x >= 60 :
    print("b")
else :
    print("c")
```

文字列aが空白でなければaを、空白の場合は"文字が入力されていません"と表示するコードを書け

```python
a = " "
if a == str :
    print(a)
else :
    print("文字が入力されていません。")

出力
"文字が入力されていません。"
```

# whileについて
countの値を1から順番に表示し、10以上になったらループを抜けるwhile文を書け（10は表示しない）

```python
count = 1

while count < 10 :
    print(count)
    count += 1
```

xに1から10までのランダムの整数を代入し、xが3の倍数の場合にループを抜けるwhile文を書け
また、ループを抜けるまで毎回xの値を表示せよ

```python
from random import randint

while True :
    x = randint(1, 10)
    print(x)
    if x % 3 == 0 :
        break
```


1から10までのランダムな整数を取るxの2乗の値を当てるゲームを作れ
なお、2回正解する、またはqを入力したらループを抜けゲームが終了するようにせよ

```python
from random import randint
correct = 0

while correct < 2 :
    x = randint(1, 10)
    ans = x**2
    question = "{}の２乗の値は？Qで終了します。".format(x)
    value = input(question)
    if value == str(ans) :
        print("正解です。")
        correct += 1
    elif value == "Q" :
        print("クイズを中断します")
        break
    else :
        print("不正解です。")
```

# for文について

２つのサイコロの目の組み合わせを出力するコードを書け 　　(1,1)のように

```python
x = range(1, 7)
y = range(1, 7)

for i in x :
    for j in y :
        print("({},{})".format(i,j))
```

リストをfor文で回し、文字列の場合、1を、それ以外の場合、0を出力するコードを書け

```python
nums = [1,2,3,4,"a",5]
for num in nums :
    if isinstance(num, str) :
        print(1)
    else :
        print(0)
```

#try文
2つの引数a,bを取り、a / bを返す関数を作れ。
ただし、例外が発生した場合は"エラー"という文字列を返す仕様にせよ。

```python
def func(a, b):
        try :
            print(a / b)
        except :
            print("エラー")
            
func(4, "r")

出力結果　エラー
```

2つの引数a,bを取り、a / bを返す関数を作れ。aとbは文字列かもしれないので整数にせよ。
ただし、整数に変換できない例外が発生した場合は"整数を入力してください"という文字列を、
0除算で例外が発生した場合は、"bは0以外にしてください"という文字列を返す仕様にせよ。
また、例外に関わらず、最後に"処理終了"と表示する機能も含めよ。

```python
def func(a, b) :
    try :
        return int(a) / int(b)
    except ValueError :
        return "整数を入力してください" # 数値に変換できなかった時
    except ZeroDivisionError :
        return "bは0以外にしてください。"
    finally :
        print("処理終了")
    
print(func(4, 2))
```

リストをfor文で回し、それぞれを2で割った数を出力せよ。例外の場合は、エラー内容を出力せよ。

```python
nums_1 = [1,2,3,4,"a",5] 
for x in nums_1 :
    try :
        print(x // 2)
    except Exception as error :
        print("エラーになりました。")
        print(error) 
```

本日はここまでお疲れ様でした！
Goのfor rangeでのポインタでハマったこと

## 概要

以下のプログラムの出力結果はどうなるでしょうか？

```go
package main

import "fmt"

func main() {
	a := []string{"A", "B", "C"}
	var b []*string

	for _, str := range a {
		b = append(b, &str)
	}

	for _, str := range b {
		fmt.Println(*str)
	}
}
```

出力結果は以下のようになります。

```
C
C
C
```

## 解説と検証コード

___strがループ中にずっと同じポインタになっていることが原因です。___


以下のプログラムで`&str`の値を出力してみます。  
つまり、`str`が指している領域のアドレスを出力します。

```go
package main

import "fmt"

func main() {
	a := []string{"A", "B", "C"}

	for _, str := range a {
		fmt.Println(&str)
	}
}
```

以下のように、ループ中に常に同じアドレスになっています。

```
0xc42000e1e0
0xc42000e1e0
0xc42000e1e0
```

つまり `_, str := range a`を実行するたびに、同じ領域の値を上書きしていっているということです。

最初のコード例では、bの配列に上記の結果が入るため、ループの最後で上書きされる`C`が出力されます。


## 意図した処理にするには？

インデックス変数を使うようにすると良さそうです。

```go
package main

import "fmt"

func main() {
	a := []string{"A", "B", "C"}
	var b []*string

	n := len(a)
	for i := 0; i < n; i++ {
		b = append(b, &a[i])
	}

	for _, str := range b {
		fmt.Println(*str)
	}
}
```

```
A
B
C
```


## 参考

Goのfor rangeでポインタを使用する際に気をつけたいこと
https://qiita.com/RunEagler/items/008e2b304f27b7fb168a
JSONデータのキー名をワンライナーでカンマ区切りで取得する

Sencha Architect で Ext JS の Model を設定する際は、使用するデータのフィールド名をカンマ区切りで指定するのが便利です。

![licecap.gif](https://qiita-image-store.s3.amazonaws.com/0/149350/8741c11f-ac97-2f92-7369-346d50061dd9.gif)

しかし、こういうのをキーボードから入力するのは微妙に面倒です。既存のJSONデータからコピペすれば手入力の手間は省けますが、項目数が多い場合はコピペするのも案外面倒です。

そこで、既存のJSONデータのキー名をカンマ区切りで取得するようなワンライナーを書いてみることにします。

# ワンライナーの例

jq を使えばキーだけを容易に抜き出せますから、それをちょいと加工するだけです。

JSONデータのファイルを使うならこうですね。

```
cat jsondata.txt | jq -r '.(rootProperty)|keys|@csv' | sed 's/"//g'
```

ライブデータから作る場合は curl を使えばよいと思います。

```
curl -s [WebAPI] | jq -r '.(rootProperty)|keys|@csv' | sed 's/"//g'
```


(rootProperty) の部分は扱うデータにあわせて適切に変更してください。rootProperty が無い場合は単に ```.``` だけで良いはずです。

JSONデータが単純な配列ではなく、構造が入り組んでいる場合でも、参照したい部分を的確に指定すればキーは取得できます。

なお、ワンライナーの最後に sed で " を消す操作が自分的にはイマイチだと思っていますので、jq だけで " を落とす方法をご存知の方がいらっしゃいましたらコメント欄でフォローしていただけると大変ありがたいです。

2019/02/08追記

ワンライナーだけでも良いのですが、ふと気がつくと jq や sed のパラメータを忘れてしまうので、シェルスクリプトにすることにしました。

そしてせっかくなので、```generateModelField.sh "ファイル名またはURL" "参照したい要素"``` のように実行できるように実装してみます。

```bash:generateModelField.sh
#!/bin/bash

file=$1
jsonpath=$2

(
    if [ -e ${file} ]; then
        cat ${file}
    fi

    if [ ${file:0:4} == "http" ]; then
        curl -s ${file}
    fi
) | jq -r "${jsonpath}|keys|@csv" | sed 's/"//g'
```

# 上記の結果に至る手順

とりあえず、環境は Ubuntu(WSL含む), macOS を想定しています。

使うコマンドは curl, jq, sed ですが、jq は未インストールのケースが多いと思いますので、この機会にインストールしてください。brew, apt でインストールできるはずです。

また、ここからの手順では主に jq を使っていますが、jq 自体の細かい使い方は解説しませんので、今回初めて jq を知った方はググってみてください。

まず、次のように実行すると、API の実行結果が jq で整形された形で取得できます。

```bash
$ curl -s http://apis.is/earthquake/is | jq '.' | more
{
  "results": [
    {
      "timestamp": "2017-10-13T12:07:24.000Z",
      "latitude": 63.976,
      "longitude": -21.949,
      "depth": 1.1,
      "size": 0.6,
      "quality": 58.73,
      "humanReadableLocation": "6,1 km SV af Helgafelli"
    },
    .
    .
    .
```

このデータは rootProperty が "results" なので、jq のパラメータを以下のように書き換えれば、JSON配列の0番目だけが取り出せます。

```bash
$ curl -s http://apis.is/earthquake/is | jq '.results[0]'
{
  "timestamp": "2017-10-13T12:07:24.000Z",
  "latitude": 63.976,
  "longitude": -21.949,
  "depth": 1.1,
  "size": 0.6,
  "quality": 58.73,
  "humanReadableLocation": "6,1 km SV af Helgafelli"
}
```

さらに jq のパラメータを次のように変えてみると、key だけが抜き出せました。

```bash
$ curl -s http://apis.is/earthquake/is | jq '.results[0]|keys'
[
  "depth",
  "humanReadableLocation",
  "latitude",
  "longitude",
  "quality",
  "size",
  "timestamp"
]
```

この結果を csv 変換すれば、key のカンマ区切りが手に入るはずですが、これだけではうまくいきません。

```bash
$ curl -s http://apis.is/earthquake/is | jq '.results[0]|keys|@csv'
"\"depth\",\"humanReadableLocation\",\"latitude\",\"longitude\",\"quality\",\"size\",\"timestamp\""
```

そこで jq のコマンドラインパラメータに -r を追加してみます。

```bash

$ curl -s http://apis.is/earthquake/is | jq -r '.results[0]|keys|@csv'
"depth","humanReadableLocation","latitude","longitude","quality","size","timestamp
```

これで概ね欲しい結果になりましたが、" が邪魔なので消しましょう。今回は jq の出力結果から一括で " を落とすために sed でフィルタしてみます。

```bash
$ curl -s http://apis.is/earthquake/is | jq -r '.results[0]|keys|@csv' | sed 's/"//g'
depth,humanReadableLocation,latitude,longitude,quality,size,timestamp
```

これで目的の結果が得られました。
ウェブサーバー のセキュリティの道具: NIKTO

「NIKTO」はウェブサーバーのセキュリティの道具です。 
公の「NIKTO」の根本的は[ここです](https://cirt.net/nikto2-docs/)。でも、この記事は大筋です!
「LINUX」の「NIKTO」の設備が易しいです。

```
$ sudo apt install nikto
```

ああ、そですか。=)
実は、`apt-get` を使わなかった :x:

「HOST」のスキャンのコマンドは`-h`。

(例え)

```
$ nikto -h 192.168.0.1
```

も、「HTML」の文法

```
$ nikto -h localhost
```

このは「HTTP」、それから「HTTPS」です。

```
$ nikto -h https://localhost
$ nikto -h localhost -ssl

```
でも、このは唯一「 HTTPS」です。８０は デフォルトの ポートです! ポートですのコマンドは`-p`。

```
$ nikto -h 192.168.0.1 -p 443
```
ああ、一緒 に例えをみましょう！

```
$ nikto -h https://example.jp -p 443, 50, 63, 24, 80
```
その例えはポートがたくさんありあります！ それは可能です。 :thumbsup_tone3:
も、PROXYを使うことができます。すごいですね！ 
「nikto.conf」を編集すですください。「PROXYのコマンドは`-useproxy` 

```
$ nikto -h 192.168.0.1 -p 50 -useproxy 
```
あ！私は仕上がった。好きでしたか? :yum:
Google Cloud Next 2018 Extended App & Infra Dayに参加してきました

Google Cloud Next 2018 Extended App & Infra Day
https://gcpug-tokyo.connpass.com/event/94417/

**趣旨：7/24～26にサンフランシスコで開催された Google Cloud Nextの発表内容の共有をする**
**日時：2018/08/24(金) 18:50 〜 21:50**
**場所：Google Japan 東京都港区六本木６丁目１０−１**

# 感想
sinmetalさんのDBの世代交代のお話はGCPにおけるDatabaseの歴史を感じた
年表形式で追って考えたことはなかったので新鮮でもありました

kumaさんのマイクロサービスの導入や運用についてのお話は刺さった。。
普段実感していることだけに「うんうん」とうなずきながら拝聴しました。
マイクロサービスの複雑になりがちな部分（どうしてもでますよね！）
ここをマネージドなサービスやツールで的確な規模で導入していくのがやっぱりいいんだろうなー

各セッションの内容をメモで残します
共有された資料へのリンクもあわせて貼ります

# 動画
[Google Cloud Next 2018 Extended App & Infra Day
](https://www.youtube.com/watch?v=oPlP_Fa3QJA)

# セッション
## Firestore :Datastore Mode & Datastore Automatic Upgrade to Firestore
#### スピーカー
[sinmetalさん twitter](https://twitter.com/sinmetal)
#### 発表資料
[GCP Databaseの世代交代](https://docs.google.com/presentation/d/11Jp1gt-n8LxVgrHBRy1ym6iJMsKww-mit1A00IS-oHk/edit#slide=id.g3cf2532adc_0_136)

#### memo
発表資料およびYoutubeをご覧になるのがベストと判断しましたw

## アプリ、インフラ、そして運用についての究極の疑問の話
#### スピーカー
[kumaさん twitter](https://twitter.com/kumakumakkk)
#### 発表資料
[アプリ、インフラ、そして運用についての究極の疑問の話](https://speakerdeck.com/kumakumakkk/apuri-inhura-sositeyun-yong-nituitefalsejiu-ji-falseyi-wen-falsehua-to-nextfalsefeng-jing-woshao-jie)

#### memo
#### nextの様子

- 写真まじえて紹介
  - God of Cloud（縄跳びをする謎のキャラ）
  - TPUのハードウェアは水冷！
  - ヨットが並ぶ様子がReal Service Mesh(Istio)
  - 発表の内容はYoutubeにあがっているよ


#### マイクロサービスについて
**マイクロサービス最高！とってもよい！！！**

 - 柔軟性・敏捷性・加速度を得ることが可能になる
  - コンポーネントごとに言語や設計を柔軟に変更できる
  - 改修がコンポーネントごとに変更できるため、テストデプロイが早くできる

**マイクロサービス最高・・・？とってもよい・・・？**

- 運用が複雑になる
  - 通信が超絶複雑で俯瞰できない
  - コンポーネントがありすぎて、デバッグもデプロイもしにくい

**マイクロサービスでもmonolithでもどちらにせよ運用は複雑化する**

**いろんなツールを使って管理できるように**
運用・管理に必要なものものを自動化

 - Docker：コンポーネントをパッケージ化
 - Kubernetes：アプリケーションの実行・管理
 - Istio：サービスを管理


**Istio 難しい**

- Kubernetesが難しいのに、更に？
- 管理するモノが増える

**ネットワーク以外にも様々な複雑さが**

- CI/CDどうする？
  - デプロイスピードは速くなるが、週に何十回、何百回とデプロイすることに
- 何をモニタリングする？
  - ログはすべて取る→多すぎる
  - 監視も全てする→多すぎる
- どこに、アプリケーション置く？
  - 特定の業種は特定の法律・法令に準拠しなければいけない

**近年のソフトウェアの開発サイクルは加速しすぎてテストを行う時間が短すぎる Fortune500で働くQALeader**

####Cloud Services Platform
googleが描く現状の最適解をパッケージ提供したもの
![alt](https://3.bp.blogspot.com/-0PF8lTgs2mc/W1ZeqBT0wAI/AAAAAAAAGHo/SirNgEV8SAQuepeZjrhRtdqi3t7abzyxgCLcBGAs/s1600/The%2BCloud%2BServices%2BPlatform%2Bfamily.png)

- マネージドなistio
- Cloud Build,Container Registry,BazelでCI/CDワークフロー作成
- Stackdriver Service Monitoring SREの考え方をベースにシステムをモニタリング（サービスマップやエラーバジェット）
- GKE On-Premでハイブリッド環境を構築

### ところでこれは誰向け？
Googleは以下が必要と言っている

- Culsture
- Infrastructure
- Tools
- Platform

```
アーキテクチャの複雑性を紐解き、
複雑なシステムを自動化し、
許容できる範囲を明確に定義し、
事業・システム・ヒトに整合性をつけて全体を無理なく保たせたい、
柔軟性を持てるシステムをしたい人向け
```

#### まとめ

- Kubernetes,Istioはとても様々なところで活用され、開発が活発
- マイクロサービスアーキテクチャも将来有望には見える
- Cloud Services PlatformはGoogleのベストプラクティスをパッケージ提供。とても期待できそう
- それらを適用するかどうかはチームで決める必要がある
アンマウントせずにデータストアを消してしもーたら

# うっかりデータストアを消してしもーた

ストレージサーバで要らないボリュームを消したら、vSphere に侵入禁止の標識みたいなオマケの付いたストレージがずらりと並んでた。ストレージの名前の後ろに `(inactive)` って表示されてる。

おもむろに右クリックして `Delete Datastore` を選択するも、件のストレージアイコンは消えない。

```
An error occured during host configuration. Operation failed, diagnostics report: Not a known device: ...
```

ですって。焦る。

# 環境・状況を確認する

- ESXi 6.5
- VMFS 形式
- VM からは使っていないデータストアを消したので、データロスとかはない。

# ストレージを再スキャンする

各 ESXi ホストを右クリックして、`Storage` > `Rescan Storage...` を選択してスキャンを実行すると、件のストレージアイコン達が消える。ほっ。

# 参考文献

1. [Volume deleted on storage cannot be removed from vSphere](https://www.experts-exchange.com/questions/29085269/Volume-deleted-on-storage-cannot-be-removed-from-vSphere.html)
Ruby の Array#uniq で重複したアイテムは、先に出てきたものが残る

```ruby
items = [
  {name: 'john', attr: 'foo'},
  {name: 'john', attr: 'bar'},
  {name: 'john', attr: 'baz'},
  {name: 'paul', attr: 'foo'},
 ].uniq { |item| item[:name] }
puts items.first[:attr] #=> ??
```

`Array#uniq` した時に残されるアイテムが保証されてるのか気になったので調べた

## 公式ドキュメントより

>uniq は配列から重複した要素を取り除いた新しい配列を返します。 uniq! は削除を破壊的に行い、削除が行われた場合は self を、 そうでなければnil を返します。
> 取り除かれた要素の部分は前に詰められます。 要素の重複判定は、Object#eql? により行われます。

[instance method Array#uniq - Ruby 2.5.0 リファレンスマニュアル](https://docs.ruby-lang.org/ja/2.5.0/method/Array/i/uniq.html)

日本語版だとどっちが残されるのか曖昧

> self is traversed in order, and the first occurrence is kept.

[instance method Array#uniq](https://docs.ruby-lang.org/en/2.5.0/Array.html#method-i-uniq)

英語ドキュメントにはちゃんと書いてあった。最初に見つけたのを保持する。
YYPHP#46「DockerでLaravelを動かそうハンズオン！」

これは2018年07月27日に開催したPHPerイベント[YYPHP#46]のイベントレポートです。

[YYPHP]は一言で「PHPerの部室」です。PHPについて、雑に、ゆるく、ワイワイ話し合う集いです。毎回お題を決めずに雑談を出発点にいろいろなことを突発的にやります。集まった人でコードリーディングをすることもあれば、一緒に開発ツールを触ってみたり、フレームワークについての情報交換をすることもあります。開催はほぼ**毎週**、高田馬場にて。

[YYPHP#46]:  https://yyphp.connpass.com/event/93170/
[YYPHP]: https://yyphp.connpass.com/
YouTubeでの配信映像はこちら-> [#YYPHP #46 #動画でわかるDocker Laravelハンズオン
](https://youtu.be/mLjnJT8I_z8)

![](https://qiita-image-store.s3.amazonaws.com/0/889/0051f99f-b555-6064-fcc9-3280e5543a1a.png)

# #YYPHP #46【PHPの情報交換・ワイワイ話そう・仲間作り・ゆるめ・にぎやかめ】

## 講師

* [reoring(れおりん)](https://twitter.com/reoring)

## ハンズオンの主旨

* DockerでLaravelを起動できるところまでを説明します! Laradockなどの既に構築されていて複雑化してしまったものだとDockerへの理解がなかなかできないため、この #動画でわかるDocker では、とてもシンプルな形を作ってみます。

## 参加者17名(うちリモート7名)

* PHP歴
    * 1年未満: 5名
    * 2年未満: 1名
    * 3年未満: 1名
    * 5年: 1名
    * 8年: 1名
    * 10年以上: 1名

## 今日聞きたいこと(内容はYouTubeでご覧ください)

* [DockerはどうやってコンテナのIDを決定しているか - Qiita](https://qiita.com/reoring/items/4aad2e297da70dbddb56)
* Dockerがどうやって動いているのかが知りたい
* Dockerを全体的に聞きたい
* いろいろあるので都度聞きたい
* ポートとかネットワーク周りを聞きたい

# Dockerハンズオン

```bash
mkdir docker-handson && cd docker-handson
mkdir src laravel
```

## install.sh

```bash
#!/bin/bash

docker run -v `pwd`/src:/src composer create-project --prefer-dist laravel/laravel /src/$1
```

```
chmod +x install.sh && ./install.sh mylaravel
```

## laravel/Dockerfile

```
FROM php:7.2-apache

RUN set -x && \
  apt-get -y update && \
  apt-get install -y libicu-dev wget unzip libpq-dev libsqlite3-dev libbz2-dev && \
  NPROC=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1) && \
  docker-php-ext-install -j${NPROC} intl pdo_pgsql pdo_mysql pdo_sqlite pcntl && \
  rm -rf /tmp/pear

RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf

WORKDIR /var/www
```


## docker-compose.yml

```yaml
version: '3.1'
services:
  web:
    build:
      context: ./laravel
    volumes:
      - ./src:/var/www
    environment:
      APACHE_DOCUMENT_ROOT: /var/www/${PROJECT_NAME}/public
    ports:
      - "8080:80"
    depends_on:
      - db
    tty: true
    stdin_open: true

  db:
    image: postgres:10
    ports:
      - "5433:5432"
    environment:
      POSTGRES_PASSWORD: dbpass
      POSTGRES_DB: laravel_test_db
```

## .env

```
PROJECT_NAME=mylaravel
```

* ビルドを実行

```
docker-compose build
```

* Laravelを起動

```
docker-compose up -d
```

* ブラウザでアクセス

http://localhost:8080/

ハンズオン内容はここまで。

## YYPHPは毎週やってます

PHPについてワイワイ話したい方は、[YYPHPのイベント情報](https://yyphp.connpass.com/)をチェックしてみて下さい。

以上、YYPHPのレポートでした。次回もワイワイやっていきたいと思います！ では、また来週！
Laravel 言語切り替えをミドルウェアでやる

# Laravelでの多言語化
https://readouble.com/laravel/5.6/ja/localization.html


App::getLocale()で得られる言語で切り替えてくれる
但し、HTTPのAccept-Languageでの切り替えは勝手にやってくれない
(App::getLocale()はconfig/app.phpのlocaleを取ってきているだけ）

# middlewareで切り替え
```php
public function handle($request, Closure $next)
{ 
    $lang = locale_accept_from_http($request->server->get('HTTP_ACCEPT_LANGUAGE'));
    \App::setLocale($lang); 
    return $next($request); 
}
```
Open Developers Conference 2018 Tokyo / 聴講メモ

## ■これは何?
* [Open Developers Conference 2018 Tokyo](https://www.ospn.jp/odc2018/)のメモ
	* 8/26(2日目)の2セッションのみ;
	* かなり雑なメモです;

## ■LLイベント2018 -Learn Languages in ODC （12:00～17:30） | [12:00-13:00　Language Update (1)](https://llevent.connpass.com/event/95443/)

* [当日の資料](https://llevent.connpass.com/event/95443/presentation/?utm_campaign=new_event_links_to_participant&utm_source=notifications&utm_medium=email&utm_content=detail_btn)

### ■■Go
* (なし)

### ■■Java
* 最近のJava -> 柔らかく: 言語仕様も
	* Java 9 モジュール
	* Java 10, 11 var
* モジュール: まだまだ大変(混在しているので)
	* publicがpublic過ぎる問題。。
	* = JAR + メタデータ(ソースレベル(依存性、公開範囲)
		* module_info.java

		```java
		module a {
			requires b;
			requires d;
		}
		```

* var
	* 動的になったわけじゃない
	* ローカル変数
	* ラムダ式の引数

		```java
		void foo() {
			var list = List.of(0, 1, 2);
		}
		(var x, var y) -> x + y;
		```

* In the Future...
	* Amber
	* Loom
	* Valhalla
	* Panaama

* Open JDK LTS(3年保証)
	* 早めにテストを

### ■■Perl
* (なし)

---
## ■[Introduction of Kubernetes & Rancher （13:00～14:45）](https://www.ospn.jp/odc2018/modules/eguide/event.php?eid=26)

### ■■TL/DR;
* k8sの苦行を無しにしてくれるRancher最高だから[やってみ](https://qiita.com/cyberblack28/items/1f5cad99b7bb34b983e9)
* Docker/Kubernetes 実践コンテナ開発 入門が良すぎたので[書評書いた](https://cyberblack28.hatenablog.com/entry/2018/08/25/025104)

### ■■Market trend of ...
* Amazon EKS
* AKS
* Docker EE/on Windows Server
* VMware Kubernetes
* GKE on-Prem
* GKE serverless add-on
* GitHub Goes All in on Kubernetes
	* SRE(Site Reliabiity Engineering)事例として...
* Investigating of Kubernetes Platform

### ■■Introduction
* Google Borgから
* 役割と実現
	* NoOps

### ■■Architecture
* Master/Node
* Container Runtime...デフォルトはDocker
* 分散処理基盤として考えると理解しやすいかも
* Podはボリュームとネットワークを共有する1個以上のコンテナグループ
* Kubernetes, Docker本、おすすめ
* DeploymentとReplicaSetの理解大事
* Service がL4, IngresがL7

### ■■Introduction of Rancher
* コンテナー管理プラットフォーム
* ホスト(ノード)をつくるのは苦行...それをブラウザで
* 1.6(DockerベースJava, Go, MySQL), 2.0(kubernetesベース)
* カタログ機能がdocker-composeからHelmへ
* LineがOpen Stackと一緒にゴリゴリ使っているらしい
	* アーキテクチャについてめっちゃ調べたスライドが公開されている
* Create, Import, Manage
* ニュートラル

### ■■Get Started with Rncher 2.0
* step1: Ubuntu, 4GB, docker
* step2: Start ther server(docker run ...)

### ■■Handson
* GCPインスタンスでクラスタ作って
* [チュートリアル](https://qiita.com/cyberblack28/items/1f5cad99b7bb34b983e9)
* Guestbookアプリケーション(Kubernetes公式サンプル)

### ■■Information
* Docker実践ガイド
* Windowsコンテナー技術入門
* プログラマのためのDocker教科書
* (オライリー)入門Kubernetes
* コンテナ・ベース・オーケストレーション
* Docker/Kubernetes 実践コンテナ開発入門 ←※
	* https://cyberblack28.hatenablog.com
* 認定試験
	* CKA, CKAD
* 自己学習
	* https://www.katacoda.com
	* https://labos.play-with-docker.com
	* のk8s
	* 今こそ始めよう!Kubernetes入門
	* cndjpコミュニティ資料集
* JAPAN CONTAINER DAYS(1日トレーニング)
	* 12/3, 4, 5
* 今日の資料
	* [slideshare/cyberblackにある](https://www.slideshare.net/cyberblackvoom/introduction-of-kubernetes-rancher)
		* DevLOVE
AVFoundationを使ったカメラの実装：フラッシュの制御Tips

この記事ではAVFoundationを使って、カスタムカメラを実装する際のフラッシュの実装のTipsを2つ紹介します。

# 確認した環境
iOS11

# 1. `supportedFlashModes` の確認

iOS端末の中にはフラッシュ機能がないカメラが存在するため、その考慮が必要です。
具体的にはインカメラや一部のiPadのアウトカメラです。
フラッシュ機能がないカメラでフラッシュが `on` or `auto` で `AVCapturePhotoOutput` の `capturePhoto` メソッドを呼ぶとクラッシュします。

## 対応方法

`AVCapturePhotoOutput` の `supportedFlashModes` でサポートされているフラッシュモードが確認できるため、サポートされているフラッシュモードのみ設定するようにします。

# 2. 端末が高温で使えない場合の考慮

iOS端末は高温になるとフラッシュ機能が使えなくなります。
標準のカメラアプリでも使用できなくなり、以下のような表示になります。
<img width="175" alt="IMG_01C603296427-1.jpeg" src="https://qiita-image-store.s3.amazonaws.com/0/40689/9791cc11-4f74-6430-c5fa-e024680aeead.jpeg"> <img width="175" alt="IMG_01C603296427-2.jpeg" src="https://qiita-image-store.s3.amazonaws.com/0/40689/3a40f082-9f85-3225-b1f0-11f147d1b6d0.jpeg">

[Appleのドキュメント](https://developer.apple.com/documentation/avfoundation/avcapturephotosettings/1648760-flashmode)にもそのような記載があります。

## 対応方法

`AVCaptureDevice` の `isFlashAvailable` でフラッシュが使えるか確認できるため、この値を監視することになります。
私のケースでは対応する必要がなかったため実装はしていないのですが、 この値を変更を受け取るDelegateメソッド等は用意されていないようなので、KVOで監視することになると思います。
このケースでフラッシュが使えない状況で、フラッシュが `on` or `auto` で `AVCapturePhotoOutput` の `capturePhoto` メソッドを呼んでも、 1. とは違い、クラッシュしませんでした。
pyfftw 0.10.4を window にインストールする

# pyfftwとは
fftwのpythonラッパー．Scipyより速いとか．

# 普通に落としてきた方が早そう
あとから気づいたが，whlが普通に落ちているので，それを環境に合わせてダウンロードすると普通にうまくいった．
https://bintray.com/hgomersall/generic/PyFFTW-development-builds/view#
からバージョンを選んで，Filesから自分の環境(pythonのバージョン，64bit/32bit)に合わせて適当にダウンロードしよう．

# 自前ビルド
とはいってもfftwのdllは落としてくることを想定．
## FFTWのDLLを手に入れる
http://www.fftw.org/install/windows.html
から自分の環境に合わせてプレビルド済みのdllを落としてくる．

## FFTWの静的ライブラリを生成
上のサイトのドキュメントに書いてあるように，libファイルは別途自前で生成しなければならない
visual Studioを使う場合．
libにパスが通ってない場合があるのでその場合，適宜パスを追加する．
自分の場合は`C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin`にパスを通す必要があった．

```
lib /def:libfftw3-3.def
lib /def:libfftw3f-3.def
lib /def:libfftw3l-3.def
```
のようにして静的ライブラリを生成．64bitマシンの場合は（普通そうだと思うが`lib /machine:x64 /def:libfftw3l-3.def`）
のようにする．

## 配置
`pip download pyfftw` 
でソースコードを落としてくる．tar.xzなので

`tar -zxvf  pyFFTW-0.10.4.tar.gz`
などとして，解凍．（最近のwindowsではtarコマンドが使える．https://kledgeb.blogspot.com/2017/12/windows-14-windowscurltar.html）
pyfftwの中身から必要なファイル(dllやlibファイルなど)を`pyfftw`ファイル配下に配置

## 微妙に修正
このままだとビルドが通らなかった
https://github.com/pyFFTW/pyFFTW/issues/228
これに従って`pyFFTW.egg-info/SOURCES.txtを修正`

```
/home/whg/Projects/github/pyFFTW/pyfftw/pyfftw.c
/home/whg/Projects/github/pyFFTW/pyfftw/pyfftw.pyx
/home/whg21/Projects/github/pyFFTW/pyfftw/pyfftw.c
/home/whg21/Projects/github/pyFFTW/pyfftw/pyfftw.pyx
```
を

```
pyfftw/pyfftw.c
pyfftw/pyfftw.pyx
pyfftw/pyfftw.c
pyfftw/pyfftw.pyx

```
に修正する．

## python setup.py
あとは`python setup.py install`を最上位ディレクトリでやったら入った．
docker-composeでcommandが長いとき改行したい

docker-composeの`command`の設定が長くなると読みにくくなってしまう。

```yaml
version: '3'
services:
  phpunit:
    command: ./vendor/bin/phpunit -c acca-component/phpunit.xml --testsuite unit --coverage-text --colors=never
```

これは普通に改行することができる:

```yaml
version: '3'
services:
  phpunit:
    command:
      ./vendor/bin/phpunit
        -c acca-component/phpunit.xml
        --testsuite unit
        --coverage-text
        --colors=never
```
NvidiaのGPUドライバインストール時にUEFI Secure Bootの警告がでる

# 起きたこと
* Cudaを利用するために、[NVIDIAのドライバをインストールする@Qiita](https://qiita.com/kkk627/items/9ab959421804341f215e)の手順でインストールしたところ、下記の警告が発生。

```
The target kernel has CONFIG_MODULE_SIG set, which means that it supports cryptographic signatures on kernel modules.
On some systems, the kernel may refuse to load modules without a valid signature from a trusted key.
This system also has UEFI Secure Boot enabled; many distributions enforce module signature verification on UEFI systems when Secure Boot is enabled.
Would you like to sign the NVIDIA kernel module?
```

# 回避方法
* UEFIセキュアブートで、署名付きのOSやドライバのみ起動可能な状態だ！というメッセージなので、
* BIOSの設定でセキュアブートの設定をOFFにする。
* (役には立たないかもしれないが）手元のマシンのBIOSでは、下記をEnabled->Disabled

```
Settings
  \Advanced
     \Widows OS Configuration
        \Secure Boot
           \Secure Boot Support
```
Pythonでプログラミングを始めよう!　〜if文の使い方〜

#if文とは
今回は、if文のいろいろな使い方を説明していきたいと思います。
if文とはプログラムの中で条件分岐を書きたいときに使う文です。
使用頻度が高いので使い方をしっかりと理解しておく必要があります。

#基本的なif文の構文
if文の基本的な構文はこのようになります。  

```python

if 条件式① :
   条件式①がTrueの場合の処理

elif 条件式② :
   条件式②がTrueの場合の処理

else:
   全ての条件がFalseの場合の処理
```

・elif, elseは省略可能
・elifは何個あってもよい。


条件式は・・・・
・ 比較演算子などで条件を指定
・ 論理演算子（and, or, not）で複数条件や否定を指定

#比較演算子などで条件を指定

比較演算子とは２つの値を比較するものでbool値(True, False)を返します。
条件式で使用する比較演算子には下記のようなものがあります。

| 演算子            　　　　|結果               |
|:-----------------:|:------------------|
|x < y             |xがyより小さければTrue 　　|
|x <= y            |xがy以下であればTrue   |
|x > y             |xがyより大きければTrue 　　|
|x >= y            |xがy以上であればTrue 　　　　|
|x == y            |xとyが等しければTrue　　　　　 |
|x != y            |xとyが等しくなければTrue |

その他の演算子として、リストや文字列に要素が含ふくまれているかを判定するものもあります。
※リストについては別の記事で説明しますね。

| 演算子            　　　　|結果               |
|:-----------------:|:------------------|
|x in y             |xがyに含まれていればTrue 　　|
|x not in y         |xがyに含まれていなければTrue|


#論理演算子（and, or, not）で複数条件や否定を指定

論理演算子とは、if文で複数の条件の関係を記述する際や否定条件を記述する際に使うものです。

|      演算子     | 結果                                             |
|:---------------:|------------------------------------------------|
| 条件① and 条件② | 条件①、条件②がどちらもTrueの場合にTrue              |
| 条件① or 条件②  | 条件①、条件②のどちらかが,Trueの場合にTrue           |
| not 条件①       | 条件①がTrueであればFalse,,条件①がFalseであればTrue |


#実際にif文を書いてみよう
サンプルコードを書いておきますので、
どのようになるか実際に書いて試してみてください。

サンプルコード①
・Xが０より大きいか判定してみる。

```python
x=5

if x > 0:
    print('xは０よりおおきい。')
```

サンプルコード②
if else を使ってみる.

```python
x=5

if x > 10:
    print('xは10よりおおきい。')
else:
    print('xは10より小さい')
```

サンプルコード③
xの文字列に0が含まれているか判定してみる。

```python
x='0が含まれている'

if '0' in x:
    print('xに0は含まれている。')
else:
    print('xに0は含まれていない。')
```

サンプルコード④
論理演算子を使用して複数条件のif文を書いてみる。

```python
x=5

if x > 0 and x <= 5:
   print('xは０より大きく、５以下である。')
```

サンプルコード⑤
まとめ①
便宜上、 test_ifとゆう関数を定義しています。

```python
def test_if(x):
    if x > 100:
        print('100 < x')
    elif x > 50:
        print('50 < x <= 100')
    elif x > 0:
        print('0 < x <= 50')
    elif x == 0:
        print('x == 0')
    else:
        print('x < 0')

test_if(100)
```
引数の数値を変えていろいろ試してみましょう！


サンプルコード⑥
まとめ②

```python 
def test_if_in(x):

    if 'a' in x:
        print('a is in string')
    else:
        print('a is NOT in string')

test_if_in('bbab')
test_if_in('bbbb')
```

サンプルコード⑦
まとめ③

```python
def test_if_and_not_or(x):
    if x >= 0 and not x % 2 == 0 or x == -10:
        print('x is positive odd or -10')
    else:
        print('x is NOT positive odd or -10')

test_if_and_not_or(5)
test_if_and_not_or(10)
```



#まとめ
if文の使用方法について説明させて頂きました。
これらについては、非常に使う場面が多いと思うのでしっかりと理解して覚えておくと、
良いと思います。

次回はfor文についてに説明していきたいとおもいます！
CoreOSでDockerが動かなくなった。(The program docker is managed by torcx) 

# 1. 事象
Docker上で何かを検証する際には、軽量のLinux OSであるCoreOSを使っています。2018年8月27日に、いつも通りの手順で実行してみたところ、dockerが使えなくなっていた。

```
#git clone https://github.com/coreos/coreos-vagrant/ 
#cd coreos-vagrant
#vagrant up
#vagrant ssh
core-01 core # cat /etc/os-release
NAME="Container Linux by CoreOS"
ID=coreos
VERSION=1786.1.0
VERSION_ID=1786.1.0
BUILD_ID=2018-05-24-2149
PRETTY_NAME="Container Linux by CoreOS 1786.1.0 (Rhyolite)"
ANSI_COLOR="38;5;75"
HOME_URL="https://coreos.com/"
BUG_REPORT_URL="https://issues.coreos.com"
COREOS_BOARD="amd64-usr"

core-01 core # docker
The program docker is managed by torcx, which did not run.
```

# 2. 解決策
torcxは、a boot-time addon managerとのことです。下記等、関連する情報があるのですが、解決方法が分からない。
[Toward Docker 17.xx in Container Linux | CoreOS](https://coreos.com/blog/toward-docker-17-in-container-linux)
[GitHub - coreos/torcx](https://github.com/coreos/torcx)

自分は、結局、config.rb.sampleをconfig.rbにリネームした上で下記のように修正し、vagrant destroy、vagrant upで解決させました。config.rb.sampleはcoreos-vagrantディレクトリ配下にあります。みなさんの参考になれば幸いです。　

```
# Official CoreOS channel from which updates should be downloaded
#$update_channel='alpha'
$update_channel='stable'

core-01 core # cat /etc/os-release
NAME="Container Linux by CoreOS"
ID=coreos
VERSION=1871.0.0
VERSION_ID=1871.0.0
BUILD_ID=2018-08-15-2242
PRETTY_NAME="Container Linux by CoreOS 1871.0.0 (Rhyolite)"
ANSI_COLOR="38;5;75"
HOME_URL="https://coreos.com/"
BUG_REPORT_URL="https://issues.coreos.com"
COREOS_BOARD="amd64-usr"

core-01 core # docker version
Client:
 Version:           18.06.0-ce
 API version:       1.38
 Go version:        go1.10.3
 Git commit:        0ffa825
 Built:             Wed Jul 18 18:54:54 2018
 OS/Arch:           linux/amd64
 Experimental:      false

Server:
 Engine:
  Version:          18.06.0-ce
  API version:      1.38 (minimum version 1.12)
  Go version:       go1.10.3
  Git commit:       0ffa825
  Built:            Wed Jul 18 18:54:54 2018
  OS/Arch:          linux/amd64
  Experimental:     false
```
[Running CoreOS Container Linux on Vagrant](https://coreos.com/os/docs/latest/booting-on-vagrant.html)
GMT (Generic Mapping Tools) で eps から画像形式変換

最近まで知らなかったのですが，GMT (Generic Mapping Tools) は eps あるいは ps 出力しかできない，これはそのとおりなのですが，GMT のコマンドで他形式ファイルに eps (ps) を変換できることを知りました．詳しくは以下の説明を．

[psconvert — GMT 5.3.2 documentation - The Generic Mapping Tools](http://gmt.soest.hawaii.edu/doc/5.3.2/psconvert.html)

当方の環境は以下の通りです．

+ MacBook Pro (Retina, 13-inch, Mid 2014)
+ macOS High Sierra
+ GMT 5.4.4
+ ImageMagick 7.0.8

これまでは，GMT で出力した eps ファイルを ImageMagick を使って以下のように jpg に変換していました．

```
mogrify -trim -density 300 -bordercolor 'white' -border 10x10 -format jpg *.eps
```

これに対し，GMT のコマンドである psconvert を使うことにより，eps を jpg に変換できます．

使い方は，以下のような感じ．

+ ```$fn``` に eps のファイル名を入れます．
+ ```-Tj``` で jpg に変換．デフォルトでは出力ファイル名は拡張子のみが変わるようです．
+ ```-A``` で余白削除．
+ 解像度の指定もできるようですが，デフォルトでは 300dpi のようです．
+ 変換できる画像は，BMP, EPS, JPEG, PDF, PNG, PPM, SVG, TIFF ということです．

```
f1=fig_gmt_cont1.eps
f2=fig_gmt_cont2.eps
f3=fig_gmt_cont3.eps
f4=fig_gmt_vect1.eps
f5=fig_gmt_vect2.eps
f6=fig_gmt_disp0.eps
for fn in $f1 $f2 $f3 $f4 $f5 $f6
do
gmt psconvert $fn -Tj -A
done
```

こんな使い方もできます．上記スクリプトと同じ結果が得られます．

```
f1=fig_gmt_cont1.eps
f2=fig_gmt_cont2.eps
f3=fig_gmt_cont3.eps
f4=fig_gmt_vect1.eps
f5=fig_gmt_vect2.eps
f6=fig_gmt_disp0.eps
gmt psconvert $f1 $f2 $f3 $f4 $f5 $f6 -Tj -A
```

フォルダ内のepsを一挙に処理する場合はこれか．

```
for fn in *.eps
do
gmt psconvert $fn -Tj -A
done
```


```gmt psconvert``` の良いところは．．．

+ ImageMagickの```mgrify -trim``` で 16 秒かかる変換作業が，```gmt psconvert``` では 5 秒で完了します．これは処理が必要な手持ちファイルでの試行結果ですが，おそらく ImageMagick より早い！
+ また GMT で eps 出力した後 ImageMagick を呼び出して処理していたのが，余白処理＋ファイル変換を全て GMT コマンドできるところが気持ちがいい．

便利です．これからはこれを使おう．

以　上
ある日突然SSHログインできない！

# ある日突然SSHログインできない
* 初心者っぽいトラブルに遭遇してしまいました
* こういうトラブル地味にこたえるのでメモしておきます

# 原因はパスワードの有効期限切れ
* パスワードなんて設定した記憶もないがそういうことだったらしい
* つまり”パスワードなしというパスワード”が有効期限切れということらしい
* 有効期限も設定した記憶ないけど。。
* パスワードの有効期限を無期限にして二度と発生しないようにする

# 対応手順

### アカウントロックを解除

```
■ロックを確認
# passwd -S appuser
appuser LK 2018-04-26 90 120 30 -1 (Password locked.)
※ LKはロック印

■パスワード変更なしでロック解除できない事を確認
# usermod --unlock appuser
usermod: unlocking the user's password would result in a passwordless account.
You should set a password with usermod -p to unlock this user's password.
※ passwordを変えないとアンロックはできないらしい

■ロックを確認
# grep appuser /etc/shadow
appuser:!!:17647:90:120:30:::
※ 「！！」はロック印

■新しいパスワードを設定
# usermod -p <new_password> appuser

■アカウントロックを解除
# usermod --unlock appuser

■ロック解除を確認
# passwd -S appuser
appuser PS 2018-08-27 90 120 30 -1 (Password set, DES crypt.)

■ロック解除を確認
# grep appuser /etc/shadow
appuser:password_123:17770:90:120:30:::

```

### パスワードの有効期限を無期限にする

```
■パスワードの有効期限を確認にする（チャゲ？）
# chage -l appuser
Last password change                                    : Aug 27, 2018
Password expires                                        : Dec 25, 2018
Password inactive                                       : never
Account expires                                         : never
Minimum number of days between password change          : 90
Maximum number of days between password change          : 120
Number of days of warning before password expires       : 30

■パスワードの有効期限を無期限にする
# chage -M 99999 appuser

■パスワードの有効期限を無期限にしたことを確認
$ chage -l appuser
Last password change                                    : Aug 27, 2018
Password expires                                        : never
Password inactive                                       : never
Account expires                                         : never
Minimum number of days between password change          : 90
Maximum number of days between password change          : 99999
Number of days of warning before password expires       : 30
```

( -᷄ ω -᷅ ). ふぅ