OmniAICreator/Qiita-1.07M huggingface dataset:
いまさらですが、WindowsのGodModeを試しました。

Windows10ではいろいろ新機能がありますが、しらない機能或いはあまり使わない機能が数多くあると思います。
私自身も何か変更をしたい場合は、Windows＋QでCortanaの検索欄に「c」などを入力してコントロールパネルを開くのは一般的な操作になっています。ほかのアプリ起動もStartメニューからではなく、Cortanaの検索欄のほうが早い気がします。

さて、表面化していない（隠れている）GodModeを試しましょう。
その１、デスクトップに右クリック⇒新規作成⇒フォルダーを選択
![image.png](https://qiita-image-store.s3.amazonaws.com/0/346425/7f84615f-3bd9-757b-8e05-3645800352c3.png)

その２、フォルダー名に下記の文字を入力します。(GodMode部分は、神様、設定管理　など変更可能です。)
>GodMode.{ED7BA470-8E54-465E-825C-99712043E01C}

![image.png](https://qiita-image-store.s3.amazonaws.com/0/346425/97a8a782-ce8d-b11c-9f21-438f8093ca27.png)

すると、下記のコントロールパネルのようなアイコンになります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/346425/1bf82329-1869-8a56-835a-890d52b7913a.png)

その３、ダブルクリックすると、コントロールパネルより操作しやすいメニューが表示されます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/346425/08e178fa-23dd-704e-4a0b-b13b3d55d50f.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/346425/b840e865-fe38-1699-24c4-4a8de344cc76.png)


などなど、どこから設定変更かはメニューをみるとなんとかできると思います。
ちょっと面白い機能ですね。

以上
「.gitignore」をコピーし損ねてGithub desktopに膨大な変更履歴があがった話


初投稿です。
初学者の私がハマった不具合の内容と原因を共有します。

###[内容]
Gitでリポジトリを作成しRailsファイルを編集していたところ、viewファイルを２~3ついじっただけでキャッシュやログのデータが１,０００件以上Github desktop上にあがってしまった。


###[経緯]
- 使用するRailsアプリケーション（仮にAとする）を`rails new A`コマンドで作成した。

- そのディレクトリとは別に空のディレクトリを作成（仮にA'とする）、そのディレクトリに`git init`をしてローカルリポジトリとした。

- Railsファイル（A)をカットアンドペーストしA’に貼り付けてA’内で作業した。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/382633/73c32564-1c87-a170-1700-2986b5c6276f.png)上の画像の様にfinderで切り取りしてAからA'にそのままRailsファイルを貼り付けた。

###[原因]![image.png](https://qiita-image-store.s3.amazonaws.com/0/382633/74dae20e-38a7-bacb-2e9f-6a864f2bcc1b.png)

実際は隠しファイルの.gitnoreは選択されていませんでした...。
.gitignore内にログやキャッシュを追跡対象から外す記述がされているので、このファイルがないとGitは全ての変更を記録してしまい、私の様に1,000件以上の変更履歴を残すことになってしまいます...。
(※因みに隠しファイルは「⌘ + shift + .(ドット)」で表示できます)

###[対応]
とりあえず、Railsディレクトリ内に「.gitignore」を作成。何を追跡対象から外すのが良いかは全く見当が付かなかったので、下記リンクからRails.gitignoreのテンプレートを使用しました。

以下、色々な.gitignoreのテンプレートが載っているリポジトリです。
https://github.com/github/gitignore 

また、.gitignoreを編集しても、既にGitが記録してしまっているものに対しては反映されません。ファイルを指定して追跡対象から外すこともできますが、私の場合キャッシュデータが膨大だった為、以下のコードでまとめて追跡対象から除外しました。

```
git rm --cached `git ls-files -i --full-name --exclude-from=.gitignore`
```

以下、参照させて頂いた記事です。

###[参考記事]
https://qiita.com/yuuAn/items/b1d1df2e810fd6b92574
https://qiita.com/koppayashi/items/fa971b641770266af9a7
コードレビューでの消耗を最小限にし、本来の目的を再度確認しに行く

# コードレビューの目的
* 品質の担保
* 知識の共有

https://プログラマが知るべき97のこと.com/%E3%82%A8%E3%83%83%E3%82%BB%E3%82%A4/%E3%82%B3%E3%83%BC%E3%83%89%E3%83%AC%E3%83%93%E3%83%A5%E3%83%BC/

> コードレビューの目的は、ただコードの誤りを修正するだけではありません。重要なのは、チーム全員に同じ知識を共有させること、またコーディングにおいて全員が守るべきガイドラインを確立することです。

# コードレビューで見たい所

* コードフォーマット
  * 余計なスペース、インデント
  * 変数名
  * メソッド名
  * ネストの深さ
  * メソッドの長さ
* 仕様を満たしているか
  * 考慮漏れはないか
* エンバグはないか
* セキュリティバグは無いか
  * SQLインジェクション 
* パフォーマンスは大丈夫か
  * 不要なループ
  * N+1 
* 良い設計か
* 分かり易いか
  * メソッドの選択

=> 人が全て見ようとすると多すぎて、大変。
   漏れが起きやすく
**これだと本来の目的が成せない**

# 人が見るところを最小限にしに行く

## 分類してみる

### ツールで担保

* コードフォーマット
  * 余計なスペース、インデント
  * 変数名
  * メソッド名
  * ネストの深さ
  * メソッドの長さ
* パフォーマンスは大丈夫か

### テストで担保

* エンバグはないか

まず、これで消耗は大分減る

### 人がレビューしたい所

* セキュリティバグは無いか
  フレームワークのお作法に乗っていれば基本大丈夫な箇所が多いが全部では無いので
* 分かり易いか
  * メソッドの選択
* 良い設計か
* 仕様を満たしているか
  * 考慮漏れはないか

# 人がレビューしたい所をさらに減らしに行きたい

## 技術力でレビューを最小にできる所

* セキュリティバグは無いか
  フレームワークのお作法に乗っていれば基本大丈夫な箇所が多いが全部では無いので
* 分かり易いか
  * メソッドの選択

# 結局レビューに時間を割きたい箇所

* 良い設計か
* 仕様を満たしているか
  * 考慮漏れはないか

これは結局 *知識の共有* に時間を割きたいという事になりそう。

## レビュイーとしての工夫

* 仕様を伝える
* やりたい事を伝える
* 設計方式を伝える
  * なぜこれを採用したのか
  * なぜあれは採用しなかったのか
