OmniAICreator/Qiita-1.07M huggingface dataset:
webpackで特定ディレクトリ以下のファイルを全てインポートして配列にする

## やりたいこと
```
src
├─ template
|  ├─ a.txt
|  ├─ b.txt
|  └─ c.txt
└─ templates.ts
```
こういうディレクトリ構造のとき、templateフォルダのファイルを

```ts
[
  {
    name: 'a',
    value: 'a.txtの中身'
  },
  {
    name: 'b',
    value: 'b.txtの中身'
  },
  {
    name: 'c',
    value: 'c.txtの中身'
  }
]
```

みたいな形で取り出したい。

## 方法

### 1. パッケージのインストール

- `raw-loader` ... webpackでtxtファイルを読み込むため
- `@types/webpack-env` ... この後使用する`require.context`の型定義を読み込むため

```bash
npm i -D raw-loader @types/webpack-env
```

### 2. `webpack.config.js`に`raw-loader`を設定
読み込ませたい拡張子が複数ある場合は`/\.txt$/`のところを変更する。
この方法で読み込む場合、TypeScriptでは必要だった`declare module '*.txt'`のような宣言も必要無さそう。

```webpack.config.js
module.exports = {
  /* 略 */
  module: {
    rules: [
      {
        test: /\.ts$/,
        use: 'ts-loader'
      },
      /* 追加 ここから */
      {
        test: /\.txt$/,
        use: 'raw-loader'
      }
      /* 追加 ここまで */
    ]
  },
  /* 略 */
};
```

### 3. 読み込み処理の記述
`require.context()`に読み込むフォルダへの相対パスを渡す。
`context.keys()`でそのフォルダ以下のファイルの相対パスが配列で渡されるので、`Array.map()`で欲しい形に変える。

```templates.ts
interface Files {
  name: string;
  value: string;
}

const context = require.context('./template');
const templates: ReadonlyArray<Files> = context.keys().map(path => {
  return {
    // 拡張子を省いたファイル名のみを抜き出す
    name: path.match(/([^/]*)(?:\.([^.]+$))/)[1],
    // ファイルの中身をstringで読み込み
    value: context(path)
  };
});

export default templates;
```

## 参考

