OmniAICreator/Qiita-1.07M huggingface dataset:
Ruby の http クライアントの使い方 (Get)

faraday というライブラリーを使います。

## ライブラリーのインストール
Arch Linux

```bash
sudo pacman -S ruby-faraday
```

## プログラム

```rb:http_get.rb
#! /usr/bin/ruby
# -*- encoding: utf-8 -*-
#
#	http_get.rb
#
#					Nov/22/2018
#
# ---------------------------------------------------------------------
require 'faraday'
require 'json'
#
# ---------------------------------------------------------------------
STDERR.puts	"*** 開始 ***"
#
URL="https://httpbin.org/get"
#
res = Faraday.get URL

puts	res.status

json_str = res.body

dict_data=JSON.parse(json_str)
#
puts	"Host:\t" + dict_data['headers']['Host']
puts	"origin:\t" + dict_data['origin']
puts	"url:\t" + dict_data['url']
#
STDERR.puts	"*** 終了 ***"
# ---------------------------------------------------------------------
```

## 実行結果


```text
$ ./http_get.rb
Top level ::CompositeIO is deprecated, require 'multipart/post' and use `Multipart::Post::CompositeReadIO` instead!
Top level ::Parts is deprecated, require 'multipart/post' and use `Multipart::Post::Parts` instead!
*** 開始 ***
200
Host:	httpbin.org
origin:	219.126.135.100
url:	https://httpbin.org/get
*** 終了 ***
```

## 確認したバージョン

```text
$ ruby --version
ruby 3.0.5p211 (2022-11-24 revision ba5cf0f7c5) [x86_64-linux]

$ pacman -Q ruby-faraday
ruby-faraday 1.8.0-1
```
文字列の扱い〜Udemy~

#文字列の扱いルール

**文字列（stringクラスのオブジェクト）はクォーテーションで囲む**

```

・’シングルクォーテーション’の場合は、中にある式や変数を展開しない

・”ダブルクォーテーション”の場合は、中の式や変数は展開する

何れにしても囲むと、それは、stringオブジェクト: 文字列データ＋メソッド
```

---
＊・・・getsは入力された値を取り出すメソッド

-------

#2”バックスラッシュ記法”
・・・プログラム内に記述できない文字や記号などを出力する際に使われる改行とか文字列の中にクォーテーションやスペースを入れたい時使う

```
Macだとオプションキーと￥マークを使う

¥t・・・タブ

¥n・・・改行

¥”・・・ダブルクォーテーション

¥’・・・シングルクォーテーション

¥s・・・スペース

¥nnn・・・８進数表記

¥xnn・・・１６進数表記
```

---


#3"データ型の変換"  to_s(文字列に変換）を使う

**例えば**

```
a = “3”
b =  6

”３” ＋ ６　を実行する。するとエラーになる。

**”３”は文字列**で、**６は整数**であり、**データの型が違う**ので、合わせたものを出力するには**データの型を合わせる必要**がある。


**そこで　　　to_s(文字列に変換）を使う**

 **a + b.to_sとしてみる。その場合、bが文字列に変換される**
つまりここでは文字列の連結で”3” + “6”となり
>>３６とされる
```



また逆に

```
**文字列を整数に変換**してみる **to_i**を使う

**to_i(整数型に変換）　　:integerの意**
a=3
b="6"

a + b.to_i      ➡️3＋6
>>9
>>nil

a * b.to_i     　➡️3*6
>>18
>>nil
```
checkboxやradioボタンでデフォルトのデザインを変更する方法

# checkboxやradioボタンでデフォルトのデザインを変更する方法
割とよくやるので忘れないためにメモ。

## やりたいこと
このデフォルトのデザインから
<img width="118" alt="スクリーンショット 2018-11-22 14.56.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/163415/292a1a3a-f34e-76b3-3a82-d9ec19751f8f.png">
こんなかっこいい感じにしたい。。(かっこよくないけど。。。)
<img width="89" alt="スクリーンショット 2018-11-22 15.04.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/163415/ed84a17b-1012-93b8-ab89-20b09b029e90.png">

## コード
html

```html
<ul class="list">
  <li class="list__item">
    <label>
      <input type="radio" name="radio_button" class="input">
      <span class="text">ラジオ1</span>
    </label>
  </li>
  <li class="list__item">
    <label>
      <input type="radio" name="radio_button" class="input">
      <span class="text">ラジオ2</span>
    </label>
  </li>
  <li class="list__item">
    <label>
      <input type="radio" name="radio_button" class="input">
      <span class="text">ラジオ3</span>
    </label>
  </li>
</ul>
```

css

```.css
.list {
  list-style-type: none;
  padding: 0;
  margin: 0;
}

.input {
  display: none;
}

.text {
  position: relative;
}

.text:before {
  content: "";
  display: inline-block;
  width: 12px;
  height: 12px;
  margin-right: 6px;
  border: 1px solid #ff0000;
  border-radius: 50%;
}

.input:checked + .text:after {
  position: absolute;
  top: 3px;
  left: 3px;
  content: "";
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: #ff0000;
}

.input:checked + .text {
  color: #ff0000;
}
```

## ポイント
そこまで難しいことは何もないです。
まずinputをdisplay:none;で非表示にして、
.text:beforeで代わりになる丸い枠を作っています。

.input:checked + .text:afterの部分は
隣接セレクトですね。あまり使わないので忘れていましたが、
要素と要素が直接隣接している時に直後の要素(ここで言う.text:afterです。)に適用されるものですね。
なので、
checkedがついた時.textのafterにはこのcssが適用されますよ〜とちっこい丸が
.text:beforeの中に表示されるように作っています。

※言わなくてもわかるよって言われるかもしれませんが、labelタグで囲っているのでその範囲でクリックすればinputはcheckedになります。

## まとめ
以上で終わりです。
radioボタンのことしか書きませんでしたが、
checkboxもほぼ、いや、全く同じことをすればできるので試してみてください。
[plotly] FigureWidgetのSubplot化

