OmniAICreator/Qiita-1.07M huggingface dataset:
(Vagrant) SSH接続時に発生する Permission denied (publickey,gssapi-keyex,gssapi-with-mic) エラーの対応

#はじめに
この記事ではWindows10(1909), Oracle VirtualBox 6.0 + Vagrant 2.2.6 の環境にて立ち上げたCentOS 8で直面したSSH接続に関する私のトラブルシュートを記録したものです。



#直面したこと
VirtualBoxで立ち上げたCentOSに対して、TeraTermを用いてSSHしようとしたところプレーンパスワードでのアクセスができなかった。



#SSHのアクセスログを確認
SSHアクセス時のログを出力するため、PowerShellからオプション -vvv を指定して接続をトライ

```ssh -vvv root@192.168.33.10```

次のようなログを確認(一部抜粋)

```
PS C:\Vagrant\centos8> ssh -vvv root@192.168.33.10
OpenSSH_for_Windows_7.7p1, LibreSSL 2.6.5
debug3: Failed to open file:C:/Users/localadmin/.ssh/config error:2
debug3: Failed to open file:C:/ProgramData/ssh/ssh_config error:2
debug2: resolve_canonicalize: hostname 192.168.33.10 is address
debug2: ssh_connect_direct: needpriv 0
debug1: Connecting to 192.168.33.10 [192.168.33.10] port 22.
debug1: Connection established.
debug3: Failed to open file:C:/Users/localadmin/.ssh/id_rsa error:2
debug3: Failed to open file:C:/Users/localadmin/.ssh/id_rsa.pub error:2
debug1: key_load_public: No such file or directory
.
.
.
debug1: Next authentication method: publickey
debug1: Trying private key: C:\\Users\\localadmin/.ssh/id_rsa
debug3: no such identity: C:\\Users\\localadmin/.ssh/id_rsa: No such file or directory
debug1: Trying private key: C:\\Users\\localadmin/.ssh/id_dsa
debug3: no such identity: C:\\Users\\localadmin/.ssh/id_dsa: No such file or directory
debug1: Trying private key: C:\\Users\\localadmin/.ssh/id_ecdsa
debug3: no such identity: C:\\Users\\localadmin/.ssh/id_ecdsa: No such file or directory
debug1: Trying private key: C:\\Users\\localadmin/.ssh/id_ed25519
debug3: no such identity: C:\\Users\\localadmin/.ssh/id_ed25519: No such file or directory
debug1: Trying private key: C:\\Users\\localadmin/.ssh/id_xmss
debug3: no such identity: C:\\Users\\localadmin/.ssh/id_xmss: No such file or directory
debug2: we did not send a packet, disable method
debug1: No more authentication methods to try.
root@192.168.33.10: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
```

どうやら認証するための鍵を参照できない模様


#解決した方法
sshが参照しようとしたところ```C:\\Users\\localadmin/.ssh/```にはRSA鍵が存在しておらず接続ができなかった。
そこで、TeraTermの新規接続画面にて次の手順を実施したところ接続できるようになった。

* TeraTermの起動
* SSH を選択し接続
    * ホストはVagrantで指定したIPアドレス
    * ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233495/b6aa9436-0dd4-8b56-d7a3-fd8d589c1aac.png)
* 「SSH認証」画面でユーザ名を入力し、「RSA/DSA/ECDSA/ED25519鍵を使う」にラジオボタンを合わせ、「秘密鍵」ボタンを押下する
    * ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233495/49d129a6-6cc9-95d3-c489-af6f0849fd44.png)
* 今回の場合は```Vagrantのホームフォルダ\ホストのフォルダ\.vagrant\machines\default\virtualbox```配下に"id_rsa"ファイルが存在していたためそれを指定
* OKボタンを押下すると接続できました。
Swiftのhttp通信を勉強する

[pre-1]:https://qiita.com/zasshyu6/items/805dc98bb3574ff36e00
[sample-1]:https://dev.classmethod.jp/smartphone/iphone/swift-3-playground-urlsession/
[json-1]:https://www.json.org/json-ja.html

[api-1]:https://developer.apple.com/documentation/foundation
[api-2]:https://developer.apple.com/documentation/playgroundsupport

[try]:https://qiita.com/koishi/items/67cf4d0f51c4d79f1d22
[in]:https://qiita.com/yuinchirn/items/2ebb6fed6de0c9c1c3c9
[clo]:https://qiita.com/narukun/items/b1b6ec856aee42767694
[iflet]:https://qiita.com/Iorin0225/items/48cdcdd7ab38a5cb8afa

#はじめに
`iPad`でプログラミングを楽しみたいなぁとおもって買ったのですが、`swift PlayGround`で遊んで終わりだったので実際使いたいのでやってみました。

###使った環境
 - `Swift PlayGround`
    - `Swift 5.1`

###やったこと
[前回記事][PRE-1]では`C#`でhttp通信を行いました。
最終目標は`iPhone`か`iPad`で`m5stack`にアクセスできるようにしたいので、はじめに`iPad`単体でのhttp通信を勉強します。

#`Swift  playgrounds`で試してみる
以下の記事のプログラムをそのまま実行してみたら出来たので、それを一つ一つ砕いて納得していきます。
>[[Swift 3.0] Playground で URLSession を使う][sample-1]
こちらを参考にさせて勉強させていただきました。ありがとうございます。

こちらのプログラムを`Swift  playgrounds`のブランクプロジェクトでそのままコピペしたら動きましたのでこれを読み解いていきます。

