OmniAICreator/Qiita-1.07M huggingface dataset:
ansible で Syntax Error

普段とは別の環境で playbook を書いていたら Syntax Error でハマったのでメモ。

```
$ ansible-playbook --version|head -1
ansible-playbook 2.4.1.0

$ ansible-playbook pg.yml
ERROR! Syntax Error while loading YAML.

exception type: <class 'yaml.reader.ReaderError'>
exception: unacceptable character #x001b: control characters are not allowed
  in "<unicode string>", position 117
```

ググってみると一応似たような報告はあるものの、解決には至っていない模様：

https://github.com/openshift/openshift-ansible/issues/3498

10分ほどハマってから気づきました。

```
~/linux-config/roles/postgresql/tasks$ nkf -g *
createdb.yml: ISO-2022-JP
main.yml: ISO-2022-JP
package.yml: ASCII
```

ファイルが ISO-2022-JP （ぉぃぉぃ

それにしても、どのファイルでエラーが起こったかくらいは出して欲しいなぁ。
偏差値以外の観点で大学を選んでみる


# はじめに
僕が高校生だったとき、どの大学を受験するかは自分の偏差値をベースに考えた。
以下のような表が高校の教室の後ろに貼ってあって、それを見ながら志望校を決めた気がする。
まぁ、妥当な決めかただったと思うけど、もっと違う軸で大学を見てみても面白かったかなと今更思って、今回は機械学習の勉強がてら違うパラメータで大学を見てみたいと思う。

