OmniAICreator/Qiita-1.07M huggingface dataset:
Rails console で url helper のデバッグ方法メモ

結論から言うと app をレシーバにすると helper や view で使えるメソッドが呼び出せます

# controller / action 名から URL を出す
```ruby
pry(main)> app.url_for(action: :show, controller: 'users', id: 1)
=> "http://www.example.com/users/1"
```

# path helper メソッドから path を出す
```ruby
pry(main)> app.users_path(id: 1)
=> "/users/1"
```
ColaboratoryでKerasからTensorboard出力をする

# 無料でGPUが使える！
素晴らしい。詳しい事はこの記事見ればOK。マジで3分でGPUがバリバリ使える環境が手に入る。

https://qiita.com/tomo_makes/items/f70fe48c428d3a61e131

※ 上記記事の通り部分的に制限はあるものの、現実的に個人利用ならほぼ問題ないし、プロダクトレベルでも上手く途中経過を保存するなりして永続化すれば割と使える。

# GoogleDriveをファイルシステムとして使う
インスタンスは落としてしまうとローカルのファイルや何やらは維持されません。そのため下記記事を参考にGoogleDriveからファイルを読み込んだり保存したりしましょう。

https://qiita.com/tomo_makes/items/b3c60b10f7b25a0a5935

[2019.06.03 追記]
→ マウントもめっちゃ簡単になってた https://qiita.com/k_uekado/items/45b76f9a6f920bf0f786

普通にpythonファイル読み込めて驚いた。

```
import sys
sys.path.append('drive/path/to/libs')

from example import example_func
```

これでGoogleDriveの `/path/to/libs/example.py` みたいにファイルを置いておくとちゃんと読み込む。（たまに読み込まない時があったのでそういう時はランタイムの再起動すると直る。多分前にパスを読み込んだ時の状態が残ってたりするんだと思う。）

# Tensorboardのファイルが0bytes?

意気揚々とこんな感じでKerasで書いたモデルの学習を走らせた。

```
model = Model(inputs, outputs)
model.compile(適当)
callback = Tensorboard(log_dir='drive/path/to/log')
try:
  model.fit(X, y, epochs=99999, callbacks=[callback])
except KeyboardInterrupt:
  model.save('drive/path/to/log/model.h5')
```

個人的によくやる、とりあえず大量のepoch走らせておいて、暇な時間が出来たら一旦止めて（止めなくてもいいけど）色々検証して再度保存した所から走らせたり、部分的に書き直して走らせたり。

ローカルでやった時はこれでちゃんとTensorboardの出力も見れてたのですが、GoogleDriveには0bytesのファイルが吐き出されるだけで処理を止めた後にDLしてローカルで見ようとしてもグラフが見れませんでした。

そこで

```
model.fit(X, y, epochs=10, callbacks=[callback])
```

として途中で止めずに最後まで走らせてみると、ちゃんとした出力ファイルが得られグラフも正しく見れました。おそらくですが、GoogleDriveのせいなのかColaboratoryのせいなのかは分からないですがファイルの書き込みがバッファにある状態で、書き込みが終わる前に終了しちゃってるのかと予想しました。

なので上のコードを下記のように書き換えると、途中で□で止めてもちゃんとTensorboardの出力が得られました。（12時間経過後の自動ランタイム再起動でも同じ挙動になるのかは未検証…）

```
model = Model(inputs, outputs)
model.compile(適当)
callback = Tensorboard(log_dir='drive/path/to/log')
try:
    model.fit(X, y, epochs=99999, callbacks=[callback])
except KeyboardInterrupt:
    model.save('drive/path/to/log/model.h5')
    callback.writer.close()
```

途中で停止した時はKeyboardInterruptの例外が投げられるようなのでそこでcallbackのファイル操作を適切に閉じてあげる感じですね。


# Googleすごい
のに、何故かそこまでバズってない気がする。
apache pdfboxでPDFの中身のテキストを抜き出す話

細かい経緯はこちらを参照。
https://qiita.com/arc279/items/95fbb15016a3ce34ec92

どうも手元のmacのインストール済みフォントと、pdf内で使われてるフォントの問題っぽかったので、
全部dockerにしたらあっさり解決した。

## こんな感じで配置して

```sh
$ tree
.
├── docker-compose.yml
├── mnt
│   └── all.pdf
└── pdfbox-app-2.0.8.jar
```

```yaml:docker-compose.yml
version: '2.2'
services:
  pdfbox:
    image: java:8u91
    volumes:
      - ./pdfbox-app-2.0.8.jar:/opts/pdfbox-app-2.0.8.jar
      - ./mnt:/mnt
```

## こうすれば

```sh
docker-compose run --rm pdfbox java -jar /opts/pdfbox-app-2.0.8.jar ExtractText /mnt/all.pdf
```

## 抜き出せる

```sh
$ head mnt/all.txt
平成29年版
厚生労働白書
（平成28年度厚生労働行政年次報告）
厚 生 労 働 省
―社会保障と経済成長―
本白書は再生紙を使用しております。
第1部　社会保障と経済成長
はじめに………………………………………………………………………… 3
第1章　我が国経済社会の中の社会保障… ………………………………… 4
第1節　社会保障の役割と機能… …………………………………………………………………… 4
```
社内勉強会継続について

社内勉強会継続について

弊社では毎月社内勉強会を開催しています。
始まりは2014年から始まり今現在では社外に公開できるレベルにまでなりました。

| 項目 | 当時（2014） | 今（2018） |
|:-:|:-:|:-:|
|実施タイミング|不定期開催|毎月開催|
|人数|約5人|10人以上|
|形式|プレゼンテーション|プレゼンテーション|
|その他| -  |外部公開(connpass)|

ここではそこに至るまでにとりまとめとして何をやったかを記載しておこうと思います。

---

###■きっかけ###
　私が勉強会のとりまとめをやるようになったきっかけは形的に言えば先輩上司から言われたからです。ただやるからにはしっかりやろうという思いはありました。そのためにはまずは目標を持つことかなと思い、以下の目標を立てました。

　・勉強会の環境作り
　　⇒存在を認識してもらうこととルール作り
　・勉強会の継続
　　⇒今まで不定期開催だった勉強会を定期的に行えるようにすること
　・勉強会の活性化
　　⇒当初は4,5人が集まる程度でしたがこれを10人以上集められるようにすること

###■目標達成に向けての行動###

##１．勉強会の認識とスケジュール化##

　「そもそも勉強会ってなに？」って人たちをとりあえずゼロにすることが最優先でした。これはそんなに難しくなく社内SNSを使って告知を流すってだけで伝えることが出来ました。
　　スケジュール化は毎月の「この日のこの時間帯に行う」というのを続けました。その結果社員の認識が「告知されないといつやるかわからない」から「告知しなくても毎月この日に勉強会がある」という形に変えることが出来ました。
　
　【やったこと】
　　⇒社内SNSを使用し告知の頻度を上げる
　　⇒毎月決まった時間に行うことで参加者にスケジュールを認識してもらう
　
　【大変だった】
　・これは毎月決まった時間に行う事でした。弊社の勉強会のスタンスでは登壇者とリスナーの形式をとっていまして話す内容も登壇者が決めるという事でした。
このスタンスは今現在も変わっていませんがとなると、一つ決定的な問題が発生します。
　
　<font color="Red">**毎月行うだけのネタと人がいない！**</font>
　
　ここで次に話すやり方です

##２.人を集めるときに考えたこと##

　上記のように「毎月開催」を考えると｢ネタ｣、｢人｣がなくなります。それに毎月開催だとやっぱり飽きます。それでも継続させるためには｢新しい事への取り組み｣と｢まだ参加した事がない人たちに参加してもらう事｣と最後に「交流を深める事」の3つが必要と感じて行動していました。
　
そもそもなぜ来ないか？
　
　弊社は客先常駐なので登壇者もリスナーも全員業務後にわざわざ堅苦しい勉強会の為に集まらなければならないという状況になります。当然面倒になってこなくなるのは考えられます。何より筆者自身が｢とりまとめ｣をする前に出席した回数は1回だけです！
　
　【やったこと】
　　⇒まだ登壇したことがない人に声をかける
　　⇒新しいこと（Topic)を作ること
　　⇒質疑応答で必ず発言
　　⇒懇親会の積極的な開催

<font color="Red">**まだ登壇したことがない人に声をかける**</font>
　
　勉強会におけるメリットを考えたときに一番スキルアップにつながるのは登壇することでした。勉強会の目的に個人スキルアップを掲げている以上ここは外せないと思い、なるべく多くの人に参加してもらえるように新しく入った社員をターゲットに登壇の声掛けをやっていました。しかしこのタイミングでの「登壇OK」はなかなか貰えません。大体が断ってきます。
ここでの本当の目的は「登壇」ではなく「出席」でした。新しく入ってきた方に「登壇」してもらうのはもっと別のタイミングになります。ではどうやって新しく入ってきた人を「出席」してもらうかってところですが、そのためには「あえて難しいお願いを先にする」・・・でした。

　【やったこと（参加作戦）】
　・新入社員に真っ先に声かけて「登壇」を依頼する
　・｢ドア・イン・ザ・フェイス｣

---

<font color="Red">**※ドア・イン・ザ・フェイスとは**</font>