プログラムでやってることは参考記事で書いているのでそちらをお読みください。
プログラムの中でよくわからなくて調べたことは以下です

 - importしているlibrary
 - 受け取っているデータ形式
 - `in`や`do catchなどの処理について

##`import`しているライブラリ
 - `Foundation`
    - [公式ドキュメント調べたらなんでも入ってた福袋みたいなやつ。][api-1]基本ライブラリと考えて良さそう？
    - サンプルプログラムでは`URL`,`URLSession`,`JSONSerialization`が使われてる
 - `PlaygroundSupport`
    - [公式ドキュメントはこちら。][api-2]ヒントとかリアルタイムコンパイルとかコンパイルエラー表示などを行なっているライブラリだそうです。
    - リアルタイムでコンパイルと実行を行う`Live view`というのがあるらしく、これを動かすと非同期に対応しない様です。なので`needsIndefiniteExecution`のオプションを変更して非同期を可能にしている様です。


##`JSON`データ受け取り
`URLSession`で`URL`にアクセスしている様です。プログラムの動きからの予想ですが、`URLSession`はデフォルトで`GET`メソッドを送る様子です。他はおそらく何も送ってないと思います。
その後のコードで`JSONSerialization`を使った関数を呼び出しているので受けとっているのは`JSON`のデータな様子です。
`JSONSerialization`のオプション`allowFragments`で`Array`と`Dictionary`は禁止にしている様子ですが、このオプションは必須なのでしょうか？

###ところで`JSON`とはなんだ？
>[JSONの紹介][json-1]
こちらに紹介されていました。

##`Swift`で使っている構文
 - `in`
    - [Swift さくっと確認したい基礎文法 [クロージャ(closure)]][in]こちらの記事に詳しく説明をありました。
    - クロージャにする様です。クロージャってデリゲートのことかとおもったらデリゲートは別にある様です。
    - [【swift】イラストで分かる！具体的なClosureの使い方。][clo]こちらにクロージャのイメージがイラストで載っていました。また、同じ記事でデリゲートの説明もあってイメージは掴みやす買ったです。絵が可愛いのは大事
 - `if let`
    - [Swiftのif let って、つまり、何？][iflet]こちらの記事が分かりやすかったです。
        - サンプルプログラムでは、`JSON`データかどうかの判別に使っています。
 - `do (try) catch`
    - [Swift 4.0 エラー処理入門][try]こちらの記事に詳しく説明がありました。
    - `JSONSerialization`からの返り値を確認するのに使っています

#まとめ
プログラムを読むだけで以下の事柄を調べることになりました。
 - `Foundation`ライブラリ
 - `PlaygroundSupport`ライブラリ
 - `JSON`データ
 - `in`,`if let`,`do (try) catch`,クロージャ、デリゲート


http通信を勉強するだけの予定でしたが、現在使われている技術と`Swift`で扱える構文、ライブラリを調べることでどうやって動いているかのイメージだけは掴めた気はします。
最後に、`URLSession`のデフォルトの設定値が見当たらなかくてわからなかったです・・・

#感想
今回参考にしたプログラムですが、本元の記事だとサクッと作っている感じです。
実際こういうのをサクッと作れちゃう人たちは本当にすごいです。
いずれサクッと作れるようになりたいですが、何年かかるでしょうねぇ。とりあえず続けて行きたいです。
「コンピュータはなぜ動くのか」メモ②

メモ②

〜〜〜〜〜〜〜〜
<b>第3章：一度は体験してほしいハンド・アセンブル</b>

・ハンド・アセンブル　＝　アセンブリ言語でプログラムを記述し、手作業でプロセサが直接実行できる「マシン語」に変換する作業

・プログラムを作成するのに必要となるハードウェアの情報
　　→【CPU】CPUの種類（CPUの種類が異なれば同じマシン語でも解釈が異なる）
　　→【CPU】クロック信号の周波数
　　→【メモリ】アドレス空間
　　→【メモリ】1つのアドレスに記録できる情報のビット数
　　→【I/O】I/Oの種類
　　→【I/O】アドレス空間
　　→【I/O】接続されている周辺装置

*クロック信号の周波数　＝　クロック・ジェネレータからCPUに与えられる電気信号の周波数
マシン語は、命令の種類によって実行に要するクロック数が決まっている。
クロック信号は0と1の変化を繰り返す電気信号。

・メモリのアドレス空間　＝　メモリの中にあるデータの格納場所を指定するアドレスの範囲のこと
・接続されているI/Oの種類　＝　マイコンと周辺装置を接続するI/Oの種類のこと
・I/Oのアドレス空間　＝　I/Oのレジスタを指定するアドレスの範囲のこと

＊メモリはどの番地でも命令やデータを記録するという同じ役割を持っているが、I/Oは番地が異なる（＝レジスタが異なる）と役割が違ってくる

・マシン語のプログラムは0と1の羅列なので、人間には判断できない。
そこで、0と1のられるにその機能を表す英語に似たニックネーム（＝ニーモニック）をつけてプログラムを作成する手法が考案された。　→ニーモニックを使ってプログラミングする言語を「アセンブリ言語」とよぶ。

・CPUの中のデータを記録する場所が<b>「レジスタ」</b>。演算もする。
　　→Aレジスタ（アキュムレータ）　＝　演算の中心
　　→Fレジスタ（フラグ・レジスタ）　＝　演算結果によって桁上がりが発生したことや大小比較の結果などが記録される。
　　→PCレジスタ（プログラム・カウンタ）　＝　CPUが次に実行する命令のメモリーアドレスが格納される。クロック信号によって自動的に更新されるようになっている。
　　→SPレジスタ（スタック・ポインタ）　＝　メモリ上に「スタック」というデータの一時記録領域を作成するために使われる。

・Little endian = データの下位から上位の順でメモリに格納する形式
・Big endian = データの上位から下位の順でメモリに格納する形式


<b>第4章：川の流れのようにプログラムは流れる</b>
・プログラムの流れ　→ 順次進行（下位アドレス/小さい番地から上位アドレス/大きい番地）、条件分岐、繰り返し
・プログラムの流れを図示したもの　→　フローチャート

・構造化プログラミング　＝　「プログラムの流れを順次進行・条件分岐・繰り返しだけで表し、ジャンプ命令を使わないようにする」（高水準言語にはジャンプ命令が不要？）

・Algorithm = 与えられた問題を解く手順のこと

・特殊なプログラムの流れ
　→割り込み処理　＝　プログラムの特定の部分に、突然プログラムの流れをジャンプさせること。ハードウェア的にはCPUに接続されたI/Oから割り込み要求信号を受け付けるもの。ただし、プログラムの中に割り込みを記述する必要はんく、ROMに記録BIOSやOSが持っている。

　→イベント・ドリブン ＝ GUI環境用のプログラムでよく利用される。イベント（マウスクリック、キーボード押す）の種類に応じて処理を行う。


<b>第5章：アルゴリズムと仲良くなる7つのポイント</b>

■アルゴリズムを考えるポイント
　①問題を解く手順が明確で有限回である
　②勘に頼らず機械的に問題が解ける（頭を使うことなく手順通りにやれば必ずできる）
　③定番アルゴリズムを知り応用する
　④コンピュータの処理スピードを利用する
　⑤スピードアップを目指して工夫する
　⑥数値の法則性を見いだす
　⑦紙の上で手順を考える（≒フローチャート）


<b>第6章：データ構造と仲良くなる7つのポイント</b>

①メモリと変数の関係を知る
②データ構造の基本が配列であることを知る
③定番アルゴリズムのデータ構造として配列を使うことを知る
④定番データ構造の種類を知り、イメージをつかむ
　　→スタック（データを山のように積み上げる、LIFO）
　　→キュー（データを行列のように並ばせる、FIFO）
　　→リスト（データの並びを任意に変更できる）
　　→２分木（データの並びを二またに分ける）
⑤スタックとキューの実現方法を知る
　　→スタックの実現方法：スタックのサイズを要素数とした配列と、スタックの最上部に格納されたデータのインデックスを表す変数（スタック・ポインタ）を宣言する。必要な関数は、格納する関数（push）と取り出す関数（pop）。
　　→キューの実現方法：任意のサイズの配列、キューの先頭のデータのインデックスを表す変数、キューの末尾のデータのインデックスを表す変数、およびキューにデータを格納する関数（Set）とキューからデータを取り出す関数(Get)のペアが必要。
⑥構造体の仕組みを知る
　・構造体とは　＝　複数のデータを一つにまとめて名前をつけたもの
⑦リストと２分木の実現方法を知る
　→リスト：簡潔に言うとつながりのデータ。リストがない場合、メモリ上の物理的な順序そのものを並べ替える必要がある（＝処理時間が長くなる）

〜〜〜〜〜〜〜〜

続きはメモ③にて。
JetsonNanoをオーバークロックする。

JetsonNanoをオーバクロックするには5V、4Aの電源が必要だ。
また、１箇所ピンヘッダをショートさせる必要がある。

<img width="465" alt="スクリーンショット 2020-01-02 21.45.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110060/ddb06239-52ed-9bf2-5540-1d353b9e938c.png">

あとは以下のコマンドを実行する事。

```bash:bash
sudo nvpmodel -m 0
sudo jetson_clocks
```
ubuntuのようにWindowsでも管理パッケージを使う方法

chocolateyとは
Windowsで使えるパッケージマネージャ
簡単にいろいろなツールをインストールや
ソフト更新できるのでおすすめします。
https://chocolatey.org/

インストールURL
(管理者権限でcmd)
@"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"

例 choco install ChocolateyGUI　-y
(ChocolateyのGUI版です)
コマンドで自動インストールすることが出来ます。

choco install
パッケージインストール

choco list
パッケージの一覧表示

choco list [packageName]
パッケージの検索

choco update [packageName]
インストール済みのpackegeをアップデート

choco update all
インストール済みのpackegeを全てアップデート

chocolatey uninstall [packageName]
アンインストール

後はWindowsのopenSSH(Windows版)入れてあげれば
別PCからubuntuのように扱えるようになります。
UbuntuでESP32を使う際のVCPセットアップメモ


下記リンクからwgetなどを用いてソースをダウンロードの後、展開すれば良い。
https://www.silabs.com/documents/login/software/Linux_3.x.x_4.x.x_VCP_Driver_Source.zip

以下を実行する。

```bash:sh
wget https://www.silabs.com/documents/login/software/Linux_3.x.x_4.x.x_VCP_Driver_Source.zip

unzip Linux_3.x.x_4.x.x_VCP_Driver_Source.zip

cd Linux_3.x.x_4.x.x_VCP_Driver_Source

make

sudo cp cp210x.ko /lib/modules/4.9.140-tegra/kernel/drivers/usb/serial/

sudo insmod /lib/modules/4.9.140-tegra/kernel/drivers/usb/serial/usb_wwan.ko

sudo insmod cp210x.ko

```

また、起動時に以下のステップが必要である。
/dev/ttyUSB*は各自環境によって違う。

```terminal:terminal
$ sudo chmod 666 /dev/ttyUSB0
```

自動化するためにexpectなどを用いてやると良い。
ただしパスワードを直接ファイルに書き込むのは危険なので工夫すること。

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

PW=$(openssl rsautl -decrypt -inkey ~/.ssh/id_rsa -in ~/.ssh/password.rsa)
expect -c "
set timeout 5
spawn env LANG=C sudo chmod 666 /dev/ttyUSB0
expect \"password:\"
send \"${PW}\n\"
expect \"$\"
exit 0
"
```
【rails】enumを利用したラジオボタン検索【ransack】


enumを利用したransackのラジオボタン検索で少しつまずいたので備忘録用として投稿

ransackの導入やenumの書き方については端折ります。

```micropost.rb
enum result: { win: 1, lose: 2, notrade: 3 }
```


***検索できなかった時***

````_serch_form.html.slim
  = search_form_for @q do |f|
        h2.my-3 検索
        = f.label :result
        br.form-check.form-check-inline
        = f.radio_button :result_eq, :win, {:checked => true}
        = f.radio_button :result_eq, :lose
        = f.radio_button :result_eq, :notrade
        br
        = f.submit nil, class:'btn btn-info'
```


***正しいやつ***

```_serch_form.html.slim
  = search_form_for @q do |f|
        h2.my-3 検索
        = f.label :result
        br.form-check.form-check-inline
        = f.radio_button :result_eq, 1, {:checked => true}
        = f.radio_button :result_eq, 2
        = f.radio_button :result_eq, 3
        br
        = f.submit nil, class:'btn btn-info'
      