# plotlyとは
plotlyはPython, R, Javascript などで使えるデータ可視化ライブラリです。
[ギャラリー](https://plot.ly/python/)を見てもらえればわかるように、レスポンシブにプロットを更新できるところに強みがあり、探索的なデータ分析に向いています。

# Figure Widget について
同じく探索的なデータ分析で有名なプラットフォームに[Jupyter notebook](http://jupyter.org/)がありますが、もちろんplotlyにはjupyter notebook用のプロットオブジェクトが提供されています。
それが[Figure Widget](https://plot.ly/python/figurewidget/)という機能で、一度座標を作成してしまえばデータやレイアウトを随時更新することができます。また座標上の特定のデータへのクリックイベントも検出することができるため、ユーザーの関心に合わせてインタラクティブにプロットを更新することも可能です。

# 今回作りたいプロット
今回作りたいのは散布図上の点を選択すると、その項目の年次推移、および地域別の売上をプロットの下部に表示するシステムです。
![ezgif-4-670be02dd65b.gif](https://qiita-image-store.s3.amazonaws.com/0/176789/b30a3ce6-8d96-0335-5cb8-761b6d377561.gif)


これはプロットへのクリックイベントの検出と複数のプロットをひとまとめにする（Subplot化）という2つの機能を合わせることで実現できます。しかしここで問題に突き当たります。クリックイベントを検出できるFigure Widgetはplotlyのsubplotに対応していない（＝複数のWidgetを一つのプロットにまとめることができない）のです。

# 解決方法
## 下にプロットを連結する
1. FigureWidgetを2つ用意する
2. display関数を2回続けて書く
3. 縦幅を調整したいときは`f.layout.height`で調整

```py

import plotly.graph_objs as go

f = go.FigureWidget()
f2 = go.FigureWidget()

display(f)
display(f2)
```

## 左右にプロットを連結する
1. プロットを追加するときにxaxis, yaxisに別名を指定
2. layoutのdomain要素でx軸を分離
3. 分離されたx軸にそれぞれy軸を対応させる（anchor）

こちらは少しややこしいです。実際のコードを見てみましょう。

```py
import plotly.graph_objs as go
import numpy as np

f = go.FigureWidget()

f.add_scatter(y=[2, 1, 4, 3])
f.add_bar(y=[1, 4, 3, 2], xaxis="x2", yaxis="y2")

f.layout.xaxis.domain = [0,0.7]
f.layout.xaxis2.domain = [0.7,1]
f.layout.yaxis2.anchor = "x2"
```

# コード
コード全文は[こちら](https://plot.ly/~khiroyuki1993/0)にあげています。
template literal example (es2015)

# template literal example (es2015)

```js
{
    const placeholder = `placeholder`;
    const understand = `this is template literal with \`back-tick\`. this is also ${placeholder } statement is replace from variables.
and enables to start newline without \\n statement.`
    const literal =()=>{return `in nested literal, enables to evaluate JavaScript itself`};
    const nestedLiteral = `this is nested ${literal()}`;
    console.log(understand);
    //this is template literal with `back-tick`. this is also placeholder statement is replace from variables.
    //and enables to start newline without \n statement.
    console.log(nestedLiteral);
    //this is nested in nested literal, enables to evaluate JavaScript itself
}
```
[MacOS X] 2018.3のJetBrains系のIDEでバックスラッシュを入力できなくなります！


JetBrains系IDEを使っている人は多いでしょう。
Intellij IDEA, PyCharm, CLion, RubyMineなどなど

Mac OS10.13以降であれば、2018.3までのアップグレードを控えた方がいいです。
なぜかというと、完全に"\"を入力できなくなります。
どう頑張っても"¥"しか出てこない。

私のキーボードの設定は"¥"のキーを"\"にしています。
<img width="663" alt="Screen Shot 2018-11-22 at 14.46.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/244432/0bdc2622-e972-1ab5-f009-ba252364be3e.png">
基本的にプログラムがそれにしてがっていますが、
Javaのアプリだとその設定を無視して、そのまま入力しようとすると¥のシンボルが入力されますが、Option+¥で"\"になってたんですが、
結構前からこのバグを作りました。
https://youtrack.jetbrains.com/issue/JRE-572

けれど、[とある修正](https://bugs.openjdk.java.net/browse/JDK-8191178)で完全にOptionのワークアラウンドも消えてしまいました。

なので、アップグレードを控えた方がいいと思います。
そしてJetBrainsにそのことを認識させるための協力お願いいたします。
これは致命的ですから
Rubyの概要〜Udemy~

Rubyの概要
----
***Rubyは全てのデータや命令をオブジェクト（変数＋メソッド）として扱う***

---------
Rubyのプログラム実行スタイル
---
```
１、テキストファイルにルビーの命令を書いて、.rbという拡張子をつけて保存して、ルビーコマンドで実行sる
テキスト状とコマンドプロンプト

２、対話式実行　　irb コマンド（インタラクティブルビー）を使うと、ターミナル状で対話的にエンターキーを押して動く



３、サーバー上で実行

>・HTMLファイルに埋め込んで実行　⇨ .erb  <%   %>    <%=  %>

>・単体で実行


4、スマホアプリやデスクトップアプリ

>・RubyMotion
>・JRuby+JavaFX+jrubyfx (JavaVMで動くRuby)
```
>いま　勉強しているのは主に1と３。


#フォルダ、ファイル作成の基本流れ
```
１、フォルダを作る際はホームから新規フォルダを選択し、名前をつけることができる

２、テキスエディタを立ち上げrて、ファイルにプログラムを書いて実行する

３、記述が終わったら保存するファイルを選択し、
  ファイルを保存する⇨ファイル名何とかかんとか.rb
  HTMLに埋め込む場合は.erb

```
index.htmlのScaleModeを変更してもデバッグでは動くが書き出すと反映されない

# 現象

こちら[アプリとデバイスのスクリーンサイズのあわせ方](https://qiita.com/motoyasu-yamada/items/5f333cbd87896b62a33f)の記事通り、`data-scale-mode`モードを変更してEgretWingでデバッグするとちゃんとスケールモードが適用されるのに書き出すとちゃんと適用されないという現象が発生しました

# 原因
`index.html`は複数あります。

|パス|説明
|----|----|
|/|プロジェクトルート|
|　index.html|EgretWingでのデバッグ時に使われる|
|　template/|書き出し時に使われる|
|　　runtime/|ネイティブアプリへの書き出し用|
|　　　index.html|これも書き換え|
|　　web/|HTML5書き出し用|
|　　　index.html|これも書き換え|

`data-scale-mode`に限らずFPSなどのindex.htmlに関する変更については、この3つすべてを書き換える必要があります。
GooglePlay定期購読でのアップグレード/ダウングレード Part1

GooglePlay定期購読のアップグレード/ダウングレードの仕様についてです。

# アップグレード/ダウングレードとは

GooglePlayでは[AppStoreのアップグレード/ダウングレード](https://qiita.com/natty420/items/b7cc167406813e9a3c00)よりもシンプルです。コースを乗り換えるという意味合いとなり、**価格が低いものから高い** ときに適用されるのが **アップグレード**、**価格が高いものから低いもの変更する** ときに適用されるのが **ダウングレード**です。
AppStoreと違い、アップグレード/ダウングレードすると即コースは変更されます。

## 仕様

|金額       |アイテム      |期間　　　　　　|
|:-----------|------------:|:------------:|
|300円           |アイテムA     |1ヶ月 　　　　　|
|600円           |アイテムB     |1ヶ月 　　　　　|

アイテムA→Bがアップグレード、B→Aがダウングレードです。

#### アップグレード
![googleplay_upgrade.JPG](https://qiita-image-store.s3.amazonaws.com/0/173676/0709c3c6-bf95-9a97-b2a6-b5243a2892e0.jpeg)

:one: Aを4/1に登録すると、次の更新日は5/1となる。:yen:300円の決済発生
:two: 4/10にBに乗り換える。この時点でBに変更となる。次の更新日は4/20となる。:yen:決済発生なし
　　　Bの有効期限の計算方法は以下の通り
　　　　Aの日割り金額が10円Bの日割り金額が20円である
　　　　Aを10日間利用したので10 * 10 = 100円分利用したこととなり、残金は200円となる
　　　　Bを200円で利用できる日数は 200 / 20 = 10日となる
:three: 4/20にBの更新が行われる。次の更新日は5/20となる。:yen:600円の決済発生

#### ダウングレード
![googleplay_downgrade.JPG](https://qiita-image-store.s3.amazonaws.com/0/173676/9351f5d1-eb2e-b31e-6e1b-2dbfd3a03bd2.jpeg)

:one: Bを4/1に登録すると、次の更新日は5/1となる。:yen:600円の決済発生
:two: 4/10にAに乗り換える。この時点でAに変更となる。次の更新日は5/20となる。:yen:決済発生なし
　　　Aの有効期限の計算方法は以下の通り
　　　　Aの日割り金額が10円Bの日割り金額が20円である
　　　　Bを10日間利用したので20 * 10 = 200円分利用したこととなり、残金は400円となる
　　　　Aを400円で利用できる日数は 400 / 10 = 40日となる
:three: 5/20にAの更新が行われる。次の更新日は6/20となる。:yen:300円の決済発生

## まとめ

GooglePlayでの課金コースの乗り換えは返金や追加のお金が発生せず、また即時の乗り換えが可能なのでユーザビリティがよさそうです。
次回はコースを乗り換えたかどうかをサーバ側でどう判定するかなどをまとめようとおもいます:sparkles:
Ansible: 値を(when:ではなく) if文を用いて条件によって変更する


例えば、trzファイルをリモートに展開する際、OSの種類により展開元ファイルを変更するとした場合、when:を使うと冗長となるが、jinja2のifなどを用いるとシンプルに書ける。

##whenを使用すると冗長


```yaml
- when: ansible_distribution == 'CentOS' 
  unarchive:
    src:  foo.trz
    dest: /qux

- when: ansible_distribution == 'Ubuntu' 
  unarchive:
    src:  bar.trz
    dest: /qux

- when: ansible_distribution not in ['CentOS', 'Ubuntu']
  unarchive:
    src: baz.trz
    dest: /qux
```

# 解1: jinja2のifを使用
jinja2のifを使用するとよりシンプルに書ける

```yaml

- unarchive:
    src: >-
      {%- if   ansible_distribution == 'CentOS' -%} foo.trz
      {%- elif ansible_distribution == 'Ubuntu' -%} bar.trz
      {%- else -%}                                  baz.trz
      {%- endif -%}
    dest:  /qux
```

- \>- はyamlの構文で、続く節を空白で繋ぎ、最後に改行を付けない。なお、インデントされた全体を""にて囲むならば\>-を削除可能。
- {%-  -%}はjinja2の構文で、内側ではjinja2の構文を含めることが可能、外側では前後の空白、改行を除去する。
    - 従って、もちろんfoo.trzなどを次の行としても可。お好みで。
- jinja2では、if, elif, else, endif, for, endfor, setなどが使用可能。

##jinja2をplaybookで使用する場合の考慮事項

- yamlそのものの構文をjinja2にて変更することはできない。
    - あくまでも値などyamlの一要素に対しての変更のみ。

この文章はjinja2の紹介の意図だったのですが、他の対応方法も追記しておきます。

# 解2: Hash|辞書|mapによる対応

```yaml
- vars:
    dist2src:
      CentOS: foo.trz
      Ubuntu: bar.trz
      else: baz.trz
  unarchive:
    src: '{{ dist2src[ansible_distribution]|default(dist2src.else) }}'
    dest:  /qux
```

task varsでHashにて対応を定義し、本文では単に参照。
この例のケースでは一番妥当かもしれません。
 
# 解3: python?によるif文対応

```yaml
- unarchive:
    src: >-
      {{
         'foo.trz' if ansible_distribution == 'CentOS' else 
         'bar.trz' if ansible_distribution == 'Ubuntu' else 
         'baz.trz'
      }}
    dest:  /qux
```

こんな書き方も可能。
リファレンスは何処に。。

# 解4: ternaryフィルターによる対応

```yaml
- unarchive:
    src: >-
      {{
        (  ansible_distribution == 'CentOS' )|ternary ( 'foo.trz' , (
         ( ansible_distribution == 'Ubuntu' )|ternary ( 'bar.trz' , 
                                                        'baz.trz' )
        ))
      }}
    dest:  /qux
```

3項演算子的に使用可能なternaryフィルターを利用する例。
可能ではあるが、読みにくい。
ansible_distribution == xxxx を括弧で括っているのは、フィルターの優先順位が==よりも高い為。


## 雑感

Ansibleでは色々な方法が使用可能であったりするが、何処を調べれば良いのか分からず、ひたすらググっては試さないといけない？

##参考
- [プログラマーのための YAML 入門 (初級編)](https://magazine.rubyist.net/articles/0009/0009-YAML.html)
- [jinja2: Template Designer Documentation](
http://jinja.pocoo.org/docs/2.10/templates/)
- [ほげめも: Ansible の Jinja2 を活用する](
http://blog.keshi.org/hogememo/2015/12/07/exploiting-ansible-jinja2) <- リスト(Array)やディレクトリー(Hash)に値を設定する場合には要注意。set _ = は set dummy = などと置き換えると混乱しないか。
- [Ansibleのregisterから任意のディクショナリやリストを生成する - Qiita](
https://qiita.com/isobecky74/items/40a2c5a7e89a45eeaf3b)
- [Ansibleで条件を使用して変数値を設定する方法を教えてください。 - 答えられる](https://steakrecords.com/ja/62251-how-can-i-use-a-condition-to-set-a-variable-value-in-ansible-ansible.html)
- [Other Useful Filters](https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#id8)
obnizのWebsocket APIを試してみる

Obniz Advent Calendar 2018 5日目の記事です。

obnizはWebsocket API、REST APIを公開しているため、Node.js以外でも操作することが可能です。

obniz.jsはバックエンドでWebsocket APIを叩いてますよ〜、とobnizの中の人に伺ったことがあります、確か。
obniz.jsで出来ることはAPIでも出来るはず！！ということで、Websocket APIを介してobnizを制御してみたいと思います。

## 【準備1】 obnizデバイスのセッティング

お手元のobnizをWi-Fiに接続しておきます。

## 【準備2】 Websocketの疎通確認を行う

Websocketの疎通確認を行うのに便利なツールは世の中にたくさんあるかと思いますが、私はGoogle Chrome拡張機能を使います。

[chrome web store](https://chrome.google.com/webstore/category/extensions)で「websocket」と検索すればいくつか出てくるので、良さげなものを追加します。

<img width="1263" alt="Screen Shot 2018-11-22 at 11.19.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/79577/e8605889-556a-64b6-24b4-35cfd2352330.png">


ちなみに私は[Smart Websocket Client](https://chrome.google.com/webstore/detail/smart-websocket-client/omalebghpgejjiaoknljcfmglgbpocdp)を使ってます〜。

## obniz Websocket API に接続する

[リファレンス](https://obniz.io/doc/about_obniz_api)より、接続先アドレスは `wss://obniz.io/obniz/{obniz_id}/ws/1` なので、自身の`obniz_id`に書き換えてWebsocket接続します。

<img width="826" alt="Screen Shot 2018-11-22 at 11.33.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/79577/940297be-f173-aa93-7665-6f1f311b3271.png">

何やら、リダイレクト先のURLが返却されたようです。
次は、返却されたドメインに置き換えて再度Websocket接続します。

<img width="822" alt="Screen Shot 2018-11-22 at 11.36.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/79577/63c489c2-daf0-198a-d727-91e8f6974153.png">

レスポンスを見る限り、接続はうまくいっているようです。

obnizのディスプレイに「Hello, obniz!」を表示してみます。
https://obniz.io/doc/sdk/doc/websocket#display

Request BobyにJSONデータを付与して接続します。

```json
[
    {
        "display": {
            "clear": true
        }
    },
    {
        "display": {
            "text": "Hello, obniz!"
        }
    }
]
```

<img width="863" alt="Screen Shot 2018-11-22 at 13.58.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/79577/f05a9820-d644-50b7-3ec2-accb2433f59a.png">


![IMG_20181122_115517.jpg](https://qiita-image-store.s3.amazonaws.com/0/79577/0417a427-384c-bfda-f8b1-29b42e4623a9.jpeg)

obnizのディスプレイに表示されたら成功です。
他の言語でobnizを触ることになったらぜひWebsocket API or REST APIを試してみてはいかがでしょうか。
Gitの時刻を日本式に表示する設定

私は米国人の中に必要性が存在しませんと考えます。

あなたが `git log` コマンドを実行すると、以下のようなコミットログが表示されます。

```
$ git log
commit 55bcdd4e7563e1041868703819006a9c86e9ae72
Author: Tnaka Taro <tanaka@example.com.com>
Date:   Thu Nov 22 12:04:50 2018

    ほげほげ

（以下略）
```

ここで、あなたは言語学の能力を発揮しなければなりません。つまり、"Nov" は何月目かです。 "november"という単語は"novem"（ラテン語の "9"）語源とする単語。ラテン人のカレンダーの年の始まりは2月です。だから "11月"は現代のカレンダーの（2 + 9 =）11月です。

しかしながら、我々はプログラマーであり、言語学のエクササイズをして給料を受け取りません。

`--date=iso-local` オプションはこの問題を解決します。日時が日本人に見慣れた形式（ISO8601）で表示されます。

```
$ git log --date=iso-local
commit 55bcdd4e7563e1041868703819006a9c86e9ae72
Author: Tnaka Taro <tanaka@example.com.com>
Date:   2018-11-22 12:03:53 +0900

    ほげほげ
```

この動作を恒久化するために、あなたはGitの設定を加えることができます。

```
$ git config --global  log.date iso-local
```

さらに、`--pretty=`オプションを用いることで、ログの他の部分を日本語で表示することが可能です。

```
$ git log --pretty='%C(yellow)コミット %H%n著者: %an <%ae>%n日時: %ad%n%n    %s%n'
コミット 55bcdd4e7563e1041868703819006a9c86e9ae72
作者: Tnaka Taro <tanaka@example.com.com>
日時:   2018-11-22 12:03:53 +0900
```

この設定も `git config` を用いて恒久化することができます。

```
git config --global format.pretty format:'%C(yellow)コミット %H%n著者: %an <%ae>%n日時: %ad%n%n    %s%n'
```

フォーマットの他の変更方法は[git-log Documentation](https://git-scm.com/docs/git-log) と[pretty-formats Documentation](https://git-scm.com/docs/pretty-formats)を読んでください。

なお、`--pretty` や `format.pretty` でログの書式を変えることは、オススメしません。
標準のフォーマットには、親コミットID・ブランチ名・タグ名などを動的に表示する機能がありますが、カスタムの書式では同じことが（おそらく）できないからです。
TypeScriptでnoUnusedParameterで消せない引数でエラーになった場合の対処法

TypeScriptの`noUnusedParameter`を`true`にした上で、下記のようなコードを書くと、indexを使用していないためコンパイルエラーが発生する。

```typescript
const foo: string[] = hoge.filter(
  // エラー発生
  (value: string, index: number, self: string[]) => {
    return self.indexOf(value) === 1
  }
)
``` 

しかしselfを使いたいためindexを削除することはできない。

この場合には変数名を`_`にすることでコンパイル時のチェックをしないようにできる。

```typescript

const foo: string[] = hoge.filter(
  // エラーは発生しない
  (value: string, _: number, self: string[]) => {
    return self.indexOf(value) === 1
  }
)
```
findしてtarしたけどファイルが全部アーカイブされていない

# 問題点
このようなシェルコマンドを打っていました。

```
find . -name "*hoge.cif" | xargs tar -cf myfile.tar
```

すると、``myfile.tar``ができたのでサーバーから落としてきてローカルで展開したところ、あれれ？ファイル全部入ってないぞとなりました。

```
find . -name "*hoge.cif" | wc -l
```
でファイル数を調べてみたらちゃんと８０００近くあるのに、

```
tar -tf myfile.tar | wc -l
```
でアーカイブされたファイル数を数えてみても1503しか入っていない。
問題はどうやら``xargs``の挙動みたいでした。

[findの結果をtarでアーカイブしたい](https://fei-yen.jp/maya/wordpress/blog/2013/01/15/find%E3%81%AE%E7%B5%90%E6%9E%9C%E3%82%92tar%E3%81%A7%E3%82%A2%E3%83%BC%E3%82%AB%E3%82%A4%E3%83%96%E3%81%97%E3%81%9F%E3%81%84/)

こちらのサイトを参考にしたところ、``xargs``は引数が多すぎるとバッファにためて実行を繰り返すみたいです。となるとずっとアーカイブファイルを上書きしてたってことか、、、。

# 解決策
上記サイトを参考に

```
find . -name "*hoge.cif" | tar -c -T - --null -f myfile.tar
```

とすれば解決！！
cloud9でvue-cli 3 環境構築

手元にChromebookしか無くなってしまったので、何か開発したいときはcloud9を活用しています。
今回、vue-cli@3環境をcloud9に構築した際に少し設定が必要だったのでメモ書いて置きます。

ちなみに、vue-cli@2の環境構築は[こちら](https://qiita.com/ultrasevenstar/items/2874ba37d72db605b487)の記事が参考になりました。

# Node.jsのversion up
[公式ドキュメント](https://cli.vuejs.org/guide/installation.html)によると、とりあえず version 8.11.0+ が推奨のようです。

> Node Version Requirement
>
> Vue CLI requires Node.js version 8.9 or above (8.11.0+ recommended). You can manage multiple versions of Node on the same machine with nvm or nvm-windows.

2018/11/22現在、cloud9におけるNode.jsワークスペースのnodeのversionはnvm含め以下となります。条件を満たしているものがありませんね:worried:

```shell
$ node -v
v6.11.2
$ nvm ls
        v0.8.28
       v0.10.48
       v0.12.18
         v4.8.4
->      v6.11.2
         v8.4.0
         system
default -> 6 (-> v6.11.2)
node -> stable (-> v8.4.0) (default)
stable -> 8.4 (-> v8.4.0) (default)
iojs -> N/A (default)
```

stableがv11.2.0のようですので、こちらをインストールします。

```shell
$ nvm version-remote stable
v11.2.0
$ nvm install stable
$ nvm current
v11.2.0
$ nvm alias default v11.2.0
```

# yarnをinstallする
これは完全に趣味ですが、yarnをinstallします。

```shell
$ npm install -g yarn
$ yarn -v
1.12.3
```

# vue-cli@3をinstallする
```shell
$ yarn global add @vue/cli
$ vue --version
bash: vue: command not found
```

パスが通っていないようなので、~/.bashrcに以下の内容を追記します。

```bash:~/.bashrc
export PATH="$PATH:`yarn global bin`"
```

```shell
$ source ~/.bashrc
$ vue -V
3.1.3
```

準備ができました。

# プロジェクトを作成する

プロジェクトの初期設定については今回触れないので、とりあえず`vue create`します。適当に選んで`Enter`を押して下さい。

```shell
$ vue create vue-cloud9
$ cd vue-cloud9
$ yarn serve
```

さて、cloud9あるあるですが、このままでは`http://<プロジェクト名>-<アカウント名>.c9users.io:8080/`でアプリケーションにアクセスできません。私の場合は`Invalid Host header`と表示されました。
そのため、vue.config.jsをvueプロジェクトディレクトリ直下に作成します。

```js:vue.config.js
module.exports = {
  devServer: {
    disableHostCheck: true
  }
}
```

再び`$ yarn serve`することで、アプリケーションにアクセスすることが出来ます:laughing:
Pandas DataFrameで一日分の行列を生成して時分秒も入れる

インターバルを1秒とした1日分の空のテーブルを作り時分秒のカラムに適切な値を入れるプログラムです．
生成後のデータフレーム行数は86400(= 24 x 60 x 60)となります．
普通に一行ずつ処理するとそれだけで1分とかかかっちゃうので処理時間若干早くなるように考慮．
手元のWindowsマシンで3秒くらいになりました．


```python:sample.ipynb
import pandas as pd
df = pd.DataFrame(index=range(86400),columns=['h','m','s'])

for h in range(24):
    df.loc[range(h*3600, h*3600+3600),['h']] = h

for ms in range(60):
    m_list = []
    for m_ in range(ms*60, ms*60+86400, 3600):
        m_list.extend(list(range(m_, m_+60)))
    df.loc[m_list,['m']] = ms
    df.loc[range(ms, 86400, 60),['s']] = ms

print(df)
```

時分秒のindexを算出してから一気に代入，ってところがポイントです．

 **実行結果**
 ![image.png](https://qiita-image-store.s3.amazonaws.com/0/105283/f8a6e2bb-e2b6-d4a9-93bd-720cbdebb0fd.png)
 [86400 rows x 3 columns]
Elasticsearch のプラグイン開発

Elasticsearch v6.4.2 でプラグイン開発するときの手順。

## 開発準備

### 開発ツール

- Elasticsearch v6.4.2
  - Docker image: `FROM docker.elastic.co/elasticsearch/elasticsearch:6.4.2`
- OpenJDK 11 のインストール
  - [Java SE Development Kit 11- - Downloads](https://www.oracle.com/technetwork/java/javase/downloads/jdk11-downloads-5066655.html)
- IntelliJ のインストール
  - [IntelliJ IDEA: The Java IDE for Professional Developers by JetBrains](https://www.jetbrains.com/idea/)
- Gradle のインストール

```bash
$ brew install gradle
```

### 開発環境構築

- Elasticsearch のソースを Github から clone する
  - [elastic/elasticsearch: Open Source, Distributed, RESTful Search Engine](https://github.com/elastic/elasticsearch)

インストール対象の Elasticsearch のバージョンをチェックアウト。IntelliJ にインポートする。

```bash
$ cd elasticsearch/
$ git clone -b v6.4.2 v6.4.2
$ gradle idea # 10分ぐらいかかる
```

IntelliJ のプロジェクト作成ウィザードでインポート

```
IntelliJ >
  Import Project >
    elasticsearch/ >
      Import project from external model >
        Gradle
```

インポートオプション

|Item|Value|
|----|-----|
|GradleJVM|11|

## プラグインを動かす
プラグインをビルドしてインストール可能な zip ファイルを作成する。

- [Help for plugin authors | Elasticsearch Plugins and Integrations [6.5] | Elastic](https://www.elastic.co/guide/en/elasticsearch/plugins/current/plugin-authors.html)
- [Installing Plugins | Elasticsearch Plugins and Integrations [6.5] | Elastic](https://www.elastic.co/guide/en/elasticsearch/plugins/current/installation.html)


### ビルド

サンプルの custom-settings-plugin をビルドしてみる。

```bash
$ cd elasticsearch/plugins/examples/custom-settings
$ gradle build
# または IntelliJ からビルド
$ ls build/distributions
custom-settings-6.4.2-SNAPSHOT.zip ...
```

### インストール

Elasticsearch を Docker で動かしている場合は volumes で上記の `build/distributions` ディレクトリをマウントする。

```bash
# build/distributions:/tmp/custom-settings-plugin にマウントしたときの例
$ elasticsearch-plugin install file:///tmp/custom-settings-plugin/custom-settings-6.4.2-SNAPSHOT.zip
-> Downloading file:///tmp/custom-settings-plugin/custom-settings-6.4.2-SNAPSHOT.zip
[=================================================] 100%?? 
-> Installed custom-settings

```

`GET /_nodes/_all/settings` を実行すると `custom.list` の値が追加されている。
PlantUMLでパッケージにコメントを付ける

クラス図をPlantUMLで書く際に、パッケージにコメントを付ける方法で結構手間取ったので備忘録に。

■テキストエディタ
Visual Studio Code


### そもそもコメントって

![plant_test-3.png](https://qiita-image-store.s3.amazonaws.com/0/270554/8d6288ac-43e6-87f5-e511-e3612fdb1fc8.png)

      class Class{
      }
      note bottom: コメント

なんぞやというのは上記のようにクラスにくっつけるメモのようなもののことです。
クラスの説明を書きたい時などに使えます。

bottom を right や left に変えることでメモの位置も変わります。
> note bottom: コメント
note right: コメント
note left: コメント


## パッケージにコメントを付ける

![plant_test.png](https://qiita-image-store.s3.amazonaws.com/0/270554/f6e0b07a-1e99-c863-3c29-b4399128399e.png)

      note "コメント" as comment
      folder "Package" as Package{
      }
      Package .. comment

packageではなくfolderを使うことでコメントを付ける事ができます。
手順としては

①コメントを宣言  

> note "コメント" as comment

② folderを宣言

> folder "A" as B {
}

③ folderにコメントを指定

> B .. comment

といった流れかと思います。
勿論folderの中にクラスを入れることも出来ます。

![plant_test-2.png](https://qiita-image-store.s3.amazonaws.com/0/270554/9451c271-a1e7-1943-9c91-a6242b1d910a.png)

      note "コメント" as comment
      folder "Package" as Package{
          class Class{
              property
              method()
          }
      }
      Package .. comment


クラスを入れると何故かレイアウトもちょっとpackageっぽくなります。


## 参考

http://forum.plantuml.net/7937/add-a-note-on-a-folder

http://www.plantuml.com/plantuml/uml/FSv12eD038NXVKxnc0Du1Y_Gkd5NYWmQRUXeolXSIF7krLQw-mX_ICgPCNCPaoJj2Jgo3G-YiwmjpIUHgrCHnXNJZe0uux8snr3a5Tjd71IXhkegu2r0xwdJZ42dDxqbdRyh_FaeW1kDTZ-vS3cuoIPoLYYA_urIfsv_xmC0
vue.jsでフォームを離脱するときに警告をだすやつを実装する

最近良く見る、フォームを離脱するときに出る警告をvue.jsで実装してみました。
![スクリーンショット 2018-11-22 13.49.05.png](https://qiita-image-store.s3.amazonaws.com/0/270996/47919177-0b7b-0ce1-9cef-7ead08f8fb20.png)


ナビゲーションガードの`beforeRouteLeave`を使うとできます。
`beforeRouteLeave`は、このコンポーネントを描画するルートが間もなくナビゲーションから離れていく時に呼ばれます。

```
beforeRouteLeave (to, from , next) { 
    const answer = window.confirm('編集した内容が消えちゃうけど移動しますか？(´・ω・｀)') |
    if (answer) { 
        next() 
    } else { 
        next(false)
    }
},
```

これだけで実装できちゃうので簡単ですね。
agora.ioを利用してrtmpサーバーへpushする

agora.ioのSDKでは独自プロトコルで映像を配信していますが、既存のRTMPサーバーへのpushも並行して配信できます。
OBSスタジオやWireCastのような配信アプリを作成する事が可能です。

#データフロー
![名称未設定.png](https://qiita-image-store.s3.amazonaws.com/0/300377/ff21ab8e-3bf3-1793-0a5a-6272a1a646dd.png)
図中の黒枠で囲んだ部分か今回の主な実装になります。

#開発環境
macOS Mojave 10.14.1
Xcode 10.1
ios 12.1
AgoraVideoSDK for iOS 2.3.1

#ソースコード
[Githubに公開しています](https://github.com/fu-jimoto/AgoraIO-RTMP-PUSH)
元のソースはSDKに内包されているサンプルプロジェクト(OpenLive-iOS)になります。

#実装内容
以下のコードを任意のタイミングで実行します。

```swift:LiveRoomViewController.swift
//描画サイズ,ビットレート,フレームレート等の設定
let transcoding = AgoraLiveTranscoding()
transcoding.size = CGSize(width: 720, height: 640)
transcoding.videoBitrate = 1024
transcoding.videoFramerate = 15
transcoding.lowLatency = true
transcoding.backgroundColor = UIColor .white
            
//配信uid,映像表示サイズ/位置等の設定
let localLayout = AgoraLiveTranscodingUser()
localLayout.uid = 1000;//Channelに接続した時のuid
localLayout.rect = CGRect(x:0, y:0, width:360, height:640);
localLayout.zOrder = 1;
localLayout.alpha = 1;
transcoding.transcodingUsers = [localLayout]

rtcEngine.setLiveTranscoding(transcoding)

//サーバーへの配信開始            
rtcEngine.addPublishStreamUrl("rtmp://[SERVER]/[APP]/[STREAM]",transcodingEnabled: true)
```

#出力
rtmp or HLSのプレイヤー上で720x640の領域内に360x640でスマホの映像が描画されています。
<img width="627" alt="スクリーンショット 0030-11-22 13.34.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/300377/468ca805-d772-32dc-3530-5f1a84db31ee.png">
(視聴側のプロトコルはRTMPサーバーの機能によります)



#最後に
[**agora.ioに関するお問い合わせはこちらから**](https://qiita.com/v-cube/items/39824adb4c9c0a4111f4)
[<img width="912" alt="スクリーンショット 0001-08-15 13.41.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300377/5d815376-9b89-08fa-9434-6fa7e8e67bcf.png">](https://qiita.com/v-cube/items/39824adb4c9c0a4111f4)
【jQuery】borderの切り替えにおける、firefox37.0以下で起きた問題

# 背景

* dl > dd

のボーダーの色を状態によって変えるということをjQueryで実装。
（動的に変遷させたかったので、とりあえずjQueryで組んでいた）

# 確認できた問題
```
$(data).parent().css('border-color',conf.chColor);
```
を指定したときに、textareaを入れていたddだけボーダー切り替わらない。

 
# 切り替えの判定条件

border-widthあるかどうか

  
# エラー時の反応

エラーメッセージなし。

その他も正常に働く

 
# 調査/推察

mozilla様のWeb開発者向け変更点一覧を確認。

詳細は読み解けなかったが、40.0か38.0の変更がborder辺りも触れているので境目はこの辺か。

  
# 結論

* バグは恐らく判定条件。

そもそもこういうのはcssで切り替えた方が安全かつ軽い。

＝ jQuery側で切り替える方が悪い

* バージョンの差分は目で見て確認するほうがいい
Unityでスクリプトを開くたびに、別のVisualStudio(VS)エディタが起動する問題

以下の内容の和訳と個人的解説つきです
https://answers.unity.com/questions/1078859/unity-keeps-opening-new-instances-of-microsoft-vis.html
***
原因は不明ですが、UnityのProject上からスクリプトを開く際に、すでにVisualStudioのエディタが開いているにもかかわらず、新しいエディタが開かれるということがありました

対処法は、今使用しているプロジェクトのあるフォルダに移行し`.csproj`と`.sln`の二つの拡張子のファイルを削除します
https://gyazo.com/b307ee8da1328f2f67462687701e6a18
この画像の下3つのファイルです
これらのファイルは、再度UnityでVSを開くと自動的に作成されます

その後Unityエディタを開きなおし、スクリプトをVSで開くと治っていると思います
Apache + uWSGI + Flask でHello World! @Amazon Linux 2

## 概要
Nginxを使いたかったけど既存環境がNginxでなかったので、Apacheを使ってFlaskを動かした話。
EC2の立ち上げについては他記事に投げてますすいません。

## 環境
- AMI : 4.14.62-70.117.amzn2.x86_64
- Apache : 2.4.34
- uWSGI  : 2.0.17.1
- Python :2.7.14

## EC2
ここら辺を読むとわかります。

> AWSでWebサーバー構築！EC2を作成してSSH接続する（第3回）
> https://miyabi-lab.space/blog/15

## Apache
EC2を建てると既にApahce2がインストールされているのでそのまま利用しました。

また、
/etc/httpd/conf.modules.d/00-proxy.conf
を見ると必要なモジュールが既に存在しているのでこれもそのまま利用。

```
LoadModule proxy_http_module modules/mod_proxy_http.so ←コレ
LoadModule proxy_hcheck_module modules/mod_proxy_hcheck.so
LoadModule proxy_scgi_module modules/mod_proxy_scgi.so
LoadModule proxy_uwsgi_module modules/mod_proxy_uwsgi.so ←コレ
```

リバースプロキシの設定を以下のようにし、/etc/conf.d/flask.confとして保存しました。

```
ProxyRequests Off //フォワードプロキシoff
ProxyPass /hoge uwsgi://127.0.0.1:8930 //転送設定
ProxyPassReverse /hoge uwsgi://127.0.0.1:8930 
```

詳しい説明は以下で、
>Apache 2.4 で リバースプロキシの設定
>https://qiita.com/gingi99/items/83c1fb07644cd232d91e

## uWSGI
以下のように最小限の設定にし、uwsgi.iniとして保存。

```ini
[uwsgi]
socket = 127.0.0.1:8930 #上記のProxyPassに合った設定を
module = app   #app.pyならapp main.pyならmainを設定する
callable = app #moduleで設定したファイル内のこの名前→app = Flask(__name__) 
master = True  #子プロセスが死んでもそれを蘇生する親プロセスを立ち上げる否かのフラグ
```

>Quickstart for Python/WSGI applications
>https://uwsgi-docs.readthedocs.io/en/latest/WSGIquickstart.html

## Flask

上記uwsgi.iniの設定通りにapp.pyを作成

```python

from flask import Flask

app = Flask(__name__)

@app.route('/')
def upload():
    return 'Hello World!'

if __name__ == '__main__':
    app.run()
```

## 実行

こんなディレクトリ構成になりました。

```
.
├── app.py
└── uwsgi.ini
```

apache再起動して、uWSGIを実行します。

```
sudo service httpd restart
uwsgi --ini uwsgi.ini
```

curlコマンドで確認して出てました。

```bash

curl http://example.com/hoge
Hello World!
```

以上、Amazon Linux 2はいろいろ勝手に入っててくれるので環境構築が楽でした。
間違いがあればご指摘おねがします。
RSpecのfeatureテストで、複数の商品のテストデータ作成を簡潔にする方法

#はじめに
RSpecのfeatureテストで、複数の商品のテストデータ(それぞれ違う商品名)を作成する際に役立つ方法を紹介します。

##いままで
下記のように各商品ごとに１つ１つテストデータを書いていました。

```ruby:spec/features/product_spec.rb
RSpec.feature "Hogehoge::Products", type: :feature do
  given(:cap_taxon) { create :taxon, name: "Cap" }
  given!(:caps_1) { create(:product, name: "Ruby Cap 1", taxons: [cap_taxon]) }
  given!(:caps_2) { create(:product, name: "Ruby Cap 2", taxons: [cap_taxon]) }
  given!(:caps_3) { create(:product, name: "Ruby Cap 3", taxons: [cap_taxon]) }
  given!(:caps_4) { create(:product, name: "Ruby Cap 4", taxons: [cap_taxon]) }
  given!(:caps_5) { create(:product, name: "Ruby Cap 5", taxons: [cap_taxon]) }
 

(以下省略)
```

##変更後
n.times.collectを使うことで、１行で書けるようになりました！

```ruby:spec/features/product_spec.rb
RSpec.feature "Hogehoge::Products", type: :feature do
  given(:cap_taxon) { create :taxon, name: "Cap" }
  given!(:cap_product) { 5.times.collect { |i| create(:product, name: "Ruby Cap #{i}", taxons: [cap_taxon]) } }


(以下省略)
```
Heroku Scheduler でnode.jsを動かす(追記:worker)

# Heroku Scheduler でnode.jsを動かす
## 目的
Heroku schedulerでnode.jsの定時実行を行いたい

## 前提
 - 動作確認環境
   - Windows10, VSCode
   - Node v8.11.3 (local)
   - Heroku
 - 参考
  - http://www.modeo.co/blog/2015/1/8/heroku-scheduler-with-nodejs-tutorial
  - https://devcenter.heroku.com/articles/scheduler


## Heroku Projectの作成、設定

Heroku Projectの作成、設定

```bash
node.jsプロジェクトフォルダで heroku create
> heroku create n2-sample-scheduler
Heroku sckedulerのインストール
> heroku addons:create scheduler:standard

package.jsonの作成
> npm init
```

## ジョブ用ソース作成
hello.js

```javascript:hello.js
#!/usr/bin/env node
function sayHello() {
  console.log('Hello hello.js');
}
sayHello();
```

npmコマンドの追加
package.json

```:package.json
  "scripts": {
 +     "job-hello":"node hello.js",

```

## Localで動作テスト

herolo localコマンドでテスト

```bash
> heroku local:run npm run job-hello
```

## Deploy to Heroku 
Herokuへアップロード

```bash
> git add .
> git commit -m "add job-hello"
> git push heroku master

```
動作確認( Heroku remote)

```bash
> heroku run npm run job-hello
```

ログ確認

```bash
> heroku logs 
```

## Heroku Schedulerの設定

Heroku Schedulerの設定

```bash

> heroku addons:open scheduler
```
- [Add new Job] > "npm run job-hello"を設定 
- FREQENCY = Every 10 minutes
- [Save]

10分後に実行されているかログを確認する

```bash
> heroku logs
```

## その他（随時追記）

### [mongoose] scheduleがスキップされることがある

- 原因
mongooseの接続が残っっていてプロセスが次のスケジュールまでに終わらない。

- 対策
Job終了時に接続を閉じること

```javascript
var mongoose = require("mongoose") 
// いろいろ処理される
//最後に切断
mongoose.disconnect()
```

### workerとcronを使ってもっと柔軟に実行したい
下記参考
 [worker Dynoを利用してNode.jsバッチを実装する](https://solutionware.jp/blog/2016/03/24/worker-dyno%E3%82%92%E5%88%A9%E7%94%A8%E3%81%97%E3%81%A6node-js%E3%83%90%E3%83%83%E3%83%81%E3%82%92%E5%AE%9F%E8%A3%85%E3%81%99%E3%82%8B/)

- procfile にworkerを定義
- cron パッケージを利用する

```bash:Procfile
worker: node worker.js
```

```javascript:worker.js
var CronJob = require('cron').CronJob;

var workerJob = new CronJob({
  cronTime: '*/10 * * * * *', //毎10秒実行
  onTick: function() {
    //ここに実行したい処理を書く
    console.log('Hoge !');
  },
  start: true, //newした後即時実行するかどうか
  timeZone: 'Asia/Tokyo'
});
workerJob.start();
```

デプロイ後 workerを有効にする
>  heroku scale worker=1 

ログ確認
>heroku logs

```bash
2018-12-13T16:20:30.016441+00:00 app[worker.1]: Hoge !
2018-12-13T16:20:40.008675+00:00 app[worker.1]: Hoge !
2018-12-13T16:20:50.010855+00:00 app[worker.1]: Hoge !
2018-12-13T16:21:10.008725+00:00 app[worker.1]: Hoge !
```
Laradock使わないでdocker-composeでnginx,laravel(php-fpm),mysql,redis,swaggerの開発環境を整える

何度目の車輪の再発明かわからないけど、laravelの開発環境、及び本番環境もコンテナ運用する想定でのファイル構成を作った。

## 要件

* 開発環境はdocker-composeで一発で立ち上がるようにしたい
* 本番環境（production build）もコンテナを作れる様に。
* laravelは基本APIサーバになるので、swagger(Open API)に対応して、swagger-uiも使えるようにしたい

## 作ったやつ

https://github.com/geerpm/php-docker-dev

```
/
├ docker ... 本番用docker構成ファイル群
├ docker_local ... 開発用docker構成ファイル群
├ laravel ... app本体
├ openapi.php ... openapi.ymlを更新するためのスクリプト
└ openapi.yml ... swagger-uiで使われる
```


## 解説

### 開発する時

* READMEどおりにsetup
* `docker_local`ディレクトリで`$ docker-compose up`すると、5コンテナが立ち上がり開発スタート出来る
* `laravel`ディレクトリのファイル編集したら`http://localhost`で確認できる
* mysqlはホストから、`$ mysql -uroot -p -h127.0.0.1 -P3306`でアクセス可能

> コンテナ間通信はコンテナ名で行われる `app`, `mysql`, `redis`等
> ホストからコンテナへのアクセスはポート番号。`http://localhost`(80), mysqlは3306等

### OpenAPI(swagger)について

* `http://localhost:8080`でswagger-uiにアクセス可能
* プロジェクトルートで、`$ php openapi.php`するとymlが更新され上記ui画面もリロードで確認可能

> SwaggerがOpenAPIになったので、名称等もろもろ変わる過渡期

### 本番用コンテナビルド

* `docker`ディレクトリの`docker-compose.yml`を使う
* 多分動かない。要調整
vue-router の ハッシュ(#) を消したい（vue-router で History API を使う）

# はじめに
VueCLI で作ったアプリ実行したときの vue-router で設定される、

![image.png](https://qiita-image-store.s3.amazonaws.com/0/81813/27ab50c9-06c4-c6ca-313d-830388f0e529.png)
　　　　　　　　👆 このハッシュ(#)やめたい


**環境情報：**
※ VueCLI で生成してそのまま

  * Node v6.11.3
  * WebPack v3.6.0
  * Vue,js v2.5.2
  * vue-router v3.0.1

# 手順

## 1. vue-router を history モードに設定
vue-router は、初期設定でURL のシミュレート（表記）を `'hash'`  モードにして、SPAを実現している。
これを `'history'` にすると、ハッシュ不要、[history API](https://myakura.github.io/dih5ja/history.html) を用いた方法でのURLシミュレートを実現できる。
モードの変換は /src/router/index.js に記載の、vue-router のインスタンス宣言のオプションに一行追記するだけ。カンタン。


```javascript:/src/router/index.js
 const router = new Router({
 + mode: 'history', // enable history mode
   routes: [
    ...
```

## 2. history モードによる副作用に対処する
history モードを使用すると、ローカルで実行している webpack-dev-server に Routingが設定されていないため、アドレスバーからハッシュの無いURL (ex: http://localhost:8080/home) にダイレクトにアクセスすると404エラーが発生する。
これに対して [connect-history-api-fallback Middleware](https://github.com/bripkens/connect-history-api-fallback) をインストールして対処する。

### 2-1. インストール

```console
 npm install connect-history-api-fallback --save
```

### 2-2. 実行コマンドを更新
npm-scripts の dev コマンドに`--history-api-fallback` を追記する

```json:package.json
 {
   ...
   "scripts": {
    "dev": "webpack-dev-server --inline --history-api-fallback --progress --config build/webpack.dev.conf.js",
     ...
```

以上で、`npm run dev` すればOK。

----

参考：
 [HTML5 History モード - vue-router 公式ドキュメント](https://router.vuejs.org/ja/guide/essentials/history-mode.html)
 [CLI: History API Fallback Option - GitHub](https://github.com/webpack/webpack-dev-server/tree/master/examples/cli/history-api-fallback)
 [vue-routerのルーティングURLからハッシュを除去しつつ、URL直接指定でも表示させる（Node, Express） - Qiita](https://qiita.com/uwettie/items/3766c7b3fb106e36f5df)
windowsでVagrant + MobaXtermをパッと起動する

# インストール
## 環境
- Windows 7

## 用意するもの

- [VirtualBox](http://www.virtualbox.org/)
- [Vagrant](https://www.vagrantup.com/)
- [MobaXterm](https://mobaxterm.mobatek.net/)

以上をそれぞれインストール

## 事前準備
1. VirtualBoxを起動し環境設定からデフォルトの仮想マシンフォルダーを肥大しても問題ないフォルダに変更する
2. 環境変数`VAGRANT_HOME`を設定する  
boxファイルを置く場所になるのでこれも肥大化しても問題ない場所へ
3. `Vagrantfile`を作る
  1. コマンドプロンプトを開き`Vagrantfile`を作りたいファルダへ移動  
  2. 環境変数`VAGRANT_HOME`が適用されているか確認すること
  3. `vagrant init centos/7`
  4. VirtualBoxを使う場合ついでに`vagrant plugin install vagrant-vbguest`も実行しておくとよい
  5. `vagrant up`で起動のテスト
  6. `vagrant ssh`でログインのテスト
  7. `vagrant halt`で停止

# Vagrantを起動してMobaXtermで接続 さらには切断したら自動でhaltまでしてほしい

```bat
@echo off
@rem Vagrantfileのあるフォルダを指定
cd /d F:\DEV\VM\centos7
vagrant up
vagrant ssh-config > vagrant-ssh-config
cmd /c ""C:\Program Files (x86)\Mobatek\MobaXterm\MobaXterm.exe"^
  -exec "ssh -A -F `cygpath %cd:\=/%/vagrant-ssh-config` default""

@rem MobaXterm終了時にhaltする
vagrant halt
```
ローカルでCDNのBootstrapVueを試そうとしたらハマった

Bootstrap Vueに限った話ではないが、小一時間消耗したのでメモ

Bootstrap Vueを使う方法はいろいろあるが、手軽に試したかったのでCDN版を試した。
https://bootstrap-vue.js.org/docs/
の「Browser」に導入の仕方が書いてある (2018/11時点)

```html:
<!-- Add this to <head> -->
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css"/>
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.css"/>

<!-- Add this after vue.js -->
<script src="//unpkg.com/babel-polyfill@latest/dist/polyfill.min.js"></script>
<script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.js"></script>
```
ローカルに作成したindex.htmlの`<head>タグ`の内側にcssを、`<body>タグ`にjsの読み込みを追加。Vueのインスタンス生成を記述。

Bootstrap Vue コンポーネント Collapseのサンプル：
https://bootstrap-vue.js.org/docs/components/collapse
も貼り付けて保存。

ブラウザで開いてみたが、CSSとJSが上手く適用されなかった。

問題は、CDNのURLを記入するところで**プロトコル(http or https)を省略していたこと**だった。css読み込みのhrefの箇所と、js読み込みのsrcの箇所に`https:`を追加したら上手く適用された。


```html:index.html
<!doctype html>
<html lang="jp">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-with, initial-scale=1, shrink-to-fit=no">
    <meta http-equiv="content-type" content="text/html; charset = UTF-8">
    <title>My first Bootstrap-Vue app</title>
    <link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
    <link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.css" />
</head>

<body>
    <div id="app">
        <b-btn v-b-toggle.collapse1 variant="primary">Toggle Collapse</b-btn>
        <b-collapse id="collapse1" class="mt-2">
            <b-card>
                <p class="card-text">Collapse contents Here</p>
                <b-btn v-b-toggle.collapse1_inner size="sm">Toggle Inner Collapse</b-btn>
                <b-collapse id=collapse1_inner class="mt-2">
                    <b-card>Hello!</b-card>
                </b-collapse>
            </b-card>
        </b-collapse>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/babel-polyfill@latest/dist/polyfill.min.js"></script>
    <script src="https://unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.js"></script>
    <script>
        var app = new Vue({
            el: '#app',
            data: {
                message: 'Hello Vue!'
            }
        })
    </script>
</body>

</html>
```
⇒ 期待する表示になった

調べたら`http:`、`https:`を省略して参照先URLを書くと、参照元の接続プロトコルを補完してリンクしてくれるらしい。ローカルのファイル参照(?)プロトコルは`file`であるため、上手くいかないのは当然だ。


すでに、書いてる人がいた。

* [jQueryライブラリをCDNで読み込んでローカルで動作確認する時に注意すべきこと](https://azunobu.hatenablog.com/entry/2015/06/07/031800)
* [CSSやJavascriptを読み込む時httpやhttpsを省略する](https://qiita.com/su_mi/items/d3c0b5319d6b3c41db11) のコメント
Laravelローカル開発環境構築メモ(laravel/homestead)

Laravelのローカル環境をLaravel Homesteadで構築した際の自分用メモ

## 前提条件
- Windows 10 Enterprise
- VirtualBox version 5.2.22
- Vagrant version 2.2.0
    - vagrant-vbguest version 0.16.0
- cygwin version 2.10.0-1
- git version 2.17.0
- rsync version 3.1.2

## 手順
### ディレクトリ作成

```
mkdir hoge
cd hoge
// laravelのプロジェクトの共有ディレクトリとする
mkdir app
```

### Homestead Vagrant Boxのインストール
- 使用するプロバイダを聞かれるので、virtualboxを選択する
- 以下のようなエラーが出る場合は、再度コマンド実行すれば、途中から再開可能
    - OpenSSL SSL_read: SSL_ERROR_SYSCALL, errno 10054

```
vagrant box add laravel/homestead
```

### Homesteadのインストール
```
git clone https://github.com/laravel/homestead.git
cd homestead
git checkout v7.19.2
```

### Homestead.yamlの設定
```
bash init.sh
copy Homestead.yaml Homestead.yaml.org
vi Homestead.yaml
```

```diff.txt
diff Homestead.yaml.org Homestead.yaml
4c4
< cpus: 1
---
> cpus: 2
13,14c13,14
<     - map: ~/code
<       to: /home/vagrant/code
---
>     - map: ../app
>       to: /home/vagrant/hoge
17,18c17,19
<     - map: homestead.test
<       to: /home/vagrant/code/public
---
>     - map: hoge.local
>       to: /home/vagrant/hoge/public
>       php: "7.2"
21c22
<     - homestead
---
>     - hoge
```

### Vagrant 起動
```
vagrant up
```

### 仮想環境にSSH接続
```
vagrant ssh
```

### laravelプロジェクト作成
```
cd /home/vagrant/
composer create-project --prefer-dist laravel/laravel hoge
```

### 動作確認
- ホストPCから[http://192.168.10.10/](http://192.168.10.10/)にアクセスして、以下の画面が表示されればOK
![laravel-welcome.PNG](https://qiita-image-store.s3.amazonaws.com/0/315427/4ab68c68-a192-a9d9-41bf-cd21ba865783.png)
- hostsを編集すれば、[http://hoge.local/](http://hoge.local/)でアクセス可能
    - C:\Windows\System32\drivers\etc\hosts

```
# hoge
192.168.10.10 hoge.local
```

### おまけ
- タイムゾーン変更(UTC→JST)

```
sudo timedatectl set-timezone Asia/Tokyo
```

- ngrokで外部公開

```
ngrok http 80
```

- IDEでコード補完するために

```
cd /home/vagrant/hoge
composer require --dev barryvdh/laravel-ide-helper
php artisan ide-helper:generate
```
CivilizationⅥチックなゲームを作るための情報まとめ【C#】【Unity】

随時更新していきます。

##デモ
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">2つの記事の合わせ技で、六角形でもRaycastの被りを回避できた。動画ではButtonを押すとSpriteがnullで白地になる。<a href="https://t.co/DRnfWbk8iK">https://t.co/DRnfWbk8iK</a><a href="https://t.co/JhSz9vkd8C">https://t.co/JhSz9vkd8C</a> <a href="https://t.co/8qa1h18yiN">pic.twitter.com/8qa1h18yiN</a></p>&mdash; アズマゴロ―@デジゲー博C-02a (@azumagoro) <a href="https://twitter.com/azumagoro/status/1065292381237391360?ref_src=twsrc%5Etfw">November 21, 2018</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet" data-conversation="none" data-lang="en"><p lang="ja" dir="ltr">あ、もう楽しそう。 <a href="https://t.co/RljPU4uuXp">pic.twitter.com/RljPU4uuXp</a></p>&mdash; アズマゴロ―@デジゲー博C-02a (@azumagoro) <a href="https://twitter.com/azumagoro/status/1065332624032317440?ref_src=twsrc%5Etfw">November 21, 2018</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>



##Hex配置
[【Unity】uGUI で六角形のタイル状に UI を整列できる「HexGridLayout.cs」紹介](http://baba-s.hatenablog.com/entry/2018/06/06/090000)

##クリック範囲の制御
[UnityのuGUIのクリック範囲を広げたり制限したりする方法](http://tsubakit1.hateblo.jp/entry/2015/01/30/213000)

##最短経路
[Hexagonal grid: Path-finding using A* algorithm
](https://tbswithunity3d.wordpress.com/2012/02/23/hexagonal-grid-path-finding-using-a-algorithm/)

#UILineRendererなど
https://www.youtube.com/watch?v=r69TW8uZAdU

##Texure Asset
[Painted 2D Terrain Tiles: Basic Set](https://assetstore.unity.com/packages/2d/environments/painted-2d-terrain-tiles-basic-set-45675)

##Mapアイコン
[Fantasyマップアイコン素材集](https://www.dlsite.com/maniax/work/=/product_id/RJ238071.html)
JavaScriptで前年の1月1日と12月31日を文字列で使いたかった

```javascript
var start = (today.getYear() - 1 + 1900).toString() + '-01-01'; // 前年の1月1日 e.g. 2017-01-01
var end   = (today.getYear() - 1 + 1900).toString()+ '-12-31'; // 前年の12月31日 e.g. 2017-12-31

console.log(start); // 2017-01-01
console.log(end); // 2017-12-31
```


JavaScriptで日付を扱う場合には`Date`を使う。
ただ`Date`の`getYear()`は1900年からの差分を戻してくるため、足してやる必要がある。

> For years greater than or equal to 2000, the value returned by getYear() is 100 or greater. For example, if the year is 2026, getYear() returns 126.
> For years between and including 1900 and 1999, the value returned by getYear() is between 0 and 99. For example, if the year is 1976, getYear() returns 76.
> For years less than 1900, the value returned by getYear() is less than 0. For example, if the year is 1800, getYear() returns -100.
> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getYear

ちなみに1900年以前、例えば`1800年`とかだと`-100`が戻るらしい。なるほど。


でもなぜ1900年が基準なんだろう…。
google apps script で ただ post されてきた テキストを返す

google apps script で、ただ文字列を返してみよう。

参考
https://qiita.com/tanabee/items/c79c5c28ba0537112922

# GASへ
https://script.google.com にアクセスし、 + 新規スクリプト を選択。
GAS エディタが立ち上がる。


# コード作成

とりあえず、まずはPOST送信されてきたデータを返してみる。

```js

function doPost(e){  //このeの中にPOSTされてきた情報が入っている（オブジェクト形式）

  var text = e.parameter.text;
  return ContentService.createTextOutput(text);

}



```

上記を保存。
変更する時は、
公開 > ウェブアプリケーションとして導入の
プロジェクトバージョンを変更しないとコードの変更が有効にならないので注意。

# HTML 

```html

<form action="https://script.google.com/macros/s/[YOURIID]/exec" method="post" target="_blank">   <!-- methodはpostで -->

    <label>このテキストが帰ってくるぞ
        <input type="text" name="text" value="tarou">
    </label><br/>

    <input type="submit" value="送信">

</form>


```


これでPOST送信し、POST送信したデータを取得することができます。


# 直接ファイルPOST送信して結果をもらう

普通にPOSTしただけじゃリダイレクトされてエラーになる。
ということで、一旦POSTし、遷移先を取得。
その遷移先のURLからデータを取得。

CAKEPHP3 を利用

```php

    //use Cake\Http\Client;
    public function test()
    {

        $http = new Client();
        $response = $http->post(
            'https://script.google.com/macros/s/[YOURID]/exec',
            [
                'text' => 'おっぴゃー'
            ]
        );


        $head = $response->headers();

        $res = $http->get(
            $head['Location'][0]
        );

        pd($res->body);//おっぴゃー
        die;


    }

```
Gitlab と Discord をSlack WebHook互換を使ってサクッと連携させる。

## はじめに結論

Discord から発行される WebHook URL

`/webhooks/{webhook.id}/{webhook.token}`

の末尾に `/slack` をつけ、Slack API として Gitlabに登録する

`/webhooks/{webhook.id}/{webhook.token}/slack`

## はじめに

Discord をチームの連絡ツールに使っているという方もいらっしゃると思います。そして ソースコードは **Github** ではなく、**Gitlab** を利用している方もいるでしょう。

そうしていると、Gitlab の Push イベントやビルドイベントの通知を Discord で取得したくなりませんか。

しかしながら悲しいことに、Gitlab から Discord への Webhook はそのままでは対応していません。そこで対応策としてネット検索すると、いかのような記事が出てきます。

[GitLabの通知をWebhookでDiscordに送信する](https://qiita.com/otuhs_d/items/fbb80a0bad8d0921b8e6)
(https://qiita.com/otuhs_d/items/fbb80a0bad8d0921b8e6)

たしかに上記の記事通り設定を頑張れば、Discord へ通知できるようになるですが、わざわざプログラムを書くのも面倒くさい。できれば、マウスポチポチすることで簡単に設定したい。

もう少し簡単な方法はないのかなと調査したら、あったのでお知らせします。

## Discord のWebHook について

まずは公式サイトで情報の確認です。以下の URL が Webhook の解説になります。

https://discordapp.com/developers/docs/resources/webhook

そこを読むと以下のような記述があります。

> Execute Slack-Compatible Webhook
>
> POST /webhooks/{webhook.id}/{webhook.token}/slack

Discord の Webhook は末尾に /slack を付加すると Slack 互換のWebhook になります。Gitlab は Slack へのWebhook は対応しているため、こちらのURLを利用することで Slack Bot として登録できるようになります。

そのことを踏まえて設定していきましょう。

## Discord のWebhook設定

「サーバー設定」-「Webhooks」からWebhookの設定をします。

![discord_menu.png](https://qiita-image-store.s3.amazonaws.com/0/77617/62fd6f8c-310e-31f9-96c0-30e2ac823e80.png)

Webhookを作成をクリックして、以下のとおりオプション設定をしてください。

![discord_webhook.png](https://qiita-image-store.s3.amazonaws.com/0/77617/710948bd-4711-3d30-d630-ca13f9cc789f.png)

`チャンネル`：メッセージを投稿するチャンネルの選択
`名前`：メッセージを投稿する際のユーザ名
`WEBHOOK ICON`：メッセージを投稿する際のユーザのアバターの編集

`WEBHOOK URL`  をコピーしてメモしてください。

## Gitlab の Webhook を設定

「設定」-「インテグレーション」から一番下の「Slack notifications」を選択します。

![gitlab_integration.png](https://qiita-image-store.s3.amazonaws.com/0/77617/8b0bff94-bc7b-13ee-3c2a-ba82ddcf217f.png)


`Active` にチェックを入れて通知を有効化します。

`Trigger` でどの通知を行いたいのかチェックボックスで指定できるので指定してください。


![gitlab_slack_webhook.png](https://qiita-image-store.s3.amazonaws.com/0/77617/b6cf5187-f51b-7f1e-fd9d-20ccfc63676b.png)

ページ下部の `Webhook` に Discord から発行された `WEBHOOK URL` を記入してください。そして末尾に `/slack` を追加してください。

例えば、Discord から発行された `WEBHOOK URL`が以下の場合

```
https://discordapp.com/api/webhooks/{webhook.id}/{webhook.token}/
```

以下のように`/slack`を追加してください。

```
https://discordapp.com/api/webhooks/{webhook.id}/{webhook.token}/slack
```

好みで`Username`を指定し、`Test settings and save changes` をクリックして設定は完了です。

正しく設定されていれば、Discord に通知が飛んでくるはずです。

お疲れ様でした。

## おわりに

「Discord は Slack 互換で動作させることができる」というのが今回の記事の肝です。最近のサービスではたいてい Slack は対応しています。おそらく、Slack互換動作のことを知っていれば、ほかの Webhook サービスも簡単に Discord に対応させることが出来ると思います。

開発の助けになればと思い記事にしました。