OmniAICreator/Qiita-1.07M huggingface dataset:
文字コードの指定ミスによる、マイグレーションファイルが実行できないエラーについて。

|No.    |*タイトル*                  |
|----------|--------------------------|
|1|[マークダウンの備忘録](https://qiita.com/kawashi23/items/8466e744035fef6daf17)
|2|[投稿記事一つ目](https://qiita.com/kawashi23/items/50c8570d7cba34b95c9b)
|3|**現在の記事**


エラーが発生いたしました。

```
An error has occurred
```

マイグレーションファイルの実行をした時です。

```
rails db:migrate
```

```
:Error: Specified key was too long; max key length is 767 bytes
```
キーの長さが最大767バイトを超えてしまったとエラー文です。

直前の自身の操作を思い返してみます。

```
t.string :name,               null: false
```

キーについてマイグレーションファイルに記述を行なっていました。

では、このキー(:name)が怪しいです。
名前の文字数に関連する何かであると考えられます。


エラー文を検索すると以下の記事に詳細が書かれていました。
https://qiita.com/terufumi1122/items/9ea764618eba01144e09



**RailsやCakePHPのデフォルトで生成される255文字のVARCHARでは、3バイトのutf8では255×3=765でほぼぴったり収まります。一方、utf8mb4ではオーバーしてしまうので、エラーとなりました。**



*ここでVARCHARとは、データベースのフィールド定義などで用いられるデータ型の一つで、可変長の文字列を意味するデータ型のことです。*
http://e-words.jp/w/VARCHAR.html#:~:text=VARCHAR%E3%81%A8%E3%81%AF%E3%80%81%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E3%81%AE,%E3%82%92%E6%84%8F%E5%91%B3%E3%81%99%E3%82%8B%E3%83%87%E3%83%BC%E3%82%BF%E5%9E%8B%E3%80%82

*つまり推測になりますが、カラムの型と、そのキーを記述してマイグレーションファイルを実行するということは、
そのキー(テーブルにおけるカラム)について767バイト分のデータ容量を確保するといことになるのでしょうか。
可変長ということなので、レコードごとにその容量は異なりますが、767バイトは超えてはいけなく、かつnull: falseによって0バイトでもいけないということでしょう。*




ここでもう一度、上記の引用です。
**RailsやCakePHPのデフォルトで生成される255文字のVARCHARでは、3バイトのutf8では255×3=765でほぼぴったり収まります。一方、utf8mb4ではオーバーしてしまうので、エラーとなりました。**



Railsにおいて、255文字分のVARCHARは自動生成され、
そして、一文字ごとのデータの大きさは文字コードによって異なるみたいです。

文字コードutf8は255文字生成されたとしてもそのデータの大きさは765バイト、可変長容量内です。

**よって今回、文字コードの指定がutf8mb4となっていると考えられます。**

アプリケーションの開発において、
文字コードの記述があるパスは、
*config/database.yml*です。

行ってみると

```ruby

encoding: utf8mb4
```
と記述がされていました。

```ruby
ecoding: utf8
```
に記述を書き直し。

再度マイグレーションファイルの実行をします。

```
:Error: Table 'users' already exists
```

不安を覚えましたので
Sequel Proを確認しにいきます、
文字コードに関連しているだろう記述がある部分を見つけました。

![10e5c8a893f7e8c6452c104aa1e9bb54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703383/529a900c-a4e0-aa21-fddf-20b72b636e2b.png)

￼

utf8mb4のままの部分がございます。

データベースのリセットを一度行います。

```
rails db:reset
```

その上でマイグレーションファイルを実行いたします。

```
rails db:migrate
```

今回はエラー文が表示されませんでした。

￼

再度、確認しに行きますと
しっかりとutf8となっています。

![935e08cdb5323459dc9b03759ee1426e.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703383/c2d20e66-8703-0d56-356c-0d9f33c868b1.png)

以上でエラー解決とさせていただきます。

最後まで、お読み頂きありがとうございます。
誤った認識をしている箇所、認識が不足している部分について、ご指摘して頂けますと幸いに存じます。
【#PowerApps Tip's】アイコンを素早く簡単に見つける

ひさしぶりの Power Apps Tip's です。今回は、画面の動作やデザインで活躍してくれるアイコンを、素早く、手軽で簡単に見つける方法です。
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215892/dc3ff610-5bc5-2000-2670-7fdf0b2bee41.png)

# アイコンを素早くアレする実例
動画を用意しておきました。ご確認ください。
<blockquote class="twitter-tweet"><p lang="en" dir="ltr"><a href="https://twitter.com/hashtag/PowerApps?src=hash&amp;ref_src=twsrc%5Etfw">#PowerApps</a> Search for icons quickly. <a href="https://t.co/BTHKF6Pnrt">pic.twitter.com/BTHKF6Pnrt</a></p>&mdash; やま (Yama) (@yamad365) <a href="https://twitter.com/yamad365/status/1302541097344757760?ref_src=twsrc%5Etfw">September 6, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 操作の説明
1年ほど前は無かったの機能だと記憶しているのですが、現在の Power Apps 編集画面ではアイコンを検索することが可能です。ただし、メニューバーからは検索できない（´・ω・｀）
なので、下記のような手順になります。

 1. メニューバーの[アイコン]をクリック
 2. 表示された上位の何でも良いのでクリックして Screen に追加
 3. 追加したアイコンをクリックし、右ペインの「プロパティ」領域で[アイコン]をクリック
 4. 検索するなり、目視で探すなりご自由に！

プロパティ領域で表示されるヤツのが見やすいですし、検索機能もついてて便利ですよね。アイコンを置いた後で表示する内容を切り替えられるのも便利です。配置したアイコンが間違っていても、わざわざ消して再実施する必要もなくなります。

# 実は検索できないヤツもある
そうなんですよ。メニューバーの「アイコン」から選択可能なくせに、検索できないヤツらがいるんですヽ(`Д´)ﾉﾌﾟﾝﾌﾟﾝ

<blockquote class="twitter-tweet"><p lang="en" dir="ltr"><a href="https://twitter.com/hashtag/PowerApps?src=hash&amp;ref_src=twsrc%5Etfw">#PowerApps</a> Some icons can&#39;t be searched. <a href="https://t.co/jdfzsISdpj">pic.twitter.com/jdfzsISdpj</a></p>&mdash; やま (Yama) (@yamad365) <a href="https://twitter.com/yamad365/status/1302542444655861761?ref_src=twsrc%5Etfw">September 6, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## ”図形” カテゴリーは検索できないっぽい
記事投稿時点で、ですが、左の領域にある「＋」からコントロールを挿入する箇所で”図形”にカテゴリーされてるヤツらは[アイコン]プロパティが無いようで、検索できません。つまり、配置する対象を間違えたらコイツらは削除してやり直しになります。
![図2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215892/4936d9ff-d7ef-ca7c-809a-ef11e425ca64.png)

# まとめ
- アイコンの１部は操作の柔軟性が Up している
    - 配置した後でもアイコンが変更可能になっている
    - アイコンの種類はプロパティ領域で検索が可能
    - アイコンの変更なので、コントロール名は変わらない(※重要)
- ”図形”カテゴリーに属する一部のアイコンは検索できない
    - 配置後に種類を変更することもできない

一部、未対応のモノがありますが、数が多いアイコンをいちいちスクロールしていた過去に比べたら断然便利になったと感じます。”戻る” や ”保存” などはアイコンを配置した後に、画面全体のデザインと見比べて「あ、やっぱりコッチに変更しよう」等が比較的多く発生する部分だと思います。その際、消して → 追加しなおす、という必要が無くなるだけでも便利さを実感できるんじゃないでしょうか。
また、前述のとおり『コントロール名が変わらない』のは重要なポイントだと思います。消して、再配置したら、また名前から変更しないとダメですから。テマが減るのは良いことですねー。

それでは、皆さま。素晴らしい Power Platform Life を！
firebaseライブラリを使おうとすると、、、、

約50行にも及ぶ長文で怒られた。

```console:
$ yarn add firebase
$ yarn run dev

Module not found: Error: Can't resolve 'core-js/modules/es6.array.find' in '/app/.nuxt'./.nuxt/client.js
・・・・・
```

firebase公式では、npmでインストールしてるし、そういうのも関係してるのかなと思い、npmで再インストールしても怒られてた。

#解決

シンプルにcore-jsについてのエラーなんだと、初心に立ち返りググり、そして見つけた解決法がこちら。


```
$ yarn add core-js@latest2.6.2

? Please choose a version of "core-js" from this list: 3.6.5
3.6.5
3.6.4
3.6.3
3.6.2
3.6.1
・・・
```

おそらく、`yarn add core-js@latest`でも大丈夫であろうが、この方がコンソール上でバージョン指定できるので安心して選択できる。（個人的な性格の問題）
EfficientNet

勉強メモ

英語解説動画
https://www.youtube.com/watch?v=3svIm5UC94I
・width, depth, resolutionを組み合わせてCompoundsでScaling upしたほうが精度良い(同じ計算量で)

sonyのNeural Network Consoleが出している動画
https://www.youtube.com/watch?v=UximUEjPQco
・3x3、1x1（Pointwise）、Grouped、Separable（Depthwise + Pointwise）Convolution
JetPack のサイトアクセラレーター有効時にフルサイズ画像が縮小されてしまう問題への対処法

## 問題

WordPress で　JetPack の <q>サイトアクセラレーターを有効化</q> と<q>静的ファイルの読み込みをスピードアップ</q> を ON にしていると、投稿内で読み込まれる画像の幅が、<q>画像サイズ</q>: <q>フルサイズ</q> を指定していても、1024px に縮小されたものになってしまいます。


## 原因

JetPack は `global $content_width` を参照して、画像の最大幅を決定しているため[^width]。

[^width]: したがって、テーマ内で `global $content_width` が指定されている場合は、1024px 以外の幅になる場合もあります。

## 解消方法

functions.php 等に以下の内容を追記し `$global $content_width` を上書きします[^child-theme]。

[^child-theme]: 子テーマやプラグイン内での指定は未検証です。`add_action( 'after_setup_theme',  $function_to_add )` を使う必要があるかもしれません。


```PHP:functions.php
<?php
// ...

( function() {
	global $content_width;
	$content_width = 1920; // 想定される画像の最大幅を指定する.
} )();

// ...
```

[^1]: 未検証。

## 備考

将来的[^wordpress-version]に、`add_theme_support()` で `global $content_width` を変更できるようになる可能性があります[^21256]。

[^wordpress-version]: この記事の執筆時点での最新 WordPress バージョンは、5.5.1。 
[^21256]: Cf. [#21256 (New theme feature - add_theme_support( 'content-width', $defaults )) – WordPress Trac](https://is.gd/yVv4V5).

## 参考ページ

* [Full image size (Gutenberg block "image") is not full size but limited at 702px · Issue #13433 · Automattic/jetpack](https://is.gd/5N18kN).
* [コンテンツ幅 - WordPress Codex 日本語版](https://is.gd/iQR7yR).
ファイル共有システムに出てくる用語（SAN,NAS,iSCSI,NFS,SMB,CIFSなど）


ファイルシステムの構築関係について調べていたところ、知らない用語がバンバン出てきたのでざっくりまとめてみます。（自分の理解用です。間違いがあれば指摘歓迎です。）

以下の用語を調べたものです。
![ファイルサーバー系用語整理.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296083/d4ad843d-910e-5018-a8c2-ec2af72744bd.jpeg)


##DAS,SAN,NASについて
### DAS
Direct Attached Storage
サーバとストレージが1：1でケーブルでつながっている、普通の物理PCの構成。

### SAN
Storage Area Network
ストレージ専用ネットワークを使って、ケーブルで繋ぐのではなくネットワーク越しにストレージを接続させようとしたもの。
これによって複数のPCから一つのストレージを共有することができるようになった。

### NAS
Network Attached Storage
Windwos, Linux問わず使われるネットワーク越しに使われるファイルシステムの名称で、NFSがLinuxのファイルサーバー（兼プロトコル）の名前、CIFSがwindows向けのファイルサーバのプロトコルの名前らしい。

## SANで使われるプロトコル
### SCSI（プロトコル）
SANを実現するための通信方式。Fibre Channelという光ファイバーを使った通信上で動く。Fibre Channel用の機材が高い。 

### iSCSI
iSCSIはSANを実現するためのプロトコルでIPネットワーク上で動く。
もともとFibre Channelという光ファイバーを使った通信上で動くSCSIという方式が使われていたが、こっちより既存ネットワークを利用するため安くて構築が楽。


## NASで使われるプロトコル
### NFS 
Unix系のOSで使われる、ネットワーク越しにファイルを共有するファイルシステムの名前。プロトコルの名前でもある。

### SMB
マイクロソフトで作られたプロトコルで、ネットワーク越しにファイルの共有を行うときに使われる。廃止予定。

### CIFS
マイクロソフトで作られたプロトコルで、SMB同様ネットワーク越しにファイルの共有を行うときに使われる。SMBの後継プロトコル。windows系以外のファイル共有にも使えるようにしているっぽい。

## その他の用語
### CHAP
Challenge Handshake Authentication Protocol
ユーザーが入力した認証情報を記録してそのまま再利用するプレイバック攻撃を避けるために、毎回パスワードを暗号化した乱数を使う方式。

### イニシエータ接続の認証
iSCSIのアダプタとの接続時に認証を行うこと

## 調べる中での疑問
### ISCSIとNFSの違いはなにか？
ISCSIはSANで、NFSやCIFSはNASで使われるプロトコルだ。
なので、ISCSIとNFSの違いというよりSANとNASの違いをわかったほうが良さそう。
SANはブロックストレージ、NASファイルストレージという分類のものらしい。

**SANへのアクセス→ブロック単位でのアクセス**
ファイルシステムより小さなブロックでストレージにアクセスする。
より低レイヤでのアクセスになるのでNASより高速に動作する。

**NASへのアクセス→ファイル単位でのアクセス**
ファイル単位でストレージにアクセスする。NASがファイル構造を理解していて、変更要求を受けたときにどのファイルに変更を加えるかを認識できている。必要に応じてロック処理をしてくれるので、競合が起きない。
ASUS PRIME H470M-PLUSのボードにWindows Server 2019をインストールする

#はじめに
このマザーボードに対して、AHCLモードでなくIntel RSTモードでもインストールができたので、新たに[Qiita](https://qiita.com/tokinkouju/items/8fa5ee1e5dcaa1b93672
)を起こしました。

#概要
[ASUS PRIME H470M-PLUS](https://www.asus.com/jp/Motherboards/PRIME-H470M-PLUS/)はWindows 10しか公式にサポートしていないが、そのボードを使って最低限利用できそうな[^最低限]Windows Server 2019を入れてみる。


#注意点
このような利用は本来サポート外のため自己責任において実施してください。情報提供はありがたいですが、このサイトをみて実際にインストールしてできなかったからと言って私のせいにはしないようにお願いします。

#前提知識
PCを自作したことがある、またはその知識があってPCを組めそうという方を対象にしている。

デバイスドライバーはWindowsで共通的に使えることが多く（少しハックする場合もあるが）おおよそ以下の関係があると思っている。以下の表を念頭にサーバ用ドライバがないときはクライアントOSのドライバを探すと大体よさげな感じがする。

|クライアントOS|サーバOS|
|:-:|:-:|
|Windows XP|Windows Server 2003|
|Windows Vista|Windows Server 2008|
|Windows 7|Windows Server 2008 R2|
|Windows 8|Windows Server 2012|
|Windows 8.1|Windows Server 2012 R2|
|Windows 10(Ver.1809より前)|Windows Server 2016|
|windows 10(Ver.1809以降)|Windows Server 2019|

#PCを組み立てる必要のある部品のほかに用意するもの

* LANボード（OSをインストールすると一緒に入れてくれるもの、またはOS用のデバイスドライバが提供されているもの）[^LANボード]
* Windows Server 2019のインストールメディア（またはそれを入れたUSBメモリ）、ライセンスキー

#インストール前に
BIOSの設定でRAIDはかけていない[^BIOS設定]。その他基本的にデフォルト設定のままで実施している。（intel Virtualization Technologyだけは事情があり有効化）

#インストール手順
1. OSをインストールする
2. マザーボードに付属のCD（なかったら[インターネットサイト](https://www.asus.com/jp/Motherboards/PRIME-H470M-PLUS/HelpDesk_Download/)からダウンロード）よりChipsetをインストールする。インストールする際にAsusSetup.exeではなく、SetupChipset.exeを実行してインストールする。[^chipset]
![Chipset-install.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101343/12a59c35-c7d1-6cfb-bb40-e4aef0cf2f60.jpeg)
3. 同じくマザーボード付属のCDからAudioをインストールする。インストールする際にAsusSetup.exeではなく、install.batを実行してインストールする。
![audio-install.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101343/29037e4f-6573-a0f9-d8b8-5253cad36f82.jpeg)
4. LANボードを認識していればLANドライバーをインストールする。
5. Windows Updateを実行する。[^RAID]

#終わりに
実はこのボードを購入したお店の方から（結構詳しい方と思われる）「Windows Server 2019はちょっとデバイスドライバーが厳しくなった」というような話を受けたので、ちょっとチャレンジしてみた。オンボードだけでは確かにLANポートが使えていないのでお店の方の言う通りであった。
この後、自宅のActive Directoryサーバが古いのでアップグレードする準備のためにいったんこのOSは消した。

P.S. 画像がスマホ撮影なのは手っ取り早く伝えたかったため。

[^最低限]: インターネットが利用できて最新のセキュリティ更新プログラムが適用できる状態で普通にOSの操作が利用できるという意味。

[^LANボード]: 記載した2020/9/6時点ではLANコネクタ（Intel Ethernet Connection I219-V）に対応したWindows Server 2019のドライバが[Intelのサイト](https://downloadcenter.intel.com/download/28410/Adapter-User-Guide-for-Intel-Ethernet-Adapters?product=82186)にあるのは知っているのですが、書いている時点ではうまく当たらなかったので、再度トライする。

[^BIOS設定]: 検証をしていないこともさることながら、Intel Rapid Storage TechnologyのドライバーはOSをインストール後に入った関係でうまくいくか不安だったから（かつ、あとでインプレースアップグレードをかけるときに、これが邪魔する可能性が高いため）

[^chipset]: デバイスマネージャーから不明なデバイスと出ている箇所の多くがこれで埋まる。

[^RAID]: RAIDドライバーを入れる際には.net Framework 4.6.1以上をインストールしてから入れられそうだが（1回入ったけど再度確認のため）未記載。
わかりやすい変数名の付け方

#プログラミング勉強日記
2020年9月6日
わかりやすいコードを書くために必要不可欠であるわかりやすい変数名の付け方をまとめる。変数名をわかりやすくすることで、読みやすく、コードの間違いにも気づきやすくなる。


#PHPの変数の書き方
- PHPの場合は変数は`$`から始まる
- そのあとは半角英数字とアンダーバー(`_`)が使用することができる。($のあとにすぐ数字を使うことはできない)

 以上のルールに違反すると、実行時にエラーとなってしまう。

 また、ルール(命令規則)ではないが以下の決まりもある。

- 大文字と小文字は区別される。
- 変数名を全て大文字にすることもできるが、特別な意味を持つ変数を全て大文字にすることがあるので、全て大文字にはしないほうがいい。



ルールではないが、複数単語になる場合は
単語と単語の間をアンダーバー(`_`)で区切るか、2語目以降の先頭の文字を大文字にする。

<font color=orange>☆ポイント</font>
　複数の単語を使うときはどちら(先頭を大文字にするのか`_`を使うのか)を決めておく。

```php:複数単語の例
//悪い例
$userid = "123";
$user_name = "Tanaka";
$userGroup = "A";

//良い例
$userID = "123";
$userName = "Tanaka";
$userGroup ="A";
```


#変数名の付け方
　変数の中身は何を格納するのか。中身は何なのかを示したものにする。つまり、変数がどの用途で使われるのかわかりやすい名前にする。
　変数名は長すぎず短すぎずちょうどいい長さにする。
　データベースのテーブルから取得したデータには、テーブルの名前やカラム名をそのまま付けるとわかりやすくなる。

```php:例
//悪い例
$data //何のデータかわからない
$a    //何を格納しているのかわからない
$var  //何の変数(variable)かわからない

//良い例
$error_message //エラーメッセージが格納されている
$user_id       //ユーザのidが格納されている
```
機械学習は平行四辺形を予測できるか？（２）内挿みたいなのに外挿ってどうなるかな？？


前の記事
[機械学習は平行四辺形を予測できるか？（１）外挿ってできるかな？](https://qiita.com/motoyuki1963/items/0f8758599c08030e2393)

前の記事を書いて思ったのですが、あまりプログラムテクニックが書いてありませんでした。でも、一応pyhtonで計算しているので、タグはpythonにしてあります。pythonで機械学習している人も多いだろうから、qiitaへの投稿でも良いですよね。。。
この計算は、`scikit-learn`で計算しています。

さて、前の記事で外挿ができないことはわかりました。
じゃぁ、次のような問題は、どうなるでしょうか？

####問３：小さい値と大きい値で学習して、その間は予測できるか？

![sihenkei.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336017/d42280ae-8d9c-ae6c-84b7-1b79777e34de.jpeg)


||ａ　|ｂ |角度ｃ|
|---| -------------- | ---------- |---------- |
|学習用|0~50　and　1000~1100|0~100|0～90|
|内挿？外挿？|150～900 |50|45|


簡単な問題です。底辺の長さａを0~50、1000~1100で予測して、その間の150~900は予測ができるのでしょうか？

線形回帰のLassoは、たぶん予測できるのでしょう。でもランダムフォレストやニューラルネットワークは、どうなるのでしょうか？
このデータセットがあったら、0~1100まで予想できると、ついつい思ってしまいます。現実のデータは、こういう例がありそうです。


結果です。
まず、学習の結果の決定係数とグラフです。

|決定係数　 |学習|テスト|
| -------------- | ---------- |---------- |
|Lasso回帰 |0.686|0.661|
|ランダムフォレスト| 0.999|0.975|
|ニューラルネットワーク　　|0.997|0.997|
Lasso
![lasso.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336017/d40636d9-1cd9-4b69-6b85-80724b43c43f.png)
ランダムフォレスト
![random.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336017/50e8344e-e104-3020-a432-1fc7360ed44e.png)
ニューラルネットワーク
![mlp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336017/3e9dab70-f916-b8ae-dfab-5f9ba660a871.png)
底辺aの値は、小さい値と大きい値にしてありますが、bと角度cがランダムに作られているため、面積のareaの領域はつながって見えます。

グラフで見ると、ランダムフォレストの２つのはずれ値がなぜ出たのかはわかりませんが、でも、これらのグラフと決定係数をみれば、Lassoを選ぶ必要はないと感じてしまいますし、ランダムフォレスト最高！ニューラルネットワーク最高！って思いますよね。


では、底辺ａで学習した間の値を予測するとどうなるか？です。
とりあえずグラフを見てみましょう。
Lasso
![lasso_gaisou.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336017/c77ab234-4f0b-3f22-e3c6-4966b51da522.png)
ランダムフォレスト
![random_gaisou.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336017/f224802d-3eb1-94b3-1139-4d5e052e42ec.png)
ニューラルネットワーク
![mlp_gaisou.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336017/99839e03-878d-2cd1-e79a-540aa1f6997e.png)

底辺ａの数値を学習の間に入れていますが、ニューラルネットワークは全然ダメです。これを見ると、ディープラーニングでの回帰予測は、しっかり内挿で予測しないと危ないですね。
ランダムフォレストもそうです。内挿、外挿をしっかり見極めないといけません。

Lassoは、みてわかるように、近い値で予測できています。少しでも外挿の恐れがある場合は、線形回帰が良いということかもしれません。

###結論
####機械学習で外挿の予想はやめましょう。特に、内挿のように見える外挿が要注意です。少しで外挿の予想をしていると思ったら、線形であると仮定を立て、線形回帰で頑張りましょう。

ということかもしれません。

次は、記述子設計を検討してみます。
declare moduleで型を拡張するときのtsconfigの設定

## 問題点

vuexのように既存の型が貧弱なライブラリではユーザーが型定義ファイル(d.ts)を用いて型を拡張することができます。

```ts:type/vuex.d.ts
declare module 'vuex' {
  type Getters<S, G> = {
    [K in keyof G]: (
      state: S,
      getters: G,
      rootState: RootState,
      rootGetters: RootGetters
    ) => G[K]
  }
...
}
```

そしてこのvuexを使おうとしたところ

```ts
import { Getters } from 'vuex'
//       ~~~~~~~ Module '"vuex/types/index"' has no exported member 'Getters'. Did you mean 'Getter'?ts(2724)
```

と怒られた。
この時vuexは`module "node_modules/vuex/types/index"`とmode_moduleの方しか見ていなかった。

vuexをインポートするときに`type/vuex.d.ts`を見てくれるようにしたい

## 解決

tsconfigでインポートするときに見るパスを直接指定する方法がある。
`paths`オプションに以下のようにパスを指定した。

```json:tsconfig.json
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "vuex": ["src/types/vuex.d.ts"]
    },
  }
}
```

baseUrlを指定し、そこからのパスを設定したらうまく読み込むようになった。
AndroidにおけるHMSのAPI Keyの二重定義の問題とその解決策

#HMSのAPIキー
[ファーウェイ（Huawei）](https://www.huawei.com/jp/)の[HMS（Huawei Mobile Services）](https://developer.huawei.com/consumer/jp/)は[プッシュキット（Push Kit）](https://developer.huawei.com/consumer/jp/doc/development/HMSCore-Guides/service-introduction-0000001050040060)や[マップキット（Map Kit）](https://developer.huawei.com/consumer/jp/doc/development/HMSCore-Guides/android-sdk-introduction-0000001050158633)など、複数のキッドより構成されています。特定なキッドを利用するのに、APIキーが必要です。

#APIキーの場所
APIキーはAppGallery Connectの[Project Setting] -> [General Information]にあります。
![AppGallery Connect - Project Setting.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704548/6d3b0111-3dbd-b79d-3d44-7d2929cb9588.png)

#APIキーの導入とその問題点
通常、APIキーは次のように導入します。

```Kotlin:MainActivity.kt
// たとえば、private val API_KEY = "CgB6e3x9iW/qiE9l9wAUPK0e/bJQe5uIgTlYUD4bPc8gzjriSVxDDzX2fAVjCVdUHkP+tan0Xi0sf4tj7t11TJJe"
private val API_KEY = "Your API key"