```

インデントとか気にしないで下さい。

なぜか最初はハッシュを入力していました。
barryvdh/laravel-corsをv1.0.0以上にアップグレードする時の注意点

## はじめに

あけましておめでとうございます。新年はいかがお過ごしですか。年末年始は、Netflixのナルコスをずっと見てました。自分は個人プロダクトで使用しているLaravelのミドルウェアをバージョンアップしていました。さっさと終わらせてシーズン３に戻りたかったのですが、 `barryvdh/laravel-cors` を v1.0.3にアップグレードしようとしたところ、地味にハマってしまい、ナルコスに戻れなくなってしまいました。

## 困ったこと

`barryvdh/laravel-cors` を v.1.0.0以上にアップグレードしようとしたところ以下のエラーが突然表示された。

```php
    Illuminate\Contracts\Container\BindingResolutionException: Target class [Barryvdh\Cors\HandleCors] does not exist.
```

## 注意点

### １．リポジトリが移動した

2019年12月28日にリポジトリの場所が、 `barryvdh/laravel-cors` から `fruitcake/laravel-cors` に移動しました。偶然このツイートを見て知ったけど、GitHubのリリースノートやREADMEにも書いておいてほしかったですね...。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="en" dir="ltr">Moved barryvdh/laravel-cors to fruitcake/laravel-cors and tagged V1, simplifying the middleware a bit. It now uses a global middleware + path filter, instead of group middleware, to better handle errors. Please give it a try and report issues :) <a href="https://t.co/A0ixn3NwOa">https://t.co/A0ixn3NwOa</a></p>&mdash; Barry vd. Heuvel (@barryvdh) <a href="https://twitter.com/barryvdh/status/1210582552949460993?ref_src=twsrc%5Etfw">2019年12月27日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

### ２．v1.0.0から Breaking changesの変更が入った

これは [v1.0.0のRelease Note](https://github.com/fruitcake/laravel-cors/releases/tag/v1.0.0) に詳細が書いてあります。この後解決方法でも具体的に紹介していきます。

## 環境

- Laravel 6.9.0
- barryvdh/laravel-cors 0.11.4

## ゴール

`barryvdh/laravel-cors` 0.11.4 から `fruitcake/laravel-cors`1.0.3 にアップグレードします

## 解決方法

まずは `composer.json` でパッケージ名を変更して、 `composer upgrade barryvdh/laravel-cors` 。

```diff
- "barryvdh/laravel-cors": "^0.11.1",
+ "fruitcake/laravel-cors": "^1.0.3",
```

次に `config/cors.php` のオプション名を lowerCamelCase形式からsnake_case形式に変更します。

```diff
-    'supportsCredentials' => true,
-    'allowedOrigins' => ['*'],
-    'allowedOriginsPatterns' => [],
-    'allowedHeaders' => ['*'],
-    'allowedMethods' => ['*'],
-    'exposedHeaders' => [],
-    'maxAge' => 0,
+    'supports_credentials' => true,
+    'allowed_origins' => ['*'],
+    'allowed_origins_patterns' => [],
+    'allowed_headers' => ['*'],
+    'allowed_methods' => ['*'],
+    'exposed_headers' => [],
+    'max_age' => 0,
```

`config/cors.php` に `v1.0.0` から追加になった `paths` オプションを追加する。 `paths` でCORSを許可するルーティングが指定できるので、適宜調整してください。

```diff
+     'paths' => [*], 
```

`app/Http/Kernel.php` の `$middleware` で読み込むクラスを差し替えます。

```diff
-        \Barryvdh\Cors\HandleCors::class,
+        \Fruitcake\Cors\HandleCors::class,
```

これで以上です。

## まとめ

リポジトリが移動されたことが分かっていれば大した内容ではないです。ですが、自分は最初そのことに気づかず、地味に少しハマってしまったので、同じようにハマる人が少しでも減ればと思い、本記事をまとめました。お役に立てれば幸いです。
改めてprint()       print()のキーワード引数

こんにちは。初めて記事を書きます。
1番使っている言語はPythonで、C言語とその他もろもろを少しかじっています。
print()はPythonの入門によく使われますが、キーワード引数が使えることを最近知り、備忘録がてらまとめてみました。

１月６日追記：バージョンは3.5.3でした。（全然違った）また、例の`word = Python`のところに`''`（シングルクォーテーション）を付け忘れていたので修正しました。すみません。

---

2021/4/18 追記　上書き出力の説明と必要なくなった部分の削除とコード例の修正。

Pythonで上書き出力。

書式） ```print("\r 文字列")``` or ```pirnt("\r" + "文字列")```

```py
print("\rhello")
input() #処理を一時停止Enterで再開。
print("word!")

#使用例

import time
for i in range(100):
    print("\r" + str(i) + "%")
    time.sleep(0.1) 

#同じ行に％表示が上書き出力される。

```

---

[ドキュメント](https://docs.python.org/ja/3/library/functions.html#print)から引用

>print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)
objects を sep で区切りながらテキストストリーム file に表示し、最後に end を表示します。sep 、 end 、 file 、 flush を与える場合、キーワード引数として与える必要があります。

###例
```py

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

test = 'てすと'
print(test)
#てすと

#キーワードで区切る
word = 'Python'
print(test, word, sep='と')
#てすととPython

#最後の行に出力する文字列を指定
print(test, end='と')
#てすとと

#応用？
print(test, end='')
#改行しない
```



改行しない出力で、表現の幅が広がると思うので、ぜひ参考にしてください。
異なるアルゴリズムによるフィボナッチ数列の実行速度の違い

# はじめに
こんにちは。

最近、アルゴリズムを勉強をしている中で、学校の授業でも扱ったことがあるフィボナッチ数列に出会いました。
今回は、全探索と動的計画法といったアルゴリズムでフィボナッチ数列の解を求めました。
その際に、この2つのアルゴリズムの実行速度を比べてみると圧倒的に違ったので、その結果を記事にしてみました。
アルゴリズムの重要性も伝わるのかなと思います。

ただし、この記事では、フィボナッチ数列や、全探索、動的計画法の解説はしていないので、もし分からない場合は調べてみてください。また、使用したプログラミング言語はC++です。よろしくお願いします。

# 環境 
- Windows 10 home
- gcc 8.2.0
- Intel Core i9-7900X


# 全探索によるフィボナッチ数列のソースコード

```Fibonacci1.cpp
#include <bits/stdc++.h>
#include <chrono>

using namespace std;
typedef long long ll;

ll fib(ll n){
  if(n <= 1){
    return n;
  }else{
    return fib(n-1) + fib(n-2);
  }
}

int main() {

  ll N;
  cin >> N;

  const auto startTime = chrono::system_clock::now();

  cout << fib(N) << endl;

  const auto endTime = chrono::system_clock::now();
  const auto timeSpan = endTime - startTime;
  cout << "処理時間:" << chrono::duration_cast<chrono::milliseconds>(timeSpan).count() << "[ms]" << endl;
}
```

## 実行結果


<img width="500" alt="全探索の場合.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309633/118e8968-4281-c639-d72b-e2d32d7ef216.png">

コンソール上に上記のような実行結果になりました。
全探索で50番目のフィボナッチ数を求めようとした結果、解が**12586269025**で処理時間が**112240**ミリ秒となりました。



# 動的計画法によるフィボナッチ数列のソースコード

```Fibonacci2.cpp
#include <bits/stdc++.h>
#include <chrono>

using namespace std;
typedef long long ll;

ll memo[1000];

ll fib(ll n){
  if(n <= 1){
    return n;
  }else if(memo[n] != 0){
    return memo[n];
  }else{
    return memo[n] = fib(n-1) + fib(n-2);
  }
}

