OmniAICreator/Qiita-1.07M huggingface dataset:
【備忘録】GIMP 覚書

備忘録です。

Windows の時はちょっとした画像編集に「ペイント」を使っていたんですが、
Mac を使う様になり、
仕方がないので、GIMP でも覚えようかな、
ということで、

普段よく使う手順をメモしとこうと思います。

# ■ 画像を拡大・縮小する

1. メニューから「画像」→「画像の拡大・縮小」を選択します。
1. 「画像の拡大・縮小」ダイアログが表示されるので、「キャンバスサイズ (画像サイズ)」を変更して、「OK」ボタンを押下します。
1. 後は、そのままエクスポートします。

基本ですね。
最近の画像は大きすぎるので、縮小することが多い。

# ■ 上下左右にある要らない部分をカットする (値指定)

1. メニューから「画像」→「キャンパスサイズの変更」を選択します。
1. 「キャンパスサイズの変更」ダイアログが表示されるので、「キャンバスサイズ」や「オフセット」を変更し、いらない上下左右のカットします。
1. 「レイヤー」の「サイズ変更するレイヤー」で、「すべてのレイヤー」を選択し、「サイズ変更」ボタンを押下します。

「「切り抜き」使ったら」、という話もあるんですが、
出来れば px 単位でやりたい派なので、これで。
本当は矢印キーを使って出来るといいんだけど…。