Computational Optimal Transport 精読会 記録 (#3: 2.5前半)

# 背景

- 前回: [Computational Optimal Transport 精読会 記録 (#2: 2.4)](https://qiita.com/takilog/items/d0d139c405f9070a595a)は3/18に開催，今回は3/25に開催
- 職場でCOTを読んでおり，{自己満足,復習,将来のため}などの理由で記録をしている

# 今回の範囲の内容

- Kantorovich問題の双対問題について(後半)と残りの諸定理について(測度論パートは含まない)

## アンチョコ

- *coupling matrix*: $U(a, b) = \\{\mathrm{P}\in \mathbb{R}_+^{n\times m}\mid \mathrm{P} \mathbb{1}\_m = \mathbf{a}, \mathbf{P}^T \mathbb{1}\_n = \mathbf{b} \\}$

- Kantorovich problem: $L_C(\mathbf{a,b}) = \min_{\mathrm{P}\in U(\mathbf{a, b})} \langle C, P \rangle$


## 2.5 Dual Problem

- Prop2.4ではKantorovich problemの双対問題としての特徴を見ていく

### Prop 2.4

- 主張
     - $L_C(\mathbf{a,b}) = \max_{(\mathbf{f, g})\in R(C)} \langle \mathbf{f, a}\rangle + \langle \mathbf{g, b}\rangle$
     - $R(C) = \\{(\mathbf{f,g})\in\mathbb{R}^n\times \mathbb{R}^m \mid \mathbf{f \oplus g} \leq C\\}$ <font color="red">(注) 本では$\forall (i,j)$がある  
- $\mathbf{f, g}$を**Kantorovich potential**と呼ぶ

### Prop 2.4の解説(Proof)

- Lagrangian dualityから以下を議論する
    - 参考資料: http://www.eng.newcastle.edu.au/eecs/cdsc/books/cce/Slides/Duality.pdf
    - infを取った関数をmaxする操作を参考にする

- 以下のように最適化問題を変形する
    - (注イメージのみ): max (f, g)を挟むと，この項を0にして最小化するには，coupling matrixの制約条件を満たす必要がある（上げて落とす）
    - $f\oplus g = f 1_m^T + 1_n g^T$ の部分を計算するには，簡単な方法では要素ごとに分解して計算すると一致すると分かる

```math
\begin{align}
& \min_{P\geq 0} \max_{(f,g)\in R^n\times R^n} \langle C, P\rangle + \langle a - P 1_m\rangle + \langle b - P^T 1_n, g\rangle \\
& = \max_{(f,g)\in R^n\times R^m} \langle a, f\rangle + \langle b, g\rangle + \min_{P\geq 0} \langle C - f 1_m^T - 1_n g^T, P\rangle 
\end{align}
```

-  $P$に関する部分について以下が成り立つので

```math
\min_{P\geq 0} \langle Q, P\rangle = \begin{cases}
0 & \text{if} Q \geq 0\\
-\infty &\text{o/w}
\end{cases}
```

- 次の制約条件を満たさなければ最適化問題が意味のないものになる:  $\mathbf{f \oplus g} \leq C$
- これはドメイン $R(C)$の条件にほかならない


# 次回

- 2.5の後半と応用例を読み解く
よく使うGitコマンド一覧

#Gitとは
Gitはバージョン管理システム。（バージョンとは、コミットした時点のファイルやフォルダをセーブしたもの。）

#メリット
Gitを使うことで、開発しているときに、自分が何を変更したかわからなくなったり、ファイルを消したりしてしまったときに、前回のバージョンへ戻ることができることである。また、GithubやBitbucketといったリモートリポジトリと組み合わせて使うことで、チーム開発に置いて非常に効率を上げることができる。

#コマンド集

##基本コマンド
・ローカルリポジトリの作成（projectのrootで行う）

```
$ git init
```
・変更をステージに追加

```
$ git add . 
$ git add <ファイル名>
```
・変更をローカルリポジトリに追加

```
$ git commit -m "commit message"
```
・ローカルに新規ブランチを作成

```
$ git branch <新規ブランチ名>
```
・ブランチ名を変更

```
$ git branch -m <ブランチ名>
```
・ブランチの切り替え

```
$ git checkout <ブランチ名>
```
・新規ブランチを作成後、移動

```
$ git checkout -b <新規ブランチ名>
```
・リモートのブランチをローカルにコピー（ローカルに作成するリポジトリ名はリモートと異なっていてもOK）

```
$ git checkout -b <新規ブランチ名> <origin/リモートリポジトリ名>
```
・ブランチの削除

```
$ git branch -d <ブランチ名>
```
・ブランチの確認

```
$ git branch  // ローカルのブランチのみ参照
$ git branch -a  // リモートのブランチも参照
```
・ローカルで作成したブランチをリモートに登録

```
$ git push -u origin <ブランチ名>
```
・現在のGitの状態を確認

```
$ git status
```
・変更差分を確認

```
$ git diff
```
・変更履歴を確認

```
$ git log
$ git log --oneline
```
##変更の取り消し
・作業中ファイルの変更取り消し

```
$ git checkout -- .
```
・ステージしたファイルの変更取り消し

```
$ git reset HEAD .
```
・直前のコミットの取り消し

```
$ git commit --amend
$ git commit reset --head HEAD^ // --hard: 現在のワークツリーも削除
$ git commit reset --soft HEAD^ // --soft: 現在のワークツリーはそのまま
```

##リモートリポジトリとのやりとり
・設定しているリモートリポジトリを表示

```
$ git remote
```
・リモート名を登録（これ以降URLの代わりにリモート名を使用できる）

```
$ git remote add <新規リモート名> <リモートURL>
```
・リモート名を変更

```
$ git remote rename <旧リモート名> <新規リモート名>
```
・リモート名を削除

```
$ git remote rm <リモート名>
```
・リモートリポジトリへ変更を送信

```
$ git push <リモート名> <ブランチ名>
```

・リモートリポジトリからローカルリポジトリに情報を取得

```
$ git fetch <リモート名>
```
・ローカルリポジトリからコンピュータ上に情報をコピー

```
$ git merge <リモート名/ブランチ名>
```
・リモートリポジトリからコンピュータ上に情報をコピー（fetch + merge）

```
$ git pull <リモート名> <ブランチ名>
```

・リモートリポジトリからコンピュータ上にコピー（init + pull）

```
$ git clone
```

##作業中ファイルの一時避難
・作業中ファイルを一時避難

```
$ git stash
```
・一時避難中ファイルを表示

```
$ git stash list
```
・一時避難中ファイルを復元

```
$ git stash apply --index
```
・避難したファイルの削除

```
$ git stash drop --index
```

##その他
・タグの一覧表示

```
$ git tag
```
・タグの作成

```
$ git tag -a [タグ名] -m "[メッセージ]"
```
・タグをリモートリポジトリに送信

```
$ git push [リモート名] [タグ名]
```
PWAについて調べてみた

## PWAとは

"**P**rogressive **W**eb **A**pps"　「革命的な（前進）Webアプリケーション」

**ネイティブアプリケーションに近いUX**を作ることができる

## 何がうれしいの？

Webアプリケーションの手軽さをそのままにして、ネイティブアプリの利点を獲得できる

### 具体的にはこんなこと

* **Webアプリだけどホーム画面にアイコンを追加できる**
  Web App Manifesst(後述)とService Worker(後述)を用意することで、スマホやタブレットのホーム画面に起動アイコンを追加できる。

  つまりApple StoreやGoogle Play Storeから**インストールする必要がない**。
  iOSで追加しようとするとこんな感じらしい。

<img width="375" alt="無題2.png" src="https://qiita-image-store.s3.amazonaws.com/0/334906/3f40e6fe-d7ae-827d-78ef-16fd67300fc6.png">

<img width="375" alt="IMG_1154.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/334906/b8f7d8f4-e9dd-f2f5-cf9d-65da9a114c93.png">

（気づかんがな…(´・ω・`)）

  Androidだとブラウザ上に通知が出るから気づきやすくなっているそう。

* **オフラインでも動作する**
  Service Workerを利用してHTMLやその他リソース(画像、CSSファイル、JSファイルなど)をブラウザ上にキャッシュできる。そのため、オフライン環境や低速回線時でも高速にWebページを開くことができる。

* **ネイティブアプリに比べて開発コストが低い**
  ネイティブはiOS、AndroidといったようOSごとのチューニングが必要。

* **プッシュ通知**
  (iOSではまだできない模様?)

### ちなみに

ユーザーがPWAに対応していないブラウザを使っていても、サイトが見れないというようなことはない。その場合は普通のwebサイトとして表示されるだけ。

## PWAを支える技術

* **Service Worker**
  ブラウザがバックグラウンドでスクリプトを実行する仕組み。

  * バックグラウンドで動作するプログラミング可能なネットワークプロキシ Web Workerの一つ
  * DOM(Document Object Model)の操作ができない
  * Webページと異なるライフサイクル

  

* **manifest.json**
  Webアプリケーションの情報(アプリケーションの名称やアイコン)を記述する。JSON形式で記述して、HTMLファイルのhead要素に次のようにコードを追加すれば良い。
  `<link rel="manifest" href="/manifest.json">`

  

* **HTTPS**
  なんでHTTPSじゃないとダメなのかをどこかで見た気がするのだけど、失念…。

  

## PWAの価値を高めるAPI

* CSS3...GPUによるなめらかなレンダリング
* WebVR…よりImmersiveな体験 
* WebPayments...独自決裁を可能に
* **Web Assembly(WASM)**....高速な演算 (めちゃエモなので詳しく調べてしまった)
  ブラウザからアセンブリ(機械語)を実行できるようにする技術。 C/C++/Rust といったプログラミング言語で記述したコードを WebAssembly に変換して使用する。バイナリコードをブラウザから扱えるようになることで、 JavaScriptに比べてファイルサイズを大幅に小さくすることができる。 JavaScriptとの連携も可能。
  * **いつ使うか**…
    **部分的な処理の高速化をしたいとき。**
    ブラウザ上で高速な画像処理、動画処理が必要な場合とか。重たい処理をWASMで実装して、UIなどをWeb技術で実装する。
  * **コンパイル環境を作るのが面倒(らしい)**

　今後5G通信が発達してきて、ますますクライアント側のデータ処理速度は重要になるだろうから大事な技術になっていくんじゃないかなと思ったり。

閑話休題。

## 思ったこと

* 今すぐネイティブアプリに取って代わるものでもなさそう
  （iOSは特にOS側がまだ追いついていない感じ）
* PWAとしてアプリケーションを作り直すという感じではないので導入コストはとても高いわけでもなさそう




## 参考文献

WEB+DB-PRESS-Vol.103

[PWA 入門 〜iOS SafariでPWAを体験するまで〜 2018年6月版](https://qiita.com/umamichi/items/0e2b4b1c578e7335ba20) 

[PWAでウェブアプリとしてスマホのホーム画面に追加しよう](https://magnets.jp/web_design/9341/)

[進化する Web ～ Progressive Web Apps の実装と応用 ～](https://www.slideshare.net/osamum/web-progressive-web-apps?qid=9bd57d3c-69a1-4a10-b0f1-10578f6e68eb&v=&b=&from_search=2 )
Ubuntuエラー対処もろもろ

# UbuntuでGPGエラーが出た時の対処法
なにかパッケージをインストールしようとした時に、

```
E: There were unauthenticated packages and -y was used without --allow-unauthenticated
```
と出てインストール出来ない。
そして、**apt-get update**すると、**GPG error**が出てupdateも出来ない時の対処法。

https://co.bsnws.net/article/140
サイトが消えてた場合の、Internet Archive
https://web.archive.org/web/20190109044649/https://co.bsnws.net/article/140
PyTorch + LSTM で Hello World 的プログラムを実行

# 概要
RNN(LSTM) の使い方がどうしてもよくわからなかったので、ごく小さな toy program を書いてみて、使い方を確かめてみた。

# コードの概要

RNNの使い方の基本は、時系列データを与えて、次に来るデータを予測する、というものだ。
ここでは究極単純に、

```
1,2,3,4
```
という数列を与えたら、次に

```
5
```

が来ると予測するようにモデルを学習させてみる。

# 学習


```python3
import torch
import numpy as np
from itertools import chain

dict_size = 10
depth = 3
hidden_size = 6

# モデル定義
embedding = torch.nn.Embedding(dict_size, depth)
lstm = torch.nn.LSTM(input_size=depth,
                            hidden_size=hidden_size,
                            batch_first=True)
linear = torch.nn.Linear(hidden_size, dict_size)
criterion = torch.nn.CrossEntropyLoss()
params = chain.from_iterable([
    embedding.parameters(),
    lstm.parameters(),
    linear.parameters(),
    criterion.parameters()
])
optimizer = torch.optim.SGD(params, lr=0.01)

# 訓練用データ
x = [[1,2, 3, 4]]
y = [5]

# 学習
for i in range(100):
    tensor_y = torch.tensor(y)
    input_ = torch.tensor(x)
    tensor = embedding(input_)
    output, (tensor, c_n) = lstm(tensor)
    tensor = tensor[0]
    tensor = linear(tensor)
    loss = criterion(tensor, tensor_y)
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
    if (i + 1) % 10 == 0:
        print("{}: {}".format(i + 1, loss.data.item()))
```

実行すると、確かに loss が減少していくのが観察されるはずだ。
さすがにここまでモデルが単純だと LSTM でも爆速で実行できる。


```
10: 1.994105339050293
20: 1.893094778060913
30: 1.7957065105438232
40: 1.7019000053405762
50: 1.6116480827331543
60: 1.5249345302581787
70: 1.4417483806610107
80: 1.362081527709961
90: 1.2859251499176025
100: 1.2132656574249268
```

LSTM モデルの戻り値は怪しげである。

```
    output, (tensor, c_n) = lstm(tensor)
    tensor = tensor[0]
```

上の tensor の位置に、時系列の最後のセルの隠れ状態(hidden state)が入ることになる。
output, c_n に何が入るか、どうして、 `tensor[0]` するのか、は、　[PyTorchの公式ドキュメント](https://pytorch.org/docs/stable/nn.html#torch.nn.LSTM)を確認されたい。

# 推論

上のコードに続けて実行する。
(Jupyter Notebook で実行すると良いかも)

```
tensor_y = torch.tensor(y)
input_ = torch.tensor(x)
tensor = embedding(input_)
output, (tensor, c_n) = lstm(tensor)
tensor = tensor[0]
tensor = linear(tensor)
print(tensor)
print(torch.argmax(tensor))
```

実行すると、

```
tensor([[ 0.0875, -0.4316,  0.0791,  0.0485, -0.1336,  1.5148, -0.4815,  0.1055,
         -0.2639, -0.2552]], grad_fn=<AddmmBackward>)
tensor(5)
```

となり、きちんと `5` と予測できている。素晴らしい！


# 感想

Toy program の実行を通じて、PyTorch で LSTM をどうやって使えるか感触がつかめた。上の for ループの内側で同じデータを投入し続けているが、実際には毎回異なるデータをミニバッチとして入れることになる。自然言語処理では、登場する語彙に対して単語番号を付け、文章を単語番号のリストとして表現するが、上の `[1, 2, 3, 4]` 等がそれに当たると考えてもらえればよい。
TypeScript: Duplicate identifier 'LibraryManagedAttributes'. 解消法

#環境
ts-lint: 5.14.0
yarn: 1.15.2
node: v10.15.1
#エラーログ
/Users/ユーザー名/プロジェクト名/node_modules/@types/react-dom/node_modules/@types/react/index.d.ts
(2777,14): Duplicate identifier 'LibraryManagedAttributes'.


#原因
調べてみたところ、LibraryManagedAttributesの定義が
①node_modules/@types/react/index.d.ts
②node_modules/@types/react-dom/node_modules/@types/react/index.d.ts
と2箇所存在。
@types/reactの定義がyarn.lockにバージョン違いで２つ定義されていたことが原因。

#解消法
①package.jsonに"resolutions"を追加。
②yarn install実施

```package.json
  "devDependencies": {
    "@types/react": "^16.8.10",
    "@types/react-dom": "^16.8.3",
    ...
  },
  "resolutions": {
    "@types/react": "^16.8.10"
  }
```

③yarn.lockを確認してみると
"@types/react@*", "@types/react@^16.8.10":
といった形でバージョンを統一。


```yarn.lock
"@types/react-dom@^16.8.3":
  version "16.8.3"
  resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.8.3.tgz#6131b7b6158bc7ed1925a3374b88b7c00481f0cb"
  integrity sha512-HF5hD5YR3z9Mn6kXcW1VKe4AQ04ZlZj1EdLBae61hzQ3eEWWxMgNLUbIxeZp40BnSxqY1eAYLsH9QopQcxzScA==
  dependencies:
    "@types/react" "*"

"@types/react@*", "@types/react@^16.8.10":
  version "16.8.10"
  resolved "https://registry.yarnpkg.com/@types/react/-/react-16.8.10.tgz#1ccb6fde17f71a62ef055382ec68bdc379d4d8d9"
  integrity sha512-7bUQeZKP4XZH/aB4i7k1i5yuwymDu/hnLMhD9NjVZvQQH7ZUgRN3d6iu8YXzx4sN/tNr0bj8jgguk8hhObzGvA==
  dependencies:
    "@types/prop-types" "*"
    csstype "^2.2.0"
    ...
```

#参考サイト
https://stackoverflow.com/questions/52399839/typescript-duplicate-identifier-librarymanagedattributes
プログラミング学習記録42〜ハンバーガーメニューが究極にダサくなってしまったが、見やすくなったのでオーケー👍〜

##今日やったこと
- Progate Railsのレッスンで作ったアプリをCSSでざっくりレスポンシブ化する
- 前田裕二さんの「メモの魔力」に書かれているメモを共有できるWebアプリ作りに取り組む


今日はだいぶ進みました。

ユーザーの退会機能以外はほぼ終わりました。

Progateのアプリでは投稿内容を入力するフォームが１つだけなのですが、３つにしたものを作ってみました。

「メモの魔力」ではただファクトをメモするだけでなく、「ファクト→抽象化→転用」というフレームワークに従ってメモしていきます。

なので、「ファクト」「抽象化」「転用」の３つを分けて投稿できるようにするために、入力フォームを３つ作りました。

最初はめんどくさそうだな〜と思ったのですが、３つにするのは意外と簡単でした。

いじったところはビュー、コントローラ、データベースの３つだけです。

ルーティングはいじらずにできました。

コントローラで設定する処理の種類（アクション）もedit、show、new、index、、、などある程度使われるものが決まっているのもあって、そんなに難しくなかったんだと思います。

Herokuにデプロイして終わろうかなと思ったのですが、疲れたので今日はここで終わります。

明日、デプロイしてみてちゃんと動くかどうか確かめます。

ということで明日からも引き続きプログラミング学習頑張ります。

おわり
Elastic BeanstalkにSpring Bootアプリケーションをデプロイ

Spring Bootを使ったJavaアプリケーションをElastic Beanstalk（AWSのPaaS）上にデプロイする手順をざっくりおさらいします。
初投稿なので、至らないところもあるかとは思いますが、ご了承ください。

BeanstalkへのデプロイはAWSのコンソールからでもできるのですが、今回はCIツールからも実行したいので、CLI（EB CLI）を使います。

## 前提
今回はBeanstalkの設定手順を説明します。
SpringBootアプリの作成については割愛します。
ビルドツールはgradleです。

## 環境
Mac OSX10.14.3

## EB CLIのインストール
homebrewでBeanstalkのCLIをインストールします。

```
$ brew install awsebcli
```

## AWS CLIのインストール
Access KeyとSecret Access Keyの設定を保存するためにAWSのCLIもインストールします。

```
$ brew install awscli
```

## アクセスキー設定
```
$ aws configure
AWS Access Key ID [None]: {アクセスキーを入力}
AWS Secret Access Key [None]: {シークレットアクセスキーを入力}
```

## プロジェクト設定
デプロイはプロジェクトのディレクトリで行います。

```ruby:例
$ cd workspace/ebdemo/demo
```

初めにプロジェクトの設定です。

```
$ eb init
```

対話型で設定していきます。

```ruby:リージョン
Select a default region
1) us-east-1 : US East (N. Virginia)
2) us-west-1 : US West (N. California)
3) us-west-2 : US West (Oregon)
4) eu-west-1 : EU (Ireland)
5) eu-central-1 : EU (Frankfurt)
6) ap-south-1 : Asia Pacific (Mumbai)
7) ap-southeast-1 : Asia Pacific (Singapore)
8) ap-southeast-2 : Asia Pacific (Sydney)
9) ap-northeast-1 : Asia Pacific (Tokyo)
10) ap-northeast-2 : Asia Pacific (Seoul)
11) sa-east-1 : South America (Sao Paulo)
12) cn-north-1 : China (Beijing)
13) cn-northwest-1 : China (Ningxia)
14) us-east-2 : US East (Ohio)
15) ca-central-1 : Canada (Central)
16) eu-west-2 : EU (London)
17) eu-west-3 : EU (Paris)
18) eu-north-1 : EU (Stockholm)
(default is 3): 9
```

```ruby:アプリケーション
Select an application to use
1) [ Create new Application ]
(default is 1):