int main() {

  ll N;
  cin >> N;

  const auto startTime = chrono::system_clock::now();

  cout << fib(N) << endl;

  const auto endTime = chrono::system_clock::now();
  const auto timeSpan = endTime - startTime;
  cout << "処理時間:" << chrono::duration_cast<chrono::milliseconds>(timeSpan).count() << "[ms]" << endl;
}
```



## 実行結果

<img width="450" alt="メモ探索の場合.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309633/d89e5074-fc16-45bc-0928-7ab313a86434.png">


コンソール上に上記のような実行結果になりました。
動的計画法で50番目のフィボナッチ数を求めようとした結果、解が**12586269025**で処理時間が**1**ミリ秒となりました。


# おわり
いかがだったでしょうか。
同じ解を求めるのにもかかわらず、アルゴリズムが違うだけで、**処理時間の差が10万倍以上**ありました。
こんなに分かりやすく違いが出たので、アルゴリズムの重要性をより実感しました。

もし興味があれば、ぜひ試してみてください。
ここまで読んでいただき、ありがとうございました。
Ubuntu Server 18.04 LTSをUSBから起動させる方法

##概要
この記事では、Ubuntu Server 18.04 LTSをUSBに入れて、サーバーとして使いたいパソコンで起動させる所までを書いています。

##準備
- サーバーとして使いたいPC(今回使うのは、SONYのVAIOです。)
- USB　4GB以上
(Ubuntu Server 18.04 LTSは1GB弱なので、これで十分です。)
- OSをダウンロードするためのパソコン（本来必要ないと思いますが、日頃使い慣れているMacでUSB作成作業をしたかったため採用。）

##やっていきましょう
### Ubuntuのisoファイルをダウンロード
まずはOSを準備していきます。

下のリンクから、UbuntuのServer 18.04 LTSを選んでダウンロードしていってください。
Ubuntuディストリビューションはデスクトップ用とサーバー用で違いますので、サーバー用を選んでください。
![スクリーンショット 2020-01-02 21.05.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280415/e9aeac39-a2d0-1f8f-333e-e365ac7942f2.png)


[Ubuntuのダウンロードページ(リンク)](https://jp.ubuntu.com/download)

### USBのフォーマット
次に準備してあるUSBをフォーマット(初期化)していきます。
今回使うパソコンはMacですので、気を付けてください。
また、フォーマットすると中のデータは全て無くなるので、バックアップはご自身で行ってください。

まずは、USBを本体に接続し、ディスクユーティリティを開きます。

![スクリーンショット 2020-01-02 21.00.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280415/bec8fe9a-1ae3-3ad5-33cd-ebdf3661c0fe.png)

そして、次にUSBの項目を選択し、上の方にある「消去」を押します。


![スクリーンショット 2020-01-02 21.03.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280415/e3209b1c-3a42-65d1-cdc0-e937e6ae5a01.png)
このような画面になります。

ここの「フォーマット」と「方式」を変更します。

今回は、使うデバイスがWindowsですので、MacでもWindowsでも動く「MS-DOS（FAT）」を選択します。
方式は「マスター・ブート・レコード」にして、消去します。
![スクリーンショット 2020-01-02 21.04.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280415/f0b7fff6-2a0f-e988-a7c0-be037f366f79.png)


これでフォーマットは完了です。


### USBにOSを入れる
そして、ダウンロードしたUbuntuをUSBに入れていきます。

やり方としては、Balenaが作っているEtcherというサービスを使っていきます。
*（余談）Etcherはラズパイの設定の時とかにも使えるし、MacとWindowsどちらでも使えるのでとても便利です。
![スクリーンショット 2020-01-02 21.08.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280415/be359ede-2d8f-75bd-ce30-4297fe6ced59.png)
[EtcherのHP(リンク)](https://www.balena.io/etcher/)

インストールして起動します。

![スクリーンショット 2020-01-02 21.25.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280415/a19697a0-dfb9-d22e-27ee-ee9ee92bf111.png)
こちらがアプリを起動した時の画面です。
シンプルで分かりやすいです。

手順は、左のアイコンからisoファイルを選択し、真ん中でUSBのデバイスを選択して、右の「Flash」ボタンを押すだけです。
少し待てば、Ubuntuの入ったUSBの出来上がり。

###パソコン側で起動するデバイスを設定する
UbuntuのサーバーOSの入ったUSBは完成しましたが、これを単に挿しこめば起動できるわけではありません。
設定が必要です。

今回、使用するのはVAIOなので、そちらのやり方を書きます。

本体をF2を押しながら起動させます。BIOSセットアップの画面が表示されるかと思います。

![IMG_4581.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280415/51fdfb54-338d-f7a5-0a24-8a85de1f5b3b.jpeg)
次に方向キーを使ってBootのタブにいきます。

こちらの画面で次の作業をしてください。
- 「Boot Configuration」をDisabled→Enabledにします。
- 「Boot Priority」のExternal Deviceの優先度を1番上にします。

![IMG_1354.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280415/0d1fae47-a3b1-92b2-b705-d42997dbf0d1.jpeg)

作業が終わりましたら、一度シャットダウンしUSBを挿しこんで再度起動します。
すると今までとは違う画面が表示されたかと思います。これがUbuntuのサーバーOSの起動画面になります

##参考記事
これで解説は終わりになります。
参考にした記事やサイトを貼っておきますので、参考にしてください！！

[Mac - USBメモリをフォーマット（消去）](https://pc-karuma.net/mac-format-usb-flash-drive/)
[VAIO電子マニュアル-起動デバイスを変更する-](https://www.sony.jp/support/vaio/products/manual/vpcf13/contents/03_rec/bios/01/01.html)
Bashプロンプトのカスタマイズ

コマンドラインのデフォルトのプロンプトだと `[hoge@localhost ~]$ ` と大体ユーザー名、ホスト名、ディレクトリ名を表示してくれます。
これはこれでいいのですが、Gitステータス情報や時刻も表示できるとより快適です。
ただ、情報が多く横に長くなってしまいコマンドを入力するたびに折り返しが入って見辛いです。

試行錯誤の結果、2行プロンプトにするのが一番利便性が高かったので設定方法をまとめます。

## 環境

- Mac
- 標準ターミナルアプリ
- Bash

## 完成形

<img width="889" alt="スクリーンショット 2020-01-01 2.00.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52879/68ea1011-700d-ac4b-89b8-63b1c8595a72.png">

完成形はこの2行プロンプトです。

```shell-session
ディレクトリ名 Gitブランチ名 ユーザー名@PC名 [時:分:秒]
$ 
```

## 準備

### bash-completion のインストール

Gitのステータス情報を表示するには、 bash-completion をインストールする必要があります。

```
$ brew install bash-completion
```

## 設定

```bash:~/.bash_profile
# bash-completion 読み込み
if [ -f $(brew --prefix)/etc/bash_completion.d/git-prompt.sh ]; then
  . $(brew --prefix)/etc/bash_completion.d/git-prompt.sh
fi

if [ -f $(brew --prefix)/etc/bash_completion.d/git-completion.bash ]; then
  . $(brew --prefix)/etc/bash_completion.d/git-completion.bash
fi

# プロンプトカラー設定
_CYAN="\[$(tput setaf 6)\]"
_GREEN="\[$(tput setaf 2)\]"
_YELLOW="\[$(tput setaf 3)\]"
_RESET="\[$(tput sgr0)\]"

# プロンプトに各種情報を表示
GIT_PS1_SHOWUPSTREAM=1
GIT_PS1_SHOWDIRTYSTATE=1
GIT_PS1_SHOWUNTRACKEDFILES=1
GIT_PS1_SHOWSTASHSTATE=1

export PS1="${_CYAN}\w${_GREEN}\$(__git_ps1 ' %s')${_RESET} ${_YELLOW}\u@\h${_RESET} [\t]\n\$ "
unset _CYAN _GREEN _YELLOW _RESET
```

## デフォルトの設定

```
export PS1="[\u@\h \W]\$ "
```

## 参考

- [「Git補完をしらない」「git statusを1日100回は使う」そんなあなたに朗報【git-completionとgit-prompt】](https://qiita.com/varmil/items/9b0aeafa85975474e9b6)
CentOS8 - Install - Apache

### Apacheインストール
~~~
// Apacheはhttpdというパッケージ名で公開
$ sudo yum install httpd
~~~
~~~
// 確認
$ httpd -version
Server version: Apache/2.4.37 (centos)
Server built:   Oct  7 2019 21:42:00
~~~
- Apacheのインストールと同時に以下のディレクトリやファイルが自動作成
    - /etc/httpd/
    - /etc/sysconfig/httpd
    - /etc/logrotate.d/httpd
    - /usr/lib64/httpd/
    - /var/www/
    - /var/run/httpd/
    - /var/log/httpd/

### 起動と停止
~~~
// 状態確認
$ systemctl status httpd.service
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor pres>
   Active: inactive (dead)
     Docs: man:httpd.service(8)
~~~
- 丸印が赤ならば停止状態
- "Q"を押下して脱出

~~~
// 起動
$ systemctl start httpd.service

// 状態確認
$ systemctl status httpd.service
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor pres>
   Active: active (running) since Thu 2020-01-02 21:23:44 JST; 6s ago
     Docs: man:httpd.service(8)

（以下省略）
~~~
- 丸印が緑ならば起動状態

~~~
// 停止
$ systemctl stop httpd.service
~~~

### 設定確認
~~~
// httpd.conf：設定ファイル
$ sudo vim /etc/httpd/conf/httpd.conf

（中略）

// ServerName
// 何かを設定した方がいいようだが、詳細不明
# ServerName www.example.com:80

（中略）

// ドキュメントルート（公開ディレクトリ）
// この配下に置いたディレクトリ・ファイルを公開
DocumentRoot "/var/www/html"

（中略）
~~~
- 変更する必要がなければそのまま閉じてよい

### テストページ作成
~~~
$ sudo vim /var/www/html/index.html
~~~
- ドキュメントルート配下にテストページ用のファイルを新規作成
- テストページ用のファイル名やコードは任意（以下は例）
    - ファイル名：index.html
    - 記述コード：This is test page.
- 保存して終了

### 起動と確認
~~~
$ systemctl start httpd.service
~~~
- ブラウザから以下のアドレスにアクセス
    - http://localhost/index.html
    
### 自動起動設定と解除
~~~
// 自動起動の設定
$ sudo systemctl enable httpd.service
Created symlink /etc/systemd/system/multi-user.target.wants/httpd.service → /usr/lib/systemd/system/httpd.service.

// 自動起動の確認
$ systemctl list-unit-files -t service
~~~
- リスト内の以下の項目が enabled になっていれば自動起動状態
    - httpd.service

~~~
// 自動起動の解除
$ systemctl disable httpd.service
Removed /etc/systemd/system/multi-user.target.wants/httpd.service.
~~~
- 自動起動したくなければ、自動起動を解除
スクレイピングした画像の連番リネーム

#はじめに
[google-images-downloadでgoogle画像からスクレイピング](https://qiita.com/jin237/items/485ca29c8e5880995bd0)で投稿したスクレイピングのあと処理の連番リネームをしただけです。そんなに難しいことはしてません。

#ソースコード

```python

