OmniAICreator/Qiita-1.07M huggingface dataset:
Let’s EncryptでサイトをSSL化する方法

Let’s Encryptを使うと無料でサイトをSSL化できます。


###### 環境

- さくらVPS
- Debian　10.3


##### 手順
以下の３つのコマンドを実行してください。

```
$ wget https://dl.eff.org/certbot-auto
$ chmod a+x certbot-auto
$ ./certbot-auto
```

最後のコマンド` ./certbot-auto`を実行すると、SSL化するドメインはどれにしますか？などといった質問が色々表示されます。

これに答え終わると、自動で設定ファイルを書き換えてくれているので、質問で選択したドメインにアクセスしてみると、すでにSSL化が完了しています。

いや〜、すごい簡単。


###### 参考
https://free-ssl.jp/usage/install-certbot.html:title
【kotlin】Map型 コレクション

#■Map型
キーと値を紐づけて格納する。

```kotlin
//書き方
val map = mapOf("キー" to "値","キー" to "値")
```

#■値へのアクセス
List型や配列などはインデックス番号を使って値にアクセスしていました。
Map型はインデックス番号の代わりに値にキーが決められているので
キーを使ってアクセスします。

``` kotlin
//キーがtoの左です。
val map = mapOf("炎柱" to "煉獄さん", "水柱" to "富岡さん","蛇柱" to "伊黒さん")

println(map["炎柱"])
//結果: 煉獄さん

println(map["風柱"])
//結果: null
```

###■全てのキーへのアクセス
▼keys

``` kotlin
println(map.keys)
//結果: 炎柱,水柱,蛇柱
```

###■全ての値へのアクセス
▼values

``` kotlin
println(map.values)
//結果 : 煉獄さん,富岡さん,伊黒さん
```

###■要素数
▼size

``` kotlin
println(map.size)
//結果: 3
```

#■MutableMap 可変可能
空のMutableMap()

``` kotlin
//キーがString型で値がInt型
val a = mutableMapOf<String,Int>() 
//もう一つの書き方
val a: MutableMap<String,Int> = mutableMapOf() 
```

###■MutableMapのさまざまな値の追加方法

▼インデックス番号のようにキーを設定、=の右に値を入れる。

``` kotlin
a["孫悟空"] = 100 
```

▼put(キー,値)

``` kotlin
a.put("ベジータ",200)
```

▼+=演算子を使用
キー to 値

``` kotlin
a += "トランクス" to 400
```

結果

``` kotlin
println(a)
// ["孫悟空" to 100, "ベジータ" to 200, "トランクス" to 400]
```

###■複数のキーと値を追加

▼putAll
キーと値のペアを複数用意したlistOf()を入れる。

``` kotlin
a.putAll(listOf("パン" to 500, "悟天" to 600))
```

▼+=演算子

``` kotlin
a += mapOf("パン" to 500, "悟天" to 600)
```

###■値の消去
どっちも同じ処理キーのみでも大丈夫

``` kotlin
a.remove("孫悟空")
a.remove("孫悟空",100)
```

▼全て消去

``` kotlin
a.clear()
```

###■ループ処理
for文
▼引数
k = キー
v = 値

``` kotlin
for((k,v) in a)  {
  println("${k}の給料は${v}円です。")
}
```

▼forEach

``` kotlin
a.forEach{(k,v) -> printin("${k}の給料は${v}円です。")}
```

▼itに引数を置き換えるver
it.Key = キー
it.values = 値

``` kotlin
a.forEach{println("${it.key}の給料は${it.values}円です。")}
```

#■List型の中にMap型
空のList型の中に空のMap型

どちらも意味は同じ

``` kotlin
//型指定を後に記述
val hoge = mutableListOf<MutableMap<String,String>>()

//型指定を最初に記述
val hoge: MutableList<MutableMap<String,String>> = mutableListOf()
```

▼値の追加
中身がMap型でも基本はList型なのでaddを使う。
中にMap型のコレクションを書く

変数に先にmap型を代入して変数を渡してもよい

``` kotlin
hoge.add(mutableMapOf("いぬ","ねこ"))
```

▼値の消去
インデックス番号を使って消すのが楽そう
removeAt(インデックス番号)

```kotlin
hoge.removeAt(0)
```
RAILS_ENV=production rails db:create db:migrate　コマンドがエラーになる時の対処法

Railsアプリのpriduction環境用のデータベースを作成するときに、`RAILS_ENV=production rails db:create db:migrate`コマンドを実行したのですがエラーが発生しました。

```terminal
$ RAILS_ENV=production rails db:create db:migrate

FATAL:  Peer authentication failed for user "test_2"

Couldn't create 'hello_rails_production' database. Please check your configuration.

rails aborted!

PG::ConnectionBad: FATAL:  Peer authentication failed for user "test_2"

/home/horikoshi5/hello_rails/bin/rails:9:in `<top (required)>'

/home/horikoshi5/hello_rails/bin/spring:15:in `<top (required)>'

bin/rails:3:in `load'

bin/rails:3:in `<main>'

Tasks: TOP => db:create

(See full trace by running task with --trace)

```

 

これを解決するには、`/etc/postgresql/11/main/pg_hba.conf`ファイル（11の所は入っているpostgresqlのバージョンによって異なります）の

```

local   all             all                                     peer

```

を下記のように変更すれ必要があります。

```

local   all             all                                     md5

```

 

そして最後にpostgresqlを再起動すれば完了です。

```terminal
$ sudo systemctl restart postgresql.service 
```

#### 参考