無理なお願いを断らせておいて次に本題を話す手法です。心理学で｢ドア・イン・ザ・フェイス｣と呼ばれているみたいです。
この手法を用いていたので**先に断れるであろう登壇依頼**を行っていました。当然相手は断ってきますのでそれなら参加するだけ(リスナー)として出席はどうですか？といった具合です。ここでは人を集めることを最優先としていましたので、「登壇者」を確保した段階でこの手法をつかって「リスナー」を集めました。<font color="Red">**またすでに登壇をお願いして断られていることから次にお願いしたときに断られる可能性が少なくなる**</font>のもメリットでした。

　　参照先　：　http://renai-shinri.net/zatugaku/43.html

---

<font color="Red">**新しいこと（Topic)を作ること**</font>
　目的は「勉強会が盛り上がってるのかもな！？」と参加したことがない人にも思ってもらうことです。その盛り上がってるかもなと思わせる題材が「新しい事」って判断でした。要は面白くて珍しければなんでもいいってノリでやってました。実際には告知文章に「今回のTopicは〇〇です」ってのを毎回乗っけてただけです。

<font color="Red">**質疑応答で必ず発言**</font>
　自分が作った資料や展開する技術が誰も興味を示さないとやる気なくなります。そこを改善するには登壇が終わった後の質疑応答で何かしらは質問するという事かなと思い、誰の登壇に対しても必ず質問するというのは意識的にやっていました。

<font color="Red">**懇親会**</font>
　個人的にはこれは重要な事だと思っています。これをやることで社員内で会話が生まれ交流につながります。特に新しく入ってきた人にとっては自分の顔と名前を知ってもらう大チャンスかなと思っています。それに帰社精神が薄い業界だからこそ社員交流の場は定期的にあってもいいのではないかと思い開催していました。その上勉強会が任意である以上その延長線上にある「懇親会」も任意になります。こういう集まりが苦手な人も「断りやすい環境」でもあるのかなと思います。


---

##3.結果と今##

　以上の事を継続的に取り組んできた結果、当初の目的である「勉強会の継続」と｢毎回10人以上の出席｣が達成することが出来ました。今現在は今まで一人だった「とりまとめ役」が「とりまとめチーム」に変わり、より発展した内容になっていってます。

今後どうなるかはわかりませんが、今あるもの以上の事も達成できる環境にしたいですね

---

###■さいごに###

　こういった記事を載せるのは初めての為ちょっと文章的にはまだ精査が必要かなって気もしました。m(TT)m
対人間の話なのでマニュアルなんて存在していないので自分は上記のことを試行錯誤しながらやっていました。ただせっかく目的達成できた行動案があるのに自分だけでとどめているのはどうかなと思い記事にした次第です。
　同じ境遇になった人が迷った時のサンプルにでもなればいいかなっておもいます。
Unityをコードから強制的に終了させる

無性に Unity を強制終了させたくなる時ってありますよね。
以下のようなコードでお手軽に落とせます。

```C#
using UnityEngine;

public class ForceCrasher : MonoBehaviour {

    void Start()
    {
        // どちらかを実行する
        // performStackOverflow();
        // crash();
    }

    void performStackOverflow()
    {
        performStackOverflow();
    }

    void crash()
    {
        Application.ForceCrash(0);
    }
}
```

performStackOverflow() はスタックオーバーフローで落とします。
Application.ForceCrash() はマニュアルには載っていない隠しコマンドで、多分ネイティブ側で何かやばいことをして落としてます。

Unity は大抵のエラーをハンドリングしてくれるので普通の例外を起こすだけでは落ちません。
できるだけシンプルに、エディタだろうと一瞬で落とすことができる2つはこれ、という紹介でした。
Kerasのbackendが、思い通りならない時のメモ

# このページについて
* Anaconda環境でKerasを動かした時に、
    * keras.jsonで、tensorflowバックエンドを設定したはずなのに、、、
    * theanoが起動してしまう時にどうしたか？　のメモです。
