OmniAICreator/Qiita-1.07M huggingface dataset:
AWS初心者がAWS勉強会に参加してみた②

この前やった①の続きです。
①ではAWSについて簡単に説明しましたが、
今回以降はAWSのコアとなるサービスについて書いて行きたいと思います。


#AWSのコアサービスって？
AWSのコアとなるサービスは、三種類あり「コンピューティング、ストレージ、データベース」です。
管理API、アプリケーションサービス、デプロイメントサービスやネットワーキングサービス
などのコンポーネントがそれらを補強しています。

もちろん、これらは全てAWSインフラ内でホストされてるので、
ユーザはインターネットに繋がる環境があれば、サービスを利用することが可能です。
②では、コアサービスを補強する役割である、AWSのネットワーキングサービスについて
説明していきたいと思います。

#Amazon VPC

VPCは 「Virtual Private Cloud」 の略です。
AWS上にネットワーク的に分離されている
仮想のプライベートネットワークを構築することが可能です。
ユーザが指定するIPアドレス範囲の仮想ネットワーク内で、
AWSの様々なリソース（コンピューティング、ストレージ、データベースなど）を
起動することが可能です。
Amazon VPCのコンポーネントは以下の通りです。

① サブネット
② Network Access Control List （NACL）
③ 固定グローバルIP （Elastic IP Address）
④ VPN接続


①サブネット
VPCのIPアドレス範囲を更に複数のサブネットワークに分割することができ、
分割されたネットワークを、オープンやクローズドな領域として振舞うことができます。
つまり、アプリケーションサービスの特性に合わせたネットワークの構築ができます。

② Network Access Control List （NACL）
個々のサブネット宛や個々のサブネットからの送信/受信の制御をすることが可能です。

③固定グローバルIP (Elastic IP Address)
Amazon VPCネットワーク内のインターネットに公開されたサブネットに配置している
仮想コンピュータ （インスタンスと呼ばれる） に対して、
Amazon Elastic IP Addressを付加するすることが可能であり、
サーバに固定のグローバルIPアドレスを付与したことと同じ扱いです。
つまり、インターネット上からインスタンスへアクセスすることが可能です。

④VPN接続
既存のデータセンターにあるシステムのセキュリティポリシーや管理ポリシーを
AmazonVPCに適用した上で、セキュアにオンプレミスな既存データセンターと
AWSを繋ぐことが可能です。