![国公立大学偏差値表](http://blog.meigaku.ac.jp/tateishi/files/2011/07/331247cc6b997e7d0139a05c7feaf0c3.jpg)


# 進学に大事な要素
今回は、私の独断と偏見で以下の4つの要素で大学を評価する。

- 将来のお給料
    - 理由：大事だよね（笑）
    - パラメータ：卒業生の平均年収
    - ソース：[DODA](https://doda.jp/careercompass/ranking/daigaku_nenshu.html)
- 男女比
    - 理由：キャンパスライフの充実度はこれに尽きる！
    - パラメータ：学生の男女比
    - ソース：[パスナビ](https://passnavi.evidus.com/search_univ/0220/campus.html)
- 授業料
    - 理由：奨学金もらうひともいるしね
    - パラメータ：入学初年度の授業料の平均
    - ソース：[パスナビ](https://passnavi.evidus.com/search_univ/0220/expense.html)
- 大学が都会にあるか田舎にあるか
    - 理由：バイトするにしてもデートするにしても就活するにも都会の方がいいよね
    - パラメータ：大学の本部所在地がある市町村の人口密度
    - ソース：wikipedia


# データ

以下は自分でスクレイプしたデータ。今回は、これを利用する。合計124大学。
[university_data_with_header.csv](https://github.com/toita/university_pca/blob/master/data/university_data_with_header.csv)


# 手法
上記のように大事な要素が4個あって可視化しにくいので、まず次元を減らすために主成分分析する。
そのあと良さげな感じにグループ分けするためにK-meansを使う。
[実装はこちら](https://github.com/toita/university_pca/blob/master/university_pca.py)

# 結果
![university_pca.png](https://qiita-image-store.s3.amazonaws.com/0/171192/a492b688-c4b3-b5ab-34fa-670b130a0147.png)


主成分分析の結果は、第一主成分が0.40646819で第二主成分は0.24849364の寄与率。微妙。。
k-meansのCluster数は5個が一番しっくりきたのでそれで。
以下がクラスタごとの特徴。

- クラスタ0（青）
    - 特徴：女子率が高い系な私立大学。薬科大学も多い。授業料高め。
    - 主な大学：東邦、昭和、学習院、ICU、東京薬科大 etc
- クラスタ1（オレンジ）
    - 特徴：地方で授業料やすい系大学。地方国公立など。金銭的に親孝行な進路。下に飛んでる点は京都府立大学（女子率高）。
    - 主な大学：筑波大学、千葉大学、弘前大学、信州大学 etc
- クラスタ2（緑）
    - 特徴：都会で将来の年収も多い系大学。上に2個突き出てる点は、東工大と東大。
    - 主な大学：東大、一橋、東工大、慶應、早稲田 etc
- クラスタ3（赤）
    - 特徴：中堅都市の私立大学。男女比もまあまあ。
    - 主な大学：日本大学、中央大学、上智大学、明治学院大学 etc
- クラスタ4（紫）
    - 特徴：政令指定都市などの国公立大学。年収もまずまず。一番左の飛んでる点は防衛大。
    - 主な大学：京都大学、東北大学、埼玉大学、九州大学 etc

詳しい結果は[こちら](https://github.com/toita/university_pca/blob/master/data/results.log)


# どの大学に進学すべき？
主成分分析&K-meansしなくてもわかることだが、、

- 薬科大学は女子の比率も給料も高いのでやはりそこが安パイ（授業料も高いけど）
- 金銭的にリーズナブルな所を選ぶなら、地方国公立。
- 年収高めをめざすなら、国公立。


# まとめ
- 年収、男女比、授業料、都会度を入力にして主成分分析 + Kmeansした
- 累積寄与率は0.654961831763とそんな高くない
- 年収はMINとMAXでそんなに差がないから結果にそこまで寄与してなさそう。
- 個人的には、薬科大は授業料が高いけど女子率&年収も高いのでオススメ！
- 特定の第一志望校がある場合、同じクラスタの大学を併願しても良いかも！（レコメンドっぽいこと）
レプリケーション遅延を発生させないMySQLデータ更新

# 目的
レプリケーションを行っているMySQL環境にて
大量のデータ更新、削除をサービスを停止させずノーメンテで行うことを目的としています。

# 背景
大量のデータ更新、削除を行う際、ある程度の塊を対象とした作業を行うことが多いと思います。
(例：ある期間に登録されたデータ, あるタイプを持つデータ)

```
DELETE FROM hoge WHERE ins_date BETWEEN '2017-01-01 00:00:00' AND '2017-06-30 23:59:59';
```

その際、単純なWhere句を使用し1クエリで実行をしてしまうと実行に時間がかかり、
同等の実行時間がスレーブでも発生するためレプリケーション遅延の原因となります。

ですので理想としては各UPDATE,DELETEクエリはPrimaryKeyを指定して実行ができると好ましいです。


```delete_old_hoge.sql
DELETE FROM hoge WHERE id=1;
DELETE FROM hoge WHERE id=2;
DELETE FROM hoge WHERE id=3;
...
DELETE FROM hoge WHERE id=999999;
DELETE FROM hoge WHERE id=1000000;
```

```
mysql -u user -ppass fuga < delete_old_hoge.sql
```

ですが、各クエリを1SQLファイルにまとめてインポートをしてしまうと、
そのインポートが1トランザクションとして扱われ、この1SQLファイルの処理にかかった時間が
同様にスレーブでもかかり、こちらもレプリケーション遅延の原因となります。

ではどうすればよいのでしょうか？

# 実行用スクリプトの作成
オススメとしては用意したSQLファイルの各クエリを
1クエリ1トランザクションで反映するスクリプトを作成します。

## execute_query.sh
```
#!/bin/sh

l_num=1

BUFIFS=$IFS
IFS=

exec 3< $1
while read FL 0<&3
do
        if test `expr $l_num % 1000` -eq 0 ; then
                sleep 1s
        fi
        echo "$FL"
        mysql -h [DBHost] -u [User] -p[Password] -A [TableName] -e $FL
        l_num=`expr $l_num + 1`
done
exec 3<&-

IFS=$BUFIFS
```

## 実行方法

```
sh execute_query.sh [SQL File Path]

```


このような1クエリ1トランザクションでクエリを実行する方法を取ることで
時間こそかかりますが安全にかつ作業も少なくクエリを反映することができます。

1回スクリプトを用意しておくと何かと便利なのでオススメです。
raspberry pi 3 でstretch その14

#概要
raspberry pi 3 でstretchやってみた。
node-redやってみた。

#写真

![2017-11-14-152653_1024x768_scrot.png](https://qiita-image-store.s3.amazonaws.com/0/18104/18e65741-264b-f5d4-02fa-865893b5ab33.png)


#環境
Raspberry Pi 3 model B v1.2 element14
2017-09-07-raspbian-stretch

#設定

sudo systemctl enable nodered.service

#サンプルコード
injectionノードを貼る。

```
名前 power on
起動時に実行
```

execノードを貼る。

```
名前 start
コマンド sudo python /home/pi/py/atart.py
```
ノードをつなぐ。
デプロイ実行。

以上。
python3で外部プログラムとstdin/stdoutで双方向通信を行う

# やったこと

python3でsubprocessを利用して外部プログラムと双方向通信をしたかったのですが、その情報が見つけられなかったため、自分でモジュールを作成しました。

# はじめに

python上でfasttextを利用して機械学習を試していますが、python用のfasttextのモジュールがバグがあるらしく、現状は複数の文をテキストファイル化してバッチ的に処理を行っていました。
それを、テキスト１文ずつ文字列で渡して、結果が返ってくればいいな。。。。

# 作ったもの

モジュール化したものを作成しました。

```shell_communication.py
import subprocess

class Execute(object):
    """外部プログラムを実行。stdinとstdoutで対話する。"""
    
    def __init__(self, *args_1, **args_2):
        if 'encoding' in args_2:
            self.encoding = args_2.pop('encoding')
        else:
            self.encoding = 'utf-8'
        self.popen = subprocess.Popen(*args_1, stdin=subprocess.PIPE, stdout=subprocess.PIPE, encoding=self.encoding, **args_2)
    def __enter__(self):
        return self
    
    def __exit__(self, type, value, traceback):
        self.close()
        
    def send(self, message, recieve=True, incr=False):
        message = message.rstrip('\n')
        if not incr and '\n' in message:
            raise ValueError("message in \\n!")
        self.popen.stdin.write(message + '\n')
        self.popen.stdin.flush()
        if recieve:
            return self.recieve()
        return None
    
    def recieve(self):
        self.popen.stdout.flush()
        return self.popen.stdout.readline()
    
    def close(self):
        self.popen.stdin.close()
```

※ ゾンビプロセスができる場合があるため、waitを追加。

# 使い方

ソースを見ていただけると分かるとは思いますが以下の通りです。

```
import shell_communication
e = shell_communication.Execute(引数)
```

として使います。
引数は、Popenと基本的に同様ですが、以下が異なります。

- 常に、stdin=subprocess.PIPE, stdout=subprocess.PIPEを指定している。
- encodingをデフォルトで'utf-8'指定している。

以下サンプルです。

```sample.py
import shell_communication
e = shell_communication.Execute(["cat", "-n"])
for i in range(10):
    print(e.send(str(i)))
```

出力

```
     1	0

     2	1

     3	2

     4	3

     5	4

     6	5

     7	6

     8	7

     9	8

    10	9
```

# 分かったこと

- stdin,stdoutはbinaryなので、encode,decodeが必要。
- stdinに書いてもバッファリングされるため、flushが必要。

# 疑問点

- 出力を、self.popen.stdout.readline()で取得しているため、出力がない場合にブロックしてしまう。どうすればいいんだろう？？

# 感想

- 今までこういうことはnode.jsを利用して非同期にやってきました。pythonだとなんでもブロックしちゃって書きにくいなぁ。。。
Terminalを使ってBoot USBを作る方法

使っていないPCにCentOSを載せたいと思ったのでBoot USBを作ってみました。



#前提
##私の環境
macOS version 10.13.1
Shell : Zsh
##使ったコマンド
diskutil (/usr/sbin/diskutil)
dd (/usr/local/opt/coreutils/libexec/gnubin/dd)

##用意するもの
Boot出来るISOイメージ
USBメモリ（容量はISOイメージのサイズ以上でOK）



#実際にセットアップしてみる

##手順 1 : USBのパスを調べる
```
$ diskutil list
```
を入力するとアクセスできる記憶媒体のリストが表示されます。

```
/dev/disk0 (internal):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                         251.0 GB   disk0

/dev/disk1 (synthesized):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      APFS Container Scheme -                      +250.0 GB   disk1
/dev/disk2 (external, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *15.8 GB    disk2
   1:             Windows_FAT_32 X DATA                  15.8 GB    disk2s1
```
この`/dev/disk2`が今回のパスになります。
環境によってはこのパスが変わりますので容量を参考にパスをメモしてください。


##手順 2 : MS-DOSで初期化する
```
$ diskutil eraseDisk MS-DOS UNTITLED /dev/disk2    
```
`/dev/disk2`をMS-DOSで削除します。
`/dev/disk2`の部分は手順1でメモした物を使ってください。
 

##手順 3 : FinderからUSBをアンマウントする
```
$ diskutil unmountDisk /dev/disk2
```    
次の手順のためにUSBをアンマウント(安全に取り外せる状態)します。
`/dev/disk2`の部分は手順1でメモした物を使ってください。

##手順 4 : ISOをセットアップする
ついに、ISOイメージをセットアップします。
```
$ sudo dd if=./CentOS-7-x86_64-Everything-1708.iso of=/dev/disk2 bs=32MB
```
`if=`から`スペース`の間でインストールしたいISOイメージを指定します。
`of=`以降の`/dev/disk2`の部分は手順1でメモした物を使ってください。

####メモ
if(Input file)-----インストールするISOのパス
of(Output file)---出力先のUSBのパス
bs(Buffer Size)--メモリに一旦保存するサイズ


##手順 5 : 完成！
後はこのUSBを使ってOSをインストールするだけです。
文字列から enum 型への安全な変換

# 文字列からの変換

文字列を数値型とか enum 型とかに変換する場合、`Parse()` とか `TryParse()` を使うかと思います。

`Parse()` は、成功すれば変換された値が返ってくる点は楽なのですが、失敗したときに例外を吐くので少々扱いにくいです。

一方、`TryParse()` のシグネチャは `bool TryParse(string s, out T v)` となっています。返り値は解釈成功・失敗を表し、変換された値は `v` に入ります。変数 `v` を事前に宣言する[^1]面倒くささはありますが、失敗したときの処理は簡単です。

[^1]: C# 7 では、事前の宣言が不要になるようです。

# enum 型への変換

enum 型には、`bool Enum.TryParse<TEnum>(string s, out TEnum e)` が使えます。
名前からでも数字からでも `TEnum` 型に変換できます。

```csharp
enum Weekday {
  Sunday = 0,
  Monday = 1,
  Tuesday = 2,
    :
  Saturday = 6
}

Weekday wd;
Enum.TryParse("2", out wd); // true, wd = Weekday.Tuesday
Enum.TryParse("Friday", out wd ); // true, wd = Weekday.Friday
Enum.TryParse("April", out wd); // false, wd = ?
```

ところが、数字からの変換が曲者で、enum 型で定義していない値でも変換に成功したことにして `out`の変数に入れてしまいます。

```csharp
Enum.TryParse("100", out wd); // true, wd = 100
```


# enum 型への安全な変換

ある値が enum 型で定義されているか検証するには、`Enum.IsDefined()` を使います。これを `TryParse()` と組み合わせれば、安全な変換が実現できます。

```csharp
static class EnumExt
{
  static bool TryParse(string s, out Weekday wd)
  {
    return Enum.TryParse(s, out wd) && Enum.IsDefined(typeof(Weekday), wd);
  }
}

EnumExt.TryParse("100", out wd); // false, wd = 100
```

任意の enum 型に対応するため、ジェネリック化します。
型パラメータ `TEnum` は enum 型のみを許容するので、'where` 節で制約します。

```csharp
static class EnumExt
{
  static bool TryParse<TEnum>(string s, out TEnum wd) where TEnum : struct
  {
    return Enum.TryParse(s, out wd) && Enum.IsDefined(typeof(TEnum), wd);
  }
}

Weekday wd;
EnumExt.TryParse("Thursday", out wd); // true, wd = Weekday.Thursday
SolarSystem ss; // Sun=0, Mercury, Venus, ...
EnumExt.TryParse("5", out ss); // true, ss = SolarSystem.Jupiter
```

> 残課題
> - `: struct` は、`TEnum` を値型に制約しています。できれば enum 型に制約したいのですが、enum 型はクラスではないのでできません。
> - 作成した `TryParse` は自作クラスのメンバになります。できれば `Enum` 型の拡張メソッドにしたいのですが、静的メソッドで `this` を引数にできないので、拡張メソッドにはできません。
Power BI Desktop 2017年11月のアップデート内容

今月も **Power BI Desktop** の更新時期が来ましたよってことで、**Power BI Blog** の内容をざっくり日本語にしました。
ご参考までに。詳細は下記のページの YouTube 動画を見てください。
YouTube で Power BI と検索しても出てくるはずですがリンクも載せておきます
###[Power BI Desktop Update - November 2017]
https://youtu.be/sI3yRjdnJ7w

#[Power BI Desktop 2017年11月のアップデート]
https://powerbi.microsoft.com/ja-jp/blog/power-bi-desktop-november-2017-feature-summary/

- ルールベースの条件付き書式 - テーブル、マトリックス
- セル内の横位置指定 - テーブル、マトリックス
- 選択ウィンドウによるオブジェクト（グラフや表）のコントロール
- レポート内でのオブジェクトのロック（固定）
- ArcGIS Maps for Power BI に Esri Plus Subscription が新たに[リリース](https://powerbi.microsoft.com/ja-jp/blog/esri-plus-subscription-for-arcgis-maps-for-power-bi-is-now-available/)
    - 月額 $5.00/ユーザー
    - 様々なグローバルオープンデータへのアクセス
    - 12のベースマップ(地図背景)
    など
- Slow データソースへのオプション
    - クエリを減らす オプション
    - デフォルトでクロスハイライトを無効化する
    - スライサー、フィルターで [適用] ボタンを表示
- 最近追加されたカスタムビジュアル
    - [Image Timeline](https://appsource.microsoft.com/ja-jp/product/power-bi-visuals/WA104381254?tab=Overview)
    - [Social network graph](https://appsource.microsoft.com/ja-jp/product/power-bi-visuals/WA104381236?tab=Overview
)
    - [Venn daigram by MAQ Software](https://appsource.microsoft.com/ja-jp/product/power-bi-visuals/WA104381231?tab=Overview)
    - [HTML viewer](https://appsource.microsoft.com/ja-jp/product/power-bi-visuals/WA104381214?tab=Overview)

##分析
・セルレベル書式設定 多次元モデル 複数行カード

##データ接続
・Impala Connector - Windows 認証のサポート

##クエリ編集
・Add Column From Example Improvements
    - 既存列の値を、いわゆる Key-Value の Key にして、新たな Value 列を 条件付き列 として作成することができる
これからGitでのソース管理者になる人へ

いまあなたはSubversionの管理者で、日々の開発案件で、Subversionに特に大きな不満は持っていない、上手く言っていると思っている。ただ、世間ではGitという名前が聞こえてくる、多分ソース管理の仕組みなんてそんなに変わらないし、必要になったら勉強しよう、と考えている。

そういう管理者がいざ急にGitでのソース管理になり、開発メンバーは全てGitは初めて使う、というプロジェクトは恐らく悲惨な結果を招きます。GitはSubversionとは異なることを管理者はまざまざと見せつけられ、あるものはGitを使うことを怖がり逃げてしまい、あるものは、これを期にようやく真剣に学び始めます。

学習するものはネットで検索をし、少しずつ学んでいくが実際に現場でGitに挑むと、様々な想定外の経験をすると思います。

ここでは、その初めてのGit管理者に少しでも参考になる事前実施事項を挙げています。

## Pull, Fetch, Pushの概念を教える

初めてGitを使用する人が最初につまずくのが、Pull等をしないで、Pushをしようとして、Pushができないという事象です。
Gitを長く使っている人は当たり前でも初心者は最初につまずきます。

## Rebase, Merge (ff, no-ff)の理解と、コンフリクト時の操作を教える

これも同様につまずくポイントで、特に初心者はRebaseのことをあまり分からず何でもMergeをする、こうなるとコミット・ツリーは意味のない枝ばかりになります。

## 改行コードを統一する

特にWindows環境の場合は特に重要で、改行コードはUnix系のLFに統一するような設定をすべきです。

## 分かりやすいブランチ・モデルを選択する

[a successful git branching model](http://nvie.com/posts/a-successful-git-branching-model/) ([日本語訳](https://qiita.com/homhom44/items/9f13c646fa2619ae63d0)) というブランチ・モデルが非常に有名になり、特にGitの初心者はこれをネット検索で引っかかりやすいため、まず最初に「これこそ実績のあるブランチ・モデルだ！」と盲目に受け入れてしまいます。  
ところが、この有名なブランチ・モデルは初心者が始めるにはリッチすぎて、多分すぐに行き詰まると思います。Git Flowはその価値をメンバーが十分に認識できるのであれば採用すればよいと思いますが、そうでないならば、もっとシンプルな戦略を取るべきでしょう。  
とにかく最初はシンプルに始め、徐々に課題が出てきたら、様々なブランチ戦略を試すのがよいです。(最初はmasterだけでもよいと思います)

## 良い管理ツールを使用する

あなたがGitHubを使用したことがあれば、この意味が分かるとは思うが、GitはGitHubのようなツールと一緒に使うことが望ましいです。

* ブランチはいつでも作れ、いつでも消せる (もちろんちゃんとしたコントロール配下で)
* Pull Request/Merge Requestのようなマージをコントロールするワークフローが備わっている
* ソース等にコメントができる
* チケットと連動ができる

など。  
Gitを使用する場合は、ツールも一緒に検討しましょう。


## EclipseのGitマージツールを使用しない

これは私が経験したことです。  
Git管理者から「マージが失敗して、全ファイルに差分がでてしまいました」という悲痛な連絡がありました。
Eclipseでマージ・コミットの確認をすると、コミットしているのは、数ファイルで問題がないのに、なんとGitコマンドで確認すると、すべてのファイルが改行コードが変わってコミットされていました。
その管理者はEclipseのみで確認していたので、そのままPushをしてしまいました。  
なんという恐ろしいことと思いますが、これは実際に起こったことです。ひょっとすると、いまはもうEclipse (JGit)側で修正されているかもしれないですが、もう恐ろしくてEclipseのGitツールはAddくらいしか使用しないルールにしました。

## まとめ

以上が私が経験した中ので、ソース管理者へのTipsです。参考になれば。

**Hirofumi Arimoto**

Java, Scala, JavaScriptや、機械学習に興味あり
実際の開発での知見を可能な限り記事にしたいと思っている
20代半ばの若僧が2回転職したときに気を付けていたこと(システムエンジニア)

# 僕が転職活動をするにあたり気を付けていること

こんにちは。@mashiと申します。20代半ばの僕が転職活動をするにあたり、気づいたことや気を付けていたことを記載していきます。
**あくまでも僕の個人的な意見です**ので、ご理解いただける方だけ読んでいただければ幸いです。
そしてなにより、これを読んでいる方のご助力となれば嬉しいです。


## なぜ書くのか

僕は初めての転職活動では、(当たり前でしたが)なにも分からない状態でした。
「ググれば大丈夫でしょ！」なんて思っていましたが、情報多すぎですね・・・
そしてなにより、**エージェントの会社さんが載せている情報**がわりと検索結果の上位にくることが多かったんですよ。
で、そういう記事って「エージェントさんを利用するために書いたもの」なのかなって思ってしまいまして(僕がひねくれ者であるせいも大いにあると思います)、じゃあ何を信じたらいいの？というふうになりました。


であるならば、エンジニアの端くれとして、自分の体験談を書いておこうかなと。
そしてそれが少しでも誰かにプラスになってもらえたらと思い書くことを決めました。(誰にも読まれないなら僕のメモとして残す予定です)


## 一番心にとどめていたこと
- 真実を見極める
  - エージェントは人によっては営業数字のために嘘をつく
  - 面接官は人によっては採用実績のために嘘をつく
  - とはいえ全てが嘘というわけでも全員が嘘をつくわけでもない
  - 提示された給与と本社の場所だけは唯一信用できる(絶対ではないけれど)
- 今(2017年～2020年)はエンジニアは売り手
  - 会社選びの選択肢が多い
  - わけの分からないことを言う会社は蹴ってしまえばいい
  - **自身を安く売る必要は全くない**

## エージェントについて
- 話を鵜呑みにしない
- 受ける気がない企業はしっかり断る
- 信用できないエージェントならエージェントを変えてもらうかそのエージェント会社を利用しない
- **初めての転職活動なら１度はお世話になったほうがいい**
  - 面接練習
  - 職務経歴書
  - 履歴書
  - 業界情報
- 必要がないと感じたらその旨を伝えるのも全く問題ない
  - その際は最低限のマナーを守りましょう(突然音信不通になることはしないetc...)
- **自身にとってちょうど良い距離感を保つ**

## ここに気を付けていた
### 給与面
- ベース給与
- みなし残業かどうか
- みなし残業であるなら何時間か
- 賞与は存在するか
- 大まかな直近５年の賞与実績(１人当たり何か月分くらいか)
- 大まかな直近３年の昇給平均(１人当たりいくらくらいか)

### 会社概要
- 最寄駅からの距離
- 会社周辺のお店
- 面接官や会社の雰囲気(なんとなくの空気感も)
- 業務として今後長く売れると思えるか
- 自身が胸を張って言える会社・業務か

### 業務内容
- 正社員かどうか
- 自社サービス開発/受託/SES/業務委託などの中ではどれに属することになるのか
- 就業時間
- 休日(盆休み・年末年始含む)
- フレックス制度の有無とコアタイム

## 情報収集していたサイト
- 転職会議
- カイシャの評判
- Vorkers


## 最後に
最終的に、面接を受けるか・入社するかは**いろいろな条件のバランス**かなと思っています。
そしてなにより、当たり前ですが、自分が納得できるかどうか。

どの会社にもきっと良いところ悪いところがあると思います。

そして、正直なところ、入社してからじゃないと分からないと思っています。
なので、**外せない条件だけはきっちり押さえて、入社してみて合わなかったらスッパリ辞めるのも手**かなと思っています。

## 【おまけ】僕が２度目に転職活動していた時のマスト項目
- 給与(額面30万以上)
- 業務内容は自社サービス開発・保守であること(コーディングがメインであれば良い)
- 通勤時間1時間以内
- 年功序列じゃない社風であること
- 完全土日休日

※バランスによっては多少の違いがあっても許容してました

ご意見・ご感想等あればいただければありがたいです。

20190305.追記
エンジニア中途の有効求人倍率は**約7～8倍**であるようです。すごい。

20190725.追記
エンジニア中途の有効求人倍率は**約8～9倍**とさらに上昇したようです。とんでもないインフレですね…

20201113.追記
エンジニア中途の有効求人倍率は**約4～5倍**であるようです。コロナ禍ではありますが大きな案件もあるようですので言語によってはエンジニア需要はまだありそうですね。
途切れた線の描画

[Interrupted Line (1) | CreateJS](http://labo.project-nya.jp/createjs/interrupted_line/ver1/)

```js
var graph = new createjs.Shape();
stage.addChild(graph);
graph.graphics.setStrokeStyle(3, "round", "round");
graph.graphics.beginStroke("#FF3366");
var drawn = false;
for (n = -320; n <= 320; n++) {
	px = n;
	py = 120*Math.sin(n*RADIAN);
	if (!drawn) {
		graph.graphics.moveTo(px, -py);
		drawn = true;
	} else {
		graph.graphics.lineTo(px, -py);
	}
}
graph.graphics.endStroke();
```

[Interrupted Line (2) | CreateJS](http://labo.project-nya.jp/createjs/interrupted_line/ver2/)

```js
var graph = new createjs.Shape();
stage.addChild(graph);
graph.graphics.setStrokeStyle(3, "round", "round");
graph.graphics.beginStroke("#FF3366");
var interrupted = true;
for (n = -320; n <= 320; n++) {
	px = n;
	py = 120*Math.sin(n*RADIAN);
	//描画領域を制限
	if (-py > -LIMIT_HEIGHT && -py < LIMIT_HEIGHT) {
		if (interrupted) {
			graph.graphics.moveTo(px, -py);
		} else {
			graph.graphics.lineTo(px, -py);
		}
		//連続している
		interrupted = false;
	} else {
		//途切れた
		interrupted = true;
	}
}
graph.graphics.endStroke();
```
Windows10について

サポートや更新について情報が錯そうしているWindows10。
頭の中を整理するために情報をまとめておく。情報が古くなっている可能性もあるため注意。

## Windows10で提供されるエディション

| エディション | 特徴 |
| :--- | :--- |
| Home | 家庭向けであり、いくつかの機能がオミットされている。 |
| Pro | SOHO向けであり、ほとんどの機能を利用できる。 |
| Enterprise | 企業利用向けであり、フル機能を利用できる。 |
| Education | 教育機関利用向けであり、ほとんどの機能を利用できる。 |
| LTSB | ベースはEnterpriseだが、アップデート体系が特殊。 |
| S | ストアアプリのみインストールできる。 |

## LTSBとLTSB以外のエディションは別物として考える
LTSBは "Long Term Servicing Branch" の略称であり、提供開始から10年間(メインストリーム5年＋延長サポート5年)に渡って、**品質更新プログラムのみ**提供される特殊なエディション。
その他のエディションからはアップグレードすることが出来ず、例えばProからLTSBにしたい場合にはクリーンインストールが必要になる。

## LTSBは毎年配信されるわけではない
現時点では2015と2016が配信されているが、2017が出ていないところを見ると毎年出るわけではなさそうである。

| バージョン | リリース日 | 延長サポート終了日 | サポート状況 |
| :--- | :--- | :--- | :---: |
| LTSB 2016 | 2016.8.2 | 2026.10.13 | ○ |
| LTSB 2015 | 2015.7.29 | 2025.10.14 | ○ |

## アップデート体系が変更された
Windows10からWaaS(Windows as a Service)という更新モデルになり、年に2回大型のアップデート(機能アップグレード)が配信されるようになった。

### 機能アップグレードについて
LTSBを除いたWindows10の全エディション向けに、新しい機能が追加される大型のアップデートが配信される。
これを機能アップグレード(Feature Upgrade)と呼ぶ。

機能アップデートの現在の配信状況は以下の通り。

| 機能アップデート | リリース日 | サポート終了日 | サポート状況 |
| :--- | :--- | :--- | :---: |
| 1709 (Fall Creators Update) | 2017.10.17 | 2019.3 予定 | ○ |
| 1703 (Creators Update) | 2017.4.11 | 2018.9 予定 | ○ |
| 1607 (Anniversery Update) | 2016.8.2 | 2018.3 予定 | ○ |
| 1511 (November Update) | 2015.11.12 | 2017.10.10 | × |
| 1507 (初版) | 2015.7.29 | 2017.3.9 | × |


### 機能アップグレード毎のサポート期間について
機能アップグレードにきちんと追従していけば、原則として永続的にサポート(品質更新プログラムなど)を受けられることになるが、もし追従しない場合には、~~n+2バージョンが提供された時点~~ 配信から18ヵ月でサポートが終了する。

なお、機能アップグレードはスキップしてはならず、順番に適用しなければならない。
例えば、1607→1709といったように間の1703を飛ばさず、1607→1703→1709といったようにしなければならない。
※できないわけでは無いが、不具合が起きる可能性がある。


### 更新チャンネルについて
更新チャンネルとは、"半期チャネル(ターゲット指定)" と "半期チャネル" の2種類がある。Windows上の設定で切替可能。
※1703以前は "Current Branch, CB" と "Current Branch for Business, CBB" と呼ばれていた。

真っ先に機能アップグレードが配信されるのは "半期チャネル(ターゲット指定)" であり、約4ヵ月遅れて "半期チャネル" に配信される。
半期チャネル(ターゲット指定)は、OSが起動しないなどのクリティカルなバグを内包している可能性があるため、半期チャネルに設定して成熟するのを待ったほうが良い。

更新内容的には "半期チャネル(ターゲット指定)" と "半期チャネル" に差はない。単純に配信時期が遅れるだけである。


## 参考
* WaaSについて:
https://docs.microsoft.com/ja-jp/windows/deployment/update/waas-quick-start
https://blogs.msdn.microsoft.com/nakama/2016/08/18/win10waas-part3/

* リリース情報:
https://technet.microsoft.com/en-us/windows/release-info

* サポート期限など:
https://support.microsoft.com/en-us/help/13853/windows-lifecycle-fact-sheet
https://support.microsoft.com/en-us/lifecycle/search?alpha=Windows%2010%20Enterprise%20LTSB
レッツラズパイ！〜Webカメラで監視しちゃうゾ編〜

## レッツラズパイ！・プロジェクト
1. [レッツラズパイ！〜Raspberry3にOSをインストールしよう〜](https://qiita.com/westvirginia/items/edc3b56da7be58419d70)  
[【番外編】レッツラズパイ！〜"ディスプレイなしで"RaspberryPiにOSをインストールしよう編〜](https://qiita.com/westvirginia/items/0d3b7d7dd19116cc14bf)
2. [レッツラズパイ！〜Lチカ＆Lピカをマスターしよう編〜](https://qiita.com/westvirginia/items/e339dbaf3286ea966483)
3. レッツラズパイ！〜Webカメラで監視しちゃうゾ編〜(これ)
4. [レッツラズパイ！〜温度センサーとmailgunで検知メールを送ろう編〜](https://qiita.com/westvirginia/items/c06887fd464e3718082d)
5. [レッツラズパイ！〜Google HomeでLピカさせよう編〜](https://qiita.com/westvirginia/items/47437d547485cd2784ef)
6. [レッツラズパイ！〜Google Homeに室温を教えてもらおう編〜](https://qiita.com/westvirginia/private/f0842c034695665a78a6)
7. [レッツラズパイ！〜Lチカボタン編〜](https://qiita.com/westvirginia/private/7b33d27ce50d30895e13)

RaspberryPiを始めて触る＆IT初心者向けのドキュメントです。私の所属する会社で使う、IT初心者の方のインターンシップ向けのドキュメントとして書きはじめたので、かなり丁寧に書いていますがご了承下さい。



## Webカメラを使ってスマホから監視しよう

### 用意するもの
- USBカメラ
- スマホ
    - RaspberryPiと同じネットワークのWifiに接続しておく

### 簡単な構成図
スマホとRaspberryPiは同一のネットワークのWifiに接続させます。RaspberryPiにはUSBポートが予め用意されているので、USBカメラをRaspberryPiに接続し、motionというモジュールを使って映し出された映像をスマートフォンでリアルタイム監視します。

![構成図](https://qiita-image-store.s3.amazonaws.com/0/164786/bba5a0d2-f7c9-943b-1107-21d240231198.jpeg)


### USBカメラの接続
カメラを接続する前に、RaspberryPiにSSH接続をし、以下のコマンドを実行してください。

```
$ lsusb
```

これは、USBデバイスを確認するためのコマンドです。デバイスナンバーやIDが表示されたかと思います。次に、USBカメラをRaspberryPi本体のUSBポートに接続します。接続したら、Raspberry PiがUSBカメラを認識しているのか確認します。

```
$ lsusb
```

先ほどの結果とは違う結果が表示されたかと思います。その表示された差分が、今回接続されたUSBカメラの情報となります。今回はRaspberryPiがカメラを認識できていればOKなので、先に進みます。

### motionのインストール
motionというモジュールを使えば、とても簡単にWebカメラのシステムを構築することが出来ます。以下のコマンドを実行してmotionをインストールしましょう。

```
$ sudo apt-get install motion
# 続行しますか？[Y/n] は、Yを入力し次に進む
```

インストールできたら、コンフィグを編集し、motionの基本設定を行います。ファイルには既に設定値が記入されていますので、編集する値のみ以下の内容を参考にして編集してください。

```
$ sudo vim /etc/motion/motion.conf

daemon on               # motionをサービスとして実行
width 640               # 幅
height 480              # 高さ
framerate 30            # フレームレート
threshold 3000          # 検知の閾値を変更
output_pictures off     # 写真キャプチャはとりあえず無効に
stream_localhost off　　　　　　　　# 本体からのみのストリーミング無効
```

motionをサービスとして動かすために、 以下を編集します。
（start_motion_daemonを「no」から「yes」に変更します。）

```
$ sudo vim /etc/default/motion

start_motion_daemon=no
↓
start_motion_daemon=yes
```

カメラに映し出された画像は指定のフォルダに保存されていくため、保存ディレクトリに権限を付与します。

```
$ sudo chmod 777 /var/lib/motion 
```

　これで基本設定は以上となります。

### Webカメラにアクセス！

設定が完了したら、motionをサービスとして実行してみましょう。

```
$ sudo motion -n  
```

正常に起動できていれば、8081ポートでWEBカメラとして動作しているはずです。 スマホでブラウザから以下のURLに接続してください。

```
http://raspberrypiのIP:8081/
```

ブラウザから接続できればWEBカメラは完了です。

Webカメラで監視しちゃうゾ編は以上です。お疲れ様でした♪次は[レッツラズパイ！〜温度センサーとmailgunで検知メールを送ろう編〜](https://qiita.com/westvirginia/items/c06887fd464e3718082d)です。
ViewControllerとUIをクラスで分離する方法 - Swift3.0

# 概要

UIの定義がViewControllerに沢山書いてあると可読性が下がるので、UIを別のクラスに定義してViewControllerではaddSubviewするだけにしようと思いました。ViewControllerに書かれる行数が減って楽です。今回は、外部のクラス（.swiftのファイル）に定義した`UISlider`をViewControllerに呼び出して使いたいと思います。

# 説明

大まかな処理の流れはこんな感じ。まず`class UISliderStartEnd`を定義して、`class UISliderStartEnd`の中に` UISlider`を引数として返す関数`func makeSliderStartEnd`を作ります。

ViewController内ではクラスをインスタンス化して使えるようにします。そのあとに`addSubview`の引数でインスタンス化したクラスの関数を実行します。返り値がUISliderを返すので`addSubview`することができます

# 実装

## UISliderStartEnd.swift

```UISliderStartEnd.swift

import Foundation
import UIKit

class UISliderStartEnd:UIViewController{
    
    
    func makeSliderStartEnd() -> UISlider {
        
        // スライダー
        let startPointSlider = UISlider(frame: CGRect(x:0, y:0, width:350, height:30))
        startPointSlider.layer.position = CGPoint(x:self.view.frame.midX, y:500)
        startPointSlider.backgroundColor = UIColor.white
        startPointSlider.layer.cornerRadius = 10.0
        startPointSlider.layer.shadowOpacity = 0.5
        startPointSlider.layer.masksToBounds = false
        startPointSlider.addTarget(self, action: #selector(self.onStartPointlabel(_:)), for: .valueChanged)
        
        // 最小値と最大値を設定する.
        startPointSlider.minimumValue = 0
        startPointSlider.maximumValue = 100        
        return startPointSlider

    }
    
    /*
     Sliderの値が変わった時に呼ばれるメソッド
     */
    
    @objc func onStartPointlabel(_ sender:UISlider!)
    {
        print(sender.value)
        
    }
}
```
# ViewController.swift

```ViewController.swift

//クラスをインスタンス化
var UISliderStartEndInstance = UISliderStartEnd()

override func viewDidLoad() {
    super.viewDidLoad()
    
self.view.addSubview(UISliderStartEndInstance.makeSliderStartEnd())
}
```


# 注意点

下記のように、インスタンス変数を作る手間を端折って下記のように直接アクセスすると、Actionメソッドが動かないので、しっかりインスタンス変数は作りましょう。

```swift
self.view.addSubview(UISliderStartEnd().makeSliderStartEnd())
```
jsdoでcytoscape.js その2

#概要
jsdoでcytoscape.jsをやってみた。

#成果物
http://jsdo.it/ohisama1/4QK5

![](http://jsdo-static-contents.s3.amazonaws.com/images/capture/4/Q/K/4QK5.jpg?t=1510704232)
#成果物
http://jsdo.it/ohisama1/uwvm

![](http://jsdo-static-contents.s3.amazonaws.com/images/capture/u/w/v/uwvm.jpg?t=1510707210)

#成果物

http://jsdo.it/ohisama1/OXgZ

![](http://jsdo-static-contents.s3.amazonaws.com/images/capture/O/X/g/OXgZ.jpg?t=1510709242)

以上。
Socket emit inside functions

````
// config/lib/socket.io.js
{
...
  // Add an event listener to the 'connection' event
  io.on('connection', function (socket) {
    config.files.server.sockets.forEach(function (socketConfiguration) {
      require(path.resolve(socketConfiguration))(io, socket);
    });
  });

// added this line below
app.set('socketio', io);

return server;
}
````

Second, I load this variable as 'app.get' which is like snipplet below:

````
// any server controller file, I want to emit, 
// in my case, user.profile.server.controller.js
{
var io = req.app.get('socketio');

...
io.emit('rom1', msg);

````
【PHP】連想配列の特定のキーの値の合計をいろんな方法で取得してみる

タイトルの通りですが、DBからデータを取得したり、CSVファイルを読み込んだときにできる下のような連想配列の特定のキーの合計を求めたいってときにいつも同じやり方でやっていたので、違う方法がないか調べてみました。

```php
// quantityの合計を求めたい。。。
$arrData = array(
                array('name' => 'A', 'quantity' => 0),
                array('name' => 'B', 'quantity' => 2),
                array('name' => 'C', 'quantity' => 1),
                array('name' => 'D', 'quantity' => 4),
                array('name' => 'E', 'quantity' => 10),
            );
```

# foreachでループする
まず合計値を初期化(0を代入)し、foreachでループさせ特定のキーの値を加算させる方法です。最初に思いつくやり方かと思います。（今までずっとこれでやってました）

```php
$f_total = 0;
foreach ($arrData as $data) {
    $f_total += $data['quantity'];
}
echo "foreach：total = ".$f_total.PHP_EOL; // foreach：total = 17
```

# array_reduceとクロージャを組み合わせる
array_reduceの第1引数にループさせる配列、第2引数に処理する関数をしてします。処理する関数は関数化するまでもないので、ちょっとカッコよくクロージャで実装します。
[array_reduce](http://php.net/manual/ja/function.array-reduce.php)
[クロージャ(無名関数)](http://php.net/manual/ja/functions.anonymous.php)

```php
$ar_total = array_reduce($arrData, function($carry, $item){
            return $carry += $item['quantity'];
        });
echo "array_reduce：total = ".$ar_total.PHP_EOL; // array_reduce：total = 17
```
foreachの処理と比べるとあまり直感的ではないような気がします。


# array_sumとarray_columnを組み合わせる
array_columnで特定のキーのみを抽出した配列を取得します。その配列の合計値をarray_sumで求めます。
[array_sum](http://php.net/manual/ja/function.array-sum.php)
[array_column](http://php.net/manual/ja/function.array-column.php)

```php
$as_total = array_sum(array_column($arrData, 'quantity'));
echo "array_sum：total = ".$as_total.PHP_EOL; // array_sum：total = 17
```

# 結局どれがいいの？
結果はどれも一緒なので好きなの使ってもいいんですが、順位付けのためそれぞれの処理時間を計測してみます。

```php
// 100万個のデータを作成
$arrData = array();
for ($i = 0; $i < 1000000; $i++) {
    array_push($arrData, array('name' => 'hoge', 'quantity' => rand(0, 10)));
}

$start = microtime(true);
foreach ($arrData as $data) {
    $f_total += $data['quantity'];
}
$end = microtime(true);
$elapsed = $end - $start;
echo "foreach：time = ". $elapsed ."[sec]".PHP_EOL; // foreach：time = 0.14497804641724[sec]

$start = microtime(true);
$ar_total = array_reduce($arrData, function($carry, $item){
            return $carry += $item['quantity'];
        });
$end = microtime(true);
$elapsed = $end - $start;
echo "array_reduce：time = ". $elapsed ."[sec]".PHP_EOL; // array_reduce：time = 0.16593194007874[sec]

$start = microtime(true);
$as_total = array_sum(array_column($arrData, 'quantity'));
$end = microtime(true);
$elapsed = $end - $start;
echo "array_sum：time = ". $elapsed ."[sec]".PHP_EOL; // array_sum：time = 0.076914072036743[sec]
```

|方法|処理速度[sec]|
|:--|:--|
|foreachでループする|0.14497804641724|
|array_reduceとクロージャを組み合わせる|0.16593194007874|
|array_sumとarray_columnを組み合わせる|0.076914072036743|

処理速度を比べてみるとarray_sumとarray_columnを組み合わせた方法が明らかにベストですね。
Visual Studio | WPF > fileIO > link: FileクラスとFileInfoクラス

```txt:動作環境
Windows 8.1 Pro (64bit)
Microsoft Visual Studio 2017 Community
Sublime Text 2
```

### 関連

[Visual Studio | WPF > fileIO > ファイルのコピー (上書きあり|上書きなし) > System.IO.Fileクラス使用](https://qiita.com/7of9/items/506575341ccd52b37e65)

### FileクラスとFileInfoクラス

[ファイルをコピー、移動（名前の変更）、削除する](https://dobon.net/vb/dotnet/file/filecopy.html#filevsfileinfo) @ DOBON.NET

情報感謝です。

上記において「FileクラスとFileInfoクラスのメソッドの違い」について詳しい。

一部引用すると

> 以上の理由により、1度だけファイルをコピー、移動、削除するのであれば、Fileクラスの方が効率的ですが、1つのファイルに対して何度もコピー、移動、削除等を行うのであれば、FileInfoクラスの方が効率的になる可能性があります。

１つのファイルを何度も処理する場合にはFileInfoを使うことになるだろう。
複数選択できるUITableViewを実装する（Swift）

# 概要

UITableViewはCellの複数選択をサポートしています。
ここではその簡単な実装例を紹介します。

### スクリーンショット

 <img src="https://qiita-image-store.s3.amazonaws.com/0/10057/aa6b8f8e-419f-b1ce-49dc-4018fc8d8380.png" width="320">

### ソースコード

UITableViewはStoryboard側で追加されていて、dataSourceとdelegateは`ViewController`に接続されているとします。

```swift
import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
        navigationItem.rightBarButtonItem = editButtonItem

        // 複数選択を有効にする
        tableView.allowsMultipleSelectionDuringEditing = true
    }

    override func setEditing(_ editing: Bool, animated: Bool) {
        super.setEditing(editing, animated: animated)
        tableView.isEditing = editing
    }
}

extension ViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 10
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell()
        cell.textLabel?.text = "Item \(indexPath.row)"
        return cell
    }
}

extension ViewController: UITableViewDelegate {
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("select - \(indexPath)")
    }

    func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
        print("deselect - \(indexPath)")
    }
}
```

### ポイント

* `tableView.allowsMultipleSelectionDuringEditing = true`で複数選択を有効
* 選択時に`didSelectRowAt`、選択解除時に`didDeselectRowAt`が呼ばれる
  * 選択中のindexPathのリストを保持したい場合は、ここで配列に追加/削除を行います

### 環境

* Xcode 9.1
* Swift 4.0

以上、Cellの複数選択ができるUITableViewの実装メモでした。
今回試したコードは[こちらに置いておきます](https://github.com/himaratsu/MultipleSelectionTableView)。
Visual Studio | WPF > fileIO > ファイルのコピー (上書きあり|上書きなし) > System.IO.Fileクラス使用

```txt:動作環境
Windows 8.1 Pro (64bit)
Microsoft Visual Studio 2017 Community
Sublime Text 2
```

ファイルのコピー方法に関して。

### 参考

- [Fileクラス @ MSDN](https://msdn.microsoft.com/ja-jp/library/system.io.file(v=vs.110).aspx)
- [File.Copy(String, String)](https://msdn.microsoft.com/ja-jp/library/c6cfw35a(v=vs.110).aspx)
- [File.Copy(String, String, Boolean)](https://msdn.microsoft.com/ja-jp/library/9706cfs5(v=vs.110).aspx)

二つ目のFile.Copy()はoverwriteを指定できる。

### code

```MainWindow.xaml
<Window x:Class="_171115_t0940_filecopy.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:_171115_t0940_filecopy"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Button Name="B_filecopy" Height="30" Content="file copy" Click="B_filecopy_Click"/>
    </Grid>
</Window>
```

```MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
// 以下を追加
using System.IO;

namespace _171115_t0940_filecopy
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        private readonly string kFromFile = "D:\\FileProcess_171115\\171010.csv";
        private readonly string kToFile = "D:\\FileProcess_171115\\171015.csv";

        public MainWindow()
        {
            InitializeComponent();
        }

        private void copyFile_noOverwrite()
        {
            try
            {
                File.Copy(kFromFile, kToFile);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString()); // (1)
            }
        }

        private void copyFile_overwrite()
        {
            try
            {
                File.Copy(kFromFile, kToFile, overwrite: true);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString()); // (2)
            }
        }

        private void B_filecopy_Click(object sender, RoutedEventArgs e)
        {
            copyFile_overwrite();
            copyFile_noOverwrite();
        }
    }
}
```

File.Copy(String, String)実行時にファイルが既存するためにエラーが出る。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/019c8e24-9953-d583-015d-cc92d5b8754c.png)
vagrant の時間変更

# 概要
vagrantで時間による制約などの検証を行う場合にvagrantの時間を変更するコマンドを調べたのでメモしておく。

基本的には**管理者権限を持っている**ものとする。

## ホストOSとゲストOSの時刻同期を切る

```shell-session
$ service vboxadd-service stop 
```

## 時刻変更

```shell-session
$ date -s "2017/08/23 00:00:00"
```


## ホストOSとゲストOSの時刻同期を接続

```shell-session
$ service vboxadd-service start
```
WebSocketCat(wscat) の代替としての StreamRelay.NET.exe

「-RemoteProxy」オプションにある「WebSocket」スキームを指定する事で、「Remote」と呼称する側の相手をWebSocket-APIとする事ができる

---
### 相手

[WebSocketでリモートシェルを作った](http://rocketeer.dip.jp/sanaki/free/free148.htm)ので、それを相手とする

ws://192.0.2.1:9999/shellでWebSocket-APIが待機しているものとする

---
### WebSocket へのアップグレード

「-RemoteProxy」オプションの「WebSocket」スキームを使う事で、「Remote」と呼称する相手に対して、WebSocketへのアップグレードを依頼するHTTPリクエスト・メッセージを送ることができる

`StreamRelay.NET.exe -LocalPort 0 -RemotePort 9999 -RemoteHost 192.0.2.1 -RemoteProxy WebSocket://192.0.2.1:9999/shell?Origin=http://192.0.2.1:9999/^&Sec-WebSocket-Key=AAAAAAAAAAA%3d`

こんな感じで、「Local」と呼称する側(コンソール)と、「Remote」と呼称する側(ws://192.0.2.1:9999/shell)とWebSocketプロトコルで会話する事ができる。
ただし、これでは、WebSocketへのアップグレードだけで、WebSocketプロトコル内部で用いるWebSocketデータグラム(リクエストはマスクする等)は、自分で作る必要がある。

---
### WebSocketデータグラムも符号化

次は、

`StreamRelay.NET.exe -LocalPort 0 -RemotePort 9999 -RemoteHost 192.0.2.1 -RemoteProxy WebSocket://192.0.2.1:9999/shell?Origin=http://192.0.2.1:9999/^&Sec-WebSocket-Key=AAAAAAAAAAAA -RemoteProxy netstream:///?WebSocketEncode=text%26mask%3d00000000 -RemoteProxy netstream:///?WebSocketDecode`

とすると、WebSocketプロトコルへアップグレード後、WebSocketデータグラムの符号化(送信時は、テキストモード、マスクを実施)と、符号化解除(受信時はテキストモード)を実施する。

maskは「00 00 00 00」だけど、ここで、
`mask%26"乱数アルゴリズム名"` とか(例:`mask%26random`)乱数プラグインの指定をする事で、任意の乱数アルゴリズムを指定できる

下記の文字コードの話を考えると、textモードより、binモードの方が適切かもしれない

この符号化は、Plugin.BaseFilterStream.dllに実装しているので、これをプラグインとして読み込む必要がある

---
### WebSocketの文字コード

WebSocket-APIが、特に何もしていなければ、シェル側とコンソール側で同じ文字コードを使っていれば、上記で問題はない。

しかし、WebSocketは文字コードが UTF-8なので、WebSocket-APIが文字コードをUTF-8に変換しているなどの場合、そして、コンソールの文字コードがUTF-8でない場合、文字コード変換が必要になってくる。

`StreamRelay.NET.exe -LocalPort 0 -RemotePort 9999 -RemoteHost 192.0.2.1 -RemoteProxy WebSocket://192.0.2.1:9999/shell?Origin=http://192.0.2.1:9999/^&Sec-WebSocket-Key=AAAAAAAAAAAA -RemoteProxy netstream:///?WebSocketEncode=text%26mask=00000000 -RemoteProxy netstream:///?WebSocketDecode -LocalCharset Shift_JIS -RemoteCharset UTF-8`

とすると、「Local」と呼称する側の文字コードは「Shift-JIS」で、「Remote」と呼称する側のWebSocket-APIに対しては文字コードUTF-8に変換する。という事ができる。

---
### Sec-WebSocket-Key

「Sec-WebSocket-Key=AAAAAAAAAAAA」を「Sec-WebSocket-Key-Auto="乱数オプション"」にする事で、Sec-WebSocket-Keyを適当な乱数にする事ができる

例えば、
「Sec-WebSocket-Key-Auto=6-7%2cCryptoRandom」とすると、アルゴリズムCryptoRandomで、バイト数=6～7の範囲の乱数となる

---
### 乱数の指定方法

[乱数アルゴリズムの試用ツールとしてのStreamRelay.NET.exe](https://qiita.com/tomoki0sanaki/items/36df6463cafec0f93313)

---
### 目次へ戻る

[目次というか最初の一歩](http://qiita.com/tomoki0sanaki/items/85f20cbe18378e33cd6f)
bash-it導入後に自分のaliaseを設定しておく


公式のヘルプを読めばよいだけなんだけど、毎日は使わないレベルだとその度に忘れるし、どこに設定したのかも忘れるし。ということでメモ。

GitHub - Bash-it/bash-it: A community Bash framework.
https://github.com/Bash-it/bash-it#your-custom-scripts-aliases-themes-and-functions

>For custom scripts, and aliases, just create the following files (they'll be ignored by the git repo):
>
>aliases/custom.aliases.bash


```
$ cd ~/.bash_it/aliases
$ touch custom.aliases.bash
```


として、作成したファイルにaliaseを記述

```
$ source custom.aliases.bash
```

以上
WebSocketCat(wscat) の代替としての StreamRelay.jar

`java.exe -Djava.security.policy=StreamRelay.policy -jar StreamRelay.jar`
⇔
`StreamRelay.bat`

「-Proxy」オプションにある「WebSocket」スキームを指定する事で、「Remote」と呼称する側の相手をWebSocket-APIとする事ができる

---
### 相手

[WebSocketでリモートシェルを作った](http://rocketeer.dip.jp/sanaki/free/free148.htm)ので、それを相手とする

ws://192.0.2.1:9999/shellでWebSocket-APIが待機しているものとする

---
### WebSocket へのアップグレード

「-Proxy」オプションの「WebSocket」スキームを使う事で、「Remote」と呼称する相手に対して、WebSocketへのアップグレードを依頼するHTTPリクエスト・メッセージを送ることができる

`java.exe -Djava.security.policy=StreamRelay.policy -jar StreamRelay.jar -LocalPort 0 -RemotePort 9999 -RemoteHost 192.0.2.1 -Proxy WebSocket://192.0.2.1:9999/shell?Origin=http://192.0.2.1:9999/,Sec-WebSocket-Key=AAAAAAAAAAAA`

こんな感じで、「Local」と呼称する側(コンソール)と、「Remote」と呼称する側(ws://192.0.2.1:9999/shell)とWebSocketプロトコルで会話する事ができる。
ただし、これでは、WebSocketへのアップグレードだけで、WebSocketプロトコル内部で用いるWebSocketデータグラム(リクエストはマスクする等)は、自分で作る必要がある。

---
### WebSocketデータグラムも符号化

次は、

`java.exe -Djava.security.policy=StreamRelay.policy -jar StreamRelay.jar -LocalPort 0 -RemotePort 9999 -RemoteHost 192.0.2.1 -Proxy WebSocket://192.0.2.1:9999/shell?Origin=http://192.0.2.1:9999/,Sec-WebSocket-Key=AAAAAAAAAAAA -RemoteRequestWebSocket=text,mask -RemoteResponseWebSocket`

とすると、WebSocketプロトコルへアップグレード後、WebSocketデータグラムの符号化(送信時は、テキストモード、マスクを実施)と、符号化解除(受信時はテキストモード)を実施する。

下記の文字コードの話を考えると、textモードより、binモードの方が適切かもしれない。

---
### WebSocketの文字コード

WebSocket-APIが、特に何もしていなければ、シェル側とコンソール側で同じ文字コードを使っていれば、上記で問題はない。

しかし、WebSocketは文字コードが UTF-8なので、WebSocket-APIが文字コードをUTF-8に変換しているなどの場合、そして、コンソールの文字コードがUTF-8でない場合、文字コード変換が必要になってくる。

`java.exe -Djava.security.policy=StreamRelay.policy -jar StreamRelay.jar -LocalPort 0 -RemotePort 9999 -RemoteHost 192.0.2.1 -Proxy WebSocket://192.0.2.1:9999/shell?Origin=http://192.0.2.1:9999/,Sec-WebSocket-Key=AAAAAAAAAAAA -RemoteRequestWebSocket=text,mask -RemoteResponseWebSocket -LocalCharset shift_jis -RemoteCharset utf-8`

とすると、「Local」と呼称する側の文字コードは「Shift-JIS」で、「Remote」と呼称する側のWebSocket-APIに対しては文字コードUTF-8に変換する。という事ができる。

---
### Sec-WebSocket-Key

「Sec-WebSocket-Key=AAAAAAAAAAAA」を「Sec-WebSocket-Key-Auto」にする事で、Sec-WebSocket-Keyを適当な乱数にする事ができる

---
### 目次へ戻る

[目次というか最初の一歩](http://qiita.com/tomoki0sanaki/items/85f20cbe18378e33cd6f)
Enterprise Cloud (Cloud Management Portal) を使ってみたの巻

#はじめに
AWS, Azure, GCP, ECL2.0 など、検証向けに複数のクラウドを管理している。

野良サーバが出てきており、取り締まり強化を目標とする。

 

ECL契約時に無料で使える

“Cloud Management Portal ” を使って、まずは、可視化を試みる。

 
#見える化
まずは、指定のサーバ一覧だけ見えるようにする。

 

使い方は、下のサイト参照

https://ecl.ntt.com/documents/tutorials/rsts/Cmp/setting.html

 

まずは、

プロバイダーを追加する。

サイトと実際の操作が違う。。。

プロバイダアカウント一覧画面とはなんぞや？？

 

設定　＞　アカウントの追加　で、行うようだ。

 

Enterprise Cloud の追加

Enterprise Cloud ログイン　＞　ダッシュボード　＞　ユーザ　＞　プロファイル

にある下の項目をコピペ

１．API キー

２．API シークレットキー

３．契約(ポータル上”契約ID” の項目)

※なぜか項目名が違うので、3.の項目は注意。

 

無事にリソース追加できた。

 
#見えない化
念のため、削除もやってみた。

ダッシュボード　＞　設定　＞　アカウント　＞　該当アカウントをクリック　＞　1分ぐらい待つ　＞　ページ左上部の「三」マークをクリック　＞　リソースの削除

※アカウントは、削除しても残ってる。追加で、削除を行うとエラーとなるので、消えた、、、のか？？

 

 

 

#イケてないなと思ったメモ

監視用にWeb ページを放置しておくと、セッション切られて、再度ログインしないといけない。

つまり、例えば1日中監視～っという用途ではなく、朝一や監査の時だけ起動して、チラ見するためのサービスのようだ。

 

更新頻度は低く、リアルタイム性を求めない場合に使うようだ。

※リアルタイム性を高めるとAWS 等のAPI を叩きまくり、コストが高まるので、低いことが悪いことではない。

#備考
下のサイトから
https://wordpress.com/post/ic8ghatake.wordpress.com/840
UITableViewで常にCellの並び替え（ソート）ができるようにする

# 概要

編集モードをユーザーが選ぶことなしに、常に並び替え（ソート）ができるUITableViewを実装したメモです。

### スクリーンショット

<img src="https://qiita-image-store.s3.amazonaws.com/0/10057/633ab8ee-5c3a-e87c-2fed-0d27c40b3794.png" width="320">

### ソースコード

```swift
class ViewController: UIViewController {
    @IBOutlet weak var tableView: UITableView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.isEditing = true
        tableView.allowsSelectionDuringEditing = true
    }
}

extension ViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 10
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell()
        cell.textLabel?.text = "Item \(indexPath.row)"
        return cell
    }

    func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
        return true
    }

    func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
        // TODO: 入れ替え時の処理を実装する（データ制御など）
    }
}

extension ViewController: UITableViewDelegate {
    func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
        return .none
    }

    func tableView(_ tableView: UITableView, shouldIndentWhileEditingRowAt indexPath: IndexPath) -> Bool {
        return false
    }
}
```

#### ポイント

* viewDidLoadで`tableView.isEditing = true`を呼ぶ
* `canMoveRowAt`や`moveRowAt`を実装すると、並び替えができるようになる
* `editingStyleForRowAt`や`shouldIndentWhileEditingRowAt`で見た目を制御
* Cellをタップ選択できるようにするには、`tableView.allowsSelectionDuringEditing = true`をviewDidLoadで読んでおく

以上で編集モードをユーザーが選ぶことなしに、Cellの並び替えがいつでもできるTableViewができました。
com.google.testing.compile を使ったテスト


アノテーションプロセッサーを使用したクラスのテストをjunitを利用して行いたいと思い最初はAptina Unitを使っていましたが、大人の事情により、compile-testingを使用しないといけなくなりましたので、使い方を忘れないようにここに書いております。

compile-testingのgithub
https://github.com/google/compile-testing

(´-`）.｡oO（英語を見てひるむ。）


他に参考にしたページはこちら
http://blog.64p.org/entry/2015/03/26/055347  
http://hisaichi5518.hatenablog.jp/entry/2017/09/21/213423  
http://blog.duck8823.com/entry/2016/05/07/095947  

(´-`）.｡oO（安心の日本語）


# 使い方
pom.xmlには、こう書きます。

```
<dependency>
  <groupId>com.google.testing.compile</groupId>
  <artifactId>compile-testing</artifactId>
  <version>0.12</version>
  <scope>test</scope>
</dependency>
```

(´-`）.｡oO（ここでやめたくなる。）


# テストコード
プロセッサーが出力したソースを確認するために書いたテストコードのサンプルです。  

```


import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.*;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import javax.tools.JavaFileObject;

import org.junit.Test;

import com.google.common.io.Resources;
import com.google.testing.compile.Compilation;
import com.google.testing.compile.JavaFileObjects;

import static com.google.testing.compile.Compiler.javac;
import static com.google.common.truth.Truth.assert_;
import static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;

public class MyProcessorTest {
	@Test
	public void test_プロセッサーの出力確認(){
		MyProcessor processor = new MyProcessor();
		
		// assert
		assert_().about(javaSource())
			.that(JavaFileObjects.forResource(Resources.getResource("HelloWorld.java")))
			.processedWith(processor)
			.compilesWithoutError()
			.and()
			.generatesSources(JavaFileObjects.forSourceString("foo.bar.baz.Blah", "package foo.bar.baz;\n"
					+ "\n"
					+ "import java.lang.String;\n"
					+ "import javax.annotation.Generated;\n"
					+ "\n"
					+ "@Generated({\"me.geso.sample.hello.MyProcessor\"})\n"
					+ "public class Blah {\n"
					+ "  public String hello() {\n"
					+ "    return \"hello\";\n"
					+ "  }\n"
					+ "}"));


	}
}
```

`generatesSources()`でfoo.bar.baz.Blahが次のパラーメーターと一致していることを確認できる。


エラーを確認したい時のテスト 
 
```
	@Test
	public void test_process_エラー() throws Exception {
		File stub = new File(System.getProperty("user.dir") + "/src/test/java/jp/co/processor/MyProErrStub.java");
		
        assert_().about(JavaSourceSubjectFactory.javaSource())
        	.that(JavaFileObjects.forResource(stub.toURI().toURL()))
        	.processedWith(new MyProcessor())
        	.failsToCompile();
	}
```  

* `failsToCompile()`で、エラーとなることの確認ができる。
電子書籍で技術書を読む生活～電書ノススメ

# はじめに
10年以上もこの業界に居ると、あ、この本面白そうだなとか、仕事で使うなとか、と色々購入していた技術書がいつの間にか段ボール3箱分になり、色々シャレにならなくなってきたので、思い切って電子書籍メインに変えてみました。
今回は皆さんの参考になればと思い、いつもと毛色を変えて、この辺の話をしてみようと思います。

# 読書用端末
とりあえず電子書籍を読むにあたり、PC・スマホ・タブレット、或いはKoboやKindleなどの専用端末が必要になります。
私の場合、スマホをiPhone6S plusに機種変更した後、あまり使わなくなって回線だけ解約したiPad mini 3があったので、それを再利用して電子書籍用の端末にすることにしました。

勿論普段使いのスマホにアプリケーションを入れて読む形でも全然問題はありませんが、端末サイズによってレイアウトを調整してくれる書籍と固定レイアウトの書籍がありますので、出来れば大きいサイズの端末を用意した方がいいかと思います。

Amazonプライム会員だとタイミングによっては数千円でそれなりの端末が手に入るので、金銭的に余裕があれば読書専用の用途として端末を買うのもありかもしれません。

自宅だけで読む場合は特にケースを気にする必要はありませんが、持ち運ぶ場合は落としても平気なケースを用意すると破損の心配が減ります。
勿論、その分端末が一回り大きくなって重くなりますが、端末が傷つくリスクを考えると・・・・・・
私の場合、移動中に読むことは殆どないのですが、意図せずとも鞄ごと落としたり強い衝撃を受けたりする場合があるので、耐衝撃ケースを付けています。

タブレットの場合、1世代以上古い端末だとケースなどを含めた周辺機器がAmazonや家電量販店の実店舗にて在庫処分のために投げ売りされていることもよくあります。読書用であればそこまで高いスペックは要求されませんので、拘りがなければ古い端末を購入することも検討してもいいかもしれません。

# 電子書籍を自炊する
まずはScanSnapと裁断機を用意して手持ちの技術書を何冊か自炊してみました。
多少斜めになったりとか点や皺が入ったりとかはありましたが、とりあえず読む分には問題ないクオリティのものが出来ました。

一番苦労した点としてはスキャンした後の紙の処分、或いはスキャン途中の紙の置場の確保などでしょうか。
一気に裁断して一気にスキャンしたので、床がバラバラにした書籍だらけで足の踏み場もないほどでした・・・・・・
最近はBOOKSCANなど安価で書籍を電子化してくれるサービスがあるので、そちらを利用するのがいいかもしれません。

# 電子書籍を購入する
Kindle始め、どこの電子書籍サービスも月1～隔月くらいで技術書のセールをやっています。
モノによっては半額で入手できることもあるのでありがたいですね。

どこの電子書籍サービスもラインナップは大体同じですが、
例えばオライリー・ジャパンなんかは、自社サイト内でDRMフリー形式のPDFとかepub形式で販売しています。（大体紙書籍の2割引）

ただし、海の向こうの本家オライリーは自社サイトでの電子書籍の販売をやめ、Amazonなどの外部サイト、或いは子会社の提供する定額制サイト（読み放題とは言え月39ドルはちょっと高い気が・・・・・・）での提供という形に変えたので、いずれオライリー・ジャパンも追随する可能性はあります。
DRMフリーのデータが欲しい場合は今のうちに購入しておいた方がいいかもしれませんね。

# おわりに
気付けば段ボール3箱分くらいあった技術書も1箱ちょっとくらいに収めることが出来ました。
ゆくゆくは完全にペーパーレスにするのもいいかもしれませんが、他人にも是非薦めたいような本だけはいつでも貸せるように紙媒体で持っておくというのもアリなような気がします。
メルカリのデータをマイニングして、適正価格を算出してみた

# やったこと

* メルカリで売られているルンバの価格データをマイニングした
* どのくらいの値段なら、何割で売れるか算出してみた

![ルンバ.jpg](https://qiita-image-store.s3.amazonaws.com/0/134704/308770ad-6a2a-cd2b-1ac8-81bbae3acbeb.jpeg)


# 手法

* Python
* Jupyter Notebook
* Tableau

# 結果

* 購入金額別にヒストグラムを作成してみた
* 値段が安いほど、購入割合が高いことが分かった（当たり前だけど
* この値段で売ると、何割で売れるかも出た（かなりだいたいの値だけど）
* 適正価格のサジェストとかできそう

![ルンバの相場.PNG](https://qiita-image-store.s3.amazonaws.com/0/134704/715726ec-d6fa-a84d-92b7-8400636df1a3.png)

![価格と購入率.PNG](https://qiita-image-store.s3.amazonaws.com/0/134704/d9001223-01d9-8ccb-cfb2-4b69fe0e8b45.png)

# 参考

具体的な手法は、こちらを確認してください。

メルカリの出品データをマイニングして、適正価格を分析してみた

https://review-of-my-life.blogspot.jp/2017/11/mercari.html