OmniAICreator/Qiita-1.07M huggingface dataset:
APIを含むNuxt.jsをHerokuへデプロイ 

# Heroku 設定
```
//App作成, _ は使えないので注意
$ heroku create {name}

//共通で必要な環境変数設定
$ heroku config:set NPM_CONFIG_PRODUCTION=false
$ heroku config:set HOST=0.0.0.0
$ heroku config:set NODE_ENV=production

//AxiosのBaseURL
$ heroku config:set API_URL=$(heroku info -s | grep web_url | cut -d= -f2)

//mongodbをmlabで利用する場合
$heroku addons:create mongolab:sandbox

//.envをherokuへ反映
$ heroku plugins:install heroku-config   //install 
$ heroku config:push

```

#設定ファイル修正
nuxt.config.js

```javascript

//setBaseURL for Axios
var env = process.env.NODE_ENV || 'development';
if (env === 'development' || env === 'test') {
  var API_URL='http://localhost:3000'
}
else{
  var API_URL=process.env.API_URL
}
module.exports = {
・・・略・・
axios: {
    baseURL:API_URL
  },
・・・略・・
```

package.json に追記　"heroku-postbuild"

```json
  "scripts": {
    "dev": "nuxt",
    ・・略・・
    "heroku-postbuild": "npm run build"　//追記
  },
```
# git commit 後、Heroku へデプロイ
```shell
$ git add .
$ git commit -m " comment for heroku deploy"
$ git push heroku master
```

#参考サイト
http://dackdive.hateblo.jp/entry/2016/01/26/121900
https://ja.nuxtjs.org/faq/heroku-deployment/
LaravelでSHOW COLUMNS FROM hogehoge

# やりたいこと

Mysqlで実行できるSHOW COLUMNS FROM hogehogeをLaravelでも実行したい。

ちなみにMysqlで実行するとこんなの。
サイトの権限管理用のrolesというテーブル。

```shell
mysql> SHOW COLUMNS FROM roles;
+------------+------------------+------+-----+---------+----------------+
| Field      | Type             | Null | Key | Default | Extra          |
+------------+------------------+------+-----+---------+----------------+
| id         | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| name       | varchar(191)     | NO   |     | NULL    |                |
| created_at | timestamp        | YES  |     | NULL    |                |
| updated_at | timestamp        | YES  |     | NULL    |                |
| deleted_at | timestamp        | YES  |     | NULL    |                |
+------------+------------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)
```

# やりかた

SHOW COLUMNS専用のメソッドが無いようなので、こうやるしかなさげ

```php
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\DB;

class Role extends Model
{
    protected $table = 'roles';

    use SoftDeletes;
    protected $dates = ['deleted_at'];

    public static function showColumns()
    {
        $role       = new Role;
        $sql        = 'SHOW COLUMNS FROM ' . $role->table;
        $columns    = DB::select($sql);
        var_dump($columns);
    }
}
```

結果

```
array(5) {
  [0]=>
  object(stdClass)#910 (6) {
    ["Field"]=>
    string(2) "id"
    ["Type"]=>
    string(16) "int(10) unsigned"
    ["Null"]=>
    string(2) "NO"
    ["Key"]=>
    string(3) "PRI"
    ["Default"]=>
    NULL
    ["Extra"]=>
    string(14) "auto_increment"
  }
  [1]=>
  object(stdClass)#911 (6) {
    ["Field"]=>
    string(4) "name"
    ["Type"]=>
    string(12) "varchar(191)"
    ["Null"]=>
    string(2) "NO"
    ["Key"]=>
    string(0) ""
    ["Default"]=>
    NULL
    ["Extra"]=>
    string(0) ""
  }
  [2]=>
  object(stdClass)#909 (6) {
    ["Field"]=>
    string(10) "created_at"
    ["Type"]=>
    string(9) "timestamp"
    ["Null"]=>
    string(3) "YES"
    ["Key"]=>
    string(0) ""
    ["Default"]=>
    NULL
    ["Extra"]=>
    string(0) ""
  }
  [3]=>
  object(stdClass)#913 (6) {
    ["Field"]=>
    string(10) "updated_at"
    ["Type"]=>
    string(9) "timestamp"
    ["Null"]=>
    string(3) "YES"
    ["Key"]=>
    string(0) ""
    ["Default"]=>
    NULL
    ["Extra"]=>
    string(0) ""
  }
  [4]=>
  object(stdClass)#915 (6) {
    ["Field"]=>
    string(10) "deleted_at"
    ["Type"]=>
    string(9) "timestamp"
    ["Null"]=>
    string(3) "YES"
    ["Key"]=>
    string(0) ""
    ["Default"]=>
    NULL
    ["Extra"]=>
    string(0) ""
  }
}
```
【Python】時間発展する箱の中の粒子



時間発展する箱の中の粒子を書きました

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">時間発展する箱の中の粒子を描いた 0≦x≦π<br>ψ(x,t) = 0.9φ1(x,t) + 0.1φ2(x,t) <a href="https://t.co/vK4TACGhOD">pic.twitter.com/vK4TACGhOD</a></p>&mdash; カルバニオン (@78910jqk13) <a href="https://twitter.com/78910jqk13/status/1022051833898921985?ref_src=twsrc%5Etfw">July 25, 2018</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

おもに参考にさせていただいた文献は

入門 量子ダイナミクス(上) 時間依存の量子力学を中心に
David J. Tannor (原著), 山下 晃一 (翻訳)
です。
Python3.6.3で書きました。

# 説明
時間に依存するSchrödinger方程式
<img width="400" alt="8FA459E4-67D5-4596-B255-9D0F55CCFD6E.jpeg" src="https://qiita-image-store.s3.amazonaws.com/0/257157/00bacd03-ba36-2eff-fa46-f94a72b5ce88.jpeg">

を満たすψはこれらの線形結合
<img width="400" alt="BC4C4B2D-0614-41F5-BECD-8C39C961AE5A.jpeg" src="https://qiita-image-store.s3.amazonaws.com/0/257157/0d07474b-ba9d-3084-26d3-448cd49156b0.jpeg">

も
<img width="400" alt="8FA459E4-67D5-4596-B255-9D0F55CCFD6E.jpeg" src="https://qiita-image-store.s3.amazonaws.com/0/257157/00bacd03-ba36-2eff-fa46-f94a72b5ce88.jpeg">
を満たします。
というわけで、0≦x≦πの箱の中の粒子のn=1のときの解をφa、n=2のときの解をφbとして、これら２つの線形結合
<img width="600" alt="14149350-A22F-4470-A3C3-B32C2529A168.jpeg" src="https://qiita-image-store.s3.amazonaws.com/0/257157/3a227e8f-3adf-b3bc-5035-e5c41157e273.jpeg">

の確率存在密度
<img width="900" alt="A94FB29A-F07B-4E77-B7D2-1E00F8FDADF8.jpeg" src="https://qiita-image-store.s3.amazonaws.com/0/257157/06009250-53b6-2eba-bdb5-d212fe47a30e.jpeg">

をグラフにしてみました。
今回はa=0.9,b=0.1としました。

# コード

```python:mixture.py
import matplotlib
matplotlib.use("Agg")
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

time,x = np.mgrid[-3.141592:3.141592:40j,0:3.1415:100j]
wavefunction1 = 1.414213 * np.sin(x) * np.exp(-1j * time)
wavefunction2 = 1.414213 * np.sin(2 * x) * np.exp(-4j * time)
wave_mixture = 0.9 * wavefunction1 + 0.1 * wavefunction2
probability_density_wave_mixture = np.conj(wave_mixture) * wave_mixture

#plot
fig = plt.figure()

imgs = []

for i in range(40):
	img = plt.plot(x[i],np.real(probability_density_wave_mixture[i]), linewidth =4, color="#2e0fc1")
	imgs.append(img)
	

ani = animation.ArtistAnimation(fig, imgs, interval=70)
ani.save("output3.gif", writer="imagemagick")
```
# 作業環境

Debian 4.9.82
Python3.6.3 Anaconda                                            

またgifの保存にはImagemagickを入れる必要があります。

```bash:
sudo apt-get install imagemagick
```

# 参考にさせていただいた本、サイト

入門 量子ダイナミクス(上) 時間依存の量子力学を中心に
David J. Tannor (原著), 山下 晃一 (翻訳)

