OmniAICreator/Qiita-1.07M huggingface dataset:
Salesforceで昨年度売上比較のレポートを作成する

最近言われることが多い気がするのでメモを残します。

前年比を見るだけなら以下のヘルプページに記載の内容でも十分なのですが、
https://help.salesforce.com/articleView?id=000220136&language=ja&type=1

**「そうじゃなくて実際の金額を見たいんだ」**
みたいなことを言われることがあります。
なので前年と今年の売上金額の比較ができるレポートの作成を目指します。

# 対象レコードを集計する
当四半期と前年の同四半期の売上が比較したいという場合、対象のレコードだけ絞り込みする必要があります。
とりあえず売上日が当会計年度と前会計年度のもので絞り込みします。
![screencapture-dakudo2-dev-ed-lightning-force-lightning-r-Report-00O7F00000ApRc8UAF-view-2019-02-26-22_16_47.png](https://qiita-image-store.s3.amazonaws.com/0/364548/8dc314be-3505-3cbe-10a3-aa7fc6953097.png)

**今四半期**だけのような制約がある場合は、条件に応じて数式を作って条件に加えます。

# とりあえず集計してみる

売上を年度別に比較するには以下で集計する必要があります。

- 会計年度
- 月

会計年度はレポートの集計期間単位を「会計年度」にすると表すことができます。
![無題.png](https://qiita-image-store.s3.amazonaws.com/0/364548/9b7d40ff-fdf3-d1cb-e657-32450a858477.png)

月は数式を作って対応します。

```javascript
TEXT(MONTH( 日付項目 )) & "月"
```

会計年度と月で売上をまとめるとこんな感じのレポートになります。
![no3.png](https://qiita-image-store.s3.amazonaws.com/0/364548/51638956-76bf-337c-fccc-4aa80e3ef1e8.png)


一見良さそうですが、このままだと会計年度・月ごとの合計金額がわからないので、
売上を比較できる形にしてみます。
売上の合計を表示するには以下の方法があります。

# 1.年度ごとの数式を作るパターン
今年度の金額を求めるために、以下のような数式を作ります。

```javascript:今年度売上

IF (
    OR(
        AND( 
            YEAR(TODAY())=YEAR( 日付項目 ) , 
             OR(
                 AND(
                     AND(4<=MONTH(TODAY()), MONTH(TODAY())<=12), 
                     AND(4<=MONTH( 日付項目 ),MONTH( 日付項目 )<=12)
                  ),
                 AND(
                     AND(1<=MONTH(TODAY()),MONTH(TODAY())<=3),
                     AND(1<=MONTH( 日付項目 ),MONTH( 日付項目 )<=3)
                  )
             )
        ),
        AND( 
            YEAR(TODAY())=YEAR( 日付項目 ) +1, 
             AND(
                 AND(1<=MONTH(TODAY()), MONTH(TODAY())<=3), 
                 AND(4<=MONTH( 日付項目 ),MONTH( 日付項目 )<=12)
              )
        )
     ), 売上 ,0
)
```
前年度の数式も同じように作成し、レポートに追加します。
![no2.png](https://qiita-image-store.s3.amazonaws.com/0/364548/63d82128-d1bc-341b-9f13-d8fdc2b83faa.png)
グラフを追加して、「縦棒グラフ」を選択し、「売上月」で「今年度売上」と「前年度売上」を集計します。
![graph1.png](https://qiita-image-store.s3.amazonaws.com/0/364548/bdb1e643-08c4-304e-43ea-f6a1f54258ba.png)

これで年度ごとの合計の確認と比較を一緒にできるようになります。
![screencapture-dakudo2-dev-ed-lightning-force-lightning-r-Report-00O7F00000ApRdfUAF-view-2019-02-26-22_18_42.png](https://qiita-image-store.s3.amazonaws.com/0/364548/daf0bb6d-41fe-6519-8a9e-b56dfee40a5b.png)


**メリット**

- 各年度の合計金額をグラフ上部に表示することができる

**デメリット** 

- 金額項目ごとに数式を作る必要がある
- 年度ごとに数式を作る必要がある

# 2.マトリクス形式にするパターン
レポート形式をマトリクスに変更すると会計年度・月のそれぞれの合計行が表示されるようになります。
マトリクスでは「売上日」の会計年度を行の集計に、「売上月」を列の集計にそれぞれ使用します。
![graph2.png](https://qiita-image-store.s3.amazonaws.com/0/364548/49701101-58ef-1702-37ab-877994e69d49.png)

グラフを追加して、「縦棒グラフ」を選択し、「売上月」「売上日」ごとに「売上」を集計します。
![graph3.png](https://qiita-image-store.s3.amazonaws.com/0/364548/9a99639c-3442-7deb-a765-53c11d7de5aa.png)
この方法でも年度ごとの合計の確認と比較を一緒にすることができます。
![graph4.png](https://qiita-image-store.s3.amazonaws.com/0/364548/bbd08902-28a8-9ada-728c-314fa6d24780.png)

**メリット**

- 金額項目の数式を新たに作る必要がない

**デメリット** 

- グラフ上部に年度ごとの合計金額を表示することはできない
Swift エラー集

```
'lazy' cannot be used on a let
```
グーグル翻訳
```'lazy'はletでは使えません```
 ```let``` を ```var```に変更

```
guard let postImageUrl = metadata?.downloadURL()?.absoluteString else { return }
```

エラー文

```
Value of type 'StorageMetadata' has no member 'downloadURL'
```
グーグル翻訳
タイプ 'StorageMetadata'の値にはメンバ 'downloadURL'がありません


xcodeで改行した際、インデント位置が前の行を異なる
https://www.setoya-blog.com/entry/2012/10/10/180701
UE4.22preview3における、サウンドファイルのインポートの検証

#イントロダクション

~~よくきたな、俺は逆噴射ry~~

>Improvements to Sound Asset Importing. We have improved sound asset importing, in addition to supporting multi-channel wav files, Unreal Engine now converts from a variety of sound file formats upon import including AIFF, FLAC, and OGG/Vorbis.
「２チャンネル以上のwavファイルに対応したし、AIFF・FLAC・OGGvorbisとかにも対応したよ。」
>>https://forums.unrealengine.com/unreal-engine/announcements-and-releases/1583659-unreal-engine-4-22-preview より

[元から裏技を使えば再生できたのだけど](https://qiita.com/Polaris1080/items/13f874ed9e04841e1a3b)、公式にサウンドファイルの対応が広がったと言うので、試してみたら、エディター落ちが乱発するので、詳しく検証することにした。

#検証

サウンドファイルをTAudioConverterを変換して検証した。
元となったサウンドファイルのスペックは以下の通りである。

+ 形式：waw
+ 周波数：192000Hz
+ ビットレート：32Bit

##形式

形式だけを変更して、その他の条件は以下に統一した。

+ 周波数：44100Hz
+ ビットレート：16Bit

###正常（サウンドウェーブとしてインポート）
+ waw
+ mp4
+ m4a

###FileMediaSource扱いとしてインポート

+ ac3
+ alac
+ wma

###インポート不可（不明な拡張子）

+ aiff
+ opus
+ ape

###エディターが落ちる

+ flac
+ ogg

##ビットレート

上記の内容を踏まえて、ビットレートだけを変更し、その他の条件は以下に統一した。

+ 形式：waw
+ 周波数：192000Hz

###正常

+ 16Bit

###エディターが落ちる

+ 24Bit
+ 32Bit

##周波数

上記の内容を踏まえて、周波数だけを変更し、その他の条件は以下に統一した。

+ 形式：waw
+ ビットレート：16Bit

###正常

+ 8000Hz
+ 44100Hz
+ 48000Hz
+ 96000Hz
+ 192000Hz

#結論
現在、以下の条件を満たすサウンドファイルのインポートに対応している。

+ 形式：waw・mp4・m4a
+ 周波数：8000~192000Hz
+ ビットレート：16Bit

**現状では、AIFF・FLAC・OGGvorbisには対応していないと言える。**

#考察
24Bit・32Bitに対応していないのは、現在のサウンドウェーブの設定において、ビットレートを指定できないからである。
変換後のビットレートを指定できるようにすれば、24Bit・32Bitにも対応すると思われる。

~~突如メキシコの荒野に放りだされることもある。タフになれ。~~
node.jsでファイルの入出力操作

# はじめに
なんかのコードテストをJavaScript(node.js v10)で受験していた際、ファイルの入出力に関する出題があり、やったことなかったので入出力関連処理だけをまとめました。

# ファイル読み込み
node.jsの標準ライブラリ```fs```を用いて実装します。
一般的にファイルの入出力は時間がかかる処理のため、同期処理、非同期処理のメソッドがそれぞれ用意されています。

### 同期処理メソッド「readFileSync」
要はファイルの読み込みが完了してから、後続の処理を行いたい場合ですね。
JavaやPythonなんかに慣れている人はこちらの方が直感的かと思います。

基本構文は、```fs.readFileSync(path[, options])```です。

```javascript:readFileSync.js
const fs = require('fs');
let text = fs.readFileSync("sample.txt");
console.log(text);
```
```node readFileSync.js```とかで実行してみると、ファイルの中身が表示されるかと思います。

文字コードを指定したい場合、第二引数で直接指定するか、オプションオブジェクトとして指定する方法があります。

```javascript:readFileSync.js
const fs = require('fs');
// 文字コードを直接指定
let text = fs.readFileSync("sample.txt", 'utf-8');
console.log(text);

// 文字コードをオプション指定
let text2 = fs.readFileSync("sample.txt", {encoding: 'utf-8'});
console.log(text2);
```

#### ※オプションに指定できる```flag```について
ちょっと話が逸れますが、オプションオブジェクトのパラメータは```encoding```の他に```flag```があります。
```flag```のデフォルトは```r```で「読み取り用でファイルを開く。ファイルが存在しない場合は例外を発生する」動きになります。
例えば、ここを```a```とかすると、ファイルが存在しない場合に新規作成してくれたりします。
詳しくは[公式ページ[fs_file_system_flags]](https://nodejs.org/api/fs.html#fs_file_system_flags)を参照ください。


### 非同期処理メソッド「readFile」
要はファイルの読み込みを待たずに後続処理を捌きたい場合です。
基本構文は```fs.readFile(path[, options], callback)```です。

```javascript:readfile.js
const fs = require('fs');

fs.readFile("sample.txt", 'utf-8', (err, data) => {
  if (err) throw err;    // 例外発生時の処理
  console.log(data);
});

console.log('ファイル読み込みを待たずに後続処理が走ります。');
```
非同期で処理を実行するため、以下のように出力されるかと思います。

```
ファイル読み込みを待たずに後続処理が走ります。
ファイルの中身
```

ファイル読み込み後に行いたい処理が複雑になればなるほど、コールバック地獄に陥りやすいので注意です。。
```Node.js v8.0```以降をお使いであれば、```util.promisify```でPromise化してあげることも検討してみてください。

# ファイル書き出し
こちらもファイルの読み込みと同様、同期処理か非同期処理かでメソッドを使い分けましょう。

### 同期処理メソッド「writeFileSync」
基本構文は```fs.writeFileSync(file, data[, options])```です。

```javascript:writeFileSync.js
const fs = require('fs');
let text = "書き出したい内容";
fs.writeFileSync("output.txt", text);
```

こちらも```readFileSync```同様、オプションの指定ができます。
ファイル書き出しの場合のデフォルトは```w```で、ファイルが存在しない場合は新規作成してくれますが、ファイルが存在する場合は上書いてしまうので注意してください！

### 同期処理メソッド「writeFile」
基本構文は```fs.writeFile(file, data[, options], callback)```です。
書き出した結果の処理（成功した場合にメッセージを出すなど）を実装したい場合はこちらを使うのが良いかと思います。

```javascript:writeFile.js
const fs = require('fs');
let text = "書き出したい内容";
fs.writeFileSync("output.txt", text, (err) => {
  if (err) throw err;
  console.log('ファイルが正常に出力されました。');
});
```

# おわりに
こういうのは一回使うと忘れがちなので、こまめにまとめてTips化したいなーと思っていますが、なかなか時間なかったり…

# 参考
[公式ドキュメント: Node.js v11.10.0 Documentation](https://nodejs.org/api/fs.html#fs_file_system)
[from scratch: util.promisify が追加された](https://yosuke-furukawa.hatenablog.com/entry/2017/05/10/101752)
GoogleChromeチームのWeb画像最適化無料テキスト Essential Image Optimization 目次

[GoogleChrome](https://github.com/GoogleChrome)チームの[Addy Osmani](https://twitter.com/addyosmani)氏らによる画像最適化のテキスト**Essential Image Optimization**が、基礎から最新情報まで網羅されていてとても勉強になります。

Essential Image Optimization
https://images.guide/

ソースが[GitHubで公開](https://github.com/GoogleChrome/essential-image-optimization)されていて少しずつでも翻訳してみたいなーと思いつつ、目次だけ日本語で紹介します。

## Essential Image Optimization 目次

* はじめに
* 画像フォーマットの選び方
* 謙虚なJPEG
* JPEGの圧縮モード
  * プログレッシブJPEGの利点
  * プログレッシブJPEGの実用例
  * プログレッシブJPEGの欠点
  * プログレッシブJPEGの作り方
  * クロマ(またはカラー)サブサンプリング
  * JPEGに続く次世代フォーマット
  * JPEGエンコーダーの最適化
  * MozJPEGとは何か
  * Guetzliとは何か
  * MozJPEGトGuetzliの比較
  * Butteraugli
* WebPとは
  * WebPにできること
  * WebPの実用例
  * WebPエンコーダのはたらき
  * ブラウザのサポート状況
  * WebPへの変換方法
  * OSごとのWebPの表示方法
  * WebPの配信の仕方
* SVGの最適化
* 非可逆圧縮の繰り返しは避ける
* 不要な画像のデコードやリサイズを減らす
  * srcsetによるHiDPI画像の提供
  * アートディレクション
* カラーマネジメント
* CSSスプライト
* 画像の遅延読み込み
* display: none;の罠を避ける
* 画像加工機能付きのCDNの使いどころ
* 画像のキャッシュ
* 画像の先行読み込み(preloading)
* 画像のパフォーマンスバジェット
* まとめと推奨値
* トリビア

JpegやWebPの話題が多めですが、一読をお勧めします。

## WebP

WebPもEdge、Firefoxの対応で利用が増えていますね。[Wikipedia](https://ja.wikipedia.org/)や、あの[マイクロソフト](https://www.microsoft.com/ja-jp)も今やWebPを積極的に利用しています。

弊社の**ページまるごとWebP変換・効果測定と一括ダウンロード**も頻繁に使われています。Appleの対応に期待しましょう。

ページまるごとWebP変換・効果測定と一括ダウンロード
https://sim.lightfile.net/webp/
default_transaction_isolationって何？ Udemy 【3日でできる】はじめての Django 入門　レクチャー49

# はじめに
[【3日でできる】はじめての Django 入門 ( Python 3 でウェブアプリを作って AWS EC2 で公開！）](https://www.udemy.com/django-beginner/)レクチャー49で

```
postgres=# ALTER ROLE mybloguser SET default_transaction_isolation TO 'read committed';
```
「実行された結果だけをみに行くという設定です」と井上先生が説明してくれてるけど、なんだか分からんですよね。。。というお話です。

# 結論
初学者には結構難しいよ！！
→何の解決にもなっていない笑

『トランザクション分離レベル』というお話があって、そこの設定を例のコマンドでは行なっているのだけど、多分初学者には理解できないと思う。。。
（かく言う自分もなんとなくしか分かってない）

「トランザクション分離レベル とは」で検索すればいくつか説明が出てくるんだけど、そもそも『トランザクションって何？』とか『RDBMSって何。。。？』とか『コミットって。。。』が分かっていないと厳しいので、**今回は推奨の設定がされているんだな！**という認識だけ持っておけばいいのではないかと思います。

[TECHSCORE](https://www.techscore.com/tech/sql/index.html/)に一通り目を通せば雰囲気はわかると思うので興味があれば読んでみるといいと思います。
それから
[[RDBMS][SQL]トランザクション分離レベルについて極力分かりやすく解説
](https://qiita.com/PruneMazui/items/4135fcf7621869726b4b)@PruneMazui 様
を読まれればなんとなくわかると思います。
グローバルインストールなしで nodemon を使用する

## はじめに

Node.jsで開発中、修正が終わるたびに再起動するはなかなかの手間になり、
ストレスがたまります。そこでソース修正後に自動再起動してくれる`nodemon`の登場です。

`nodemon`はグローバルにインストールして使われることが多いようですが、
今回は`nodemon`をローカルインストールで動かす方法を調べてみました。

## インストール

```terminal
$ npm install --save-dev nodemon
```

この例では開発依存としてインストールしました。
`--save-dev` の代わりに `--save` を使用して、通常の依存としてインストールしても問題ありません。

## package.jsonを編集

その後、`package.json`を以下のようにを編集します。

```json:package.json
"scripts": {
  "start": "nodemon index.js"
}, 
```

`index.js`は適宜実行したいファイル名に置き換えてください。

## サーバーを起動

```terminal
$ npm start
```

以上で、ファイル修正後に`nodemon`が自動で再起動してくれるようになりました。
WordPressで相性の悪かったプラグイン

# 注意事項
- サーバー環境によるかもしれない。
- バージョンアップによって解消されている可能性がある。
- 気づいたものからメモ書きで随時追加しているため、細かい検証はしていない。

# Simply StaticとYoast SEO
日時:2019/02/27　環境:PHP 7.2　WordPress 5.1

Simply Static（バージョン 2.1.0）
https://ja.wordpress.org/plugins/simply-static/

Yoast SEO（バージョン 9.7）
https://ja.wordpress.org/plugins/wordpress-seo/

Simply Staticが有効になっていると、Yoast SEOのSearch Console接続のためのGoogle認証が出来なかった。
認証コードを入れても無反応。
静的ページにするプラグインと相性が良くないかもしれない。
Yoast SEOのGoogle認証がうまくいかなかったらプラグインの相性を確認する。
Text Mesh Pro を使って日本語ルビをつけるのと、注意したいところ

# ルビをつける
ふりがなふりたいですよね。
子供向けに作るコンテンツだと欲しくなると思います。

# 設定
参考リンクにあるように Style Sheet の設定で実現可能です。（横書き）
リンク先の内容をもとに、自分の環境用に設定したのが以下の通り。

| 種類      | Name      | Opening Tags                                          | Closing Tags |
|:----------|:----------|:------------------------------------------------------|:------------------:|
| 1文字用    | p1        |`<space=-2.8em><voffset=.85em><size=50%><mspace=4em>`|`</size></voffset></mspace>`|
| 2文字用    | p2        |`<space=-3.6em><voffset=.85em><size=50%><mspace=4em>`|`</size></voffset></mspace>`|
| 3文字用    | p3        |`<space=-6.7em><voffset=.85em><size=50%><mspace=4em>`|`</size></voffset></mspace>`|
| 4文字用    | p4        |`<space=-7.5em><voffset=.85em><size=50%><mspace=4em>`|`</size></voffset></mspace>`|
| 5文字用    | p5        |`<space=-8.5em><voffset=.85em><size=50%><mspace=4em>`|`</size></voffset></mspace>`|
| 6文字用    | p6        |`<space=-11em><voffset=.85em><size=50%><mspace=4em>`|`</size></voffset></mspace>`|

# 問題点
印刷物などだと、ルビの有無で行の位置が変わることはありませんが、
この方法で上揃えにした場合、ルビの有無で行の位置が変わってしまいます。

動的に差し替わるテキストフィールドで、ルビの有無が混在する場合に、
デザイン調整がしづらくなります。

# 対応
挿入するテキスト文字列の冒頭に `<line-height=1em>` などを付与してtextプロパティに代入することで、
2行目以降の行についてはルビの有無に左右されずに行間が固定できます。
1行目は許容する形。

例

```xml
<line-height=1em>青<style=p2>あお</style>い空<style=p2>そら</style>
```

別案として、改行が無い、箇条書きみたいな文章であれば
テキストフィールドを分割して、下揃えにしてあげることでも解決できそうです。


## 参考
http://baba-s.hatenablog.com/entry/2019/01/10/122500
https://forum.unity.com/threads/how-to-display-extra-little-characters-above-characters-in-a-text.387772/
slackリマインダーで自分を煽ったらポモドーロより生産性上がるかもよ？

# TL;DR

何らかの理由で作業にポモドーロテクニックを使えない人はSlackリマインダーで自分を煽ってみたら生産性が増すかもしれないですね、というお話です。

# ポモドーロって？

広く知られていますが念の為。

[ポモドーロテクニック](http://d.hatena.ne.jp/keyword/%A5%DD%A5%E2%A5%C9%A1%BC%A5%ED%A5%C6%A5%AF%A5%CB%A5%C3%A5%AF)。

作業を<font color="red">*25分やる→5分休憩→25分やる→...繰り返し*</font>で行って生産性上げるテクニックですね。

# ポモドーロが出来ない人もいる？

仕事の性質上難しい人はいるかもしれませんが、一人でコーディングしている最中はほぼ全ての人に効果があるんじゃないかなと。
ただ、オフィスで5分間をうまいこと使えないケースだったり、なかなか慣れなかったり、とどこかしらに歯がゆさを感じている人も一定数いると思います。

# slackリマインダーで自分を煽ってみては？

本題です。
何かしらの理由でポモドーロテクニックをうまいこと使えない場合の代替案として、<font color="red">Slackリマインダーで自分を煽ったら良い感じになるのでは？</font>と思ったのでその備忘録です。

## 準備

times文化がある環境だと効果が増しそうです。
timesも幅広く認知されているのかなと思うので説明は[こちらのリンク](http://c16e.com/1511101558/)だけに留めておきます。

slackでメンバーごとに `times_○○` のチャンネルを作りましょう。

## やってみる

やる作業と目標時間が決まったらリマインドセットするだけです。

```
/remind #times_○○ in 30minutes "@自分 お前○○の作業終わったの？"
```

こんな感じですね。
<img width="756" alt="スクリーンショット 2019-02-27 11.27.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/173370/cb7d047e-bee9-461e-7ae6-d1448e68f910.png">



# ポモドーロとのプロコン

## Pros

1. 縛られすぎない
    - これはPros＆Consどちらもあるんですが、何らかの理由でポモドーロテクニックを使えない人にとっては、ということで
2. 周りと作業内容を共有出来る
    - ポモドーロとの純粋な比較と考えると趣旨から外れるんですが、 `生産性を上げる` という観点から見るとこれは大きなプラスになるんじゃないかと

## Cons

1. times文化がないと効果が薄い
    - Prosの3．の恩恵を受けることが出来なくなります
2. 手間がかかる
    - 慣れればリマインドセットは秒で終わりますが、それでもやはりポモドーロの `自身で区切りをコントロールしない` ことに楽さに比べると手間は掛かりますね

## まとめ

正直Pros1.だけだと効果は薄いのかなと思っていますが、times文化があるチームであればPros２.による効果は<font color="red">場合によってはポモドーロ以上かも？</font>とも思います。

ですので、

- times文化があるチームの方
- 何らかの理由でポモドーロテクニックを使えない方

は一度お試し頂くのもアリだと思います。

## 蛇足

ポモドーロアプリ、Macの方は[Just Focus](https://itunes.apple.com/jp/app/just-focus/id1142151959?mt=12)が一般的ですかね？
Windowsの方はアプリの困っているようですがもしWindowsでおすすめのポモドーロアプリあればご教示頂けますと幸いです🙇
[TF] Object Detection API でNewRandomAccessFile failed to Create/Openエラー

# やりたかったこと
WindowsでTensorflowのObject Detecton APIを試した後、
それを自分のプログラム・環境から呼び出せるようにしたい。
WindowsでQuick Startするまでは、[本家](https://github.com/tensorflow/models/tree/master/research/object_detection)や、[参考サイト](https://qiita.com/x-lab/items/224e63565ecf1c3109cf)が参考になりました。


## 遭遇したエラー

```
tensorflow.python.framework.errors_impl.NotFoundError: NewRandomAccessFile failed to Create/Open: data\mscoco_label_map.pbtxt : \udc8ew\udc92?\udc82?\udc83p\udc83X\udc82\udcaa\udc8c\udca9\udc82?\udca9\udc82\udce8\udc82?\udcb9\udc82\udcf1\udc81B
```
のようなエラー。
上記以外でも、モデルの読み込み時にもエラーが発生しました。

## 解決策
Githubのissuesは未解決のものが多かった印象。
結果としては[こちらのサイト](http://louis-needless.hatenablog.com/entry/try_tensorflow_model_1)の通り、
参照する際の相対パスを絶対パスに書き換えたら解消しました。
（絶対パスもスラッシュでパス書いたらアウトだったので、¥¥で書いたらOKでした。）

Tensorflow以外でもWindowsだと時々遭遇する問題なので、
あまり時間かけずに解消したかったです...。


# 参考サイト
本家：https://github.com/tensorflow/models/tree/master/research/object_detection
QuickStart：https://qiita.com/x-lab/items/224e63565ecf1c3109cf
本エラーについて：http://louis-needless.hatenablog.com/entry/try_tensorflow_model_1
[Vue.js] IME入力時にEnterキーイベントを発火しない様にする

Vue.js **^2.5.16** においてIME-ON時にも `keydown.enter` が発火する様になったらしいので
それを制御するお話
備忘録程度に

## 対策
* `compositionstart` `compositionend` を使いましょう

> Source
> https://forum.vuejs.org/t/how-does-vue-handle-real-enter-event/2169/4

<p class="codepen" data-height="512" data-theme-id="dark" data-default-tab="js,result" data-user="shinomiya_ag" data-slug-hash="YgPBye" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid black; margin: 1em 0; padding: 1em;" data-pen-title="YgPBye">
  <span>See the Pen <a href="https://codepen.io/shinomiya_ag/pen/YgPBye/">
  YgPBye</a> by 🍆あんじぇあーと🍆 (<a href="https://codepen.io/shinomiya_ag">@shinomiya_ag</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
未経験SEが突然C#をふられた時のメモ

##  自己紹介
・Java検定2級に合格して喜んでたらC#をふられた
・相変わらずお先真っ暗

##発端
「1週間後にC#を使った案件にいってもらうから準備しといてね」

突然の上司からのお告げ。
C#？？？Javaは？？？？
~~プロジェクトが週単位でころころ変わるのは勘弁していただきたい~~
文句言ってもしょうがないのでいろいろ調査しました。

##調査
**C#（シーシャープ）**
Microsoftがつくったプログラム言語。
JavaとC++のいいとこどりをした言語でJavaに似ててC++よりカンタン。
スマホアプリ、ゲーム、Windowsクライアント、ウェブサイト、データベース、クラウドなどいろいろカバーしているスゴイ言語。
開発環境は『Visual Studio』が多く使われていて、拡張子は『.cs』

**.NET Framework（ドットネット フレームワーク）**
Windowsに入ってるプログラムを動かしたり作ったりするときに使える便利な環境のこと。
ようするにwebサービスとかwebアプリケーションを作成するための開発環境、実行環境。
（Visual Studioとはちょっと違う？）

**WPF(Windows Presentation Fondation)**
.NET Frameworkに含まれるプレゼンテーション層技術。
画面系（GUI）をいろいろ弄りやすくしてくれる便利な技術で
柔軟性があるため、

・任意の形状のボタンを作成できる！
・背景に動画を流すことができる！
・動的に拡大・縮小ができる！　　など。

XAML（ザムル）と呼ばれるXML形式の言語を用いてUIを記述することができ、
ロジック部分はC#で記述するという特徴がある。
わざわざ別々になってるのは、
『デザインとロジックを分離することでそれぞれの担当者が作業を進めやすくするため』らしい。

##結果的に
事前調査してみたけど知識がフワフワ状態です。
C#に限ったことじゃないと思いますが、新しい言語を勉強するのって大変だと再確認しました。
実はこの記事書いてる時点ではこの案件はもう終了しているんですが
正直理解しきれていないところが多々あります・・・

まだまだ勉強しなくちゃいけないことが多いなぁ～
Laravel 環境構築まとめ

#概要
Laravelを学ぶ上で必要となる環境構築についてまとめていきます。
環境構築にはHomesteadかLaraDockを使っていくのですが、今回はHomesteadを使って環境構築していきます。Homesteadは標準で様々な機能を持っているので初めてLaravelに触れるにはHomesteadを使ったほうがいいかと思います。
macでの説明になります。
#必要となるもの
必要となるものとして`git`, `VirtualBox`, `vagrant`が必要となります。
それぞれインストールできているか`--version`で確認しましょう。

```terminal
git --version
git version 2.17.2

vagrant --version
Vagrant 2.2.3
```
#環境構築していく
はじめに`vagrant`を使ってHomesteadを使うためのBoxを追加します。

```terminal
vagrant box add laravel/homestead
```
プロバイダの種類を聞かれると思うので、`virtualbox`の番号を選択しましょう。

環境によっては上記のコマンドが異様に遅いかと思います。
その時は以下の記事を参考にしてください。

- [vagrant box add が遅すぎて発狂した](https://qiita.com/ssnyarii/items/34877e07ce9888311598)

Boxが追加できたらgithub上から色々と設定が入ったファイルをクローンします。
ホームディレクトリ以下にHomesteadとしてクローンします。

公式　https://github.com/laravel/laravel

```terminal
git clone https://github.com/laravel/homestead.git Homestead
```
次にHomesteadに移動して初期化します。

```terminal
cd Homestead

bash init.sh
```
初期化できたらHomesteadディレクトリにあるHomestead.yamlで必要であれば諸々の設定を行う必要があります。

```vim:Homestead.yaml
provider: virtualbox

folders:
    - map: ~/code
      to: /home/vagrant/code

sites:
    - map: homestead.test
      to: /home/vagrant/code/[フォルダ名]/public
```
色々書かれていますが、上記の３つを見ていきます。
`provider`には使うプロバイダの種類が入ります。
`folders`には仮想環境とホストOSの間で共有するフォルダを設定します。
デフォルトではcodeディレクトリになっていると思うのでそのままにしておき後でcodeディレクトリを作ります。
`sites`にはアクセスする場所を指定します。
上記ではhomestead.testにアクセスするとto:以下のものが出てくるよといったものです。
後で実際にコードを書いていく新規プロジェクトを作成するコマンドを打つのでその時に設定する名前を指定してあげます。


ホームディレクトリに戻ってcodeディレクトリの作成

```terminal
cd

mkdir code
```

次にhostsファイルにIPアドレスを設定します。
hostsファイルの設定の仕方は以下を参照してください。

https://hazimaru.jp/820/

hostsファイルにIPアドレスを追加します。

```terminal
192.168.10.10 homestead.test
```
Homesteadに移動してvagrantを起動させます。

```terminal
cd Homestead

vagrant up
```
時間がかかるかもしれないです、、、

仮想環境の中に入って新規プロジェクトを作成します。

```terminal
vagrant ssh

laravel new [フォルダ名]
```

上記のコマンドではlaravelの最新バージョンになるのでバージョンを指定したければ以下のコマンドを打ちます。

```terminal
composer create-project laravel/laravel [フォルダ名] --prefer-dist "5.5.*"
```
上記では例としてバージョン5.5を指定しています。
ここまできたら`homestead.test`にアクセスしてみます。

welcome画面が出ていれば成功です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/286470/0a55c5b4-5278-6db3-97b6-024e8c038fa6.png)

#まとめ
laravelの環境構築についてまとめました。
色々ややこしいし時間がかかるなあと感じたのが率直な感想です。
ある程度勉強したら`LaraDock`を使って環境構築もしてどのぐらい違うかも理解したいです。
格納先がS3のgzip圧縮ファイルをpandasを用いて読み書き



#背景

AWS Lambdaのメモリ制限が3GBに倍増されて久しいが、昨年10月にtimeout制限も5分から15分になった。
AWSから話を聞くところによると、この変更はAWS GlueとLambdaの空白地帯を埋めるためらしい。
少し突っ込んで説明をすると、データ変換にはGlueを用いることがよくある。しかし、これは1回の最低課金時間が10分と比較的長く、数秒～数分で終わってしまうような軽いデータの変換では無駄な料金を払うことになってしまう。
そのため、比較的特性の近いLambdaを代替として使うことも多かったが、こちらは実行時間制限が5分しかなく、実行時間が5～10分のジョブに関しては結局Glueを使用するしかなかったのですが、
今回の制限変更を経てこの空白を埋めることができたわけです。
（処理能力の差とか細かい事を言うといろいろあるのですが、本題でないので割愛します）
すなわち、Lambdaを比較的軽いデータの変換リソースとして使ってもらう狙いがあるようです。

※今年の1月22日にPythonシェルジョブというタイプという物ができ、界隈の事情がさらに変わっていますが、その話は置いておきます。

さて、そんな時にS3へアップされるデータを利用しやすい形式に変換して再度保存する機能を組むことになったので
私は（いろいろ検討した結果）このAWSの狙いにどっぷりと乗っかることにしてLambdaを用いた変換を行うことにしました。

#要件
・最大1GB程度になる生のCSVデータがgzip圧縮された状態で定期的にS3にアップされてくる
・このファイルを読み込んで、必要な処理をしたのち再度gzip化したcsvファイルをS3に保存する
・アップしたファイルはすぐに変換処理に回して変換後からすぐに使用したいので比較的高速なこと
・Lambdaを使用する
　→ディスクが512MBしかないのでオンメモリ上でさばく必要がある
　→メモリの制限があるので、じゃぶじゃぶと変数を使えない

ということで、gzipをわざわざディスクに落としてきたりせず、またメモリ上でgzipを解凍したりせずに、直接データ読み込んで、そのまま必要な編集をして、編集後のデータもどこかに吐き出したりせず、直接S3にgzip化して書き出すという処理をしたいわけです。これをpandasとs3fsを利用して実現していきます。

#準備
lambdaで実行する場合はpandasとs3fsを実行できるようにモジュールの実ファイルを用意する。
下記コマンドを打って、生成されたファイル群をコードと一緒にあげる。

```
pip install pandas -t ./
pip install s3fs -t ./
```

#S3に格納されたCSV.gzをpandasに読み込む
pandasにはread_csvというcsvファイルを読み込むメソッドがあります。
こいつが何とも強力で、S3にあるパスを直接指定することができます。（Lambdaからのアクセス権を設定する必要があります）
更に、対応する圧縮形式であれば、拡張子から形式を自動判別して直接読むことができます。
もちろん、その中にgzipが含まれるので、読み込みはこのメソッドに任せればOKです。
なお、.gz以外の拡張子のgzipはcompressionパラメタに'gzip'を指定することで読み込めるようです。

```Python
import pandas as pd
df = pd.read_csv( 's3://bucket_name/load/csv.gz' )
```

#pandasに格納されているデータをgz圧縮した状態でS3に格納する

※2019/03/14修正しました
以前のコードではどうやら、見た目上はファイルが作成されているのですが、破損ファイルが保存されるようです。

gzip化するにはpythonの標準ライブラリのgzipを使用します。

```Python
import pandas as pd			
import gzip

buf = io.BytesIO()
with gzip.GzipFile(mode='w', fileobj=buf) as gz_file:
    data.to_csv(gz_file)
s3 = boto3.client('s3', region_name='region', aws_access_key_id='access key', aws_secret_access_key='secret key')
s3.put_object(Bucket='bucketName', Key='outpath', Body=buf.getvalue())
```

		
#まとめ
想像していたよりは簡単に行きました。
しかし、500MBを越えるデータをLambdaで回すと、すぐにメモリ不足に陥るのでメモリの量か、ディスクの量がもっと欲しくなります。
GlueでPythonを動かせるようになったので、今後はそちらの利用も選択肢の一つに入れるといいかもしれませんね。

#参照
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_csv.html
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_csv.html
https://s3fs.readthedocs.io/en/latest/
VirtualBox6にしたらCentOS7がOh no!

今月Qiitaさんにお世話になりまくったので、恩返しに初投稿～（ﾖﾛﾋﾟｺ m(_ _"m)ﾍﾟｺﾘ

と言うか、Web探しまくっても見当たらなかったので備忘録的に。

我が社のPCがリプレースされたので折角だからVirtualBoxも最新を入れようと思い、公式に行ったらVer5 -> 6にメジャーVupしてたので一先ず何も考えず導入。すると...
![VirtualBox_CentOS7 PHPDev_27_02_2019_10_13_51.png](https://qiita-image-store.s3.amazonaws.com/0/368522/78f829f6-56ba-d128-b425-b4c0c62e5d47.png)
うっひゃーーーー。sigotodekineee;

Ggl先生質問しまくりを開始し、とりあえず画面で[ctrl]+[alt]+[f2]でCUIを出してログイン後、手動でGuest Additions CDを入れる手段を見つけたが改善せず。

さらに質問を続けてると「こういうのってGraphicじゃね？」みたいな情報が目立ち始めたので、じゃぁVirtualBoxのディスプレイ設定でも眺めてみますかと。そしたら...
![2019-02-27_101631.png](https://qiita-image-store.s3.amazonaws.com/0/368522/681593ff-1456-9ec5-70dd-a05ed6216996.png)

ん？　何か見慣れん「Graphics Controller」とか言う表示が増えとる。
"VMSVGA"ってOpenVMSじゃないんだから（古）と、ひとまず一番標準そうな"VBoxVGA"に変更。そしてCentOS7を再起動してみたら...
![VirtualBox_CentOS7 PHPDev_27_02_2019_10_21_38.png](https://qiita-image-store.s3.amazonaws.com/0/368522/1f54e7a0-faa6-cd1c-31ab-4f268c69d5e0.png)
Qiitaｰｰｰ!　ヽ(○｀∀´)ノ

昔からテキストベースで設定できたものがGui化されたもの、みたいですね。メジャーVupはこういう事があるから怖いなぁ。
（最初、マイグレ時にイメージぶっ壊したかと思い何度もでかいイメージをコピーしまくった私。時間返せぇぇー。）

(後日談)
で、ほかのCentOS7イメージもVirtualBox6に登録して、↑あたりを忘れてそのまま起動したら..
![VirtualBox_CentOS7_27_02_2019_10_34_30.png](https://qiita-image-store.s3.amazonaws.com/0/368522/6f76e5e3-981c-b7d5-3b97-84a94220cda9.png)
ありゃりゃ？

なんか、ふつーに起動するし（謎

どうやら起きるのは環境によりけり、みたいですねぇ。
（先のイメージって、やっぱ何か調子イマイチな感じだし）
JavaScriptのコーディング面接した際の出題問題(Sort)

JavaScriptのコーディング面談で下記のような問題がでました。
緊張すると頭が真っ白になって、実装できなかったです。
帰りの電車で考えたらあっさりできました。。

##問題
時間は5〜10分ぐらいです。

```js
const data = `pineapple,160
apple,80
watermelon,160
grape,160
melon,80
mango,170
banana,80
strawberry,170
peach,160
orange,170
kiwi,80
`

// printSortedDataに処理を記載して、shoud　print以下の内容が表示されるようにする
// 要件はdataの金額でソートする。同一金額はdataの記載順で表示する。
// dataは改行区切りの文字列である
const printSortedData = (items) => {
}

printSortedData(data)

// should print
// apple,80
// melon,80
// banana,80
// kiwi,80
// pineapple,160
// watermelon,160
// grape,160
// peach,160
// mango,170
// strawberry,170
// orange,170
```

##実装例
もっと良い方法や書き方があれば、コメントや編集リクエストを頂けると幸いです。
paizaさんのオンラインエディタとかですぐ確認できて便利でした。
https://paiza.io/ja/projects/new


<details><summary>実装例</summary><div>

```js

const printSortedData = items => {
  const array_data = items.split("\n").slice(0, -1);
  const sort_data = array_data.slice().sort(function(a, b) {
    const a_price = Number(a.split(",")[1]);
    const b_price = Number(b.split(",")[1]);
    if (a_price < b_price) return -1;
    if (a_price > b_price) return 1;
    return 0;
  });
  // console.log(array_data)
  // console.log(sort_data)
  result = sort_data.join("\n");
  console.log(result);
};

```
</div></details>

##所感
初めてのコーディング面談でしたが、日頃から手を動かしてプログラミングしているかが重要であると感じました。
悔しいので、アルゴリズム問題をちょくちょく解いていこうと思います。

## 追記
つとむ( @TsutomuNakamura )さんがbashで書いてくれました！！
bashだと一行で書けるらしいです。スゴイです。
[なおとさんの「コーディング面接した際の出題問題(Sort)」をbash で解いてみた](https://qiita.com/TsutomuNakamura/items/bb526b97206be08f8a79)
Lolipop環境にLaravelをインストールする方法（+Laravel mixによるVue.js）

毎度忘れてしまうので、覚書として。

※ご注意：現時点での操作方法になりますので、時間の経過によって環境も変わる可能性があります。

# ロリポの契約
スタンダードプラン以上にしましょう。
独自ドメインの設定、無料SSL、SSH接続が無いと設定できません。

# ロリポの設定
## 独自ドメイン取得
ムームドメインだと連携が簡単なので、ムームドメインで取ってしまいましょう。
私は年間80円のドメインを購入しました。

## サブドメイン設定
xxxxx.hogefuga.jp => /hogefuga/public/

## PHP7.1のパス

/usr/local/php7.1/bin/php

## MySQL設定
設定メニューの「データベース」→「作成」ボタンを押下

## Laravelインストール
時間かかっても簡単な方法で、というのであればvendorディレクトリなども全部SFTPで転送してしまう方法です。
npmコマンドが使えないようなので、node_modulesについては頑張って転送しました。

## マイグレーション
ロリポのデータベースはMySQL5.6しか選べないので、マイグレーションしようとすると以下のエラーが表示されます。

```console:console
SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes (SQL: alter table `password_resets` add index `password_resets_email_index`(`email`))
```

以下のページを見ながらusersとpassword_resetsテーブルを修正しましょう。
https://qiita.com/beer_geek/items/6e4264db142745ea666f

# 参考
https://lolipop.jp/pricing/
http://0gravity000.sunnyday.jp/ProgramingNote/2017/10/21/tip_09_02_008/
PHP: 関数合成する関数を作る方法【愚直にforeach編】

前回は[PHP: 関数合成する関数を作る方法 - Qiita](https://qiita.com/suin/items/7de4e9a6f60fd08a9337)という投稿をした。そこで紹介した関数合成する関数の実装は次のコードだった。

```php
$composeAll = function (callable $function, callable ...$functions): callable {
	return array_reduce(
		$functions,
		function (callable $f, callable $g): callable {
			return function (...$arguments) use ($f, $g) {
				return $g($f(...$arguments));
			};
		},
		$function
	);
};
```

この関数は、関数の配列をreduceしていってひとつの関数を作る設計になっているが、ものすごく大量の関数を合成することは想定されていない。

試してみると分かるが、2つの関数を合成するたびにメモリが増えていき、memory_limitに達するとFatal Errorが発生する。

```php
$increment = function (int $value): int {
	return $value + 1;
};

// 1,048,576個の関数を合成する
$increments1048576 = array_fill(0, 1024 * 1024, $increment);

$add1048576 = $composeAll(...$increments1048576); // Fatal Error
```

実行結果:

```
Terminated due to signal: SEGMENTATION FAULT (11)

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 20480 bytes) in /.../Untitled 3.php on line 11
```

これは、関数合成1回ごとにつなぎの関数のためのメモリが確保されていくから仕方がないところ。イメージとしては、こんなかんじで変数を大量に定義するのと同じ:

```php
$increments1_2 = function (...) { return $increment2($increment1(...)); };
$increments1_2_3 = function (...) { return $increment3($increments1_2(...)); };
$increments1_2_3_4 = function (...) { return $increment4($increments1_2_3(...)); };
$increments1_2_3_4_5 = function (...) { return $increment5($increments1_2_3_4(...)); };
$increments1_2_3_4_5_6 = function (...) { return $increment6($increments1_2_3_4_5(...)); };
...1048570個くらい略...
$increments1_2_3_4_5_6_snip_1048576 = function (...) { return $increment1048576($increments1_2_3_4_5_snip_1048575(...)); };
```

100万個もの関数を合成することはそうそうないので、実際は直面する可能性が低い軽微な問題ではある。

それでも性能上の限界があることは記憶に留めておきたい。そして、限界はメモリだったりと実行時の状況次第で限界点のしきい値が変わるということも。

プログラムの完成度として、できるだけ限界がないようにしておきたいときは、愚直にforeachする方法もある:

```php
$increment = function (int $value): int {
	return $value + 1;
};

$composeAll = function (callable ...$functions): callable {
	return function ($argument) use ($functions) {
		foreach ($functions as $function) {
			$argument = $function($argument);
		}
		return $argument;
	};
};

$increments1048576 = array_fill(0, 1024 * 1024, $increment);

$add1048576 = $composeAll(...$increments1048576);

echo $add1048576(0); //=> 1048576
```
一意性制約のscopeオプション

# 一意性制約とは

別のレコードに保存されている値を保存できなくする制約です。

```User.rb
class User < ApplicationRecord 
  validates :email, uniqueness: true 
end 
```

# 本題

現在学習の記録が出来るサービスを作成しています。
投稿に必要な項目の中に学習日があります。(learning_dateというカラム名にします)
同じ日の学習記録は出来ないようにしたいので一意性制約をかけます。

```Post.rb
class Post < ApplicationRecord
  belongs_to :user
  validates  :learning_date, presence: true, uniqueness: true
end
```

これで良さそうに見えますがこのバリデーションのかけ方だと問題が生じます。　
このバリデーションのかけ方をすると
他のユーザーが投稿した学習日の学習記録も投稿出来なくなってしまいます。

では、どうするか、、、


ここでscopeオプションを使います！

```Post.rb
class Post < ApplicationRecord
  belongs_to :user
  validates  :learning_date, presence: true, uniqueness: { scope: [:user_id] }
end
```

上記の書き方だとuser_idとlearning_dateが同じ場合にバリデーションがかかります。
SQL - ランダムに行を取得したい


主にデバッグで。

参考URL

- http://stackoverflow.com/questions/19412/how-to-request-a-random-row-in-sql

```SQL
SELECT column FROM table
ORDER BY RAND()
LIMIT 1
```

ただしこの方法は大きいテーブルだと重くなるらしい。
行が計算を必要とする乱数と連携するためにシーケンシャルなスキャンが発生するから、らしい。

これを一定の速度で行うならば、インデックスされた数値を納めたカラムを使って以下の様に書く。

```SQL
SELECT * FROM table WHERE num_value >= RAND() * 
    ( SELECT MAX (num_value ) FROM table ) 
ORDER BY num_value LIMIT 1
```
最近知った JavaScript のメソッドや記法の話

## 概要
こんにちは TOMMY です。
タイトルのとおりですが今日は JavaScript の話です。ぶっちゃけ別に大した内容じゃないんですが、最近こんなメソッドや記法を知って地味に便利で感動しているっていう話を書きたいと思います。

## String.prototype.padStart()
[String.prototype.padStart() - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/padStart)

```js:基本形
"1".padStart(2, 0); //=> "01"
"12".padStart(2, 0); //=> "12"
```

↓パッと思いつく使い方としては、日付などの 0 埋めなどでしょうか。

```js:月を0埋めしてみる例
const date = new Date();
console.log(
  (date.getMonth() + 1).toString().padStart(2, 0)
); //=> "02"
```


ちなみに 0 埋めだけなら slice を使う手もあります。わりとこっちも好きです。
[String.prototype.slice() - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/slice)

```js:sliceを使った例
const date = new Date();
console.log(
  ("0" + (date.getMonth() + 1)).slice(-2)
); //=> "02"
```

ただ、前者のほうが英単語的に何をやっているかが直感的でわかりやすいかと思います。ん？直感的か？と思った方は、詰め物の pad (パッド) って考えればピンと来るんじゃないでしょうか。肩パッドとか、胸パッドとか(ぁ

## Template literals (Template strings)
[Template literals (Template strings) - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)

こんなかんじでバッククオートを使うと文字列に式を埋め込むことができます。

```js:使用例1-メソッド呼び出し
console.log(`現在は${new Date().getFullYear()}年です。`);
//=> 現在は2019年です。
```

```js:使用例2-変数
const nowYear = new Date().getFullYear();
console.log(`現在は${nowYear}年です。`);
//=> 現在は2019年です。
```

```js:使用例3-演算など
console.log(`現在は${2017 + 1 + 1}年です。`);
//=> 現在は2019年です。
```

下記はES5以前でよくやっていた文字列を連結する方法です。

```js:ES6以前からある文字列連結
const nowYear = new Date().getFullYear();
console.log("現在は" + nowYear + "年です。");
//=> 現在は2019年です。
```

数が少なければこれでもいいんですが数が増えたり、区切りが細かくなってくると差は歴然としてくるとおもいます。

百聞は一見に如かずということでこちらをご覧ください。

```js:テンプレートリテラルと従来の文字列連結の比較
//テンプレートリテラル
const template = `現在は${nowYear}年${month}月${date}日(${day})です。`
//従来の文字列連結
const concat   = "現在は" + nowYear + "年" + month + "月" + date + "日" + day + "です。"
```

明らかにテンプレートリテラルのほうが読みやすいかと思います。ついでに後者は書くのも面倒ですし、油断すると文字列の閉じクオート忘れたりもして余計面倒です(僕だけか

## Support
- [Can I use... pad-start-end](https://caniuse.com/#feat=pad-start-end)
- [Can I use... template-literals](https://caniuse.com/#feat=template-literals)

今日紹介したものはどちらもIEはダメです。IEでどうしても使いたい場合は [Babel](https://babeljs.io/) 等によるトランスパイル必須です。IEはほんとWEB開発者泣かせですね:scream:

それにしても ES6 にさわりはじめたころは Babel が手放せなかったんですが、近頃は最新版の Chrome や Firefox なら軒並み素で動くようになってきましたね。

もしご存知なかったという方がいらっしゃいましたら、けっこう便利なので機会があればぜひ使ってみてください。

それでは。
サードパーティーで発行された証明書をACMに再インポートするときに注意する事(CloudFront利用時)

## 結論
この辺を注意です。

- リージョンを確認する
- 反映時間が思ったより長い

## リージョンを確認する
Amazon CloudFront で証明書を利用する場合は、リージョンを要チェック。
東京リージョンは対応していないので、バージニア北部を利用する必要があります。
[AWS Certificate Manager への証明書のインポート](https://docs.aws.amazon.com/ja_jp/acm/latest/userguide/import-certificate.html)

> Amazon CloudFront で証明書を使用するには、米国東部（バージニア北部） リージョンに証明書をインポートする必要があります。


## 反映時間が思ったより長い
約12時間ほどかかりました。
設定は間違っていないと思いつつ、実反映までの時間が長いと不安でしたが、
結局約12時間で反映しました。(心臓に悪い。)
その間、設定を見直したり、公式サイト読んだりしていました。

環境により反映時間は変わると思いますが、基本的に余裕を持って作業されることをお勧めします。

## 反映されたか？の確認方法
Chromeで確認できます。
Global Signさんが記事にしてたのでご確認ください。
[SSL証明書の内容と確認する方法](https://jp.globalsign.com/ssl-pki-info/ssl_practices/authentification.html)

## 感想
メモを残しておかないと次回も不安の12時間を過ごしそうなので、記事にしました。
php-master-changes 2019-02-26

今日は以前に行ったテスト修正のマージし直し、zend_vm_gen.php のリファクタリングがあった！

# 2019-02-26
## nikic: Fix tests bareword fallback with error suppression
- https://github.com/php/php-src/commit/b4cbf6faca9d44fb569e308e6909497c1da8fadf
- [7.4~]
- [以前に行ったテスト修正](https://qiita.com/sj-i/items/f71dd92b38dbb077fd58#guilliamxavier-fix-tests-bareword-fallback-with-error-suppression)のマージし直しっぽいんだけど、パッと見だとなんかよう分からんなこれ
- なんかマージミスとかで消してしまってたのだらうか

## beberlei: Make regex replacements in zend_vm_gen.php more obvious
- https://github.com/php/php-src/commit/d303225c3a463cb0a7dabb51234adf684de13fa5
- [7.4~]
- zend_vm_gen.php で、[preg_replace()](http://php.net/manual/ja/function.preg-replace.php) の引数の与え方を変更して何がどう置き換えられるかの対応が分かりやすくなるよう修正
- 対応表から [array_keys()](http://php.net/manual/ja/function.array-keys.php) と [array_values()](http://php.net/manual/ja/function.array-values.php) で引っ張ってくる形に
Win7からWinServ2012R2へのリモートデスクトップが切れる

ので
「接続が失われました セッションに再接続中」と表示されるので
ググってみると

https://answers.microsoft.com/ja-jp/windows/forum/all/%E3%83%AA%E3%83%A2%E3%83%BC%E3%83%88%E3%83%87/5161fb0a-b15c-432c-8abf-b498f736debc?auth=1

--------
接続品質自体が怪しいような気もしますが…。

ping応答を返す適当なinternet siteに-tオプションつけてpingを継続的に打ってみて、remote desktopが切れた時に同時に応答性が低下していないか見てみるとか?

--------
とあったので
ping -t www.google.com
とやってみると
接続が失われました セッションに再接続中
と表示される時に
接続がタイムアウトされました。

と表示されます……

回線の品質の問題かな？？？
カタパルトのCowでトランザクション手数料を設定する

# はじめに

カタパルトのCowが出ました。どうやら、手数料の設定ができるようになったみたいです。

# 手数料設定

https://github.com/nemtech/catapult-server/blob/master/resources/config-node.properties#L20

```
minFeeMultiplier = 0
```

# やってみる

## 設定

最低手数料積？は100にしてみます。

```
minFeeMultiplier = 100
```

まず、使用するアカウントの残高を見てみます。

初期の残高は、`[2811359534,963522852]`が`[1004000100,0]`あります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/172833/aede8928-d5c5-0e20-5127-615b7379b0c0.png)


では、トランザクションを送信していこうと思います。

## 手数料なし

はじめは、手数料なし。送金金額は`1000000`。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/172833/2acce896-f9aa-9b34-c739-4096537df8ff.png)

送れませんでした。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/172833/a185b6bd-0cc2-9239-0c08-bac7b3739805.png)

ノードのコンソールには、このようなログが記録されていました。

```
api-node-0_1              | 2019-02-22 00:47:01.007738 0x00007ff396fed700: <info> (chain::UtUpdater.cpp@144) dropping transaction 4BD3CC536CCECC8FCA9C2275844C136F454B9FD75464D5C12711DE04060F0409 with max fee 0 because min fee is 16500 
peer-node-1_1             | 2019-02-22 00:47:01.218005 0x00007fc6dcff1700: <info> (chain::UtUpdater.cpp@144) dropping transaction 4BD3CC536CCECC8FCA9C2275844C136F454B9FD75464D5C12711DE04060F0409 with max fee 0 because min fee is 16500 
peer-node-0_1             | 2019-02-22 00:47:01.370277 0x00007f8fe3ff7700: <info> (chain::UtUpdater.cpp@144) dropping transaction 4BD3CC536CCECC8FCA9C2275844C136F454B9FD75464D5C12711DE04060F0409 with max fee 0 because min fee is 16500 
```

手数料は最低`16500`でないとだめそうです。

## 手数料付き

次は、手数料`1000000`で送ってみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/172833/ad12a35a-ff3d-57fa-1dd3-6c60dd62dc28.png)

送れました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/172833/1fa822db-24b7-851a-b6dd-a7de33eff0de.png)

`"maxFee": "1000000"`と書いてあります。

残高はどうなったでしょうか

![image.png](https://qiita-image-store.s3.amazonaws.com/0/172833/0833ae5e-7975-e82a-9816-b46d494d875e.png)

`[1004000100,0]`から、`[1002000200,0]`になりました。

`1999900`少なくなりました。

送金金額を差し引くと、`999900`引かれたことになります。指定した手数料より少し小さいですね。

# 手数料の計算

以上の出来事から手数料の計算について推測します（ソースを見ればわかると思うけど、見かたがわからない）。

- 設定した手数料を超えない最大のトランザクションサイズ倍数が引かれる。
- 最低手数料は、トランザクションサイズと`minFeeMultiplier`の積である。

まず、今回送信したトランスファートランザクションの先頭4バイトは、`A5000000`となっており、これはサイズが165バイトであることを意味します。

なので、手数料0で送ると`16500`以上出せと怒られたのだと思います。

また、`999900`は、`165 * 6060`なので、たぶん、トランザクションサイズに関係しているのだと思いました。

# ハーベスト

手数料として引かれた金額は、ブロック作成者にいっているのでしょうか。見てみます。

まえ

![image.png](https://qiita-image-store.s3.amazonaws.com/0/172833/2b13359e-4f6e-31ae-e1e4-769662668ff6.png)

あと

![image.png](https://qiita-image-store.s3.amazonaws.com/0/172833/457133f7-0169-2b78-3ddc-1fb8cd5d645b.png)



`[2811359534,963522852]`が、`[3969189972,95248]`から`[3970189872,95248]`に増えました。

差分はしっかりと`999900`になってます。

# おわりに

この仕様はこれからまた変わっていくと思います。
外部サーバーの Docker の MySQL に Sequel Pro から接続する

Docker で運用している Redmine の MySQL サーバーに [Sequel Pro](https://www.sequelpro.com/) からアクセスしようとしたら、以下のエラーメッセージが表示されて接続できない。

```
Lost connection to MySQL server at 'reading initial communication packet', system error: 0
```

外部サーバーに SSH で接続してコンソールから mysql コマンドで接続することは成功している。

```bash
mysql -h 127.0.0.1 -u root -p
```

MySQL サーバーの接続ホスト名を `0.0.0.0` や `172.18.0.2` (コンテナの IP アドレス) などにしてみるも変わらず。

```bash
grep refused /var/log/secure
```
```
Feb 27 05:49:29 rm sshd[23858]: refused local port forward: originator 127.0.0.1 port 54698, target 172.18.0.2 port 3306
Feb 27 06:34:16 rm sshd[25509]: refused local port forward: originator 127.0.0.1 port 55548, target 0.0.0.0 port 3306
Feb 27 06:34:40 rm sshd[25530]: refused local port forward: originator 127.0.0.1 port 55565, target 127.0.0.1 port 3306
```

`/var/log/secure` を覗くと `refused local port forward` というエラーが出力されているので検索すると `/etc/ssh/sshd_config` の `AllowTcpForwarding` ディレクティブが影響するよう。

```bash
grep ^AllowTcpForwarding /etc/ssh/sshd_config
```
```
AllowTcpForwarding no
```

Docker が動作しているホスト OS の `sshd_config` の `AllowTcpForwarding` の値が `no` になっていた。

`AllowTcpForwarding` は TCP 転送を許可するかどうかを指定する。 [^AllowTcpForwarding]

[^AllowTcpForwarding]: ["Specifies whether TCP forwarding is permitted." - AllowTcpForwarding - sshd_config(5) - OpenBSD manual pages](https://man.openbsd.org/sshd_config#AllowTcpForwarding)

```
sed -i '/^AllowTcpForwarding/ s/no/yes/' /etc/ssh/sshd_config
systemctl restart sshd
```

`AllowTcpForwarding` の値を `yes` に変更して sshd を再起動したところ、無事に Sequel Pro で Docker コンテナの MySQL サーバーに接続することができた。
MacBook* でDrag＆Dropできない場合の対処法

## 結論
OS再起動しましょう。
自分のケースでは２台ともそれで治りました。

## 経験談

- 2019/02/04 MacBook Pro
    - High Sierra
- 2019/02/27 MacBook Air
    - Mojave

にて経験しました。

不調時の共通点としては、トラックパッドの下端のクリック感がなくなっていました。

※ 個人的には、このクリック感がソフトウェア的に制御されているとは思ってなかったので、驚きでした。
IoT向けの軽量なKubernnetes(?) k3sとはなにか

# はじめに

こちらは、2/26付けでRancher Labs社より発表のあった軽量なKubernetes distributionであるk3sに関する解説の記事です。

## k3sとは
[k3s](https://k3s.io/)は、[Rancher Labs社](https://rancher.com/)が発表した軽量な[Certified Kubernetes distribution](https://www.cncf.io/certification/software-conformance/)(CNCF公式の認証付き)の1つで、40MB未満のバイナリと、わずか512MBのメモリ使用量を特徴としています。

その軽さから、以下の環境において強さを発揮するとしています。

- CI
- IoT
- ARM環境
- エッジコンピューティング

もともとは、RancherのエンジニアであるDarren Shepherd([@ibuildthecloud](https://twitter.com/ibuildthecloud))が個人で始めたものが、最近になってRancher社のプロダクト傘下に入ったようです。

rioというコンテナをもっと気軽に使えるようにしようぜ！というプロジェクトがRancherにはあって、そのベースとなるコンテナオーケストレーションエンジンとして始まったのがk3sだったのですが、「あれ、これ軽量なエンジンとして単体で出したら需要あるんじゃね？」と思って独立したプロジェクトにしたんだそうです。

## なんでk3s?読み方は?
Kubernetesと比べて5つの変更があるから、らしいです。(k8s-5)
読み方は[確認中](https://github.com/rancher/k3s/issues/55)だけどkatesだったようなそうじゃなかったような


## Rancher Labsって何の会社？
Rancher Labs(以下、Rancher社)は、Kubernetesをベースとしたコンテナ環境の構築や管理をGUIベースで可能とするOSS、Rancherの開発元です。

オンプレ、パブリッククラウドなどの環境を跨いでクラスタの管理ができることが大きな特徴で、Kubernetes環境をマルチクラウドで構築する際に非常に便利なソリューションの1つとなります。

## k3sの最低動作環境

|項目|条件|
|---|---|
|Linuxカーネル|3.10以上|
|各サーバーのRAM|512MB以上|
|各ノードのRAM|75MB以上|
|ディスク容量|200MB以上|
|対応アーキテクチャ|x86_64, ARMv7, ARM64|

参考までに、Kubernetes単体の要件としては、API Serverを動かすのには1GB以上のRAMがあって、x86_64のCPUを使っているのが「望ましい」と[ドキュメント](https://kubernetes.io/docs/setup/scratch/#nodes)にはそれとなく書かれていたりします。ですが、実際にはもっと高スペックなマシンを利用するケースが多いはずです（無論、規模によります）。

それと比べ、k3sは非常に小さな環境でも動作します。どうしてなのでしょうか？
いくつか、特徴的な部分をピックアップしてみることにします。

### Kubernetesの中で利用シーンの少ない機能を削っている
Kubernetesには、後方互換性のために残しているレガシーな機能やAPIや、新たに追加されようとしているAlphaやBetaの機能が多数存在します。
k3sでは、軽量化のためにそれらの機能を削っています。

### デフォルトのetcdをsqlite3にしている
etcdは非常に高い信頼性を誇るGo言語製のKVSで、Kubernetesにおいてもデフォルトのステート管理に使われています。
k3sでは、より軽量でファイルベースのsqlite3をデフォルトのストレージ機構に用いていますが、こちらはetcdを選ぶことも可能です(※発表時点では、etcdはまだ動作しないみたいです)。

### デフォルトのランタイムをcontainerdにしている
Kubernetes自身は、管理者からの指定がない限りはDockerをデフォルトのコンテナランタイムとして利用しようとします。
k3sでは、Dockerが内部的に利用しているCRI、containerdを利用するため、より軽量な動作が可能なようです。

### バイナリ1つで全部入り
>k3s is packaged as a single binary which is about 40 megabytes in size. Bundled in that single binary is everything needed to run Kubernetes, including the container runtime and any important host utilities like iptables, socat, and du. The only OS dependencies are the Linux kernel itself and a proper dev, proc, and sysfs mounts (this is done automatically on all modern distros).

と公式の発表であるように、40MBのバイナリに必要なもの全て(ランタイム、ネットワーク周り含む)が入っています。そのため、kubeadmと違ってCNIやCRIを自前で入れる必要もありません。便利。

### プロセスの統合化
Kubernetesの管理ノードで使われるコンポーネント(kube-apiserver, kube-controller-manager, kube-scheduler, kubelet, kube-proxy)のプロセスを統合化することで、消費メモリの節約を行っているようです。ようやったな。

### インストールオプションの簡素化
Kubernnetesにおいてはkubeadmなどがインストールオプションを大幅に簡素化してくれますが、k3sでもそれに近い開発者体験が得られるようになっています。CNIやCRIのインストールが要らない分、かなりセットアップ時間は短そうです。

## 所感

うーん、どうなんでしょうね。わかんないけど面白いことになってほしいです。
Kubernetesは機能が豊富ゆえ、それ自体が重くなりがちなのは間違いないと思っていて、こいつがKubernetesの利用シーンを広げてくれるといいですね。
Rancher社は、他のビッグネームなベンダたちにに真っ向から向かっていく感じがあってとても面白いので、今後も大きな動きに期待しています。

Moby Projectが出てきたときに「コンテナの標準化」という動きが始まり、その中でIoTやエッジコンピューティングにおけるコンテナ技術もそのうち何か出てくるんだろうなあとぼんやり考えていたところ、今回このk3sがRancherの公式なプロジェクトとして入るとの知らせが入って、いよいよ来たかという感じはしています。

情報がまだまだ少ないので分かり次第追記していく所存です。
ElmでHelloWorld

@jinjor さんが書いたElm本がついに発売されました！うきうきしています。
https://www.amazon.co.jp/dp/B07P253FPG/ref=cm_sw_r_tw_awdb_c_x_9TBDCbY7VKWY7

ガイドにはなかったような気がするHelloWorldを見て、コンパイラ母さんはどこまで親切に教えてくれるのか気になり始めて試しました。

# 意味のない文字列だけのソース

```elm:
adgjpmtwp
```

```:make結果
$ elm make src/hello.elm                 Detected errors in 1 module.
-- PARSE ERROR --------------------------------------------------- src/hello.elm

Something went wrong while parsing your code.

2|
   ^
I was expecting to see more indentation? I was not done with that last thing
yet.
```

「パースできなかったんだけどぉ。これインデント？」(適当翻訳)

#　mainだけは書いてあるソース

```elm:
main = 1
```

```:make結果
$ elm make src/hello.elm
Detected errors in 1 module.
-- BAD MAIN TYPE ------------------------------------------------- src/hello.elm

I cannot handle this type of `main` value:

4| main =
   ^^^^
The type of `main` value I am seeing is:

    number

I only know how to handle Html, Svg, and Programs though. Modify `main` to beone of those types of values!
```

「俺はこんな型のmainはしらねー。俺にはnumber型に見えるんだけど。俺が知ってるのはHtml、Svg、Programs型だけだ。直して！」(適当翻訳)

# じゃあHtml型を代入してみるか...

ということで、リファレンスのhtmlを参照。
https://package.elm-lang.org/packages/elm/html/latest/Html

本に出てきたtext関数が載っています。
文字列を引数にとってHtmlを返す。これだ。

```elm:importつけないとHtmlを認識してくれないのでつけた
import Html
main = Html.text "Hell World!"
```

```:実行結果(ブラウザにて確認)
Hell World!
```

# というわけで...
mainさえ書いてあればなんとか動かすところまで行ける！親切！ありがとう！
jupyterをsystemdで自動起動する

※ 2019/2/28 ユニットファイルがrootでjupyterを起動する設定になっていたので, "user"グループのユーザ名"user"で起動するよう修正

## 背景
GCPで構築しており（従量課金なので）使っていないときはサーバを落とているが、OS起動のたびにコンソールに入って`jupyter notebook`と打つのが面倒だったので

## 環境
- OS: debian 9 stretch
- ユーザ名"user"でAnacondaを導入済み
- 環境名は"seminar"

## 構築手順
**1. ユニットファイル作成**
まずはユニットファイルの作成から。細かい設定は正直わからない部分もあった... （`WantedBy`ってなんだ？）

```bash
sudo vim /etc/systemd/system/jupyter.service
```

ファイル内容は以下の通り

```bash:/etc/systemd/system/jupyter.service
[Unit]
Description=Jupyter Notebook (seminar)

[Service]
Type=simple
WorkingDirectory=/home/user
ExecStartPre=. /home/user/anaconda3/etc/profile.d/conda.sh; conda activate seminar
ExecStart=/home/user/anaconda3/envs/seminar/bin/jupyter notebook --config=/home/user/.jupyter/jupyter_notebook_config.py
User=user
Group=user

[Install]
WantedBy=multi-user.target
```

Anacondaの環境を切り替えるために`ExecStartPre`を指定しているので、素のjupyterならもっと簡単になると思う。設定ファイル(`jupyter_notebook_config.py`)を生成していなければオプション（`--config`）は不要。`WorkingDirectory`は指定不要な気もしたけど、後で気づいたのでそのままに。。。


**2. 起動確認**
正常に動作するか`systemctl`で確認してみる。

```bash
sudo systemctl start jupyter
sudo systemctl status jupyter
```

これでエラーっぽいログが出力されず、jupyterにアクセスできればOK

**3. 自動起動化**
以下のコマンドで自動起動を有効化する。

```bash
sudo systemctl enable jupyter
```

一応OSを再起動してみてjupyterにアクセスできればOK
条件文の分解(Decompose Conditional)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/257568/fdaf5b9d-a029-52fa-35b6-44022684defa.png)


1つずつリファクタリング技法まとめ
個人的に簡単かつ取り入れ易いと思うものから

## 目的
すぐ引き出せるようにする

## 基本作業サイクル
- システムを動かして仕様を精査
- テストメソッドを作成
- テストの失敗を確認
- テストの成功を確認
- 小さい変更、随時テスト実行(失敗確認->成功確認)
- 最後テスト実行
- 最後動作確認

## 条件文の分解(Decompose Conditional)とは
判定メソッド化
条件文をメソッドとして抽出し、メソッド名に意味を持たせること
 
## ポイント
- 算術演算子をifの条件式から消す。
- 複数の条件式の示す意味をメソッド名にする。
- コメントに記載してある内容をメソッド名にする。

## 例
```
# 平成
if i >= 1989 && i <= 2019

end
```
　　　↓

```
def heisei?(i)
  i >= 1989 && i <= 2019
end

if heisei?(i)
  puts '多分平成'
end
```  

## 書籍情報
Jay Fields (著), Shane Harvie (著), Martin Fowler (著), Kent Beck (著),
長尾 高弘(訳), リファクタリング:Rubyエディション
https://amzn.to/2VlyWML

## 雑感
スコープが狭くて影響が小さいものから
Rspec導入まとめ

最低限の導入手順を記載
後ほどいつもやりそうな初期設定を追記

## 事前設定
config/database.ymlにtestの指定がある事

```ruby:config/database.yml
test:
  <<: *default
  database: プロジェクト名_test
```
テストを導入したい環境に以下のgemを指定している事

```ruby:Gemfile
group :development, :test do
    ・
    ・
  gem 'rspec-rails', '~> 3.6'
  gem 'factory_bot_rails'
  gem 'database_cleaner'
    ・
    ・
end

```
## 導入

rspecに必要なモジュールをインストールする 

```
bundle install
rspec:install
rails generate rspec:install
```

下記を追記

```ruby:spec/support/factory_bot.rb
RSpec.configure do |config|
  config.include FactoryBot::Syntax::Methods
end
```
テスト用DBの作成

```
rails db:migrate RAILS_ENV=test
```

## 実行方法
```
rspec spec/対象の階層下 or ファイル
```
Mac で git send-email して Net/SMTP/SSL.pm がないと言われたら

# エラーの内容

Gmail の SMTP server で git send-email しようとしたらエラーになった。
macOS High Sierra バージョン 10.13.6 で git のバージョンは

```
$ /usr/bin/git --version
git version 2.15.2 (Apple Git-101.1)
```

エラーメッセージは

```
$ /usr/bin/git send-email 0001-add-readme.patch
... 略 ...
Can't locate Net/SMTP/SSL.pm in @INC (you may need to install the Net::SMTP::SSL module) (@INC contains: /Applications/Xcode.app/Contents/Developer/usr/../Library/Perl/5.18/darwin-thread-multi-2level /Applications/Xcode.app/Contents/Developer/usr/share/git-core/perl /Library/Perl/5.18/darwin-thread-multi-2level /Library/Perl/5.18 /Network/Library/Perl/5.18/darwin-thread-multi-2level /Network/Library/Perl/5.18 /Library/Perl/Updates/5.18.2/darwin-thread-multi-2level /Library/Perl/Updates/5.18.2 /System/Library/Perl/5.18/darwin-thread-multi-2level /System/Library/Perl/5.18 /System/Library/Perl/Extras/5.18/darwin-thread-multi-2level /System/Library/Perl/Extras/5.18 .) at /Applications/Xcode.app/Contents/Developer/usr/libexec/git-core/git-send-email line 1450.
```

# 解決方法

```
$ sudo -H cpan5.18 Net::SMTP::SSL
```

でモジュールをインストールしたら解決した。

# はまったこと

手元の環境では Homebrew でインストールした perl が存在していたため、バージョン明記して cpan5.18 とするのではなく cpan コマンドを実行したら、git send-email が使ってたのとは別のバージョンの perl に対してインストールしてて効かなかった。

# 教訓

エラーメッセージはちゃんと読もう（ちゃんと読んでいれば perl5.18 が使われているとわかった）

# 参考: Gmail を使う準備

.gitconfig に以下を記載

```
[sendemail]
        smtpencryption = tls
        smtpserver = smtp.gmail.com
        smtpuser = ユーザ名@gmail.com
        smtpserverport = 587
```

二段階認証の設定をしている場合は https://support.google.com/mail/answer/185833?hl=ja を参考にアプリパスワードを発行しておく