Amazon VPCについて文字だけだと分かりにくいかなと思ったので
以下に図を作ってみました。
![無題.png](https://qiita-image-store.s3.amazonaws.com/0/257565/d1514a76-2d19-8a6b-88ee-99e3d493273b.png)
※クオリティの低さは許して

#AWS Direct Connect

Amazon VPCで作成されたネットワークと自社ネットワーク（DCネットワーク）を専用線や
自由度の高い広域イーサネットサービスで接続することが可能であり、
例えば自社の内部ネットワークに対してAWSのネットワーク環境を接続することが可能です。


今回はここまで、次回③はコンピューティングについて
書きたいと思います。

③に続く
laravelでルーティング一覧を表示する


ver : Laravel Framework 5.6.21



```
$ php artisan route :list
+--------------------------------------------------------+-----------------------------+------------------------------------------------------------------------+----------------------------------------------+--------------------
| Domain | Method   | URI                                                    | Name                        | Action                                                                 | Middleware                                   |
+--------+----------+--------------------------------------------------------+-----------------------------+------------------------------------------------------------------------+----------------------------------------------+
|        | GET|HEAD | _debugbar/assets/javascript                            | debugbar.assets.js          | Barryvdh\Debugbar\Controllers\AssetController@js                       | Barryvdh\Debugbar\Middleware\DebugbarEnabled |
|        | GET|HEAD | _debugbar/assets/stylesheets                           | debugbar.assets.css         | Barryvdh\Debugbar\Controllers\AssetController@css                      | Barryvdh\Debugbar\Middleware\DebugbarEnabled |
|        | DELETE   | _debugbar/cache/{key}/{tags?}                          | debugbar.cache.delete       | Barryvdh\Debugbar\Controllers\CacheController@delete                   | Barryvdh\Debugbar\Middleware\DebugbarEnabled |
|        | GET|HEAD | _debugbar/clockwork/{id}                               | debugbar.clockwork          | Barryvdh\Debugbar\Controllers\OpenHandlerController@clockwork          | Barryvdh\Debugbar\Middleware\DebugbarEnabled |
|        | GET|HEAD | _debugbar/open                                         | debugbar.openhandler        | Barryvdh\Debugbar\Controllers\OpenHandlerController@handle             | Barryvdh\Debugbar\Middleware\DebugbarEnabled |
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
```
こんな漢字で一覧が表示される
FreeBSDでLAGG+VLAN tagを使う

# はじめに
laggでNICを束ね、そこにVLAN tagを通します。

# NICを束ねる
`em0`と`em1`はNICです。

```
# ifconfig em0 up
# ifconfig em1 up
# ifconfig lagg0 laggproto lacp laggport em0 laggport em1
```

スイッチとリンクが確立されると以下のようになります。

```
# ifconfig lagg0
lagg0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=4019b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,TSO4,VLAN_HWTSO>
        ether 00:15:17:6f:55:ee
        nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
        media: Ethernet autoselect
        status: active
        groups: lagg 
        laggproto lacp lagghash l2,l3,l4
        laggport: em0 flags=1c<ACTIVE,COLLECTING,DISTRIBUTING>
        laggport: em1 flags=1c<ACTIVE,COLLECTING,DISTRIBUTING>

```

# VLAN用IFを作る
VLAN-IDが101のNICを作ります。

```
# ifconfig lagg0.101 create
# ifconfig lagg0.101 inet 192.168.1.10 netmask 255.255.255.0
```

# `/etc/rc.conf`に設定を書く

`/etc/rc.conf`には以下のように記述します。

```
cloned_interfaces="lagg0 lagg0.101"
ifconfig_em0="up"
ifconfig_em1="up"
ifconfig_lagg0="laggproto lacp laggport em0 laggport em1"
ifconfig_lagg0_101="inet 192.168.1.10 netmask 255.255.255.0"
```
AIアプリへの道:Python基礎(3)

Aidemy Python基礎

#今日学んだことのまとめ
##所感
Pythonのオブジェクト指向について学んだ。概念はJavaと同じオブジェクト指向なので理解は容易だった。
ただし、コンストラクタ(`__init__`）の際の引数にselfをつけることには違和感。呼び出す引数の数と合わないため、、。
##今日一番の驚き
コンストラクタの定義

```python

 def __init__(self, 引数): 

*第一引数にselfを指定すること
```

クラス内のメンバは変数名の前にself.を付ける。

そのほかのメソッド定義はコンストラクタと同じように、メンバの頭にself.を、第一引数にselfを指定する。
**しかし他の部分は通常の関数定義と同様に書くことができます。


クラスは設計図。
オブジェクトを作るにはクラスが必要。
クラスを呼び出す際にコンストラクタを呼ぶ。
##他の気づき
###関数のインポートに関して

```Python
import パッケージ
X = パッケージ名.モジュール名()
```
OR

```Python
from モジュール　import パッケージ
X = モジュール名()
**パッケージ名を省略できる
```

###文字列フォーマットに関して
.format()とする方法と、ダブルorシングルクオーテーション内で%書式をつかうと、文字列の後ろに置かれたオブジェクトを引き渡すことができる。

```Python:.format()を使う
print("私は{}、{}歳です。".format("氏名", 年齢)
```
```Python:%書式を使う
print("私は%sです。" % name)
```
###関数定義の方法

```Python:関数定義
def 関数名(引数)：
```

###学んだ関数
```Python
b.sort() bの要素を小さい順に完全に並び替え
b.reverse() bの要素大きい順に完全に並び替え
sorted(b) 単純に（一時的に）並べ替えたリストを参照したい場合
b.index() bの要素内のaのインデックス番号
b.count(a) bの要素内のaの数を数える
```
で新しい関数を作ることができる。
おわり！
ティラノスクリプトでPWA対応

#必要なもの
* ティラノライダー v200以上

#できること
* ホーム画面に追加
* リソースのキャッシュ

##やっておくこと
[ティラノライダー](https://tyrano.jp/dl/rider)で「スーパーブラウザゲーム」形式でパッケージング
![20180603_01.png](https://qiita-image-store.s3.amazonaws.com/0/190389/a716036d-6637-0e15-1bd8-c69e571be3ea.png)
↑赤で囲ったうちのどちらか

ティラノビルダーを使用している場合は一度ビルダー側で「ブラウザゲーム」形式で出力、出力したフォルダをティラノライダーで読み込んでスーパーブラウザゲーム形式でパッケージングすればOK

##ホーム画面に追加
１．manifest.jsonの作成

```json:manifest.json
{
    "name": "GAME_TITLE",
    "short_name": "SHORTNAME",
    "icons": [
        {
            "src": "link.png",
            "sizes": "144x144",
            "type": "image/png"
        },
        {
            "src": "link_02.png",
            "sizes": "192x192",
            "type": "image/png"
        }
    ],
    "start_url": "/",
    "display": "fullscreen",
    "background_color": "#000",
    "theme_color": "#fff",
    "orientation": "landscape"
}
```
manifest.jsonの書き方は[このへん](https://developers.google.com/web/fundamentals/web-app-manifest/?hl=ja)

２．manifest.jsonをアップロード
pwa対応したいフォルダに置く
たとえば`game`というフォルダにティラノライダーから出力したファイルがあるとすると

```
game
├ data
│ └scenarioとか
├ tyrano
│ └libとか
├ index.html
└ manifest.json <=ここ！
```

ゲームを公開しているサイト全体ではなくゲームを個別にpwa化したいということならゲームのindex.htmlと同じ階層にmanifest.jsonを置いておけばいいと思う

３．manifest.jsonをhtmlのヘッダーで読み込む

```html:index.html
<link rel="manifest" href="/manifest.json">
```
デスクトップから確認するやりかたは[このへん](https://amymd.hatenablog.com/entry/2017/10/12/001612#Desktop-Chrome%E3%81%8B%E3%82%89%E3%81%AE%E7%A2%BA%E8%AA%8D)
というかこのページにやり方全部書いてある
スマホから確認はlocalhostではできない？
確認のときはhttpsでアクセスする必要があるので注意（自戒）

##リソースのキャッシュ
やることはだいたいティラノくんがやってくれる
config.tjsで`;debugMenu.visible=true`にした状態でDeveloper Tools（F12キー）を開き、Networkタブから画像などが読み込まれていることを確認できればOK
![20180603_02.png](https://qiita-image-store.s3.amazonaws.com/0/190389/46bcb3e2-d169-de4a-c39c-c12bb995c514.png)

ティラノライダーからスーパーブラウザ形式で出力すればServiceWorkerの登録はデフォルトで設定されているので特にいじる必要はない（と思う）

スマホからブラウザゲームをプレイするとどうしてもアドレスバーが邪魔に感じることが多いと思うのでpwa化して少しでも表示領域を広く取りたい気持ち
traitsObject()から呼ばれる関数でeval()を呼び出してはいけない。

特定の条件が有効な時だけ効果が発生するステートを作ろうとしたのですよ。
中身はこんなものです。

```:js

/*:
 * @plugindesc 条件式が有効な時だけ実行されるステートです。
 * 
 * @help
 * 
 * メモ欄に<StateConditon:任意の式>の形式で記述を行ってください。
 * ただし、>は使えません。
 * 左右を入れ替えて対応してください。
 * 処理負荷の関係上、戦闘中のみ判定式を使用します。
 */

(function(){
    'use strict';
/**
 * @param {String} expr 
 * @param {RPG.State} state 
 */
Game_BattlerBase.prototype.evalStateCondition_MA =function(expr,state){
    const a =this;
    var v = $gameVariables._data;
    const V=v;
    const s = $gameSwitches._data;
    const S =s;

    return eval(expr);
};

const Game_BattlerBase_states=Game_BattlerBase.prototype.states;
Game_BattlerBase.prototype.states = function() {
    const list = Game_BattlerBase_states.call(this);

    if(!$gameParty.inBattle()){
        return list;
    }

    return list.filter(function(state){
        const expr = state.meta.StateConditon;
        if(expr){
            this.evalStateCondition_MA(expr,state)
        }
        return true;
    },this);
        
};

})();

```

たとえば、「HPが50%以下である限り、攻撃力が倍になる」というステートを作ろうとしたとします。
この場合、ステートの処理でHPが50%以下である限りを取得しようとするとtraitObjects()が呼び出され、states()が呼び出され無限再起が発生して死にます。
なので、条件として使える式がかなり限定されます。
やるとしたら、慎重に内部の状態を調べる必要がありますが、面倒でしょうがないですね。

上記の問題を解決しても、ポールポジション問題を発生させることがあります。
《[ポールポジション](http://yugioh-wiki.net/?%A1%D4%A5%DD%A1%BC%A5%EB%A5%DD%A5%B8%A5%B7%A5%E7%A5%F3%A1%D5)》というのは遊戯王のカードです。
装備モンスターの攻撃力が1位である限り魔法の効果を受けないカードなのですが、装備魔法を付けただけで酷い結果になります。
フィールドの攻撃力２位のモンスターに装備魔法等を使うことで１位を追い抜いた場合、無限ループが発生してしまうのです。

もし、攻撃力が100以下なら+50するというステートを組んだとしましょう。
元々の攻撃力が80の場合、どういう結果になるでしょうか？

eval()は何をしでかすかわからないので、気をつけようが無いですね。
対策ですが、ステートの仕様から各自個別実装しかないでしょう。
本当に不毛です。
docker-composeでrailsを動かす

# RailsにDockerを導入
1. Dockerのインストールと起動
2. imageの作成(imageの作成は割愛)
3. docker-compose.ymlの作成
4. `docker-compose up`でスタート
5. `docker-compose stop`でストップ


# docker-compose.ymlの構成

```yaml:docker-compose.yml
version: '2.0'

services:
  db:
    image: postgres:9.6.7-alpine
    volumes:
      - ./docker/pg:/var/lib/postgresql
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: test_db
    ports:
      - '5433:5432'

  web:
    image: <docker_image>:latest
    ports:
      - "3000:3000"
    volumes:
      - .:/my_app
      - bundle:/my_app/vendor/bundle
    working_dir: /my_app
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    links:
      - db

volumes:
  bundle:
```

# 基本的な考え方

1. dbとwebは、それぞれデータベースとrailsで、2つのコンテナを作成したことになる。
2. dbの情報はdocker-compose.yml内で指定し、これをconfig/database.ymlに書くことで、railsからdockerコンテナのdbに接続できるようにしている。
2. webからdbに依存するために、`links -db`というのをつけている。
3. volumesとは、Dockerが作成したコンテナ上のデータを実際に自分のマシン上に保存するように、対応を書いてデータを保存しておくことができる。`./docker/pg:/var/lib/postgresql`これは、左側は、実際にマシン上でrailsのrepoのdocker/pg以下にdocker内で立てたpostgresのDBのデータが保存される場所を対応させ、データを保存している。
4. `ports`は、コンテナ内のポートを自分のマシン(外部)にオープンする。今回の例では、3ブラウザからlocalhost:3000を叩いて、開けれるようにするために、コンテナの3000と自分のマシン上の3000を対応付ける必要がある。


# 陥りやすいポイント

1. dbなどで、Dockerを使う前にlocalhostとして使っていたhostは、dockerのcontainerの名前と同じようにしないといけない。containerの名前を`db`とした場合

    ```:before
    development:
      adapter: postgresql
      encoding: unicode
      pool: 25
      database: test_db
      username: postgres
      password: postgres
      host: localhost
      template: template0
    ```

    ```:after
    development:
      adapter: postgresql
      encoding: unicode
      pool: 25
      database: test_db
      username: postgres
      password: postgres
      host: db
      template: template0
    ```

2. `docker-compose down`するとすべてデータも消えてしまうので、downはしない。(down: Stops containers and removes containers, networks, volumes, and images created by up. https://docs.docker.com/compose/reference/down/)
dockerを再起動しても、downしてないものはちゃんと残っているので、stopとupを使っておけば、Volume内に保存されたデータも残る。
第9話 カタラン予想

この記事は[仮面ライダービルドの数式](https://qiita.com/izmktr/items/e26a624e79bce3edccc9)の第9話です。

```math
x-y=1(x,y=m^n ),\ x=9
```

カタラン予想です。
現在は解決されているので予想ではありません。
ちなみに、予想は誰にも証明されてない事柄で、証明された後は定理と言われます。
証明されているのに予想、とついているのは、証明までに時間がかかりすぎて、
～予想の名前で定着したという経緯があります。

さて、この式はべき乗数に関する問題です。
べき定数は自然数をべき乗した数で、こんな数があります。

```math
2^n=4,8,16,32,64 \cdots \\
3^n=9,27,81,273,819 \cdots \\
5^n=25,125,625,3125 \cdots
```

カタラン予想とは、このべき乗数が隣り合うのは8と9だけである、という予想です。
べき乗数は急激に大きくなるので、密度としてはまばらにはなるのですが、
無数にありますから偶然隣り合うことが決してない、というのは不思議に思えます。

この証明は公開されて約150年経過して証明されました。

流石に年月がかかっているだけあって簡単に理解できそうな証明ではないですが、
気になる人向けに途中までざっくり解説します。

$a^p-1$は次のように因数分解できます。

```math
a^p-1=(a-1)(a-\xi)(a-\xi^2)\cdots(a-\xi^{p-1})=b^q \\
\xi^p=1, \ \xi\neq1 \\
a-1 = x^q
```

ξはn乗すると1になる複素数です。
とにかくこのように素因数分解(素元分解)すれば、a-1はなにかのq乗になります。
なぜなら、これらの因数は「互いに素」だからです。

…とまぁ、複素数に約数なんてないし、互いに素ってどういうこと？って感じになりますが、
この辺は整数環という概念で、そのへんの知識が必要になります。

ちなみに、ABC予想を使えば、pやqは3以下が確定し、pとqは違う値のはずなので、
$a^2 \pm 1=b^3$ を頑張って解くだけで証明が完了します。
ABC予想すごいですね。
【jQuery】formの入力を一括削除



#前提
form内に複数の入力エリアがあり、
ボタンを押したら、一括ですべての入力欄の内容が消えるようにしたいと思います。

間違いや、別手法などのご助言頂けると幸いです。

#コード
```html:index.html

<form method="post" action="#">
  <input type="text" name="text">
  <input type="password" name="pass">
  <input type="number" name="num">
  <button type="button" id="del-btn">入力削除</button>
</form>

```

```js:deleteAll.js

$(function()
{
  $('#del-btn').on('click',function()
  {
    $(this).parent('form').find(':text').val("");
    $(this).parent('form').find(':password').val("");
    $(this).parent('form').find('input[type="number"]').val("");
  });
});

```

##解説
削除ボタンが押されたら、
自身の親要素のformの中から、inputのそれぞれ探して,valを書き換えています。
`$(this).parent('form')`としているのは、複数formがある時対策です。
この構造の場合findじゃなくて、`children()`でも良いです。

formが一つであるなら、

```js:deleteAll.js

$(function()
{
  $('#del-btn').on('click',function()
  {
    $('form').find(':text').val("");
    $('form').find(':password').val("");
    $('form').find('input[type="number"]').val("");
  });
});

```

メソッドチェーンを使って繋げることも出来ます。

```js:index.html

$(function()
{
  $('#del-btn').on('click',function()
  {
    $('form').find(':text').val("").end()
        .find(':password').val("").end()
            .find('input[type="number"]').val("");
  });
});

```
UbuntuでWiresharkをインストールする

UbuntuでWiresharkをインストールする

環境は以下

- Windows10 Enterprise

 - プロセッサ：Corei7 6600U @ 2.60GHz 2.81GHz
 - 実装メモリ(RAM)：8.00GB
 - OS種：64bit

- VMware(R) Workstation 12 Player
 - 12.5.7 build-5813279

- Ubuntu 16.04.04


#ブラウザからインストールする場合
Firefoxで検索してインストール

#コマンドでインストールする場合
下記コマンドを実行

```
smatsuo@ubuntu:~$ sudo apt install wireshark
```

途中、一般ユーザでも使用しますか？と聞いてくるので「YES」を選択。


#起動
左上の検索で「Wireshark」で検索して起動。
![キャプチャ.JPG](https://qiita-image-store.s3.amazonaws.com/0/224022/9f2edea6-602c-2c04-ef61-5f6c48d5ac78.jpeg)


![キャプチャ.JPG](https://qiita-image-store.s3.amazonaws.com/0/224022/95996d9a-67fd-2659-15a2-a1372cdc05fc.jpeg)

権限が無いと言われます。
（さっき設定したはずなのに）

![キャプチャ.JPG](https://qiita-image-store.s3.amazonaws.com/0/224022/afae297a-311b-1e27-658f-125cd5cfca29.jpeg)


#一般ユーザに権限追加
下記コマンドを実行して、一般ユーザをwiresharkグループに追加する必要があるみたいです。


```
smatsuo@ubuntu:~$ sudo usermod -a wireshark [user]
```
※smatsuo@ubuntu:~$ sudo usermod -G wireshark [user]　既存のグループを上書き


一度ログアウトして、再度一般ユーザでログインしなおします。
![キャプチャ.JPG](https://qiita-image-store.s3.amazonaws.com/0/224022/b492c5e4-7c70-00d5-d743-9f81d0be23b6.jpeg)

任意のインターフェースが選択できるようになりました。
『はじめて学ぶソフトウェアのテスト技法』を読み解く - 「テストとはなにか」

## はじめに

[『はじめて学ぶソフトウェアのテスト技法』](http://amzn.asia/i5oU2nG)を読んでいます。
このQiitaは本の内容をもとに、自分の思考整理と、理解促進のために書いています。

技術書に出てくる概念的な説明は、とにかく理解が難しいです。
読み進めているとだんだんとページの上を視線がすべるだけになっていって理解することができない、なんてことはよくあります。
なので理解を深めるために、噛み砕き、自分の言葉でアウトプットし直していこうと思いました。そんなQiitaです。

## テストとはなにか

テストとはなにかを説明したり定義するものは数多く存在します。
本の中に書かれている部分では、以下の一文が自分の理解と合っているように思いました。

> 「ある特定の条件下でシステムまたはコンポーネントを操作するプロセスであり、その結果を観察または記録して、システムまたはコンポーネントのある側面を評価すること」
> "IEEE Standard Glossary of Software Engineering Terminology" より

本の中では `「ある特定の条件」` を具体化したものがテストケースだと書かれています。この点には同意します。
また、文章中の言葉は以下のように読みました。

- 「システムまたはコンポーネントを操作する」 = 入力
- 「結果を観察または記録」 = 出力
- 「評価する」 = 出力結果と期待値の比較

入力と出力があって、その結果と期待値を比較するのがテスト、かな。

## テストの成熟度

テストには成熟度というものがあって、5つのレベルに分けられるそうです。
この5つというのは、組織や人のテストに対する姿勢であったり、その時々でのシチュエーションによってどう認識しているかを測るものに見えます。

### レベル0

> 「テストとデバッグには何の差もない。デバッグ以外にはテストには特別な意味はない」

そもそもテストが無い状況だと読みました。
テストを書くことはバグの原因究明を助けたり、再現性を高めることにもつながりますが、その認識も出来ていない（あるいはする余裕がない）状況かもしれません。

### レベル1

> 「テストの目的は、ソフトウェアが動くことを示すことである」

動くことを示すテストというのは、つまり動くソフトウェアに合わせて作るテストになる可能性があるということ。

> このアプローチは、ソフトウェアが（基本的に）正しいという全体から始まっていますが、欠陥を見つけ出そうとする我々の眼を曇らせる可能性があります。

正しい仕様をもとにしてテストケースを考えるべきだということと読みました。
TDDにおけるテストファーストにも、同じような意味が込められていますね。

### レベル2

> 「テストの目的は、ソフトウェアが動かないということを示すことである」

動かないことを示すテストを書くことで、その時にソフトウェアがどう振る舞うべきかを考える姿勢につながりそうです。
ここで例外を見つけることで、検査するパターンを増やすか、あるいは「例外」として丸めるか、その判断が必要になってくるレベルだと思います。

### レベル3

> 「テストの目的は、何かを証明することではなく、プログラムが動かないことによって発生する危険性をある許容範囲までに減らすことである」

プログラムが動かない場合に発生する問題を把握した上で、どこまで許容できるか判断を下すレベル。
この問題の発生確率は低いとはいえ、もし起きてしまえば会社が潰れてしまうほどにインパクトがあるので対応しようとか。
この問題の発生確率は高いとはいえ、起きても会社がどうこうなるほどのインパクトはないのでまだ対応しなくていいとか。
ビジネス面も考慮して優先順位付けができるレベルで、現場ではこのレベルが特に必要になりそう。

### レベル4

> 「テストは行動ではない。大げさなテストをすることなく品質の高いソフトウェアを作るための精神的な規律である」

つまりこれまでのレベルを全てクリアした状態と読みました。神状態。

> この成熟度レベルになると、よりテストの容易なソフトウェアを開発することに重点が置かれます。

例えば行き届いた自動化であったり。
例えばテスト容易な設計でプロダクトコードが書かれていたり。
品質保証のためのテストという観点のみでなく、プロダクト開発も加速するような、そんなレベルと読みました。

## さいごに

今自分がどこのレベルにいるか、組織はどのレベルにいるか、今この瞬間ではどのレベルのスタンスを選択するかが、実際の開発現場では重要になりそうです。

自分はおそらく品質を担保するためでなく、安心して開発を行うための補助輪としてのテストを書くという意味ではレベル2と3の間くらいに居るように思いました。
レベル4になりたい。
MQを利用した非同期処理を現実のものに例えて解説してみる

## 記事を書くに至った経緯
若手にMQを使って非同期処理をするって話をしたら、そもそもMQって何？非同期だと何が嬉しいの？という反応があったので、自分なりにMQとはなんぞや非同期処理だとなにが嬉しいのかってところをまとめてみようという感じです！

### 注意
MQと非同期処理のざっくりしたイメージを掴むための内容なので、細かいところまでは言及しません。
そのため既にMQや非同期について理解している人にはあまり参考になる内容ではありません。
ただし、SEである以上、非エンジニアに説明する機会もあると思うのでその点では参考になるかもしれません。

## MQとは
メッセージキュー（英: Message queue）は、プロセス間通信や同一プロセス内のスレッド間通信に使われるソフトウェアコンポーネントである。制御やデータを伝達するメッセージのキューである。（wikipediaより）

はい、これではなんのことかさっぱりですよね。（笑）:persevere:

キューとは先入れ先出し型のリストのことですね。つまり一方通行で出し入れできる箱です。

メッセージキューとはメッセージを一方通行で出し入れできる箱のことです。

現実のもので例えると郵便ポストのようなものです（先入れ後出しになる可能性がある点については目を瞑ってください）

## MQを使って非同期処理をするとは
WEBアプリケーション（WEBとは限りませんが）がMQにメッセージを詰め、リスナーがMQからメッセージを受け取ることでアプリケーションとリスナーの処理を別プロセスで行うことができることを非同期処理と言います。

と言われてもよくわからないかなと思います（急にリスナーとかいう言葉が出てきたし）

リスナーとはMQからメッセージを受け取って仕事をする人のことです。

これも現実のものに例えてみます。
WEBアプリケーションが手紙を出したい人、MQが郵便ポスト、リスナーが郵便屋さんとしてみます。
手紙を出したい人が郵便ポストに手紙を入れてあげて、郵便屋さんが手紙があれば宛先に届けてあげます。
このように手紙を宛先に送るという動作の間に郵便ポストを挟むことによって、手紙をポストに投函する、手紙を宛先に届けると行動（プロセス）を分けることができるということです。

##非同期だとなにが嬉しいの
手紙を誰かに出したいという時、近くにいれば自分で直接届ければOKですが、これがもし、とても遠くにいるとかいう場合、私たちが直接渡しに行っては時間もお金も掛かりますよね。
手紙を出して家に帰ってくるまでとても時間が掛かってしまいます。

これが非同期だと手紙を出したい人は郵便ポストに手紙を入れるだけで済みます。
手紙を出すために掛かる時間とお金が節約できますよね。:relaxed:

これがWEBアプリケーションの場合だと、リクエストを飛ばしてレスポンスが返ってくるまでの時間が手紙を出すための時間に相当します。
非同期でない場合、リクエストを投げてからレスポンスが返ってくるまでにとても時間が掛かってしまいます。
WEBアプリケーションにとってレスポンスが遅いということは致命的なことです。

またプロセスが分かれることにより、障害発生時の原因の切り分けにもなります。
たとえばリスナーになにか問題があって、処理が進まないという事態が発生したとします。その場合も、リスナーを停止するだけでよいので、WEBアプリケーション側に障害を感じさせることなく障害対応ができます。
障害解消後はMQに溜まったメッセージをまた順番に処理していくだけなので、何事もなかったかのようにできます。

##色々書いたけど覚えて帰ってほしいこと
MQは郵便ポスト、リスナーは郵便屋さんということだけです（笑）
![image.png](https://qiita-image-store.s3.amazonaws.com/0/207298/ad3c3093-7025-252e-98f1-1e78b8eb1252.png)
blockdiag の Web API サーバとライブプレビューをする WebUI を作りました

# はじめに

* [blockdiag](http://blockdiag.com/ja/) をリアルタイムでプレビューできたら素敵だな、ということで作ってみました。
* 公式でも http://interactive.blockdiag.com/ が用意されていますが、 ブラウザ側での SVG ダウンロード機能や CodeMirror を導入したかったため、自作することにしました。

# そもそも blockdiag って？

特定の書式でテキストを記述すると、図として出力してくれるダイアグラムジェネレータです。
詳しくはこちら ( http://blockdiag.com/ja/ )

個人的には packetdiag や seqdiag あたりが気に入っています。

# デモ

![blockdiag-livepreview2.gif](https://qiita-image-store.s3.amazonaws.com/0/19717/b4e1d8e3-6a21-e33b-4207-7a2e5e8dc974.gif)

# 実装に使った言語やライブラリ

## API サーバ側
* Python 3.6.5
* sanic ( https://github.com/channelcat/sanic )
    * そこそこ快適にプレビューしたかったので、速度面は若干気にしました
    * japronto の次に速いフレームワークだそうです。 ( [負荷試験のためのノウハウと Webフレームワークの負荷試験 (Python,Node,Go,PHP)](https://qiita.com/tkngue/items/62101788c0f384a5b12e) )
    * Flask-like に書けることもなかなかに良さげと思い、採用に至りました

## WebUI 側

こちらはあまりこだわりはありません

* javascript (ES6)
* React.js
* webpack4 + webpack-dev-server
* reactstrap
* bootstrap4
* CodeMirror
* etc ...

# ソースコード & デモサイト

以下で公開しています

* ソースコード
    * https://github.com/kaishuu0123/blockdiag-api
* デモ
    * https://blockdiag-api.com/

# 所感

* 最近の Python Web フレームワークを調べる機会が無かったので良い機会になった
* 利用したいライブラリに合わせて、言語を選んで実装する、という流れはなかなか楽しい
* python アプリの docker コンテナ化は思ったよりお手軽だった
Pythonista3 をいろいろ触ってみる_その4


# 4.Pythonistaで開発をしやすくするためのツール

iPadの標準キーボードからコーディングするのは、画面を見にくくなるし、打ちにくい。
とはいえ、サードパーティ製の外部キーボードも相性などあり、ちょっと準備する手間もお金もかかってしまう。

ということで、MacBookのキーボードをiPadの入力キーボードに使うことのできるアプリを入れました！
有料アプリにはなりますが、外部キーボードを購入するよりはお得です！！

<font color="Red">**[1Keyboard](https://itunes.apple.com/jp/app/1keyboard/id766939888?mt=12)**</font>

2018/06/03現在、1,200円で購入可能です。

使用して2週間ほど経過しましたが、
特別入力したときに遅延などもなく、ストレスなく使用できています！

![スクリーンショット 2018-06-03 0.47.54.png](https://qiita-image-store.s3.amazonaws.com/0/33479/ee6dec40-8fd6-3486-d5e3-32c8efc10382.png "スクリーンショット 2018-06-03 0.47.54.png")
Railsで使われる用語をちゃんと理解しておく（初心者向け,随時更新）

# はじめに

開発していて、困らない程度には用語を理解してるつもりだけど、「それって何ですか？」って言われたらいまいちちゃんと説明できていないので、用語集的なものを作って頭の整理をしようと思って書きました。

## 用語集

- Bundler とは、 Ruby や Rails のプロジェクトで使用するライブラリの**管理ツール**
- Bundler を使うと
    - *Gemfile*というファイルにインストールしたいライブラリ名と必要なバージョンのリストを全て書き出してくれる
    - `bundle install`で一気にそれらのライブラリをインストールしてくれる
- REPLとは、 Read Eval Print,and loop の略で、その意味は「読み込み-処理-表示」の繰り返しという意味
    - 対話型の**Ruby実行環境**のこと
    - `irb`で実行
- マイグレーションファイルとは、Rails からデータベースのテーブルを管理するための**ファイル**
- ActiveRecord は、Rails の中の1つで、Model全般の操作を担う**ライブラリ**
- Controller とは、ユーザから送信されてきた HTTP リクエストを処理するやつ
- Router と対応している Controller のメソッドのことをアクションという
- コントローラ名はモデルの複数形を`generate`する



## その他 Railで覚えておくといいこと

### Model
- マイグレーションの実行後はこのファイルを修正してもデータベースの変更はできない
- データベースのレコード1つが、Model のインスタンス1つに対応

### Router と Controller と View の流れ

- ユーザからの`HTTP`リクエストはまず`Router`を通る
- そして`Router`によって設定された`Controller`のアクションを通る
- そして、`Controller`のアクションに対応した`View`を`HTTPレスポンス`として返す
設定したalias名を忘れるのでpecoで探して実行する

タイトルどおりです。

aliasを設定したはいいんですが、たまにしか使わないものってよく忘れませんか？
gitのブランチ削除、sshのknow_hostsファイルからec2インスタンスを削除、とか作ったはいいんですがほぼ毎回aliasの設定を確認している気がします。
なので、pecoで簡単に実行してみました。

```shell-session
$ eval $(alias | sort | peco | sed -e 's/=.*$//')
```

自分の環境はzshです。
今回は単純に`alias`で読み込ませていますが、pecoの一覧に出てきてほしいものに予め分けておいたほうが良さそうです。
Pythonista3 をいろいろ触ってみる_その3


## 3.Pythonのチュートリアル

Pythonについての基本的な内容は、以下のサイトを確認すればだいたい把握できる。

<font color="Red">★個人的には、座学で勉強するよりも、とりあえず実践するのがおすすめ！</font>

- [The Python Tutorial](http://omz-software.com/pythonista/docs/tutorial/index.html)
- [The Python Standard Library](http://omz-software.com/pythonista/docs/library/index.html)
- [Pythonista Documentation](http://omz-software.com/pythonista/docs/)
ejsでレイアウト機能を使う

最近個人プロジェクトでExpress x ejsを使っています。
viewファイルを作っていて、当然ですけど絶対レイアウト機能を使ったほうが修正も楽だろうと思って調べました。

* express v4.16.3
* ejs v2.5.9

## レイアウト機能使用に必要なもの
* [express-ejs-layouts](https://www.npmjs.com/package/express-ejs-layouts)

これだけです

## 手順
### express-ejs-layoutsインストール
```shell
$ yarn add express-ejs-layouts Or npm i express-ejs-layouts --save
```

### app.js修正
app変数作成後に、expressLayoutsをrequire、app.useを実行します。

```javascript:app.js
const app = express();
+ const expressLayouts = require('express-ejs-layouts');
+ app.use(expressLayouts);
```

### layout.ejs作成
ポイントは`<%- body %>`です。このタグ内にejsファイルの中身が展開されます。

```html:views/layout.ejs
<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
    <h1>Layout Page</h1>
    <%- body %>
  </body>
</html>
```

### 個ページごとのejsファイルを作成
```html:views/index.ejs
<h2>index.ejs</h2>
```

## 結果

以下のように表示されました。
<img width="241" alt="ejs-layout.png" src="https://qiita-image-store.s3.amazonaws.com/0/18699/19521b85-ba07-2e11-06be-acb6660d674c.png">


```html:ソースコードを表示
<!DOCTYPE html>
<html>
  <head>
  </head>
  <body>
    <h1>Layout Page</h1>
    <h2>index.ejs</h2>
  </body>
</html>
```

しっかりとlayoutテンプレートが適用されていることが確認できたかと思います。
これで、テンプレートファイルの共通部分（ヘッダー、フッターとか）は一箇所で管理できますね。

ejs本体にレイアウト機能が無いのは意外でした（過去にはあった？）。
とはいえnpm PKG１つ追加でサクッと実現できました。
みなさんの参考になれば幸いです。
Alibaba Cloud Container ServiceのKubernetesサポートについて

# Alibaba Cloud Container Serviceの概要
Alibaba Cloud Container Serviceは、**フルマネージドのクラウドコンテナ管理サービス**です。
ECSインスタンス上のDockerアプリケーションを実行及び管理できます。

Alibaba Cloud Container Serviceは、以下のサービスを備えています。

- クラスターの管理
- Elastic Compute Service(ECS)インスタンスのスケーリングなど
- コンテナライフサイクル管理
- Docker SwarmやDocker Composeとの互換性
- スケジューリングポリシー

アクセス権の設定やアプリケーションのオーケストレーション、標準のDocker APIとの互換性があり、また大規模なコンテナを数秒で起動出来る利点があります。

# Kubernetesの概要
Kubernetes(以下、K8s)は、オープンソースの**コンテナオーケストレーション**ツールです。
現在はCNCF(Cloud Native Computing Foundation)がメインで開発しています。
コンテナ型の仮想環境を利用する際、単体ではなく負荷分散の対応などのため複数台構成(クラスタ環境)にする事があります。
それぞれのコンテナを個別に管理するのは手間がかかり、操作ミスを起こす可能性があります。
この様な課題は、コンテナをまとめて管理(コンテナの監視やネットワークの管理、負荷分散、スケーリングなど)するコンテナオーケストレーションツールを利用することによって改善します。

KubernetesはGCP、AWS、Azureといったクラウドでも利用することが出来ます。

# Alibaba Cloud Container ServiceでのKubernetesについて
Alibaba Cloud上のコンテナアプリを管理するために、Kubernetesクラスタのサポートが提供されています。
10点程ピックアップして紹介します。
##特徴
###1.クラスタの管理
　・コンソール上でK8sクラスタを簡単に作成できる
　・既存のECSインスタンスを追加可能。
　　ただし、ワーカーノードのみ対応。
　・K8sクラスターのワーカーノードの拡張と縮小に対応しています。
　　ただし、マルチAZ K8sクラスタは容量の拡張とスケーリングはサポートしていません。
　　現時点では自動スケーリングはサポートされていないため、手動での操作となります。
　　これ以外にもいくつか制約事項があるので注意が必要です。
　・異なるAZのECSインスタンスを含んだK8sクラスタの作成に対応。
　この他にも基本的なクラスタの管理機能がありますが、まだまだ制約が多いので構築する際は注意が必要です。

###2.ノード管理
　ノードのリストを表示したり監視を行います。

###3.ストレージ管理
　Alibaba Cloud Disk、Alibaba Cloud NAS、Alibaba Cloud OSSといったストレージサービスを自動的にバインドするためのK8s Podをサポートしています。
ただし、Alibaba Cloud OSSの動的データボリュームはサポートされていません。

###4.アプリケーション管理
 ミラーリングやレイアウトテンプレートを利用してアプリケーションを作成することが出来ます。
さらに、ノードのスケジューリングやサービスの表示・更新・削除、コンテナの設定変更なども管理出来ます。

###5.ルート管理
　Webインターフェイス経由でルートを作成したり、変更・削除を行いことが出来ます。

###6.リリース管理
　Helmを利用してアプリケーションの公開状態などを管理します。

###7.ロードバランシング
　Alibaba CloudのServer Load BarancerやIngressを利用することで、内部へのアクセスやロードバランシングがサポートされています。

###8.ログ
　Alibaba Cloud Log Serviceを利用することでK8sクラスタのログを収集することが出来ます。

###9.監視
　リソースをグルーピングし監視を行います。
　ただし、K8sのバージョンが1.8.4以降のみ利用することが可能です。

###10.サーバレスK8sクラスタ
　Alibaba Cloudless Serverless K8sは現在オープンベータ版です。
　一次的に上海地区は利用できますが、他のリージョンは順次展開しています。
　注意点としては、
　　・Serverless K8sクラスタは１つしか作成できない
　　・作成出来るポッドの最大数は5つ
　です。

##注意事項
まだ、サービスとして多くの事はカバー出来ていないため、利用をする際には注意が必要です。

- Kubernetesクラスタが対応しているのは現時点で**Linuxコンテナ**のみ。
- Windowsコンテナは対応していませんが、対応を計画中。

##まとめ
Alibaba Cloud Container ServiceのKubernetesへのサポートは順次拡張されると予想されます。
最近K8sが日本でも盛り上がってきているので、注目のサービスです。
今回は下記の参考サイトをもとに簡易的にまとめました。
詳細を知りたい方は、リンクをたどってみてください。
Alibaba Cloud Helpは中国語のサイトとなっております。(日本語のドキュメントが未対応？のため)

### 参考サイト
[Kubernetes 公式](https://kubernetes.io/)
[Running Kubernetes on Alibaba Cloud](https://kubernetes.io/docs/getting-started-guides/alibaba-cloud/)
[Alibaba Cloud Help](https://help.aliyun.com/document_detail/53751.html)
https://jp.alibabacloud.com/product/container-service#product-details
https://www.slideshare.net/YuyaOhara/30kubernetes-81054893
Javaでのテキストファイル入出力を思い出せないのでまとめてみた

どういうわけか、プロジェクトが変わる毎に、利用するプログラミング言語も変わることが多い。
毎回、テキストファイルの入出力がどうだったか、ググってしまう。
今の現場は、Javaなので、まとめみる！

# 書き込み

```java
List<String> lines = new ArrayList<>();
lines.add(LocalDateTime.now().toString());

final String baseDir = "c:/tmp";
File f = new File(baseDir + "/timestamp.txt");
BufferedWriter bw = new BufferedWriter(new FileWriter(f));
lines.forEach(line -> {
	try {
		bw.write(line);
		bw.newLine();
	} catch (IOException e) {
		e.printStackTrace();
	}
});
bw.close();
```
* 改良版。クロースを書かなくても大丈夫になっている
* 最後にcatchの部分が増えているので、修正前の方が見やすい。
* と言うわけで、改良できていない？！

```java
List<String> lines = new ArrayList<>();
lines.add(LocalDateTime.now().toString());

final String baseDir = "c:/tmp";
File f = new File(baseDir + "/timestamp.txt");
try (BufferedWriter bw = new BufferedWriter(new FileWriter(f));) {
	lines.forEach(line -> {
		try {
			bw.write(line);
			bw.newLine();
		} catch (IOException e) {
			e.printStackTrace();
		}
	});
} catch (IOException e) {
	for (Throwable t : e.getSuppressed()) {
		t.printStackTrace();
	}
}
```

# 読み込み

* ラムダ式内で外部に定義された変数の値は変更できない。
* だが、配列なら書き換えられるというよく分からない仕組みになっている。
* [【参考】ラムダ式で、なぜ外側に定義された配列の値を変更できるのか](https://teratail.com/questions/36426)

```java
final String baseDir = "c:/tmp";
File f = new File(baseDir + "/timestamp.txt");
StringBuffer sb = new StringBuffer();
String[] lineSeparator = { "" };
BufferedReader br = new BufferedReader(new FileReader(f));
br.lines().forEach(line -> {
	sb.append(lineSeparator[0]);
	sb.append(line);
	lineSeparator[0] = System.lineSeparator();
});
br.close();
```

* こちらも改良版を作りました。

```java
final String baseDir = "c:/tmp";
File f = new File(baseDir + "/timestamp.txt");
StringBuffer sb = new StringBuffer();
String[] lineSeparator = { "" };
try (BufferedReader br = new BufferedReader(new FileReader(f));) {
	br.lines().forEach(line -> {
		sb.append(lineSeparator[0]);
		sb.append(line);
		lineSeparator[0] = System.lineSeparator();
	});
} catch (Exception e) {
	e.printStackTrace();
}
```
こだわること・こだわないこと


ネットワーク系研究室に属する4年生が身内に思ったことを書いた記事です．

酔っ払いがノリで書いた記事だけど，これは共有したさと文章化したさがあったので書く．

勉強会後に話をしてたことと，思ってたことをいい感じにまとめようと思う．

これは俺自身が，普段のレポート作成，プログラミング，サーバ管理・構築の作業の際にこだわっていること，こだわってないことを紹介する．

## 大事なこと
- 目的を見失わないこと
例えば，webサーバを立てる時にwebサーバを立てるのが目的であってapacheとかnginxを入れたりするパッケージを入れるのが目的ではない．

- 目的のために建てた道を歩けないように下準備をして挑む
さっきのapacheの例だとubuntuにapacheを入れる方法がわからなければそもそも何も始まらない．サイトのデータをサーバにアップする方法がわからないければ設定できても肝心のコンテンツを上げることができない．


そもそも基礎的なLinuxの使い方がわからないとやりたいことがあっても，違うとこで躓いてしまう．
それってせっかくやりたいことがあっても，そこに行く前に辛くなってしまう．という点がある．

基礎的なLinux力は必要(これから鍛えていけばいいと思う)

### Linux力の鍛え方
#### ガチでやりたい人向け
- 自分のノートパソコンからwindowsを消し去り，Linuxと一緒に生活する(サッカーアニメの主人公がボールと一緒に寝る感じ)

#### ガチまではないけど困らないレベルでやりたい人向け
- [windows subsystem for Linux](https://qiita.com/Brutus/items/f26af71d3cc6f50d1640)をwindowsに入れましょう 

そして普段GUIでやることをCLIでどうやってやるか調べてみてください．
小さなことでもいい．クリックすることをコマンドでやってみるように意識してみる

#### お金ある人
Macを買ってください

## 見えるとか見えないという話
ここで少し前置き的な話

大学に入ってネットワーク・インフラと俺なりに見てきた側面もあるけど，割とソフトウェア開発系の界隈にもいた(今もPerl界隈はお世話になりってます)，

大学3年の時期にいろいろ知り合いができてあることに気づいた．
「見える成果物がない」

散々勉強，体験はしてきた．でも目の前でこんなアプリ，サイトを作りましたと出される．

そういう見えにくい分野にいることに気づくまですこしかかった．

なので承認欲求が強いひとは気をつけましょう

ちなみに今は僕も成果物がある

https://github.com/haw-itn/sls-monitor-py

ご紹介までに


## こだわること
ここでは僕がこだわっているものを紹介する
### エディター
#### レポート作成
文章を書く，これはなにもストレスがない状態でないといけないと思っている．だから文章量が多くなると重たくなるwordは使わない．
でもLatexで書く以上エディタの支援はうけたいのでTexStudioを使っている．

- mac Texpadをおすすめ
- emacs使いの方 YaTexをおすすめ

#### プログラミング
こちらもレポートと同様ストレスがない状態でやりたい．おれはバイトでpythonを嗜んでいるのでpycharmを使っている．

しかしまあそれ以外にshellscriptとかなんとかいろいろ機会はあるのでvimとかemacsとかvscodeみたいなエディタを入れている.

僕はspacemacsを使っている．YAPC::Okinawa(Perlのカンファレンス)のLTでであって，惚れた．

#### 要は何がいいたいか
プロ野球選手がバットやグローブにこだわるように，道具にこだわってみませんか？

先輩とかにも聞いてみるときっとこだわっているツールを教えてくれるとおもう！

個人的にはLinux力を上げたいならvimかemacsを使ってみてはどうでしょうという提案ですね．

もちろんviｍの派生のエディタであるNeovimとかemacsの派生のspacemacsでもいいと思う．


デフォルトならデフォルトにこだわるという手もある．ただいろんなものにいたづらに触れて死ぬよりも一つを極めてみてはどうでしょう．
自分が使うものはしっかり把握してみましょうということが言いたいです．

## こだわないこと
こだわならないのはプログラミング言語です．世の中には「pythonならなんでもできるぜ　俺はすべての問題をpythonで解決してやるぜ！」という人もいる．

しかしインフラ・ネットワーク系にいるというのもあるのかわからんないけど，「おれはすべてをこれぜ解決するぜええ」みたいなのをしなくなった．

じゃあどうやって言語を選ぶというかというと適材適所，環境に最適な言語を選ぶ．という感じです．

文字列処理をじゃんじゃんやりたいからPerl，機械学習だからpython，バイト先はrubyを使っているからrubyという感じに分けれると思う．それに研究でプログラムを触る人もいると思う．

ならその言語に絞って練習したらいいと思います．
あとプログラミング言語は聞ける人がいる言語を選びましょう

俺はいろんなとこに出没しているのもあり，いろいろな言語に触れているけどあんま気にせずに
## やりたいなら
pythonをやりたいひとはslackbotを作るついでに一緒にやりましょう！

もしそれは興味ないけどプログラミングも少しという人がいればPerl界隈に招き入れます．
## git勉強会とAWS勉強会をやるぞ!
日的決めるぞ!
以上
児童見守り安心システム「ツイタもん」を「ツイテないもん」にする

我が子の小学校で、「ツイタもん」が導入されました。

児童見守り安心システム　ツイタもん
https://tsuitamon.jp/

学校の門を通ると、「ツイタもん」とメールが来ます。
今どきなサービスですが、毎日メールが来ると、そのうち気にしなくなりそうです。
そこで、万が一、門を通ってないときだけ「ツイテないもん」と連絡が来る仕組みを考えました。

# 仕組み
仕組みとしては、子供が学校に行くまでの時間に、 **「ツイテないもん」通知を行うスケジュール** を有効にし、「ツイタもん」メールが来たらこの **「ツイテないもん」通知を行うスケジュール** を無効にします。
学校についたら、スケジュールはキャンセルされて通知は実行されず、学校についてなければ、通知スケジュールに従って通知されるわけです。

これをIFTTTとAWSのLambdaやCloudWatch Eventsを組み合わせて実現します。

# 構成

## 全体構成

![ツイテないもん.png](https://qiita-image-store.s3.amazonaws.com/0/41574/2d8fc951-8e42-7637-bb7c-868addfbf786.png)

## 学校についた場合

![ツイテないもん-ついた場合.png](https://qiita-image-store.s3.amazonaws.com/0/41574/eee94b98-0def-b05e-f715-1537da831803.png)

## 学校についてない場合

![ツイテないもん-ついてない場合.png](https://qiita-image-store.s3.amazonaws.com/0/41574/fa8e9710-4932-cde0-b24b-1aaabaeb9194.png)


# Lambdaの処理

## CloudWatch Eventsを無効にするLambda

超適当
CloudWatch Eventsのイベント名は環境変数にセットしました。
無効ではなく有効にする場合は`disable_rule`が`enable_rule`になります。

```python
import os
import boto3

def lambda_handler(event, context):
    # TODO implement
    event_name = os.environ.get("EVENT_NAME")

    client = boto3.client('events')

    response = client.disable_rule(
        Name=event_name
    )

    return response
```

## ツイテないもん通知を行うLambda

超適当

```python
import requests
import os

def lambda_handler(event, context):
    requests.post(os.environ.get("REQUEST_URL"))
    return 'Hello from Lambda'
```
Javaのお勉強 ～その9～ スコープ

# 1. はじめに
変数には、「**スコープ**」と呼ばれる可視範囲があります。
ある範囲では、その変数が使えるが、その範囲外では、その変数が使えないといったものが、スコープです。

基本的に、変数は、宣言された行から { } の間にまでが寿命となり、その外に出てしまえば、使えなくなってしまいます。 
私は、寿命って言葉をよく使います。スコープ寿命

---

<font color="Red">※</font>スコープを意識するのは、制御文を勉強した後からとなりますが、一応基本的なことなので先に記述しておきます。

制御文を一通り終えた後に、またこの「スコープ」を見てもらえると理解が深まるかなと思います。
飛ばしてしまって、また後でこのページに戻ってきてもらうのも構いません。

それでも、一応目を通しておきたいという方は、そのまま読み進めてください。 
それと、今回は説明上、いびつなプログラムになっていますので、真似した書き方はあまりしないと思います。

---

# 2. スコープ
先ほども記述しましたが、スコープには { } の間が寿命となります。

今までのプログラムだと、気にしていなかったはず。

```java:Main.java
public class Main {
	public static void main(String[] args) {

		int test = 100;

		System.out.println(test);

	}
}
```

100を出力しているだけですね！

では、次のプログラムはどうでしょうか？

```java:Main.java
public class Main {
	public static void main(String[] args) {

		int outter = 100;

		{
			int inner = 200;
		} // inner の寿命

		// outter と inner の加算を出力
		System.out.println(outter + inner);

	} // outter の寿命
}

```

エラーになるはず！~~ぶきっちょなソース~~

何故なら inner の寿命が尽きた後に、標準出力に inner を使用しているからです。無いものを使おうとしているわけですね。

コメントで「// inner の寿命」と記載しているところで、inner という変数は寿命が尽き、その外では使うことは出来ません。

---

試しに次のソースは問題なく動くことができます。

```java:Main.java
public class Main {
	public static void main(String[] args) {

		int outter = 100;

		{
			int inner = 200;
			// outter と inner の加算を出力
			System.out.println(outter + inner);

		} // inner の寿命

		// outter の出力
		System.out.println(outter);

	} // outter の寿命
}
```

途中で inner と outter を出力してますね。

捕捉として、outter は、inner が宣言されている { } の間でも使用することは出来ます。

# 3. おわりに
普通は今後使う「制御文」というもの以降の勉強で、スコープを意識するようになります。

今回のようなソースの書き方は普通しません。
ごめんなさい。説明上ぶきっちょな書き方になっています。

とりあえず、

**変数は { } の範囲が寿命**

とだけでも覚えてもらえると嬉しいです！！

以上です！

次回は「if文」について書きます！制御文！
長かったですが、ここからプログラムらしくなっていきます！
楽しくがんばりましょー！


次回 →「[Javaのお勉強 ～その10～ if文](https://qiita.com/koukonko/items/97de6e490fcc0e23cc26)」
Flycheckが~/.flake8を見てくれない対策

Emacsのflycheck(文法チェッカー)がflake8の設定ファイル ~/.flake8 を参照してくれていない(ignoreに指定した項目も警告される)ようなので、対策を調べてみた。

.dir-locals.elをプロジェクトルートディレクトリに置き、以下の内容にする。簡単！

```emacs-lisp:.dir-locals.el
((python-mode . ((flycheck-flake8rc . "~/.flake8"))))
```

----
- 参考リンク:
  - [flake8 checker ignores project-specific configuration](https://github.com/flycheck/flycheck/issues/721)
  - [Qiita: Emacs の Directory Variables でディレクトリ毎に Emacs の設定を自動で切り替える](https://qiita.com/polamjag/items/e913bbaeb49b7efcd0bc)
【新卒～若手向け】プルリクエストでやってほしいこと

中堅に片足入り始めたけど、まだ若手だと思っていたいくらいの人です。

若手じゃなくてもたまにいる「プルリクエストに差分出てるんだからそこ見てよね！」っていう投げやりな人が減ればいいなと思って、自分が気を付けてることと、他の人にもやってほしいことを備忘録。

#説明文に要点をまとめる
大前提の話なんだけど。
色んな要素が関連して、重点的に見てほしい部分は必ずあると思う。
その時に、説明文でもソースコード上でも一言付け足すだけで、レビュアーはまずそこを見てくれる。
言わなければ見られない可能性もある。
レビュアーは人の心が読めるエスパーではないので、言わなければお前の不安な部分なんて知らんってなるから、見てほしい部分は恥ずかしがらずに宣言するのが大切。

#ついでの修正を含めるな
「一覧画面を実装するブランチなのに、削除機能もとりあえず実装しました」
これやる人本当に理解できない。
大体の人がとりあえず実装できないような機能をとりあえず実装してくる。
変更が1ファイルだとしても、機能が違うならプルリクエストは分割するべきである。
新卒の人が「別課題の実装も期限内に実装することが出来たのでレビューお願いします」ってプルリクエスト出して来たら感動する。

#エビデンスをつける
修正内容に対するエビデンスは過剰なくらい添付していいと自分は思っている。
ドキュメントがない現場なら尚更。
エビデンスは相手に納得してもらうものではなくて、自分を守るためと考えると提示する範囲がわかりやすくなる。
自分が意識してやっていることは
・実装前の画面イメージ、バリデーションチェックを課題に記載
・実装する上で前提としている既存仕様の共有
・実装後に実装前の設計と差異が埋まれた部分の記述
・実装したコードの前提とした仕様の記述
このあたりは数行の変更でもやっているし、やるべきだと思っている。
(レビュアーや開発体制でかなり左右されるけど。。。)

レビューしたんだから、お前の責任でしょって言うのもいいけど、それを言う度に信用が落ちて行ってるのをわかってほしい。
穴だらけのものをプルリクエストに出してくる奴はプロジェクトに必要ないと思われる。

#数百、数千のプルリクエストをいきなり出すな
「実装してたらこの差異の行数になりました」
って言う奴、絶対途中でこの行数になるのわかってるだろ。
プルリクエストが肥大化するとわかった瞬間にレビュアーにレビュー単位を確認するべき。
WIPをつけて同じプルリクエスト内でこまめにレビューをしたり、別のプルリクエストにする単位を相談したり、やり方はたくさんあるはず。

これは声を大きくして言いたいけど、
「自分がレビュアーの時にやられて嫌なことはするな」
以上。

#まとめ
他にもたくさんあるけど、適宜追加する。
環境によって違うところが多すぎてなんともいえない部分は多い。
それでも、
「プロジェクトの運用ルールを守る」
＋
「自分の所感を記述する」
これさえやっておけば生きていける。
所感大事。

#雑記
「ローカルでファイルに変更いれてるから、ブランチ切り替えて作業できないです」
って言ってきたおっさん、svnに帰ってくれ。
git stash してくれ。
MacでSeleniumはじめてみる

#Selenium
ブラウザ自動操作ツール
テスト効率化ツールなんて呼ばれてる
cURLを強力にしたものだと思ってる


#SeleniumのAPI利用方法
Seleniumを使うには、python, java,ruby,etc...を用いる
さくっとはじめたかったので、pythonで試してみる

##環境
OS: MacOS High Sierra
言語 : Python 2.7.10

##導入

これだけ！
```
pip install selenium
```

firefoxでgoogleを開くサンプル

``` main.py
# -*- coding: utf-8 -*-
from selenium import webdriver
#firefoxを利用
driver = webdriver.Firefox()
#access to google
driver.get("http://google.com")
#googleの検索窓を取得(後述
element = driver.find_element_by_id( 'lst-ib')
#
element.send_keys("Hello Selenium!")
```

#要素のみつけ方
SeleniumのAPIによると、idや名前で要素を取得できる
https://kurozumi.github.io/selenium-python/locating-elements.html

ちなみにfirefoxで、サイトの調べたい部分を右クリックして「要素を調査」を選択すると
idやnameが取得できるよ

<img width="1280" alt="Screen Shot 2018-06-02 at 23.15.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/94861/40c5d0cf-b8a3-d458-bea7-868168ec4308.png">


#Webのスクレイピングなどに利用してみる予定
AtCoderのサンプルケースのテストを半自動化するUserScriptを作った

# お知らせ
こちらのUserScriptの影響でAtCoderのジャッジサーバーの負荷が増大し、AtCoder社に御迷惑をお掛けしてしまったため、8月13日を以てGreasyForkでの配信を停止させていただきました。既にインストールされているスクリプトも、UserScriptの自動更新機能によって無効化致しました。この度は皆様に御迷惑をおかけし申し訳ありませんでした。

---

AtCoderの問題に書いてあるサンプルケースを自動で検出し、コードテストで簡単に動かせるUserScriptを作りました。
（以前はWandboxで動かしていたのですが、速度や互換性の問題からAtCoderのコードテストに移行しました。使い方は以前と変わっていません）

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">AtCoderのサンプルケースをWandboxでテストするUserScriptを作った <a href="https://t.co/ZTdvGjmy7I">https://t.co/ZTdvGjmy7I</a> <a href="https://t.co/TmmS0mQ6HW">pic.twitter.com/TmmS0mQ6HW</a></p>&mdash; prince (@prince__0203) <a href="https://twitter.com/prince__0203/status/1002917065945071617?ref_src=twsrc%5Etfw">2018年6月2日</a></blockquote>

# インストール方法

1. [TamperMonkey](https://tampermonkey.net/)をブラウザにインストールします。
1. [こちら](https://greasyfork.org/ja/scripts/368836-atcoder-sample-case-tester)からUserScriptをインストールします。

# 制限事項(仕様)

- [ベータ版](https://beta.atcoder.jp/)のAtCoderでしか動作しません。
- 古いコンテストでは動作しません(Practice Contestなど)
- インタラクティブ問題では正常に動作しません。
- 相対誤差の判定はできません。
- AtCoderの仕様変更により動作しなくなることがあります。

# ソースコード

[GitHub:prince0203/atcoder-sample-case-tester](https://github.com/prince0203/atcoder-sample-case-tester)

# 技術的な話

- async/await, fetchなどのJavaScriptの最新仕様をいくつか取り入れてみました。
- モジュールバンドラに[Rollup.js](https://rollupjs.org/)を採用しました。非常に読みやすいコードが出力されるので、UserScriptに最適です。コンフィグも[このように](https://github.com/prince0203/atcoder-sample-case-tester/blob/master/rollup.config.js)非常に簡潔に書けます。
- DOM操作にはAtCoderで使われているjQuery 1.9.1(!)をそのまま流用しています。
【Python】Qiitaの最新記事をスクレイピングしてHTML１ページの中に一覧表示してみた

###【概要】
Qiitaの[最新記事](https://qiita.com/items)を見るのが好きなのですが、1ページに20件しか表示されずページ移動が面倒でありました。
そのため、記事一覧を1ページで閲覧できるようなHTMLをスクレイピングを使用して作成してみました。


###【環境】
・windows8.1
・python3.6

###【コード】
```python
# -*- coding: utf-8 -*-
import os
import requests
from bs4 import BeautifulSoup

HTML_FILE = 'C:/Users/nobu/Desktop/qiitaScraping.html'
CSS_FILE = 'C:/Users/nobu/Desktop/qiitaScraping.css'
QIITA_URL = 'https://qiita.com/items/?page='

# CSS作成
if not os.path.exists(CSS_FILE) :
    cssFile = open(CSS_FILE, 'w', encoding='utf-8')
    cssFile.write('''
        .square_btn{
            position: relative;
            display: inline-block;
            font-weight: bold;
            padding: 0.25em 0.5em;
            text-decoration: none;
            color: black;
            background: #FFABCE;
            transition: .4s;
          }
        
        .square_btn:hover {
            background: #00bcd4;
            color: white;
        }
        
        a > img { width: 20px;
                  height: 20px;
                  max-width:100%;
                  max-height:100%;
                  }
    ''')
    cssFile.close

if os.path.exists(HTML_FILE) :
    os.remove(HTML_FILE)

# HTML作成
htmlFile = open(HTML_FILE, 'a', encoding='utf-8')
htmlFile.write('''
    <!DOCTYPE html>
    <html lang="ja">
    <head>
        <meta charset="UTF-8">
        <title>Qiita記事一覧</title>
        <link rel="stylesheet" type="text/css" href="qiitaScraping.css">
    </head>
    <body>
''')

# スクレイピング
for pageNum in range(1, 6) :
    result = requests.get(QIITA_URL + str(pageNum))
    content = result.content
    soup = BeautifulSoup(content, 'lxml')
    # ユーザ画像取得
    userList = soup.find_all('a', 'media__image')
    # 記事のタイトル取得
    titleList = soup.find_all('a', 'u-link-no-underline')
    
    # 装飾用にclass属性を追加する
    for (title) in titleList :
        title['class'] = "square_btn"
    
    for (user, title) in zip(userList, titleList) :
        userStrReplace = str(user).replace('href="', 'href="http://qiita.com')
        titleStrReplace = str(title).replace('href="', 'href="http://qiita.com')
        htmlFile.write(userStrReplace + '\n')
        htmlFile.write(titleStrReplace + '\n')
        htmlFile.write('<br><br>')
    
htmlFile.write('''
    </body>
    </html>
''')
htmlFile.close
```

###【実行結果】
qiitaScraping.html, qiitaScraping.cssがデスクトップに作成され、開いてみると以下の画像のようになっています（2018年6月2日 22:56時点）。
Qiita最新記事の1ページ目から5ページ目をスクレイピングしているため、100件(20件 × 5ページ)の記事が1ページのHTMLの中に収まっています（画像では途中までをキャプチャしてます）。
もちろん、ユーザのサムネイル画像・記事タイトル名をクリックするとQiitaのURLへ飛ぶようになっています。

![記事一覧.png](https://qiita-image-store.s3.amazonaws.com/0/121997/fa94530b-15a6-300d-9967-f2b44a0993c5.png)

###【参考サイト】
・[記事タイトルのCSS](https://saruwakakun.com/html-css/reference/buttons)
　　→　「2. フラットデザインなボタン」の一番最初のシンプルを参考にしました。
UNIX V6 on PDP-11をMacで動かす

まず、歴史的コンピュータのシミュレータである[simh](http://simh.trailing-edge.com/)をインストールする:

```sh
$ brew install simh
```

これで`pdp11`などのシミュレータを起動するコマンドが使用可能となる。

続いて、UNIX V6のディスクイメージを取得し、展開する:

```sh
$ wget http://simh.trailing-edge.com/kits/uv6swre.zip
$ unzip uv6swre.zip
$ cd uv6swre
```
展開したディレクトリに、任意の名前で設定ファイルを作成する:

```sh
$ vim pdp11.ini
$ cat pdp11.ini
set cpu 11/40
set cpu u18
att rk0 unix0_v6_rk.dsk
att rk1 unix1_v6_rk.dsk
att rk2 unix2_v6_rk.dsk
att rk3 unix3_v6_rk.dsk
boot rk0
```

これで準備は整った。次のコマンドでシミュレータを起動する:

```sh
$ pdp11 pdp11.ini

PDP-11 simulator V3.9-0
Disabling XQ
@
```

`@`以下には`unix`と、ログインユーザは`root`と入力する:

```
@unix

login: root
# pwd
/
# ls -l
total 182
drwxr-xr-x  2 bin      1040 Jan  1  1970 bin
drwxr-xr-x  2 bin       352 Jan  1  1970 dev
drwxr-xr-x  2 bin       304 Aug 20 12:19 etc
drwxr-xr-x  2 bin       336 Jan  1  1970 lib
drwxr-xr-x 17 bin       272 Jan  1  1970 mnt
drwxr-xr-x  2 bin        32 Jan  1  1970 mnt2
-rw-rw-rw-  1 root    28472 Aug 20 12:01 rkunix
-rwxr-xr-x  1 bin     28636 Aug 20 11:38 rkunix.40
drwxrwxrwx  2 bin       144 Aug 20 12:14 tmp
-rwxr-xr-x  1 bin     28472 Aug 20 12:01 unix
drwxr-xr-x 13 bin       224 Aug 20 12:22 usr
drwxr-xr-x  2 bin        32 Jan  1  1970 usr2
```

UNIX V6を終了するには、`sync`を三回入力し、`<ctrl-e>`とする。

```
# sync
# sync
# sync
# <ctrl-e>
Simulation stopped, PC: 021630 (MOV (SP)+,177776)
```

最後に、シミュレータを終了するには、`quit`と入力する:

```
sim> quit
Goodbye
$
```
TDD Motivation Pokerを作ってみた

# TDD Motivation Pokerを作るモチベーション

自分が思っているテスト駆動開発をやる理由（メリットを感じる部分）の認識と、他の人は違っているかもしれない。
その違いを話し合うには、どのようにしたらよいだろう？

ということで、
Management3.0のMoving Motivatorsを活用しようかとしていたところ、
どうせならTDDの良さをカードにしてTDD Motivation Pokerにしてはどうかと思いついた。

# Moving Motivatorsとは？

Management3.0のツールの一つで、他人とのモチベーションの違いを認識し、
お互いの違いを認め合うのが Moving Motivators と そのカード Motivation Pokerだ。

詳しくは、以下を見てもらいたいと思う。
http://nuworks.jp/ja/2016/10/26/moving-motivators/

# 使い方＆カードの内容

![TDDMotivationPokerPhoto.jpg](https://qiita-image-store.s3.amazonaws.com/0/73918/ceb5240c-4f07-0ca4-8a6d-07b47c25d016.jpeg)

基本的に、Moving Motivatorsと同じ。
1. それぞれ、11枚のTDDのモチベーションのカードからベスト3を選ぶ。
2. グループ全員に自分のベスト3に選んだモチベーションを紹介して、一つずつ理由とともに述べる。理由は、自分の経験でもいいし、TDDに期待していることでもOK。

カードの内容は、以下の通り。
1. Psychological safety(安心感が得られる)
2. A lot of code(たくさんのコードが書ける)
3. Cost reduction by regression test(回帰テストのコスト削減ができる)
4. Simple Design(シンプルな設計を実現できる)
5. Reduce debugging time(デバッグの時間が短くなる)
6. Less Bugs(バグが減る)
7. Maintained document(最新の挙動を反映したドキュメントが手に入る)
8. Courage to refactor(リファクタリングする勇気が起きる)
9. Clear specification(曖昧な仕様を排除できる(要件への理解が早まる))
10. Quick feedback(素早いフィードバックが得られる)
11. Other(その他)

Motivation Pokerは10枚だが、TDD Motivation Pokerは11枚目に「その他」を用意した。
10個以外に思いつくモチベーションがあれば、それを語るもいい。

# 実際にやってみた

実際にやってみたところ、それぞれ選ぶカードは人それぞれ。
Otherのカードも出て、「コミュニケーションがとりやすくなる」、「達成感が得られる」という意見も出た。
カードは依存関係のあるものもあるので、ほんとはMECEにしたいところ。
今後、バージョンアップする機会があれば、いろんな意見を入れられるようにしてみたい。

# カードのダウンロード

こちらから無料でダウンロードできます。
A4の厚紙用紙に印刷して使えます。
https://github.com/tokudiro/tdd_motivationpoker

使った方は、よければ感想をコメントまで。
また、元となった Management3.0ついては、http://management30.jp からご覧いただけます。

# 謝辞

NüWorksのステファンさん、公開することを快く許可いただきありがとうございました。
TypeScriptで関数の好きな位置の引数の型を取る

## 前提

* typescript@^2.8 ([Type inference in conditional types](https://github.com/Microsoft/TypeScript/pull/21496))

---

```typescript
interface SomethingObject {
  aA: string;
  bB: string;
  cC: string;
  dD: string;
  eE: string;
  fF: string;
}

function convertCamelcaseKey(obj: {
  a_a: string;
  b_b: string;
  c_c: string;
  d_d: string;
  e_e: string;
  f_f: string;
}) {
  // ...変換処理...
  return {} as SomethingObject;
}

// [ts] Property 'f_f' is missing in type
const snakecaseKeySomethingObject: typeof convertCamelcaseKey extends ((
  obj: infer O
) => SomethingObject)
  ? O
  : any = {
  a_a: 'a_a',
  b_b: 'b_b',
  c_c: 'c_c',
  d_d: 'd_d',
  e_e: 'e_e',
  f_f: 'f_f'
};

// convertCamelcaseKey(snakecaseKeySomethingObject);
```

取りたい引数の型の部分を`infer T`とするだけです。上記では、`infer T`の部分を`any`と考えて、`extends`の左を右にキャストできるので、`convertCamelcaseKey`第一引数の`typeof obj`となります。

```typescript
// typeof convertCamelcaseKey;
// (obj: {
//   a_a: string;
//   b_b: string;
//   c_c: string;
//   d_d: string;
//   e_e: string;
//   f_f: string;
// }) => SomethingObject

// 下ができるかどうか
convertCamelcaseKey as ((obj: any) => SomethingObject);
```



僕的には1、２回しか使わないような`interface`をわざわざ定義するか悩むこと多いです（英語力的に）ので、まぁプロパティが多くてサジェストはほしいぜって時にいいなと思います。

戻り値の型を使いたいなら`ReturnType`という超便利なものがあるのでこっち使いましょう。

何度も使うなら`ReturnType`を真似て

```typescript
type FirstArg<F extends Function> = F extends (arg: infer T) => any ? T : never;
```

としちゃうのもいいかもですね。
メソッド参照とラムダ式、どちらが速いのか

# はじめに

よく、次のようなコードを目にします。

```java
employees.stream().map(e -> e.getName()).collect(Collectors.toList());
```

`employees` というリストの要素をすべて名前に変換したリストを作成するコード。
ごく普通のコードですが、ラムダ式ってインナークラスみたいなものだから、オーバーヘッドがあるのではないか？
こんなgetterを呼ぶだけのものであれば、

```java
employees.stream().map(Employee::getName).collect(Collectors.toList());
```

の方が速いんではないか？

と思って、確かめるべく、計測してみました。
（ちょっと古いが、 Oracle JDK 1.8u131で計測しました。）

# メソッド参照か、ラムダ式か

## ベンチマーク

[JMH](http://openjdk.java.net/projects/code-tools/jmh/)を使って、それぞれのコードの1秒あたりの実行回数（スループット）を計測してみました。

```java
public class PerformanceMethods {
    /** 10000個の要素を生成 */
    private static final List<Employee> employees = IntStream.range(0, 10000)
            .mapToObj(i -> new Employee(i, "name" + i))
            .collect(Collectors.toList());

    @Benchmark
    public void useReference() {
        employees.stream().map(Employee::getName).collect(Collectors.toList());
    }

    @Benchmark
    public void useLambda() {
        employees.stream().map(e -> e.getName()).collect(Collectors.toList());
    }
}
```

結果は・・・

    Benchmark                         Mode  Cnt     Score     Error  Units
    PerformanceMethods.useLambda     thrpt    5  5842.820 ±  65.662  ops/s
    PerformanceMethods.useReference  thrpt    5  5762.353 ± 343.302  ops/s

Scoreが大きいほど処理速度が速いのですが、結果はほとんど変わらず。
繰り返し実行するなら、どちらでもよい、ということになります。

ちなみに、参考として、ラムダ式の実行の仕組みが書かれた資料を貼っておきます。
https://www.slideshare.net/miyakawataku/lambda-meets-invokedynamic

通常、インナークラスを作るとコンパイル時にクラスファイルが生成されますが（「$」付きのクラス）、ラムダ式は実行時に初期化されるため、起動が速くなるようです。
逆に取ると、ラムダ式を実行する最初のタイミングのみ、初期化が行われる分だけ遅くなる、ということになります。

気にするほどでもないと思いますが、個人的にはすっきりしているメソッド参照を使用したいと思います。

# ラムダ式1回か、map2回か

他人が作ったコードのレビューをしていると、こんなコードを見かけました。

```java
employees.stream().map(Employee::getAddress).map(Address::getPostalCode).collect(Collectors.toList());
```

ネストしたエンティティの値のリストを作るときに、 `map` を2回使って変換する方法を初めて見ました。。

確かに「個人的にはすっきりしているメソッド参照を使用したい」とは書きましたが、さすがに `map` 2回は効率が悪いのではないか・・・？

ということで、ラムダ式1つで `map` 1回で書く場合と、メソッド参照で `map` 2回で書く場合のパフォーマンスを計測してみました。

## ベンチマーク

```java
public class PerformanceMethods {
    private static final List<Employee> employees = IntStream.range(0, 10000)
            .mapToObj(i -> new Employee(i, "name" + i, new Address("code" + i)))
            .collect(Collectors.toList());

    @Benchmark
    public void mapOnce() {
        employees.stream()
                 .map(e -> e.getAddress().getCode())
                 .collect(Collectors.toList());
    }

    @Benchmark
    public void mapTwice() {
        employees.stream()
                 .map(Employee::getAddress)
                 .map(Address::getCode)
                 .collect(Collectors.toList());
    }
}
```

結果は・・・

    Benchmark                     Mode  Cnt     Score      Error  Units
    PerformanceMethods.mapOnce   thrpt    5  6340.454 ± 1291.055  ops/s
    PerformanceMethods.mapTwice  thrpt    5  5487.546 ±  488.373  ops/s

ラムダ式（ `mapOnce` ）の方のError（処理時間のばらつき）の範囲が大きいのは気になりますが、やはり `map` 1回の方が速いことが分かりました。

`map` 1回でラムダ式を書いた方が分かりやすいし。。

# 結論

- メソッド参照とラムダ式で速度の差はほとんどなし。ただし、ラムダ式は実行時に初期化されるため、最初だけ少しオーバーヘッドあり。
- `map` 2回でメソッド参照を用いて値を取るよりも、`map` 1回でラムダ式を使って書いた方が速い。そして、読みやすい。