OmniAICreator/Qiita-1.07M huggingface dataset:
VirtualBoxでネットワーク帯域制限

# まえがき
VirtualBoxでネットワーク帯域制限をやろうとしたが、素直なやり方じゃなかったのでメモ。
VirtualBoxの4.2以降から帯域制限できるようになっている。
やり方はヘルプの `6.10. Limiting bandwidth for network I/O`に記載されてる。
以下はヘルプの内容にちょっとだけ情報を追加したものになる。

# `VBoxManage`にパスを通す
`VBoxManage`コマンドを使っていろいろ設定することになるが、
普通にインストールしただけじゃパスが通ってないのでパスを通す。
もしくは、VirtualBoxのbinフォルダに移動してコマンドを実行する。

# 帯域制限の設定を作る
```
VBoxManage bandwidthctl "VM name" add Limit --type network --limit 20m
```
上記コマンドで`Limit`という名前の20Mbpsの帯域制限設定を作ったことになる。
**このコマンドだけVMを停止している必要あり**

# 帯域制限の設定をネットワークアダプタに割り当てる
```
VBoxManage modifyvm "VM name" --nicbandwidthgroup1 Limit
```
上記コマンドで`アダプター1`に制限設定`Limit`を割り当てたことになる
 -> `nicbandwidthgroup2`に変えると`アダプター2`への割り当てになる。

# 帯域制限の設定を変更する
```
VBoxManage bandwidthctl "VM name" set Limit --limit 100k
```
上記コマンドで`Limit`の制限を100Kbpsに変えたことになる
また、VM実行中に設定変更が可能。
**作成のコマンドと微妙にオプションが違うので注意**

# アダプターの帯域制限を無効化する
```
VBoxManage modifyvm "VM name" --nicbandwidthgroup1 none
```
上記コマンドで`アダプター1`の帯域制限を無効化したことになる。
他のアダプターの制限は有効のまま。

# 帯域制限設定を無効化する
```
VBoxManage bandwidthctl "VM name" set Limit --limit 0
```
上記コマンドで帯域制限`Limit`を無効化したことになる。
複数のアダプターに割り当てられていれば、それらすべての帯域制限が無効になる。

# あとがき
VMWareだと画面から帯域制限をいろいろいじれたが、VirtualBoxだと上記のようにコマンドでいろいろやんないといけないのでちょっと面倒くさい。。。
また、データ受信側のNICに対して制限を掛けても効果がないので送信側に対して制限を掛ける必要がある。
【書評】Apache Kafka 分散メッセージングシステムの構築と活用