// マップキットを利用するケース
MapsInitializer.setApiKey(API_KEY)
```

または、次のようにように導入します

```XML:strings.xml
<!-- たとえば、<string name="api_key">CgB6e3x9iW/qiE9l9wAUPK0e/bJQe5uIgTlYUD4bPc8gzjriSVxDDzX2fAVjCVdUHkP+tan0Xi0sf4tj7t11TJJe</string> -->
<string name="api_key">Your API key</string>
```

```Kotlin:MainActivity.kt
// マップキットを利用するケース
MapsInitializer.setApiKey(getString(R.string.api_key))
```

しかし、上記の導入方法ですと、APIキーを明示的にソースコードに記載しなければなりません。

HMSを利用するのに、agconnect-services.jsonをAppGallery Connectからダウンロードし、プロジェクトのappフォルダに置く必要があります。
![Android Studio - Project.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704548/12e84a50-7a64-4edb-fc0c-cfa1495a8b86.png)
agconnect-services.jsonを開くと、client -> api_keyにAPIキーが載っています。
![agconnect-services.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704548/7ba41bf0-4ef1-792f-3931-0bb658c6218c.png)

これですと、APIキーが二重定義になってしまい、ソースコードとしてはあまりよろしくありません。

#解決策
次のように書けば、APIキーの二重定義の問題が解決されるだけでなく、agconnect-services.jsonに載っているAPIキーをそのまま利用するので、APIキーの記載間違いも起きません。

```Kotlin:MainActivity.kt
val api_key = AGConnectServicesConfig.fromContext(applicationContext).getString("client/api_key")

