OmniAICreator/Qiita-1.07M huggingface dataset:
TypeScriptの組み込み型関数は便利だ

今まであまり使って来なかったんですが、いざ使ってみるとすごく便利でした。

# 組み込み型関数とは？
既存の型から新しい型を生成する組み込みユーティリティです。
ジェネリクスを使って既存の型に被せることで新しい型を生成できます。

# 最近使ってみて特にいい感じだったもの
全ての型関数を紹介するわけではありません。悪しからず。

## Omit
TypeScript3.5で追加された新しい組み込み型関数。
既存の型から特定のプロパティを除いた型を作ることが出来ます。

``` typescript
type Hoge = {
 a:string
 b:number
 c:boolean
}
type Omitted = Omit<HOGE,"c">;
/**
{
 a:string
 b:number
}
*/

```

オブジェクトの生成過程の型を管理する場合などに個人的にはよく使います。
ちなみに、当然ですが以下のように除いたものを補完してやれば元の戻ります。

``` typescript
const hoge:HOGE = {...omitted,...{c:true}};
```

## Partial
全てのプロパティに?を付けた型を作ります。

``` typescript
type Hoge = {
 a:string
 b:number
 c:boolean
}
type PartialHoge = Partial<HOGE>;
/**
{
 a?:string
 b?:number
 c?:boolean
}
*/
```
正直初めに見たときは、何に使うのか今一つピンとこなかったのですが、
外部からの入力値を受けて部分更新に使うという使い方を聞いて納得しました。
以下のようにスプレッド構文と組み合わせることでいちいち各プロパティの存在確認を行わなくても存在する値だけで上書きが出来ます。
ReduxのReducerで辺りでかなり使えそう。

``` typescript
//oldHogeが古いHoge型,inputPartialがPartial<HOGE>型とする
const newHoge = {...oldHoge,...inputPartial};

```

## Exclude型
主にUnion型から特定の型を除外した型を作ります。

``` typescript
type Fuga = "AAA" | "BBB" | "CCC";
type FugaWithoutC = Exclude<FUGA,"CCC">;
```
Union型で列挙した定数のうち、一部だけ使いたい時にとても便利です。
似たような役割にExtractもありますが、ちょっとこれは使いどころが思いつきませんでした。
二つの型の共通部分のみを抜き出すものなのですが、大体のケースはそのまま宣言すれば済む気がします。

## ReadOnly
全てのプロパティにReadOnlyを付けた型を作ります。
Immutableなオブジェクトを作りたい時に。
【Mac購入後すぐ】 初心者エンジニア向け環境構築メモ

#趣旨
環境構築するときに、迷わないようにメモ
適宜追加、更新予定です。

#インストールしたもの
##基本
・vscode
https://code.visualstudio.com/download

・chrome
https://www.google.com/chrome/

・Homebrew
terminal上で以下を実行
`/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"`
ちゃんと入ったか確認
`brew doctor`

・pyenv
` brew install pyenv`

・Anaconda
こちらの記事の流れを参考にしました
https://qiita.com/y4m3/items/19246624d3ba4d299313

・jupyter
`brew install jupyter`

terminalで`jupyter notebook`してみて、動くか確認

・g++
 `brew install gcc`
 MACに標準で入っているGCCはだめぽいのでbrewで入れました

・docker
こちらの記事がわかりやすかったです。
これからdockerも触っていきたい
https://qiita.com/kurkuru/items/127fa99ef5b2f0288b81

以下よく使うけど忘れがちなdockerコマンド

- コンテナ確認
    `docker ps`

- コンテナ環境に入る
    `docker exec -it <container name> /bin/bash`

よく使用するコマンドがまとめられています。
https://morizyun.github.io/docker/about-docker-command.html

##App Store
Slack, Trello

#設定
## terminal
###Dockに常に出しておく
Dockの左側にスライドさせるだけ

###terminalの文字の色変更
https://qiita.com/lemtosh469/items/81919186611ac68b11c8

###~/.bashrcの作成
自分でbashに追加した設定とごっちゃになるのが嫌なので
`code ~/.bash_profile`
で設定ファイルを開きます。（VSCodeがなければ、お好きなエディタで）
そこに以下を追加。

```terminal
if [ -f ~/.bashrc ]; then
  . ~/.bashrc
fi
```
`source ~/.bash_profile`して設定を反映させます。
ここから先bashを自分でいじるときは、~/.bashrcを変えていきます。

##VSCode
###自動整形
設定（左下の歯車アイコン）から「format」で検索
Format on ×××
で、好きなものにチェック。
formatterの選択を忘れないように。

###拡張
- Prettier コード整形（細かくできる）
- Remote - Containers Dockerコンテナ内部をvscodeで編集できる（オススメ！）
    - vscodeのcommand paletteに`Remote-Containers: Attatch running containers`があるのでこれをクリックすると起動中のコンテナにアクセスできる（便利！）

###PATHを通す
vscodeのコマンドパレットに 「shell」　と入力し、
Shell Command: Install code command in PATH　を選択すればOK

##機械学習
やったこと

###DLの有名フレームワークが詰め込まれたDockerはこちら
https://github.com/floydhub/dl-docker

###自分の環境で構築したい人向け
・python関係は後々環境を分けたくなるので、仮想で作っておきます。
・Terminalを立ち上げると自動で仮想環境に入るように
　先ほど作った.bashrcに以下を追加。

```
source activate ENVNAME
```

`source ~/.bash_profile`して設定を反映させます。
ENVNAMEは、<自分で作成した環境名>です。
 
ちなみに
####Anacondaでは

anaconda仮想環境を有効にする
`source activate ENVNAME`

anaconda仮想環境から抜け出すときは
`source deactivate`

をterminalで実行すれば、仮想環境のON/OFFができます。



##補足
###git error
####大きいサイズのファイルをgithubにpushしてしまって、pushできなくなる
大きいサイズのファイルをcommitしたキャッシュを消す
`git filter-branch -f --index-filter 'git rm --cached --ignore-unmatch xxx.csv'`
そのままできるようになる

参考：https://paper.hatenadiary.jp/entry/2016/10/09/225804
やったこと
AWSサービス、コンピューティング

# コンピューティング

AWSコンピューティングサービスについての備忘録
サービスの概要・特徴・料金などを簡潔（できれば）に記載します。

## Amazon EC2(Amazon Elastic Compute Cloud)

### 概要
安全でサイズ変更可能なコンピューティング性能をクラウド内で提供するウェブサービス

### 特徴

* AZサービス
* ウェブサービスのインターフェイスを使用して、さまざまなオペレーティングシステムのインスタンスを起動できる
* オンデマンド・リザーブド・スポットの3料金体系
* オンデマンド料金においてAmazon Linux、Ubuntuは、秒単位（最小60秒）の課金

## Amazon EC2 スポットインスタンス

### 概要
EC2インスタンスをオンデマンド料金と比べ最大 90% の割引価格で利用できるインスタンス

### 特徴

* Amazon EC2 Auto Scaling の統合
* ワークロードの停止/休止と再開
* スポットインスタンスの中断 2 分前に発行される終了通知機能
* 永続リクエスト
* Amazon EMR との統合
* Amazon CloudFormation の統合
* Amazon ECS の統合

### ユースケース

* ワークロードが途中中断しても問題ないケース
* ビッグデータと分析


## Amazon EC2 Auto Scaling

### 概要
アプリケーションの可用性を維持するうえで役立ち、お客様が定義した条件に応じて EC2 インスタンスを自動的に追加または削除できる

### 特徴
* リージョンサービス
* Amazon CloudWatch メトリクスに基づいて動的にスケールすることができる
* 定義したスケジュールに従って予測どおりにスケールすることができる
* 動的スケーリングと予測スケーリングを一緒に使用すると、迅速にスケールできる


### スケーリングできるリソース
* Amazon EC2 インスタンス
* Amazon EC2 スポットフリートのインスタンス
* ECS サービス
* DynamoDB テーブルまたはグローバルセカンダリインデックスで、プロビジョニングされている読み込みおよび書き込みキャパシティー
*  Aurora リードレプリカ

### 手動スケーリング
Auto Scaling グループの希望する容量を更新したり、Auto Scaling グループにアタッチされているインスタンスを更新

### スケジュールに基づくスケーリング
スケジュールに基づいたスケーリングにより、予想可能な負荷の変化に対する独自のスケーリングスケジュールを設定

### 動的なスケーリング

* Target tracking scaling
  * 特定のメトリクスのターゲット値に基づいて、グループの現在の容量を増減
* Step scaling
  * アラーム超過のサイズに応じて変動する一連のスケーリング調整値 (ステップ調整値と呼ばれる) に基づいて、グループの現在の容量を増減
* Simple scaling
  * 1 つのスケーリング調整値に基づいて、グループの現在の容量を増減

### Amazon SQS に基づくスケーリング
Amazon Simple Queue Service (Amazon SQS) キューの需要の変化に応じて Auto Scaling グループをスケールする

## Amazon EC2 Container Registry

### 概要
完全マネージド型の Docker コンテナレジストリです。このレジストリを使うと、開発者は Docker コンテナイメージを簡単に保存、管理、デプロイできます

### 特徴

* Amazon Elastic Container Service の統合
* Docker のサポート


## Amazon Elastic Container Service(Amazon ECS)

### 概要
Docker コンテナをサポートする拡張性とパフォーマンスに優れたコンテナオーケストレーションサービス

### 特徴

* AWS が独自開発したコンテナ管理サービス
* AWS Fargate のサポート
* Docker のサポート
* コントロールプレーン
* データプレーンは、EC2とFargate

## Amazon Elastic Kubernetes Service

