OmniAICreator/Qiita-1.07M huggingface dataset:
ioDrive2 インストール

#ドライバダウンロード
[dellのダウンロードページ](http://dell.fusionio.com/)からLinux_rhel-6->3.2.6-Dellを選択・以下ファイルをダウンロード

- fio-common-3.2.6.1212-1.0.el6.x86_64.rpm
- fio-firmware-dell_iodrive-3.2.6.20131118-1.noarch.rpm
- fio-sysvinit-3.2.6.1212-1.0.el6.x86_64.rpm
- fio-util-3.2.6.1212-1.0.el6.x86_64.rpm
- iomemory-vsl-3.2.6.1212-1.0.el6.src.rpm
- libvsl-3.2.6.1212-1.0.el6.x86_64.rpm 

#インストール
```
#インストール(kernel module/utility/firmware) 
rpm -ivh *.rpm
#firmwareアップデート 
 fio-update-iodrive /usr/share/fio/firmware/dell_iodrive_3.2.6-20131118.fff
 shutdown -r now
#ドライバビルド
 cd ~/rpmbuild/SPECS/
 rpmbuild -bb fio-driver.spec
 cd ../RPMS/x86_64
 rpm -ivh io*
 modprobe iomemory-vsl
 fio-status
#フォーマット
 fio-detach /dev/fct0
 fio-format /dev/fct0
 fio-attach /dev/fct0
#ファイルシステム作成・マウント
 yum install kmod-xfs xfsprogs
 mkfs.xfs /dev/fioa
 mkdir /fio
 mount /dev/fioa /fio
 vi /etc/fstab
 （以下追加）
 /dev/fioa               /fio                    auto    defaults        0 0
```
jedi-vim対応 pythonコンパイルオプション

--with-features=huge --enable-multibyte --enable-pythoninterp=yes --enable-tclinterp --enable-cscope --enable-fontset --enable-gui --enable-gnome-check --without-x --enable-gpm --disable-darwin --disable-netbeans --disable-selinux --with-python-config-dir=/usr/local/lib/python2.6/config
ssh パスワードなし認証

#鍵作成
ssh-keygen -f ~/.ssh/id_rsa.remote
全部空リターン

#公開鍵をリモートサーバに追加 †
remote$ cat id_rsa.remote.pub >> ~/.ssh/authorized_keys
remote$ chmod go-rwx ~/.ssh/authorized_keys

#リモートサーバで遠隔実行 †
ssh -i ~/.ssh/id_rsa.remote remote ls
ThinkPad X1 Carbon(2017) + Windows10環境でトラックポイントの中クリックとスクロールを両立する

# 背景
ThinkPad X1 Carbonを使い始めたが、中央ボタンがスクロールと中クリックが排他になっている。
TPMiddleというソフトも見つけたが、うまく動作せず。
代替手段を考えた。

# 対策方法
1. 中央ボタンの設定を"中央クリックに変更。
![tp1.PNG](https://qiita-image-store.s3.amazonaws.com/0/212876/ef39b3cd-914c-6799-6785-352ff3c55393.png)

2. [W10Wheel.NET](https://github.com/ykon/w10wheel.net)を導入。
タスクトレイのアイコンより、Trigger->MiddleDragを選択。
![tp2.png](https://qiita-image-store.s3.amazonaws.com/0/212876/028e73b7-d8d6-546b-59fb-18956904e707.png)

3. W10Wheel.NETのスタートアップ設定
W10Wheel.NETは常駐させておく必要があるが、単純に登録した場合、管理者権限で起動しているアプリで使用できない。
よって、タスクスケジューラを使って、管理者権限で自動起動させる。
![tp3.png](https://qiita-image-store.s3.amazonaws.com/0/212876/fe6cb8ea-11a4-5b10-dba5-d7274295ddc4.png)
![tp4.png](https://qiita-image-store.s3.amazonaws.com/0/212876/571bbbe6-ba81-97b8-3325-b22154981fb1.png)
![tp5.png](https://qiita-image-store.s3.amazonaws.com/0/212876/a1d734de-9c18-8737-072a-19f86f4558ee.png)

# 使用
中央ボタンを単独で押せば中クリック、中央ボタンを押しながらドラッグすればスクロールします。
外付けマウス等の中クリックもスクロールになる点に注意です。
うざったいときはW10Wheel.NETの"Pass mode"で一時的に無効にします。
git基本

#概念図
レポジトリ登録
`work dir->(git add)->index->(git commit)->local repository->(git push)->remote repository`

レポジトリ参照
`remote repository->(git pull)->local repository->(git checkout)->work dir`

#使用法
作業ディレクトリ作成
`mkdir /path/to/your/project`
`cd /path/to/your/project`
レポジトリ初期化
`git init`
リモートレポジトリ登録
`git remote add origin https://hoge@bitbucket.org/hoge/test1.git`
origin=リモートレポジトリのalias。慣習的にoriginというだけでunkoとかでもいい

レポジトリに作業ファイル登録
`echo "# This is my README" >> README.md`
`git add README.md`
ローカルレポジトリにコミット
`git commit -m "First commit. Adding a README."`
リモートレポジトリにプッシュ
`git push -u origin master`
netflowエントリ表示 on IOS

```
swname#sh flow monitor m1 cache format table
Load for five secs: 10%/2%; one minute: 9%; five minutes: 9%
Time source is hardware calendar, *12:04:06.868 JST Fri * *
  Cache type:                               Normal
  Cache size:                                 1000
  Current entries:                               1
  High Watermark:                                1

  Flows added:                                2543
  Flows aged:                                 2542
    - Active timeout      (    60 secs)       2542
    - Inactive timeout    (    30 secs)          0
    - Event aged                                 0
    - Watermark aged                             0
    - Emergency aged                             0

INTF INPUT            ipv4 src addr    ipv4 dst addr    trns src port  trns dst port  tcp flags  intf output                bytes        pkts    time first     time last  ip prot
====================  ===============  ===============  =============  =============  =========  ====================  ==========  ==========  ============  ============  =======
Po2                   x.x.x.x  x.x.x.x           32254             53  0x1A       Po4                         9578          97  12:03:58.865  12:04:01.865       17
```
温度センサ選定

- デジタル(I2C）
 - Pros:工場出荷時時点でキャリブレーション済み（アキュレーション±2度以内）・周辺環境（ノイズ・アナログ回路）によって誤差の発生無し
 - Cons:部品単価高い。
 - 相対湿度および温度センサ「Si701x/702x」ファミリ[Si7020 Datasheet:](https://www.silabs.com/Support%20Documents%2fTechnicalDocs%2fSi7020.pdf)
 - SHT-11ライブラリ
 - SHT-11使用法
 - 基板実装
  - Si Labs、相対湿度および温度センサ「Si701x/702x」ファミリを発表
Si7013/20/21 2nd Generation Relative Humidity and Temperature Sensors
- [アナログ](http://forum.arduino.cc/index.php/topic,19961.0.html)
 - Pros:部品単価安い。(100円から）
 - Cons:誤差多め(±3度）
 - [テスト基板作成](http://www.m-mes.co.jp/index.html)
VeeValidateで日付のバリデーションをする

Vue.jsのフォームバリデーションであるVeeValidateで、日付のバリデーションをする手順を書いていく。

VeeValidate : http://vee-validate.logaretm.com/

# moment.jsを入れる
VeeValidateの日付処理にはmoment.jsが必要なためインストールする。

moment.js : https://momentjs.com/

```
$ npm install moment --save
```

インストールしたら、以下のようにして設定。

```app.js
import Vue from 'vue';
import moment from 'moment';
import VeeValidate, { Validator } from 'vee-validate';

Validator.installDateTimeValidators(moment);
Vue.use(VeeValidate);
```

# 日付のバリデーションをする
日付のバリデーションには`date_format`を使用する。

```html+jinja:DateValidation.vue
<template>
    <div>
        <input
            type="text"
            name="date"
            v-model="date"
            v-validate="'required|date_format:YYYY-MM-DD HH:mm:ss'"
        />
    </div>
</template>
```

特に日付フォーマットは[moment.jsのドキュメント](http://momentjs.com/docs/#/parsing/string-format/)に沿って書く必要があり、DDがddになっていたり、ssがSSになっていると動かないので注意する。
Big-IP tmsh

``` 
 config　　マネージメントIP等の設定
 tmstat　　現在時刻・CPU使用率・メモリ割り当ての表示
 qkview　　quick view。情報一括取得。他処理を圧迫しないためにniceコマンドと併用すること。
 bigtop　　負荷分散の概要表示 対象のin/out等。virtual serverはip+portで表示。
 bigtop -vname　　負荷分散の概要表示 virtual serverは名前で表示。
 bigtop -scroll　　フルスクリーンモードを無効にする。(更新表示)
 
 
 bigpipe version　　バージョンと使用可能な機能の表示
 bigpipe virtual　　virtual serverとpoolの関連状態表示
 bigpipe pool　　poolとpool memberの状態表示
 bigpipe vlan　　vlanの状態表示
 bigpipe node　　nodeの状態表示(オプション有り)
 bigpipe monitor　　monitorの状態表示
 bigpipe mirror　　mirrorの状態表示
 bigpipe failover　　failoverの状態表示(オプション有り)
 bigpipe http　　GLOBAL HTTP STATISTICS。
 bigpipe icmp　　(リセットはbigpipe icmp stats reset)
 bigpipe tcp　　GLOBAL TCP STATISTICS。
 bigpipe udp　　GLOBAL UDP STATISTICS。
 bigpipe platform 　プラットフォーム表示。CPU型名や物理メモリ量等。
 bigpipe persist 　パーシステンステーブルの表示。
 bigpipe ha table 　(b ha table show) HAテーブルを表示
 bigpipe global 　GLOBAL STATISTICS。TMM traffic等。
 bigpipe db　　環境設定値等表示
 bigpipe unit　　unitsの表示
 bigpipe user　　userの表示
 bigpipe memory　　memoryの総計、詳細表示
 bigpipe mgmt　　マネージメントポートについて
 bigpipe mgmt route　　マネージメントルートについて
 
 
 bigpipe config sync show 　コンフィグ同期状態
 
 
 bigstart list
 bigstart status　　サービス状態表示
 
 
 
 
 b　オプション無しだとbに関するオプション表示。/usr/bin内のbもbpもbigpipeへのリンクです。
 
 
 b pool (Virtual Server名) delete 
 b pool (Virtual Server名) {member (実サーバIP):(実port番号)} 
 b pool (Virtual Server名) member (実サーバIP):(実port番号) add 
 b pool (Virtual Server名) member (実サーバIP):(実port番号) delete 
 b pool (Virtual Server名) member (実サーバIP):(実port番号) session enable 
 b pool (Virtual Server名) member (実サーバIP):(実port番号) session disable
 
 
 
 b virtual (Virtual Server名) delete
 b virtual (Virtual Server名) {destination (仮想サーバIP):(仮想port番号) pool (Virtual Server名) profile http enable} 
 b virtual (Virtual Server名) {destination (仮想サーバIP):(仮想port番号) pool (Virtual Server名) profile http persist (Virtual Server名) enable} 
 
 b profile persist (Virtual Server名) delete 
 b profile persist (Virtual Server名) {mode cookie cookie mode hash cookie name (cookie名) cookie hash offset 0 cookie hash length 4}
 
 
 b config save ファイル名
 b config sync
 
 
 
 b failover standby　　スタンバイへ移行する
 b failover show
 
 b ha table show 　High Availabilityテーブル表示
 b list
 b vlan
 b node (実サーバIP) delete 
```
特定行を抜き出す

+ 2行から30行抽出
`cat data.txt | awk "NR==2,NR==30 {print}" 
 sed -n "2,30p" data.txt`
+ 最初から10行
`cat data.txt | awk 'NR<=10 {print}'`
+ 10行目以降全て
`cat data.txt | awk 'NR>=10 {print}'
 sed -n "10,$p" data.txt`
ファイルのカラムを並べ替え

# カラムを並び替え

```shell
 $ cat data.txt
 hoge1 hoge2 hoge3
 $ awk '{print $0}' data.txt
 hoge1 hoge2 hoge3
 $ awk '{print $3,$2,$1}' data.txt
 hoge3 hoge2 hoge1
 $ awk '{print "hoge"$3,$2,$1}' data.txt
 hogehoge3 hoge2 hoge1
細かすぎて伝わらない一秒でクローラーになるワンライナー

細かすぎて伝わらない一秒でクローラーになるワンライナ

いきなりずるいワンライナーでごめんなさいmm

## 注意事項

[Webスクレイピングの注意事項一覧](https://qiita.com/nezuq/items/c5e827e1827e7cb29011)
を一読してから実行してください。

自己責任でお願いします。


## やっていること

* sitemapから``` <loc></loc> ``` を抜き出してその内容をファイルに書き出す
* sleepを3秒ずついれている
* 取得したコンテンツの内容をshell実行直下のファイルに書き出している
* ネストしたsitemap用に書いています。単体のsitemapの場合は個人で工夫してください

## 細かすぎて伝わらない一秒でクローラーになるワンライナ

```
URL="{取得したいサイトのURL}";[ -e site_map_urls.txt ] && rm -rf site_map_urls.txt; for xml_sitemap_url in $(curl -s "$URL" | grep "<loc>.*</loc>"|sed -e s/\<\\/loc\>//g | sed -e "s/<loc>//g" | tr -d '\t'); do for url in $(curl -s "$xml_sitemap_url" | grep "<loc>.*</loc>"| sed -e s/\<\\/loc\>//g | sed -e "s/<loc>//g"|tr -d '\t'); do echo $url >> site_map_urls.txt; done; done; for url in `cat site_map_urls.txt | sort | uniq`; do file_name=$(echo $url | tr ":" "-" | tr "/" "-"); curl -sS $url > "$file_name.txt"; sleep 3; done;
```

## 原文

```shell
#!/usr/bin/env bash
URL="{取得したいサイトのsitemapurl}";[ -e site_map_urls.txt ] && rm -rf site_map_urls.txt;
rm -f site_map_urls.txt;
for xml_sitemap_url in $(curl -s "$URL" | grep "<loc>.*</loc>"|sed -e s/\<\\/loc\>//g | sed -e "s/<loc>//g" | tr -d '\t')
do
  for url in $(curl -s "$xml_sitemap_url" | grep "<loc>.*</loc>"| sed -e s/\<\\/loc\>//g | sed -e "s/<loc>//g"|tr -d '\t')
  do
    echo $url >> site_map_urls.txt
  done
done
for url in `cat site_map_urls.txt | sort | uniq`; do file_name=$(echo $url | tr ":" "-" | tr "/" "-"); curl -sS $url > "$file_name.txt"; sleep 3; done;
```
「第1回AI・業務自動化展」にいってきた。

####「第1回AI・業務自動化展」
リードが幕張メッセで開催している「第1回AI・業務自動化展(JapanITWeek秋2017内)」にいってきた。
思ったような感じではなかった。

####業務自動化by Java
複数の会社が提供している業務自動化はJavaで実現しているとのこと。Javaではそもそも重くて話にならん気がするしJavaをメンテナンスするのがたいへんで、自動化できるスコープが狭すぎるだろう。そのうえ、アクシデントがあると、当然、処理は止まるという。まああたりまえだけれども。自動化するためには、シナリオを書くのだが、それはつまりプログラムを書くのとおなじで、それならJavaでGUIごしに書くのではなくて、直接その業務を自動化できるシステムを開発したほうが、ずっと効率的でスマートな気がする。
業務-Java-GUI(CUIシナリオエディタ)-アプリケーション等という手順でなくて、直接業務処理用プログラムを書くわけだ。それなら業務-アプリケーションと、あいだにはさむものがなくなる。スマートで高速で安定する。
もちろん、既存のアプリケーションを改変しなくてよい、というメリットはあるけれど、屋上屋を重ねるようなもので、ちょっと無理があるんじゃないのと思う。既存のアプリケーションを認識するのは画像認識だったりするので、まあそこにAIの要素があるといえばあるし、ないといえばほとんどないともいえる。AIは単なるはやりのラベルのようなものにすぎないわけだ。

####シナリオをGUIで
シナリオもGUIで書けるといってもボタンがあるだけでボタンの内容はifとかtry-catchとかいうもので、日常生活にはまったくなじみがない。そもそもif文的な条件分岐って、日常性と関係あるのかと思うし、日常生活をif文として明示できるのなら、GUI/CUIを使ってプログラムするのでなく、直接プログラムにするほうがずっとスマートだとしかいえない。日常生活は暗黙知で動いていて、そこからプログラミング的な条件を抜き出す作業は、きわめて困難だ。切りがない。違う気がする。

####業務自動化をC#で
業務自動化を、C#で書いたことはある。もちろん画像認識もしてみた。場合によっては、C++を呼び出して行うこともある。それでも安定しないなと感じた。あるごく特定の処理をシナリオ化するのも思っていたのよりもずっと手間がかかるのだ。
思っていたのというのがどういうものなのかは説明しにくいのだけれど。その説明しにくさが暗黙知なのであって、やはり違うとしかいえない印象だ。それでも(そういうのを・ー・というらしいが)、ある・・ーの・ー・で1年半運用して、総合ランキングを38位まであげたことがある。・ー・の・ー・・が終了したためそこで終わったが、自動化すればできることはあるなという実感は得ることができた。こういう確信は大事だと思う。個人的にだけれど。

####チャットボット・マジック
チャットボットにも、同様のマジックを感じた。チャットボットは、大量のテキストがなければそもそもボットとしての魅力を満たさないと思うのだが、「ウィザード式に項目をひとつずつチャット画面で入力して書類ができました」というもののどこがチャットボットなのだ? そんなの、ぜんぜん技術もAIもなんにも関係ないじゃないか。子どもだましもたいがいにしてくれ。

####チャットシナリオをGUIで
ある会社では、チャットの質問シナリオをGUIで記述できるエディタを展示していたのだが、そもそもチャットの質問シナリオをGUIで記述できるとしたら、そのシナリオの深さ(あるいはシーン)は、数えるほどしかないだろう。GUIは数えられないような規模のものを記述するのには不向きだ。案の定回答は、5-6階層を想定しているという…。あのな…。小学生向きの雑誌の正月号の付録の双六じゃないんだから、もうちょっと深みのあるものにしないと、すぐに飽きちゃうじゃないか。チャットボットが「個性」を感じさせるから、AIでありなにかちがうアトモスフィアを感じるのであって、そこに生命性とか心とかのゆらぎがあるからおもしろいのだと思うのだが、既存の業務用チャットボットといっているのは、質問を6つしか用意してなくて、それ以上の会話をしないというものなのだ。そんなの…。ぜんぜんAIでもなんでもないじゃないか。昭和の男は「フロ・メシ・ネル」しかいわなかったというがそれは食欲と睡眠欲と性欲は満たしていたのかもしれないけど、なんですかそのAIの6つというのは。そんなので、なにかコミュニケーションできるのだろうか。そういうのをコミュニケーションというのか。というような根本的な疑問が、もうでてきちゃうのだ。

####Amazon Echo
そうこうしていると、Amazon Echo発売の話題で盛り上がっている。そこでは、「Alexa京王線の運行状況を教えて」とかいえるようになるとかいうのであって、京王線がAPIを公開するのなら、Alexaでなくても使えるようになるだろうし、そもそも京王線には乗らないから関係ない気もする。
チャットボットも書いているが、飽きないようにするためには、すくなくとも数百以上のシナリオが必要だ。人の複雑さに達するためにどのくらいあればよいのかは、ぜんぜんわからない。
思ったような感じではなかったのなにを思っていったのかは、すこし説明できるかもしれない。つまり、なにかのヒントがあるかもしれないと思っていったのだ。ヒントは、なかった。現実なんて、そんなものだ。世界にはないものを作っている。
インターネットに公開する ELB は Private Subnet に配置してはいけない

## はじめに
<del>ここに書く内容は、発生したある問題に対して「何故だかわからないけどこうやったら解決した」というやつなので、あまり信用しすぎないようにお願いします・・・。もしこの現象について詳細をご存じの方がいましたらコメントいただけますとうれしいです。</del>

この現象の謎は解明されたので最後に追記してあります。

## やりたかったこと
- ELB から EC2 インスタンスに HTTP リクエストを流す
- EC2 インスタンスは Private Subnet[^private_subnet] に置く
    - インターネットに出ていくときは Public Subnet にある NAT インスタンスを経由する

[^private_subnet]: Subnet ごとに「これは Private Subnet です」というパラメータがあるわけではなく、Subnet のルートテーブルに設定されているデフォルトゲートウェイ (`0.0.0.0/0`) がインターネットゲートウェイに向いていない (NAT インスタンス等を向いている) 場合、その Subnet を Private Subnet と呼ぶ (はず...)

![](https://qiita-image-store.s3.amazonaws.com/0/16369/90031ae9-618a-c17b-6e52-62f572c9ad4a.png)


## 発生した問題
ELB に対して HTTP リクエストを投げたときに、レスポンスがものすごく遅いときがある。

ちゃんと返ってくるときは1秒以内に返ってくるのだが、返ってこないときは1分以上待たされる。

ブラウザの開発者ツールで内訳を見てみると、

![](https://qiita-image-store.s3.amazonaws.com/0/16369/5a8c453a-f01e-6561-4f76-ab9315247633.png)

このように Initial connection に一分以上かかってしまっている。

そもそも ELB から Web サーバ (EC2 インスタンス) まで接続するのにものすごく時間がかかっている。

## 解決した方法
**Private Subnet と同じ AZ に空の Public Subnet を作成し、ELB の設定で Public Subnet の方を指定した**ところ問題が再現しなくなった。

![](https://qiita-image-store.s3.amazonaws.com/0/16369/3e7accdb-8d2e-59f2-f4ad-33a701699f0d.png)

「EC2 インスタンスを置いてない方のサブネットを設定したらターゲットとして指定できないんじゃないの」と思うかもしれないが、そんなことはなく、普通に指定できる。

## ELB の挙動についての考察
そもそも ELB の設定では、**Subnet ではなく AZ を選択する。**

![](https://qiita-image-store.s3.amazonaws.com/0/16369/fef85505-6078-a53c-37f2-c133af28a5ab.png)

ここで選択した AZ に含まれる EC2 インスタンスをターゲットとして指定することができる。

そして、**選択した AZ ひとつにつき Subnet をひとつ選択する必要がある**。

おそらく、各 AZ にロードバランサを配置する際に「この AZ 内のどの Subnet に配置するか」を選択する必要があるのだろう。

そして**ロードバランサを配置した Subnet が Private Subnet である場合、ロードバランサから EC2 インスタンスに接続するまでに (なぜか) 一分以上かかってしまうことがある。**

なぜ Private Subnet だとダメなのかは、調べた限りではよくわからなかった。

### 追記
ELB 作成時に Private Subnet を選ぶと Warning が出るっぽい。

> You are creating an internet-facing Load Balancer, but there is no Internet Gateway attached to these subnets you have selected

見逃していた・・・。

## まとめ
- ELB の配置先を Private Subnet にすると、(理由は不明だが) 接続に時間が掛かる問題が発生する
- 同じ AZ に Public Subnet を作成してそこに ELB を配置すれば解決する

## 2020.03 追記
AWS 詳しい同僚に解説してもらって3年越しで謎が解けたのでまとめておく。

0. ELB インスタンスは AZ ごとに作成される
    - 今回のケースの場合、片方の AZ では Public Subnet に、もう片方の AZ では Private Subnet に ELB インスタンスが配置されるように設定した
0. この状態で ELB エンドポイントの A レコードを引くと、IP アドレスが2つ返ってくる
    - Public な ELB の IP (Global IP) と Private な ELB の IP (VPC の Private IP)
0. 接続先の IP アドレスが複数ある場合にどのように接続されるかは Web ブラウザによって挙動が異なる
    - Google Chrome の場合、ランダムに1つを選択して接続を試みるが、Private IP の方が選択された場合は接続できないので1分でタイムアウトして他の IP アドレスで再試行する
0. 結果的として、「接続できるときとできないときがある」「1分以上待つと接続できる」「Web ブラウザによって挙動が異なる」という現象が発生する
AWS CLIをpipインストールした際のエラーを解決する

## 状況

pipをインストール

```terminal
$ sudo easy_install pip
```

AWS CLIをインストール

```terminal
$ sudo pip install awscli
```

ここで以下のようなエラーが発生！

```terminal
Installing collected packages: six, python-dateutil, docutils, botocore, awscli
Found existing installation: six 1.4.1
    DEPRECATION: Uninstalling a distutils installed project (six) has been deprecated and will be removed in a future version. This is due to the fact that uninstalling a distutils project will only partially uninstall the project.
    Uninstalling six-1.4.1:
Exception:
Traceback (most recent call last):
  File "/Library/Python/2.7/site-packages/pip/basecommand.py", line 211, in main
    status = self.run(options, args)
  File "/Library/Python/2.7/site-packages/pip/commands/install.py", line 311, in run
    root=options.root_path,
(略)
```

## 解決策

どうやらSixというパッケージをアンインストールしようとしてエラーになってるようである．

```terminal
$ sudo pip install awscli --upgrade --ignore-installed six
```

これで解決できた．Sixっていうのはpython2系と3系の差異を埋めてくれるユーティリティライブラリとのこと．
Windows版 PHP(7.1前) での日本語パスの filemtime()

## はじめに

filemtime() を使っている箇所で、しばしばログに E_Warning が出ていました。例の SJIS 上の「表」などの文字の問題です。

やれやれと思いながら調べると下記の記事を見つけました。

参考：[Windows版 PHP(7.1前) での日本語パスの対応状況と暫定回避策](https://qiita.com/algo13/items/479a44aac713c01ee454)

簡単には行きませんでした。

## 実装

上記の記事を参考に、「dir /T:w」を使用して filemtime() を実装しました。

```php

<?php
// Windows 専用の filemtime()
function filemtime_win($filename)
{
    $ret = FALSE;
    $dirCmdError = null;
    $m = null;
    if (!ob_start()) {
        return FALSE;
    }
    passthru('dir /T:w ' . $filename . ' 2>nul', $dirCmdError);
    if ($dirCmdError !== 0) {
        ob_end_clean();
        return FALSE;
    }
    foreach (explode("¥r¥n", ob_get_contents()) as $line) {
        if (preg_match('/^¥d{4}¥/¥d{2}¥/¥d{2}¥s*¥d{2}:¥d{2}/', $line, $m)) {
            $ret = strtotime($m[0]);
            break;
        }
    }
    ob_end_clean();
    return $ret;
}


// 「表」配下の「ン」配下の「可能.pdf」にアクセスしてみる
$filename = "表¥¥ン¥¥可能.pdf";
$utf8 = mb_convert_encoding($filename, 'UTF-8', 'CP932');
if ($filename !== mb_convert_encoding($utf8, 'CP932', 'UTF-8')) {
    echo 'ERR: file name encoding error.', PHP_EOL;
    die;
}
$mtime = filemtime_win(escapeshellarg($filename));
if ($mtime === FALSE) {
    echo 'ERR: file mtime error.', PHP_EOL;
    die;
}
echo Date('Y/m/d H:i:s', $mtime);

```

escapeshellarg() は外に出しました。
サーバでrmコマンドを安全にする

サーバで操作してる時にrmコマンドで消さないようにしたい。
ローカルにあるファイルとサーバにあるファイルを間違え、消してはいけないサーバのファイルを削除してしまいそうになったのでどう対策したのか書きます。

## やったこと

1. `rm` でゴミ箱へ送られるようにする
2. 本当に削除したいものは `rmrm` で削除するようにする


### 1. `rm` でゴミ箱へ送られるようにする
rmでゴミ箱へ送るためのaliasなどを公開されている方がいますが、便利そうだったので[trash](https://github.com/rcmdnk/trash)を使うことにしました。同名のファイルを削除した時に番号を割り振るなどをやってくれてるので早いです。
インストール。

```
$ cd ~/src  # 自分がサーバでソースをインストールする先
$ git clone git@github.com:rcmdnk/trash.git
```

ここで落としてきたtrashを叩くと分かりますが[sentaku](https://github.com/rcmdnk/sentaku)が必要です。なのでここでは先にインストールしちゃいましょう。

```
$ git clone git@github.com:rcmdnk/sentaku.git
```

trashとsentakuにパスを通す。どこかパスが通ってる場所にリンク貼っても良いですし以下でも可。

```bash:.bashrc
export PATH=$PATH:~/src/trash/bin:~/src/sentaku/bin
```

反映

```
$ source ~/.bashrc
```

試してみます

```
$ cd ~/tmp/
$ touch hoge
$ trash hoge
~/tmp/hoge was moved to ~/.Trash/my_trash_box/20171109/hoge

#　同名のファイルをtrashすると連番が振られる
$ touch hoge
$ trash hoge
~/tmp/hoge was moved to ~/.Trash/my_trash_box/20171109/hoge.1
```

`rm` は　`trash` へのエイリアスにしてしまいます

```bash:.bashrc
alias rm="trash"
```

更に、デフォルトの設定だと、一度にゴミ箱へ移動できる容量が100MBなので、3GBにしておきました。

```bash:.bashrc
export MAXTRASHBOXSIZE=3072
export MAXTRASHSIZE=3072
```

#### trash詳細
色んなオプションがありますが少しだけ。
-bでゴミ箱から戻せます（これがめっちゃ便利です）。

```
 -b              Restore (turn Back) the file from the trash box
```

環境変数に関して。

|環境変数|詳細|デフォルト|
|---|---|---|
|TRASHLIST|ゴミ箱へ移動したファイル/ディレクトリの情報が残っている。ログファイルのようなもの。|~/.trashlist|
|TRASHBOX|ゴミ箱の場所。この下にゴミが捨てられていく。|~/.Trash|
|MAXTRASHBOXSIZE|ゴミ箱の容量（MB）。クリーンアップする時にこの容量を超えている分だけ削除される。|1024|
|MAXTRASHSIZE|一度に捨てられるゴミの上限（MB）。このサイズを超えるゴミは `rm` コマンドで直接削除される。|102|

### 2. 本当に削除したいものは `rmrm` で削除するようにする
rmへエイリアスを張ってもtrashで上書きされてしまっているので `/bin/rm` へ直接エイリアス。

```bash:.bashrc
alias rmrm="/bin/rm"
```

反映する。

```
$ source ~/.bashrc
```

最後に試した例を載せておしまいです。

```bash:
$ cd ~/tmp
$ touch foo
$ rm foo
~/tmp/foo was moved to ~/.Trash/my_trash_box/20171109/foo
$ touch foo
$ rmrm foo
$ 
```
いろいろな分散トレーシングシステムの予約済みSpanタグキーを見比べる

## はじめに〜なぜこの記事が必要か

分散トレーシングシステムによってSpanフォーマットが違う。Spanに付与できるメタデータ/タグにはシステムによって予約済み/Well-Knownなキーがあって、そのタグに設定された値はそれぞれWeb UI上で表示するときに特別扱いされたりするらしい。

zipkin-go-opentracingやdd-zipkin-proxyのように、クライアントライブラリ、プロキシエージェントのような形で、様々な分散トレーシングシステムのSpanフォーマットを透過的に変換してくれるようなソフトウェアは存在する。

しかし、ソフトウェアによって、予約済みのSpanタグキーを適切に読み替えてくれたりくれなかったりします。もし、そのようなソフトウェアを利用して期待通りの結果にならなかったときは、このページの内容を思い出してみると解決の糸口がつかめるかもしれません。

## OpenTracing

[Data Conventions · Opentracing](http://opentracing.io/documentation/pages/api/data-conventions.html)
[specification/semantic_conventions.md at master · opentracing/specification](https://github.com/opentracing/specification/blob/master/semantic_conventions.md)

- component
- db.instance
- db.statement
- db.type
- db.user
- error
- ...

## Datadog APM

Trace APIの仕様書には書いてない。Pythonライブラリに定義されている定数が参考になる。

[dd-trace-py/ddtrace/ext at master · DataDog/dd-trace-py](https://github.com/DataDog/dd-trace-py/tree/master/ddtrace/ext)

- [DB関係](https://github.com/DataDog/dd-trace-py/blob/master/ddtrace/ext/sql.py)
    - db.name (OTのdb.typeに相当?)
    - db.user
- [SQL関係](https://github.com/DataDog/dd-trace-py/blob/master/ddtrace/ext/sql.py)
    - sql.db (OTのdb.instanceに相当?)
    - sql.query (OTのstatementに相当?)
    - sql.rows (OTには相当するものがない)
- [ネットワーク一般](https://github.com/DataDog/dd-trace-py/blob/master/ddtrace/ext/net.py)
    - out.host
    - out.port
    - net.out.bytes
- ...


## Zipkin

タグというのはなくて、binary annotationのkeyがタグ名、valueが値に相当する。
[Data Model · OpenZipkin](http://zipkin.io/pages/data_model.html)
[example zipkin trace with 3 spans](https://gist.github.com/adriancole/f26b154c987265c5e376)

- jdbc.query (otのdb.statement、ddのsql.queryに相当)
- とか...

参考までに、Envoyが送るbinary annotation keyは以下。

- guid:x-request-id
- http.url
- http.method
- downstream_cluster
- user_agent
- http.protocol
- guid:x-client-trace-id
- request_size
- upstream_cluster
- http.status_code
- response_size
- response_flags
- error

annotation typeはなぜかすべてBOOL(STRINGではなく)

https://github.com/envoyproxy/envoy/blob/e0c6eaa3945a501e7a74bb41a92f00daf8fb4581/source/common/tracing/http_tracer_impl.cc#L123-L158
https://github.com/envoyproxy/envoy/blob/cbff0f7fc56c53e3aac383081021856c8dbcb732/source/common/tracing/zipkin/zipkin_core_constants.h
https://github.com/envoyproxy/envoy/blob/04d2f9b129075705d1c0416a5b120d56b442f210/source/common/tracing/zipkin/zipkin_core_types.cc#L257

## dd-zipkin-proxy

Zipkinスパン(b3-propagation, thrift)をDatadog APM Spanに変換してくれるやつだが、データモデルの違いを吸収するために一部拡張がある。

具体的には、以下のようなkeyのzipkin binary annotationがあると、そのannotationをDatadog APM Spanのフィールドに読み替えてくれる。

[dd-zipkin-proxy/main.go at master · flachnetz/dd-zipkin-proxy](https://github.com/flachnetz/dd-zipkin-proxy/blob/master/example/main.go#L49-L68)

- dd.resource -> dd spanのresource
- dd.name -> dd spanのname

その他、zipkinのbinary annotationはそのままkey=valueのタグとしてdd spanのmetadataにいれてくれる。

なお、zipkinｂのjdbc.queryをddのsql.queryに変換・・してくれたりはしないので、Zipkinでjdbc.queryを表示するときに特別扱いされてたようなケースでも、DatadogのWeb UIでは特別扱いしてくれないかもしれない。

その点については、dd-zipkin-proxyを改良して、dd側にwell-knownなタグキーがあればzipkin->ddのキーに読み替えるようにするとよさそうではある。
時間・スキルがなくてもauto-sklearnで機械学習して予測モデルをつくる

2019/06/25 追記：
MS製のLightGBMでも簡単に予測ができそうです。
https://www.kaggle.com/shep312/applying-lightgbm-to-titanic-dataset

以前社内コンペで同僚がLightGBMを使って開始30分でハイスコアを叩き出していました（そのコンペは評価関数が Log Loss だったのもあったのか、私はあまり良い結果は出せませんでした）。
追記終わり

---
[auto-sklearn](https://github.com/automl/auto-sklearn)という機械学習の自動化ツールがあるらしいです。これを使うことで、時間・スキルがなくてもそこそこの精度でKaggleの問題がとけないかやってみました。下記チュートリアルを試してみました。

- [Titanic生存予測](https://www.kaggle.com/c/titanic)
- [House Price予測](https://www.kaggle.com/c/house-prices-advanced-regression-techniques)

## Notebook
auto-sklearnを使ってみたNotebookは下記です：

- Titanic生存予測
  - https://github.com/raiich/myKaggle/blob/master/auto-titanic.ipynb
- House Price予測
  - https://github.com/raiich/myKaggle/blob/master/auto-house.ipynb

自分の環境だと、それぞれ1時間程度の実行時間となりました。

## 準備
今回は、下記を参考にしてDocker for Mac上にコンテナを立てました。

- https://qiita.com/inoue0426/items/ffd7f4235dcfde88942b

```
$ docker run -it -v $PWD:/opt/nb -p 8888:8888 felixleung/auto-sklearn /bin/bash -c "mkdir -p /opt/nb && jupyter notebook --notebook-dir=/opt/nb --ip='0.0.0.0' --port=8888 --no-browser --allow-root"
```

コンテナが立ち上がったら、いくつかライブラリをインストールしました（コンテナ内のTerminal等から）。

```
$ pip install arff matplotlib seaborn  # in docker container
```


## データの確認、整形
Notebookではまずデータの確認をして、その後に簡単な整形をしています。
auto-sklearnに食わせるデータは、NA値を補完したりLabelEncoderを使ってCategoricalな文字列を数値に直したりする必要があるようです（[ソースコード](https://github.com/automl/auto-sklearn/blob/master/autosklearn/estimators.py#L402)に書かれていたのを後から気づきました...）。


## ユーティリティ
Notebookではいくつかユーティリティを用意しています。

- `fillna()` 関数: NA値を補完
    - 数値であれば平均値を、それ以外は前後の行の値で埋めるようにしています
- `categoricalize()` 関数: Categoricalなデータを数値に変換


## ローカルでモデル精度の確認
House Price予測では、まずは `train.csv` のデータをトレーニング用とテスト用に分割して精度を確認しました。その後テスト用に使ったデータも使って `refit()` し、提出用予測の精度向上を図ります。

### `refit()`のエラー回避
使用したバージョンでは`refit()`でエラーが発生したため、とりあえず回避策として下記のように置換しました：

```
#`refit` raises an error, so modified
!sed -i -e 's/if self.max_leaf_nodes == "None":/if self.max_leaf_nodes == "None" or not self.max_leaf_nodes:/' \
  /usr/local/lib/python3.5/dist-packages/autosklearn/pipeline/components/regression/gradient_boosting.py
```

## 結果
予測して結果を提出した結果、下記のようになりました。

| 問題 | Score |
|-------|-------|
| Titanicの生存予測 | 0.78468 |
| House Price予測  | 0.15161 |

例えばTitanicの方はLeaderboardによると下記のようになるので、まずまずの精度ではないでしょうか？ (2017-11-09 19:30時点 20989投稿)

#### 【参考】Titanicの回答の統計量

| 統計量      | Score |
|------------|---------|
| 平均        | 0.74271 |
| 最頻値(個数) | 0.76555 |
| 中央値      | 0.77033 |


## まとめ
一度auto-sklearnの環境を作ってしまえば人手が必要な作業は下記だけで済み、精度もそれなりに出るので良いと思いました（ただ機械学習モデルの生成に時間がかかるのと試行ごとに生成されるモデルがばらつくのが...）。

- 何を予測するのか（regressionなのかclassificationなのか）
  - `AutoSklearnClassifier` を使うのか `AutoSklearnRegressor` を使うのか
- 各カラムのデータはCategoricalなのかNumericalなのか
C# 動的にPanelを生成する

#Panel を動的に作成する。

```
using System;
using System.Windows.Forms;
using System.Drawing;

class FormMain : Form {

  Panel panel1;

  [STAThread]
  public static void Main() {
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run( new FormMain());
  }

  FormMain()
  {
    Text = "Button Click Sample";
    ClientSize = new Size(600, 400);
    Button btn1 = new Button();
    btn1.Location = new Point(50, 50);
    btn1.Text = "Create Panel";
    btn1.Click += btn1_Click;
    Controls.AddRange(new Control[] { btn1 });
    
    this.Controls.Add(panel1);
  }
  
  public void CreateMyPanel()
  {
     panel1 = new Panel();

     // Initialize the Panel control.
     panel1.Location = new Point(56,72);
     panel1.Size = new Size(264, 152);

     // Set the Borderstyle for the Panel to three-dimensional.
     panel1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;

     // Add the Panel control to the form.
     this.Controls.Add(panel1);
  }
  
  void btn1_Click(object sender, System.EventArgs e) {
     CreateMyPanel();
     MessageBox.Show("Panel Close.", "message!");
     this.Controls.Remove(panel1);
  }
}
```

![image1.png](https://qiita-image-store.s3.amazonaws.com/0/211884/687fb69b-9905-26fa-a094-a55b69848be4.png)

![image2.png](https://qiita-image-store.s3.amazonaws.com/0/211884/d57f42cf-cc25-cea5-44c1-f02cd6df5364.png)
dict をフィルタリングする

辞書内包表記を使います。

```pycon
>>> magica_dict = {
...   'homura': '暁美 ほむら',
...   'madoka': '鹿目 まどか',
...   'sayaka': '美樹 さやか',
...   'mami': '巴 マミ',
...   'kyoko': '佐倉 杏子',
...   'nagisa': '百江 なぎさ'
... }

>>> {k: v for k, v in magica_dict.items() if 'y' in k}  # 条件: キーに 'y' を含む。
{'sayaka': '美樹 さやか', 'kyoko': '佐倉 杏子'}

>>> {k: v for k, v in magica_dict.items() if v not in ['佐倉 杏子', '美樹 さやか']}  # 条件: 値が配列に含まれない。
{'homura': '暁美 ほむら', 'madoka': '鹿目 まどか', 'mami': '巴 マミ', 'nagisa': '百江 なぎさ'}
```
MySQLにアクセスできない時に試してみるコマンド

## 概要
MySQLにアクセスしようとして、今まで問題なかったのに何かのタイミングで以下のエラーが出ることがあります。
`ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)`
このエラーは多くの方が経験したことがあると思いますが、以下の流れでうまくいきました。

### 1. ディレクトリを移動する。
`$ cd /usr/local/var`

### 2. ディレクトリの状態を確認する。
`$ ls -l`

```
total 0
drwxr-xr-x   3 Masahiro  admin    96  5 14 21:27 cache
drwxr-xr-x   4 Masahiro  admin   128  4 21  2017 homebrew
drwxr-xr-x   2 Masahiro  admin    64  4 29  2017 log
drwxr-xr-x  26 _mysql    _mysql  832 11  8 01:39 mysql
drwx------  23 Masahiro  admin   736  2 12  2015 postgres
```
mysqlの所だけ`Masahiro`ではなく`_mysql`となっています。
### 3. ディレクトリの権限を変更する。
`$ sudo chown -R [ユーザー名] mysql`
[ユーザー名]の部分に任意のユーザー名を入れます。
`$ sudo chown -R Masahiro mysql`
変更を確認します。
`$ ls -l`

```
total 0
drwxr-xr-x   3 Masahiro  admin    96  5 14 21:27 cache
drwxr-xr-x   4 Masahiro  admin   128  4 21  2017 homebrew
drwxr-xr-x   2 Masahiro  admin    64  4 29  2017 log
drwxr-xr-x  26 Masahiro  _mysql  832 11  8 01:39 mysql
drwx------  23 Masahiro  admin   736  2 12  2015 postgres
```
先ほど`_mysql`だったところが`Masahiro`に変更できました。

### 4. MySQLにアクセスする。
`$ mysql -u root -p`

```
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.7.20 Homebrew

Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>
```
これでうまくいきました。

調べると同じようなエラーでも他の方法で解決したケースもあるようですが、権限の確認を行うようにすると比較的早く解決するかもしれません。
PromCon 2017 のセッション紹介 - Staleness in Prometheus 2.0

少し時間が経ってしまっていますが, 8 月に Prometheus に特化したカンファレンス [PromCon 2017](https://promcon.io/2017-munich/) がミュンヘンにて開かれたので, [Z Lab](https://qiita.com/organizations/zlab) からは私と @tkusumi が参加して来ました.

この記事ではそこで聞いたセッションの中から, [先日リリースされた Prometheus 2.0](https://prometheus.io/blog/2017/11/08/announcing-prometheus-2-0/) で改善された Staleness の取り扱いに関するセッションについて紹介させてもらおうと思います.

## 概要

**スピーカー**: Brian Brazil (Robust Perception)
**ビデオ**: <https://youtu.be/GcTzd2CLH7I>
**スライド**: <https://www.slideshare.net/brianbrazil/staleness-and-isolation-in-prometheus-20-promcon-2017>

Prometheus のコアデベロッパーかつ, Prometheus のコンサルタント会社 Robust Perception の創始者による Prometheus 2.0 で変更される Staleness の振る舞いについてのセッション.

**NOTE**: この記事で使われている画像は全て, スピーカーからの承諾を得た上で上記のスライドから引用しています.

## 内容

Staleness とは日本語に直訳すると腐敗という意味になりますが, Prometheus のコンテクストでは有効でなくなった time series を無視するための仕組みのことを意味します.

### Prometheus v1 での Staleness の取り扱い

![2.0.staleness_before_v2.png](https://qiita-image-store.s3.amazonaws.com/0/18658/634f08be-0a54-88a3-f6ee-01a89e5ef43c.png)

Prometheus v1 では range vector と instant vector のクエリ結果は次のようになります.

**range vector**: `my_counter_total[10m]` のようなクエリの場合, クエリの実行時刻から 10m 前までの間のすべてのデータポイントが返る

**instant vector**: `my_counter_total` のようなクエリの場合, クエリの実行時刻から最も近いデータポイントが返る. ただし, 5m 以上離れている場合は, どのデータポイントも返さない

### 理想的な Staleness の取り扱い

![2.1.what_do_we_want.png](https://qiita-image-store.s3.amazonaws.com/0/18658/822fd9bf-34eb-2dad-6b9f-da41bd610e2b.png)

理想的には Staleness を次のように扱われるべきです.

- 監視対象がいなくなったら, そこから取得していた time series を stale とする
    - v1 では上述した理由から 5m が経過するまで stale とならない
- 監視対象がメトリクスを返さなくなったら, その time series を stale とする
    - v1 では上述した理由から 5m が経過するまで stale とならない
- 過去の timestamp を持つメトリクスを expose したい
    - Pushgateway などで利用するため
- より長い eval/scrape 間隔をサポートしたい
    - 今回の改善の対象外

### どのように実現するか

![2.2.staleness_implementation.png](https://qiita-image-store.s3.amazonaws.com/0/18658/d3b87579-43f5-d171-1751-eb19f3fd4056.png)

stale であることを示すマーカーを各データポイントに仕込むことで staleness の取り扱いを改善しようとしています.

instant vector の場合, 最新のデータポイントにマーカーが仕込まれていれば, その time series を無視します.

range vector の場合, 対象のデータポイントの集合のうち, マーカーが仕込まれているものを除外します.

![2.3.word_bits_expression.png](https://qiita-image-store.s3.amazonaws.com/0/18658/f19d9c6e-9e1f-611b-f624-3db31194b129.png)

64bits の浮動小数点数では NaN (Not a Number) の fraction パートが非ゼロであるという仕様になっています. この fraction パートを特定の値にすることで, stale のマーカーが仕込まれていることを表現します.

![2.4.how_it_worked_out.png](https://qiita-image-store.s3.amazonaws.com/0/18658/fb1c3c81-d70a-0b16-491a-615c27725748.png)

このマーカーの導入により次のような結果が得られています.

- 監視対象がいなくなったら, そこから取得していた time series を stale としたい
    - 解決している
- 監視対象がメトリクスを返さなくなったら, その time series を stale としたい
    - 解決している
- 過去の timestamp を持つメトリクスを expose したい (Pushgateway などで利用するため)
    - 解決しなかった (明示的な timestamp を持つデータは staleness のサポート対象外)
- より長い eval/scrape 間隔をサポートしたい
    - 変化なし

### まとめ

![2.5.staleness_summary.png](https://qiita-image-store.s3.amazonaws.com/0/18658/5ee0562e-6e53-ebaa-c92d-ea5c260c55e6.png)

- 特別な NaN による stale マーカーの導入により, stale の取り扱いが改善されています
- マーカーは監視対象かその time series がなくなったときに挿入されます
- 明示的な timestamp とともに expose されたメトリクスでは staleness がサポートされません
- バックアップとして, 5m 間の lookback (v1 の staleness の取り扱い方) は適用されます
Swift 4でSwinjectStoryboardを使ったDIができない時の解決法

# エラーの概要

[Swinject/SwinjectStoryboard](https://github.com/Swinject/SwinjectStoryboard)を使ってViewControllerにViewModelをDIしようとしたのですが、Xcode 9・Swift 4環境下では上手くDIできず、ViewModelインスタンスの値が`nil`になってしまいました。。。

```swift:SwinjectStoryboard+Setup.swift

import SwinjectStoryboard

extension SwinjectStoryboard {
    
    class func setup() {
        
        defaultContainer.register(HogeViewModel.self) { _ in
            HogeViewModel()
        }
        
        defaultContainer.storyboardInitCompleted(HogeViewController.self) { (r, c) in
            c.viewModel = r.resolve(HogeViewModel.self)
        }
    }
}

```

```swift:HogeViewModel.swift

class HogeViewModel {
    func foo() {
        print("foo")
    }
}

```

```swift:HogeViewController.swift

import UIKit

class HogeViewController: UIViewController {
    
    var viewModel: HogeViewModel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        viewModel.foo()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }


}

```

実行すると

![picture1.png](https://qiita-image-store.s3.amazonaws.com/0/172234/aa98a0e9-6f9d-6877-6ad7-4d0e68fab66a.png)

値がnilになっている。。。


# エラーの解決法

[こちらのIssue](https://github.com/Swinject/SwinjectStoryboard/issues/72)を発見し、もう一度READMEをよく読むと以下の一文が。。。

> Note that @objc attribute is mandatory here in swift 4.

これに従ってsetup()の頭に`@objc`をつけると

```swift:SwinjectStoryboard+Setup.swift

import SwinjectStoryboard

extension SwinjectStoryboard {
    
    @objc class func setup() {
        
        defaultContainer.register(HogeViewModel.self) { _ in
            HogeViewModel()
        }
        
        defaultContainer.storyboardInitCompleted(HogeViewController.self) { (r, c) in
            c.viewModel = r.resolve(HogeViewModel.self)
        }
    }
}

```

![picture2.png](https://qiita-image-store.s3.amazonaws.com/0/172234/282081b8-222e-0c98-c748-c8c324f30c55.png)


無事にDIできました！

# 参考
https://github.com/Swinject/SwinjectStoryboard
https://github.com/Swinject/SwinjectStoryboard/issues/72
AutosizingTextViewを使う

AutosizingTextView使ってみました。
軽く使い方と、ちょっとハマったところがあったので自分への戒めのためにまとめておきます。
まったく知らないよってかたはこちらを読むとすぐ使えますよ。▷[Android Developer/Autosizing TextView](https://developer.android.com/guide/topics/ui/look-and-feel/autosizing-textview.html)

## AutosizingTextViewとは
Android O (API Level 26)から、レイアウトサイズに合わせてフォントサイズを自動調節してくれるTextViewが使えるようになりました。

```text_view.xml
<TextView
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:autoSizeTextType="uniform"  <!-- この一行を加える -->
/>
```
default設定のまま使用するのであれば，上記をTextViewに追記すればOKです。

API26より以前のバージョンでも対応したい場合には

```text_view_pre26.xml
<android.support.v7.widget.AppCompatTextView
    android:layout_width="match_parent"
    android:layout_height="200dp"
    app:autoSizeTextType="uniform"  <!-- この一行を加える -->
/>
```
こちらを使いましょう。

その他使い方は[Android Developer](https://developer.android.com/guide/topics/ui/look-and-feel/autosizing-textview.html)に書いてるので割愛しますが、需要あれば日本語でまとめます。

## Tips
### `wrap_content`は使っちゃダメ
widthかheightどっちか固定値入れておけば、固定値使っていい感じに動くのかな？と思っていました。
#### layout_width="wrap_content"を指定（ダメな例）
![スクリーンショット 2017-10-31 14.32.45.png](https://qiita-image-store.s3.amazonaws.com/0/98896/26bc4a76-996f-0dea-c59d-24693be2dee6.png)

こんな風にギュってなっちゃいます

#### layout_height="wrap_content"を指定（ダメな例）

![スクリーンショット 2017-10-31 14.33.09.png](https://qiita-image-store.s3.amazonaws.com/0/98896/9690751a-856c-ffa4-3b91-b3e1a977f2d6.png)

言うこと聞いてくれません

#### 良い例
![スクリーンショット 2017-10-31 14.32.25.png](https://qiita-image-store.s3.amazonaws.com/0/98896/e0d5bf84-7d8c-1aa2-c2f8-c0fdb0e5135e.png)

`wrap_content`を使わなければ、ちゃんと動きます。Autosizingさせたいときは`wrap_content`は使わないようにしましょう。
ちなみに貼ったリンクにはちゃんと書かれてありました。

<img width="898" alt="スクリーンショット 2017-11-09 19.07.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/98896/152b61ae-0926-2699-2954-763c1c518e6f.png">

ちゃんと読まないとダメですね

### 

## さいごに
領域さえ指定すれば，フォントサイズ(sp)を気にせずに開発できる上に，デザインするときもマージンを気にするだけでよくなるので，楽になりそうではありますね。

最近まで`android:singleLine`がDeprecatedされてること知らなくて（無知），一行に収める制約入れたくてつけてたら
「AutoSizing反応しないやん！」ってなりました...。
ヒアドキュメント

###ヒアドキュメント

■ekimukanri_formatorder.awkに出力結果を渡す処理
cat <<EOF |mongo # | `dirname $0` /ekimukanri_formatorder.awk
use crowidb
db.pages.find( { "path": ${TARGET}} ).forEach(
function(doc){
    db.revisions.find({ "_id": doc.revision }).forEach(function(item){
        print( item.path );
        item.body.match(/\|\d+:\d+\|[^\|]*\|[^\|]+\|[^\|]*\|[^\|]*\|/gi).forEach(
        function( order ){
                  print( order );
        })
    })
})

EOF

■例　書き込み
[root@localhost order]# cat <<EOF >> test.txt
\>test
\>EOF
[root@localhost order]# cat test.txt
111  222
333  333
444  444
test
test
GoでORMライブラリまわりを綺麗に書く

GoのWebアプリケーションで、ORM周りを綺麗に書くTipsです。
今回の例では、ORMに[go-gorp](https://github.com/go-gorp/gorp)を使ってます。

サービス層からマッパー層使うときに、gorpを直接触りたくないのと、
いちいちerror判定を入れるのが面倒なので、チェインで書けるようにしてみました。

コード一部の記載なので、よしなに参考にしてください。

## Before

マッパーがgorpを外に教えちゃうと

```mapper.go
// どこかで初期化する
var tx *gorp.Transaction

func GetTransaction *gorp.Transaction {
	return tx
}
```

サービスの全funcで、こんだけのエラー判定ずっと書くのヤバい・・・。
gorpに依存してるのも嫌だ。

```service.go
// 例）UserとSessionを作成してSessionを返す
func (s *Service) CreateUserAndSession() (*model.Session, error) {
	// *gorp.Transaction
	tx, errBegin := mapper.GetTransaction()
	if errBegin != nil {
		return nil, errBegin
	}

	u := model.NewUser()
	if errIns1 := tx.Insert(u); errIns1 != nil {
		return nil, errIns1
	}

	s := model.NewSession(u.ID)
	if errIns2 := tx.Insert(s); errIns2 != nil {
		return nil, errIns2
	}

	if errCommit := tx.Commit().Commit(); errCommit != nil {
		return nil, errCommit
	}
	return s, nil
}

```

## After
マッパーの方で、一枚噛ませるようにして、エラーも内包すると。

```mapper.go
package mapper

type MyTransaction struct {
	tx  *gorp.Transaction
	err error
}

func Begin() *MyTransaction {
	tx, err = gorp.dbMap.Begin()
	return &MyTransaction {
		tx:  tx,
		err: err,
	}
}

// CRUDをラップしてチェインできるように
func (t* MyTransaction) Insert(m *interface{}) *MyTransaction {
	if t.err == nil {
		t.err = t.tx.Insert(m)
	}
	return t
}

// 最後のコミット時にerrorを返す
func (t* MyTransaction) Commit(m *interface{}) error {
	if t.err != nil {
		return t.err
	}
	return t.tx.Commit()
}
```

サービス側がスッキリ。
error発生しても全てをリレーするため若干パフォーマンス勿体無いですが、
それが常時起こるような構造の方を改善すべきで、コードの保守性のメリットが大きいかなと思います。

```service.go
package service

func (s *Service) CreateUserAndSession() (*model.Session, error) {
	u := model.NewUser()
	s := model.NewSession(u.ID)
	if err := mapper.Begin().Insert(u).Insert(s).Commit(); err != nil {
		return nil, err
	}
	return s, nil
}

```
ワークスペースを開いた直後にRubyMineがフリーズする場合の解決方法

# 問題点
特定のワークスペースを開いた直後にRubyMineがフリーズしてしまう。

> Macでレインボーカーソルが表示されたままになりRubyMineを操作できなくなる

# 解決方法
RubyMineのCacheを削除する

## Macの場合
Macの場合は`~/Library/Caches/<PRODUCT><VERSION>`を削除。
削除するのが怖い場合は`<PRODUCT><VERSION>_bk`などにリネーム。

![rubymine01.png](https://qiita-image-store.s3.amazonaws.com/0/141934/cba78863-cd6c-c53e-adbe-6802126b4736.png)

## Cache保存場所
OS毎のCache保存場所については公式サイトの「[Directories Used by RubyMine to Store Settings, Caches, Plugins and Logs \- Help \| RubyMine](https://www.jetbrains.com/help/ruby/directories-used-by-rubymine-to-store-settings-caches-plugins-and-logs.html)」ページに掲載されてます。
NativeScriptのListView(iOS)でセル選択時の背景色をカスタムする

# 何がしたいのか

NativeScriptのListViewでは、セルをタップすると、背景がグレーになる。
この色を変更したい。

# テスト環境

NativeScript v3.3 + Angular 4
iOS 11のエミュレーターで動作を確認

# ダメだった方法

CSSをいじって、`ListView:hover` とか `ListView:highlighted` といった擬似クラスを付けてみたが、見事にすべて動かなかった。擬似クラスでは、タップ時の背景色を変えることはできないようだ。

# そもそも、iOSのネイティブアプリではどうやるのか

NativeScriptで困ったときには、ネイティブのノウハウを調べるのが早道だ。
iOSのUITableViewでセルの背景色を変更する方法を調べると、色々出てくる。

http://furodrive.com/2016/01/change_uitableviewcell_selection_color/
https://stackoverflow.com/questions/18823808/uitableviewcell-change-selectedbackgroundview-alpha

背景色用のUIViewを生成して、セルオブジェクトの `selectedBackgroundView` というプロパティに、そのUIViewをセットすれば良さそうである。実際に試したところ、以下の方法で背景色を変えることができた。


# うまくいった方法

```html:component.html
		<ListView [items]="items" (itemLoading)="onItemLoading($event)">
			<ng-template let-item="item" let-i="index">
			</ng-template>
		</ListView>

```

```ts:component.ts
	onItemLoading(args: ItemEventData){
		// iOS: セルをタップ時の背景をうすいグレーに設定
		if ( args.ios ) {
			let view : UIView = UIView.alloc().init();
			view.backgroundColor = new Color(10, 0, 0, 0).ios;
			let cell = <UITableViewCell>args.ios;
			cell.selectedBackgroundView = view;
		}
	}
```

# おわりに

問題が起きた時、ネイティブアプリ開発のノウハウが活かせるのがNativeScriptの素晴らしいところだ。ネイティブとのブリッジは少々難解な部分もあるが、使えると確実に出来ることの幅が広がる。以下の公式ドキュメントも参考になる。

https://docs.nativescript.org/angular/runtimes/ios/types/objc-classes
DialogFragmentでonActivityResult()をするハマったこと

#やりたかったこと
DialogFragment上のボタンを押すとギャラリーが開き、結果をDialogFragment上の`onActivityResult()`で受け取る。

#実際に起きたこと
DialogFragment上の`onActivityResult()`が呼ばれていない？
なぜかDialogFragment呼び出し元(MainActivity)の`onActivityResult()`が呼ばれている。
(こちらは別の操作で使用中。ていうかDialogFragmentのことはDialogFragment上で完結させたい)

#解決法
MainActivity上の`onActivityResult()`で`super.onActivityResult()`を呼ぶ。

#感想
とっても初心者なのでどうしてこれでDialogFragment上の`onActivityResult()`が呼ばれるようになるのかわからない…誰かコメントで教えてください。

#参考にしたサイト
[FragmentのonActivityResultが呼ばれない](http://shinonome.hatenablog.jp/entry/2015/08/17/235628)
Google Apps Script でセル結合を解除してシートを複製する


データ入力、閲覧では役に立つセルの結合ですが、プログラムで処理する場合は邪魔でしかありません。

- 普通にセル結合を解除すると左上のセル以外は空文字として結合が解除される
- プログラムで行単位処理する場合も、左上以外のセルは値は空文字

な仕様になっているので、プログラムで処理する場合には一旦セル解除したシートを作成し、そのシートに対して処理した方が良さそうです。


## Before

![スクリーンショット 2017-11-09 18.08.32.png](https://qiita-image-store.s3.amazonaws.com/0/20642/7904db0e-6d52-0b17-df71-5ed382f08601.png)


## After

￼![スクリーンショット 2017-11-09 18.09.28.png](https://qiita-image-store.s3.amazonaws.com/0/20642/44f7e982-2daa-6448-f048-5d05b69bc73d.png)


## スクリプト
```js
function createUnmergedSheet(sheetName) {
  // オリジナルのシート名_unmerged のファイルを作成
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sourceSheet = ss.getSheetByName(sheetName);
  var unmergedSheet = sourceSheet.copyTo(ss);
  var name = sourceSheet.getName() + "_unmerged";
  unmergedSheet.setName(name);

  // 作成したシート上の全セル結合を解除
  var ranges = unmergedSheet.getDataRange().getMergedRanges();
  for (var i = 0; i < ranges.length; i++) {
    var targetRange = ranges[i];
    var value = targetRange.getDisplayValue();
    targetRange.breakApart();
    targetRange.setValue(value);
  }  
}
```
artisan cache:clear したらセッションがふっとんだ

# 現象

CACHE_DRIVERとSESSION_DRIVERをどちらも`redis`にしたうえで

```
$ php artisan cache:clear
```
したところセッションが消えてこまった

# 原因

CacheとSessionで使っているRedisのDBが同じだから

# 対策

Cache用のDBと、Session用のDBを分けてやればよい

# 具体例

config/database.php でセッション用のredisの接続を定義して
config/session.php でその接続を指定するようにしました

```config/database.php
...
    /*
    |--------------------------------------------------------------------------
    | Redis Databases
    |--------------------------------------------------------------------------
    |
    | Redis is an open source, fast, and advanced key-value store that also
    | provides a richer set of commands than a typical key-value systems
    | such as APC or Memcached. Laravel makes it easy to dig right in.
    |
    */

    'redis' => [

        'client' => 'predis',

        'default' => [
            'host' => env('REDIS_HOST', '127.0.0.1'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => env('REDIS_PORT', 6379),
            'database' => 0,
        ],

        'session' => [
            'host' => env('REDIS_HOST', '127.0.0.1'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => env('REDIS_PORT', 6379),
            'database' => 1,
        ],

    ],
...
```

```config/session.php
...
    /*
    |--------------------------------------------------------------------------
    | Session Database Connection
    |--------------------------------------------------------------------------
    |
    | When using the "database" or "redis" session drivers, you may specify a
    | connection that should be used to manage these sessions. This should
    | correspond to a connection in your database configuration options.
    |
    */

    'connection' => 'session',
...
```
Swagger Editorでコメントを挿入する方法

# コメントは 『#』(シャープ)
![SnapCrab_NoName_2017-11-9_17-54-21_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/212825/2aa7a0d1-4713-6aa3-cf40-f72e87783a3b.png)
# エスケープは 『\』(バックスラッシュ)
![SnapCrab_NoName_2017-11-9_17-57-43_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/212825/0a45d3f0-926c-a69d-7869-ecc9d6eb5d33.png)
## エスケープしなくても動く？？
![SnapCrab_NoName_2017-11-9_18-0-58_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/212825/1f846407-3635-42cb-d9d6-ddb2b9f41f53.png)
macOS High Sierra + Python 3.6でmysqlclientをインストールする

## 概要
[mysqlclient-python](https://github.com/PyMySQL/mysqlclient-python)を公式のREADME.mdどおりにpipでインストールしようとすると、`IndexError: string index out of range`とエラーが出るので、下記の要領でインストールしたら成功した。

## コマンド

```
$ brew install mysql  # <- mysql-connector-cの代わり
$ pip3 install mysqlclient
```

## 雑記

- `mysql-connector-c`を使うMySQL系Pythonパッケージは軒並みインストールに失敗するぽいですね。
- 本当はREADME.mdを変更してPull Request出したほうが良かったのかもしれないのですが、原因を探っていろんな環境でテストして、しっかりしたIssueを書く時間がなかったです、すみません…

## 環境

- macOS High Sierra 10.13.1
- Homebrew 1.3.6
- Python 3.6.3
- pip 9.0.1
- MySQL 5.7.20

## 参考

- https://stackoverflow.com/questions/43634584/cant-install-mysql-python-with-pip-on-macos-10-12-4/43645248#43645248
- https://stackoverflow.com/questions/44501705/error-while-installing-mysqlclient-on-macos-sierra-python-3-6
4 Significant Benefits of Opting Carpet Flooring for Your Home

<p>Opting for carpet flooring can reward you several times as you enjoy its countless benefits. There are so many reasons to love carpet flooring for living rooms, play rooms, dining rooms and more. From durability to classy appearance, <a href="http://www.perthfocusonflooring.com.au/"><b>carpet in Perth</b></a> flooring can provide you with benefits listed below:</p>

<ul>
<li><p><b>Comfort:</b> The most important benefit of opting for carpet flooring is the great comfort. Walking into a well-finished carpet room can give you a cosy and welcomed feel.</p>

</li>
</ul>

<ul>
<li><p><b>Safety:</b> <a href="http://www.perthfocusonflooring.com.au/"><b>Carpet Perth</b></a> flooring also makes your home a safer place to live in, especially for children and elderly people as they are more prone to slip or fall, carpet flooring can save them from major injuries.</p>

</li>
</ul>

<ul>
<li><p><b>Appearance:</b> Carpets come in a variety of styles, colours and textures hence homeowners have flexibility to choose the one that perfectly matches the colour theme of the room. Carpets can also be considered as the best part for home decor that may attract your guests.</p>

</li>
</ul>

<ul>
<li><p><b>Warmth feel:</b> As carpets hold warmth inside them, hence they are perfect for flooring during extreme winter climate. These can provide a warmth and cosy feel inside your home and make people comfortable.</p>

</li>
</ul>

<p>As carpet floors can provide you with a variety of benefits, thus you should hire professionals to avail proper carpet flooring services. A professional makes carpet flooring installation easier on different type of floors and avoid rolls, lumps in the carpet. There are several companies available in the market which claims to be the best in offering carpet flooring services, but choosing the right one is imperative.</p>

<p>Perth Focus on Flooring is the most trusted Western Australian Company which provides top-of-the-line carpet flooring services. They boast a team of sales consultant which is dedicated to offering their customers with ultimate flooring experience possible. Apart from carpet flooring, Perth Focus on Flooring also provides timber flooring, laminate flooring and bamboo flooring services. They also import a wide range of flooring accessories such as splay beading, skirtings, stair nosing and scotia. Their mission is to serve their customers with 100% satisfaction through their quality services and professional guidance in selection of flooring.<br />

</p>
<p><b>About Perth Focus on Flooring:</b></p>

<p>Perth Focus on Flooring is a leading team of professionals specialized in offering top-quality <a href="http://www.perthfocusonflooring.com.au/"><b>Perth carpet</b></a>flooring services at highly competitive charges.</p>

<p>To know more details, please visit <b><a href="http://www.perthfocusonflooring.com.au/">Perthfocusonflooring.com.au</a></b></p>