// マップキットを利用するケース
MapsInitializer.setApiKey(api_key)
```
普通の事務OLがVBAのおかげでちょっと幸せになった話

##私がVBAの勉強を始めたきっかけとか色々…
今日はコードの話とかじゃないです！
今日は日曜日だし、いつもと違う感じのこと書いてみようかと思いました。
今からVBAの勉強をしてみようかなと思っている普通の事務OLの方には参考になるかもしれません。
（限定的なターゲット！笑）
##特別なスキルを持ってると時給も良いっぽいけど…
私はここ数年ずっと派遣の事務で働いてますが、いつも新しい募集案件とかみる度にそう思ってました。
昔からExcelは大好きで、普通の人よりはちょっと関数を使いこなしたり簡単なマクロを作ったりしたことはあったものの、ただのOLということには変わりなく
「本格的に何か勉強してそれ専門の仕事をするのは大変そうだしな…」って思って避けてました。

例えばVBAとかスキルとして身につければ、お給料がよくなるのはわかっていてもなかなか踏み出せずにいました。

ちなみに私の登録してる派遣会社が出してる案件（都内）の時給相場は
普通の事務案件は
__1550円〜1750円ほど__

外国語や業界専門知識、VBAなどが必須スキルの事務案件は
__1800円〜2000円ほど__
こんな感じだと思います。
##やっぱこれからのことを考えると何かスキルを身につけなければ…！
勉強するのを躊躇してたものの年齢を追うごとに、「特にこれといって得意なこともないし、このままで大丈夫かしら…」って考えるようになり、やっと一念発起！
何かスキルになるものを勉強してみようと思いました。

当時は人事で事務をしてましたが、今の仕事にも活かせて自分が好きになれそうなもの…
そうやって色々考えた結果が__「ExcelVBA」__でした。
##まずはテキストを一冊、最初から最後までやってみること！
自分の仕事でやってる作業を自動化していけばそのうち色々作れるようになるかな〜って思ってSEをやっている友達に相談してみたところ、
__「いや、自分の作りたいものだけ作っていても勉強にならない。まずはテキストに忠実にひとつのものを最後まで作ってみるほうが基礎からしっかり学べるよ！」__と言われました。

私は自分の作りたいものを作ったほうが勉強になりそうと思ってたので、「え？そうかな〜…」と思いつつ、その人が勧めてくれた本をその人に教えてもらいながら始めてみました。
ちなみにその時の本がこちらです。
[アプリ作成で学ぶExcelVBAプログラミングユーザーフォーム&コントロール](https://www.amazon.co.jp/dp/4798032956)
（今はExcelのバージョンも変わって新しいものが出ていると思います。）
##男は裏切るけど、プログラムは裏切らない！！
男に裏切られた話は省略しますが
テキスト通りにプログラムを書き、解説を読んで理解する、分からないとこは質問したり調べたり、という繰り返しをしてアプリケーションがだんだん出来上がっていくのがすごく楽しくてどんどんハマっていきました。
__命令をしたらその通りに動いてくれる、嘘がない、忠実、そんなプログラム君に私はもうメロメロです♡__

本が大半まで進んだころには
自分の仕事を自動化するプログラムもいつの間にか書けるようになりました。最初は簡単な転記マクロでしたが、テキストで基礎もしっかり学んだおかげで、分からないとこがあってネットで調べたとしてもちゃんと理解できたし、自分の思った通りのものがどんどん作れるようになりました！
##数ヶ月の経験を経てVBA専門の案件へ##
当時の職場で自分の仕事以外にもチーム内の業務を自動化したり、ExcelだけではなくAccessの本も買って今度は1人で1冊勉強してAccess化もしたりしてました。

そんな中、「今のままだと自分と周りの業務自動化という範囲しかできない、もっと色んな依頼を受けて開発していく仕事をしてみたい」と思い、退職を決め__VBAで業務自動化のための社内ツール開発__という案件にエントリーしてみたら、めでたく受かりました！
この手の募集案件は結構たくさんありました。
##現在は業務改善チームにて自動化ツール作成の日々
色んなチームから依頼を受けヒアリングし、VBAでツールを作成・改修・仕様設計書作成などが今の主な仕事内容です。たまにAccessやPowerBI、PowerQueryとかも使ってます。

まあ初めての業界だし入社してからも「こんなはずじゃ！」な話もたくさんあったのですが、それは置いといて、今、仕事内容に充実を感じてます。
前職では依頼者からのヒヤリングや仕様書作成は、ちゃんとやってこなかったのですが今はなんとか形になって来ました。
一番きつかったのは仕様書もマニュアルも何もない__前任者が作成したツールのコードを読み解く仕事__ですかね…

今の職場で1年半ほど経ちましたがちゃんと評価が返ってきてる実感も少しはあります。

しかしながらプログラミングはまだまだ日々勉強。ブログを書き始めてまたそう再認識させられました。暇さえあれば色んな書籍や記事、Twitterなどで勉強してます。

そして、最近ではさらなるスキルアップのためPythonの勉強も始めました。
##最後に
私の場合、つまるところ、VBA学習のきっかけは__「将来への漠然とした不安」__でした笑

きっかけは人それぞれだと思いますが今、「VBAでも始めようかな〜」って思ってる人は始めて損はしないと思います。

だってVBAを使えるようになったことで仕事は楽しいし、お給料はあがったし、そのおかげで気持ちにも余裕ができて、生活が豊かになって。
__VBAの学習は心身共に健康にしてくれました。__


というわけで
__普通の事務OLがVBAのおかげでちょっと幸せになった話__でした。

いつもブログを読んでくださる方、
こんな素人の書いているものを読んでくださり本当にありがとうございます。
仕様"書"はやめて、VuePressで仕様サイトを作ろう

1. 2021/01/09 追記
    1. ドキュメントサイトにREST APIのサンプルを追加
        1. <https://flatring.github.io/document-site-using-vuepress/internal/api/users.html>
        1. 参考元: GitHub Docs - <https://docs.github.com/ja/free-pro-team@latest/rest/reference/users>

## 先に結論
1. GitHub ActionsでpagesにdeployしたVuePress
    1. <https://flatring.github.io/document-site-using-vuepress/>
1. GitHub
    1. <https://github.com/flatring/document-site-using-vuepress/>
1. スクリーンショット
    ![screenshot_home.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704534/f0fcc97c-8eb0-e97d-86f5-822d46057209.png)

**注意:** 実際のプロジェクトでは公開してはダメなはずなので、actions(github workflow)は使わないように。

## VuePressを使っていなかった時の難点
### Excelの場合
1. セルを方眼紙状態にして仕様変更するたびに整形してゲンナリ
    1. 段落番号も入力していると、挿入行以降を全部編集するハメに
1. バージョン管理やルールが徹底していないと、どれが最新かあやふやに
    1. 複数人が同時に編集してしまうとmergeが大変。
1. 印刷レイアウトまで考えると見切れるなんてことがよくある。
1. こんな感じで"仕様"とは違うことで労力がかかってしまう。 

### google spreadsheetの場合
1. 複数人で編集できるのはいいけど、承認プロセスが曖昧になって決定なのか推敲なのかがわかりづらい。

### 補足
誤解のないように書いておくとExcelは素晴らしいツールだと思っています。
ピボットテーブルによる解析やスクリーンショットを交えたbug報告とか
ただ、「"仕様書"としては他の方法がいいでしょ？」という提案です。

## 本題
1. ということでVuePress。
1. 他にも静的サイト作成するものはありますが、使いやすさや導入のしやすさという点でVuePressを選びました。 
1. VuePressが何かは他に素晴らしい記事があるのでココでは触れません。
1. VuePressを仕様サイトとして使うという点だけ絞って書きます。

### メリット
1. markdownで書けるものならなんでも書き残せる。
1. 構成図のようにイメージなら 「[draw.io](https://drawio-app.com)」
    1. ただし、普通に扱うとsvg形式なので差分を見るのは難しいかも
        1. これはどのイメージ編集も避けられないと思いますが。
1. UMLなら「[PlantUML](https://plantuml.com/ja/)」で書ける
    1. 基本設計としてのユースケース、状態を把握するためのシーケンス図など慣れるとドローツールで書くより楽だったりします。
1. gitで管理できる = 差分で変更箇所が見やすい。
    1. ソースと同じリポジトリで管理できる。
    1. GitHub等のDevOpsを使えばpull requestでレビューできる。
    1. ソースと乖離があるかなどチェックリスト化しておくとチェック漏れも防げる♪
1. ここまでのことが Visual Studio Code 1つでできる♪
1. markdownなのでGitHubやGitLabでも見れる。

### デメリット
1. どんなものでもやっぱり銀の弾丸はない...
1. GitHubやGitLabのSaaSでpagesを使うと一般に公開されてしまうので使えない。
    1. 対策としては
        1. オンプレ環境にdeployする
        1. 自分のPC(ローカル)でdeployする
        1. など
    1. 自分のPCでdeployする場合、branchによって表示結果が違うので、運用上の注意が必要。
1. 既にswaggerなど別のサイトを使っていたりするといっしょにするのが難しい。
    1. この場合はVuePressの仕様サイトをポータルにして目次にしてしまうのがよろしいかと。
1. 仕様の納品をPDF等で約束されていた時
    1. ページ(A4とか)の概念が入ってくるので改ページ箇所とか考えると辛い。
    1. やったことはないですが、Windowsならヘルプファイルにするとか。
    1. ここは最初から「HTMLで納品します」と言えたら一番の解決策かも。 

## まとめ
すでに[shpinx](https://www.sphinx-doc.org/ja/master/)とか使っていれば差し替えるほどではないと思っています。
けど、「今までExcelを使っていた」とか「Redmineのチケットにしか仕様が残ってないからまとめたい」なんて場合にはおすすめな方法です。

## 今後
プロジェクトによって仕様として残したいものは違うことケースが多々あると思いますが、
ほとんどプロジェクトで「これは必要」みたいなことをテンプレとしてサンプルサイトに追加していきたいと思っています。

1. GitHub
    1. <https://github.com/flatring/document-site-using-vuepress/>
What is to send a email ??

## Why We want to send a email??

We have 2 Uses.
1. Safety confirmation
2. Confirmation of user existence such as membership registration and user registration

## How is the Managed services like SES or SendGrid.
Unfortunately, existing email delivery managed services didn't work well with our environment, where we could send out a lot of emails. On the other hand, if you are in an environment,  where a large amount of mail is sent regularly, you should actively use it.

In our case, we chose to build and operate our own mail server on the cloud.


## Sender domain authentication

There are SPF/DKIM/DMARC etc.

- https://ja.wikipedia.org/wiki/Sender_Policy_Framework
- https://ja.wikipedia.org/wiki/%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E3%82%AD%E3%83%BC%E3%83%BB%E3%82%A2%E3%82%A4%E3%83%87%E3%83%B3%E3%83%86%E3%82%A3%E3%83%95%E3%82%A1%E3%82%A4%E3%83%89%E3%83%BB%E3%83%A1%E3%83%BC%E3%83%AB
https://ja.wikipedia.org/wiki/%E9%80%81%E4%BF%A1%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E8%AA%8D%E8%A8%BC#DMARC
- https://ja.wikipedia.org/wiki/%E9%80%81%E4%BF%A1%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E8%AA%8D%E8%A8%BC#DMARC


## Reputation

http://multirbl.valli.org/

https://www.spamhaus.org/dbl/
http://www.sorbs.net/
https://www.abuseat.org/
goのテストの書き方【備忘録】


# テスト実行
```
go test ./... -v
```

## テストの流れ
各レイヤーのテストは基本的に下記の流れです。

- `mock`を作成して
- テスト対象のレシーバにセットして
- テスト対象のメソッドを呼び出して
- 結果を検証する

#### 例
```
	t.Run("error", func(t *testing.T) {
		ctrl := gomock.NewController(t)
		GroupUsecase := mocks.NewMockIGroup(ctrl) -> mockを作る
		GroupUsecase.EXPECT().GetTopList().Return(nil, fmt.Errorf("test")) -> mockの挙動を決定
		h := &Group{
			GroupUsecase: GroupUsecase, -> セットして
		}
		e := echo.New()
		req := httptest.NewRequest(http.MethodPost, "/", nil)
		rec := httptest.NewRecorder()
		c := e.NewContext(req, rec)
		err := h.TopList(c) -> テスト対象メソッド呼出

		assert.Error(t, err) -> 結果を検証する
	})