* ※参考
    * [6\.11\. キャンバスサイズの変更\.\.\.](https://docs.gimp.org/ja/gimp-image-resize.html)

# ■ 上下左右にある要らない部分をカットする (矢印キーやマウスで)

1. メニューから「選択」→「すべて選択」を選択します。
1. メニューから「ツール」→「変形ツール」→「移動」を選択します。
1. マウスや矢印キーで要らない部分を外側に移動します。
    * 矢印キーで大きく移動させたい場合は、Shit + 矢印キーで大きく動かせます。
1. メニューから「画像」→「キャンパスサイズの変更」を選択します。
1. 「キャンパスサイズの変更」ダイアログが表示されるので、「キャンバスサイズ」や「オフセット」を変更し、いらない上下左右のカットします。
1. 「レイヤー」の「サイズ変更するレイヤー」で、「すべてのレイヤー」を選択し、「サイズ変更」ボタンを押下します。

# ■ 複数の画像を繋げる

1. 元の画像を開き、メニューから「画像」→「キャンパスサイズの変更」を選択。
1. 「キャンパスサイズの変更」ダイアログが表示されるので、「キャンバスサイズ」や「オフセット」を変更して、繋げた時のサイズより大きいキャンバスを作成します。
1. 「レイヤー」の「サイズ変更するレイヤー」で、「すべてのレイヤー」を選択し、「サイズ変更」ボタンを押下します。
1. 繋げたい画像を開き、領域を選択し、メニューから「編集」→「コピー」を選択します。
1. 元の画像に移り、メニューから「編集」→「貼り付け」を選択します。
1. メニューから「ツール」→「変形ツール」→「移動」を選択します。
1. マウスや矢印キーで繋げたい位置まで移動させます。

Qiita への投稿の際には画面キャプチャを繋げたいことが結構あったりするので、重宝します。

# ■ 余計な文字などを塗り潰す

1. メニューから「ツール」→「選択ツール」→「短形選択」を選択。
1. 塗りつぶしたい領域を枠で囲みます。
    * px 単位で調整したい場合は、マウスを短形選択の枠のところに移動させて、アイコンを十字マークから「三角」マークに変えると、十字キーで px 単位の調整が出来ます。
1. 枠が決まったら、ツールボックスの一番下にあるの描画色をクリックし、「描画色の変更」ダイアログで塗り潰したい色を決定します。
1. 描画色を選択領域までドラッグすると塗り潰されます。

Qiita への投稿の際には消したい文字が結構あったりするので、重宝します。

# ■ 囲み線を描く

1. メニューから「ツール」→「選択ツール」→「短形選択」を選択。
1. 囲みたい領域を枠で囲みます。
    * px 単位で調整したい場合は、マウスを短形選択の枠のところに移動させて、アイコンを十字マークから「三角」マークに変えると、十字キーで px 単位の調整が出来ます。
1. 枠が決まったら、メニューから「編集」→「選択範囲の境界線を描画」を選択。
1. 「選択範囲の境界線を描画」ダイアログが表示されるので、各種項目を設定し、「描画」ボタンを押下すると、囲み線が描画されます。

Qiita への投稿の際には囲みたい部分が結構あったりするので、重宝します。

* ※参考
    * [GIMPで枠線\(囲み線\)を描く \| 【Webサイトお〜や】Webサイトのあれこれ＋α](http://blog.pleeds.com/web/gimp-waku)

# ■ 所定のサイズの画像を作成する

1. メニューから「ファイル」→「新しい画像」を選択。
1. 「新しい画像を作成」ダイアログが表示されるので、「キャンバスサイズ (画像サイズ)」を変更して、「OK」ボタンを押下。
1. 後は、何か書いたり、色つけたりしてエクスポートします。

開発してると、所定のサイズの画像が必要な時があったりします。

# ■ 鉛筆の幅を調整する。

1. メニューから「ツール」→「描画ツール」→「鉛筆で描画」を選択。
1. 以下のサイトを参考にして、ツールオプションを表示する。
    * [ツールボックス・ダイアログウィンドウが消えたときの戻し方｜GIMPの使い方講座！初心者のための分かりやすい解説](https://ameblo.jp/twiameuta/entry-11544719593.html)
1. ツールオプションのサイズを変更して、調整する。
機械学習における属性評価

#機械学習における属性評価
機械学習に使用する属性数が多い場合，過学習などにより，精度が低下する可能性があります．
これを防ぐために，属性が持つ情報量を評価し，重要な属性を選択する必要があります．

今回，WEKAを用いて属性評価するやり方および見方をまとめます．

#情報利得による属性評価
1. Select attributesタブを選択
2. Attribute Evaluatorをweka>attributeSelection>infoGainAttributeEvalに変更
3. Serch Methodをweka>attributeSelection>Rankerに変更
4. Attribute Selection Modeを選択．Cross-validationに変更することもできます
5. Startボタンをクリック

#結果（10Folds Cross-validationで行った場合）
average merit：高い方が重要（+-で10回の交差検定を行った結果の差を表示）
average rank：ランク（+-で10回の交差検定を行った結果の差を表示）
attribute：対象の属性

#まとめ
属性評価をすることによって，その属性がもつ情報量を比べることができます．
しかし，安易に下位の属性を除いてしまうと，精度が下がることもあるので注意が必要です．
npm-scripts　変数の使用方法

フロントエンド開発環境であるnpmにおいて、npm-scriptsのみで完結したい時、package.json内において、変数を使用したいと考えると思います。しかし、変数の使用方法についての記述を見つけることができなかったので、投稿いたします。
## 変数の定義
config内で変数名(key)を設定

```json
{
 "config": {
  "key": "value"
 },
 "scripts": {}
}
```
## 変数の使用
scripts内で$npm_package_config_keyとすると、展開される。

```json
{
"scripts": {
  "scriptName": "command $npm_package_config_key"
 }
}
```

参考：　[npmの公式ページにおける、package.jsonについて](https://docs.npmjs.com/files/package.json)
【開発環境】Dockerコンテナ上でGoアプリケーションをホットリロードさせる

## やりたいこと

Goで開発していて、変更するたびに手動でビルドするのが面倒なので、[fresh](https://github.com/pilu/fresh)を使って自動的にビルドさせたい。

## freshの再ビルドが遅い問題

https://github.com/pilu/fresh で `go build`　を使っていたので、代わりに `go install` を使うように変更しました。

https://github.com/Kooooya/fresh/commit/87fcc724df43aa4d025ebcf7e58953fcf5f52181#diff-6dd5d9d6e536da32c7aaef7fb2595774R18

これでビルドにキャッシュが効いてビルド時間が短くなりました。

## Dockerfile

Dockerfileをプロジェクトのルートに設置します。

```
FROM golang:1.9.3-alpine3.7

COPY . /go/src/github.com/hoge/fuga
WORKDIR /go/src/github.com/hoge/fuga

RUN apk update && apk upgrade && \
    apk add --no-cache git

# 必要に応じて
# RUN go get github.com/tools/godep && \
#    godep restore

RUN go get -u github.com/Kooooya/fresh
CMD ["fresh"]
```

## docker-compose.yaml

docker-compose.ymlをプロジェクトのルートに設置します。

```
version: '3.4'
services:
  app:
    build: ./
    environment:
      - MYSQL_HOST=mysql
      - REDIS_HOST=redis
      - ELASTICSEARCH_HOST=elasticsearch
    volumes:
      - ./:/go/src/github.com/hoge/fuga
    links:
      - mysql
      - redis
      - elasticsearch
    ports:
      - "3000:3000"
  mysql:
    image: mysql:5.7
    environment:
      MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
      MYSQL_USER: root
    ports:
      - "3306:3306"
  redis:
    image: redis:4.0.8
    ports:
      - "6379:6379"
  elasticsearch:
    image: elasticsearch:5.6.7
    ports:
      - 9200:9200
```

## fresh.conf.yml

fresh用の設定ファイルをプロジェクトのルートに設置します。

```
root_path: github.com/hoge/fuga
tmp_path: tmp # relative path from root_path
build_path: api # relative path from root_path
build_log_name: runner-build-errors.log
colors: "1"
ignored: tmp
log_color_app: ""
log_color_build: yellow
log_color_main: cyan
log_color_runner: green
log_color_watcher: magenta
valid_ext: .go
build_delay: "1000"
```

## Launch an Application

あとは起動するだけです。

```
docker-compose up -d redis mysql elasticsearch
docker-compose up app
```

シンプルな構成のアプリケーションだと以上のをほとんどコピペするだけで動くと思います。

## 補足

1. `tail -F tmp/runner-build-errors.log` でビルドエラーのログを見ることができる
ただただ、ブリンクするカーソルが欲しい場合のcss

### 初期値 lime
```css
/*<span class="ef-blink"></span>*/
.ef-blink:after{content:'|';color:lime}
.ef-blink{opacity: 1;animation: blink 1s infinite}
@keyframes blink{ 0%{opacity:1}50%{ opacity:0}100% { opacity:1} }
```
### あるいは__inherit__
```css
/*<label class="lime"><span class="ef-blink"></span></label>*/
.lime{color:lime}
.ef-blink:after{content:'|';color:inherit}
.ef-blink{opacity: 1;animation: blink 1s infinite}
@keyframes blink{ 0%{opacity:1}50%{ opacity:0}100% { opacity:1} }
```
【PHP】とりあえずAPIのスタブをパパっと作る

# とりあえずAPIのスタブつくろう
APIとのやり取りを実装するのに仮のAPIをパパっと作って、ささっと自分の実装する箇所をある程度作ろう
というのが事の始まりです

# スタブAPI
このPHPファイルを仮サーバーにおいてこいつと通信する。
例ではPOSTパラメータは`name`を受け取って、その値に対して`'_RECEIVED'`を付加して、時間とともにjsonにして返す
てな感じの処理をしてます。
また、受け取ったlogも出力するようにしてます。

```api.php
<?php
/* スタブAPIが受け付けるPOSTパラメーター：name */

// header('Access-Control-Allow-Origin: *'); // どこからでもアクセス許可するならワイルドカード
header('Access-Control-Allow-Origin: https://*******/post.php');
header('Access-Control-Allow-Credentials: true'); // Basic認証やCookieのやり取りする際は必要（ワイルドカード使用すると使えない）
header('Access-Control-Allow-Headers: Content-Type');
header('Content-Type: application/json; charset=utf-8');

date_default_timezone_set('Asia/Tokyo');

if(isset($_POST['name']) === false || $_POST['name'] === '') {
    $_POST['name'] = 'TEST_API';
}

$postName = htmlspecialchars($_POST['name'], ENT_QUOTES);

$array = [
    'name' => $postName . '_RECEIVED', // API側で受け取ったよというマーク的なやつを付加
    'date' => date("Y-m-d H:i:s"),
];

$json = json_encode($array);

/* logをAPI側のサーバーに出力する */
$file = new SplFileObject('log.txt', 'a');
$file->fwrite(
    "【→API】RequestParameter:" . $postName . "'\n【←API】ReturnParameter :" . $json . "\n----------\n"
);

echo $json;
exit;
```


単純に**api.php**にアクセスすると↓こんな感じで表示されるはず。
`{"name":"TEST_API_RECEIVED","date":"2018-02-08 13:47:14"}`


もし、呼び出し元でnameをPOSTすると
`{"name":"YOBIDASHI_RECEIVED","date":"2018-02-08 13:48:45"}`
みたいな感じで`name`のとこが**【POSTした値＋_RECEIVED】**に変わってるはず

# おわり
- `header`の設定箇所が不安なので指摘あれば教えてくださいです
- あとスタブって使い方あってます？

# 参考
- [PHPでJSONを返すAPIを作ってcURLでPOST送信して動作を確かめてみる - ゆっくり備忘録](http://mitsuakikawamorita.com/blog/?p=689)
- [スタブ【テスト】 (stub)とは｜「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](http://wa3.i-3-i.info/word14933.html)
Xampp / imagick導入方法

##■はじめに
別の方の記事を参考に導入を試みたが微妙に詰まったので、自分なりの補足を入れつつ書いてみる。
[xampp+PHP+Windows7でimagickを使う](https://qiita.com/joh/items/88dce4ea633127ac0b0c)

###■注意
xamppが32bitなので、導入するのも32bit(x86)になります。


##■imageMagicのダウンロード
[imageMagic](http://windows.php.net/downloads/pecl/deps/)からダウンロードする。

※コンパイラのバージョンにより、ダウンロードするものが変わりますので、ご注意ください。
MSVC11の場合、`ImageMagick-X.X.X-X-vc11-x86.zip`
MSVC14の場合、`ImageMagick-X.X.X-X-vc14-x86.zip`

当方、phpinfoにて確認したところ、MSVC11 (Visual C++ 2012) と判明したため、`ImageMagick-6.9.3-7-vc11-x86.zip`をダウンロードしました。


###■imageMagicのインストール
`C:\develop\xampp\`にファイルを置けばOKです。


##■imagickのダウンロード
[imagick](http://windows.php.net/downloads/pecl/releases/imagick/)からダウンロードする。

バージョンについては、今回、3.4.3をダウンロードしてみました。
バージョンが決まったところで、どれを落とせばいいか迷いましたが、下の基準で環境にあったものをダウンロードすれば問題ないようです。

`php_imagick-3.4.3-[PHPのバージョン]-[スレッドセーフ]-[コンパイラのバージョン]-x86.zip`

当方、phpinfoにて確認したところ、PHP Version 5.6で、Thread Safety : enabledと判明したため、`php_imagick-3.4.3-5.6-ts-vc11-x86.zip`をダウンロードしました。


###■imagickのインストール
ダウンロードしたzipを解凍し、開きます。
そして以下の2ファイルを操作します。

・`php_imagick.dll`
→ `C:/develop/xampp/php/ext/` にドラッグ&ドロップします。

・`CORE_RL_~~`（CORE_RLで始まる複数ファイルが対象です。）
→ `C:/develop/xampp/ImageMagick/bin/`にドラッグ&ドロップします。（CORE_RLで始まる全部をドラッグ&ドロップしてください。）


次に、`/xampp/php/php.ini`のDynamic Extensionsに` xtension=php_imagick.dll `を追記します。

```
;;;;;;;;;;;;;;;;;;;;;;
; Dynamic Extensions ;
;;;;;;;;;;;;;;;;;;;;;;
...
...
extension=php_imagick.dll 
```

##■環境変数の追加
最後に環境変数を追加したらおしまいです。
環境変数の追加手順の詳細は省かせていただきますが、pathにimageMagicフォルダのパスを書きます。

imageMagicフォルダまでのパスを
`C:\develop\xampp\ImageMagick`
こんな感じで追加すれば大丈夫です。

###■再起動
設定反映のため、パソコンを再起動します。

再起動完了後に、phpinfo()で、imagickが追加されていることを確認しましょう。
もしくは、コマンドプロンプトで、`php -i | find "imagick"`と入力して、下記の通り返ってくればOKです。

```
C:\develop\xampp\ImageMagick>php -i | find "imagick"
imagick
imagick module => enabled
imagick module version => 3.4.3
imagick classes => Imagick, ImagickDraw, ImagickPixel, ImagickPixelIterator, ImagickKernel
imagick.locale_fix => 0 => 0
imagick.progress_monitor => 0 => 0
imagick.skip_version_check => 0 => 0
```
Clojure: Herokuで強制的にHTTPS通信をさせようとしたらページが表示できない場合



## 症状

ring.middleware.ssl/wrap-ssl-redirectを使って強制的に接続をhttpsにしようとしたら、Heroku上のアプリでページが表示されなくなった。

## 解決

[Clojure: wrap-ssl-redirect on heroku?
](https://stackoverflow.com/questions/30689577/clojure-wrap-ssl-redirect-on-heroku) のコメントに対処法が共有されていた。

```clj
(defn wrap-force-ssl
  "Almost like in lib-noir. 
   If the request's scheme is not https [and is for 'secure.'], redirect with https.
   Also checks the X-Forwarded-Proto header."
  [app]
  (fn [req]
    (let [headers (:headers req)
          host    (headers "host")]
      (if (or (= :https (:scheme req))
              (= "https" (headers "x-forwarded-proto"))
              (not= "secure.mydomain.com" host)) ;you might not need this!
        (app req)
        (redirect (str "https://" host (:uri req)) :permanent)))))
```

※更新
自身の環境で上手く作動していないことに気づいたので[ringのソース](https://github.com/ring-clojure/ring/blob/23e72c046c53061bfa6067c78e6c5d5343e8b091/ring-core/src/ring/util/response.clj#L12)を確認したら、permanentの指定方法が違っていました。
なので、上記の`:permanent`は `:moved-permanently`にするか `:permanent-redirect`にするとよいです。
status codeの違いは[stackoverflowの説明](https://stackoverflow.com/a/42138726)がわかりやすいかったので、参考にして下さい。
更新ここまで。


lib-noirを使っている人はこのような関数があるようですのでそちらを使えばいいそうです(使ったことがないのでよく知らない)

あとは`wrap-ssl-redirect`と同じようにhandlerに渡してやればいい

```clj
(-> handler
    (wrap-defaults site-defaults)
    wrap-force-ssl)
```


※ ringの設定の変更(?)のためかredirectの設定が上手く作動していなかった旨を更新しました。
kintoneで複数フィールドを一度に上下に移動させる

kintoneでフォーム画面を修正する際、
「この3つのフィールドは全部最下部に移動させよう」
みたいなことがたまにありますが、
フィールド数が多いと、一つ一つドラッグするのが超手間がかかります。

そんな時、ちょっとしたハックでかなり効率が上がります。

* 新しいフォームグループを作成
* 移動させたいフィールドを一度全部グループ内に放り込む
* グループごと移動させる
* 移動先に到着したら全フィールドをグループから出す
* グループを削除する

どうだい？！ローテクだろぉ〜？w

全くプログラミングを伴わないので、Qiitaに書くべきでないのかもしれませんが、
意外と役立つと思うのでメモでした。
（画面キャプチャは面倒臭いので撮ってません。すんません。。。）

この辺を、もっとキッチリとツールでやるべく、
早く`ginue push`を完成させたいと思っとります。
そもそもginueについては、まだQiitaに書いてませんでしたね。
そのうち書きますので、今日はURLだけでご容赦w
https://github.com/TailsGarden/ginue
使わなくなったiPhoneとMESHアプリ単独で会議スペースの声量制限

プログラミング知識を共有するQiitaでノンプログラミングなMESHの投稿をします...笑
（MESH公式レシピに書いてるのですが、公開の仕方がわからずこちらにも書いています）

#経緯
- 新規PJが立ち上がり、そこに参加した私は、やる気に満ち溢れたメンバーとともに、熱気に熱気をぶつけるように議論を交わしていた。
- ふと我に返ると、執務スペースの真横にあるこのMTGスペース。めっちゃうるさくね...
- 周りから特に言われることはなかったけど、電話対応などしてるのを見ると、少し声量を落とした方が良いかと思った。
- ただ、周りに注意してもらうというのは、周りにかなりの心理的負担を強いることになるので、こちらで用意した。

#作り方
1. キャンバスの通りにレシピを作ります。
(IFTTTはお好みで。Slack連携など出来ます。)
   <img width="320" alt="b0f539a8782d460cd72bbdd2e959d680_1516960474362-1.png" src="https://qiita-image-store.s3.amazonaws.com/0/58496/1c8b0946-85c5-7d01-eb9e-e3513fd1dc44.png">
マイク: 音を感知したら(60-100)
タイマー: 10秒間隔
カウンター: 3回
スピーカー: 再生する(ここではベル音。お好みで。)
<br>

1. MTGスペースのそばに置きます。
<br>
1. 終わり

#運用
最初はマイクの感知値を低めにして、運用してみてください。
それから、反応しすぎない程度に、マイク感知値やタイマー間隔、置く位置を調整していくのがオススメ。

#効果
- ベルが鳴らないように控えめに盛り上がるようになった！(たまに鳴って反省)
- 社内で発表したら好評だった！
- 発表後に周りから「"ちょっと賑やかだな"とは思っていたんだよね。ありがたい。」と、腹割って話ができた！
Railsのrakeタスクの定義箇所を調べる

railsのrakeタスクがどこで定義されているか調べたい。

今回は`rake time:zones:local`の実装がどこで行われているか調べてみた。

`rails console`上で以下のようにすればよい。

```rb
> Rails.application.load_tasks
> Rake.application['time:zones:local'].actions.map(&:source_location)
#=> [["/.../.rbenv/versions/2.5.0/lib/ruby/gems/2.5.0/gems/railties-5.1.4/lib/rails/tasks/misc.rake", 40]]
```
MinAvgTwoSlice

内容理解は出来たけど、解くのが難しそう、というのが第一印象。二重ループが許されるなら正確性に
ついては満足させられると思うけど、計算量は `O(N)` 指定なので、不可。よって何かしら工夫が必要。
でも、とりあえず問題の理解が合っとるか確認するために、二重ループにて回答を作成した。

## [1st][a]

<table>
    <tr><th>Correctness</th><th>Performance</th><th>Task Score</th></tr>
    <tr>
        <td>100%</td>
        <td>20%</td>
        <td>60%</td>
    </tr>
</table>

```php
function solution($A) {
    $start_position = 0;
    $min_avg = (($A[0] + $A[1]) / 2);
    
    for($i = 0, $sum = 0, $avg = 0; $i < count($A)-1; $i++) {
        $sum = $A[$i];
        for($j = $i+1; $j < count($A); $j++) {
            $sum += $A[$j];
            $avg = $sum / ($j - $i + 1);
            if($min_avg > $avg) { 
                $min_avg = $avg;
                $start_position = $i;
                }
        }
    }
    
    return $start_position;
    
}
```

ノーテストで上手くいったから、気持ち良かった。思わずこれで終わろうとした。でも、本題はここから。
いかに `O(N)` で処理するか。

・・・なのだが、一日で解決しきれなかったので、解答を見る。

## 解答
[いつもの jimii さん][b]のものを解答としました。Thx.

<table>
    <tr><th>Correctness</th><th>Performance</th><th>Task Score</th></tr>
    <tr>
        <td>100%</td>
        <td>100%</td>
        <td>100%</td>
    </tr>
</table>

```php
function solution($A) {
   $length = count($A);
   $min_average = ($A[0] + $A[1]) / 2.0;
   $position = 0;
   if ($length==2) return 0;
   for ($i=2 ; $i < $length; $i++) {
       $temp1 = ($A[$i-1] + $A[$i]) / 2.0;
       $temp2 = ($A[$i-2] + $A[$i-1] + $A[$i]) / 3.0;
       if ($temp1 < $min_average) {
           $position = $i - 1;
           $min_average = $temp1;
       }
       if ($temp2 < $min_average) {
           $position = $i - 2;
           $min_average = $temp2;
       }
    }
    return $position;
}
```

今回、新たな発見を２つした。
一つは、[このページ][c]に書いてある。

> Codilityの例題PDFにかかれたprefix sumのアルゴリズムの工夫だけでとけるのかな？と思って、
> ずっと考えてたのですがどうやら違いそうだという事でググってしまいました。

**例題 PDF**？確かに、Lesson ごとに PDF があるのは知っとったけど、それに何か意味が？
と疑問に思いつつ見てみると、**Lesson に取り組む前に必読のものだ**ということが分かった。
（ただ、Prefix/Suffix sum 自体の概念が難しいため、要勉強・・・。）

もうひとつは、単に、この問題を解く際、**４つ以上のスライスを考慮する必要がないこと**。
つまり、２つの場合と３つの場合で最小となる平均値が全体でみても最小平均値。
ただ、飲み込めないのは、**「２つ／３つに分解した際の最小平均値より、分解する前の平均値の方が
小さいことはないのか？」**という疑問。

これは、問題の前提を考えれば分かる。
例えば、[1, 2, 3, 4] という配列の場合、`(1 + 2 + 3 + 4) / 4 = 2.5` であり、分解したスライスで
見ると、左部分は `(1 + 2) / 2 = 1.5` 、右部分は `(3 + 4) / 2 = 3.5` となる。
よって、この場合は左部分が最小の平均値を持つスライスであり、問題の答えは 1 になるのだが、
0 ≦ a ≦ b ≦ n (a は始点、b は終点、n は要素数) の条件で考えれば、上記の数列は考えられる
最小の数列であり、・・・。この後の説明が思いつかないし、これで合っているのかも怪しいが、
要は**４つ以上のスライスは２つまたは３つのスライスに分解でき、分解後のそれぞれのスライスの
平均値は、分解前のそれより必ず小さい**そうだ。なので、jimii さんの解き方のように、
`$A[$i-2]` から `$A[$i]` の範囲で２つまたは３つのスライスを `$i` を増分しながら計算し、
最小の平均値となったスライスの始点を返り値とすれば良い、のである。
恐らく `prefix sum` の大事な概念が使われていると思うが、今は理解出来ていないのでパスである。


悔しくて jimii さんのコードの `for` 文を `foreach` に置き換え、`$second_last` と `$last` なる
変数を用意し、ちょっと意味を分かりやすくしようとしたものの、明らかに jimii さんのように、
`$A[$i-2]`, `$A[$i-1]` と表記した方が分かりやすいしスッキリするしで、改変は諦めた。無念。

<!-- 以下、参考 URL -->
[a]: https://app.codility.com/demo/results/trainingUDJ8ER-VMG/
[b]: https://github.com/jimii/codility/blob/master/MinAvgTwoSlice/php/MinAvgTwoSlice.php
[c]: http://codility-lessons-jp.blogspot.jp/2014/07/lesson-3-minavgtwoslice.html
VSCode のターミナルで PATH 自動設定

VSCode v1.20 で[統合ターミナルの環境変数を自動設定できるようになった](https://code.visualstudio.com/updates/v1_20#_variables-resolved-in-env-setting)ので、これを利用して [npm](https://www.npmjs.com/) でローカルインストールした CLI を使えるようにしてみる。

```json:ユーザー設定
{
    "terminal.integrated.env.windows": {
        "PATH": "${workspaceRoot}\\node_modules\\.bin;${env:PATH}"
    },
}
```

簡単便利。
WEKAにおけるover-sampling

#WEKAにおけるover-sampling
収集したデータが均一でなく，不均衡データとなった場合，under-samplingやover-samplingを利用して，データ数を調整する必要があります．
今回はover-samplingをWEKAでどのように行うのかについて記述します．

#不均衡データとは
[sfchaos blog](http://d.hatena.ne.jp/sfchaos/20111202/p1)より引用

>クラス分類を実行する際の悩みどころの一つとして，クラス分類の興味の対象となるクラスのサンプル数が他のクラスと比べて少ないケースがよくあることが挙げられます．このようなデータは不均衡データと呼ばれます．
例えば，スパムメールかどうかの判別において，スパムであるサンプル数とスパムではないサンプル数．あるいは，ある重病に罹患する人を特定したい場合，その病気に罹患した人数と罹患していない人数．こうしたケースではクラス間でサンプル数に偏りがあるため，クラス分類の手法をそのまま適用しても十分な分類精度を得られないことが往々にしてあります

不均衡データのまま分類を行うと，分類精度に問題があるため，データ数の調整を行います．

#over-sampling
今回は,[SMOTE](https://www.jair.org/media/953/live-953-2037-jair.pdf)を利用します．

1. weka>filters>supervised>instance>SMOTEを選択．
2. 詳細設定からclassValueとpercentageを設定．

**classValue**：データ数を増やしたい分類データを指定．
**percentage**：増やすデータの割合を指定．100%の場合，元データの2倍となる．
3. Applyボタンを押してフィルターを適用．

#まとめ
WEKAでのover-samplingのやり方が動画でしか見つけられなかったため，まとめました．
また，SMOTEは初期ダウンロード時には含まれていないので，パッケージをダウンロードする必要があります．

#参考
[Weka Tutorial 04: Systematic Oversampling (Class Imbalance Problem)
](https://www.youtube.com/watch?v=w14ha2Fmg6U)
iOS11とiOS10でUILabelのAttributedの扱いがちょっと違う

# 環境

Swift 4
Xcode 9.2

# 本題

XibとかStoryboardでUILabelのTextをAttributedに設定した時に、コードで再度文字列を代入した時の挙動に関して、iOS10とiOS11で異なったのでメモ。


XibとかStoryboardでUILabelのTextをAttributedにしてから、LineHeightとかをいじって、以下のようにコードで文字列を代入するとiOS11だとAttributedがそのままだけど、iOS10では消えちゃう。

```swift

@IBOutlet private weak var label: UILabel!

self.label.text = "ほげほげ"
```

なので、iOS10でも動作させる場合は以下のようにNSAttributedStringを作り直して代入する必要がある

```swift
var range = NSMakeRange(0, self.label.attributedText?.string.count)
let attrs = self.label.attributedText?.attributes(at: 0, effectiveRange: &range)
self.label.attributedText = NSAttributedString(string: "ほげほげ", attributes: attrs)
```
<%= form_for @post do|f| %>は何が便利か

```new.html.erb
<%= form_for :post,url:posts_path do|f| %>
        <p>
            <%= f.label :title %><br>
            <%= f.text_field :title%>
        </p>
        <p>
            <%= f.label :body %><br>
            <%= f.text_area :body %>
        </p>
        <p><%= f.submit %></p>
 <% end %>
```
```edit.html.erb
<%= form_for :post,url:edit_path do|f| %>
        <p>
            <%= f.label :title %><br>
            <%= f.text_field :title%>
        </p>
        <p>
            <%= f.label :body %><br>
            <%= f.text_area :body %>
        </p>
        <p><%= f.submit %></p>
 <% end %>
```
のようにnew/editでurl送信先を変えるのがめんどさい＆ほとんど同じコードのformを二つ作るのはDRYに反する。
そこで、以下のように変更。
new/editは以下のようにpartialで_formに飛ぶ

```new/edit.html.erb
<%= render "form" %>
```
_formでは、<%= form_for @post do|f| %>と、@postにするだけでrailsが「newに送るべきか、editに送るべきか」を自動で判断してくれる。

```＿form.html.erb
<%= form_for @post do|f| %>
        <p>
            <%= f.label :title %><br>
            <%= f.text_field :title%>
        </p>
        <p>
            <%= f.label :body %><br>
            <%= f.text_area :body %>
        </p>
        <p><%= f.submit %></p>
 <% end %>
```
GCPのWordpressを無料でhttps化 [bitnami][ssl]


https://nkmrkisk.com/archives/1600
最初こちらの記事の方法でやってみたのですが、
うまくいかず。

https://www.onepagezen.com/free-ssl-certificate-wordpress-google-cloud-bitnami/
こちらの方法でやるとすんなりとできました。
特にこちらの方法以外にやったことはありません。


まずはこの手順をやる前にCloudLancherで
Wordpress（bitnami）をインストールしている必要があります。
参考：https://nkmrkisk.com/archives/1417


```markdown
wget https://dl.eff.org/certbot-auto && chmod a+x certbot-auto
```
こちらでCerbot-autoを取ってきて

```markdown
./certbot-auto certonly --webroot -w /opt/bitnami/apps/wordpress/htdocs/ -d YOUR_DOMAIN -d www.YOUR_DOMAIN
```
wwwを使ってなければ`-d www.YOUR_DOMAIN`のところはいらないと思います。




問題はこのやり方でSSL証明書を自動更新してくれるのか？
英語の読解力が足らずわかりません；
でも多分`cerbot-auto`って書いているから自動更新なんじゃなかろうか？

ちょっとわかってきた

```markdown
sudo crontab -e
```

```markdown
1
```

エンターして

```markdown
0 0 * * * ./certbot-auto renew --quiet --no-self-upgrade 
0 12 * * * ./certbot-auto renew --quiet --no-self-upgrade
```

のところで自動更新設定しているようですね。
Node Package Manager (npm)


```console:npmバージョン
$ npm --version
5.6.0
```

# 概要

**Node.js** アプリのパッケージ管理マネージャー

以下の機能を持つ

* パッケージの作成 (`npm init`)
* パッケージのインストール (`npm install` or `npm i`)
* パッケージのアンインストール (`npm uninstall`)
* スクリプトの実行 (`npm run-script` or `npm run`)
* 開発環境の表示・設定(`npm root`, `npm config`, `npm adduser`, ...)


# パッケージの作成 (npm init)

## 使い方

```console:パッケージの作成
$ cd hello_world
$ npm init

{
  "name": "hello_world",
  "version": "1.0.0",
  "description": "My first node app",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
```

* package.jsonが生成される
* オプション
	* `-y` 対話環境のスキップ


## package.json


|キー                   |説明|
|:----------------------|:------------|
|name                   |パッケージ名|
|version                |パッケージバージョン|
|description            |パッケージについての説明 (オプション)|
|main                   |エントリーファイル。<br> 他のパッケージからインポート(require)された際、mainファイルの **module.exports** が返り値となる。 <br> 実行モジュールの場合は、省略可能。(ただし省略しなければ `node .` で実行する事ができる。)|
|dependencies           |依存関係にあるパッケージの登録|
|devDependencies        |開発時のみに使用する依存関係パッケージの登録|
|optionalDependencies   |ある環境においてのみ必要となる依存関係パッケージの登録|
|scriipt                |スクリプトの登録|


# [パッケージのインストール (npm install)](https://docs.npmjs.com/cli/install)

## 使い方1 パッケージのインストール

```console:その他のパッケージのインストール
$ npm install `library`
```

* `npm i` と省略が可能

### オプション

|オプション名    |簡略スタイル |説明|
|:---------------|:------------|:---------|
|--global        |-g           |グローバル領域へのインストール|
|--save-prod     |-P           |インストールしたパッケージを **dpendencies** に追加する。(デフォルト値、version5以前の **--save** からの置き換え)|
|--save-dev      |-D           |インストールしたパッケージを **devDependencies** に追加する。|
|--save-optional |-O           |インストールしたパッケージを **optionalDepencies** に追加する。|
|--no-save       |             |dependenciesへの追加を防止する。 |


## 使い方2 再インストール

```console:再インストール
npm install
```

ライブラリーを指定しなければ、package.jsonを元に再インストールする。


# [パッケージのアンインストール (npm uninstall)](https://docs.npmjs.com/cli/uninstall)

```terminal
$ npm uninstall `library`
```

* -g オプションをつけるとグローバル領域から削除される


# [スクリプトの実行 (npm run-script)](https://docs.npmjs.com/cli/run-script)

```console:スクリプトの実行
$ npm run script_name
```

* スクリプト名が、 **"start"** の場合は、runを省略可。 `npm start` でOK。
* スクリプトの定義において、node_module配下のツールはパスが不要。

## スクリプトの登録

package.jsonの **scripts** キーに定義する。

```package.json
...
scripts: {
	"start: "node .",   // mainファイルは実行される
	"build": "webpack", // node_modules配下のツールはパスが不要
	"develop": "webpack -w"
},
```

# 開発環境の表示・設定

## node_modulesパスの表示 (npm root)

有効な **node_moduels** フォルダパスを表示する。

```console:node_modulesパスの取得
$ npm root
```

* -g オプションをつけるとグローバル領域の **node_modules** フォルダのパスが出力される

# 公式リファレンス

https://docs.npmjs.com/cli/

# 参考サイト

[[Qiita] ちゃんと使い分けてる? dependenciesいろいろ。](https://qiita.com/cognitom/items/acc3ffcbca4c56cf2b95)
flex でのセンタリングメモ

`display: flex`、便利なので何気なく使っている気がします。

人が組んでいるのをちょこちょこ触って気づきましたが、
Web サービスの UI の位置をセンタリングする場合、

- `align-items: center`
- `justify-content: center`

でセンタリングするより、
内部要素に `margin: auto` を当てた方が使い勝手が良いです。

flex 系のプロパティでセンタリングした物は、
画面サイズを小さくしたり要素を大きくして見切れるようにすると、
上側と左側へのスクロールができなくなります。

- [jsfiddle テスト](https://jsfiddle.net/x0t149b1)

内部でスクロール出来るか出来ないかだけの違いですが、
何気にウィンドウ系な UI を配置する場合、表示する術が無いと辛いケースが。

flex のプロパティを使いこなせば普通に回避できそうな気もしますが、
割とシンプルに回避できるので `margin: auto` がお勧めです。


~~**[追記：2018年8月30日]**~~
~~IE で `margin: auto` でのセンタリングが効かない様なので、
IE 対応が必要な物には利用しないほうが良いです。~~

**[追記：2019年1月1日]**
IE でも効いたので何かの勘違いだった？模様。
効かなかった気がするのだけど。。:frowning2:
JetPack 3.1 を Jetson TX1 で動かす時の注意

JetPack 3.1 を Jetson TX1 にインストールすると JETSON TX1 開発者キットの開発ボードの内蔵カメラ（/dev/video0）が認識されなくなる。

回避方法は[コチラ](https://devtalk.nvidia.com/default/topic/1019986/jetson-tx1/getting-errors-in-using-onboard-camera-jetpack-3-1-/2)。

普通、修正版出すでしょ。普通。

NVIDIA、ナメてる。
Flexboxを用いて汎用性の高いコンテンツスライダーを実装する


## Introduction

コンテンツスライダーは現在でもよく使われているUIコンポーネントです。
多くのjQueryプラグインがありますが、以下のような懸念点があります。

- 他のjQueryプラグインとの競合
- 画面デザインとの親和性

「作りたい画面に合いそうな、格好いいjQueryプラグインをやっとのことで見つけたけど、かゆいところがあるし他のjQueryプラグイン入れられない…」というような声を聞きます。

__Flexbox__を使うことで容易にコンテンツスライダーを作成することができますので、サードパーティ製のjQueryプラグインを使わず自作してカスタマイズしてみるのはいかがでしょうか。

## Goal


![ezgif.com-optimize.gif](https://qiita-image-store.s3.amazonaws.com/0/140939/4914ca67-d12a-6681-b1b8-09300c084032.gif)


https://codepen.io/s0tter/pen/WMwpXJ

## How to

### HTML

```html
<div class="container">
  <div class="content">
    <div class="image">
      <img src="画像ファイルのパス"/>
    </div>
  </div>
  <div class="content">
    <div class="image">
      <img src="画像ファイルのパス"/>
    </div>
  </div>
  <div class="content">
    <div class="image">
      <img src="画像ファイルのパス"/>
    </div>
  </div>
  ...
</div>
```

`container`クラスがコンテンツスライダーの大枠です。
`content`クラスはコンテンツスライダー内でスライドされるページです。

### CSS

```css
.container {
  display: flex;
  width: calc(100vw * 0.64 * 1.25);
  height: calc(100vh * 0.48 * 1.25);  
  overflow: hidden;
}
.content {
  min-width: 100%;
  min-height: 100%;
}
```

コンテンツスライダーのサイズを決めて(%でもOKです)、`display: flex`と`overflow: hidden`を指定します。スライドされるページにおいては、最小サイズをコンテンツスライダーのサイズに合わせます。これによりスライドが横に並んだ状態になります。

### Javascript

```javascript
const animate = () => {
  const container = document.querySelector('.container');
  var pos = container.scrollLeft;
  var end = container.scrollLeft + container.offsetWidth;
  var d = 2;
  if (pos === (container.scrollWidth - container.clientWidth)) {
    end = 0;
    d = -10;
  }

  var id = setInterval(frame, 5);
  function frame() {
    if ( (d <  0 && pos <= end)
      || (d >= 0 && pos >= end) ) {
      clearInterval(id);
    } else {
      pos+=d;
      container.scrollLeft = pos;
    }
  }
}

document.addEventListener("DOMContentLoaded", () => {
  setInterval(animate, 10000);
});
```

まず、`DOMContentLoaded`イベントをハンドリングし、setIntervalを用いて10秒おきにanimate関数を実行します。animate関数はスライドを行うメソッドです。

animate関数ではコンテンツスライダーを取得して現在のスクロール位置(scrollLeft)とコンテンツスライダーの横幅(offsetWidth)を加算した値をアニメーション終了位置として保持します。その後setIntervalを使って一定時間ごとにscrollLeftの値を更新します。終了位置に到達(または超過)した際に処理を終了(clearInterval)します。

上記例の変数dの値を変えるとアニメーションの速度が変化します。上記コードでは次のスライドに移るときは 2、最初のスライドに戻るときは 10 としています。

----

あとは好きなようにスタイリングしてください。

より複雑なアニメーションをする場合は、サードパーティ製ライブラリを__充分な検討をしてから__使用する方が良いと思います。

この実装は汎用性が高く、DOMContentLoadedイベントハンドラ内のsetIntervalを廃止し、ボタンのclickイベントハンドラでcontainer.scrollLeftを更新することでタブナビゲーションにすることもできます。

## Conclusion

jQueryプラグインは初期コストを抑える反面、ランニング・コストは大きくなりがちです。どのような構造になっているか理解していないと対策がうてなくなる可能性があるため、慎重に選択しなければなりません。

自作の方がシンプルになることもあるので試してみてはいかがでしょうか。

## Reference

[Simple Contents Slider | CodePen](https://codepen.io/s0tter/pen/WMwpXJ)
string.charCodeAt(n) < 256 との遭遇

`string.charCodeAt(n) < 256` という条件文と遭遇し、前後の文脈から「半角英数文字か否かの判断をしているのだろう」と推測したものの、具体的に何をどう判定しているのか分からなかったので調べた。

##.charCodeAt(n)メソッド
指定位置のUnicodeコードポイント（10進数）を返す
[String.prototype.charCodeAt() - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/charCodeAt)

## そもそもUnicodeとは

* 文字コード規格のひとつ。
 * 文字コードは文字集合と符号化（エンコード）方式から成る。
   * Unicodeは文字集合にあたる。
   * Unicode用の符号化方式としてUTF-8などが存在する。
* 多言語対応。文字種毎にブロックが分けられている。
* コードポイントは「U+」 の後に十六進法で表す

[Unicodeについて](http://maxy.osdn.jp/help/HTML/for_developers/unicode.html)
[文字コードの考え方から理解するUnicodeとUTF-8の違い](http://equj65.net/tech/charcode/)

## Unicodeコードポイント < 256 の意味
256未満つまり255＝0xFF以下ということで、UnicodeコードポイントU+0000～U+00FFの範囲に相当。

* [Unicode一覧 0000-0FFF](https://ja.wikipedia.org/wiki/Unicode%E4%B8%80%E8%A6%A7_0000-0FFF)

上記の表を見ると、半角英数も含まれているが、それ以外の記号・制御文字・英語以外の言語の文字も含まれていることが分かる。

ブロックとしては0000～007Fが**基本ラテン文字**、0080～00FFが**ラテン1補助**に相当。ラテン文字はこのほかに拡張A/Bブロックもあるので、`< 256は`**ざっくりラテン文字か否か**を判断していることに…。ざっくり過ぎる…。


##文字判定は正規表現かきっちり指定が分かりやすい 
ゆるふわ範囲指定は今回のように意図がブレて混乱が生じるので、例えば英数のみなら正規表現[a-zA-Z0-9]でチェックする方が何をしているか分かりやすい。
もしくはUnicodeコードポイントでも0031〜0039,0041〜005A,0061〜007Aのようにきっちり範囲指定するか。
Pythonの `==` と `is`

===

pythonでテストを書いていてオブジェクト（辞書）の比較で引っかかったのでメモ。

```shell
$ python
Python 2.7.11 (default, Oct  6 2016, 09:16:39)
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.38)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> a = { 'a' : 1 }
>>> b = { 'a' : 1 }
>>> a == b
True
>>> a is b
False
>>>
```


refs.

* https://www.python-izm.com/tips/difference_eq_is/
* https://qiita.com/i13602/items/6d8914e019c13e858c72
* http://dackdive.hateblo.jp/entry/2014/08/07/172135
ITエンジニアが組織図を作ろうとするとこうなる PlantUML

ITエンジニアが組織図や体制図を作ろうとすると、きっとこういう選択をするかなっていうお話と
PlantUMLを使ってみたっていうお話です。

# すとーりー

会社に所属していると組織やら体制やらがコロコロ変わったりしますよね？

組織図や体制図で私が今まで見たことあるのは、エクセルやパワポでシェイプを駆使して作られたものでした。
当然、組織改正や人事異動なんかがあったりすると修正が必要になります。

量が多い（大きな組織）と特に大変ですよね。
さらに分担して作業なんてしてたら、マージも大変だし最悪デグレします。

そして私はこう思う訳です。

* マージをもっと簡単にしたい！
* 差分だけ見れればいい！
* 誰かにチェックしてもらいたい！
* 社内向けなら見栄えなんて気にしない！
* もっとオープンに最新版が常に見れる状態にしてほしい！
* エクセル・パワポで組織図、体制図の管理なんてしたくない！
* etc...

そして、私は決断します。
エクセル・パワポは止めよう。すべてテキストで管理しよう。
gitで管理すれば、タグも付けられるし差分比較もマージもとても簡単にできるよね。

でも。。。やっぱり文字だけはやだな。
図でも確認したい。

そして使ってみようと思ったのが`PlantUML`。
テキストからUMLダイアログを作成するツールがあるので試してみようというお話です。

# PlantUMLについて

[PlantUML](http://plantuml.com/)

色々なダイアグラムを書けるみたい。

* シーケンス図
* ユースケース図
* クラス図
* アクティビティ図
* コンポーネント図
* 状態遷移図（ステートマシン図）
* オブジェクト図
* 配置図
* タイミング図

今回は、オブジェクト図を選択してみます。

# 使ってみた

```text
@startuml 組織図
object 代表

package グループA {
  object A部 #ccffe5 {
    #リーダーA
  }
  object B部 #ccffe5 {
    #リーダーB
  }
  object TeamA {
    +メンバー
    +メンバー
  }
  object TeamB {
    +メンバー
    +メンバー
    +メンバー
  }
}

package グループB {
  object C部 #ccffe5 {
    #リーダーC
  }
  object D部 #ccffe5 {
    #リーダーD
  }
  object TeamC1 {
    +メンバー
    +メンバー
  }
  object TeamC2 {
    +メンバー
    -メンバー
  }
}

代表 --> A部
代表 --> B部
代表 --> C部
代表 --> D部

A部 --> TeamA
B部 --> TeamB
C部 --> TeamC1
C部 --> TeamC2

A部 -[hidden]r- B部
C部 -[hidden]r- D部

@enduml
```

![組織図](http://www.plantuml.com/plantuml/png/SoWkIImgAStDuSfFoafDBb5uidlnYuKhkBWA4fEp4zDJ5HutRNZSlFfnyvx7pTCT5Qgv51IW2XrVDgzGK4vEJajBDGMBAoWeFsvU1LRP02GTWKAr2ELE19GxeIeFIKtCTOIgqtxSlF1ny-R7pHE0wh2Ae6bq8beZDgDgiNlU2TdppWHyuupgA1S2obqm_U1iIAxldOrmwjJ5vbb8Z2lewjg1unIPxuJ6TqRZW_p5nGLE2I0kEDAud92vJbpEo5ndGpI-4KnxT4PcIafgNcoHBiHMPtHHi5qEgNafmCGA0000)

# 所感

オブジェクトの数が少ないので、以外と簡単に出来た。
レイアウトも多少調整が可能なようなので、コメントを追加したり文字を強調したりすることでより見やすくすることもできると思う。

エクセルやパワポでの管理にお困りの方にいかがでしょうか？

PlantUMLのサイトにオンラインジェネレータがありますので、一度お試しください。

# 参考

* [PlantUML Cheat Sheet - Qiita](https://qiita.com/ogomr/items/0b5c4de7f38fd1482a48)
Slack — 分報を、荒らしちまった悲しみに。(失敗談)

Slackで分報を書いているが、始め方を失敗したので、ここにメモを残す。

# 失敗1. 一人専用チャンネルにしていた

「一人専用のチャンネルなので、ジョインはしないでください」と、チャンネルの説明に書いていた。

その理由は
「他の人がチャンネルにいると、緊張して思ったことが書けない」
「ジョインしなくても、気になった時に見てくれれば良い」
というものだった。

だがこれは思い違いだった。

ただでさえSlackのメッセージの流量は膨大だ。
「ジョインもしていないチャンネルを、わざわざ見る人」は、ほとんどいないということに気付いた。

途中で「一人専用チャンネル」というルールはやめにしたが、「稲浦さんの分報って、一人専用でしたよね？」というイメージはずっと残っていた。

# 失敗2. メモ替わりに何でも放り込んでいた

仕事上のメモをなんでもかんでも放り込んでいた。
他の人が見ても仕方ないようなものまで、作業履歴として残していた。

たとえば仕事の進みが思うように行かない日でも「ちゃんと仕事してる感」を出したかった。

だがこれは読者にとっては、まったくノイズにしかならない。

分報は「報」という文字が使われているけれど、同時に読み物でもある。
半分は自分のため。半分は読者のためでもある、という意識で書くのが良いかもしれない。

今はSlackでメモをとる時は、自分自身へのDMや、ひとりだけのシークレットチャンネルを使うようにしている。

# 失敗3. Twitter連携のやり方がマズかった

Twitterでツイートをすると、Slackにも同じメッセージが流れるようにしていた。

「社内だけに流れるより、パブリックに流れた方がお得じゃないか」「ずっと残るし、いつでも参照できるし」と思っていた。一石二鳥というか。
社内向けにだけ呟きを流す価値が、あまり分からなかった。
(もちろん社外に出して良いメッセージだけをツイートしていた。一般的な技術ネタとか)

さらに、Twitter自体を「読んだウェブページのメモ」にも使っていたので、さらに分報が混沌としてしまっていた。
分報は単なるTwitterの通知場所になってしまった。

これだけでは、分報が生きた感じがしない。
死んだ分報へようこそ。

なんというか、必ずしも「広い」ことが良いとは限らない。「狭さ」も価値だと思った。
パブリックなサービスにはパブリックの文化が、社内には社内の文化があると思うので、社内向けだけのつぶやき場所があっても良いのかもしれない。

いまもTwitterと連携させているが、そもそも大事なことしかTwitterでつぶやかなかったり、社内向けにしかつぶやけないようなことは分報に書いたりして、使い分けをしている。


# 追記

この反省を活かして、社内のSlackでQiitaのこの記事を共有したところ、数名の方が新しく分報に参加してくれた。








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Project Euler 24「辞書式順列」

これは閃きましたわぁ（ﾄﾞﾔｧ

## Problem 24 「辞書式順列」
順列とはモノの順番付きの並びのことである. たとえば, 3124は数 1, 2, 3, 4 の一つの順列である. すべての順列を数の大小でまたは辞書式に並べたものを辞書順と呼ぶ. 0と1と2の順列を辞書順に並べると
012 021 102 120 201 210
になる.
0,1,2,3,4,5,6,7,8,9からなる順列を辞書式に並べたときの100万番目はいくつか?

```python
def hoge(num):
    numbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
    ans = ''
    # 階乗の計算関数を定義
    f = lambda n: n * f(n-1) if n != 0 else 1
    # 総組み合わせ数（10!=3628800通り）より大きい数字の場合は即終了
    if num > f(len(numbers)):
        return
    # i = 9 → 1 でループ
    for i in xrange(len(numbers)-1, 0, -1):
        # 最初の数字を固定した場合の組み合わせ数を算出する
        # 最初のループではi=9のため9!通り
        combi_cnt = f(i)
        # このif分は2ループ目以降に通る
        if num == 0:
            ans += numbers.pop(-1)
            continue
        # 以下の計算でx+1番目の数字で始まるnum番目の数字が答えとなることが分かる
        # 最初のループでは x=2, num=274240 となるため、2で始まる274240番目が答えとなる
        # (num=0の場合はx番目の数字で始まる最後の組み合わせ)
        x, num = divmod(num, combi_cnt) # 商と余りがとれるdivmodを最近知った
        if num != 0:
            ans += numbers.pop(x) # listのindexは0からなのでちょっと気持ち悪いけどx+1ではなくx
        else:
            ans += numbers.pop(x-1)
        # 以降、同様にループしつつ1文字ずつ確定させていく
    # 最後に残った数字を付け加えて返却
    return ans + numbers[0]

print hoge(1000000)
```
itertools使っちゃいなよ、という甘い囁きが何度も脳内を駆け巡ってた。
頭の体操が目的なので出来るだけ便利系ライブラリは使わない方針です（今のところ）。
[WIP]GAのトラッキングが上手く行かないときに確認すること

#GAのトラッキング
webエンジニアをしているとよく聞く。
けどサービス作ったことない人はほとんど知らないはず。
GAについては各自調べてください。

設定する際に自分が詰まった所というか、常に公開しているサービスやドメインを持っている所に自由にアップして試していいよ
ってなっている人はいらないかもしれない。

結構詰まったてたくさん調べて自分が必要だった所を一箇所に集約しておこうかなと思いました。
時間がある時に更新。

##localhostでの試し方

##GAの設定はあっているか

##その他
Adblock系を入れてる人はOFFにして試してみましょう。
[iOS][Swift]JavaScriptと相互通信

WebViewでJavascriptとSwiftの双方向通信を行う方法です。

# JavascriptからSwiftのメソッドを実行する
## 基本的な使い方
### Swift
`UIWebView`ではなく、`WKWebView`を使用します。
`WKUserContentController`でJavaScriptで実行するコールバックを登録します。
実行されたコールバックは`WKScriptMessageHandler`の`userContentController`で受け取れます。
Javascript側で呼び出したコールバックは`message.name`で取得できます。

```swift
class ViewController: UIViewController, WKScriptMessageHandler {

    override func viewDidLoad() {
        super.viewDidLoad()

        let webConfig: WKWebViewConfiguration = WKWebViewConfiguration()
        let userController: WKUserContentController = WKUserContentController()
        userController.add(self, name: "hoge")
        webConfig.userContentController = userController
        let wkWebView = WKWebView(frame: frame, configuration: webConfig)
        self.view.addSubview(wkWebView)
    }

    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        if message.name == "hoge" {
            // do something
        }
    }
}
```

### Javascript

```javascript
window.webkit.messageHandlers.hoge.postMessage("");
```

## 値を受け渡したい場合
### Swift
`message.body`で取得できます。

```swift
class ViewController: UIViewController, WKScriptMessageHandler {

    override func viewDidLoad() {
        super.viewDidLoad()

        let webConfig: WKWebViewConfiguration = WKWebViewConfiguration()
        let userController: WKUserContentController = WKUserContentController()
        userController.add(self, name: "hoge")
        webConfig.userContentController = userController
        let wkWebView = WKWebView(frame: frame, configuration: webConfig)
        self.view.addSubview(wkWebView)
    }

    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        if message.name == "hoge" {
            let number = message.body as! String
            // do something
        }
    }
}
```

### Javascript
`postMessage`の引数に渡したい値をセットします。

```javascript
var number = 123;
window.webkit.messageHandlers.hoge.postMessage(number);
```

# SwiftからJavaScriptのメソッドを実行する
## 基本的な使い方
### Swift
`evaluateJavaScript`を使用してJavascript側で拡張したwindowオブジェクトを呼び出します。

```swift
wkWebView.evaluateJavaScript("window.hoge();", completionHandler: nil)
```

### Javascript
windowオブジェクトを拡張することでSwift側からの呼び出しを受け付けます。

```javascript
window.hoge = function() {
  // do something
}
```

## 値を受け渡したい場合
### Swift
通常のメソッドを呼び出すのと同じように引数を渡して呼びます。
※呼び出すメソッド自体を文字列にする必要があるので、「\\()」もしくは「+」で連結します。

```swift
wkWebView.evaluateJavaScript("window.hoge(\(number));", completionHandler: nil)
```

### Javascript

```javascript
window.hoge = function(number) {
  // do something
}
```
Swiftでクロージャを書く時に循環参照を避けつつ安全に非Optionalにしてみる

ギョムでコードを書いていて、質問が来て、どうやら認知度は高くないというテクだったらしいので折角なのでシェアしてみる。

Swiftでのクロージャの構文はこう。

```swift
class Foo {
  func bar() {
    let x: (Int) -> Int = { a in a + 1 }
  }
}
```

引数をinの前に列挙する。宣言時に参照可能な変数をキャプチャすることも出来る。この時対象のretain countが増える。

```swift
class Foo {
  func bar() {
    let b = 2
    let x: (Int) -> Int = { a in a + b }
  }
}
```

retain countが増えるので、`self`を参照し、クロージャをキャプチャしてしまうと循環参照が生まれることがある。

```swift
class Foo {
  var inc: Int = 2
  var myClosure: ((Int) -> Int)?

  func bar() {
    myClosure = { a in a + self.inc } // self <-> myClosure の循環参照ができる。
  }
}
```

これを避けるのに一般に使われる方法が、`unowned`, `weak`だ。前者はクラッシュの危険があり、後者はOptionalになる。
これらを用いて最も安全に書くなら、 `weak`と`guard`を組み合わせる方法だろうか。

```swift
class Foo {
  var inc: Int = 2
  var myClosure: ((Int) -> Int)?

  func bar() {
    myClosure = { [weak self] a in 
     guard let `self` = self else { fatalError() } // 発生しないと保証する。こうするならunownedでも良い。
     return a + self.inc 
    }
  }
}
```

実は`let`プロパティなら、変更されないことが保証されているため、`weak`も`unowned`も使わない方法がある。

```swift
class Foo {
  let inc: Int = 2
  var myClosure: ((Int) -> Int)?

  func bar() {
    myClosure = { [inc] a in a + inc }
  }
}

```

キャプチャされるのはincなので、`self`のリテインカウントは増えない。
`inc`は値型なのでこの場合はクロージャの宣言時にコピーされる。

注意が必要なのが、プロパティを`var`で宣言している場合、クロージャの宣言時に存在したプロパティを対象にしているので変更しても反映されなくなってしまうという点。これはプロパティの種類が値型かクラスであるかは関係なく、どちらでも発生する。`let`に限定して使うのが良いだろう。

クロージャの中に「init以降変更することのないプロパティ」を渡したい、という場面は多くあるはず。
毎回`guard`して長いコードを書いたり、`unowned`を使ってクラッシュに怯えるならば、この方法使ってみては如何でしょうか。
Dartを使って、Flutter と Html5 上で File のRead/Writeをしたみた。

Dart は、 サーバーサイド、 Html5、 iOS、 Android で 動作します。
Android と iOS は [Flutter](https://flutter.io/) を利用します。 Html5 は [WebDev](https://webdev.dartlang.org/)を利用します。

残念ながら、Web用、スマートフォン用で APIが違います。
そこで、Html5 と Flutter で、同じInterface で 動作する　File Package を作成してみました。 

# ことはじめ
今、実験的に Html でも、 Flutter でも動作可能な、ゲームフレームワークを、作成しています。

ゲームだと、「画像データのCacheしたり」、　「ゲームの記録を保存したり」する必要がでてきます。Key-ValueやSWのCacheなどを利用したりすることになります。


今回は、 Html5 の FileSystem API を利用して、Html5側を実装しました。


# こんな感じにした

https://github.com/kyorohiro/umiuni2d_io

Interface を以下のように切りました。

```:interface.dart
abstract class Entry {
  String get name;
  String get path;
  Future<bool> isDirectory();
  Future<bool> isFile();
}

abstract class Directory extends Entry {
}

abstract class File extends Entry {
  Future<int> writeAsBytes(List<int> buffer, int offset);
  Future<List<int>> readAsBytes(int offset, int length);
  Future<int> getLength();
  Future<int> truncate(int fileSize);
}

abstract class FileSystem {
  Future<FileSystem> mkdir(String path);
  Future<FileSystem> rm(String path,{bool recursive: false});
  Stream<Entry> ls(String path);
  Future<Entry> wd();
  Future<FileSystem> cd(String path);

  Future<FileSystem> checkPermission();
  Future<Directory> getHomeDirectory();

  Future<bool> isFile(String path);
  Future<bool> isDirectory(String path);
  Future<Entry> getEntry(String path);
}
```

で、Html5とFlutterで動作させてみました。

![s_Screenshot_20180207-012858.png](https://qiita-image-store.s3.amazonaws.com/0/54192/961e03bd-a617-8b5e-c8d1-661750f55156.png)



おわり


# REF

ということで、 Html5 と Flutter 上で動作する Audio Package 
https://github.com/kyorohiro/umiuni2d_io/

以下でもアレコレ書いています。
https://medium.com/@kyorohiro_72753/file-api-with-dart-for-flutter-and-html5-59ee89f5f5b5


### INFO FILESYSTEM API IS DEPRECATED?
https://github.com/w3c/filesystem-api/issues/8
Apacheのmod_brotliをインストールしてみる

以前から気になっていたbrotli。
[Googleが開発したというこの新しい圧縮技術](https://github.com/google/brotli)を使って、ウェブページの配信をもっと速くできないかと思い、いろいろ調べてみました。

結論から言うと、既存の圧縮技術であるGzipに対して、圧縮後のサイズで優位性はあるとしても
私が現在携わっている環境、Amazon LinuxにyumでインストールしているApacheでは対応していないため
インストール方法を切り替えてまで採用するほどではないと思いました。

今回はbrotli、及びApacheのmod_brotliのLinux環境でのインストールについてまとめたいと思います。
また、gzipとの比較としてベンチマークも実施したので、それについては後日別の記事にてご紹介できればと思います。

[apacheの公式ドキュメント](https://httpd.apache.org/docs/2.4/mod/mod_brotli.html)を確認すると
Apacheの2.4.26以上で利用できるようです。

私が携わっている環境(Amazon Linux)にyumで入っているhttpdは2.4.25で、アウトでした。
新しいバージョンがないか調べてみると

```
$ yum info httpd24
Installed Packages
Name        : httpd24
Arch        : x86_64
Version     : 2.4.27
Release     : 3.75.amzn1
Size        : 4.1 M
Repo        : installed
From repo   : amzn-main
Summary     : Apache HTTP Server
URL         : http://httpd.apache.org/
License     : ASL 2.0
Description : The Apache HTTP Server is a powerful, efficient, and extensible
            : web server.
```
2.4.27、ということでいけそうです。

`yum update httpd24`でアップデートさせます。

gzip圧縮のモジュールであるmod_deflatellのように
`SetOutputFilter BROTLI_COMPRESS`
をconfファイルに追記して再起動します。

ところがブラウザで確認してみるも、レスポンスヘッダーには"br"の文字列がありません。
圧縮がかかっていないようです。
そこでapacheのエラーログを見てみると、

```
an unknown filter was not added: BROTLI_COMPRESS
```

というエラーが出力されていました。
そこで/etc/httpd/modules配下を探してみるもmod_brotli的なものはありません。
yumでアップデートしても入っているわけじゃないみたいですね。

ということでソースからインストールしてみようと思います。

## mod_brotliをソースからコンパイルしてインストール

まずは[brotliのレポジトリ](https://github.com/google/brotli)をクローンします。
記載されている手順通り、cmakeでインストールします。
(cmakeはなかったので`yum install cmake`してます)

```
git clone https://github.com/google/brotli
mkdir out && cd out
../configure-cmake
make
make test
make install
```
これで`/usr/local/bin`にbrotliがインストールされます。

次にApache Httpdをソースからコンパイルしてインストールします。

http://ftp.riken.jp/net/apache//httpd/httpd-2.4.29.tar.bz2

こっからソースをダウンロードして伸長。
思えばapacheをソースからインストールしたのは初めてです。

brotliを使いたいので`--with-brotli`オプションを指定してconfigureします。

```
./configure --with-ssl --with-mpm=prefork --enable-rewrite --with-brotli=/usr/local
make
make install
```

すると`/usr/local/apache2`にhttpdがインストールされます。httpd.confを見ると

```
#LoadModule brotli_module modules/mod_brotli.so
```

があるので、こいつをコメントイン。modulesの下を探してみると。

`/usr/local/apache2/modules/mod_brotli.so`

があるのを確認できると思います。
いよいよapacheを起動してみようと思います。

```
/usr/local/apache2/bin/apachectl -t
httpd: Syntax error on line 106 of /usr/local/apache2/conf/httpd.conf: Cannot load modules/mod_brotli.so into server: libbrotlienc.so.1: cannot open shared object file: No such file or directory
```

何かがうまく行っていないようです。
ここで結構つまづいたのですが、調べてみたところ
[ライブラリ関係がうまくいってなかったようです](https://blog.apar.jp/linux/7956/#Brotli-)。

```
echo /usr/local/lib > /etc/ld.so.conf.d/usr-local-lib.conf
ldconfig
```

これできちんとapacheがmod_brotli.soを認識してくれるようです。

適当なconfファイルに以下を追記する。

```
SetOutputFilter BROTLI_COMPRESS
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-brotli
```

ブラウザで確認すると・・・。

<img width="235" alt="レスポンスヘッダーのContent-Encodingのところにbrがあるのが確認できる" src="https://qiita-image-store.s3.amazonaws.com/0/237077/ec8c25c5-a765-1ff2-1173-61ae3ba559e1.png">

Response Headerの"Content-Encoding"のところに"br"が見えました！
[Gzipとの比較をしてみました。](https://qiita.com/takeshi_nozawa/items/562bf0ea378e0a327b66)
CentOS7に手軽にそこそこ新しめのElixirをインストールする

現在, yumのepelリポジトリで公開されているerlangとelixirは

```
> yum info erlang
...
バージョン          : R16B

> yum info elixir
...
バージョン          : 0.12.5
```

とまあ、だいぶ古いものになっています.
(これを書いている時点での, erlangの最新バージョンは20.2, elixirの最新バージョンは1.6.1)

ちょっと触ってみるにしても, これは古すぎるし, かといってソースからコンパイルするのもちょっと…
と思っている人は, [FedoraCoprで公開されているこちらのリポジトリ](https://copr.fedorainfracloud.org/coprs/ynishi/elixir/packages/)を使ってみましょう.

リポジトリの追加手順は以下の通り

```
> curl -OL https://copr.fedorainfracloud.org/coprs/ynishi/elixir/repo/epel-7/ynishi-elixir-epel-7.repo
> sudo mv ynishi-elixir-epel-7.repo /etc/yum.repos.d
>
>yum info erlang
バージョン          : 18.3.4.1
>
> yum info elixir
...
バージョン          : 1.3.1
```

後は, 通常通り`yum install`するだけ

```
> sudo yum install erlang
...
> erl --verison
Erlang/OTP 18 [erts-7.3.1] [source] [64-bit] [smp:2:2] [async-threads:10] [hipe] [kernel-poll:false]
>
>
> sudo yum install elixir
...
> elixir --version
Erlang/OTP 18 [erts-7.3.1] [source] [64-bit] [smp:2:2] [async-threads:10] [hipe] [kernel-poll:false]

Elixir 1.3.1
```

このように, 完全な最新版とはいえないまでも, erlang18+elixir1.3というそこそこ新しめな環境が
ソースからビルドするよりははるかにお手軽に構築することができます.
Elixirに興味はあるけどyumで公開されているバージョンが古すぎて断念していた方も
これを機会に触ってみてはいかがでしょうか？
Oracle OWNER, OBJECT_TYPE, STATUS毎の件数取得

```SQL:count_objects.sql
--
-- OWNER, OBJECT_TYPE, STATUS毎の件数取得
--
SET ECHO OFF
SET FEEDBACK OFF
SET LINESIZE 120
SET PAGESIZE 50000
SET TAB OFF
SET TERMOUT OFF
SET TRIMSPOOL ON
-- SPOOL pass includes CONNECT_IDENTIFIER, USER_NAME and SYSDATE
COLUMN USER_NAME    NEW_VALUE USER_NAME
COLUMN SYSTEM_DATE  NEW_VALUE SYSTEM_DATE
SELECT USER || '_' AS USER_NAME
     , TO_CHAR(SYSDATE, 'YYYYMMDD_HH24MISS') AS SYSTEM_DATE
FROM DUAL ;
SPOOL count_objects_&&_CONNECT_IDENTIFIER._&&USER_NAME&&SYSTEM_DATE..log
-- Windows ↑,  UNIX/Linux では ↓ を有効に
-- SPOOL count_objects_\&&_CONNECT_IDENTIFIER._\&&USER_NAME\&&SYSTEM_DATE..log
COLUMN OWNER        FORMAT A15
COLUMN OBJECT_TYPE  FORMAT A21
COLUMN STATUS       FORMAT A10
COLUMN COUNTS       FORMAT 999,990
BREAK ON OWNER SKIP 1 ON OBJECT_TYPE
SELECT
    NVL(OB.OWNER      , 'OWNER TOTAL')       AS OWNER
  , NVL(OB.OBJECT_TYPE, 'OBJECT_TYPE TOTAL') AS OBJECT_TYPE
  , NVL(OB.STATUS     , 'STATUS TOTAL')      AS STATUS
  , COUNT(*) AS COUNTS
FROM DBA_OBJECTS OB
WHERE OB.OWNER NOT IN  -- 今回はOracle側スキーマを除く。お客様によってはこれで良いかは保証の限りではない。笑い
    (
    'ANONYMOUS'
  , 'APEX_030200'
  , 'APEX_040000'
  , 'APEX_040200'
  , 'APEX_PUBLIC_USER'
  , 'APPQOSSYS'
  , 'AURORA$JIS$UTILITY$'
  , 'AURORA$ORB$UNAUTHENTICATE'
  , 'CLUSTER_MONITOR'
  , 'CTXSYS'
  , 'DBSNMP'
  , 'DIP'
  , 'DMSYS'
  , 'EXFSYS'
  , 'FLOWS_FILES'
  , 'LBACSYS'
  , 'HR'
  , 'MDDATA'
  , 'MDSYS'
  , 'MGMT_VIEW'
  , 'OAS_PUBLIC'
  , 'ODM'
  , 'ODM_MTR'
  , 'OE'
  , 'OLAPSYS'
  , 'ORACLE_OCM'
  , 'ORDDATA'
  , 'ORDPLUGINS'
  , 'ORDSYS'
  , 'OSE$HTTP$ADMIN'
  , 'OUTLN'
  , 'OWBSYS'
  , 'OWBSYS_AUDIT'
  , 'PERFSTAT'
  , 'PM'
  , 'PUBLIC'
  , 'PUBUSR1'
  , 'QS'
  , 'QS_ADM'
  , 'QS_CB'
  , 'QS_CBADM'
  , 'QS_CS'
  , 'QS_ES'
  , 'QS_OS'
  , 'QS_WS'
  , 'REPADMIN'
  , 'RMAN'
  , 'SCOTT'
  , 'SH'
  , 'SI_INFORMTN_SCHEMA'
  , 'SPATIAL_CSW_ADMIN_USR'
  , 'SPATIAL_WFS_ADMIN_USR'
  , 'SYS'
  , 'SYSADM'
  , 'SYSMAN'
  , 'SYSTEM'
  , 'TRACESVR'
  , 'TSMSYS'
  , 'WEBSYS'
  , 'WK_TEST'
  , 'WKPROXY'
  , 'WKSYS'
  , 'WMSYS'
  , 'XDB'
  , 'XS$NULL'
    )
AND OB.OBJECT_NAME NOT LIKE 'BIN$%' -- except trash box, since Oracle10.1.0, DBA_OBJECTS にも DROPPED列が欲しい
AND OB.OBJECT_NAME NOT IN
        (
        'CHAINED_ROWS'  -- except Oracle side table
      , 'EXCEPTIONS'
      , 'PLAN_TABLE'
      , 'PLAN_TABLE$'
        )
GROUP BY CUBE
    (    ----
    OB.OWNER
  , OB.OBJECT_TYPE
  , OB.STATUS
    )
ORDER BY
    OB.OWNER
  , OB.OBJECT_TYPE
  , OB.STATUS ;
SPOOL OFF
COLUMN OWNER        CLEAR
COLUMN OBJECT_TYPE  CLEAR
COLUMN STATUS       CLEAR
COLUMN COUNTS       CLEAR
CLEAR BREAKS
SET ECHO ON
SET FEEDBACK ON
SET LINESIZE 80
```
Pandas Error: Exception: cannot handle a non-unique multi-index!

pandasで、マルチインデックスを持つDataFrame同士を結合したらしようとしたらタイトルのようなエラーが発生した.

```
pd.concat([df1, df2, ...], axis=1)
```

エラーの意味は、インデックスに重複があるからconcatを実行できないよという内容だったので、実際に調べたら幾つかのDataFrameのインデックスに重複があることが判明。
indexの重複除去はストレートな関数が用意されていなさそうなので、DataFrameを読み込むときにあらかじめ重複を削除することによって解決。

```python:解決策1
def read_csv_wrap(f):
    df = pd.read_csv(f).pipe(
        lambda d: d.drop_duplicates(
            list(d.columns[:3]), keep='first'
        )
    ).pipe(
        lambda d: d.set_index(
            list(d.columns[:3])
        )
    )
    return df
```

ちなみに、DataFrameをindexをkeyにして順番にmergeしていくことによって、重複があってもエラーなく連結することができた

```python:解決策2
df_merged = data_frames[0]

for df in data_frames[1:]:
    df_merged = df_merged.merge(df, left_index=True, right_index=True, how='outer')
```

このばあい、`df_merged`は重複したindexを残したままだったので、重複行を残す必要がことさらない場合一つ目の解決法がベター

pandasのマルチインデックスは仕様が謎だし扱いが難しい...
スタティックライブラリ(静的ライブラリ) .a を複数結合するには


### スタティックライブラリを複数結合する

#### libA.aとlibB.aの複数のライブラリを結合して、libZ.aというライブラリを作成します

```console
$ ar cqT libZ.a libA.a libB.a
```

作成されるファイル(libZ.a)はthin archive形式です。
以下の情報を保持しているだけで、この段階では実体そのものは含んでいません。

・シンボルテーブル
・元ファイルのパス

#### thin archive形式のファイルをarコマンドで変換する

arコマンドに "-M" オプションを付与することでarをインタプリンタモードで起動し、以下を実行します。

```console
$ ar -M
AR >create libZ.a
AR >addlib libA.a
AR >addlib libB.a
AR >save
AR >end
```
libZ.aの容量も変わると思います。これで、実体を含んだスタティックライブラリが完成します。

インタプリンタモードで実行せず、echoコマンドを利用する場合は以下。

```console
$ echo -n -e "create libZ.a\naddlib libA.a libB.a\nsave\nend" | ar -M
```


### Makefileで行う場合
```Makefile
libZ.a: libA.a libY.a
    $(RM) $@
    $(AR) cqT $@ $^
    echo -n -e "create $@\naddlib $@\nsave\nend" | ar -M
```