from google_images_download import google_images_download
import glob
import os
from PIL import Image
```
前回にプラスして、”__from PIL import Image__”をいれる。

```python
config = {
    "Records": [
        {
            "keywords": "Sho Hirano",
            "limit": 10,
            "no_numbering": True,
            "output_directort": "images",
            "image_directory": "Sho Hirano",
            "chromedriver": "C\\[path to chromedirver]\chromedriver\chromedriver.exe",
        }
    ]
}

response = google_images_download.googleimagesdownload()
for rc in config["Records"]:
    response.download(rc)

gifImgs = glob.glob("images" + os.sep + "*" + os.sep + "*.gif")
print(f"removing gif files: {len(gifImgs)} files")
_ = [os.remove(f) for f in gifImgs]
```
ここまでは前回と一緒。これに対して以下のようなコードを入れる。
ここで、for文でenumerate関数を使用して画像ファイルのリネームを行う。

```python
files = glob.glob('./*.jpg')
for (i, old_name) in enumerate(files):
    new_name = ('./shohirano_{0:03d}.jpg'.format(i + 1))
    os.rename(old_name, new_name)
    print(old_name + " → " + new_name)
```
printの内容は以下のようになる。

```terminal
C:\[path to image]\280full.jpg → C:\[path to dir]\shohirano_001.jpg
C:\[path to image]\2966d3c610bf42015a1f853410848b5c.jpg → C:\[path to dir]\shohirano_002.jpg
C:\[path to image]\300px-Hirano_Sho-p2.jpg → C:\[]\shohirano_003.jpg
C:\[path to image]\4f3340a3005c32ffcc64728b75b70792.jpg → C:\[path to dir]\shohirano_004.jpg
C:\[path to image]\5o0JZc.jpg → C:\[path to dir]\shohirano_005.jpg
C:\[path to image]\d8ea5b8f0f2ae32dbf5a62c00c8c3c3e.jpg → C:\[path to dir]\shohirano_006.jpg
C:\[path to image]\ed909d1bd55e96e5bab12881b350f28964e30aa3.jpg → C:\[path to dir]\shohirano_007.jpg
C:\[path to image]\MV5BODk2YzAyNGUtNTI0Yi00MDllLWFlNDUtNGJlMjAwMThmM2Q5XkEyXkFqcGdeQXVyNDQxNjcxNQ@@._V1_UY1200_CR565,0,630,1200_AL_.jpg → C:\[path to dir]\shohirano_008.jpg
C:\[path to image]\NEOBK-2298759.jpg → C:\[path to dir]\shohirano_009.jpg
C:\[path to image]\Sho_Hirano-p2.jpg → C:\[path to dir]\shohirano_010.jpg
```
​
#ファイル内の結果
![スクリーンショット (24).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533115/8c59446c-a3ee-7bd7-aa81-1ff20b1ade03.png)
このように連番にリネームができる。ちなみに平野紫耀にしたがイケメンだよね。それだけ。（田中みな実と迷った笑）
###ファイル構造
scrapy
├── downloads
│　　├── Sho Hirano
│　　│　　├──shohirano_001.jpg
│　　│　　└── ...
│　　└── ...
└── scrapy.ipynb
他の人の名前のファイルを実行したら、downloadsの中にどんどんたまっていく。
#活用
この枚数を増やして、顔だけ切り取ったものをファイルとして蓄積すると、学習用のデータとして活用できる。顔認識などに。
Vue.jsはじめの一歩（HelloWorldしてみよう）

正月で、Vue.jsを触ってみたので、そのアウトプット第一弾。
Vue.jsでとりあえずHelloWorldしたい人向けの記事です。
## できるようになること
・Vue.jsの環境設定
・ローカルサーバでの動作確認


##Vue.jsって何よ
ユーザインタフェースに特化した、JavaScriptフレームワーク
導入のしやすさや、**学習コストの低さ**が特徴(初心者にとって嬉しい)
また、公式ドキュメントも日本化されてる。
[公式ドキュメント](https://jp.vuejs.org/)


##環境設定
###npmが入ってない人
（コマンドラインでnpmと打って、command not foundになる人）
npmというパッケージ管理ツールが必要となります。npmの導入には、 Node.jsのインストールが必要となります。
以下を参考にインストールしてください。
Macユーザ：[MacにNode.jsをインストール](https://qiita.com/kyosuke5_20/items/c5f68fc9d89b84c0df09) @kyosuke5_20 
Winユーザ：[[Node.js] Node.js の導入(Windows編)](https://qiita.com/ksh-fthr/items/fc8b015a066a36a40dc2) @ksh-fthr 

###Vueの環境セットアップ
様々な方法があるようですが、今回は簡単なVue CLIとWebPackを使いました。

Vue CLIのインストール

```
$ npm install -g vue-cli
```

作業ディレクトリに移動して（プロジェクトを作りたいところ）
今回はプロジェクト名がtest-vueとなります。

```
$ vue init webpack test-vue
Project name test-vue
? Project description A Vue.js project
? Author 
? Vue build standalone
? Install vue-router? Yes
? Use ESLint to lint your code? Yes
? Pick an ESLint preset Standard
? Set up unit tests Yes
? Pick a test runner jest
? Setup e2e tests with Nightwatch? Yes
? Should we run `npm install` for you after the project has been created? (recommended) npm
```
色々聞かれますが、Enter連打で進めて行ってください。
これで、テンプレートとなるプロジェクトが完成。

###ローカルサーバで動作確認
```
$ cd test-vue
$ npm install 
$ npm run dev
```
ブラウザ上で、http://localhost:8080/#/ にアクセスすると
<img width="916" alt="スクリーンショット 2020-01-02 20.39.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309863/42005856-e06a-a492-6bee-bcc750f5427d.png">

HelloWorld完了

次回は、Vueのコンポーネント追加と、ルーティングについてまとめたいと思います。
GiNZA(SudachiPy)のユーザ辞書に単語を登録する

#はじめに
数週間前から自然言語処理に携わっており、これまでRとMeCabを用いることが多かったが、最近pythonのGiNZAが自然言語処理の優れたツールだと聞いて移行中。
まずは辞書にない単語を追加する必要があったので流れをまとめてみました。

#環境
- Ubuntu 16.04
- Python 3.6 (pyenv/anacondaの仮想環境)
- GiNZA 2.2.0

#0. GiNZAのインストール
pipコマンドで簡単にインストール出来ます。

```
$ pip install "https://github.com/megagonlabs/ginza/releases/download/latest/ginza-latest.tar.gz"
```

#1. 辞書を用意する
GiNZAの形態素解析には「SudachiPy」を動かしているようです。よって単語の追加は、基本的には「Sudachi」のユーザ辞書への追加方法と同じです。
まずはじめにcsvファイルで辞書を用意します。辞書のフォーマットは
`見出し,左連接ID,右連接ID,コスト,見出し,品詞1,2,3,4,品詞(活用型),品詞(活用形),読み,正規化表記,辞書形ID,分割タイプ,A単位分割情報,B単位分割情報,未使用`
の順で並べます。

```
$ vim add_term.csv
アナと雪の女王,4786,4786,5000,アナと雪の女王,名詞,固有名詞,一般,*,*,*,アナトユキノジョオウ,アナと雪の女王,*,*,*,*,*
```

各項目については[こちら](https://github.com/WorksApplications/Sudachi/blob/develop/docs/user_dict.md)に詳しく書いてありますが、今回は推奨されているIDとコストを割り当てました。不要な項目は「*」を入力してください。上記サイトに例が掲載されているのでそちらから近いものを選択すれば良いと思います。
※csvファイルは「UTF-8」で作成します。

#2. 辞書を作成する
GiNZAをインストールした際にSudachiPyもインストールされているので、sudachipyコマンドを用いて辞書をビルドします。コマンドは`sudachipy ubuild -s [システム辞書のパス] [作成したcsvファイルのパス]` です。

```
$ sudachipy ubuild \
  -s .pyenv/versions/anaconda3-5.2.0/envs/ginza/lib/python3.6/site-packages/sudachidict/resources/system.dic \
  add_term.csv
```

筆者はpyenvで環境構築しているためパスが長いですが、自分の環境にあわせて変更してください。実行すると以下のようなメッセージが表示されます。

```
reading the source file...2 words
writing the POS table...2 bytes
writing the connection matrix...4 bytes
building the trie...done
writing the trie...1028 bytes
writing the word-ID table...14 bytes
writing the word parameters...16 bytes
writing the word_infos...96 bytes
writing word_info offsets...8 bytes
```

成功するとカレントディレクトリに「user.dic」が追加されます。

#3. SudachiPyの設定ファイルに作成したユーザ辞書を追加する
生成されたuser.dicのパスを追加します。設定ファイルの以下の箇所にパスを追記してください。

```
$ vim ./pyenv/versions/anaconda3-5.2.0/envs/ginza/lib/python3.6/site-packages/sudachipy/resources/sudachi.json