Enter Application Name
(default is "demo"):
Application demo has been created.
```

```ruby:プラットフォーム→SpringBootの場合はJava
Select a platform.
1) Node.js
2) PHP
3) Python
4) Ruby
5) Tomcat
6) IIS
7) Docker
8) Multi-container Docker
9) GlassFish
10) Go
11) Java
12) Packer
(default is 1): 11

Select a platform version.
1) Java 8
2) Java 7
(default is 1):
```

```ruby:SSH
Cannot setup CodeCommit because there is no Source Control setup, continuing with initialization
Do you want to set up SSH for your instances?
(Y/n): Y

Select a keypair.
1) key
2) [ Create new KeyPair ]
(default is 2): 2
```

##デプロイ
デプロイの前にアプリケーションのjarをプロジェクトルートにコピーします。

```
$ cp build/libs/demo-0.0.1-SNAPSHOT.jar .
```

デプロイします。

```
$ eb create
Enter Environment Name
(default is demo-dev):
Enter DNS CNAME prefix
(default is demo-dev):

Select a load balancer type
1) classic
2) application
3) network
(default is 2):
```

数分かかります。

##動作確認
動いてます。

```
$ curl http://demo-dev.ap-northeast-1.elasticbeanstalk.com
Hello, World!
```

##２回目以降のデプロイ
2回目以降は以下のコマンドだけでデプロイできます。
SSH、アクセスキー等設定しておけば、CIツールから自動デプロイ可能です。

```
$ gradle clean build test
$ cp build/libs/demo-0.0.1-SNAPSHOT.jar .
$ eb deploy
```

## 追記
application.propertiesに下記の設定が必要なようです。

```
server.port=5000
```
DynamoDBでランダムに出力するオミクジ的なサイトを作る

ランダムで表示するサイトを作るのが好きなのだが、前に作ったGoogle SpreadsheetとかCloud Functionsは遅いのでDynamoDBで作り変えてみた。

- [Google SpreadsheetとCloud Functionsでランダムに出力するオミクジ的なサイトを作る](https://qiita.com/usop4/items/9c00ac04497ec0dcb5ec)
- [Google Spreadsheetでランダムに出力するオミクジ的なサイトを作る(2)createTemplate編](https://qiita.com/usop4/items/1d90b4b3c4a8cc37c582)

まず、DynamoDBで適当なテーブル（ここではxxxx）を作成する。プライマリパーティションキーはid（数値）にしている。ソートキーは設定しない。

ローカルで`url_list.txt`というファイルから1行ずつ読み込み、DynamoDBに流し込む。

```py
import boto3
import json
from boto3.dynamodb.conditions import Key, Attr

dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('xxxx')

def dynamo_update(url):
    res = table.scan(
        FilterExpression=Attr('url').eq(url)
    )
    if res["Count"] == 0: # まだ未登録のURLであればput_itemする
        res = table.scan()
        cnt = res["Count"]
        table.put_item(Item={"id":cnt+1,"url":url})

with open("url_list.txt") as f:
    lines = f.readlines()
    for line in lines:
        data = line.rstrip()
        dynamo_update(data)
f.close()
```

読み出す方はLambdaで作成する。テーブルから件数を取得して、その件数からランダムな数値を取得して、get_itemする。

```py
import boto3
from boto3.dynamodb.conditions import Key, Attr
import random

def lambda_handler(event, context):

    dynamodb = boto3.resource('dynamodb')
    table = dynamodb.Table('xxxx')
    res = table.scan()
    cnt = res["Count"]
    rnd = random.randrange(cnt)

    res = table.get_item(Key={
        "id":rnd
    })

    return {
        'id':rnd,
        'url': res['Item']['url']
    }
```

これをAPI GatewayからアクセスできるようにしてJavaScriptから呼び出す。今回、このHTMLファイルもS3に置いたのだが、S3でもアクセス権限でCORSRuleを書かなければいけない。

```html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>unknown protocol</title>
  </head>
  <body>
    <script>
    const url = "https://xxxx.execute-api.ap-northeast-1.amazonaws.com/default/getRandomFromNote";
    fetch(url)
        .then(function(response) {
            return response.json();
        })
        .then(function(json) {
            location.href = json["url"];
        });
    </script>
  </body>
</html>
```

DynamoDBから件数を取得し、ランダムで表示するという仕様だが、DynamoDBから途中のデータを削除するとどうなるんだっけ？といった詰めはできてないので、あくまでサンプルということで。

肝心のパフォーマンス比較。Google Spreadsheetで作った似たような処理が1.5秒ぐらい。

<img width="866" alt="スクリーンショット 2019-03-30 19.51.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/33389/81c0cefc-82a2-6d50-2e93-6ca9ddf94483.png">

それに対してDynamoDB+Lambda+S3が1秒ぐらい。

<img width="861" alt="スクリーンショット 2019-03-30 19.45.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/33389/7980d867-d405-ff74-ba0d-44d7e4f2c2ac.png">

htmlファイルが最初にロードされる分、体感的には、もっと早い気がする。
わかばちゃんと学ぶGit使い方入門学習メモ

会社では、CVSとSVNしか使用したことがなくGitを使ってみたいと思い学習をしてみました。
学んだことをメモ

#Gitってなーに
- バージョン管理システムのこと
- バージョン管理システムには、分散型と集中型がある。

###分散型と集中型
バージョン管理システムには分散型(例：CVS、SVN)と集中型(Git、Marcurial)がある。
・分散型：リモートリポジトリから各自のPCにリポジトリを持ち作業を行う。
・集中型：リモートリポジトリをみんなで一緒に見てつかう。

分散型はコミットしても自分のPC上のリポジトリへの更新になるが、集中型はコミットすると即座にみんなが見ることができるリモートリポジトリに反映される。

##用語：Git編
- リポジトリ　　：ファイルやディレクトリの状態が保存されている場所
- コミット　　　：変更をローカルリポジトリに反映させる
- チェックアウト：指定したコミット時の状態にローカルリポジトリの状態を戻す

##用語：Github編
- Github　　　　：Gitの機能を使用したソフトウェア開発プロジェクトのためのソースコード管理サービス
- フォーク　　　：他人が作成したリモートリポジトリを自分のアカウントのリモートリポジトリへコピーすること
- クローン　　　：リモートリポジトリをローカルリポジトリに落としてくること
- プッシュ　　　：ローカルリポジトリの変更をリモートリポジトリへ反映させること
- プル　　　　　：リモートリポジトリの状態をローカルリポジトリへ反映させること
- プルリクエスト：自分がした変更を他者のリポジトリに反映してもらう依頼すること
SpringBoot+Vueなアプリケーションを構築する

# 目標

- サーバーサイドはSpring
- フロントはVue
- npmの恩恵を受けたい
- アウトプットはJarだけ

# リポジトリ

https://github.com/iwanagat85/spring-boot-vue

# 構築

### ディレクトリ構成

- [Spring Initializr](https://start.spring.io/)等で出来たSpringプロジェクト直下に`web`ディレクトリを作成
- そこに[vue-cli](https://cli.vuejs.org/)を使ってvueのプロジェクトを作成する

```bash
.
├── .gitignore
├── build.gradle
├── gradle
├── gradle.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
├── src
|   ├── main
|   └── test
└── web
    ├── public
    ├── src
    ├── .gitignore
    ├── babel.config.js
    └── package.json
```

### VueProjectの設定

- デフォルトのポートがSpringと被るので`8081`へ変更
- `build`時の出力先を`/src/main/resources/static/`に指定

```json:package.json
  "scripts": {
    "serve": "vue-cli-service serve --port 8081",
    "build": "vue-cli-service build --dest ../src/main/resources/static/",
    "lint": "vue-cli-service lint"
  }
```

### SpringProjectの設定

- 画面のリソースはVue側で自動生成するので`static`ディレクトリを`.gitignore`にまるっと登録

```:.gitignore
src/main/resources/static/
```

- リソース生成時にvue側の`build`を実行する
- `--prefix`で`npm`を実行するディレクトリを直接指定する
- `node_modules`ディレクトリが存在しないときのみ`npm install`する

```gradle:build.gradle

task npmRunBuild() {
    if (!file("${rootDir}/web/node_modules").exists()) {
        "npm --prefix ${rootDir}/web install ${rootDir}/web"
                .execute()
                .waitForProcessOutput(System.out, System.err)
    }
    "npm --prefix ${rootDir}/web run build"
            .execute()
            .waitForProcessOutput(System.out, System.err)
}

processResources {
    dependsOn npmRunBuild
}
```

- 開発中はSpringとVueを別々に起動することも考えられる。  
開発中のみ`8081`からのアクセスを許可するようCorsの設定を追加する

```kotlin:WebConfig.kt
    override fun addCorsMappings(registry: CorsRegistry) {
        registry.addMapping("/**")
            .allowedOrigins("http://localhost:8081")
            .allowedMethods("GET", "POST")
            .allowCredentials(false)
            .maxAge(3600);
    }
```

# 実行

```bash
$ ./gradlew bootRun
```

# その他

- npmのビルドが毎回走るから起動が物凄く遅い、、、
- フロントエンド作成時は`npm run serve`しながら
三種の液晶

手元にある液晶を整理してみました。

|型番|[T18SPI-2P](https://qiita.com/yamori813/items/ae66330ccbf6fe6bd5ab)|[SEL10016B](https://qiita.com/yamori813/items/bc2bebdf06517023e721)|[GMF12064ASLY](https://qiita.com/yamori813/items/fe909ed750bb94eddc39)|
|:--|:--|:--|:--|
|表示|カラー|モノ|モノ|
|サイズ|128x160|100x32|128x64|
|コントローラー|ST7735|WS0010|AVR自作|
|転送方法|SPI|USB(FTDI BITBANG)|シリアル|
|mrbgem|mruby-bsdtft|mruby-libftdi|mruby-serialport|
|入手先|aitendo|ストロベリーリナックス|Hardoff|
|入手価格|250円|1260円|300円|

![IMG_20190406_071502.jpg](https://qiita-image-store.s3.amazonaws.com/0/104066/929a728f-111b-e280-9f34-8e796fc15d3f.jpeg)

すべて[mruby-cairo](https://qiita.com/yamori813/items/6b723d1a94abcf682863)に書いて、データを転送しています。

UTF8の日本語文字列を扱うためにMRB_UTF8_STRINGを定義してmrubyをビルドするようにしてみたところmruby-serialportでのデータ送信がうまくできなくなりました。調べてみたところバイトデータの8ビット目が立つとデータが化けてしまうようです。chrメソッドで1バイトの文字列にしていたのですが、仕様のようなので下記の方法で回避しました。

```ruby
       bytestr = " "
       bytestr.setbyte(0, pat)
       sp.write bytestr
