OmniAICreator/Qiita-1.07M huggingface dataset:
Windows10 HomeでもDockerの環境構築ができる ！！　WSL1 からWSL2に変更する際に出るエラー　error : 0x800701bc の解決方！　（2020年9月）



#Docker 初学者必見！！


![2020-09-22 (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/5d17e17f-dcba-5330-ad31-ad85416e2245.png)


#はじめに
###・Windows10 ユーザー
###・Dockerの環境構築をしたい
###・WSL2の設定に困っている

人に向けた、記事になります。


#公式サイト 
👉　https://docs.microsoft.com/ja-jp/windows/wsl/install-win10#enable-the-virtual-machine-platform-optional-component

![2020-09-22 (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/9b08b4d3-e825-2e03-84f3-a27c0cf0d602.png)


これにそって進めます。
（※ページの下の方にはいくつかのトラブルシューティングが記載されています。）

#Windows10 Home のバージョンを確認してください！
![2020-09-22 (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/bcb880a5-8420-485b-d8d7-31601da3403c.png)


#error : **0x800701bc** の解決方！

![2020-09-22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/c8ec82aa-40d7-3903-55cf-6ada2cca4f56.png)

同じようなエラーが出た人は、Linux kernelのupdateをしなければ、Linuxが起動しません。

そこで、GitHubで解決方を探していたところ、海外:flag_us:の方が解決していたのでその記事を掲載します。

#参考にしたGitHubのページ 
( https://github.com/microsoft/WSL/issues/5393 )
![2020-09-22 (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/42a6a4fe-d37b-16b5-31bc-a5d17525261b.png)

#:star:**要は、kernelのupdateが必要**:star:

こちらのサイトから、updateができます！！
https://docs.microsoft.com/en-us/windows/wsl/install-win10#step-4---download-the-linux-kernel-update-package

![2020-09-22 (6)_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654025/49bd6a59-7146-1222-746a-372120049bac.jpeg)

インストーラを起動させれば、解決！

これで、Linuxを起動させることができます🎉🎉🎉🎉🎉🎉

あとは、Dockerのインストーラを起動して、順に進めれば完了です:star:

###Dockerの学習に役立てばうれしいです:blush:

#引用
>GitHub ➡　https://github.com/microsoft/WSL/issues/5393
RazorPagesで1Form内の複数SubmitボタンでPostハンドラメソッドを切り分ける方法

1Form内の複数SubmitボタンでPostハンドラメソッドを切り分ける方法
環境：ASP.NET core 3.1, Visual Studio 2019

```html:Index.cshtml
<form method="post">
    <button type="submit" asp-page-handler="View">View</button>
    <button type="submit" asp-page-handler="Prev">Prev</button>
    <button type="submit" asp-page-handler="Next">Next</button>
</form>
```

```cs:Index.cshtml.cs
public class IndexPage : PageModel
{
	public void OnPostView()
	{
	}
	public void OnPostPrev()
	{
	}
	public void OnPostNext()
	{
	}
}
```

参考：

ASP.NET Core MVCで、複数ボタンを区別するには？
https://ja.stackoverflow.com/questions/47925/asp-net-core-mvc%E3%81%A7-%E8%A4%87%E6%95%B0%E3%83%9C%E3%82%BF%E3%83%B3%E3%82%92%E5%8C%BA%E5%88%A5%E3%81%99%E3%82%8B%E3%81%AB%E3%81%AF

複数ボタンのあるFormで押されたボタンを判断する
https://qiita.com/echoprogress/items/17e85ad489bddf07b540

ASP.NET Core MVC 複数ボタンのあるFormでSubmit先を変えたい
http://heinlein.hatenablog.com/entry/2018/02/21/151026
Mac で Caps Lock と Command のキーバインドを変える方法

"Karabiner" や "Hammerspoon" や "KeyHac" や "⌘英かな" などでやる方法があると思いますが、macOS X Sierra(2016-09-20リリース)で急に使えなくなるなどの事が今後起きることを避けたいので macOS の標準ぐらいでやっておくのが良いと考える。

Macで修飾キーの動作を変更する
https://support.apple.com/ja-jp/guide/mac-help/mchlp1011/mac

を参考に下記の画像のように変更できる。

![Screen Shot 2020-09-22 at 5.15.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18869/8f503e19-49b3-c6ac-603e-708b8ff3cec7.png)

```
Caps Lock
Control
Option
Command
Function
```

の挙動はデフォルトの機能で変えられる。
SQL 入門でつまずいたこと_『マンガでわかるデータベース』4章

#はじめに
『マンガでわかるデータベース』（オーム社）の4章（データベースを利用しよう-SQLの基本操作）を学習しました。この4章では、表の作り方や編集の仕方、そして「こんなSQLのフレーズを入力すれば、こういった情報を抽出したり集計したりできますよ。」ということが解説されていました。かつ、「お題のデータを引き出すためのSQLを書きなさい」といった練習問題が22問あり、SQLの文法の基礎を学ぶことができました。

この記事では、4章の中で私がつまずいたポイントについて書いていきます。
【つまずいたポイント】
・(かっこ)を使うのはどんなとき？
・「相関副問い合わせ」ではなぜ「表の別名」を使うのか？

#SQLとは
リレーショナルデータベースを操作するためのデータベース言語。
Structured : 構造化された
Query : データベースに対する命令文
Language : 言語

#(かっこ)を使うのはどんなとき？
SQL分の中で、同じ項目について（かっこ）を使っている場合と、使っていない場合がありました。
どのように使い分けているのか混乱したので、家計簿に置き換えて、下記の通りまとめました。
「金額」を例にして書いていきます。


「支出」表（金額の単位：円）

|店コード|店舗名|金額|費目|
|:---|:---|:---|:---|
|10|あ商店|1,000|食費|
|11|いスーパー|2,000|食費|
|12|う書房|1,600|雑費|
|13|えスーパー|5,000|食費|
|14|お電気|10,000|電気|

###(かっこ)を使う例
①

```
SELECT SUM(金額)
FROM 支出;
```
②

```
SELECT MAX(金額)
FROM 支出
WHERE 費用='食費'; 
```
③（1・4行目）

```
SELECT 費目,AVG(金額)
FROM 支出
GROUP BY 費目
HAVING AVG(金額)>=1500; 
```
###(かっこ)を使わない例
④

```
SELECT 金額
FROM 支出
WHERE　店舗名='あ商店'; 
```
⑤

```
SELECT COUNT(*)
FROM 支出
WHERE 金額>=1500; 
```

最初は「SELECT文のものに(かっこ)が付いているのかな？」と考えてしまいましたが、
「HAVING AVG(金額)」となっている③、「SELECT 金額」となっている④を見て
**「集計関数**（COUNT(列名),SUM(列名),AVG(列名),MAX(列名),MIN(列名)等）
　**に(かっこ)が付いている」**のだとわかりました。

#「相関副問い合わせ」ではなぜ「表の別名」を使うのか？
問い合わせの中に別の問い合わせを埋め込むことを「副問い合わせ」（サブクエリー;subquery）という。
副問い合わせ内では、副問い合わせ外で指定された表を使うことがある。（内側の問い合わせの中で外側の問い合わせの表を使う。）
これを「相関副問い合わせ」（correlated subquery）という。

本では、この相関副問い合わせを実行する際、「内側の問い合わせ」で「外側の問い合わせ中の表と同じ表」を使うために、外側で指定した表に「別名U」を与えると説明されていました。
ここで私は、なぜ別名を与える必要があるのか、理解できませんでした。

「商品」表

|商品コード|商品名|単価|
|:--|:--|:--|

「売上明細」表

|報告書コード|商品コード|個数|
|:--|:--|:--|

本の見本は↓こうでした。

```
SELECT *
FROM 売上明細 U
WHERE 個数>
(SELECT AVG(個数)
FROM 売上明細
WHERE 商品コード= U.商品コード);
```
2&6行目について、下記の書き方では不可なのでしょうか？

```
SELECT *
FROM 売上明細 
WHERE 個数>
(SELECT AVG(個数)
FROM 売上明細
WHERE 商品コード);
```
別名を使わない場合、外側からも内側からも同じ項目について問い合わせる状態になるので、
それだとコンピュータが混乱するということでしょうか？

「相関副問い合わせ　別名」「相関副問い合わせ　内側　外側」等でググってみましたが、
こちらの記事 (https://www.atmarkit.co.jp/ait/articles/1209/14/news146.html) では、
>主問合せでも副問合せでも同じ「EMP」表を使っているので、比較するために、主問合せのEMP表を「o（外側を表すouterの頭文字）」、副問合せのEMP表を「i（内側を表すinnerの頭文字）」と、別名を付けて指定しています（別名は何でも構いません）。

と説明されていました。
ここでは主問い合わせの方にも別名が付けられていました。
なるほど。方法はどうであれ、やはり別名で「区別」する必要があるようです。
わかったような、わからないような…。

今の段階ではノートにSQLを手書きしていて、実際にSQLを実行できる環境ではないので、
よけいに理解ができないのかもしれません。
この先実際にSQLを打ち込んで実行する段階に進んでから、改めて理解に努めようと思います。

#おわりに
「(かっこ)を使うのはどんなとき」は、練習問題を解いている時点では本当にわからず、Qiitaにまとめながら「集計関数に(かっこ)が付いている」ことに気づくという有様でした。集計関数の解説を読んでいる時にはわかったつもりになっていたけれど、実はまるで理解していなかったのだなぁと、情けなくなりました。

4章終わりに「SQLを利用するJavaコードの例」が参考として紹介されていましたが、現段階ではチンプンカンプン。先は長いです。コツコツ進んでいきます。

ここまで学習して、
ごちゃついた情報を整理し、視覚的にもわかりやすくまとめていくというプロセスが楽しく、
データベースを学びたいという気持ちがますます強くなりました。
5章（データベースを運用しよう）、6章（データベースの普及と活躍）についてはざっと目を通すにとどめて今は保留とし、次は『スッキリわかるSQL入門第2版ドリル222問付き！』に進みます。

#進捗記録
2020/9/15：学習スタート
2020/9/15～2020/9/21：『マンガでわかるデータベース』（オーム社） 1～4章（Qiita記事2本）

#参考
・『マンガでわかるデータベース』高橋麻奈 著　オーム社
・  [Webブラウザで気軽に学ぶ実践SQL講座（12）：高度な副問合せの構文](https://www.atmarkit.co.jp/ait/articles/1209/14/news146.html)
WordPressの利用について最低限やって欲しいと思っていること

# 前書き
某所で利用するために作成した表題の内容のメモだが、お蔵入りになったようなのでここに記す。対象としているのは個人や研究室内でウェブサイト構築のため、WordPressを利用（しようと）しているnewbie。

書きたい項目はほかにもいくつかあるけど、とりあえずはこれだけ。

# 1. 不要なファイルの削除
WordPressの導入などで設置した不要なファイルは、用が済んだら速やかに削除すること。あるいは適切なアクセス制限を行うこと。代表的だと思っているのは以下の３つ。

 * phpMyAdmin
 * phpinfo.php
 * [Search Replace DB](https://interconnectit.com/search-and-replace-for-wordpress-databases/)

phpMyAdminをWordPressの導入時にDBを作成するために導入したのだと思われるが、通常使うことは無いから、削除しておいて欲しい。
phpinfo.php の中身は ``<?php phpinfo();`` となっていて、PHP実行環境の情報が漏洩するだけで直接的な被害は無いが、このようなファイルが残っていることに管理状況を疑ってしまう。
Search Replace DBのバージョン4より前には、自動的に wp-config.php を読んでくれるという神機能があった。

また、不要なプラグインについても、無効化ではなく削除する。例えば「[FileManagerプラグインの脆弱性を利用したファイルアップロード](https://www.jpcert.or.jp/newsflash/2020090301.html)」は、プラグインが無効であっても影響を受ける。

# 2. アカウント管理の実施
  * 複数人でアカウントを使い回さないようにする（鉄則だがあまり守られてないように思える）。
  * 簡単なパスワードを利用させないよう徹底する。
  * 必要がなくなったアカウントは削除することが望ましいが、投稿した記事の所有者が変更されるため、残す場合はパスワードとメールアドレスの変更を行う。

# 3. アカウント登録内容の確認
WordPressがインストールされているサイトの wp-json/wp/v2/users にアクセスすると、登録されているユーザ名や詳細などが取得できる。[脆弱性ではなく仕様](https://core.trac.wordpress.org/ticket/49858)とのことなので、登録内容に注意する。
あるいは、設定等により wp-json/wp/v2 へのアクセスをブロックする。ブロック方法によってはプラグインなどの動作に支障が出る可能性がある。https://developer.wordpress.org/rest-api/  

# 4. 管理画面へのアクセス元IPの制限
可能であれば、 wp-login.php へのアクセス可能なIPアドレスを制限する。スマホアプリによる記事投稿などを利用していない場合は xmlrpc.php についても同様に制限する。
WordPressのユーザアカウントのパスワードを「ユーザID+生年月日」みたいなものに変更されても、影響を受けにくくできる。

# 5. WordPressおよびプラグインのアップデート
自動アップデートによる運用が望ましいが、場合によってはサイトが正常に表示されなくなる。カスタマイズを行っている場合は自動アップデートに注意が必要。検証用サイトを構築してアップデートに問題が無いかを検証してからアップデートを実施するのが定石だが、片手間に運用されているサイトだと敬遠されがち。

# 6. 自動化された定期的なバックアップの実施
WordPressの脆弱性を突かれて不正アクセスされた場合は、原則的にバックアップから復元することになる。そのため、定期的にWordPressのインストールされたディレクトリ配下とDBの内容をバックアップしておく。もしWordPressのアップデートで不具合が生じた場合にもバックアップを復元することで対応することができる。

# 7. アップロードディレクトリ上でスクリプトの実行を制限する
wp-content/uploads ディレクトリに.htaccessを設置するなどにより、PHPスクリプトの実行を制限する。これにより、不正なPHPスクリプトを uploads ディレクトリにアップロードして実行するタイプの攻撃を阻止する。
プラグインによってはこのディレクトリ内に実行ファイルを設置する場合があるため、設定の際は注意が必要。

# 8. セキュリティ用プラグインの導入
システム監査プラグイン（Wordfence Securityなど）を導入し、WordPressシステムの改ざんや不正なログインを検知できるようにする。
また、多要素認証プラグインを導入し、不正なログインを防ぐ。wp-login.php へのアクセス元IP制限が可能な場合は見送っても良いと考える。

# 9. WAF（Web Application Firewall）の導入
mod_securityなどのWAFを導入することでWordPressの未知の脆弱性に対応できる可能性がある。ただし、WAFの設定を誤るとWordPressに記事が投稿できないなど一部の機能の動作に問題が発生する。
Raspberry Pi 4 に入れた Manjaro でIPアドレスを固定する

# はじめに
自宅サーバとして Raspberry Pi 4 (8GB) を買った！
OS は Manjaro にしました。
インストールはそこそこに、まずはネットワーク設定から始める。
初めてのArch系なのでどうかなと思ったけれど、`systemd`周りは一緒らしい。

- Raspberry Pi 4 (8GB)
- Manjaro-ARM-xfce-rpi4-20.06.img.xz


# systemd でIPアドレスを固定する

[公式のWiki](https://wiki.manjaro.org/index.php?title=Networking) に詳しい説明がある。

初期状態では NetworkManager が動いていた（`systemctl list-dependencies` で確認した。）ので、無効にする。

```
$ sudo systemctl disable --now NetworkManager.service
```

IPアドレスを固定するネットワークデバイス名を確認。

```
$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.132/24 brd 192.168.1.255 scope global dynamic noprefixroute eth0
       valid_lft 222980sec preferred_lft 222980sec
    inet6 fe80::a0dd:d732:ac2a:f581/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
3: wlan0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc fq_codel state DOWN group default qlen 1000
    link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
```

有線のデバイス名は `eth0` のようだ。

`/etc/systemd/network/` 配下に `XX-*.network` という命名で設定ファイルを作成する慣習らしいので、今回は `20-wired-eth0-static.network` とした。

```
$ sudo vim /etc/systemd/network/20-wired-eth0-static.network
$ cat /etc/systemd/network/20-wired-eth0-static.network
[Match]
Name=eth0

[Network]
Address=192.168.1.22/24
Gateway=192.168.1.254
DNS=192.168.1.254
DNS=1.1.1.1
```

設定ファイルを作成したら、`systemd-networkd`を起動する。

```
$ sudo systemctl enable --now systemd-networkd.service
```

反映させるために今回は再起動したった。

```
$ sudo reboot
```

以上。

# おわりに

自宅サーバとしての用途は決めていないので、とりあえず Docker 入れて Pi-hole か unbound 入れて、内向きDNSサーバでも立てて広告ブロッカーとして運用する。
AWS Copilot でnginxを動かしてみる。

__前提__

* 環境
  * Mac OS
  * AWS CLIを使うことができる
  * Dockerがインストールされている。

## Copilot のインストール

```bash
curl -Lo /usr/local/bin/copilot https://github.com/aws/copilot-cli/releases/download/v0.1.0/copilot-darwin-v0.1.0 && \
  chmod +x /usr/local/bin/copilot && \
  copilot --help
```

## Dockerfileを用意

```
mkdir copilot
cd copilot
```

`copilot`ディレクトリの中に下記のDockerfileを作成します。

```Dockerfile
FROM nginx:alpine
EXPOSE 80
COPY . /usr/share/nginx/html
```

## copilot init
```
copilot init
```

CLI上でいくつか質問されるので下記を入力・選択しました。

```
Application name: nginx-test
Service type: Load Balanced Web Service
Service name: nginx
Dockerfile: ./Dockerfile
```

## 確認
### ブラウザ
先ほどの`copilot init`の実行結果、最終行にURLが記載されています。
ここにアクセスします。

```aws
✔ Deployed nginx, you can access it at http://nginx-Publi-64I230BK4R＊＊＊＊＊＊5852852.ap-northeast-1.elb.amazonaws.com.
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117099/31a3d23f-17ef-fb0e-fc72-32d15875d126.png)

### AWS ECS
FARGATEで先ほどのnginxが実行されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117099/2b61f3a8-145a-5c66-d590-0aeb2c96b2c8.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117099/9907a32b-6985-a822-0849-2de95e2d634c.png)


## 参考
公式：
https://aws.amazon.com/jp/blogs/news/introducing-aws-copilot/
enumを使ってリテラルをまとめる


こんにちは。
最近自分が書いているCodeの品質を上げるために日々模索中です。
最近よく思うのは stringの文言とか、identifierを直書きしたりとか、そういうのしたくないなと思うようになり、
良い書き方ないかなと考えてCode読みあさって考えてみたら良さげな実装を思いついたので、記事にしようと思いました。

## 結論
enumで定義してしまえばまとまっててわかりやすいんじゃね？

## よくある実装1
- UITableViewのidentifierとか

```swift
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! TableViewCell
    /// ...
    return cell
```

## よくある実装2
```swift
private let cellId = "hogeCell"
/// ...
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! TableViewCell
    /// ...
    return cell
```

上記のよな感じで実装するとなんかいけてないし、個人的に直書きしたくないので（よきせぬ不具合を出したくない）ので以下の実装にしてみました。

## 実装

```swift
enum IdentifierType {
    static let segueId = "hogeSegue"
    static let cellId = "fugaCell"
    static let nibId = "HogeFugaTableViewCell"
   }
```
こんな感じで定義して、

```swift 
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: IdentifierType.fugaCell, for: indexPath) as! TableViewCell
    /// ...
    return cell
```
とか

```swift
let nib = UINib(nibName: IdentifierType.nibId, bundle: nil)
hogeTableView.register(nib, forCellReuseIdentifier: IdentifierType.cellId)
```

みたいにして定義してあげれば、どこの何が定義してあるのかとてもわかりやすいし、直書きしなくてより安全なのではと思いこのような実装にしてみました。

# まとめ
今回は、さくっとできてそれなりにまとめられて、すっきりできて、より安全に、より可読性も上がるなと個人的に思い上記の実装をしてみました。

しかし、より大規模アプリとかになると上記のような実装だけだといろいろ足りないし、より広範囲でまるっとサポートしてくれたらと思うので、より安全性や品質を高めて行ったり、楽したかったりしたらR.swiftがとても優秀なのでそれ使った方が良いと思います。
あくまで上記は小規模アプリとかで、ライブラリ入れなくても良いくらいの規模感のアプリなら、上記で対応しても良さそうに思いました。

読んでいただきありがとうございました！
もっと良い実装とか他何かありましたらコメントいただけたら涙が出るくらい喜びます！！
ブログの表示高速化のためにやったこと・調べたこと

## 元記事
https://coincidence.netlify.app/post/blog-display-speed
（ブログからの転載になります。）

## 表示が遅い!!

このブログ、現状でもかなり表示が遅いのですが、本記事での取り組みをやる前はさらに遅かったです。
参考までに[Lighthouse](https://chrome.google.com/webstore/detail/lighthouse/blipmdconlkpinefehnmjammfjpmpbjk?hl=ja)のスコアをお示ししますと、Performanceスコアが32〜36点ほどでした。
この状態から以下の対応を行なったことで、50点以上を安定して取れるようになりました。正直このブログにとっては意味のない対応もありましたが、勉強の意味で残しておこうと思います。
各施策の最初には星印で効果の度合いを示しました。黒星（ぬりつぶし）が多い方が、効果があったものになります。ただしこれは、私のSPAブログ環境ではこうだった、という話ですので、設計が異なれば有効な対策も異なるということはご注意くださいませ。（大丈夫だと思いますけど）

### 施策1:APIへの問合せ回数減
**効果　★★★☆☆**

これは、トップページ(/page/1)の表示時間短縮には直接影響しない部分ですが、画面遷移時のオーバーヘッドを減らす意味で非常に役立ちました。
SPAの基本的な振る舞いとして、「情報の更新が必要であればその都度サーバーサイドに問合せ、結果を取得して表示更新する」という像があると思うのですが、WebページというよりWebアプリエンジニアの私はこの考えに縛られすぎていたようです。ページの表示、タグ一覧の表示、タグに紐づく記事一覧の表示…といった振る舞いをSPAブログにさせるために、毎回Contentfulに問い合わせをしていたのです。情報の更新はされていないにもかかわらず。
これはあまりに無駄が大きいので、ビルド実行前にContentful APIから情報を取得してjsonとして保存するスクリプトを書きました。記事数が増えてきたらまた対応を考えなければならないかもしれませんが、とりあえずは表示速度改善の意味で満足できる結果になりました。

### 施策2：コードチャンクの整理(highlight.js)
**効果　★★★★☆**

スコア向上の意味ではこれの効果が大きかったです。
Vue CLIで作成したプロジェクトは、`yarn run build --report`すると`/dist/report.html`を生成してくれます。webpackでバンドルしたコードチャンクのうちなにが重いか？を可視化してくれる素晴らしいツールです。(単体では[webpack-bandle-analyzer](https://www.npmjs.com/package/webpack-bundle-analyzer)として配布されています。有名だから今更かも。）
見ると、highlight.jsが大量のチャンクを吐き出していたので、何事かと思い調べたら、どうやら単に`require`するだけでは不要な言語パックまで引き連れてきてしまうそうです。面倒でもちゃんと`registerLanguage`した方がいいみたいね。

```javascript 
// このやり方だと重くなります
import hljs from "highlight.js";

// こうしたらマシです(ちなみにhtmlはデフォルトでハイライトしてくれるっぽい）
import hljs from "highlight.js/libs/highlight";
import javascirpt from "highlight.js/lib/languages/javascript";
import css from "highlight.js/lib/languages/css";

hljs.registerLanguage("javascript", javascript);
hljs.registerLanguage("css", css);
```

ちなみに、[最新バージョンだと`registerLanguage`がまともに動いてくれないバグ](https://github.com/MurhafSousli/ngx-highlightjs/issues/126)があるようなので、大人しくバージョンを下げて使いましょう。package.jsonを以下のとおり更新して、`yarn`もしくは`npm i`です。

```json
{
  "dependencies": {
    "highlight.js": "~9.18.1",
    ...
  }
}
```

### 施策3:トップページのプレレンダリング(prerender-spa-plugin)
**効果　★☆☆☆☆**

SPA高速化の手段の一つとして代表的なのがプレレンダリングですが、私の場合はそもそもHTMLの構造が複雑なために速度低下を招いていたわけではなさそうなので、これはあまり効果がありませんでした。また、ブログという性質上ルーティングが動的に変わるので、とりあえずよく参照されるトップページだけこの対応を埋め込みましたが、全てのブログページをプレレンダリングするのはやや設定が面倒そうな印象でした。
（ちょっと頑張ればやれなくもなさそうですが、記事数が増えるに従ってビルド時間がとんでもないことになりそうな気がしています。）
ページ数が限定されているSPAなら、やってみるのは大いにアリなのではないでしょうか。

### 施策4:ルーティングコンポーネントの非同期読み込み
**効果　★★★☆☆**

これもなかなか良い感じに速度を改善してくれました。
メインの領域はVue Routerで切り替えているのですが、どのルートにアクセスしても、直近で必要のないJSを読み込んでしまっていたようなので、とりあえずはそのルートに必要なJSだけ呼び出してもらうように設定しました。[Vue Router公式ドキュメント](https://router.vuejs.org/ja/guide/advanced/lazy-loading.html)が参考になりましたが、要するにrouterの処理を書いているファイル内のコンポーネントのimport文を、なにも考えずに書き換えれば良いです。

```javascript

// before..最初に全部読み込み
import HogeComponent from "@/components/HogeComponent.vue";

// after ..遷移時に必要に応じて読み込み
const HogeComponent = () => import("@/components/HogeComponent.vue");
```

## Nuxt.jsとかGridsome、VuePressに移行したい
施策3でプレレンダリングを試してみたとはいえ、結局のところは静的サイトジェネレータに対応した上記のライブラリを使った方がよいのでは？感が拭えない結果となりました。Lighthouseのスコアも50止まりですしね。大人しく、JAMStackな設計のベストプラクティスに従ったほうがよさそうだ、というなんともしょっぱい結論となり恐縮です。
Nuxtとか使う時はまた記事書きます。ではでは。
Rubyで割り算！ なぜ0になる？

割り算（除算）の落とし穴をはじめから丁寧に。Rubyを例に扱います。前置きも説明も非常に長いです。結論は[こちら](#to_fメソッドを使う)。

# 答えが小数になるときは要注意

たとえば「80÷100」をしたい、とします。
期待する答えは「0.8」（ないしはそれと等しい数）ですが…

```
80 / 100
=> 0
```
0が返ってきますね。なぜでしょうか？

# プログラムとはそういうもの
先ほどの計算が"整数同士の計算"とみなされているからです。「整数同士であってるじゃん」と思うのですが、整数と整数の計算は整数でしか返ってきません。

たとえば「101÷100」もそうです。答えとして「1.01」を返してほしいところですが、次のようになってしまいます。

```
101 / 100
=> 1
```

# どうやって計算するの？
期待する答えを得るためには、小数の桁まで計算に含める必要があります。「整数としてではなく、小数として計算してね！」と伝えなくてはいけないわけです。日常的には特段意識してやっていないような計算も、プログラムではこれらが違うことを意識して書いてあげる必要があります。

たとえば、次のように書けば、小数の桁も計算のうちであることを伝えることができます。

```
80.0 / 100
=> 0.8
```

と書いても良いし、

```
80 / 100.0
=> 0.8
```

と書いても良いし、もちろん

```
80.0 / 100.0
=> 0.8
```
でも良いですね。

なるほど。でも、これが変数だったら？ そういった状況に対応するためにも、次のメソッドを知っておきたいです。

## to_fメソッドを使う
Rubyで"小数"として扱いたい時に使えるのが`to_f`メソッドです。「f」はfloatの「f」、"浮動小数点数"を意味します。（こちらもまた独特の概念ですが、参考にできる記事がたくさんあるのでそちらに譲ります。）
さて、使い方ですが、数値（変数なら変数）の後に`to_f`をつけるだけです。

```
80.to_f / 100
=> 0.8
```

と書いても良いし、

```
80 / 100.to_f
=> 0.8
```

と書いても良いし、もちろん

```
80.to_f / 100.to_f
=> 0.8
```

でも良いですね。

この方法なら変数がきても大丈夫です。

```
n = 80

n.to_f / 100
=> 0.8
```

これで期待する結果が得られましたね。
数弱によるダイクストラ法証明

##はじめに
大学の学部の授業でダイクストラ法を習った時、同時に証明も一通り習いましたが帰納法と背理法を同時に扱ったりしていて数弱情報系の自分にはてんてこまいでした。
京大院試に向けて一通り復習している中でようやく腑に落ちたのでここにまとめておきます。
なお、この記事全体は記事末尾に記載した参考文献に基づいております。

##ダイクストラ法
ダイクストラ法はグラフ$G=(V,E)$のなかで始点$v_s\in V$と終点$v_t\in V$を繋ぐ経路のうち最短となる経路を求めるアルゴリズムです。
ダイクストラ法のアルゴリズムについては参考文献[データ構造とアルゴリズム]より

>```math
d(v_s)\leftarrow 0 \\ 
V-\{v_s\}に属す全ての頂点vに対してd(v)\leftarrow \infty \\
A \leftarrow \{v_s \}\\
----以下繰り返しステップ----\\
Aの中の頂点のうちdの値が最小となっているvを取り出す\\
v=v_tならd(v_t)を出力して終了\\
T(v)に属す各頂点wに対して\\
if d(w) = \infty\ then\ w をAに追加してd(w)\leftarrow d(w) + l(v, w)\\
elseif\  d(w) > d(v) + l(v, w)\ then\ d(w) \leftarrow d(v) + l(v, w) 
```

ここで$d(v)$は$v_s\rightarrow v$のそのステップにおける最短距離, $T(v)$は$v$に隣接する頂点集合です。このアルゴリズムが言いたいことは、$d$が最小となっているものをとり出し、そこから行ける頂点に対して取り出した頂点から行った場合、より短い経路で行ける時にはその行先の最短距離を更新する。そしてそれを繰り返し、$d$が最短のものとして,終点である$v_t$が取り出された場合にはその$d(v_t)$が$v_s\rightarrow \ v_t$への最短距離となっている、ということです。（と自分は理解しています。）

##ダイクストラ法の証明
上の説明の中で
>$d$が最短のものとして,終点である$v_t$が取り出された場合にはその$d(v_t)$が最短経路となっている

と説明しましたが本当にそう言えるのでしょうか？
これは以下に示す定理を証明することで示せます。
###定理
ダイクストラ法のアルゴリズムの中で$A$から取り出された任意の頂点$v$に対してその時点での$d(v)$は$v_s$から$v$までの最短距離となっている

###この定理を示したい気持ち
任意のタイミングで取り出された$v$の$d(v)$が最短距離であることを示せれば最後に$v_t$が取り出された時の$d(v_t)$が最短距離であると言えるからですね

###証明
全体の証明は帰納法を用います。
そのために$k-1$回目までに取り出された頂点$v'$については
その時点における$d(v')$はスタートからの最短距離になっていると仮定します。
次に帰納法による証明のために
$k$回目に取り出された$v$について$d(v)$がスタートからの最短距離であることを示せば良いとわかります。
それを背理法で示します。
$k$回目に取り出される$v$についてその時点での$d(v)$が最短でないと仮定し、真の最短距離を$d^* (v)$とします。
そして$d^* (v)$を満たす経路において$v$の一つ手前に存在する頂点を$w$とします。
$w$について次の二通りで場合分けをすることができます。

#####  wがk-1ステップ目までに取り出される場合
$w$が$k-1$ステップ目までに取り出される場合
$w$を経由した経路が最短であることから$k$ステップ目が来るまで$d(v)$が更新されることはない
すなわち必ず$d(v) = d(w)+l(w,v)$のまま$k$ステップ目で取り出されることになる
よって$k$ステップ目で$v$が取り出されたとき$d(v)$が最短でないことに矛盾。


##### wがk-1ステップ目までに取り出されれない場合
$k-1$ステップ目までに取り出されるもののうち、$v_s\rightarrow \ v$の最短経路上にある最も$v$に近いものを$x$として,その後に$w$, $v$が続いているものとする。
この時$w$は$v$の最短経路上に存在することから
$d(w)\leq d(w) + l(w, v) = d(v)$を満たす。
このことから$k$ステップ目における最小の$d$は$d(v)$ではなく$d(w)$であることがわかり、
よって$k$ステップ目に$v$が取り出されるという帰納法の仮定に反する。

##### 結論
以上より背理法の仮定が正しくないとわかり、$k$ステップ目で$v$が取り出された時$d(v)$は$v_s\rightarrow \ v$までの最短距離であるとわかる。
このことから$k$ステップ目での定理の成立が示され、帰納法によって定理が示される。

##まとめ
出来る限りわかりやすくしようと思いましたが逆にわかりづらくなってしまったらすみません。
また、記事を書いた経験が少ないため、駄文になってしまっていたら申し訳ありません。
訂正等ありましたらご指摘いただけますと幸いです。



##参考文献

この記事は以下の情報を参考にして執筆しました。

- データ構造とアルゴリズム 杉原厚吉　著
nuxt-i18n+vee-validateでの多言語対応

Qiita初投稿なのでよくわかってないですが
vee-validateの公式見て妙に詰まったので自分用備忘録として

# 説明しないこと
- nuxt-i18nやvee-validateのインストール方法
- vee-validateのテンプレートでの使用方法

# 環境
```
    "nuxt": "^2.14.0",
    "nuxt-i18n": "^6.15.1",
    "vee-validate": "^3.3.11",
```
## i18n設定
**~/nuxt.config.js**

```js
import i18n from './nuxt-i18n.config'
export default {
  ...
  modules: [
    ...
    ['nuxt-i18n', i18n],
  ],
```
**~/nuxt-i18n.config.js**
fileは使わずvueI18nに言語ファイルを指定する

```js
import messages from './src/locales/message'

export default {
  locales: [
    { code: 'ja', name: 'Japanese', iso: 'ja_JP' }, // fileを使って言語ファイルは読まない
    { code: 'en', name: 'English', iso: 'en-US' },
  ],
  defaultLocale: 'ja', // デフォルトの言語
  strategy: 'prefix_and_default', // URLに言語のプレフィックスを追加するかの指定
  vueI18n: {
    // 翻訳ファイルが見つからなかった場合の言語を指定
    fallbackLocale: 'ja',
    messages,  // ←各言語ファイルはここで読み込む
  },
  rootRedirect: 'ja',
  detectBrowserLanguage: {
    useCookie: true,
    cookieKey: 'i18n_locale',
  },
}
```
**~/src/locales/message.js**
言語ファイルは管理のしやすいようにページ単位で作成したものを結合
そこにvalidation用のファイルも作成

```js
import TopEn from './en/top'                  // TOPページ用
import ValidationEn from './en/validation'    // validation用

import TopJa from './ja/top'
import ValidationJa from './ja/validation'

export default {
  en: {
    ...TopEn,
    ...ValidationEn,
  },
  ja: {
    ...TopJa,
    ...ValidationJa,
  },
}
```
**~/src/locales/en/validation.js**
vee-validationのlocalesファイルを読み込んでmessagesに組み込む
カスタムルールのメッセージや変数名もここで定義(password)
既存ルールのメッセージ上書きも可能(excluded)

```js
import ValidateMessage from 'vee-validate/dist/locale/ja'

export default {
  validations: {
    fields: {
      user_name: 'ユーザ名',
      password: 'パスワード',
    },
    messages: {
      ...ValidateMessage.messages,
      password: 'パスワードの形式が正しくありません。',
      excluded: '既に使用されています。',
    },
  },
}
```
## veeValidate設定
**~/nuxt.config.js**
プラグインとして追加

```js
export default {
  ...
  plugins: [
    ...
    { src: '~plugins/validation/vee-validate' },
  ],
```
**~/src/plugins/validation/vee-validate.js**
ポイントとしてvee-validate公式のlocales設定を使用した多言語化は行わない
※言語を変更した時にエラーメッセージの再生成をしないと切り替わらないため

```js
import Vue from 'vue'
import {
  ValidationProvider,
  ValidationObserver,
  extend,
  configure,
} from 'vee-validate'

// vee-validateのすべてのルールを読み込んでexportする
import * as rules from 'vee-validate/dist/rules'
// 公式に無いカスタムルールを作成した場合はそれらも読み込む
import * as CustomRules from './custom-roles.js'

Object.keys(rules).forEach((rule) => {
  extend(rule, rules[rule])
})
Object.keys(CustomRules).forEach((rule) => {
  extend(rule, CustomRules[rule])
})

Vue.component('ValidationProvider', ValidationProvider)
Vue.component('ValidationObserver', ValidationObserver)

// locales以下のvalidation.jsで指定した定数を使用してエラーメッセージを生成する
export default function VeeValidatePlugin({ app }) {
  configure({
    defaultMessage: (field, values) => {
      values._field_ = app.i18n.t(`validations.fields.${field}`)
      return app.i18n.t(`validations.messages.${values._rule_}`, values)
    },
  })
}
```
完了！

---
nuxt.js使い始めて数日なのでこれが正しいやり方なのかはわからないですが
URLで言語切り替えてエラーメッセージが切り替わったので現状良しとする
.
UVScrollシェーダーの書き方 

# はじめに
この記事は以下のサイトの記事を参考にさせていただいてます
[https://qiita.com/Nekomasu/items/d50a4409e48ad77bc7f2]()
[https://amagamina.jp/unity-shader/]()

# 制作背景的な
そもそもUVスクロールをなぜ作ろうとしたの？
->インターンの実装で少しでも画面をにぎやかしたかったから。
以上！！！


#仕様的なもの
UnlitShaderで作成
必要プロパティ
    + テクスチャを入れるための_MainTex
    + X軸のスクロールスピードを制御する_ScrollX
    + Y軸のスクロールスピードを制御する_ScrollY
    
時間が進むごとにスクロールさせたいので定義済みの値である_Timeをスクロールの処理に追加

# 実際のコード
```shader:UVScroll.shader
Shader "Unlit/UVScroll"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
		_ScrollX("X ScrollSpeed",Range(0.0,1.0))=0.1
		_ScrollY("Y ScrollSpeed",Range(0.0,1.0))=0.2
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
			float _ScrollX;
			float _ScrollY;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                UNITY_TRANSFER_FOG(o,o.vertex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
				i.uv.x += _ScrollX * _Time;
				i.uv.y += _ScrollY * _Time;
                // sample the texture
                fixed4 col = tex2D(_MainTex, i.uv);
                // apply fog
                UNITY_APPLY_FOG(i.fogCoord, col);
                return col;
            }
            ENDCG
        }
    }
}
```
フレームワークとの付き合い方

# バックエンドフレームワークとの付き合い方について

Qiita投稿3回目です。今回はWebフレームワークを学習する際に私が心掛けていることについて説明します。

**あくまで私なりのやり方なので、本記事が必ずしも正しいわけではありません。**

## 1 学習するWebフレームワークについて軽く検索

私がWebフレームワークの学習を開始する前にまずすることは「学習するフレームワーク」について検索をすることです

あくまで検索は軽く記事を読むだけにします。公式のドキュメントやあまりに長い記事は読みません。使った感想や特徴に関して説明している記事を閲覧し学習するフレームワークについて軽い知識を付けます。

## 2 学習するフレームワークで作成された成果物について調べる

軽い知識をつけ、フレームワークの特徴についての学習を終えたら、そのフレームワークで作成されたアプリやサービスについて調べます。

実際にアプリやサービスの利用はしません。作成されたものの知名度や人気度を知ることで学習するフレームワークがマイナーかメジャーかを識別しています。

検索してもなかなかでてこない場合、「使用するフレームワーク」　使い方　と検索をして、Qiitaに記事は多くあるかを確認しています。

そのフレームワークがメジャーな場合はエラーや困難に遭遇しても必ず自分を助けてくれる情報が存在するという安心感を抱くことができます。

## 3 動画で実践開発を視聴する

次はフレームワークについてYouTubeやUdemyで検索をして、自分で良質だと感じた動画を視聴します。

YouTubeでは主に海外の人たちが積極的にフレームワークを用いた開発動画について発信しているので、そのような動画を視聴しています。説明は英語ですが、英語がわからなくてもある程度フレームワークの処理の流れや使い方について理解できるので大丈夫だと思います。

一方でUdemyでは日本人も積極的に動画を提供している印象です。Udemyの動画は大半が有料ですが、期間限定のセールで大変お求め安い価格で購入することができるので私はセール時に学習したいコンテンツについて良い動画教材だと判断できた場合購入をしています。

Udemyでの学習の場合基本的な利用方法に加えて現場での使い方などより詳しい内容の学習をすることができます。

## 4 実践開発

最後に学習したことをアウトプットするために実際に開発をします。

開発は簡単な内容のものを開発します。CRUDやAPIサーバーの開発。

分からないことやエラーが発生した場合は検索をしています。また開発都度でGitHubで他の人が作った作品をみて、作成中の作品の改善や向上をしています。

## 書籍について

私はあまりフレームワークについての書籍の購入はしません。

どうしても詳しく知りたい場合は公式ドキュメントを読みます。

<br>

以上が私のバックエンドWebフレームワークとの付き合い方です。
UnityでHTTP(GET)通信によるJSONデータ取得


たまに使うことあって、
その都度「どうだったけー？」って悩むので自分用備忘録。

UNityアセットストアから
<b>JSON Object</B>
というアセット をダウンロード

[![Image from Gyazo](https://i.gyazo.com/ed2bbfbae672e3242f348893948b8144.png)](https://gyazo.com/ed2bbfbae672e3242f348893948b8144)


プログラム中、GET通信したいタイミングに

```
StartCoroutine(connect("https://URL"));
```
を記述。

<br><br>
こんな感じ

```c#:update.cs
void Update() {
    //通信したいURLを代入
    StartCoroutine(connect("https://URL"));
}

IEnumerator connect(string url){
    WWW www = new WWW(url);
    yield return www;
    print(www.text);
    JSONObject json = new JSONObject(www.text);
    //powerというkeyのvalueを取得
    JSONObject power = json.GetField("power");
    print("power is " + power.n); ;
}

```
データハンドリング2　様々なデータフォーマットの解析

[Aidemy](https://aidemy.net/)　2020/10/11
#はじめに
　こんにちは、んがょぺです！バリバリの文系ですが、AIの可能性に興味を持ったのがきっかけで、AI特化型スクール「Aidemy」に通い、勉強しています。ここで得られた知識を皆さんと共有したいと思い、Qiitaでまとめています。以前のまとめ記事も多くの方に読んでいただけてとても嬉しいです。ありがとうございます！
　今回は、データハンドリングの二つ目の投稿になります。どうぞよろしくお願いします。

＊本記事は「Aidemy」での学習内容を「自分の言葉で」まとめたものになります。表現の間違いや勘違いを含む可能性があります。ご了承ください。

今回学ぶこと
・pandasで変換できるフォーマットの紹介
・pandasを使ったデータフォーマットの変換
・CSVファイルをグラフ化

#データフォーマットの解析
##pandasを使ったファイルの入出力
・HTML,JSON,CSV,Excelは、それぞれ、Webページ,WebAPI,データ整理など用途が異なる。これらのデータ形式について__pandasを使えば相互に変換が可能になる。__

##pandasでHTMLのスクレイピング
・基本的に、HTMLの\<h1>や\<p>などのタグ要素はBeautifulSoupでスクレイピングするが、__テーブル要素\<table>__に関しては、pandasでスクレイピングする。

##JSONについて
・JSONとは、"JavaScript Object Notation"の略で、異なるプログラミング言語のデータのやり取りをサポートする物である。
・JSONファイルの構造は基本的にはPythonの辞書型変数の構造と同じで、{key:value,}のような形で表される。

##CSVファイルについて
・CSVとは"Comma Separated Values"すなわち「カンマで区切られた値」のことである。軽量で簡単なデータ構造のため、古くからデータのやり取りなどで使われる。
・CSVファイルは「a, b, c, 」のように、値ごとに間まで区切られているだけの構造である。

##Excelについて
・Excelは言うまでもなく表計算ソフトのことである。広く使われていることから、Excelのスクレイピングができるようになるとデータ解析の幅が広がる。
・Excelの各名称について、まず、ファイルのことを__「book」__とよび、ファイル内の表のことを__「sheet」__、そのうち縦が__「column(列)」__横が__「row(行)」__であり、一つ一つの項目を__「cell」__と言う。

#データフォーマットの変換
##ファイルをDataFrameで読み込む
・先述のデータフォーマットを実際に変換していく。まず、ファイルの読み込みは、
__pd.read_データ型("ファイル名")__　で行う。例えばHTMLなら「pd.read_html()」、Excelなら「pd.read_excel()」となる。

・ファイルの書き出しは、__pd.to_データ型（"ファイル名"）__で行う。また、ここでは「pd」としているが、DataFrame型のオブジェクト「df」をHTMLファイルに書き出したいのであれば「df.to_html()」となる。

#CSVファイルのデータをグラフ化する
##グラフ化の手順
・「CSVファイルを読み込む(read_csv)」「pandasでグラフの作成」「matplotlibでグラフを描画（plt.show）」
・このうち、「pandasでグラフの作成」が新出。方法は__「df.plot()」__でOK。

```python
data=pd.read_csv("data.csv")

data.plot()
plt.show()
```

#まとめ
・pandasによって、様々なデータフォーマット間のデータのやり取りができる。
・pythonに他のデータフォーマットを読み込んだり書き出したりする時は__「pd.read_csv()」「df.to_html()」__のように表す。
・読み込んだCSVファイルは、__df.plot()__のようにしてグラフを作ることができる。

今回は以上です。最後まで読んでいただき、ありがとうございました。
データハンドリング1　データの整形とファイルの入出力

[Aidemy](https://aidemy.net/)　2020/10/11
#はじめに
　こんにちは、んがょぺです！バリバリの文系ですが、AIの可能性に興味を持ったのがきっかけで、AI特化型スクール「Aidemy」に通い、勉強しています。ここで得られた知識を皆さんと共有したいと思い、Qiitaでまとめています。以前のまとめ記事も多くの方に読んでいただけてとても嬉しいです。ありがとうございます！
　今回は、データハンドリングの一つめの投稿になります。どうぞよろしくお願いします。

＊本記事は「Aidemy」での学習内容を「自分の言葉で」まとめたものになります。表現の間違いや勘違いを含む可能性があります。ご了承ください。

今回学ぶこと
・テキストデータの変形の方法
・文字列の分割の方法
・ファイルの出入力の方法

#（一部復習）テキストデータの整形
##オブジェクトを文字列（str）に変換する
・__str(オブジェクト)__で文字列型に変換できる。

##文字列に、変数を埋め込む

```python
name="んがょぺ"
print("私は{}です".format(name)) #私はんがょぺです
```

##format()の引数に辞書型を指定したとき
・format()の文字列に含まれる{}のなかに辞書のキーを指定すると、キーの値を出力できる。

```python
dic={"name":"ヒトカゲ", "gen":1}
print("{0[name]}、君に決めた!".format(dic)) #ヒトカゲ、君に決めた！
```

##文字幅を指定する
・format()が入る{}に、以下のように指定すると、文字の幅を指定できる。
・中央に寄せる：__{:^10}.format()__
・左に寄せる：__{:<10}.format()__
・右に寄せる：__{:>10}.format()__

#文字列の分割
##分割してリストに入れる
・分割は__.split("区切る文字（記号）")__でできる。

```python
poke="フシギダネ、ヒトカゲ、ゼニガメ、ピカチュウ"
print(poke.split("、")) #["フシギダネ","ヒトカゲ","ゼニガメ","ピカチュウ"]
```

##リストを一つの文字列にする（splitの逆）
・__"つなげたい文字（記号）".join(リスト)__でつなげられる。

```python
list=["2020","10","4"]
print("-".join(list)) #2020-10-4
```

#ファイルの入出力
##ファイルを開く
・プログラム上でファイルを扱いたいとき（例えばWebから取得したデータファイル）は
__open(ファイル名,モード)__で開くことができる。
・モードは、書き込み可能な「"w"(上書き)」「"a"(追記)」、読み込み可能な「"r"」、読み込みも書き込みも可能な「"r+"」がある。

##ファイルを閉じる
・ファイルを開いたら、必ず閉じなければならない（処理が重くなるため）。
・__ファイル.close()__で閉じることができる。

##ファイルに書き込む
・__f.write("内容")__で書き込める。
・"w"モードの場合、この「内容」で上書きされてしまうので注意。

##ファイルを読み込む
・ファイルのモードが"r"または"r+"になっているとき、__f.read()__で読み込める。
・一行だけ読み込みたい時はf.readline()を使う。

##ファイルの開閉を自動で行う
・__with open("ファイル名","モード")as f:__ のように、with文を使えば自動でファイルを閉じてくれるようになる。そのため、実務では普通with文を使ってファイルを扱う。

```python
#read.txtをwith文で読み込む
with open("read.txt","r") as f:
    f.read()
#text.txtをwith文で上書き
with open("text.txt","w") as f:
    f.write("私はんがょぺです")
```

#まとめ
・__.format()__で文字列の{}に文字を埋め込める。埋め込む文字は辞書型やリスト型でも可能。
・{}のなかで__:^10__などとすれば、文字を幅寄せできる。
・__split()__で文字列を分解できる。
・__open()__でファイルが開ける。__close()__でファイルを閉じ、書き込むのは__.write()__、読み込むのは__read()__で行える。
・ファイルを扱う時は__with文__の中で行うことで、閉じる必要がなくなるので便利。

今回は以上です。最後まで読んでいただき、ありがとうございました。
ubuntuでホームディレクトリを残してクリーンインストール

#Ubuntuのクリーンインストールがしたい
アアッ環境ぶっ壊れた！！
ホームディレクトリは残して環境だけ初期化したい。
そんなときに読んでください。

#必要なもの
ubuntuのブータブルメディア

#環境
ubuntu 18.04

#手順
普通にインストーラーから起動し、普通にここまで進めます。
インストールの種類でそれ以外を選択してください。
![install.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196598/b6a3791a-cc20-fe8b-475b-a7eafb718f44.png)

そのまますすめるとubuntuが入ったディスクを探してください。
こんな感じになっています。
![install2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196598/08d6e0ed-e702-f657-eefa-6f400bce59df.png)

そしてubuntuのパーティションを選択し、マウントポイントを元と同じように/に設定します。
**ここでパーティションの初期化にはチェックを入れずにおいておきます。←重要！**
![install3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196598/cb201f29-88fa-849b-60cf-6dd066fefebe.png)

そのままインストールを進めましょう。

![install4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196598/ac7d705c-af29-22a3-2103-39e823ba646f.png)

次起動すると、ホームディレクトリは残ったまま環境はクリーンインストールされています。
getsとgets.chompの違いについて(改行以外)

インターネットに掲載されているドリル問題を解いていたときにrubyの```gets```と```gets.chomp```の違いについて新たな発見があったためアウトプットして行きます！

# 結論
改行は１文字に含まれる！
は？っ思った方もいらっしゃるでしょう。私にとっては新たな発見だったのです...。
以下のコードを例にみてみます。

```ruby:ruby.rb
str = gets
puts str.length
```
getsメソッドを使用しているためターミナルが入力待ちの状態になります。
そこで'abc'と入力すると４と出力されます。
てっきり３が返ってくると思っていた私は「なぜ！！？？？？」とプチパニック状態に笑
もしかしてと思い```gets.chomp```で同じことを行うと予想通り3と返ってきました。

# 最後に
今までは``chomp``をつけることで改行しないんだよな〜くらいの認識でしかありませんでした。
返り値が変わってくるというのは新たな発見でした。
```length```メソッドでは改行だけではなく空白も１文字としてカウントされますが、なかなかその感覚に慣れておらず、変な感じがしてしまいます。これは慣れなのでしょうかね？
Reactで自動整形しようと思った時にハマったこと【VSCode】


# はじめに

最近投稿を始めた[Tutu](https://twitter.com/padde_cross)です。
**VSCode**で**EsLint**、**Prettier**を使用して自動整形しようと思ったのですが、チュートリアルを読んでもなかなか適用されませんでした。
その時の自分の解決策を備忘録として残しておきます。




#原因
以下の画像の「JavaScript React」という部分が「JavaScript」になっていたため**React**の書き方である、**jsx**,**tsx**内で適用されなかっただけだった。
![スクリーンショット 2020-10-11 23.17.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360479/677f77ab-d9d8-4b04-5013-542922ff8447.png)


# 解決策
該当部分をクリックして出てくる部分で下記画像の「Auto Detect」を選択し、「JavaScript React」と入力するだけ

※このままだと選択時のファイルにしか適用されないので、「.js」拡張子全体に適用したい場合は「Configure File Association for '.js'...」を選択後、同様の操作を行う


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360479/909a2128-4fe4-7a88-a4d5-f051a9ac1a5e.png)

# 最後に
同じような現象でハマってしまっている方のために一応今回このような記事を投稿しましたが、初歩的すぎてあまり役に立たないような気がします....w
WSL2 + Ubuntu 20.04 LTS環境にVivadoをインストール


https://qazsedcftf.blogspot.com/2020/08/windows-wsl-vivado.html
を参考に試してみました。

## 必要なファイルのダウンロード

https://japan.xilinx.com/support/download.html
上記のページからVivado Design Suite-HLx Editionの
「Linux用自己解凍型ウェブインストーラー」をダウンロードします。
ダウンロードしたBINファイルは、${HOME}/downloadの下に置くことにします。

※ダウンロードするためにはXilinxのアカウント登録が必要になります。

## GUIの設定

https://astherier.com/blog/2020/08/run-gui-apps-on-wsl2
を参考にWSL2 + Ubuntu 20.04上でGUIが起動するように準備します。

### Windows側の設定

まず、Windows上にXサーバ（VcXsrv）をインストールします。
インストールが終わったらXLaunchを開き、起動オプションを以下のように設定します。

* Display Numberに「-1（自動）」
* Additional parameters for VcXsrvに「-ac -nowgl」

※各種パラメータの意味は、
　https://sourceforge.net/p/vcxsrv/wiki/Home/ に記載があります。

次に、Windowsのスタートアップに上記設定ファイルを登録しておきます。
Save ConfigurationボタンでVcXsrvの設定ファイル（config.xlaunch）を生成し、
Win+Rで「shell:startup」と打つと開くフォルダに設定ファイルを保存します。

また、Windowsのファイアウォールの設定で、
「VcXsrv windows xserver」のパブリックアクセスを許可しておきます。

### WSL2側の設定

WSL2側（Xクライアント）からWindows（Xサーバー）のIPアドレスやディスプレイ番号を指定する必要があります。
これらは、DISPLAYという環境変数に.bashrc等で設定しておきます。

```bash:.bashrc
export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}'):0
```

## インストール

以下の手順でインストールを行います。

```bash

# インストーラの抽出
./Xilinx_Unified_2020.1_0602_1208_Lin64.bin --noexec --target installer

# 認証トークンの生成
# 途中でUser ID（Xilinxアカウントのメールアドレス）とパスワードの入力が必要
./installer/xsetup -b AuthTokenGen

# 設定ファイルの生成
# Select a Product from the listでVivado (2) を選択
# Select an Edition from the listでWebPACK (1) を選択
./installer/xsetup -b ConfigGen

# インストール
sudo ./installer/xsetup --agree XilinxEULA,3rdPartyEULA,WebTalkTerms --batch Install --config ${HOME}/.Xilinx/install_config.txt
```

expectコマンドを利用して、上記の手順を自動で実行するスクリプトを作成しました。
第1引数の「user id」にはXilinxアカウントのメールアドレスを、
第2引数の「password」にはXilinxアカウントのパスワードを設定します。

※デフォルトでは/xools/Xilinx以下にVivadoのインストールを行うため、
　sudo権限での実行が必要になります。

```bash:${HOME}/download/install.sh
#!/bin/bash

if [ $# -ne 2 ]; then
    echo "usage: installer.sh <user id> <password>"
    exit 1
fi

USER=${1}
PASS=${2}

./Xilinx_Unified_2020.1_0602_1208_Lin64.bin --noexec --target installer

expect -c "
set timeout 60
spawn ./installer/xsetup -b AuthTokenGen
expect \"User ID:\"
send \"${USER}\n\"
expect \"Password:\"
send \"${PASS}\n\"
expect eof
"

expect -c "
set timeout 60
spawn ./installer/xsetup -b ConfigGen
expect \"Please choose:\"
send \"2\n\"
expect \"Please choose:\"
send \"1\n\"
expect eof
"

./installer/xsetup --agree XilinxEULA,3rdPartyEULA,WebTalkTerms --batch Install --config ${HOME}/.Xilinx/install_config.txt
```

## 実行

以下の手順でVivadoのGUIが起動することを確認します。

```bash
source /tools/Xilinx/Vivado/2020.1/settings64.sh
vivado
```
よく使うRailsコマンドの省略形一覧

Rails on Rails開発でコマンドラインを叩く中、その便利さ故に省略形を使うことが多かったので、今回はよく使うものを一覧化して紹介いたします。

#省略できる単語一覧
console → c
destory → d
generate → g
server → s
test → t

#使用例
Railsサーバ起動

```ruby:rails_server.rb
#省略なし
rails server
#省略あり
rails s
```

Railsコンソール起動

```ruby:rails_console.rb
#省略なし
rails console
#省略あり
rails c
```

テスト実行

```ruby:test.rb
#省略なし
rails test
#省略あり
rails t
```

コントローラ生成

```ruby:generate_controller.rb
#省略なし
rails generate controller コントローラ名（複数形） アクション名
#省略あり
rails g controller コントローラ名（複数形） アクション名
```

モデル生成

```ruby:generate_model.rb
#省略なし
rails generate model モデル名（単数形） カラム名:型
#省略あり
rails g model モデル名（単数形） カラム名:型
```

コントローラ削除

```ruby:destroy_controller.rb
#省略なし
rails destroy controller コントローラ名（複数形）
#省略あり
rails d controller コントローラ名（複数形）
```

モデル削除

```ruby:destroy_model.rb
#省略なし
rails destroy model モデル名（単数形）
#省略あり
rails d model モデル名（単数形）
```
#最後に
Ruby on Railsの開発では省略形のコマンドを使用することにより、ターミナルに文字を打ち込む時間を短縮することが出来ます。
一回あたりでは大した差にはなりませんが、Rails開発ではコマンドを打つことが多いので、塵も積もれば山となり、最終的には大きな時間短縮になると思います。
キーワードで勉強しよう！ - クラウドコンピューティングとAWSについて

##クラウドコンピューティング
ネットワーク・サーバ・データベースなどの機能をクラウド上で提供して最も早くインプラを構築できる記述。
インプラを構築するのに発生した莫大な費用コストや人的資源を削減できるし、最初の使用以降にもベンダーが管理とアップデートしてくれるため、使用者のインプラ運用難易度を下げてくれる。

##クラウドコンピューティングの頂点
・すでに構築されている環境を借りるため、コスト低いかつ導入速度が速い。
・最初の構築コストや管理費が発生しない。（使った分だけ料金がかかる）
・インターネットに接続されていれば、パソコン、タブレット、スマートフォンなどデバイスを問わない。
・システムを提供するプロバイダーが一元管理しているので、セキュリティやシステムのアップデートが自動で行われる（保安対策を気にする必要がない）

##クラウドコンピューティングの種類
・OS、ハードウェア、ネットワークのみクラウドから提供するIaaS（Infrastructure as a Service）→　コンピュータ本来の機能を提供
・IaaSの機能とミドルウェアをクラウドから提供するPaaS（Platform as a Service）→　WindowsなどのOSまで提供
・PaaSの機能とアプリケーションもクラウドから提供するSaaS（Software as a Service）→　起動可能なプログラム単位まで提供

##AWS(Amazon Web Service)
AWSはアマゾンから提供するクラウドファンディング

##参考
[参考１](https://www.tramsystem.jp/voice/voice-2729/)
[参考２](https://www.skyarch.net/proactive/cloud/aws/aboutaws_01.html)
FTサーバとは？

## 勉強前イメージ

全然思い浮かばない。。。
なんかのミドルウェア専用のサーバ的な？webサーバと同じ立ち位置？

## 調査

### FTサーバとは？

FTははFault Tolerant(耐障害性)の略
サーバ製品のうちすべての部品を二重化し、どこかで障害が起きても全体が停止しないように設計されたサーバ

CPU・メモリ、またサーバの部品もすべて二重化されている。
HDDはRAID1でミラーリングになっている。
![2020-10-08Untitled Diagram.drawio - diagrams.net - Google Ch.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/5aa36e98-1b13-ac49-ba7c-205f46c96795.png)


### クラスタ構成とFTサーバの違いは？

よくクラスタ構成と比較されるが違いは
`FTサーバ` : サーバ単体での可用性が向上する
`クラスタ構成` : システムでの可用性が向上する

FTサーバは、`絶対に落とせない` サーバを構築するのに有効な1つの手段であるとさています。
また、FTサーバでクラスタ構成を組むことにより、より高い可用性を実現できます。

![5Untitled Diagram.drawio - diagrams.net - Google Ch.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/b8342fea-d0cb-b887-6714-2084c8897612.png)



## 勉強後のイメージ

よく、`サーバ自体は壊れるものだ`と聞きますが、
壊れても落ちないようにサーバ自体が二重化されているってすごい・・・
高そうではあるけど、１つの手段では有る


## 参考

- [障害時も無停止！止められないシステムに最適な「ftサーバ」とは？](https://ascii.jp/elem/000/000/958/958750/)
- [FTサーバ  【 Fault Tolerant server 】 ](http://e-words.jp/w/FT%E3%82%B5%E3%83%BC%E3%83%90.html#:~:text=FT%E3%82%B5%E3%83%BC%E3%83%90%E3%81%A8%E3%81%AF%E3%80%81%E4%BC%81%E6%A5%AD,%E3%82%88%E3%81%86%E8%A8%AD%E8%A8%88%E3%81%95%E3%82%8C%E3%81%9F%E3%82%82%E3%81%AE%E3%80%82)
Unexpected end of JSON input while parsing near '...":"^3.5.0","concurren'　のトラブルシューティング

#以下コマンドで解決

```
npm cache clean -force
```

パッケージインストール時に何らかの理由で汚いログが残っていることが原因のようです。
npmのキャッシュを強制的に消す事で解決。
Gitログを整形して、コミットしたファイル名をcsv形式で取得する

### 目的
gitのコミット情報をcsv形式で取得したかったが
git logの--pretty=formatのオプションでは、私が欲しかったフォーマットで取得できなかったため、 一度ログを出力した上でログの整形を行うようにした。

### 環境
OS Mac Catalina
Pycharm CE
python 3.7 

### 準備
#### gitログの取得
GitBashなどのコンソールで叩くとログファイルが出力される。
```git --no-pager log --name-status --no-merges --all \
--date-order --date=format:'%Y/%m/%d %H:%M:%S' > git.log```

##### 取り込む想定のgitログ

``` git.log
commit f36da445d06d2db7b4f08a508be835f5464ded
Author: nomori<hoge@example.com>
Date:   2020/10/10 23:50:29
    first commit.
A	.gitignore
A	perse_git_log.py
```
### 実装
``` perse_git_log.py
import re
import csv
import os

COMMIT_ID = 'commit '
STATUS_ADD = 'A	'
STATUS_MOD = 'M	'
STATUS_DEL = 'D	'
GIT_AUTHOR = 'Author: '
GIT_DATE = 'Date:   '

path = './input/git.log'

# gitのlogファイルを読み込む.
array_commit_info = []
with open(path) as git_log_file:
    data = git_log_file.readlines()

for item in data:
    # 末尾の改行コードを削除.
    item = item.replace('\n', '')

    if COMMIT_ID in item:
        # コミットのハッシュIDを取得.
        commit_id = item.replace(COMMIT_ID, '')

    elif GIT_AUTHOR in item:
        # コミットしたユーザー情報を取得.
        author_tmp = item.replace(GIT_AUTHOR, '')
        # メールアドレス部分を削除.
        author = re.sub(' +<.*>', '', author_tmp)

    elif GIT_DATE in item:
        # コミット日時を取得.
        date = item.replace(GIT_DATE, '')

    else:
        # ファイルの変更履歴を取得.
        file_status = item[0:2]
        if file_status == STATUS_ADD or file_status == STATUS_MOD or file_status == STATUS_DEL:
            # Gitのステータスを除いたファイル名の取得.
            file_name = item[2:]
            # 出力用の配列に情報を保持.
            array_commit_info.append([commit_id, author, date, file_name])

print(array_commit_info)

# CSV形式で出力.
file_path = './output/'
if not os.path.exists(file_path):
    os.mkdir(file_path)

output_filename = file_path + 'git_output.csv'
with open(output_filename, 'w') as f:
    writer = csv.writer(f)

    # ヘッダ情報を出力.
    writer.writerow(['COMMIT_ID', 'AUTHOR', 'DATE', 'COMMIT_FILE_NAME'])
    for line_data in array_commit_info:
        # コミット情報を出力.
        writer.writerow(line_data)

```

### 出力例
``` git_output.csv
f36da445d06d2db7b4f08a508be835f5464ded,nomori,2020/10/10 23:50:29,.gitignore
f36da445d06d2db7b4f08a508be835f5464ded,nomori,2020/10/10 23:50:29,perse_git_log.py

```



## 参考
- Pythonでファイルの読み込み、書き込み（作成・追記） https://note.nkmk.me/python-file-io-open-with/
- Python文字列操作マスター https://qiita.com/tomotaka_ito/items/594ee1396cf982ba9887
- Pythonで文字列の一部を削除（stripなど）https://note.nkmk.me/python-str-remove-strip/  
- 【Python3】configparserの使い方とサンプル https://www.mathkuro.com/python/configperser/
- Pythonの設定ファイル管理まとめ　https://kodocode.net/python-begin-settings/
- Git log Document https://git-scm.com/docs/git-log
- git ignore https://www.toptal.com/developers/gitignore
BigQueryクエリの最適化　メモ

# リンク
- [クエリ パフォーマンスの最適化](https://cloud.google.com/bigquery/docs/best-practices-performance-overview)
- [BigQuery で費用を抑える](https://cloud.google.com/bigquery/docs/best-practices-costs)

# 注意点　メモ
- BigQuery のパフォーマンス チューニングは通常、クエリ実行時間の短縮やコストの削減を目的として行われる。
- パフォーマンス チューニングは開発段階の最後に、通常のクエリでは時間がかかりすぎることが判明した場合にのみ行う。
- 一般的には、わずかなパフォーマンス向上のためにわかりづらいテーブル レイアウトとクエリにするよりも、テーブル スキーマを柔軟なものにし、洗練され読みやすく保守性の高いクエリを記述する方がはるかに大きなメリットがある。
- ただし、実行頻度が高く、わずかな改善でも効果があるクエリの場合には、パフォーマンス改善が必要になることがある。
- Donald Knuth 氏の「早計な最適化は諸悪の根源である」という言葉を忘れないように。
【Flutter】「No Firebase App '[DEFAULT]' has been created - call Firebase.initializeApp() occurred in Instance of xxx 」が発生しFirestoreに接続できない

## 開発環境
* Flutter: 1.22.0
* Dart: 2.10.0
* cloud_firestore: ^0.14.1+3
* firebase_core: ^0.5.0+1

## エラー内容
cloud_firestoreライブラリの`FirebaseFirestore.instance`を参照したら下記のエラーが発生した。

```
Unhandled Exception: Unhandled error [core/no-app] No Firebase App '[DEFAULT]' has been created - call Firebase.initializeApp() occurred in Instance of
```

エラー文によると、`Firebase.initializeApp()`を呼べということらしい。

## 対処法
`main.dart`にmainメソッド内のrunAppメソッドの前で`Firebase.initializeApp()`呼ぶ。
initializeAppメソッドは非同期処理なので、`await`キーワードをつけてあげる。
つけないと、Firebaseに接続される前に`FirebaseFirestore.instance`を参照して、また同じエラーが発生する可能性がある。

``` main.dart
Future<void> main() async {
  await Firebase.initializeApp();
  runApp(MyApp());
}
```

これでビルドしてみる。

## 別のエラー発生
今度は下記のエラーが発生した。

```
E/flutter ( 6504): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: ServicesBinding.defaultBinaryMessenger was accessed before the binding was initialized.
E/flutter ( 6504): If you're running an application and need to access the binary messenger before `runApp()` has been called (for example, during plugin initialization), then you need to explicitly call the `WidgetsFlutterBinding.ensureInitialized()` first.
```

今度は`WidgetsFlutterBinding.ensureInitialized()`メソッドを呼べということらしい。

下記、[ensureInitializedメソッドの公式ドキュメント](https://api.flutter.dev/flutter/widgets/WidgetsFlutterBinding/ensureInitialized.html)から引用する。

>Returns an instance of the WidgetsBinding, creating and initializing it if necessary. If one is created, it will be a WidgetsFlutterBinding. If one was previously initialized, then it will at least implement WidgetsBinding.

>You only need to call this method if you need the binding to be initialized before calling runApp.

>In the flutter_test framework, testWidgets initializes the binding instance to a TestWidgetsFlutterBinding, not a WidgetsFlutterBinding.

runAppメソッドの前に非同期の処理を実行する際はこのメソッドを使え、と無理やり解釈する。

ということで`Firebase.initializeApp()`メソッドの前に、`WidgetsFlutterBinding.ensureInitialized()`を実行する。

``` main.dart
Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MyApp());
}
```

これでようやくエラーが消えた。
めでたしめでたし。

## 参考
* [FlutterFireドキュメント](https://firebase.flutter.dev/docs/overview/#initializing-flutterfire)
単純なミスを減らしていきたい。自分への戒めに。

#はじめに
　今日、学習を進めていて、30分ほど解決に時間がかかったものをまとめる。
##問題
詳細ページに行きたくても、思い通りのページに飛ばないで、どのリンク画像を触っても、同じ詳細ページに行ってしまう。


##解決までの道筋

```ruby

def show
    @prototype = Prototype.find(params[:id])
end
```

コントローラーのアクションが間違っているのだと思い、何度も見返すが、問題が見当たらない。
Prototypeテーブルからidを探し、それをインスタンス変数に入れる。

次に詳細ページに飛ぶときに触る部分のコードを見ることに。

```ruby
<%= link_to image_tag(prototype.image), prototype_path(prototype.user.id)%>
```

はいそう、リンク先のパスが、`.user`を入れることによって、`prototype`のidを探し出したかったのに、`user`テーブルのidを探していた。だから、id＝１のユーザーで入っていると、どのリンク画像を触っても、１番の詳細ページにいっていた。prototypeテーブルとuserテーブルがアソシエーションしているから起きたミス。

正しくは↓

```ruby
<%= link_to image_tag(prototype.image), prototype_path(prototype.id)%>
```
【TypeScript】Abstractクラスを使ってうまくエラーハンドリングする

# はじめに
コーディング初学者のYNといいます。お読みいただきありがとうございます。
ようやくTypeScriptを学び始めまして、その素晴らしさを実感しつつあります。
今回は、expressを使ったときのエラーハンドリングについて気づきをまとめておきます。

# 概要と基本構造

![スクリーンショット 2020-10-11 23.02.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/543f9d43-b709-d3c1-f50d-e6b32dc9d7ba.png)

![スクリーンショット 2020-10-11 23.03.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/2fb5942d-e786-b35e-d392-84ad1ffb4afc.png)


# エラーが起きたときの処理

![スクリーンショット 2020-10-11 23.04.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/91d865d4-af6e-6687-452f-52db334bbc5c.png)


# エラーの内容を細分化しようとおもったとき、エラーごとに処理を増やす必要があって困る
![スクリーンショット 2020-10-11 23.06.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/8efd04b3-1e62-1cb2-4aed-a9ad3e37fd48.png)

# Abstractクラスを利用して、エラー処理を一つにまとめることができる
![スクリーンショット 2020-10-11 23.08.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/5e2fd1ef-2674-4f77-0d68-3a7f82742ba9.png)

![スクリーンショット 2020-10-11 23.13.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/690da234-e1b0-29c7-3c12-6dbda63b83aa.png)
乃木坂認識プログラム（Yolov5を利用）目次

この記事はあくまで目次です.
## 目次（Yolov5）
⓵システム導入
https://qiita.com/asmg07/items/e3be94a3e0f0195c383b
⓶学習編
https://qiita.com/asmg07/items/01b429ad8443ac346f7f
⓷モデル構築について
https://qiita.com/asmg07/items/8502fe59b65f92d1e379
④GPUを使ったYoloの学習について
https://qiita.com/asmg07/items/0abad3e16886cb60ecef
⑤最後
https://qiita.com/asmg07/items/979d054d1b813afc8c74
【Kubernetes】マニフェストファイルの概要と必須項目


# 概要
- Kubernetesマニフェストファイルとは
    - Kubernetesのリソース管理に用いるファイル
- 具体的にはどんな物か
    - Kubernetesリソースの構成を記述したテキストファイル
    - 必須フィールド(項目)は`apiVersion`, `kind`, `metadata`, `spec`の4つ。（[公式ドキュメント](https://kubernetes.io/ja/docs/concepts/overview/working-with-objects/kubernetes-objects/#%E5%BF%85%E9%A0%88%E3%83%95%E3%82%A3%E3%83%BC%E3%83%AB%E3%83%89))

```yaml:example.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx
```

# 必須フィールド
## apiVersion

- 利用するKubenetesAPIのバージョン。
- 参考：[Kubernetesの apiVersion に何を書けばいいか](https://qiita.com/soymsk/items/69aeaa7945fe1f875822)

## kind
- 作成するオブジェクトの種類。
- [公式ドキュメントのリソース一覧表](https://kubernetes.io/docs/reference/kubectl/overview/#resource-types) の、`Kind`列から選択する。

## metadata
- オブジェクトを一意に指定する為の情報。
- `name`, `labels`などのフィールドを用いて下記の様に指定する。

```yaml
metadata:
  name: nginx-deployment
  labels:
    app: nginx
```

- `name`, もしくは`namespase`フィールドが必須。  
（どちらも無いとデプロイ時に下記のエラーが発生する）

```
"" is invalid: metadata.name: Required value: name or generateName is required
```

## spec
- 作成するオブジェクトの理想状態。
    - 現実の状態がここに記載した理想状態に一致する様に、よしなに調整してくれる （[公式ドキュメント](https://kubernetes.io/ja/docs/concepts/#%E6%A6%82%E8%A6%81) 参照）
- 作成するオブジェクトの種類によって指定するフィールドは異なる。（下記は`pods`オブジェクトの例）

```yaml
kind: Pod
spec:
  containers:
  - name: nginx
    image: nginx
```

#