{
  "characterDefinitionFile" : "char.def"
  "userDict" : ["user.dicのパス"] #ここにuser.dicのパスを追記してください
  "inputTextPlugin" : [
  ...
  ...

```

#動作確認
- コマンドラインから確認する

GiNZAインストール時にSudachiPyがインストールされているので、それを利用します。

```
$ sudachipy

#追加前
アナと雪の女王
アナ	名詞,普通名詞,一般,*,*,*	アナ
と	助詞,格助詞,*,*,*,*	と
雪	名詞,普通名詞,一般,*,*,*	雪
の	助詞,格助詞,*,*,*,*	の
女王	名詞,普通名詞,一般,*,*,*	女王
EOS

#追加後
アナと雪の女王
アナと雪の女王	名詞,固有名詞,一般,*,*,*	アナと雪の女王
EOS
```


- pythonのGiNZAで使用する

```python:python3
import spacy

nlp = spacy.load('ja_ginza')
doc = nlp('アナと雪の女王を観に行きたい')

for sent in doc.sents:
    for token in sent:
        print(token.orth_)
```

実行結果

```
アナと雪の女王
を
観
に
行き
たい
```

正しく形態素に分割できました！

#結論
GiNZAの形態素解析には中でSudachiPyを使っているということもあり、筆者としてはMeCabの単語追加よりも簡単だった気がします。もし間違っている点などありましたらご指摘をいただけますと幸いです。

#参考サイト
- [GiNZA - Japanese NLP Library](https://megagonlabs.github.io/ginza/)
- [はじめての自然言語処理](https://www.ogis-ri.co.jp/otc/hiroba/technical/similar-document-search/part4.html)
- [SudachiPy (GitHub)](https://github.com/WorksApplications/SudachiPy#customized-dictionary)
- [Sudachiユーザー辞書作成方法 (GitHub)](https://github.com/WorksApplications/Sudachi/blob/develop/docs/user_dict.md)
Dockerについて　エンジニア戦記　#1


積み上げ（今日のお勉強）のまとめ

★Dockerって何？★

ソフトウェアの実行に必要なすべてもの（環境）をコンテナという箱にパッケージ化・共有することで
いつでも、どこでも開発中のアプリケーションを開発、拡張、実行できるようにするソフトウェアプラットフォーム

参考
https://aws.amazon.com/jp/docker/
https://knowledge.sakura.ad.jp/13265/


★ツイでの勉強★

Dockerをお勉強する際に気になった用語のまとめ

●ビルドとデプロイの違い

ビルド　　環境構築　
デプロイ　ビルドした環境を本番環境に適応

例）
ブログ　ブログ作成→プレビュー→保存（ビルド）
　　　　保存したブログを公開する（デプロイ）

●DevOps

ソフトウェア手法の一つ。（開発と運用を有機的に
ビルド、テスト、リリースする環境を迅速かつ確実に構築することを目指す
[Flutter] AppBundle をビルド + 実機にインストール

Flutter の公式ドキュメントは [Build and release an Android app](https://flutter.dev/docs/deployment/android#test-the-app-bundle)。

## 1. [bundletool](https://formulae.brew.sh/formula/bundletool) のインストール
```sh
brew install bundletool
```

詳細は [bundletool の公式ドキュメント](https://developer.android.com/studio/command-line/bundletool) を参照

## 2. App Bundle の build + 実機へのインストール
build flavor による分岐も含めて、こんな感じでスクリプト化しています。普段から頻繁に使うので。

```terminal
export KEY_STORE_PASS=XXX
export KEY_PASS=YYY
./scripts/install_aab.sh -f development -s
```

```scripts/build_aab.sh
#!/bin/sh

# 以下2つは、環境変数としてセットされていることを前提とする
# • KEY_STORE_PASS
# • KEY_PASS

SKIP_INSTALL=0
while getopts sf: OPT
do
    case $OPT in
        s)  SKIP_INSTALL=1
            ;;
        f)  FLAVOR=$OPTARG
            ;;
    esac
done

AAB_PATH=/sampleProjects/${FLAVOR}Release/app-${FLAVOR}-release.aab
APKS_PATH=/sampleProjects/build/app/outputs/app.apks
KEY_STORE_PATH=/foo/bar/key.jks
KEY_ALIAS=key

# 生成済みだとエラーになるので、まず削除する
rm $APKS_PATH

# aab の build
flutter build appbundle -t lib/main_${FLAVOR}.dart --release --flavor ${FLAVOR}

# aab を実機に install しなくていい場合は、ここで終了
if [ $SKIP_INSTALL -eq 1 ]; then
  exit
fi

# bundletool を使って aab, apks を生成する
# See: https://developer.android.com/studio/command-line/bundletool
DEVICE_ID=XXX # 自分の Android 実機
bundletool build-apks \
--connected-device \
--device-id=${DEVICE_ID} \
--bundle=${AAB_PATH} \
--output=${APKS_PATH} \
--ks=${KEY_STORE_PATH} \
--ks-pass=pass:${KEY_STORE_PASS} \
--ks-key-alias=${KEY_ALIAS} \
--key-pass=pass:${KEY_PASS}

# USB で接続済みの端末にインストールする
bundletool install-apks --apks=${APKS_PATH} --device-id=${DEVICE_ID}
```
音楽のコードの構成音をその場で確認できるChrome拡張機能を作った

# Chord Dictionary

音楽のコードの構成音をその場で確認できるChrome拡張機能を作りました。
[Chrome ウェブストア](https://chrome.google.com/webstore/detail/chord-dictionary/lnefagbhokamcaedbeopnhdabkcemkcf?hl=ja)に公開しています。

## 成果物
任意のサイトでコードネームにポインタを当てるとコードの構成音が見れます。
コードが表示されている状態でCtrl+Spaceを押すとコードが再生されます。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">コードの構成音をその場で確認できるChrome拡張機能をアップデートしました。ローマ数字表記追加（認識も可）やクリックでの再生機能も追加して最強になってます💪<a href="https://t.co/idSgKoc0GE">https://t.co/idSgKoc0GE</a> <a href="https://t.co/TkvZpkYvko">pic.twitter.com/TkvZpkYvko</a></p>&mdash; あっしゅん (@ashcolor06) <a href="https://twitter.com/ashcolor06/status/1235516006702841856?ref_src=twsrc%5Etfw">March 5, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 開発

### 経緯
[Mouse Dictionary](https://qiita.com/wtetsu/items/c43232c6c44918e977c9)をみて音楽のコードでも同じ機能があれば便利なのでは？と思って調べてみると、コードの変換に関してはコード進行共有サービスの[rechord](https://rechord.cc/)の開発者さんが[ライブラリ](https://qiita.com/comorebi_notes/items/c8b4dde0f6bd91666a5c)を公開されており、割と簡単に作れそうだったので開発を始めました。

### ソースコード
https://github.com/ashcolor/chord-dictionary

### Vue + Chrome拡張機能
勉強がてらVueを使いたくて調べていたところ、VueでChrome拡張機能を作成するためのテンプレートを作成している方がいたのでお借りしました。
https://github.com/Kocal/vue-web-extension

以下のコマンドでテンプレートが一瞬でできます。

```
# vue initがインストールされていない場合、以下のコマンドを実行
# npm install -g @vue/cli-init
vue init kocal/vue-web-extension my-extension #オプションを聞かれるので適当に答える
cd my-extension
npm install
npm run watch
npm run build
npm run build-zip #zipファイル生成
```

### 使用したライブラリ
#### chord-translator
https://github.com/comorebi-notes/chord-translator
(ver1.1.0から次に紹介するChordNoteに変更しています。)
コードネームを構成音に変換してくれます。

```
chordTranslator("A", "add9")  // ["A3", "Db4", "E4", "B4"]
```

#### ChordNote
https://graphemecluster.github.io/ChordNote.js
[ぐらふぃーむさん](https://twitter.com/graphemecluster)が作成したスクリプトです。
chord-translatorと同じくコードネームを構成音に変換してくれます。(今回の拡張機能では多少手を加えています。)
自前で実装予定だったオンコードの処理や♭と♯の表記問題(全てのコードが♭表記になる)もこのスクリプトを入れて一発で解決しました。感謝です。

#### Tonal
音楽理論全般で役に立つライブラリです。
ChordNoteを使用した場合に返ってくるダブルシャープやダブルフラットがtone.jsに対応していないため、ノートを正規化してくれるNote.simplifyという関数を使いました。

```
 Note.simplify("C##")  // => "D"
