OmniAICreator/Qiita-1.07M huggingface dataset:
weather-jsを使ってDiscordに天気を送る

#使うもの
```$ npm i weather-js```
weather-js
```$ npm i discordjs/discord.js```
masterブランチのDiscord.js
#コードたち
```js
  const args = message.content.slice(/*ここにプレフィックス*/).trim().split(/ +/g);
        weather.find({search: args[0], degreeType: 'C'}, function(err, result) {
            if (err) message.channel.send(err);
            if (result.length === 0) {
                message.channel.send('**場所を取得できませんでした**') 
                return; 
            } 
            var current = result[0].current;
            switch(current.skytext){
            case "Mostly Sunny": 
            var skytext = "ほぼ晴れ";
            break;
            case "Cloudy" :
            var skytext = "曇り";
            break;
            case "Partly Cloudy":
            var skytext = "晴れのち曇り";
            break;
            case "Sunny":
            var skytext = "晴れ";
            break;
            case "Clear" :
            var skytext = "雲1つない快晴";
            break;
            case "Mostly Clear":
            var skytext = "ほぼ快晴";
            break;
            case "Mostly Cloudy":
            var skytext = "ほぼ曇り";
            break;
            case "Partly Sunny":
            var skytext = "所により晴れ";
            break;
            case "Light Rain":
            var skytext = "小雨";
            break;
            default:
            var skytext = current.skytext;
            break
            }
            const embed = new Discord.MessageEmbed()
                .setDescription('**' + skytext + '**') 
                .setAuthor(`${current.date}の${current.observationpoint}の天気`) 
                .setThumbnail(current.imageUrl) 
                .setColor(Color) 
                .addField('温度',`${current.temperature}℃`, true)
                .addField('体感温度', `${current.feelslike}℃`, true)
                .addField('風',current.winddisplay, true)
                .addField('湿度', `${current.humidity}%`, true);
            message.channel.send(embed);
        });
```
#動作
[![Screenshot from Gyazo](https://gyazo.com/1a85fdfe1c2c76ea5c8ace4a493d7b5c/raw)](https://gyazo.com/1a85fdfe1c2c76ea5c8ace4a493d7b5c)
#説明
weather.findのところはweather-jsの機能で、天気を探しているやつ。
searchのところは検索する場所(地名),DegreeTypeはCとFのやつ。Cをお勧めする
if(err)からswitchの場所までは地名を検索できないまたはエラーが出た時の動作。
switchはそのままweather-jsから引っ張ると英語なので翻訳した。
翻訳しなくていいなら、switchのところをぜーんぶ消してembedのsetDescriptionをcurrent.skytextに変える。
#最後に
天気を取得するとき、APIの仕様変更やいろいろのせいで泥沼にハマってしまったので、記事を作ってみました。
実は、これ初めての記事なので悪い部分があれば指摘をお願いします。
もしこの記事を見てDiscord.jsに興味が沸いたら、
Discord.js全般の[コミュニティ](https://discord.gg/DbTpjXV)があるのでそこでさらに詳しい情報が得られると思います。

#参考にしたサイト
[Discord.jsのライブラリ](https://Discord.js.org/#/)
[weather-jsのnpmのサイト](https://www.npmjs.com/package/weather-js)
Bootstrap4をカスタマイズしてソースからビルド

意外と簡単にできるので紹介

###ソースの入手
以下のサイトからSource filesの見出しにある[Download source]からダウンロード
https://getbootstrap.com/docs/4.1/getting-started/download/

###Node.js
以下のサイト、もしくはyumなどで予めNode.jsをインストールしておいてください。
https://nodejs.org/ja/

###ソースの確認
ダウンロードしたソースのアーカイブを解凍して中身を確認してみてください。

###カスタマイズ例
今回カスタマイズしてみるのは
[Bootstrapのトップ(解凍した)ディレクトリ]/scss/にあるファイルの_variables.scssを書き換えて配色パターンに
ピンク系のthirdaryというパターンを足してみます。
74行目辺りにあるsecondaryの下にthirdaryを足します。

```scss:_variables.scss
$secondary:     $gray-600 !default;
$thirdary:      $pink !default;
```
87行目辺り(上記改変前は86行目)にあるsecondaryの下にthirdaryを足します。

```scss:_variables.scss
    "secondary":  $secondary,
    "thirdary":   $thirdary,
```

###ビルド
解凍したディレクトリのトップで以下のコマンドを実行してビルドに必要なパッケージ群をインストールします。

```terminal
$ npm install
```
また以下のコマンドにてビルドを実行します。

```terminal
$ npm run dist
```

###ビルドしたBootstrapの確認
ビルド後に[Bootstrapのトップディレクトリ]/dist/にあるcss,jsディレクトリを適当にコピーし
以下のようなhtmlを書いてみてピンク色のボタンが表示されれば成功です。

```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Custom Bootstrap</title>
<link rel="stylesheet" href="css/bootstrap.min.css" />
<script src="https://code.jquery.com/jquery-3.3.1.js" integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60=" crossorigin="anonymous"></script>
<script src="js/bootstrap.min.js"></script>
</head>
<body>
<br />
<div class="container">
<input type="button" value="Thirdary Button" class="btn btn-thirdary"/>
</div>
</body>
</html>
```

ちなみに原因はわかっていないのですが
解凍直後のディレクトリにあるdistとビルドした後にできるdistの内容を比較したところ
以下の定義だけ生成されていないことを確認しています。

```css:bootstrap.css
.form-control:-ms-input-placeholder {
  color: #6c757d;
  opacity: 1;
}
```
Terraformでリソースを参照するのに困ったとき

#TerraformのTips

Terraform書いていてリソースを参照するとき具体的に追加すればよいか困るときがあります。そんなときの対処法です。

例えばPeering作成してRouitingにそのPeeringを追加するということをしましょう。
とはいえ、ルーティングを追加したいのでまずaws_routeでググります。
見つけた[aws_route](https://www.terraform.io/docs/providers/aws/r/route.html)でvpc_peering_connection_idというところにpeeringのidが必要とわかります。
ここでpeeringのリソースをググってもそのドキュメントが出てきてそのIDを取得する方法がわかりません。そういうとき私の場合は下記をBookmarkしていてこちらに来てソースをみます。。
https://github.com/terraform-providers/terraform-provider-aws/tree/master/aws
この中でファイル名からそれらしきものを探します。
[それらしきソース](https://github.com/terraform-providers/terraform-provider-aws/blob/master/aws/data_source_aws_vpc_peering_connection.go)を見つけます。
[スキーマ](https://github.com/terraform-providers/terraform-provider-aws/blob/master/aws/data_source_aws_vpc_peering_connection.go#L16-L79)を探します。詳しくはソースをたどって行く必要がありますが、辿らなくてもこれかな？と思うものを使用してterraform planしていけば問題がある場合はエラーになりますので大丈夫です。今回の場合idというものがあるのでそれかなと試します。

今回の場合は具体的には下記のようになるでしょう。

```
resource "aws_route" "someroute" {
  route_table_id         = "[ルートテーブルのID]"
  destination_cidr_block = "x.x.x.x/24"
  vpc_peering_connection_id = "${aws_vpc_peering_connection.hogehoge.id}"
  ## ↑ここのidを知る方法知りたかったということです
  depends_on             = [どこかのリソース名]
}
```
全問正解クイズのサンプルをActions on Google のInline Editorだけで作成した

# 全問正解クイズのサンプルを作成


# 「うんこパンツ検定」を公開
うんこパンツ検定は、全問正解クイズです。「うんこ」または「パンツ」の２つのモードを備えています。また、モード選択時に、質問内容のキーワードに関する解説を聞くことができます。
https://assistant.google.com/services/a/uid/00000039ea22b626?hl=ja
WordPress 5.0 強制クラシックエディター

WordPress5.0ではGutenbergという新しいエディターが採用されました。  
  
ですが、WordPress4.9.8以下からのマイグレートとなると新しくGutenbergに対応が難しい場合もあるかと思います。

そこでこのフィルターフックでFalseを返してあげることで従来のエディターが呼び出せるようです。


```php
// force classic editor mode
add_filter('use_block_editor_for_post',function($use_block_editor){
    return !$use_block_editor;
});
```
※RC2現在の状態なので、今後残るかはわかりません。
※5.0リリース版でも存在してました。

[Classic Editor](https://ja.wordpress.org/plugins/classic-editor/)プラグインをインストールできない状況などにご活用ください。

#2018/12/12 追記
[@webbingstudio@github](https://qiita.com/webbingstudio@github/items/f86e964226e7617a72f4)さんの投稿のようにAdvanced Custom Fieldsなどカスタム投稿を利用した機能拡張プラグインを使用している場合、この設定が干渉しプラグインが正しく動作しない場合があることが確認できました。

詳しくは[WordPress5.0でプラグインの新規追加画面・編集画面が真っ白になった場合の対処](https://qiita.com/webbingstudio@github/items/f86e964226e7617a72f4)を参照してください。

ACFを使用した場合のみここに記述しておきます。

```php
// force classic editor mode
add_filter('use_block_editor_for_post',function($use_block_editor){
    if($post->post_type === 'acf-field-group'){
        $use_block_editor = false;
    }else{
        $use_block_editor = true;
    }
    return $use_block_editor;
});
```
バーゼル問題と数値計算

## はじめに
この記事はBasel問題

```math
\sum_{n \in \mathbb{N}_+} \frac{1}{n^2}
```

を計算する問題を数値計算でやってみるというものです。
よく知られているようにこの問題の答えは$\pi^2/6$です。

## 解法1: 素直にとく
数値計算でこの問題を解く場合、当然無限大までの和を考えることができませんから、どこかで打ち切ったもの、つまりある程度大きな数$N$を定義して、

```math
S_n := \sum_{n = 1}^{N} \frac{1}{n^2}
```

という数を計算することになります。例えば、C++ではこのように計算できます。

```cpp
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;

const double target = M_PI * M_PI / 6;

void calc1(long n_max)
{
  double sum = 0;
  cout << "start calc1" << endl;
  for (long i = 1; i <= n_max; ++i){
    sum += 1.0 / (i * i);
  }
  cout << "result: " << fixed << setprecision(15) << sum << endl;
  cout << "diff: " << scientific << target - sum << endl;

}

int main () 
{
  const long n_max = 1000000000; // 10^9
  cout << "target: " << setprecision(15) << target << endl;
  calc1(n_max);
  return 0;
}
```

これを計算すると、

```terminal
target: 1.64493406684823
start calc1
result: 1.644934057834575
diff: 9.013651380840315e-09
```

このように計算できるはずです。

## 方法２: ちょっと工夫する

少し工夫して、逆順に計算してみましょう。

```cpp
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;

const double target = M_PI * M_PI / 6;

void calc1(long n_max)
{
  double sum = 0;
  cout << "start calc1" << endl;
  for (long i = 1; i <= n_max; ++i){
    sum += 1.0 / (i * i);
  }
  cout << "result: " << fixed << setprecision(15) << sum << endl;
  cout << "diff: " << scientific << target - sum << endl;

}

void calc2(long n_max)
{
  double sum = 0;
  cout << "start calc2" << endl;
  for (long i = n_max; i >= 1; --i){
    sum += 1.0 / (i * i);
  }
  cout << "result: " << fixed << setprecision(15) << sum << endl;
  cout << "diff: " << scientific << target - sum << endl;
}

int main () 
{
  const long n_max = 1000000000;
  cout << "target: " << setprecision(15) << target << endl;
  calc1(n_max);
  calc2(n_max);
  return 0;
}
```
これを実行すると

```terminal
target: 1.64493406684823
start calc1
result: 1.644934057834575
diff: 9.013651380840315e-09
start calc2
result: 1.644934065848226
diff: 1.000000082740371e-09
```

となります。
１桁程度精度が改善しています。

## まとめ
これが起こる理由は、大きさの極端に異なる数を足し合わせることによる**情報落ち**によるものです。

大きい方から足し合わせた*方法１*の場合、足し合わせる量の大きさの差が徐々に大きくなっていくことになり、情報落ちが起きやすくなっていました。

一方、*方法２*では、小さいものから徐々に足したため、足す数同士の大きさは比較的同じぐらいになり、情報落ちが緩和されました。

情報落ちは、常に大きさが近いものを足し合わせることである程度回避できるため、例えば、

1. 足し合わせるリストをソートし
1. もっとも小さい2つを足し
1. 足し合わせたものを大きさ順で挿入し
1. 2.と3.を繰り返す

という計算を行うともう少し精度が改善します。

計算順序も数値計算には必要なこともあります。[^1]

[^1]: とはいえ、数学的にはどちらも同じものです。順序のない世界に順序を導入しないといけないということに数値解析をやり始めた時は混乱しました。
はじめに覚えるvectorscript

ハンドル　LNewObj　FSActLayer
座標取得　GetBBox( FSActLayer,  x1,y1,x2, y2);　
座標設定　SetBBox( FSActLayer,  x1,y1,x2, y2);
中心座標　(x1+x2)/2,(y1+y2)/2
高さ設定　SetWidth( FSActLayer, 375);
幅　設定　SetHeight( FSActLayer, 255);
コメント　{ }
移　　動　MoveObjs( -(x1+x2)/2, -(y1+y2)/2,FALSE,FALSE );
伸　　縮　Scale(375/(x2-x1),255/(y2-y1);

※ScriptFunctionReference.htmlで確認
Proc.newとラムダは引数の扱いが異なる

## はじめに
Rubyでブロックをオブジェクト化したいとき、Procクラスが用意されています。Procオブジェクトの生成方法は複数ありますが、今回はそれらの**引数の扱いの違い**について、学んだことをまとめたいと思います。(Ruby2.5.1)

## Procオブジェクトの生成方法
Procオブジェクトの生成方法は複数ありますが、その中でも今回は以下の４つを例に挙げたいと思います。

```ruby:
#①Procクラスのnewメソッドを使う
Proc.new {...}

#②Kernelモジュールのprocメソッドを使う
proc {...}

#③ラムダリテラルを使う
-> {...}

#④Kernelモジュールのlambdaメソッド　を使う
lambda {...}  
```

ここでは**①と②をProc.new**、**③と④をラムダ**と呼ぶことにします。

## ラムダのほうが引数の扱いに厳密である
Proc.newとラムダでは、**ラムダの方が引数のチェックが厳しく**、引数に過不足があるとエラーが発生します。

## 実際のコード
a,bの2つの引数を取り、それらを表示するProcオブジェクトを作ります。

###・ Proc.new
引数の過不足による**引数エラーは発生しません。**

```ruby:
proc = Proc.new { |a, b| p "#{a}, #{b}" }
proc.call(1)        #=> "1, "　
proc.call(1, 2, 3)  #=> "1, 2"　　　　　　　　　　     
```

```ruby:
proc = proc { |a, b| p "#{a}, #{b}" }
proc.call(1)        #=> "1, "
proc.call(1, 2, 3)  #=> "1, 2"      
```

###・ ラムダ
引数に過不足があると**引数エラーが発生します。**

```ruby:
lambda = -> (a, b) { p "#{a}, #{b}" }
lambda.call(1) 
#=> ArgumentError: wrong number of arguments (given 1, expected 2)　
lambda.call(1, 2, 3) 
#=> ArgumentError: wrong number of arguments (given 3, expected 2)　　  　       
```

```ruby:
lambda = lambda { |a, b| p "#{a}, #{b}" }
lambda.call(1) 
#=> ArgumentError: wrong number of arguments (given 1, expected 2)　　
lambda.call(1, 2, 3) 
#=> ArgumentError: wrong number of arguments (given 3, expected 2)　　        
```

## 引数の取扱の厳密さを確かめる
Procオブジェクトの引数の取扱の厳密さを確認したいとき、`.lambda?`メソッドが使えます。
引数の扱いが厳密であれば、`.lambda?`メソッドは`true`を返します。

```ruby:
proc = Proc.new { |a, b| p "#{a}, #{b}" }
proc.class    #=> Proc
proc.lambda?  #=> false
```

```ruby:
lambda = -> (a, b) { p "#{a}, #{b}" }
lambda.class    #=> Proc
lambda.lambda?  #=> true
```
https://docs.ruby-lang.org/ja/latest/method/Proc/i/lambda=3f.html


## まとめ
Proc.newとラムダでは、**ラムダの方が引数の扱いが厳密**で、`.lambda?`メソッドで引数の取扱の厳密さを確認することができました。

### 参考文献
- [プロを目指す人のためのRuby入門 言語仕様からテスト駆動開発・デバッグ技法まで ](https://www.amazon.co.jp/プロを目指す人のためのRuby入門-言語仕様からテスト駆動開発・デバッグ技法まで-Software-Design-plusシリーズ/dp/4774193976)
逆順のRangeでeachを実行した場合の挙動

eachを回した時に、何もせずエラーにもならず、そのまま処理が続いたせいでハマったので備忘録に。

#Rangeのインスタンス生成

始点<終点の場合、始点>終点の場合どちらでも問題なくインスタンス生成はできる。


```ruby
aaa = Range.new(1,5)
=> 1..5

bbb = 1..5
=> 1..5
```


```ruby
ccc = Range.new(5,1)
=> 5..1

ddd = 5..1
=> 5..1
```

#Range#each
##Range#eachの挙動
問題となるのは、逆順で生成したRangeでeachを回した場合。

```ruby
aaa.each {|i| puts i}
1
2
3
4
5
=> 1..5
```

```ruby
ccc.each {|i|puts i}
=> 5..1
```

##Range#eachの説明
るりまによるとRange#eachはsuccでイテレーションしているらしい。
https://docs.ruby-lang.org/ja/latest/method/Range/i/each.html

Integerのsuccの説明を見てみると単に次の整数を返すだけのようだ。

```ruby
aaa.begin.class
=> Integer
```

https://docs.ruby-lang.org/ja/2.5.0/method/Integer/i/next.html

```ruby
aaa.begin
=> 1
aaa.begin.succ
=> 2
```

```ruby
ccc.begin
=> 5
ccc.begin.succ
=> 6
```

##Range#eachの実装
おそらくstatic VALUE range_each(VALUE range)が呼ばれ、その先でwhileの条件を満たさないので１周もループせず処理が終わっている模様。

https://github.com/ruby/ruby/blob/trunk/range.c#L833

```c
static VALUE
range_each(VALUE range)
{
//...省略
	    if (!NIL_P(end))
		range_each_func(range, each_i, 0);
	    else
		for (;; beg = rb_funcallv(beg, id_succ, 0, 0))
		    rb_yield(beg);
//...省略
}
```

https://github.com/ruby/ruby/blob/trunk/range.c#L239

```c
static void
range_each_func(VALUE range, int (*func)(VALUE, VALUE), VALUE arg)
{
    int c;
    VALUE b = RANGE_BEG(range);
    VALUE e = RANGE_END(range);
    VALUE v = b;

    if (EXCL(range)) {
	while (r_less(v, e) < 0) {
	    if ((*func)(v, arg)) break;
	    v = rb_funcallv(v, id_succ, 0, 0);
	}
    }
    else {
	while ((c = r_less(v, e)) <= 0) {
	    if ((*func)(v, arg)) break;
	    if (!c) break;
	    v = rb_funcallv(v, id_succ, 0, 0);
	}
    }
}
```

https://github.com/ruby/ruby/blob/trunk/range.c#L157

```c
/* compares _a_ and _b_ and returns:
 * < 0: a < b
 * = 0: a = b
 * > 0: a > b or non-comparable
 */
static int
r_less(VALUE a, VALUE b)
{
    VALUE r = rb_funcall(a, id_cmp, 1, b);

    if (NIL_P(r))
	return INT_MAX;
    return rb_cmpint(r, a, b);
}
```
JavaScript: f( array ) よりも f( [...array] ) がいいとき?

単純なことなんですが、最近うっかり踏みそうになったプチ地雷からのクイズ?です。
# 突然ですが
何が表示されるでしょうか?

```js:
const array2Gen = xs =>
  function*(){ yield* xs; }();

const a = [0,1,2];
const g =array2Gen( a );

for(let i of a.keys() ){
  a[i] = undefined;
  console.log(g.next().value);
};
```
配列をジェネレータにして、順番に配列の要素の値を変更しながらジェネレータを呼んで表示させるということです。
こんなこと普通はしないでしょうけど。

答は：

```js:
undefined
undefined
undefined
```
です。
const で配列を宣言しても、配列の要素は変更できるのでしたね。ある意味、当然の結果です。
でも場合によっては、ジェネレータにした時点で中味が固定されて、もう変ってほしくないと思うんじゃないでしょうか?  
```0  1  2``` が返ってきてほしいなあ...

## うけとった配列をコピーして使う
これはどうでしょう。何が表示されるでしょうか?

```js:
const array2Gen = xs =>
  function*(){
    const ys = [...xs];
    yield* ys; 
  }();

const a = [0,1,2];
const g =array2Gen( a );

for(let i of a.keys() ){
  a[i] = undefined;
  console.log(g.next().value);
};
```
受け取った配列 xs を[...xs]で浅いコピーをしてからジェネレータにしています。
これで xs が変更されても大丈夫なはずです。
が、実行してみると...

```js:
undefined
1
2
```
あれ?一回目だけ変更されてる。なぜでしょう?
説明できます?
ともかく、このやりかたでは不十分です。別のやりかたを考えましょう。
## コピーしてから渡す
今度はどうでしょう。何が表示されるでしょうか?

```js:
const array2Gen = xs =>
  function*(){ yield* xs; }();

const a = [0,1,2];
const g = array2Gen( [...a] );

for(let i of a.keys() ){
  a[i] = undefined;
  console.log(g.next().value);
};
```
今度は ```const g = array2Gen( [...a] );```で浅いコピーをしてから関数に渡しています。
結果は?：

```js:
0
1
2
```
やったー!やっとできたー
# まとめ
1. 何でできたんだろう? 説明できる?
2. いつもコピーしたほうがいい? どんなときにコピーするべき?
3. 配列だけ? 他に気をつけたほうがいいモノは?
4. 浅いコピーで大丈夫? どうやって見分ける?
5. やった方がいいことは? 逆にやらない方がいいことは?
6. ほかに気付いたこと? 何でも

...というようなクイズ? なんですが、何かお役に立つ内容でしたでしょうか?
pdf を生成できる良さげな ruby gem 調査


## pdf を生成できる gem の候補
gem の候補：
`prawn`, `prawn-table`
 - 独自言語でpdfを生成, 🔑付きも可能
 - 9M downloads

`wicked_pdf`
-  HTMLからpdfを生成
-  6M downloads

`pdfkit`
 - HTMLからpdfを生成
 - 3M downloads

`combine_pdf`
 - pdfをマージしたり編集することが主
 - 1M downloads

`hexapdf`
 - メンテナンスがよくされている 
 - better prawn を意識している
 - 52k downloads

## hexapdf の使い方

```
require 'hexapdf'

doc = HexaPDF::Document.new
canvas = doc.pages.add.canvas
canvas.font('Helvetica', size: 100)
canvas.text("Hello World!", at: [20, 400])
doc.write("hello-world.pdf")
```
HTMLコーダーさんにVue.jsを教えてみた話（Photocreate Advent Calendar 4日目 ）

フロントエンドエンジニア の @kazuyuki_ito です。
この記事は [Photocreate Advent Calendar 2018](https://qiita.com/advent-calendar/2018/photocreate) の 4 日目 の記事です。

## はじめに
リニューアルのプロジェクトで`Vue.js`、`Nuxt.js`を採用することになったので、今年4月にちょっとした管理画面を3日ほどで実装した経験から、先行して学習を進めていた私がコーダーさんたちに`Vue.js`をSlackのチャンネルを用いて教えてみたときのことについて書いてみました。

### 自己紹介
私は2016年5月より派遣社員としてフォトクリエイトにお世話になり、縁があって2017年1月より正社員として働いています。

主にフォトクリエイトが提供する全てのECサイトのフロント側、主にHTMLコーディングからJavaScriptの実装・改修をメインに携わっているフロントエンドエンジニアです。

### フロントエンドエンジニアと呼ばれてるが・・・
一応、フロントエンドエンジニアと呼ばれていますが自分は全く「フロントエンドエンジニア」だと思っていませんw

入社当初はHTMLコーダーからスタートし、チョロチョロと`jQuery`をメインとしたJavaScriptの実装が出来るぐらいでした。

そんな自分がフォトクリエイトに入り、`AngularJS`とPHPフレームワークの`Symfony`を使用したECサイトのリニューアルを3件ほど経験し現在に至ります。

正直まだまだ技術スキルは低いのですが、このリニューアル経験のおかげでフォトクリエイトが提供するECサイトのサービス理解度はエンジニアのメンバーの中でも高い方だと思っています。

技術的な面でなくサービスを意識したモノづくりに重きを置くそんな自分を、メンバーは「フロントエンドエンジニアだ」と言ってくれる社風がとても面白いなと思っています。

## Vue.js勉強会
現在フォトクリエイトでリニューアルプロジェクトが進行中です。
その中で開発は`Laravel` + `Nuxt.js`で行うことが決まりました。

Vue.jsでの実装経験はiOSアプリの管理画面の作成であるのですが、その時はHTMLコーディングと公式ガイドを読みながらアニメーションを使った画面の動きを3日間で実装しただけで、`Vue.js`の肝となるコンポーネント化については他のエンジニアさんが行ったのでほぼ経験はありません。~~（と言うか、もう実装した記憶は遥か彼方・・・）~~

また現在在籍するHTMLコーダーのメンバーももちろん`Vue.js` + `Nuxt.js`の経験はありませんので、この機会に`Vue.js`のインプットするいい機会だなと思い勉強会を実施しました。

## コーダーさんにVue.jsを教えるのに意識した事
現在のHTMLコーダーさんは`html5`、`css`、`sass`、`jQuery`での業務経験がある人が多いと思います。
考え方としては「直接DOMを操作して画面を描画する」実装方法だった思いますが、Vue.jsは「JavaScriptのデータを更新して描画する」という大きな違いがあります。
また、直接DOMが更新されるのではなく、仮想DOMを経由してDOMの更新が行われるのも大きな点かなと思います。

とはいえ、とりあえずそこら辺の意識して勝手にハードルをあげて欲しくなかったので、超初心者にも理解できるように噛み砕いて分かりやすさだけを目指しました。
まぁ一部のメンバーには「内容がナマヌルい」とまで言われましたが、理解力は人それぞれと気にせず、また自分の復習も兼ねて実施しました。

まずはslackのチャンネルを開設し、見慣れたhtmlソースにたくさんのディレクティブのサンプルを用意し、「`Vue.js`でこんな事出来るよ〜」的な感じで流し続けました。
slackで行ったのは普段業務を抱えているメンバーでも空いた時間に`Vue.js`の基礎知識を勉強してもらえるようにです。

![モザイク.png](https://qiita-image-store.s3.amazonaws.com/0/125666/d22e5223-59d0-13dd-9782-65e2989f5e83.png)


メンバーには「分かりやすいし内容がスッと入ってきた」「具体的に動くコードも載せてくれたのでありがたかった」などお言葉をいただきました。

思いつきで始めたslackでの勉強会ですが、とても良かったなと思います。
一つの部屋にみんなで集まって・・・というのもいいですが、メンバー間で時間が合わせられず、なかなか開催できなかったと思います。
しかしslackだと履歴が追え、メンバーは自分のペースで学習できますし、私の方も行いたいタイミングで投稿できました。
まぁデメリットといえばHTMLやJavaScriptのソースを毎回アップするのは大変ですけどね・・・w

先日業務に追われ、更新が途絶えるとslackbotから「アーカイブしますか？」って通知が来てしまい、「ちゃんとやりなさい！」ってslackに怒られてる感じも良かったです・・・w

![スクリーンショット 2018-11-30 15.51.31.png](https://qiita-image-store.s3.amazonaws.com/0/125666/309d47ef-fdf2-7f3b-8558-dd1a8357a7cd.png)

## 現在

現在はリニューアルプロジェクトにアサインされる担当のHTMLコーダーさんが決まり、具体的なリニューアルのデザインを見つつ、コンポーネント化の設計、`Vuex`、`Nuxt.js`、さらには`Atomic Design`などの思想などの学習とディスカッションを毎日長い時間抑えて行っています。
私もアサインメンバーも業務を抱えながらですが、とても有意義な時間を過ごしています。

![IMG_2482.JPG](https://qiita-image-store.s3.amazonaws.com/0/125666/b4ac78f6-ac3e-3ce9-720c-692de66cd020.jpeg)


## まとめ
現在繁忙期で業務が立て込んでおり、さらにリニューアルプロジェクトも進む中、新しい技術の導入や、それに伴うインプットや勉強会に割く時間を取る事を上司もプロジェクトメンバーも了承してくれており、とてもありがたいです。
その反面、リニューアルプロジェクトの進行の足を引っ張らないよう身が引き締まる思いです。
それでも自身のレベルアップ、そしてHTMLコーダーさんのフロントエンドエンジニアとしてのステップアップを一緒にできるよう頑張っていきたいと思います。

「自分も一緒に成長したい」と興味を持っていただけるのであれば、 [ご応募をお待ちしております](https://recruit.photocreate.co.jp/entry/?utm_source=qiita&utm_medium=advc2018&utm_campaign=d692432f0964a3947c3b)。

よろしくお願いします。
Node.jsにおけるルーティングの話(MVC実装まで)

node.jsどころかweb系ほとんど初心者知識しかなかったのですが、集中的に2ヶ月ほど独学で学んできたので分かったことを書こうかと。

今回はルーティングの話です。

##node.jsのプロジェクトの基本
今回はフレームワークにExpressを使っています。
基本的にはapp.jsですべての処理が指示されます。(bin/wwwもありますが...)

app.js -> router -> Model(View)
といった感じに処理を分けることもできます。 
というか、それが基本です。

以下の例では、最後の部分でルーターに処理を指示しています。

```app.js
const createError = require('http-errors');
const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
const logger = require('morgan');
const bodyPaser = require("body-parser");
const fs = require("fs");

const index = require('./routes/index');

coonst app = express();

// view engine setup
const.set('views', path.join(__dirname, 'views'));
const.set('view engine', 'pug');

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', index);

```

##ルーティングって何？
簡単に言えば特定のhttpアクセスが来た時にどのように処理をするのかということです。
get(URLへのアクセス)が来たらどんな処理をするとか、post(付加情報を持ったアクセス)が来たらどんな処理をするとか、
アプリケーションにおける基本的な操作を担う処理です。

```routes/index.js
//getの例
router.get('/index', (req, res) => {
  res.send('index');
});

//postの例
router.post('/', (req, res) => {
  req.body.title;
  res.send('index');
}

```


```views/index.html
 <!--postの例 -->
<form method="post" action="/">
<input type="submit" name="title">

<!--getの例-->
<a href="/">

```

##ルーティングの必要性
はじめ小さいプロダクトだとルーターを分ける必要性を全く感じません。

なぜなら分けなくても動くから。

なんならapp.jsにすべての処理を書いても動きます！
だから何でルーターも分けるの？と思います。

ただ機能を追加していくうちにhttpアクセスの分岐の数も増えていきます。('/top/add/id'　のように)
そういったときにひとつのルーターに記述するのでは処理が分かりづらいし、手直しもしづらいです。

そのためルーターは分ける必要があります。

```app.js

app.use('/login', login); //ログインおよびログインから派生する処理(アカウント作成など)
app.use('/top', top);　//topページの処理
app.use('/', index);　//適当な処理
app.use('/users', users);　//ユーザー画面

```

##node.jsでのMVCの構築
ここは悩みました。
ルーターがあることでコントローラーの役割が分からなくなり、どのように役割を分けようかと。

ただ小さなプロダクトを作ってみた感じ、コントローラーはいらないです。

基本的には
Model・・・データベストのやり取りをする関数群
View・・・viewテンプレートをhtml変換して送る処理
Controller・・・MVへの指示

といったような役割で分けると思いますがルーターもコントローラーも同じ役割です。
ただ処理が複雑になったりプロダクトが大きくなってくる(ログイン、topページからさらに分かれる処理、個々のユーザの処理、などなど)とルーターの次にコントローラーを作る必要が出てくるかと思います。

ちなみにルーターでviewテンプレートをレンダリングできるのでviewもあまり必要ない気もします。
![MVC.PNG](https://qiita-image-store.s3.amazonaws.com/0/249038/6f05f020-d9e6-23f2-32ac-5fb49dce42e2.png)



以上ですが、また分かったことがあれば追記します。
子ディレクトリの中も含め、あるパターンに一致するファイルのみコピー(rsync)する

ハードディスクにある特定のファイルのみ(様々なディレクトリに分散している)を
別のディレクトリに移したいということがあり、
以外に苦戦したのでここに方法を記載する。

# やりたいこと
これを
```plantuml
@startuml
!theme toy

salt

{
  {T
    + dir1
      ++ fileA.mp3
      ++ fileB.mp3
      ++ fileC.zip
      ++ fileD.zip
      ++ fileE.zip
      ++ fileF.zip
  }
  {T
    + dir2
      ++
  }
}
@enduml
```

こうしたい
```plantuml
@startuml
!theme toy

salt
{
  {T
    + dir1
      ++ fileA.mp3
      ++ fileB.mp3
      ++ fileC.zip
      ++ fileD.zip
      ++ fileE.zip
      ++ fileF.zip
  }
  {T
    + dir2
      ++ fileA.mp3
      ++ fileB.mp3
  }
}

@enduml
```


# rsync

単純にファイルのコピーだけなら`scp`でもいいが、ファイルの所有者やタイムスタンプなども保持したまま
コピーするなら、`rsync`を使う。

## `exclude`オプション

Usage : `exclude="PATTERN"`

そのパターンにマッチするファイル、ディレクトリを除外する。
(*,??)などのワイルドカード指定も可。

```bash:example
rsync -avPh --exclude="*.mp3" dir1/ dir2/
```

これで、dir1/の中にある`.mp3`ファイル以外のファイルがコピー（同期）される。


## `include`オプション

Usage : `include="PATTERN"`

そのパターンにマッチするファイル、ディレクトリを**除外させない**。
`*,??`などのワイルドカード指定も可。

しかし、

```bash:example
rsync -avPh --include="*.mp3" dir1/ dir2/
```

とすると、dir1/の中にある`.mp3`ファイルのみがコピーされるのではなく、
**dir1/のなかのファイルが全てコピーされてしまう。**
さらに直下のディレクトリのみしか判定しなかったりと、思ったとおりに動かない。

## `include`は`exclude`と併用する

はじめに正解を書くと、

```bash:example
rsync -avPh --include="/*" --include="*.mp3" --exclude="*" dir1/ dir2/
```

となる。

一つずつオプションの解説をする。

 - `--include="/*"`
    - 現ディレクトリだけでなく、子ディレクトリ（それより深いディレクトリも含め）対象とする

 - `--include="*.mp3"`
    - コピーしたいファイルのパターンを指定。（今回は`mp3`）

 - `--exclude="*"`
    - `include`しているもの以外を除外する

また、`--include="*.mp3 --include="*.wav"` などとすることで複数のパターンでも指定できる。

### FYI `include`,`exclude`には順序がある。

```bash:example(wrong)
rsync -avPh --exclude="*" --include="/*" --include="*.mp3" dir1/ dir2/
```

とすると、何もコピーされない。

これは、`include`,`exclude`には**先頭から順に適用される**という特性があるためである。
`--include="/*"`は、**除外させない**というオプションであり、上の例だと、

1.　`exclude="*"`で全てを除外
2.　`include`したいけどなにもない
3.　以下同様

という処理になっている。


正解の例だと
（`rsync -avPh --include="/*" --include="*.mp3" --exclude="*" dir1/ dir2/`）、

1. `include="/*"`で子ディレクトリ以下も対象にし、
2. `include="*.mp3"`で.mp3ファイルは除外されないようにしてから、
3. `exclude="*"`で除外されないようにしたファイル以外を除外している

という処理のため、うまくいく。
英語が得意ではないけどre:Invent2018でGameDayに参加した話

[ミクシィグループ Advent Calendar 2018](https://qiita.com/advent-calendar/2018/mixi) の記事です。

先週、ラスベガスにて [AWS re:Invent 2018](https://reinvent.awsevents.com/)が開催されたのですが、弊社からは10人ほどで参加してきました。
re:Invent自体はラスベガスのホテル7つが会場となり、5万人以上が参加する巨大カンファレンスなのですが、その中でも人気のイベントであるGameDayというものに参加してきました。

# GameDayとは

https://aws.amazon.com/jp/gameday/

ハッカソン形式のイベントです。
AWSのサービスをフルに使っていうサービスを運用し、次々に発生するトラブルを解決していくことでポイントを稼ぎ、その合計ポイントを競うというゲームです。

これに出るためにre:Inventに行くという人もいるらしいとAWSの中の人が言ってましたが、本当でしょうか？
まあ、それくらい内容の濃いイベントで、実際に自分も非常に楽しかったです。

# 受付〜始まるまで

まず、チームを決めます。
受付で4人一組でチームを組んで参加するのですが、事前に知り合い同士でチームを組んで参加することもできますし、自分のレベル感を伝えて、その場でバランスよくチームを分けてもらうこともできます。

自己申告で3種類のレベルを選べます。
<img src="https://qiita-image-store.s3.amazonaws.com/0/12659/31381267-ef86-9ea9-4ef6-d2dff444c398.png" width="30%">

自分は英語圏の人と組んでコミニケーションしたいと思って一人で参加したのですが、どうしても言葉の面で不安だったので、受付で日本人のいるチームに入れてほしいとお願いしたところ、スタッフが日本の方を見つけてきてくれて、その場で一緒に、ほか二人は海外の方と参加しました。

そのまま中に入り、自己紹介し、チャットツールとして使うためにFBで繋がり、記念写真を撮るなどして楽しく待っていました。

# 開始〜やったこと

まずルールとシステム構成の説明がありました。
しかし自分は残念ながらこういうところでの説明が本当に聞き取れなくて、ところどころ笑いが起きていたのに何が面白いのかどころか何を言っているのかさっぱり聞き取れませんでした。。英語頑張らねば。
構成についてはスライドの内容から判断できたのですが、それでもすべてを理解するのは難しかったです。

ただ、開始した後は問題が発生するとログも出ますし、スコアにも反映される仕組みになっているので、それらのヒントをもとに解決していくというのはなかなかエキサイティングでした。

他のイベントで同じ内容で開催する可能性があるらしいので、ゲームの具体的な内容は伏せますが、問題の特定から対応までを如何に速く行うかがポイントを稼ぐ秘訣で、実際に運用したことがあるかどうかでけっこう判断が変わったんじゃないかと思います。
まあ特に、インスタンス単体の負荷が急に高まった時に即座に対応しなければならない場合なんて、まずやることは決まってますよねｗ

そんなこんなで、問題が発生 -> 原因を特定 -> 解決 -> 別の問題が発生 -> … という感じで常に気を抜けない感じで進んでいき、それぞれ時間はかかりましたが、最終的にシステムが安定稼働している状態で終われたので、恐らく発生した問題はすべて解決できたんじゃないかと思います。

# 結果

![image.png](https://qiita-image-store.s3.amazonaws.com/0/12659/b9a453a8-d7b2-8bea-5a5b-2f6966324cb9.png)

我々はT-22というクールなチーム名をつけましたが、結果は13位でした。
合計50以上のチームがいるなかで、まずまずの結果じゃないでしょうか。

1位がダントツでしたが、どうやら5人チームだったようでちょっとずるいなと思いました。

# 感想

自分はTOEIC推定400点程度の英語力なので、言葉でのコミュニケーションは非常に難しかったですが、まあなんとかなった感はあります。
というのも、伝える方法は言葉だけではないので、PCの画面を見せて確認すれば大抵の意図は通じますし、あと、メンバーに日本人もいたことも安心感が大きかったです。

また、スタッフにも日本の方がいらっしゃいましたので、もし日本人一人だったとしてもその方のサポートを受ければなんとかなった気もします。

内容のレベル感ですが、各障害に対してヒントがありますし、落ち着いてやれば難しい内容ではないのですが、短時間で対応するというのはそれなりの経験と勘が必要だと感じました。
自分としてはそのバランスが丁度良かったです。

来年も必ず参加したいと思いました。

# お知らせ

mixiグループではこういったカンファレンスに参加して、現地からほぼリアルタイムにレポートを配信しています。もちろん今回のre:Inventでも配信していました。
https://www.youtube.com/channel/UCdptmubXopWRBnT0pQDh00w/videos

まだ試行錯誤しながらやっているのであまり見られていないですし、改善すべきところは多々あるとは思いますが、ウォッチしていただけると幸いです。
『AWS Loft Tokyo』に行ってみた

渋谷にあるWeb制作会社で、営業（兼広報）をしているおたまと申します。
本記事は、2018年10月にオープンしましたAmazonのコワーキングスペース[『AWS Loft Tokyo』](https://aws.amazon.com/jp/start-ups/loft/tokyo/)の紹介記事になります。
※Qiita初投稿になりますので、不慣れな部分もありますが生暖かく見守ってください。
# 「AWS Loft Tokyo」とは？
![無題.png](https://qiita-image-store.s3.amazonaws.com/0/295959/faace731-e9a4-f5e3-483a-4a70f923bbb5.png)
AWS Loft Tokyoとは、主にAWSを利用したスタートアップとデベロッパーを対象に課題解決を支援するための施設になります。基本的にはコワーキングスペースとして提供されており、AWSアカウント（登録無料）を持っている方なら誰でも利用可能です。予約不要でいつでも自由に利用できます。
● 料金：無料
● 平日10:00 - 18:00
● 180名収容
## 目黒駅徒歩1分!
[目黒セントラルスクエア](http://www.centralsquare.jp/)の17Fにあります。ビル正面に着いたら、まず目の前のエスカレーターで2階まで上がります。そこからさらにエスカレーターで3階まで上がりましょう。受付にて『AWS Loftに来ました。』と伝えると、入場ゲートを通してくれます。 そこから、奥にあるエレベーターで17Fまで登りましょう！
![IMG_1089.JPG](https://qiita-image-store.s3.amazonaws.com/0/295959/3658e293-27cf-be64-e3b7-d13228abf0c8.jpeg)
▲エレベーターのドアがAmazonのダンボール風デザインとなっています。（ベリベリしたいですね）
## 必要なものは？
まずは受付スペースでチェックインを済ませましょう！タブレットで簡単に手続きもできますし、常に受付スタッフが常駐しているので初めての方でも安心して利用できます。以下、二点をお忘れなく。
● 身分証明書
● AWSアカウントID
## どんなところなの？
エントランスに入ると、Amazonのプロダクトを網羅できます。思わずユーザー目線で、Amazon商品を観察。
![IMG_1092.JPG](https://qiita-image-store.s3.amazonaws.com/0/295959/31f0c03a-b4b7-9115-9cdd-d8ea6ea5a5e2.jpeg)
▲Amazon Dash Button（一気に押したい…）
![IMG_1093.JPG](https://qiita-image-store.s3.amazonaws.com/0/295959/7dbd91c5-b56a-4b5f-0eb4-666e5cc61624.jpeg)
▲Amazon Robotics（物流の要！）
Amazon Echoをはじめ、Amazon製IoT・タブレットデバイスを愛でることができます。
そして、なんといってもこの抜け感。ふと見上げると、この景色が広がる空間演出も心地よいです。
![IMG_1100.JPG](https://qiita-image-store.s3.amazonaws.com/0/295959/541bff3e-49f0-3999-711f-70174342168c.jpeg)
▲置かれている植物は全てホンモノ
## スペシャリストの鎮座
また、AWSの技術者の方が常駐している「Ask An Expert」スペースが設置されています。こちらは経験豊富なAWS技術者に、いつでも相談できるスペースとなっています。
![IMG_1095.JPG](https://qiita-image-store.s3.amazonaws.com/0/295959/b1ddfbb7-9d8d-e986-1d1f-aba1fe291f12.jpeg)
![IMG_1097.JPG](https://qiita-image-store.s3.amazonaws.com/0/295959/b4c1599a-6e3f-819f-b65f-ae0c8629c8dd.jpeg)
# まとめ
まじめにコワーキングするもよし、定期的に[イベント](https://aws.amazon.com/jp/start-ups/loft/tokyo/events/)も開かれているので参加するもよし。環境を少し変えるだけで新たなアイデアや交流も生まれると思います。奥にはカフェ「hello, world」もあるので、煮詰まった頭を解放するにはもってこいです。今回は、あくまで素人目線でのレポートとなりましたが、次回は弊社サーバエンジニアと遊びに行きたいと思ってます！

※今回の取材/撮影に関しては、「AWS Loft Tokyo」の許諾を頂いております。ありがとうございます。

:christmas_tree: [FORK Advent Calendar 2018](/advent-calendar/2018/fork)
:arrow_left:03日目 [vsixを使ったvscodeのアップデートに負けにくいCSSや拡張機能のカスタマイズ方法](https://qiita.com/BigFly/items/495994f0443d85eadb7d)  @BigFly
:arrow_right: 05日目 [AWS Toolkits for Visual Studio Code (プレビュー)を使ってみました](https://qiita.com/Kodak_tmo/items/9d0a32e34bd927eaaea5) @Kodak_tmo
システムを継続して開発する場合にはバージョン情報を自動で付けると良かったです

「あれっ…、このバグいつから発生してるんだ…？」
「テスターはいつのバージョンで試した結果なんだ？」

という状況ありますよね。
こういうときにバージョン番号やコミットIDが付いていると問題の特定が捗ります。
以前はバージョン番号を手動で変更していたのですが、デプロイするときにこれを自動的に付けるとすごく便利です。
バージョン番号を付ける習慣ができるとNPM、アプリ、プロジェクトなど色んな所が捗ります。

# ポイント
ポイントがいくつかあります。

1. Gitのタグでバージョン番号を付ける
2. AndroidアプリやPWA、WordPressプラグインなどのバージョン番号と合わせる
3. 小さい修正の場合でもバージョン番号を上げていく

# スクリプト

```bash:version.sh
echo $(git describe --abbrev=0 --tags) '-' | tr -d " \n"; git rev-parse HEAD | cut -c1-7 | tr -d "\n"; echo '-'$(date +%Y%m%d)
```

もしくはこの方法です

```bash
# @see https://stackoverflow.com/questions/4493205/unix-sort-of-version-numbers
TAG=$(git describe --abbrev=0 --tags)
COMMIT_ID=$(git rev-parse HEAD | cut -c1-7 | tr -d "\n")
```

コードはこちらです。　https://gist.github.com/yousan/34016e297cad5871b27a94135d5e4d43/

| コマンド | 解説 |
|---|---|
| git tag | リポジトリに付けられたタグを出力 |
| sort -V | 昇順に並び替え。-Vでバージョン番号を理解してソート（11などの二桁を文字列ではなく数字としてソートなど） |
| tail -1 | 最後の1行を取得 |
| tr -d " \n" | 空行削除 |
| git rev-parse HEAD | 現在のコミットID取得 |
| cut -c1-u7 | コミットIDを7文字に |
| echo '-'$(date +%Y%m%d) | 日付を付与 |

# 使い方

`version.sh`を呼ぶと出てきます。

```bash
$ bash version.sh | bash

v1.7.1-b599631-20181203
```

Gistのオンライン上のスクリプトをそのまま使うことも出来ます。

```bash
$ curl -s -L https://gist.githubusercontent.com/yousan/34016e297cad5871b27a94135d5e4d43/raw/46f5662225ffec4bcfc4bc720a42cbb74cd8c9b3/version.sh | bash
```

# 付与される情報と目的
上記のスクリプトでは `v1.7.1-b591234-20181203`といった形で出力されます。

| それぞれ | 目的 |
|----|-----|
| バージョン番号 | エンドユーザ、テスターからの報告や開発のやりとりを簡易的にするため |
| コミットID | コミットID決め打ちで再現させるため |
| 日付（YYYYMMDD形式） | ぱっと見で発生時期がわかるため |

上記のような目的で付けています。
テスターからバグ報告をもらう際にバージョン番号が入るようにすると一目瞭然なのでいい感じになります。

# バージョン番号を打つために
バージョン番号を打つためにリリース用のGitのタグを打ちます。
Git-flow[^1]に沿ってリリースを行うと、自動的にリリース用のタグが打たれます。

[Git-flowって何？](https://qiita.com/KosukeSone/items/514dd24828b485c69a05)

こんな感じです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/47327/002c4754-5e35-6967-1bda-eef58056d097.png)

バージョン番号は`数字のみ`か`先頭にvを付けるか`に分かれていますが、最近はvを付ける派のほうが多そうなのでそちらにしています。（画像は少し前に作ったリポジトリなのでvが無いです）
今回付けたいそれ以外の情報、コミットIDと日付についてはプログラム側でまかないます。

[^1]: Git-Flowなのかgit-flowなのかレターケースがいつも分からなくなります…ｗ

# バージョン番号を入れるタイミング
バージョン番号を入れるタイミングですが、初回リリース時（大体このときをバージョン1.0としています）から始めています。
というのも最初期はバージョンアップも非常にこまめに行っていて、バージョン情報が頻繁に更新され過ぎるのを防ぐためめです。

# 使い方の例
少し前ですがCakePHPで作ったプロジェクトの際の例です。

スクリプトを元に`Config`に書きだし、テンプレートで読み出ししています。

```php
<?= Configure::read('Version') ?>
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/47327/2ecba342-6d3c-5d65-be21-49f6cc057933.png)

[Gitで打ったReleaseバージョンをプログラム側で参照できるようにする](https://2017.l2tp.org/archives/870)

# 是非教えてください
これをつかった方法やもっと便利な方法があれば是非教えてください！開発プラクティスに飢えてます😜

# 参考記事

[GitHubのリリース機能を使う
](https://qiita.com/todogzm/items/db9f5f2cedf976379f84)

書いててほぼ網羅されている記事を見つけました、完璧ですね！
[タグ付けデプロイの思想的裏付け
](https://qiita.com/niisan-tokyo/items/22500c8b7a3cb44331ee#github-flow-%E3%81%A8-%E5%90%8C%E4%B8%80%E6%80%A7)

# 謝辞
コードは [@ur0n](https://github.com/ur0n)くんに書いてもらいました。ありがとうございます！
Kotlinではエルビス演算子よりも、先に四則演算が優先される

この記事は[ZOZOテクノロジーズその2 Advent Calendar 2018](https://qiita.com/advent-calendar/2018/zozo_tech2)4日目の記事になります。


# エルビス演算子は最後に評価される

例えば下記のコードを実行したときに `print()` で出力される結果は何でしょう。

```kotlin
fun main() {
    val x: Int? = 2
	val y: Int = 3
	val sum = x?:0 + y
	println(sum)
}
```

- a) 3
- b) 5
- c) 2
- d) 0


答えは **c)** です！！！


## 解説

タイトルにある通り、エルビス演算子より、四則演算が優先されます。

つまり、

```kotlin
val x: Int? = 2
val y: Int = 3

val sum = x?:0 + y

```

↓

```kotlin
val sum = x ?: 0 + 3
```

↓

```kotlin
val sum = x ?: 3
```

↓

```
sumは `xはnullではない` ので答えが `2` です。
```

短いですが、こういうのも頭の片隅に置いておくとちょっとしたところで役立つかもしれません。


## 余談

Kotlinは他にも面白い問題があるので、紹介します。


```kotlin

fun main() {
    hello()
}

fun hello(): Boolean {
  println(print("Hello") == print("World") == return false)
}
```


- a) HelloWorld
- b) HelloWorldfalse
- c) HelloWorldtrue
- d) will not compile


答えは **a)** です！

Kotlinでは `print` は実行された瞬間コンソールに中の文字を出力します。
そしたら `HelloWorld` と表示され、一番外の `println` が実行される前に `return` されるので、外の `println` は実行されません。

ちなみに、 `print("Hello") == print("World")` は `true` になります。


他の問題も下のスライドのアップしてますので、よろしければどうぞ

https://speakerdeck.com/yshogo/jin-rou-kt
offsetのメモ

### offset()に関してのメモ
実装上でちょっとハマったのでメモがわりとして

## 実装
特定のページで固定フッターCTAを設置

## エラー
目的のページ以外で`Uncaught TypeError: Cannot read property 'top' of undefined`と表示させる

## 解決
```
(function () {
  $(window).scroll( function(){
    var $target = $('.target')
    //ここで判定
    if ($target.length) {
      var $ele = $('.cta');
      var $pos = $('.box').offset().top;
      var $win = $(window).scrollTop();

      if( $win > $pos ){
        $($ele).fadeIn(1000)
      }else{
        $($ele).fadeOut(1000)
      }
    }
  });
})();
```

## まとめ
offsetでごにょるときは、すごい人ならもっとスッキリ描くのでしょうが、一旦メモとして記録
RailsのBootstrap覚え書き

# はじめに
いっつもやりかた忘れちゃうので書きます。書いて覚えます。
RailsにBootstrapを適用する、です。

# 実装
まずはGemfileに書いてinstallします。

```:Gemfile
# bootstrap
gem 'bootstrap', '~> 4.1.3'
gem 'jquery-rails'
```

```:bash
$ bundle install
```

次に `app/assets/stylesheets/` 下にある、`application.css` ファイルを `application.scss` にリネーム(拡張子変更)

あとはscssファイルとjsファイルに次を追記しておしまい！

```scss:app/assets/stylesheets/application.scss
@import bootstrap
```

```js:app/assets/javascripts/application.js
//= require jquery3
//= require popper
//= require bootstrap-sprockets
```
MacからVS CodeでVM上のWindows内のファイルを編集する

タイトルがやたら冗長ですが…。

# あらすじ

作業マシンはMacだけど、IISサーバを使用する必要があったためVM Fusionをインストールし、そこにWindows環境を構築した。
しかし、VMのWindowsでファイルを編集すると非常に動作が遅い…。またVMのファイル共有機能はホストマシンのファイルが対象でありゲストのファイルは対象外だった。
そこで、今年の春に正式リリースされたWindows10のOpenSSH機能を使うことにした。


# 前提

Windows 10 April 2018 Update (1803) 以降がインストールされていること

# 1. OpenSSH サーバのインストール

`スタートメニュー` から `設定` をクリックし `アプリ` を選択。

![01.png](https://qiita-image-store.s3.amazonaws.com/0/45634/5ec26f7a-dbb3-53af-2269-179ff40221b8.png)

`オプション機能の管理` をクリック。

![02.png](https://qiita-image-store.s3.amazonaws.com/0/45634/958ed23c-ac84-4dbd-7923-ab14bca83343.png)

`機能の追加` をクリック。

![03.png](https://qiita-image-store.s3.amazonaws.com/0/45634/74d53c51-90d4-20a4-8634-d5146213c016.png)

`OpenSSH サーバー` をインストール。

![04.png](https://qiita-image-store.s3.amazonaws.com/0/45634/0e1f8da6-f38a-29b3-e677-bf17e4d81461.png)

# 2. SSHサーバの起動

`コントロールパネル` から `管理ツール` を開き、 `サービス` を表示する。

![05.png](https://qiita-image-store.s3.amazonaws.com/0/45634/fa7a0bfe-7212-306e-64ca-d75ebbd77341.png)

`OpenSSH SSH Server` の項目で右クリックしてプロパティを開く。
`スタートアップの種類` の項目で `自動` を選択し再起動する。

![06.png](https://qiita-image-store.s3.amazonaws.com/0/45634/e6c165ca-d6ad-2aef-74a9-9619b285b579.png)

# 3. macからSSHログイン

Macでターミナルを開き以下のコマンドを実行する。

```:Shell
ssh user_name@IP
```

`user_name` はWindowsのログインユーザー名
`IP` はWindowsのIPアドレス

```:Shell
Are you sure you want to continue connecting (yes/no)?
```

と聞かれるので `yes` と入力。  
その後パスワードを聞かれるのでWindowsのログインパスワードを入力する。


# 4. Visual Studio Code に SSH FS をインストール

こちらの記事を参考に、Visual Studio Codeの設定をする。


> Visual Studio CodeでSSHごしにファイルを編集する
> https://qiita.com/informationsea/items/5c9f05c81a41fb885460

設定ファイルは以下のようにした。

```:JSON
{
    "label": "Local Windows",
    "root": "プロジェクトファイルの場所",
    "host": "WindowsのIPアドレス",
    "port": 22,
    "username": "Windowsのログインユーザー名",
    "password": true
}
```

以上で、Macから編集できるようになりました。めでたしめでたし。
でぶきゃんお留守番日記

これは [Delphi Advent Calendar 2018](https://qiita.com/advent-calendar/2018/delphi) の 6 日目の記事です

2018 年 12 月 6 日 (木)
東京・秋葉原 UDX GALLERY で開催する「[第 36 回エンバカデロ・デベロッパーキャンプ](https://www.embarcadero.com/jp/events-japan/developer-camp/program/tokyo)」
当日お留守番で何をしているのかをつらつらと

##Twitter
当日の実況中継っぽいもの "#dcamp_jp"のハッシュタグをつけてつぶやきます
事前にすべてのスライドに目を通している(LT除く)ので、予めポイントとなるものについては、つぶやく内容を準備しています（ただし、後述しているお客様対応もしているので、そのタイミングでつぶやけるかは謎）
今回は１トラックなので、いつもよりはちょっとだけ楽です

##Togetter
上の実況中継っぽいものを含めた
[第36回エンバカデロ・デベロッパーキャンプのまとめ](https://togetter.com/li/1282782)
のまとめをコツコツと更新

##配信状態の確認
後でビデオとして公開する当日の映像を、ツイートしたり、Togetter をまとめたり、いろいろやりながら確認してます
２トラックあるときには２個のヘッドホンをたすきがけにして、左と右から違う音声を聞きながらというすごい状態で確認していたりします
今回は１トラックなので助かった....

##ちなみに、でぶきゃんに対して、会社側から与えられたタスク
- 不足機材の対応待機
- 機材の受け取り

だけのはずなんだけどなぁ
前日に搬入荷物のまとめとか、あれとか、これとかフってくるのはヤメテェーww

##さーらーに

- お客様からの問い合わせの対応
- あれとかこれとかそれとか、ここには書けないこととか
- 裏から手を回したりとか
- 必要であれば会場のメンバーに連絡をとり対応したり
- たまーに会場からメッセージ飛ばしてくる人がいるので、それも対応してます

## そんな訳で
ぜんぜんゆっくりできませんw
懇親会にも参加できません
なので、[ゆるふぁい](https://yuru-phi.connpass.com/)で、僕と握手！！
エンジニアリングマネージャーになってハマった2つの罠

本記事は [Engineering Manager vol.2 Advent Calendar 2018](https://qiita.com/advent-calendar/2018/em2) の1日目の記事になります(何故か空いていたので後追いで投稿しています)

## 自己紹介
@takochuu といいます。
エンジニアリングマネージャー歴は、前職を含めて約3-4年と言ったところです。
主にマネジメントしているメンバーの数は ~ 10人。評価・育成・チーム運営がお仕事です。(実装も3-4割ぐらいやっています)
主にプロジェクトマネジメントが得意ワザだと認識しています。

本記事の対象読者はエンジニアリングマネージャーになって1年ぐらいの新人マネージャーのみなさまへ僕がハマった事についてお伝えします。

## TL;DR
* 正しいロジックで伝える事よりもコミュニケーション頻度を意識して振る舞うことで納得してもらえるようにする
* 組織(チーム)マネジメントの目的は事業の成長・達成に紐づけて考える

## 正しい結果を言おうとしてしまう罠
例えば一介のエンジニアからエンジニアリングマネージャーへ役割の変更がなされた際、多くの人たちは以下のような新しい仕事を受け取る事になります。

* 評価
* 1on1など、「話す側」から「聞く側」への変化

このようなケースにおいて、ハマっていた罠が「正しいことを話す」ということを目的にしてしまうことです。
例えばメンバーが何かに悩んでいた時に、話せる関係性であれば、悩みや問題を話してもらえます。以前の僕は、ここで正しい答えを出してあげてしまっていました。

これは良く言われる話ですが、「気付きを与える」事で納得してやってもらうのが目的であるとするとあまり相応しい行動ではありません。
頭ではわかっているがどうもモヤモヤする、というのはみなさんも経験がある話だと思います。例えば自分が1on1で話をする側だった時を思い浮かべると理解できるかと思います。

そこからの学びとして、1on1や普段のコミュニケーションでは「正しい結論」を伝えるのではなく「正しい問い」を立てる事によって、気付きを与えて成長してもらうのが今の自分なりの考え方になりました。

## チーム運営・組織運営と事業運営は両輪というおはなし
僕の場合はですが、あまり経験がないEMだった時は「チームを上手くいかせる」ことに必死だったなと思い出しました。
具体的には以下のようなことです。

* チームのキャパシティプランニング
* 心理的安全性の担保
* 仲の良さ、風通しの良さの担保
* 個人の成長の担保

確かにこれは大事なのですが、1つ重要な観点として「何のために」やっているのかということです。
ブチャラティも「任務は遂行する、部下も守る。両方やらなくっちゃあならないってのが幹部のつらいところだな」と言っていますが、当時の僕にはチームを守って、任務を遂行するという観点が抜けていました。

そうすると一見チームは仲がよいように見えますが、サイロ化ではないですが何のためにやるのかという要素が抜けてきます。抜けてくると大きな課題発見や技術的チャレンジに目を向けられないチームになってしまいます。

今のマネジメントスタイルとしては「EMとして大きな課題発見に取り組む、その課題の解決によって、チームの成長を実現する」という考え方に変わってきています。
あくまでエンジニアのマネージャーだということを考えると、課題発見とその解決アプローチに足る技術力を持っていなければいけない、というのも重要な観点です。

チームと事業、どちらかではなくどちらもやる。これがEMのつらいところだな。

## おわりに
ちょっと雑になってしまいましたが、これが最近得た学びとしてあります。
ぜひEMのみなさんと意見交換などしたいな、と思っているので共感頂けたら @takochuu までmentionいただければ是非ランチでもよろしくおねがいします。

次は[hidenorigoto](https://qiita.com/hidenorigoto)さんの[エンジニアリングマネージャーとソフトウェア設計者に共通するスキルを考えてみた](https://tech.mercari.com/entry/2018/12/02/000000) です。
スプレッドシート API で行を追加する

![append.gif](https://qiita-image-store.s3.amazonaws.com/0/10713/c977b831-da26-22ea-6bce-b2db8fdd27e0.gif)

## きっかけ
スプレッドシートに雑にデータを溜め込んでいきたいと思って、スプレッドシートのデータ書き込み系 API を調べた。

## データ書き込み API
スプレッドシート API にはデータを書き込む [spreadsheets.values.append](https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/append) というメソッドがあります。

このメソッドでは、データを書き込む範囲 (`range`) を指定する必要があります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/10713/e035b07c-932b-97f1-ab4f-3ba30e95374c.png)

しかし、範囲といわれても困ります。目的はシート全体の空いてる箇所に順番に行を追加することだからです。


**「範囲とかじゃなくて、空いてる行にデータを追加したいだけなのに！！」**

## `insertRowsOption` で解決！

でも大丈夫、 この API には `insertRowsOption` というオプションがあります。そこに `INSERT_ROWS` を指定してあげれば、**指定した範囲から下にたどっていき、空いているセルが見つかったらそこに書き込んでくれます。**

よって、範囲は `A1` とかで大丈夫です。 `A1` は一番左上のセルですが、そこから下にデータのある行をどんどんスキップしてくれるので、結局一番下の空いている行に書き込んでくれます。

## サンプルコード (Node.js)
Node.js でシートに一行追加するだけの簡単なサンプルを書きました。一番上の GIF 動画で実行しているものと同じです。

※実行には `GOOGLE_APPLICATION_CREDENTIALS` 環境変数が必要となります。[→詳しくはこちら](https://dev.to/seizans/gcp-api--429k)

```js
const { google } = require('googleapis');

(async () => {
    const auth = await google.auth.getClient({
        scopes: ['https://www.googleapis.com/auth/spreadsheets']
    });
    const sheets = google.sheets({version: 'v4', auth});

    const req = {
        spreadsheetId: '<SPREADSHEET ID>',
        range: 'A1',
        valueInputOption: 'USER_ENTERED',
        insertDataOption: 'INSERT_ROWS',
        resource: {
            values: [
                ['a', 'b', 'c'],
            ],
        },
    };

    await sheets.spreadsheets.values.append(req);
})();
```
pgrepで特定のプロセスをkillしたいとき

検索した際、stackoverflowのベストアンサーなどに少し翻弄されたので備忘録として

消したいプロセス名の取得を確認

```bash
pgrep -l python

# -lを省くとpidのみ表示される
11111 python3.6
22222 python3.6
```

killする

```bash
pkill -l python

# -lを省くとこの結果は表示されない
kill -15 11111
kill -15 22222
```

killされたか確認

```bash
pgrep -l python
```

# 結論
公式マニュアルを見よう

```bash
man pgrep
```
【VPT 8】プロジェクションマッピングに挑戦してみた

## はじめに

ディズニー○ンドや東京駅とかに写しだされるプロジェクションマッピング、綺麗ですよね。
自分であれができないか・・挑戦してみました！！
**会社のプロジェクターを使えば経費もかからないしね＾＾**


## 動作環境

Windows7　64bit
VPT 8（video Processor Tools）


## プロジェクションマッピングについて

プロジェクションマッピングとは、立体物に映像を張り合わせる技術を指す。
ただプロジェクターを利用して立体物に映像を貼り付けるだけでは、歪んだ映像になってしまう。
プロジェクションマッピングという技術の肝は、
投影する映像を映写される立体物の形状に合わせて変化させることにある。
・・・とのこと。。なるほど。

## 実際にやってみた

###作業風景　※こちらはプロジェクションマッピングの設定画面です
![csビジョン１（設定）.png](https://qiita-image-store.s3.amazonaws.com/0/186615/0131f408-66b1-a9dc-91ca-8180640b94b6.png)


###映してみた１　※２つの面に異なる画像が映ってます
![CSビジョン２（うつしてみた）.jpg](https://qiita-image-store.s3.amazonaws.com/0/186615/fdbf290e-f311-43cb-6357-cdffaf1adfa9.jpeg)


###映してみた２　※こちらも２つの面に異なる画像が映ってますね
![csビジョン３（うつしてみた）.jpg](https://qiita-image-store.s3.amazonaws.com/0/186615/c203c8d7-713a-c79b-89ec-63b8f56e8619.jpeg)


###映してみた３　※3つの面に立体的に映ってますね
<img src="https://qiita-image-store.s3.amazonaws.com/0/186615/1bd77426-9d94-5846-2b02-7b2d64147985.jpeg" width=50%>
<img src="https://qiita-image-store.s3.amazonaws.com/0/186615/187cf9ec-2f26-a905-e9ab-29844bb13f26.jpeg" width=50%>




## プロジェクションマッピングを映すまでの流れ
①画像、映像のソースを指定フォルダ配下に置く
②プルダウンから追加した画像/映像を選択する
③映す対象物を設置（角度も気を付けて）
④映します！！（VPT8起動！）
※映し出す画像、映像は自分で作成・加工できます！

## 感想
映す対象が大きければ大きいほど、また多面であるほど映しがいがありますね！
静止画、動画問わずプロジェクションマッピングが可能なので、
プロジェクションマッピングは奥が深いですね＾＾
【Laravel】エラーメッセージ、値部分のカスタマイズ

#やりたいこと
required_if等で 「◯◯が▲▲の場合、□□も指定してください」で、▲▲部分が値で直接表示されるのでカスタムしたい。
ただし、Validatorファサードでカスタムはしたくない。

#想定
userテーブルにroleカラムがあり、roleが１(承認者)の場合は承認対象ページも入力させたい。

#コード
nameにprefixでテーブル名をつけいている場合。

```php:app/Http/Requests/UserRequest.php
    public function rules()
    {
        return [
            'user.role' => 'required',
            'user.authority_target' => 'required_if:user.role,1',
        ];
    }
```

```php:resources/lang/ja/validation.php
<?php

return [

// 〜省略〜

    'values' => [
        'user' => [
            'role' => [
                '1' => '承認者',
            ]
        ],
        // 下記だと読み込まれない
        //'user.role' => [
        //  '1' => '承認者',
        //],
    ]
];


```

#蛇足
上記の設定ファイル読み込んでいる部分

```php:vendor/laravel/framework/src/Illuminate/Validation/Concerns/FormatsMessages.php
    // 30４行目〜
    /**
     * Get the displayable name of the value.
     *
     * @param  string  $attribute
     * @param  mixed   $value
     * @return string
     */
    public function getDisplayableValue($attribute, $value)
    {
        if (isset($this->customValues[$attribute][$value])) {
            return $this->customValues[$attribute][$value];
        }

        $key = "validation.values.{$attribute}.{$value}";

        if (($line = $this->translator->trans($key)) !== $key) {
            return $line;
        }

        return $value;
    }

```

間違いや良き方法ありましたら、コメントください。
以上。
Sphinxの導入とLinux Kernelドキュメントのビルド

# 概要

v4.8.1以降のLinux kernelドキュメントではSphinxが使用されています。
ここでは試しに、Ubuntu環境にSphinxを導入し、ドキュメントをビルドしてみます。

# Sphinxについて

SphinxはPythonで書かれたドキュメント生成ツールです。
reStructuredText(reST)と呼ぶマークアップから、htmlやxmlなどのドキュメントを生成します。

Sphinx <http://www.sphinx-doc.org/ja/stable/index.html>
reStructuredText入門 <http://www.sphinx-doc.org/ja/stable/rest.html>

Linux kernelでは、マルチメディア系などを中心にreSTが採用されています。
Sphinxでビルドできるのは、このreSTを採用しているドキュメントです。

# Sphinxの導入

Qiitaにもインストール方法がいくつか書かれているので探してみてください。

Ubuntuの場合、Sphinxのバージョンにこだわらなければ、aptで簡単にインストール可能です。
Python 2とPython 3の実装がありますが、とりあえずPython 3実装版をインストールします。

```
$ sudo apt install python3-sphinx
```

# Linux kernelドキュメントのビルド

kernelのソースコードはkernel.olgのサイトからダウンロードできます。

The Linux Kernel Archives <https://www.kernel.org>

バージョンはv4.8.1以降ならなんでもよいですが、あまり古いとビルドでコケるようです。
(私の環境ではv4.8.1ではビルドエラーが出てうまくいきませんでした)

ここでは例として、stable版のv4.19.6で試します。
手順は簡単で、ダウンロードしたソースコードのトップディレクトリに移動し、「make htmldocs」と叩くだけです。

```
$ tar xaf linux-4.19.6.tar.xz
$ cd linux-4.19.6
$ ls
arch   COPYING  Documentation  fs       ipc      kernel       Makefile  README          scripts   tools
block  CREDITS  drivers        include  Kbuild   lib          mm        REPORTING-BUGS  security  usr
certs  crypto   firmware       init     Kconfig  MAINTAINERS  net       samples         sound     virt
```

```
$ make htmldocs 
  SPHINX  htmldocs --> file:///work/linux/linux-4.19.6/Documentation/output
  PARSE   include/uapi/linux/dvb/audio.h
  PARSE   include/uapi/linux/dvb/ca.h
=== 省略 ===
dumping object inventory... done
build succeeded, 81 warnings.
```

私の環境ではWARNINGがいっぱい出ますが、**とりあえず無視します。**

生成されたドキュメントはDocumentation/output以下に出力されます。
ウェブブラウザでDocumentation/output/index.htmlを開くと、下のようなページが読めるはずです。
![linux_v4.19.6_Documentaion.png](https://qiita-image-store.s3.amazonaws.com/0/282813/a40c8430-245f-0498-7dbe-e1c5246dfcd3.png)



中を見ていくとsvg形式の画像が含まれるなど、べたなテキストよりも随分読みやすくなる印象です。検索機能などもあり、ある程度スピーディに目的の記述まで辿れるようになっています。

他にもLaTeXやPDFなど、Sphinxのビルド時に選択できる形式で出力できます。
（別途、texliveなどのパッケージのインストールが必要です。）
「make help」で使い方を参照できます。

```
$ make help
=== 省略 ===
Documentation targets:
 Linux kernel internal documentation in different formats from ReST:
  htmldocs        - HTML
  latexdocs       - LaTeX
  pdfdocs         - PDF
  epubdocs        - EPUB
  xmldocs         - XML
  linkcheckdocs   - check for broken external links (will connect to external hosts)
  refcheckdocs    - check for references to non-existing files under Documentation
  cleandocs       - clean all generated files
=== 省略 ===
```

# ドキュメントのクリーン

生成したドキュメントのクリーンは「make cleandocs」を叩きます。

```
$ make cleandocs
```
Pythonでコマンドライン引数を自作したい

## 背景
- Pythonのスクリプトを実行するときに、コマンドライン引数の有無によって処理を分岐させたい

## 使用するライブラリ
- [argparse - コマンドラインオプション、引数、サブコマンドのパーサー](https://docs.python.jp/3.6/library/argparse.html#module-argparse)

## サンプルコード
### 実行させるpythonファイル

```python:script.py
# 1. ライブラリインポート
import argparse

# 2.コマンドラインオプションパーサーのインスタンス化
parser = argparse.ArgumentParser()

# 3.コマンドラインオプションの追加(bool)
## action='store_true' は 'オプションがあると'True'になりますよ' の意
parser.add_argument('-a','--auto', action='store_true', default=False, help='use only when you want execute with regularly')
args = parser.parse_args()

# 追加されたオプションは 'args.[オプション名] に格納されている'
if args.auto:
    print('auto!!!')
else:
    print('not-auto!!!')

# more code...
```

### 実行時のコマンドと出力結果

```bash
# コマンドラインオプションなし
$ python script.py
not-auto!!!

# コマンドラインオプションあり(-a)
$ python script.py -a
auto!!!

# コマンドラインオプションあり(--auto)
$ python script.py --auto
auto!!!

# 定義していないコマンドラインオプション
$ python script.py --none
usage: script.py [-h] [-a]
script.py: error: unrecognized arguments: --none

# コマンドラインオプション一覧を見たい時
$ python script.py -h
usage: script.py [-h] [-a]

optional arguments:
  -h, --help  show this help message and exit
  -a, --auto  use only when you want execute with regularly # parser.add_argument(help='') で定義したメッセージ
```

## こんな感じで使いたい
- 手動で実行させるときはユーザーに日付を手入力させて、そこを基準日として処理する
- 定期実行(cronなど)に仕込むときには `-a` オプションをつけて実行日を基準日として処理する
Perlでファイル名の文字化けIE対応

めちゃくちゃ苦戦しました。IE滅ぶべし†
調べてもPHPの記事しかでてこないんですよね。ということで、自分と同じ状況になっているパーラーを助けるべく記事として残します。

# 解決策
いってしまうとこれでOKです。レスポンスヘッダにファイル名を明記します。

```perl
# 日本語ファイル名である、$file_nameを引数として受け取る

$c->res->header(
       'content_disposition' => "attachment;
                                 filename=$file_name.csv;
                                 filename*=UTF-8''$file_name.csv",
   );
```

filenameが2行あるのがミソで、filename*が有効なブラウザではfilename側は無視されるという特徴を突いた記述になります。

参考）https://tools.ietf.org/html/rfc6266#section-4.3

もちろん、日本語のファイル名を渡す際にURIエンコードしてくださいね！

```perl

use URI::Escape;
$file_name = URI::Escape::uri_escape($file_name);
```

* 日本語ファイル名はURIエンコードして渡す
* 日本語でないファイル名は通常通り渡す
  * 別にURIエンコードしてもOK！

このルールさえ徹底すれば、日本語ファイルでも問題なく全ブラウザでエンコードする事ができます。
全ブラウザとか言ってますが、以下でしか動作確認してないので注意。スマホとかOperaは知りません。

* IE11
* Edge
* GoogleChrome
* FireFox
* Safali