OmniAICreator/Qiita-1.07M huggingface dataset:
opencv3.4.0インストールメモ

# ソースをダウンロードして展開
```.sh
$ cd ~
$ mkdir temp
$ cd temp
$ wget https://github.com/opencv/opencv/archive/3.4.0.zip -O opencv-3.4.0.zip
$ wget https://github.com/opencv/opencv_contrib/archive/3.4.0.zip -O opencv_contrib-3.4.0.zip
$ unzip opencv-3.4.0.zip
$ unzip opencv_contrib-3.4.0.zip
$ cd opencv-3.4.0
$ mkdir build
$ cd build
```
# $HOME/temp/opencv/opencv-3.4.2/modules/python/src2/cv2.cpp の885行目を以下のように修正
```.cpp
const char* str = PyString_AsString(obj);
```
# コンパイル＆インストール
cuda9.1がインストールされている。
システムにはpython3.7がインストールされている。
それとは別に python3.7.0 を pyenv で global に指定していて普段はそれを使っている。

```.sh
$ cmake -D CMAKE_BUILD_TYPE=RELEASE \
-D CMAKE_INSTALL_PREFIX=/usr/local \
-D ENABLE_CXX11=1 \
-D INSTALL_PYTHON_EXAMPLES=ON \
-D HAVE_opencv_python3=ON \
-D PYTHON_DEFAULT_EXECUTABLE=$HOME/.pyenv/versions/3.7.0/bin/python3.7 \
-D PYTHON_EXECUTABLE=$HOME/.pyenv/versions/3.7.0/bin/python3.7 \
-D PYTHON_INCLUDE_DIRS=$HOME/.pyenv/versions/3.7.0/include/python3.7m \
-D PYTHON_LIBRARY=/usr/lib/x86_64-linux-gnu/libpython3.7m.so.1 \
-D INSTALL_C_EXAMPLES=OFF -D BUILD_opencv_python2=OFF \
-D BUILD_opencv_python3=ON \
-D BUILD_NEW_PYTHON_SUPPORT=ON \
-D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib-3.4.0/modules \
-D BUILD_EXAMPLES=ON ..
```
```.sh
$ make -j8
$ sudo make install
$ sudo ldconfig
$ cd ~/.pyenv/versions/3.7.0/lib/python3.7/site-packages
$ sudo ln -s /usr/local/lib/python3.7/site-packages/cv2.cpython-37m-x86_64-linux-gnu.so cv2.so
```
# チェック
```.sh
$ cd ~
$ python
Python 3.7.0 (default, Jul 26 2018, 05:22:48) 
[GCC 7.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
>>> cv2.__version__
'3.4.0'
>>> exit()
```
AWS Lambda (Python) からCloudFormationのスタック作成・削除を行う

業務時間だけ使うAWSリソースがあり、それをCloudFormationを使って管理しているという場合、Lambdaからスタックの作製・削除ができると便利です。

削除するのは簡単なのですが、作成するときは少し手こずったのでそれを書いておきます。

### 作成

TemplateURLにS3バケット内のファイルを指定する場合は次のようにします。
※httpsとスキームが付きますが、Webホスティングの設定は必要ありません。

```
https://s3-ap-northeast-1.amazonaws.com/(S3バケット名)/ファイル名
```

ということで作成するときはこんな感じになります。

```py
    cf = boto3.client('cloudformation')
    res = cf.create_stack(
        StackName=(スタック名),
        TemplateURL='https://s3-ap-northeast-1.amazonaws.com/(S3バケット名)/ファイル名',
        Parameters=[
            {
                'ParameterKey': 'パラメータ名1',
                'ParameterValue': '設定値1'
            },
            {
                'ParameterKey': 'パラメータ名2',
                'ParameterValue': '設定値2'
            },
        ],
        Capabilities=[
            'CAPABILITY_NAMED_IAM',
        ],
    )
```

### 削除

削除はスタック名を指定するだけなのでとても簡単。

```py
    cf = boto3.client('cloudformation')
    res = cf.delete_stack(
        StackName=(スタック名)
    )
```
[cocoa][swift]BUKURO.swift 2018-07に行ってきた

<p>会場はいつもの池袋コワーキングスペース Open Office FOREST。前回の勉強会は新生MOSA始動のイベントだったので、通常の勉強会は久しぶりだ。</p>

# 発表

## VirtualBoxへのMojaveのインストール
<p>VirtualBoxへmacOS Mojaveをインストールするという発表だが、MojaveはUSB1.1コントローラがサポートされていないのと、インストール時にフォーマットをAPFSに変更してしまうのだが、VirtualBoxがAPFSからの起動をサポートしていないという問題があり、それを回避する内容だ。</p>

## 通信デバッグ
<p>Remote Virtual Interfaceを使って、Macに接続されたiOS端末をMacのターミナルで動かしたtcpdumpでパケット・トレースするという内容だ。</p>

## SwiftのOptionalを理解する
<p>Swiftでプログラミングする範囲で必要なoptional関連の構文とサンプルコードをスライドにして、それを参加者と内容を確認していくといった内容だ。</p>

## 構文糖衣なしでSwiftのオプショナルを使うとどうなるか？
<p>前の発表を踏まえて、Optionalの内部での定義を紹介して、より深く理解するという内容だ。</p>

<p>予定していた『モブプログラミング』は時間切れとなり次回以降の実施となった。</p>

<p>秋に田町のコワーキングスペース 森永ヴィレッジで、特別な勉強会の開催が発表されたのだが、現状、勉強会の名称が統一されていないのと、池袋以外での開催となるので、新たな名称として『Cocoa.swift』の提案があった。</p>

<p>より詳細な内容については、FacebookのCocoa勉強会 関東のグループで行うことになったので、是非、意見をいただければ。</p>

【関連情報】
<a href="https://cocoa-kanto.connpass.com/event/91202/">BUKURO.swift 2018-07</a><br />
<a href="https://cocoa-kanto.connpass.com/">Cocoa.swift</a><br />
<a href="https://www.facebook.com/groups/cocoa.kanto/">Cocoa勉強会 関東</a><br />
<a href="http://www.bitz.co.jp/weblog/">Cocoa練習帳</a><br />
<a href="https://qiita.com/m_yukio">Qiita</a><br />
MyBatisとLocalDateTimeとSpring

# 概要
SpringBootでAPIを作ってみようと思って、DBとの連携はMyBatisだ！って軽い気持ちで挑んだらしょうもないとこでぶつかりまくったのでメモ残しておく