```
他に移調も簡単にできるので今後の機能追加で利用する予定です。

#### tone.js
https://tonejs.github.io/
Web Audio APIを簡単に扱うことができるJavaScriptライブラリです。コードの再生に使いました。サンプリングにも対応しているため、数ファイルの音源から全ての音階の音を出力することができます。
（今回はC1~C5までの5つのmp3のみ使用）

#### vexflow
http://www.vexflow.com/
楽譜の描画ライブラリです。多機能なライブラリですが今回は単純に白玉を描画しているだけです。
mysql 8k の壁を超える手順

# 現状をチェック

```
show table status;
```

を打つと、`Row_format=Compact` になっていると思います。

```
show variables like "%innodb_file%";
```

これをうつと

`innodb_file_format=Antelope`

になっていると思います。


# この状態で以下をやっても無駄です

- `ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;` をつけた create table をしても
-  `ALTER TABLE tbl ROW_FORMAT=DYNAMIC;` なんかをしても


# Barracuda にしてあげる


```conf:my.cnf
innodb_file_format = Barracuda
innodb_file_format_max = Barracuda
```

などとしてあげる。

これで、alter table などで Row_format を変更することができるようになります。


# AWS での変更方法

参考 https://medium.com/tensult/converting-rds-mysql-file-format-from-antelope-to-barracuda-ba8a60b2c1ec
Vue.DraggableをTypeScriptで使用した際、moduleが見つからないというエラーが出た際の解決方法

## Prologue
TypeScriptでVue.Draggableをimportした際、以下のようなエラーが出ました。

```
Could not find a declaration file for module 'vuedraggable'. '/******/node_modules/vuedraggable/dist/vuedraggable.umd.min.js' implicitly has an 'any' type.
Try `npm install @types/vuedraggable` if it exists or add a new declaration (.d.ts) file containing `declare module 'vuedraggable';`
```

## 環境
- macOS: 10.15.2
- node.js: 10.16.0
- terminal: iTerm
- VS Code

- Project概要
    - 言語: Vue.js, TypeScript
    - パッケージマネージャ: `yarn`

インストールした際のコマンド:

```
yarn add vuedraggable
```

## 確認と解決方法の決定

1. package.jsonとnode_modulesを確認し、該当のmoduleがインストールされていることを確認。

2. 確認するとTypeScriptに関する[Issue](https://github.com/SortableJS/Vue.Draggable/issues/379)が残ったままなので(2020/1/2時点)がありました。エラー内容とIssue内のコメントを参考に以降の内容で解決を図ります。

## 実際に解決した方法

1. `d.ts`ファイルを¥src内に作成。ここでは`types.d.ts`。

```
¥src¥types.d.ts
```

2\. 宣言を書きます。
 
```
declare module 'vuedraggable'
```

3\. ここまででIssueにもあるように、VS Codeのエラーが消えませんでした。うまく読み込めていないかと思い、VS Codeを再起動したところ、エラーはなくなりました。 

終了。

## Epilogue

### 課題

参考:
https://www.typescriptlang.org/docs/handbook/namespaces-and-modules.html
https://developer.hatenastaff.com/entry/2016/06/27/140931

- ファイル名について
特に明記されていないこととミニマムなプロジェクトだったため、`d.ts`ファイルは`types.d.ts`としました。
命名のルールや設計的レベルで良いものがあれば、それに則って使用したいと思います。
また、`@types`ディレクトリを作成して、`tsconfig.json`のcompiler設定を追加する方法もいつか試して見たいと思います。

- VS Codeを使用していると、たまにこのような保存？設定？に関して遅延のようなものが起こります。何故...VS Codeはエラーがわかりやすく表示され助かっているので、この遅延に関する良い解決方法もあれば追って記載します。
GitHub でリポジトリを作成・削除する方法

##GitHub でリポジトリを作成・削除する方法

###GitHubでリポジトリを作成
GitHubにログインして、Your Repositoriesのページにいきます。
![new1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559347/1a545167-0151-da9f-2532-66d1c769fe8f.png)
緑色のNEWボタンがあるのでクリックします。
![new2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559347/a3574f04-2ff7-6c94-1b3b-601083ffdc98.png)
リポジトリの名前を入力してCreate Repositoryをクリックすればリポジトリを作成できます。
PublicとPrivateを選択することも可能です。

###GitHubでリポジトリを削除する方法
![githubdelete.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559347/fab0883d-7489-b08e-bd8e-39b63c6ce495.png)
削除したいリポジトリの中でsettingsをクリックします。
![githubdelete2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559347/dbf9796b-6543-a228-bb76-f0dd41042b33.png)
settingsページの下部の方にDanger Zoneがあります。その中のDelete this repositoryをクリックします。
![githubdelete3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559347/971597f1-41d6-4953-e7f6-2642532998a3.png)
削除したいリポジトリ名を入力することでリポジトリを削除することが可能です。
adb(コマンドライン)でlogcat(Androidのログ)を表示する

Android Studioのlogcatがデバイスを認識してくれずエラーログなどが一切見れない...(なにかアップデートしたのが原因か?)
Android StudioやSDKを再インストールしたものの直らず...
途方に暮れていたところ、adbからならlogcatを表示できることがわかったのでメモ。  
  
# 前提
- OS:Win10
- adb.exeへパス通しされていること  

# adbでlogcat表示
PowerShellなどから下記コマンド入力  

```
adb logcat
```  
  
このままだと有象無象のログが出てきて見づらいです。
下記のように書くとフィルタされます。  

```
adb logcat -s [フィルタしたい文字列]:[エラーレベル]
```

- フィルタしたい文字列:flutter
- エラーレベル:指定なし  
で絞りたい場合は下記。

```
adb logcat -s flutter:*
```
  
詳しくは参考サイト参照  
  
# 参考
https://maku77.github.io/android/filter-logcat.html
cdせずに別ディレクトリでコマンドを実行

# 初めに
Rust製のコマンドラインツール [Exeat](https://github.com/j-hira/exeat) を作成しました。ディレクトリとコマンドを指定することでcdすることなく別ディレクトリでコマンドを実行することができます。

## 開発環境
macOS Catalina 10.15.2
Rust 1.40.0

## Exeatの作成
Qiita初投稿です。
最近Rustを学び始め、なにかコマンドラインツールでも作ってみたいなーと思ってました。そこで今のディレクトリから別のディレクトリにいるようにコマンドを実行できたら便利だなと思い作ってみました。Rustで作るということでcargoを使ってプロジェクトを作成しました。

```bash
cargo new exeat --bin
```
ソースコードは[GitHub](https://github.com/j-hira/exeat/blob/master/src/main.rs)で公開しています。
１５行という非常に短いプログラムでファイルも一つしかありません。Rustでは標準ライブラリの`std::process::Command`で外部コマンドを実行することができます。またこのライブラリが非常に便利で、実行するディレクトリも引数も自由に指定することができます。ということで実現したいことすべてこのライブラリにまかせるだけで良かったです。

## Exeatの使い方
cargoを使用しているので簡単にビルド、実行を行うことができます。

```bash
cargo run ~/rust ls -a
```
このように１個目の引数に実行したいディレクトリ、２個目以降の引数にコマンドとオプションを指定することができます。このコマンドだと `~/rust` で `ls -a` を実行することができます。もちろん`ls`だったら引数でディレクトリを指定することができますが、普通だったらディレクトリ指定できないコマンドでもディレクトリを指定することができます。でもこのままだとプロジェクトがあるディレクトリでしかこのプログラムを実行できないのでcargoを利用してビルドしてパスを通してどのディレクトリでも実行できるようにしておきましょう。

```bash
cargo build --release
```

## 最後に
これからもRustで色々作れたらなーと思ってます。まだRust初心者なので間違ってることなどご教授いただけたら嬉しいです。
rbenv でインストールした irb で readline が効かなくなったときにやったこと

# rbenv でインストールした irb で readline が効かなくなったときにやったこと

rbenv は Homebrew でインストールしています。たぶん、OS アップグレードか何かのタイミングで、irb のキー移動や補完が効かなくなっていたので、readline 関係の問題だろうということで調べた結果、[こちらの手順](https://github.com/rbenv/ruby-build/issues/1138#issuecomment-510011376)で治りました。

1. `brew reinstall rbenv ruby-build readline`
2. インストールされているバージョンを `rbenv versions` で確認し、すべて `rbenv uninstall`
3. 改めて `rbenv install VERSION`

```
[Ace] $ rbenv install 2.7.0
...
Installing ruby-2.7.0...
ruby-build: using readline from homebrew
```

## どうでもいい補足

[readline](https://tiswww.case.edu/php/chet/readline/rltop.html) ライブラリは補完やヒストリーを実現するための便利なライブラリですが、ライセンスが [GPLv3](http://www.gnu.org/licenses/gpl.html) であるため、Mac OS X では NetBSD 由来の libedit がインストールされており、libreadline は libedit へのシンボリックリンクになっています。

```
$ ls -la /usr/lib/libreadline.dylib 
lrwxr-xr-x  1 root  wheel  15  2  2  2019 /usr/lib/libreadline.dylib -> libedit.3.dylib
```

しかし、少なくとも数年前までは libedit にはいくつかの問題があり、ユーザーがおのおの readline をインストールして有効にしている、と認識しています。

- [libedit(editline)の闇を垣間見る - ¬¬日常日記](https://keita-yamaguchi.hatenadiary.org/entry/20080717/1216270090)
- [MySQLクライアントに日本語が入力できない理由 - Suzna Developer Blog](https://developer.suzna.com/entry/2018/04/23/103928)

もっとも、最近は Mac OS も積極的にアップグレードしていないので、状況は変わってるかもしれない。
#Ruby でお手軽にハッシュの差分を確認するには引き算

差分というか差分チックな。ちょっとした差を確認するならお手軽そう。


```rb
({a: 1, b: 2, c: 3}.to_a - {a: 1, b: 2, c: 3}.to_a).to_h
# => {}

({a: 1, b: 2, c: 3}.to_a - {a: 1, b: 2}.to_a).to_h
# => {:c=>3}