```

## gomock, mockgen
`handler`, `usecase`は依存するinterfaceのmockをテスト中で実装していますが、mockは[gomock](github.com/golang/mock/gomock)を使って実装しています。

また、`mockgen`という定義したinterfaceからmockを作ってくれるツールも同梱しているのでmockはそれを使って生成しています。

```
$ go get github.com/golang/mock/gomock
$ go install github.com/golang/mock/mockgen
```

interfaceを追加、修正などしたら`mockgen.sh`を実行してください。


```
sh mockgen.sh
```

すると、各レイヤーの`mocks`以下にmockが生成されます。

```
handler/mocks/
└── group.go
```

## sqlmock

`repository`レイヤーは`gorm.DB`に依存しているので[go-sqlmock](https://github.com/DATA-DOG/go-sqlmock)を使って`gorm`が依存する`database/sql`の`database/mysql`をモックしてしまいます。



## mockとは

各レイヤーはinterfaceを通じて依存しているので、interfaceを遵守するmockを代わりにセットすることで擬似的に各インスタンス呼び出しています。

mockを使うとモックDBなど用意する必要が無く原則ソースコード単体でテストを作ることができるようになります。
Rubyの文法エラーと対策

備忘録の最たる例として、遭遇したエラーと解決方法を書いていく。

# ①構文がおかしいよ？[syntax error, unexpected tIDENTIFIER]
syntax error = 構文エラーなので、記述したコードの何処かが間違っていると怒られる。
下記コードはファイルをターミナルで出力した結果。

```
main2.rb:81: syntax error, unexpected tIDENTIFIER, expecting ')'
      hp: params[:hp]
