OmniAICreator/Qiita-1.07M huggingface dataset:
ABC - 065- A&B&C

#AtCoder ABC 065 B&C
[AtCoder - 065](https://atcoder.jp/contests/abc065)

#A問題
賞味期限のA日前に食品を買ってきたので、$A=購入日$

 - 購入日＞買ってきてからB日後
    - delicious
 - 購入日+賞味期限をX日過ぎている＞買ってきてからB日後
    - safe
 - 購入日+賞味期限をX日過ぎている＜買ってきてからB日後
    - dangerous

```java
	private void solveA() {
		int numX = nextInt();
		int numA = nextInt();
		int numB = nextInt();

		if (numA >= numB) {
			out.println("delicious");
		} else if (numA + numX >= numB) {
			out.println("safe");
		} else if (numA + numX < numB) {
			out.println("dangerous");
		}

	}
```

#B問題

 - 必ず1番目（配列の0番目 {$a_o$}）からスタート
 - {$a_0$}で指定された{$a_i$}を確認して次の{$a_n$}を見る
 - loopして、2を見つけたら終了(2を見つけたときにもボタンを押す必要はある)
 - ただし、$ボタンを押した回数>配列の個数$までいったら、ボタン同士がloopしているので2にはたどり着けないと判定
    - {$3,2,1$}のようなな配列は双方向なので簡単だが、{$3,2,4,1$}のような配列は何個か経由してloopするため回数で判定している

```java
	private void solveB() {
		int numN = nextInt();
		int[] wk = IntStream.range(0, numN).map(i -> nextInt()).toArray();

		int res = chkB(wk, 1, 0, 0);

		out.println(res);
	}

	private int chkB(int[] wk, int currentI, int total, int buttonCnt) {

		if (buttonCnt > wk.length) {
			return -1;
		}
		int index = wk[currentI - 1];
		if (index == 2) {
			return total + 1;
		} else {
			return chkB(wk, index, total + 1, buttonCnt + 1);
		}

	}
```

#C問題

偶数の場合と奇数の場合で場合わけ

 - そもそも、犬犬猿や犬猿猿のような組み合わせは認められないので、犬と猿の差分は$\leqq1$出ないといけない。ありえるパターンは4つ。
    - 犬猿犬猿犬猿犬（合計が奇数）
    - 猿犬猿犬猿犬猿（合計が奇数）
    - 猿犬猿犬猿犬（合計が偶数）
    - 犬猿犬猿犬猿（合計が偶数）
 - $(3,2)$匹の組み合わせの場合は、$(3 * 2) * (2 * 1)$となる
 - $(2,2)$匹の組み合わせの場合は、$(2 * 2) * (1 * 1)$となる
    - ただし、$(1 * 1)$の時は、$(A,B),(B,A)$という二つの組み合わせがあるのに注意

```java
	/**
	 * 3 , 2
	 * (3 * 2) * (2 * 1)
	 *
	 * 2 , 2
	 * (2 * 2) * (1 * 1)
	 */
	private void solveC() {
		long numN = nextInt();
		long numM = nextInt();
		long diffNum = Math.abs(numN - numM);
		//犬と猿の差分が2以上の場合は犬犬、猿猿の組み合わせが発生する
		if (diffNum > 1) {
			out.println(0);
			return;
		}

		//両方1なら組み合わせは二通り
		if (numN == 1 && numM == 1) {
			out.println(2);
			return;
		}

		long CONST = (long) (Math.pow(10, 9) + 7);
		long res = 1;
		long big = numN > numM ? numN : numM;
		long small = numN > numM ? numM : numN;

		while (small >= 1) {
			if (small != 1) {
				res *= (big * small) % CONST;
			} else {
				//1*1は組み合わせとしては2通り
				res *= 2;
			}
			//modしておかないと溢れる
			res = res % CONST;
			big--;
			small--;
		}
		out.println(res);

	}
```
prisma.yml

```:prisma/prisma.yml
endpoint: http://192.168.99.111:4466
datamodel: datamodel.graphql
```
上のようなとき、endpoint: http://192.168.99.111:4466は service name と stage name をdefaultにセットしている
⇒ 省略されてるだけで本当は endpoint: http://192.168.99.111:4466/default/default ということ
⇒  http://192.168.99.111:4466/(service name)/(stage name)

これを endpoint: http://192.168.99.111:4466/reviews/default と変更すると、全く新しい保存領域がDBに作成される (default/defaultとconflictしない)

例えば以下のように新たなprismaディレクトリを作成したと仮定する
![キャプチャ.JPG](https://qiita-image-store.s3.amazonaws.com/0/385539/e5cf6335-2425-351f-62e1-1ca8f574a997.jpeg)

```:prisma/prisma.yml
endpoint: http://192.168.99.111:4466
datamodel: datamodel.graphql
```

```:prisma-review-website/prisma.yml
endpoint: http://192.168.99.111:4466/reviews/default
datamodel: datamodel.graphql
```
このときは、次のコマンドを実行することで異なる2つのDB領域が生成される。

```
~graphql-prisma\prisma> prisma deploy
~graphql-prisma\prisma-review-website> prisma deploy
```
playgroundにアクセスしたいときはそれぞれ以下にアクセスする。
・ http://192.168.99.111:4466/
・ http://192.168.99.111:4466/reviews
JavaScriptで重複のあるソート済み配列から指定した値の範囲をバイナリサーチで取得する

ソート済み配列から指定した値を持つインデックスの範囲をバイナリサーチで取得する方法です。

`binarysearchMinIndex`は重複要素があるソート済み配列`array`から指定した値`target`を持つ最も小さいインデックスを取得する関数です。引数の`from`と`to`はサーチする配列の範囲を指定します。`binarysearchMaxIndex`は`binarysearchMinIndex`とは逆に指定した値を持つ最も大きいインデックスを取得する関数です。
`binarysearchRange`が目的のソート済み配列`array`から指定した値`target`を持つインデックスの範囲を取得する関数です。内部では`binarysearchMinIndex`と`binarysearchMaxIndex`を使用しています。

```js

function binarysearchMinIndex(array, target, from, to) {
  while (from !== to) {
    const middle = from + Math.floor((to - from) / 2);
    if (array[middle] < target) {
      from = middle + 1;
    } else {
      to = middle;
    }
  }
  if (array[from] === target) {
    return from;
  } else {
    return -1;
  }
}

function binarysearchMaxIndex(array, target, from, to) {
  while (from !== to) {
    const middle = from + Math.ceil((to - from) / 2);
    if (array[middle] > target) {
      to = middle - 1;
    } else {
      from = middle;
    }
  }
  if (array[from] === target) {
    return from;
  } else {
    return -1;
  }
}

function binarysearchRange(array, target) {
  const from = binarysearchMinIndex(array, target, 0, array.length - 1);
  const to = from !== -1 ? binarysearchMaxIndex(array, target, from, array.length - 1) : -1;
  return { from: from, to: to };
}
```

---

通常のバイナリサーチのコードも載せておきます。重複要素のないソート済み配列`array`から指定した値`target`のインデックスを取得します。もし指定した値の要素がない場合は`-1`を返します。

```js
function binarysearch(array, target) {
  let from = 0;
  let to = array.length - 1;
  while (from <= to) {
    const middle = from + Math.floor((to - from) / 2);
    if (array[middle] < target) {
      from = middle + 1;
    } else if (array[middle] > target) {
      to = middle - 1;
    } else {
      return middle;
    }
  }
  return -1;
}
```

今回は目的の`binarysearchRange`関数をその値を持つ最も小さなインデックスと最も大きなインデックスをそれぞれバイナリサーチで見つけるような実装をしました。同じ値を持つ要素が少ないことが分かっている場合、通常のバイナリサーチでその値を持つインデックスを見つけてからその前後を線形探索で調べるというアルゴリズムもあります。

---

ソースコードをgistに置いておきました。
https://gist.github.com/aadebdeb/964ff754d4045e2b7b1fea8044e7420d
Excel の小技集1

#Excelのちょっとした小技

仕事して覚えたちょっとしたテクニックや個人的なメモをご紹介します。

##1. 比較は「＝」を使う
比較はexact関数などが使えますが、セル同士をイコールでつなげるのが効率がいいですね。

##2.可視セルのコピー
「Alt＋；」で見えているセルをコピーします。非表示やフィルターなどをしたあとにセルを全選択しコピーすると非表示のセルまでコピーされてしまいます。しかし、セルを全選択したあと「Alt＋；」を押すと、見えているセルだけコピーできます。

##3.日付や時間入力のショートカット
「Ctrl+;」で現在の日付が一発で入力できます。また「Ctrl+:」で現在の時間を入力できます。

##4.画像の選択
画像がたくさん選択したいとき、画像をひとつひとつ選択のはめんどくさいですよね。そういった場合は、「オブジェクトの選択」を使うと、ドラッグして選択したい範囲を調節できます。このテクニックを知るまでずっとCtrlを押しながら画像を選択していました。この方法を使うと楽ちんです。

##5．貼り付けのオプション
Excelでは、コピーしたデータをそのまま貼り付けるとたいてい事故ります。その場合は貼り付けのオプションで貼り付けたい条件を指定できます。フォーマットを崩したくないときは、値の貼り付け、数式の貼り付けを選択するとフォーマットを崩さなくてすみます。ショートカットは、データをコピーした後、「Ctrl＋Alt」を押しながらVを押します。

##6．表示形式を文字列にする。
シートに何かのデータを貼り付けする前に、表示形式を文字列に指定します。例えばセルに「00001」など頭に0をつけたデータを入力すると、標準設定では1に自動変換されます。こういう変換はお節介であり、勝手に変換されると困ることが多いので、あらかじめ表示形式を文字列に指定するとコピーしたデータをそのまま貼り付けられるので事故が減ります。

##さいごに
Excelは仕事をするうえでとても便利です。便利ですが、時短技やテクニックを知るとさらに生産性が上がります。私はかなりの横着者なので、常にもっと楽にできないかを考えながら作業しています（笑）。同じ成果物であっても、より短い時間で少ない工程で実現できないかを模索しております。
最後までお読みいただきありがとうございました。
redisとruby on railsの連携

環境
macOS Mojava 10.14.4
Docker 18.09.2
Rails 5.2.2
ruby 2.6.1p33

Webアプリケーションのセッション管理の方法はいくつかあるのですが、ruby on railsは特に指定しなければローカルのCookieにセッションが保存されます。
この状態でrailsを動作させるとCookieが作成されています。
Safariだと
Safari > 環境設定 > プライバシー > CookieとWebサイトのデータ:
を確認すると127.0.0.1のWebサイトのデータが保存されています。（ローカル開発時）

開発だけであればいいんですが、実際の環境でユーザーCookieでセッション情報を管理するのは問題があるのでredisで管理するようにしました。

redisをインストール

```command
$brew install redis
・・・インストールログ・・・
==> Summary
🍺  /usr/local/Cellar/redis/5.0.4: 13 files, 3.1MB
```
なんかログにビールが出ました。多分成功の証です。

```
$redis-cli
Could not connect to Redis at 127.0.0.1:6379: Connection refused
```
インストールできていました。
redisサーバーが起動してないので接続できていません。

せっかくなんで学習のため、redisサーバーはDockerコンテナを使ってみようかと思います。
Dockerのインストールはこちらを参考にしました。
https://qiita.com/kurkuru/items/127fa99ef5b2f0288b81

redisのDockerコンテナーの起動
停止したら削除するために--rmをつけます。
-pでコンテナのポートを公開します。（ホストのポート6379をコンテナのポート6379に接続） 

```
$docker container run --name local-redis -d --rm -p 6379:6379 redis
Unable to find image 'redis:latest' locally
latest: Pulling from library/redis
27833a3ba0a5: Pull complete 
cde8019a4b43: Pull complete 
97a473b37fb2: Pull complete 
c6fe0dfbb7e3: Pull complete 
39c8f5ba1240: Pull complete 
cfbdd870cf75: Pull complete 
Digest: sha256:000339fb57e0ddf2d48d72f3341e47a8ca3b1beae9bdcb25a96323095b72a79b
Status: Downloaded newer image for redis:latest
cbc1a37039dab71ce996cecdae2cd7cbdbbb78cd76e281ff5837eac3113dd403
```
dockerイメージがローカルにない場合はDocker Hubから自動でPullしてくれます。
https://hub.docker.com

redisのコンテナが動作しているかの確認

```
$docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
cbc1a37039da        redis               "docker-entrypoint.s…"   51 seconds ago      Up 50 seconds       0.0.0.0:6379->6379/tcp   local-redis
```
--nameで指定した名前がNAMESに出力されています。（コンテナの名称）

接続できることを確認します。

```
redis-cli
127.0.0.1:6379> 
```
exitを入力し、終了

redisサーバーが用意できたので、railsのセッションをredisで管理するように変更します。

redisを使うためGemfileにredis-railsを追加します。

```file:Gemfile
gem ‘redis-rails’
```
インストールを行います。

```
bundle install
```

railsのセッションの設定を行います。
config/initializers/session_store.rbにredisにセッション情報を格納することを記載します。
特に何も設定していない場合はsession_store.rbは存在しないので作成します。

```ruby:session_store.rb
Rails.application.config.session_store :redis_store, {
  servers: [
   {
     host: ENV['REDIS_HOST'] || 'localhost',
     port: ENV['REDIS_PORT'] || 6379,
     db: 0,
     namespace: 'session'
   }
  ],
  expire_after: 10.minutes
}
```
これでセッション情報はredisに記録されるようになります。
実際にredisコンテナを停止させてからrailsを起動するとredisに接続できないことによるエラーが発生します。
SafariでCookieを確認しても127.0.0.1のWebサイトの情報はなくなります。

ローカル開発でこれをやると、毎回redisコンテナを起動させないとエラーで落ちてしまうのでなにか自動化は別途しようと思います。
Ruby on Rails スタートライン〜アプリ立ち上げ〜

##開発の道具

- ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-darwin17]
- Rails 5.2.2

##アプリ立ち上げ
ターミナルでコマンド入力

```
$ rails new tweet-app
```
これでtweet-appというフォルダが作成され、フォルダの中にappやらbinやら色んなフォルダが生成されました。

早速、ブラウザで見てみたいと思います。

まずはtweet-appに移動します。（最初の頃はこれがわからずに苦労した）
次にサーバーを立ち上げます。

コマンドは以下の通りです。

```
$ cd tweet-app
$ rails server
```
ブラウザで、http://0.0.0.0:3000/ を開いてください。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/321960/9fe82bc4-da9c-8038-b64c-58e5ba4cb4c9.png)

あれ、、、

原因について調べてみると、どうやらsqlite3のloadにエラーが出ているみたい。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/321960/be4fa0d7-39b3-5330-5637-a029c7603fc4.png)