```

受信側も自分でプログラムしているので太古の7ビット送信という手も頭によぎりましたが、データが大きくなるのでやめました。

他の二つは自前のmrbgemsが配列でデータを受け取っているので、問題が起きませんでした。

ARMにも液晶つないでみました。
https://qiita.com/yamori813/items/8a721d8d5d7864088fb4

Linux方面には[LCD4Linux](https://lcd4linux.bulix.org)というプロジェクトがあるようです。
MAAS  2.5.0のDocker imageをひとまず立ち上げた時の記録

Dockerコンテナからネットワークブートをする為に動的にローカルIPを取得してやったりする当たりがわからないので
ひとまず物理マシンから直接することにしたのですがちゃんとMAAS2.5.0が簡単にデプロイできるDocker imageがあったので
メモ代わりに記録しておきます


#Docker install & 環境構築
https://qiita.com/iganari/items/fe4889943f22fd63692a

上記の記事をそのまま参考にDocker installを行います。

```
$ docker --version
Docker version 18.09.4, build d14af54266

```

ひとまずdockerが入ってる状態まで持っていきます。

次にMAASのimageをpullします

ちょうどよさそうなDocker imageがあったので使わせてもらいます
https://hub.docker.com/r/foexle/maas-server

```
$ docker pull foexle/maas-server
$ docker run --name maas  -d --tty --interactive --publish 127.0.0.1:5240:5240 foexle/maas-server
```
 http://localhost:5240 
でアクセスすればログイン画面が開かれるはずです

```
username test
password test
```
ユーザネームとパスワードは上記の通りに設定されています

versionは```MAAS version: 2.5.0 (7442-gdf68e30a5-0ubuntu1~18.04.1)```です


#TODO
PXEブートをするにはIP周りをしっかりやらないとダメなのでこんごそこら辺をまとめておきたい
Chromebookのターミナルで日本語入力

# フォントをインストールする
「源ノ角ゴシック Code JP」をダウンロードします。
適当なディレクトリに移動し、下記を実行します。

```bash
$ curl -OL https://github.com/adobe-fonts/source-han-code-jp/archive/2.011R.tar.gz
```
次に、展開しフォントディレクトリにコピーします。

```bash
$ tar zxvf 2.011R.tar.gz
```

「**source-han-code-jp-2.011R**」というディレクトリが出来るので、これをフォントディレクトリにコピーします。
root権限が必要なのでsudoを使えるようにしておいてください。

```bash
$ sudo cp -a source-han-code-jp-2.011R /etc/share/fonts
```
NOTOフォントはAPTでインストール出来ます。

```bash
# apt install fonts-noto-cjk
```

# fcitx-mozcをインストールする
インプットメソッドのmozcを使うために、fcitx-mozcをインストールします。

```bash
# apt install -y fcitx-mozc
```
systemdの設定を上書きするために、
`/etc/systemd/user/cros-garcon.service.d/cros-garcon-override.conf`
に下記を追記します。

```
Environment="GTK_IM_MODULE=fcitx"
Environment="QT_IM_MODULE=fcitx"
Environment="XMODIFIERS=@im=fcitx"
```

fcitxを起動します。

```bash
$ fcitx > /dev/null 2>&1
```
fcitxにmozcを追加します。

```bash
$ fcitx-configtool
```

自動起動するようにします。

```bash
$ fcitx-autostart
```
ABC - 069- A&B&C

#AtCoder ABC 069 A&B&C
[AtCoder - 069](https://atcoder.jp/contests/abc069)

#A問題

 - 「道路に囲まれた=外周部は除外する」となる

```java
	private void solveA() {
		int numN = nextInt();
		int numM = nextInt();

		out.println((numN - 1) * (numM - 1));
	}
```

#B問題

 - 以下の文字を生成すればよい
    - 文字列の最初の文字 ＋ 数値=文字列長-2 ＋ 文字列の最後の文字
        - 文字列長-2 = 文字列長 - 1(文字列の最初の文字) - 1(文字列の最後の文字)

```java
	private void solveB() {
		char[] wk = next().toCharArray();
		out.println("" + wk[0] + (wk.length - 2) + wk[wk.length - 1]);
	}
```

#C問題

 1. $(a_i * a_{i+1})mod4=0$ということは、$a_i$または$a_{i+1}$のどちらかは4の倍数ということ
    - 4の倍数に何をかけても4の倍数
 2. ただし例外として、2の倍数同士をかけた場合も4の倍数となる
 3. 4の倍数が数列の半分以上あれば　$(a_i * a_{i+1})mod4=0$　が成り立つ
 
なので実装は、
 1. 4の倍数の数をカウント
 2. 4の倍数ではないものの中で、2の倍数の数をカウント
 3. 2の倍数が偶数だったら、$数列長-(2の倍数の数)$　をする
 4. 2の倍数が奇数だったら、$（数列長-（2の倍数の数-1）$　をする
 5. 3または4の処理後の数列長の半分以上4の倍数があればtrue

---

||||||||
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|1|2|2|1|4|4|この数列も|
|2|2|1|4|1|4|となればよい|
|||1|4|1|4|2の倍数同士の乗算は4の倍数になるので、実質の数列はこうともとれる|

---


```java
	private void solveC() {
		int numN = nextInt();

		int[] wk = IntStream.range(0, numN).map(i -> nextInt()).toArray();

		int cnt4 = 0;
		int cnt2 = 0;
		/*
		 * 4の倍数か2の倍数かの判定
		 * 4の倍数は前後に何が来ても条件を満たす
		 * 2の倍数の場合は、2の倍数同士をかけると4の倍数となるので、
		 * 4の倍数ではない場合は組み合わせで条件を満たすものを探しておく
		 */
		for (int val : wk) {
			if (val % 4 == 0) {
				cnt4++;
			} else if (val % 2 == 0) {
				cnt2++;
			}
		}

		/*
		 * 4の倍数が0
		 * そして、
		 * 2の倍数も0　または　2の倍数が偶数ではない（組み合わせで消し込めない）
		 * 場合は無理
		 */
		if (cnt4 == 0 && (cnt2 % 2 != 0 || cnt2 == 0)) {
			out.println("No");
			return;
		}

		/*
		 * 組み合わせを考慮しなくてはいけない数
		 * 2-2の組は2*2=4となるので外す
		 *
		 * 1 2 2 4 1 4　の組を
		 * 2 2 1 4 1 4　とするために
		 *     1 4 1 4　2の倍数の組み合わせを消込む
		 *
		 * 1 2 2 4 1 4 2　の場合、2の倍数の組み合わせを消込む(2が1個残る)
		 * 2 1 4 1 4　として、4の倍数になるのか？と考える
		 */
		int targetCnt = numN - (cnt2 % 2 == 0 ? cnt2 : cnt2 - 1);

		if (targetCnt % 2 == 0) {
			out.println(cnt4 >= targetCnt / 2 ? "Yes" : "No");
		} else {
			out.println(cnt4 >= (targetCnt - 1) / 2 - 1 ? "Yes" : "No");
		}

	}