({a: 1, b: 2, c: 3}.to_a - {a: 1, b: 7}.to_a).to_h
# => {:b=>2, :c=>3}

# 検知できない
({a: 1, b: 2, c: 3}.to_a - {a: 1, b: 2, c: 3, d: 4}.to_a).to_h
=> {}
```

ちゃんと見たい場合は hashdiff gem とかで

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2904








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Jestによるテスト実行時のタイムゾーンを固定する

# タイムゾーンによるテストへの影響

Jestを使って現在時刻の表示処理のようなテストをする場合、タイムゾーンが問題となるケースがあります。これは、開発に使うPCのタイムゾーンと、テストを実行するCIのタイムゾーンが異なるケースがあるためです。

例えば、開発用マシンは日本標準時(UTC+9)になっているのに対し、CircleCIやTravisCIなどのタイムゾーンがUTC+0だと、テストで得られる結果が異なり、どちらか一方で行われたテストが失敗することがあります。

# Jestのテスト実行時のタイムゾーン指定方法

Jestでテストを実行する際に、環境に依存することなく明示的にタイムゾーンを指定する場合は、 [globalSetup](https://jestjs.io/docs/en/configuration#globalsetup-string) で `process.env.TZ` を指定すれば良いです。具体的には以下のように設定します。

```json:package.json
{
  "jest": {
    "globalSetup": "./jest-global-setup.js"
  }
}
```
(上は `package.json` を例としていますが、 `jest.config.js` を使用している場合も設定方法は同様です)

```javascript:jest-global-setup.js
module.exports = async () => {
  process.env.TZ = 'Asia/Tokyo'; // 固定したい任意のタイムゾーンを指定
};
```

# その他の方法

なお、蛇足ではありますが、 [CircleCIの場合はコンテナのタイムゾーンを指定する方法](https://circleci.com/docs/2.0/faq/#how-can-i-set-the-timezone-in-docker-images) もあるので、このアプローチを使うこともできます。

# 参考
- [How do I set a timezone in my Jest config?](https://stackoverflow.com/questions/56261381/how-do-i-set-a-timezone-in-my-jest-config)
Swiftでのdoの使われ方

# はじめに
Swiftで調べ物をしているとdoが急に出てきて公式レファレンスにも特に言及がなく困ったりしたので簡単に整理します。

1. do-catch文(エラーハンドリング)
2. do文(catch無し)
3. do while -- swift2以降はrepeat whiile
4. 番外編：RxSwiftで副作用を記述する

# 1.do-catch文
doの下にcatchがあれば**エラー処理構文**です。

```swift

// 例外(エラー)を持ちうるメソッド
func eee() throws {
...
}

// 呼び出し元
func method() {
    do {
        try? eee()
    } catch {
        // エラー処理
    }
}
```
まずエラーも持ちうるメソッドをthrowsキーワードを付けて記述します。
それを**do**のスコープ内でtryキーワードを付けて呼んであげると、エラー時にcatchスコープで捕捉できるというアレです。
これは一番オーソドックスなので調べればいくらでも情報が出てくると思います。
[レファレンス](https://developer.apple.com/documentation/swift/cocoa_design_patterns/handling_cocoa_errors_in_swift)も充実しているのでそちらをどうぞ。

# 2.do文(catch無し)
むしろ困るのは**catch無し**で登場した場合ではないでしょうか。
調べてもdo-catchばかりで「お前はもういいよ！」となっているのでは？(私はそうでした)

これも文法的にはdo-catchのcatchが無いだけで、別概念というわけではないようです。
しかし、用法は異なり、スコープという機能そのものを使いたいときによく利用されるようです。

例えばスコープ内で定義した変数はその中のみで有効です。なので実行が終わればそのインスタンスは解放されるはずです。
その解放をPlayground等で確認するため使われたりします。
簡単な例です。

```swift
class Prof {

    let name: String

    init(name: String) {
        self.name = name
        print("init:" + self.name)
    }

    deinit {
         print("deinit:" + self.name)
    }
}

let prof = Prof(name: "Tarou")

do {
    let profInDo = Prof(name: "Jirou")
}
```

### 結果

```
init:Tarou
init:Jirou
deinit:Jirou
```
インスタンス化しただけのprofは当然解放されません。
しかし、**doのスコープに入れたprofInDoはdeinitまで呼ばれている**のが確認できます。
このように手っ取り早くスコープを使うためにdoを使います。

## do-while
これはSwift1.2までの記法で、Swift2以降は**repeat while**となります。
repeat while自体あまり使わない(偏見)のでこれでつまる人はまずいないでしょう(偏見)。

## 番外編:RxSwiftで副作用を記述
多くの現場で使われているRxのライブラリであるRxSwiftのオペレータにもdoは存在します。
弊社のプロジェクトでも無数に使われています。
observableが発行するイベントとは別に、何らかの処理を記述したい場合に使います。
### 定義
```swift

    public func `do`(onNext: ((Self.Element) throws -> Void)? = nil, afterNext: ((Self.Element) throws -> Void)? = nil, onError: ((Error) throws -> Void)? = nil, afterError: ((Error) throws -> Void)? = nil, onCompleted: (() throws -> Void)? = nil, afterCompleted: (() throws -> Void)? = nil, onSubscribe: (() -> Void)? = nil, onSubscribed: (() -> Void)? = nil, onDispose: (() -> Void)? = nil) -> RxSwift.Observable<Self.Element
```
以上になります。
誤りや他の用法がありましたらご指摘くださいませ。
参考:詳解Swift第5版
Ubuntu の Network設定

# はじめに
Ubuntu の Network 設定は17.10から netplanベースに変更されている。ただ、Ubuntu を Desktop として利用する場合は従来通りの NetworkManager ベースとなっている。どうなっているのかのメモ。
[ここ](https://www.komee.org/entry/2018/06/12/181400)の記事が一番わかりやすかった。

## 調査したバージョン
- Ubuntu 18.04. Ubuntu Desktop での Network設定は、19.10でも NetworkManager 経由で変わりはなかった。

- Ubuntu 20.04. Ubuntu Desktop でも変更なし
- Ubuntu 22.04. Ubuntu Desktop でも変更なし

### Ubuntu Desktop のデフォルト
Ubuntu DesktopのデフォルトNetPlan設定. 18.04 ～ 22.04では共通だった。

```console:/etc/netplan/01-network-manager-all.yaml
# Let NetworkManager manage all devices on this system
network:
  version: 2
  renderer: NetworkManager
```

この`renderer`キーは、NetworkManager か networkd のどちらかを入れられる。Desktop を構築した場合のデフォルトは NetworkManagerとなっている。 Ubuntu Server だと networkd になる. NetworkManager は GUI 操作で設定できるため、Desktop PC として利用するのならこれでも良い。

この実体がどこかというと、`/etc/NetworkManager` 配下にある。GUI上からInterface設定をデフォルト値から編集すると、`/etc/NetworkManager/system-connections/`配下にConfigが生成される。

少し複雑なことを実現するためには NetworkManager よりも networkd を使うべきなのだろう。ただ、 NetPlan を使えばすべてを解決できるかというとそうでもない。例えば NetPlanでは Promiscuous Interfaceを設定できず、[スクリプトで頑張る](https://ubuntuforums.org/showthread.php?t=2390958)ことが推奨されていたりする。頑張った例は[これ](https://qiita.com/Shakapon/items/2dce71e2f6de1e59b2e1#network-dispatcher)。

### NetPlanを実際に書いてみる。
```console:/etc/netplan/01-network-manager-all.yaml
network:
  version: 2
  renderer: networkd
  ethernets:
    ens3:
      dhcp4: false
      addresses: [192.168.1.66/24]
      routes:
      -  to: default
         via: 192.168.1.1
      nameservers:
        addresses: [8.8.8.8] 
```

ブリッジドメインとかを定義する際は　renderer を networkd にしたほうが使いやすい。
Ubuntu 22.04から ```gateway4```が非推奨となり、```routes``` コマンドの利用が推奨されるようになった（ gateway4 でも動きはした）。

### netplanの適用
### いきなり変更する
```
$ sudo netplan apply
```

### 一息入れる
Syntax Checkしたり、ダメだったら切り戻したりするには ```try```オプションをつける。こっちのほうが安心してできる。
```
$ sudo netplan try
$ sudo netplan try --timeout 10
[sudo] password for shakapon: 
Do you want to keep these settings?
Press ENTER before the timeout to accept the new configuration
Changes will revert in  10 seconds
（10秒後）
Reverting.
```

# 参考

### アドレス/ルーティング設定確認コマンド群
```
$ ip address show ens3
$ ip link
$ ip route
```

#### DNS設定確認
```
$ resolvectl
Global
       Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
resolv.conf mode: stub

Link 2 (ens3)
    Current Scopes: DNS
         Protocols: +DefaultRoute +LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
Current DNS Server: 8.8.8.8
       DNS Servers: 8.8.8.8

$ systemd-resolve --status #20.04ではこれも利用可能
```

Ubuntuが名前解決する際、実際にどのDNSを叩いているかを確認するコマンドが、22.04から```
resolvectl```に変更された。```resolvectl```は20.04でも利用可能で、出力結果は従来の```systemd-resolve --status```から変わらない。