[https://ryotatake.hatenablog.com/entry/2019/05/03/postgresql_peer_authentication_failed:title]
AWS Wavelength (KDDI / 5G MEC)を気軽に試せるAWS CDK環境を作った件

# はじめに
AWS Wavelength流行ってますよね！？（当社比）

ただAWS Wavelengthは複雑なEC2やVPCの設定をしなければならず、ハードルが非常に高く試しづらい状況でした。
　
そこでWavelengthの最小構成をほぼ自動で構築できるリポジトリを作成しました。

AWS CloudFormationとその構成をコードで構築できるAWS CDKで作成しました。

不要になればコマンド一つですべて消すことができます。

# 使い方

次に今回準備したリポジトリをCloneします。

使い方はREADME.mdに記載してます。

https://github.com/ChujoHiroto/AWSCDKWavelengthExample

# まとめ
他にAWS CloudFormationでWavelength環境を構築した情報がほとんどなく苦労しましたが、これで試せるようになりました。

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-eip.html

このAPIだけ改善されればCloudFormationですべて管理できるようになるのですが、、、

キャリアIPに対応したAPIが出るの待ってます。

以下にAWSのフォーラムを用意したので、回避方法を知っている方がいればぜひ情報ください。

https://forums.aws.amazon.com/thread.jspa?threadID=341152

次はUnreal Engine 5 Pixel StreamingをAWSに自動デプロイする記事が書きたいなと思ってます。

# 関連、参考記事

手動での設定、遅延、スループットの測定、既存のAWS EC2との性能比較をしている記事です。

https://qiita.com/yyasuda/items/ca1727a89dfb707e80b2

https://qiita.com/yyasuda/items/7b6d374710db2c912fa5

https://qiita.com/yyasuda/items/205596e5204d90bf0ee4
ディスプレイ・キーボード無しでRaspberryPi初期設定

ラズパイの初期設定の際ディスプレイやキーボードマウスを用意するのが面倒なことがあるかと思います。そんな場合に使える備忘録です。
#環境
PC : ubuntu20.04
RaspberryPi : RaspberryPiZero
#Imagerの準備
公式ページ(https://www.raspberrypi.org/software/) からimagerをダウンロードし、 `sudo apt install ~/Download/rpi-imager` とします。ubuntuSoftwareにも公開されていますが私の環境では書き込みがうまく行かなかったのでこちらの方法をおすすめします。
書き込む前にSDカードをフォーマットしましょう
Operating Systemの中にERASEがあるのでそれを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/522264/5f858fd5-238d-3dc1-a08b-a63e511151a9.png)
Storageを適宜選択後Writeを押下します。誤って違うドライブを選択しないよう気をつけましょう。データが消えてしまいます。
#OS書き込み
ctrl+shift+Xを押下すると設定画面が出てきます。
EnableSSHとConfigurewifiを予め設定しておくことがディスプレイやキーボードなしでセットアップするための要点です。適宜設定しましょう。Enable SSHからAllow public-key authentication onlyを選択し、公開鍵を設定することでセキュアに使うことが出来ます。wifiに関しては5GHz帯に対応していないモデルがあるので気をつけましょう。

2022/01/12追記
sshつながらないね?とディスプレイつないでみたらwifiがoffになっていました...pi4だったので有線LAN用意してあげて事なきを得ましたがこれがzeroとかだったら...念の為ディスプレイとHIDデバイスの用意はあったほうがいいですね(なんのためのこの記事なんだろう

OSやStorageを適宜設定しWRITEを押下します。
書き込みがうまく行かない場合はターミナルから`sudo rpi-imager`と起動してやるとうまく行くことがあるようです。

#起動
出来上がったSDをラズパイに刺し、電源を投入後しばらく待ち、`ssh pi@raspberrypi.local`(ホスト名を設定していない場合)とするとsshで接続できます。
#初期設定
初期設定として、`sudo raspi-config ` から
SDカード全体を利用するために 
``6 Advanced - OptionsA1 Expand Filesystem`` 
raspberryPiOSのアップデートのために
`8 Update `
その他アップデートのために
`sudo apt-get update -y && sudo apt-get upgrade -y`
は最低限走らせましょう。その他ufwやsshのポート変更などお好みで設定していけば最低限使えるようになるかと思います。
HerokuでとりあえずJava(Spring Boot)アプリを動かすまでのメモ DB周り

[前回](https://qiita.com/epsilon_87_myo/items/0d6ce36f0fe38beae776)の続き

## 自端末からデータベースに接続する

`psql` を入れていれば `heroku pg` で操作できるが
今回はGUIツールで操作します。

ツールは `PSqlEdit` を使いました。

### 接続情報の確認
Herokuのページ上で `Resources` タブから `Heroku Postgres` を選ぶ
`Settings` タブの `Database Credentials` から接続情報が確認できる

![02-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628749/d651458d-ac42-bcc8-4e70-2366f446819d.png)


これをGUIツールの接続情報に入力すればOK

注意書きにもあるように この情報は変更されることがあるようで永続的なものではないそうです。

## バックアップ関係
[Heroku PGBackups](https://devcenter.heroku.com/articles/heroku-postgres-backups) に書いている

プランによって保持する期間とかに制限があるらしい

`Durability` からGUIで操作することもできるが、コマンドラインで実行することもできる。
以下は基本的なコマンドのメモ

### バックアップの一覧
```
heroku pg:backups
```

### バックアップの取得

```
heroku pg:backups:capture
```

### バックアップのスケジューリング

#### スケジュールの確認
```
heroku pg:backups:schedules
```

#### スケジュールの設定
[ここ](https://devcenter.heroku.com/articles/heroku-postgres-backups#scheduling-backups)

```
heroku pg:backups:schedule --at "00:00 Asia/Tokyo"
```
でできる

Windowsだとダブルクォーテーションで囲むそうだ

#### スケジューリングの解除
```
heroku pg:backups:unschedule
```



とりあえずこれだけやれば
最低限のWebアプリは動かせるはず..
Linux OSの管理ツール Cockpit

今回はLinuxOSで使用可能な管理ツールであるCockpitについて紹介したいと思います。
現場で使用しているツールではありませんが、息抜きを兼ねています。

#Cockpitとは
Cockpitは、webブラウザ上でサーバーの管理を行うためのツールです。
CentOS8(おそらくRHEL8も)にて標準でインストールされるツールとなります。※インストール時に選択したアプリケーショングループによってはインストールされない場合もあります
Cockpitでは主にCPUやメモリ等の使用率を監視したり、ユーザーアカウントの管理を行ったりログを確認したりすることが出来ます。
また、別途プラグインをインストールすることで機能を追加できます。

#Cockpitのインストール
先程説明した通り、CentOS8系であれば標準でインストールされますが、CentOS7系の場合は手動でインストールする必要があります。
まずはパッケージのインストールを行います。

```
yum install cockpit
```

インストールが完了しましたら、サービス起動と有効化を行います。

```
systemctl start cockpit.socket
systemctl status cockpit.socket
systemctl enable cockpit.socket
```

最後にCockpitのGUIへアクセスするためのポートを開けます。

```
firewall-cmd --add-port=9090/tcp --zone=public --permanent
firewall-cmd --reload
```

インストールは以上となります。

#Cockpitへのアクセス
Cockpitのインストールが完了しましたら、`http://<サーバーのIP>:9090/`へアクセスします。
以下の通りログイン画面が表示されれば正常です。
なお、Cockpitの場合は接続するブラウザとの相性があるようで、相性が悪いブラウザでアクセスすると正常に接続出来ません。
例えばChromeでアクセスしますとログイン後に真っ白の画面しか表示されませんので、FireFox等別のブラウザでアクセスする必要があります。

![CP01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/858317/78508ec8-3220-c5a8-8216-e9dfb042acc3.png)

ログインすると以下の画面が表示されます。
トップページではマシンの基本的な情報とCPU等の使用率が表示されています。

![CP02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/858317/6fcdb9a1-7fb7-4bf6-e0ac-a5e08e56ea85.png)

左ペインにて様々な項目が表示されていますが、各項目の説明については次回実施します。
なお、「ストレージ」と「仮想マシン」の項目は標準では存在していません。別途`cockpit-storaged`や`cockpit-machines`のインストールが必要です。
「仮想マシン」については正しく機能させるために他にもインストールが必要なパッケージがありますが、次回以降に紹介したいと思います。
ES7 ECMAScript 2016 入門

### はじめに
今回ですが個人的にES７以降の新機能や構文で追えていない知識がありましたので、自分用のメモとして記述します。今更感も否めないですがそこはご了承くださいませ🙇‍♂️
また、今回はES7のみですが、次回以降でES8以降の機能も順番に書いていきたいと思います。

### そもそもECMAScriptって？
最初ですので簡単にECMAScriptに触れておきます。
ECMAScriptは、European Computer Manufacturer Associationの略称で、Ecma Internationalによって標準化されたJavaScriptを実装する上での仕様です。ES６（ECMAScript 2015）以降は、毎年６月に公開され、正式な仕様となっております。


* ECMAScriptのバージョン（ES6以降）

| バージョン |略称（通称) | 公開日 |
|:------------:|:------------:|:------------:|
| ECMAScript 2015       | ES2015(別名ES6)        | 2015年6月         |
| ECMAScript 2016     | ES2016(別名ES7)      | 2016年6月       |
| ECMAScript 2017       | ES2017(別名ES8)        | 2017年6月         |
| ECMAScript 2018         | ES2018(別名ES9)          | 2018年6月           |
| ECMAScript 2019       | ES2019(別名ES10)       | 2019年6月       |
| ECMAScript 2020    | ES2020(別名ES11)     | 2020年6月      |

### ES2016(ES7) の新機能
では、早速本題に入ります。
ES7で追加された新機能は主に下記の２つです。

- **Array.prototype.includes（）メソッド**
- **べき乗演算子**

### ・Array.prototype.includes（）メソッド
まずはArray.prototype.includes（）メソッドについてみていきます。
includes()は、配列内に特定の要素が含まれているかどうかを真偽値で返してくれるメソッドです。要素が含まれていればtrue、含まれていなければfalseとなります。
#### 【例】
```javascript
const array = ['要素1','要素2','要素3'];

console.log(array.includes('要素1')); // => true
```

また、includesメソッドは第2引数に配列内で探し始める位置をインデックスで指定することができます。（下記参照）
#### 【構文】

```
arr.includes(valueToFind[, fromIndex])
```

#### 【例1】
```javascript
const array = ['要素1','要素2','要素3'];

console.log(array.includes('要素1', 3)); // => false
```
上記の例はインデックスに3を指定していますが、配列内の要素は3つ（インデックス番号が2まで）しかないのでfalseが返ります。
#### 【例2】
```javascript
const array = ['要素1','要素2','要素3'];

console.log(array.includes('要素3', -1)); // => true
```
また、上記の例はインデックスに負の数を指定すると、その絶対値の数だけ配列の末尾から戻った位置が検索開始地点となりますのでtrueが返ります。

### ・べき乗演算子
続いてべき乗演算子について記述します。
べき乗演算子は、1番目のオペランドを2番目のオペランドの累乗まで上げた結果を返す演算子です。簡単にいうと累乗計算ですね。こちらは例を見て頂いた方がわかりやすいかと思います。
#### 【構文】

```
Operator: var1 ** var2
```

#### 【例1】
```
console.log(2 ** 2); // => 4
console.log(2 ** 3); // => 8
console.log(1 ** -1); // => 1
console.log(NaN ** 1); // => NaN
```
NaNは、累乗してもNaNになります。

#### 【例2】
```
console.log(2 ** 3 ** 2); // 512
console.log(2 ** (3 ** 2)); // 512
console.log((2 ** 3) ** 2); // 64
```

べき乗演算子は右結合的の為、a ** b ** c と a ** (b ** c) は等しいべき乗式となります。優先順位と異なる順に計算したい場合は、丸カッコを用いて計算順序を明示します。

はい、今回はここまでとさせて頂きます✍️

### おわりに
ES７はES６に比べる新機能のボリュームは少ないですが、特にArray.prototype.includes（）メソッドは個人的に実務で使える場面が多くありますので大変ありがたいメソッドです🙇‍♂️また、ES8については次回以降で書きます。

### 参考文献
---

[MDN Web Docs](https://developer.mozilla.org/ja/ "MDN Web Docs")
驚くほど簡単なラズパイでの格安モーターコントロール(IoT)


#1.はじめに
IoTでは必須の「アクチュエーター」の基礎としてのモーターコントロールです。格安ステッピングモーターを前から持っていましたが、あまり使っていなかったところ、ラズパイで動かしてみようと思いたちました。ライブラリを探してみたところ、とても簡単なpythonコードで動かせることがわかりました。
ラズパイをお持ちの方は、モーターが使えると「できること」が大きく広がってくると思いますのでぜひトライしてみてください。面白いですよ。以下の内容の実践は自己責任でお願いします。

#2.今回使うモーター
ユニポーラ　ステッピングモーター　２８ＢＹＪ－４８という数百円で売られているモーターを使います。

https://akizukidenshi.com/catalog/g/gP-13256/

あと、モータドライバモジュールとしては、ZC-A0591を使います。（アマゾンなどでは、セットで販売されているようです）

#3.Pythonのモジュール
ステッピングモータの理論的なところ、原理は、Youtubeなどでわかりやすく解説されているので、もし時間があれば、一度みておくことをお勧めします。(例えば以下。英語です）

https://www.youtube.com/watch?v=Dc16mKFA7Fo&t=432s

その上で、今回はRpiMotorLibというモジュール（Python）を使いたいと思います。以下のGitHubサイトに丁寧な解説があります。（英語）

https://github.com/gavinlyonsrepo/RpiMotorLib

それでは、このライブラリをRasberryPiにインストールしておきましょう。

```terminal

$ pip3 install RpiMotorLib

```

#4.ステッピングモータとRasberry Piの結線

ラズパイのGPIOとモータードライバーのIN1~IN4をつなぐとともに、モータードライバーに電源を供給します。

以下、結線の例です。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280313/65a17368-41e1-dfa9-5d18-3aae86126ce3.png)



実際に結線した時の画像がこちら↓

![IMG_1084.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280313/d05bc304-b2d6-0bff-fb27-2cd8424c7f11.jpeg)

#5.Pythonコード

モータを動かすプログラムをPythonで書いて実行します。コード例を以下に示します。

```python3
import time 
import RPi.GPIO as GPIO
from RpiMotorLib import RpiMotorLib  

# 先ほど結線した際に使ったGPIOピンの番号をIN1〜In4まで順にリスト形式で定義しておきます。
GpioPins = [17, 18, 27, 22]  

f = 3  # 回転速度 [Hz]
Rev = 1  # １回転に設定します
s_angle = 5.625  # ステップ角 [deg]を設定します。これはモーターによって異なります
wait = (1/f)*(s_angle/360)/2  # パルス間の時間を定義しておきます

# モーターの名前をつけて、モーターの型式を指定します。（ここでは、28BYJですね。）．
mymotortest = RpiMotorLib.BYJMotor('Mymotor', '28BYJ') 

# 引数は、①GPIOピン，②wait，③ステップ数，④回転方向，⑤実行中の各PINの動作表示の要否，⑥ステップモード，⑦最初の遅延時間の設定 [ms]
mymotortest.motor_run(GpioPins, wait, Rev*512, True, False, 'half', 0.05)

# 上記が終了するとPINをクリーンアップして終えます。
GPIO.cleanup()
```

#6.終わりに
どうでしたか？たったこれだけのプログラムでモーターが１回転してくれましたね。ぜひ、プログラムのパラメーターを変えてみて、いろいろ試していただければと思います。
Amazon Linux 2 に Amplify CLI を入れて Python Lambda を作ろうとしたら Python3.8以上が必要というエラーが出て困った話


タイトルのとおり困ったことが解消できたので手順のメモ。Pythonの環境構築について何もわかっていないので、解決はできたもののわかっていない。
## エラーまでの手順
Amazon Linux 2 起動 && Amplify CLI インストール(4.52.0)

```sh
amplify init
amplify add function # Pythonを選択
amplify push
```

## 出たエラー

```
python found but version  is less than the minimum required version.
You must have python >= 3.8 installed and available on your PATH as "python3" or "python". It can be installed from https://www.python.org/downloads
```
Cloud9 でも確か同じエラーが出て、`python`も`python3`も3.8未満だったため出ている。

## 試した方法
Python3.8のインストールコマンドとどのタイミングでやったかは忘れてしまった。。後述の[ユーザーのエイリアス設定]の`sudo amazon-linux-extras install -y python3.8`だった気もする。

### ユーザーのエイリアス設定
まず試したのはこれ。
https://qiita.com/hiren/items/17984191da2ab8955174

```
sudo amazon-linux-extras install -y python3.8
echo 'alias python=python3.8' >> ~/.bashrc
source ~/.bashrc
```

==>エラー解消せず(多分sudoユーザーのpython3が書き換えられていないせい？


### ルートユーザーにエイリアスを設定

sudoユーザーが3.8以上をpython3 or pythonコマンドで実行できないといけないのだと予想し、次試したのはこれ。
https://qiita.com/homines22/items/ba1a6d03df85e65fc85a
==>エイリアスではダメなようでエラー解消せず

### 最終的にいけた方法

多分エイリアスじゃなくてコマンドそのものの割り当てを変えてくれるんだと思う？
https://qiita.com/syu-kwsk/items/5ba485edabd19fb99d4d

```
sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.8 1
sudo update-alternatives --config python3
```

##まとめ
これを知っておくとAmazon Linux 2 からシンプルに`amplify add function`でPython Lambdaを作れる。
記憶を頼りにかいているのでコピペだと多少エラーが出るかもしれない。
カスタムクラスのリストを、UserDefaultsに保存する。

# はじめに
以下のようなカスタムクラスのリストをUserdefaultsに保存しようとすると、ビルドは通りますがエラーが出てしまいます。

```swift
import Foundation

class Task: Codable {
    var body: String
    var isCompleted: Bool
    
    init(body: String, isCompleted: Bool) {
        self.body = body
        self.isCompleted = isCompleted
    }

}
```

~~~swift
// インスタンス化して保存
let task = Task(body: "こんにちは", isCompleted: false)
UserDefaults.standard.setValue(task, forKey: "hoge")

// エラー文
// A default object must be a property list—that is, an instance of (or for collections, 
// a combination of instances of) NSData, NSString, NSNumber, NSDate, NSArray, or NSDictionary.
// If you want to stｆore any other type of object, you should typically archive it to create an instance of NSData.
~~~

これはなぜかというと、UserDefaultsに保存できるのは、エラー分の通りNSData, NSString, NSNumber, NSDate, NSArray, NSDictionaryとなっているからで、カスタムクラスはこれに準拠していないからです。

解決策として、カスタムクラス型をNSData型に変換して保存し、読み出すときはNSData型が読み出されるので、それを再度カスタムクラス型に変換する、ということを考えます。実装したコードは次のとおりです。


# 実装
まず、先程のカスタムクラスに**Codable**に準拠させます。名前の通り「NSData型に変換できるよ！」みたいなイメージです。


~~~swift
class Task: Codable {
~~~

そして、次のファイルを作成します。

~~~swift:JsonEncoder.swift
class JsonEncoder {
    
    class func saveItemsToUserDefaults<T: Codable>(list: [T], key: String) {
        let data = list.map { try! JSONEncoder().encode($0) }
        UserDefaults.standard.set(data as [Any], forKey: key)
        UserDefaults.standard.synchronize()
    }
    
    class func readItemsFromUserUserDefault<T: Codable>(key: String) -> [T] {
        guard let items = UserDefaults.standard.array(forKey: key) as? [Data] else { return [T]() }
        let decodedItems = items.map { try! JSONDecoder().decode(T.self, from: $0) }
        return decodedItems
    }
    
}
~~~

そして次のように呼び出すことで、カスタムクラスのリストをUserdefaultsに保存することが出来ます。

~~~swift
// 保存処理
JsonEncoder.saveItemsToUserDefaults(list: taskList, key: "hoge")

// 読み出し処理
let taskList: [Task] = JsonEncoder.readItemsFromUserUserDefault(key: "hoge")
~~~


# 解説

saveItemsToUserDefaultsはカスタムクラスのリストを受け取り、JSONに変換して保存していて、eadItemsFromUserUserDefaultはその逆の処理をしているのがわかると思います。

<br>

また**T: Codable**というふうにTが型みたいになっているのは、これは**ジェネリクス**という概念で、引数の型を複数指定することを可能にします。今回では、「CodableならなんでもOKだよ！」というふうなイメージです。ジェネリクスで共通化をしたので、どのようなカスタムクラスでも保存ができるようになっています。
さらに引数の型にはCodableに準拠したカスタムクラスはもちろん、CodableはEncodableプロトコルとDecodableプロトコルを合わせて作られたので、これに準拠した方も引数に取ることが出来ます。

<br>

また読み出し処理において、定義する変数の型を指定してあげないと、ジェネリクス側が型推論できなくなってしまい、コンパイルエラーが起きるので注意してください。
【YOLOv5】Google ColabでYOLOv5を使って物体検出を試してみる

#はじめに

物体検出を試してみる方法について備忘録としてまとめました。
Google Colaboratory上でYOLOv5を使用して、物体検出を試していきます。
今回の方法ではGoogleアカウントがあれば誰でも同じように試すことが可能です。

（Qiita初投稿です。わかりにくい箇所があるかと思いますがご容赦ください。)

#Google Colaboratoryの設定

Googleアカウントを作成し以下のリンクから開始します。

https://colab.research.google.com/notebooks/intro.ipynb?hl=ja#recent=true


#物体検出とは

物体検出（object detection）とは、画像内の「どこに」「何が」写っているかを検出する技術のことです。
物体検出としては、SSDやYOLOといったものがよく使用されます。

#YOLOv5とは

YOLOv5とは、物体検出をするアルゴリズムですがYOLOv3の後継にあたり、2020年に公開された最新のモデルです。YOLOv4という高精度化したYOLOv3の後継モデルもありますが、YOLOv5は推論処理時間がより速くなっているのが特徴です。


#YOLOv5の準備

Google Colaboratoryを起動したら順番にやっていきます。

YOLOv5をインストールします。

```ruby:python.py
!git clone https://github.com/ultralytics/yolov5
%cd yolov5/
!pip install -qr requirements.txt
```

以上で準備は終了です。


#実際に物体検出してみる

以下のコードを実施するだけ物体検出が可能です。

```ruby:python.py
!python detect.py --source /content/yolov5/data/images/zidane.jpg
```

結果を表示してみます。

```ruby:python.py
import matplotlib.pyplot as plt
img = plt.imread('/content/yolov5/runs/detect/exp/zidane.jpg')
plt.imshow(img)
plt.show()
```

以下の画像が表示されたら成功です。
![zidane.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1559455/d859b939-57ea-948a-9766-f60247bb8d96.jpeg)
それぞれ検出した範囲に枠付けがされ、左上に検出した物体名と確信度が表示されます。

確信度とは物体検出の精度がどのくらい確実であるかの指標で0~1の間の値をとります。
この値が1に近いほど機械が自信を持って判定していることになります。

#任意の画像で物体検出してみる

サンプル画像以外でも任意の画像で物体検出が可能かどうか試してみます。

実際に物体検出したい画像を`/content/yolov5/data/images/`に`bus.jpg`を格納します。
（bus.jpgはサンプル画像として元から入っているが、ここでは自分で追加したものとして扱う）
格納した画像のファイル名として以下のコードを実行します。

```ruby:python.py
!python detect.py --source /content/yolov5/data/images/bus.jpg
```

先ほどと同様に結果を確認します。

```ruby:python.py
import matplotlib.pyplot as plt
img = plt.imread('/content/yolov5/runs/detect/exp2/bus.jpg')
plt.imshow(img)
plt.show()
```
![bus.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1559455/409a6cf6-6449-702f-fd4d-bc118fb3012d.jpeg)


任意の画像でも物体検出ができました。

https://qiita.com/hkwsdgea_ttt2/items/ccac4cec24a3799df8f3

#終わりに

最後までご覧いただきましてありがとうございました。

https://tt-tsukumochi.com/archives/tag/yolov5
【kotlin】Set型 コレクション

#■Set型
前記事で紹介したList型と似ている。
複数の値を格納でき読み取り専用と可変専用がある。

###■Set型の特徴
●値が重複しない
●インデックス番号で管理していない

例：Set型とList型の違い
重複した値は無視され出力される。
インデックス番号でアクセスできない。

``` kotlin
//List型の場合
val a = listOf("あ","い","う","あ","い")
println(a)
//結果: ["あ","い","う","あ","い"] 

//Set型の場合
val b = setOf("あ","い","う","あ","い")
//値が重複しない
println(b)
//結果: ["あ","い","う"] 

printin(a[0])
//結果: あ

println(b[0])
//結果: エラー
```

#■値の参照であれば一応可能
ループ処理を行なっているため速度が遅くなるパフォーマンスの低下につながりやすい
頻繁に使うのは避けたい。

``` kotlin
val b = setOf("あ","い","う","あ","い")

println(b.elementAt(1))
//結果: い
```
プライベートクラウドとパブリッククラウドとは？

#はじめに
私は現在AWSの資格取得のために日々クラウドについての勉強に励んでいます。
そんな中で、<b>プライベートクラウド</b>と<b>パブリッククラウド</b>という言葉が出てきたのでその違いについて調べてみました。

#プライベートクラウドとは？
プライベートクラウドとは、自社専用で構築・運用されるクラウド環境のことを言います。自社の運用に合わせて環境の構築やカスタマイズができるのが特徴です。
プライベートクラウドには<b>オンプレミス型</b>と<b>ホスティング型</b>という２種類のタイプがあります。

###オンプレミス型プライベートクラウド
オンプレミスとは自社内の建物内にサーバや回線などの設備を構築・運用することを言います。
オンプレミス型は自社でサーバや回線などの設備をすべて用意する必要があるので、イニシャルコストや運用の手間がかかります。
![privatecloud01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1549760/7672a12d-3b09-3fc5-6b16-566538f8fd11.jpeg)

###ホスティング型プライベートクラウド
ホスティング型は、ホスティング業者が提供するクラウド環境(パブリッククラウド)内に自社専用のクラウド環境を用意します。そのため、サーバ・回線などの物理的な設備の管理をホスティング業者に任せることが可能です。
![privatecloud02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1549760/8db211fe-d724-3e3c-bd4f-eaf2cc1f4425.jpeg)

#パブリッククラウドとは？
ホスティング業者が提供するクラウド環境を、不特定多数のユーザがインターネットを通じ共有して利用するサービスを指します。
クラウド環境の構築に不可欠なサーバーやソフトウェア、通信回線などのリソースを持たずに、安定的なクラウド運用を行うことが可能です。
![publiccloud01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1549760/99a481f3-bf8d-6761-2a92-0994b5e7aaf3.jpeg)

#それぞれのメリットとデメリット
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1549760/71fd3e4f-55c8-f0ac-43e2-05057a780c2a.png)
（引用：https://it-trend.jp/cloud_construction/article/misc ）

#ハイブリットクラウドとは？
プライベートクラウドとパブリッククラウドを組み合わせて使うことをハイブリットクラウドと言います。
それぞれの弱点を補いあって、片方ずつだけでは実現できないことを可能にします。
プライベートクラウドだけを使うより、費用や運用の負荷を減らすことができる上に、スピーディーにシステムを拡張することができます。

###ハイブリットクラウドの導入例
<b>・機密情報をプライベートクラウドで扱う</b>
顧客の個人情報はプライベートクラウドに保管。その個人情報をベースとした会員向けサービスを提供するウェブサーバは、安価なパブリッククラウドにて構成し、VPNにて両者を連携させます。

<b>・システムの一時的な拡張パターン</b>
短期的なキャンペーンなどで一時的にウェブサーバーの負荷が上がることが想定される場合、そのためだけにプライベートクラウドに物理サーバーを追加するのは費用対効果に優れません。その際に、すぐに導入でき利用した分だけコストがかかるパブリッククラウドを組み合わせて利用します。

#高まるパブリッククラウドの市場規模
IDC Japanによると、2020年の国内パブリッククラウドサービス市場は、前年比19.5％増の1兆654億円だったそうです。2020年～2025年の年間平均成長率（CAGR）は19.4％で推移し、2025年の市場規模は2020年比2.4倍の2兆5866億円になると予想しています。
政府のデジタル化や働き方改革などが叫ばれる中で、システムのクラウド化が非常に注目されています。

https://it.impress.co.jp/articles/-/21160


#参考サイト
https://www.kagoya.jp/howto/network/privatecloud/

https://it-trend.jp/cloud_construction/article/misc
OpenVPN が突然つながらなかったときのメモ(CRL 証明書有効期限切れ)

いままでつながっていたが, 突然つながらくなった.

journalctl -xe などで client 側のログをみると

TLS Error: TLS key negotiation failed to occur within 60 seconds

と出る.

https://openvpn.net/faq/tls-error-tls-key-negotiation-failed-to-occur-within-60-seconds-check-your-network-connectivity/

https://docs.aws.amazon.com/ja_jp/vpn/latest/clientvpn-user/common-troubleshooting.html

ネットワーク構成が変わっていなかれば, CRL 証明書の有効期限切れでしょう.
(今回遭遇したケースもそうだった. サーバ側 systemd ログで expired だった)


https://bucci.bp7.org/archives/39523/

デフォルトで生成したのは 180 日まででした.

CRL を更新して解決です!
ちょ、、待てよ、、ちゃんとNGINX入るじゃん

#はじめに
前回までにGCP上にUbuntuインスタンスを構築し、その中でDockerを動かすことに成功。
仮想技術を使って仮想化ソフトウェアをインストールという仮想仮想した世界に戸惑うも興奮冷めやまない夜を過ごすのであった。

#Docker上にNGINXをインストールしてみた
そもそも私がNGINXというソフトウェアを知ったのは３年前のことである。
新人営業時代に、これからはMicro Service時代だ！Micro Serviceを支える技術を提供しよう！ということで、疎結合環境をAPIゲートウェイ機能によって柔軟にコントロールするNGINX Plusという製品に初めて出会う。
そのときに初めてNGINXとはWebServerであり、OSSとして世界中で使用されているデファクトに近い存在だということを知った。
他にもWeb Serverを調べてみると、「Apache」なども有名なようだったが、過去の経験から今回はNGINXをインストールすることにする。

#実践
まずはDocker環境にNGINXをインストールする手順を調べるべく、Google先生に相談。
すると、NGINXの公式ブログにたどり着く。
https://www.nginx.com/blog/deploying-nginx-nginx-plus-docker/

こちらをざっと読むと、
1.コンテナ環境でデフォルトのNGINXをインストールするコマンドを入力(1行)
2.Docker環境の確認

ちょ、、待てよ、、コマンド１つで終了だと！？
ただ公式がそう言っているなら信じるしかない。
信じてやってみよう。

##1.コンテナ環境でデフォルトのNGINXをインストールするコマンドを入力
公式に記載されているコマンドを読み解いてみると、いくつか発見があった。
１行のコマンドの中でいくつもの命令が含まれている。
①Docker起動
②名前の決定
③ポート番号の決定
④Docker Hubからインストールするイメージ決定

```
$ docker run --name mynginx1 -p 80:80 -d nginx
```

今回は名前を「chomateyonginx」とする。
実際に実行。
![スクリーンショット 2021-06-18 23.55.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1578917/69466798-d7ea-00f3-754c-d542ca24c210.png)

ステータスに「Download newer image for nginx:latest」の文字が！

##2.Docker環境の確認
ステータスにも「最新版のNGINXをダウンロードしました」と表示されているが、本当にインストールされているのかDocker環境を確認してみる。

```
$ sudo docker ps
```

![スクリーンショット 2021-06-20 17.04.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1578917/5488e0bd-ef79-54f6-167c-ed7df330c8ca.png)

私が２日ほど寝かせたため４１時間前の表示にはなっているが、「chomateyonginx」と命名したDocker上のNGINX環境が構築されていることがわかる。

**ちょ、、待てよ、、一行しかコード書いてないのにちゃんとNGINXが入っている、、**
では、NGINX上ではどのように表示されているんだ！？
と、いうことでlocalhostでアクセスし、確認してみる。

```
$ curl http://localhost
```

![スクリーンショット 2021-06-20 17.06.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1578917/f537ec20-a39f-0c8f-8163-cbd466c07f58.png)

ぬおおおおお。
NGINX：「Welcome to nginx!」
私：「お会いできて光栄です。結婚してください」
NGINX：「世界から求められるためあなただけを選ぶことができません」
私：「・・・ちょ、、待てよ、、」

**終劇**

#次回
NGINXのデフォルトhtmlを編集してみる
設定ファイルを管理するrcmが便利だった


環境構築用のスクリプト、そう頻繁に使うものでもないけど一つ持っておくと便利ですよね。
そんなスクリプトで必要な処理は大きく分けて以下の2つ。

- よく使うツールのインストール
- ツールの設定ファイルの配置


今回紹介するrcmは2つ目の処理を楽にしてくれるものです。


## インストール

```
$ sudo apt install rcm
```

## 使い方

[チュートリアル](http://thoughtbot.github.io/rcm/rcm.7.html#QUICK_START_FOR_EMPTY_DOTFILES_DIRECTORIES)もありますが、基本的には以下の2つのコマンドだけ覚えておけば大丈夫です。

```
$ mkrc .bashrc
$ rcup -v
```

上記2つのコマンドを実行すると、ホームディレクトリ直下に bashrc が入った.dotfilesという名前のディレクトリが作成されます。
2つ目のコマンドで .bashrc が ~/.dotfiles/bashrc へのシンボリックリンクとなります。

新たにrcmで管理するファイルを追加したい場合も、mkrcでファイルを追加し、rcupでシンボリックリンクの作成ができます。

こうしてできた.dotfilesをGit管理することで、環境構築するときは ```rcup -v``` を実行するだけで設定ファイルをコマンド一つで適切な場所に配置できます。

## 更新時

rcmで管理しているファイルの内容を更新したいときは、`~/.dotfiles/` 以下のファイルを直接編集でよい

## 参考
- [GitHub - thoughtbot/rcm: rc file (dotfile) management](https://github.com/thoughtbot/rcm)
- [rcmを使ったdotfilesの管理 - kikukawa's diary](https://kkkw.hatenablog.jp/entry/20210303/1614730278?utm_source=feed)
ウェブアプリを独立表示させる方法

##ブラウザの現在のページをシンプルな別ウィンドウで表示するブックマークレット
・任意のブラウザを表示する。
・下記のブックマークレットを実行

```javascript
javascript:(()=>{window.open(location.href,null,'width=500,toolbar=yes,menubar=yes,scrollbars=yes')})()
```

##Discordのウェブ版をアプリ化しよう
訳あってデスクトップ版のアプリが使用できないためDiscordをこのブクマに登録してみる。

```javascript
javascript:(()=>{window.open('https://discord.com/channels/@me',null,'width=500,toolbar=yes,menubar=yes,scrollbars=yes')})()
```

SUCCESS!
プログラミング初心者が書いたComposerのインストール

**はじめに**
-------
Laravelをインストールしようとターミナルでぽちぽちしていたら
``zsh: command not found: composer``
と言われてしまったので``composer``をインストールせねばということになりました。

Composerのインストール
------
※Macで行うときの方法しか書いてませんのでご了承くださいませ。

まずはブラウザでComposerの公式サイトにアクセスします。
![composer画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1478204/ad11b044-dc11-7539-1ec4-b6533f80fe92.png)
僕は指揮者に対して日焼けしているイメージは持っていないですが、composerの方では
そういうイメージなのかもしれません。

こちらのページに移りましたら``Download``の部分をクリックします。
![composerコマンド.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1478204/54ab3f42-be72-cf65-7cf4-a2bc71fd603a.png)
上記の画面に移りましたら既に僕がドラッグした部分のコマンド順番に打ち込んでいきます。

ターミナルでの操作
-----------
僕はMAMPの中のhtdocsの中で作業しているのでそこまで移動します。
``$ cd /Applications/MAMP/htdocs/``

該当の場所まで移動しましたら先ほどの画面の``php -r "copy~~~``から一行ずつ
順番に打ち込んでいきます。

そして最後の``php -r "unlink~~~~``まで打ち込んだらcomposerのインストールが完了です！！

試しに``composer --version``で確認をしようとしたところ.....

``zsh: command not found: composer``


**なんでじゃ！？！？！？**


と心の中で強めに思ってしまいました。

特にタイポした訳では無さそう（コピペなので）だったので困惑しましたが
色々と調べた結果、次のコマンドを打って解決しました。

``sudo mv composer.phar /usr/local/bin/composer``

このコマンドを打つことにより、composer.pharをbinフォルダーの直下に移動させることが出来
composerというコマンドをどのフォルダーでも使えるようになります。(PATHを通すというやつらしいです)

そして改めて``composer --version``で確認をすると....

``Composer version 2.1.3 2021-06-09 16:31:20``

となり無事にcomposerのインストールが完了しました！

公式の手順通りに行っても上手くいかないとめちゃくちゃ焦りますね。。。
今回の記事は以上となります。
ここまで読んで頂きありがとうございました！！

参照元
https://qiita.com/4roro4/items/f4f7911ee1ec7abe0733
https://qiita.com/soarflat/items/09be6ab9cd91d366bf71
Search Console 所有権周り

## 概要
Search Consoleでの「サイトの所有権確認」と「所有権の移譲」についてのメモ書きです。

## サイトの所有権確認について

Search Consoleのプロパティ作成にあたっては作成者がドメインを所有していることを証明する必要があり、証明方法としては主に5つの方法があります。

証明はプロパティー作成時に限定せず、継続して確認できる状態にする必要があります。
途中で確認できない状態になってしまうとプロパティ自体が非表示になり、所有権の確認が再度必要となるので注意が必要です。

### 1) HTMLファイル
ドメインルートに特定のファイルを置いて所有権の確認をします。

この方法ではGoogleのクローラーがファイルを閲覧できる必要があります。
クローラーのUserAgentは以下のようになっており、このUserAgentに対してファイルを返却できないようなURLルーティングの場合にはクローラによる確認ができません。

```
Mozilla/5.0 (compatible; Google-Site-Verification/1.0)
```


### 2) HTMLタグ
ドメインルートのhtmlファイルに任意のmetaタグを設定して所有権の確認をします。

```HTML
<meta name="google-site-verification" content="~~~" />
```

HTMLファイルでの確認方法と同様に、クローラーのUserAgentが入れないようなページでは確認することができません。

一般的に、前述したようなUserAgentの場合にはPCページを返却することが多いと思いますので、モバイル限定のWebサイトの場合には注意が必要です。

### 3) Google Analytics

サイトに設置しているGoogle AnalyticsのSDKを用いて所有権の確認をします。

この方法ではGoogleアナリティクスプロパティの「編集権限」が必要となり、JavaScript SDKは`<head>`タグの中に設置する必要があります。
また、Google Tag Managerを経由してGoogle Analyticsを配信している場合は確認はできません。

Google Analyticsの編集権限が必要になるため、自社でGoogle Analyticsを管理していない場合にはこの方法を取るのは難しいかもしれません。

### 4) Google Tag Manager

サイトに設置しているタグマネージャーのSDKを用いて所有権の確認をします。

この方法ではタグマネージャーコンテナの「公開権限」が必要となり、JavaScript SDKは`<head>`タグの中に設置する必要があります。

Google Tag Managerの公開権限が必要になるため、自社でGoogle Tag Managerを管理していない場合にはこの方法を取るのは難しいかもしれません。

### 5) DNS設定
DNSにてTXTレコードもしくはCNAMEレコードにてGoogleが指定した文字列を設定します。

## 所有権の移譲について

「確認済みサイト所有者(オーナー)」権限をもつユーザーが存在しなくなった場合には、新たなユーザー追加ができなくなります。
また、プロパティの作成や所有権の確認も改めて必要となりますので、退職リスクという観点でも事前に複数人に所有権を付与したり、共通のアカウントで所有権を保持することをおすすめします。

所有権の移譲ができるページへは以下2通りの遷移方法があります。

**1) 新UIから設定ページに遷移する場合**

新UIの「ユーザーと権限」ページ(https://search.google.com/search-console/users?resource_id={siteUrl}) にて、オーナー権限を所有しているユーザーのメニューを押下し、[プロパティ所有者の管理]を押下することで設定ページに遷移できます。

![スクリーンショット 2021-06-05 18.24.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147689/13f277a5-b4fd-6f5b-eb80-6f4f292336be.png)
※オーナー以外のユーザーのメニューでは表示されません。


**2) 旧UIから設定ページに遷移する場合**

認証済みURL一覧ページ(https://www.google.com/webmasters/verification/home) にて任意のプロパティを選ぶことで設定ページに遷移することができます。

![スクリーンショット 2021-06-13 15.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147689/aebf18c8-c8e0-8df8-46ea-445279618208.png)


### 設定ページにて所有者の追加をする

遷移後のページ(https://www.google.com/webmasters/verification/details?siteUrl={siteUrl}) の一番下にある[サイト所有者を追加]を押下して任意のアカウントへ所有権を付与します。

![スクリーンショット 2021-06-05 18.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147689/fde09344-c1f8-3db5-2a6a-64e577008841.png)
## 参考URL
- [サイトの所有権を確認する - Search Console ヘルプ](https://support.google.com/webmasters/answer/9008080?hl=ja&ref_topic=9455938)
【Javascript】axiosエラーハンドリング共通化を考えてみた

Vue.jsの開発で非同期通信に`axios`を使用している。
非同期通信時のエラーハンドリングのロジック自体は同じで、各`axios`実装箇所で行っていた。


開発の効率や、ソースコードの可読性、後々メンテナンス、拡張などを考えた時のために共通化を考えてみた。


## axios実装のビフォーアフター

### Before
【既存のaxios実装】
axiosの各呼び出し箇所で下記のようなエラーハンドリングしており、同じロジックコードが散在している。

```js
axios.post(url, params)
  .then(response => {
          // 成功時の処理
  }).catch(error => {
      // 失敗時の処理
      switch (error.response?.status) {
        case 401:
        // HTTPステータスに応じて処理
        case 403:
        default:
        // 例外処理
      }
 });
```

### After
【エラーハンドリングの共通化後のaxios実装】
エラーハンドリングを共通化したことでaxiosの各呼び出し箇所では成功時の処理のみを実装する。
ソースコードがスッキリした！！

```js
const response = axios.post(url, params);
if(response) {
 ​// 成功時の処理(エラー時は共通コードでハンドリングされるため、responseが返らない)
}
```


## axiosのエラーハンドリング共通化
axiosAPIの`Interceptors`を活用する。

Interceptorsについてはこちら参照：[Interceptors | axios公式](https://axios-http.com/docs/interceptors)

- Interceptorsを使って、axiosのエラーハンドリングを共通化

```axiosErrorHandler.js
axios.interceptors.response.use(function (response) {
    // 成功時の処理
    return response;
  }, function (error) {
    // 失敗時の処理
    switch (error.response?.status) {
       case 401:
       // HTTPステータスに応じて処理
       case 403:
       default:
       // 例外処理  
    }
  });
```

ちなみにInterceptorsはaxiosのrequest前処理も共通化することができる:bulb:

Nuxt.jsを使っていたらpluginが用意されているのでそちらを使用するのが良さそうです:ok_hand:
→[nuxt/axios](https://axios.nuxtjs.org/helpers/)



Vue.jsでのエラーハンドリングについて、ご意見や事例があればぜひお聞かせください:bow:
EC2へのsshコマンド、mysqlの接続コマンド

##cloud9からEC2へSSH接続するコマンド
```
ssh -i ~/.ssh/practice-aws.pem ec2-user@パブリックコメントIPまたはEIP
```

##mysqlへ接続するコマンド
```
mysql -u root -p -h エンドポイント
```
<ul>
<li>エンドポイントはRDSのメニューで確認する。
<li>接続を解除するには、```exit```を入力するか、```Ctrl+D```を押下する。
CSVデータの改行ズレを変換するVBAマクロを作成する

##■経緯
　Redmineサーバーのデータバックアップで、CSV出力する際に、「カラム囲み記号:」を指定できない（ダブルクォーテーションで囲めない）事態が発生し、改行コードが問題となってデータ復旧できなくなってしまった。
　※MySQLでは「カラム囲み記号:」の指定は可能であるが、今回バックアップしたredmineサーバーはMySQL以外のDBで運用されていた。

##■環境：
　・Redmine3.4
　・Excel　2019　64bit

##■やりたいこと：
　・改行を含む情報をもつCSVデータを通常の形式に復旧させたい
　　※復旧後に開業コードを含まなくてもとりあえずは良しとする。
　・修正前
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651745/827c9af7-6721-1f97-ca1b-c91eff399098.png)

　・修正後
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651745/6540facc-a4dc-effb-75ca-99706052eaa3.png)

##■復旧作業をEXCELのVBA環境で実装
　・凝ったものは要らないので、最低限EXCELにCSVデータを貼り付けてマクロを実施する程度のオペレーションに留め、
　・コードを作成し、対象のデータが目的通りに修正されるかを確認する。
　・文字列の復旧は再帰処理で実装する。

##■コード
```VBScript:Module1.vba
Public endsellrow As Long
Public endsellcolumn As Long
Sub Restore()
    Dim chkcolumn As Long
    Dim temp As String
    Dim i As Long
    Dim j As Long
    Dim rst As Long
    rst = 1
    '先頭行と最終行には正しいデータが入っている前提
    endsellrow = Cells(Rows.Count, 1).End(xlUp).Row
    endsellcolumn = Cells(1, Columns.Count).End(xlToLeft).Column
    For i = 2 To endsellrow
        chkcolumn = Cells(i, Columns.Count).End(xlToLeft).Column
        If chkcolumn <> endsellcolumn Then
            temp = Cells(i, chkcolumn) 'データを退避
            rst = i '問題の発生した行（復旧対象）
            i = RecursiveRestore(i, temp)
            Cells(rst, chkcolumn) = temp 'データ修復（改行されたものをまとめる）
            For j = 1 To Cells(i, Columns.Count).End(xlToLeft).Column - 1   'データ修復(復旧先の「,」は飛ばす)
                Cells(rst, chkcolumn + j) = Cells(i, j + 1)
            Next j
            rst = rst + 1
            Rows(Trim(Str(rst)) & ":" & Trim(Str(i))).Select
            Application.CutCopyMode = False
            Selection.ClearContents’復旧後に不要なデータをクリア
        End If
    Next i
End Sub
Function RecursiveRestore(i As Long, temp As String)
    If i < endsellrow Then
        i = i + 1
        chkcolumn = Cells(i, Columns.Count).End(xlToLeft).Column
        If chkcolumn <= 1 Then
            temp = temp + Cells(i, chkcolumn) 'データを退避
            i = RecursiveRestore(i, temp)
        End If
    End If
    RecursiveRestore = i
End Function
```
##■デバッグ：
・実行結果
　動作させるとデータは復旧する。修正して不要になった行は削除しようかと思ったがクリア処理にとどめた。
　※後で空白行を削除するほうがリスクが少ないと判断した。必要があればクリア処理を各自で削除処理に変更してほしい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651745/15177140-60ae-4f11-de51-fe65c4d66d07.png)

以上です、お疲れ様です。
npmとyarnとは？

#はじめに
Rails開発を進めていく中で、使い分けがわからなかったためまとめました



#Node.js
サーバーサイドJavaScriptとも呼ばれている。
JavaScriptはブラウザ上でしか動けなかったが、Rubyなどのようにパソコン上で動作可能にしてくれる**JavaScript実行環境**である。



#npmとは
Node Package Maneger
Node.jsで書かれている様々なパッケージを管理している
  例:
  Ruby(gem)
  Mac(Homebrew)
  npm(Node.js)

Node.jsで使いたいライブラリがあれば、npmでインストールできる

```Vue.jsのインストール
$ npm install vue
```

##使い方
①ディレクトリをnpmの管理下に置く

```
$ npm init
```

これでpackage.json(パッケージに関する情報を格納するファイル)が作成される
②パッケージをインストールする

```Vue.jsのインストール
$ npm install vue
```

これでパッケージがインストールされる

  


#yarn

こちらもnpmと同じくNode.jsのパッケージマネージャー
npmと互換性があり、package.jsonが併用できる
機能面での差はほとんどないが、npmの欠点を補うように開発されている

##使い方
①yarnのインストール

```
$ brew install yarn
```

②package.jsonが存在しない場合、

```
$ yarn init
```

③パッケージのインストール

```
$ yarn add (パッケージ)
```

#付随するファイル
##node_modules
インストールしたパッケージのインストール先

##package.json
依存関係を記載したJSONファイル
ここに記述しておけば、インストールの際にパッケージがインストールされる

そのため、githubから引っ張ってきて、自分の環境で`npm install`をすることで、
同様のパッケージが使用できる

##package-lock.json
`npm install`時に作成される
そこで実際にインストールされたパッケージ情報が記載されている


#参考文献
Node.jsとはなにか？なぜみんな使っているのか？
 https://qiita.com/non_cal/items/a8fee0b7ad96e67713eb
yarnとは
https://qiita.com/akitxxx/items/c97ff951ca31298f3f24
Yarn：Facebook発のパッケージマネジャーはnpmに代わるスタンダードになるか
https://www.webprofessional.jp/yarn-vs-npm/
【kotlin】List型 コレクション

#■コレクション型
複数の値を格納できるもの
配列も複数入るがコレクション型ではない。

コレクション型はList,Set,Mapの3つからなっている。

#■List
●複数の値を格納できる。
●読み込み専用と変更可能ができる2つの種類がある。
●順番がある。インデックス番号で値にアクセスできる。
●値が被っていても許される。

#■読み取り専用と変更可能な List
####■読み取り専用
中身の変更ができないそのままの配列を使う時に使う。

▼書き方

``` kotlin
val hoge = listOf(1,2,3)
```

####■変更可能
中身の値を記述してから変更する事ができる。


▼書き方
mutableをつける。

``` kotlin
val hoge2 = mutableListOf(1,2,3)
```

####▼お互いそのまま変数名だけで中身を全て出力できる。

``` kotlin
val hoge = listOf(1,2,3)
val hoge2 = mutableListOf(1,2,3)

println(hoge)
//結果: [1,2,3]
println(hoge2)
//結果: [1,2,3]
```

#■型パラメータ
####▼読み取り専用の場合
List<型名>

``` kotlin
val hoge: List<String> = listOf("かに","さそり","魚")
```
▼変更可能なmutableの場合
MutableList<型名>

``` kotlin
val hoge2: MutableList<String> = mutableListOf("豚","牛","鳥")
```

#■MutableListの追加と消去
###▼空のMutableListを用意
配列では要素数を決めnullを埋めて作るある意味,空の配列は用意できた。
MutableListでは要素数もなくnullを埋めるわけでもない。

``` kotlin
//String型を指定している。
val hoge = mutableListOf<String>()

//Any型も指定可能
val hoge = mutableListOf<Any>()
```

###▼値を追加
add(追加したい値)でMutableListの末尾に値を追加します。

``` kotlin
hoge.add("かめ")
```

add(インデックス番号,値)で値を好きなインデックスの場所に追加できます。

``` kotlin
hoge.add(0,"さる")
println(hoge)
//上記2つのaddの結果： ["さる","かめ"]
```

+=演算子で値を末尾に追加も可能

``` kotlin
hoge += "吉野"
println(hoge)

//結果:上記3つの結果 ["さる","かめ","吉野"]
```

###▼複数の値を追加
■addAllで中身のlistOf()を全部MutableList()に追加するよ

``` kotlin
val aaa = MutableListOf<Int>()
//追加する値をlistOf()でまとめている。
aaa.addAll(listOf(1,2,3,4))

println(aaa)
//結果： [1,2,3,4]

//変数にしてaddAllの引数に渡す事もできる。
val bbb = listOf(5,6,7,8)
aaa.addAll(bbb)
```

■+=演算子でも同じ事ができる。

``` kotlin
aaa += listOf(1,2,3,4)
```

■スコープ関数のapplyを使って連続で値を追加も可能

``` kotlin
//applyでaaaを省略している。
aaa.apply{
 add(1)
 add(2)
 add(3)
}
```

###▼値を消去
■remove(消去したい値)で値を消去

``` kotlin
hoge.remove("かめ")
```

■-=演算子で消去も可能

``` kotlin
hoge -= "かめ"
```

■インデックス番号を指定して消去
removeAt(インデックス番号)

``` kotlin
hoge.removeAt(0)
```

■全ての値を消去
clear()

``` kotlin
hoge.clear()
```
Elasticsearchの裏側調べてみた

多くのサービスで使用されている全文検索エンジンのElasticsearch、以前自分も手を動かして触ってみましたが、今回は実際にどうやって検索をしているのか+αを調べたので、まとめてみることにしました。

## ESの起源
Elastic社のCEOが、妻の料理レシピの情報を検索するためのアプリケーションとして開発されたそうで、ほっこりエピソードでした。

## ESのクエリ
RDBのようにSQLでクエリを書くのではなく、**jsonでクエリを作成**し、検索を行う。

## RDBとの語句の違い
ここを押さえとかないとドキュメントや記事を読んでも理解できない羽目に。

|RDB  |Elasticsearch  |
|---|---|
|データベース  |インデックス  |
|テーブル  |マッピングタイプ  |
|カラム(列)  |フィールド  |
|レコード(行) |ドキュメント |

## 検索について

まず、英語と日本語で、単語の区切りに違いがあります。
- 英語　　：　空白
- 日本語　：　品詞の違い（分かりにくい）

## 検索の手法
そして、この単語を区切りにくい日本語に対応するために、2つの手法が存在します。

### Ngram
- N文字ずつ文章を釘って単語分解する方法
（例）N=2, 「東京都美術館」
⇨ 「東京」 「京都」 「都美」 「美術」 「術館」 

- 検索を行う時には、件s買うクエリを単語分割し、ANDで結合する
「美術館」という検索クエリに対しては、「美術AND術館」

#### Ngramのメリット
- 部分一致検索できるため、検索の漏れがない

#### Ngramのデメリット
- 無意味な分割が多いため、インデックスが肥大化しやすい

「東京都美術館」の場合、「京都」という検索クエリに対してもヒットしてしまう。
↓
ユーザーが求めていない情報＝**検索ノイズ** が多くなる。


### 形態素解析
- 事前に用意した辞書を用いて、意味のある単語で区切る
⇨ Ngramでの無意味な区切りがなくなる。

#### 形態素解析の問題点

- 辞書の性能によっては謝った箇所で分解してしまう
（例）「外国人参政権」を、「外国」 「人参🥕」 「政権」 と分解してしまった場合、「参政権」 という検索クエリにヒットしない。

- 固有名詞を一単語とした場合
（例）「関西国際空港」 で一単語の場合、「国際空港」 「空港」 のような検索クエリでヒットしない

#### kuromoji

上記の問題を解決してくれるのが、日本語形態素解析エンジンの「kuromoji」

（例）「関西国際空港」 からプラスして、「関西」 「国際」 「空港」 の、辞書に基づいて分割した三単語、合計四単語でインデックスすることで、部分一致に対応。

（辞書、形態素解析の性能に依存するため、Ngramほどの部分一致には至らない）

#### 形態素解析のメリット
- 検索ノイズが少ない

#### 形態素解析のデメリット
- 辞書の性能によっては、検索漏れが発生
- 新しい単語（未知語・流行りの若者言葉）に弱い

### Ngramと形態素解析の併用

|  |検索ノイズ  |検索漏れ  |
|---|---|---|
|Ngram  |多い  |少ない |
|形態素解析  |少ない  |多い |

Ngramと形態素解析はトレードオフの関係性。
併用することで、精度を上げている。

#### インデックス生成
Ngramと形態素解析によるインデックスを**それぞれ生成** 。

#### 検索処理
二つのインデックスに対して同時に検索を行い、最終的に**形態素解析による結果が先頭になりやすいよう重み**をつけて検索結果をマージする。そうすることで、**Ngramによる検索ノイズの結果を後ろに回し、ユーザーが理想とする表示結果を実現** 。

### 参考
- https://techblog.zozo.com/entry/solr_hybrid_search
Nuxt.jsでgsapを使って左から文字を表示させる

#GSAPを使って横から文字を表示させたいと思う。
前提条件
・GSAPをインストールしてある。
・もしくはCDNで読み込んでいる。
まだの人はこちらから
https://greensock.com/docs/v3/Installation?checked=core,scrollTrigger

ではやってみる。
↓このテキストを横から表示させたい。

```
<div>
    <p class="sample-text">
        テキストテキストテキストテキストテキストテキストテキスト
    </p>
</div>
```

まずテキストを隠すためにpositionを使う。

```
div{
   position: relative;
}

.sample-text{
　content: '';
  position: absolute;
  top: 0;
  right: -400px; //数を大きくするほど右に隠れる
  letter-spacing: -0.3em; //文字の間隔を伸ばしながら表示したいので文字間を狭くしとく
}
```

早速GSAPを記載していく。

```
<script>
import { gsap } from 'gsap'
//GSAPをimportして使えるようにする。

export default {
  mounted() {
    gsap.to('.sample-text', {
      x: -400, // アニメーションの内容
      letterSpacing: 1, //文字の間隔を戻す
      scrollTrigger: {
        trigger: '.sample-text', // トリガーとなる要素（アニメーションの開始、終了の位置決定に使用する）
        start: 'center center', // アニメーションの開始位置の指定
      },
    })
  },
}
</script>
```

こんな感じで行けた。
最近コード書きたすぎて記事書けてないな〜。
とりあえずメモ用として残していこう。
【EC2】WordPressを構築しよう　sec7後半

TCP/IPの4階層モデル
sec7後半：なぜWordPressが表示されるのか？
下の図の部分を学ぶ。

## TCP/OPについて学ぶ

通信の中では実際に何が起きているのか？
→　TCP/IPプロトコルに基づいて行われている。

### プロトコル とは
コンピュータ同士の約束事。共通言語のような役割。

### TCP/IP
TCP/IPを中心として、インターネットを構築する上で必要なプロトコル群。

### TCP/IPの4階層モデル
各階層の役割がわかりやすく、上下の階層を意識する事なく自身の役割を果たすことができる。

#### アプリケーション層
アプリケーション同士が会話する。（HTTP, DNS, SSH

#### トランスポート層
データの転送を制御する。（TCP, UDP

#### ネットワーク層
IPアドレスを管理し、経路選択する。（IP, ICMP, ARP

#### ネットワークインタフェイス層
直接接続された機器同士で通信する。（Ethetnet, PPP
AWSがよしなにやってくれる。
上位層から階層へは、自分のデータ処理に必要になる"ヘッダ"を付随させてやり取りを行う。

### HTTP
HyperText Transfer Protocol、HTMLなどのコンテンツの送受信に用いられる約束事。
クライアントがHTTPリクエストを送り、それに対してサーバーがHTTPレスポンスを返す。

### HTTPリクエスト

- リクエストライン（GET / HTTP / 1.1
- ヘッダー（その他の情報
- ボディ（オプション

### HTTPレスポンス

- ステータスライン（HTTP / 1.1 200 OK
- ヘッダー（その他の情報
- ボディ（HTMLのテクスト情報など

### TCP

アプリ間のコネクションの確立・切断する。
どのアプリと通信するか決定する。（ポート番号を利用する。

#### TCP

Transmission Control Protocol
通信を制御するプログラム、データの到達確認・コネクション管理を行う。信頼性の高い通信

#### UDP

User Datagram Protocol
コネクションレスな通信サービス、高速性やリアルタイム性が高い通信（電話など。

### IP

最終的な宛先のコンピュータにパケットを届ける役割、重要。
役割は3つ。

#### IPアドレス

通信を行う相手先を識別するのに使われる

#### ルーティング

宛先までパケットを届ける役割、ルートテーブルを活用

#### パケットの分割・再構築処理

ネットワークインターフェイス層により、最大転送範囲が異なる。最大転送範囲よりパケットを小さくし、宛先で再構築する。
機械学習-まとめ

ラピッドチャレンジの機械学習の章で学んだことを自分でまとめたページの目次を作成してみた。

#機械学習

コンピュータプログラムは、タスクTを性能指標Pで測定し、その性能が経験Eにより改善される場合、タスクTおよび性能指標Pに関して経験Eから学習すると言われている。
どうやら、何か経験(学習)することで、性能指標が改善される事と指すようだ。

##よく使われるライブラリ
Scikit-learn
pandas
numpy

##汎化性能
モデルの未来のデータへの当てはまりの良さを示す。
精度の平均を CV値と呼ぶ。一番良いモデルを選ぶと良い。
下記の方式がある。

- ホールドアウト法
- クロスバリデーション(交差検証)
- グリッドサーチ

##線形回帰モデル
- 要点
下記参照。

https://qiita.com/gataca27/items/8e6702adf03831f6dc02

- サマリーと考察
学習から求めたいのは重みと切片。


##非線形回帰モデル
- 要点
下記参照。

https://qiita.com/gataca27/items/055f0c2185e1ab86ffa4

- サマリーと考察
線形回帰モデルと同じで、学習から求めたいのは重み。
重みに着目すると、結局は一次関数を解く事になる。

##ロジスティック回帰モデル
https://qiita.com/gataca27/items/33abe51e7abef5dc3da7

##主成分分析
- 要点
下記参照。

https://qiita.com/gataca27/items/5cdef13ecd2d506a1264

- サマリーと考察
シグモイド関数がキーになる。
重みの計算は手計算でやると、具体的に値が変化して面白い。

##アルゴリズム
- 要点
k近傍法 (kNN)
下記参照。

https://qiita.com/gataca27/items/9196476acffa9281b189

k平均法 (k-means)
下記参照。

https://qiita.com/gataca27/items/5b56aa0ebc0a77233c5e


- サマリーと考察
k近傍法はK個をいくつにするか、k平均ほうは開始点をどこにするかで結果が変わる。
アートというか、試行錯誤なのかなと。
慣れと経験が必要な世界かもしれない。。。


##サポートベクターマシン
- 要点

https://qiita.com/gataca27/items/9a3a5fed3afa0f849c82

- サマリーと考察
解を求めるのは、次元を低くするだけでなく、高くする場合もあるようだ。
確かに2次元を3次元にすれば、線形で表せる場合もあるよなぁと。
whereで複数条件でカラムを合計する

現在作っているダイエットのためのカロリー計算アプリですが、
トップページの本日食べた栄養素とカロリー合計を表示するようにしています。
集計するには
user_id別
カロリー別
同一日付内で合計しています 

■id別日付別という２重条件についての処理

```rb
.where(×××××: day).where(×××××: current_user.id)　　　　　※：カラム名
```

■合計します

```
.sum(:×××××)　　　　　※：カラム名
```

■小数点以下の計算が多いので小数点３桁以下を四捨五入

```rb
.round(3)
```

でき上がったのは以下

```rb:[circle_contoroller.rb]
     @calorie = CookedFood.where(meal_date: day).where(user_id: current_user.id).sum(:calorie).round(3)
     @protein = CookedFood.where(meal_date: day).where(user_id: current_user.id).sum(:protein).round(3)
     @carbohydrate = CookedFood.where(meal_date: day).where(user_id: current_user.id).sum(:carbohydrate).round(3)
     @sugar_content = CookedFood.where(meal_date: day).where(user_id: current_user.id).sum(:sugar_content).round(3)
     @fiber = CookedFood.where(meal_date: day).where(user_id: current_user.id).sum(:fiber).round(3)
     @salt = CookedFood.where(meal_date: day).where(user_id: current_user.id).sum(:salt).round(3)
     @lipid = CookedFood.where(meal_date: day).where(user_id: current_user.id).sum(:lipid).round(3)
     @meal_quantity = CookedFood.where(meal_date: day).where(user_id: current_user.id).sum(:meal_quantity)
```
2Dアクションゲームを作りながらUnity学習　#最終日

# 環境
* MacBookAir(M1,2020)
* UnityHub 2.4.3
* Unity バージョン2020.3.10f1

# 学習内容
* コンティニュー設定
* ステージクリア設定
* 次のステージへのシーン移動

# 苦労した点
* コンティニュー位置へのリスポーン設定
* 次のシーンへの移動の設定

# 感想
2Dアクションゲームのゲームスタートからクリアまでの流れを一通り学ぶことができました。これからは学んだ事を活用しつつ、新しい知識も取り入れつつゲーム制作を出来ればと思います、
初学者がlaravel 8.xのBreezeでログイン機能を実装してみた

初学者が簡単なCRUDアプリにログイン機能を実装したいなと思ったとき、
公式ドキュメントより**「まず、Breezeより始めよ」**とのお告げがあったので
Breezeでログイン機能を実装してみました。

##環境
OS: Windows 10 home
CPU: AMD Ryzen 2700X
GPU: NVIDIA GTX 1060
RAM: 16GB 2666Mhz
PHP: ver 8.0.3
Laravel: ver 8.45.1
MySQL(MariaDB): ver 15.1

##1.laravelの認証機能

laravel 8.xでは認証機能構築のスターターキットとして、
jetstreamとbreeze、が提供されています。
**jetstream**はログイン、ユーザー登録、メール検証、２要素認証、セッション管理等を含む
多機能な認証パッケージであるのに対して、**breeze**はログイン、ユーザー登録、パスワードのリセット、
メールの検証、パスワードの確認等の最小限の認証パッケージとなっています。
そのため、公式ドキュメントは**「まず、Breezeより始めよ」**とbreezeから始めることを推奨しています。
また、jetstreamとbreezeはCSSフレームワークがbootstrapから**Tailwind CSS**に変わっていることに留意。
なんで**Tailwind CSS**推しに...bootstrapでいいじゃないですか。

##2.laravel Breezeのインストール

事前にlaravelプロジェクトを作成しておきます。
筆者はlaravel/installerで作成しているので以下のコマンドになります。

```
 laravel new example-app
```
ターミナルで作成したlaravelプロジェクトのディレクトリまで移動し、
ComposerでLaravel　Breezeパッケージをインストールします。

```
composer require laravel/breeze --dev
```

Laravel　Breezeパッケージのインストールが完了したら
Artisanコマンドでプロジェクトにインストールします。

```
php artisan breeze:install
```

最期にNode.jsモジュールのインストールとアセットのコンパイルを行いますが、
そのためにはNode.jsとnpm(Node Package Manager)が必要となります。

```
npm install
npm run dev
```
これでLaravel　Breezeの実装は完了しました。

php artisan serveコマンドで簡易サーバーを立ち上げて確認すると、
画面右上赤丸内にloginとregisterが表示されます。

![laravel_breez.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1507835/a7acd997-24cf-4dbf-0492-743bea296f88.jpeg)
大文字、小文字に関係なく部分検索[PostgreSQL]


### 結論
大文字、小文字に関係なく部分検索を行うには、ILIKEを使えばいい。


■ 普通の部分検策

```sql
select * from users name like '%iizuka%';
```
name = iizukaがヒット。

■ 大文字、小文字に関係なく部分検索

```sql
select * from users name ilike '%iizuka%';　
```

name = iizuka ,name= IIZUKA,name =iIzUka などがヒット 。
CentOS7のダウンロード手順（macOS）

## 概要

備忘録として、下記手順を記載する。
・CentOS7のダウンロード

### 前提
OS：macOS Big Sur
バージョン：11.2.1

## 手順

### 1 CentOS7のダウンロード
[CentOS公式ページ](https://www.centos.org/)にアクセス
ヘッダーの`Download`をクリック
![スクリーンショット 2021-06-19 23.50.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581782/d8f92128-a856-9612-0f07-7ae7e5d91ca6.png)
ダウンロードページに遷移
画面下部の項目［Older Versions］の、`then click here`をクリック
![スクリーンショット 2021-06-19 23.50.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581782/2c769485-6b1e-7834-50d3-67ecbb1d9d28.png)
［Download CentOS Linux ISO images］画面に遷移
`CentOS Linux Version：7`の、`mirrors`をクリック
![スクリーンショット 2021-06-20 0.00.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581782/5ba1f76d-92d8-e6d3-68b0-7344d8930913.png)
［In order to conserve the limited bandwidth available, ISO images are not downloadable from mirror.centos.org］画面に遷移
（google翻訳：利用可能な限られた帯域幅を節約するために、ISOイメージはmirror.centos.orgからダウンロードできません。）
［The following mirrors in your region should have the ISO images available:］から、任意のURLをクリック
（google翻訳：お住まいの地域の次のミラーでは、ISOイメージを利用できるはずです。）
![スクリーンショット 2021-06-20 0.04.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581782/137d685a-9ee3-1ef5-7dfd-e59e2e149f93.png)

格納されている`CentOS-7-x86_64-DVD-2009.iso`をクリック
ファイルのダウンロードが開始される
（通信状況によっては、1時間以上時間を要するため注意）
![スクリーンショット 2021-06-20 13.11.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581782/d6754ec4-3001-46e7-ad61-2b06dc671ddf.png)


ダウンロードフォルダに、isoファイルがダウンロードされたことを確認
![スクリーンショット 2021-06-20 15.16.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581782/7204137e-e0b1-e625-c2de-85ae1c406eb0.png)


以上

[VertualBoxに仮想マシンを作成する手順](https://qiita.com/kazuho_0531/items/10e09a353fe7e645c37d)へと続く
nullを気にせず文字列結合[PostgreSQL]

null + 1 = nullになったり厄介なnullだが、
以下のようにすると、もし引数がnullになった場合も空白に置き換えてくれる。

```sql
select concat('マイクチェック','ワンツー'); => 'マイクチェックワンツー'
select concat('マイクチェック',NULL); => 'マイクチェック'
```
AWS EC2にMySQL Serverをインストールする

# はじめに
<!-- 発端や概要を記載 -->

# 目次
<!-- タイトルとアンカー名を編集 -->
1. [MySQLをインストール](#Chapter1)
1. [MySQLへアクセスする](#Chapter2)

<!-- 各チャプター -->
<a id="#Chapter1"></a>
# EC2にMySQL Serverをインストール
####【前提】
・MySQL SevrerをインストールしたいEC2インスタンスにルート権限でログインしてください。

####【手順】
**1.MySQLリポジトリをインストールする。**

```
yum localinstall https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm -y
```
**2.MySQL Serverをインストール。**

```
yum install mysql-community-server -y 
```
※サーバのインストールのため時間がかかる場合があります。

**3.MySQLを起動。**

```
systemctl start mysqld
```

**4.サービス自動起動に設定。**
EC2インスタンスが停止するとサービスも停止されるため、「EC2起動してるのにMySQL使えない！なんで？」なんてことがないように自動起動を設定します。

```
systemctl enable mysqld
```

<a id="#Chapter2"></a>
# MySQLへアクセスする

**1.MySQLログから初期パスワードを確認する**
MySQLインストール時に発行される一時パスワードを確認します。
パスワードは```/var/log/mysqld.log```に出力されています。

```
cat /var/log/mysqld.log | grep localhost
```
次のように出力されているはずです。

```
2021-06-19T10:36:06.105340Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: [パスワード]
```

**2.MySQLにログイン**

```
mysql -u root -p
```
※Enter password：とでたら１で確認したパスワードを入力します。

**3.初期パスワード変更**
一時パスワードのままだとMySQLの操作ができないため、パスワードを変更します。

```
ALTER USER root@localhost IDENTIFIED BY 'パスワード';
```

以降、通常のSQL操作可能です。