### 概要
可用性が高く、スケーラブルで安全な Kubernetes サービス

### 特徴

* マネージド型 Kubernetes コントロールプレーン
* データプレーンは、EC2のみ

## Amazon Lightsail
* 仮想プライベートサーバーを起動および管理

## AWS Batch
* あらゆる規模でバッチジョブを実行

## AWS Elastic Beanstalk
* ウェブアプリを実行および管理

## AWS Fargate
* サーバーやクラスターを管理することなくコンテナを実行

## AWS Lambda

### 概要
イベント発生時にお客様のコードを実行し、基盤となるコンピューティングリソースをお客様に代わって管理する、サーバーレスコンピューティングサービス

### 特徴
* 実際に使用したコンピューティング時間に対する料金のみ
* カスタムロジックを使って AWS の他のサービスを拡張することや、AWS の規模、パフォーマンス、セキュリティを活用して運用する自社のバックエンドサービスを作成することができる
* Lambda関数（ファンクション）、AWS Lambdaで実行するアプリケーション
* Java、Go、PowerShell、Node.js、C#、Python、Ruby のコードをサポート
* VPC内のリソースへインターネットを経由せずにアクセス可能
* 同時実行数は、セーフガードとしてアカウントに対してデフォルト1,000となる。実績に応じて制限緩和申請が可能

### 環境
* 64MBごとに128MBから3008MB間で設定可能
* タイムアウトの最大900秒(15分)まで設定可能 

### 制限
* インバウンドネットワーク接続はブロックされる
* アウトバウンドはTCP/IPとUDP/IPソケットのみ
* ptraceシステムコールはブロックされる
* TCP25番ポートのトラフィックはブロックされる


## AWS Outposts
* AWS インフラストラクチャをオンプレミスで実行

## AWS Serverless Application Repository
* サーバーレスアプリケーションを検索、デプロイ、公開する

## VMware Cloud on AWS
* カスタムハードウェアを使用せずにハイブリッドクラウドを構築