先日発売された書籍[Apache Kafka 分散メッセージングシステムの構築と活用](http://amzn.asia/d/4yu1BcP)を読みましたので、その感想をご紹介します。本書はかなり丁寧に書かれており、補足が充実しているので、他のメッセージバスの経験がない人でも読みやすいと思います。
![51pP-TJNR5L._SX394_BO1,204,203,200_.jpg](https://qiita-image-store.s3.amazonaws.com/0/320798/815ceaf5-ce84-e445-3be2-117de9b85ffd.jpeg)
第1部　導入Apache Kafka
1　Apache Kafkaの概要
2　Kafkaの基本
3　Kafkaのインストール
4　KafkaのJava APIを用いたアプリケーションの作成

第2部　実践Apache Kafka
5　Kafkaのユースケース
6　Kafkaを用いたデータパイプライン構築時の前提知識
7　KafkaとKafka Connectによるデータハブ
8　ストリーム処理の基本
9　Structured Streamingによるストリーム処理
10　Kafkaで構成するIoTデータハブ
11　さらにKafkaを使いこなすために

# 感想

```
1. 高いスループットでリアルタイムに処理したい
2. 任意のタイミングでデータを読み出したい
3. 各種プロダクトやシステムとの接続を容易にしたい
4. メッセージをロストしたくない
```
本書ではKafkaが持つ特徴を上記の４つの項目として定義し、それぞれに関する理論的な背景や他のセービスとの連携のところを説明しているのが興味深かったです。Kafkaのバージョンが今年に入って0系から2.0系までアップデートが進んでおり、個人的にはキャッチアップができなかったところがありましたが、2.0系までカバーしている本書のおかげである程度新しい情報が把握できたと思います。
特に「Kafka」と「Apache SparkのStructured Streaming」との連携を行うところも充実に説明されているので、Exactly once semanticなど新しい手法でStreaming処理を行い人には良いレファレンスになると思います。だた、この部分はDataFrameではなくDatasetをベースに説明されていますが、DatasetだとEncoder使用によるSerialization処理で一部パフォーマンスの低下が発生する他、Datasetが利用できないPySparkユーザには役に立たないため、DataFrameで書かれた方がよかったのではないかと思います。

# 気になった箇所

- *高いスループットを実現するため、KafkaではPublisher-Subscriber メッセージングモデルをベースにしつつ、複数のConsumerが分散で処理するためにConsumer Groupという概念を導入している（p18）*

- *Ackの設定を１またはallにした場合の重要な点として、各レプリケーションが「書き込まれた」判断しAckを返すタイミングはMessageがメモリ（OSのバッファ）に書き込まれたタイミングとなります。ディスクにflushする（永続化する）タイミングは別のプロパティで制御されます。（p45）*

- *イベントソーシング：データに対する一連のイベントを記録し、逐次CQRSの考え方と併用して大量のイベント処理を柔軟に実現する（p95）*

# まとめ

以前まで参考にしていた[Kafka: The Definitive Guide](http://a.co/d/cvUoKdv)が O'Reillyの「The Definitive Guide」シリーズとしてはかなり低い評価だったため残念と思いましたが、本書は簡潔な日本語で書いており概念のおさらいに非常に役に立ちました。また様々な場面で使われている図もかなり分かりやすく描かれてましたのが良かったと思います。
ASP.NET > Core2 > デプロイしてもWebが反応しない時


忘れるのでメモ

仮想パスを切っている環境にデプロイしても、

以下のようにサーバー直下を参照してしまって、Webが表示できない場合がある。

http://servername/static/css


そういう時には、以下のように`package.json` にhomepageを追加する

```js
{
  "name": "projectname",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "bootstrap": "^3.3.7",
    "react": "^16.0.0",
    "react-bootstrap": "^0.31.5",
    "react-dom": "^16.0.0",
  },
  "scripts": {
    "start": "rimraf ./build && react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  },
  "homepage": "/pathname/"
}

```

以下のように、build/index.htmlファイル中のパスに仮想パスが追加される。

```html
src="/pathname/static/js/main.98ccb00e.js"
```
VPS(Cent6.5)を借りてNginx, Ruby on Rails, MySQLでサービスをつくる(1)

とある事情でVPS借りてサービスを作ってみようと思ったのでその記録


## セキュリティ周り
https://qiita.com/ktkiyoshi/items/bf920b4df02d98b570e3
を参考にsshの設定まで行った。

## nginx
```
nginxをインストール
sudo yum install nginx

バージョンの確認
$ nginx -v
```

## iptablesを許可する
iptablesを編集

```
vim /etc/sysconfig/iptables
```
80番ポートを許可

```
-A INPUT -p tcp --dport 80 -j ACCEPT
```
iptablesを再起動

```
service iptables restart
```

これでnginxを起動すると、

```
sudo service nginx start
```

これでipアドレスをブラウザから叩く(80番ポート)と
nginxのindex画面をみることができます。
<img width="1234" alt="スクリーンショット 2018-11-16 19.03.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/203454/7246fa57-6dd0-e3c5-c258-d9e981e3c96f.png">


## rbenvのインストール
### gitのインストール
```
sudo yum -y install git
```
### rbenv をcloneする
```
git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
```
エラーが出たので
https://qiita.com/murai-taisuke/items/173b3cbbd697e630047d
を参考に、

```
yum update -y nss curl libcurl
```
を実行します。
cloneできました。

### 環境設定
```
# echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
# echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
# 各種設定の再読み込み
# exec $SHELL -l
# rbenvのversion確認
# rbenv --version
rbenv 1.1.1-39-g59785f6

```
#### ruby-buildをcloneする
```
git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
```

#### rubyの最新版確認
```
rbenv install --list
```

rails5.2.1にしたかったのとrubyの安定版をみると2.5.3なので
https://www.ruby-lang.org/ja/downloads/
https://rubygems.org/gems/rails/versions/5.2.1

```
rbenv install -v 2.5.3
```

とすると

```
BUILD FAILED (CentOS release 6.5 (Final) using ruby-build 20181106-11-g648fc99)

Inspect or clean up the working tree at /tmp/ruby-build.20181116230340.14758
Results logged to /tmp/ruby-build.20181116230340.14758.log

Last 10 log lines:
The Ruby openssl extension was not compiled.
The Ruby readline extension was not compiled.
The Ruby zlib extension was not compiled.
ERROR: Ruby install aborted due to missing extensions
Try running `yum install -y openssl-devel readline-devel zlib-devel` to fetch missing dependencies.
```
もう一度rbenv install -v 2.5.3

再読み込み

```
 rbenv rehash
```

インストールされているrubyを確認

```
 rbenv versions
* system (set by /root/.rbenv/version)
  2.5.3

```

```
[root@v133-130-74-221 admin]# rbenv global 2.5.3
[root@v133-130-74-221 admin]# ruby -v
ruby 2.5.3p105 (2018-10-18 revision 65156) [x86_64-linux]
```

rubyを2.5系にできました。

#### Railsのインストール
gemをインストールします。

```
gem install rails
```
#### MySQLのインストール
MySQLが入っていなかったためインストールします。

```
yum install mysql-server
```

#### プロジェクトの作成
```
rails new [project_name] -d mysql -B
```

これでRailsのインストールができました。

続きは別の記事に書こうと思います。
Updating packages in Emacs

# What is this?
This is really a memo....just for myself. Sorry, never mind (><)

# command
In terminal:

```emacs-lisp
emacs
M-x list-packages
```

this puts you in the *packages* buffer

```emacs-list
shift-u x
```

emacs will ask you (y/n), wait for updates

```emacs-lisp
C-x k <ret>
```

this will kill the *packages* buffer and return you back to *scratch*

```emacs-lisp
C-x-C-c
```

this will exit emacs, and let you relaunch via, but you might have to debug :(

# Reference
- [elpa - Updating packages in Emacs - Stack Overflow](https://stackoverflow.com/questions/14836958/updating-packages-in-emacs)
【プログラミングいろは】はじめるのはカンタンです


# はじめるのはカンタン

イマドキはインターネット上でプログラミングができるので準備はカンタン。
特別な準備しなくても、スマホやタブレットとかでもちょちょいとやってみることができる。

ブロックを並べるとプログラムが出来ていく感じ。

例えば、有名なのはScratchというのがあって、キャラクターを動かすプログラムを組める。
スマホとかで試すなら、開発中だけど次世代ベータ版のこちらが良いかなと。
⇒https://beta.scratch.mit.edu/

他には、K3Tunnelというのもある。⇒https://k3tunnel.com/

スマホで見てみるとこんな感じ。動かせたけど画面がちょっとせまいですかね・・・

|| Scratch | K3Tunnel |
|---|---|---|
|見た目こんな感じ|<img width="100%" src="https://qiita-image-store.s3.amazonaws.com/0/297642/f825e885-cc02-11fa-681f-bba708f01efc.png">|<img width="100%" src="https://qiita-image-store.s3.amazonaws.com/0/297642/e675cefb-efd6-3249-e559-76d0b2e4fcc8.png">|

プログラミングをカンタンに始められる世の中になったので、気軽に試せるよう、私もプログラミングって何だっけ？という復習の気持ちで入門情報・・・「いろは」を書いてみようと思い立ちました。

プログラミング言語って、C言語でもJavaでもpythonでもなんでも基礎は同じ。

なのでブロックを並べてプログラミングの基本技を一つずつ紹介。基本技を組み合わせていくと、ちゃんとしたプログラムになる。

Scratchのほうが、音をだせたりキャラクターを動かせたり、いろいろできることが多くて、
K3Tunnelは地味目・・・

プログラミングってσ(^_^;)?・・・という方もできるだけ迷わないように、シンプルなK3Tunnelでいきたいと思います。

# やってみよう

ちょいちょいっとやると、プログラミングを始られる。

1. K3Tunnelのサイトに行く。これをタップ。⇒https://k3tunnel.com/
2. 画面の一番下にある「Make Project」をタップ。
3. プロジェクトを作る。
    「＋」をタップして、好きなプロジェクト名を書き込んで「新規作成」をタップ。
4. プログラミングを始める。作ったプロジェクトをタップして、出てきたスパナマーク（コード編集）をタップ。
5. 以下のような画面になったらOK。
<img width="80%" src="https://qiita-image-store.s3.amazonaws.com/0/297642/42183703-894f-046f-1e1d-27d2c15f6191.png">

# んじゃあ、プログラムしてみる

とりあえず、ブロック1個を動かしてみる。

6. 画面真ん中の点々が並んでいる部分にブロックを並べると、プログラムが出来上がっていきます。
7. 左のほうに並んでいる「表」「グラフ」「条件文」たちをタップすると、いろいろブロックが出てきます。
8. 「文字」をタップしてみると、ブロックがいくつか出てくると思います。そこから「"abc"をメッセージボックスに表示する」を真ん中の点々がならんでいる部分に移します（ドラッグ＆ドロップする）。
<img width="80%" src="https://qiita-image-store.s3.amazonaws.com/0/297642/67d36e91-6eb3-5c92-84ae-4e8826ec3764.png">
9. これでプログラミング終わり。
10. プログラムを動かしてみましょう。画面の上のほうに並んでいるボタンの中の「実行」をタップ。
11. "abc"っていう文字が出ます。
<img width="80%" src="https://qiita-image-store.s3.amazonaws.com/0/297642/fa19b694-9146-4527-905c-5f93a2c2b5dd.png">

プログラミングって、こんな感じ。
気が向くままに、いろんなブロックをいろいろ並べて「実行」してみるといいんじゃないかと思います。

少しずつプログラミングの基本技を投稿していきたいと思います・・・ではでは。
Nuxtアプリのnowへのデプロイがうまくいかなくなったら

それはnowのバージョンが2.0になったからかもしれません。
プロジェクトのルートディレクトリにnow.jsonを作成してバージョンを1.0に指定しましょう。


```json
//now.json
{
  "version": 1
}
```
そしてnow。

```bash
$ now
```

Server Errorが表示されたら

```bash
$ now logs <url of your site>
```
でログを確認。
エラーの原因が環境変数をセットしていないからだったら、環境変数をセットするには、

```bash
now -e APIKEY='' -e AUTHDOMAIN='' -e DATABASEURL='' -e PROJECTID='' -e STORAGEBUCKET='' -e MESSAGINGSENDERID=''
```

このように-eオプションをつければOKです。
2.0でNuxtをデプロイするやり方は少し調べてみたのですがわかりませんでした。誰かわかる方いましたら教えてください。
GAE, AWS, Herokuを試しましたが、今の所Nowが一番簡単かつ安くにSSRするNuxtアプリをデプロイできるホスティングサービスだと思います。
メモ書き程度ですが、誰かのお役に立てば幸いです。
変数が定義されているか、nullかどうかの判定をする[Javascript]

## 変数が定義されているか判定する

ある変数が（ここでは hoge という名前とします）定義されていない状態で参照すると、

```javascript
console.log(hoge) // ReferenceError: hoge is not defined
```
のように、「未定義ですよー」というエラーを発生させてしまいます。
それを回避するためには、

```javascript
const hoge = 'fuga'
if (typeof hoge !== 'undefined') {
  console.log(hoge) // fuga
  console.log(typeof hoge) // string
  console.log(typeof undefinedVarible) // undefined
}
```
上記のように、[typeof演算子](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/typeof)というものを用いて判定します。
未定義のものに対してtypeof演算子を用いると、"undefined"という文字列が返ってくるのでそれで条件分岐ができます。

## nullかどうか判定する
次に、ある変数がnullかどうか判定したいとしましょう。
先ほどのを真似して以下のように書くと...

```javascript
const foo = null
if(typeof foo === 'null'){
  console.log('null')
}else{
  console.log('not null')
}
```
なんとこれ、**else句に飛び込んできます。**
[こちら](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/typeof#null)に書いてある通り、**typeof null は "object"** という文字列を返します。（歴史的な事情があるようです）

なのでnullの判定は素直に、

```javascript
const foo = null
if(foo === null){
  console.log('null') // こっちが呼ばれる！
}else{
  console.log('not null')
}
```
と書いてあげましょう。

## undefinedとnullをいっぺんに判定したいとき
```javascript
undefined === null // false
undefined == null // true
```
と、イコール2つの比較をすると、undefinedとnullは等しいと判定されます。
それを利用して、 @forl_head_officer さんのコメントのように条件分岐することができます。
ToolbarにTabLayoutをもたせてみる


ToolbarはViewを内部に持つことが可能
なので

``` xml
<androidx.appcompat.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="@color/colorPrimary"
    >
    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tab_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center_horizontal"
        android:layout_marginLeft="64dp"
        android:layout_marginRight="64dp"
        android:background="@android:color/background_light"
        app:tabGravity="fill"
        app:tabMode="scrollable"
        app:tabIndicatorColor="@color/colorPrimary"
        app:tabIndicatorHeight="2dp"
        />
</androidx.appcompat.widget.Toolbar>

```
のようにしてToolbarの中にTabを作る事もできる。

![device-2018-11-29-201347.png](https://qiita-image-store.s3.amazonaws.com/0/44384/0cd01c9a-a742-c2de-4fe6-05ba9bd436ee.png)


両サイドに透過グラデーションをつけたdrawableを背景にしたViewを配置して、すみっこに行った時に消えるような感じ

```xml
<androidx.appcompat.widget.Toolbar
     android:id="@+id/toolbar"
     android:layout_width="match_parent"
     android:layout_height="?attr/actionBarSize"
     android:background="@color/colorPrimary"
     >
     <FrameLayout
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:layout_marginLeft="64dp"
         android:layout_marginRight="64dp"
         >
         <com.google.android.material.tabs.TabLayout
             android:id="@+id/tab_layout"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:layout_gravity="center_horizontal"
             app:tabGravity="fill"
             app:tabMode="scrollable"
             app:tabIndicatorColor="@color/colorPrimary"
             app:tabIndicatorHeight="2dp"
             android:background="@android:color/background_light"
             />
         <View
             android:layout_width="52dp"
             android:layout_height="match_parent"
             android:background="@drawable/gradation_left"
             android:layout_gravity="start"
             />
         <View
             android:layout_width="52dp"
             android:layout_height="match_parent"
             android:background="@drawable/gradation_right"
             android:layout_gravity="end"
             />
     </FrameLayout>
  </androidx.appcompat.widget.Toolbar>
```

![device-2018-11-29-202111.png](https://qiita-image-store.s3.amazonaws.com/0/44384/bb3f3c66-33e1-5518-d14e-7aa13b480c40.png)


やってみたけどToolbarの中でやる必要は無いと思う。FrameLayoutで重ねても出来るし。
NavigationDrawerとかCollapsingToolbarLayoutを使っている時に使えるかもしれない？いやないか
短絡評価って本当に処理が速いの？ Javaにおける&&と&の違い

# 短絡評価とは
Javaを少し勉強すると「短絡評価」というものが出てきます。これは&&や||といった論理演算子において、左辺を評価した時点で、式全体の真偽値が決定し右辺を評価する必要がない場合、右辺を評価しないという機能のことです。
次の例をみてください。

```java
boolean flag1 = false;
boolean flag2 = false;
if(flag1 && flag2){
    System.out.println("２つの変数はどちらもtrueです。");
}
```
このプログラムでは3行目の条件分岐で中括弧のブロック内が実行されるためには、flag1,flag2がともにtrueでなければなりません。今回はflag1がfalseであるため、flag2の真偽値を確かめるまでもなく中括弧のブロック内を行う必要がないことがわかります。このような状況で、自動でflag2の評価は行わないようにしてくれる機能が短絡評価です。

#&&と&の違い
Javaには&&と&という二つの似た演算子があります。この二つの演算子はほとんど同じような機能を持つのですが、少し異なる部分があります。
先ほど述べたように&&という演算子は短絡評価の機能が働きます。しかし、&には短絡評価が働きません。すなわち、&は右辺の値を評価する必要がない状況でも右辺の値を評価するのです。

#本当に短絡評価は処理が早いのか？
Javaの参考書やWebサイトでは、&&の方が余分な評価をしないため処理が早いなどと書いてあります。その記述を読んだ時、私は疑問に思いました。「一応異なる処理なのだから、本当に右辺の処理をパスしただけで速くなるのだろうか？」
そこで私は実際に&&と&の処理速度の違いについて検証してみました。

### 検証用プログラム

#### 短絡評価を行うプログラム

```java:Test1
long start = System.currentTimeMillis();
boolean flag1 = false;
boolean flag2 = false;

for(long i=0; i<10000000000l; i++) {
    if(flag1 && flag2) {
        System.out.print("");
    }
}

long end = System.currentTimeMillis();
System.out.println("実行時間" + (end - start)  + "ms");
```
if文の条件式に&&が使われています。


#### 短絡評価を行わないプログラム

```java:Test2
long start = System.currentTimeMillis();
boolean flag1 = false;
boolean flag2 = false;

for(long i=0; i<10000000000l; i++) {
    if(flag1 & flag2) {
        System.out.println("");
    }
}

long end = System.currentTimeMillis();
System.out.println("実行時間" + (end - start)  + "ms");
```
if分の条件式に&が使われています。

### 検証結果
実際に上記の２種類のプログラムを走らせてそれぞれのプログラムの実行時間の統計を撮ってみました。以下の表がその結果です。

##### プログラムの実行時間（単位：ms）

|  | 短絡評価あり(&&) | 短絡評価なし(&) |
|:-:|:-:|:-:|
| １回目  | 3546  | 3500  |
| ２回目  | 3556  | 3595  |
| ３回目  | 3586  | 3565  |
| ４回目  | 3574  | 3564  |
| ５回目  | 3552  | 3636  |
| ６回目  | 3570  | 3620  |
| ７回目  | 3512  | 3568  |
| ８回目  | 3563  | 3597  |
| ９回目  | 3560  | 3565  |
| １０回目  | 3555  | 3500  |
| 平均  | 3557.6 | 3571.0  |

表の平均を見る限り、短絡評価を行なっている方が処理速度が速いと考えられます。しかし、今回の実験では標本数が少なく、短絡評価ありと短絡評価なしの実行時間の差は小さいものであったので、短絡評価なしの&より短絡評価ありの&&を利用した方が処理が速くなると結論づけるには少し根拠が弱いです。

# まとめ
今回私が行なった実験では短絡評価を利用した方が処理が速くなるという結果が得られました。とりあえず、Javaで複数の真偽値の論理積を取る場面では、&&を使う方が良いと考えられます。また、C言語などの他の言語では、&が両辺を２進数と見て各桁について論理積をとるという全く雰囲気の異なる機能となっている場合もあるので、言語を乗り換えた際にミスが増えないようにする意味でも、Javaで&を使っても&&を使っても同じ結果になるという場合には、&&を使うことをお勧めします。
Firebaseのデータベース（Cloud Firestore）をWebからサクッと使ってみる

## なにがしたい？

Firebaseのデータベースを使ってみる。
Web（フロントエンド）のJavaScriptから操作してみる。

## はじめに

FirebaseのセッティングとHostingできるところまでは持っていってください。
単なるHostngだけならそんなに苦労しないです。

簡単言うと、Firebaseのサイト（コンソール）から、

1. 新しいプロジェクトの作成
2. Hostingを使ってみるを選ぶとコマンドが出てくる
3. パソコンのターミナルから`firebase login` → `init` → `deploy`を実行

という感じです。

> Basic認証付きという状態で良ければ、手前味噌ながらにこの記事を参考にしてくれてもいいです。
> （もっとわかりやすい記事も探せばあると思います）
> [FirebaseでBasic認証をかけてHostingをする(Windows)](https://qiita.com/567000/items/65f55eda8d7c6df09138)

## DBの作成

ここからが本題です。

Firebaseのサイト上のメニューから **Database** を選択して、「データベースの作成」をクリックします。
とりあえず、**テストモード**で開始します。

> 後で変えられるので大丈夫です

画面が切り替わるので、「＋コレクションを追加」します。RDBで言うところのでいわゆるテーブル名です。
適当に「`data`」という雑な名前を付けておきます。
> 実際は「`users`」とか意味ある名前にするほうが吉です。

次に、フィールドの設定を行います。RDBで言うところのいわゆるカラム名です。
今回はJavaScriptからカラムを追加したいので、もしフィールドが出ていたらマイナスのボタンを押して消して、空の状態にします。

「保存」を押して終了です。

これでサーバ上にDBの準備が出来ました。

## Webからアクセスする準備をする

Firebaseのサイト上の`Project Overview`を押して`+アプリを追加`をクリック。
メニューが開くのでWebのマーク`</>`をクリック。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/33095/1ac7b546-ad8f-deb8-f8b5-2c3690d54e0f.png)

スクリプトのコードが出てくるのでコピーしておきます。
本来これをヘッダに張り付けてHTMLを作りますが、いろいろTipsがあるのですが一気にコードに行ってみたいと思います。

## Webからデータ追加するHTMLを作る

下記がDBに値を追加するコードです。
APIキーやドメインといった部分だけ上でコピーしたコードをうまく使って埋めてください。

```html:public/add.html
<html>
  <head>
  <script src="https://www.gstatic.com/firebasejs/5.5.9/firebase-app.js"></script>
  <script src="https://www.gstatic.com/firebasejs/5.5.9/firebase-firestore.js"></script>
  <script>
    // Initialize Firebase
    // ここの各値を書き換える
    var config = {
      apiKey: "xxxx",
      authDomain: "xxxx",
      databaseURL: "xxxx",
      projectId: "xxxx",
      storageBucket: "xxxx",
      messagingSenderId: "xxxx"
    };
    firebase.initializeApp(config);

    const firestore= firebase.firestore();
    const settings = { timestampsInSnapshots: true };
    firestore.settings(settings);

    // この data をドキュメント名にする。
    // 今回は、サンプルなので LA のデータをいれてみる    
    firestore.collection("data").doc("LA").set({
      name: "Los Angeles",
      state: "CA",
      country: "USA"
    })
    .then(function() {
      console.log("Document successfully written!");
    })
    .catch(function(error) {
      console.error("Error writing document: ", error);
    });
  </script>
  </head>
  <body>
    <p>add data!!</p>
  </body>
</html>
```

ここで作るデータはチュートリアルからとってきた適当なものです。
いわゆるNoSQL系のDBなので、フィールドを事前に用意してなくても勝手に作ってくれます。

ファイルができたら、デプロイしてみましょう。

```
> firebase deploy
```

URLにアクセスしてみます。

```
https://xxxxxx.firebaseapp.com/add.html
```

画面には`add data!!`など出てるはずです。

次に、Firebaseのサイトの`database`を見てみます。
コレクション`data`に、ドキュメント`LA`が追加されているのがわかると思います。

これにてデータ追加が完了です。

## いったんまとめ

これで一通りの流れができました。
あとは、チュートリアルなど参考にJavaScriptからコールするAPIを変えることで、参照でもなんでもできると思います。


次は、セキュリティルールなど、実運用を考えた設定をしたいと思います。
次の記事書くまで少々お待ちください。
その判定本当に正しいですか？

##はじめに
ある判定式を書いたときに`「この判定方法正しいのかな?」`と思いました。
知ったかぶって実装している訳ではなかったのですが、心なしか腑に落ちなかったので調査しました。
その調査をそのままアウトプットとして記載します。

##前提
- `?hoge=1`というクエリパラメータが飛んできた場合

##実装コード

```php:sample.ctp
if (isset($this->request->query['hoge']) && $this->request->query['hoge'] === '1') {
    // ゴニョゴニョ
}
```

##やりたいこと
`hoge`というクエリパラメータなのか、ということと、その値は`1`なのか、を判定したい。

##目的
- やりたいことを満たせているのか調査をする
- 調査のノウハウを知識として蓄積する

##調査方法
- スプレットシートと[PHP 型の比較表](http://php.net/manual/ja/types.comparisons.php)を使用。

##調査


<img width="1317" alt="スクリーンショット 2018-11-29 20.22.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/267738/1e498b95-38ab-746b-55bf-b23293ba1689.png">


図は`トリプルイコール`で比較した場合の結果
[PHP 型の比較表](http://php.net/manual/ja/types.comparisons.php)から引っ張ってきました。

<img width="1171" alt="スクリーンショット 2018-11-29 19.41.59.png" src="https://qiita-image-store.s3.amazonaws.com/0/267738/ca37a3ad-4bd3-d3b3-25e0-1a50135afe39.png">

上記の表から今回実装したコードの結果の部分を引っ張ってきます。
期待値は`文字列の1`のみTRUEになって欲しいので、このようにしています。

結果を求めます。
IF関数を使用して求めます。参考→[GoogleスプレッドシートのIF関数の使い方](https://www.relief.jp/docs/018738.html)

```
IF(B37,IF(B38,"TRUE","FALSE"),"FALSE")
```

このような条件で、`isset=TRUE`かつ`"1"=TRUE`かどうかを判定します。

<img width="1316" alt="スクリーンショット 2018-11-29 19.57.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/267738/1bff7476-c7fa-ca48-0c2d-16fa89d51c8d.png">


結果はこのようになりました。
期待値通りになっている事がわかりました。

issetの役割としては、CakePHPのクックブックの[クエリー文字列パラメーター](https://book.cakephp.org/3.0/ja/controllers/request-response.html#id4)にも書かれているように、
>キーが存在しない場合、 null が返ります。

今回でいう`hoge`というkeyが存在しない場合の考慮をしてくれています。ありがとう`isset`

##結果
今回でいう所の実装は正しかった。

##まとめ
今回の調査で大事なのは、正しく実装できていたか、を知る事より、疑問に思った時に調査してすぐ解決できるノウハウを自分の知識として蓄積する事です。
PHPの型の比較表を暗記することではないのです。

調査をする、というアクションを取る上で、`目的`がしっかりしていれば、そのアクションは何倍にも効果的なアクションとする事ができます。

`目的`にも書きましたが、今回の調査でしっかり蓄積できたと思います。
しっかり今後に生かして圧倒的成長の源としたいと思います。
AnsibleのDry Runのテストの際、インストールとかその辺りでコケるのをなんとかしたい。

#【事象】

AnsibleのDry Runテストの際、いつもサービスのstart時や、symlinkを張るtaskで、not found等のエラーになりroleが最後まで確認できず困っていた。CIツールも結局Dry Runで流してるコマンドは同じ。。。

```
# ansible-playbook -i hosts playbook.yml -vvv --check
```

#【解決】
tasksに`when: not ansible_check_mode`と入れることで、コケそうなtaskもskipしてくれる。


###いざ...
■YAMLの書きっぷり

```
[root@localhost work]# cat test/tasks/01_test_check.yml
# Check status of taks
- name: Check status of test
  systemd:
    state: started
    enabled: yes
    name: "{{ test.name }}"
  when: not ansible_check_mode ←これを書く
[root@localhost work]#
```


■スキップしてくれたログ

```
TASK [Test : Check status of test]
 ********************************************************************************************************************
task path: /work/test/tasks/01_test_checkl.yml:9
skipping: [test1] => {
    "changed": false,
    "skip_reason": "Conditional result was False" ←skipしてくれてい〜る!!
}
```

##【備考】
ドキュメント通りに`check_mode: no`で実施してみたけれど、<font color="Red">真っ赤っ赤</font>になって叱られます。
どうやら、`check_mode: no`だとDry Runでもとりあえず**強制的に実行**しちゃうみたいですね～。
そのため、インストーラがない、ファイルが無い等の場合は false が返ってきてコケるのですね。

```
tasks:
  - name: this task will make changes to the system even in check mode
    command: /something/to/run --even-in-check-mode
    check_mode: no

  - name: this task will always run under checkmode and not change the system
    lineinfile:
        line: "important config"
        dest: /path/to/myconfig.conf
        state: present
    check_mode: yes

>Enabling or disabling check mode for tasks
 https://docs.ansible.com/ansible/latest/user_guide/playbooks_checkmode.html#id2
```

#<参考>
Skip Ansible task when running in check mode?
https://stackoverflow.com/questions/28729567/skip-ansible-task-when-running-in-check-mode

check_mode:
https://docs.ansible.com/ansible/latest/user_guide/playbooks_checkmode.html#information-about-check-mode-in-variables

ansible_check_mode
https://docs.ansible.com/ansible/2.5/user_guide/playbooks_variables.html?highlight=ansible_check_mode
WordPressで使う、カテゴリー・タクソノミー・スラッグって色々あるけどなんじゃそりゃ？


WordPressで構築し始めると、
普段聞きなれないタクソノミー・スラッグ等の言葉が出てきますよね。
カテゴリーじゃないの？
カテゴリーと何が違うの？
何を取得しようとしているのか？混乱する事もあるので
自分用にも備忘録まとめです。

##カテゴリー
これは一番分かりやすいと思いますが、
いわゆる記事をカテゴライズするものですね。

前提として、WordPressには様々な投稿タイプがあります。
デフォルトの投稿タイプは全部で5つ
>投稿 (投稿タイプ: 'post')
固定ページ (投稿タイプ: 'page')
添付ファイル (投稿タイプ: 'attachment')
リビジョン (投稿タイプ: 'revision')
ナビゲーションメニュー (投稿タイプ: 'nav_menu_item')

詳しくはこちら：
http://wpdocs.osdn.jp/%E6%8A%95%E7%A8%BF%E3%82%BF%E3%82%A4%E3%83%97

その中で、通常記事を投稿するのに使うのが、投稿タイプ: 'post'
管理画面で言うと「投稿」の欄になります。

投稿欄のタブには、デフォルトで「カテゴリー」と「タグ」を追加出来るようになっているので、
馴染みがあるかもしれません。

例えば、ブログを書くとすれば
内容に合わせてカテゴライズして投稿することが出来ます。

![category.png](https://qiita-image-store.s3.amazonaws.com/0/139029/32daa026-3aaa-da1d-95d9-68eace04c1ac.png "category.png")


##スラッグ
お次はスラッグ。
既に、管理画面でカテゴリーを追加する時に「スラッグ」と言う欄が出てきてますね。
さらに、説明もしっかり書いてありました。

>“スラッグ” は URL に適した形式の名前です。通常はすべて半角小文字で、英数字とハイフンのみが使われます。


###URLに適した形式の名前

URLに適した形式の名前と言うと分かりにくいですが、
固有の名前付けのようなイメージで、
スラッグに付けたものが、そのままURLの一部になります。

例えば、先程作ったカテゴリーにこんな感じでスラッグをつけて行くと、

![slug.png](https://qiita-image-store.s3.amazonaws.com/0/139029/e7614092-ec46-709d-cd38-2b81b393d655.png "slug.png")

スラッグがそのままURLに反映されます。

http://hoge/food/
http://hoge/movie/
http://hoge/book/

###記事データの絞り込みに使う

さらに、このスラッグ名を使って、
記事データを取得することが出来ます。

例えば、投稿を取得するパラメータで
category_nameにスラッグ名を入れると
記事のカテゴリー絞り込みが出来ます。

```
$args =  array(
  'post_type'      => 'post',
  'category_name'  => 'food'
);

// カテゴリー「食べ物」だけの記事で絞り込みが出来る
```

##タグ
こちらも投稿欄にデフォルトで追加出来るようになっているので、
馴染みがあると思います。

カテゴリーがカテゴライズだとすれば、
タグはキーワードの目印を付けるような感じだと分かりやすいかもしれません。

カテゴリーと同じように、名前とスラッグを設定して使います。

![tag.png](https://qiita-image-store.s3.amazonaws.com/0/139029/93b136d7-1170-98e5-5498-7718ac85beec.png "tag.png")

##タクソノミー

そしてお次は、タクソノミー。
1番馴染みがなさそうな言葉ですよね。

意味的には「分類」になるのですが、
カテゴリーと何が違うのかというと...
実は、カテゴリーもタクソノミーも同じです。

...と言いつつ、実態は同じではなくて、
タクソノミーの中にカテゴリーがあるというイメージです。

つまり、今まで出てきた「カテゴリー」「タグ」をまとめて「タクソノミー」となります。
タクソノミー（分類）のうちの1つが「カテゴリー」だったり「タグ」だったりする訳ですね。

##ターム

タクソノミーを追加すると、次に出てくる言葉が「ターム」
タームって何なの？というと、
タクソノミー「カテゴリー」「タグ」で追加した項目部分のことです。

例えば、記事をカテゴライズするために作った「カテゴリー」タクソノミー。
「新規カテゴリー」ボタンで「食べ物・映画・本」というカテゴリーを追加して行くと、こんな感じになります。

![slug.png](https://qiita-image-store.s3.amazonaws.com/0/139029/e7614092-ec46-709d-cd38-2b81b393d655.png "slug.png")

この、名前の列に出来た「食べ物・映画・本」という項目がタームです。

管理画面では「名前」と出ているのに、タームと呼ぶのでちょっと混乱しちゃいますよね。
タームは、タクソノミーの項目と言うと分かりやすいかもしれません。


##カスタム投稿タイプ

さらに、WordPressを使い進めると、デフォルトの要素だけでは事足りなくなってきますよね。
個人のブログなら、「お知らせ」の投稿がしたいな〜とか、
会社のサイトなら、「社員紹介」の投稿したい、などなど。

前記したように、WordPressのデフォルトの投稿タイプは全部で5つですが、
この他にオリジナルで投稿タイプを追加することが出来ます。

それが、カスタム投稿タイプ。

カスタム投稿タイプは、functions.phpにregister_post_type()を使って追加することが出来ます。

詳しくはこちら：
http://wpdocs.m.osdn.jp/%E9%96%A2%E6%95%B0%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9/register_post_type



##カスタムタクソノミー

さらにさらに、カスタム投稿タイプにも「カテゴリー」「タグ」を追加する事が出来ます。
それらをまとめて、カスタムタクソノミーと呼びます。

カスタムタクソノミーは、functions.phpにregister_taxonomy()を使って追加することが出来ます。

詳しくはこちら：
https://wpdocs.osdn.jp/%E9%96%A2%E6%95%B0%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9/register_taxonomy


---


カテゴリーやタクソノミー、スラッグやタームなど、
混乱しがちなあれこれをまとめてみました。

自分が今何を取得したらいいのか迷った時に、
この辺りが頭の片隅にあると欲しいものが手に入りやすくなるかもしれません🙈

おわり！
PowerAppsで長押しを作る

2018年11月29日時点では、PowerAppsに長押しにあたるアクションがありません。
長押しをしたいケースがいくつかあったので、コントロールを組み合わせて疑似的に実装することにしました。

**(追記)**2018年12月12日に状況が変わって、ボタンコントロールでPressedが使えるようになったようです。
https://powerusers.microsoft.com/t5/PowerApps-Ideas/Button-Pressed-trigger-an-action/idi-p/34397
https://docs.microsoft.com/ja-jp/powerapps/maker/canvas-apps/controls/control-button
ということで、長押しはPressedを使ってください。
以下の対応は不要です。

## 作り方
スライダーを挿入し、プロパティを以下のように変更します。

```c#:Slider1
Default = 0
HandleSize = 1
Max = 1
Min = 0
OnChange = UpdateContext({isPressing:false})
OnSelect = UpdateContext({isPressing:true})
ShowValue = false

// 以下透明にするための設定
BorderColor = RGBA(0, 0, 0, 0)
BorderStyle = BorderStyle.None
DisabledBorderColor = RGBA(0, 0, 0, 0)
HandleFill = RGBA(0, 0, 0, 0)
RailFill = RGBA(0, 0, 0, 0)
ValueFill = RGBA(0, 0, 0, 0)
```

これでほぼ出来上がりです。
あとはボタンを挿入してスライダーの下に重なるように配置してください。

ボタンを長押しするとスライダーが反応します。
こんな感じなります。
![長押し2.gif](https://qiita-image-store.s3.amazonaws.com/0/97601/558a1f8f-bbc2-34bb-28f9-bccd71ab20dc.gif)


## 解説
スライダーの**OnSelect**はスライダーを押した直後に反応するアクションになります。
また**OnChange**は離したときに反応するアクションのようです。
この二つを利用して、押している間はisPressingがTrueになるようにしているだけになります。
また、**Max**と**Min**の差を1にして**HandleSize**を1にすることで、スライダーのほぼどこを触ってもOnChangeが発動するようになります。
さらに、スライダーの値が出ないように**ShowValue**はFalseにするとよいでしょう。

最後に、スライダーを隠すためすべての色を透明に設定します。
これで完成です。

PowerAppsは少しずつ改善されているのでそのうち長押しも標準で使えるようになるのかなぁと思ってます。
AWS Elastic Beanstalk をダウンタイム無しでアップデートする

# 深夜に勝手にやってもらう

Elastic Beanstalk では、時刻指定で勝手にやってもらうこともできます。ウェブサービス本体の環境だと怖いですね。phpMyAdminみたいな管理ツールは、これでアプデしてよいでしょう。

* [マネージドプラットフォーム更新](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/environment-platform-update-managed.html)

# ダウンタイムがあってかまわない & 戻せなくてもかまわない

公式マニュアルに手順の記載があります。

* [Elastic Beanstalk 環境のプラットフォームバージョンの更新](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/using-features.platform.upgrade.html#using-features.platform.upgrade.config)

# ダウンタイム無しでやりたい & 戻せるように備えたい

ウェブサーバーは特にこの要求があると思います。

ざっくりこういう手順。

* 現行環境から、環境クローンの作成
    * [Elastic Beanstalk 環境のクローンを作成する](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/using-features.managing.clone.html)
    * クローン環境は、現行環境と同一バージョンになる
    * 現行環境をバージョンアップさせることで、以後のeb deploy先を変更せずに済む
* 現行環境からクローンに、環境URLのスワップ
    * [AWS Elastic Beanstalk を使用した Blue\-Green Deployment](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/using-features.CNAMESwap.html)
* 現行環境へのトラフィックが十分に止まるまで待つ
    * [AWS マネジメントコンソールでの環境の状態のモニタリング](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/environment-health-console.html) で、ELBやEC2へのネットワーク受信を見る
    * EC2のELBのコンソールで見てもよい
* 現行環境を、 [Elastic Beanstalk 環境のプラットフォームバージョンの更新](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/using-features.platform.upgrade.html#using-features.platform.upgrade.config) に従ってアップデート
    * プラットフォームバージョンを上げたい場合は、現行環境を削除して、 [AWS Elastic Beanstalk で異なるプラットフォームバージョンに eb clone \- Qiita](https://qiita.com/sasasin/items/72c3455318175e497e1a)
* クローンから現行環境に、環境URLのスワップ
* 動作確認
    * うまくいったら
        * クローンへのトラフィックが十分に止まるまで待つ
        * クローンを削除する
    * あやしいなら
        * 現行環境からクローンに、環境URLのスワップ
        * 調査して出直す
現在志向バイアスとキャッシュレス社会

この記事は[リンク情報システム](https://www.lis.co.jp/)の2018年アドベントカレンダーのリレー記事です。
engineer.hanzomon のグループメンバーによってリレーされます。
（リンク情報システムのFacebookは[こちら](https://www.facebook.com/lis.co.jp)から）

--------

8日目を担当しています。
プログラミングにはあまり詳しくないので、技術的なお話はできないのですが、
IT技術の発展に伴う問題の一つを、認知バイアスの話を添えて取り上げていきたいと思います。

## はじめに
以下の報酬が貰える二つのアンケートが存在するとします。

* 回答した直後に5千円分の商品券がもらえるアンケート
* 回答した半年後に1万円分の商品券がもらえるアンケート

あなたなら、どちらのアンケート調査に協力したいと思うでしょうか。

5千円か1万円かと問われれば、当然、1万円が貰えるアンケートのほうが良いはずです。
しかし、いつ貰えるのかについても考えなければならないとき、物の価値は変わってきます。
5千円分の商品券を選んだ方でしたらもうお気づきかと思いますが、
「今」貰える5千円は「未来」に貰える1万円よりも魅力的に映ることがあるのです。
この認知バイアスは、IT分野においても無視できるものではありません。

##現在志向バイアスとは
未来の成果か、目先の欲求か。
そのどちらが優先されるのかについて調査した有名な実験として、マシュマロ・テストというものがあります。
4歳の子供を対象とした実験であり、マシュマロを1つだけ与えられた状態で、実験者が帰ってくるまでの20分間、食べずに待っていられたらマシュマロがもう1つ貰えるという内容です。この実験において、3分の2の参加者は、実験者が帰ってくる前にマシュマロを食べてしまいました。
目先の欲求を優先する理由は様々ですが、それらが物の価値を変化させているのは確かです。
現在志向バイアスとも呼ばれるこの心理傾向は、個においても社会においても、単純な利益の計算を妨げてきました。
（マシュマロ・テストの本来の目的は、幼少期の自制心の強さと将来的な成功の関係性を調査するものでしたが、ここでは現在志向バイアスを説明するものとして取り上げています。
この関係性については今年の再実験でまた新たな結果が得られたのだとか）

前置きが長くなってしまいました。本題はここからです。

新しい技術やシステムに対して、人は様々な抵抗感を抱きます。
現在志向バイアスもその内の一つと言えるでしょう。
将来的に大きな利益が得られることが分かっているシステムであっても、導入時の手間や損失を考えると導入に踏み切れず、結局既存のシステムに頼ってしまう。
そんな経験をしたことがある人は多いはずです。
将来的な利益を取るか、導入時の損失を避けるかの判断は、いつの時代でも人を悩ませてきましたが、現在志向バイアスの働きが強いと、判断において後者、つまりは導入時の損失のほうを問題視するようになるのです。

以下、例として、キャッシュレス化の動きについて見ていきます。


##■キャッスレス化が進まない日本
2020年の東京オリンピックに向けて、日本でもキャッスレス化が推進されていますが、未だ現金支払いが根強く残っているのが現状です。
その理由に関しては様々な記事で取り上げられていますが、現金支払い派のユーザの意見に絞ってまとめると次のようなものが多いことが分かります。

* 電子決済の安全性への不安
* 現金支払いへの不満のなさ
* 使いすぎる可能性
* 多様すぎる決済方法
* バッテリー問題　など

これらの問題を全て解決するのは難しいでしょう。
日々の生活に密接に関わる問題ですから、キャッシュレス化の動きに対して多くの不安や疑問を抱くのは当然です。

しかし、何割かのユーザはキャッシュレス社会に対応するのが億劫なだけである可能性もあると考えています。
なにせ、カード決済を導入したからといって、明日からレジ締め作業がなくなるわけではありませんし、クレジットカードを作ったからといって、明日からカード一枚で生活できるわけでもありません。
現在志向バイアスを踏まえて話すのであれば、キャッスレス化による利益は未来にあり、「今」得する感が少ないために、何となく乗り気になれないのではないでしょうか。

というのも、自分がその手の現金支払い派ユーザだからなのですが。

導入時のお得感を求めるユーザの中には、新しい技術やシステムを導入しない理由を他に見出そうとする人もいるでしょう。
将来的に得をすることがわかっていても、今は導入する気分になれない、といった不合理さに理由を求めるからです。
そのため、安全性や、使い過ぎへの不安などを理由にしている可能性もあるのではないでしょうか。
（勿論、上述した問題点はキャッシュレス社会を実現する上で軽視はできません）

##■今何が得られるのか
新しい技術やシステムが明日の生活を劇的に変えるわけでないことは周知の事実でありますが、かといって、誰もが未来の利益を辛抱強く待てるかといえば、そうでないのもまた事実です。
将来的にどれだけの利益が見込めるかだけでなく、今何が得られるのかを提案していかないことには、現在志向バイアスの強い日本人たちの心を動かせないのかもしれません。

現金支払い派の自分にも、一枚だけ日々使っているカードがあります。
それはSuica。
Suicaの定期券は導入時のお得感を体現していたカードであったと思います。
半年分の交通費を切符で払うのと、Suicaで払うのとでは料金に雲泥の差がありますから、これには現金派の私もカード支払い一択となりました。
一度使い始めると手放せなくなりますし、クレジットカードも何かきっかけがあれば使い始めるのだと思います。

こうした心理というのは、自分に限った話ではないはずです。
「今」お得感を味わえる魅力的な「とっかかり」を与えていくことが、キャッスレス化の促進にも繋がるのではないのでしょうか。

##■まとめ
オンライン決済の多様化が進んでいると聞いて、今回はキャッシュレス化について取り上げましたが、現在志向バイアスを意識することは、IT分野のマーケティングにおいても重要であるように思います。
消費者としてはこのバイアスに惑わされることなく判断していきたいところですが、ここまで話しておいて今日も自分は現金支払いでお昼ご飯を買っているのですから不思議なものです。

認知バイアスって知る分には面白いけれど、扱うとなると厄介だなあ、という話でした。
Windowsストアアプリの実体

Windowsストアアプリの実体ファイルについてメモしておきます。

Windowsストアアプリの保存場所は、`C:\Program Files\WindowsApps`以下にあります。
ただ、そこにはexe形式の実行ファイルはありません。
何が実行しているかというと`C:¥Windows¥System32¥WWAHost.exe`というファイルでした。
WWAHost.exeはjavascript実行エンジンでこれの上でWindowsストアアプリが動いていました。



追記 2020/01/22
公式の情報があったので貼っておきます。時間があるときにでも記事自体を更新しようと思います。
https://docs.microsoft.com/ja-jp/archive/blogs/osamum/windows-html-javascript
Node-REDからWatson Studioの機械学習モデルを呼び出す

# はじめに
Node-REDの追加ノードにWatson Machine Learning用のものがあることを発見しました。
その利用メモを残しておきます。

# 前提
呼出し対象のモデルは、別記事[SPSSクラウド版で簡単機械学習](https://qiita.com/makaishi2/items/85d7694168e71ee3c094)でクラウド上にWebサービスとしてデプロイしたものを利用します。
他のサービスであっても手順などはほぼ同じはずです。

# 追加ノードの導入
Node-Redに追加ノードを導入する手順については、別記事[IBM CloudのNode-REDで追加ノードの導入手順](https://qiita.com/makaishi2/items/5c1e922352d6c30adaf0)に記載しておきましたので、この手順を参考にして下さい。
今回追加導入するノードの名称は ```node-red-contrib-watson-machine-learning```になります。
正常に導入されたノードは、図のようにIBM Watsonグループに追加されます。

![スクリーンショット 2018-11-29 18.27.00.png](https://qiita-image-store.s3.amazonaws.com/0/206130/6d854298-ea1a-a9ba-9c09-93f2b84e2da9.png)

# WMLノードの配置、設定
まず、WMLノードを編集エリア上に配置し、設定を行いましょう。
配置したWMLノードをダブルクリックし、設定画面がでたら、下記の鉛筆アイコンをクリックし、config nodeの設定画面を表示します。

![スクリーンショット 2018-11-29 18.30.35.png](https://qiita-image-store.s3.amazonaws.com/0/206130/5467135d-ffbb-667d-ad97-26c75eb51b51.png)

下の画面が出ますので、名前は ```WML-config```など適当な名前を設定し、それ以外の構成情報はWMLのcrednttail情報をコピペして設定します。ちなみにAccess KeyのところはAPIKeyで読み替えます。

![スクリーンショット 2018-11-29 18.33.16.png](https://qiita-image-store.s3.amazonaws.com/0/206130/313b9ace-f1bd-9c34-b337-da60acd2324f.png)

全部入力が終わったら「Add」ボタンをクリックして下さい。
元のNodeの設定画面に戻ったら、いったん「Done」でパレットに戻り、この段階でDeployボタンをクリックして下さい。
その後、再度このノードの設定画面を開きます。
下の図のように、「Mode」は「Run Prediction」を選択します。IDの設定が正しくできていると、「Model」「Deployment」のドロップダウンに、呼び出したい機械学習モデル、Webサービスがでてくるはずです。
図のように、それを選択した状態で、「Done」をクリックし、再度Deployを行います。

![スクリーンショット 2018-11-29 19.00.50.png](https://qiita-image-store.s3.amazonaws.com/0/206130/b392d489-a6da-f908-a7fd-4b6fe42a9a90.png)

# Flowの作成
ここまでできれば後は簡単です。
下の図のように「inject」「function」「debug」の各ノードを編集エリアに配置し、一直線につなぎます。
![スクリーンショット 2018-11-29 19.05.36.png](https://qiita-image-store.s3.amazonaws.com/0/206130/a758ac29-7c41-269e-e3a3-16c05587d605.png)

Function Nodeのコードは次のような形にして下さい。
"fields"には、入力項目名のリスト、"values"には入力値をリストのリストとして作成します。

```js

msg.payload = {
    "fields": ["CLASS", "AGE", "BP", "AL", "SC", "POT", "PCV"],
    "values": [[null, 75, 70, 0, 0.8, 3.5, 46]]
};
return msg;
```

全部設定が終わったら再度deployを行います。

# テスト
準備はすべて整ったので、後はinjectノードをクリックしてテストを行います。
うまくいくと、下の図のように呼出し結果が表示されます。

![スクリーンショット 2018-11-29 19.14.03.png](https://qiita-image-store.s3.amazonaws.com/0/206130/fc384a82-2f23-5745-27a6-9c6aa923fc0c.png)
vagrant upの際に起きたerrorのlogを見る方法

プログラマーとして初案件に入るにあたり、**vagrant**を使用した環境構築で詰まったので自戒を込めて記事にします。

##詰まった箇所
vagrant up の際に404エラーが吐き出されて原因が特定できず詰まった。。。

##せや！！エラーログ の確認や！！
→どこにエラーログ吐き出されてるねん／(^q^)＼

##解決策を模索
①vagrantでssh接続

```
vagrant ssh
```
②rootユーザー(最高権限者（神））にユーザー変更

```
sudo su -
```

③下記のルートファイルを漁る

```
cd /var/www/httpd
```

④lsでディレクトリ内ファイルを確認し、参照したいファイルを選択(今回はerror.logというファイルを参照)

```
tail -f error.log
```

##注意点（時間を食った箇所）
 - local環境内をひたすら捜索  
 =>見えないものを見ようとして１時間を無駄にした（あるわけない）
 - ssh接続後rootユーザーに切り替えずerror.logを探す  
 =>httpdから先が聖なるバリアで弾かれる（権限の問題)


####以上
環境設定まだまだ怖いとです・・・
Vue CLI UIを使ってプロジェクト作成

# はじめに
とあるきっかけで自分で未習得のVue.jsを勉強がてら導入しようということになりまして。
まずはインストールから始めたわけですが、手順通りやったつもりがどうやらしくじったらしく、先生と同じ画面が出ない。バージョンの違い？
折角なので、そのあたりをQiitaにまとめていきましょう！という事に。

しかも、Vue CLI UIを使って修正とかできればなおハッピーみたいに言われたのでこれまた勉強です。ちょっと知識が偏ってしまっているので、よい機会です。

# 前提条件
- Vue.js 3.1.1

# 触ってみよう
Vue.jsのインストールは特記するほどでもないので省略。
この状態でCLIを使ってプロジェクトまで作成済み。

<img width="576" alt="project.png" src="https://qiita-image-store.s3.amazonaws.com/0/315883/b9041020-88af-cd0d-fbe6-be1686defe82.png">

Vue CLI UIもインストール済みで起動してみます。

<img width="823" alt="vueui.png" src="https://qiita-image-store.s3.amazonaws.com/0/315883/e315974f-6887-46dd-f6c6-1d9efce51231.png">

見事にないと言われました。でもよく見たらインポートってコマンドが見えるのでやってみます。
<img width="823" alt="import.png" src="https://qiita-image-store.s3.amazonaws.com/0/315883/58598358-117e-7703-4cda-4adbd704f7b8.png">

<img width="960" alt="impafter.png" src="https://qiita-image-store.s3.amazonaws.com/0/315883/bbef56a3-ac8d-95f2-5073-add0649d9999.png">
できたみたいです！
変更を行いたかったので、左バーにある`依存のアイコン`をクリックしてみると、
<img width="823" alt="import2.png" src="https://qiita-image-store.s3.amazonaws.com/0/315883/af2c5a7b-cf11-d33b-d3a2-cefdb8eebd50.png">
すでにimport済みなFont awesomeとかが見えました。
これで更に追加してみます。右上の`依存をインストール`をクリックし、プラグイン検索で`fortawesome`と入力すると、
<img width="823" alt="some.png" src="https://qiita-image-store.s3.amazonaws.com/0/315883/75f329c3-d09e-e78c-7879-e25c23266d50.png">
一覧で出てくるのでやりやすいですね。
`free-regular-svg-icons`を追加してみます。
<img width="823" alt="some2.png" src="https://qiita-image-store.s3.amazonaws.com/0/315883/3c24b3e4-41dc-8803-2fee-3afb1d73a375.png">
簡単に追加できました。
AWS SNSでHTTPエンドポイントでメッセージを受け取ったときの出力結果メモ

# 前提

- 受信確認まで終わってること
    - 	【AWS SDK for PHP】AWS SNSでHTTPエンドポイントへの受信確認するまでの簡単なメモ - Qiita https://qiita.com/kure/items/b286b003050c326a1843


# メモ

```json
{
  "Type" : "Notification",
  "MessageId" : "xxxxxxxxxx",
  "TopicArn" : "arn:aws:sns:ap-northeast-1:xxxxxx:http-test",
  "Subject" : "kenmei",
  "Message" : "message",
  "Timestamp" : "2018-11-29T10:00:51.206Z",
  "SignatureVersion" : "1",
  "Signature" : "xx+xxxxxxx==",
  "SigningCertURL" : "https://sns.ap-northeast-1.amazonaws.com/SimpleNotificationService-xxxxxxx.pem",
  "UnsubscribeURL" : "https://sns.ap-northeast-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:ap-northeast-1:xxxxxx:http-test:xxxxxxx"
}
```
プログラミング初心者 Swift 関数とクロージャについて

# 関数とクロージャ
いつまでたっても関数を引数で呼ぶという作業をするときに手が止まってしまう長期インターン生です。
作業をしている最中に引数の扱い方が分からなくなったことが何度もある。
そこで、また手が止まってしまった時のためにキータにあげておこうとおもいます。
投稿する内容が教科書レベルなことばかりで恥ずかしい。
###処理の再利用
- 関数とクロージャはひとまとまりの処理を切り出し、再利用可能とするためのもの。
- 関数やクロージャは任意のタイミングで実行できるので、**重複した処理を１箇所にまとめ、可読性やメンテナンス性を高めることが出来る。**

## 関数
`名前を持ったひとまとまりの処理`

#### 定義方法
```swift
func 関数名(引数名1: 型, 引数名1: 型) -> 戻り値の型 {
    関数呼び出し時に実行される文
    必要に応じてreturn文で戻り値を返却
}
```
EX

```swift
func double(x: Int) -> Int {
    return x * 2
}

double(x: 2) // 4
```
#### 実行方法

```swift

関数名(引数名1: 型, 引数名1: 型)
```
- 引数名がない場合は引数だけを記述。
- 戻り値が定義されている関数を呼び出す場合、戻り値を変数や定数に代入する。
- 戻り値の代入を省略するとコンパイラが警告をだす。

```swift

let 定数名 = 関数名(引数名1: 型, 引数名1: 型)
```

### 引数
`関数への入力`
#### 仮引数と実引数
**仮引数**
関数の定義時に宣言するもの
**実引数**
関数の呼び出し時に指定するもの

この場合intが仮引数、１が実引数になる。

```swift
func printInt(int: Int) {
    print(int)
}

printInt(int: 1)
```

###外部引数名と内部引数名
引数名は関数の呼び出し時に使用する外部引数名と、関数内で使用される内部引数名の二つを持つことができる。
#### 定義方法
`外部引数名　内部引数名 : 型`

- 外部引数名は_で省略することができる。
- 外部引数名が_で省略されている場合は、引数名と引数で分けている:も省略して呼び出す

```swift
func sum(_ int1: Int, _ int2: Int) -> Int {
    return int1 + int2
}

let result = sum(1, 2)
```
###　デフォルト引数
`引数のデフォルト値`

- 引数にはデフォルト値を指定でき、デフォルト値を持っている引数は関数呼び出し時に省略できる。
- 引数のデフォルト値をデフォルト引数と呼ぶ。
- デフォルト引数を指定するには、**通常の引数宣言のあとに値の代入を追加する**

```swift
func eat(food: String = "カレー") {
    print("私は\(food)が食べたい")
}

eat()
eat(food: "ラーメン")
```
###　インアウト引数
`関数外に変更を共有する引数`
引数の型の先頭に`inout`を追加する。
インアウト引数を持つ関数を呼び出すには、インアウト引数の先頭に`&`を加える。

```swift
func start(user: inout String) {
    if user.isEmpty {
        user = "World"
    }
    print("Hello, \(user)!")
}

var user: String = ""
start(user: &user) // Hello, World!
```

### 可変長引数
`任意の個数の値を受け取る引数`

- 関数の呼び出し側に配列であることを意識させない
- 1つの関数につき最大1つの可変長引数を定義できる
- 引数定義の末尾に...を加えて定義する
- 引数を,区切りで渡す
- 可変長引数として受け取った引数は、関数内部ではArray<Element>型として扱われる。そのため、関数内での可変長引数へのアクセス方法は、Array<Element>型の要素へのアクセス方法と同様になる。

関数内部では、可変長引数の型は[String]として扱われている。

```swift
func print(strings: String...) {
    if strings.count == 0 {
        return
    }
    
    print("first: \(strings[0])")
    
    for string in strings {
        print("element: \(string)")
    }
}

print(strings: "abc", "def", "ghi")
//first: abc
//element: abc
//element: def
//element: ghi
```

### 戻り値
`関数の出力を表す値`
関数宣言での戻り値の型の指定は必須ではなく、戻り値が不要な場合は、関数宣言での戻り値の型を省略できる。

```swift
func start(user: String) {
    print("Hello, \(user)!")
}

start(user: "World") // Hello, World!
```
関数宣言で戻り値の型の定義を省略した場合、関数の戻り値はVoid型となる。

```swift
func start(user: String) -> Void {
    print("Hello, \(user)!")
}

start(user: "World") // Hello, World!
```
## クロージャ
`スコープ内の変数や定数を保持したひとまとまりの処理`
クロージャについては時間がある時やります:confounded:

最近は大学が忙しくて全くプログラミングに打ち込めていなかったので、これから空いてる時間を有効活用していきたい。あとインターンで手が止まる時間を減らしたい、、。

## 参考文献
[改訂新版] Swift 実践入門
MySQLでユーザ変数を使わずにRankのような動きをするSQLを作ってみた

最新のMySQLでは分析関数が使えるらしいが古いMySQLでは使えなかった為作ってみた。

#ユーザ変数を使わなかった理由について
MySQLのユーザ変数は評価順序が未定義の為、RowNumberやRankの動作に使ってはいけないという記事がちらほらあったのだが、マニュアル文の解説を読んでも動作保証されるのかどうか良く分からなかった。なのでとりあえず使用しないSQLで作成してみた。
『ユーザ変数では動作保証されないことを確認したわけではない』のでご注意を。

#要件
商品ごとの最新の仕入情報を最新から3件づつ出したい
同一仕入日の場合、搬入回数が多いものを優先する

#テーブル
**仕入情報**

|商品コード|仕入日|搬入回数|仕入数|
|:-:|:-:|:-:|:-:|
|A0001|2018/11/01|1|5|
|A0001|2018/11/02|1|5|
|A0001|2018/11/03|1|5|
|A0001|2018/11/04|1|5|
|A0002|2018/11/01|1|5|
|A0002|2018/11/01|2|5|
|A0002|2018/11/01|3|5|
|A0002|2018/11/01|4|5|
|A0003|2018/11/01|1|5|
|A0003|2018/11/01|2|5|
|A0003|2018/11/02|1|5|
|A0003|2018/11/02|2|5|

#サンプルSQL

```SQL
SELECT 
    商品コード
  , 仕入日
  , 搬入回数
  , 仕入数
  , 仕入日降順
  , 搬入回数順補正
  , 仕入日降順 - 搬入回数順補正 AS 順位
FROM (
    SELECT
        商品コード
      , 仕入日
      , 搬入回数
      , 仕入数
      , (/* 仕入日降順での順位 */
         SELECT 
             COUNT(*)
         FROM 仕入情報 仕入日降順
         WHERE 仕入情報.商品コード = 仕入日降順.商品コード
         AND 仕入情報.仕入日 <= 仕入日降順.仕入日
        ) AS 仕入日降順
      , (/* 仕入日が同じとき、仕入日ごとの搬入回数降順での順位 */
         SELECT 
             COUNT(*)
         FROM 仕入情報 搬入回数降順
         WHERE 仕入情報.商品コード = 搬入回数降順.商品コード
         AND 仕入情報.仕入日 = 搬入回数降順.仕入日
         AND 仕入情報.搬入回数 < 搬入回数降順.搬入回数
        ) AS 搬入回数順補正
    FROM 仕入情報 
) 仕入情報_順位付き
WHERE 仕入日降順 - 搬入回数順補正 <= 3 /* 順位が3以内の物を表示 */
ORDER BY 
    商品コード
  , 順位
```

#実行結果

|商品コード|仕入日|搬入回数|仕入数|仕入日降順|搬入回数順補正|順位|
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|A0001|2018/11/04|1|5|1|0|1
|A0001|2018/11/03|1|5|2|0|2
|A0001|2018/11/02|1|5|3|0|3
|A0002|2018/11/01|4|5|4|3|1
|A0002|2018/11/01|3|5|4|2|2
|A0002|2018/11/01|2|5|4|1|3
|A0003|2018/11/02|2|5|2|1|1
|A0003|2018/11/02|1|5|2|0|2
|A0003|2018/11/01|2|5|4|1|3

#解説
仕入日降順のサブクエリで商品コードごとの仕入日降順を取得している。
搬入回数順補正のサブクエリは、商品コード、仕入日ごとの搬入回数降順を取得している
仕入日降順は同一仕入日の場合は同じ値になるため、搬入回数順補正の結果分を減算することで順位をつけている
Linuxでパーティションにラベルをつけよう

パーティションにラベルを付けると管理でラクができます。
fstabを見ると「LABEL=/boot」とか書いてあることがありますよね。

代表的なext系ファイルシステムのラベルを操作するe2labelコマンドを紹介します。

# ラベルを確認する

```
e2label デバイス名
```

こんな感じで使います。

```
# e2label /dev/sda1
/boot
```

ラベルが付いて無い時には、以下のように空行が表示されます。

```
# e2label /dev/sda2

```

# ラベルを付ける

```
e2label デバイス名 ラベル
```

こんな感じで使います。

```
# e2label /dev/sda2 /hoge
```

確認してみましょう。

```
# e2label /dev/sda2
/hoge
```

# ラベルを変更する

これはラベルを付ける場合と同じです。

試しに変更してみましょう。

```
# e2label /dev/sda2
/hoge
```

これを

```
# e2label /dev/sda2 /fuga
```

こうすると

```
# e2label /dev/sda2
/fuga
```

変わったね！

# ラベルを削除する

このやり方が意外とどこにも書いてないんですよね。
以下のやり方で出来ます。

```
e2label デバイス名 ""
```

こんな感じで使います。

```
# e2label /dev/sda2 ""
```

確認してみましょう。

```
# e2label /dev/sda2

```

消えたね！
IM-FormaDesigner 明細テーブルの行挿入、削除、ドラッグアンドドロップ時に処理を行う

## IM-FormaDesigner 明細テーブル行操作

formaのクライアントサイドAPI、アクション設定カスタムスクリプトのどこを探しても
明細テーブルの行操作を行ったときのイベントハンドラがいなかったので、やってみました。

下記スクリプトを画面アイテム：スクリプトに張り付ければ使えます。

```javascript:formaTableEvent.js
// テーブル識別IDを指定 （formaでのテーブル識別ID）
var tableId = 'tb1'; 
var tableSelector = "[table_id='" + tableId + "']";
```
formaの明細テーブルはdomのidがランダムで振られますがtable_id属性が
formaから指定したものになっているので、それでdomを取得するようにします。


```javascript:formaTableEvent.js
// 行ドラッグアンドドロップ時、イベントバインド 
$(tableSelector).on("sortupdate", function( event, ui ) {
    imuiAlert("sortupdate");
});
```

ドラッグアンドドロップ実現にはjQueryUI sortableが使われているので、この辺の情報をかき集めて対応します。
https://api.jqueryui.com/sortable/#event-update

```javascript:formaTableEvent.js
// 明細テーブル内のtableタグidを取得
var domTableId = $(tableSelector + " table").attr("id");
// 既存の行削除イベント取得
var orgDeleteRowFunc = forma.table[domTableId].deleteRow;
// 既存の削除イベントと合わせて任意の処理実行
forma.table[domTableId].deleteRow = function(target) {
    orgDeleteRowFunc(target);
    imuiAlert("deleteRow"); // このへんにやりたいことを書く
};
```
行番号右クリックでメニューが出てますが、そこの行削除イベントはdeleteRowが呼ばれるようになっているので、そいつを上書きします。

```javascript:formaTableEvent.js
// 既存の行追加イベント取得 このイベントは「行挿入」、「コピーした行の挿入」内部で呼ばれている
var orgAddRowFunc = forma.table[domTableId].addRow;
// 既存の行追加イベントと合わせて任意の処理実行
forma.table[domTableId].addRow = function(position, copyInput) {
    orgAddRowFunc(position, copyInput);
    imuiAlert("insert or copyAndPaste"); // このへんにやりたいことを書く
};
```
このaddRowは「行挿入」「コピーした行の挿入」から呼ばれています。
Vue.js で日本語の PDF を生成する

## 環境
Vue： 2.5.17

## 日本語を使わない場合のミニマム実装
日本語を使わなくて良いなら、以下のような感じで速攻で作れる。
https://jsfiddle.net/eywraw8t/480739/

```
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.39/pdfmake.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.39/vfs_fonts.js"></script>
```

上記では便宜上、CDN から呼び出しているが、日本語を使わないなら普通に npm でインストールでも大丈夫。

pdfmake の公式サイトで、ブラウザ上からPDFの編集イメージが見られるのでオススメ。
http://pdfmake.org/playground.html

## 日本語を使いたい場合
まず、日本語を使用したい場合は以下に注意する必要がある。

- vfs_fonts.js を少しいじる必要がある
 - そのため npm 非推奨
- pdfmake の playground では日本語が文字化けるのであまり役に立たない
- 後述の手順を踏めば日本語が使えるようにはなるが、一部使用できない文字がある（ `〜` など）

## 完成イメージ
![スクリーンショット 2018-11-29 18.37.53.png](https://qiita-image-store.s3.amazonaws.com/0/57002/730062cd-0c88-7c15-cc50-c0f4a839cc4a.png)



## 日本語を使用するまでの手順
### ライブラリを導入する
- [pdfmake](https://github.com/bpampuch/pdfmake/blob/master/build/pdfmake.js) をダウンロードする
- 日本語対応済みの [vfs_fonts.js](https://github.com/naoa/pdfmake/blob/master/build/vfs_fonts.js) をダウンロードする
 - 自分で公式からフォークして作成しても良いが結構大変そうなので、先駆者のもの使用させてもらう

### ライブラリを読み込む

Vue のコンポーネントでは `<script>` タグが使えないので、以下のように生成することで実現できる。

```.js
created() {
	let pdfmakeScript = document.createElement("script");
	pdfmakeScript.src = `/pdfmake/pdfmake.min.js`;
	document.body.appendChild(pdfmakeScript);

	let fontsScript = document.createElement("script");
	fontsScript.src = `/pdfmake/vfs_fonts.js`;
	document.body.appendChild(fontsScript);
}
```

しかし、pdfmake.min.js の後に vfs_fonts.js を読み込まなければいけないようで、上記だとたまにエラーになる。
参考になった [issue](https://github.com/bpampuch/pdfmake/issues/910)

解決策として、index.html に以下のようにフルパスで定義すれば回避できる。

```
<script src="https://your-domain.jp/pdfmake/pdfmake.min.js"></script>
<script src="https://your-domain.jp/pdfmake/vfs_fonts.js"></script>
```

上記を実施する場合、ビルドされる場所にライブラリを格納する必要がある。

- ビルド前のパス例

```
/public/pdfmake/pdfmake.min.js
/public/pdfmake/vfs_fonts.js
```

- ビルド後のパス例

```
/dist/pdfmake/pdfmake.min.js
/dist/pdfmake/vfs_fonts.js
```

### PDF を生成する
あとは設定した日本語のフォントを設定するだけで、日本語の PDF が生成できる。

```.js
methods: {
    submit() {
		pdfMake.fonts = {
	        // 日本語が使用可能なフォントを設定
	        GenShin: {
	            normal: "GenShinGothic-Normal-Sub.ttf",
	            bold: "GenShinGothic-Normal-Sub.ttf",
	            italics: "GenShinGothic-Normal-Sub.ttf",
	            bolditalics: "GenShinGothic-Normal-Sub.ttf"
	        }
      	};
	    const defaultStyle = "GenShin";
    	const docDefinition = {
	        content: [
				{
					text: "ヘッダー",
					style: "header"
				},
				{
					text: "サブヘッダー",
					style: "subHeader"
				},
				{
					text: "文章",
					style: "sentence"
				},
        	],
        	styles: {
			    header: {
			        fontSize: 35,
			        alignment: "center",
			        margin: [0, 0, 0, 50]
		  		},
		  		subHeader: {
		        	fontSize: 20,
			        alignment: "left",
			        margin: [0, 0, 0, 10]
	      		},
	      		sentence: {
			        fontSize: 15,
			        alignment: "center",
			        margin: [0, 0, 0, 30]
	      		},
		    },
        };
        pdfMake.createPdf(docDefinition).download();
    }
}
```

## あとがき
これでなんとか日本語のPDFを生成できた。
PDF の文字量が多くなってくるとかなり苦行なので、不変な部分は画像にして読み込んだ方が効率的だと思う。
せめて公式の playground が日本語対応してくれれば。。