* 作業メモレベルですので、粗末な内容です。
* **(追記)** 同じ事象の記事があったので[リンク](https://qiita.com/uminor/items/b2cd07401aa403b7ff82)させて頂きます。重複しスミマセン。

# こんな状況です
* keras.jsonはtensorflowを指定しているのに、、

```shell
(tensorflow_p36)[ec2-user@hostname ~]$ cat .keras/keras.json
{
    "backend": "tensorflow"
}
```
* 起動したバックエンドは、、

![image.png](https://qiita-image-store.s3.amazonaws.com/0/183826/dd2c837a-6669-fb90-8f2f-7736cae0edc5.png)

# 対応方法
* 結論から書くと、anacondaだとkeras.jsonの設定が効いていないので、環境変数にてKERAS_BACKENDを指定するとtensorflowバックエンドが使えます

```shell
export KERAS_BACKEND=tensorflow
```

# 発生原因と特定した過程
* 以下は原因箇所とその特定の過程です。
* 細かい事が知りたい人は読んで頂ければと。。

## まずは、jupyterと子プロセスを確認
* 自分の場合、Anaconda環境のjupyter notebookを使っていたので、まずはjupyterのプロセスを疑いました。
* psしてみるとこんな感じで、★がjupyterから起動したpythonの子プロセス。

```
(tensorflow_p36)[ec2-user@hostname ~]$ ps -ef |grep python
　　ec2-user  5978  5954  2 06:56 pts/0    00:00:01 /home/ec2-user/anaconda3/bin/python /home/ec2-user/anaconda3/bin/jupyter-notebook
★　ec2-user  6000  5978  1 06:56 ?        00:00:00 /home/ec2-user/anaconda3/envs/tensorflow_p36/bin/python -m ipykernel -f /home/ec2-user/.local/share/jupyter/~中略~.json
　　ec2-user  6054  6018  0 06:57 pts/1    00:00:00 grep --color=auto python
[ec2-user@hostname ~]$
```

## それらのプロセスの環境変数を確認（犯人発見）
* この子プロセス★がなぜ、theanoバックエンドを利用してしまうか？
* 環境変数を/proc以下で確認すると、犯人発見！、なぜか **KERAS_BACKEND=theano** が定義されている。。。

```
(tensorflow_p36)[ec2-user@hostname ~]$ vi /proc/6000/environ
～～～（色々な環境変数）～　 KERAS_BACKEND=theano 　　～～～～
```

## どこで、**KERAS_BACKEND** が定義されたか？
* jupyterではなく、生でAnaconda仮想環境を触っても、backendがtheanoになっている。。

```
(tensorflow_p36) [ec2-user@hostname ~]$ python
Python 3.6.3 |Anaconda, Inc.| (default, Nov 20 2017, 20:41:42)
[GCC 7.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import keras
Using Theano backend.　★ここ★
>>>
```

* Anaconda環境が怪しいので、activateコマンドをbash -x でデバッグ
    * なんと、keras_activate.shが環境変数でtheanoをバックエンドで利用するよう指定していた。。
    * なぜだ。。

```
(tensorflow_p36) [ec2-user@hostname ~]$ bash -x activate tensorflow_p36
+ _CONDA_ROOT=/home/ec2-user/anaconda3
+ _conda_script_is_sourced

～～（中略）～～

++ . /home/ec2-user/anaconda3/envs/tensorflow_p36/etc/conda/activate.d/keras_activate.sh　　★犯人★
++++ uname
+++ '[' Linux == Darwin ']'
++++ uname
+++ '[' Linux == Linux ']'
+++ export KERAS_BACKEND=theano　　　★環境変数★
+++ KERAS_BACKEND=theano
+ _conda_hashr
+ case "$_CONDA_SHELL_FLAVOR" in
+ hash -r
```

## では、keras_activate.shの中身は？
* なんだ、この分岐。。。
* Linuxだったら自動的にtheanoだと！！

```bash
#!/bin/bash
if [ "$(uname)" == "Darwin" ]
then
    # for Mac OSX
    export KERAS_BACKEND=tensorflow
elif [ "$(uname)" == "Linux" ]
then
    # for Linux
    export KERAS_BACKEND=theano
fi
```

# 結局、activateコマンドがtheanoを指定していた。。
* 回避するためには、環境変数（.bashrc)あたりに下記を指定しておけばOK。
* activateコマンドを叩くとtheanoで上書きされるので、下記をactivate後に実行。

```shell
export KERAS_BACKEND=tensorflow
```
【Bundler】Commands: Index

# 【Bundler】Commands Index
- [bundle init]
 (https://qiita.com/chiikotsu=draft/items/53fc56a0b0c699a69b91#bundle-init)
- [bundle install](https://qiita.com/chiikotsu--
 draft/items/425903b52342f92bef6c#bundle-install)
- [bundle exec](https://qiita.com/chiikotsu-draft/items/7ccc28d47e80d77eb08e#bundle-exec)
- [bundle update](https://qiita.com/chiikotsu-draft/items/6dc0a6155ca1b047cc73#bundle-update)
関連pivotテーブルを持つダミーデータをFaker使って入れる時のSeederの書き方

# 今日書くこと
タイトルどおり。
Laravel 5.5で実装してみたけど、5系ならどれでも似たり寄ったりだと思う。

# 例
店舗一覧があって、その店舗にユーザが所属するManyToManyな関係。  
ユーザは複数の店舗に所属することが可能。

- ナウい書店本店
  - ユーザ1
  - ユーザ3
- ナウい書店大阪店
  - ユーザ1
  - ユーザ5
  - ユーザ7
- ナウい書店マサチューセッツ店
  - ユーザ5

# テーブル構成
- shops (店舗マスタ)
- users (ユーザマスタ)
- shop_user (店舗×ユーザのpivotテーブル)

# Seeder
おいらのpivotテーブルにはcreated_byとcreated_atが存在していたので
連想配列で値をセットしてやってます。

あとダミーデータには論理削除されたユーザやデータを含めるとデバッグしやすいのでwithTrashedを噛ませてます。

```php
<?php

use Illuminate\Database\Seeder;

use App\Shop;
use App\User;

class ShopSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        Shop::truncate();
        DB::table('shop_user')->truncate();

        $faker = \Faker\Factory::create('ja_JP');

        $users = User::withTrashed()->pluck('id')->toArray();

        factory(Shop::class, 20)->create()->each(function ($shop) use ($faker, $users) {
　　　　　　　　　　　　　　　　　　　　　　　　// ランダムなアイテム数のuserのidの配列を作る。
            $arr = $faker->randomElements($users); 
            $data = [];
　　　　　　　　　　　　　　　　　　　　　　　　// pivotテーブルの更新したいカラムの値をセット
            foreach ($arr as $val) {
                $user_id = $faker->randomElement(\App\User::withTrashed()->pluck('id')->toArray());
                $data[$val] = [
                    'created_by' => $user_id,
                    'created_at' => $faker->dateTimeThisYear(),
                ];
            }
　　　　　　　　　　　　　　　　　　　　　　　　// あとはsyncするだけ！！
            $shop->users()->sync($data);
        });
    }
}

```

# 感想
factoryでダミーデータ作るの楽しい。癒やし。
gcloud ツールで Pub/Sub を行う

GCP の　gcloud ツールで　Pub/Sub を行います。

gcloud init で　configuration の作成が終っているものとします。

```text
$ gcloud init
Welcome! This command will take you through the configuration of gcloud.

Settings from your current configuration [default] are:
core:
  account: abcde@gmail.com
  disable_usage_reporting: 'True'
  project: my-project-sep-10-2017

Pick configuration to use:
 [1] Re-initialize this configuration [default] with new settings 
 [2] Create a new configuration
Please enter your numeric choice:
```

topic_1 というトピックを作成します。

```text
$ gcloud pubsub topics create topic_1
Created topic [projects/my-project-aug-29-2016/topics/topic_1].
```

subscription_1 というサブスクリプションを作成します。

```text
$ gcloud pubsub subscriptions create --topic topic_1 subscription_1
Created subscription [projects/my-project-aug-29-2016/subscriptions/subscription_1].
```

topic_1 に　メッセージを publish します。

```text
$ gcloud pubsub topics publish topic_1  --message "Good Morning"
messageIds:
- '33129870297757'

subscription_1 からメッセージを取ります。

```text
$ gcloud pubsub subscriptions pull --auto-ack subscription_1
┌──────────────┬────────────────┬────────────┐
│     DATA     │   MESSAGE_ID   │ ATTRIBUTES │
├──────────────┼────────────────┼────────────┤
│ Good Morning │ 33129870297757 │            │
└──────────────┴────────────────┴────────────┘
```

別のメッセージを topic_1 に送ります。

```text
$ gcloud pubsub topics publish topic_1  --message "Hello World!"
messageIds:
- '33123573760843'
```

subscription_1 からメッセージを取ります。

```text
$ gcloud pubsub subscriptions pull --auto-ack subscription_1
┌──────────────┬────────────────┬────────────┐
│     DATA     │   MESSAGE_ID   │ ATTRIBUTES │
├──────────────┼────────────────┼────────────┤
│ Hello World! │ 33123573760843 │            │
└──────────────┴────────────────┴────────────┘
```

トピックの一覧

```bash
gcloud pubsub topics list
```

topic_1 のサブスクリプションの表示

```bash
gcloud pubsub topics list-subscriptions topic_1
```

サブスクリプションの一覧

```bash
gcloud pubsub subscriptions list
```

トピック　と　サブスクリプションを GUI で確認することもできます。
![gcloud_pubsub_feb0701.png](https://qiita-image-store.s3.amazonaws.com/0/179446/a7e78961-c52a-dc15-fce2-58b13b4c25fe.png)

トピック　(topic_1) の削除

```bash
gcloud pubsub topics delete topic_1
```

サブスクリプション (subscription_1) の削除

```bash
gcloud pubsub subscriptions delete subscription_1
```
【Bundler】Commands: `bundle init`

# `bundle init`

### Summary
* Gemを初期化する

### Roles
* アプリケーションで使用するGem達を指定する
* アプリケーションで使用するGem達のバージョンを管理する

### How to
* カレントディレクトリに移動してから実行する


### Result
* カレントディレクトリ内にGemfileが作成される

### Examples
1 testディレクトリを作成し、testディレクトリに移動する
 
```
$ mkdir test
$ cd test/
```


2　`bundle init`を実行する

```
$ bundle init
Writing new Gemfile to /Users/macuser/test/Gemfile
```

~Rusult~

```
$ ls
Gemfile # testディレクトリにGemfileが作成された
```
Excel 2016 > 警告:数値が文字列として保存されています > 設定変更後の設定場所の謎

```txt:動作環境
Windows 8.1 Pro (64bit)
Excel 2016
```

## 数値が文字列として保存されています

- セルの書式を「文字列」にする
- `(80)`のような数値を入力する
- >> 警告:数値が文字列として保存されています。(下図) 

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/b14f9b39-7174-c7d1-75e4-bc5919d920ad.png)

## 対処方法

### 設定項目

**「文字列形式の数値、またはアポストロフィで始まる数値(H)」**

### Case A. EXCELの設定変更 (同一人物)

上図の「エラーチェックオプション」を選択し、「文字列形式の数値、またはアポストロフィで始まる数値(H)」の項目の「チェックを外す」。

チェックを外したことで、「ツール > オプション > 数式」にある「エラーチェックツール」の同じ項目は「チェックを外した状態」になる。

設定変更以後、異なるファイルに対しても警告は表示されなくなる。

### Case B. ファイルの設定変更 (異なる人物間)

- Aさんが上記の「EXCELの設定変更」で掲示した操作を行う
    - Aさんの環境では設定の「チェックが外れている」
- そのファイルをBさんに渡す
- Bさんがそのファイルを開くと、警告は表示されない
    - Bさんの環境では設定の「チェックはついている」

Bさんが新たに同じ形式のファイルを作成すると「警告は表示される」。

### 備考

「文字列形式の数値、またはアポストロフィで始まる数値(H)」設定はファイルに付いていくのだろうか?
ファイル付随でなく、環境付随であるのであれば、Case Bの場合はBさんが開いた時に警告が表示されるはず。しかしながら、実際にはそうはなっていない。


## 警告表示させない方法

以下のようにすると、環境によらず警告は表示されなくなる。

- `(80)_`のように後ろに適当な文字を追加する
- その文字を選択し、白色にする
    - 備考: セルの内容を参照したときに"_"の意図が分からなくなる恐れはある
pip listの警告を消す

# 概要
　Python3のpipを``pip 9.0.1``にアップデートしたら``pip list``コマンドを実行する度に以下の警告メッセージが出るようになりました．

>
DEPRECATION: The default format will switch to columns in the future. You can use --format=(legacy|columns) (or define a format=(legacy|columns) in your pip.conf under the [list] section) to disable this warning.
>

　このままでも使えるけど，実行する度に警告が出るのは鬱陶しいのでこれを出ないようにします．ちなみに環境はOSX High Sierra 10.13.2で，Pythonはhomebrewを使って入れてます．

# 解決策
　警告を読むと，どうやらpip 9.0から``pip list``を実行するときは表示形式を指定しないといけなくなったみたいです．
　毎回表示形式を指定するのは面倒なのでpipの設定ファイルに表示形式を記述します．pipの設定ファイルは，

$HOME/Library/Application Support/pip/pip.conf

にあります．存在しない場合は新規作成してください．

```zsh
touch $HOME/Library/"Application Support"/pip pip.conf
```
※ ターミナル上で半角スペースを含むディレクトリやファイルを扱う場合は，上記のコマンドのようにダブルクォーテーション(")で囲む必要があります．

　設定ファイルに以下を追記します．

```pip.conf
[list]
format=legacy
```

　これで警告文は表示されなくなりました．

　ちなみに表示形式には以下のものがあります．

* legacy（従来と同じ表示形式）

```
numpy (1.14.0)
pip (9.0.1)
```

* columns

```
Package         Version
--------------- -------
numpy           1.14.0
pip             9.0.1
```

* freeze

```
numpy==1.14.0
pip==9.0.1
```

# おわりに
　``pip list``を実行した時に表示される警告文を消すことができました．
不均等クラスの学習に関して

参考になりそうな記事を自分用にまとめます。

#[Dealing with Imbalanced Classes in Machine Learning](https://towardsdatascience.com/dealing-with-imbalanced-classes-in-machine-learning-d43d6fa19d2)
### 大事なことはどのような分類を目標とするのか？
* 不均等クラスの学習で問題となるのは数の少ないクラスの予測がうまくいかないこと
 * "the goal is to identify the minority class"
* Accuracy=(TP+TN)/(All)ではかってしまうとTPが少ない場合にも精度が高く見える
* それ以外の指標の最大化を目指すべき
 * "consider using metrics beyond accuracy such as recall, precision, and AUROC"
 * recall=TP/(TP+FP)
 * precision=TP/(TP+FN)
 * [AUC optimization](http://proceedings.mlr.press/v28/gao13.pdf)という学習のやり方もある

###考えられる対策
* 各予測に対する重みを変える
 * TP, FP, TN, FNそれぞれに対するゲイン or ペナルティをcost matrixで表現する * 数が合うようなサンプリングをする
 1. oversampling （問題：過学習）
 2. undersampling　（問題：重要なサンプル（フィーチャー）を取り損ねる可能性、訓練データの減少）
* SMOTE
 * 今論文読んでる
 * k-nearest neighborの値の差を補完する形でoversampling用のデータを生成する手法
 * "creates new instances of minority class  by forming convex combinations of neighboring instances"
 * 0,1 classのサンプルの間の決定領域にあるようなデータを作るのが目標のようだ
 * データをもとに生成を行うのでoversamplingと同様に過学習はさけられない
 * [imblearn](http://contrib.scikit-learn.org/imbalanced-learn/stable/generated/imblearn.over_sampling.SMOTE.html)
* 異常検知の文脈に落とす
 * 大多数の部分に対してモデルをあてはめて、それと異なるサンプルを検出す
 * "Clustering methods, One-class SVMs, and Isolation Forests"
 * [Isolation forest in sklearn](http://scikit-learn.org/stable/modules/generated/sklearn.ensemble.IsolationForest.html)

###蛇足
 * [Positive unlabeled learning](http://www.ms.k.u-tokyo.ac.jp/~gang/paper/niu_ibisml030.pdf)はデータセット自体が違う（正例しかない）が不均等という点では同じかもしれない

#[Class Imbalance, Redux](https://pdfs.semanticscholar.org/a8ef/5a810099178b70d1490a4e6fc4426b642cde.pdf)
* 結局うまくいくことが知られているのはbagging（ブートストラップでアンサンブル学習する）だけ
* それがなぜなのかをsimulation/realデータを併用しながら調べた

という話。英語がどことなくおしゃれで馴染みのない単語が多かった（感想）。
こちらでは既存の手法を

* over/undersampling
* synthetic data (SMOTE)
* cost-sensitive algorithm (weighted SVMなど)

の3つに分類。
多次元のときにはその単純さからundersamplingが選ばれるが、それ以外でもしばしばundersamplingがoutperformする。

* FNに対するFPのコストをかえる作戦はトレーニングデータセットが分類できない（not separable）なときだけうまくいく。（P/Nがということだと思う）
R クラスタ分析

#はじめに
個人の勉強用に制作しました．

#クラスタ分析
p個の変数を持つ，n個の対象(object)を似たものが同じクラスになるように分類するのがクラスタ分析である．

i) 階層的方法
階層的方法は各個体からそれぞれの個体までのすべての距離を計算して，併合または分割によってクラスタを形成していく．併合過程では、1つの個体を1つのクラスターとするところから始まって，最終的にn個の個体全体で1つのクラスターとするところまで階層的に進んでいく．分割過程はこれとはまったく逆の方法でクラスターを分割していく． 

ii) 非階層的方法
最初にクラスタの数を与え，適当なクラスタの中心を与えて
これに個体を入れたり出したりしてクラスタを形成していく方法である．

``` 階層的方法.R

X = c(1,2,3,7,8,9)
Y = c(3,2,4,9,7,9)
m.data = data.frame(x=x, y=y)
m.dist = dist(m.data, method = "euclidean") #距離を計算 #dist関数
m.clust = hclust(m.dist, method = "single") #クラスタの形成　#hclust関数
plot(m.clust)
dend = as.dendrogram(m.clust) #as.dendrogram関数 #具体的な数値を確認したい
str(dend) #str関数
h3 = cutree(m.clust, h=3) #h=3で分割 #cutree関数
h2 = cutree(m.clust, h=2) #h=3で分割
```

```非階層的方法.R

c1 = kmeans(m.data, 2) #k-means関数
plot(m.data, col=c1$cluster) #kmeansの結果を色分けして表示
points(c1$centers, col=1:2, pch=8) #各クラスタの代表点を*で表示
head(cosmetics)

d.cosme = dist(cosmetics, method = "euclidean") #dist関数
c.cosme = hclust(d.cosme, method = "single") #クラスタの形成
plot(c.cosme)

```

# 練習問題

## 大問1

次々と近郊のデータを統合してクラスタが形成される「鎖効果」が発生．
これを回避するにはウォード法を用いると良い.(距離の定義を実用的なウォード法に変える)

```ウォード法.R
d.cosme = dist(cosmetics, method = "euclidean") #dist関数
C.cosme = hclust(d.cosme, method = "ward.D") #ウォード法
plot(C.cosme)

dend = as.dendrogram(c.cosme)
str(dend)


```
○ データを持ちに被験者を2グループに分ける場合，どれぐらいの距離で分けるのが良いか
- ウォード法を用いた樹形図のグラフを確認すると，以下のようになるため，20に近い距離の値で分類するのが良い．
- (3つに分類する場合は約12前後の値)

<img width="511" alt="Screen Shot 2018-02-07 at 18.33.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/190917/a18bb21c-203b-5659-9064-8acbc5c5e248.png">


##大問2

```kmeans法.R
head(iris)　#データをセット #irisはもともとRにあるデータ
my.iris = iris[,2:3]　#必要なデータのみ取り出す
plot(my.iris, col=iris[,5])　#3色に分けて表示
k3 = kmeans(faithful, 3)$cluster #k=3でクラスタリング #kmeans法
plot(faithful,col=k3)#3色に分けて表示

```
1. 今回の分析だと，irisのデータから，クラスタの中心点を３つ打たれる
2. 全てのデータからもっとも近くにある中心点のクラスタが割り当てられる
3. 分類されたクラスタ内のデータの平均値を新たなクラスタの中心点にする
4. 2に戻る

のようにクラスタを割り当てるための中心点が徐々に正しい位置へ収束していく構造になっているため，複数回分析を行う必要がある．


<img width="502" alt="Screen Shot 2018-02-07 at 18.58.01.png" src="https://qiita-image-store.s3.amazonaws.com/0/190917/fc8aa2f6-cba3-ae26-7faa-902ff5399ab7.png">

<img width="507" alt="Screen Shot 2018-02-07 at 18.56.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/190917/42869a37-7063-99f9-d0c2-0cdc4785ee07.png">
iOSドラムロール（スロットマシンピッカー）の実装について

以下、自分用メモです。

##どうやってドラムロールを出すの

最初はセレクトボックスで実装しようと思っていたのですが、
複数列に対応するには、html5で追加された

```hoge.html
<input type="month" />
```

というものが使えるとのこと。
[セレクトボックスを複数列のドラムロール表示にしたい(iOS)](https://teratail.com/questions/111225)
（webエンジニアをしていながら、無知でお恥ずかしい...）

##実機でCSSがあたらない
この方法で実装はできたものの、なかなか希望するデザインにCSSがあたらず試行錯誤。
クロームのインスペクタでは反映されていても、実機では反映されていないこともしばしば。
スマホ独自のCSSを無効化する記述も必要。

```hoge.css
#hoge {
    -webkit-appearance: none;
}
```

##イベント発火のタイミング
ドラムロールの項目を選択
↓
「完了」押下したタイミングでイベントを発火

したい。
[onchange event for input type=“number”](https://stackoverflow.com/questions/9609731/onchange-event-for-input-type-number)

```hoge.js
jQuery(":input[type='month']").bind('change', function () {
    // しょり
});

```

最初、上記のように change で記述したところ、
iOSだと、（どれを選ぼうかな...）とクルクル選んでいる間にも、
つねにイベントが発火されつづけてしまう...！

どうやら、この場合は change ではなく、 **focusout** というイベントが用意されているらしい。
[iPhone で change イベントが発火されすぎる問題](http://www.mnemonic.co.jp/blog/5739407210446848)

```hoge.js
jQuery(":input[type='month']").focusout(function () {
    // しょり
});

```

無事、「完了」押下時のみ、発火できました。

先達はあらまほしきことなり、です。


##追記
**なんと、 android では focusout で発火しない！**
なぜなら android は「設定」を押しても、違う箇所をタップしない限り
フォーカスが外れないため。
結局、UAでの切り分けを追加しました。
[スマートフォン（iPhone/Android）のページ内振り分け|Smart](http://rfs.jp/sb/javascript/js-lab/smartphone_user-agent.html)

```hoge.js
if ( navigator.userAgent.indexOf('iPhone') > 0 || navigator.userAgent.indexOf('iPad') > 0 || navigator.userAgent.indexOf('iPod') > 0 ){
    jQuery(":input[type='month']").focusout(function () {
        // iPhoneのしょり
    });
}else if( navigator.userAgent.indexOf('Android') > 0 ){
    jQuery(":input[type='month']").bind('change', function () {
        // androidのしょり
    });
}

```


##追記2

```hoge.html
<input type="month" max="2018-02" min="1999-01" />
```

と書くと、日付範囲の指定ができます。
ただ、iOSのsafariには対応していない...！
(T.T)
HTML5の書き方_2(リンクの貼り方)


#1.基本の書き方

```html:link.html
<a href="[url]">[リンク名]</a>
```

・hrefはリンクを貼るための属性
・aタグはリンクを貼るために使うタグ

<見本>
<a heaf="https://qiita.com/trend">Qiitaトレンド</a>

###・外部サイトなら

`https://[ドメイン名]/[ファイル名].html`

###・内部サイトかつ表示元と同じフォルダ階層なら

`./[ファイル名].html`

###・内部サイトかつ表示元から一つ階層をあがった場合

`../[ファイル名].html`
※一つ階層を上げるごとに「../」を付ける

#応用編
###・同ページ内で移動するリンクをつくる

```html:Move.html
～～～テキスト～～～
<a name="tako">[リンク先]</a>
～～～テキスト～～～
<a href="#[link]">[Topへ戻る]</a>
～～～テキスト～～～
```

※ポイントはlinkの先頭に「#」を付ける

##感想
リンクを上手く使えばいろいろできそう

ちなみにマークダウンでリンク貼る時は

```
[リンク名](url)
```
ハメられた

[次へ](https://qiita.com/2_MaYu_2/items/1699ad5c367ad36779aa)
VirtualBoxで64bitが選択できない場合の対応方法

## はじめに

元々VirutalBoxで64bitが選択できていたのに、ある日仮想マシンを作成しようとした時に「あれ？32bitしかでないぞ？」という状況になりました。
その時の対応内容を記載しています。
※そもそも「なぜ32bitしか出なくなったか？」が不詳な為、この対応で正しいかも不詳…

事象の発生/解消をした環境は以下の通りです。

* OS：Windows10 Pro
* VirutalBox：5.6


## 32bitしか選択できなくなった時の状況

1. Docker for Windowsを入れていた  
VirtualBoxと競合してしまうとの事で1日程度でアンインストール
1. Docker Toolboxを入れていた  
Kitematic経由でDocker Imageを落とそうとしたが、接続ERRが解消できず。  
それ程緊急性も無かった為、こちらも1日程度でアンインストール。
1. 動作不安定になりDocker for Windowsの入れる直前までシステムの復元を実施

ここまで対応した後、2週間程VirtualBoxには触れず。
新しく仮想サーバを作るか…と起動した時に32bitしか選択できなくなっていた。
(作成済の64bitマシンを起動しようとした際にはブルースクリーンが出たのはビビった)

## 解消の為に実施した事

結果的には以下のいずれでも解消しませんでした。

1. BIOS設定の確認、再設定
``Intel Virtualization Technology``が``Enable``になっている事を確認。  
一旦、``DISABLE``にして再度``ENABLE``にする。
1. VirutalBoxのアンインストール/インストール
1. システムの復元

## 解消した際に実施した事

**「Hyper-V」の再インストール/削除を実施。**
結果的にこれで無事64bitが選択できる様になりました。

Docker for Windowsをインストールする際にHyper-Vの有効化の設定がちょっと残っちゃっていたのかな…
EC2インスタンスに関連付けられたリソースにタグを付けてまわる

## やっていること
- インスタンスのタグをもとにEBSのタグを作る
- インスタンスのタグをもとにENIのタグを作る
- インスタンスに所属するEBSのタグをもとにSnapshotのタグを作る

TagEditorでこつこつやってましたが途中からだるくなったので・・・

## 注意点
- もとのリソースがない場合当然タグはつくられません
 - スナップショットはあるけど関連のEBS volumeが残ってないとか
- Nameタグはコピーしないよ
 - 私の環境で不都合があったので外しました
 - コピーしたい場合改変してください
- 環境のクレデンシャルを使います
 - OSに設定してね

## code
```file:ruby
#!/usr/bin/env ruby
require 'aws-sdk'

region = 'ap-northeast-1'
ec2 = Aws::EC2::Client.new(region: region, credentials: Aws::SharedCredentials.new)

instances = ec2.describe_instances
all = ec2.describe_instances[0].map {|i| i.instances[0] }
snapshots = ec2.describe_snapshots

all.each do |i|
  tags = i.tags.map(&:to_h)
  # Nameタグは作らない
  tags = tags.reject {|k, v| k[:key] == "Name"}
  volumes = i.block_device_mappings.map(&:ebs)
  volumes.each do |volume|
    # インスタンスのタグからEBSのタグを作成
    ec2.create_tags resources: [volume.volume_id], tags: tags
    p volume.volume_id

    # EBSのタグからスナップショットのタグを作成
    target = snapshots[0].map do |snapshot|
      snapshot if snapshot.volume_id == volume.volume_id
    end
    target.delete nil
    target.each do |t|
      ec2.create_tags resources: [t.snapshot_id], tags: tags
      p t.snapshot_id
    end
  end

  i.network_interfaces.map(&:network_interface_id).each do |eni_id|
    # インスタンスのタグからENIのタグを作成
    ec2.create_tags resources: [eni_id], tags: tags
    p eni_id
  end
  p tags
end
```
powershellに関する備忘録


windowsで簡単なプログラム作成する時に、
デフォでインストールされているpowershellを使用するのが便利ですね。


```powershell

# コマンドレットのエラーもtrapでキャッチできるようにする
# デフォルトはcontinue
$ErrorActionPreference = "Stop"

trap{
        ＃＃処理
        
        continue
}      

```

trapでキャッチして、continueすることで無視して続けることができる。


```powershell:文字列のNULLチェック

#NULLでなければ・・・
if(![string]::IsNullOrEmpty($vcn)){

}

```


```powershell:テキスト検索

#　テキスト検索
$result =  Select-String -Path [ファイルパス] -SimpleMatch  [検索ワード] | % { $_.Line } 

```

$resultに検索結果が格納される


```powershell:空ファイルの作成

# 空ファイル作成
Clear-Content  error_word.txt

```

```powershell:CSVファイルの読み込み

Import-Csv [CSVファイルパス] | ForEach-Object{

}

```
俺言語 その２

#概要

俺言語をやってみた。
スタックマシーンでバイトコードインタープリタを書いてみた。
fizzbuzzやってみた。
  

#出力

```
1 2 fizz 4 buzz fizz 7 8 fizz buzz 11 fizz 13 14 fizzbuzz 16 17 fizz 19 buzz fizz 22 23 fizz buzz 26 fizz 28 29 fizzbuzz 31 32 fizz 34 buzz fizz 37 38 fizz buzz 41 fizz 43 44 fizzbuzz 46 47 fizz 49 buzz fizz 52 53 fizz buzz 56 fizz 58 59 fizzbuzz 61 62 fizz 64 buzz fizz 67 68 fizz buzz 71 fizz 73 74 fizzbuzz 76 77 fizz 79 buzz fizz 82 83 fizz buzz 86 fizz 88 89 fizzbuzz 91 92 fizz 94 buzz fizz 97 98 fizz buzz
```

#バイトコード

```

  push  "x"
  push  ""
  set  
  push  "i"
  push  "0"
  set
loop  push  "i"
  push  "i"
  push  "i"
  get
  ++
  set
  get
  push  "i"  
  get
  push  "15"
  %
  push  "1"
  >
  if  skip2  
  push  "i"  
  get
  push  "5"
  %
  push  "1"
  >
  if  skip1
  push  "i"  
  get
  push  "3"
  %
  push  "1"
  >
  if  skip0
  push  "x"
  push  "x"
  get
  push  "i"
  get
  add
  set
  push  "x"
  push  "x"
  get
  push  " "
  jp  skip3
skip0  push  "x"
  push  "x"
  get
  push  "fizz "
  jp  skip3
skip1  push  "x"
  push  "x"
  get
  push  "buzz "
  jp  skip3
skip2  push  "x"
  push  "x"
  get
  push  "fizzbuzz "
skip3  add
  set
  push  "i"
  get
  push  "100"
  >
  if  loop
  end
```

#成果物
http://jsdo.it/ohisama1/mX8M


以上。
Windows10のHyper-Vを用いて仮想環境を立ち上げる(Windwos Server2012 R2)

#さくっと仮想環境を立ち上げます

こんにちは、@mashiです。

Windows10にて個人利用のための仮想環境を立ち上げることが度々あるので、方法をメモしておきます。(今回は内部接続のみを目的としています)

# 前準備
- ISOファイル
- Hyper-Vのイントラ用スイッチ
 - 「Hyper-Vマネージャー」画面にて、「仮想スイッチマネージャー」をクリック
 - 「内部」を選択し、「仮想スイッチの作成」をクリック
 - 「OK」をクリック

# 手順
- Hyper-Vマネージャー画面
 - Hyper-Vを起動し、「新規/仮想マシン」を選択
 - 「名前と場所の指定」にてわかりやすい名前にする
 - 「ネットワークの構成」にて準備したイントラ用スイッチを選択
 - 「インストールオプション」で「ブートCD/DVD-ROMからオペレーティングシステムをインストールする」を選択し、「イメージファイル」の欄にて準備していたISOファイルを選択する
 <br>
※記載箇所以外は既定値のままで問題ありません
 - 「完了」をクリック
- 仮想マシン画面
 - 作成した仮想マシンを「接続」
 - 「起動」
 - 「Windowsセットアップ」画面はそのまま「次へ」
 - 「今すぐインストール」
 - 「Windows Server 2012 Standard(GUI使用サーバー)」を選択し「次へ」
 - 「インストールの種類を選んでください」画面にて、「カスタム」を選択
 - そのまま「次へ」

**完了です** 

# ローカルPCから仮想サーバにアクセスする
- 仮想サーバのファイアウォールを無効にしてください
angular4 ng serve 4200ポートへの外部からのアクセス方法

# 問題
 - `ng serve` で起動したURLに外部端末からだとアクセスできない。 `http://localhost:4200` は当然としても、 `http://192.168.11.1:4200` みたいなアクセスも出来ない。

# 解決
 - angular-cli.jsonを以下のように書き換える

```json
  "defaults": {
    "styleExt": "scss",
    "build": {
      "showCircularDependencies": false
    },
    "serve": {
      "port": 4200,
      "host": "192.168.11.1"
    },
    "component": {}
  }
```

 - `ng serve` して外部端末から `http://192.168.11.1:4200` でアクセスできるようになる

# 参考にしたもの
 - [DockerでAngular quick start](https://qiita.com/TakashiOshikawa/items/6339b094a19d438c68eb)

# 感想
 - 参考にしたやつと全く同じで行けた。知識足らず。。。。。
MacでGenymotion + Android Studioを使おうとしたら、Genymotionボタンが出てこない！

# Genymotionボタンが出てこない！

MacでGenymotionをインストールし、
Android Studioを使えるように設定しようとしたところ、

Genymotionのプラグインをインストールするところまではできたのに、
なぜかGenymotionボタン（Genymotion Device Managerボタン）が
Android studioのツールバーに表示されなくて、
先に進まない…。

あとちょっとで使えそうなのに…！
という時のメモです。

# Genymotionボタンの表示方法

Android studioのツールバーは、
View > Toolbar をチェックすることで、表示されます。
そうすると、Genymotionが正しくインストールされていれば、
Genymotionボタンも右端に表示されます。

あまり無いケースかもしれませんが、
同じような状況になった方に伝わればと思います…。
Oracle 数値判定 PL/SQL

```PL/SQL:is_number.sql
CREATE OR REPLACE FUNCTION IS_NUMBER
    (
    IN_STRING IN VARCHAR2 -- 文字列
    )
    RETURN VARCHAR2 -- 'OK' or 'NG'
--
-- 数値チェック
--
--  入力文字列が数値かチェックする。
--
IS
    L_NUMBER  NUMBER ;
BEGIN
    L_NUMBER := TO_NUMBER(IN_STRING) ;
    RETURN('OK') ;
EXCEPTION
    WHEN OTHERS THEN
        RETURN('NG') ;
END IS_NUMBER ;
/
-- 以下、インスタンス内のすべてのスキーマで実行できるように共有プログラムを置くスキーマに置くことを想定。要 CREATE PUBLIC SYNONYM, DROP PUBLIC SYNONYM 権限
CREATE OR REPLACE PUBLIC SYNONYM IS_NUMBER FOR IS_NUMBER ;
GRANT EXECUTE ON IS_NUMBER TO PUBLIC ;
```

```SQL
-- 使用例
COLUMN STRING     FORMAT A20
COLUMN IS_NUMBER  FORMAT A2
SELECT A.STRING
     , IS_NUMBER(A.STRING) AS IS_NUMBER
FROM(
    SELECT '0123456789'  AS STRING FROM DUAL UNION ALL
    SELECT '0123.456789'           FROM DUAL UNION ALL
    SELECT '-0123456789'           FROM DUAL UNION ALL
    SELECT '0123456789+'           FROM DUAL UNION ALL
    SELECT '012345 6789'           FROM DUAL UNION ALL
    SELECT ' 0123456789'           FROM DUAL UNION ALL
    SELECT '0123456789 '           FROM DUAL
    ) A ;
COLUMN STRING    CLEAR
COLUMN IS_NUMBER CLEAR

STRING               IS
-------------------- --
0123456789           OK
0123.456789          OK
-0123456789          OK
0123456789+          NG
012345 6789          NG
 0123456789          OK
0123456789           OK

7行が選択されました。

```
Azure Functions BotのソースZIPファイルをローカルデバッグする方法

QnAmakerとつないだAzureFunctionsBotからダウンロードしたZIPファイルソースをPCローカルでデバッグする方法です。

#環境


- Visual Studio 2017
- Windows10 （ビルド1703）

#手順
####Azure Functions CLIインストール
[この手順](https://qiita.com/taketakekaho/items/c3146510f26e62e0836e)で実施

####DotNet CLIインストール
[Get started with .NET in 10 minutes](https://www.microsoft.com/net/learn/get-started/windows)の項番１だけ実施で大丈夫っぽいです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/178016/6616987b-b1dc-f924-ef7a-80a3d4b63792.png)
以下の画面で[install]
![image.png](https://qiita-image-store.s3.amazonaws.com/0/178016/5acf9ab3-756a-a653-cd17-f08e43bfa96b.png)
この画面で[Close]
![image.png](https://qiita-image-store.s3.amazonaws.com/0/178016/4c6b87b2-1dd4-a721-943c-c805708d2d11.png)
WindowsPowerShellで`dotnet`コマンド打って以下の応答があればOK
![image.png](https://qiita-image-store.s3.amazonaws.com/0/178016/725cb8b6-8e04-8258-acb5-de0c225759c9.png)

####BotFramework Emulator
[BotFramework-Emulator](https://github.com/Microsoft/BotFramework-Emulator#download)からダウンロードします。

####Azure Functions BotからソースZIPファイルをダウンロード
ポータル＞ビルド＞zip ファイルをダウンロードからダウンロードできます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/178016/d2dca104-3372-632a-15a5-c32cfc80a7ad.png)

####ローカルでデバッグ
Visual Studio 2017を管理者として実行して起動します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/178016/142aeec4-6440-a148-6a58-0f4e585ab1bb.png)

ファイル > 開く > プロジェクト/ソリューション からダウンロードした ソリューション ファイル “Bot.sln” を開きます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/178016/b18d0dc3-576e-fd85-50a2-ddf07ab082ff.png)

コマンドプロンプトかWindowsPowerShellを管理者として起動し、Bot.slnの展開先へ移動します

以下のコマンドでbotをローカルで起動します

```:powershell
> .\debughost.cmd
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/178016/70471b26-bcbc-5016-8c9c-3c60ad7b9f18.png)

ずらずらと水色の文字が流れまして最後にこんなのが出力されるはずです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/178016/e1153d95-0e69-e45d-2e21-b4f65122f0b9.png)

このhttpから始まるのがエンドポイントです。

####Emulatorで起動
Bot Framework Emulatorを起動してエンドポイントを入力します。Microsoft App IDやMicrosoft App Passwordは空欄でOK
![image.png](https://qiita-image-store.s3.amazonaws.com/0/178016/885197b2-06ea-ad53-1c5f-7c976fcf57cf.png)

動いた～～
![image.png](https://qiita-image-store.s3.amazonaws.com/0/178016/a59e339d-d17a-ca85-237e-106da32343af.png)

終わる時にはPowerShellでCtrl+Cすればよいかと。
ちなみにAzureFunctionsのアプリ設定の項目にIDやKeyを入れていた場合はZIPソースには入らないのでローカルでは動作しません。ご注意ください。

#参考ドキュメント
- Debug a Bot Service bot
　https://docs.microsoft.com/ja-jp/bot-framework/bot-service-debug-bot#debug-csharp-serverless

- Azure Functions CLI
　https://www.npmjs.com/package/azure-functions-cli

- DotNet CLI
　https://github.com/dotnet/cli

- Bot Framework Emulator
　https://github.com/Microsoft/BotFramework-Emulator/releases
AWS EC2で自動復旧するために、Auto Scalingで実現する3つのパターン考察


※この投稿は答えが書いてるわけじゃなく、みんなどうやってるのかなぁ？と思いながら書いてます。

ec2 auto scalingを使って、ec2が万が一落ちても自動復旧してくれないかなぁと思ったのですが、ec2 auto scaling自体はどうやらAMIからec2を立ち上げるくらいしかしてくれないことがわかりました。
この新規で立ち上がったec2をどうやって最新状態にするのか？以下3つのパターンを考えてみました

## パターン1: そもそも最新の状態のAMIを常に用意しておく
多分一番多いパターン。
デプロイスクリプトに「AMIの作成」と「auto scalingで指定しているAMI-idの変更」を組み込んでおけばよいのではないかと考えられる。
しかし、runningのインスタンスからAMI作成しようとすると瞬断しちゃうので、みんなAMI作成用のインスタンスを毎回立ち上げてAMI作成してるんだろうか？

## パターン2: ec2が起動したときにプロビジョニング用の外部APIを叩くスクリプトを仕込んだAMIを用意しておくパターン
ec2の起動スクリプトに、自身をプロビジョニングするためのAPIを叩くスクリプトを用意しておくパターン。
「自身をプロビジョニングするためのAPI」はansble towerやjenkinsが多いんだと思う。
環境変数で、外部からAPIのurl（及びパラメータ）を操作できるようにしておけば用意するAMIはサービスに関係なく1つだけでよい。一方で立ち上がるまでに時間がかかってしまう

## パターン3: ec2が起動時のnotificationを利用してプロビジョニング
パターン2と酷似するが、起動スクリプトではなく、auto-scalingが発火するnotificationをSNSで受け取ってlambdaなどでapiを叩くパターン
メリデメはパターン2と同じ

## みなさんどうしてます？
いずれにしても、結構めんどくさいなぁというのが所感でした。
もう開発が止まっていて構成も変わらないようなサービスはパターン1が絶対にいいと思うんですが、更新が頻繁なサービスはどうしてるんでしょうか？
他にもパターンあるよ。うちはこうしてるよなど教えていただきたいです。
よろしくお願いします
日付テーブルとしてマークする とは

Power BI Desktop 2018年2月の更新で "日付テーブルとしてマークする" という機能が追加された。この機能は、PowerPivot や SSAS では用意されていた機能なのだけど、やっぱり Power BI Desktop でも必要ということで追加されたのでしょう。

日付テーブルについては 以前のポストの通り
[日付テーブル は必要か、それが問題だ - Qiita](https://qiita.com/PowerBIxyz/items/375573ebe78a48b6d7de)

# 必須ということではないけれども
リレーションシップ で使用する列のデータ型が 日付型 であれば 設定しなくても結果は変わらないので、必要であれば設定すればよい。
独自に用意した日付テーブルを "日付テーブルとしてマークする"と クイック メジャーが割と使えるようになるので設定してもいんじゃないかなと思う。

# どのようなときに使うか
## たとえば
ファクト テーブル上で日付を表す列のデータ型が日付時刻ではないとき使用できる。個人的には DWH などでよく見かけるかな。

**テーブル 'ファクト'**

|DateKey|Quantity|
|--:|--:|
|20180105|1000|
|20180110|5000|
|...|...|
|20180210|700|
|20180220|300|
|...|...|

**テーブル 'カレンダー'**

|DateKey|Year|Month|Day|Dates|
|--:|--:|--:|--:|--:|
|20180101|2018|1|1|2018-01-01|
|20180102|2018|1|2|2018-01-02|
|20180103|2018|1|3|2018-01-03|
|...|...|...|...|...|

このとき、
リレーションシップは 'カレンダー'[DateKey] 1 --> * 'ファクト'[DateKey]
そして、
タイム インテリジェンス関数に使うのでテーブル 'カレンダー' には 日付型 もしくは 日付時刻型の [Dates]列 がある。

```text:メジャー：TotalQuantity
TotalQuantity = SUM( 'ファクト'[Quantity] )
```

```text:メジャー：TotalQuantityLM
TotalQuantityLM =
CALUCLATE(
    [TotalQuantity],
    PREVIOUSMONTH( 'カレンダー'[Dates] ),
    ALL( 'カレンダー' ) --- 日付テーブルとしてマーク & 日付列として指定しない場合に必要
)
```

タイム インテリジェンス関数自体は結果を返すけれども、伝搬されるフィルターによりメジャーで期待する結果が得られない。なので、結果セット各行で 'カレンダー'テーブルに適用されるフィルターを ALL 関数 で除外する必要がある。

## 日付テーブルとしてマークすると
### 自動的に適用される ALL
タイム インテリジェンス関数を使用する フィルターコンテキストに使用する場合、自動的に ALL( 'カレンダー' ) が適用されたものとなる。

```text:メジャー：TotalQuantityLM
TotalQuantityLM =
CALUCLATE(
    [TotalQuantity],
    PREVIOUSMONTH( 'カレンダー'[Dates] )
)
```

### 中の人が用意した 日付テーブル
Power BI Desktop の タイム インテリジェンス機能 で用意された日付テーブルはすべて削除される。なぜなら、独自に日付テーブルを用意したから。あわせて、用意された内部の日付テーブルを使用するメジャーはすべて機能しなくなるのは必然。

# その他
- [【2018年2月】忙しい人のためのPower BI Desktop Update](https://qiita.com/h_kobayashi1125/items/f0bcfd5eda090fcd325f) @h_kobayashi1125 
- [Power BI 勉強会 - connpass](https://powerbi.connpass.com/)
- [Power BI Desktop を使い始めるには](http://qiita.com/PowerBIxyz/items/6c4735cb5b5712e70981)
SupersetのFree formでのTime指定

# はじめに
[superset](https://github.com/apache/incubator-superset,"superset")(airbnb製のBIツール)のSliceを操作する際に日付を指定する部分で Free formなるボックスがある。
ここには`now` だったり`last month`という形で日付を指定することができるものである。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/236832/f1b0ffab-2cbe-ddfb-a80b-1de3e9d3b25f.png)


だが、`last month`が先月の1日を表すが`this month`は今月の1日ではなく最終日を表すなど、やや不透明な部分があったのでここで一度まとめてみた。

# Free formへの入力と実際に指定される日時の例

| Free form  | 指定される日時(`yyyy-MM-dd HH:mm:ss`形式の場合) |
|:-----------|-------------:|
| now        | 実行時刻の 年-月-日 時:分:秒 |
| today      | 実行時刻の 年-月-日 00:00:00 |
| this month | 実行月の最後の日の 年-月-日 00:00:00 |
| this week  | 実行時刻から見て次の金曜日の 年-月-日 00:00:00 |
| last monday| 実行時刻から見て最後の月曜日の 年-月-日 00:00:00 |
| last week  | 実行時刻の7日前の 年-月-日 00:00:00 |
| last month | 実行時刻から見て前月1日の 年-月-日 00:00:00 |

# Free formへの入力の工夫
先も述べたようにFree form には今月の先頭からという意図で`this month`が使えない。
ではどうするのかというと、実はFree form には計算式のように`+`, `-`が使えたり、
`before`, `after`, `ago`, `from`などを使って書くこともできるのである。

今月の先頭を表したい場合には次のように書けば良い:`last month + 1 month`
また、次のように書くこともできる:`1 month after from last month`
Oracle Dockerの起動からOracleクライアント実行まで(メモ)

MacでOracleサーバをDockerで立ち上げてクライアント接続までを試してみたがディスク容量を消費するのですぐ消してしまいたい

```
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
oracle/database     12.1.0.2-se2        2fff32c00a7f        4 hours ago         10.5GB
oraclelinux         7-slim              9870bebfb1d5        2 months ago        118MB
```
そこで、比較的簡単に環境を再現出来るようにメモとして残すことにした

なお、手順の詳細な説明が以下に存在する(この記事もそれを参照している)のでそちらの方が一般的には役に立つ

[OS X 10.11で，Oracle Database 12cのDocker Imageを使ってみた](https://qiita.com/lethe2211/items/0bb493fa93a0088cfac9)

# 環境

サーバ: Oracle 12.1.0.2 Standard Edition
クライアント: sqlplus, [xo/usql](https://github.com/xo/usql)

※ この usql を評価したかったというのが動機(そういう意味では導入しにくいOracleにする必要もなかったのだけど、一度Oracle環境作って見たかったので)

# 手順メモ


1. oracle install

    ```sh
    git clone https://github.com/oracle/docker-images.git
    cd docker-images/OracleDatabase/dockerfiles

    # image download
    # (12.1.0.2.0) - Standard Edition (SE2)
    # Linux x86-64 の File1, File2 をダウンロードしたものとする
    #  http://www.oracle.com/technetwork/database/enterprise-edition/downloads/index.html

    mv ~/Downloads/linuxamd64_12102_database_se2_{1,2}of2.zip 12.1.0.2/

    # standard edition の場合
    ./buildDockerImage.sh -v 12.1.0.2 -i -s
    # enterprise edition の場合
    #./buildDockerImage.sh -v 12.1.0.2 -i -e

    # standard edition の場合
    sudo docker run -p 1521:1521 --name oracle oracle/database:12.1.0.2-se2
    # enterprise edition の場合
    # sudo docker run -p 1521:1521 --name oracle  oracle/database:12.1.0.2-ee
    ```

    ```sh
    # set password for sys and system
    docker exec oracle ./setPassword.sh PASS
    ```

2. client install

    ```sh
    # download
    # instantclient-basic-macos.x64-12.1.0.2.0.zip etc..

    unzip instantclient-basic-macos.x64-12.1.0.2.0.zip
    unzip instantclient-sdk-macos.x64-12.1.0.2.0.zip
    unzip instantclient-sqlplus-macos.x64-12.1.0.2.0.zip

    instantclient_12_1/sqlplus system/PASS@localhost/ORCLPDB1
    ```

3. setup oci8

    ```sh
    cat <<END > oci8.pc
    prefix=$PWD/instantclient_12_1

    version=12.1
    build=client64

    libdir=\${prefix}
    includedir=\${prefix}/sdk/include

    Name: oci8
    Description: Oracle database engine
    Version: \${version}
    Libs: -L\${libdir} -lclntsh
    Libs.private:
    Cflags: -I\${includedir}
    END
    ```

4. usql install

    ```sh
    export PKG_CONFIG_PATH=$PWD
    export DYLD_LIBRARY_PATH=$PWD/instantclient_12_1
    go get -u -tags oracle github.com/xo/usql

    usql oracle://system:PASS@localhost/ORCLPDB1
    ```
E2Eテストで会員登録などのメール認証を簡単にする方法を編み出した話

# 初めに

会員登録などで一度メールを受信してメールに記載のURLをクリックすることで認証する仕組みが
よくあると思います。
seleniumなどでE2Eテストを作ったりするときにgmailを利用してメールから認証URL押して・・って
せっかく作ってもgmail側のUIが変わったすると突然テストが動かなくなったりしちゃいます。

なので、Google Apps Script(GAS)を使って自動化してみました。
https://developers.google.com/apps-script/

# Google Apps Scriptに作ったスクリプト

作ったGASを外部から叩くと、HTMLを返してJavaScriptでメールにあるURLへ
リダイレクトするように作りました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/143303/9399fa5c-aab5-fe8f-644e-b304cbb36465.png)





外部からGASを叩く方法は以下を参考にさせていただきました。

参考：GASのExecution APIを使ってGASを外部からぶっ叩く
https://qiita.com/soundTricker/items/1bcfc5c9e80d29a7ae4b

```JavaScript:コード.gs
var SEARCH_TERM = 'subject:(会員仮登録のお知らせ) ';

function doGet(){
  var text = getActivateUrl();
  // HTMLテンプレート読み込み
  var template = HtmlService.createTemplateFromFile('index');
  template.foo = text;
  template.bar = text;
  return template.evaluate();
}

function getActivateUrl(){
 
  var myThreads = GmailApp.search(SEARCH_TERM, 0, 30); 
  var myMessages = GmailApp.getMessagesForThreads(myThreads); 
  
  //最新の仮登録メールを探す
  var lastNum = myMessages[0].length - 1;
  var body = myMessages[0][lastNum].getBody();
  
  // メールbodyからURLを正規表現で引っこ抜く
  // 正規表現はサイトの仕様に合わせて変更してください
  var result = body.match(/http:.*hogehoge/);

  return result;
}
```

```html:index.html
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <script language="JavaScript" type="text/javascript">
    function AutoJump() {
      window.top.location.href="<?= bar ?>";
    }
    AutoJump() ;
    </script>
  </head>
  <body onLoad="javascript:setTimeout('AutoJump()',3000);">
    <a href="<?= foo ?>">link</a>
    aaaa
  </body>
</html>
```

# Nightwatch.jsでE2Eテストを書く

こんな感じで。

```JavaScript:
module.exports = {
    'メール登録' : function (client) {
        client
           // メール登録フォームがあるURLを開く
            .url('https://hogehoge/')
            .waitForElementVisible('body', 1000)
             // メアドを入れて送信
            .setValue('#mail', 'GASを作ったgmailアカウントのメアド')
            .click('#submit')
           // gmailが受信されるまで5秒くらい待つ
            .pause(5000)
            .end();
    },
    'GASに作ったURLを叩いてその先に進む': function(client) {
        client
           // GASで払い出されたURLに遷移→メール記載のURLにリダイレクトされる
            .url('https://script.google.com/macros/hogehoge・・・・')
           ・・・
```
ローカルPCの時刻を変更する方法

# やりたいこと
テストで指定の期日などの検証を行うため、ローカルPCの時刻を変更したい

# 現象
google先生などで検索した方法で、windowsの時刻をGUIツールで変更しても、一定時間たつと同期が走って元に戻ってしまう

# 解決方法
- コマンドプロンプトで以下を実行<br/>
`net stop w32time`<br/>
その後GUIツールで時刻を変更！
<br/>
終わったら
`net start w32time`で開始するのを忘れずに。

# ちなみにLinuxだと・・・
`sudo /etc/init.d/ntpd stop`
`sudo date -s "2017/01/22 13:00"`
で設定できます。
解除は
`sudo /etc/init.d/ntpd start`
embulk-output-bigquery 利用時に rateLimitExceeded エラーの対応

Embulk 便利ですよね。BigQuery にデータを入れる時に、 `rateLimitExceeded` が出たとき

```
errors:[{:reason=>"rateLimitExceeded", :message=>"Exceeded rate limits: too many table up
date operations for this table. For more information, see https://cloud.google.com/bigquery/troubleshooting-er
rors", :location=>"table.write"}]
```

の対応として、タスク数を減らして BigQuery への登録 job 自体を少なくすることで、rate limits に引っかかりにくくなります。もちろん、処理時間は長くかかります。

```
exec:
  max_threads: 1
  min_output_tasks: 1 
```

Embulk 初心者でそもそも並列処理をどう減らすのかが解らなく、と解決までちょっと時間がかかったのでメモ。

- デフォルト実行環境の LocalExecutor の流れについては、sonots さんの記事が解りやすかったです。
  - https://qiita.com/sonots/items/4445467ddb5cea0622a5

## 追記

コメントで sonots さんから GCS Bucket のオプション使うと並列でアップロードできるとのこと!

- https://github.com/embulk/embulk-output-bigquery#gcs-bucket
Laravel5.5 で非同期処理(Queue)を実装【database編】

# 環境
- CentOS 6.9
- Apache 2.2
- MySQL 5.6
- PHP 7.1
- Laravel 5.5

# 前回からの変更点
前回の [Laravel5.5 で非同期処理(Queue)を実装【sync編】](https://qiita.com/tsuyopon-md/items/9cd4711c14a46cef32fa) で作成した非同期処理を `database` を利用した処理に変更する。

## マイグレーションファイルを作成
```:console
php artisan queue:table
php artisan queue:failed-table
```

`database/migrations` にジョブ登録用のテーブル（jobs, failed_jobs）のマイグレーションファイルが作成される。

## マイグレーションを実行
```:console
php artisan migrate
```

データベースに `jobs`, `failed_jobs` テーブルが作成される。

## キューサービスの変更
```php:.env
#QUEUE_DRIVER=sync
QUEUE_DRIVER=database
```

前回はデフォルトの `sync` だったが、今回は `database` に変更する。

## キューワーカーの起動
```:console
php artisan queue:work
```

コードを変更した際はリスタートしない限り変更が反映されないため、かならず以下のコマンドでリスタートする。

```:console
php artisan queue:restart
```
実行環境では自動起動や定期的に再起動するなどの考慮が必要。

> バックグランドでqueue:workプロセスを永続的に実行し続けるには、キューワーカが止まらずに実行し続けていることを確実にするため、Supervisorのようなプロセスモニタを利用する必要があります。
> ※[Laravel 5.5 キュー](https://readouble.com/laravel/5.5/ja/queues.html) より抜粋

`Supervisor` の導入はまた後で考えよう。。。


# その他
ジョブクラスやコントローラは前回と同じものをそのまま利用。

## ジョブが失敗した場合

以下のコマンドにてジョブの確認等が可能。

### 失敗したジョブの確認

```:console
php artisan queue:failed
```

### 失敗したジョブの再実行

```:console
php artisan queue:retry ジョブID
```

### 失敗したジョブの削除

```:console
php artisan queue:forget  ジョブID
```

### 失敗したジョブの全削除

```:console
php artisan queue:flush
```


# 参考
- [Laravel 5.5 キュー](https://readouble.com/laravel/5.5/ja/queues.html)
- [laravel5.5のデータベースキュー投入とジョブ処理で非同期処理を実現する](https://www.ritolab.com/entry/37)
PC画面(tty)から繋いだときの文字化けを何とかする

PCに直接接続されているモニター上のコンソール（以後tty）は、基本的に日本語表示に対応しておらず、OSのロケールを日本向けに設定すると文字化けに悩まされること必至です。
そこでいくつか対策を考えてみました。

#その場しのぎ
```
export LANG="C"`
```
とコマンド打って環境変数**LANG**を変更すれば、とりあえずは英語出力となり、最小限の対応はできるようになります。
(なおLANG=C は**既定値を使う**という意味で、英語にするという意味ではないので念の為。）

#tty使用時のみ文字化け回避
ttyからログインされた場合のみ環境変数LANGを変更するようにして、
tty上では文字化けを回避、ssh接続時は日本語出力されるように出来ました。

```sh:~/.bashrc
#末尾に追加
#ttyコマンドの出力に"tty"が含まれていた場合`export LANG="C"`を実行する
(tty|fgrep -q 'tty') && export LANG="C"
```
※全ユーザーを対象とする場合は`/etc/bash.bashrc`(debian系) `/etc/bashrc`(redhad系)を修正。

#tty自体を日本語表示に対応させる→放棄 :sweat_smile: 
理想なんですが、以下の理由により諦めました。
- 日本語表示対応のターミナルエミュレータを、怪しい方法で稼働させることで対応できるようだが、その怪しい方法自体にセキュリティ上の問題がある。
- 日本語フォントも入れなければならない。
- そもそもttyを使う機会が少ない（ワークステーション用途ならX入れるだろうし、サーバー用途ならssh使うだろうし）

どうしてもというなら、[fbterm](https://www.google.co.jp/search?q=fbterm)で検索してみてください。

#言語の既定値自体を変える→放棄
`localectl` コマンドや、ディストリビューション付属の設定ツール(Raspianならraspi-configとか）を使用してロケール自体を文字化けしない言語に変える方法。
この方法だと確実に解決出来ますが・・・**日本語表示を諦める**ということなんで、
sshやtelnet経由でも常に英語出力とかになってしまいます。
sshであればターミナル側のフォントを利用して日本語表示を行えるため、ロケールまでいじるのはちょっと大げさな気が...

#参考文献
[ttyとかptsとかについて確認してみる](https://qiita.com/toshihirock/items/22de12f99b5c40365369)
jcaptcha実装時にライブラリを認識しない

# jcaptcha実装時のトラブルシューティング
## 環境
- windows7
- java7
- javaServerFaces2.2
- glassfish4.1
- eclipse
 
## ビルドパスからライブラリに登録したもの
- jcaptcha-1.0.jar
- jcaptcha-api-1.0.jar
- imaging-01012005.jar

## 現象
- コード上でimportしてjar内のクラスは利用できる
- ビルドしてみると、jarクラス内の「CaptchaServiceException」などが無いといわれビルドできない。

## 解消方法
1.　ビルドパスからライブラリを削除
2.　mavenコマンドを利用してjarファイルを配置
3.　pom.xmlの<dependency>に追加
※3.は当然といえば当然なのですが、それだけだと上記現象が解決できませんでした

mevenコマンドは以下
- mvn install:install-file -Dfile=C:\Users\{ユーザ名}\Downloads\octo\captcha\jcaptcha\1.0\jcaptcha-1.0.jar -DgroupId=com.octo.captcha -DartifactId=jcaptcha -Dversion=1.0 -Dpackaging=jar
- mvn install:install-file -Dfile=C:\Users\{ユーザ名}\Downloads\octo\captcha\jcaptcha-api\1.0\jcaptcha-api-1.0.jar -DgroupId=com.octo.captcha -DartifactId=jcaptcha-api -Dversion=1.0 -Dpackaging=jar
- mvn install:install-file -Dfile=C:\Users\{ユーザ名}\Downloads\jhlabs\imaging\01012005\imaging-01012005.jar -DgroupId=com.jhlabs -DartifactId=imaging -Dversion=01012005 -Dpackaging=jar
　※pathは適宜読み替えてください