main2.rb:82: syntax error, unexpected ':', expecting end
      offense: params[:offense]
main2.rb:83: syntax error, unexpected ':', expecting end
      defense: params[:defense]
main2.rb:84: syntax error, unexpected ')', expecting end
    )
```

```main2.rb(間違ってるコード）
super(
      name: params[:name]
      hp: params[:hp]
      offense: params[:offense]
      defense: params[:defense]
    )
```

```main2.rb（修正したコード）
super(
      name: params[:name],
      hp: params[:hp],
      offense: params[:offense],
      defense: params[:defense]
    )
```

原因はsuperメソッド内の各項目が「,」で区切られておらず、全て同じ行扱いになっていたが為に怒られた。

**尚、superメソッドは、実行しているメソッドがオーバーライドしているメソッドを呼び出します。オーバーライドとは「親クラスのメソッドを子クラスで上書きすること」です。
initializeメソッド中でsuperを使うことにより、指定クラスのinitializeメソッドを実行することが可能。結果、「共通している部分」と「共通していない部分」で処理を振り分けることができる。**

# ②そんな名前は存じません！uninitialized constant <class名> (NameError)

```main.rb
Traceback (most recent call last):
main.rb:1:in `<main>': uninitialized constant <class名> (NameError)
```

main.rbファイルの中にその様なclass名は無いと怒られています。
もし、別に切り分けているファイルを呼び出したくて起きたエラーならば、
下記の様にrequireを記述して別ファイルを呼び出せる様にしてあげましょう。

```
require './<class名>'
```

#③必要な値を渡すんだぞ！ArgumentError
```
wrong number of arguments (given 1, expected 0) (ArgumentError)
```
引数エラーの場合に発生。
(given 1, expected 0) とあるように必要な値を一個渡してるけど、受け取り手がいないと怒られている。
そもそもの引数の記述し忘れてる可能性が高いから記述したメソッドのチェックをしてみよう。

#④メソッドを定義しましょう！NoMethodError

```
monster.rb:51:in `transform': undefined method `transform_message' for #<Monster:0x00007fea761c2b28> (NoMethodError)
```

文字通り、メソッドが定義されてない事によるエラー。

単純にタイポが原因の可能性があるが、どこかのメソッドがdef〜endの閉じ忘れの可能性もあり。インデントの位置も注意してみよう。


**以下はエラーに遭遇、解決したら追記していく。**
LaravelでFormクラスのインストールメモ

#・Class ‘Form’ not found

Laravelで開発したときにFormクラスでデータ送信をしようとしたら、ありませんとのことだったのでインストールしたときのメモ。Laravelのverは7.27.0

composer.jsonのrequireのセクションに以下を追加。

```composer.json

"require": {
        "php": "^7.2.5",
        "doctrine/dbal": "^2.10",
        "fideloper/proxy": "^4.2",
        "fruitcake/laravel-cors": "^2.0",
        "guzzlehttp/guzzle": "^6.3",
        "laravel/framework": "^7.24",
        "laravel/tinker": "^2.0",
        "laravelcollective/html": "^6.1.0" //ここを追加
    },

```

追加後、下記でcomposerを更新

```
composer update
```

これで無事Formクラスが使えるようになった。
topコマンドを使ってパフォーマンスチューニングをする

- CPU負荷
- メモリ負荷

の2種類があると話をしました。

どっちなのっていうのを知るためにどうすればいいかについて書きます。

## top

```
$ top          # CPU使用率順にソート
$ top -a       # メモリ使用率順にソート
$ top -p [PID] # 特定のプロセスを監視
$ top -d1      # 1秒ごとに更新
```

### やってみた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309507/bbd3e745-6980-6000-5836-7cc4984b0683.png)

まず、非常に重要な数値が

### load average

これは、システム全体の負荷(メモリ、CPUに関わらず)を表す数値として認識してください。
つまり、もしこの数値が高ければ、サーバーを最適化することで、処理が高速になる。
この数値が低いのに、レスポンスタイムが遅いなどの問題があれば、ネットワーク負荷(トラヒック理論)など別の原因によるものになるので、最初に確認しましょう。

定義は以下です。
<mark>1CPUにおける単位時間あたりの実行待ちとディスクI/O待ちのプロセスの数</mark>

Linuxカーネルはプロセス１つごとにプロセスディスクリプタを持っていて、そのstateメンバにプロセスの状態を入れて管理している。
プロセスの状態は以下のように区別される。

- TASK_RUNNING: 実行可能な状態。CPUが空いていれば実行できる。
- TASK_UNINTERRUPTABLE: 割り込み不能な待ち状態。ディスクI/O待ちなど、短時間で復帰するもの。
- TASK_INTERRUPTABLE: 割り込み可能な待ち状態。ユーザの入力待ちなど、復帰時間が予測できないもの。
- TASK_STOPPED: 実行中断になった状態。リジュームされるまでスケジューリングされない。
- TASK_ZOMBIE: ゾンビプロセス。子プロセスがexitして親プロセスにwaitされていないもの。
run queueに入っているプロセスのうち、TASK_RUNNINGとTASK_UNINTERRUPTABLEのものがload averageとして換算される。

load average、つまりシステムの負荷とは、「CPUの実行権限が与えられるのを待っているプロセス」と「ディスクI/Oの完了を待っているプロセス」の多さのことである。

### Tasks
実行してるプロセスの数がわかる。
TASK_RUNNINGの個数をかぞえあげる。

思ってる以上にプロセスが動いてたりしたら、
何が動いてんの？ってなるから、みておくといいかも。

### %CPUs

左から

- users
- systems
- nice
- idle
- wait
- heardware
- software
- steal

CPU使用率がわかるので、100%に近くなっていたら、
負荷が大きすぎるとわかる。

その原因が

- user program
- system program

のどちらにあるのかがわかるので、チェックする必要がある。

### Mem

```
3696.7 total,   1900.0 free,    226.4 used,   1570.3 buff/cache
```

### Mem Swap

スワップの回数が多いと、
メモリに収まりきっていなくて、ストレージの方を頻繁に参照していることがわかる。
そのせいでI/O待ちが発生しているかどうかは、
load averageや `sar` `vmstat`を確認してください。

| PR | NI | VIRT | RES | SHR | S | %CPU | %MEM | TIME+ |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 優先度 | 相対優先度 | 仮想メモリ | 物理メモリ | 共有メモリ | 状態 | CPU使用率 | メモリ使用率 | 実行時間 |


> I/O待ち時間は非常に誤解を招きやすい指標だ。CPUを酷使するプロセスがほかにやってくると、I/O待ち時間の値は下がる。するべき仕事ができたので、CPUはアイドル状態で待っていなくてよいのである。しかし、I/O待ち時間の数値が下がっても、同じディスクI/Oがなくなったわけでも、スレッドをブロックしなくなったわけでもない。逆もありうる。
LinuxではI/O待ち時間は今でもよく使われている指標であり、混乱を招く性質を持ちながら、あるタイプのディスクのボトルネック、つまりCPUがアイドルでディスクがビジーになっている状態を見つけ出すことができている。I/O待ち時間の一つの解釈方法は,I/O待ち時間が存在することをシステムにボトルネックがある兆候と捉え、例え高いCPU使用率とI/O待ち時間が両立している場合でも、I/O待ち時間を最小限に抑えるようにシステムをチューニングするというものである。

[詳解　システムパフォーマンス](https://www.amazon.co.jp/%E8%A9%B3%E8%A7%A3-%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%83%BB%E3%83%91%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%B3%E3%82%B9-Brendan-Gregg/dp/4873117909/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=%E8%A9%B3%E8%A7%A3+%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%83%BB%E3%83%91%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%B3%E3%82%B9&qid=1595068413&sr=8-1)
から引用

I/O負荷に関しては、まずは仕組みを正しく理解して、
CPUへの負荷がかかっていないか、
Swapの回数は増えているのか
といった情報についても同時にみていく必要がある。
クラウンドサービスのサービス形態（SaaS、PaaS、IaaS）ー午後

応用情報技術者平成30年春期 午後問4

ファイル：2018h30h_ap_pm_qs.pdf

参照：
https://www.ap-siken.com/kakomon/30_haru/pm04.html


この問は簡単と思っておりますので、メモも簡単に記載します。
詳細の分析は、上記リンクをご参照くだいますようよろしくお願いします。


１、〔仕様の変更〕について，(1)，(2)に答えよ。
（１）F課長が仕様を変更したサブシステムの名称と，選択したクラウドサービスの利用形態〔サービス形態と提供形態)を，本文中の名称で答えよ。
（２）（１）のクラウドサービスの利用形態を選択した理由を30字以内で述べよ。

独自の業務対応がありと、他システムとのデータ連携が必要になる　（私の答え）
→
販売管理サブシステムとのデータ連携が必要だから (23文字)　（参考答え）


サービス形態の概要によると、開発したアプリケーションや市販ソフトウェアをカスタマイズしたものがIaaS又は、PaaSのいずれかを利用できますね。
なので、「独自の業務対応があり」又は、「他システムとのデータ連携があり」は理由でしょう。
いずれかでいいの？かな。



＜＜サービス形態の概要＞＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/30473118-a0f0-852a-f8dd-e902076549ee.png)


＜＜表４　システム要件＞＞
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/e7a4bb20-4c74-3902-5906-764bfea47a84.png)


**SaaS、PaaS、IaaSについて：**
JIS X 9401:2016では、クラウドコンピューティングのサービスモデル「SaaS」「PaaS」「IaaS」について次のように区分しています。
**１、SaaS（Software as a Service）**
サービス利用者が、クラウドサービス提供者のアプリケーションを利用することができる形態
※アプリケーション利用するだけ

**２、PaaS（Platform as a Service）**
サービス利用者が、クラウドサービス提供者によってサポートされる一つ以上のプログラミング言語と一つ以上の実行環境とを使って利用者が作った又は利用者が入手したアプリケーションを配置し、管理し、及び実行することができる形態
※アプリケーション自作など可
※MWインストールは不可

**３、IaaS（Infrastructure as a Service）**
サービス利用者が、クラウドサービス提供者の演算リソース、ストレージリソース又はネットワーキングリソースを供給及び利用することができる形態
※アプリケーション自作など可
※MWインストールは可

つまり、上記に三つは、
・SaaSはSoftware提供される。　
→Softwareを利用するだけ。　
例：Salesforce

・PaaSはPlatform提供される。　
→Softwareを自作する要。　
例：Google App Engine やMicrosoft Azure

・IaaSはInfra提供される。　　
→MW（IIS、Apacheとか）インストール要。その上でSoftware構築する。
例：Google Compute Engine や Amazon Elastic Compute Cloud (EC2)

となりますね。

参照：
https://qiita.com/lymansouka2017/items/c0aaf9ea4125cd33c592
【Gradle】shadowJarに任意の名前をつけたかったお話

~~shadowJarとはなんぞやという方はご自身で調べて下さい~~(有名なプラグインなのでご存じの方も多いと思います)

## 名前をつける

今回はこちらの記事を参照しました。
[gradle - How to change name of jar created using shadowjar - Stack Overflow](https://stackoverflow.com/questions/33526612/how-to-change-name-of-jar-created-using-shadowjar)

```groovy:build.gradle
...

shadowJar {
   //ここにshadowJarの設定をする
}

...
```

まずこれ。
んでshadowJarの名前は`archive***Name`(`***`には空文字を含む任意の文字列)で指定できるらしい。
というわけでやってみる。

```groovy
...

shadowJar {
   //補完でなんか出てきた
   archiveBaseName = "hoge"

...
```

んで`gradle build`...っと。

```:./build/lib/
hoge.jar
hoge-all.jar
```
おー。

---

これ`archive***Name`の違いがよく分かっていない(`[無し]`, `Base`, `File`があった)ので、また追記するかも知れません。
kubernetesの中に入るコマンド備忘録とログを確認する方法

## なかに入りたい時

クラスタの中のAPIからMySQLに繋がらない時に、毎回ビルドしてデプロイしているとエラーも見にくいし死ぬほど時間かかるので、
サーバーレスじゃないメリットとして、本番の中に入ってごちょごちょできることが挙げられる。

例えばMySQLの場合だったら、

```
kubectl run --restart=Never mysql --image=mysql -- bash -c 'while true; do sleep 10000; done'
```
こんな感じで、Podを立てることができます。
このmysqlのなかに入りたいのであれば、

```
kubectl exec -it mysql bash
```
これで入れます。

APIサーバーのなかに入りたいとかだったら
まずは、どんなPodがあるのかを確認してください。

```
$ kubectl get pods

NAME                                  READY   STATUS    RESTARTS   AGE
altair-deployment-74bc9b84bf-4h4fm    1/1     Running   0          18d
altair-deployment-74bc9b84bf-tqqvx    1/1     Running   0          18d
regulus-deployment-5796dcfdb7-879xm   1/1     Running   0          18d
regulus-deployment-5796dcfdb7-rt5h8   1/1     Running   0          18d
sirius-deployment-c6d9fbdd4-8kz2j     1/1     Running   0          18d
sirius-deployment-c6d9fbdd4-smkcv     1/1     Running   0          18d
```

Podのなかに入るときは、

```
$ kubectl exec -it sirius-deployment-c6d9fbdd4-8kz2j ash
/go/src/github.com/Tech-Design-Inc/sirius # 
```

で入れれます。
alpine linuxはbusyboxを元に作られていているらしいです。
https://stackoverflow.com/questions/35689628/starting-a-shell-in-the-docker-alpine-container
ashで入るので、気をつけてください。
alpineじゃないCentとかであれば、bashで入れます。


## ログを確認したい時

本番でエラーが出たとかそういう時にとりまログみたいですよね。

そういうときは、`stern`を使うとめっちゃいいです。
`kubectl logs -f`
を使うと別のPodのログが別々に取れるので、見にくくてしょうがないんですよ。

sternは名前にマッチするやつ全部返してくれるので、サービス名で検索すれば、全部ヒットします。

そこが強いです。

```
$ brew install stern
$ stern sirius
```

使い方はこんな感じです。
マッチするすべてのPodのログが色付きで見えます。
map・filter・reduceの書き方・使い方

Reactでポートフォリオ のアプリを作成し始めたのですが、
その時使った配列操作の map、filter、reduceについて、
書き方と使い方をまとめておきます。

※文法に集中する為、Reactの書き方は全て排除しJavaScriptのみでまとめてます。

# mapメソッド
mapは元々の配列から操作して、新しい配列を作ります。

具体的な例はこんな感じ↓

```JavaScript
incomeItems = [{text: "本の売却", amount: 500, id: 123343434}, {text: "宝くじ", amount: 5000, id: 123454523}]
const incomeAmounts = incomeItems.map(incomeItem => incomeItem.amount);
//結果 incomeAmounts = [500,5000]
```

incomeItemsはオブジェクトの配列です。
中にはユーザーが入力した「text」と「amount」、ランダムなIDが入ってます。
そのincomeItemsに対してmapメソッドを使ってます。


【アロー関数でのmapの書き方】
**配列. map ( value => 新しい配列としてリターンしたい内容 )**

第二引数にindex、第三引数に実行しているarray自身を入れることもできます
**配列. map(( value, index, array ) => 新しい配列としてリターンしたい内容 )**

mapを使ってincomeAmountsという数字だけを取り扱う用の配列が作れました。

# filterメソッド
filterメソッドは条件に合致した要素で新しい配列を作ります。

今回のアプリでは、ユーザーがdeleteボタンを押した時に、その項目が削除されるという操作のため使いました。

具体的な例はこんな感じ↓

```JavaScript
incomeItems = [{text: "本の売却", amount: 500, id: 1}, {text: "宝くじ", amount: 5000, id: 2}]

//onClickなどでdeleteHandlerを実行させる
const deleteHandler = () => {
  setIncomeItems(incomeItems.filter((e) => e.id !== incomeItem.id));
}
//結果: incomeItems = [{text: "宝くじ", amount: 5000, id: 2}]
```
incomeItemsにユーザーが入力した内容がオブジェクトの配列として入ってます。
その配列に対してfilterを実行し、各配列の要素(e)のidとincomeItemのid(
消したいitem）を比べてます。
idが一致しない要素だけのincomeItemsの配列が出来上がります。（=削除以外の項目）

【filterの書き方】
**配列. filter ( ( element )  =>  条件)**

これもまた第二引数にindex、第三引数に実行中のarray自身を指定できます。
**配列. filter ( ( element,  index, array )  => 条件)**

filterを使ってユーザーが削除した以外の要素を取り出せました。

#reduceメソッド
reduceは配列の各要素を一つにできます。累積系に便利ということです。
今回のアプリでは、配列の中にある数値の合計を出してみました。

具体的な例はこんな感じ↓

```JavaScript
incomeAmounts = [500,5000]
const incomeTotal = incomeAmounts.reduce((acc, cur) => acc += cur, 0);
//結果: 5500
```

incomeAmountsの配列に対してreduceを実行してます。
reduceの第一引数(arr)は、前までに蓄積された値で、第二引数(cur）は、現在の値が入ります。
この場合「合計」を出したいので、蓄積の値(arr）と現在の値(cur）を足して一つの要素として返してます。

【reduceの書き方】
**配列. reduce ( ( accumulater,  current ) => 条件, 初期値)**
今回の例では第二引数までで、0を初期値として渡してます。

なんと引数は４つまで渡せます。
**配列. reduce ( ( acc, cur, idx, src ) => 条件, 初期値)**
1: (acc)　アキュムレーター。前までの蓄積された値
2: (cur)　現在値 
3: (idx)　インデックス 
4: (src)　元々の配列 

<br>
配列操作のメソッドはもっといっぱいあるで、色々使いながら学んでいきたいですね。
mecab-python3ではunidic-liteが必要っぽい

## 追記
**下にコメントがありますが、mecab-python3の開発者の方によるとunidic-liteは必要ないとのことです。こちら不正確な記事ではありますが、個人的な経験として残させていただきます。**

---

Qiitaなどの記事を見ながらUbuntuにMeCabを動かす環境構築をしていたのですが、記事の通りにやってても動かない。コマンドラインでは動くのに、Pythonで利用しようとするとなぜかエラーを吐いてしまっていました。

なんでだろうなって思ってたら、よくよく調べるとパッケージが足りていませんでした。mecab-python3のREADMEにちゃんと書いてあったのを読まなかったのが悪い。ちゃんと一次ソースを見ましょう。

UbuntuなのでGoogle Colabで困っている方も試してみてください。me

## 解決法

```
pip install unidic-lite 
```

## 参考記事

mecab-python3のリポジトリ：https://github.com/SamuraiT/mecab-python3

こちらの記事を参考に構築しました：https://qiita.com/ekzemplaro/items/c98c7f6698f130b55d53
[Vuex] 複数のdispatchを全て実行するにはPromise.allを使う

VuexのActionsを実行するトリガーとなる**dispatch**を
複数全て実行したい場合には
**Promise.all**
を使うと実装できます。

```index.vue
<script>
export default {
  async fetch({ store }) {
    await Promise.all([
      store.dispatch('〜〜〜'),
      store.dispatch('〜〜〜'),
      store.dispatch('〜〜〜')
    ])
  }
}
</script>
```
Gmailでネタメールを一斉送信

#動機
ラジオでネタ投稿を本格的にやろうと決意した。
採用数を上げるにはたくさんの投稿をするのは必須、いっぱい送らないと。
そんな中思ったのが、メールがめんどくさい。
基本的にネタはメールで投稿。１通につき１ネタ。10個のネタ送るのに10通のメール・・・。
ということで、一括でネタメールを一斉送信するものを作ろうと思った次第。


#準備
1. 自動送信をするアカウントの「Googleシート」と「Googleドライブ」のAPIを有効化し、JSONファイルを入手する
3. JSONファイルを Renameする。
4. コードを書くファイルを作成する。
5. jsonをファイルを同じフォルダに格納する


#スプレッドシート
使うsheetは2つで、sheet名は「Index」、「Main」としました。内容は次の通り。
・Index：カウントのメールアドレスとパスワード、送信先、送信元、ラジオネーム、住所、名前
・Main：件名、ネタ、作成日、送信日、状態、結果

**Index**
![スクリーンショット 2020-09-06 17.17.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148800/e0891dfe-25a1-2ae5-b9f5-1699864b9db9.png)
**Main**
![スクリーンショット 2020-09-06 17.16.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148800/27ce6869-cab7-f20a-15f0-ecaa1de23b5b.png)


#ライブラリインストール

```
$ pip install gspread oauth2client
```


#コード
```python:send.py
#メール送信関係
from email.mime.text import MIMEText
from email.utils import formatdate
import smtplib
#API連携関係
import gspread
from oauth2client.service_account import ServiceAccountCredentials
import datetime
from pprint import pprint 

scope = ["https://spreadsheets.google.com/feeds",'https://www.googleapis.com/auth/spreadsheets',"https://www.googleapis.com/auth/drive.file","https://www.googleapis.com/auth/drive"]

creds = ServiceAccountCredentials.from_json_keyfile_name("creds.json", scope)

client = gspread.authorize(creds)

SPREADSHEET_KEY = '******************************************'
sheet1= client.open_by_key(SPREADSHEET_KEY).worksheet('Index')
sheet2= client.open_by_key(SPREADSHEET_KEY).worksheet('Main')

# Index
_id        = sheet1.cell(2,1).value
_pass      = sheet1.cell(2,2).value
_from      = sheet1.cell(4,1).value
_to        = sheet1.cell(4,2).value
_radioName = sheet1.cell(4,3).value
_name      = sheet1.cell(6,1).value
_address   = sheet1.cell(8,1).value

# 全ての値を、dataという変数に代入しています。
data = sheet2.get_all_records()

# データ数を取得
last_number = len(data)

# pprint(data)

for row in range(last_number):
    #　送信判定
    status = data[row]["結果"]
    if status == "完了":
        continue
    # メール送信に必要な情報を抽出
    body = data[row]["ネタ"]
    radioName = "ラジオネーム：" + _radioName
    msg = MIMEText(body + "\n\n" + radioName + "\n\n" + _address + "\n\n" + _name)
    # sheet更新
    now = datetime.datetime.now()
    sheet2.update_cell(row + 2, 5 , now.strftime("%Y/%m/%d %H:%M:%S.%f"))
    sheet2.update_cell(row + 2, 6, "送信済み")
    sheet2.update_cell(row + 2, 7, "完了")

    msg['Subject'] = data[row]["件名"]
    msg['From'] = _from
    msg['To'] = _to
    msg['Date'] = formatdate()

    # pprint(msg)

    smtp = smtplib.SMTP('smtp.gmail.com', 587)
    smtp.ehlo()
    smtp.starttls()
    smtp.ehlo()
    smtp.login(_id, _pass)
    smtp.send_message(msg)
    smtp.close()
```

#補足
Python2系だと、次のエラーがでます。

```python:
Traceback (most recent call last):
  File "send.py", line 6, in <module>
    import gspread
ModuleNotFoundError: No module named 'gspread'
```

対応としては３系をインストールすればいいだけなんですが、Pythonに関して勉強不足なもんで、数時間詰まってしまいました。

##参考
https://qiita.com/njn0te/items/4318347f8c4ed5137476
CRA(v3.4.1)のReact Testing Libraryで最初に対処すること

## 概要
CRA(create-react-app)にはテストフレームワークが最初から入っており、テストコードファイルも最初からミニマムで用意してくれています。
試しにサクッとテスト実装を、、、と思ったら冒頭からエラーで手間取ってしまったので、対処結果を書いてみます。

## 前提
* create-react-app : 3.4.1
  * テンプレートはtypescriptです
  * create-react-app [プロジェクト名] --template typescript
* react-scripts : 3.4.1
* @testing-library/jest-dom : ^4.2.4
* @testing-library/react : ^9.3.2

## エラー：「@testing-library/react"' has no exported member 'screen'」
#### コード
```typescript:App.test.tsx
import { render, screen } from '@testing-library/react';
```
#### エラー
```md:error
"@testing-library/react"' has no exported member 'screen'"
```

#### 対処
```bash:console
yarn remove @testing-library/react @testing-library/jest-dom && yarn add @testing-library/react @testing-library/jest-dom
```

#### 参考
https://github.com/testing-library/react-testing-library/issues/610#issuecomment-614982674
yarn upgradeでは他のモジュールバージョンも上がって依存関係が解消されないようで、対象モジュールのみを再インストールする必要があるようです。

## エラー：「MutationObserver is not a constructor」
#### コード
```typescript:App.test.tsx
const result = await screen.findByText('xxx', undefined, {timeout: 3000});
```
#### エラー
```md:error
"MutationObserver is not a constructor"
```

#### 対処
```json:package.json
- "test": "react-scripts test",
+ "test": "react-scripts test --env=jest-environment-jsdom-fourteen",
```

#### 参考
https://github.com/testing-library/react-testing-library/issues/731#issuecomment-667632723

## 感想
* 新しいライブラリを触った際、文法が正しそうなのにエラーが出ると「まずはTypeScriptの@type~が足りないのかも」など、つい疑ってしまうのですが、ちゃんとissueとか探るのも大事ですね。
Reactで書いたWEBサイトをGithubにコミットして、netlifyにデプロイした。

自分の自己紹介的なWEBサイトを用意したい。かつ、Reactを触ってみたい。
と思い、やってみたのでメモとして記録を残しておく。

#手順
1. githubに登録する
2. netlifyに登録する
3. npxでcreate-react-appでプロジェクトを作る
4. githubにプッシュする
5. netlifyからgithubにプッシュされたリポジトリを選択してデプロイする
6. WEBサイトにアクセスできた！

変更を加えたら、githubにプッシュすれば自動的にビルドされて変更が反映される。
MacにkubectlとgcloudとTerraformコマンドを入れる方法



## gcloud
```
brew cask install google-cloud-sdk
gcloud init
gcloud auth login
```

## kubectl
```
brew install kubernetes-cli
```
うまくいかない人は

```
gcloud components remove kubectl
brew install kubernetes-cli
brew link --overwrite kubernetes-cli
```

## Default Resion
```
gcloud config set compute/zone us-central1-a
```

## Terraform

```
brew install terraform
```
VSCodeのExtension「Jest」の設定ファイルjest.configのパス

Githubからクローンしてきたソフトウェアで、yarn testとかは動くけど、VSCode上のJest拡張機能のテストが失敗してしまいました。このような場合は、package.jsonのscriptsにJestの設定ファイルのパスが指定されていないか確認してみましょう。

VSCodeのJest拡張機能で見に行くconfigファイルは`jest.config.js`なので、package.jsonでこれ以外のパスを設定していたりするとうまく動きません。

https://github.com/jest-community/vscode-jest
> we find Jest configuration files in the workspace: jest.config.js or jest.json

私の場合は、VSCode上のJestだけ以下のエラーが出ている状態でしたが、configのパスを修正したところエラーが解消しました。
> Support for the experimental syntax 'jsx' isn't currently enabled
MacにSource Han Code JPを導入する

![macOS-10.15.6 (19G2021)](https://img.shields.io/badge/macOS-10.15.6 (19G2021)-brightgreen) ![Last Modified-2020/09/06](https://img.shields.io/badge/Last Modified-2020/09/06-brightgreen)

## Fonts Install

ダウンロードします

```
$> curl -L https://github.com/adobe-fonts/source-han-code-jp/archive/2.011R.tar.gz | tar zx
```
最新リンクは下記からコピーします。
https://github.com/adobe-fonts/source-han-code-jp/releases

```
$> mv source-han-code-jp-2.011R/OTC/SourceHanCodeJP.ttc ~/Library/
$> mv source-han-code-jp-2.011R/OTC/SourceHanCodeJP.ttc ~/Library/Fonts
$> rm -rf source-han-code-jp-2.011R
```

## Terminalに適用させる

`menu` の `Preferences` をクリックします。

<img width="200" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494121/71ac82bf-7b7d-48f1-5f52-f2afd19c8176.png>

`Font` の `Change` をクリックします。

<img width="400" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494121/1731761c-89dc-b32a-e859-b262a1500161.png>

`Souce Han Code JP`を選び、サイズなどを選択します.

<img width="300" src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494121/bcffee95-988c-e047-bd69-0c52e13cc6fd.png>

以上で導入完了です。
型チェックツールFlowはMaterial-UIのバージョンアップに対応していない？

型チェックツールのflowを走らせたら、@material-ui/coreのimportで失敗しました。

```
$ yarn run flow
$ flow
> Error 
> Cannot resolve module @material-ui/core. [cannot-resolve-module]
```

Material-UI公式にflowの対応状況について説明が書かれていて、リンク先のプロジェクトで型定義情報がメンテナンスされているとあります。
https://material-ui.com/guides/flow/

> flow-typed
>
>flow-typed is a repository of third-party library interface definitions for use with Flow. The community is maintaining the definitions under this project.

しかし、リンク先を見ると`core_v1.x.x/flow_v0.58.x-v0.88.x`と書かれています。Material-UIのバージョンアップに追従していないようです。

https://github.com/flow-typed/flow-typed/tree/master/definitions/npm/%40material-ui

少しググってみたら以下のページを発見して一応試してみましたが、@types/material-uiはTypeScriptの型情報なのでエラー解消しませんでした。
https://stackoverflow.com/questions/58941816/how-to-install-flow-types-for-material-ui-corev4-x-x
【CSS】BEM・MindBEMding の命名規則をミスりがちな人に送る超簡単な覚え方

`BEM`・`MindBEMding`の命名規則は、
一見複雑そうに見えるけど、至ってシンプルで覚えやすいです。
その覚え方を超簡単に説明いたします！

## 基本ルール
### `BEM`と`MindBEMding`の違い
**正直この部分は覚えなくて良いです！！**
両方ともBEMなんだな〜程度で大丈夫です。

* `BEM`
    * CSS設計のこと
* `MindBEMding`
    * BEMをCSSのクラス名に適用するために作られた命名規則
    * `MindBEMding`のことをBEMと呼ばれがち。笑

> 参考：[[CSS]BEMの方法論とMindBEMdingという記法](https://qiita.com/torumiyamon1987/items/5c73eb2116190c9a652d)

### 書き方
BEMでは、`Block` `Element` `Modifire`の三つに分けて、命名します。

* Block - 一番大きな塊。
* Element - 塊に対する子要素
* Modifire - それぞれの要素の装飾(色を変えたり、形を変えたり)

基本的には、`Block` `Element` `Modifire`を
`Block__Element--Modifire`
と結合して書きます。

## ミスりがちな部分と覚え方
### `Modifire`と`Element`をミスりがちな人へ
* `__`は下に線があるので子要素
* `--`は真ん中に線があるので同階層のバージョン違い

と私は覚えています。

![スクリーンショット 2020-09-06 16.18.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142322/6c77504f-189a-4b49-93b0-ac196773dce5.png)

```css
.Block--Modifire {} /* Blockの同階層のバージョン違い */
.Block__Element {} /* Blockの子要素 */
.Block__Element--Modifire {} /* Blockの子要素に対するバージョン違い */
```

### ハイフンやアンダーバーの個数をミスりがちな人へ
BEMが基本的にハイフンやアンダーバーが2本なのは、
**単語の命名にケバブケース**を使う可能性があるからです。
(キャメルケースに統一して、個数を1つにしているケースもちらっとお聞きしますが、
共通認識取りづらいためおすすめはしません！)