[matplotlib でアニメーションを作る](https://qiita.com/yubais/items/c95ba9ff1b23dd33fde2)

[【python】水素様原子のpx軌道の存在確率密度plot](https://qiita.com/78910jqk/items/0c9bddd62c0cce955d4f)
mysql コマンドを実行できるようにしたいけど出来ないよ〜

mysqlコマンドを実行したいので以下を打った。


```
$sudo export PATH=/usr/local/opt/mysql@5.6/bin:$PATH
```
確認の
`which mysql`を打つと
/usr/local/opt/mysql@5.6/bin/mysql
とは出なかった。。。。

なので以下を参考にhome brewを入れ直した。

https://ema-hiro.hatenablog.com/entry/20170406/1491490645

入れ直して、以下のコマンドを実行！
```$ sudo cp /usr/local/opt/mysql@5.6/bin/mysql /usr/local/bin```

------------------
結果
/usr/local/opt/mysql@5.6/bin/mysql
が表示された！
やったね
console.logでJSON形式の値が[object Object]になる時

＊個人の記録用

```shell:こういうとき
console.log(value);
→[object Object]
```

```shell:中身を文字列化する
console.log(JSON.stringify(value));
→{"type":"THE_WORLD","dio":"WRYYYYY"}
```

@indometacinさん、コメントありがとうございます！
console.dirを使ってもJSON形式の値が確認できます。

```shell:console.dirでJSONの中身を確認する
console.dir(value);
→Object {type: "THE_WORLD", dio: "WRYYYYY"}
```
Ruby : 複数配列の要素ごとに演算する

割と悩んだので。
ベクトル和的なことやりたいとき

```rb
arr1 = [1, 2, 3]
arr2 = [4, 5, 6]

[arr1, arr2].transpose.map { |ele| ele.inject(:+) }
# => [5, 7, 9]
```

----

#### transpose

https://ref.xaio.jp/ruby/classes/array/transpose

配列縦に並べていって列要素ごとに新しい配列返す
配列の長さ違うとエラーになるので[zip](https://ref.xaio.jp/ruby/classes/array/zip)にする

```rb
[[1, 2, 3], [4, 5, 6], [7, 8, 9]].transpose
# [1, 2, 3]
# [4, 5, 6]
# [7, 8, 9]
# 列要素ごとに新しい配列返す
# => [[1, 4, 7], [2, 5, 8], [3, 6, 9]]

# これはエラー
[[1, 2, 3], [4, 5]].transpose
```

#### inject

https://ref.xaio.jp/ruby/classes/enumerable/inject

最初の要素と次の要素に対してメソッド実行、戻り値とその次の要素でメソッド実行、･･･で最後に結果返す
初期値指定もできる

```rb
# 初期値なし
[1, 2, 3, 4].inject(:+)
# 1 + 2 => 3
# 3 + 3 => 6
# 6 + 4 => 10
# => 10

# 初期値あり
[1, 2, 3, 4].inject(5, :+)
# 5 + 1  => 6
# 6 + 2  => 8
# 8 + 3  => 11
# 11 + 4 => 15
# => 15
```

----

最初のやつは

```rb
arr1 = [1, 2, 3]
arr2 = [4, 5, 6]

[arr1, arr2].transpose.map { |ele| ele.inject(:+) }

# transpose実行後
# [[1, 4], [2, 5], [3, 6]].map { |ele| ele.inject(:+) }
#
# mapで以下が実行されて戻り値が配列に格納される
# [1, 4].inject(:+)
# [2, 5].inject(:+)
# [3, 6].inject(:+)
# => [5, 7, 9]
```
EC-CUBE3.nでフォームの値をhiddenで持たせたいとき

例えば、

入力画面 -> 確認画面 -> 完了画面

みたいな遷移の時に確認画面でフォームの値をhiddenで持たせたいときは `type: hidden` を付与すれば良い。

例えば入力画面で以下のようにフォームを出力してたとする。

```twig
{{ form_widget(form.phone_number) }}
```

確認画面では以下のように記述するとhiddenでフォームが出力される。

```twig
{{ form_widget(form.phone_number, { type : 'hidden' }) }}
```

入力内容を画面にテキストで表示させたいときは別で出力させるコードを記述する。
入力内容は `.vars.data` で参照できる。

```twig
{{ form.phone_number.vars.data }}
{{ form_widget(form.phone_number, { type : 'hidden' }) }}
```

うまくいかない場合はtwig内でEC-CUBEのカスタムフォームが読み込まれているか確認しよう。

```twig
{% form_theme form 'Form/form_div_layout.twig' %}
```

それでもうまく行かない場合は `Form/form_div_layout.twig` の内容を確認してみるといいかもしれない。

`/src/Eccube/Resource/template/default/Form/form_div_layout.twig`
Chromeのwarningに関するメモ

### 自身の備忘録としてメモ

* Vue.jsで開発しているWebアプリにGoogle Chromeでアクセスしたら、以下のwarningが表示された

`[Deprecation] Using unescaped '#' characters in a data URI body is deprecated and will be removed in M71, around December 2018. Please use '%23' instead. See https://www.chromestatus.com/features/5656049583390720 for more details.
`

どうやらソース内で定義しているSVGの中で#を使用しているとダメらしい

※発生していた箇所一部抜粋`
  background-image: url('data:image/svg+xml;utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#8F9DB3"><path d="M7 10l5 5 5-5z"/><path d="M0 0h24v24H0z" fill="none"/></svg>');
`
fill="***#***8F9DB3" を fill="***%23***8F9DB3" にしたら、warningが表示されなくなりました。

そもそも、正しい書き方をしなくてはいけなかったのでしょうね

肝を冷やしたとある夏の一日
Install yum with rpm

## Motivation

```bash
$ yum install lsof
-bash: yum: command not found
```

## TL&DR;
1. Find rpm files from the following link: 
http://mirror.centos.org/centos/6/os/x86_64/Packages/
2. `wget` the rpm file
3. Install via `rpm -ivh *.rpm`

```
# wget http://mirror.centos.org/centos/6/os/x86_64/Packages/yum-3.2.29-81.el6.centos.noarch.rpm
# rpm -ivh yum-3.2.29-81.el6.centos.noarch.rpm
```

## Dependencies
```
# rpm -ivh yum-3.2.29-81.el6.centos.noarch.rpm
error: Failed dependencies:                                                                  
        python-iniparse is needed by yum-3.2.29-81.el6.centos.noarch                
        python-urlgrabber >= 3.9.1-10 is needed by yum-3.2.29-81.el6.centos.noarch
        yum-metadata-parser >= 1.1.0 is needed by yum-3.2.29-81.el6.centos.noarch                                                                                                                         
        yum-plugin-fastestmirror is needed by yum-3.2.29-81.el6.centos.noarch   
```

Then find all the `rpm` file on the link above, and install all of them using `wget` and `rpm`.

If they have recursive dependencies, try installing at a time.

```
# rpm -ivh yum-*.rpm
```

## Enable EPEL
Almost same as above...

```
# wget http://ftp-srv2.kddilabs.jp/Linux/distributions/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm
# rpm -ivh epel-release-6-8.noarch.rpm
```

## Update repository before installing package

```
# yum check-update
# yum update
```
gem install rails が実行できない

```
gem install rails --version='4.2.6' 
```
 を行うと、エラーが出たで。

```
ERROR:  While executing gem ... (Errno::EACCES)
    Permission denied @ rb_sysopen - /Users/〜〜〜
```

rails newを行うと、permission denied と怒られてしまった。。。。




試しに、`rails -v`を打つと以下と出た。

```
Rails is not currently installed on this system. To get the latest version, simply type:

    $ sudo gem install rails

You can then rerun your "rails" command.
```
多分、sudo gem install rails を打て！と言うことなんでしょう。
なので、
```
$ sudo gem install rails 
```
実行して、
`bundle update + bundle install` してみた

---------------------

動き申した！！！
やったね！
AWSでプライベートサブネットをTerraformで作ったらハマった

# AWSでプライベートサブネットをTerraformで作ったらハマった

AWS上にVPCでプライベートサブネットを作成し、VPNサーバに接続したらEC2やRDSに接続するはずなのだが、なぜか新しく作った環境ではVPNサーバ以降につながらなくなった？？なぜだ

- プライベートサブネット参考
  - [OpenVPNでリモートアクセスVPNする時の2種類のネットワーク設定を確認してみた](https://dev.classmethod.jp/cloud/aws/openvpn-network-settings/)
  - [NAT Gatewayによるアクセス元IPアドレスの固定](https://dev.classmethod.jp/cloud/aws/fix-sender-ip-address-with-nat-gateway/)

## デバッグ

VPNサーバからプライベートサブネット内のEC2にはつながるので、次の３者間でtcpdumpをとって通信を眺めてみた。

① ローカルからのSSH接続（テスト用）
```>ssh -i ~/.ssh/private.pem ec2-user@x.x.x.x -vvvv```

② ローカル～VPNサーバの通信観察
```$ tcpdump src host 10.8.0.x```

③ VPNサーバ～EC2の通信観察
```$ tcpdump src host 10.8.0.x```

これでわかったのは、ローカルPCからのSSHのパケットがVPNサーバまで流れていてEC2までは届いていないということ。

## 原因

現行サーバとTerraformで作ったサーバを比べていると、EC2の「送信元/送信先チェック」が有効になっていることに気づいた。これのせいでVPNサーバからほかのEC2への通信が遮断されていた。

## 解決

- TerraformでこういうEC2作るときは`source_dest_check`を`false`にしよう

```
resource "aws_instance" "my-server" {
  source_dest_check = "false"
}
```
POSIX sh 準拠のスクリプトを書くために shellcheck を導入した

# できごと

実装したshell scriptが、docker環境(alpine linux)で動作しなかった

# 原因

- alpine linuxのshellはash
- POSIX標準ではない記法をスクリプトに書いてしまったため、ashで動作しなかった

# 対策

shellcheck というshell用のlintツールがあるので、事前に確認しよう

# 使い方

homebrew でインストール

```.shell-session
$ brew install shellcheck
```

以下のコードで動作確認してみる

```test.sh
#!/bin/sh

if [[ ${HOGE} =~ fuga ]]; then
  echo "aaa"
fi
```

```.shell-session
$ shellcheck test.sh

In test.sh line 3:
if [[ ${HOGE} =~ fuga ]]; then
   ^-- SC2039: In POSIX sh, [[ ]] is undefined.
```

無事、`[[` はPOSIX標準記法ではないと怒られました
Railsの開発用Welcome画面をproductionでも出す

毎回検索してしまう、ので自分のキータに残すことにした。お久しぶりです。

ref: https://stackoverflow.com/questions/17964830/where-is-the-default-welcome-aboard-page-located-in-my-app

```ruby
Rails.application.routes.draw do
  get '/rails/info/properties' => "rails/info#properties"
  get '/rails/info/routes'     => "rails/info#routes"
  get '/rails/info'            => "rails/info#index"
  root to: "rails/welcome#index"
end
```
[Rails]Simple Calendarでカレンダー表示

#環境
ruby 2.4.4
rails 5.1.6

#Gem
[Simple calendar](http://excid3.github.io/simple_calendar/)
説明を参考にしつつ

```ruby:Gemfile
gem "simple_calendar", "~> 2.0"
```

```
bundle install
```

#表示
##コントローラー

```ruby:tasks_controller.rb
@task = Task.all
```

この辺は適宜変更

##ビュー
今回は週ごとの表示にします。
月ごと表示は`week_calendar`を`month_calendar`にするだけ。

```show.html.erb
  <%= week_calendar @task do |date, tasks| %>
    <%= date %>
    <% tasks.each do |task| %>
      <div>
        <%= task.title %>
      </div>
    <% end %>
  <% end %>
```

Taskテーブルに`start_time`があればこれでOKだが、ほぼ無いと思うので以下

```hoge.html.erb
  <%= week_calendar(attribute: :input_date, events: @task, number_of_weeks: 2) do |date, tasks| %>
    <%= date %>
    <% tasks.each do |task| %>
      <div>
        <%= task.title %>
      </div>
    <% end %>
  <% end %>
```

・`attribute: :column`　カラムの指定
・`events: @hoge`　インスタンス変数指定
・`number_of_weeks: int`　int週分を表示

あとは`<div>`の中身をイイッ感じにしてあげればOK

#参考
[【Rails】Simple Calendarを使ったカレンダー表示
https://qiita.com/mikaku/items/0971442a7308dc669122](https://qiita.com/mikaku/items/0971442a7308dc669122)

##他に使えそうなカレンダーGem
・[carender](https://medium.com/@kami_zh/rails-gem-carender-3e6c51e6d9a2)　→使い方がよくわからなかった･･･
・[fullcalendar](https://qiita.com/ShoutaWATANABE/items/3d0cddafadb4f275991e)　→JS、JQuery満載でわからない

#最後に
Googleアカウントが使えるなら、Googleカレンダー使った方が楽です！
カレンダーの埋め込みも出来ます。
rails5にしたらAWSのS3に画像をアップできなくなった際の治し方【undefined method `match' 】

# rails5で画像アップすると undefined method `match' 
## エラー内容

エラー分は以下の通りである。

```
undefined method `match' for nil:NilClass excluded from capture: Not configured to send/capture in environment 'development'

NoMethodError (undefined method `match' for nil:NilClass):

app/controllers/admins/attachments_controller.rb:37:in `upload_eyecatch'
```

## 原因
これらの記事を読んだところ AWS REGION を明示的に記入する必要があることがわかった。

https://stackoverflow.com/questions/37129020/aws-s3-integration-yields-undefined-method-match
https://github.com/ankane/pghero/issues/69
https://code.i-harness.com/ja/q/2368b3c

## 解決方法
環境変数 AWS_REGION を定義する

```rb:.env
AWS_REGION="ap-hogehoge-1"
```

こちらはお好みで Setting.aws.aws_region とアクセスしたい場合に設定ください。

```rb:development.yml
aws:
  alias: <%= ENV['AWS_ALIAS'] %>
  access_key_id: <%= ENV['AWS_ACCESS_KEY_ID'] %>
  secret_access_key: <%= ENV['AWS_SECRET_ACCESS_KEY'] %>
  region: <%= ENV['AWS_REGION'] %>
```

```rb:使用部分にこれを
  s3_option_private = {
    storage: :s3,
    url: ":s3_alias_url",
    s3_protocol: :https,
    s3_host_alias: Settings.aws.alias,
    s3_permissions: :private,
    s3_credentials: {
      bucket: Settings.aws.bucket,
      access_key_id: Settings.aws.access_key_id,
      secret_access_key: Settings.aws.secret_access_key
    },
    s3_region: Settings.aws.region #ここを追記する
  }
```


これで対応完了。

## 解決しない場合
rails c で環境変数が入っているかチェック

```rb:rails_c
Settings.aws.region
```
[UnityTest]UnityTestのPlayModeテストをコマンドラインから実行する

# 概要
統合テストを自動化するためにUnityTestRunnerのPlayModeをJenkinsで動かしたかったが、EditModeで動かす時は[公式のドキュメント](https://docs.unity3d.com/ja/current/Manual/CommandLineArguments.html)に書いてあるように、**-runEditorTests**を指定すればよかったが、PlayModeに関しては乗っていなかった。

出来ないと思って諦めてたが、調べてみたら隠し引数があるみたいで色々やってたら出来たので備忘録として掲載した。
~~どっかに書いてあったらUnityさんごめんなさい~~

# 環境
* Unity2017 4.3f1 Personal
* Mac

# やり方(Mac)
コマンドライン上で以下を叩く

```shell
/Applications/Unity2017/Unity.app/Contents/MacOS/Unity \
-batchmode \
-runTests \
-testFilter HogeTest \
-testPlatform playmode \
-projectPath ~/Unity/HogeProject/ \
-logfile ~/Unity/HogeProject/unitytest.log \
```
* -runTests
Unityのドキュメントに乗ってなかった引数その１
この引数を指定してあげれば、Playmodeで動いてくれるらしい(もしかしたら、EditModeとPlayMode関係なくすべてのテストが実行されてるかもしれない

* -testFilter
Unityのドキュメントに乗ってなかった引数その2
-runTestsだと全てのテストが実行されてしまうので、指定したテストのみを実行させたい場合に使う。
テストスクリプトのクラス名を指定する。
複数実行したい時はカンマ区切りで指定する。

* -testPlatform
Unityのドキュメントに乗ってなかった引数その3
実行時の環境を選択出来る。
※ちゃんと検証してないので、意味がないかも

とりあえずコマンドライン上でPlayModeのテストがなんとか動いてくれたので、UIのテストだったり、統合テストだったりの自動化が出来そう。

# 引用・参考元
[【Unity】”実機に出力したアプリ”の動作テストを自動化する](http://tsubakit1.hateblo.jp/entry/2017/12/11/233000)
[統合テストランナーとテストの分析について](https://blogs.unity3d.com/jp/2015/10/07/unified-test-runner-test-analytics/)
【簡易版】Docker Container 上のアプリケーションにスマホからアクセスする

## やりたいこと

ホスト上で開発しているときは，`docker-machine ip dev` で得られる IP アドレスで Docker Container 上のアプリケーションにアクセスできる．

例えば，アプリケーションが 8080 ポートを開放している場合は `http://192.168.99.100:8080/`　でアクセス可能
一方，スマホをホスト PC と同じネットワークに接続し，スマートフォンから `http://192.168.1.11:8080` ではアクセスはできない．

Rails の `-b` オプションみたいなことをやりたい

```bash
$ bundle exec rails s -b 192.168.1.11
```

`http:192.168.1.11:3000` で同ネットワーク上のスマホからアクセスできる


## 前提

- macOS High Sierra `10.13.5`
- Docker `18.03.1`
- Virtual Box `5.2.12`
- Docker Container 上で Python Bottle を動かしている

```index.py:python
from bottle import route, run, template, request, static_file, error

@route('/')
def home():
    return template('home')

run(host='0.0.0.0', port=int(os.environ.get("PORT", 8080)))
```

※ host='localhost' ではなく '0.0.0.0' とする必要がある

## VirtualBox 上で Port Forwarding 設定

Settings > Network > Port Forwarding で

![image.png](https://qiita-image-store.s3.amazonaws.com/0/31862/85dcc85a-f645-dcc5-b2f5-8506b578ade9.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/31862/fe021201-ef7e-5308-e3bb-4deae0e466b4.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/31862/1e724224-6d55-2aae-db53-baf2ba8dc683.png)


`http://192.168.1.11:4649` でアクセスができるようになる．
【Swift4】UITableViewで何度も同じ画像が表示されてしまうときの対処法

# はじめに
APIから複数の画像データをとってきて、CustomCellのUIImageViewに表示させたかったのですが、
何度も同じ画像が表示されてしまい困ったので、原因とその時の対処法を載せておきます。

<img width="325" alt="スクリーンショット 2018-07-25 17.12.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/112818/56879370-c7b2-f698-1269-388b5a4f2c1a.png">

#原因と対策
調べたところ、**セルが画像をキャッシュしてしまうこと**が原因のようでした。

そこで、CustomCellのファイルに画像を初期化するコードを追加します。
`prepareForReuse`は、非表示となって必要なくなったセルが再利用されるときに呼び出されるので、初期化処理を記述するのに適しています。

```swift

class CustomTableViewCell: UITableViewCell {

    @IBOutlet weak var hogeImage: UIImageView!
    
    override func awakeFromNib() {
        super.awakeFromNib()

        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

    // 追加
    override func prepareForReuse() {
        super.prepareForReuse()

        //画像を初期化
        hogeImage.image = nil 
    }

}
```

これで無事に正しい画像を表示することができました。

## 追記（2018/07/26）
コメントでご指摘頂いた通り、`prepareForReuse`の[Appleのドキュメント](https://developer.apple.com/documentation/uikit/uitableviewcell/1623223-prepareforreuse)には

>For performance reasons, you should only reset attributes of the cell that are not related to content, for example, alpha, editing, and selection state. The table view's delegate in `tableView(_:cellForRowAt:)` should *always* reset all content when reusing a cell.

との記述があり、今回の画像を初期化する処理も、パフォーマンス的な理由から`tableView(_:cellForRowAt:)`の中に書くのが適切なようでした:bow:


```swift
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "tableViewCell", for: indexPath) as! CustomTableViewCell
        //画像を初期化
        cell.hogeImage.image = nil
        return cell
}
```

直接内容に関係ない属性（例えばアルファ値、エディティングやセレクション状態など）であれば、`prepareForReuse`内でリセットしても良いとのことです。

# 参考:pray:
* [iOSアプリでやってしまいがちなバグと対策](https://qiita.com/musclemikiya/items/5528c2d2418ebeade7b4#uitableviewcell%E3%82%84uicollectionviewcell%E3%81%AB%E6%84%8F%E5%9B%B3%E3%81%97%E3%81%AA%E3%81%84%E7%94%BB%E5%83%8F%E3%81%8C%E8%A1%A8%E7%A4%BA%E3%81%95%E3%82%8C%E3%82%8B)
* [[iOS 10] UICollectionViewにおけるセルのライフサイクルの変更とPre-Fetching APIによるスムーズなスクロールについて](https://dev.classmethod.jp/smartphone/ios-10-uicollectionview-pre-fetching/)
phpMyAdmin インストールメモ

phpMyAdminを入れるときよく忘れるのでメモ

phpMyAdminの設定(パスワードとか)は範囲外。
インストール中にパスワードを設定するが全て統一して登録したので注意。

### 環境

* Ubuntu 16.04
* Mysql 7.0
* Apache/2.4.18 (Ubuntu)
* PHP 7.0.30

# phpMyAdmin インストール準備

## ApacheとPHPを入れる

```bash
$ sudo apt update
$ sudo apt install -y apache2
$ sudo apt install -y php php-mysql libapache2-mod-php
$ sudo systemctl apache2 restart
```

とりあえず`/var/www/html/phpinfo.php`を作成して
__http://localhost/phpinfo.php__に接続できるか確認。

```php
<!-- phpinfo.phpの中身 -->

<?php phpinfo();
```

## mySqlを入れる

```bash
$ sudo apt install mysql-server
## パスワードを設定
```

mySqlに入れるか確認。

```
mysql -uroot もしくは mysql -uroot -p
```

# phpMyAdmin インストール

本題。

```bash
$ sudo add-apt-repository ppa:nijel/phpmyadmin
$ sudo apt update
$ sudo apt install phpmyadmin
# 全て[yes]、パスワードを設定
```
インストールが終わったらapacheに認識させる。

```bash
$ sudo ln -s /etc/phpmyadmin/apache.conf /etc/apache2/conf-available/phpmyadmin.conf
$ sudo a2enconf phpmyadmin
$ sudo systemctl restart apache2
```

__http://localhost/phpmyadmin__で入れれば完了。

## apache conf-availableとconf-enabled

`conf-enabled`に`apache.conf`を持ってけばいいでしょと思ったけど、
基本動作は`conf-available`にコピー、リンクを作成し、`a2enconf`コマンドで有効にするらしい。
`conf-enabled`に直接コピー、リンクを貼っても動くには動く。

>conf-available: this directory contains available configuration files. All files that were >previously in /etc/apache2/conf.d should be moved to /etc/apache2/conf-available.
>
>conf-enabled: holds symlinks to the files in /etc/apache2/conf-available. When a configuration file >is symlinked, it will be enabled the next time apache2 is restarted.

参考:https://help.ubuntu.com/lts/serverguide/httpd.html
Android:「Could not determine java version from '10.0.1'」の対処方法


#はじめに
Android開発で、`./gradlew `を行う際に
`Could not determine java version from '10.0.1'.`
というエラーに遭遇いたしました。初心者のため備忘録を含め残したいと思います。

最初に今回参考にしたGitHubとなります。より正確な情報が記載されておりますので、よろしければご参照ください。

今回参考にしたGitHub:https://github.com/gradle/gradle/issues/5764

#①gradleのアップグレードを行う
https://gradle.org/install/#with-the-gradle-wrapper
上記公式の記事を参考に、

```Android:upgrade
$ ./gradlew wrapper --gradle-version=4.9 --distribution-type=bin
```
とすることで解決できるようでしたが、僕の場合は、当初のエラー同様に

<img width="814" alt="スクリーンショット 2018-07-25 16.48.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/226787/987a1102-e5a0-4d85-92ba-e9605345f5dd.png">

上記の通りとなり解決できませんでした。

#②gradle/wrapper/gradle-wrapper.propertiesのバージョンを変更する

```Android:gradle/wrapper/gradle-wrapper.properties


distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip

以下のように変更

distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-all.zip
```
<img width="652" alt="スクリーンショット 2018-07-25 16.53.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/226787/dcc0c6cc-7a46-fb38-01b6-0dc0a517c033.png">

上記のように変更し再度、


```Android:ターミナル
$ ./gradlew wrapper --gradle-version=4.9 --distribution-type=bin
```

とすることで殆どの方が解決されると思います。

以下は上記でも解決しなかったケースです。
gradle/wrapper/gradle-wrapper.propertiesのバージョンを変更しましたが、
僕のケースでは下記のエラーが返ってきました。

```Android:ターミナル
because of exception org.spockframework.util.IncompatibleGroovyVersionException: The Spock compiler plugin cannot execute because Spock 1.0.0-groovy-2.3 is not compatible with Groovy 2.4.12.
```
というエラーとなり、upgradeができませんでした。

http://ksoichiro.blogspot.com/2015/10/gradle-28spock.html
上記記事を参考にbuild.gradleを調整すれば無事にupgradeすることができました。

ご参考になれば幸いです。
Python3.7とDjango1系が一緒に使えない

# やろうとしたこと
DockerでDjango環境の構築
https://docs.docker.com/compose/django/#connect-the-database
公式に従ってやろうとした

# エラー

```bash
SyntaxError: Generator expression must be parenthesized
```

# 原因
Python3.7とDjango1系を併用してはいけないっぽい

# 解決策
Dockerfile

```docker
# ここが元々はFROM python:3になってるせいでPython3.7がインストールされてた
FROM python:3.6
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
ADD requirements.txt /code/
RUN pip install -r requirements.txt
ADD . /code/
```

# もし引っかかってからこの記事を見たら
誤って構成されたimageを消し、生成されたDjango関係のmanage.pyやディレクトリを消してからやり直しましょう
SeleniumのCapabilitiesリンク集（を作りたい）

# 概要

Seleniumを利用するときに設定できるCapabilitiesの値を探すのが面倒でした。
Capabilitiesリンク集を作り、このページから探せればと思い作成しています。

各ブラウザのオプション名はJavaの org.openqa.selenium.MutableCapabilities 内にある OPTION_KEYS から取っています。

後で簡単なcapabilitiesのjson記述サンプルも載せたい。

こんなのあるよってのがあれば、追加したいので教えていただきたいです。


# Selenium

- [DesiredCapabilities](https://github.com/SeleniumHQ/selenium/wiki/DesiredCapabilities) - Selenium本家

### json Example


# Chrome

- [Capabilities & ChromeOptions](https://sites.google.com/a/chromium.org/chromedriver/capabilities) - ChromeDriver用

### chromeOptions

- [List of Chromium Command Line Switches](https://peter.sh/experiments/chromium-command-line-switches) - argsの説明
- [Preferences](https://www.chromium.org/developers/design-documents/preferences) - prefsの説明
- [Configuring Other Preferences](https://www.chromium.org/administrators/configuring-other-preferences) - prefsの説明

### json Example

```json
[
 {
  "browserName": "chrome",
  "chromeOptions": {
    "args": [
         "headless",
         "disable-gpu",
         "proxy-server=http://proxy:8080",
         "remote-debugging-port=9222"
    ],
    "prefs": {
       "download.prompt_for_download":false
    }
  }
 }
]
```


# Firefox

- [WebDriver capabilities](https://github.com/mozilla/geckodriver/blob/master/README.md) - GeckoDriver用

### moz:firefoxOptions

- [コマンドラインオプション](https://developer.mozilla.org/ja/docs/Mozilla/Command_Line_Options) - argsの説明
- [About:config entries](http://kb.mozillazine.org/About:config_entries#Browser.) - prefsの説明

### json Example

```json
[
 {
  "browserName": "firefox",
  "moz:firefoxOptions": {
    "args": [
         "-headless"
    ],
    "prefs": {
        "browser.download.folderList": 0,
        "browser.download.useDownloadDir": true,
        "browser.download.manager.closeWhenDone": true
    }
  }
 }
]
```


# Internet Explorer

これといったものが見つからなかった・・・探し方が悪いかも。

### se:ieOptions

- [InternetExplorerOptions](https://seleniumhq.github.io/selenium/docs/api/dotnet/html/T_OpenQA_Selenium_IE_InternetExplorerOptions.htm) - ここのPropertiesの名前で試すくらい？

### json Example

```json
[
 {
  "browserName": "internet explorer",
  "se:ieOptions" : {
    "enablePersistentHover" : true,
    "requireWindowFocus" : true
  }
 }
]
```


# Edge

- [WebDriver](https://docs.microsoft.com/en-us/microsoft-edge/webdriver) - EdgeDriver用

### edgeOptions

### json Example


# Safari

これといったものが（略

### safari.options

### json Example


# Appium

- [Appium Desired Capabilities](https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/caps.md) - Appium本家

### json Example


# その他

- [WebDriver capabilities](https://w3c.github.io/webdriver/#capabilities) - W3Cの資料
Jpiereで帳票出力時のPDFにフォントを埋め込む

結論：日本語は埋め込めませんでした。



#環境
iReport 5.6.0
JPiere 4.1.0
Eclipse Version: Oxygen.2 Release (4.7.2)

埋め込むフォントにはMeiryo.ttfを使用しました。



#方法
基本的には参考サイト様にあります方法を試していきました。ただし、環境がJasperReportsだったり、使用しているサーバーが違ったりしたため、完璧に同じことが出来てはいません。


始めに試したのは[1つ目のサイト][link1]のPDF にフォントを埋め込む方法（Font extentionを使う）です。
こちらのサイトではiReportで行っており、個人的には一番期待が高かったのですが、ダメでした。

この際、.ttfを埋め込まなくてはならないということではあったのですが、PCにMeiryo.ttcしかなかった為、一度.ttcで試しております。なぜか問題なくフォント自体は登録されましたが、表示はされませんでした。その後、.ttfでも試しましたが結果は変わりませんでした。


次に試したのが公式サイトの[ここ][link2]です。試した結果、[エラー][link4]が出たので[ここ][link3]を参考にして修正しました。

当環境ではTomcatではなくJettyを使用していたため、.tomcatpluginにどうこうする部分は省いております。


以上のことを試した結果、PDFにフォントを埋め込むことは出来ませんでした。


iReport側では、この画像のように
<img width="268" alt="iReport-fontUI.png" src="https://qiita-image-store.s3.amazonaws.com/0/272245/c39d3ff3-b82b-84da-ed5f-9d87029c4fce.png">
２つフォントを指定できる場所があるのですが、
Font nameをメイリオにしたりMeiryoに、
Pdf Font name is now deprecated.~~~ を<Default>でなく空欄に、
日本語対応のHeiseiKakuGo-W5やHeiseiMin-W3にしてみたり、
PdfEmbeddedをtrueに、
Pdf Encodingを日本語に対応したUniJIS-UCS2-HW-H (Japanese)などにしたり
といろいろ試してみましたが、効果はありませんでした。

**実施例**

| Font name | Pdf Font name~ | PdfEmbedded | Pdf Encoding |
|:-:        |:-:|:-:|:-:|
| メイリオ | \<default> | false | CP1252 (Western European ANSI aka WinAnsi) |
| メイリオ | HeiseiKakuGo-W5 | false | CP1252 (Western European ANSI aka WinAnsi) |
| メイリオ | \<default> | True | UniJIS-UCS2-HW-H (Japanese) |
| メイリオ | HeiseiKakuGo-W5 | True | UniJIS-UCS2-HW-H (Japanese) |
|︙|︙|︙|︙|

Pdf Font name is now deprecated~~~は大抵の場合、変更するとエラーを吐きにきます。
PdfEmbeddedはあんまり関係がなさそうな感じです。
Pdf Encodingは、変更するとエラーが出たり、Pdfは出力されるけど表示されなかったり、文字が化けて?になったりというバリエーションはありました。
<img width="160" alt="iReport-fontByquestion.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/272245/250e439b-0961-ce38-dc99-902e07ec0c86.png">

とはいえ、Font nameに何かを指定していても、下の欄でFontをしっかり指定すると、Pdf出力時のフォントはそちらのフォントに代わっていたので、やっぱり特に弄らない場所な気がしています。

**以上。**



#参考サイト様
[link1]:http://blue-red.ddo.jp/~ao/wiki/wiki.cgi?page=JasperReports+%A4%C8+iReport
１．[FreeStyleWiki][link1]

[link2]:https://www.compiere-distribution-lab.net/2016/04/28/jpiere-0177-jasperreports%E3%81%ABipa%E3%83%95%E3%82%A9%E3%83%B3%E3%83%88%E3%81%AE%E8%BF%BD%E5%8A%A0/
２．[iDempiere Lab　JasperReportsにIPAフォントの追加][link2]

[link3]:https://www.compiere-distribution-lab.net/2014/01/08/idempiere-lab-jasper-report%E3%81%AE%E6%97%A5%E6%9C%AC%E8%AA%9E%E5%8C%96%E5%AF%BE%E5%BF%9C%E6%89%8B%E9%A0%86/
３．[iDempiere Lab　JasperReportの日本語化対応手順][link3]

[link4]:https://www.compiere-distribution-lab.net/jpiere-lab/customize/jasper/
４．[iDempiere Lab　JasperReportsにかかわるJPiereのカスタマイズ]()

５．[iDempiere Lab　PDFのレポートで日本語を出力する](https://www.compiere-distribution-lab.net/jasper-lab-0001/)

６．[日本JasperServerユーザ会](https://sites.google.com/site/japanjasperserverusergroup/documents/create_report_by_ireport/exceldatasource/pdfoutput)

７．[Tk2Kpdn Wiki　JasperReports 6 で PDF を作り、ブラウザーで表示する (5)](http://wiki.tk2kpdn.com/create-pdf-by-jasperreports6-and-java-p5/)

８．[Embedding fonts in jasper reports](http://blog.space-headed.net/2015/05/02/embedding-fonts-in-jasper-reports/)
API Blueprint で value に "_" が含まれていると、キーとして認識されてしまう件

#困ったこと
リクエストパラメータ等のデフォルト値の部分。
アンダースコア(_)が入ると何故かvalue値として認識されず、キー名になってしまった。

※HTML生成コマンド

```bash
aglio -i test.apib -o test.html
```

# 前提
Node.js v10.7.0
aglio 2.3.0
olio 1.6.3

## 例
```markdown
+ Request
    + Attributes
        + test_test: test_now (string) - テスト
```

##生成されたHTML
![スクリーンショット 2018-07-25 16.44.24.png](https://qiita-image-store.s3.amazonaws.com/0/108431/f810822e-ca44-4a9f-611b-e318cdd0e2ac.png)


# 状況
キー名にアンダースコアが含まれた状態でバリュー値にもアンダースコアが含まれると、誤認識されてしまう模様。

## ※キー名にアンダースコアなしの場合
![スクリーンショット 2018-07-25 16.44.08.png](https://qiita-image-store.s3.amazonaws.com/0/108431/56d5a0ba-f9da-9b3f-99d9-af0016a3dc2d.png)
→value値が悪さしてるわけでは無さそう



# 暫定対応
グレイヴ・アクセント（`）で囲うと正しく表示されました。
（これ、グレイヴ・アクセントって言うんですね）

## 例
```markdown
+ Request
    + Attributes
        + `test_test`: test_now (string) - テスト
```

## 生成されたHTML
![スクリーンショット 2018-07-25 16.47.21.png](https://qiita-image-store.s3.amazonaws.com/0/108431/bbf95945-7482-c5f7-f3b2-9ae153cf52bf.png)

ちゃんとvalue値が表示されました！

#原因
未調査。 勉強がてらやってみようか考え中。
nuxt.config.jsでpug-loaderにoptionsを渡す

### やりたかったこと
- Nuxt.jsでpugにoptionのbasedirを渡したかった
  - [API Reference – Pug](https://pugjs.org/api/reference.html#options)

### 有効だった書き方:ok_woman: 

```js
{
  build: {
    extend (config) {
      config.module.rules.forEach((rule)=> {
        if(rule.loader === 'vue-loader') {
          // vue-loaderのrule.options.templateから渡せる
          rule.options.template.basedir= path.resolve('templates')
        }
      })
    }
  }
}
```

### ダメだった書き方:no_good:
```js
{
  build: {
    extend (config) {
      // こう書いても動かない
      config.module.rules.push({
        test: /\.(pug)$/,
        loader: 'pug-loader',
        options: {
          basedir: path.resolve('templates')
        }
      })
    }
  }
}
```
ファイル更新時刻をもとにクエリストリングを自動生成する

## キャッシュとの戦い
デザイナーの変更が反映されていないのは、だいたいキャッシュのせい。
それも、ブラウザキャッシュです。
ウェブサーバーに設定を書いても、スーパーリロードしても、なぜか思うように消えないブラウザキャッシュとの戦い。

（´-`）.｡oO（つらい）

## URLの後ろに `?` をつける日々
URLにその都度クエリストリングを付加することで、ブラウザキャッシュを回避することはできます。
今どきのPHPフレームワークなら、自動でやってくれるでしょうが、素のPHPや古いフレームワークだと、それをいちいち手動でやらないといけません。

ただキャッシュさせないだけなら現在時間を使えばいいでしょうが、読み込みのためには、変更がないときは逆にキャッシュを使ってほしい。
デプロイした時間をどこかのファイルに書き込んで利用するのも手でしょうが、未変更のファイルまで読み込まれるのも困ります。

PHPの`filemtime` 関数で、最終更新時刻が取れるので、それを使いましょう。

## 実装（フレームワーク非依存）
[PHPのマニュアル](http://php.net/manual/ja/function.filemtime.php)によると`filemtime`関数はキャッシュするそうですが、[一度のスクリプト内のみキャッシュする](https://qiita.com/laineus/items/ae9c9117cbcbd5333035) らしいので、おそらく大丈夫でしょう……。


```hoge.php
class Util
{
    const PROJECT_ROOT = '/path/to/www_root';
    private static function getFileLastUpdateTime($path)
    {
        //一応ディレクトリトラバーサル対策
        if (preg_match('/\.\./', $path)) {
            return false;
        }
        return filemtime(realpath(self::PROJECT_ROOT . '/htdocs' . $path));
    }

    public static function getQueryStringPath($path)
    {
        $modified = static::getFileLastUpdateTime($path);
        if (!modified) {
            $modified = '';
        }
        return $path . '?' . $modified;
    }
}

// /path/to/www_root/htdocs/css/main.css の最終更新日を取得
echo Util::getQueryStringPath('/css/main.css');
// =>/css/main.css?1532503558
```
GAE/GoでPugを使おうとしてちょっとハマった

# GoでPugを使う

Go(GAE)でちょっとしたHTMLを返すアプリを作っているんですが、生HTML書きたくないのと`html/template`は避けたいのでPugのライブラリをさわってみました。

## Pug(Jade)ライブラリ
いくつかあるっぽいですが、以下の2つがメジャー?なようでした。

- [Joker/jade: Jade\.go \- template engine for Go \(golang\)](https://github.com/Joker/jade)
- [eknkc/pug: Go port of Pug \(jade\) template engine](https://github.com/eknkc/pug)

前者の方がPugとしての機能は充実してそうなんですが、今回そんなに複雑な機能はいらないのと、I/Fが後者の方がシンプルでこれで十分だなって思えたのでそちらを使うことにしました。

## `*.pug`ファイルへのpath

若干はまりました。
GAE+dupで開発しており、`GOPATH`以下にgoのソースをおいて、`app.yaml`があるディレクトリには`main.go`のみ、という構成にしていたので`*.pug`ファイルも`GOPATH`以下におこうとしてました。
`pug.CompileFile`の第二引数でdirを指定できるのでそれでやろうとしたのですが、GAEだとうまくいかなかったです。

```go
import (
  "net/http"
  "path/filepath"


  "github.com/eknkc/pug"
  "github.com/eknkc/pug/compiler"
)

func Render(w http.ResponseWrite) error {
  path, err := filepath.Abs("../lib/view")
  if err != nil {
    return err
  }
  t, err := pug.CompileFile("index.pug", pug.Options{Dir: compiler.FsDir(path)})
  if err != nil {
    return err
  }

  params := map[string]string{
    Key1: "foo",
    Key2: "bar",
  }
  if err := t.Execute(w, params); err != nil {
    return err
  }
  return nil
}
```

`compiler.FsDir`が`../`みたいのをうけつけないので、`filepath.Abs`で絶対パスを渡してあげます。
これだとlocalで`dev_appserver.py`とかする分には動きます。
ただdeployすると、`index.pug`にpermissionがないっていわれてエラーになってしまいます。
これはGAEだと読み込めるpathが制限されているからです。
`app.yaml`があるディテクトリ以下のファイルしか開けないようなので、そちらに`view`ディレクトリを作るようにします。

```golang
  path, err := filepath.Abs("view")
  if err != nil {
    return err
  }
  t, err := pug.CompileFile("index.pug", pug.Options{Dir: compiler.FsDir(path)})
  if err != nil {
    return err
  }
```

最初こんな感じで絶対パスにしてたんですが、これだと`app.yaml`以下であってもpermission errorになってしまい、動きませんでした。
絶対パスだと有無をいわさずダメっぽいですね。(documentに書いてありそうですがみつけられておらず…)
そもそも絶対パスは最早不要なので、素直に`main.go`からのpathを渡すようにします。

```go
import (
  "net/http"

  "github.com/eknkc/pug"
)

func Render(w http.ResponseWrite) error {
  t, err := pug.CompileFile("view/index.pug")
  if err != nil {
    return err
  }

  params := map[string]string{
    Key1: "foo",
    Key2: "bar",
  }
  if err := t.Execute(w, params); err != nil {
    return err
  }
  return nil
}
```

全体はこんな感じに。
だいぶスッキリしましたね!
これでGAE上でpugをrenderできるようになりました。
jQuery validation.js 使い方

###jQuery validation.js使い方

説明資料書くことがあったのでバックアップがてら載せておきます。

DLはここ

>[validation.js](https://jqueryvalidation.org/)

![48FD08BC-7376-4201-99A0-15C9493378DF.png](https://qiita-image-store.s3.amazonaws.com/0/260113/459b1fab-3555-5cdf-3a63-dac8dd54d083.png)
![20634304-F997-4754-97C2-E47297F4FF81.png](https://qiita-image-store.s3.amazonaws.com/0/260113/44cc8263-c614-c7cd-0443-4246c4414bc9.png)
![ED43A480-1928-4AF3-9A8F-38353465E1D3.png](https://qiita-image-store.s3.amazonaws.com/0/260113/873df2c0-acb1-73d2-ddf6-b79d65783874.png)
PHPExcelからPhpSpreadsheetへの移行ではまったところ

# はじめに
phpのバージョンを7.2に変えたところ今まで使っていたPHPExcelが使えなくなっていたので、これを機会にPhpSpreadsheetへの移行を行いました。
[PhpSpreadsheetの公式](https://phpspreadsheet.readthedocs.io/en/develop/topics/migration-from-PHPExcel/)に移行手順が載っていたので参考にしながら行いました。

#　環境
OS : AmazonLinux2
php : 7.2.8
ちなみにDockerで行いました。
[環境構築についてはこちらで](https://qiita.com/thimi0412/items/9df65e626e8df2029df5)

# インストール
```
$ composer require phpoffice/phpspreadsheet
```
私はcomposer.jsonに記述してインストールしました。

```
"phpoffice/phpspreadsheet": "*"
```
バージョンがわからなかったのでとりあえず`*`、結果としてバージョンは`1.3.1`が入っていました。

# はまったところ
[PhpSpreadsheetの公式](https://phpspreadsheet.readthedocs.io/en/develop/topics/migration-from-PHPExcel/)を見ながらプログラムを変更していき、実行したところ`ziparchive not found`のエラーが出ました。 PhpSpreadsheetの他記事などでは結構簡単そうに行っていたのですが、まさかのエラー。
とりあえずググって見たら、どうやら`php-zip`をインストールすればいいようです。

Dockerで環境構築したのでDockerfileに記述しました。

```dockerfile
RUN yum install -y \
          php72 \
          php72-php \
          php72-php-devel \
          php72-php-mbstring \
          php72-php-opcache \
          php72-php-soap \
          php72-php-mysqlnd \
          php72-php-pear \
          php72-php-zip    ← こいつ
```
自分は`yum install -y php72-php-zip`で入れましたが`php-zip`はphpのバージョンやAmazon Linuxのリポジトリなどで変わってくるので各自で調べてください。


ちなみに後で気づいたのですが[PhpSpreadsheetの公式](https://phpspreadsheet.readthedocs.io/en/develop/)に書いてありました。
<img width="527" alt="スクリーンショット 2018-07-25 16.17.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/166626/62d03310-5bbb-07f5-c23b-a09d85756186.png">
JavaScriptにおける関数合成・別解

[こちらの記事](https://qiita.com/ttatsf/items/ffa0b696bbe11963bd5e)の `reduceRight()` を使った `compose()` の定義は、関数に値を適用した結果の値をaccとして受け渡すという使い方をしていると思います。

しかし、合成された関数もまた関数であり、それも値としてaccで受け渡すことができるという発想をすれば、`reduce()` に `compose2()` をそのまま渡すという選択肢も出てきます。

`compose2()`を整数の加算 `+` と対比してみると、初期値 `0` の代わりになるものが何か考えれば良いわけです。

```js
[1,2,3].reduce((a,b)=>a+b, 0);  // -> 6
[add1, add2, add3].reduce(compose2, ???);  // -> add6
```

`0` はどのような整数と加算しても値の変わらない性質があるため `reduce()` の初期値に選ばれています。

```js
N + 0 == N
```

同じようにどんな関数と合成しても結果が変わらない関数があればそれを初期値として使えます

```js
compose2(f, ZERO) == f
```

答えは「引数をそのまま返す関数」です。
このような関数を一般的に恒等関数 `id` と呼ぶようです。（数学では「恒等写像(identity mapping)」）

```js
const id = (x) => x;
```

結論として、 `compose2()` と `id()` を使えば、任意の数の関数を合成する関数 `compose()` は以下のように書くとこができます。

```js
const id = (x) => x;
const compose2 = (f, g) => (x) => f(g(x));
const compose = (...fs) => fs.reduce(compose2, id);
```

ちなみに、この`compose`が実際に役に立った場面について書いた過去の記事はこちらです。
[関数合成Composeが初めて役に立った話](https://qiita.com/_shimada/items/667a0025767f35129093)
Macのpbcopyはもっと使えるというお話

別に大した話ではないのですが。

Macの`pbcopy`というコマンドをご存知でしょうか。

```
➜  ~ pbcopy
abc
kakaka
```

と打って、ctrl + d
で抜けるとそれがそのままクリップボードに保存されて、cmd + vで貼り付けることができるのです。

また、
`echo kuso | pbcopy`
と打ってもクリップボードに保存されるのです。


## 実用編

僕は業務で仕方なく、Bigqueryにクエリを投げることが多いのですが、
基本的に、

vi でクエリを書いて保存する
↓
cat a.sql
↓
出力した内容をコピー

という手順を踏んでいます。

ただ、最後のコピーの作業がちょっと面倒。
tmuxのコピーモードとやらでキーボード操作のみで行えているのですがやはり面倒です。

そこでふとpbcopyを思い出しました。
すると、

vi でクエリを書いて保存する
↓
cat a.sql | pbcopy

これで事足りたのです。

ただそれだけのお話でした。


以前、自分のブログに、
【MacでGoogleの2段階認証（ワンタイムパスワード）をコマンド一発で取得する方法】
https://chat-rate.com/oyakudachi/2915/　

というのを書いて、これくらいでしかこのpbcopyさんをつかっていなかったのですが、
ついさっき「こんなふうにも使えるなー」と感動したので書いてみました。



## 追記

投稿した後に、

「いや、絶対viだけでなんとかなるだろ」
って思って調べたところ、

`:%y`

と打つと、ファイル全体がヤンクされる模様。

とはいえヤンクじゃだめなので、

http://pky.jp/?p=24

このサイトを参考しようと思ったのですが、

```
➜  ~ vim --version | grep clipboard
-clipboard       +job             +path_extra      +user_commands
+eval            -mouse_dec       +statusline      -xterm_clipboard
```

`-clipboard`

・・・

有効にできなくもないんだろうけど、もう諦めましたｗ
Rubyの正規表現周りのメソッドいろいろメモ

# String#end_with?, String#start_with?

文字列の後方/前方一致をチェックするメソッド

こんなコードが

```.rb
/\.tar\.gz\z/.match?(path)
``` 

こう書ける

```.rb
path.end_with?('.tar.gz')
```

# String#delete_suffix, String#delete_prefix

後方/前方一致したら削除(ruby2.5から)


```.rb
path = 'hoge.tar.gz'
path.delete_suffix('.tar.gz') # => "hoge"
```

# MatchData#post_match, MatchData#pre_match

正規表現でマッチした前後の文字列を取得

```.rb
/bbb/ =~ "aaabbbccc"
$~.post_match # => "ccc"
$~.pre_match # => "aaa"
```
webpack4: ライセンスコメントを挿入したい

# 要望
webpackでビルドしたJavaScriptファイルの先頭に、バージョンやライセンスを表記したコメントを挿入したい。

```javascript:my-plugin.min.js
/*! my-plugin v1.2.3 | Yuusaku Miyazaki <toumin.m7@gmail.com> | license: MIT */
```

# 解決策
[BannerPlugin](https://webpack.js.org/plugins/banner-plugin/)を使います。
webpackに最初から入っていて、追加のインストールが不要なので楽です。

# 具体例
下記のようなプラグインを作っているとします。

```json:package.json
{
  "name": "my-plugin",
  "version": "1.2.3",
  "author": "Yuusaku Miyazaki <toumin.m7@gmail.com>",
  "license": "MIT",
```

下記のように設定します。

```javascript:webpack.config.js
const path = require('path');
const webpack = require('webpack');
const pjson = require('./package.json');

module.exports = {
  mode: 'production',
  entry: path.join(__dirname, 'src/index.js'),
  output: {
    filename: pjson.name + '.min.js',
    path: path.join(__dirname, 'dist')
  },
  plugins: [
    new webpack.BannerPlugin({
      banner: `${pjson.name} v${pjson.version} | ${pjson.author} | license: ${pjson.license}`
    })
  ]
};
```

`package.json`の内容は簡単に呼び出せるんですね。知りませんでした。
:link: [node.js - Is there a way to get version from package.json in nodejs code? - Stack Overflow](https://stackoverflow.com/questions/9153571/is-there-a-way-to-get-version-from-package-json-in-nodejs-code)

## 複数行のコメントの場合
混乱しないように、`raw: true`にして前後のコメント記号の挿入を阻止したほうがいいと思います。
:link: [オプションの説明](https://webpack.js.org/plugins/banner-plugin/#options)

```javascript:webpack.config.js
  plugins: [
    new webpack.BannerPlugin({
      banner: `
/*!
 * ${pjson.name} v${pjson.version}
 * (c) ${pjson.author}
 * license: ${pjson.license}
 */
`,
      raw: true
    })
  ]
};
```
PHPのmax関数をSQLで実現したい

```PHP
$a = 1;
$b = 3;
$c = max($a, $b);
$d = 2;

if ($c > $d) {
  print 'ok';
} else {
  print 'ng';
}
```

これ、SQLで実現しようと思うとめっちゃ面倒くさい

```sql
select case when a > b then a else b end
```

でも、null が入ってたら 演算結果 null になるんですよね……

```sql
select case when coalesce(a, 0) > coalesce(b, 0) then a else b end
```

```sql
select
    case
        when (select case when coalesce(a, 0) > coalesce(b, 0) then a else b end) > d
        then 'ok'
        else 'ng'
        end;
```

まだなんとかなったけど、演算とかいろいろ噛むと地獄になってくるよね

```sql
select max(t.a) from (select 1 as a union select 2 as a) t
```

こうすると、１つの値を２回かかなくてよくなる、PHPのmax関数と同じ挙動にできる
AlpakkaのGoogle Cloud Pub/Subコネクタを使う

GoogleからCloud PubSub用Javaライブラリが提供されているが、その代替として AlpakkaのCloud Pubsubコネクタがあったので使ってみることにする。

ちなみに先にJavaライブラリを簡単に確認しておくと、、

# Javaライブラリ
https://github.com/GoogleCloudPlatform/google-cloud-java/tree/master/google-cloud-clients/google-cloud-pubsub

## publisher
以下のような感じ。

```java
Publisher publisher = null;
try {
  publisher = Publisher.newBuilder(topic).build();
  ByteString data = ByteString.copyFromUtf8("my-message");
  PubsubMessage pubsubMessage = PubsubMessage.newBuilder().setData(data).build();
  ApiFuture<String> messageIdFuture = publisher.publish(pubsubMessage);
} finally {
  if (publisher != null) {
    publisher.shutdown();
  }
}
```

## subscriber

以下のような感じ。

```java
MessageReceiver receiver =
  new MessageReceiver() {
    @Override
    public void receiveMessage(PubsubMessage message, AckReplyConsumer consumer) {
      System.out.println("got message: " + message.getData().toStringUtf8());
      consumer.ack();
    }
  };
```

MessageReceiverインタフェースを実装する。
メッセージ受信するたびに、receiveMessageメソッドが呼び出されメッセージが渡ってくる。
メッセージが正しく処理されたら最終的にackを返す。

Javaライブラリを使ったSubscriberのプログラムは、メッセージ１件をどう処理するかというスタイルのコーディングとなる。

続いてAlpakka。

# Alpakka

## 公式ドキュメント
https://developer.lightbend.com/docs/alpakka/current/google-cloud-pub-sub.html

## Publisher

### 提供コネクタ
Akka StreamのFlowとしてCloud Pub/SubにPublishする部品が提供されている。

```scala
val publishFlow: Flow[PublishRequest, Seq[String], NotUsed] =
  GooglePubSub.publish(projectId, apiKey, email, privateKey, topic)
```

使うためには、５つの引数に適切な値が設定される必要がある。

- projectId・・・プロジェクトのID
- apiKey・・・GCPコンソールより[APIとサービス] - [認証情報] - [認証情報を作成] - [APIキー]で作成される「キー」情報を使用する
- email・・・プロジェクトを使用するIAMのメンバーのメールアドレス
- privateKey・・・GCPコンソールより[IAMと管理] - [サービスアカウント] - [サービスアカウントを作成] - [新しい秘密鍵の提供] - [JSON]でダウンロードされるjsonのprivate_key項目の値を使用する
- topic・・・Cloud PubSubのトピック名


### 使ってみる
プログラムは以下のような感じになる。
10件のメッセージをpublishするサンプル。メッセージIDが標準出力される。

```scala
val source: Source[PublishRequest, NotUsed] = {
  val msgs = (1 to 10).map { i =>
    PubSubMessage(messageId = i.toString, data = new String(Base64.getEncoder.encode(s"Hello${i}".getBytes)))
  }
  Source.single(PublishRequest(msgs))
}

val done: Future[Done] =
  source.via(publishFlow).runForeach(println)
```

## Subscriber
### 提供コネクタ
メッセージ源泉としてのSource部品。

```scala
val subscriptionSource: Source[ReceivedMessage, NotUsed] =
  GooglePubSub.subscribe(projectId, apiKey, clientEmail, privateKey, subscription)
```

Ackを返すSink部品。

```scala
val ackSink: Sink[AcknowledgeRequest, Future[Done]] =
  GooglePubSub.acknowledge(projectId, apiKey, clientEmail, privateKey, subscription)
```

なお、各種引数はpublisherのときと同様。ただし、5番目はサブスクリプション名を指定する。

### 使ってみる

3件分をまとめてAckを返すプログラム。
publishされたメッセージ内容見てないの微妙ですが。。

```scala
val done: Future[Done] =
  subscriptionSource
  .map(_.ackId)
  .grouped(3)
  .map(AcknowledgeRequest.apply)
  .runWith(ackSink)
```

### ちなみにCloud PubSubからはどうやってメッセージを受信しているのかな？

```scala:alpakka/googlecloud/pubsub/HttpApi.scala
// ・・・略・・・

val uri: Uri = s"$PubSubGoogleApisHost/v1/projects/$project/subscriptions/$subscription:pull"

val request = HttpApi.PullRequest(returnImmediately = true, maxMessages = 1000)

// ・・・略・・・
```

Cloud PubSubのWEB APIを叩いていて最大1000件がメッセージSourceとなるようだ。
JQueryで作る解除可能なラジオボタン(もう一度クリックで解除可能)

汎用的に使えるように作ってみました。

```javascript
 //解除可能なラジオボタン
  (function($) {
      $.fn.uncheckableRadio = function() {
          return this.each(function() {
              var radio = this,
                    label = $('label[for="' + radio.id + '"]');
              if (label.length === 0) {
                  label = $(radio).closest("label");
              }
              var label_radio = label.add(radio);
              label_radio.mousedown(function() {
                  $(radio).data('wasChecked', radio.checked);
              });
              label_radio.click(function() {
                  if ($(radio).data('wasChecked')) {
                      radio.checked = false;
                      $(radio).change(); //変更イベントを発生
                  }
              });
          });
      };
  })(jQuery);

  $(document).ready(function() {
      $('input[type=radio]').uncheckableRadio();
  });
```