```
stm32f4-discoveryの作法 その10

#概要

stm32f4-discoveryの作法、調べてみた。
toppersをmakeするため、cfgをmakeしてみた。

#環境

debian squeeze

#cfgをdownload

https://www.toppers.jp/download.cgi/cfg-1.9.6.tar.gz

#configureする。

boostが無い。

#aptitudeでinstall

not 404でエラー

#/etc/apt/sources.lists

```
deb http://archive.debian.org/debian/ squeeze main
deb-src http://archive.debian.org/debian/ squeeze main
```

#boostをインストール

```
aptitude install libboost-dev
aptitude install libboost-system-dev
aptitude install libboost-filesystem-dev
aptitude install libboost-program-options-dev
aptitude install libboost-regex-dev
```

#再度、コンパイル

```
./configure
make
```

以上
UDPはTCPと何が違うの？

## UDPとTCPって何が違うの？
以前[TCPについてまとめた記事](https://qiita.com/tamago3keran/items/0c4535e19cd8a368b242)で、「届いたことを確認し、もし届いていなかったら送り直す」というTCPの仕組みによって、データが確実に届けられるようになっていることを学びました。

大半のアプリケーションはTCPに則って、データ送受信を行いますが、すべてがそうではありません。トランスポート層にはもうひとつ、UDPという通信プロトコルがあります。

[DNSについてまとめた記事](https://qiita.com/tamago3keran/items/eb5c1bd56a3927382c09)でも紹介したのですが、クライアントとDNSサーバが通信するときはUDPに則って行われます。今回は、UDPがTCPとどういった点で異なるかについてまとめます。

## これは何の記事か？
プログラミングしか学んでこなかったエンジニアが本を参考に、`UDP`の仕組みについて**大まか**にまとめた記事です。

**対象読者**

- プログラミングしか学んでこなかった
- UDPってなんですか？？
- TCPとUDPって何が違うんですか？

## この記事のゴール
- `UDP`が`TCP`とどういった点で異なるかを簡単に説明できる

## 全体像の把握
この記事は、トランスポート層で行われる処理のうち、`UDP`についてまとめたものになります。（赤枠の部分）

![network-OSI参照モデル.png](https://qiita-image-store.s3.amazonaws.com/0/186009/26e55634-720e-72ad-c2ca-1e1e9bb42e2d.png)

## TCPのおさらい
TCPに則った通信では、届けたいデータを特定の大きさに分割して、**クライアントとサーバがお互いに確認を取り合いながら送受信**を行います。途中で**データの取りこぼしなどがあったら再送信**することで、確実に全てのデータを送受信できる仕組みになっています。

参考: [TCPのおかげでデータが確実に届く！](https://qiita.com/tamago3keran/items/0c4535e19cd8a368b242)

このように複雑な仕組みになっているのは、データを確実に届けるためです。データを確実に届けるために、随時届いたかどうかを確認し、もし届かなかったらそのデータだけを再送信するようしているわけです。

## TCPで送信する必要のないデータも存在する
TCPはどこまでデータが届いて、どこから再送信しなければならないかを制御しているために複雑になっています。この仕組みを、**データを全て送り終わった後に受信側から受信確認応答をもらうだけ**にすれば、どこまで届いたかなど気にしなくてよくなります。

そうすればTCPの複雑さは取り除かれるのですが、問題もあります。パケットをひとつでも取りこぼしてしまったら、また全データを送受信し直さなければならなくなります。これではあまりにも非効率です。

データがいくつものパケットに分けられて送信される際は、TCPに則って通信を行った方が効率的なのです。しかし、逆を言えば、データが1つのパケットだけで十分なものだったら、TCPで通信を行わなくてもいいわけです。

このように、**1つのパケットで済んでしまうような短いデータの時**にUDPが使用されます。

## UDPが使用されるケース
### 制御用の短いデータ
DNSサーバへの問い合わせなど、制御用に行う通信は、1つのパケットで済むことが多いので、こういった場面ではUDPを使用します。

UDPにはTCPのような受信確認がないので、接続や切断のフェーズがありません。アプリケーションからデータを受け取り、UDPヘッダーを付加した後、IPに依頼して送信するだけとなります。

UDPの場合、プロトコル・スタックがエラーを検知できないので、問題になるのではと思うかもしれません。しかし、返事が返ってこないことはアプリケーションが気づけるので、アプリケーションが送り直せば問題は解決します。

### 音声や動画のデータ
音声や動画のデータを送る場合もUDPが使用されます。音楽や動画は決められた時間にデータを届けなければ、音声や映像が止まってしまうことになります。

TCPのように受信確認応答でエラーを検出して送り直していては時間もかかりますし、再生タイミングに間に合わなかったデータが届いても役に立ちません。

また音声や動画のデータが一部届かなかったとしても、一瞬途切れるか止まるだけであり、その程度なら許容できますよね。

つまり、**送り直しが必要ない**、もしくは、**送り直しても役に立たない**ときにUDPが使用されます。

## まとめ
- `UDP`は`TCP`とは違って受信確認をしないので、信頼性はないが、即時性の高い通信が行える。
- `UDP`は`TCP`とは違って、パケット１つで送信できるようなデータや、届かなくても再送する必要のないデータを届ける時に使用される。

## 参考にした本
- [ネットワークはなぜつながるのか 第２版](https://www.amazon.co.jp/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%81%AF%E3%81%AA%E3%81%9C%E3%81%A4%E3%81%AA%E3%81%8C%E3%82%8B%E3%81%AE%E3%81%8B-%E7%AC%AC%EF%BC%92%E7%89%88-%E6%88%B8%E6%A0%B9-%E5%8B%A4-ebook/dp/B077XSB8BS)

## 所感
`UDP`を理解するには、まず`TCP`を理解することが先だなと感じました。`TCP`がパケットの受信確認や再送信を行う仕組みや、その目的をわかっていないと`UDP`について学んでも、深くは理解できなのかなと思いました。
[ThinkPad T440p] synaptics製 独立タッチパッド交換

Think pad T440pのパコパコパッドにイライラが募り物理ボタンへ交換しました。

[購入したタッチパッド](https://www.amazon.co.jp/gp/product/B00XJ59C5W/ref=ppx_yo_dt_b_asin_title_o01_s01?ie=UTF8&psc=1)

![105698.jpg](https://qiita-image-store.s3.amazonaws.com/0/333756/52e0811e-6497-4634-60a5-7c231e06d1ea.jpeg)

大まかな流れはこの記事を参考にさせていただきました。
[タッチパッド交換手順参考](https://qiita.com/kexi/items/aa6b2586fa9361f258b6)

ただ私の届いたものが裏にドットのあるSynapticsのものだったので後半のDriverを充てる部分が少し違ってきます。

環境はWin10 64bitです．


私の環境では
[n10gx25w](https://www.userdrivers.com/Notebook-Tablet-PC/Synaptics-ThinkPad-UltraNav-Driver-18-0-7-57-for-Windows-7-8-8-1-x86-x64/download/)
このドライバをあてることで動作しました。

他に
[n10gx25j](http://download.lenovo.com/mobilesjp/n10gx25j.exe)(クリックするとダウンロードがはじまります。)
でも動作したのですが、当方の環境ではデスクトップアイコンをクリックすると言語が切り替わる不具合が起こりました。

n1xgx14w
n10gw27w
n10gx38w
j5gh07ww
も試してみましたが物理ボタンが動作しませんでした。

Before
![105701.jpg](https://qiita-image-store.s3.amazonaws.com/0/333756/0854e474-ac74-4f80-c43e-fa0adbec0b16.jpeg)
After
![105711.jpg](https://qiita-image-store.s3.amazonaws.com/0/333756/b2b44f14-85ef-782e-7f33-f1cba8e27940.jpeg)
ESLint v5.16.0

前 [v5.15.0] | 次 [v6.0.0]

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">ESLint v5.16.0 has been released: <a href="https://t.co/z2dnP92J8r">https://t.co/z2dnP92J8r</a><br><br>Formatters can now use rule metadata (e.g., documentation URL) in their output. This was originally designed through our RFC process: <a href="https://t.co/vWiQLGFOYB">https://t.co/vWiQLGFOYB</a></p>&mdash; ESLint (@geteslint) <a href="https://twitter.com/geteslint/status/1111844044836081664?ref_src=twsrc%5Etfw">March 30, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

ESLint `5.16.0` がリリースされました。
小さな機能追加とバグ修正が行われました。

特に問題がなければ、これが ESLint 5.x 系の最後のリリースになります。次回は ESLint `6.0.0` プレリリースの予定です。

質問やバグ報告等ありましたら、お気軽にこちらまでお寄せください。

> 🏢 [日本語 Issue 管理リポジトリ](https://github.com/eslint/eslint-jp)
> 👫 [日本語サポート チャット](https://gitter.im/eslint/eslint-jp)
> 🏢 [本家リポジトリ](https://github.com/eslint/eslint)
> 👫 [本家サポート チャット](https://gitter.im/eslint/eslint)

# 🚀 本体への機能追加

## [RFC 10]: カスタム フォーマッターからルールの定義データにアクセスできるようになりました。

従来はフォーマッターはリント結果のみにアクセスできました。しかし、各ルールのメタデータ (例えば各ルールのドキュメントへの URL) を使いたいという要望が強くあったため、これにアクセスできるようになりました。

詳細は[ドキュメント](https://eslint.org/docs/developer-guide/working-with-custom-formatters#the-data-argument)を参照ください。

## [RFC 10]: フォーマッター `json-with-metadata` が追加されました。

リント結果を、各ルールのメタデータを含む JSON 形式で出力するフォーマッターです。

# 💡 新しいルール

特になし。

# 🔧 オプションが追加されたルール

特になし。

# ✒️ `eslint --fix` をサポートしたルール

特になし。

# ⚠️ 非推奨になったルール

特になし。

[v5.15.0]: http://qiita.com/mysticatea/items/1cc0afa2a3d3aa0e2de5
[v6.0.0]: http://qiita.com/mysticatea/items/274347ff9473b26b575a
[RFC 10]: https://github.com/eslint/rfcs/tree/master/designs/2019-expose-rules-to-formatters
[#9999]: https://github.com/eslint/eslint/issues/9999
[xxxx]: http://eslint.org/docs/rules/xxxx

<!-- 
![JSCS Icon](http://jscs.info/favicon.ico) JSCS 互換ルールです。
-->
ABC - 068- A&B&C

#AtCoder ABC 068 A&B&C
[AtCoder - 068](https://atcoder.jp/contests/abc068)

#A問題

 - 問題文上は0埋めいらないので、本当は`"ABC" + numN`でもよい

```java
	private void solveA() {
		int numN = nextInt();

		out.println("ABC" + String.format("%03d", numN));
	}
```

#B問題

 - 2で何回割れるのか？
 - 一つ一つチェックするfunction()を作ったけど、、、結局のところ「N以下の2の倍数の最大値」を出せばよい
    - $N\leqq100$　なので、　${1,2,4,8,16,32,64}$　の中でN以下の最大を探すだけではある。

```java
	private void solveB() {
		int numN = nextInt();

		int res = 0;
		int index = 0;
		for (int i = numN; i > 0; i--) {
			int wk = chkB(i);
			if (res <= wk) {
				res = wk;
				index = i;
			}
		}

		out.println(index);
	}

	private int chkB(int numN) {
		int cnt = 0;
		while (numN > 0) {
			if (numN % 2 == 0) {
				numN /= 2;
				cnt++;
			} else {
				break;
			}
		}
		return cnt;
	}

```

#C問題

 - 島１から始まり、2回で島Nにたどり着けることが条件なので
    - $a_i=1$　の　$b_i$　を取得して、
    - $a_i=b_i$　かつ　$b_i=N$　となっている組が存在するかを調べればよい

 - 2回で行くという限定条件下でのコード

 1. $a_i=1$　の　$b_i$　をsetに詰める(from)
 2. $b_i=N$　の　$a_i$　をsetに詰める(to)
 3. fromの要素がtoの要素に含まれるなら2回で行ける

```java
	private void solveC() {
		int numN = nextInt();
		int numM = nextInt();

		int[][] wk = new int[numM][2];
		Set<Integer> fromSet = new HashSet<Integer>();
		Set<Integer> toSet = new HashSet<Integer>();

		for (int i = 0; i < numM; i++) {
			wk[i][0] = nextInt();
			wk[i][1] = nextInt();
			if (wk[i][0] == 1) {
				fromSet.add(wk[i][1]);
			} else if (wk[i][1] == numN) {
				toSet.add(wk[i][0]);
			}
		}
		for (Integer integer : fromSet) {
			if (toSet.contains(integer)) {
				out.println("POSSIBLE");
				return;
			}
		}

		out.println("IMPOSSIBLE");
	}
