OmniAICreator/Qiita-1.07M huggingface dataset:
[Excel]AccessのテーブルをExcelに連携する。SQLで絞り込む。

Office365 BusinessでもAccessが使えるようになったのでエクセルで管理していたデータをAccessに移行しました。
Accessはあまり触れてこなかったので簡単な内容ではありますがデータ接続の方法をメモします。※Office2016でしか試してません。

# やりたいこと

↓Accessのデータを
![10.png](https://qiita-image-store.s3.amazonaws.com/0/97601/385ea7a9-23f7-e81e-75c1-fcb3a116d416.png)

↓Excelで表示します。
![11.png](https://qiita-image-store.s3.amazonaws.com/0/97601/e1081a1e-c8ef-556d-78e5-e371f6876bb0.png)


# やったこと
データタブのAccessデータベース接続からデフォルト設定で接続しました。

![13.png](https://qiita-image-store.s3.amazonaws.com/0/97601/2f1c315b-dd6b-d48d-3517-7c1c514ebbf2.png)

これでできました。思った以上に簡単でした。

![11 - コピー.png](https://qiita-image-store.s3.amazonaws.com/0/97601/2b1a4f12-ad0b-2a8d-8348-135a875fdb29.png)

## ついでに
折角なので再取得ボタン用のマクロを作成しようと思います。
テーブル名を「Users」に変更して下記コードをボタンに登録します。

```js:sample
Sub Sample()
    ThisWorkbook.Worksheets("Sheet1").ListObjects("Users").Refresh   
End Sub
```
データを再取得できました。簡単すぎます。

## SQLも書いてみる。
[データ]-[接続]-[ブックの接続]で名前を確認します。
![12.png](https://qiita-image-store.s3.amazonaws.com/0/97601/103ccd0b-3c92-1612-dc69-f305e65afbf2.png)

Databese1でしたのでConnectionsから接続文字列を変更します。

```js:sample
Sub Sample()
    Dim sql As String
    sql = "SELECT FamilyName, FirstName FROM users WHERE Age >= 20"
    ThisWorkbook.Connections("Database1").OLEDBConnection.CommandText = sql

    ThisWorkbook.Worksheets("Sheet1").ListObjects("Users").Refresh    
End Sub

```

![15.png](https://qiita-image-store.s3.amazonaws.com/0/97601/9a038d77-5917-4f69-2b95-266b3f120758.png)


絞り込まめました。
もっと、こう、ForでまわしてRangeを指定してセルにセットして・・・、なんてことを考えていましたが予想以上に簡単でした。

## そのほか
Accessを立ち上げていたり、Excel起動時にAccessを立ち上げたりすると共有エラーが出ることがありました。
ただこれは、デフォルトの接続設定ではアクセス許可が「Share Deny Write」になっていたためでした。
ReadやReadWrite、Share Deny Noneにすると解消されました。

![3.png](https://qiita-image-store.s3.amazonaws.com/0/97601/2f27a554-e76b-6c8a-280b-5bc00f7b69ea.png)
[LT] ソースフォーマットをカスタマイズする方法

> チーム全体、毎週金曜日の朝、一人３分 LT をやっています。忘れないように、また日本語の勉強もしたいと思います、記事として記録します。

## Xcode にエクステンションを導入

Xcode で Objective-C を例にする。個人的には手動フォーマットを慣れた、余計な時間にならない気がする（笑。しかし、チームでみんな同じフォーマットで書くを要求するのがひどくない？もしツールで同じフォーマットを適応すると、楽になるかもしれない。

Xcode 8 にアップデートする前、[ ClangFormat プラグイン](https://github.com/travisjeffery/ClangFormat-Xcode) というツールは使いやすいですが、多分 XcodeGhost の影響で、Xcode 8 から 3rd party プラグインが禁止された。

同時に、**Xcode Source Editor Extension** という案が出てくる。簡単に言いうと、編集中のテクストを取って、いろいろな処理を行って、また書き戻すみたい。安全性は高くなるけど、実現できる機能は以前よりけっこう少なくなる。

幸いなことは、ソースフォーマットはエクステンションでも実現できる。ここで [XcodeClangFormat](https://github.com/mapbox/XcodeClangFormat) を紹介しようと思う、五つの **Clang Format** スタイルをサポートの上、カスタマイズもできる。

<img width="600" alt="setting2.png" src="https://qiita-image-store.s3.amazonaws.com/0/140059/3d55373d-9805-a808-0879-86dcb94b37c9.png">

リリースからツールの最新版をダウンロード、一度起動する。その後、システム環境設定より、機能拡張を開いて、下のようなチェックをつける。

<img width="600" alt="setting.png" src="https://qiita-image-store.s3.amazonaws.com/0/140059/30bfb1c1-6037-5f4a-e14b-cd21f3871eb1.png">

そして、提供しているスタイルはもう使えるようになる：

<img width="400" alt="スクリーンショット_2017-03-24_23_47_08.png" src="https://qiita-image-store.s3.amazonaws.com/0/140059/82c42af3-b6bf-1d5b-1b3e-d969c10d8410.png">



## .clang-format をカスタマイズ

しかし、もし全てのスタイルは自分の要求に応えなければ、どうしたらいいですか？:sweat_smile:

新しいスタイルを定義しましょう！フォーマットファイルの拡張子は .clang-format、ファイル自体は YAML スタイルです、書き方は理解しやすい。まず [Clang Format Style](https://clang.llvm.org/docs/ClangFormatStyleOptions.html) を参考して、使いたいオプションの意味を理解してみる。既存の .clang-format、ファイルをベースにして編集するのはもっと理解しやすいかもしれない。

今私は [.clang-format](https://gist.github.com/Ckitakishi/dd8baa945af268fa6f80a9a6a963854b) を編集している。:no_mouth:
【初心者投稿-9】htmlとPHPを並行で学習する

#昨日までのおさらい
挫折
実際に一からコードを書くことはまだまだ道が遠い。
特に自分のコードのどこがダメなのか探して、正しいコードに書き換えるところがハードル

#今後の学習について
今日、エンジニアの友達と話したところ、「PHPとhtmlを並行で学習することでPHPを学びながらにhtmlも包括的に学べるのでは」と言われたため、明日からはPHP初級編も始めていこうと思う。

あとは、友達が作っているウェブサイトの最初のページを実戦も兼ねて作ることに…
エンジニア歴１週間でどこまで出来るか、こうご期待！

#学習の記録
* Progate7日目
* 今日の勉強時間：20分
* 総学習時間：7時間30分
* 今日学んだこと：cssの要素があまりにも多すぎる！これ使うの？っていう。字にアンダーバーを引くだけでborder-bottomとか…どうやらエンジニアから言わせるとそこが"こだわり"のようだ。
ズンドコキヨシ(ズンドコチェック)

巷で流行っているというズンドコキヨシ(ズンドコチェック)をやってみました
普通にやっては面白くないのでCSSメインで挑戦

# コード
```html:zundoko.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <title>ずんどこ</title>
  <style>
    #list {
      width: 300px;
      list-style: none;
      line-height: 25px;
      margin: 50px auto;
    }
    .zun:before {
      content: 'ズン';
    }
    .doko:before {
      content: 'ドコ';
    }
    .zun+.zun+.zun+.zun+.doko+ *:before {
      font-size: 25px;
      content: 'キ・ヨ・シ' !important;
    }
    .zun+.zun+.zun+.zun+.doko+ *:after {
      font-size: 25px;
      content: '！' !important;
    }
    #list > *:nth-last-child(-n+6):before {
      font-weight: bold;
    }
    #list > *:nth-last-child(-n+6):after {
      content: '♪';
    };
  </style>
</head>
<body>
  <ul id="list" />
  <script>
    const css = ['zun', 'doko'];
    do {
      const li = document.createElement('li');
      const wk = parseInt(Math.random()*100 % 2);
      li.classList.add(css[wk]);
      list.appendChild(li);
    } while (!document.querySelector('.zun+.zun+.zun+.zun+.doko+*'));
  </script>
</body>
</html>
```
動くやつはこちらhttps://codepen.io/taqm/pen/yMEjRv

疑似要素とCSS3のセレクタでなんとか実現できました。
絞めの部分はいろいろと装飾するようにする徹底ぶりです。

# まとめ
いい感じでした！
そのうちアニメーションもつけたい
GoogleスプレッドシートAPI(v4)のクイックスタートのサンプルプログラムを削れるだけ削ってみる

※Windowsのpython3.6.0で動作確認

GoogleDriveのスプレッドシートのファイルをpythonで読み出したいけど、Googleのサンプルなにやってるのかわかんねーよ、とりあえず読みたいんだよ、という人向け。

元ネタ
https://developers.google.com/sheets/api/quickstart/python
まずはSTEP2まで頑張ってください。

それではSTEP3のプログラムの部分です

```python
# coding:utf-8
import httplib2

import apiclient
import oauth2client

# 設定
# -----------------------------------------------------------------------------
SCOPES = 'https://www.googleapis.com/auth/spreadsheets.readonly'  # 読み込み許可を求める
APPLICATION_NAME = 'read sample'  # 日本語通らないので英文字のみで

SHEET_ID = 'スプレッドシートのファイルID。ファイル編集時のURLから拾える'
SHEET_TAB = 'スプレッドシート内のシート名'
RANGE = 'A1:Z1000'  # 読み込む範囲
# -----------------------------------------------------------------------------


# 認証ファイルの読み込み
store = oauth2client.file.Storage("./credential.json")  # 認証ファイルある？
credentials = store.get()

# 未認証だった場合は許可を求める(ブラウザ認証)
if not credentials or credentials.invalid:
    flow = oauth2client.client.flow_from_clientsecrets('client_secret.json', SCOPES)
    flow.user_agent = APPLICATION_NAME

    # 初回認証
    import argparse
    args = '--auth_host_name localhost --logging_level INFO --noauth_local_webserver'
    flags = argparse.ArgumentParser(parents=[oauth2client.tools.argparser]).parse_args(args.split())

    credentials = oauth2client.tools.run_flow(flow, store, flags)  # ブラウザ認証で許可すると認証ファイルが作成される

# 認証ファイルを使って接続
http = credentials.authorize(httplib2.Http())

# シートの読み込み
service = apiclient.discovery.build('sheets', 'v4', http=http, discoveryServiceUrl='https://sheets.googleapis.com/$discovery/rest?version=v4')
values = service.spreadsheets().values().get(spreadsheetId=SHEET_ID, range=SHEET_TAB+'!'+RANGE).execute().get('values', [])

# valuesを使って色々やれるよ
print(values)
```

エラー処理とかは各自追記してくだせぇ_(:3」∠)_


#おまけ
スプレッドシートの中のシートを全部読みたいときは、SHEET_TABを固定値じゃなくメタデータのシートのリストから取得すると便利です。

```python
# シートの読み込み
# サービスの取得は一緒
service = apiclient.discovery.build('sheets', 'v4', http=http, discoveryServiceUrl='https://sheets.googleapis.com/$discovery/rest?version=v4')

# valuesを読み込む前に、シートの名前を取得する
sheet_meta = service.spreadsheets().get(spreadsheetId=SHEET_ID).execute()
for sheet in sheet_meta.get('sheets', ''):
    # sheet名取得
    SHEET_TAB = sheet.get("properties", {}).get("title", 0)

    # ここも一緒(直前でSHEET_TAB上書きしてる)
    values = service.spreadsheets().values().get(spreadsheetId=SHEET_ID, range=SHEET_TAB+'!'+RANGE).execute().get('values', [])

    # valuesを使って色々やれるよ
    print(values)
```
勤務シフト表の作成1(1)【GLPK】

[__<--目次へ__](https://qiita.com/ki073/items/508b3c20eb03078703dd)



勤務シフト表の作成1(1) (基礎編) ←ここ [(2)](https://qiita.com/ki073/items/1a7b92e2e764ee8a4355)　[(3)](https://qiita.com/ki073/items/119edcc7fab2491892d2)　[(4)](https://qiita.com/ki073/items/28abdfc5733997538dc8)
[勤務シフト表の作成2](https://qiita.com/ki073/items/d45cd648e0625c488ee6) (2日連続して勤務する場合の勤務シフト)

# マニュアルなど
GLPKに同梱されているマニュアル(gmpl.pdf)に詳しく書かれていますが、いきなり読んでも分かりにくいと思います。
[GLPKスーパー簡易マニュアル](http://pse.web.nitech.ac.jp/doc/easymanual.pdf)
[GLPKでのペンシルパズル(ナンリンなど)攻略法](http://www21.tok2.com/home/kainaga11/glpk/glpk.htm)
などが参考になりそうです。
## 勤務シフト表作成
まず簡単な例を書いておきます。

```glpk:shift1.model
# version 0.1
# シフト表作成
param firstDate; # 期間の最初の日付
param endDate;   # 最後の日付
set Date := firstDate..endDate; # 期間内の日付
set TimeSlot := {"朝", "夕", "夜"}; # シフト時間枠
set Staff; # スタッフ名
param maxWorkingDays{Staff}; # 各スタッフの最大勤務日数
# 日付,シフト時間枠,スタッフの配列を確保、出勤の割り当ては1が入る
var assignShiftSchedule{Date, TimeSlot, Staff} binary;

# シフト時間枠に必ず1人従事
s.t. keepStaffInTimeSlot{d in Date, t in TimeSlot}: sum{s in Staff}assignShiftSchedule[d,t,s]==1;
# 出勤は1日1回以下
s.t. avoidShiftPatten1{s in Staff, d in Date}: sum{t in TimeSlot}assignShiftSchedule[d,t,s]<=1;
# 最大勤務日数で制限
s.t. restrictMaxWorkDays{s in Staff}: sum{d in Date, t in TimeSlot}assignShiftSchedule[d,t,s]<=maxWorkingDays[s];

solve;
# 出力
for{d in Date}{
    printf "%2d ", d;
    for{t in TimeSlot}{
        printf{s in Staff : assignShiftSchedule[d,t,s]==1}" %s", s;
    }
    printf "\n";
}

data;
# 期間の最初の日付と最後の日付
param firstDate:=1; 
param endDate  :=12;
# スタッフ名と最大勤務日数
param : Staff : maxWorkingDays :=
"A"  9
"B"  9
"C"  9
"D"  9
;
```

## 制約条件の追加
### 休みを定期的に
上のプログラムでは休みが不規則に入ってします。ちょっと使いたくないですねえ。
それでは定期的に休みが入るようにします。ここでは連続した勤務は3日以内に制限する場合を考えてみます。
GLPKなどの整数計画法のソルバーはvarで指定した変数を足し算や引き算で制限を加えています。
4日連続したどの期間においても3日以下しか勤務しない条件を加えると実現できます。式にすると
`s.t. keepOffDay{s in Staff, d in firstDate..endDate-3}: sum{t in TimeSlot}(assignShiftSchedule[d,t,s]+assignShiftSchedule[d+1,t,s]+assignShiftSchedule[d+2,t,s]+assignShiftSchedule[d+3,t,s])<=3;`
になります。solveの前に挿入すると制限が追加されます。

### 翌日の勤務時間帯の制限
次に、"夕"や"夜"勤務の後に翌日の"朝"の勤務にならない条件を加えてみます。
`s.t. avoidShiftPatten2{s in Staff, d in firstDate..endDate-1}: assignShiftSchedule[d,"夕",s]+assignShiftSchedule[d,"夜",s]+assignShiftSchedule[d+1,"朝",s]<=1;`
さらに"夜"の勤務の後に翌日の"朝"や"夕"の勤務にならない条件も
`s.t. avoidShiftPatten3{s in Staff, d in firstDate..endDate-1}: assignShiftSchedule[d,"夜",s]+assignShiftSchedule[d+1,"朝",s]+assignShiftSchedule[d+1,"夕",s]<=1;`
これで少しはマシになってきたような。

### スタッフの出勤時間帯の指定
例えば1日の朝にAが出勤するように指定するには
`s.t. fix01: assignShiftSchedule[1,"朝","A"]=1;`
のように強引に制約条件を追加することで実現できます。
逆に出勤できない場合には
`s.t. fix11: assignShiftSchedule[2,"朝","A"]=0;`
のようにその時間を0にする制約条件を追加すればできるのですが、美しくないですねえ。

[GLPKによる勤務シフト表の作成1(2)](http://qiita.com/ki073/items/1a7b92e2e764ee8a4355)->
【Androidライブラリ】アニメーションしながら自動で折り返すViewを作りました - AnimationWrapLayout

# 概要
この記事では、Androidの自作ライブラリを紹介させていただきます:grinning:
ソースは[AnimationWrapLayout(GitHub)](https://github.com/sjnyag/AnimationWrapLayout)で公開しています。
サンプルコードもあるので詳しくはリポジトリを確認して下さい。

# 何ができるか
* Viewを横に並べて、画面からはみ出しそうになったら自動で折り返すことができます。
* LayoutにViewを追加する際にアニメーションしながら追加できます。
* LayoutからViewを削除する際にアニメーションしながら削除できます。
* アニメーションはカスタマイズできます。

![same_size.gif](https://qiita-image-store.s3.amazonaws.com/0/107434/31864c35-4045-39f2-33fc-32b02a536acc.gif)
![random_size.gif](https://qiita-image-store.s3.amazonaws.com/0/107434/cd3312cb-a8ec-712b-388c-8bbe27a40a08.gif)


# 使い方
#### 1. ``AnimationWrapLayout`` をdependencyに追加します。
```groovy:build.gradle(Project)
allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}
```

```groovy:build.gradle(Module)
dependencies {
        compile 'com.github.sjnyag:AnimationWrapLayout:0.1.0'
}
```

#### 2. ``AnimationWrapLayout`` をレイアウトに追加します。

```xml
    <com.github.sjnyag.AnimationWrapLayout
        android:id="@+id/list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:padding="8dp"
        animation_wrap_layout:each_margin_height="4dp"
        animation_wrap_layout:each_margin_width="4dp" />
```

#### 3. Viewを追加・削除するコードを書きます。

* 任意のタイミングで``addViewWithAnimation(View view, int position)``や``removeViewWithAnimation(View view)``を実行して下さい。

```java
        AnimationWrapLayout list = (AnimationWrapLayout) findViewById(R.id.list);
        findViewById(R.id.button1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mList.addViewWithAnimation(yourView, position);
            }
        });
        findViewById(R.id.button2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mList.removeViewWithAnimation(yourView)
            }
        });
```

* アニメーションさせたくない場合は``ViewGroup``の要領で``addView``や``removeView``を実行して下さい。
* あらかじめViewをレイアウトファイルに配置することもできます。


# おわりに
DroidKaigi2017のセッションを聴いて、アニメーションを書きたいな！というモチベーションが高まり、今回のViewを作成しようと思いました。刺激にもなったし、開発のモチベーションやAndroidへの愛が深まるとてもいいイベントでした。ありがとうございました。

[google/flexbox-layout: Flexbox for Android](https://github.com/google/flexbox-layout)でも自動折り返しはできそうですが、アニメーションを伴いたい場合は当ライブラリを考慮に入れていただけると嬉しいです:relaxed:
Selenium WebDriver 各Locatorのパフォーマンス

#Locatorパフォーマンスの重要性
初めての投稿になります。
さて、E2Eテストでは、各要素に頻繁にアクセスすることになるため、そのパフォーマンスはテストに要する時間に直接影響を与えるものです。そのため、要素へアクセスする最適な方法を理解することはテストに要する時間短縮に寄与すると考えられます。ここでは、ブラウザ毎に各Locatorのパフォーマンスを計測してみます。

#前提条件
- ブラウザ
    - Internet Explorer 11
        - IEDriverServer 3.3.0
    - Microsoft Edge 38.14393.0.0
        - MicrosoftWebDriver 3.14393
    - Chrome 56
        - chromedriver 2.28
    - Firefox 52
        - geckodriver 0.14
- テスト環境
    - nodejs 6.9.2
    - selenium-webdriver 3.3

#テスト内容
以下のhtmlを使用し、最下層(id=test3)の要素を取得することとします。

```html:html
<div id="test1" class="test1">
    <div id="test2" class="test2">
        <div id="test3" class="test3"></div>
    </div>
</div>
```

計測に利用するクエリ

```js:By.id
driver.findElement(By.id("test3"));
```
```js:By.className
driver.findElement(By.className("test3"));
```
```js:By.css
driver.findElement(By.css(".test1 .test2 .test3"));
```
```js:By.xpath
//xpathは全称セレクタとします

//1. シンプルケース
driver.findElement(By.xpath("//*[@class='test1']//*[@class='test2']//*[@class='test3']"));

//2. 要素を一度キャッシュし、その要素から子要素を探索する
//*キャッシュ部分は計測に含みません
var element = driver.findElement(By.id("test1"));
element.findElement(By.xpath("*[@class='test2']//*[@class='test3']"));
```

#計測結果
ブラウザ毎に各1000回実行し、その平均値を算出しました。

| Locator            | Internet Explorer | Microsoft Edge | chrome | Firefox |
|:-------------------|------------------:|---------------:|-------:|--------:|
| By.id              | 50.1ms            | 1.8ms          | 4.6ms  | 3.2ms   |
| By.className       | 50.0ms            | 1.6ms          | 4.2ms  | 2.9ms   |
| By.css             | 50.1ms            | 1.6ms          | 4.2ms  | 3.0ms   |
| By.xpath          | **34.4ms**        | 1.6ms          | 4.3ms  | 3.1ms   |
| By.xpath(cache)    | **50.4ms**        | 1.8ms          | 4.7ms  | 3.2ms   |

#考察
まず、第一に言えることはIEのみ総じてパフォーマンスが低いことです。一方、他のブラウザで各Locator間の速度差はほぼ認められませんでした。また、どのブラウザにおいてもBy.id、By.className、By.cssの速度差は認められませんでした。ソースコードを見ますと、By.idおよびBy.classNameは内部的にBy.cssに変換されているようなので差がないのだと思われます。
https://github.com/SeleniumHQ/selenium/blob/master/javascript/node/selenium-webdriver/lib/by.js

次に、IEにおけるLocator間の速度差を見てみますと、By.cssよりもBy.xpathの方が高速という結果でした。前述の通り、By.idで取得してもBy.cssに変換されてしまうため、WebDriverではその効果が得られないということでしょうか。

最後に、2つのxpath同士を比較してみますと、要素をキャッシュしない場合(By.xpath)と、要素をキャッシュする場合(By.xpath(cache))とでは、キャッシュした方が遅くなっています。これは僅かではありますが他のブラウザでも同様の傾向が見てとれます。Webアプリ開発の延長線で考えますとキャッシュしたくなるところですが、WebDriverの場合は返ってパフォーマンスの低下を招くようです。

#結論
今回の検証では、Locatorで最速はxpathであり、IEを除くLocator間の速度差はほとんど認められないため、Locatorを使い分けるよりはxpathで統一してしまう方が良いと言えます。
またパフォーマンスの観点からは、要素のキャッシュはせずに常にフルパスで取得することが望ましいと言えます。しかしながら、可読性の観点からは返ってメンテナンス性を損なうことをも考えられるため、ボトルネックに成り得るかの見極めが重要でしょう。

今回はIE8等の古いブラウザでは検証できなかったため、機会がありましたらそれらも検証したいと思います。

＊本検証はマシン環境、ブラウザやWebDriverのバージョンによって異なる結果が得られる可能性もございますので、参考程度に捉えていただけますと幸いです。
terraformで開発者個人別に自由にECSにコンテナをデプロイできる開発環境を用意する

できるだけproductionに近い状態でAWSの各コンポーネントと通信したり、DBのデータを取得できる環境で、アプリケーションの動作確認をしたいことがある。
共有の開発者用のステージング環境等で、それを行うこともできるが、開発者が増えてくると利用が競合して順番待ちが発生したりとかする。

RDBのスキーマを弄ったり、データ投入フロー自体を修正する様な場合は、排他的に利用するべきだが、必ずしも全ての修正がそんなにヘビーな修正ではない。
コンテナの独立性を利用すれば、開発者個別にもっと自由に使える環境を開放できるはず。

というわけで、terraformと組み合わせて、そこそこ手軽に作る方法を考えてみた。

```
resource "aws_alb" "per_developer" {
  count = "${length(var.users)}"

  name = "${element(var.users, count.index)}"
  internal = false
  subnets = ["<your subnet id>"]
  security_groups = ["<your security_group id>"]
  idle_timeout                = 120

  tags {
    PerDeveloper = true
    User = "${element(var.users, count.index)}"
  }
}

resource "aws_alb_target_group" "per_developer" {
  count = "${length(var.users)}"

  name = "${element(var.users, count.index)}"
  port = 8080
  protocol = "HTTP"
  vpc_id = "<your vpc id>"
  deregistration_delay = 60

  health_check {
    path = "<your health_check path>"
  }
}

resource "aws_alb_listener" "per_developer" {
  count = "${length(var.users)}"

  load_balancer_arn = "${element(aws_alb.per_developer.*.arn, count.index)}"
  port = 443
  protocol = "HTTPS"
  ssl_policy = "ELBSecurityPolicy-2016-08"
  certificate_arn = "<your certificate_arn>"

  default_action {
    target_group_arn = "${element(aws_alb_target_group.per_developer.*.arn, count.index)}"
    type = "forward"
  }
}

resource "aws_route53_record" "per_developer_analysis" {
  count = "${length(var.users)}"

  zone_id = "${var.zone_id}"
  name = "${element(var.users, count.index)}.${var.domain_name}"
  type = "A"
  alias {
    name = "${element(aws_alb.per_developer.*.dns_name, count.index)}"
    zone_id = "${element(aws_alb.per_developer.*.zone_id, count.index)}"
    evaluate_target_health = true
  }
}
```

こんな感じでterraformのcountと配列へのアクセスを利用するモジュールを作成する。
countと配列を組み合わせてループっぽいことを実現するのは、マニュアル読んでるだけだと、とても分かりにくいので最初どうしようかと思ったが、一応これでやりたいことはできた。

利用する時はこんな感じ。

```
module "per_developer_env" {
  source = <module path>

  users = ["josuke", "okuyasu", "rohan", "koichi"]
}
```

これで、各メンバー毎のDNSとALBが準備できる。
ALBを利用するのは、コンテナのdynamic port mappingを利用するためだ。
ECSのtask definitionで`host_port`の指定を空欄にすれば、コンテナを起動する際に空いてるポートとコンテナ側の待受ポートをマッピングしてくれる。
ECS serviceをALB target groupと紐付ける際に、`host_port`が動的であれば、ECSが自動的にコンテナ側へのマッピングに利用しているポートを使って、ALB target groupにそのポートでノードを登録してくれる。
これで、アプリケーション側やミドルウェア側のポートを変更しなくても、同じマシンリソースに相乗りすることができる。

ECS側の設定は、各開発者が自分のIDを指定して`USERNAME=josuke cap member deploy`等と実行すると、個別のIDと同一の名前のALB Target Groupを検索し、それと紐付いたECS Serviceを定義する様にしている。
デプロイ方式に依存する所が大きいので、サンプルは出せてないけど……。

というわけで、これで必要なユーザーが個別に自分だけの環境を簡単に持てる様になった。
まあ、まだ運用に乗せたばかりなので、上手く活用されるかは分からないが。
sphinxでlatexpdfjaのときスタイルにjsarticleを使用する

自分のための覚え書き

conf.py で次のように設定する。

ページ番号はシンプルに下部中央に表示する。
目次部分のページ番号をローマ数字にする。
`JT1/gt/bx/it` と `JY1/gt/bx/it` について、フォントの未定義の警告が出るのも対処。 

~~~
# -- Options for LaTeX output ---------------------------------------------

latex_elements = {
     # The paper size ('letterpaper' or 'a4paper').
     #
     'papersize': 'a4paper',

     # The font size ('10pt', '11pt' or '12pt').
     #
     'pointsize': '11pt',

     # Additional stuff for the LaTeX preamble.
     #
     'preamble': '''
%\\pagestyle{plain}
%\\thispagestyle{plain}
\\pagestyle{fancy}
\\thispagestyle{fancy}
\\lhead{}
\\chead{}
\\rhead{}
\\DeclareFontShape{JY1}{gt}{bx}{it}{<->ssub*gt/m/n}{}
\\DeclareFontShape{JT1}{gt}{bx}{it}{<->ssub*gt/m/n}{}
\\DeclareFontShape{JY1}{gt}{m}{it}{<->ssub*gt/m/n}{}
\\DeclareFontShape{JT1}{gt}{m}{it}{<->ssub*gt/m/n}{}
\\DeclareFontShape{JY1}{mc}{bx}{it}{<->ssub*mc/m/n}{}
\\DeclareFontShape{JT1}{mc}{bx}{it}{<->ssub*mc/m/n}{}
\\DeclareFontShape{JY1}{mc}{m}{it}{<->ssub*mc/m/n}{}
\\DeclareFontShape{JT1}{mc}{m}{it}{<->ssub*mc/m/n}{}
\\pagenumbering{roman}
'''

     # Latex figure (float) alignment
     #
     # 'figure_align': 'htbp',
}

latex_docclass = {
    'howto': 'jsarticle',
    #'howto': 'jarticle',
    #'howto': 'jreport',
    'manual': 'jsarticle',
    #'manual': 'jsbook',
}

numfig = True
numfig_format = {'section': '%s',
                  'figure': '図 %s',
                  'table': '表 %s',
                  'code-block': 'リスト %s'}

~~~

本文のページ番号はアラビア数字にするため、index.rst の先頭に、下記を追加。

~~~
.. raw:: latex

    \clearpage
    \pagenumbering{arabic}

~~~
Spring Fox ①導入編

# Spring Fox ①導入編
## Spring Fox とは

Springフレームワークと組み合わせて使うことで対象システムのAPIドキュメントを自動生成してくれる。
※内部的には後述の**Swagger**を利用している。

また、システムから**自動生成**することで**ヒューマンミス**を抑えて**統一性**のあるドキュメントにすることが可能です。

## Swaggerとは

要点が多いので箇条書きで・・・。φ(。。)

* Swagger Specという定義ファイルで管理
* JSON or YAMLで定義
* Swagger Specを基にSwagger UIがドキュメント化する
* 生成ドキュメントはHTMLとjQueryベースでカスタマイズも可能
* さまざまな言語のフレームワークに対応
* Swagger Specを作らずSwagger coreを用いてrのように作成可能することも可能
* 他にもSwagger EditorやSwagger Codegen、Swagger Node等のツールもある(らしい)
* Postman、Amazon API Gateway等の外部ツールも対応をしている
* Swagger Test Templateを使うとSpecファイルからJavaScriptのテストコードを自動生成して実行してくれる
* RESTful APIのインターフェイスを記述するための標準フォーマットを推進する団体「Open API Initiative」がSwaggerを採用している

※他のAPIドキュメント生成ツールとしては、**API blueprint**が有名

#　導入

## 1. 依存関係の追加

gradleの依存関係に追加

```java:build.gradle
dependencies {
...
  compile "io.springfox:springfox-swagger2:2.2.2"
  compile "io.springfox:springfox-swagger-ui:2.2.2"
  compile "com.google.guava:guava:17.0"
...
}
```

## 2. Spring Foxの有効化

アノテーションを追加し、有効にする

```java:Application.java
@SpringBootApplication
@EnableSwagger2//追加
public class Application extends SpringBootServletInitializer
{
    public static void main( String... args )
    {
         SpringApplication.run( Application.class, args );
    }
}
```

## 3. ドキュメント用のJavaConfigを追加

```java:SwaggerConfiguration.java
@Configuration
public class SwaggerConfiguration
{
    @Bean
    public Docket publicDocument()
    {
        return new Docket( DocumentationType.SWAGGER_2 ).groupName( "public" )
                .select()
                .paths( paths() )
                .build()
                .apiInfo( apiInfo() );
    }
    
    private ApiInfo apiInfo()
    {
        ApiInfo apiInfo = new ApiInfo(
                "My REST API",
                "Some custom description of API.",
                "API TOS",
                "Terms of service",
                "myeaddress@company.com",
                "License of API",
                "API license URL");
        return apiInfo;
    }
    
    private Predicate<String> paths() {
        return or(
           regex("/some/endpoint")
        );
    }
    
}
```

## 4. 動作確認

/swagger-ui.htmlにアクセス
※自動でエンドポイントが追加されています。

<img width="649" alt="swagger_demo.png" src="https://qiita-image-store.s3.amazonaws.com/0/113654/44f2c77c-4378-0b54-f3e6-205f0d5bca95.png">

戻り値のJavaクラスが自動でJSON　SCHEMAに変換されていたり、この画面からリクエストを投げることができるので便利。

# 次回

次は

- ヘッダーパラメータの追加方法
- DB値を使ったプルダウン化
- 静的ドキュメント化

あたりでも触れるつもりです。

じゃあの。
Ruby でエポックミリ秒

JavaScript が `Date.now()` でエポックミリ秒を返すので時間のフォーマットをそれにしていたら、Ruby で扱うときに Time クラスだとマイクロ秒しか取れなくって非常に面倒くさかったので、Ruby でエポックミリ秒を生成する方法をいくつかまとめておく。

## Time クラスを使う方法
``` ruby
Time.now.strftime('%s%L').to_i
```

`%L` でミリ秒単体で取れるので、エポック秒とくっつければエポックミリ秒になる

``` ruby
(Time.now.to_f * 1000).to_i
```

これだと文字列に変換しなくて済むけど、パッと見わかりづらい気もする

## DateTime クラスを使う方法
``` ruby
require 'date'
DateTime.now.strftime('%Q').to_i
```

DateTime クラスだと `%Q` が使えるらしいが、 `require` 要るので微妙
OS Xでruby-installでRubyを入れる

OS XでRubyをインストールする時に[ruby-install][]を使っているのですが、今Rubyをインストールしたら失敗したので、対応を書きます。Homebrewを使います。

環境
----

* OS X El Capitan 10.11.6
* ruby-install 0.6.1

エラー
------

単純に

    % ruby-install ruby-2.3.3

とかやるとエラーになります。

    (snip)
    Undefined symbols for architecture x86_64:
      "_rb_ary_resize", referenced from:
          _ary_resize in resize.o
      "_rb_cArray", referenced from:
          _Init_resize in resize.o
      "_rb_define_method", referenced from:
          _Init_resize in resize.o
      "_rb_num2long", referenced from:
          _ary_resize in resize.o
    ld: symbol(s) not found for architecture x86_64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    make[2]: *** [../../../../.ext/x86_64-darwin15/-test-/array/resize.bundle] Error 1
    make[1]: *** [ext/-test-/array/resize/all] Error 2
    make: *** [build-ext] Error 2
    !!! Compiling ruby 2.3.3 failed!

対応
----

まずOpenSSLを最新にします。

    % brew upgrade openssl

使う時の各種パスを確認します。

    % brew info openssl
    (snip)
    For compilers to find this software you may need to set:
        LDFLAGS:  -L/usr/local/opt/openssl/lib
        CPPFLAGS: -I/usr/local/opt/openssl/include
    (snip)

`ruby-install`に失敗してもソースは残ってるので移動します。

    % cd ~/src/ruby-2.3.3

上の`brew info`で得た情報をもとに再度コンパイルします。

    % make clean
    % LDFLAGS="-L/usr/local/opt/openssl/lib" CPPFLAGS="-I/usr/local/opt/openssl/include" ./configure --prefix=$HOME/.rubies/ruby-2.3.3
    % make
    % make install

これでruby-2.3.3がインストールできました。

    % chruby
       ruby-2.2.3
       ruby-2.2.6
       ruby-2.3.3

[ruby-install]: https://github.com/postmodern/ruby-install
bokehにてカラー画像を表示

bokehでカラー画像を表示させるのに少し手間がかかったので残しておきます。

```
import numpy as np
from skimage import data
img = data.coffee()#サンプル画像読み込み

from bokeh.plotting import figure
from bokeh.io import show, output_notebook
output_notebook()

imgH, imgW, ch = img.shape

#int32にint8×4ch(RGBA)をviewを使って代入する
img_plt = np.empty((imgH,imgW), dtype=np.uint32)
view = img_plt.view(dtype=np.uint8).reshape((imgH, imgW, 4))
view[:, :, 0:3] = np.flipud(img[:, :, 0:3])#上下反転あり
view[:, :, 3] = 255

p = figure(x_range=(0,imgW), y_range=(0,imgH))
p.image_rgba(image=[img_plt], x=0, y=0, dw=imgW, dh=imgH)
show(p)
```

![20170324_bokeh_color.PNG](https://qiita-image-store.s3.amazonaws.com/0/109458/35f51768-1818-7894-4257-3b29e7903758.png)

#追記
カラー画像とモノクロ画像を表示するコピペ用関数

```
def show(img):
    import numpy as np
    from bokeh.plotting import figure
    from bokeh.io import show, output_notebook
    output_notebook()    

    imgH =img.shape[0]
    imgW= img.shape[1]

    if(img.ndim == 3):#(imgH,imgW,ch)int8*3chのカラー画像を表示
        img_plt = np.empty((imgH,imgW), dtype=np.uint32)
        view = img_plt.view(dtype=np.uint8).reshape((imgH, imgW, 4))
        view[:, :, 0:3] = np.flipud(img[:, :, 0:3])#上下反転あり
        view[:, :, 3] = 255    
        p = figure(x_range=(0,imgW), y_range=(0,imgH), plot_width=imgW, plot_height=imgH)
        p.image_rgba(image=[img_plt], x=0, y=0, dw=imgW, dh=imgH)

    else:#(imgH,imgW)モノクロ画像を表示（スケーリングは自動）
        palette_256 = ['#%02x%02x%02x' %(i,i,i) for i in range(256)] #256段階で白黒表示用
        img = np.flipud(img)#上下反転あり
        p = figure(x_range=(0,imgW), y_range=(0,imgH), plot_width=imgW, plot_height=imgH)
        p.image(image=[img], x=0, y=0, dw=imgW, dh=imgH, palette=palette_256)

    show(p)

```
Splatoonの全ブキの合計の塗ポイントを出してくれるやつ

# 概要
 
Splatoonのイカリング(ブラウザでゲーム内のいろんな情報を見れるサイト)では各ブキの塗ポイントがわかる.
しかし,各ブキの塗ポイントを合計した値がわからない.(電卓たたけばわかるが)
それをJavaScript使ってすぐ見れるようにした.

![各ブキの塗ポイント.PNG](https://qiita-image-store.s3.amazonaws.com/0/91558/0e4301c7-4b7e-1640-3b2f-f57fab82562d.png)
**各ブキの塗ポイントがわかるが,合計が見れない!**

![合計の塗ポイント.PNG](https://qiita-image-store.s3.amazonaws.com/0/91558/365f5f1f-9042-8e6f-fb18-ab1b28e03d9c.png)
**こんな感じで表示できる!**

# やり方
1. [イカリング](https://splatoon.nintendo.net/)にログインして,各ブキの塗ポイントが表示されているページ(そうびページ)にいく.
2. Google ChromeだったらCtrl+Shift+Jを押して,Consoleタブを選択する.Microsoft EdgeまたはInternet ExplorerだったらF12を押して,コンソールタブを選択する.
3. 以下の内容をコピペしてエンター(コンソールタブの">"の右あたりをクリックすると入力できる.)
4. 総塗ポイントが表示される.✌('ω')✌

コピペする内容
```var s=0;$(".equip-painted-point-number").each(function(){s+=Number($(this).text());});alert("総塗ポイント:"+s);```

![合計の塗ポイント.PNG](https://qiita-image-store.s3.amazonaws.com/0/91558/365f5f1f-9042-8e6f-fb18-ab1b28e03d9c.png)
**総塗ポイントの表示結果(Google Chromeの場合)**

# コードを見やすくしたやつ

```js
var s=0;
$(".equip-painted-point-number").each(function(){
  s+=Number($(this).text());
});
alert("総塗ポイント:"+s);
```

# 余談

なんかそれっぽいのもうあった.
[Splatoon で今まで塗ったインクの面積（ポイント）を計算するブックマークレット](http://jsdo.it/KENT/splatoon)

# 宣伝
フォローお願いします:crown: [@redshoga](https://twitter.com/redshoga)
ローカルgitリポジトリでリモートのリポジトリURL確認方法

ローカルにクローンしたリポジトリのリモートURLを確認する方法はいくつあります。

    リポジトリ例：　
    
```bash
$ git clone git@github.com:ruby/ruby.git ruby
$ cd ruby
```

#### 方法1 

```bash
$ git config --get remote.origin.url
```
```
git@github.com:ruby/ruby.git
```

#### 方法2 

```bash
$ git remote -v
```
``` 
origin  git@github.com:ruby/ruby.git (fetch)
origin  git@github.com:ruby/ruby.git (push)
```

#### 方法3

```bash
$ git remote show -n origin
```
```
* remote origin
  Fetch URL: git@github.com:ruby/ruby.git
  Push  URL: git@github.com:ruby/ruby.git
  HEAD branch: (not queried)
  Local ref configured for 'git push' (status not queried):
    (matching) pushes to (matching)

```

#### 方法4

```bash
$ git remote show origin
```
```
* remote origin
  Fetch URL: git@github.com:ruby/ruby.git
  Push  URL: git@github.com:ruby/ruby.git
  HEAD branch: trunk
  Remote branches:
    ruby_1_3   new (next fetch will store in remotes/origin)
    ruby_1_4   new (next fetch will store in remotes/origin)
....
```

#### 方法5

```bash
$ cat .git/config
```
```
[core]
        repositoryformatversion = 0
        filemode = false
        bare = false
        logallrefupdates = true
        symlinks = false
        ignorecase = true
[remote "origin"]
        fetch = +refs/heads/*:refs/remotes/origin/*
        url = git@github.com:ruby/ruby.git
```

#### 方法6
```bash
$ git config -l
```
```
...
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
remote.origin.url=git@github.com:ruby/ruby.git
```

#### 方法7

```bash
$ git remote get-url origin
```
...
git@github.com:ruby/ruby.git
```

なお、git helpを活用すれば、何でも調査できる。例

```bash
$ git remote show --help
```
```
usage: git remote show [<options>] <name>

    -n                    do not query remotes

```

参照
------------------------
- http://stackoverflow.com/questions/4089430/how-can-i-determine-the-url-that-a-local-git-repository-was-originally-cloned-fr
- http://hacknote.jp/archives/15330/
- http://qiita.com/yuyuchu3333/items/a30387bdd6a0afc1185c
レスポンシブなページでリサイズ時にスタイルをリセットしたい

先日レスポンシブのページを作った時に、スタイルをブラウザ幅が変わった時にはリセットしてほしいと思ったのでちょっとjavascriptでかいてみた。

デモを使って紹介する。
ベースは以下。灰色のボックスとボタン置いてボタン押したらボックスの色を変えるっていう簡単なデモを用意・

```index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <link rel="stylesheet" href="style.css"> 
    <script src="/common/jquery-3.1.1.min.js"></script>
    <script src="index.js"></script>
</head>
<body>
    <div class="wrap">
        <div class="box"></div>
        <div class="btn">change</div>
    </div>
</body>
</html>
```
```style.css
.box {
    width: 150px;
    height: 150px;
    background-color: #ccc;
}
.btn {
    width: 100px;
    border: 1px solid #000;
    background-color: #fff;
}
```

最初に書いたのは、ブラウザ幅が変わった時にページをリロードする、って処理。

```index.js
$(function(){
    
    $(".btn").click(function(){
    $(".box").css("background-color","red");
    })
    
    var timer = false;
    $(window).resize(function() {
    if (timer !== false) {
        clearTimeout(timer);
    };
    timer = setTimeout(function() {
            location.reload();
    }, 200);
});
    
    
});
```

setTimeoutでリサイズする度にリロード処理させる。普通にやると何度もリサイズ処理が走っちゃうのでclearTimeoutで毎回のイベントを消して、最後の一回で処理する、という流れ。
しかし問題はあって、PCならいけどSPの場合、スクロールする度に縦のブラウザサイズが変わってめっちゃリロードしてしまう。
で、改良したのが以下。

```index.js
$(function(){
    
    $(".btn").click(function(){
        $(".box").css("background-color","red");
    })

    var timer = false;
    var prewidth = $(window).width()
    $(window).resize(function() {
        if (timer !== false) {
            clearTimeout(timer);
        };
        timer = setTimeout(function() {
            var nowWidth = $(window).width()
            if(prewidth !== nowWidth){
                location.reload();
            };
            prewidth = nowWidth;
        }, 200);
    });
});
```
横幅を取得してリサイズの前後で変化なかったら処理しない、っていう風にした。
問題解決。

しかしリロードするのってユーザビリティ悪いよねってなって、最終的にはインライン要素のstyle属性を削除するっていうものに落ち着いた。

```index.js
$(function(){
    
    $(".btn").click(function(){
        $(".box").css("background-color","red");
    })
    
//    リサイズ時インラインスタイル削除
    var timer = false;
    var prewidth = $(window).width()
    $(window).resize(function() {
    if (timer !== false) {
        clearTimeout(timer);
    }
    timer = setTimeout(function() {
        var nowWidth = $(window).width()
        if(prewidth !== nowWidth){
            $('.wrap *').removeAttr('style');
        }
        prewidth = nowWidth;
    }, 200);
});
    
    
});
```

っていう話。
Cognosのレポート同時実行時のパラメーターチューニングの考え方

##概要

最近読んだ、各ベンダーのBIツールを評価するアンケートをエンドユーザーに行った結果によると、Cognosの強みは、多くの同時接続ユーザーにおけるレポートの並列処理を行う能力と答えているユーザーの方が多いようで、多くのBIツールの中でトップクラスの評価を受けてました。
特別に意識する事なく、こんなものだろうと今まで使っていましたが、せっかくなので何かしら関連した情報を投稿しようと思い、最近質問を受けた、Cognos BI&Analyticsでの同時実行処理能力に対する、パラメーターチューニングの考え方を投稿しておきます。

##Cognosのレポート実行時の動作
下図はCognosのDispatcherとReport Serviceプロセスを説明している図ですが、Cognosのレポート実行は、ブラウザ上でレポート名をクリックしレポートを実行すると、指令がGateway(WEBサーバー)を通り、図のDispatcherを通り、Dispatcherから空いているReport Serviceプロセスに振り分けられ、基本的にReport Serviceプロセス内の親和性の低い接続(スレッド)1個を使用してレポートの実行処理が行われます。

Report Serviceプロセスの中には、親和性の低いスレッドと親和性の高いスレッドを持ちます。
この2つのスレッドの違いは、初回のレポート実行は親和性の低いスレッドを用いて行われレポートが表示されます。
そのレポートの中で、次ページへの遷移やPDF出力などの初期表示の継続として行われる処理は親和性の高いスレッドを用いて行われます。

Cognosにおける同時処理能力は、Report Serviceプロセス数 x 親和性の低いスレッド数 で算出されます。
全てのプロセスの全ての親和性の低いスレッドが埋まっている状態で、次のリクエストが来ると、スレッドが空くまで処理はキューにためられ待たされます。※タイムアウト指定のパラメータあり

![image](https://qiita-image-store.s3.amazonaws.com/0/147246/53750700-5ea2-1614-e257-42d30bb4bc87.png)

##Cognosの並列処理のパラメーターチューニングの考え方
Report Serviceプロセスの数は、CPUコア数 x 2が一般的なガイドとなります。
Report Serviceプロセスは32bitのプロセスのため、プロセスで使用できるメモリーは2GBに制限されます。
Report Serviceプロセスの使用メモリーが2GBを超えると、Report Serviceプロセスがダウンし、このプロセスを使用していたユーザーのレポート実行はエラーとなります。
親和性の低いスレッドの数は、この2GBメモリーの制限を考慮して、環境ごとに全スレッドの合計使用メモリーが2GBを超えないように、スレッド数を検討します。
下の図は、Report Serviceプロセスのプロパティですが、赤枠の箇所でReport Serviceプロセス数を、青枠の箇所で親和性の低いスレッドの数を指定します。
起動中のプロセス内のスレッドの半分が使用されている場合、新規にプロセスを起動する動作になるようです。

![001.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/bd2bd3d3-92fd-700e-ed01-833b2017a2bd.png)

##補足
というのが基本ですが、動的クエリー(DQM)モード限定であれば64bitの選択も可能とか、
![002.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/5b24b552-f889-e306-29e6-f60857f23650.png)

レポートにCognos10のチャートが含まれる場合、Graphic Serviceのプロセス数やスレッド数もチューニングの対象になりますので、このあたりも考慮に入れて頂ければと思います。
![image](https://qiita-image-store.s3.amazonaws.com/0/147246/0aa22f78-777c-dfd7-7798-41c39575d510.png)

##補足2
もっと細かい調整も可能ですので、こちらもご参照下さい。
**Cognos のReport Server(BIBusTKServerMain)プロセスの動作調整**
https://qiita.com/shinyama/items/40191bd583c0852e56c4
エリック・エヴァンスのドメイン駆動設計 読書メモ5

[読書メモ4](http://qiita.com/kawachi/items/c8cfb1bd92ab962d3595) の続き。
引き続き第15章を読みました。だんだん読むペースが落ちてきている。

## 第15章 蒸留

モデルから本質的なものを抽出し、価値を高めるプロセスのこと。

### コアドメイン

システムが大きくなると、コンポーネントが増え、本質が見えづらくなる。
開発者は本質が見えないと変更しづらい。変更をスムーズに行うには特定領域を熟知する必要がある。

複数あるサブドメインの中でも中心的なものをコアドメインと呼ぶ。
コアドメインを周辺領域から区別する手段を講じる。
コアドメインは小さくする。
コアドメインはアプリケーションを差別化するビジネス資産であるため、最も才能のある開発者に担当させ、しなやかな設計を達成する。

コアドメインは1つとは限らない。

ドメインに対する関心が強く、長い間ドメインとともに歩もうと考えている開発者たちと、ドメインエキスパートのチームでコアドメインを作成する。
ドメイン知識は蓄積する必要があるため、コアドメインの作成を外部に頼むことや、コアドメインを購入することは実践的ではない。

### 汎用サブドメイン

本質的ではないが、汎用的であり、確実にドメインモデルの一部を構成するものは汎用ドメインとして切り出す。
凝集度の高い部分を識別し、汎用的なモデルとして別モジュールにすることで汎用サブドメインを抽出できる。

汎用サブドメインよりコアドメインの開発を優先するべきだ。

汎用サブドメインは買ってくることや、公開されているモデルの採用を検討するべきだ。
外部に頼むのも選択肢に入る。

汎用サブドメインの再利用性を気にしすぎないこと。
再利用性を実現するには投資が必要だが、優先的にコアドメインに投資するべきだ。

アジャイルではリスクを早期に減らしていくが、コアドメインモデリングのリスクは低く見積もられがちなので注意。

### ドメインビジョン声明文

コアドメインとその価値についての簡潔な（約1ページ）記述。
自然言語で記述する。コアドメインについての意識を高めるのに役立つ。

- 差別化要素ではないものは無視する
    - UI、外部システムインタフェース、使用技術、プロジェクト運営方法などはドメインビジョン声明文に入るべきではない
- スコープを広げすぎない
- プロジェクト早期に作る
- 新しい洞察を得たら改定する

### 強調されたコア

コアドメインをコード上で切り離す行為。

コアに対する認識が深まっていない状態で、いきなり切り離そうとするのは実用的ではない。
認識を深めるテクニックとして次の2つがある。

- 蒸留ドキュメント
    - 本質的な概念オブジェクト群とその間の主要な相互作用だけを記載したドキュメント
	- ドキュメントの維持や理解にかかるコスト、複雑さを増やさないために、コアの境界を説明する最小限のドキュメントとするのがよい
- コアにフラグを立てる
    - 既存ドキュメントのコア部分にフラグ（マーク）をつける

蒸留ドキュメントはコードとモデルを変更する際の指針として使える。

### 凝集されたメカニズム

what が how に侵食されて複雑さを増大させている場合、凝集された how (メカニズム) を切り分けることで、コアを際立たせることができる。

汎用サブドメインは表現力をもつモデルであり、チームの視点を反映している。メカニズムは処理を担当する。

### 隔離されたコア

モデルから汎用サブドメインやメカニズムを抽出していく方法では、コアは抽出の抜け殻のほうに存在する。こちらはコアを抽出する手法。

重要で巨大な境界づけられたコンテキストがあり、補助機能によって本質がわかりづらいときには、コアを隔離するべきだ。

隔離されたコアで作業すると、本質に対する洞察が深まることがある。洞察はチームで共有しする。個人で行動することはできない。

### 抽象化されたコア

多態的なインタフェースがドメインの概念と一致するときには、抽象クラスやインタフェースでの抽出を試みる価値がある。
抽出したものは別のモジュールにまとめ、実装クラスをサブドメイン置く。

### リファクタリング対象の選び方

リファクタリングの費用対効果を上げるには

1. 困ったことがおきて、それがコアドメインに一部でも関係するものであったなら、歯を食いしばってやる
1. 自由があるときは、コアドメインのより適切なくくりだし、コアの隔離、汎用サブドメインの抽出をやると良い

## 感想

前章(第14章)はコンテキストの境界を明らかにする方法を探った。本章(第15章)はドメインを分割して理解しやすくしようという試み。人間の認識力の限界を超えないように、如何に分割統治するか、という方法論だ。

[IDDD本の第2章「ドメイン」「サブドメイン」「境界づけられたコンテキスト」を読み解く](https://codezine.jp/article/detail/9744)によれば、境界づけられたコンテキストは解決領域であり、コアドメイン、サブドメインは問題領域に位置づけられる。この分類によれば本章は問題分析の方法について述べていることになる。実際には、コアドメイン、サブドメインに対応するモデルや実装のリファクタリングに対する言及があるため、問題領域と解決領域の両方にまたがった言及というふうに理解している。サブドメインが発見されることによりサブ言語が定義され、サブコンテキストが発生するのだろう(読み間違ってたら教えて)。

コアドメインこそがビジネスの根幹だが、それをやりたがる熟練開発者は少ない、という点は興味深い。開発者さん、ビジネスに敏感になろう。

汎用サブドメインを認識することで外部調達の可能性が開ける点は認識しておきたい。買ってこれるなら買ってきたほうがいいよね。

残り2章。
Vagrantでポート番号が衝突したときの対処法（Windows）

# 概要
Vagrantを起動する際にポート番号が他のアプリケーションが使っているためエラーになることがあります。
結論としては、Vagrantで別のポート番号を割り当てればよいのですが、
日ごろWindowsで開発していて、ポート番号を初めて調べたので備忘録のために手順を残します。

# 現象
vagrant up時に以下のようなエラーが表示される。

```
Vagrant cannot forward the specified ports on this VM, since they
would collide with some other application that is already listening
on these ports. The forwarded port to 3333 is already in use
on the host machine.
To fix this, modify your current projects Vagrantfile to use another
port. Example, where ‘1234’ would be replaced by a unique host port:

config.vm.network :forwarded_port, guest: 22, host: 1234

Sometimes, Vagrant will attempt to auto-correct this for you. In this
case, Vagrant was unable to. This is usually because the guest machine
is in a state which doesn’t allow modifying port forwarding.
```

## 1. Windowsでportをどのアプリケーションが使用しているか調査。

```
// Windowsコマンドプロンプトを起動してnetstatコマンドで調査
> netstat -nao
TCP         127.0.0.1:3333         0.0.0.0:0              LISTENING       XXX // <-PID
...
```

## 2. WindowsタスクマネージャでPID XXXのアプリケーションを調べる。
[タスクマネージャ起動]->[詳細]で調べる

## ~~3. Vagrantのポート番号を変更する。~~
~~Vagrantfileを開き、以下のような記述があるところを修正すれば良いです。~~
```
xxxx.vm.network :forwarded_port, guest: 22, host: 3333, id: "ssh", auto_correct: false
```

~~しかし、何番にするのがベストなのか、気になったので調べました。
https://ja.wikipedia.org/wiki/TCPやUDPにおけるポート番号の一覧~~

~~49151番までは登録済みポート番号とのことで、一見すると49152番以降だと安全そうですが、
49152番以降はOSのエフェメラルポートとして自動的に割り当てられる可能性があるようです。（OSにもよるのでしょうが。）
そうなると逆にバッティングしそうなので、何か別のポートがいいかもしれません。~~

~~3333が既に競合しているというだけなので、2223とかにして様子を見ようかな…。~~

**2017/04/06 追記**
auto_correctという機能があるらしく、ポート番号が重複した場合に自動的に別のポートを割り当てるようです。

```
xxxx.vm.network :forwarded_port, guest: 22, host: 3333, id: "ssh", auto_correct: true
```

例えばポート番号3333で2つのvagrantを起動すると、以下のように自動的に2200番を割り当てます。

```
Bringing machine 'xxx' up with 'virtualbox' provider...
==> api: Checking if box 'hogehogehoge' is up to date...
==> api: Fixed port collision for 22 => 3333. Now on port 2200.
==> api: Clearing any previously set network interfaces...
==> api: Preparing network interfaces based on configuration...
    api: Adapter 1: nat
    api: Adapter 2: hostonly
==> api: Forwarding ports...
    api: 22 (guest) => 2200 (host) (adapter 1)
    api: 80 (guest) => 8808 (host) (adapter 1)
    api: 443 (guest) => 14438 (host) (adapter 1)
    api: 8000 (guest) => 18000 (host) (adapter 1)
    api: 3306 (guest) => 23306 (host) (adapter 1)
==> api: Running 'pre-boot' VM customizations...
...
```

# まとめ
 - Windowsでポート番号調べるときには`netstat -nao`を使う。
 - エフェメラルポートというものがある。
 - ~~ポート番号には絶対に衝突しないという選択肢はなさそう。~~
 - auto_correct: trueにすると、ポート番号が衝突した場合に自動的に別のポートを割り当てることができる。

**2017/04/06 追記**
※指摘を受けて修正しました。フィードバックありがとうございます。
bash > カレントディレクトリとスクリプトのディレクトリ(絶対 / 相対)の取得

```txt:動作環境
Xeon E5-2620 v4 (8コア) x 2
32GB RAM
CentOS 6.8 (64bit)
openmpi-1.8.x86_64 とその-devel
mpich.x86_64 3.1-5.el6とその-devel
gcc version 4.4.7 (とgfortran)
NCAR Command Language Version 6.3.0
WRF v3.7.1を使用。
Python 2.6.6 (r266:84292, Aug 18 2016, 15:13:37) 
Python 3.6.0 on virtualenv
```

bashにて以下の情報を取得したい。

- スクリプトのあるディレクトリ (相対パス)
- スクリプトのあるディレクトリ (絶対パス)
- 実行ディレクトリ

参考 http://stackoverflow.com/questions/59895/getting-the-source-directory-of-a-bash-script-from-within

```bash:../SCRIPT_DIRCTORY/find_path_170324_exec
#!/usr/bin/env bash

# relative path
$(dirname $0)
# full path
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
echo $DIR
# current directory
pwd
```

```txt:フォルダ構造
├── DATA_DIRECTORY
└── SCRIPT_DIRCTORY
```

DATA_DIRECTORYにおいて以下のように実行してみた。

```txt:実行
$ bash ../SCRIPT_DIRECTORY/find_path_170324_exec 
../SCRIPT_DIRECTORY
/home/xxx/WORK/BASH_SCRIPT_170324/SCRIPT_DIRECTORY
/home/xxx/WORK/BASH_SCRIPT_170324/DATA_DIRECTORY
```

full pathの取得については

> It will work as long as the last component of the path used to find the script is not a symlink (directory links are OK).

とあるようにsymlinkではうまく動かない。
Railsで今月のカレンダーを生成するerbコード

`rails`というよりも`active_support`を使って今月のカレンダーをHTMLで生成するerbコードです。ロジックとしては次の通りです。

1. 今月の1日の週の月曜日の日付`d`を得ます。
2. `d`から1週間分をループで回します。
3. ループ内では、ループ内の日`c`が今月でない分は空欄に、今月であれば日付を入れます。
4. ループを抜けた後に`d`を1週間後にずらします。
5. 2.に戻ります(4回目迄)。


```erb
<% today = Date.today%>
<table>
  <caption><%= today.strftime('%Y年%m月')%></caption>
  <tr>
    <th>月</th>
    <th>火</th>
    <th>水</th>
    <th>木</th>
    <th>金</th>
    <th>土</th>
    <th>日</th>
  </tr>
  <tr>
<% month = today.strftime('%m')%>
<% d = today.at_beginning_of_month.at_beginning_of_week%>
<% 1.upto(5).each do|i|%>
  <tr>
<% (d..d.end_of_week).each do|c|%>
    <th><%= (c.strftime('%m') == month)? c.strftime('%d'): "  "%></th>
<% end %>
  </tr>
<% d = d + 1.week %>
<% end %>
</table>
```
2017年3月に実行して生成されたHTMLをブラウザから見るとこんな感じになります(上のコードのままだと24日のリンクは付きません)。
<img width="195" alt="calendar.png" src="https://qiita-image-store.s3.amazonaws.com/0/227/09a9d2d1-51d3-1f2b-8be2-84a231e0a5d7.png">
「れる」「られる」


**意味**　

##### （１） 受け身
* 他人に　笑わ**れる**。
* お客から　声援を　かけ**られる**。 　

いずれも、「に」「から」のかたちの文節が動作を**する人**　（他人、観客）を表しています。

```point
　話し手が他からなんらかの動作を受けることを受け身と言います。
```
##### （２） 可能
* 登**られる**ところまで登ろう。
* ここまでは覚え**られる**。 

```point
　～することができる。
```
注意
> 五段活用の動詞「登る」の可能形は、「登れる」という言い方のほうがふつうです。

##### （３） 自発
* 故郷が　偲ば**れる**。
* 母の　ことが　案じ**られる**。 

自分がそうするつもりがなくても、一人で（自然に）なつかしく思い出してしまう。

```point
　話し手の動作が自然におこること。
```

##### （４） 尊敬
* 先生が　話さ**れる**。
* お客様が　来**られる**。 

```point
　人の動作を立てることによってその人を敬う気持ちを表すことを尊敬と言います。
```

#### <i class="fa fa-thumb-tack" style="font-size:1em;"></i> まとめ
①　受け身　（他に～される）
②　自発　　（自然にそうなる）
③　可能　　（～することができる）
④　尊敬　　（人を敬う）
Adjustの初回のSDK設定で読み落としてたやつ

皆さんおなじみ広告のSDKのAdjust。

https://docs.adjust.com/ja/sdk/android/

これのAndroidのSDKの導入はかなり綺麗に描かれている。ただ一点だけ気をつけて欲しいのがここ。

<img width="858" alt="スクリーンショット 2017-03-24 18.06.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/31237/efd5c8aa-0700-7aaa-fef4-73229e8d9530.png">

これ実は1行あとで出てくる手順で追加するのだ。

```java

String appToken = "{YourAppToken}";
String environment = AdjustConfig.ENVIRONMENT_SANDBOX;
AdjustConfig config = new AdjustConfig(this, appToken, environment);
Adjust.onCreate(config);
```

最後のAdjust.onCreateってやつ。これ読み落としがちで知り合いも同じことしてた。
これがないとずっと

```
Adjust not initialized correctly
```

が出ちゃうので皆さんも気をつけてください。
testのdiv.paginationで失敗した時

##エラーが出るまでの経緯
第3版のrails-tutorialにおける11章を進めていた際に以下のようなテストを書いた。

```ruby:users_profile_test.rb
require 'test_helper'

class UsersProfileTest < ActionDispatch::IntegrationTest
  include ApplicationHelper
  
  def setup
    @user = users(:michael)
  end

  test "profile display" do
    get user_path(@user)
    assert_template 'users/show'
    assert_select 'title', full_title(@user.name)
    assert_select 'h1', text: @user.name
    assert_select 'h1>img.gravatar'
    assert_match @user.microposts.count.to_s, response.body
    assert_select 'div.pagination'
    @user.microposts.paginate(page: 1).each do |micropost|
      assert_match micropost.content, responce.body
    end    
  end  
end
```

この'div.pagination'において失敗した。以下が失敗した内容である。

```ruby
 1) Failure:UsersProfileTest#test_profile_display [/home/ubuntu/workspace/sample_app/test/integration/users_profile_test.rb:17]:
Expected at least 1 element matching "div.pagination", found 0..
Expected 0 to be >= 1.
```

エラーの内容としては、”showテンプレートの中にページネーションクラスを持ったdiv要素があるのか”をチェックしています。ここでshowテンプレートの中に該当するものがあるのかを探してみると、、、

```ruby:show.html.erb
<%= provide(:title, @user.name)%>
<div class="row">
<aside class="col-md-4">
  <section class="user_info">
    <h1>
      <%= gravatar_for @user %>
      <%= @user.name %>
    </h1>
    </section>
  </aside>
  <div class="col-md-8">
    <% if @user.microposts.any? %>
     <h3>Microposts (<%= @user.microposts.count %>)</h3>
     <ol class="microposts">
       <%= render @microposts %>
     </ol>
     <%= will_paginate @microposts %>
    <% end %>
  </div>
</div>
```

なかったので、もう一度自分が書いたshowの中身に過不足がないか確認してみるがそのような点は見当たらなかった。

##解決法
この時点では、テストを稼働させた時、失敗が出ないようにしたいのでdivのclassにpaginationを加える。


```ruby:show.html.erb
<%= provide(:title, @user.name)%>
<div class="row">
<aside class="col-md-4">
  <section class="user_info">
    <h1>
      <%= gravatar_for @user %>
      <%= @user.name %>
    </h1>
    </section>
  </aside>
  <div class="pagination col-md-8">
    <% if @user.microposts.any? %>
     <h3>Microposts (<%= @user.microposts.count %>)</h3>
     <ol class="microposts">
       <%= render @microposts %>
     </ol>
     <%= will_paginate @microposts %>
    <% end %>
  </div>
</div>
```

これを保存してテストを稼働させると、、、、

```ruby:
$ bundle exec rake test
RubyDep: WARNING: Your Ruby is outdated/buggy.
RubyDep: WARNING: Your Ruby is: 2.3.0 (buggy). Recommendation: upgrade to 2.3.1.
RubyDep: WARNING: (To disable warnings, see:http://github.com/e2/ruby_dep/wiki/Disabling-warnings )
Run options: --seed 64211

# Running:

............................................

Finished in 2.291725s, 19.1995 runs/s, 109.5245 assertions/s.

44 runs, 251 assertions, 0 failures, 0 errors, 0 skips
```

上手くいった。何故テストで失敗するのかは分かったが、どうしてrails-tutorial 4版の方はあの書き方でテストが上手くいくのかは分からなかった。
CodeIgniterの標準メールでユーザーエージェントを削除する

元々Javaばっかりやっていたのですが、ここ1年ぐらいPHPを触る機会が多くなりました。
小ネタですが、CodeIgniterのメールで「おや？」と思ったので、記事にしておきます。

# 環境

|項目|設定値|備考|
|---|---|---|
|OS|CentOS7.2||
|HTTPサーバ|Apache/2.4.6||
|言語|PHP7.1.1||
|フレームワーク|CodeIgniter3.1.3||
|メール(MTA)|Postfix||

# 事象

* CodeIgniterの[Emailクラス](http://codeigniter.jp/user_guide/3/libraries/email.html)を用いてメール送信する機能を作成
* 実際に送信したメールを見ると、ヘッダーにこんな情報が・・・

```
User-Agent: CodeIgniter
X-Mailer: CodeIgniter
```

* セキュリティ的に、フレームワーク情報などは隠蔽したい

# 結論

* CodeIgniterのEmailクラスに`useragent`という[設定項目](http://codeigniter.jp/user_guide/3/libraries/email.html#id5)がある
* これを`$config['useragent'] = '';`みたいにすればOK

# 所感

実害は無いかもしれませんが、ヘッダーにフレームワーク情報などが載ってしまうと、セキュリティリスクが高まってしまいます。
（例えば、CodeIgniterの脆弱性が見つかって、そこから攻撃される、など）
開発時には見えた方が良いときもあるかもしれませんけど、出来るだけ不必要な情報は出さない方が宜しい感じかと思いました。

以上、小ネタでした！！