# MyBatis Generator編
## LocalDateTime型生成されない問題
[この辺のサイト](https://jappy.hatenablog.com/entry/2017/01/28/235520)を参考にGradleでMyBatis Generatorが動くようにした。
これでmodelやmapperを生成するとMySQLのdatetime型カラムはJavaのDate型に対応して出力された。

LocalDateTime型が自動で生成されるようにしたくて[公式サイト](http://www.mybatis.org/generator/configreference/javaTypeResolver.html)参考にしたらconfigにJSR310のproperty設定するだけで対応する！って書いてあるからやってみると、変換されない。。。

紆余曲折したけど、ぐぐってみると2018/7/4リリースのVersion:1.3.7で[対応](https://github.com/mybatis/generator/pull/326)されたらしい。上のgradleで出来るやつがまだ対応してなくて変換されなかったらしい。 

しょうがないので1.3.7対応してるEclipse Marketplace使って上記config設定して生成したらLocalDateTimeで生成されたっぞ！！

## 関係ないデータベースのmodel/mapper生成されちゃう問題
`<table tableName="%"`こんな感じでgeneratorConfig.xml設定してデータベースの全テーブル分宜しく生成してくれーと思ったら、information_schemaデータベース内のテーブルとかも大量に現れてきた。

これは[公式](http://www.mybatis.org/generator/usage/mysql.html)にちゃんと書いてあった。  
以下の通りnullCatalogMeansCurrentを設定するといらないやつは出なくなった！！！

```xml:generatorConfig.xml
    <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost/my_schema"
            userId="my_user" password="my_password">
        <property name="nullCatalogMeansCurrent" value=true" />
    </jdbcConnection>
```

# MyBatis編
## typehandler見つからない問題
generatorはうまく言ったのにMybatis側でうまくいかない。。

```log:catalina.2018-07-26.log
Caused by: java.lang.IllegalStateException: No typehandler found for property createDate
```

[公式](http://www.mybatis.org/mybatis-3/ja/configuration.html)に書いてあったけどMyBatisのVersion:3.4.5からデフォルトでLocalDateTimeの変換対応してるらしい。  
`mybatis-spring-boot-starter:1.3.1`を指定してたが無心で`mybatis-spring-boot-starter:1.3.2`にしてみたらバージョン上がってうまく動いた！

# まとめ
ちょっとしたことだけど2日くらいかかった気がする。。
同じことで悩む人がいないようにメモ残しとこう
ClovaでAudioPlayerを試してみた

# AudioPlayerでできること

URLを指定するだけで、Clovaで音声ファイルを流すことができます。
ClvoaでLINEミュージックとかを流すのをイメージしていただけるとわかりやすいかと思います。
あれを、スキルとして自由に音声ファイルを指定してあげます。

# 基本設定

基本設定画面の「AudioPlayerの使用」を「はい」を選択して保存します。

![Clova_Developer_Center_β.png](https://qiita-image-store.s3.amazonaws.com/0/195882/d397ee70-9c6e-cc93-8d30-6f018c78ac8b.png)

# レスポンスのJSON

`url`の部分を流したい音声ファイルのURLに変更してください。

```json
{
  "version": "1.0",
  "sessionAttributes": {},
  "response": {
    "card": {},
    "directives": [
      {
        "header": {
          "namespace": "AudioPlayer",
          "name": "Play"
        },
        "payload": {
          "audioItem": {
            "audioItemId": "hogehogeeee",
            "title": "song title",
            "artist": "artist name",
            "stream": {
              "beginAtInMilliseconds": 0,
              "token": "sample-token",
              "url": "https://something.audio.mp3",
              "urlPlayable": true
            }
          },
          "playBehavior": "REPLACE_ALL"
        }
      }
    ],
    "outputSpeech": {},
    "shouldEndSession": true
  }
}
```

# この続き

音声ファイルの開始何秒からスタートするかなど細かな設定がまだまだたくさんできます。
詳しくは、公式ドキュメントに書いています。

https://clova-developers.line.me/guide/#/CEK/References/CEK_API.md#CustomExtResponseMessage
Gitでfork元のレポジトリの変更を追跡する

少し前までよくわからずに、調べてもわかりやすい記事がなく、かなり迷ったので、そんな人が出ないようにメモ

## 対象

1. あるレポジトリをforkして
2. fork元で開発が進み
3. fork元のレポジトリの変更を取り込みたい人

## 注意
fork先のレポジトリで、ブランチを切らずに変更を加えるとうまくいかない場合があります

## 1. fork元をremoteに追加する
fork元のレポジトリの変更を取得するためにremoteに追加
`git remote add upstream <URL>`
<URL>はfork元のレポジトリのURL(<>は不要)

## 2. fork元をpull
fork元のレポジトリから変更を取得します
`git pull upstream`


## 3. fork先にpush
fork先のレポジトリに変更を適用します
`git push origin`
Ruby技術者認定試験Silverに合格した

1ヶ月ほど勉強して90点で合格できました
先輩方が同様の記事をたくさん書かれていますが、僕自身それを見ながらモチベーションを維持していたので、これも誰かの参考になればと思い書いてみました

# 受験前のスキル
- Ruby開発歴は1年弱
- 普段はモバイル開発エンジニア
- SIerからweb系に転職して2年ほど

# 教材
- [Ruby技術者認定試験合格教本](https://amzn.to/2LKJKmE)
- [Rubyアソシエーション?のGist](https://gist.github.com/sean2121/945035ef2341f0c39bf40762cd8531e0)
- [AmiWiki](https://ref.xaio.jp/ruby)

# 勉強時間
- 土日3時間ずつを1ヶ月

# 勉強内容
2. Ruby技術者認定試験合格教本の練習問題と演習問題を解く
3. 間違えた問題の分野に関するページを読む
4. 1と2を全問正解するまで繰り返す
5. 繰り返し間違える分野は雑にでもいいからまとめてみる(思考が整理される)
6. Gistの問題を解いてみる(初見で8割正解できればほぼ問題なし)

# 気をつけたこと
- Rubyマスターになろうとしない
    - 資格取得だけでRubyをマスターできるほどプログラミングは甘くない
    - マスターを目指すのは知識を活かして実践で使うようになってから
    - なので、練習問題の内容を理解することに時間を割く
- Ruby2.1特有の部分は捨てる
    - 例えば、`{ "foo": 1 }` が2.1ではエラーになるが、サポート外バージョンの仕様を覚えても仕方がないと割り切った

# 試験後に振り返ってみて思うこと
- 組み込みクラスの勉強は一番大事だが、一番退屈だった。irbで試すだけで気晴らしになった。そもそも手を動かして覚えるべきですが・・・
- 正規表現はちゃんと勉強しないといつまで立っても正解できない
- オブジェクト指向の分野の問題が正解できてても、最後にもう一回module関連の範囲は読み直してみたほうがいい。精神的な余裕からか理解度が全然違った
- FileIO系の問題は意外と出題される
- Ruby技術者認定試験合格教本の問題とほぼ同じものが4割位出題される


次はGold取得めざしてみます
メモ: linuxserver/nextcloud でファイルのスキャンが必要になった場合の手順

# TL;DR

我が家では Nextcloud を Docker で運用していますが、サクッと構築したかったので Docker Image には [nextcloud](https://hub.docker.com/_/nextcloud/) ではなく [linuxserver/nextcloud](https://hub.docker.com/r/linuxserver/nextcloud/) を利用しています。
Nextcloud 配下のファイルやディレクトリを Nextcloud 以外の手段(SMB, FTP, SCP etc...)で追加/変更/削除すると、その変更が Nextcloud 上に自動的に反映されません。
このため、 `occ` というコマンドを使ってファイルとディレクトリをスキャンする必要があるのですが、そのやり方が少しだけ普通とは違っていたのでメモです。

# 前提条件

*   Docker Image: [linuxserver/nextcloud](https://hub.docker.com/r/linuxserver/nextcloud/):latest (2018/07/01 時点のもの)
*   Version: Nextcloud 13.0.5 (12 系でも同じ手順でできたはず。。。)

# 解決したいこと

[linuxserver/nextcloud](https://hub.docker.com/r/linuxserver/nextcloud/) を用いた Docker Container で、 Nextcloud 管理下のディレクトリ内にあるファイルやサブディレクトリについて、 Container 上で追加/削除されたファイルが Nextcloud に反映されていないのを反映させたい。

# やり方

## Container ID を調べる

対象となる Docker Container(`linuxserver/nextcloud`) の Container ID を調べます。

```shell-session
# docker ps
CONTAINER ID        IMAGE                          COMMAND             CREATED             STATUS              PORTS                            NAMES
317d6fb4633e        linuxserver/nextcloud:latest   "/init"             3 weeks ago         Up 3 weeks          80/tcp, 0.0.0.0:10443->443/tcp   nextcloud_20180701
```
上記例では `317d6fb4633e` が Container ID です。

## Nextcloud の Container にログインする

上記で調べた Container ID を利用して、 `linuxserver/nextcloud` の Container にログインします。

```shell-session
# docker exec -it 317d6fb4633e bash
$ hostname
nextcloud
```

## ファイルとディレクトリをスキャンする

`occ` コマンドを用いてファイルとディレクトリをスキャンします。
`occ` ファイルのパスと、実行時に `sudo -u abc` する点が通常とは異なります。

```shell-session
$ sudo -u abc php /config/www/nextcloud/occ files:scan --all

Scanning files for 2 users
Starting scan for user 1 out of 2 (ktooi)
Starting scan for user 2 out of 2 (johndoe)

+---------+-------+--------------+
| Folders | Files | Elapsed time |
+---------+-------+--------------+
| 335     | 2880  | 00:00:10     |
+---------+-------+--------------+
```

以上でスキャンは完了です。
Nextcloud 上からファイルやディレクトリを確認すると、反映されていなかったファイルやディレクトリの追加/削除が反映されているはずです。

おしまい。。。？

## 追伸

Container ID まで調べたら、 Container にログインせずに直接 `occ` を `docker exec` すればいいんじゃね？って投稿ボタンを押す直前に思った。

```shell-session
# docker exec -it 317d6fb4633e sudo -u abc php /config/www/nextcloud/occ files:scan --all

Scanning files for 2 users
Starting scan for user 1 out of 2 (ktooi)
Starting scan for user 2 out of 2 (johndoe)

+---------+-------+--------------+
| Folders | Files | Elapsed time |
+---------+-------+--------------+
| 335     | 2880  | 00:00:11     |
+---------+-------+--------------+
```
うん、らくちん。

Container Name を固定にしていれば(例では `nextcloud_20180701`)、 Container ID も

```shell-session
$ docker ps --filter status=running --filter name=nextcloud_20180701 --format {{.ID}}
317d6fb4633e
```
のように一撃で取得できるので、

```shell-session
$ docker exec -it $(docker ps --filter status=running --filter name=nextcloud_20180701 --format {{.ID}}) sudo -u abc php /config/www/nextcloud/occ files:scan --all
```
というコマンド一発で一発で完了です。
これなら Docker ホストの Cron にでも仕込んで定期的にファイルをスキャンとか簡単にできますね。

本当におしまい。
最後にマッチした文字より後ろの文字列を検索

# 検索方法
**検索に用いる正規表現**

```
(?<=c)([^c]+$)
```
→「c」を「X」に変更すると、最後にマッチした「X」より後ろの文字列を検索する。

<br>
**例）^で検索する場合**

```
(?<=\^)([^\^]+$)
```

| 検索対象文字列   | 検索結果 |
|:----------------|---------|
| abc^bcd^efg^hij | hij     |
| zzz             | (該当なし)    |
| dddddddd^ddddd  | ddddd   |
| ^ggg            | ggg     |
| xxx^            | (該当なし)    |

1個目の^以降の文字列が欲しければ以下で取得する。

```
(?<=\^)(.*)
```
散布図・重回帰分析の自分的まとめ

# はじめに
データをまとめる，相関係数まとめたり，散布図みたり，重回帰分析する機会があったので自分的メモ

github：https://github.com/Shunichi09/Qiita/tree/master/Static

# 相関係数
参考になったサイト

- https://sci-pursuit.com/math/statistics/correlation-coefficient.html#1

使ったプログラム
numpyのcorrcoefがおすすめです
速いし，列ごとでも行ごとでも設定できるので！
普通データは列で管理されると思うので．．．

```py
np.corroef(data, rowvar=False)
```

これで計算してくれます，行ごと（そんなことあんまりないかもですが）にしたい場合は，rowbar=Trueにしてください

# 散布図
いやこれはもうSeabornが圧倒的におすすめです
なんか色かっこいいし，ちょっとイケてる風になります
カテゴリー別でも分けてくれるし，回帰直線引いてくれるしいいことしかありません

参考になったサイト

- https://note.nkmk.me/python-seaborn-pandas-pairplot/

```py
sns.pairplot(data, hue='category')# カテゴリーで色分けしてくれる
```

# 回帰分析
これに関しては意見が分かれるとは思いますが
詳細に見たい場合は，statsmodelが良いです
結果を細かく出力してくれます

しかし，連続で回帰分析してその値を抽出したいときは
sklearnの方が楽かもしれません

参考になったサイト

- Sklearn：https://pythondatascience.plavox.info/scikit-learn/%E7%B7%9A%E5%BD%A2%E5%9B%9E%E5%B8%B0
- Sklearn：https://qiita.com/ynakayama/items/88b4dd5d0dd9b1604006
- Stats：https://qiita.com/yubais/items/24f49df99b487fdc374d
- Stats：http://wcs.hatenablog.com/entry/2016/11/08/231703

```py
# sklearnの場合
# 説明変数の列抜き出し
X = np_data[:, 'input your column']

# 目的変数の列抜き出し
Y = np_data[:, 'input your column']

# 結果出してくれる（切片とか正規化とかその他もろもろ設定可能）
clf = linear_model.LinearRegression(fit_intercept=True, normalize=False, copy_X=True)
 
# 予測モデルを作成
clf.fit(X, Y) # これでfit（学習）させる 
clf.coef_(X, Y) # 偏回帰係数を出してくれる  
clf.score(X, Y) # 決定係数を出してくれる
clf.predict(X) # 予測してくれる 説明変数が入力
```

こうすれば一瞬です
結果も保存できるので，appendして平均とるとかもすぐできますね

```py
# statsmodelの場合
# 説明変数の列抜き出し
X = np_data[:, 'input your column']

# 目的変数の列抜き出し
Y = np_data[:, 'input your column']

X_y = sm.add_constant(X) # 切片を追加
 
model = smf.OLS(Y, X)# 逆なので注意！

result = model.fit()# これで結果が見える

print(result.summary())
```

結果は詳細にでます
t値とかp値とかその他もろもろ

なので，時と場合に応じて使い分けていこうかと


# 最後に
まとめたやつです
参考までに

```py
import numpy as np
import pandas as pd
import statsmodels.formula.api as smf
import statsmodels.api as sm 
from sklearn import linear_model
import matplotlib.pyplot as plt
import seaborn as sns
import string

# 統計のテンプレート

# CSVの読み込み
file_name = 'PATH + file_name.csv'
data = pd.read_csv(file_name, header=None, engine='python')

# NUMPYに変換する場合
np_data = data.values

# 注意
# データはすべて列で管理されるべし

# 対散布図（多変数の場合）引数はpandasです
sns.pairplot(data, hue='category')# カテゴリーで色分けしてくれる

# 相関係数（多変数の場合）引数はnumpy これで列ごとの相関を見れる（Trueで行ごと）
np.corrcoef(np_data, rowvar=False)

# 回帰
# sklearnの場合
# 説明変数の列抜き出し
X = np_data[:, 'input your column']

# 目的変数の列抜き出し
Y = np_data[:, 'input your column']

# 結果出してくれる（切片とか正規化とかその他もろもろ設定可能）
clf = linear_model.LinearRegression(fit_intercept=True, normalize=False, copy_X=True)
 
# 予測モデルを作成
clf.fit(X, Y) # これでfit（学習）させる 
clf.coef_(X, Y) # 偏回帰係数を出してくれる  
clf.score(X, Y) # 決定係数を出してくれる
clf.predict(X) # 予測してくれる 説明変数が入力

# statsmodelの場合
# 説明変数の列抜き出し
X = np_data[:, 'input your column']

# 目的変数の列抜き出し
Y = np_data[:, 'input your column']

X_y = sm.add_constant(X) # 切片を追加
 
model = smf.OLS(Y, X)# 逆なので注意！

result = model.fit()# これで結果が見える

print(result.summary())
```
MySQLでパーティションを切るメモ

# 流れ

パーティションを切りたいテーブルのプライマリキーを消す
↓
パーティションを切りたいテーブルに、パーティションの参考値にしたいカラムともともと設定してあったカラムにプライマリキーを追加
↓
パーティションを切る

以上

# プライマリキーの削除と追加

```sql
ALTER TABLE テーブル名
  DROP PRIMARY KEY,
  ADD PRIMARY KEY (カラム, カラム, …);
```


# パーティションを切る

```sql
ALTER TABLE テーブル名
   PARTITION BY RANGE COLUMNS (パーティションを設定したいカラム名) (
   PARTITION パーティション名 VALUES LESS THAN ( MAXVALUE )
);
```


# パーティションを設定できたかの確認

```sql
SELECT
    TABLE_SCHEMA, TABLE_NAME, PARTITION_NAME, PARTITION_ORDINAL_POSITION, TABLE_ROWS
FROM
    INFORMATION_SCHEMA.PARTITIONS
WHERE
    TABLE_NAME = 'テーブル名';
```


# 参考
ありがとうございます……！
https://qiita.com/taroshin/items/608076c9f8e09497c4b1
はじめてのScala Play Framework APIでJSON返却

初めてPlay Scalaを触ってみたが暗中模索も良い所。
APIサーバを建てられるようになることを目標としてとりあえずJSONを返してみる。
DB接続、ORMの取扱いなどは次回へ回す。

# 環境
- OSX HighSierra
- Homebrew
- JDK1.8

# sbt導入
```
brew install sbt
```

# プロジェクト作成
```
sbt new playframework/play-scala-seed.g8
```

筆者はIntelliJ IDEAのプロジェクト作成を使った。

# Hello World
作成したプロジェクト直下で `sbt run` を実行。
長めのビルドが始まり、完了すると `localhost:9000` でWelcomeページが見れる。

# JSON返却

HomeControllerで下のように追記。

```diff:app/controllers/HomeController
package controllers

import javax.inject._
import play.api.mvc._
+ import play.api.libs.json._

/**
 * This controller creates an `Action` to handle HTTP requests to the
 * application's home page.
 */
@Singleton
class HomeController @Inject()(cc: ControllerComponents) extends AbstractController(cc) {

  /**
   * Create an Action to render an HTML page with a welcome message.
   * The configuration in the `routes` file means that this method
   * will be called when the application receives a `GET` request with
   * a path of `/`.
   */
  def index = Action {
    Ok(views.html.index("Your new application is ready."))
  }

+  def api = Action {
+    Ok(Json.toJson(Map("message" -> "Hello Play")))
+  }

}
```

再度 `sbt run` でリビルドする。
`localhost:9000/api` で `{"message": "Hello Play"}` が返されてるのを確認。

# 参考
https://yutaro.amebaownd.com/posts/710477
【私感】Eloquentの集計について【laravel】

# 背景
最近laravelを仕事で使った。
で、Eloquentに対しての集計方法が一歩理解できたのでそのメモ
なんとなく使えるのがフレームワークの良いところ(?)

# そこに至った経緯
なんかエラーでる
他の箇所ではこんな感じで使えていた気がするのに・・・

```php
$result = Model::where->('id', 1)->get();
echo $result->name; //Property [name] does not exist on this collection instance
```

# eloquentの集計概念

```php
Model::find(1);
```

これは主キーが"1"に一致したものをSELECTするので
必ず一つ（以下）のデータしか集計しない
→modelで返す

```php
Model::where->('id', 1)->get();
```
これは"id"といったカラムが"1"のものをSELECTするので
複数のデータを集計することがある（主キーを指定しているわけではないので）
→collectionで返す

```php
Model::where->('id', 1)->first();
```
これは"id"といったカラムが"1"のものをSELECTして
最初に見つかったものを返すので必ず一つしかデータを集計しない
→modelで返す


```php
Model::find([1, 2]);
```

配列でfindした場合である。
これは主キーが"1"もしくは"2"に一致したものをSELECTするので
必ず複数のデータを集計する
→collectionで返す

上記、厳密には一致するデータ見つからなかったりしてnullが返ることもあるが、
概ねこれを意識していればちょっと進んだ扱いができるかと思う。


# つまり上のエラーは
Collectionからプロパティにアクセスしようとしていたんですね。
そう、getとfindとか場当たりに使っていたので
うまくいったりいかなかったりしていたんですね。
ポアソン回帰


余所のサイトで勉強させて頂きました。


```{r}

#pois regression

library(dplyr)

Y <- c( 6,  9, 11, 11,
       21, 14, 13, 20,
       38, 36, 23, 29,
       30, 33, 46, 40,
       61, 48, 54, 44)

X <- cbind(rep(1, length(Y)),
       c(1, 1, 1, 1,
         2, 2, 2, 2,
         3, 3, 3, 3,
         4, 4, 4, 4, 
         5, 5, 5, 5)
       )

beta <- matrix(0, ncol = 2, nrow = 100)

beta[1, ] <- c(1, 10)

for(m in 2:100){
  lambda <- exp(X %*% beta[m - 1, ])
  W <- diag(lambda[, 1])
  XtWX <- t(X) %*% W %*% X
  U <- t(Y - lambda) %*% X
  beta[m, ] <- beta[m - 1, ] + solve(XtWX) %*% t(U)
}

params=beta[nrow(beta),]

predict=exp(X%*%params)

plot(c(1:length(Y)),(Y),type="p",col=2,xlab="num",ylab="values",ylim=c(min((Y)),max((Y))))

par(new=T)

plot(c(1:length(Y)),predict,type="p",col=3,xlab="num",ylab="values",ylim=c(min((Y)),max((Y))))



```


```{r}

data=read.csv("~/診療サンプル.csv")

library(dplyr)

Y <- as.numeric(data$発生件数)

X <- cbind(rep(1, length(Y)),
as.numeric(data$診療科),as.numeric(data$処方薬剤数)
       )

beta <- matrix(0, ncol = ncol(X), nrow = 100)

beta[1, ] <- rep(10,ncol(X))

for(m in 2:100){
  lambda <- exp(X %*% beta[m - 1, ])
  W <- diag(lambda[, 1])
  XtWX <- t(X) %*% W %*% X
  U <- t(Y - lambda) %*% X
  beta[m, ] <- beta[m - 1, ] + solve(XtWX) %*% t(U)
}

params=beta[nrow(beta),]

predict=exp(X%*%params)

plot(c(1:length(Y)),(Y),type="p",col=2,xlab="num",ylab="values",ylim=c(min((Y)),max((Y))))

par(new=T)

plot(c(1:length(Y)),predict,type="p",col=3,xlab="num",ylab="values",ylim=c(min((Y)),max((Y))))

```

データ：
![image.png](https://qiita-image-store.s3.amazonaws.com/0/230981/d9c97868-adb6-3832-f37c-4814fd6d276c.png)
Visual Studio コマンドプロンプト起動バッチの場所

コマンドラインでビルドを実行するのに使用する Visual Studio コマンドプロンプトですが、インストール時にできるショートカットを使うと新しいウインドウが開いてしまいます。
しかし、起動バッチを直接実行すれば、既存のコンソールに環境変数だけ取り込むことができます。

# 2015まで

## 標準的なインストールパス

```
C:\Program Files (x86)\Microsoft Visual Studio 11.0
```

## バッチの場所

* `amd64`や`64`などターゲットの情報がパスに入ります。

```
(インストールパス)\VC\bin\amd64\vcvars64.bat
```

# 2017

## 標準的なインストールパス

* エディションが入ります。

```
C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional
```

## バッチの場所(+コマンドライン)

* ターゲットの情報は引数になりました。

```
(インストールパス)\VC\Auxiliary\Build\vcvarsall.bat amd64
```

# PowerShellから起動

Import-VisualStudioVars` コマンドレットを使います。

```ps1
Import-VisualStudioVars -VisualStudioVersion 2017 -Architecture amd64
```

※ PSCXが必要なので、ない場合は以下のコマンドでインストール

```ps1
Install-Module Pscx -Scope CurrentUser
```
使って学ぶ transduce

ramda 使って transduce のお勉強

- まずは 出力用の reducer の定義。ふつうに `(acc, x) => acc.concat([x])` としてもいいんだけど、せっかくだから transformer で実装する:

```js
const R = require('ramda');

const xfList = {
  '@@transducer/step': (acc, x) => acc.concat([x]),
  '@@transducer/init': () => [], // ignored on transduce
  '@@transducer/result': x => x,
};
```

- 2を足して 3を掛けるという map を transduce で書いてみる。mapper を関数合成するのが普通:

```js
// reference point
const add2 = x => x + 2;
const mul3 = x => x * 3;
const f1 = x => mul3(add2(x));
[1, 2, 3].map(f1); // ->  [ 9, 12, 15 ]
R.transduce(R.map(f1), xfList, [], [1, 2, 3]); // -> [ 9, 12, 15 ]
```

- mapper を compose しても良いし、 transducer を compose してもよい。compose の順序が異なるのは何度注意してもしきれない:

```js
// composed mapper
const f2 = R.compose(mul3, add2);
R.transduce(R.map(f2), xfList, [], [1, 2, 3]); // -> [ 9, 12, 15 ]

// composed transducer. NOTE THE ORDER TO COMPOSE!
const xform = R.compose(R.map(add2), R.map(mul3));
R.transduce(xform, xfList, [], [1, 2, 3]); // -> [ 9, 12, 15 ]
```

- とはいえ、mapper を compose する方向は、filter が出てくると詰むので、transducer を compose するのがいいだろう:

```js
// composed transducer. compotition of map and filter
const xform2 = R.compose(xform, R.filter(x => x % 2));
R.transduce(xform2, xfList, [], [1, 2, 3]); // -> [ 9, 15 ]
```

- transformer の形でロジックを書いておく利点は、input や output が変わってもロジック部である transformer の実装をいじる必要がないということ:

```js
// pluggable input
const g = (function* mygen() { yield 1; yield 2; yield 3; }());
R.transduce(xform, xfList, [], g); // -> [ 9, 12, 15 ]

// pluggable output
const xfString = {
  '@@transducer/step': (acc, x) => `${acc},${x}`,
  '@@transducer/init': () => 'X', // ignored on transduce
  '@@transducer/result': x => x,
};
R.transduce(xform, xfString, '', [1, 2, 3]); // -> ',9,12,15'
```

- 普段は transduce よりも into を使う方が見た目がわかりやすい:

```js
// in most cases, use into in favor of transduce
R.into([], xform, [1, 2, 3]); // -> [ 9, 12, 15 ]
R.into('', xform, [1, 2, 3]); // -> '91215'
R.into(xfList, xform, [1, 2, 3]); // -> [ 9, 12, 15 ]
R.into(xfString, xform, [1, 2, 3]); // -> 'X,9,12,15'

```
Rubyでデータをイテレートするときどう扱うべきかのまとめ (C#やってた人向け)

## 前提
C#のList<独自モデル>,Dictionary,あたりを理解している人がRubyを勉強し始めて、
データをどう取りまわすのがいいかをまとめたメモです。


##List、配列はArray

```Ruby

ary = [1,2,3]
ary = ["Shinji","Ray","Asuka"]
ary = Array.new(3) #要素数を指定して宣言
ary = Array.new(3, 0) #二つ目の引数を入れると、その値で初期化


#2次元配列のときは下記のようにmapを使うこと (じゃないと最初の行のポインタが他の行に展開されちゃう)
ary = Array.new(3).map{Array.new(3,0)}

#Rubyは一つ一つがオブジェクトなので、配列の要素に長さの違う配列を入れたりもできる
ary = [9, 2, 3, [4, 5], [6, [7, 8]]]


#既存のオブジェクトに要素を追加するときはpush
animals = ["dog", "cat", "mouse"]
animals.push("pig")

#削除はdelete
fruits = ["apple", "orange", "banana", "kiwi", "banana"]
fruits.delete("banana")


#C#と違って、イテレートしている自分自身の要素も削除できる

fruits = ["apple", "orange", "banana", "kiwi", "banana"]
fruits.each{|fruit|
    if fruit == "orange"
        fruits.delete(fruit) #これはエラーにならない
    end
}
p fruits
```

## Dictionaryに相当するのはHash。  なんだけど、ちょっと注意が必要
RubyのHashはC#のDictionaryと違って書き方の自由度が高いので理解に迷うところもあった

```Ruby

#一番シンプルな形 (key-value) を使うときは、そのまま入れてけばOK

scores = {}           # 空のハッシュを作成
scores["Shinji"] = 80  # キー"Shinji"、値80のペアを追加
scores["Ray"] = 70
scores["Asuka"] = 60

# このように書いてもよい
scores = {"Shinji" => 80, "Ray" => 70, "Asuka" => 60 }
```

## 上記と異なり、複数のハッシュを持ったHashオブジェクトを一つのレコードとみなし、それら複数のレコードをもった配列やHashオブジェクトを扱う場合

```Ruby

#配列
students = [] #配列を宣言
students[0] = {name: "Taro", age: 16, bloodType: "A"}
students[1] = {name: "Jiro", age: 17, bloodType: "B"}
students[2] = {name: "Maro", age: 18, bloodType: "O", weight: "55kg"} # レコードの内容が異なってもOKなとこがHashは便利

students.each { |student|
    p student[:name]
    p student[:weight]
}


#Hashオブジェクト
students = {} #空のハッシュを宣言
students["A"] = {name: "Taro", age: 16, bloodType: "A"}
students["B"] = {name: "Jiro", age: 17, bloodType: "B"}
students["C"] = {name: "Maro", age: 18, bloodType: "O", weight: "55kg"}

students.each { |key,student| #keyを使わない場合でも、宣言しとかないとエラーになる
    p key
    p student[:name]
    p student[:weight]
}

```
レコードの内容が動的に変化するような場合はハッシュを使ったほうが楽。


## 定義したフィールド以外に変更したくない場合 (C#に近いやり方)
c#だと独自のクラスを作って、List<独自クラス>とかDictionary<int,独自クラス>みたいな
使いかたをよくやります。
Rubyではクラスを使って定義する方法と、structを使う方法があります。
まずは、structを使ったやり方がこちら

```Ruby
student = Struct.new("Student", :name, :age, :bloodType)

students = []

students.push(student.new("Taro", 16, "A"))
students.push(student.new("Taro", 17, "A"))

students.each{|student| p student.name} #こんな感じでc#のメンバ変数っぽく書ける
```
ただし、上記のやり方だと当然ながらメソッドは ~~持たせられない。~~ **持たせられます！！** このページの下部、scivolaさんのコメントをご参考ください。


次に、クラスを使う方法はこちら

```Ruby

class Student
    def initialize(n, a, bt) #コンストラクタはinitializeという名前で統一されている
        @name = n
        @age = a
        @bloodType = bt
    end
    
    attr_accessor :name, :age, :bloodType  #attr_accessorはいわゆるゲッター セッター
end


students = []
students.push(Student.new("Taro",16,"A"))
students.push(Student.new("Jiro",17,"B"))

students.each{|student| 
    p student.age       #get
    student.age += 1    #set
}   

puts "--------"

students.each{|student| 
    p student.age       #get
}   

```

以上です。

Rubyは自分の実力が試される言語だなと日々感じながら勉強中。
file tempfileで作った一時ファイルの自動削除

Tcl8.6で

```tcl
file tempfile
```

を実行すると一時ファイルをオープンし、そのチャンネルが返されます。

[ヘルプ](http://docs.activestate.com/activetcl/8.6/tcl/TclCmd/file.html#M39)では`file tempfile ?nameVar? ?template?`で生成した一時ファイルの削除について、

>If the nameVar is given, it specifies a variable that the name of the temporary file will be written into; if absent, Tcl will attempt to arrange for the temporary file to be deleted once it is no longer required.

と説明されており、英語に苦手意識が無い人がちゃんと読めば「フムフム、nameVarを省略すると自動削除されるが、nameVarでファイル名を受け取った場合は自動的には削除されないんだな」と理解できるのでしょう。

しかし残念ながら私は「`file tempfile`で作ったファイルはどうやら自動的に削除されるらしい。`it is no longer required`っていうのは要するにチャンネルをクローズしたらってことかな？」などと勝手に納得しちゃったもんだから、「nameVarで一時ファイルのパス名を取得しておいて、チャンネルのクローズかTclインタプリタの終了で本当に一時ファイルが消えるか試してみよう」などと目論んで見事にドツボにはまっちゃったという笑い話です。

例えばtclshを起動しておいて

```tcl
% set ch [file tempfile fn]
% glob $fn
% close $ch
% glob $fn
% exit
```

の順で実行してみて、2回目の`glob $fn`で`no files matched glob pattern`と言われれば`close $ch`の時に削除された証拠で、`exit`の後で`dir`とか`ls`とかで`glob $fn`が返したパス名のファイルを調べてみて存在しなければtclsh終了時に消された証拠、と。

ところが実際にやってみると`exit`の後もファイルは削除されずに残っている、なんで？

分からない時はソースコード見るのが一番！　これぞオープンソースの醍醐味！　ということでソースコードをあたってみました。

するとありました。

Windowsでは

```c
Tcl_Channel
TclpOpenTemporaryFile(
    Tcl_Obj *dirObj,
    Tcl_Obj *basenameObj,
    Tcl_Obj *extensionObj,
    Tcl_Obj *resultingNameObj)
{
    TCHAR name[MAX_PATH];
    char *namePtr;
    HANDLE handle;
    DWORD flags = FILE_ATTRIBUTE_TEMPORARY;
    int length, counter, counter2;
    Tcl_DString buf;

    if (!resultingNameObj) {
        flags |= FILE_FLAG_DELETE_ON_CLOSE;
    }

    :(中略)

    handle = CreateFile(name,
        GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_NEW, flags, NULL);

    :(中略)
}
```

という実装で`nameVar`が未指定(`resultingNameObj`がNULL)ならCreateFile関数にFILE_FLAG_DELETE_ON_CLOSEを与え、UNIXでは

```c
int
TclUnixOpenTemporaryFile(
    Tcl_Obj *dirObj,
    Tcl_Obj *basenameObj,
    Tcl_Obj *extensionObj,
    Tcl_Obj *resultingNameObj)
{

    :(中略)

    } else {
        /*
         * Try to delete the file immediately since we're not reporting the
         * name to anyone. Note that we're *not* handling any errors from
         * this!
         */

        unlink(Tcl_DStringValue(&template));
        errno = 0;
    }

    :(中略)
}
```

という実装で`nameVar`が未指定(`resultingNameObj`がNULL)ならばunlink関数でリンクを削除しておき、結果的にWindowsでもUNIXでもファイルを閉じた時に一時ファイルが削除されるように手配(arrange)していました。

ここまで調べてやっと「どうやらnameVarを指定したから削除されなかったらしい」と気付き、先程`glob $fn`で返されたパス名のディレクトリを監視しながらtclshで

```tcl
% set ch [file tempfile]
% close $ch
% exit
```

を実行してみると、確かに`file tempfile`を実行した直後に`TCLxxxxx.TMP`(xxxxxはtclshのプロセスIDの16進数表現)が生成され、`close $ch`を実行した直後にそのファイルが消滅することを目視確認できました。

そしてもう一度ヘルプを読み返して、(いや正確にはGoogle翻訳で訳して読んでみてw)やっと説明の意味に合点がいったというオチでした。

振り返ってみれば『暇人な徒労』でしたが、WindowsとUNIXそれぞれでの実現方法が分かったのは面白かったので、前述の『オープンソースの醍醐味！』ということにしておきたいと思います。
sympyで「3元連立方程式(Simultaneous equation)」をやってみた


(参考)

https://qiita.com/_JG1WWK/items/951667dd27631b594de5

https://qiita.com/mrrclb48z/items/a8c798e012b0051b6bc1

# sympyで
``` fullscript.py
from sympy import *
var("a11 a12 a13 a21 a22 a23 a31 a32 a33 b1 b2 b3")
var("x y z ")
var("A B C D")
print(solve([2*x+5*y+7*z-4,4*x+13*y+20*z-11,8*x+29*y+50*z-29 ]))

A =Matrix(([a11,a12,a13], [a21,a22,a23],[a31,a32,a33]))
B =Matrix(([b1],[b2],[b3]))
C=A.inv() * B
D=C.subs({a11:2,a12:5,a13:7, a21:4, a22:13,  a23:20, a31:8,a32:29,a33:50,b1:4, b2:11, b3:29})
print(C)
print(D)
print("x=",D[0],"y=",D[1],"z=",D[2])
# {x: 1, y: -1, z: 1}
# Matrix([[-b3*(-a12*(a11*a23 - a13*a21) + a13*(a11*a22 - a12*a21))/((a11*a22 - a12*a21)*(a11*a33 - a13*a31) - (a11*a23 - a13*a21)*(a11*a32 - a12*a31)) + b1*(a11*a22*((a11*a22 - a12*a21)*(a11*a33 - a13*a31) - (a11*a23 - a13*a21)*(a11*a32 - a12*a31)) - (-a12*(a11*a23 - a13*a21) + a13*(a11*a22 - a12*a21))*(a21*(a11*a32 - a12*a31) - a31*(a11*a22 - a12*a21)))/(a11*(a11*a22 - a12*a21)*((a11*a22 - a12*a21)*(a11*a33 - a13*a31) - (a11*a23 - a13*a21)*(a11*a32 - a12*a31))) + b2*(-a11*a12*((a11*a22 - a12*a21)*(a11*a33 - a13*a31) - (a11*a23 - a13*a21)*(a11*a32 - a12*a31)) + a11*(a11*a32 - a12*a31)*(-a12*(a11*a23 - a13*a21) + a13*(a11*a22 - a12*a21)))/(a11*(a11*a22 - a12*a21)*((a11*a22 - a12*a21)*(a11*a33 - a13*a31) - (a11*a23 - a13*a21)*(a11*a32 - a12*a31)))], [-a11*b3*(a11*a23 - a13*a21)/((a11*a22 - a12*a21)*(a11*a33 - a13*a31) - (a11*a23 - a13*a21)*(a11*a32 - a12*a31)) + b1*(-a21*((a11*a22 - a12*a21)*(a11*a33 - a13*a31) - (a11*a23 - a13*a21)*(a11*a32 - a12*a31)) - (a11*a23 - a13*a21)*(a21*(a11*a32 - a12*a31) - a31*(a11*a22 - a12*a21)))/((a11*a22 - a12*a21)*((a11*a22 - a12*a21)*(a11*a33 - a13*a31) - (a11*a23 - a13*a21)*(a11*a32 - a12*a31))) + b2*(a11*(a11*a23 - a13*a21)*(a11*a32 - a12*a31) + a11*((a11*a22 - a12*a21)*(a11*a33 - a13*a31) - (a11*a23 - a13*a21)*(a11*a32 - a12*a31)))/((a11*a22 - a12*a21)*((a11*a22 - a12*a21)*(a11*a33 - a13*a31) - (a11*a23 - a13*a21)*(a11*a32 - a12*a31)))], [-a11*b2*(a11*a32 - a12*a31)/((a11*a22 - a12*a21)*(a11*a33 - a13*a31) - (a11*a23 - a13*a21)*(a11*a32 - a12*a31)) + a11*b3*(a11*a22 - a12*a21)/((a11*a22 - a12*a21)*(a11*a33 - a13*a31) - (a11*a23 - a13*a21)*(a11*a32 - a12*a31)) + b1*(a21*(a11*a32 - a12*a31) - a31*(a11*a22 - a12*a21))/((a11*a22 - a12*a21)*(a11*a33 - a13*a31) - (a11*a23 - a13*a21)*(a11*a32 - a12*a31))]])
# Matrix([[1], [-1], [1]])
# x= 1 y= -1 z= 1
```

# wolframalphaで

https://www.wolframalpha.com/input?i=2*x%2B5*y%2B7*z-4%2C4*x%2B13*y%2B20*z-11%2C8*x%2B29*y%2B50*z-29


```
2*x+5*y+7*z-4,4*x+13*y+20*z-11,8*x+29*y+50*z-29
x = 1, y = -1, z = 1
```
PHP経由で別サイトからJSONを取得する

# はじめに

[こちらの記事](https://qiita.com/takatama/items/7aa1097aac453fff1d53) を参考にGoogleスプレッドシートの内容をJSONで返却出来るようにしてからサーバー経由で取得してみる。

<img src="https://qiita-image-store.s3.amazonaws.com/0/165884/fedf0127-5bcb-00ca-af2c-2176aa0805cc.png" width="300">

CORSで引っかかった場合とか、内容をキャッシュしたい時等にもこの方法が使えるはず。

## スプレッドシートからのJSON取得

上記の記事を参考にすれば特に問題なく出来るはず。

## DockerでAPIとなるサーバーを用意

```sh
docker run --name php -d -p 8080:80 -v '($pwd):/var/www/html' php:7.1-apache
```

## PHPでAPIを用意

```php:api.php
<?php
$url = '[GoogleスプレッドシートのURL]';

$curl = curl_init();
curl_setopt_array($curl,[
    CURLOPT_URL => $url,
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_SSL_VERIFYPEER => false,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_RETURNTRANSFER => true,
]);

$result = curl_exec($curl);
// 必要に応じてこねくり回す
echo $result;

curl_close($curl);
```

## ブラウザからアクセスして確認

```
http://localhost:8080/api.php
```

```json
[ { "id": 1, "name": "いわし", "value": 100 }, { "id": 2, "name": "うし", "value": 200 }, { "id": 3, "name": "ぶた", "value": 300 }, { "id": 4, "name": "とり", "value": 400 } ]
```

## axiosからアクセス

[先日の記事](https://qiita.com/FrozenVoice/items/cbfa6d3f611a87b57cf4) の index.js でのアクセス先を変更してアクセス

```js
    mounted () {
        axios
            .get("api.php")
            .then(response => {this.results = response.data})
    }
```


|![05.png](https://qiita-image-store.s3.amazonaws.com/0/165884/91f003b4-9b21-1081-b8f8-c83bc22f3395.png)|
|:-:|
jenkins docker上でdocker buildしてdocker hubにupload

jenkins コンテナ上でdocker buildしたお話。「[jenkinsコンテナ上でdockerを利用する - Qiita](https://qiita.com/paper2/items/751246ee7dcae50d5042)」の続き。

jenkins docker上でdocker buildはあまりしないのかなあ。やっぱjenkins環境もdockerfileでコードで管理したいという考えはおかしいことじゃないと思うけど。あまり記事が見つからない。CIを体験してみたかったのでとりあえず遊んでみた。

# jenkins pipelineの定義
流れとしては

```
gitをポーリング、変更があったらPipelineがトリガーされる
↓
checkout: gitからdockerfile checkout
↓
build: docker build
↓
push: docker hubへpush
```
というシンプル流れ。

以下pipeline定義ファイル。versionというファイルにversionを書き込むことでdockerイメージのversionを指定できるようにした。

```groovy
// 前提
// - ホストでdocker hubにpushするためにdocker loginを済ませている
// - Scripted pipelineという非推奨の書き方らしい

node {
    stage('Checkout') {
        checkout([$class: 'GitSCM', 
        branches: [[name: '*/master']], 
        doGenerateSubmoduleConfigurations: false, 
        extensions: [], submoduleCfg: [], 
        userRemoteConfigs: [[url: 'https://github.com/paper2/jenkins']]])
    }
    
    // versionの読み込み
    def version = readFile('version').trim()
    def imageName = "paper2/jenkins:" + version
    print imageName

    stage('Build') {
        sh "docker build -t " + imageName + " ."
    }
    
    stage ('Push') {
        // jenkinsに登録した認証情報を利用する
        withCredentials([[$class: 'UsernamePasswordMultiBinding', 
                        credentialsId: 'docker-hub-paper2',
                        usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD']]) {
            sh 'docker login -u $USERNAME -p $PASSWORD'
        }
        sh "docker push " + imageName
    }   
}
```   

# CI
サーバ公開してないためwebhook使えないのでgitへ1分ごとにポーリングする設定にした。

versionファイルを変更してみる

```sh
$ vi version # v1.0 -> v1.1に変更
$ git add -A
$ git commit -m "v1.1"
$ git push
```

1分後勝手にCIがスタート（#24です）
![Screen Shot 2018-07-26 at 22.12.20.png](https://qiita-image-store.s3.amazonaws.com/0/230552/22960472-336d-3c33-e61f-65b3cec58c4d.png)


できた！！


![screencapture-192-168-11-2-8080-job-test-pipeline-24-console-2018-07-26-22_17_05.png](https://qiita-image-store.s3.amazonaws.com/0/230552/fd112e6d-ca0d-9e34-0d7e-86c08ffbb441.png)

自動でuploadまでされる感じたまらないですね。
シェルスクリプト製のツールを爆速で作るツールの紹介

# 背景

業務でちょっとしたツールを作ることってありませんか？
最近ですとGoとかも人気だと思いますが、シェルスクリプトを使う方も少なくないと思ってます。

で、「さあツール作るか」とせっせとシェルとにらめっこするんですが、いつも以下の点が面倒です。

 - 引数チェック
 - 引数のエラー表示
 - Usageの記述
 - ヘルプモードの用意 ...etc

「いやいや、ちょっとしたツールなんだからそんな細かい事気にしなくて良いやん！」と思われそうですが、自分が作ったちょっとしたツールがどこかの運用で引き継がれて使い続けられてたりすることってよくあると思うんです（良くないけど）。
こういう状況になった時でも、上で挙げた最低限の実装さえあればなんとかなる気がします。
ただ、全部実装するとなるととにかくめんどくさい。めんどくさいけどちゃんとしたい。
それならいっそスクリプトを作るスクリプトを作るか！と思い立って作ってみました。

# 作ったツールの紹介

[xshoji/bash-script-starter](https://github.com/xshoji/bash-script-starter)

以下、実行サンプルです（`sample.sh`が生成されたスクリプト）。

```bash
bash-4.2# STARTER_URL=https://raw.githubusercontent.com/xshoji/bash-script-starter/master/ScriptStarter.sh
bash-4.2# curl -sf ${STARTER_URL} |bash -s - \
  --naming SampleScript \
  --author xshoji \
  --description "This is sample script for qiita." \
  --env PASS,xxxxx \
  --required id,1001 \
  --optional name,xshoji \
  --flag dryRun \
  --short > sample.sh

// 権限を与えて実行する
bash-4.2# chmod 755 sample.sh
bash-4.2# ./sample.sh
[!] export PASS=xxxxx is required.
[!] --id is required.

 SampleScript
----------------- author: xshoji

This is sample script for qiita.

Usage:
  ./sample.sh --id 1001 [ --name xshoji --dryRun ]

Environment variables:
  export PASS=xxxxx

Required:
  -i, --id 1001 : "1001" means id.

Optional:
  -n, --name xshoji : "xshoji" means name.
  -d, --dryRun : Enable dryRun flag.

Helper options:
  --help, --debug
```

このように、環境変数や必須パラメータのチェック機能つきのスクリプトのテンプレートが生成されます。
必須項目を設定して実行すると...

```bash
$ export PASS=test
$ ./sample.sh --id 10001 --name myname --dryRun

[ Environment variables ]
PASS: test

[ Required parameters ]
id: 10001

[ Optional parameters ]
name: myname
dryRun: true
```

スクリプトの引数の値をそのまま出力します（処理を実装する際は、この出力部分は消してしまってOKです。あくまで最初に生成されるテンプレートがそうなっているだけです。）

詳細は[README](https://github.com/xshoji/bash-script-starter#bash-script-starter)をご参照ください。まとめると、

 - スクリプト名（必須）
 - author
 - スクリプトの説明文
 - 必須のパラメータ
 - オプションのパラメータ
 - フラグパラメタ
 - exportが必要な環境変数

の中から自分が作るツールに必要なものを指定することで、以下の機能を持ったスクリプトの雛形を生成します。

 - `--help`によるusageの表示
 - `--debug`によるデバッグモード
 - 必須パラメータの存在チェック、及び足りないパラメータの表示
 - exportが必要な環境変数の存在チェック、及び足りない環境変数の表示
 - 短縮パラメータの自動生成（例：`--name`は`-n`でも指定可能になる）

この[bash-script-starter](https://github.com/xshoji/bash-script-starter)を使うことで、「XXするツール欲しいな」と思った時に、そのツールのusage表示機能や実行時に必要な引数／環境変数がすべてチェックされた状態のテンプレートが作れるため、そのツールで実現したいロジックの実装のみに集中できます。

ちなみに生成されるスクリプトのサンプルも用意してます。どんなのが生成されるのか興味がある方は[こちら](https://github.com/xshoji/bash-script-starter/blob/develop/sample/GeneratedScriptSample.sh)まで。
変化点分析：変化要因の可視化 (2)

前回

- [変化点分析：変化要因の可視化](https://qiita.com/hoxo_m/items/2dc95330671206df3281)

では、

- 売上 = 男性売上 + 女性売上

のように分解して変化要因の可視化を行ったが、指標は掛け算的に分解されることも多い。例えば

- 売上 = 顧客数 × 平均客単価

**changepointExt** パッケージでこのような場合にも対応できるようにした。

次のような売上に対して、

![売上の推移.png](https://qiita-image-store.s3.amazonaws.com/0/2570/caef6459-3671-4bf6-bf90-8abcba861460.png)

顧客数の変化と平均客単価の変化は次のようになった。

![Rplot01.png](https://qiita-image-store.s3.amazonaws.com/0/2570/b3fc0a50-d2f0-45d1-dc82-e31e91c2fbc5.png)
![Rplot02.png](https://qiita-image-store.s3.amazonaws.com/0/2570/993bf609-40a7-d94a-07e4-bb63a9ea9c8f.png)

最初の変化は平均客単価が下がったためであり、次の変化は顧客数が下がったためである。

これを可視化するために、**changepointExt** パッケージの `combine_cpts ()` 関数に `operator` という引数を追加した。
デフォルトは `operator = "+"` であり、指標を足し算的に分解したときに使う。
これを `operator = "*"` とすれば指標を掛け算的に分解したときに使える。

```r:R
# 売上データを作成 -------------------------------------------------------------
set.seed(314)
average_spend <- c(rnorm(100, mean = 150, sd = 20),
                   rnorm(200, mean = 100, sd = 30))
customer_num <- c(rnorm(200, mean = 200, sd = 20),
                 rnorm(100, mean = 100, sd = 30))
# 売上 = 顧客数 × 平均客単価
sales <- customer_num * average_spend


# 変化点検出 -------------------------------------------------------------------
library(changepoint)

cpt_sales <- cpt.meanvar(sales, method = "PELT")
cpt_average_spend <- cpt.meanvar(average_spend, method = "PELT")
cpt_customer_num <- cpt.meanvar(customer_num, method = "PELT")


# 可視化 ---------------------------------------------------------------------
library(changepointExt)

combi <- combine_cpts("客単価" = cpt_average_spend, "顧客数" = cpt_customer_num,
                      operator = "*")
autoplot(cpt_sales) + autolayer(combi)
```

![Rplot03.png](https://qiita-image-store.s3.amazonaws.com/0/2570/674dbac1-5d49-a117-46c5-0d47137f9574.png)

Enjoy!
phoenixを触ってみる

https://hexdocs.pm/phoenix/up_and_running.html#content
に沿ってphoenixを触ってみたメモです。

elixirとかerlangは入ってる前提

# 動かすところまで

## 事前準備

プロジェクト作成用のmixタスクをインストールします。

```
mix archive.install https://github.com/phoenixframework/archives/raw/master/phx_new.ez
```

## プロジェクト作成から起動まで

早速インストールしたタスクを実行します。
今回そっこう立ち上げなので、DBなしフロントスタックなしです。
（phoenixはデフォルトでpostgresに接続する設定と、brunch.io設定が入ってきます

```
mix phx.new --no-ecto --no-brunch hello
```

途中で ```Fetch and install dependencies? [Yn] ``` って聞かれるので、
yと答えます。すると以下コマンドも勝手に実行してくれます。

```
mix deps.get
mix deps.compile
```

mixの依存ライブラリの取得とコンパイルですね。
今後ライブラリとかが増えたら実行する必要があるのでしょう。

あとは起動コマンドを叩くのみ

```
mix phx.server
```

<img width="868" alt="スクリーンショット 2018-07-26 21.53.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/164994/440f223d-2b40-2172-930b-3acda4d98fb5.png">

この画面が出たらOK！
DonkeyCar の製作（RT ラズパイマウスV2）（旧バージョン2.5.1）

![RIMG0261.JPG](https://qiita-image-store.s3.amazonaws.com/0/263672/a351e254-9c66-6d04-bdda-02fccbc877bc.jpeg)
![RIMG0262.JPG](https://qiita-image-store.s3.amazonaws.com/0/263672/92a007b7-2896-921e-147b-c8961a830aac.jpeg)

#プロジェクトの生成
筆者のgithubからファイル一式を入手
$ git clone https://github.com/mituhiromatuura/donkey
テンプレートにpimouseを指定
$ donkey createcar --template manage_pimouse ~/mycar
設定ファイルもpimouse用をコピー
$ cp donkey/donkeycar/templates/config_pimouse.py ~/mycar/config.py


ストック
laravel-csv-seederを使ってseedデータを登録する(そしてcreate or updateしたい)

# 概要

- Laravelを利用していて初期データ(マスターデータ)をDBに登録する際に、以下の要件を満たす必要がありました。
    - そこそこの量のマスターデータをcsvで作ってDBに初期登録する
    - マスターデータはレコードの追加や内容の更新が発生する
- そこで、**laravel-csv-seeder**を利用して実現したのでその時のメモになります。

# laravel-csv-seeder

- [laravel-csv-seeder](https://github.com/Flynsarmy/laravel-csv-seeder)
- csvファイルをseederの仕組みでいい感じに登録してくれます。

# 使い方

- [こちら](https://github.com/Flynsarmy/laravel-csv-seeder/blob/master/readme.md#usage)をみていただけるとわかると思いますが、CsvSeederクラスをextendsしたSeederクラスをつくり実装します。
    - テーブル名と用意したcsvファイルをパスで指定するだけです。

```php
use Flynsarmy\CsvSeeder\CsvSeeder;

class HogeHogeMasterTableSeeder extends CsvSeeder
{

	public function __construct()
	{
		$this->table = 'hogehoge_master';
		$this->filename = base_path().'/database/seeds/csvs/hogehoge_master.csv';
	}

	public function run()
	{
		DB::disableQueryLog();
		DB::table($this->table)->truncate();
		parent::run();
	}
}
```

- あとはDatabaseSeederクラスに実行するSeedのクラスを指定して実行するだけです。

```php
use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $this->call(HogeHogeMasterTableSeeder::class);
    }
}
```

- コマンドからSeed実行

```bash
 php artisan db:seed

```


# Truncateしたくない

- 上記の例だとrunするたびにテーブルをtruncateする処理になっています。
- 対象のテーブルが単独でいるだけなら問題ないですが、外部参照とかで参照されているとTruncate出来なくてエラ-になります。
    - **Truncateじゃなくてレコードがなければinsert、あればupdateするようにしたいです。**

## insert処理している箇所をoverrideする

- laravel-csv-seederさんには現状ではそのような機能はないようなので、**多少強引ですが**メソッドをoverrideして拡張しちゃいます。
- CsvSeederクラスのinsertメソッドで追加処理しているのでこのメソッドをoverrideします。
    - 引数の$seedDataにはinsertするデータがarrayで渡ってくるので１レコードづつチェックしてinsert or updateするようにします。
    - **下記の例ではidカラムがユニーク制約になっている前提です。**

```php
<?php
namespace Database\seeds;

use Flynsarmy\CsvSeeder\CsvSeeder;

class MasterTableSeeder extends CsvSeeder
{

    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        \DB::disableQueryLog();
		parent::run();
    }
    
    /**
     * override method
     *
     */
    public function insert( array $seedData )
	{
        foreach($seedData as $seed){
            try {
                if ( is_null(\DB::table($this->table)->where('id', $seed['id'])->first()) ){
                    //insert
                    \DB::table($this->table)->insert($seed);
                }else{
                    //update
                    \DB::table($this->table)->where('id', $seed['id'])->update($seed);                    
                } 
            } catch (\Exception $e) {
                \Log::error("CSV insert failed: " . $e->getMessage() . " - CSV " . $this->filename);
                return FALSE;
            }
        }
        return TRUE;
	}
```

- 各Seedクラスはこちらのクラスをextendsするように変更します

```php


class HogeHogeMasterTableSeeder extends MasterTableSeeder

	public function __construct()
	{
		$this->table = 'hogehoge_master';
		$this->filename = base_path().'/database/seeds/csvs/hogehoge_master.csv';
	}
}
```

# まとめ

- 多少強引でしたが冪等性が確保される状態にすることは出来ました。
- マスターデータなんだから最初の１回だけ実行すればOKじゃんとかは言わないで下さい。。
【jQuery】onイベントでコールバック関数に引数を渡す方法

# はじめに
jQueryのonイベントで、無名関数を指定して処理を実行させる書き方は自分でもよくやるのですが、処理が長くなった場合、この書き方ではソースコードが読み辛くなってしまいます。
そのため、処理を関数化して、呼び出す方法を採用しました。
やっていることは簡単なのですが、引数を渡すところで思うようにいきませんでした。。。
今回は、色々とやり方を模索した中で、一番分かりやすく、簡単な方法をご紹介します。

# サンプルコード

```html:HTML

<buton class="btn" data-num="1">click</buton>
<buton class="btn" data-num="2">click</buton>
<buton class="btn" data-num="3">click</buton>
<buton class="btn" data-num="4">click</buton>

```


```javascript:javascript

<script>
  $(function(){
    //ボタン
    $(".btn").on("click",function(event){
      btnClick(event,this);
    });

    function btnClick(_event,_this){
      //例えば、event処理を取り消すことも可能
      _event.preventDefault();
      //クリックしたボタンを識別することも可能
      console.log($(_this).data('num'));
    }

  });
</script>

```

この書き方でイベントハンドラやthisを引数として、利用することができます。
onイベント後の無名関数が長くなってしまったと、悩んでいる方はこの方法で解決できるのではないでしょうか。

皆様のお役に立てれば幸いです。
Prometheusのrelabel_configでメトリクスにオレオレなラベルを付与する

[relabel_configs](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#%3Crelabel_config%3E)や[metric_relabel_configs](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#%3Cmetric_relabel_configs%3E)を設定することで
`example_metric{オレオレなラベル名="オレオレな値"}`
のように任意のラベルをメトリクスに付与できる。

```prometheus.yaml
    - job_name: 'hoge-service-discovery'

      # 何らかの***_configsとか***_sd_configs
      # 例としてkubernetes_sd_configsにしています
      kubernetes_sd_configs:

      # 例としてkubernetesのノード(マシン)をsd(service discovery)します
      - role: node

      # ここからオレオレなラベルを付与していきます
      relabel_configs:

      # 例 1 : ラベル名をオレオレにする
      # kubernetesのノード名に対して、
      - source_labels: [__meta_kubernetes_node_name]
        replacement: $1
        # オレオレなラベル名をmy_node_name_1としてみる
        # my_node_name_1="kubernetesのノード名" というラベルがメトリクスに付与される
        target_label: my_node_name_1

      # 例 2 : 値の方もオレオレに加工してみる
      - source_labels: [__meta_kubernetes_node_name]
        # 値を加工できる。
        # ここでは接頭辞(my-node-name-is-)を付けてオレオレな値にしてみる。
        replacement: my-node-name-is-$1
        # my_node_name_2="my-node-name-is-ノード名" というラベルがメトリクスに付与される
        target_label: my_node_name_2

      # 例 3 : ラベル名も値も完全オレオレにする
      - source_labels: [__meta_kubernetes_node_name]
        # $1を使ってないので完全に別の文字列に置き換わる。
        replacement: hoge-huga-hage
        # hoge_huga_hage_3="hoge-huga-hage" というラベルがメトリクスに付与される
        target_label: hoge_huga_hage_3

      # 例 4 : 例3と同様。
      # ***_configsや***_sd_configsに用意されていない文字列でも良いらしい。
      - source_labels: ["hoge"]
        # 結局この指定で完全に別の文字列に置き換えるのでsource_labelsは何でもいいということかと理解している。
        replacement: hoge-huga-hage
        # 例3と同様、hoge_huga_hage_4="hoge-huga-hage" というラベルがメトリクスに付与される
        target_label: hoge_huga_hage_4


      # metric_relabel_configsでも同様。
      # relabel_configsとの違いは、metric_relabel_configsの場合、
      # source_labelsには、***_configsや***_sd_configsに用意されているメタタグでなく、
      # メトリクス提供元が付与したラベル名を指定できること
      metric_relabel_configs:

        # 例 5 : これまでの例と同様です。
        # メトリクス提供元(kubernetesの場合はcAdvisor等)が付与したラベル名を指定できる
        # 例えばname="コンテナ名"というラベルがcAdvisorから付与されている場合
      - source_labels: ["name"]
        # 加工してみる
        replacement: my-container-name-is-$1
        # my_container_name="my-container-name-is-コンテナ名" というラベルがメトリクスに付与される
        target_label:  my_container_name
```

ここではdiscoveryされた全targetのメトリクスに対しオレオレなラベルを付与したが、
`regex:` 等の指定を併用することで特定の条件のときのみラベルを付与することもできる。
詳細は[Configuration | Prometheus](https://prometheus.io/docs/prometheus/latest/configuration/configuration/)を参照されたい。
UbuntuにDockerをインストールする

https://docs.docker.com/install/linux/docker-ce/ubuntu/#install-docker-ce-1
こちらのドキュメント通りにやればインストールできるんですが、英語が読めずにハマったのでメモ。
(英語読めるようになりたい)

まずこれやって

```
$ sudo apt-get update
$ sudo apt-get install docker-ce
```

次にこれやるとバージョンのリストが返ってくるのでとりあえず最新のバージョン「18.06.0~ce~3-0~ubuntu」をコピる。

```
$ apt-cache madison docker-ce
 docker-ce | 18.06.0~ce~3-0~ubuntu | https://download.docker.com/linux/ubuntu/ trusty/stable amd64 Packages
 docker-ce | 18.03.1~ce-0~ubuntu | https://download.docker.com/linux/ubuntu/ trusty/stable amd64 Packages
 docker-ce | 18.03.0~ce-0~ubuntu | https://download.docker.com/linux/ubuntu/ trusty/stable amd64 Packages
 docker-ce | 17.12.1~ce-0~ubuntu | https://download.docker.com/linux/ubuntu/ trusty/stable amd64 Packages
 docker-ce | 17.12.0~ce-0~ubuntu | https://download.docker.com/linux/ubuntu/ trusty/stable amd64 Packages
 docker-ce | 17.09.1~ce-0~ubuntu | https://download.docker.com/linux/ubuntu/ trusty/stable amd64 Packages
 docker-ce | 17.09.0~ce-0~ubuntu | https://download.docker.com/linux/ubuntu/ trusty/stable amd64 Packages
 docker-ce | 17.06.2~ce-0~ubuntu | https://download.docker.com/linux/ubuntu/ trusty/stable amd64 Packages
 docker-ce | 17.06.1~ce-0~ubuntu | https://download.docker.com/linux/ubuntu/ trusty/stable amd64 Packages
 docker-ce | 17.06.0~ce-0~ubuntu | https://download.docker.com/linux/ubuntu/ trusty/stable amd64 Packages
 docker-ce | 17.03.2~ce-0~ubuntu-trusty | https://download.docker.com/linux/ubuntu/ trusty/stable amd64 Packages
 docker-ce | 17.03.1~ce-0~ubuntu-trusty | https://download.docker.com/linux/ubuntu/ trusty/stable amd64 Packages
 docker-ce | 17.03.0~ce-0~ubuntu-trusty | https://download.docker.com/linux/ubuntu/ trusty/stable amd64 Packages
```

で、先程コピったバージョン名を使ってDockerインストール

```
$ sudo apt-get install docker-ce=18.06.0~ce~3-0~ubuntu
```

バージョンが出ることを確認して終了。

```
$ sudo docker --version
Docker version 18.06.0-ce, build 0ffa825
```