- [Webpackでフォルダ内の全ファイルを一気にrequireする](https://qiita.com/jkr_2255/items/d23e66323857d3189a00)
- [【JavaScript】ファイル名(拡張子あり)からファイル名(拡張子なし)と拡張子に分割する(正規表現)](https://qiita.com/kyoshiro-obj/items/3c59f14b37a0d7b7d59f)
digdagでエラーになった処理を、その時間で再実行するには

# digdagでエラーになった処理を、その時間で再実行するには
今の時間を取得して実行する処理を、digdagで毎日回していますが、時々エラーになって落ちる時があります。
その再実行の時にshell側でdateや、python側でdatetime.nowを使っていたため、うまく再実行できませんでした。
そして意外とはまってしまったのでメモ。

# 結論
環境変数の${settion_time}を引数に渡してやるよい

# digファイルの例
```test.dig
timezone: Asia/Tokyo
  
+now_in_digdag:
  echo>: start ${session_time}

+now_in_shell:
  sh>: date
```

# 実行結果
１回目の実行

```
2019-03-16 22:03:38 +0900 [INFO] (XNIO-1 task-15): Starting a new session project id=1 workflow name=test session_time=2019-03-16T22:03:38+09:00
2019-03-16 22:03:38 +0900 [INFO] (0081@[0:time_test]+test+now_in_digdag): echo>: start 2019-03-16T22:03:38+09:00
start 2019-03-16T22:03:38+09:00
2019-03-16 22:03:38 +0900 [INFO] (0081@[0:time_test]+test+now_in_shell): sh>: date
2019年 3月16日 土曜日 22時03分38秒 JST
```

同じセッションで２日目の実行

```
2019-03-16 22:03:49 +0900 [INFO] (XNIO-1 task-8): Starting a new session project id=1 workflow name=test session_time=2019-03-16T22:03:38+09:00
2019-03-16 22:03:49 +0900 [INFO] (0081@[0:time_test]+test+now_in_digdag): echo>: start 2019-03-16T22:03:38+09:00
start 2019-03-16T22:03:38+09:00 ←！！セッションIDは、そのセッションが最初に実行された時間のまま！！
2019-03-16 22:03:49 +0900 [INFO] (0081@[0:time_test]+test+now_in_shell): sh>: date
2019年 3月16日 土曜日 22時03分49秒 JST
```
（メモ）ZendFramework3 timezoneの初期設定

#はじめに
Zendframework3勉強中です。色々設定の問題を今後あった際、効率的処理できるように、メモしときます。
###TimeZone設定
初期化されたSkeleton Applicationでは、timezoneが設定されていないため、
>Warning: date(): It is not safe to rely on the system's timezone settings. 

のメッセージが出てきます。

timeZoneの設定は、アプリで使われている任意のphpファイルに以下のコードを入れば完了です、自分はよくPublic/index.phpに入れています。

```php:Public/index.php
//この行を入れます
date_default_timezone_set('Asia/Tokyo');
```
Cognito adminInitiateAuthのREFRESH_TOKENフローでSECRET_HASHが合致しないエラーが発生する


## 現象

下記のコードで `NotAuthorizedException: Unable to verify secret hash for client xxx` が発生。
secretHashの生成方法は間違っていないはずなのになぜ...？と若干ハマりました。

```typescript
const { username, password } = req.body
const cognitoidentityserviceprovider = new AWS.CognitoIdentityServiceProvider()
const secretHash = crypto
  .createHmac('SHA256', ClientSecret)
  .update(username + ClientId)
  .digest('base64')

// ログイン
const data = await cognitoidentityserviceprovider
  .adminInitiateAuth({
    UserPoolId,
    ClientId,
    AuthFlow: 'ADMIN_NO_SRP_AUTH',
    AuthParameters: {
      USERNAME: username,
      PASSWORD: password,
      SECRET_HASH: secretHash
    }
  })
  .promise()

// ログイン成功
const { AuthenticationResult } = data

// リフレッシュトークンを取得
// => NotAuthorizedException発生
await cognitoidentityserviceprovider
  .adminInitiateAuth({
    UserPoolId,
    ClientId,
    AuthFlow: 'REFRESH_TOKEN_AUTH',
    AuthParameters: {
      REFRESH_TOKEN: AuthenticationResult.RefreshToken,
      SECRET_HASH: secretHash
    }
  })
  .promise()
```

## 原因

結局、ログイン時のUSERNAMEはユーザーから入力されたEmail等を利用してsecretHashを作成するのですが、ログイン後はCognito User Poolsで割り振られたusername（ユニークなID）を利用しなければならないのでした。これはわかりにくい。

```typescript
const jwt = require('jsonwebtoken')

const secretHash = crypto
  .createHmac('SHA256', ClientSecret)
  .update(jwt(AuthenticationResult.AccessToken).username + ClientId) // 本番環境では署名検証が必要です
  .digest('base64')
```
Unityに自前でイージング関数を用意する(C#)

Unityといえば、豊富なアセットがあり、イージングも当然たくさんありますが、自分で用意していろいろカスタマイズして遊びたいなと思い、自前で用意してみました。ググってもC#のソースがそのまま置いてあることもなかったので、他の言語を参考にUnity用に書き直し、せっかくなので共有しようと思います。

参考にしたサイトはこちら
https://easings.net/ja

ここでは一部の紹介にとどめますが、全31種類のソースはこちらに置いておきます。
https://github.com/pixelflag/EasingTest

Unityでの動作イメージ
![easing_2.gif](https://qiita-image-store.s3.amazonaws.com/0/254824/15bd8353-fb11-c25e-e0af-e71d57a5c27c.gif)

ちょっとずれているのは、画像の上にボールを乗っけてるだけだからです。これで勘弁してください。

一般的なイージングではありますが、簡単に説明しておきます。

![ease.png](https://qiita-image-store.s3.amazonaws.com/0/254824/96535a97-2a74-003b-ea4e-3bf343b831c1.png)

サンプルの動画のグラフは参考ページと同じものなので、おなじみの形です。
tが進行度、totaltimeが目標の時間、minが開始値、maxが目標値として定義します。
ソースコードはこんな感じ。

```C#
using UnityEngine;

public class Easing
{
    public static float SineInOut(float t, float totaltime, float min, float max)
    {
        max -= min;
        return -max / 2 * (Mathf.Cos(t * Mathf.PI / totaltime) - 1) + min;
    }
}
```
変数名、自分なりに読みやすくしています。cとかbとかわかりにくいですから。本来は抽象的な言葉のほうが正解だと思います。いろいろな使い方に当てはまるので。
実行はこうですね。

```C#
y = Easing.SineInOut(time, totalTime, min, max);
```
あとは、Updateでtimeを加算していってあげれば良いです。
詳しくはGitHubのほうを見てください。




もちろんUnityなので、Vector2でも計算が可能です。

![easing_1.gif](https://qiita-image-store.s3.amazonaws.com/0/254824/cdadf0e5-5e86-0bdd-667a-c02f326a45ea.gif)

初期位置から、ターゲットに向かって座標(Vector2)をイージングさせています。
なにがおこっているか、よくわからない感じですが、動作はしていることは確認できると思います。

ソースコードは、Vector2用のクラスを用意しますが、中身は基本同じです。

```C#
public class Easing2D
{
    public static Vector2 SineInOut(float t, float totaltime, Vector2 min, Vector2 max)
    {
        max -= min;
        return -max / 2 * (Mathf.Cos(t * Mathf.PI / totaltime) - 1) + min;
    }
}
```

floatをVector2に差し替えるだけですね。（Elasticだけ難解だったので諦めました。）
実行も同じ。

```C#
Vector2 pos = Easing2D.SineInOut(time, totalTime, min, max);
transform.position = pos;
```

ちょっとしたものを作るとき、アセットも大げさだなというとき、ちょっとコピペして使うとちょうどいいかもしれないですね。
Twilioでコールバックがうまくいかなくて問い合わせた話


https://www.twilio.com/docs/voice/api/call#statuscallback

以下のサンプルコードで、

`--data-urlencode "StatusCallbackEvent=['initiated', 'answered']" \`

のような指定でコールバックが得られるとあるのだが、うまくいかない。
jsで書いてもうまくいかない、クウォートを変更してみたり書き方を変えてもうまくいかない。

問い合わせたところ、何度かやり取りがあったのち、個別に指定するといいよという答えが導かれた。

```
--data-urlencode "StatusCallbackEvent=initiated" \
--data-urlencode "StatusCallbackEvent=ringing" \
--data-urlencode "StatusCallbackEvent=answered" \
--data-urlencode "StatusCallbackEvent=completed" \
```

結果的には自分で待ち受けした方が細かくステータスが取れるので良さそう。
ドキュメントが変更されずに同じ罠にハマる人がいるのが少し不安なので記録だけしておく。
[python][DataFrame]数字を結合して文字列を作る


## エラー発生
道路ネットワークのデータを使う際にリンクのIDとその両端のノードのIDをつかって新しいキーを作ろうとしたが、雰囲気で結合させてみたらエラー。

### やったこと
+ DataFrameの数字の項目列を連結させて新しいKey列を作ろうとした

```
df_route_link["key"] = df_route_link["objectid"] + "_" + df_route_link["from_node_id"] + "_" + df_route_link["to_node_id"]
```

こんな感じ。でもエラー。


```
TypeError: ufunc 'add' did not contain a loop with signature matching types dtype('<U11') dtype('<U11') dtype('<U11')
```

そもそも数字を文字列は単純に結合できないので、DataFrameでもできないだろうなという気はしていた。


## 修正後

```
df_route_link['key'] = df_route_link[['objectid', 'from_node_id', 'to_node_id']].apply(lambda x: '{}_{}_{}'.format(x[0], x[1], x[2]), axis=1)
```

```
df_route_link['key'] = df_route_link.apply(lambda x: '{}_{}_{}'.format(x["objectid"], x["from_node_id"], x["to_node_id"]), axis=1)
```

どっちもやっていることはほぼ同じ。
先に列をピックアップしてからapplyで行に対して処理するか、行で処理する際に必要な列をピックアップするか。
個人的には後者の方がわかりやすいので好み。
でも性能差があるのかどうかはわからない。先にピックアップした方が速そうな感じがしなくもない。


apply()について
https://note.nkmk.me/python-pandas-map-applymap-apply/

※引数axis=1とすると各行に対して適用されるらしい
GitHubのOSSライセンスシェアの調査結果

# 概要

調査の結果は以下の通り。ほぼMIT系とGPL系で8割を占める。

![Gitub License Share](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114392/6e08ec30-e52a-ce0e-8651-f6852420bd4d.png)

注) MIT系はMIT,ISC、GPL系はagpl-3.0, gpl, gpl-2.0, gpl-3.0, lgpl, lgpl-2.1, lgpl-3.0

# 調査方法

以下の流れでシェアを取得する。

1. [GitHub公式検索API](https://developer.github.com/v3/search/)で各ライセンスを含むリポジトリを検索し、検索結果のJSONを取得。
2. JSONをjqコマンドでパースして件数を取得。
3. ライセンス名と件数をcsvファイルに格納。

上記の手順を実行するスクリプトは以下。

```bash:search.sh
#!/bin/bash

LICENSE_FILE=license.dat
RESULT_FILE=license.csv

rm -rf $RESULT_FILE
for line in `cat $LICENSE_FILE`
do
  license=$line
  count=`curl https://api.github.com/search/repositories?q=license:$license | jq '.total_count'`
  echo $license,$count >> $RESULT_FILE
  sleep 5s
done
```

```text:license.dat
afl-3.0
apache-2.0
artistic-2.0
bsl-1.0
bsd-2-clause
bsd-3-clause
bsd-3-clause-clear
cc
cc0-1.0
cc-by-4.0
cc-by-sa-4.0
wtfpl
ecl-2.0
epl-1.0
eupl-1.1
agpl-3.0
gpl
gpl-2.0
gpl-3.0
lgpl
lgpl-2.1
lgpl-3.0
isc
lppl-1.3c
ms-pl
mit
mpl-2.0
osl-3.0
postgresql
ofl-1.1
ncsa
unlicense
zlib
```

# 調査結果

前述のスクリプトの実行結果を以下に示す。

```json:license.csv
afl-3.0,524
apache-2.0,1054686
artistic-2.0,9821
bsl-1.0,2936
bsd-2-clause,49442
bsd-3-clause,138909
bsd-3-clause-clear,350
cc,51178
cc0-1.0,37751
cc-by-4.0,7120
cc-by-sa-4.0,6307
wtfpl,13963
ecl-2.0,376
epl-1.0,37935
eupl-1.1,677
agpl-3.0,72216
gpl,1311057
gpl-2.0,377582
gpl-3.0,926225
lgpl,95372
lgpl-2.1,25430
lgpl-3.0,69943
isc,28624
lppl-1.3c,390
ms-pl,1467
mit,3799119
mpl-2.0,37123
osl-3.0,2409
postgresql,60
ofl-1.1,2774
ncsa,9
unlicense,107055
zlib,3162
```
Cloud Schedulerのジョブにattributesを設定する


（ターゲットをPub/Subとして利用する場合のお話）

2018年11月にリリースされた[Google Cloud Scheduler](https://cloud.google.com/scheduler/)は
GCP上で定期実行したいタスクの実装に非常に便利そうな機能です。

ただし、2019年3月現在のCloud Consoleでは
`attributes` ほかいくつかの項目の入力フォームが提供されていないため
gcloudを使ってAPI経由で設定したほうが嬉しかったりします。

## 検証の事前準備

### Pub/Subトピックの作成

scheduler_test	という名前で作成するのみです。

### Cloud Functionsの作成

Cloud FunctionsでPub/Subトピックをサブスクライブする関数を作成します。
Node.js 8のデフォルトのコードに `attributes` を出力する処理を追加しただけです。

```js:scheduler_test
/**
 * Triggered from a message on a Cloud Pub/Sub topic.
 *
 * @param {!Object} event Event payload.
 * @param {!Object} context Metadata for the event.
 */
exports.helloPubSub = (event, context) => {
  const pubsubMessage = event.data;
  console.log(Buffer.from(pubsubMessage, 'base64').toString());
  console.log(event.attributes);  // <- 追加
};
```

### トピックを手動でパブリッシュ

属性（`attributes`）を設定するフォームがあります。

![メッセージの公開_-_akiba-session_-_Google_Cloud_Platform.png](https://qiita-image-store.s3.amazonaws.com/0/43116/0863fbae-e2ca-880a-ba0d-55f75968f60d.png "メッセージの公開_-_akiba-session_-_Google_Cloud_Platform.png")

この状態でパブリッシュしてみると下記のように出力されます。

```txt:CloudFunctionの出力ログ
test message from topic
{ foo: 'bar' }
```

## Cloud Console経由でジョブを作成

Pub/Subトピック経由でCloud Functionに渡せる情報はペイロードくらいです。

![ジョブの編集_-_akiba-session_-_Google_Cloud_Platform.png](https://qiita-image-store.s3.amazonaws.com/0/43116/dadd0f9e-2784-921a-edcf-a06f67eeb74c.png "ジョブの編集_-_akiba-session_-_Google_Cloud_Platform.png")

この状態で作成したジョブを実行します。

```txt:CloudFunctionの出力ログ
test message from scheduler
null
```

残念ながら、`attributes` は `null` です。

## gcloudコマンド経由でジョブを作成

Cloud Schedulerはベータ版のため、`gcloud beta` での実行コマンドを利用します。
[ドキュメント: gcloud beta scheduler](https://cloud.google.com/sdk/gcloud/reference/beta/scheduler/?hl=ja)
[ドキュメント: gcloud beta scheduler jobs create pubsub](https://cloud.google.com/sdk/gcloud/reference/beta/scheduler/jobs/create/pubsub?hl=ja)

`attributes` だけでなく、リトライ関連のオプションや
メッセージをファイルから読み込むオプションなどが隠されています。

今回は下記コマンドジョブを作成します。

```bash:Pub/Subトピックをパブリッシュするジョブの作成
gcloud beta scheduler jobs create pubsub scheduler_test_gcloud \
  --description 'for scheduler test' \
  --schedule '0 */3 * * *' \
  --time-zone 'Asia/Tokyo' \
  --topic 'projects/xxxxxxxxxx/topics/scheduler_test' \
  --message-body 'test message from scheduler' \
  --attributes 'foo=bar'
```

なおCloud Consoleとはトピック名の指定方法が違っており
プロジェクトを識別できる形式で記述する必要があるようです。

上記コマンドで作成したジョブを実行してみます。

```txt:CloudFunctionの出力ログ
test message from scheduler
{ foo: 'bar' }
```

無事に `attributes` を取得することができました。

## むすび

これでCloudFunctionsに渡せる値の自由度が上がりました。

今しばらくはジョブをgcloud経由で作成するのが懸命そうです。
まだベータ版なので、何も文句は言えないのですが。
Laravelでブラウザにキャッシュさせない

Laravelでログアウト後にブラウザバックするとキャッシュが表示されてしまう問題の対処法の一つを説明します。

Laravelで以下のようにヘッダを省略して書くとHTTPヘッダのCache-Controlフィールドはno-cacheになります。no-cacheでもブラウザにキャッシュが残ることが多く、これが上記の問題の原因となっています。

```php:
return view('example');
```

そこで、ヘッダのCache-Controlフィールの値を以下のように書いてno-storeにします。

```php:
return response(view('example'))
            ->withHeaders([
                'Cache-Control' => 'no-store',
            ]);

```

以上でブラウザにキャッシュが残らなくなるためログアウト後にブラウザバックしてもログイン中に表示された画面が表示されることはないでしょう。
au光で市販のルーターを使う

au光はルーターが付属で付いてきてこれを必ず使わないとネットに接続できない。
普通の一般大衆なら自前でルーターを調達する必要がないので大変ありがたいのだが、
ルーターの設定がほぼ固定されているので自由度が全くない。

なので
**「こんな~~くそ~~ルーターじゃなくて自前の高機能ルーターを使いたい！」**
という需要に応えるため、市販のルーターを繋げられるようにする。

※ NURO光でも使えるはず

**!! 高度な内容なので詳しい人や自己解決ができる人推奨 !!**

# 概要
au光ルーターのDMZ機能を利用し２重ルーターを構築する。
(MACアドレス偽装などだと、ひかり電話を使ってたりすると使えない。デジタル認証を裏で行っているらしい。これがなかなかのくせ者でごまかしが効かない。)

# 初心者向けの超簡単な解説

**!! 超初心者向けの解説でIPv6とかL3スイッチとかルーティングとかサブネットマスクとかすっとばして、突っ込みどころもある解説ですので、詳しい人は読み飛ばしてね。`` 192.168.0.0/24`` の場合を説明してます。**

ネットワークに繋がる機器はすべてIPアドレスという数値が割り振られます。
家庭内のIPアドレスは4つの３桁の数字をつなげたものです。例 `192.168.0.2`  (`002`などの数字は頭の`0`を省略できます)
`192.168.`の部分はこれを家庭で使うように世界で決められているので固定です。
一つのネットワーク内で使える機器の上限数は254までと決まっています。最後の３桁の数字をで管理します。`192.168.0.0` ~ `192.168.0.255`
255個以上の機器をつなげたい場合などはもう一つのネットワークを作成します。その場合`192.168.xxx.`の部分を書き換えて区別します。 例 `192.168.1.0` ~ `192.168.1.255`
それぞれのネットワークのことをセグメントと言う単位で呼びます。セグメントも255まで作れます。 `192.168.0.0` ~ `192.168.255.0`
つまり254個の機器をつなげたセグメントを254個まで作成できます。 `192.168.255.255`

ネット機器は同じセグメント内同士の機器としか通信できません。つまり254台までしか相互通信できません。
セグメントをまたいで通信を行うにはルーターを使います。
ルーターはセグメント同士をつないでネットワークとネットワークを中継する役割をします。
この世のネットワークはすべてセグメントという単位でたくさんのネットワークが存在します。
それらのネットワーク同士を繋げるのにたくさんのルーターが世界中で働いています。
今回は２台のルーターを使ってauルーターのセグメントと市販ルーターのセグメントを作成し、ルーターで連結させることで２重ルーターを実現しています。


# 前準備
市販ルーターのWAN側MACアドレスを調べておく。
※ 一度市販ルーターを起動して管理画面で確認する。(WANに何も繋がなくても単体で管理画面は使える。)
※ 市販ルーター側のWAN側のIPアドレスの指定でDHCPではなく静的IPで設定する場合は必要ない。

# au光ルーターの設定

### LAN側IPアドレスを変更

初期設定の `192.168.0.1` とかから普段使わない `192.168.10.1` などのセグメントに変更する。

※ セグメントとは今回は `192.168.xxx.1` の `xxx` の部分で `.` で区切られた右から二番の数字のこと。 設定値は0-255。普通は0か1に設定されているメーカーが多い。ルーターごとに競合してはいけない。

### DHCP固定割当設定で市販ルータのIPアドレスを固定

市販ルーターのWAN側MACアドレス登録して `192.168.10.10` などのIPアドレスに固定する。

※ 後述する市販ルーターでWAN側IPアドレス取得方法に静的IPが設定できるのであれば設定しなくても良い。

### IPv6の設定

IPv6サーバーの設定を `[RA:プレフィックス配布 DHCPv6:プレフィックス/IPv6アドレス配布]` に設定してIPv6を市販ルーターでも使えるようにする。

### DMZを設定

DMZホスト機能をONにして、さきほどIPアドレスを固定割当した市販ルーターのIPアドレスを入力する。  
例： `192.168.10.10`

# 市販ルーターの設定

### WAN側設定
ルーターの種類によって異なるがDHCPでIPを取得するように設定する。
例: `ローカルルーターモード`
例: `DHCPモード`

※ 別の方法として先述のDHCP固定割当設定の代わりに静的IPアドレスを指定しても良い。 `192.168.10.10` など。auルーター側で市販ルータのWAN側IPアドレスを設定するか市販ルーター側で設定するかの違いでしかない。

### LAN側IPアドレスの設定

au光ルーターで使っていないセグメントを指定する。
例: `192.168.0.1`

※ 普段はこのセグメントを使うことになる。

### DHCPの設定
DHCPの割当範囲に市販ルーターのに設定したIPと同じセグメントを指定する。 
例: `192.168.0.0/24` 
例: `192.168.0.0/255.255.255.0`
例: `割当数: 64`

DNSにau光ルーターのIPアドレスを指定する。
例: `192.168.10.1`

デフォルトゲートウェイに市販ルーターのIPアドレスを設定する。
例: `192.168.0.1`

### 静的ルーティングの設定

静的ルーティングの設定をして市販ルーター側からau光ルーター側のセグメントにアクセスできるようにする。

例: 
宛先IPアドレス `192.168.10.0`
ネットマスク `255.255.255.0` または `/24`
ゲートウェイ `192.168.10.1`
インターフェース `WAN`

### IPv6の設定

IPv6ブリッジ機能やDHCPv6の設定をONにする。

### ブロードキャストの設定 (出来る場合)

IGMP ProxyとIGMPスヌーピングの設定をONにする。

~~(これをONにすると `スマホで固定電話` の機能を使えるようになる)~~

※ auの `スマホで固定電話` はサービス終了したのでIGMPの設定は必要ないかも

# 終わりに
必要最低限の設定だけだけど、これで市販ルーターの大まかな機能は有効に活用できるようになる。
あとはお好みに応じて細かな微調整をしたりすれば良い。(VPNパススルーとかね)

ただ注意点としてはDDNSなどの一部の機能は使えない可能性がある。
設定内容を詳しく理解しければ、`IPアドレスのセグメン`トや`ルーターの役割`を調べると何をやっているかわかります。
この点にだけ留意してよりよいネットワークライフを！



#### 変更点
2021/3/23 一部説明追加。静的IPについて設定方法追加。
StreamでFizzBuzz~春は出会いと別れとFizzBuzzの季節~

Streamと三項演算子でFizzBuzzクソコード書いてみた。
新卒社員、転職活動で何かと書かされる時期なので備忘録

```java
import java.util.stream.IntStream;

public class FizzBuzz {
    public static void main(String args[]) {
        IntStream.rangeClosed(1, 100).mapToObj(i -> {
            if(i % 15 == 0) return "FizzBuzz";
            if(i % 3 == 0) return "Fizz";
            if(i % 5 == 0) return "Buzz";
            return String.valueOf(i);
        })
        .forEach(System.out::println);
    }
}

```
bashで001、０１０、１００の書式でループ

メモ

```bash

max=100

for ((i=0; i < $max; i++)); do

    #insert 0 or 00
    if [ $[$i] -le 9 ];then
        ZERO=00
    elif [ $[$i] -le 99 ];then
        ZERO=0
    else
        ZERO=''
    fi

    echo ${ZERO}$i

done
```
AGC027 A - Candy Distribution Again (200点)

#問題概要
[リンクはこれ](https://atcoder.jp/contests/agc027/tasks/agc027_a)

n人の子どもに持っている飴x個を全て配る。
子どもは a[i] 個ちょうどの飴を与えられると喜ぶ。喜ぶ子どもの数を最大化したい。

なお飴をもらわない子どもがいても問題ない。

#制約
- 入力はすべて整数である。
- 2 ≤ N ≤100
- 1 ≤ x ≤ 10^9
- 1 ≤ a(i) ≤ 10^9


#考えたこと
要はxからa[i]を引くという処理の回数を最大化するということなので整数a[i]が小さければ小さいほど処理の数が増えるのは自明。

よって配列をsortして順にxからa[i]を引いていきcountすればよい。

注意するのは飴を過不足なく配らないといけないということ。不足があればcountせず処理を中断させるようにする。多すぎる場合は最後にxが0以上になるので、countから1を引けばよい。

#解答

```a.cs
using System;
using System.Linq;

class Program
{
    static void Main(string[] args) {
        int[] s = Console.ReadLine().Split().Select(int.Parse).ToArray();
        int n = s[0];
        int x = s[1];
        int[] a = Console.ReadLine().Split().Select(int.Parse).ToArray();
        Array.Sort(a);
        int count = 0;
        for(int i = 0; i<n; i ++) {
            x -= a[i];
            if (x>=0) count ++;
            else break;
        }
        if (x>0) count --;
        Console.WriteLine(count);
    }
}
```
22日目、JavascriptⅡ 。console.logの出力先はブラウザの開発ツールのコンソールでした。

22日目、JavascriptⅡを攻略しました！
PHPに比べるとずっと分かりやすいです。なるほど順番には意味があったのかもしれません。

前回、Javascript１の時はProgateで作ったコードをどうやって公開するのか分かりませんでしたが、
一周回ってきたので分かりましたよ！開発ツールのコンソールで見れるのでした。

ネットのソースコードをコピペしてどうにか動かしたわけですが・・・
1ヶ月前のQiitaを見て、何も知らない方が野蛮なチャレンジをするもんだなと思いました。

なかなか思うように動かない今日なのでした。#100DaysOfCode #Day3
https://qiita.com/robamimim/items/c4706991b205371efc84

以下、JavascriptⅡまとめです。	

22日目
http://appdays.herokuapp.com/Day22/

###`console.log`の使い方
`console.log(xxxx);`で、コンソールに実行結果を出力。

###`while`で繰り返し

 ```js
///1〜100をずらっと出力するWhile文
let number=1;
while ( number<= 100) {
  console.log(number);
  number++;
}
```

###`for`で繰り返し

```js
///1〜100をずらっと出力するfor文
for ( let number=1; number<=100; number++ ) {
  console.log(number);
} 
```

###if文
if文の書き方。
※比較のイコールが３つなのに注意！なぜ３つにした！？

```js
 if ( number % 3 === 0 ) {
    console.log("3の倍数です");
    }
```
###配列
こんな感じ。

```js
const animals = ["dog", "cat", "sheep"];
console.log(animals);
for (let i = 0; i < animals.length; i++) {
  console.log(animals[i]);
}
```

###オブジェクトとは
オブジェクトがなんなのかが、今のところピンときていません。
便利な配列みたいな感じ・・・？オブジェクトと配列の使い所は？
初心者には謎めいたアイテムです！
使い方は`オブジェクト={プロパティ1: 値1, プロパティ2: 値2}`

```js
const characters = [
  {name: "にんじゃわんこ", age: 14},
  {name: "ひつじ仙人", age: 100},
  {name: "ベイビーわんこ", age: 5},
];

for (let i=0; i<characters.length ; i++ ) {
  //オブジェクトの要素を１つずつ定数に入れて処理。なるほどです！	
  const character = characters[i]
  console.log("名前は" + character.name + "です");
  console.log(character.age + "歳です");
}
```

###undefined
オブジェクトで定義されていない要素を呼び出すと`undefined`と出力されます。便利。

```js
  if (character.age===undefined) {
    console.log("年齢は秘密です");
  }
```

###演習
 最後にJavascriptⅡの内容に沿って演習問題でした。
 楽勝と思ったら、オブジェクトの中の配列ではイコールがコロンになるのに引っかかりました。

###完成！
 演習ではJavascriptの実行結果をコンソールに出力しています。
 自分の所でどうやったら見れるのでしょう。
 調べてみたら、ブラウザの開発ツールでコンソールを見れるのだそう。

 そこでindex.htmlを書いて、作ったJavascriptを読み込んでChromeの開発ツールでコンソールを開いてみると・・・文字化けですが、何かが出力されています。
 そういえば、CSSの回でutf-8を指定するんだっけと思い出してmetaに追加、できました！

 ```html
 <html>
  <head>
  	<meta charset="utf-8">
  	<title>Javascriptの練習</title>
    <script type="text/javascript" src="script.js"></script>
  </head>
  <body>
  	<h1>このページは</h1>
  	console.log(xxxx); を使って開発ツールのコンソールに実行結果を出力しています。
  </body>
</html>
 ```
Chromeでコンソールを見るとこうなりました。
![スクリーンショット 2019-03-16 20.34.49.png](https://qiita-image-store.s3.amazonaws.com/0/356263/07bec737-531c-96da-b25a-589f10d3050a.png)


(１時間半くらい)
AWS CLI で S3バケットを作成してみる


バケットを作成する。

```
$ aws s3 mb s3://<bucket-name>
```

作成されたバケットを確認する。

```
$ aws s3 mb ls
```

ファイルをアップロードしてみる。

```
$ aws s3 cp xxx s3://<bucket-name>
```

アップロードされたたか確認してみる。

```
$ aws s3 ls s3://<bucket-name>
```

--recursive でディレクトの全てをコピーしてみる。

```
$ aws s3 cp . s3://<bucket-name> --recursive
```

アップロードされたか確認してみる。

```
$ aws s3 ls s3://uw-mondopiece
```
Vue.js ことはじめ覚書

# 発音
*View* と一緒です。ビュー（*/ v j u ː /*）です。

# とりあえず使ってみる

以下の内容で *index.html* を作成してください。

```html:index.html
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <script src="https://cdn.jsdelivr.net/npm/vue"></script>
        <title>Vue.js</title>
    </head>
    <body>
        <div id="app">
            Hello {{ message }} !
            <button @click="update">change</button>
        </div>
    </body>
    <script>
        new Vue({
            el: '#app',
            data: {
                message: 'World'
            },
            methods: {
                update() {
                    this.message = 'Vue.js'
                }
            }
        })
    </script>
</html>
```

作成した *index.html* をブラウザにドラッグ＆ドロップしてください。
以下の画面が表示されます。
![hello_vue_js1.png](https://qiita-image-store.s3.amazonaws.com/0/236789/1111f2a2-f01d-6c28-6449-928215dada3d.png)


**change** ボタンを押してください。
以下の画面に切り替わります。

![hello_vue_js2.png](https://qiita-image-store.s3.amazonaws.com/0/236789/085e3a4d-c283-bd84-a57a-66da2f810b4e.png)

あなたは *Vue.js* を使って画面描画を実現しました。
おめでとう。

# なんか物足りないあなたに

要素の削除・アンドゥもしてみましょう。

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="js,result" data-user="wiethkaty" data-slug-hash="QorNXG" 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="QorNXG">
  <span>See the Pen <a href="https://codepen.io/wiethkaty/pen/QorNXG/">
  QorNXG</a> by zackey (<a href="https://codepen.io/wiethkaty">@wiethkaty</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

# 感想

jQuery でゴリゴリ頑張るよりスマートな気がしますね。
なるほど*jQuery*と*Vue.js*は併用出来るので、一画面だけ*Vue.js*を使うなど、
*jQuery*でゴリゴリしてるところを少しずつ侵食していきたいですね。

なお、お気づきかもしれませんが、以下の1,000を超えるいいねを
集めた記事に沿って少しアレンジしながら勉強した覚書です。
真新しさはありません。あしからず。

[jQueryからVue.jsへのステップアップ](https://qiita.com/mio3io/items/e7b2596d06b8005e8e6f)
railsのキホンvol.2(データベース操作系)

##<%%>と<%=%>
erbフィル内でrubyコードを描きたい場合は<%%>で囲む。
またrubyコードをブラウザに表示させたい場合は<%=%>とする。

##@変数
基本、ビューで扱う変数はアクション内で定義する。
また、アクション内で変数を定義する場合は変数の先頭に@をつける必要がある。
例：

```sample_controller.rb
def index
  @sample = "こんにちは"
end
```

```index.heml.erb
<%= @sample %>
```

##テーブル作成

####マイグレーションファイル作成
データベースに変更を指示するためのファイル。
例：

```
$ rails g model Post(postsテーブル) content:text
```
とすることで、db/migrate/にマイグレーションファイル、app/modelsにpost.rbが作られる。

####データベースに反映

```
$ rails db:migrate
```
とすることで、データベースにテーブルが作成される。
また、id, create_at, updated_atという3つのカラムも自動でテーブルに追加される。

##rails コンソール
開始

```
$ rails console
```
終了

```
$ quit
```
###テーブルにデータ保存（new,saveメソッド）
```
$ rails console
> post = Post.new(content: "Hello World")
> post.save
```
とすることで、contentが「Hello world」であるPostインスタンスを作成し、
Postインスタンスをpostsテーブルに保存できる。
###テーブルからデータを取り出す
```
$ rails console
> posts = Post.all
 ```
とすることで,postsテーブルに保存されている全てのデータを配列で取得できる。

また

```
$ rails console
> Post.all[0].content
```
とすることでpostsテーブルの一つ目のデータからcontent部分だけを取り出すことができる。

##共通のレイアウトをまとめる
「views/layouts/application.html.erb」
に共通のHTML(header,footerなど)を書いておくことができる。
各viewファイルは、application.html.erbの<%= yield %>に代入され、application.html.erbの一部として表示される。

##link_toメソッド
```application.html.erb
<%= link_to("表示する文字","URL") %>
```
とすることで、aタグを生成できる。
またlink_toはrubyコードのため、<%%>が必要となる。

続き
https://qiita.com/jonnyjonnyj1397/items/78aca1da8aac9d260b83
Spark/ScalaをJupyter Notebookから実行する


ちょっとした時のSpark/Scalaコードをチームに共有する際、
Jupyterノートブックとしてコードを共有できる方がいいかと思い、

* Pythonのインストール
* Sparkのインストール
* ノートブックでのコードの実行

こららの一連の手順についてまとめてみました。
よくあるApache Toreeを使った手順になっています。

## Python(Anaconda)のインストール

### pyenvのインストール

```sh
$ brew update
$ brew install pyenv
```

環境変数の設定

```sh
$ echo 'export PYENV_ROOT="${HOME}/.pyenv"' >> ~/.zshrc
$ echo 'export PATH="${PYENV_ROOT}/bin:$PATH"' >> ~/.zshrc
$ echo 'eval "$(pyenv init -)"' >> ~/.zshrc

$ exec $SHELL -l
```

### Anacondaのインストール

インストール可能なanacondaのバージョン一覧を取得する。

```
$ pyenv install -l | grep anaconda
  anaconda-1.4.0
  anaconda-1.5.0
 ...
  anaconda3-5.3.1
  anaconda3-2018.12
```

現時点の最新版をインストールします。

```
$ pyenv install anaconda3-5.3.1
```

バージョンを最新のものに切り替えます。

```sh
# バージョンの設定
$ pyenv global anaconda3-5.3.1

# 切り替わったことの確認
$ pyenv versions
  system
* anaconda3-5.3.1 (set by /Users/yuichi.nagakura/.pyenv/version)
```

一回ログアウトしてからPythonのバージョンを確認します。

```
$ python -V
Python 3.7.0
```

Jupyterもインストールされているか確認します。

```
$ jupyter --version
4.4.0
```

## Apache Sparkのインストール

Apache Toreeを使うには、Sparkが必要になります。
Sparkをインストールします。

```sh
# ダウンロード
$ curl -O http://ftp.kddilabs.jp/infosystems/apache/spark/spark-2.4.0/spark-2.4.0-bin-hadoop2.7.tgz

# 解凍
$ tar xvfz spark-2.4.0-bin-hadoop2.7.tgz

# シンボリックリンクの作成
$ ln -s $HOME/spark-2.4.0-bin-hadoop2.7 $HOME/spark
```


環境変数を設定します。

```sh
$ echo 'export SPARK_HOME=$HOME/spark' >> ~/.bash_profile
$ echo 'export PATH=$PATH:$SPARK_HOME/bin:$SPARK_HOME/sbin' >> ~/.bash_profile

$ source ~/.bash_profile
```

## Apache Toreeのインストール

参考) Apache Toree Quickstart
https://toree.apache.org/docs/current/user/quick-start/

```sh
$ pip install --upgrade toree

$ jupyter toree install --spark_home=$SPARK_HOME --interpreters=Scala
```

これで準備完了です。

## Jupyter Notebookの起動

ノートブックを起動します。
私は`SparkContext`が必要なかったことと、ローカルモードでSparkを使いたかったので、以下のようにオプションを指定して起動しています。

```sh
$ TOREE_OPTS='--nosparkcontext' SPARK_OPTS='--master=local[2]' jupyter notebook
```

## ScalaコードをJupyterNotebookに書く

`New`→`Apache Toree Scala`を選択してノートブックを作成します。

<img width="1353" alt="note1.png" src="https://qiita-image-store.s3.amazonaws.com/0/203061/bed49ea8-0c26-c1af-87d1-00af08d8262c.png">


コードは以下のような感じで書いてみました。
コードと実行結果を記録として残せるのでいい感じです。

<img width="1261" alt="スクリーンショット 2019-03-16 19.51.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/203061/f8425a32-7de3-dbfa-e2b9-3d0ac4503430.png">

ハマったポイントとして、ノートブックで実行する場合には、sparkセッション生成時に`enableHiveSupport`をつけないと、MetaStoreが有効にならなかったことくらいでしょうか。MetaStoreのデータベースをMySQLやPostgreSQLなどのDBを使っていない場合は不要っぽいです。

```scala
val spark = SparkSession.builder()
    .enableHiveSupport
    .master("local")
    .getOrCreate()
```
プログラミング学習記録28〜paramsを理解しました〜

##今日やったこと
- Progate rails1~3を復習に必要なスライドを見極めながらやる
- Progate rails1道場編

Progateをどのように復習すべきなのかをずっと考えてきたのですが、今日ようやく答えに近いものが出ました。

何周かした後、重要だと思うスライドをお気に入りに登録して、スライドを復習するというやり方です。

何周かしてみるとそのセクション全体像がわかり、どこの何が重要なのかということもわかってきます。

これは言葉では説明しにくいのですが、「このスライドはもう見なくてもいいな」「逆にこのスライドは必要だな」というのがわかってきます。

わかってくるぐらいまでリセット復習でコードを書いて行う復習をしていれば、あとは重要な部分のスライドを見て復習するだけで十分です。

以上のことがわかったので、明日以降の復習はより手短にできると思います。

<br>
あと今日は昨日理解が曖昧だった、paramsがわかりました。

paramsはルーティングでgetした値と、入力フォームで受け取った値を取得できる変数です。

多少、手順が複雑になってもルーティング→コントローラ→ビューの流れは変わらないということもわかりました。

入力フォームから投稿内容を受け取るときも、結局ルーティング→コントローラ→ビューという流れです。

３、４周続けてリセット復習をして、スライドをよく読んだら理解できました。

明日は１〜３をスライドのみで復習した後、時間があれば４、５に進みたいと思います。

おわり
railsのキホンvol.1（view,controller,routing）


##railsでの開発
```
$ rails new アプリケーション名
```
##サーバー
開発中のアプリケーションをブラウザで表示するためのコマンド

```
$ rails server
```
##トップページの作成
以下のコマンドで、ページを表示するのに必要なファイルを作る
view,controller,routing

```
$ rails generate controller home top
```
また同じ名前のコントローラを作ることができず、新しいページを追加するには、controller,routesを自分で追加し、viewファイルも新規で作成する必要がある。

###view
見た目を作るためのHTMLファイル。
ビューはviewsフォルダ配下に作られる。
上の例では、
app/views/home/top.html.erb
といったファイルが作られる。

###controller
ページを表示するとき、railsではコントローラーを経由してブラウザに返される。
上の例では、
app/controllers/home_controller.rb
というファイルが作成され、その中にtopメソッドができる。
また。controller内のメソッドをアクションという。

```home_controller.rb
def top
 #処理
end
```
コントローラー内のアクションはviewsフォルダの中からブラウザに返すビューを見つけ出す役割を持つ。

###routing
ルーティングはブラウザとコントローラをつなぐ役割を持ち、
送信されたURLをみて、それにあったコントローラ、アクションで処理をする。
ルーティング⇨コントローラ⇨ビュー
という順になる。
上の例では、
app/config/routes.rb
というファイルに定義され、
「get "URL" => "コントローラー名#アクション名"」
という文法で書かれる

```routes.rb
get "home/top" => "home#top"
```
の場合、ブラウザから、home/topが送られてくれば、homeコントローラのtopアクションで処理をされる。
また必要に応じて、urlの部分を変更することもできる。

##CSSの適用
ビューにCSSを適用するには
app/assets/stylesheets/のファイルを編集すればいい。
上の例では、home.scssファイルとなる。

##画像の表示
画像を表示するには、「public」フォルダに画像を入れておくことで、

```sample.html.erb
<img src="/sample.png">
```
```sample.scss
background-image :url("/sample.jpg")
```
のように表示できる。
また画像のURLには先頭に”/"が必要。

##urlの変更
localhost:3000でアプリケーションのトップページにアクセスできるようにルーティングを変更。

```routes.rb
get "/" => home#top
```

にすることでlocalhost:3000で,homeコントローラのtopアクションが実行されるようになる。

続き
https://qiita.com/jonnyjonnyj1397/items/a99c80d4e73dde58fc9c
Git Hubの使い方　作成したファイルを上げる場合

先にGitHubでレポジトリを作成しておく

コマンドプロンプトを開く
cd でプロジェクトのフォルダに移動する

git init
git remote add origin https://github.com/.../...git
git add *
git commit -m "first commit"
git push -u origin master
asp.net core で Cross-Originの設定を行う



# asp.net 

Microsoft.AspNetCore.Cors

![image](https://qiita-image-store.s3.amazonaws.com/0/49910/431b6ce2-30bf-7e7d-c492-5f57299da3cb.png)


## Startup.cs

add services.AddCors();

```csharp
public void ConfigureServices(IServiceCollection services)
{
    services.AddCors();
}
```


add app.UseCors

```csharp
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{

    app.UseCors(builder => builder
        .AllowAnyOrigin()
        .AllowAnyMethod()
        .AllowAnyHeader()
        .AllowCredentials());

    app.UseCors(
        options => options.WithOrigins("http://example.com").AllowAnyMethod()
    );

    app.UseMvc();
}
```



[Enabling CORS in ASP.net Core - .NET Core Tutorials](https://dotnetcoretutorials.com/2017/01/03/enabling-cors-asp-net-core/)
覚えておくと便利なExcelVBAのショートカット

|ショートカットキー|機能|
|---|---|
|F4|プロパティウィンドウ|
|F7|コードウィンドウ|
|Ctrl + G|イミディエイトウィンドウ|
|Ctrl + R|プロジェクトエクスプローラ|
|Ctrl + Space|メンバー候補の表示|
|Shift + F2|定義の表示|
|Shift + Ctrl + F2|定義表示後、カーソルを元の位置へ戻す|

「Shift + F2」と「Shift + Ctrl + F2」はセットで使う。

参考サイト
Excel VBAショートカットキー一覧
http://span.jp/office2010_manual/excel_vba/reference/excel-vba-shortcut.html
flashとflash.nowの違いを検証してみた

タイトルの通りです。

#### 使用環境：
ruby:2.5.1
rails:5.2.2

#### 検証
こんなコードを書きました。

```ruby:blogs_controller.rb
  def create
    @blog = Blog.new(blog_params)
    if @blog.save
      redirect_to blogs_path
    else
      flash[:notice] = '投稿に失敗しました'
      render :new
    end
  end
```

ブログを投稿し、バリデーションにひっかかると`投稿に失敗しました`というメッセージを出します。

このコードだと、こんな動きをします。
まず、投稿画面から。
![スクリーンショット 2019-03-16 17.56.18.png](https://qiita-image-store.s3.amazonaws.com/0/159704/850dbe7e-b6c0-8118-3f75-8a5dd1c179ab.png)

わざとバリデーションエラーを発火させる。
予定通り、flashメッセージが表示される。
![スクリーンショット 2019-03-16 17.55.27.png](https://qiita-image-store.s3.amazonaws.com/0/159704/00d1db24-6745-c81e-f4a0-32c114fb3360.png)

ここで、画面にある`Back`をクリックしてみる。
![スクリーンショット 2019-03-16 17.55.38.png](https://qiita-image-store.s3.amazonaws.com/0/159704/6579240e-7a11-e6f5-f8e5-da28ae775308.png)
フラッシュメッセージが出たままだ！

新規登録画面に遷移したら、ようやく消えた。
![スクリーンショット 2019-03-16 18.23.47.png](https://qiita-image-store.s3.amazonaws.com/0/159704/b43467d4-0677-1b94-96c0-f6347e59928c.png)


続いて、コードを以下のように変更します。

```ruby:blogs_controller.rb
  def create
    @blog = Blog.new(blog_params)
    if @blog.save
      redirect_to blogs_path
    else
      flash.now[:notice] = '投稿に失敗しました'
      render :new
    end
  end
```

同じくわざとバリデーションエラーを発火させ、`Back`を押下。
するとflashメッセージが消えた！
![スクリーンショット 2019-03-16 18.17.04.png](https://qiita-image-store.s3.amazonaws.com/0/159704/c7c9c14c-cefe-a6e6-cca6-b3a29931a6ee.png)


#### しくみ
flash[:notice]にすると、次のアクションまで表示させる。
flash.now[:notice]にすると、次のアクションに移行した時点で消える。
![スクリーンショット 2019-03-16 18.37.00.png](https://qiita-image-store.s3.amazonaws.com/0/159704/274c4028-bedc-de7b-0839-d5034237f1c8.png)
`render`は指定したviewsを呼び出すだけなので、アクションではないから気をつけるべし！
`redirect_to`は次のアクションになるので、flash.nowだと表示すらしない。
AmazonからSES(Simple Email Service)の警告が来た話

# 何が起きたか
- Webサービスを運用しており、AWSのSES(Simple Email Service)を使用している。
- テストのため、人物データの更新を頻繁に行った。  
→　特定のデータを保存したときに、人物が保持するEmailアドレスに、メールが自動で飛ぶような仕組みになっている。  
→　テスト用のデータなので、すべてのデータは1@testabcabctest.testのような存在しないアドレスに書き換えていた。
- 「Amazonから、バウンスレートが上がっているぞと警告のメールが来た」と、お客様から連絡を受ける。  
バウンスレートとは、存在しないアドレスに対してSESを使ってメールを送信していると上がっていくスコアのようなもの。  
https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/e-faq.html#e-faq-bn
- しかも英語で書かれてるからよくわからんとのことで、AWSから来た警告メールを私に転送してくれた。  
- このまま放置してるとサービスが使えなくなるとの情報があり、恐れおののく。

# どう対処したか
- メールボックスシミュレーターを使用した。
- メールボックスシミュレーターとは、いくら送信してもバウンスレートが上がらない仕組み（メールアドレス）の事。  
https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/mailbox-simulator.html
- つまり、送信先のメールアドレスをsuccess@simulator.amazonses.comに書き換えてしまえば、バウンスレートが上がらなくなる。
- しかし、私がメンテしている環境では、テーブルのemail列にユニーク制約が貼られているため、全部同じEmailアドレスにすることはできない。
- そこで、ラベリングという仕組みを使い、一意性を確保した。  
こんな感じ。  
success+1@simulator.amazonses.com  
success+2@simulator.amazonses.com

# その他感想など
AWSの日本法人がいい感じ。  
自動で送られてきたのであろうバウンスレート上昇警告メールのあと、AWSの日本法人からメールで連絡があり、「メールボックスシミュレーターを使えば解決するかもしれないから検討してほしい」との助言をもらった。  
AWSの機能はとても把握できないほどに多いので、具体的なアドバイスは非常に助かる。
VMware(R) Workstation 12 Playerでスナップショットを取得する

本記事はVMware(R) Workstation 12 Playerでスナップショットを取得するための手順をまとめたものです。
本記事ではNHMという外部ツールを利用しスナップショットを取得します。

## バージョンについて

VMware(R) Workstation 12 Player：12.5.9 build-7535481
NHM : ZM5w

## 参考サイト

・スナップショット機能追加手順紹介サイト
<https://www.japan-secure.com/entry/how_to_add_a_snapshot_function_in_vmware_workstation_player.html>
・NHM提供サイト
<http://euee.web.fc2.com/tool/nhm/nhm.html>
・NHMダウンロードURL
<http://euee.web.fc2.com/tool/nhm/NHM64ZM5W.ZIP>

## スナップショット取得手順

基本的に上記サイトに記載されている内容を実施すればOKです。


### NHM環境設定
1. 上記URLからダウンロード、展開します。
2. 展開したファイルをクリックし、NHMを起動します。
3. オプション(O) => オプション(O)... をクリックします。
4. [VMware Player 実行ファイル(V):] に vmplayer.exe 配置場所を指定します。  
<img width="430" alt="1.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/377697/e149fe99-489b-b0e8-794c-3009386b9708.png">
5. [OK] をクリックします。



### スナップショット取得

1. [ファイル(F)] => [新規作成] をクリックします。
2. 以下の画面が起動してきますので、[ファイル名]に適当な名前を指定し[保存]をクリックします。  
<img width="495" alt="2.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/377697/f0ecefc9-2ca8-8c73-06fb-50707c6e8a34.png">
3. 以下の画面が起動してきますので、vmxファイルを選択し[開く]をクリックします。  
<img width="495" alt="3.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/377697/54aac0db-2009-7f11-0193-9ee7733cd735.png">
4. 以下の画面にて、親(toy)を右クリックし、[子の作成]をクリックします。  
<img width="216" alt="4.png" src="https://qiita-image-store.s3.amazonaws.com/0/377697/2f3c25e1-7da4-53ed-1152-3d90793f53fc.png">
5. フォルダーの参照画面ではデフォルトのまま(vmxと同一フォルダ)で良いと思います。  
<img width="278" alt="5.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/377697/fdf08eed-3def-5a76-da89-38abef7fe4dc.png">
6. 以下の画面のように 子(toy_NHM20190316173335)が作成されましたので、子を右クリックし[実行]をクリックします。  
<img width="311" alt="7.png" src="https://qiita-image-store.s3.amazonaws.com/0/377697/d16e67f0-0ffe-4ab0-5753-0b87b1ae24b3.png">
7. VMが起動してくるため、[移動しました]をクリックします。  
<img width="329" alt="8.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/377697/537940d4-2db2-8627-8664-8e86820867cd.png">

上記でスナップショット作成が完了しました！

## スナップショット戻し手順

1. VMのOS上に適当なファイル(tekitouという名前)を作成します。  
<img width="404" alt="9.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/377697/243f847f-8174-df28-5ae4-86113a7f9af0.png">
2. shutdown -h nowなどで仮想マシンを停止します。
3. NHMから子の削除を実行します。  
<img width="273" alt="10.png" src="https://qiita-image-store.s3.amazonaws.com/0/377697/72606a9c-d6e1-6b70-a5a7-71cbfc6a5e3f.png">
<img width="160" alt="11.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/377697/d285c614-d6f1-ce7d-c409-5f213c6e5103.png">
4. 親(toy)を右クリックし、[実行]をクリックします。  
<img width="228" alt="12.png" src="https://qiita-image-store.s3.amazonaws.com/0/377697/e8574580-dd94-9192-da3e-11f8f5432124.png">
5. OS上に作成していたtekitouという名前のファイルが無いことを確認します。  
<img width="271" alt="13.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/377697/86f6a289-8137-6c5d-d352-11d437bba6f0.png">
6. VMware Player上に不要なインベントリが存在しているため、[仮想マシンをライブラリから削除]をクリックし、削除します。  
<img width="670" alt="15.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/377697/d9fd4826-17b3-507a-828b-4730afeae9a2.png">

以上
etcdのクラスタを組みたい(備忘録)

# なぜやるの?
dockerをマルチホストで運用したい
# どうやるの?
- etcdのインストール
- etcdのクラスタを組む <- ここまでqiitaに書く
- serviceとして登録する
- flannelのインストール
- flannelの設定をやる
- serviceとして登録する
- dockerの設定をやる

# 環境
- Centos7 hostname master01
- Centos7 hostname master02
- Centos7 hostname master03

# etcdのインストール
環境はCentos7を使っている今回はクラスタを組みたいだけなので,
パッケージマネージャの恩恵にあやかる

```bash
$ yum seach etcd
etcd.x86_64 : A highly-available key value store for shared configuration

$ yum install etcd
$ etcd -v
etcdmain: etcd Version: 3.2.22
```
install完了

# etcdのクラスタを組む
etcdのクラスタを組む方法は主に3つあるようだ->[CoreOSのサイト](https://coreos.com/etcd/docs/latest/v2/clustering.html)

- Static
- etcd Discovery
- DNS Discovery

staticはetcdにお互いのホストの情報をいろいろ流し込まないといけないので大変だった.

etcd Discoveryはetcdのtoken url(後述)を発行すればある程度簡単にクラスタを組んでくれるのでお勧め

DNS DiscoveryはよくわからなかったDNSのSRVレコードを使うようだがSRVレコードのへの知識がなかったので試さなかった.
今度試してみたい.

今回はetcd Discovery方式を使ってetcdのクラスタを組むことにする.

```bash
$ curl https://discovery.etcd.io/new
https://discovery.etcd.io/<token>
```
のようにクラスタを組むためのurl tokenを発行してくれる

```bash
$ etcd --name=<etcdの名前> --listen-client-urls http://0.0.0.0:2379 --advertise-client-urls http://<自分のip>:2379 --listen-peer-urls http://0.0.0.0:2380 --initial-advertise-peer-urls http://<自分のip>:2380 --discovery <token>
```
`--<name=etcd>`の名前は好きな名前を付けていいはずだ
今回はmaster01,master02,master03を付けている
上のコマンドを
- master01
- master02
- master03
で実行する
これでetcdのクラスタを組むことができる
# まとめ
etcd Discovery方式を使うと簡単にクラスタを組むことができる
やることはどのホストでも同じなのでansibleでの構築自動化はやりやすいと思う

# 参考
- https://coreos.com/etcd/docs/latest/v2/clustering.html
- https://qiita.com/hana_shin/items/602f98bd9b153d22e50c
- https://qiita.com/smallpalace/items/9f41ac3ddcc95cfddb28
Kotlinで簡単なオブジェクトを作成する

# はじめに

Kotlin でクラスを扱うときのための基本的なことのメモ

#　簡単なクラスの定義

ここでは簡単なクラスの定義をまとめます。以下には車を例に簡単なクラスの定義などを簡単にまとめます。引数としてメーカーを表す`type`と作られた年代を示す`model`を用意します。

```

class Car(var type:String,var model:Int){

    init{
        println("this class is initialized")
    }
}
```

ここで、`init`はクラスが初期化されたときに自動的に一番最初に実行されます。
例えば、以下のコードを実行します。

```

class Car(var type:String,var model:Int){

    init{
        println("this class is initialized")
    }
}

fun main(){
    var car = Car("Toyota",1999)
}
```

実行結果として以下の結果が得られます。

```

this class is initialized
```

# プロパティへのアクセス

上のコードで初期化したオブジェクトのプロパティへアクセスするには、以下のようにしてアクセスします。

```car.kt

class Car(var type:String,var model:Int){

    init{
        println("this class is initialized")
    }
}

fun main(){
    var car = Car("Toyota",1999)
    println(car.type)
    println(car.model)
}
```

実行結果として以下の結果が得られます。

```

this class is initialized
Toyota
1999
```

# メソッドの作成

メソッドの作成は以下のようにして行います。このコードでは、車が作られてから何年たったかを計算して値を返しています。

```

class Car(var type:String,var model:Int){
    init {
        println("this class is initialized")
    }

    fun getYearOfCar():Int{
        return 2019-model
    }
}
```

#リストによる複数のオブジェクトの作成

複数のオブジェクトを作成するとき、リストを使ってオブジェクトを作成することができます。

```

class Car(var type:String,var model:Int){
    init {
        println("this class is initialized")
    }

    fun getYearOfCar():Int{
        return 2019-model
    }
}

fun main(){
    //リスト
    var listOfCar = arrayListOf<Car>()
    listOfCar.add(Car("toyota",1999))
    listOfCar.add(Car("matsuda",2010))
    for (car in listOfCar){
        println(car.type)
        println(car.model)
    }
}
```

実行結果

```

this class is initialized
this class is initialized
toyota
1999
matsuda
2010
```
Laravelおすすめcomposerパッケージ集

## 機能関連

### spatie/laravel-tags
traitを使うだけでタグ機能を簡単につけられる

```php
//attaching tags
$newsItem->attachTag('tag3');
$newsItem->attachTags(['tag4', 'tag5']);

//detaching tags
$newsItem->detachTags('tag3');
$newsItem->detachTags(['tag4', 'tag5']);

```

### laracasts/utilities
phpの変数をjs側で展開できる
いちいちviewに変数で渡して、scriptタグのなかでjson_encodeして…
とかしないて一発で展開できる

```php
public function index()
{
    JavaScript::put([
        'foo' => 'bar',
        'user' => User::first(),
        'age' => 29
    ]);

    return View::make('hello');
}
```

### laravel/cashier
Stripeを使ってクレジットカードの月額課金のサービスを簡単に作れる
Netflixのように毎月固定で同じ金額がかかるタイプのサービスでは課金周りはこれだけでいける

### laravel/dusk
Seleniumを使い、ブラウザを実際に起動させるテストがかける


## デバッグ関連

### barryvdh/laravel-debugbar
出力されるHTMLにエキスパンド可能なデバッグバーを表示させることができる

```php

Debugbar::error('Error!');
```
変数の中身を常に表示させたり、ここにログ出せるので便利


### itsgoingd/clockwork
Chromeへ拡張機能を入れることでDeveloper Toolでログを確認できる
基本的には「barryvdh/laravel-debugbar」で十分かも

```php
clock()->info("User {$username} logged in!")
```

### barryvdh/laravel-ide-helper
phpDocを生成して、ideでコード補完の補助を行う
eloquentでアトリビュートの補完してくれるのがとても便利

### ARCANEDEV/LogViewer
ローカルに吐いているログをいい感じのUIで表示させられる。
databaseに吐いているログでは使えない模様



## ユーティリティ

### davejamesmiller/laravel-breadcrumbs
パンくずをRouteに合わせて自動で生成できる。
URL構造が複雑なときに便利

### rachidlaasri/laravel-installer
WordPressライクにインストール画面を作成できる。
Zip形式で配布するパッケージに便利



## おしまい
他にも追加予定…
CSS(SCSS)で直下の子セレクタを複数指定

cssで直下の子セレクタを複数指定したいときに(この場合は `a` ,  `span` の２種類の子セレクタ)

```style.scss
 .hoge {
 	> a, span {
 		color: red;
 	}
 }
```

みたいにやってはみたが、 `span` においては孫セレクタまでcssが効いてしまっていた。
よく考えてみると、

```style.scss
 .hoge {
 	> a, > span {
 		color: red;
 	}
 }
```

とやる必要があったみたい。
カンマでセレクタが区切られているのだから、当たり前っちゃ当たり前だったけど、少し悩んでしまいました。
BackupManager#requestRestoreで例外が発生

# 概要

Androidのバックアップ機能に悩まされる日々が続いております。
動作検証も問題なく、意気込んでKey/Valueバックアップ機能を実装したアプリをリリースしたところ、様々な問題が発生しました。
リリース後、Google Play Consoleのクラッシュレポートに次々とクラッシュが…
この記事では、BackupManager#requestRestoreで発生した例外について触れておきます。

# BackupManager#requestRestoreで例外が発生

[BackupManager#requestRestore][1]で復元を実行したタイミングで以下の3種類の例外が発生していました。
ドキュメントやコード上にあるAPIのドキュメントにも例外が発生することの説明はなかったのですが…

* NullPointerException
* IllegalException
* SecurityException

#### SecurityException

こちらの例外については、Fabric側にもレポートが上がってきており、android.permission.BACKUPが許可されていない内容でした。
以下のパーミッションを付与すればいいのか？

```xml
<uses-permission android:name="android.permission.BACKUP"/>
```

[1]:https://developer.android.com/reference/android/app/backup/BackupManager.html#requestRestore(android.app.backup.RestoreObserver)
[2]:https://developer.android.com/reference/android/app/backup/BackupManager#dataChanged(java.lang.String)
Vueで作った物を後からPWAに対応させる！！

#はじめに
PWAって対応させるとスマホでアプリみたいな振る舞いをしてくれるんだって！？としり対応させようと試みました〜！
Vueの３系では最初にプロジェクトを作るときにオプションでPWAを選択できるのらしい！
じゃあ昔作った２系は・・・？
２系も最初で指定できたらしい・・・
下のようにプロジェクトを作ればPWAに対応してくれたんですって・・・

```console:console
$ npm install vue-cli //Vue-cliのインストール
$ vue init pwa プロジェクト名 //プロジェクトの作成
```

じゃあ、すでに作ってしまっているプロジェクトは・・・？

##できます！！
Vueのディレクトリ構成はだいたいこうだと思います。

>root/
> ┣build/
> ┣config/
> ┣dist/
> ┣node-modules/
> ┣src/
> ┣static/
> ┣test/
> ┣READEME.md
> ┣index.html
> ┣package.json
> ┗package.lock.json


static以下に次のようなマニフェストファイルを作ります！！

```json:manifest.json
{
  "name": "ページの名前",
  "short_name": "略名",
  "icons": [
    {
      "src": "./logo.png",
      "sizes": "192x192",
      "type": "image/png"
    }
  ],
  "start_url": "/",
  "display": "standalone",
  "background_color": "rgb(255, 255, 255)",
  "theme_color": "rgb(255, 170, 42)"
}

```

ここで使うアイコンもstaticに入れておきましょう！
次に作ったこのマニフェストファイルをindex.htmlで呼んであげましょう。

```html:index.html
<!DOCTYPE html>
<html>
  <head>
    <meta NAME=”ROBOTS” CONTENT=”NOINDEX,NOFOLLOW,NOARCHIVE”>
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <link rel="icon" href="./static/logo1.png">
    <!--下の行のように呼び出します！-->
    <link rel="manifest" href="<%= htmlWebpackPlugin.files.publicPath %>static/manifest.json">
    <meta charset="utf-8">
    <title>****</title>
  </head>
  <body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>
```

これでPWAに対応しました！

#おまけ
Vueを使っているとconsoleでfavicon.icoが見つからないという旨のエラーがよく吐かれたままになっていることがあると思います。
iconに使いたいものをstaticに入れてindex.htmlで呼んであげればこれも出なくなりますよ！
さっきのマニフェストファイルを読み込んだ１つ上の行がiconを呼んでるとこなので良かったら参考にしてください！
webpackのresolve.aliasを設定するとimport/extensionsのeslintのエラーが出る

importの際、あちこちで`../../../`という相対パスだらけになっていたので、webpackのresolveに設定を書いた。

```js

  resolve: {
    alias: {
      '@config': path.join(process.cwd(), './src/config'),
    },
  },
```
すると、[import/extensions](https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/extensions.md)のeslintのルールで怒られる
調べた結果、eslintの設定はairbnbの設定をextendsしていたのだが、このairbnbの設定が古いことで怒られているぽかった。

また、eslint-plugin-importも最新にしないとこのeslintのエラー出ちゃう問題は解決しないぽかった。
https://github.com/airbnb/javascript/issues/1092

```eslintrc
{
  "extends": "airbnb",
```

package.jsonを見ると`eslint-config-airbnb`と`eslint-plugin-import`のverが固定で入っていたので最新のものにあげたらエラーは消えた。
HerokuからEメールを送る

システムを開発している中で、メールを送るシーンがあります。
例えば、サインアップするシステムを作っていると、サインアップ後に登録の確認をするメールを送るとか、パスワードのリセットするためにメールを送るとか。
これを、Herokuでやろうとしても、素のHerokuではできません。
そんな時は、SendGridを使いましょうという話です。

# HerokuにSendGridを追加
まずは、HerokuにSendGridアドオンを追加します。
HerokuのOverViewから、「Configure Add-ons」をクリックします。

<img width="452" alt="conf.png" src="https://qiita-image-store.s3.amazonaws.com/0/334727/b44dfbf5-158e-524e-2d7b-fa4d3df3b96e.png">

次に、「Find more add-ons」をクリックします。

<img width="119" alt="find.png" src="https://qiita-image-store.s3.amazonaws.com/0/334727/043a680f-7d93-e68a-0c84-b53204be28f4.png">

SendGridを検索します。

<img width="277" alt="sendgrid.png" src="https://qiita-image-store.s3.amazonaws.com/0/334727/930656c1-355f-208c-1884-d204ec9801dd.png">

「Install SendGrid」でインストールしましょう。

<img width="193" alt="install.png" src="https://qiita-image-store.s3.amazonaws.com/0/334727/95335c8f-6cd6-104d-8aa5-b2a03272f7ad.png">

# SendGridの設定
　次は設定です。
　まずは、HerokuのAdd-onsリストから、SendGridを選択しましょう。

<img width="143" alt="menu.png" src="https://qiita-image-store.s3.amazonaws.com/0/334727/75d5f328-3bed-519a-a6d4-cc7dda58cda0.png">

　次にSendGridのSettingsのAPI Keysで、メール送信時に使うAPI Keyを作成します。

<img width="122" alt="createapikey.png" src="https://qiita-image-store.s3.amazonaws.com/0/334727/9dabc3cd-bf55-63f3-0dcc-cd7b6235de8b.png">

<img width="639" alt="keyname.png" src="https://qiita-image-store.s3.amazonaws.com/0/334727/4637ffe7-6eec-d652-660a-a42e2fcb0f8b.png">

API Keyが生成されました。
ここで注意です。API Keyはここでしか表示されません。API Keyをクリックすると、クリップボードにコピーできますので、必ず、コピーしましょう。

<img width="637" alt="key.png" src="https://qiita-image-store.s3.amazonaws.com/0/334727/c8be4238-0807-f25c-b051-a85f3386f27f.png">

# Node.jsでメールを送る

## @sendgrid/mailのインストール
まずは、SendGridでメールを送るための、npmパッケージをインストールします。

> npm install @sendgrid/mail --save

## インプリする
いよいよ、インプリです。

```typescript:sendmail.ts
import { Injectable } from '@nestjs/common';
import * as sgmail from '@sendgrid/mail';

@Injectable()
export class EmailService {
    sendMail(templateName: string, toemail: string): Promise<boolean> {
        return new Promise((resolve, reject) => {
             // SENDGRID_API_KEYを設定する
             sgmail.setApiKey(process.env.SENDGRID_API_KEY);
             // 送信するメールの内容を設定する
             const msg = {
                  to: toemail,
                  from: opts.email,
                  subject: '【' + opts.servicename + '】からのお知らせ',
                  text: data
              };

               // メールを送信する
               sgmail.send(msg)
               .then((req) => {
                   resolve(true);
                })
                .catch((err) => {
                   reject(err);
                });
            }
        });
    }
}
```

これで、Herokuからメールが送信できるようになります。
簡単！！
tkinterのToplevelを非モーダルでsingletonにする方法

Toplevelでwindowを生成した際にgrab_set()でモーダルにしてしまう方法もありますが、モーダルにはしたくない場合にどうしたらいいのか困ったのでいろいろ調べて以下のようなコードにたどり着きました。

* Toplevelのインスタンスを保有するクラス(Subwindow)を用意する。保有するのであって継承はしない。
* Toplevelで生成したwindowが閉じられた時に発生する`WM_DELETE_WINDOW`イベントをハンドリングして、ToplevelのインスタンスをNoneにする。
* Subwindowを開く時にToplevelのインスタンスがNoneかどうかチェックし、NoneであればToplevelのインスタンスを生成する。

```python
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import unicode_literals
try:
    import tkinter as tk
except:
    import Tkinter as tk


class Subwindow(object):

    def __init__(self, parent):
        self.parent = parent
        self.win = None

    def open(self):
        if not self.win:
            self.win = tk.Toplevel(self.parent)
            self.win.protocol('WM_DELETE_WINDOW', self.close)
        self.win.focus()

    def close(self):
        self.win.destroy()
        self.win = None


if __name__ == '__main__':
    root = tk.Tk()
    subwin = Subwindow(root)
    menu = tk.Menu(root)
    menu.add_command(label='Sub', command=subwin.open)
    root.config(menu=menu)
    root.mainloop()
```