```
AWS KMSのマスターキーとデータキー 

AWSで暗号化の話しになると登場するKMSについて勉強したのでこのエントリーを書きました。
[公式のKMSドキュメント](https://docs.aws.amazon.com/ja_jp/kms/latest/developerguide/concepts.html)はKMS全般の優れたドキュメントですが、ここではマスターキーとデータキーの関係に絞って書こうと思います。

マスターキーとデータキー
---------------------

KMSの言うところのマスターキー(CMKとかカスタマーマスターキーとも呼ばれます)と、データキーって何？どんな関係なの？という点を図解します。例えばS3のサーバーサイド暗号化を例にとると、KMSを使う場合は以下のような関係になります。

![S3_SSE_with_KMS.jpg](https://qiita-image-store.s3.amazonaws.com/0/276584/e3705eb5-25a4-c055-fdc6-c8c02e8bf980.jpeg)

KMSがやってくれるのは、マスターキーの管理とデータキーの復号ということですね。データの暗号化に使うデータキーは使う側でちゃんと管理しないといけないと。

マスターキー
--------------

マスターキーの作成ですが、AWSマネージドの方法に加えて、ユーザー側で生成した暗号鍵をマスターキーとしてKMSに保管することもできるみたいです。

|![KMS_MasterKey_AWS.jpg](https://qiita-image-store.s3.amazonaws.com/0/276584/c6c28124-a3f6-0582-609d-2ab0c529aeef.jpeg)|
|:-:|

|![KMS_MasterKey_external.jpg](https://qiita-image-store.s3.amazonaws.com/0/276584/b238b823-4bb2-0c44-d293-58d06069326f.jpeg)|
|:-:|

自分で生成した秘密鍵をKMSに登録する具体的方法は[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/kms/latest/developerguide/importing-keys.html)に記載があります。RSAで暗号化してやりとりするんですねー。

データキー
---------

データキーの生成は、KMSにGenarateDataKeyリクエストをすることで行います。
![KMS_DataKey.jpg](https://qiita-image-store.s3.amazonaws.com/0/276584/78ee6ed2-9ea5-5c39-5b1a-8dd5db79e8db.jpeg)
平文データキーが不要な場合は、GenerateDataKeyWithoutPlaintextリクエストと言うのもあります。

マスターキーの権限管理
------------------

カスタマーマスターキーを使用する権限をIAMユーザーやIAMロールに付与しようとした場合、IAMのポリシーをどうのこうのしただけでは不十分で、KMSのキーポリシーでも権限を与えてあげる必要があります。KMSのキーポリシーはCMK毎に設定するCMKに対する権限のポリシーです。
具体的にどうすればいいのかは[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/kms/latest/developerguide/key-policies.html)にあります。
はてなブログの歴代一位をまとめて見れるサイトを作った

# はじめに
はてなブログのテクノロジーカテゴリをよく見ています。
今までの歴代一位がどのようなものだったか気になって一覧で見れるサイトを作りました。

https://hatena-hotentry.netlify.com/

# 使った技術
- serverlessFramework
- go
- goquery
- RealtimeDatabase
- lambda
- vue

## バッチ
はてなブログのデータを取得するスクリプトをバッチで動かしています。
はてなブログをスクレイピングするコード(go)を書き、ServerlessFrameworkを使ってlambdaにアップロードしています。
ServerlessFrameworkは `serverless.yml` にcronを定義しておけば、cloudWatchを使ったlambdaのスケジュール実行を設定してくれるのでお手軽にバッチ処理が作れます。

参考:https://dev.classmethod.jp/etc/serverless-framework-lambda-cron-execute/

スクレイピングしたデータを保存する場所としてはfirebaseのRealtimeDatabaseを使いました。

初めはCloudFirestoreの方に保存していたのですが、保存しているドキュメント数が5000近くになり、無料プランでの一日のドキュメント読み取り数が50000だったため、10回全件取得すると、その日はデータ取得ができなくなる状態になりました。
そのため、RealtimeDatabaseに乗り換えましたが、NoSQLにデータを保存する際の設計がわかっていれば、CloudFirestoreでもうまくできたような気がします。

## フロント
vueを使いました。vue-cliで雛形を作り、それをいじって作っています。
デプロイにはnetlifyを使っています。

# 最後に
goとvueを勉強するために作りましたが、こういう小さいアプリケーションを色々作っていきたい気持ちです。
文字コードについて整理する

仕事で文字コード変換について勉強する機会があったので、書いておきます。
文字コードについてはたくさん良記事があるので、新たに何か書くこともないのですが、
自分の知識の整理という意味合いで書きます。
既存だと、特にこの記事がいいと思います。
[新人さんに知ってほしい「文字コードのお話」](https://qiita.com/yuji38kwmt/items/b3a7820b4d3b544da4ff)

UnicodeとUTF-8の違いが正確に説明できる人であれば、この記事を読む必要はないです。

# 文字コードとは
JISとかUnicodeとかを漠然と文字コードと呼びがちですが、
実際のところ、文字コードというのは結構意味が広い用語なので、
厳密な話をしたいときは注意が必要です。

Wikipediaによると
> コンピュータ上で文字（キャラクタ (コンピュータ)）を利用する目的で各文字に割り当てられるバイト表現

ということらしいです。
文字コードというのは、文脈によって意味が異なっていますが、基本的には下記の二要素を指しています。
> 文字集合 ＋ 符号化方式

長い呼び方をすると、符号化文字集合と文字符号化方式なのですが、
ちょっと漢字が並びすぎていてイカついので、本記事では短い方を使います。

# 文字集合とは
文字に対して、１対１でバイト列を割り振った集合のことです。
たとえばJISだと、文字の「１」は0x31、「A」は0x41、です。
いくつか代表的なものを見ていきましょう。

## ASCII
１９６２年にアメリカで標準化された文字集合。
たった７ビットで、制御文字・数字・文字・記号が扱えます。
0x00〜0x1Fが制御文字になっています。
ASCIIで新たにシステム作るってことはないでしょうが、だいたいの文字集合のベースがASCIIなので、
文字コードについて調べると必ずASCIIから始めることになると思います。

## JIS
ASCIIだと日本語文字が表せない問題があった。
日本語向けの標準化が行われたのがJIS。
基本的な発想としては、ASCIIで使われていない箇所にカナ文字や句読点を割り振ってしまおうということで規格が作られています。
ただ一部記号でASCIIと異なっており、有名なところでいうと、ASCIIにおける/が¥になっています（0x5C）。

## Unicode
ASCIIだのJISだの各国の標準規格だと、結局国を超えた通信ができませんね。
そこで、
「世界のすべての文字を対象とした文字集合作ってやればよくね？」
という発想のもと、Unicodeが標準化されました。
英語だとアルファベット２６文字しかないですが、日本語だとひらがな５０文字、カタカナ５０文字、漢字もいれると……何文字なんだ……
漢字圏を入れただけでも文字数が大変なことになりますが、詳細は下記のWikipediaでも見てください。
世界中にたくさんある文字でも、2Byteあれば表現できると思って１９８０年代に標準化されましたが、
余裕で足らなかったので、現在は4Byte文字になっています。

[Unicode一覧](https://ja.wikipedia.org/wiki/Unicode%E4%B8%80%E8%A6%A7_0000-0FFF)

# 符号化方式
文字集合をコンピュータが利用できるデータに変換する方法のことです。
エンコードと呼ぶことの方が多い気がしますが、エンコードもまたもう少し広い用語です。

## 文字集合＝符号化方式では？
文字集合と符号化方式を別々に考えるのはなぜでしょう？
文字をあるバイト文字で表している文字集合があるのだから、
符号化方式も、その対応表に従って、１：１で扱うだけなのでは？　という疑問が浮かびました。

この疑問はたぶん「交通ルールをつくれば皆安全運転するだろう」レベルの疑問で、
実際は交通ルールはこうだが、実際に道路出てみると法律にはないルールが結構あるみたいな話なんだと僕の中では思っています。

文字集合が１：１対応だとしても、それを実装する方法は複数考えられます。
文字集合の規格を考える人々は、ANSIやJISなどの標準化団体であって、実装まで考えてくれません。
実装するのはIT技術者サイドなので、そこで問題が発生すると、特殊な符号化方式を考えたりするわけです。

なので、原理主義的に考えれば、文字集合と符号化方式をわけて考える必要はないのですが、
現実的には文字集合と符号化方式の間には乖離があり、
どの文字集合を扱っているかだけでなく、どの符号化方式で処理しようとしているかまで考えて設計すべきです。

## 符号化方式の例
有名どころだとShift-JISとか、UTF-8とか、UTF-16とかです。
（投げやり）
gitのやりなおし、特殊ケース

# Git やりなおし

について、いろいろなケースについて検索したりすると思います。

## 一般的なケース

これらはQiitaでも

* [\[Git\]コミットの取り消し、打ち消し、上書き \- Qiita](https://qiita.com/shuntaro_tamura/items/06281261d893acf049ed)
* [Gitでやらかした時に使える19個の奥義 \- Qiita](https://qiita.com/muran001/items/dea2bbbaea1260098051)

などの記事が参考になりますし、その他いろいろあります。

## ちょっと特殊なケース

これについて、気付きのあったものを記載していこうかなと。

### commit author

よくあるのは[^1]、

[^1]: [Git の Commit Author と Commiter を変更する \- Qiita](https://qiita.com/sea_mountain/items/d70216a5bc16a88ed932)

```console
$ git commit --amend --author="Tsuyoshi CHO <Tsuyoshi.CHO@Gmail.com>"
# あるいは
$ git filter-branch ...
```

系ですが、ある記事[^2]により、以下のほうが良さそうだと気付きました。

[^2]: [CommitとAuthorを修正する時は\-\-authorではなく\-\-reset\-authorを使おう \- ゆずめも](https://yuzu441.hateblo.jp/entry/2016/06/29/214535)

```console
$ git config --local user.name "Tsuyoshi CHO"
$ git config --local user.email "Tsuyoshi.CHO@Gmail.com"
$ git commit --amend --reset-author
```

※これについては [gitの自分アカウント設定\(リポジトリローカル\) \- Qiita](https://qiita.com/tsuyoshi_cho/items/7b5987683909cc2d084c) も参照

たしかに、せっかくconfigを直したんだから、その設定でリセットしてほしいですよね。

もし複数あったりしても、現在ブランチを別名を付けて`git checkout -b <another>`、その履歴を`cherry-pick`しつつ直したほうが、問題を考えなくていい分楽かもしれません。

## git lfs化

大きなファイルを入れてしまった場合、LFSにしたくて

```console
$ git filter-branch ...
```

とかで履歴改変をがんばること[^3]になりますが...、記述が面倒なので、子細はリンク先を見てください。

[^3]: [巨大なリポジトリを GitHub に移行した話 \- Qiita](https://qiita.com/ikmski/items/0faf9eae808ff29f6358)

これについて、`git lfs migrate`を使う[^4]という方法があります。
いつごろ普通に使えるようになってたのかは不明ですが。

[^4]: [Unity のプロジェクトで Git LFS を使い始めた記録 \- chienote](https://chiepomme.gitbook.io/chienote/git/unity-git-lfs)

こうすると

```console
$ git clone
$ git lfs migrate import --include-ref master --include="*.jpg"
# .gitattributesでのtrack設定がさもあったかのように履歴を改変する
```

と、改変を自動でやってくれるので、問題が発生しずらいです。
地理院地図でCSVをドラッグ＆ドロップすると表示してくれるようになったので試してみた(GTFSもいけます)

[2019年3月26日に地理院地図がアップデートされ](http://www.gsi.go.jp/johofukyu/johofukyu190326.html)、住所の入ったCSVをドラッグ＆ドロップすると地図上に表示してくれるようになったので早速試してみました。


# 使い方
まずは例として紹介されている住所が含まれるcsvを使ってみました。
データは[鈴鹿市の文化財一覧のオープンデータ](http://www.city.suzuka.lg.jp/kouhou/city/opendata/cultural_property.html)を使います。

## データを地図上に表示する

[地理院地図](https://maps.gsi.go.jp)にアクセスしてダウンロードしたデータをドラッグ＆ドロップします。
![gsi_suzuka.gif](https://qiita-image-store.s3.amazonaws.com/0/270436/94e09d96-3f59-ef12-ca7a-d8ab09e0a6a7.gif)

すると住所の行が自動で選択され、住所が一覧で表示されるので、読み込むと地図上に表示されます。

以上で読み込みは終了です。めちゃくちゃ簡単ですね！
なお、ジオコーディングには東京大学空間情報科学研究センターの[CSVアドレスマッチングサービス](http://newspat.csis.u-tokyo.ac.jp/geocode/)を用いているようです。

また、アイコンをクリックすると読み込んだデータの詳細が表示されます。
![gsi_suzuka_data 0.png](https://qiita-image-store.s3.amazonaws.com/0/270436/65659c65-2869-48b5-7404-eb84a1ce8d1b.png)

## 読み込んだデータをダウンロードする

アップデートのリリースには地図上に表示できることしか書いてなかったのですが、実はこのデータ、ダウンロードができます。
ダウンロードの方法が調べても上位にヒットしなかったため備忘録として書き残しておきます。

右上の機能→ツール→作図・ファイルをクリックし、保存したいデータにチェックを入れ、ファイルアイコンをクリックするとKMLまたはGeoJSONで保存できます。
![gsi_suzuka_download.gif](https://qiita-image-store.s3.amazonaws.com/0/270436/1e954da4-1a4f-1edb-f06a-2d933d814d6e.gif)
ダウンロードしたデータを見るとジオコーディングされた緯度経度が入っています！

# いろいろ試してみる
さて、通常の使い方はわかったので他のデータを読み込んで試してみたいと思います。


## 住所と緯度経度両方が含まれたCSV
データは[鈴鹿市のAED設置箇所一覧のオープンデータ](http://www.city.suzuka.lg.jp/kouhou/city/opendata/aed.html)を使います。
緯度経度のほうが自動で選択され、ジオコーディングを必要としない分、住所のみのデータよりも読み込みは早かったです。
![gsi_suzuka_latlon.gif](https://qiita-image-store.s3.amazonaws.com/0/270436/3839c98d-d079-7c59-759a-18465ccd8c01.gif)
いろいろ試したところ、どうやらヘッダ行で読み込む行を判断しているようです。


## ヘッダ行がないCSV
[鈴鹿市の文化財一覧のオープンデータ](http://www.city.suzuka.lg.jp/kouhou/city/opendata/cultural_property.html)を加工してヘッダ行を取り除いてみました。
ヘッダ行がないため、住所の行を自動で認識してくれないものの,住所の行を手動で設定して読み込めば正常に読み込むことができました。
![gsi_suzuka_noheader.gif](https://qiita-image-store.s3.amazonaws.com/0/270436/fa47239f-58f7-5ae8-162f-8b889782856b.gif)



## 各行がダブルクオーテーションで囲まれたCSV
[鈴鹿市の文化財一覧のオープンデータ](http://www.city.suzuka.lg.jp/kouhou/city/opendata/cultural_property.html)を加工してダブルクオーテーションで囲って読み込んでみました。

結論から言うと読み込めませんでした。
住所のダブルクオーテーションを外したら読み込めたので、住所がダブルクオーテーションで囲まれていると読み込めないようです。


## GTFSのstops.txt
データは[永井バスのオープンデータ](http://www.nagai-unyu.net/rosen/GTFS/index.html)の`GTFS(nbaux-gunma-jp).zip`を用いました。
[GTFS](https://developers.google.com/transit/gtfs/?hl=ja)は拡張子は`.txt`ですがカンマ区切りのデータです。
しかし拡張子が`.txt`のままでは読み込んでくれなかったので、`stops.csv`と名前を変えて読ませたところ表示させることができました。
ちゃんと緯度経度の行を認識して読んでくれています。
![gsi_nagaibus_stops.gif](https://qiita-image-store.s3.amazonaws.com/0/270436/2e0bfc4e-ac33-6304-0243-49346f916054.gif)



## GTFSのshapes.txt
続いて[永井バスのオープンデータ](http://www.nagai-unyu.net/rosen/GTFS/index.html)の`shapes.txt`を読んでみました。
例によって`shapes.csv`とリネームして読ませてみましたが、表示が重かったです。

markerは処理が重いので、大量のデータを表示するのには向きません。
この方法でデータを表示する時は軽めのデータにしておいたほうが良さそうです。


# まとめ
緯度経度の入ったデータを簡単に読み込むことができました。
なにより、読み込んだデータをダウンロードできるのが素晴らしいです。
サイズの大きいデータを読むには向かないですが、ちょっとした地図上での確認には十分な機能だと思います。
v-cardをクリックしたらv-dialogが開くサンプル

Vuetifyの公式サイトには、v-btnをクリックしてv-dialogを開くサンプルが掲載されています。[^1]

[^1]: https://vuetifyjs.com/ja/components/dialogs#without-activator

ここでは、v-cardをクリックしたときにv-dialogを開くサンプルを作成してみました。

長い文章を小さめのカードで表示するとき、v-cardでは省略形で表示しておき、そこをクリックしたら全文がv-dialogで表示されるようになっています。

# サンプル
CodePenで動くサンプルを作ってみました。

なお、元は単一ファイルコンポーネントとして「CardTest」を定義し、それをApp.vueで複数並べる使い方をしていました。
しかし、CodePenではそのままだとうまく動きませんので、propsで定義していたtitleとcontentをdata()に移動させてあります。

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



# ポイント
data()で定義されているdialogの値が、v-dialog要素のv-model属性にバインディングしてあります。
デフォルトではfalseなのでv-dialogは非表示です。
v-cardの方でクリックイベントを拾い dialog = true にすると、v-dialogが表示される仕掛けです。

単一ファイルコンポーネントのインスタンスごとに状態を持っているので、App内に複数のカードを並べてあっても、正しく各カードの状態を保持できます。

```vuejs
<template>
  <div class="cardtest">
    <v-card min-width="200px" height="100%" @click.stop="dialog = true">
      <v-card-title>{{ title }}</v-card-title>
      <v-divider></v-divider>
      <v-card-text>{{ shortenedContent }}</v-card-text>
    </v-card>

    <v-dialog v-model="dialog" scrollable max-width="80%">
      <v-card>
        <v-card-title>{{ title }}</v-card-title>
        <v-divider></v-divider>
        <v-card-text height="300px">{{ content }}</v-card-text>
      </v-card>
    </v-dialog>
  </div>
</template>

<script>
export default {
  name: 'CardTest',
  props: {
    title: String,
    content: String
  },
  data(){
    return {
      dialog: false
    }
  },
  computed: {
    shortenedContent: function(){
      let maxlength = 100;
      if(this.content.length <= maxlength){
        return this.content;
      }
      else{
        return this.content.substr(0,maxlength-10)+'...(続きを読む）'
      }
    }
  }
}
</script>
```