先ほど生成したtweet-appフォルダの中身(tweet-app/bin)を確認したら、sqlite3が入っておりません。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/321960/c8c5890a-7752-e386-dd4b-d7b35d0a8890.png)
そこでsplite3は手動で導入します。
###sqlite3の導入
以下コマンドでsqlite3がインストールしましょう。

```
$ gem install sqlite3
```

spotliteでsqlite3を検索 。
デベロッパとしてsqlite3がありますので、ドラッグ&ドロップでtweet-appのbinフォルダに移動させます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/321960/f01db7d3-c914-f88f-f205-d6d376c4dfd5.png)
こんな感じでtweet-app/binフォルダの中にsqlite3が導入されました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/321960/c4433f55-fe30-d2f6-c172-e75344bbad1d.png)

###もう一回ブラウザチャレンジ
さあ、これでブラウザで開けるはずです。
http:/0.0.0.0.3000で更新しましょう。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/321960/20db6906-9f45-6834-b7d7-f583393b070f.png)
あれ、、、
まだどこかおかしいようです。

###原因について
このエラーの原因をめっちゃ調べました。

teratailの記事にも同じようなトラブルに見舞われた人がいたようで・・・
https://teratail.com/questions/174121

結論から言うと、
![image.png](https://qiita-image-store.s3.amazonaws.com/0/321960/a8b26f45-7b66-b675-248a-9fc299f79d6f.png)
らしいです。

そこで、tweet-appのGemfileを開き、修正することにします。
これを・・・
![image.png](https://qiita-image-store.s3.amazonaws.com/0/321960/0cb9e1e8-81fb-17cb-929e-f5b46cdc4b46.png)

こう修正
![image.png](https://qiita-image-store.s3.amazonaws.com/0/321960/a1824c23-4e11-4ed8-0a42-3928a55adb2b.png)

で、ターミナルでbundle installします。

ひとつ注意なのが、rails serverを実行しているターミナルではなく、新しくターミナルのウィンドウを開いて、そこから実行してください。

コマンドは以下の通りです。

```
$ cd tweet-app #tweet-appに移動
$ bundle install
```
こうすると、インストールが完了します。

##3度目の正直
できているでしょうか。
Chromeで、http:0.0.0.0:3000にアクセスします。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/321960/0f5f00b0-b66c-fe4c-12cc-c694c9f39c36.png)

無事にできていることが確認できました。
Versionが古くて使い物にならなかったMAAS DockerFile Buildの供養

ちょうどあるから良いかな？と思ったら流石に古くてダメだったので・・・供養
既にDocker環境構築済みであることが前提

https://hub.docker.com/r/ubuntudesign/maas/
https://github.com/ubuntudesign/docker-maas

maasのサーバーのDocker imageが公開されてるのでそれを使います

```
$ git clone https://github.com/ubuntudesign/docker-maas.git
$  cd ./docker-maas/
$ sudo docker build -t ubuntudesign/maas ./
```

maasのDockerFileをビルドします、地味に時間が掛かります
```make build```でもimage buildできるようになってるようですがbzrを使うのが前提になってた上やってることは上記とあまり変わらなくてsudoを使わないのが前提になっていた為今回は自前でbuildします。

```
$ sudo docker run --name maas --tty --interactive --publish 5240:5240 ubuntudesign/maas
```

http：// localhost：5240
では入れます

デフォルトのパスワードなどは usernames: ``` "admin" or "test" password: test ```で使えます
一番新しいVersionでUbuntu 16.04のimageまで使えるみたいなのでそれでもよければ簡単にMAAS Serverがデプロイできるのでどうぞ
日章旗で円周率を求めてみた

Pythonを使って円周率を出すプログラムを作ってみました。
数学に興味を持ってもらうためのツールとしてPythonを活用しました。

```pi.py
#平成も終わりそうなので日章旗で円周率を求めてみた
%matplotlib inline
#玉手箱３つ(matplotlib、random、math)を使う
import matplotlib.pyplot as plt
import random
import math

#dot(点)を0とする
dot = 0
#1万個点を打つ
for i in range(10000):
  #点のx座標は1~100
  x = random.randint(1, 100)
  #点のy座標は1~100
  y = random.randint(1, 100)
  #中心から点までの距離(三平方の定理)
  d = math.sqrt((x-50)**2 + (y-50)**2)
  #もしdが50以下なら
  if (d <= 50):
  #dotに１を足す
    cnt += 1
  #赤色で点を打つ
    plt.scatter(x, y, marker='.', c='r')
  #その他の場合
  else:
  #白色で点を打つ
    plt.scatter(x,y,marker='.', c='w')
plt.axis('equal')
plt.show()

#円周率を求める
p = dot / 10000
pi = p * 4
print(pi)
```
<img width="417" alt="日章旗.png" src="https://qiita-image-store.s3.amazonaws.com/0/271238/fb875edb-1498-022a-5355-7a3236b87095.png">
画面は１台、２台、３台、４台、５台以上？

一人で、画面を１台、２台、３台、４台、５台以上使っている場面を記述します。
5台以上使っている場合で、独特な使い方をされていらっしゃる方のご報告を期待します。
1台はPCオシロにしているとか、１台はHILSで使っているとか。
差し支えない範囲で、PCの性能やOSの版なども付記していただけると幸いです。

# 画面１台
ノートパソコンや、Padを持ち歩いて、出先で作業する場合、画面を２台持ちあるくのは、手間。


# 画面２台

## 2.1 ノートPCとデスクトップ
1台を持ちあるき、１台を固定で使う場合に、コンパイルはデスクトップで、編集かデバッグか実行か、なにかノートでも分担する場合。


## 2.2 PC（ノートまたはデスクトップ）１台（画面付き）ともう１台外付け画面
１画面は編集に、もう１画面はデバッグか実行に。
コンパイルをどちらでさせるかは、速度の速い方。
３年ごとに、安価な機材を購入していると、速い方でコンパイルすれば、古くて遅い方も、いろいろ便利に使える。５年ごとに効果な機材を購入するよりはるかに効率的というのが経験則

## 2.3 PC１台とPADまたはスマフォ
スマフォ、またはPADのソフト開発する場合の最低限の機材。

# 3 画面３台

## 3.1 PC（ノートまたはデスクトップ)１台（画面付き）ともう２台外付け画面
画面１つが基本OS、画面２つめがdockerなど仮想OS、画面３つめが、実行またはデバッグ画面。



## 3.2 PC２台と外付け画面１台
PCが、基本OSともう一つのOSの場合。例えば、WindowsとLinuxとか、WindowsとmacOSとか、macOSとLinuxとか。
外付け画面は、実行またはデバッグ画面として使うか、dockerなどの仮装OSで使う。


## 3.3 PC3台

## 3.4 PC２台とPADまたはスマフォ

Windowsとmac OSで、PADまたはスマフォのアプリを作っている場合。

## 3.5 PC1台とPAD1台、スマフォ１台
PCでウェブ開発していて、PADとスマフォで見え具合を確認している場合。

# 4. 画面４台

## 4.1 PC（ノートまたはデスクトップ)１台（画面付き）ともう3台外付け画面


## 4.2 PC２台と外付け画面2台
WindowsとmacOSのような２つのOSと、それぞれのデバッグ、実行画面。
あるいは、Windows10とWindows8のような２つの版と、それぞれのデバッグ、実行画面。



## 4.3 PC3台と外付け画面1台
Windows, macOS, Linuxの３つのOSと、デバッグ、実行画面１つ。
ディスプレイ切り替え機で、画面を切り替えることあり。
あるいは、Windows 10, Windows 8, Windows7のように一つのOSの三つの版。

## 4.4 PC４台と外付け画面１台
Windows, macOS, Linux, Soralisなどの４つのOS。

## 4.5 PC3台とPADまたはスマフォ

## 4.6 PC２台とPADとスマフォ

## 4.7 PC2台とPAD2台(ipadとandroid)

## 4.8 PC２台とスマフォ2台(iphoneとandroid携帯）

## 4.9 PC１台とスマフォとPADが合計3台。


# 5. 5台以上
以下の組み合わせを含む、さまざまな組み合わせ
## 5.1 PC１台とPAD２台(ipadとandroid)とスマフォ2台(iPhone to
android携帯）
PCでウェブデザインをしていて、PADとスマフォで画面確認している場合。

### 最後までおよみいただきありがとうございました。

いいね　💚、フォローをお願いします。

#### Thank you very much for reading to the last sentence.

Please press the like icon 💚　and follow me for your happy life.
concrete5のレガシーフォームで自動返信メールを設定する

concrete5のフォームブロックでは、標準では自動返信機能はありません。このため問い合わせフォームから送信した方は、『正しく送信されたのか？』と心配になるかもしれません。

##イベント機能を使って自動返信させる
標準では用意されていないものの、自動返信メールを送信できるようにプログラムが作られています。on_form_submissionというイベントが用意されています。(イベントはconcrete5の用語で、プログラム実行の途中で、追加の処理を行うものです。WordPress のアクションフックに似た働きです。)
なので、イベント機能を使って、メール返信を自動化してみました。

##プログラムコード

```php:controller.php
<?php
namespace Concrete\Package\OunziwFormAutoreply;

use Concrete\Core\Package\Package;
use Concrete\Core\Support\Facade\Events;

class Controller extends Package {

    protected $pkgHandle = 'ounziw_form_autoreply';
    protected $appVersionRequired = '8.4';
    protected $pkgVersion = '0.7';

    public function getPackageDescription()
    {
        return t("Auto Reply for Legacy Form");
    }

    public function getPackageName()
    {
        return t("Auto Reply for Legacy Form");
    }


    public function on_start()
    {
        Events::addListener('on_form_submission', function($event) {
            $formEventData = $event->getArgument('formData');
            if (filter_var($formEventData['replyToEmailAddress'],FILTER_VALIDATE_EMAIL)) {
                $mh = $this->app->make('mail');
                $mh->setSubject('自動返信: フォーム送信ありがとうございました。');

                $to_email = $formEventData['replyToEmailAddress'];
                $from_email = 'info@calculator.jp';

                $mailbody = '自動返信: フォーム送信ありがとうございました。' . PHP_EOL;
                $mailbody .= PHP_EOL;
                $mailbody .= '下記の内容を受け取りました。' . PHP_EOL;
                $mailbody .= PHP_EOL;
                foreach($formEventData['questionAnswerPairs'] as $questionAnswerPair){
                    $mailbody .= $questionAnswerPair['question'] . PHP_EOL . $questionAnswerPair['answerDisplay'] . PHP_EOL . PHP_EOL;
                }
                $mailbody .= PHP_EOL;
                $mailbody .= '担当者より、後ほどお返事を差し上げます。今しばらくお待ちくださいませ。' . PHP_EOL;
                $mailbody .= PHP_EOL;
                $mailbody .= '--' . PHP_EOL;
                $mailbody .= '自動計算サイト' . PHP_EOL;
                $mailbody .= 'https://calculator.jp/' . PHP_EOL;
                $mailbody .= 'info@calculator.jp' . PHP_EOL;

                $mh->to($to_email);
                $mh->from($from_email);
                $mh->setBody($mailbody);
                $mh->sendMail();
            } else {
                \Log::addEntry("replyToEmailAddress is empty or invalid.");
            }
        });
    }
}
```

## 自動返信メールの内容の編集
ver.0.7では、controller.phpのon_start()メソッドを編集する。
利用者が多くなれば、管理画面から返信内容を設定できるように改良する予定。

## 活用事例
[自動計算フォーム:運営会社](https://calculator.jp/company)

[マイ見積:問い合わせ](https://my-mitsu.jp/contact)

## githubで公開、MITライセンス
[githubリポジトリはこちら](https://github.com/ounziw/ounziw_form_autoreply)
Swift5で起きているVapor3のLeafに関するバグ

私、おそらく日本で唯一、このバグに困っていると思う（2019/3/30現在）のですがこれからググったりする人向けの記事です。Appleが異例とも言えるこの時期にSwiftのバージョンを５に引き上げました。

Swift5ではrow stringsを使用できるようになっています。
これは文字列の頭と語尾に#" "#と区切ることで文字列を表し、今までのバックスラッシュで変数を当てはめていた処理を、""で記述をできる便利なアップデートです。

この処理がVaporの最も重要な機能であるLeafの扱うタグ機能にエラーを引き起こしていると思われます。#(タグ名) でテンプレートをセットしたり、JavaScriptをLeafファイルの部品として扱うことができないようになっています。

GithubのコミュニティやDiscordの方ではアップデートを急いでいるのでSwift5に対応するのも時間の問題と思いますが、解決するまではXcodeのバージョンを下げてSwift4.2で開発やサーバーの稼働をさせることが無難なようです。

追記：このバグですが解消したようで、以前のvaporプロジェクトでLeafのバージョンが低い場合はターミナルなどのコマンドラインツールで vapor updateすればLeafも更新されてLeafも問題なく機能するようになります。
ミクロ経済学（大学院レベル）の目次

# はじめに

本記事は，私が書いているミクロ経済学（大学院レベル）関係の記事の目次ページです．

基本的に以下の参考文献 Munoz-Garcia（2017）に従って書いています．

Munoz-Garcia, F. (2017) *Advanced Microeconomic Theory: An Intuitive Approach with Examples*. The MIT Press, ISBN: 978-0262035446.

通常，大学院レベルのミクロ経済学では以下のマスコレルとか MWG（筆頭著者の Mas-Colell と共著者の頭文字をとって）とか呼ばれている教科書が使われます．

Mas-Colell, A., Whinston M.D., and Green, J.R. (1995) *Microeconomic Theory*. Oxford University Press, ISBN: 978-0195102680. 

今回 Munoz-Garcia（2017）を採用したのは，本書が MWG と内容的には同レベル（だと思う）で，より最近の本なので MWG と比べて（フォントやデザインなどの出版のテクニカルな部分から例の多さなどの構成などで）色々と読みやすい工夫がされていると判断したからです．ただし，新しい本だからなのか，Munoz-Garcia（2017）は誤植が多かったり図（特に領域を斜線等で表すような図）が見にくかったりするので，買うときはそこら辺に注意しましょう．

ちなみに Munoz-Garcia （本当は n の上にアクセント記号~がつく）も Mas-Colell もスペイン人です．サッカーや料理などでなんとなくスペイン好きな私としては，（全然会ったことないけど）なんか親しみを感じるような…

MWGと同様に…というか大学院で使うようなテキストは分野を問わずそうだと思いますが、分厚い本ですので、まあ飽きなければじっくり数年かけてここにまとめてようかな、とか。
もちろんwebにまとめるとか考えなければもっと早く読める本ですので、MWGに代わる本を探している人は参考までに。

# 目次

1. 選好と効用についての記事
    1. [Preference-based Approach: Introduction](https://qiita.com/kosetasaki/items/0746b6462663e15a538c)
    2. [Preference-based Approach](https://qiita.com/kosetasaki/items/8ed43941271d918436b6)
    3. [合理性を持つ選好と効用関数](https://qiita.com/kosetasaki/items/9dc91d23e3a1792f9a77)
    4. [単調性，強単調性，局所非飽和性](https://qiita.com/kosetasaki/items/d5c8990a9f7f54eee977)
プログラミングの原始衝動を思い出す旅の途中で by 業務経験約4年 Ruby on Rails エンジニア #転職 #ノベル 2019-03-29

# いちど自分が書いたプログラムは、実行前に、査読をすると良い。

セルフコードリーディング。とにかく手を動かす派だと、ついつい省略してしまいがちなステップだが、ここでもコードリーディングにおける禅というか、眼の使い方を養うことが出来る。

# スクリプトやクラスや関数、分割するかどうか迷ったら、まず分割した方が良いと思う派だ。

自分の脳に優しい方を選ぶ。チーム開発の場合、個々人の感じ方や脳の経路も違うので、見方がまるで違う場合は、円集合に合わせる。みんなにやさしいプログラミング。


# shell script は、スクリプト毎に、なにかと役目を分割させて、それぞれの役割を小さく抑えた方が良いな。

良いやり方を探していくと、必然的に Linux 哲学に行き着きそうだ。 stdin / out ではなく log file を input / output の 媒介とする マイベストプラクティスが成長する。

# 世間でまだまだマルチタスクが悪の権化とみなされていないのは、

仕事の余幅を意図的にもたせるためには、むしろそれほど悪くない風潮なのかもしれない。今後シングルタスク教みたいなものがもし出来上がれば、あらゆる横道が封鎖されて、封建社会的なデスクワークさえ出来上がりかねない。社会は誤用に満ちている。


# Zapier は あなたをもっと幸せ Hapier にするという意味でサービス名がつけられたような感じがある。

なかなかハッピーな話だと思った。 It Makes you Happier Zapier. 

# 転職の時、なぜ前職の給与というものが基準になるのだろうなあ。

給与というのは会社全体の儲けに強く依存するというし、個人の資質よりもそちらの影響が強いと聞くのだが。やはり誰もが確かな評価基準を持たないところで、採用の指針になるものなのだろうな。とかく採用や就職の世界は難しい。#e 

# 就職で、前職の給与が基準となる件。たとえば仮の話だが、売上に苦戦する会社で10年間働き、めきめきと実務能力を伸ばしたとしよう。だが給与がまるきり上がらなかったとしよう。その時、その有能な人材の報酬を、前職の給与で決めたりするのだろうか。このことはかねてより疑問であった。


#engineer 

# 自分が望むものは、自ら動かなければ手に入らないという。

受動的に流されてばかりでは、理想は叶えられるのだと。しかしその逆には、縁という考え方もある。ゆるやかなタイミングと、機会と、その波に身を委ねる姿勢とでもいうか。例えば結婚でも、お互いちょうど良いタイミングというものがある。#e 

# まだ本格的に就職活動を始めてもいないのにも関わらず二社からラブコールをいただいた。

QiitaやTwitterやらの威力おそるべし。こう書けばなんとも鼻に付く感じもしなくもないが、たとえ仮に不運続きだろうと僕は事実を淡々と書いただろうから、勝手に引き分け審判としようか。 

# 幸いに仕事先が瞬で決まろうかというにも関わらず、それでふわっと浮かれる感じも微弱であり、なおかつほんの5分も続かない。

少し寂しくもあるが良い傾向だ。僕は良いネガテイブを信条としており、前職でもほぼ4年間、ストーリー着手のたびに、まず自分には無理だろうと、最初には思う連続であった。#e 

# しかし問題はこのようなアイデンティティ問題ではなくいかに良い仕事ができるかということである。

長く組織にいると意識が埋没して見えにくくなる部分でもあろうから、この機会に見直したい。今後仮にひとつの組織で長く働くにしても、そうでないにしても、責任には緊張感を。取引関係、契約関係。#e

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/987








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
swi-prologで形態素解析

文章を、jumanで形態素解析し、名詞を取り出す。jumanの場合、カテゴリ情報を追加している場合があるので、重要な要素なので、それも付加する。

```prolog:juman.swi
%% 
%% 文章から名詞のキーワード取得
%% jumanのカテゴリ情報を付加する
%% 

%% TOP述語
keywords(String) :- juman(String,Lines),
        getkeys(Lines,List),
        write(List),!.

%% 再帰処理の終了条件
%% 最後は、Aが'EOS'のatomになっているはず
getkeys(A,[]) :- atom(A).
%% 念のために、空リストの場合も終わらせる
getkeys([],[]).

%% 本体、再帰的処理、splitはstringを返すので、名詞は、"名詞"でなければならない
%% stringは、swi-prologの拡張概念
%% split_string, nth1はswi-prologの拡張述語 manual参照
%% 名詞語を取得、カテゴリがある場合は付加する
getkeys(Lines,[Word|List]) :- [H|T]=Lines,
        split_string(H,' ',' "',P),
        nth1(1,P,A),
        nth1(4,P,"名詞"),
        getsublist(12,P,E),
        getcategory(E,C),
        %% ストリームの代わりにatom に書き込む swi-prologの拡張述語
        format(atom(Word),'~s:~s',[A, C]),
        getkeys(T,List),!.
%% カテゴリがない場合（上がどこかで失敗するので）
getkeys(Lines,[Word|List]) :- [H|T]=Lines,
        split_string(H,' ',' ',P),
        nth1(4,P,"名詞"),
        nth1(1,P,Word),
        getkeys(T,List).
%% 名詞でない場合、ただ次を調べる
getkeys(Lines,List) :- [_|T]=Lines,
        getkeys(T,List).

%% 名詞の場合、カテゴリがついている可能性があるのでそれを取得する
%% カテゴリがリスト冒頭に見つかる
getcategory([H|_],C) :- split_string(H,':',':',P),
        nth1(1,P,"カテゴリ"),
        nth1(2,P,C),!.
%% 見つからなかったら、後尾を調べる
getcategory([_|T],C) :- getcategory(T,C).

%% I番目以降の要素でサブリストを作る builtinに見つからなかったので作成
%% 再帰の終了条件。インデクスIがリストLの長さを超えたら空をつなげて終わりにする
getsublist(I,L,[]) :- J is I-1,length(L,J),!.
%% 要素を再帰的につなげていく
getsublist(I,L,[A|S]) :- nth1(I,L,A),J is I+1,getsublist(J,L,S).

%%
%% juman 形態素解析実行
%% http://www.ibot.co.jp/wpibot/?p=2693 で解説済み
%% jumanを実行可能なパス上に置いておく
%%
juman(String, Lines) :-
        setup_call_cleanup(
            process_create(path(juman), [  ],
                [ stdout(pipe(Out)), stdin(pipe(In))
                ]),
            proc_stream(In, Out, String, Lines),
            close(Out)).

proc_stream(In, Out, String, Lines) :-
        write(In,String),
        close(In),
        read_line_to_codes(Out, Line1),
        read_morpheme(Line1, Out, Lines).

read_morpheme(end_of_file, _, []) :- !.
read_morpheme(Codes, Out, [Line|Lines]) :-
        atom_codes(Line, Codes),
        read_line_to_codes(Out, Line2),
        read_morpheme(Line2, Out, Lines).
```

実行例は次の通り。


```prolog
?- ['juman.swi'].
true.

?- keywords('今日は良い天気ですね').
[今日:時間,天気:抽象物]
true.


```
VSCode + Vim で IME コントロール

VSCode の Vim プラグインに，[Input Method (Disable input method when exiting Insert Mode.)](https://github.com/VSCodeVim/Vim#input-method) という設定があるのを見つけました。

fcitx を使っている環境では，次のようにすると，NORMAL モードになるときに IM を off にしてくれました。

```json:settings.json
"vim.autoSwitchInputMethod.enable": true,
"vim.autoSwitchInputMethod.obtainIMCmd": "/usr/bin/fcitx-remote",
"vim.autoSwitchInputMethod.switchIMCmd": "/usr/bin/fcitx-remote {im}",
"vim.autoSwitchInputMethod.defaultIM": "-c"
```
[Gmail to LINE]GASで新着メールをLINEに転送する

#やりたいこと
Gmail　→　LINE
3月末でIFTTTでGmailがサポート終了となるため、Gmailを転送する機能が使えなくなったので、応急処置として。
調べるとGAS使えばすぐできるみたいなので早速やってみた。

1.　GAS(Google App Script)でGmailの新着メールを取得
2.　LINEに転送
3.　一定の時間が立つと1～2を繰り返す

#準備
- LINE NotifyのToken(lineToken)を発行し、コードに貼り付ける。
- 転送間隔（get_interval）を設定し、GASのトリガーをこれに合わせる

![image.png](https://qiita-image-store.s3.amazonaws.com/0/272825/dd5e6fa4-559d-a79a-b92c-565f774ca453.png)


# コード
``` Gmail_to_LINE.js
var lineToken = "ABC"; //LINE notify token
var get_interval = 30; //〇分前～現在の新着メールを取得 #--トリガーをこれに合わせておく！！


function send_line(Me){
  var payload = {'message' :   Me};
  var options ={
        "method"  : "post",
        "payload" : payload,
        "headers" : {"Authorization" : "Bearer "+ lineToken}  
      };
    UrlFetchApp.fetch("https://notify-api.line.me/api/notify", options);
}


function fetchContactMail() {
  //取得間隔
  var now_time= Math.floor(new Date().getTime() / 1000) ;//現在時刻を変換
  var time_term = now_time - (60 * get_interval); //変換

  //検索条件指定
  var strTerms = '(is:unread after:'+ time_term + ')';
 
  //取得
  var myThreads = GmailApp.search(strTerms);
  var myMsgs = GmailApp.getMessagesForThreads(myThreads);
  var valMsgs = [];
  for(var i = 0; i < myMsgs.length;i++){
    valMsgs[i] = "\n【date】: " + myMsgs[i].slice(-1)[0].getDate()　
                  + "\n【From】: " + myMsgs[i].slice(-1)[0].getFrom()
                  + "\n【Subject】: " + myMsgs[i].slice(-1)[0].getSubject()
                  + "\n【Body】: \n" + myMsgs[i].slice(-1)[0].getPlainBody().slice(0,200); 
  //  myMsgs[i].markRead(); //メッセージを既読にする
  }
    
  return valMsgs;
  
}

function main() {
  new_Me = fetchContactMail()
  if(new_Me.length > 0){
    for(var i = new_Me.length-1; i >= 0; i--){
      send_line(new_Me[i])
    }
  }
}

```


#参考URL
https://developers.google.com/apps-script/reference/gmail/gmail-app#search(String,Integer,Integer)
https://tonari-it.com/gas-add-contact-mail/
https://qiita.com/3mc/items/39b2c8241c6b52811ad2
PythonでFizzBuzz

# PythonでFizzBuzz

## FizzBuzzとは？
数字が3で割り切れると `Fizz`
数字が5で割り切れると `Buzz`
数字が3でも5でも割り切れると `FizzBuzz`
上記以外の場合は、そのまま数値を出す
(本来は、海外の言葉遊びらしいです。[wiki参照](https://ja.wikipedia.org/wiki/Fizz_Buzz)

## PythonでFizzBuzzやってみる。
普通にやると

```:python
def FizzBuzz(x):
    if x % 3 == 0 and x % 5 == 0:
        return "FizzBuzz"
    if x % 3 == 0:
        return "Fizz"
    if x % 5 == 0:
        return "Buzz"
    return x
```

こんな感じでしょうか

ちょっと変わった感じに書いてみる

```:python3
def fizbuz(num):
    try:
        dic = {(True, True): "FizzBuzz", (True, False): "Fizz", (False, True): "Buzz"}
        return dic[num%3==0, num%5==0]
    except:
        return num
```

いかがでしょうか？

後者ではif文がありません。

いろんなアプローチがあると思うので、是非皆さんも考えてみてください:point_up:
ConoHa VPS(CentOS7)+Flask+Nginx+uWSGIでWEBアプリを作ってみる(2)

[ConoHa VPS(CentOS7)+Flask+Nginx+uWSGIでWEBアプリを作ってみる(1)](https://qiita.com/shikao_yuzu/items/ddfaf2c8bd47f098a464)
の続き。

Nginx+uWSGIを使って本番環境で動かしてみます。
以下を参考にしました。

- [Flask + uWSGI + Nginx でハローワールドするまで @ さくらのVPS (CentOS 6.6)](https://qiita.com/morinokami/items/e0efb2ae2aa04a1b148b)
- [Flask+Nginx+uWSGI+CentOS7でアプリケーションを作る際にやったこと+日記::12/9](https://fgjiutx.hatenablog.com/entry/2018/12/10/013755)
- [便利で超強力なWSGIサーバー uWSGI を使ってみよう](http://m-hiyama.hatenablog.com/entry/20120312/1331513519)

# 1. ドメイン取得

とりあえずドメインを取得します。

[お名前.com](https://www.onamae.com/)とか[Google Domains](https://domains.google/)からドメインは取れます。
無料だったら[Freenom](https://www.freenom.com/ja/index.html)というサービスがあるようです。

参考
- [freenomでドメインの取得](https://qiita.com/hanbaga324/items/da0c4f6fa8d365db10c9)
- [無料のドメインを取得する](https://qiita.com/teekay/items/135dc67e39f24997019e)
- [freenom で取得した無料ドメインを ConoHa の VPS に登録する](https://walkingmask.hatenablog.com/entry/2017/12/05/154722)

# 2. uWSGIとは

まず，WSGI(Web Server Gateway Interface; ウィズギーと読むらしい)とは，Pythonで実装されたWebアプリケーションとWebサーバ間のインターフェースを規定した仕様([PEP333](https://www.python.org/dev/peps/pep-0333/))です。uWSGIは，既存のWebサーバ(Nginxなど)にWSGI仕様を付加し，WSGIに対応したWebサーバを作成します。つまり，

```
[WSGIに対応したWebサーバ] = Nginx + uWSGI
```

といった関係になっている(と思われます)。

# 3. uWSGIの設定

uWSGIの設定ファイルを作成します。設定ファイル名は何でもよいですがuwsgi.iniとしておきます。
なお，デーモン化するためにdaemonizeを指定しています。

```uwsgi.ini
[uwsgi]
module = app
socket = /home/{ユーザ名}/app/uwsgi.sock
chmod-socket = 666
callable = app
uid = {ユーザ名}
gid = {ユーザ名}
daemonize = /home/{ユーザ名}/uwsgi/uwsgi.log
pidfile = /home/{ユーザ名}/uwsgi/app.pid
```
socket, daemonize, pidfileのパスはpermissionが問題なければどこでも良いと思います。

# 4. Nginxの設定

Nginxの設定ファイルは/etc/nginx/conf.d/に拡張子confで置けば勝手に読み込まれるので，名前をapp.confとして次のように作成します。

```app.conf
server {
    listen 80;
    server_name {取得したドメイン};
    charset utf-8;
    client_max_body_size 75M;

    location / { try_files $uri @myapp; }
    location @myapp {
            include uwsgi_params;
            uwsgi_pass unix:///home/{ユーザ名}/app/uwsgi.sock;
    }
}
```

これで，Nginxを再起動すればいけるはずですが，permissionエラーになってしまいました。どうやら，Nginxがユーザnginxで実行されていることが原因のようだったので，以下のように5行目をコメントアウトして{ユーザ名}で実行するように設定を変更しました。

```/etc/nginx/nginx.conf
# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

#user nginx;
user {ユーザ名};
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
```

参考
[Unicorn x Nginx x AWS で、*11 connect() to unix:/home/ec2-user/app/current/tmp/sockets/unicorn.sock failed (13: Permission denied) while connecting to upstream のエラーの回避方法](https://qiita.com/okitsutakatomo/items/d98e3f4e9120c622ac44)

# 5. サーバの起動

ここまでくれば，以下の手順でサーバを起動できるはずです。

```
$ cd /home/{ユーザ名}/app
$ systemctl restart nginx
$ source env/bin/activate
(env) $ uwsgi --ini uwsgi.ini
```

http://{取得したドメイン}にアクセスできれば成功です。
停止する場合は以下のようにします。

```
$ cd /home/{ユーザ名}/app
$ source env/bin/activate 
(env) $ uwsgi --stop /home/{ユーザ名}/uwsgi/app.pid
(env) $ deactivate
$ systemctl stop nginx
```

おわり。
17日目: Empirical Study and Improvement on Deep Transfer Learning for Human Activity Recognition

# Empirical Study and Improvement on Deep Transfer Learning for Human Activity Recognition 要約
## 読んだ論文
Empirical Study and Improvement on Deep Transfer Learning for Human Activity Recognition
Renjie Ding, Xue Li, Lanshun Nie, Jiazhen Li, Xiandong Si, Dianhui Chu, Guozhong Liu, Dechen Zhan
https://www.mdpi.com/1424-8220/19/1/57

上記の論文を読んだので簡単にまとめます．本当は[Deep Transfer Learning for Cross-domain Activity Recognition](https://arxiv.org/abs/1807.07963)を読もうと思ったのですが，これを引用して本稿が最新だったのでこちらを読むことにしました．Sensors MDPIのJournal Paperです．

## 3行でまとめる
- 教師なしの深層転移学習な手法を色々実践してみたよ．
- 比較した結果MMDが良かったよ．

## 本稿の貢献
1. 教師なしの深層転移学習手法を大規模に実践した初めての論文である．広く一般的に使われる手法を検証しMMDが良く働いたことを示した．
2. CNNで抽出された特徴を分析し，同じクラス内の分布は広く，他クラスとの分布は小さいという傾向があり，これが転移に影響を及ぼしている．
3. 特徴分布を改善することが役立つと検証すべく，MMDとCenter Lossを組み合わせ，2の傾向の改善に取り組んだ．この改善が教師なし転移に役立つ．

## 検証した手法
### MMD 
そろそろおなじみになってきたMMD (Maximum Mean Discrepancy)です．MMDは[10日目のDomain Separation Networks](https://qiita.com/himatya/items/353b5ccc66ea8c5c19b4)，16日目の[Unsupervised Domain Adaptation with Residual Transfer Networks](https://qiita.com/himatya/items/8d22e9dd1a71c4878026)でも紹介しています．
$MMD[F, p, q]:=sup_{f \in F}(E_p[f(x)]-E_q[f(y)])$
MMDでは，上式でpとqの分布が同一かを判定する（0だと同一だとみなす）．実践的には実際は次式が用いられる．
$MMD[F, X, Y]=sup_{f \in F}(\frac{1}{m}\sum_{i=1}^{m}f(x_i) - \frac{1}{n}\sum_{j=1}^{n}f(y_j))$
深層学習によって得られる特徴表現について，ターゲットソース間での不一致度合を最小化することで同じ表現形式を学習しようとする方法である．なお今回はMK-MMDを採用しているらしい（後で書かれていた）．

### DANN
こちらもそろそろおなじみのDANN ()です．DANNは[11日目のDomain-Adversarial Training of Neural Networks](https://qiita.com/himatya/items/17dcae2c770c5b89c63b)で原典を読んでいます，
詳細な説明は上記引用先に任せますが，簡単に言うと，ソースドメインを単純に訓練する損失と，ソースとターゲットを見分ける弁別器の損失を合わせて学習することで敵対的学習によりソースターゲット間で共通する表現を学習するという手法です．

### WD
こちらだけ初見の手法，WD (Wasserstein Distance)です．WDは確率分布間の距離を計算する手法らしく，以下の式で定義されます．
![20190329_001.png](https://qiita-image-store.s3.amazonaws.com/0/376859/8a1b33b3-bfed-6b8a-ad80-57745a996421.png)

$\Pi (P_r,P_g)$は(x,y)の同時確率分布の集合を示す．そこから$\gamma$を選択し，(x,y)が$\gamma$に従う際の||x-y||の期待値を算出する．この時の最小期待値がWDとなる．

## 評価実験
### データセット
UCI dailyとSports，UCI-HADの三つを使用した．HADの方はエレベータの上り下りがほぼ同一なのでこれは結合して使用した．
今回はユーザ間のTransferが目的なので，ターゲットユーザに対する推定精度が評価指標となる．全員を使ってるときりがないのでランダムに選んだ数人に対して実施した．まずソースユーザたちからは2/3のラベルありデータを訓練に使用し，ターゲットユーザからは2/3のラベルなしデータを適応に使用し，残り1/3をテストに使用した．なお20000エポック中の最高精度を採用している．
![20190329_002.png](https://qiita-image-store.s3.amazonaws.com/0/376859/1a19f081-47f6-9f82-02a4-48a1c584e528.png)

最終的にTable4の結果となり，平均的にMMDが優秀であることを示した．あおTable5にはターゲットドメインの適応データを1/3に減らした評価結果も載っている（が，原典をご覧くださいませ）．

この後，各クラスが中央に寄るような損失関数を追加で定義して検証を行っているが，疲れたのでここまでにします．

## まとめ
- 教師なしのドメイン適応手法を行動認識における**ユーザ適応**に使用した（多分初めての）論文．
- 最近よく使われるベーシックなドメイン適応手法を検証されていて，引用元にするにはいい感じに思います．
- 一方で，個人→個人の転移のみに焦点を当てていたので，不特定多数→個人の検証が気になりました．

## 所管
今回は論文選定に時間を取りませんでしたが，読むのに1時間半くらいかかりました．ユーザ適応にディープな手法を使うというのは，自分で先駆けてやりたかったのですが，すでにやられていました．残念．ただ差別化するような検討はいくつかできそうかなという印象も受けました．良論文だったと思います．
metabaseを別サーバーに移行する

## はじめに
先日、metabase（構築したのは自分ではない）を別サーバーに移行することがありました。

既存環境にて登録済みのユーザーやクエリを別サーバーに移行する点で、
いまいちそれっぽい情報が見つからず、手間取ったので手順を書いておきます。

## やりたいこと
- metabaseを別サーバーに移行する
- 移行対象はmetabaseに登録してあるユーザー情報とクエリなど諸々の設定

## 前提など
公式のdocker imageを使用して、既存環境が構築されている
（それ以外の環境の場合は、やることとしては大体一緒かもしれませんが調べてないので不明です）

公式が書いた下記の記事を参考にして進めています。
[metabase: "Running Metabase on Docker"](https://www.metabase.com/docs/latest/operations-guide/running-metabase-on-docker.html#mounting-a-mapped-file-storage-volume) > Mounting a mapped file storage volumeの箇所



## ざっくり手順
1. 設定ファイルが格納されているディレクトリをコンテナから引っこ抜く（デフォルトは`/metabase.db`）
2. 移行先のサーバーに1.で抜いた設定ファイルが格納されているディレクトリを置き、
 `docker run -v`などでマウントしてmetabaseを起動する
3. 起動後は必要に応じて、参照するDBの向き先を変更する

## 手順

#### 1. 設定ファイルが格納されているディレクトリを引っこ抜く

まずマウントされているか確認

```bash:
// マウントされていたらホスト側に設定ファイルが入ったディレクトリがあるはずなので、そのディレクトリを移行先に持っていく。
// 仮に、記事通りのコマンドで、マウントして起動されていた場合、`docker inspect ~~~` を叩くと下記の通りになる
$ docker run -d -p 3000:3000 -v ~/metabase-data:/metabase-data -e "MB_DB_FILE=/metabase-data/metabase.db" --name metabase metabase/metabase
$ docker inspect metabaseのコンテナID |grep -E "Source|Destination"
                "Source": "/metabase-data", // ホスト側
                "Destination": "/metabase-data",　// コンテナ側
```

マウントしていない場合、デフォルトではルート直下にmetabase.dbというディレクトリがあるので、このディレクトリをホスト側にコピーする

```bash:マウントせずにコンテナを立ち上げてみた場合こうなります
$ docker run -d -p 3000:3000 --name metabase metabase/metabase
// ルートにmetabase.dbというディレクトリが確認できる
$ docker container exec -ti metabase ls /metabase.db
metabase.db.mv.db     metabase.db.trace.db
```

```bash:ホスト側にコピーするコマンドはこれ(一応)
$ docker cp metabase:/metabase.db .
$ tree
.
└── metabase.db
    ├── metabase.db.mv.db
    └── metabase.db.trace.db
```





#### 2. 移行先でmetabaseを起動する
あとは移行先の任意のディレクトリにmetabase.dbを配置して、下記のコマンドが動くようマウントしてコンテナを立ち上げる

```bash
$ docker run -d -p 3000:3000 -v ~/metabase-data:/metabase-data -e "MB_DB_FILE=/metabase-data/metabase.db" --name metabase metabase/metabase
```

記事のコマンド通りにするなら、
あらかじめ下記のように、~/metabase-dataの下にmetabase.dbを置くディレクトリ構成にし、metabase-detaをマウントする

```bash
$ tree -a ~/metabase-data
metabase-data
└── metabase.db
    ├── metabase.db.mv.db
    └── metabase.db.trace.db
```

#### 3. 起動後
- 移行前のmetabaseから参照先のDBが変わっていないのであれば、動作確認して終わり
- ステージングから本番へ、ユーザーやクエリだけ移動するようなケースであれば向き先のDBを変更して終わり
Python3でWindowsの壁紙を変更する

#環境
* Windows 10
* Python3.7.1 (Anaconda)

#方法
　お馴染みのctypesを使う．絶対パス指定じゃないと上手くいかなかったので注意．

```python
import ctypes

ctypes.windll.user32.SystemParametersInfoW(20, 0, "画像ファイルの絶対パス" , 0)
```
　デュアルモニタなので不安だったが普通に動いた．

#ちなみに
　Pythonのバージョン(2系 or 3系）によって関数名が違う．文字の扱いがバージョンによって違うからだと思う．
　Python3系は`SystemParametersInfoW`で動作したが，Python2系の場合も`SystemParametersInfoA`に名前を一文字変えるだけで使えるっぽい(未確認)．

#参考
[stack overflow : Creating a background changer in python with ctypes, not working](https://stackoverflow.com/questions/21715895/creating-a-background-changer-in-python-with-ctypes-not-working)
Google Apps Script でクラスの継承を行う

# 概要
Google Apps Script で親クラスを継承した子クラスを作成するためのメモ。
Google Apps Script は ES6 非対応のため Object.setPrototypeOf() などが使用できない。

# 方法
Object.setPrototypeOf() の代わりに継承用の関数を作成して使用する。

## 継承用の関数を作成

```javascript:inherits
function inherits(ctor, superCtor) {
  
  ctor.super_ = superCtor;
  
  ctor.prototype = Object.create(superCtor.prototype, {
    
    constructor: {
      
      value: ctor,
      enumerable: false,
      writable: true,
      configurable: true
      
    }
    
  });
  
}
```

## クラスの作成と継承

```javascript:class
function parentClass(arg){
  
  /* コンストラクタ */
  
}

function childClass(arg){
  
  parentClass.call(this, arg); // 親クラスのコンストラクタを呼び出す
  
}

inherits(childClass, parentClass); // prototype を継承
```

# コード例
```javascript:test
function inherits(ctor, superCtor) {
  
  ctor.super_ = superCtor;
  
  ctor.prototype = Object.create(superCtor.prototype, {
    
    constructor: {
      
      value: ctor,
      enumerable: false,
      writable: true,
      configurable: true
      
    }
    
  });
  
}

function test(){
  
  function parentClass(arg){
    
    this.property1 = arg;
    
  }
  
  parentClass.prototype.property2 = 'fuga';
  
  function childClass(arg){
    
    parentClass.call(this, arg);
    
  }
  
  inherits(childClass, parentClass);
  
  var instance = new childClass('hoge');
  
  Logger.log(instance.property1); // 'hoge'
  Logger.log(instance.property2); // 'fuga'
  
}
```

# 参考
[ES5なJavascriptでモダンなクラス的継承＆スーパー呼び出し](https://qiita.com/no22@github/items/d3bead2acbb7ff1fb86b)
[Google流 JavaScript におけるクラス定義の実現方法](https://www.yunabe.jp/docs/javascript_class_in_google.html)
Ansibleで対象ディレクトリ配下のファイルを一括操作するメモ

#はじめに
この記事ではAnsibleを使って対象ディレクトリ配下の複数ファイルをまとめて操作する方法を紹介します。

#実行環境
Ansible 2.7
クライアント側OS：Linux

#概要
1. findコマンドで対象ディレクトリ配下のファイル名一覧を取得。
2. Ansibleのwith_linesに一覧を渡してファイル毎に操作。
 
#サンプル
改行コードをCRLFからLFに一括変換してみます。

・クライアント側ディレクトリ構成

    /home/user/sample
                 |---aaa
                 |    |---a.txt
                 |    |---bbb
                 |         |---b.txt
                 |---ccc
                      |---c.txt
・Ansibleのロール

```yml:main.yml
- name: convert CRLF to LF
  replace:
    path: '{{ item }}'
    regexp: '\r'
  with_lines: find /home/user/sample/* -type f
```

・実行結果

```terminal:
TASK [main : replace] 
changed: [localhost] => (item=/home/user/sample/aaa/bbb/b.txt)
changed: [localhost] => (item=/home/user/sample/aaa/a.txt)
changed: [localhost] => (item=/home/user/sample/ccc/c.txt)
```
`with_fileglob: /home/user/sample/*` では再帰的に処理してくれないので注意。

#参考
 https://docs.ansible.com/ansible/latest/plugins/lookup/lines.html
ブラウザ拡張でのidle.onStateChangedの実行タイミングがWindows10でのみ異なる件

# `idle.onStateChanged`とは

ブラウザの拡張機能で使用できる `idle` というAPIがあります。

[chrome.idle - Google Chrome](https://developers.chrome.com/apps/idle)

私はChromeでしか試していないですが、一応、Firefoxなどでも実装されているみたいです。

[idle - Mozilla | MDN](https://developer.mozilla.org/ja/docs/Mozilla/Add-ons/WebExtensions/API/idle)

OSがスクリーンロック（Macだと`⌘+Control+Q`、Windowsだと`Win+L`）になったり、
一定時間操作が無かったかなどを取得できるAPIです。

## サンプルコード

```
chrome.idle.onStateChanged.addListener((newState) => {
    // newState "active", "idle", or "locked"
});
```
`onStateChanged` というイベントにCallbackを指定することで、
状態変化時にコードを実行することができます。

## 用途

用途は様々に考えられますが、例えば、チャットのような拡張機能を作ったのであれば、
一定期間何も操作されていなかったり、スクリーンロックされたら離席状態にする、というような機能に使えます。

# 本題：Windows10における問題

Mac、Windows7、Windows10で動作するChrome Extensionを作った際に発覚した問題として、
Mac、Windows7においては、スクリーンロックの操作（ショートカットキーを押したり、メニューからロックを選んだり）した段階で、`chrome.idle.onStateChanged`のイベントは実行されます。

## 問題点

**しかし、Windows10においては、スクリーンロックの操作を行った時点では `chrome.idle.onStateChanged` のイベントが実行されません。**

Windows10からは、スクリーンロック操作を行った時点でロックスクリーン（綺麗な壁紙に日時が表示されているアレ）が表示されますが、
この時点では`onStateChanged`イベントは発生せず、
任意のキーを押すなどしてログイン画面を表示した時点で`onStateChanged`イベントが発生します。

## バグ報告

一応、この現象はChromiumのForumにもバグとして報告されているみたいですが…
https://bugs.chromium.org/p/chromium/issues/detail?id=524663

個人的には、

* Chrome側は「OSの通知してくるスクリーンロックのイベントを拾ってるだけだから仕様です」
* Windows側は「即イベントを発生しないのは仕様です」

…って言いそうな気がするので、OS・ブラウザ側のバージョンアップでは対応されないのではないかと予測しています。

# 対応方法

上記の通り、恐らくこの動作は「仕様」であるため完全に対応することはできません。
しかし、Windows10側の設定を変更し、ロックスクリーンを無効にすることでWindows7と同じ挙動にすることが可能です。

## ロックスクリーンを無効にする方法

以下のサイトに手順がまとめられています。

[Windows10でロック画面を無効または有効にする方法 – iBitzEdge](https://i-bitzedge.com/tips/how-to-lock-screen-enable-or-disable-on-windows-10)

いくつかの方法がありますが、今回、私の場合はWindows10 Homeだったため、
レジストリエディタで値を追加することを選択しました。

また、対象のPCが複数台あったため、バッチファイルを作成し対応しました。

## ロックスクリーンを無効にするコマンド

```
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\Personalization" /v NoLockScreen /t REG_DWORD /d 1 /f
```

上記を記述したバッチファイルを作成し、
PC上でバッチファイルを「管理者として実行」することで、レジストリに書き込まれます。

なお、管理者として実行しなかった場合は、「エラー: アクセスが拒否されました。」と表示されます。

# おまけ：他に考えたけど採用しなかった対応方法

## 一定時間で`active`から`idle`になったら`locked`と同じ状態として扱う

`chrome.idle.setDetectionInterval()`で`idle`になるまでの秒数を設定することができるので、
ある程度はこの方法でもまかなえるかと思います。

ただ、今回の要件では、どうしてもロック時で正確に状態を取りたかったので採用しませんでした。

## WindowsAPIを直接使ってどうにかする

昔はExtensionでDLLを使ったりできたので可能だったかもしれませんが…今は不可能なので諦めました。
Electronアプリで構築していた場合などは、もしかすると可能かもしれません。

詳しくどのAPIを使えば良いのかなどは調べていないので、本当に可能かどうかは不明です。
Rubyでソートアルゴリズム

# 0.概要
ソートについて色々と調べた上で、クイックソートとヒープソートを実装した。

# 1.クイックソート
ピボットを基準として、値の大小で2つに分割していく方法。
O(n log n)で計算でき、他のソートと比べると高速なソート法。
ただし、データの並びやデータの数によって計算量が変化する。最悪計算量はO(n**2)となる。

実装は以下の通り。

```ruby:quick_sort.rb
class Array
  def quick_sort
    return self if size <= 1
    pivot = choice_pivot
    smallers, biggers = partition { |item| item < pivot }
    push(pivot)
    smallers.quick_sort.concat([pivot]).concat(biggers.quick_sort)
  end

  def choice_pivot
    self[0] >= self[1] ? delete_at(0) : delete_at(1)
  end
end
```

ピボットの選択によって計算量が変わるらしく、今回は2つの数値からより大きいものをピボットにした。

# 2.ヒープソート
ヒープという木構造を構築すると、必ず根が最大の値になる。
これを利用してソートしていくのがヒープソート。
あまり実装例を見かけないので、チャレンジという意味も込めて試してみた。

実装は以下の通り。

```ruby:heap_sort.rb
class Array
  def build_heap(arr)
    parent = (arr.length - 1) / 2
    node_cnt = parent

    until node_cnt < 0
      l_child = 2 * parent + 1
      r_child = l_child + 1

      if arr[r_child] && arr[r_child] >= arr[l_child] && arr[r_child] > arr[parent]
          arr.swap!(r_child, parent)
          parent = r_child
      elsif arr[l_child] && arr[l_child] > arr[parent]
          arr.swap!(l_child, parent)
          parent = l_child
      else
        node_cnt -= 1
        parent = node_cnt
      end
    end
    arr
  end

  def swap!(a, b)
    self[a], self[b] = self[b], self[a]
  end

  def heap_sort
    arr = self.dup
    res = []
    until arr.empty?
      heap = build_heap(arr)
      heap.swap!(-1, 0)
      res.unshift(heap.delete_at(-1))
    end
    res
  end
end
```

# 3.実行速度について
実行速度を測りたいという意図もあり、以下のテストコードを書いた。

```ruby:quick_sort_test.rb
class QuickSortTest < Minitest::Test
  def setup
    num = 10000
    @arr = []
    num.times { @arr << rand(num)  }
  end

  def test_quick_sort
    assert_equal @arr.quick_sort, @arr.sort
    run_time = Benchmark.realtime { @arr.quick_sort }
    p run_time
  end
end
```

```ruby:heap_sort_test.rb
class HeapSortTest < Minitest::Test
  def setup
    num = 10000
    @arr = []
    num.times { @arr << rand(num)  }
  end

  def test_quick_sort
    assert_equal @arr.heap_sort, @arr.sort
    run_time = Benchmark.realtime { @arr.heap_sort }
    p run_time
  end
end
```

結果は以下の通り。

クイックソート　0.029008000157773495
ヒープソート　4.9474329999648035

圧倒的にクイックソートのほうが速い...
ヒープソートも書き方を変えたらもっと速くなるのだろうか。

# 4.終わりに

アルゴリズムはほぼ未学習の状態だったので、よい勉強になった。
【初心者】Androidアーキテクチャの種類メモ

※知識ゼロの大学生が勉強会に参加してよくわからなかった単語を覚えておくために書き留めるためのメモです。もし、ここは違うぞ！というような箇所があればぜひ教えてください！:bow:

***

この前、DroidKaigi2019の報告会のイベントに行ってきました！その中で、スピーカーさんたちのLTで多くでできたキーワードの一つが「アーキテクチャ」だったので、初心者なりにメモしました。:relaxed:

# Androidアーキテクチャの紹介と流行り

Androidのアプリ開発にもにはアーキテクチャの選択肢がたくさんありますが、DroidKaigiでも毎年アーキテクチャがキーワードに上がり続けているほど、アーキテクチャには正解がなく改善し続けるもののようです。

以下は、アーキテクチャの種類メモです。

- MVP(model view presenter)
    - 描画と画面のふるまいとロジックに分けるアーキテクチャ
- MVVM
    - 描画と画面保持と入力の変換とロジックにわけるアーキテクチャ
- Redux(flux)
    - データフローに関するアーキテクチャ
- MVI
    - Reduxの思想をMV○○に持ち込んだアーキテクチャ
- clean architecture
    - システムを層に分割し方針と詳細を分割するためのアーキテクチャ

MV○○系とflux系とclean architecture系統で分けられるのかな？
まあ一つのアプリに様々なアーキテクチャが混在してしまったときの対策になりうるマルチモジュールというのもあるそう。
    
公式アプリで使われているアーキテクチャはこのようになっているようです。
2017年：MVVM
2018年：AACベースMVVM
2019年：AACベースMVVM ＋ Flux

スピーカーさんによると、アプリはWebの拡張ではなくなってきており、androidの進化とアプリの複雑化によりアーキテクチャは今後も変わり続けるだろうとのことです。

javaを勉強してもっとアプリ開発をしてみれば今回の話ももう少し理解できるかなあ。勉強頑張ります！
生まれて初めてGitHubのOSSにプルリクエストを通した話

正直n番煎じな内容なのですが，自分用のメモとして残しておきます．

# OSSとは
> オープンソースソフトウェア（英: Open Source Software、略称: OSS）とは、利用者の目的を問わずソースコードを使用、調査、再利用、修正、拡張、再配布が可能なソフトウェアの総称である [https://ja.wikipedia.org/wiki/オープンソースソフトウェア]

GolangやKotlinなどのプログラミング言語をはじめとして，Visual Studio CodeのようなエディタもOSSとして流布されています．また，多くのOSSがGithub上で管理されています．

# OSSの開発に貢献するための手順
今回実際に通したPR(プルリクエスト)はこちらになります．株式会社ロックオン様が開発しているECサイトのOSSです．
CSS一行を書き換えただけの簡単な編集しかしていません．

https://github.com/EC-CUBE/ec-cube/pull/4123

## OSSの開発ドキュメントを読む
OSSは不特定多数に人が自由に編集し，ソースコードの追加・修正が行われていきます．
そのため，命名規則やディレクトリ構成などがあらかじめ策定されていることが多いです．編集を始める前にドキュメントを一読しておきましょう

## issueを探す 
現時点での不具合や追加すべき機能などがGithubのissuesで挙げられ，各エンジニアが議論します． 
issueは解決の優先順位や修正の難易度によって異なるラベルがつけられています．
今回は簡単に貢献できそうな「Easy」を選んで探しました．

## ソースコードを編集してPRを送る
### リポジトリをフォークする
+ フォークするリポジトリにアクセスする
+ 右上のforkボタンを押して自分のアカウントのリモートリポジトリにコピーする

<img width="490" alt="スクリーンショット 2019-03-29 23.19.04のコピー.png" src="https://qiita-image-store.s3.amazonaws.com/0/264209/6c7c9e34-042f-26b3-2970-84f79e458556.png">

フォークした旨がリポジトリ名の下に表示されます
<img width="284" alt="スクリーンショット 2019-03-29 23.52.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/264209/7671c691-e35c-62bb-d714-376244d8a5cf.png">

### ローカルリポジトリにクローンする
フォークした自分のリモートリポジトリからクローンし，remote urlを設定します．

```&nbsp;
$ git clone [repository url]
$ git remote add origin [your repository url]
```

さらに，自身の作業用ブランチを用意します．どのissueを解決したのかわかるブランチ名が好ましいようです．
今回はCSSによる表示を変更するだけですので，修正する旨を示すブランチ名にしました．

```&nbsp;
$ git checkout -b fix/plugin-version-display
```

### 実際に作業し，自分環境でテストする
ソースコードの編集を行いコミット，プッシュしていきます．

## PRの作成
フォークしたリポジトリにプッシュするとPRを作成するボタンがGithubに出てくるのでボタンを押してPRを作成します．
PRの作成時にはメッセージを書く欄があるので，ここにどのissueを解決したのか，どんな実装を行なったのかなど今回のPRの概観がわかるような説明を記述します．
今回はPRメッセージの形式も決まっているため，それに沿って記述します

## CIとレビュー
今回のプロジェクトではPRに対してScrutinizerやTravis CIによるテストが行われていました．
これらのテストに通らないと，そもそもリクエストが承認されることはありません(品質を保つためです)．
PRはレビュワーの方が内容を確認し，問題がなければマージされます．今回は修正になんの問題もなくそのままマージしていただきました．

# 感想
1ファイル1行修正1コミットだけの簡単なPRでしたが，原因を探す間にプロジェクトに用いられている技術的なことが知れたりと学ぶことがたくさんありました．
実際に自分が行なった修正が本バージョンに反映されるとモチベーションが上がるし，次もコントリビュートしたくなります．もっとPR量産していきます！！！！
Responder + Vue.jsプロジェクト作成手順

# TL;DR
最近`responder`というPython製の非同期処理が売りのWebフレームワークを知ったので、Vue.jsと組み合わせてプロジェクトを作成した手順を紹介します。

完成したものはこちら
[https://github.com/KeisukeToyota/responder-vue-sample](https://github.com/KeisukeToyota/responder-vue-sample)

# プロジェクト作成

## Responder側
まずはディレクトリを作成して`pipenv`で環境を作っていきます。

```console
$ mkdir responder-vue-sample
$ cd responder-vue-sample
$ pipenv --python 3.7
```

`Pipfile`を以下のように編集

```
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true

[dev-packages]

[packages]
asgiref = "==2.3.2"
responder = "*"

[requires]
python_version = "3.7"
```
`responder`以外に`asgiref`を`Pipfile`にバージョンを固定して記述しています。
`asgiref`は`responder`の依存パッケージで`responder`をインストールすれば自動的にインストールされるのですが、**記事投稿時**そのままでは`3.0.0`が入ってしまいVue.jsのビルド済みファイルが入る`static`ディレクトリ配下のファイルを正しく読み込めないため`2.3.2`で固定しています。


以下のコマンドでライブラリをインストールします。

```console
$ pipenv install
```

### サーバープログラム
プロジェクト直下に`app.py`を作成して`static/index.html`を表示するだけのコードを記述します。

```python:app.py
import responder

api = responder.API()

if __name__ == '__main__':
    api.add_route('/', static=True)
    api.run()
```

## Vue.js側
まず`vue-cli`をグローバルにインストールします。

```console
$ npm install -g @vue/cli
```

インストール後、先程作ったプロジェクト直下にVue.jsのプロジェクトを作っていきます。
カレントディレクトリの指定以外はお好みで大丈夫です。

```console
$ vue create .
Vue CLI v3.5.1
? Generate project in current directory? (Y/n) Y
? Please pick a preset: (Use arrow keys)
❯ default (babel, eslint)
  Manually select features
```

Vue.jsのプロジェクトの作成ができたら`vue.config.js`を作成して、ビルドしたファイルを`static`に吐くために`outputDir`、ベースURLを`/`から`static`に変更するために`publicPath`を追加します。

```javascript:vue.config.js
module.exports = {
  publicPath: "static",
  outputDir: "static"
}
```

最終的に以下のようなファイル構成になるかと思います。

```console
$ tree -L 1
tree -L 1
.
├── Pipfile
├── Pipfile.lock
├── README.md
├── app.py
├── babel.config.js
├── node_modules
├── package.json
├── public
├── src
├── static
├── templates
├── vue.config.js
└── yarn.lock
```


# ビルドと実行
では実際にビルドしてからサーバープログラムを起動して`responder`からVue.jsが呼べているか確認していきます。

```console
$ pipenv run responder build # or yarn build
$ pipenv run python app.py
```

これで`localhost:5042`にアクセスして以下のようにVue.jsのホーム画面が出たら終了です。お疲れ様でした。

![スクリーンショット 2019-03-30 0.16.12.png](https://qiita-image-store.s3.amazonaws.com/0/211748/821a162e-5e07-c0c6-c07d-c04285e7fa41.png)