## 他の製品、サービスについて
[AWSサービスまとめ](https://qiita.com/yodyman/items/e1dccdd194356db6fab8)
MS SQL Server のデータを LocalDB にリストアする

## 経緯

本番 DB のデータを使ってテストを行いたいことがあり、サーバーとして使われている MS SQL Server にあるデータを、クライアントの LocalDB にリストアすることにした

その時のメモを備忘録として雑に残す

## 手順

### MS SQL Server のバックアップ

1. SSMS(SQL Server Management Studio) を起動
2. Object Explorer から、バックアップをとる Database を右クリック -> Tasks -> Backup を選択  

バックアップオプションはデフォルトで取得


### バックアップファイルをリストア

クライアント PC にバックアップファイルを移動

クライアント PC で SSMS を起動、LocalDB に接続
![](https://1bed.allright.life/wp-content/uploads/2019/09/1.png)

データベース master を右クリックして、New Query を選択
![](https://1bed.allright.life/wp-content/uploads/2019/09/2.png)

下記クエリーを実行

```sql
RESTORE FILELISTONLY
FROM DISK = '<バックアップファイルのフルパス>';
```

例.
![](https://1bed.allright.life/wp-content/uploads/2019/09/3.png)

ここでバックアップファイルの LogicalName を確認する

リストアコマンドを実行する

```sql
RESTORE DATABASE <リストア先データベース名>
FROM DISK = '<バックアップファイルのフルパス>'

WITH MOVE '<LogicalName>' TO '<データベースファイルのフルパス>',
MOVE '<LogicalName>' TO '<データベースログファイルのフルパス,
REPLACE;
```

例.
![](https://1bed.allright.life/wp-content/uploads/2019/09/4.png)

## 考察

できることは確認できたので、コマンドライン化して楽したい
[Java] クラス, コンストラクタ, 静的メンバ

# 9章 クラス機構
FQCNでのメソッド呼び出しと、クラスからのインスタンス（属性, 操作)で、頭がちょっと混乱したので、まず整理。

* FQCN: `package.Class.method()`

* インスタンスでのメソッド呼び出し（Class）。インスタンスの変数をnとすると、 
`n.method()`
 
// FQCN: Fully Qualified Class Name

##クラス
###### インスタンスのフィールドとは、属性の変数。
インスタンスは、クラスで定義した、フィールドと操作(メソッド, 動作)から生み出される。

###### has-aの関係: あるクラスが、別のクラスををフィールドとして利用している関係。

## コンストラクタ(constructor)とは
クラスがnewされた直後に自動的に実行されるメソッド。
`public class Hero {
int hp;
Hero() {
    this.hp = 100;  // hpフィールドを100で初期化。
}
}`
#### オーバーロードにおける、『別コンストラクタの呼び出し』ルール
* `this(引数);`と書く。

`Class(String names) {
this.name = names;
this.hp = 100
Class {
this("Bob");
}}`

## 静的フィールド
フィールドにstaticをつけると、静的フィールドになる。
静的フィールドへ、インスタンス変数からアクセスしても、元の静的フィールドに影響を与える。
まず覚えるべきgitコマンドまとめ

自分用にメモ。
前提条件として、gitがインストールされている事とgithubに登録されている事。

<h2>初期設定で使うgitコマンド</h2>

```
ユーザー名登録  git config --global user.name "githubユーザ名"

メールアドレス登録  git config --global user.email "github登録メアド"

使うエディタ設定  git config --global core.editor "使ってるエディタ名"

設定確認　git config --list
```

<h2>開発中使用gitコマンド</h2>

基本的に作業ディレクトリにて使用

```
ローカルリポジトリ作成  git init

Gitリポジトリのコピー　git clone リポジトリURL

変更を全てステージに追加  git add .

変更を記録　git commit

変更状況を確認　git status

リモートリポジトリ作成　git remote add origin　追加したいリポジトリ

リモートリポジトリへ送信　git push origin master
```

<h2>さらに先へ</h2>

通常の開発ではブランチを分けて、主にmasterブランチをリリース用として使用する。

```
新しいブランチを作成  git branch ブランチ名

ブランチの一覧表示　git branch -a

ブランチの切り替え  git checkout 切り替えたいブランチ名

```

また他の人の変更を取り込むことを「マージ」と呼び、複数人で開発するときは必須のスキルになっている

```
作業中のブランチにマージ  git merge ブランチ名
```

ただしここら辺は少し複雑なので、引き続き勉強が必要。
gRPC-WebをKotlinバックエンドで試した時のメモ - 3. ReverseProxy編

# About

このテーマの連載、ReverseProxy編です。

https://qiita.com/hosopy/items/d7afd9cf85bd6e155815

# 構成

おさらいになりますが、`ReverseProxy`は、gRPC-Webから受け取ったリクエスト(HTTP/1.1)を、バックエンドのgRPCサービスにリクエストを変換(gRPC,HTTP/2)して転送する役割を担います。

<img width="752" alt="architecture.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1489/5f7e10bb-60f7-8004-096a-d60655e622d7.png">

# 設定

ReverseProxyの設定は、サンプルの[reverse-proxy](https://github.com/hosopy/grpc-web-kotlin-sample/tree/master/reverse-proxy)ディレクトリに入っていますが、設定ファイルとDockerfileだけです。

## Envoyの設定(reverse-proxy.yaml)

[Envoyの公式ブログ](https://blog.envoyproxy.io/envoy-and-grpc-web-a-fresh-new-alternative-to-rest-6504ce7eb880)に解説があるので、その設定ファイルを参考にしてすぐに設定できました。

デバッグのために、アクセスログを標準出力に書き出す設定を追加しています。

```yaml:reverse-proxy/reverse-proxy.yaml
admin:
  access_log_path: /tmp/admin_access.log
  address:
    socket_address:
      protocol: TCP
      address: 0.0.0.0
      port_value: 9901
static_resources:
  listeners:
  - name: listener_0
    address:
      socket_address: { address: 0.0.0.0, port_value: 8080 }
    filter_chains:
    - filters:
      - name: envoy.http_connection_manager
        config:
          codec_type: auto
          stat_prefix: ingress_http
          route_config:
            name: local_route
            virtual_hosts:
            - name: local_service
              domains: ["*"]
              routes:
              - match: { prefix: "/" }
                route:
                  cluster: service
                  max_grpc_timeout: 0s
              cors:
                allow_origin:
                - "*"
                allow_methods: GET, PUT, DELETE, POST, OPTIONS
                allow_headers: keep-alive,user-agent,cache-control,content-type,content-transfer-encoding,custom-header-1,x-accept-content-transfer-encoding,x-accept-response-streaming,x-user-agent,x-grpc-web,grpc-timeout
                max_age: "1728000"
                expose_headers: custom-header-1,grpc-status,grpc-message
          access_log:
            - name: envoy.file_access_log
              config:
                path: /dev/stdout
          http_filters:
          - name: envoy.grpc_web
          - name: envoy.cors
          - name: envoy.router
  clusters:
  - name: service
    connect_timeout: 0.25s
    type: logical_dns
    http2_protocol_options: {}
    lb_policy: round_robin
    hosts:
    - socket_address:
        address: service
        port_value: 6565
```

## Dockerfile

コンテナ化します。

```dockerfile
FROM envoyproxy/envoy-alpine

EXPOSE 8080
EXPOSE 9901

ADD reverse-proxy.yaml /etc/reverse-proxy.yaml

ENTRYPOINT [ "/usr/local/bin/envoy", "-c", "/etc/reverse-proxy.yaml", "--service-cluster reverse-proxy" ]
```

# 次回

次回はWebフロントエンド編です。
php-master-changes 2019-08-28

この日は Travis の設定修正、pcntl のリファクタ、T_INC / T_DEC について precedence を指定していたのをやめる修正、min() / max() の警告を例外投げるエラーに昇格する修正、鬼車の更新、zend_memnstr() / zend_memnrstr() の実装修正、循環参照を含む静的変数 / プロパティでリークが検出される問題の修正、テストコードの不要処理を削除する修正があった！

# 2019-08-28
## nikic: Add --with-pear to Travis build
- https://github.com/php/php-src/commit/c1fbc3900f66ce9b45ddc40c97ee6d47fc5dc5a5
- [7.4~]
- Travis ビルドの設定へ --with-pear を追加

## nikic: Some pcntl cleanup
- https://github.com/php/php-src/commit/99ce142f6e37e803ce7c0fdaece79b9813c33543
- ext/pcntl で、インデントの修正と ZPP を一貫して使うようにする修正

## nikic: Don't specify precedence for T_INC/T_DEC
- https://github.com/php/php-src/commit/e5c7f710048ac5705f1782f3697da74676f1135f
- [7.4~]
- T_INC / T_DEC について precedence を指定していたのを修正

## Girgias: Promote warnings to errors in min()
- https://github.com/php/php-src/commit/b91a881b326950a2952962205e71f1da141e0847
- min() の警告を例外投げるエラーに昇格

## Girgias: Promote warnings to errors in max()
- https://github.com/php/php-src/commit/9fc3d5da110a12bc3b55a211408248f3e97a6a03
- max() の警告を例外投げるエラーに昇格

## smalyshev: Upgrade oniguruma lib to 6.9.3
- https://github.com/php/php-src/commit/5748cec3eef3a4a7973929d4c4b43da1b68a5d7d
- [7.3~]
- ext/mbstring で、鬼車を 6.9.3 へ更新

## nikic: Compute needle end only after checking it's non-empty
- https://github.com/php/php-src/commit/937d5f6598036d48713e28bf68df52cd56e1c974
- zend_memnstr() / zend_memnrstr() の実装で、needle の終端を空でない判定後にとるよう修正

## nikic: Fixed bug [#78335](https://bugs.php.net/bug.php?id=78335)
- https://github.com/php/php-src/commit/ec9a96dc60c3fd2cccf5b21033a0e87807366bdb
- [7.4~]
- 循環参照を含む静的変数 / プロパティでリークが検出される問題の修正

## cmb69: Fix test regarding ZPP TypeErrors
- https://github.com/php/php-src/commit/afb69b6f2d4872d6b916c10d7d394ca304481865
- ext/odbc で、テストコードから ZPP の挙動テストとなっているに過ぎない処理の削除
Rails +  MySQL + Vue.jsでアプリを作成する④/Vueの導入

※前回：
####Rails + MySQL + Vue.jsでアプリを作成する②/MySQLの導入
https://qiita.com/tksh8/items/885eb1ca51b32d6ea3a9
####Rails + MySQL + Vue.jsでアプリを作成する➂/簡単な画面を作成する
https://qiita.com/tksh8/items/741cf379da06d8817389


##Vueの導入


```ruby:Gemfile
gem "webpacker"

を追加する
```



```
gemのインストール
$ bundle install
webpackerインストール
$ bin/rails webpacker:install
コンパイル
$ bin/webpack
vueインストール
$ bin/rails webpacker:install:vue
```

できない場合はこちらを参考にしました。
https://qiita.com/_kanacan_/items/c1499f6c13b1c41da982#bundle-install%E3%81%97%E7%9B%B4%E3%81%99

https://qiita.com/keien-nishikawa/items/a285bcf4a58d14d4a36f





##RSpecの導入
https://qiita.com/tksh8/items/f0b5b656580334181e3c

##Rails +MySQLのプロジェクトをherokuへデプロイ
https://qiita.com/tksh8/items/39e1462e0bb556abbcbb

## AWSでのデプロイ手順はこちら
https://qiita.com/tksh8/items/9a8e88a777a3a4ee7a09
WebページにYoutubeの動画を埋め込みたい際にiframeを使用する

最近の勉強で学んだ事を、ノート代わりにまとめていきます。
主に自分の学習の流れを振り返りで残す形なので色々、省いてます。
Webエンジニアの諸先輩方からアドバイスやご指摘を頂けたらありがたいです！

#Youtubeの動画を埋め込みたい
自分の作成したページでYoutubeの動画をそのまま動画再生できるようにしたいと思ったのですが方法が分からず困っていました。

そして、この記事を見つけて早速、コーディングしたのですが
[iframeタグを使ってwebページにコンテンツを埋め込もう
](https://webliker.info/34774/)

なんだ、簡単やんと思い、早速以下の様に記述したのですが

```
<iframe src="https://www.youtube.com/watch?v=9No-FiEInLA&feature=youtu.be/"></iframe>
```

ダメでした

![スクリーンショット 2019-09-09 16.37.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394657/210cfdd6-e66c-05dd-26f8-0b9844698827.png)

なんで、できないんやと思っていたのですが、 YoutubeのURLを埋め込み用のコードにしないといけないらしくちょっと、めんどくさいなと思ったのですがYoutubeのページからiframeと埋め込みコードを以下の手順で生成できるのでコピペするだけでOK。

![スクリーンショット 2019-09-09 16.45.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394657/38da01a2-4dc4-01c2-f865-95d95af03506.png)

Youtubeからコピペして以下の様にコードを追加したところ

```
<iframe src="https://www.youtube.com/embed/9No-FiEInLA"></iframe>
```

![スクリーンショット 2019-09-09 16.48.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394657/cfd0d470-0167-ce86-9b4d-3f7896986b22.png)

上手くいきました！Youtubeありがたいですね笑
メンバーに応じて、混乱を生む手法より分かりやすい手法で

# オブジェクト指向はいいのかもしれないけど、問題を引き起こさずに使えてるのか？

 以下の記事を読むと、オブジェクト指向を今一度考え直す視点を与えてくれるように思います。記事の筆者は、オブジェクト指向の欠点を指摘しつつ、関数型言語のEarlangの良さを説いています。

　個人的には、関数型言語礼賛よりも、オブジェクト指向が現場に抽象化を持ち込むことで多くの混乱をもたらしたという所にすごく共感をもちました。グローバル企業、大企業でJavaの案件、ベンチャーでのRails案件をしてきた経験からも、たしかに指摘されていること見られると思いました。

[Object-Oriented Programming — The Trillion Dollar Disaster : オブジェクト指向プログラミング - 数兆ドルの損害](https://medium.com/better-programming/object-oriented-programming-the-trillion-dollar-disaster-92a4b666c7c7)


# よい手法だけど使いこなすのが難しいものを採用するべきか？

　オブジェクト指向については、よい手法もいろいろあると思います。それは適用ケースによりけりだとも思っています。
これに限らず、アジャイルへのアンチテーゼもちらほらあるみたいで、それについても使いようかと思います。

　ところで、手法がいろいろな手続を踏んだり、いろいろな経験をベースにする、または、人の能力に依存してしまうものは、いつでも採用していいいのだろうか？
　
　仕事をしていると、いろいろなスキルのプログラマーであったり、現場の文化があったりします。オブジェクト指向なんかも、その現場のプログラマーや文化によって、ひどいものになったり、成功したりします。

　必ずしもよい結果をもたらさないから、ある手法が駄目だとは結論できません。けれど、一方で、使いこなすのが難しいものを無理に採用すると、結局、問題を起こしかねず、それはそれで考える必要があると思います。


# プログラムはより民主的に（幅広いスキルの人が使える手法も選択肢に）

　今、以前にもまして、プログラミングスクールがでたり、学校でのプログラム教育が義務化されていきます。つまり、より幅広い能力の人がプログラマーが増えていきます。ある意味、今まで、すごく得意な人たちが使っていた絶対王政的なものから、民主的なものへと変わっていくように思います。

　そうしたとき、すごくスキルが必要な手法を必ずしも採用する必要はなく、できるだけ幅広いスキルの人が使える手法を使うほうが結果的にいいのではないかと思います。

　プログラム言語自体は文法を覚えれば、動きます。

　ですが、それを組み合わせるには、設計手法やプロジェクトの進め方なども必要になります。その手法については、いろいろと難しさもあり、どのような設計にするかによって、きれいなプログラムになるときもあれば、ひどくなるときもあります。

　こうした手法は、メンバーのスキルによるので、まずは、メンバーをみて、それをみて手法を選択することが必要に思います。並行して、プログラマー個人や会社として、より効率的な手法を習得していく研鑽も必要だと思います。

　権威的に語られる手法も必ずしも採用しないといけないわけじゃないし、メンバーに応じた手法を選べばいいように思います。
そうした幅広い、柔軟な手法選択がこれからもっと求められるように思います。

# 従来当たり前、権威的に語られていた手法への評価時期なのだろうか

　オブジェクト指向は、Javaと共に普及したといっても過言ではないと思います。そして、出たばかりのときは、すごく権威的で、プログラマーはオブジェクト指向をしないといけないという風潮すらありました。

　ですが、あれから20年近くも達、いろいろ問題をもたらすこともわかってきました。で、開き直ってといったらおかしいかもしれませんが、オブジェクト指向への一つの評価時期がきているのかなと思います。アジャイルについても同じかもしれません。

　プログラムの技術も歴史があり、ある程度時間がたつとその良さと悪さを評価される時期がくると思います。未来永劫変わらない賢威というものはないのだと思います。

　たえず、今あるものへの懐疑心をもって、自分たちが使いこなせるかどうかを賢威になびかずに、冷静に判断するのが大切な気がします。
フレームワーク内にちりばめられた composer を実行して回るワンライナー【Linux, composer, php】

## TL;DR

```sh:カレントディレクトリ以下のcomposer.jsonを探してcomposerを実行するワンライナー
find . -name composer.json -exec cd `dirname {}` \; -exec composer install \;
```

## 検証環境

ホストOS: Windows10
ゲストOS: CentOS Linux releaase 7.6 1810 (Core)
VituralBox: 5.2.28
Vagrant: 2.2.0
apache2(httpd): 2.4.6 (CentOS)
PHP: 5.6.38
Composer: 1.9.0
bash: 4.2.46(2)

## 解説

1. `find . -name composer.json` で、カレントディレクトリ（`.`）以下からファイル名`composert.json`を探します。
2. `find` コマンドのオプション `-exec` によって、検索結果のパスが入った変数(?) `{}` が１行ずつ展開され、`dirname`コマンドで composer.json ファイルが入っているディレクトリへのパスが取得されます。
3. `dirname`コマンドの結果で得られたディレクトリへ `cd` します。
4. `find` コマンドの `-exec` オプションは、`\;` をつけることで、次の `-exec` オプションに継続させることができるので、`cd` した先のディレクトリで `composer install` を実行します。
6. `find` で発見したファイルのあるディレクトリすべてで `composer install` が実行されます。

※`composer install` は `composer i` と略記できるので、可読性が気にならない場合は略記することが可能です。

## おわりに

fuelPHP を使っているプロジェクトに参加しているのですが、仮想環境にプログラムを展開したとき、ソースの各地に散らばる composer.json を蹴って回るのがめんどくさいので全力で手を抜くために頑張りました。
Laravel などでも同じことが利用できるかもしれません。お役に立てれば幸甚です。
php-master-changes 2019-08-27

この日は strpos() / strstr() 系の needle へ空文字列を渡せるようにする修正、chunk_split() の実装修正、arginfo の PHP スタブへの移行、循環参照 GC の実装修正、fpm でログの出し分けが正常に行われていなかった問題の修正、テストの修正、get_class() を VM 側で処理する際のエラー処理修正、AppVeyor の設定修正、不要コードの削除、デフォルトの php.ini へ ffi の読み込み例示を追加する修正があった！

# 2019-08-27
## Girgias: Improve strpos and strstr function family implementation
- https://github.com/php/php-src/commit/6d578482a933be7597b686b59a935b316161d251
- strpos()、strrpos()、stripos()、strripos()、strstr()、stristr() の needle に空文字列を渡せるよう修正
- [PR:4558](https://github.com/php/php-src/pull/4558)

## Girgias: Remove memory exhaustion checks in php_chunk_split()
- https://github.com/php/php-src/commit/5b09e6043c930168cacce3aa37346560be65d8b3
- [chunk_split()](https://www.php.net/manual/ja/function.chunk-split.php) の実装で、デカいアロケーションを避けるようなコードがあったのを削除しチェックをアロケータに任せ false を返さないよう修正

## duncan3dc: Convert exif functions arginfo to php stubs
- https://github.com/php/php-src/commit/743591458c8505ea13e2391898cc502702461983
- ext/exif で、arginfo の PHP スタブへの移行

## nikic: Remove properties HT from nested GC data
- https://github.com/php/php-src/commit/589542f50cbaf2bfc88aea79092df9db54f75ac6
- [7.2~]
- 循環参照 GC の実装で、オブジェクトプロパティのハッシュテーブルを入れ子オブジェクトの GC の際にバッファから取り除くよう修正

## duncan3dc: Convert fileinfo functions arginfo to php stubs
- https://github.com/php/php-src/commit/4836660b9070b9eef0d30b8ba43f8c82dbbded1f
- ext/fileinfo で、arginfo の PHP スタブへの移行

## sadapon2008: Fix bug [#78334](https://bugs.php.net/bug.php?id=78334) (fpm log prefix message includes wrong stdout/stderr notation)
- https://github.com/php/php-src/commit/ffcf57fa187f55b6e2cf3e6de43b03332cc750de
- [7.3~]
- sapi/fpm で、stdout / stderr のプレフィクスでのログの出し分けが正常に行われていなかった問題の修正

## nikic: Fix chunk_split test on i386 release
- https://github.com/php/php-src/commit/085ddd0cdeb46ab2fb030bf7b94c0fec34ff3d52
- [chunk_split()](https://www.php.net/manual/ja/function.chunk-split.php) の i386 でのテストこけの修正

## nikic: Add skipifs for zmm
- https://github.com/php/php-src/commit/f107b670daeb02a9f2f1d4e081b8e226b17e25f3
- ZMM 有効を要するテストへの SKIPIF の追加

## nikic: Throw TypeError from VM implementation of get_class()
- https://github.com/php/php-src/commit/d93b09458430dae6fa6475d09811673520338597
- [get_class()](https://www.php.net/manual/ja/function.get-class.php) の VM 側で処理する際の実装で TypeError 投げる化が適用されてなかったのを修正

## cmb69: Update SDK version for AppVeyor
- https://github.com/php/php-src/commit/88ab3746278c1e52aaba4dce264ae61431f94024
- [7.2~]
- AppVeyor の設定で、PHP SDK の更新

## weltling: Fix signature and calls
- https://github.com/php/php-src/commit/9b5d66bd52c90f37aa39ea6bcab4c46b6121f3d8
- [7.4~]
- php_win32_image_compatible() で使っていなかった第 2 引数を削除

## Gemorroj: add ffi to php.ini extension [ci skip]
- https://github.com/php/php-src/commit/f08095faa5a59ea89d6a554311f2c968c4c439f9
- [7.4~]
- デフォルトの php.ini へ、ffi の読み込み例示を追加
参考記事まとめ

#AWS
##ソリューションアーキテクト　アソシエイト
[３週間でAWS認定ソリューションアーキテクト-アソシエイト-とったので、勉強法などまとめてみる](https://qiita.com/fukubaka0825/items/238225f9e4c1962bc00c)
##cloud watch
###AWSの"メトリクス"とはなにか？
【基礎から学ぶ】Amazon CloudWatch<メトリクス編>](
http://blog.serverworks.co.jp/tech/2017/09/12/kiso-cloudwatch-metrics/)

#ruby
##オブジェクト指向
[Rubyを始めたけど今ひとつRubyのオブジェクト指向というものが掴めないという人、ここに来て見て触って！](https://melborne.github.io/2013/02/07/understand-ruby-object/)

##selfについて
[【Ruby】selfの意味が分からない](https://teratail.com/questions/116158)

##リファクタリング
[[初心者向け] RubyやRailsでリファクタリングに使えそうなイディオムとか便利メソッドとか](https://qiita.com/jnchito/items/dedb3b889ab226933ccf)
[C#]CelesTrakからTLEデータ取得

# 環境
+ Windows 10
+ Visual Studio 2019
+ .NET Framework 4.7.2

# プログラムの流れ
①[WebClient](https://docs.microsoft.com/ja-jp/dotnet/api/system.net.webclient?view=netframework-4.8)を使って、[CelesTrak](https://celestrak.com/)の任意の[TLE](https://gportal.jaxa.jp/gpr/assets/mng_upload/GCOM-W/TLE.pdf)情報ページのHTMLを取得。
HTMLソースは以下のような感じ。

```html
<!doctype html>

<html>

<head>

<title>TLE for NORAD Catalog Number 27424</title>

</head>

<body>

<pre>
AQUA                    
1 27424U 02022A   19252.13049769  .00000059  00000-0  23155-4 0  9997
2 27424  98.2068 191.7488 0002405 118.9436  65.4284 14.57115315922808

</pre>
	
</body>

</html>

```

②上記のHTMLから正規表現を使って、衛星名とTLEを抽出。
③抽出した内容をテキストファイルに書き込む。

## 注意
HTMLの構成はちょいちょい変わるので気を付けてください。

# 作成したプログラム

```c#
using System.IO;
using System.Net;
using System.Text.RegularExpressions;

namespace GetTleFile
{
    class Program
    {
        static void Main(string[] args)
        {
            var wc = new WebClient();
            wc.Encoding = System.Text.Encoding.UTF8;
            var tleHtml = wc.DownloadString("https://celestrak.com/satcat/tle.php?CATNR=27424");

            var anchor = "<pre>.*?\r\n(?<satName>.*?)\r\n(?<line1>.*?)\r\n(?<line2>.*?)\r\n";
            Regex re = new Regex(anchor);
            Match m = re.Match(tleHtml);

            var filePath = ".\\tle.txt";
            if (!File.Exists(filePath))
            {
                using (File.Create(filePath)) { }
            }

            File.WriteAllText(filePath,
            $"{m.Groups["satName"].Value}\n{m.Groups["line1"].Value}\n{m.Groups["line2"].Value}\n");
        }
    }
}

```

## 出力結果
```:tle.txt
AQUA                    
1 27424U 02022A   19252.13049769  .00000059  00000-0  23155-4 0  9997
2 27424  98.2068 191.7488 0002405 118.9436  65.4284 14.57115315922808

```

出力されるtle.txtは、文字コード: UTF-8, 改行コード: LF としました。
GitHubActionsの環境変数は大文字に変換されない

公式には以下のように記載されています。

https://help.github.com/en/articles/virtual-environments-for-github-actions#environment-variables

> GitHub converts environment variables names to upper case. For example, if you set the variables first_name, middle_name, and last_name for a step in your workflow, you could read the FIRST_NAME, MIDDLE_NAME, and LAST_NAME environment variables.
> 
> ```
> steps:
>   - name: Hello world
>     run: echo Hello world ${FIRST_NAME} ${MIDDLE_NAME} ${LAST_NAME}!
>     env:
>       first_name: Mona
>       middle_name: The
>       last_name: Octocat
> ```

が、実際には大文字小文字は区別されるようです。

記述

```
    - name: Test
      run: |
        echo "1-1: $KEY1"
        echo "1-2: ${KEY1}"
        echo "1-3: $key1"
        echo "1-4: ${key1}"
        echo "2-1: $KEY2"
        echo "2-2: ${KEY2}"
        echo "2-3: $key2"
        echo "2-4: ${key2}"
      env:
        key1: value
        KEY2: VALUE
```

実行結果

```
1-1: 
1-2: 
1-3: value
1-4: value
2-1: VALUE
2-2: VALUE
2-3: 
2-4: 
```

しばらくハマってしまいました。
わかりやすいデザインを考える

若い頃、趣味でFlashサイト/ゲームを作って友達に見てもらい意気揚々と感想を聞くと、

「どうしたら良いかわからない」
「変わったデザインだね」

といった評価をもらい、**「あんなの飾りです。偉い人にはそれが分からんのですよ。」**という名言を思い出しながら憤りを感じつつも落ち込んでました。

言われてみると当たり前なんだけど慣れていない人だと結構失敗するかもしれないと思い、今回投稿してみました。

# デザインにおける「わかりやすさ」とは

* 迷わないこと
* 何が起きるのか予想ができること
* 安心できること

デザインにおける「わかりやすさ」を説明するとこんな感じでしょうか。
では、WEBやアプリでは具体的にどういったことを考えれば良いのでしょうか。

ユーザーの行動から順を追って考えてみます。
PCであればこんな行動をします。

* 画面を見る
* マウスを動かす
* クリックする

それでは「画面を見て、次の動線までマウスを持っていき、クリックをする」というシナリオで考えてみましょう。

## 画面を見る

画面を見て得たい情報を探します。
たいていの場合、文字を読んだり画像を見る、そして次の画面への動線を探します。

### 文字は見やすいか

当然ですが、小さかったり、色のコントラストが低いと読みづらいです。
最近だと**16pxの文字サイズ**が多い気がします。

業務で高齢者がターゲットとなるアプリを作ることがあったのですが、オフィスで老眼の方を探して「この文字読めますか？」と（失礼にも）聞いて文字サイズが十分か確認してました。
ターゲットによって最適な文字サイズは変わるので一概にどの大きさが良いということは言えないかと思います。

### 動線は気づきやすいか

通常のWEBであれば、リンクには下線が引かれ文字の色も変わります。
もし、これが普通の文字と同じであればかなりわかりづらいでしょう。

アプリであればリンクじゃなくてボタンのような部品もあるでしょう。
見た感じでクリック/タップできそうなことを表現しないといけません。
例えば、マテリアルデザインであれば、影をつけることによって「押せる感」を表現します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201603/0ce06aeb-53d1-70f3-0f95-e4b0d165ec3f.png)


## マウスを動かす

動線を見つけたらユーザーはそこにマウスを持っていきます。
そして「やっぱり押せそうだ」という実感をユーザーに与える必要があります。

### 押せることに気づきやすいか

もし、ボタンの上にマウスを持って行って何も変化がなければ、「押せる感」が全くありません。
**マウスのカーソルは指(ポインタ)に変化するべきです。**
これはUIをあまり作らない人がUI部品を作った場合によくあるのですが、マウスカーソルを変化させることに気が回らないことがあります。
CSSであれば cursor: pointer という記述にあたります。
また、ボタンはマウスが重なった時に色が変わると、より一層わかりやすくなります。

スマホの場合、「マウスが重なる」に相当する動作がないので、より一層「押せる感」を表現する必要があります。
余談ですが以前、父と母にLINEで「紙を撮影した写真」を送ったことがあったのですが彼らは「読めない」と言ってきました。
写真をタップして拡大表示すれば十分読める大きさだったのですが、そもそも彼らはLINEで送られた写真をタップできることを知りませんでした。画面を見てもタップできることに気づかなかったのです。


## クリックをする

マウスを動線まで持っていき「確かに押せそうだ」と感じたユーザーはクリックをします、
この時、ユーザーに不安を持たせないようにする必要があります。

### 何が起きるのか想像しやすいか

押した結果が想像できないと怖くて押せません。

例えば、「購入画面へと遷移するボタン」を考えてみます。
次の2つのボタンを見比べると、左のボタンは「購入が確定する」ように感じてしまいます。
これではユーザーは怖くてボタンを押せないかもしれません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201603/f967d70e-ef43-7984-ce3b-dae08d030b85.png)

他にもアイコンを使うことがあるかと思いますが、アイコンだけで内容が想像できない可能性がある場合は言葉も添えた方が安心できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201603/ef8af570-259b-72ef-e5da-84c864fcb973.png)


### 押したことがわかりやすいか

押して何も反応がなければユーザーは本当に押せたのか不安に感じます。
ボタンが凹んだような色や動きをしたり、新しい画面を表示したりなど、何らかのフィードバックをする必要があります。

またスマホの場合、自分の指が邪魔で色の変化が見えない可能性もあるので、アプリであれば振動したり音を出したりすると、より一層押したことが実感できると思います。

# まとめ

「画面を見て、次の動線までマウスを持っていき、クリックをする」という流れを例に、「わかりやすさ」の話をしました。
どれも当たり前のことだったと思いますが、いざ自分でUIを作るとなると意識できてなかったりします。
ユーザーの行動を分解して、それぞれの動作についてわかりやすいかを考えてみると良いかもしれません。

また「わかりやすさ」は対象とするユーザーによって変わることを知っておく必要もあります。
アイコンに文字を添える話を書きましたが Instagram では文字は添えられていません。
電話の表現でよく黒電話のシルエットを使うことありますが、今時の子供は黒電話は知らないでしょう。（ジブリの影響とかで意外と知ってますけど）

他にもUI関係の投稿をしてますのでご興味があれば是非読んでみて下さい。


　失敗しづらいUIへのアプローチ
　https://qiita.com/megumu-u/items/b96b7fc7b0a57d72a47f

　失敗しづらいアプリ開発へのアプローチ
　https://qiita.com/megumu-u/items/c3c8f160f7c94599b717
第三回JDLA e資格に合格したので感想を書く

# JDLA e資格とは
東大の松尾豊教授（AIの領域では超有名）が中心となって作られた日本で初めてのAIに関する資格。
資格としては、一般的な知識を問うG検定とエンジニアとして必須知識を問うe資格がある。

## 取ってよかったか？
資格を受験するとき、皆さん一番気になる点だと思います。
個人的には**取ってよかった**と思っています。

良かった点としては、
　・ものすごく漠然としていたAIの勉強に関する指針がつかめた
　・資格という形で一つのゴールがあったので、変に独学するより学習が早かった
　・輪読会などAIに本当に興味のあるコミュニティに参画できた
　・自信になった
といった点が主なところです。

もともと私自身がITエンジニアであり、会社に新しいサービス開発の気風が生じていることもあって、
**「AIの見地から仕事がしてみたい」**という思いから受験を決めていました。
そういう意味で、**漠然としていたAIの勉強に関する指針がつかめた**ことが一番大きな収穫だったように思います。

ただ微妙だった点は、
　・認定講座（６桁の金額）の受講が必須でお金がかかる
　・この資格があるから、すぐに現場で通用するかと言われたら疑問
　・今この領域は博士課程出身者等がとても評価されているので、学歴をひっくり返すほどの効力は単体では持たない
ということでしょうか。

私はお金に関してはクリアできる環境が偶然整ったため受講しました。
残りの二点は注目度が高い資格のため、私の過剰な期待からくるもののようにも思います。
資格取得してみて、またAIの現場に属してみて思うのは、AIは全く新しい領域のため
**資格があろうがなかろうが自分で勉強しないと使い物にならない**ということです。

即仕事につなげたいのなら、Kaggleのコンペティションに独力で参加して上位に食い込んだ方が資格よりもよっぽど評価されると思います。

ということを鑑みると、
**お勧めしたい人**
　・AIに興味があるが、AIが何をやっているのか全く知らないので、仕組みをしっかり知りたい人
　・AIの仕事をしたいが、上記のKaggleのコンペティションで何をやっていいか全くわからないので、その取っ掛かりをつかみたい人
　・AIにつきものの数学が分かりづらく、ネット上のAI関連の記事で、数式を見てもイメージをつかめない人
　・現在技術職（製造など）で、工学やその他のドメイン知識があるため、AIと組み合わせて実務を発展させたい人（異常系の自動検知等）


**あまりお勧めしない人**
 ・大学等でAIに触れるより良い環境がすでに整っている人
 ・とりあえず資格があれば就職、転職につながるというステータスとしてとらえている人
 ・そもそもの英字論文をあたってイメージをとらえ、実装までつなげられる人

と二分されるかなと思います。就職、転職に即つなげたいなら他に有利になる資格がいくらでもあると思うので、別のものをお勧めします。
ただ、**AIとは何か理解できるようになり、どう応用していくかを自分で考える素地になる資格**なので、スキルアップととらえている場合はとても有用だと思います。

## 資格試験の内容に関して
前回（第２回）受験した方の記事等を参考に対策をしていたのですが、第三回は思ったよりも**基礎より実務に耐えうる技術**を中心に出題されたように感じました。
もっとやっておけばよかったと思ったのは以下の通りです。

・RMSProp、Adamの詳細な数式と実装　（SGD,momentumとAdaGradで満足してたら痛い目見ますよ）
・RNNの逆伝播の実装
・LSTMとGRU
・VAEをKLダイバージェンスでなくJSダイバージェンスに変更するとどうなるか
・強化学習の報酬関数の種類と詳細な数式
・Object Detection(物体検出)の各アーキテクチャとIOUの計算方法
・クラスタリングのDBScan や Kmeans++の実装

そのほかにCNNとResnet, 発展の歴史や、固有値分解や主成分分析、カーネル法など出るのは
対策されている方なら把握されているかと思います。

実装と書いたところはプログラムの穴埋めベースでした。このような、現実に開発ではスタンダードな技術がどのように組み込まれるかという出題に寄せてきていたように思います。
逆に、sigmoidやsoftmax関数の数式と逆伝播の式などは、出題はしませんが知っていて当然という風に問題文に組み込む形に変わっていました。憶測でしかありませんが、実用のレベルに達さない知識は今後出題が少なくなるかもしれません。
Kmeansも、Kmeans++のみ詳しく聞いてきたので…

## 試験までに行った勉強
以下はご参考までに講座受講後から試験まで、私の行った勉強を記載します。受講した講座はAIジョブカレです。

**半年前～ひと月前まで**
・KaggleのTitanicとHouse Priceで、RegressionとClassificationを３０回づつくらい提出。（上位1/3程度でした）
・CNNの独力実装でcifar10の精度を上げようと頑張って78%を出した後、imagenetのデフォルトのResNet50であっさり98%をたたき出されて落ち込む。
・物体検出に関してのみ講座でノータッチだったことに気づき、血球の検出や音符の検出など、英語で探すと見つかる写真とannotationのデータセットを中心に実装をしてみる

**１か月前から**
・認定講座側で設けられていた輪読会（参加費３０００円）に参加し、出やすそうなところの情報を得る(LSTM, GRU, im2col,　あとは逆伝播の実装)
・受講した動画（数学、機械学習、深層学習）を見返し。深層学習のみ３周しました。
・修了試験を解きなおし。数学は全て選択肢なしでも満点が取れた方がいいと思います。

以上のような流れで勉強をしていました。

最後にテクニカルな話をすると、
試験は問題数が多いため、わからないものや時間のかかるものは飛ばしてあとから解いた方がよいと思います。
また、問題はあえてわかりづらく聞いてくる節はあります。その時パッと見て暗記してきた中からでは答えが浮かばなくても、概念を理解している人であれば、**問題文をよく読んで咀嚼すれば答えの選択肢にたどり着ける**親切(?)な作りになっているので、落ち着いて最後まで諦めないでください。

これを読んで対策された方が一人でも合格するよう願っています。
Chart.jsで回帰直線を描画

# はじめに
RやPython+matplotlibでは簡単に描画できる回帰直線を、JavaScriptのグラフライブラリ「Chart.js」で描画します。
以下は、散布図を描画するデータから回帰式を求めて、回帰直線を描画するサンプルです。

<img width="804" alt="chart.js_regressionLine.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445427/05f0bdfa-1eaf-67cc-d23a-4a213383f28e.png">


# サンプル
```html
<!DOCTYPE HTML>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>cahrt.jsで回帰直線を描くサンプル</title>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.bundle.js"></script>
</head>
<body>
<!-- グラフ描画エリア設定 -->
<div style="width:100%">
  <canvas id="canvas"></canvas>
</div>

<script>
// 散布図データ
var sample = [
  {x:1, y:4},{x:2, y:3},{x:3, y:4},{x:4, y:5},{x:5, y:6},{x:6, y:5},{x:7, y:7},{x:8, y:6},{x:9, y:8},{x:10, y:7}
];


// 回帰直線の傾きと切片を求める
var sx = 0;
var sy = 0;
var sxy = 0;
var sxsq = 0;
var xmean;
var ymean;
var alpha;
var beta;
var n;

sample.forEach(function(val) {
  sx += val.x;
  sy += val.y;
  sxy += val.x * val.y;
  sxsq += Math.pow(val.x,2);
});

n = sample.length;
xmean = sx/n;
ymean = sy/n;
beta  = ((n*sxy) - (sx*sy))/((n*sxsq)-(Math.pow(sx,2))); // 傾き
alpha = ymean - (beta * xmean); // 切片


// 回帰式より、回帰直線描画用データを作成
var regressionLinePlot = [];
sample.forEach(function(val) {
  regressionLinePlot.push({'x': val.x, 'y': alpha + beta*val.x});
});


// 散布図と回帰直線を描画
window.onload = function() {
  var ctx = document.getElementById("canvas").getContext("2d");
  window.myChart = new Chart(ctx, {
    type: 'scatter',
    data: plotData,
  });
};


// 描画データ
var plotData = {
  datasets: [
    { // 散布図
      type: 'scatter',
      label: 'scatter',
      data: sample,
      borderColor : 'rgba(100,120,255,1)',            // プロットの線の色
      backgroundColor: 'rgba(130,160,255,1)',         // 凡例の背景色
      pointBackgroundColor: 'rgba(100,120,255,1)',    // 点の色
      fill: false                                     // 線とＸ軸で囲まれた範囲の描画
    },
    { // 回帰直線
      type: 'scatter',
      label: 'Regression line',
      data: regressionLinePlot,              // 始点と終点のデータ（座標）
      borderColor : 'rgba(20,100,20,1)',     // 線の色
      backgroundColor: 'rgba(70,100,70,1)',  // 凡例の背景色
      borderWidth : 2,                       // 線幅
      pointRadius: 0.5,                      // 点の形状の半径（0にすると点を描画しない）
      tension: 0,                            // 線を直線にする
      showLine: true,                        // 線を描画
      fill: false                            // 線とＸ軸で囲まれた範囲の描画
    }
  ],
};
</script>
</body>
</html>
```
Treasure Data の Custom Scripts で任意のライブラリを読み込む

Custom Scripts で未インストールのライブラリを使いたい場合のメモです。

例えば、以下のようにファイルが配置されている時、

```
├ py_scripts
│ └ sample.py
└ sample.dig
```

ワークフローの設定ファイルには以下のように記述し、

```
timezone: Asia/Tokyo

+task1:
  py>: py_scripts.sample.sample_sleep
  docker:
    image: "digdag/digdag-python:3.7"
```

sample.py の中で以下のようにインストールします。

```python
import sys
import subprocess

subprocess.call([sys.executable, '-m', 'pip', 'install', 'tqdm'])

def sample_sleep():
  from tqdm import tqdm
  import time
  
  for i in tqdm(range(100)):
    time.sleep(0.1)
```

### 参考になった記事
[Introduction to Custom Scripts](https://support.treasuredata.com/hc/en-us/articles/360026713713-Introduction-to-Custom-Scripts)
[Adding a Custom Python Script to your Workflow](https://support.treasuredata.com/hc/en-us/articles/360026547734-Adding-a-Custom-Python-Script-to-your-Workflow)
プログラミングスクールや講座の履修と実際のスキル（個人の感想）

# プログラミングスクールやオンライン講座履修者との会話

　時々、プログラミングスクールやオンライン講座の履修者から質問を受けることがあります。といっても、それほど多くの人ではないですが、数人レベルです。
　なので、以下に記載することは一般的な傾向ではなく、あくまでも個人の感想です。

# 一応、カリキュラム内容は目を通し、「作業」はしてるけど・・・

　カリキュラムは一通りこなして、何かは作ったりしているけど、道が引かれているからなのか、「作業」化してて単純に「しただけ」になっているように思うことがあります。

　というのも、質問内容が結構初歩的な事が多く、「それ、スクールとか講座でしてんじゃないの」と心のなかで思ったりします。
　実は、実際の現場では必要だけど、カリキュラムにのってないこともあるんでしょうか。

　デバッグや設計、テスト周りはあんまりないんですかね。少なくとも、デバッグやユニットテストぐらいは、専門でするならカリキュラムでしておいてもよさそうですが。

# 経験数が足りないから仕方ない

　プログラミングに限らないですが、学校の勉強は数学、英語にしろ使うところがなかったら、やっぱり頭に入ってないし、使い所もわからないです。
　それにスクールや講座を1回、なめただけでいきなり仕事ができるぐらいの知識の理解度や、使いこなしができる人は、稀だと思います。

　カリキュラムにある内容でも、意識の濃淡があり、理解度が異なります。実際、仕事の現場では、困ったことがあれば、すごく理解もするし、その応用もできます。

# 課題は困るぐらいの内容を経験してるといいかも

　困るぐらいの課題をこなして、その技術の理解が得られているなら、カリキュラムをした経験はより活きるのかもしれません。
　とりあえず「流すだけ」、「しただけ」で終わっていると、結局、また、同じようなことを勉強しなおさないといけないと思います。

　とはいえ、１回経験しているから、何をしたらいいのか「目次」は頭にはいっているからいいと思います。


# スクールや講座を受けただけではスキルは判定できない

　実際、スクールや講座を受けて就職する人はたくさんいます。要は、社外研修を積んできているので、採用のメリットはありますね。
でも、採用する側、される側も、スクールや講座でしたことを過大評価しない方がいいと思います。

　結局のところ、どれだけ困った経験をしているか、そして、それを解決したかが大切で、それを超えて知識を理解し、応用ができてはじめて仕事として使える「スキル」になっているのだと思います。

　**「知識を見るだけ、知るだけ」では、仕事はできない。**
　**「知識の使い所、応用」ができて初めて仕事になる。**


# スクールや講座を受けたら自分で何か作ってみる

　スクールや講座の卒業試験や課題としてあるならいいのですが、できるだけ自分でやりたいことをきめて、設計、製造、テスト、デプロイまでやると知識の理解が深まり、応用ができるようになりますね。

　逆に言えば、そうした課題をこなしたかスクールや講座を判定する一つの観点だと思います。

　採用側も、どんなスクールや講座が存在していて、それでどういったことが得られるのかも知っておいた方がいいと思います。
また、スクールや講座では、「自己解決」をどれだけ経験できたかを聞くのがいいように思います。

　最近は、「儲けのため」で「とりあえず、やらせる」になっているスクールやカリキュラムもあるみたいで、修了しましたというけど、
　基礎的な言葉も考えもわからないという人に時々あうので、受講者や就職の採用者は気をつけたほうがいいなと思います。
carrierwaveでvalidation失敗したときの正しい書き方

### 要約
- validationが失敗したときのキャッシュのさせ方は`f.hidden_field :image_cache`書くだけでいい
- fog使ってs3に保存している場合でも`config.cache_storage = :fog`書けばs3でこのキャッシュ処理やってくれる
- carrierwaveの記事で結構正しくない情報が多い

### validationが失敗したときのキャッシュのさせ方
`carrierwave cache`でググると

```ruby
# controller
model.image.cache!

# view
f.hidden_field :image_cache
```
のようにしろという記事が出てくるのですが、実はcache!は手作業でやる必要なくて、単純にviewの方の

```ruby
f.hidden_field :image_cache
```

だけを書けば、validationに失敗したときだけ自動で`image_cache`に値が入ってくれます。
githubのreadmeに書いてあります。
https://github.com/carrierwaveuploader/carrierwave#making-uploads-work-across-form-redisplays
(cache!はreadmeでは触れられておらず、普通に使う分には利用者が呼ぶ必要はなさそうです)

さらに、fogを使っていても

```ruby
# config/initializers/carrierwave.rb
config.cache_storage = :fog
```
していればs3上でこのキャッシュファイルが処理されるので、サーバを2台構成にしていてvalidation失敗したときにサーバAにキャッシュしていて、やり直しのリクエストがサーバBに行ったときにキャッシュファイルがなくてエラーになるということもありません。
pythonでホスト名をゲット

## osモジュールというものがある

```
import os
```

## unameコマンド結果が取れる

```
os.uname()
('Linux', 'ip-172-31-13-213.ap-northeast-1.compute.internal', '4.14.123-111.109.amzn2.x86_64', '#1 SMP Mon Jun 10 19:37:57 UTC 2019', 'x86_64')
```

## ホスト名だけ

```
os.uname()[1]
'ip-172-31-13-213.ap-northeast-1.compute.internal'
```

## OSバージョン

```
os.uname()[2]
'4.14.123-111.109.amzn2.x86_64'
```

## 参考
https://qiita.com/iorionda/items/cfceac93c9e87d430077
Python 3(pyenv) と Google Cloud SDK を共存する

GCP を使う上である種必須とも言える Google Cloud SDK は、Python 3がデフォルトの環境だと動かない問題がある。
~~Python 2の死までもう4ヶ月を切っているけどリプレースする気はあるのだろうか:thinking:~~

(pyenvの導入方法などは割愛)

pyenvを使っている環境で `pyenv global 3.x.x` とした際には `$CLOUD_SDK_PYTHON` という環境変数に Python 2 へのパスをセットするのが一般的なのだと思っていた。

しかし、 `pyenv global 3.x.x 2.x.x` とバージョンを2つ記載するとPython 2/3の環境を共存させることができる。

この場合の各バージョンは以下のようになる。

```
$ python --version
Python 3.x.x

$ python2 --version
Python 2.x.x

$ python3 --version
Python 3.x.x
```

`pyenv help global` を実行してもバージョンを複数指定できることは書いていない[^1]。

```
$ pyenv help global                                                                                  (git)-[fix/webdav-put]
Usage: pyenv global <version>

Sets the global Python version. You can override the global version at
any time by setting a directory-specific version with `pyenv local'
or by setting the `PYENV_VERSION' environment variable.

<version> should be a string matching a Python version known to pyenv.
The special version string `system' will use your default system Python.
Run `pyenv versions' for a list of available Python versions.
```

これにより上述の `$CLOUD_SDK_PYTHON` をセットしなくとも Google Cloud SDK が使えるようになる。

[^1]: [GitHubのREADME](https://github.com/pyenv/pyenv#choosing-the-python-version) には書いていた
pythonでCPU、メモリ、ディスク使用率をゲットするプログラム

## psutilをインストール

```sh
$ pip install -U psutil
```

## CPU、メモリ、ディスク使用率をゲットするプログラム

```resource.py

import psutil

# mem
mem = psutil.virtual_memory()
print(mem.percent)

# cpu
cpu = psutil.cpu_percent(interval=1)
print(cpu)

# disk
disk = psutil.disk_usage('/')
print(disk.percent)
```

## 実行結果

```sh
$ python resource.py
23.9
0.0
18.4
```

## 参考手順
[公式サイト](https://pypi.org/project/psutil/)
pip install実行時に「Command "/usr/bin/python3 -u -c "import setuptools, tokenize～」と出る


## メッセージ

```
Command "/usr/bin/python3 -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-1zxgesds/psutil/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-4_6kb2qn-record/install-record.txt --single-version-externally-managed --compile" failed with error code 1 in /tmp/pip-build-1zxgesds/psutil/
```


## 解決策
`-U`オプションを付ける
そういうもんですかね？

```
pip install -U psutil
```
大規模C++ソフトウェアデザイン

#諸言
　学習履歴全体のリンク
　https://qiita.com/shigural/private/444b991293e5ab1b40af
#本文
##大規模C++ソフトウェアデザイン
###1-10章
執筆中
###付録A
Protocol Hierachyパターン
多くのオブジェクトを1つのクラスにまとめたいが、派生クラスの持つ関数が独立しており、基底クラスに空の関数を実装しなければならない かつ派生クラスが今後多数発生すると考えられるような状況で用いられるデザインパターン。
クラスは2層以上からなるが、ここでは基底クラス（A）→派生クラス（B）→派生クラス（C）の派生クラス　の3つの場合を例にとって説明する。
（基本的に3層以上で構成することが望ましい）
Aクラス：基本機能を実装する。派生クラスに関する実装は書かない
Bクラス：独自の実装を書く
Cクラス：さらに独自の実装を書く
クラスを利用する場合には必要な一番基底となる型にキャストする。例えばobjectがBクラス独自の実装を利用する場合には次のように実装する
if(p=ClassB::dynamicCast(object)){
  p->function();
}
else{
 cout<<"object is not have function()"<<endl;
}
これにより、派生クラスに追加で機能をもたせた場合にも基底クラスを変更しなくてすむ
###付録B-D
執筆中
JuliaでEuler法やってみた

# 1. Euler法 とは
[Wikipedia](https://ja.wikipedia.org/wiki/%E3%82%AA%E3%82%A4%E3%83%A9%E3%83%BC%E6%B3%95) によると、

>オイラー法（オイラーほう、英: Euler method) とは、常微分方程式の数値解法の一つである。この方法は、数学的に理解しやすく、プログラム的にも簡単なので、数値解析の初歩的な学習問題としてよく取りあげられる。
しかし、1階段数常微分方程式の数値解法としては誤差が蓄積されるため、精度が悪く、元の微分方程式によってはいかなる h をとっても元の方程式の解に収束しないこともある方法なので、学習目的以外であまり使われない。


ざっくりとEuler法を書くと微分の定義を用いて、
$$
y' = \frac{y(t + \Delta t) - y(t)}{\Delta t} 
$$
これを式変形してまとめると、
$$
y(t + \Delta t) = y(t) + y'\Delta t 
$$
となる。これをプログラムを書くために配列によって書き表すと

```Julia
y[n+1] = y[n] + y'*dt 
#y'は関数により、Δt = dt と表記する。
```

誤差は生じれど、数値計算の初歩的な練習には適しているみたいだ。最近私はJuliaでの数値計算を練習したりしているので使ってみよう。(Pkgで[ODEProblem](http://docs.juliadiffeq.org/latest/index.html)とかあるけど、今回は使わないよ)

より正確に数値計算やるなら改良Euler法とかRunge-Kutta法で解くのが良いかと思います。



# 2.コードを書くための準備
以下の手順にしたがって準備を進めていこう。

## 2.1 今回使用する一階線形微分方程式

ここでは、
$$
y' = 3y + 2~~ , ~~y(0) = y_0
$$
を例にする。これをEuler法で考えていく。

# 2.2 Euler法への落とし込み

1. で導入した式に代入すると、

$$
y(t + \Delta t) = y(t) + (3y + 2)\Delta t 
$$

自明に $y = y(t)$ であるので、$y(t)$でくくると、

$$
y(t + \Delta t) = (1 + 3\Delta t)y(t) + 2\Delta t
$$

である。この式を、配列によって書き直すと

```Julia
y[n+1] = (1 + 3*dt)*y[n] + 2*dt   
#Δt = dt
```

である。ここまで準備できれば、ほぼ完成したようなものだろう。

## 2.3 厳密解も準備しておこう
数値解との比較もしたいので、厳密解も同時にプロットしよう。与えられた微分方程式を微分積分学の知識を用いて解くと、

$$
y(t) = \left(y_0 + \frac{2}{3}\right)e^{3t} - \frac{2}{3}
$$
となる。

# 3. コードを記述する

それでは、これまで準備してきたことを使ってコードを記述していこう。

```Julia:euler.jl
using Plots;gr()

# 点数
N = 1000

# 刻み
dt = 0.001

# 初期化
y = zeros(N)

# 初期値(y(0) = y_0 = 1 とした)
y[1] = 1

# 数値計算
for n = 1:N-1
    y[n+1] = (1 + 3*dt)y[n] + 2*dt
end

# x = 開始値:間隔:終了値
x = 0:dt:(N-1)dt

# 厳密解
function f(x)
    5//3 * exp.(3*x) - 2//3
end

#色々と指定してplot.
#plot!はグラフを追加する機能をもつ。
plot(x, f, color=:black, linewidth=3, label="Exact",xlabel="t",ylabel="y" , fmt = :png)
plot!(x, y, color=:red, linewidth=2, linestyle=:dash, label="Numerical" , fmt = :png)
```

これを実行すると、きちんとグラフが出力される。
<img width="1680" alt="スクリーンショット 2019-09-10 3.10.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367076/36487114-e14d-7624-b56b-bf752bfb7b89.png">

たかだか $t \in [0,1]$だと誤差はなさそう。出力を確認したらpdfで保存しよう（pngだと画質が荒かった）。

```Julia:euler.jl
savefig("myplot.pdf")
```
で実行しているディレクトリに保存される。（こんな感じ）
<img width="1680" alt="スクリーンショット 2019-09-10 3.13.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367076/b125e80d-41eb-9bdd-e464-85c3ac6f8db9.png">



# 4. 最後に
さて、皆様の環境下でも実行できたでしょうか。やっぱりコードが動くと楽しいですね！
`Julia`には微分方程式を解くためのPkgもあるので、そちらで解いたverもこれから書いていこうと思います。

（追記）
書いたよ　→　[こちら](https://qiita.com/Mizuto_Kadowaki/items/0a1f67441568424ccb64)
Excelのリンク集をHTMLに変換するPythonスクリプト作った

# はじめに
自分のよく利用するサイトはVivaldiのスピードダイヤルに登録していますが、そこに追加するほどでもないが定期的にアクセスする必要のあるサイト（主に就活のマイページ等）がいくつかあります。Excelにリンクをまとめていたのですが、いちいちExcelを起動するのは無駄だと感じていました。

そこで、HTMLで一覧表示するページを作成してスピードダイヤルに追加しておけば、ブラウジング中にExcelを起動する必要なくリンクへ移動することができると考え、HTMLで書くことにしました。
しかし、編集する際にはExcelの方が楽であるため、「Excel→HTML変換」のプログラムを作成することにしました。

# できること
- ブラウザで開けるリンク集
- Excelで作成したリンク集をHTMLに変換（表形式）
- リンクの説明を記載
- リンクへジャンプする際に指定した文字列を１つコピー（ログインID等）

# 変換する形式
今回私の作成したPythonスクリプトでは以下の形式のExcelシートをHTMLに変換する。メモが欲しければ、これらの右隣に備考などを書くことも可能。（HTMLに反映するためには少し変更が必要）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282145/dfd100f0-8c64-a4a8-c186-a29d1284dfba.png)

変換後は以下のようなページとなる。`Qiita`をクリックすると`https://qiita.com/`にアクセスするとともに`Qiita`という文字がコピーされる。

<img width="257" alt="スクリーンショット 2019-09-10 2.33.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282145/b67a5d1b-b9e1-296c-9120-30af2870b261.png">

# 生成されるHTML
以下の形式でリンク集を作成することにした。

```html:links.html
<!DOCTYPE html>
<html links>
    <div style="margin:20px 0">
        test page<br />

        <table border="1">
          <tr>
            <th>Qiita Home</th> <th><a href="https://qiita.com/" onclick="link_copy(this)">Qiita</a></th>
          </tr>
          <tr>
            <th>Google Home</th> <th><a href="https://google.com/" onclick="link_copy(this)">Google</a></th>
          </tr>
        </table>

        <script>
            function link_copy(element){
                let range = document.createRange();
                range.selectNodeContents(element);

                let selection = document.getSelection();
                selection.removeAllRanges();
                selection.addRange(range);
                document.execCommand('copy');
            }
        </script>
    </div>
    </body>
</html>
```

# 変換器
`xlrd`というExcelを読み書きするライブラリを使用することにした。
Pythonスクリプトの書き方は非常にダサいが、なんとか変換器が完成した。

```py:converter.py
import xlrd

wb = xlrd.open_workbook('links.xlsx')
sheet = wb.sheet_by_name('Sheet1')

html_header = '<!DOCTYPE html>\n<html links>\n<div style="margin:20px 0">\n<h1>' + str(sheet.cell_value(0,0)) + '</h1><br />\n'
html_footer = ' <script>\n function link_copy(element){\n let range = document.createRange();\n range.selectNodeContents(element);\n let selection = document.getSelection();\n selection.removeAllRanges();\n selection.addRange(range);\n document.execCommand("copy");\n }\n </script>\n </div>\n </body>\n </html>'

outputpath = './links.html'
with open(outputpath, mode='w') as f:
    f.write(html_header)
    f.write('<table border="1">')
    for i in range(4, sheet.nrows):
        f.write('<tr> <th>')
        f.write(sheet.cell_value(i,0))
        f.write('</th> <th>')
        this_link = '<a href="'
        this_link += str(sheet.cell_value(i,1))
        this_link += '" onclick="link_copy(this)">'
        this_link += str(sheet.cell_value(i,2))
        this_link += '</a></th></tr>\n'
        f.write(this_link)
    f.write('</table>')
    f.write(html_footer)
print('link collection is generated.')
```

生成されたHTMLファイルをブラウザのショートカットに設定することで、ブラウジングの途中に思い立った時にページリストを確認したりアクセスできる。満足。

# おわりに
今回はデザインのしょぼいページを作成しましたが、今後慣れてきたらオシャレなページも作ってみたいと思っています。
Googleが開発してるらしい QUIC as a VPN (QBone)について (2020年更新)

# QUIC as a VPN (QBone)について
(落ちの無い話です)

<font color="Red">[追記]</font>
IETF107 (2020/03/25)において、Googleでの利用例が共有されました。それについて、記事最後に追記しました。


## QUIC as a VPN (QBone)
公式な情報はまだないが、GoogleがQUICコネクションをVPNとして利用する「<b>QUIC as a VPN (QBone)</b>」なるものを作ってるのは窺い知ることができる。

2017年6月に、GoogleでQUICの開発に携わっているIan Swett氏より「[QUIC Messages](https://docs.google.com/document/d/18acTXqwP8D8nBjhJjTtRrP1eaSjyQSojTUYjPViC1Zc/edit)」という提案書が出ている。この提案書の、提案背景の章で「<b>QUIC as a VPN (QBone)</b>」は登場する。

> Today, most production QUIC traffic is HTTP.  However, developers are actively working on running WebRTC over QUIC (aka Quartc) and using QUIC as a VPN(aka QBone) and there is a large amount of external interest in DNS over QUIC.

しかし、その詳細について語られることはなく月日は過ぎ去るのである。

(「QUIC Messages」の解説は「[QUICの信頼性のないデータグラム拡張(MESSAGEフレーム/Datagramフレーム)](https://asnokaze.hatenablog.com/entry/2018/09/23/012519)」参照)

## The MASQUE Protocol
話は少々それるが、2019年2月にはGoogleのDavid Schinazi氏より「[The MASQUE Protocol](https://tools.ietf.org/html/draft-schinazi-masque-00)」という、提案仕様が出ている。

詳細は「[HTTP/3で接続してVPNとして使うMASQUEプロトコルの提案仕様](https://asnokaze.hatenablog.com/entry/2019/03/02/144708)」こちらの通りであり、IETFで目下議論中である。

## Google quiche
GoogleのサーバやChromiumで利用されているHTTP/2, QUIC実装ライブラリの「[quiche](https://quiche.googlesource.com/quiche/)」

この中に、2019年8月に qbone というディレクトリが登場した([コミット](https://quiche.googlesource.com/quiche/+/f975eac6d917a01a1c45eb7c9f38b0e7fe0b7aed))。そう、「QUIC as a VPN (QBone)」である。

ALPN識別子として `qbone` を使うため、MASQUEとは異なるプロトコルであることがわかる (ユースケースがそもそも違いそう)。

ソースコードを眺めると、VPN的に、来たデータ(ICMP, UDP, TCPパケット)をQUICコネクション上でトンネリングさせていそうなことがわかる。

``` qbone_client_session.cc
void QboneClientSession::ProcessPacketFromNetwork(QuicStringPiece packet) {
  SendPacketToPeer(packet);
}
void QboneClientSession::ProcessPacketFromPeer(QuicStringPiece packet) {
  writer_->WritePacketToNetwork(packet.data(), packet.size());
}
```

``` qbone_server_session.cc
void QboneServerSession::ProcessPacketFromNetwork(QuicStringPiece packet) {
  string buffer = string(packet);
  processor_.ProcessPacket(&buffer,
                           QbonePacketProcessor::Direction::FROM_NETWORK);
}
void QboneServerSession::ProcessPacketFromPeer(QuicStringPiece packet) {
  string buffer = string(packet);
  processor_.ProcessPacket(&buffer,
                           QbonePacketProcessor::Direction::FROM_CLIENT);
}
```

まだツールとしては提供されてはいないが、そのうち触れるようになるかもしれない。。。

## [追記] Googleでの利用例
IETF107(2020/03/25)の、MASQUE BoFのセッション内において、GoogleでのQBone利用事例について共有がありました。

170国以上に設置されたGoogle Global CacheノードをQBoneでつないでおり、100Gbps以上のトラフィックを処理しているとのこと。

![ET6KdX5U4AEpIRF.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32425/421cf4b7-5de9-55e2-ca81-518140d08395.jpeg)

![ET6LMK8U8AES4n3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32425/51d30b9c-2707-d9e9-ae71-21034f5c8dc0.jpeg)