OmniAICreator/Qiita-1.07M huggingface dataset:
Railsポートフォリオ作成中によく使う(けど覚えられない)コマンドまとめ

よく使うけど覚えられない、でもいちいち調べるのもめんどくさいコマンドまとめ
自分用なので分かり辛い＆他の環境だと出来ない可能性大

####【ページ内リンク】
[０．環境](#０環境)
[１．テーブル作成](#１テーブル作成)
[２．seed読み込み](#２seed読み込み)
[３．MySQL関連](#３mysql関連)
&emsp;[①起動](#起動)
&emsp;[②データベース確認](#データベース確認)
&emsp;[③データベース内のテーブル一覧確認](#データベース内のテーブル一覧確認)
&emsp;[④テーブル内確認](#テーブル内確認)
&emsp;[⑤テーブル削除](#テーブル削除)
[４．PostgreSQL関連](#４postgresql関連)
&emsp;[①起動](#起動-1)
&emsp;[②【--More--】無くしたい](#--more--無くしたい)
&emsp;[③テーブル一覧確認](#テーブル一覧確認)
&emsp;[④テーブル内確認](#テーブル内確認-1)
&emsp;[⑤テーブル削除](#テーブル削除-1)
&emsp;[⑥終了](#終了)

#０．環境
・AWS
・heroku/7.48.0 linux-x64 node-v12.16.2
・Rails 5.2.4.5
・ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-linux]
・MySQL 5.7.31
・PostgreSQL 9.2.24

#１．テーブル作成
```
$ rails g model テーブル名(単数形で頭は大文字) カラム名1:型 カラム名2:型 ･･･
$ rails db:migrate
```
※例：`$ rails g model Team name:string`
・カラム名は複数指定可能。無くてもOK
・型指定しなくてもいいけどその場合string型になる
・コロン(:)の後に空白はNG。痛い目見た

[ページ内リンクへ戻る](#ページ内リンク)

#２．seed読み込み
```
$ rails db:seed
```
・`/db/(ファイル名).csv`読み込ませたいCSVファイルは入ってる？
・`/db/seeds.rb`ちゃんと編集した？

[ページ内リンクへ戻る](#ページ内リンク)
#３．MySQL関連

##**①起動**

```
$ mysql -u root -p
Enter password: (Enter押すだけ)
```
※前提：MySQL登録済み且つパスワードを無しとしている
・`$ mysql --user=root --password`と同義。`root`はユーザー名にあたる
・`-pパスワード`と`--password=パスワード`は同義。上記はパスワードを省略しているだけ。すなわち

```
$ mysql -u root --password=
```
これでEnterを打つ手間が省ける(普通にEnter押す方が早いと思う)

[ページ内リンクへ戻る](#ページ内リンク)
##②データベース確認
```
mysql> show databases;
```

[ページ内リンクへ戻る](#ページ内リンク)
##③データベース内のテーブル一覧確認
```
mysql> show tables from データベース名;
```
※例：`mysql> show tables from insta_development;`

[ページ内リンクへ戻る](#ページ内リンク)
##④テーブル内確認
```
select * from データベース名.テーブル名;
```
※例：`mysql> select * from insta_development.users;`

[ページ内リンクへ戻る](#ページ内リンク)
##⑤テーブル削除
>[【Rails】マイグレーションファイルの削除](https://qiita.com/ISSO33/items/33a935cb3255c269bef2)

↑このページを参考にさせていただきました。下のコマンドはこれを簡略化したもの。

```
$ rails db:migrate:down VERSION=マイグレーションファイル名
$ rm db/migrate/マイグレーションファイル名
```
※例：`$ rails db:migrate:down VERSION=20210302092833_create_users.rb`
・`VERSION`は小文字厳禁
・マイグレーションファイルは**Status:down**してからじゃないと消しても意味ない
・つまり`$ rails db:migrate:down ~`の後には手動で消してもOK。というか怖いから普通に手動で消すべき？（最近、`$ rm -rf /`した人の記事を読んだ影響）
・**Status**の確認方法は`$ rails db:migrate:status`

[ページ内リンクへ戻る](#ページ内リンク)
#４．PostgreSQL関連
※前提：**本番環境(herokuにデプロイ後)**に対してしか使わない
herokuにコマンド打ちたいなら`$ heroku run コマンド`

##①起動
```
$ heroku pg:psql
```

[ページ内リンクへ戻る](#ページ内リンク)
##②【--More--】無くしたい
```
(省略)::DATABASE=> \pset pager
```
・起動するたびこれ打つのが面倒･･･
・上のコマンドは[on/off]を切り替えているだけ。デフォはon。Moreを無くすのはoff。
※on：`\pset pager on`、off：`\pset pager off`

[ページ内リンクへ戻る](#ページ内リンク)
##③テーブル一覧確認
```
(省略)::DATABASE=> \dt
```
・セミコロンは付けてもOK
・`\d`だとType:Table以外も表示される

[ページ内リンクへ戻る](#ページ内リンク)
##④テーブル内確認
```
(省略)::DATABASE=> select * from テーブル名;
```
※例：`(省略)::DATABASE=> select * from users;`

[ページ内リンクへ戻る](#ページ内リンク)
##⑤テーブル削除
```
(省略)::DATABASE=> drop table テーブル名;
```

[ページ内リンクへ戻る](#ページ内リンク)

##⑥終了
```
(省略)::DATABASE=> \q
```
・セミコロンは付けては**駄目**

[ページ内リンクへ戻る](#ページ内リンク)
お猿さんのためのReactまとめ：Vol.3  React Hooks編


前回、前々回自分なりにまとめてみたものの、わかったようなわかってないような不安な気持ちでいっぱいになりました。
今回はReactのHooksについてまとめてみます。
ウキィー！！
##1...React Hooksとは?
* クラスコンポーネントの機能（stateやライフサイクル）を関数コンポーネントでも使えるようになる。
* 過去に書いたコードに追加記述をしてもバッティングしない。
* 記述がシンプルになる。
 * ライフサイクルのように時間の経過に合わせてまとめるのでなく、機能ごとにまとめれる。
 * thisを使わなくても良い。
* Hook? Hooks? どっち？

##2...useState()
関数コンポーネントでstateを扱う。
![React (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1132336/85ad0ec8-c194-71a2-0436-f248c1b0bfdb.png)
記述量はこんなに減り、状態管理が自己完結型でわかりやすくなった。
![React (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1132336/ef66ea38-cd94-49d4-9ace-8b812ddb828d.png)

##3...useEffect()
###①componentDidMount()箇所の変更
関数コンポーネントでライフサイクルを扱う。
こちらもかなり記述量が減り、コードの見通しも改善されている。
![React (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1132336/49f654cd-d94d-8678-3068-0790137db43b.png)

![React (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1132336/e93b9a4d-b36f-04b7-dd9a-d2adc4f831f0.png)



###②componentDidUpdate()とcomponentWillUnmount()箇所を追加する。
![React (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1132336/0520f41c-1abd-8295-a203-561f3ba0fc6c.png)

###③おまけ
![React (8).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1132336/0d7675df-6793-314d-facc-cfc779ada1a2.png)

![React (9).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1132336/5f6a4cf8-a844-c284-31de-a1c4244ee566.png)

![React (10).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1132336/d6236fbc-1689-c19b-c25e-0a370e894ac2.png)

参考：[日本一わかりやすいReact入門【基礎編】](https://youtube.com/playlist?list=PLX8Rsrpnn3IWKz6H5ZEPWBY8AKWwb9qq7)
オブジェクト指向って結局なに？

# はじめに

Rubyを学習するにあたって、自分が難しいと感じた**オブジェクト指向**について備忘録。
まだ100%理解できてるとは思えないので、間違いがあればご指摘お願いします！

[参考記事 [オブジェクト指向]](https://qiita.com/ICT_hero/items/b2f8e39d7cc23ad505f9)
[参考動画 [Youtube]](https://www.youtube.com/watch?v=75EHCXuR5BI)

# 結論
記事や本によっても若干異なりますが、自分が納得できたものを3つ上げます！

- **簡単にいうとオブジェクト(モノ)と、操作に分けてプログラムを組み立てていく考え方のこと。**
- **いかに効率良く開発を行うかを突き詰めた考え方。**
- **オブジェクト指向とは現実世界を正しく捉えること。**

抽象的、、、もう少し深掘ります！

# 具体的に

テレビのリモコンを作るときを想像します。

まず**本体を作る**、その後**リモコンを操作するための要素(電源を入れたり操作するなど)を追加**します。

|必要な要素||
|----|-----|
|モノ|リモコン本体|
|操作1|電源OFF|
|操作2|チャンネル変更|

モノと操作を分けて作っていき、組み立てて完成させます。
オブジェクト指向の考え方としてはまさにこれです！
でも、「まだオブジェクト指向の必要性が分からない！」というのが本音。。

# なぜ必要なのか(メリット)

- **プログラムの設計・開発が効率的に！**

Webアプリなどのボタンを作る時を想定します。
新規登録ボタンや更新ボタン、削除ボタンなどたくさんのボタンが考えられます。

早速、モノと定義したボタンを一つだけ作りました。
でも、**登録、更新、削除**などのいろんな種類のボタンを作りたい！と考えたとき、
同じ工程をボタンの数だけ繰り返すのは結構大変。。色を変えたり表記文字だけを変えれればなぁ、、
という悩みを解決してくれます！
**オブジェクト指向により定義すること**でコレ、できてしまうんですね。
色を変えたりサイズを変えても同じボタン。再利用し簡単に作ることが可能にできるんです！


- **不具合が生じた時に原因を特定しやすくなる！**

開発中に、エラーやなんらかの不具合が出たとき、原因を探すために、ソースコードの中から探します。しかし当てが無い中、長ーいコードを辿るのはきついです、、。

しかし、オブジェクト指向は、モノと操作に分けているため、
**どこでエラーが起こったか、どんな操作をした時にエラーが出たかを推察することが出来ちゃいます！**
(範囲が狭ければ全てを確認するより多少は予測できる！)

また、操作ごとに処理が分かれてるため、エラーの処理が起こった部分を操作処理を見るだけで、原因が特定しやすくなるんですね！

- **プログラムの仕様が変わっても対応しやすい！**

今あなたは、メルカリのようなWebアプリケーションを開発しています。ボタンサイズが小さくて見づらい！と開発責任者から指摘された時を想像してください。

前でも書きましたが、ボタンには、新規登録、ログイン、ログアウト、購入、出品、詳細確認、、など多数のボタンが存在します。全部修正しなければいけません。

オブジェクト指向でないと、一つ一つのボタンのサイズを修正し拡大しなければなりません。
10個修正するなら10箇所の修正が必要になるという事。。(　ﾟдﾟ)

対してオブジェクト指向を使うと、定義したボタン幅や高さを**一箇所だけ**修正すれば全てのボタンが変更できます！
効率的にスピーディーに対応できますね！


# オブジェクト指向を学ぶ時に必要なキーワード

### カプセル化
**他のプログラムからできるだけ変更できないようにする仕組みのこと。**

モノとして使いまわしたい時に、変更したくない部分がある。他プログラムにより簡単に変更できないように設定して守ってくれるのが「カプセル化」。

### 継承
**継承は、同じようなプログラムを一箇所にまとめて、そのコードを再利用しやすく仕組みのこと。**

アプリを開発していると、データの登録や、テストを書く時などに、似たような処理を作るケースが出てくる。
もし、使用の変更が必要になったら？
この時、別々にコードを書くと、これまたカプセルかの時と同じように、書いた分だけコードの修正箇所があるということに・・探すのも大変、書くのも大変。＿|￣|○

また、開発が進んでいくと、重複したコードが多くなっていく。それを読むとなると時間がかかり、コードを探すのも大変。記述も冗長に、、

しかし継承を使えば、登録や更新、削除などのカテゴリー別にコードをまとめられるため、新しい機能機能を追加するときも、似たような処理がないかを確認しやすくなる。

コードを書いていて、これは確かに感じました。
例えばテストなんか、FactoryBotを使用して、処理をまとめて書けば工数も減るし、仕様が変わっても、修正にさほど手間はかからないです。
結合テストなんかも、同じログイン処理を一箇所にまとめて使いまわしていたのもまさにコレかと。

### 抽象化
**重要な要素や共通な要素を抜き出し、他は切り捨てる考え方。**

例えばスマートフォンを作りたいとき。

**聞かなければ分からないこと**

- どれくらいのサイズ？
- どんなデザイン？
- どんなコンセプト？

**必ず必要な共通要素**

- バッテリーがついている
- 操作するための画面がある
- 通話機能がある

などと言ったことが考えられる。

この後者の**必ず必要な共通要素**を考えるのが**抽象化**。
詳しいことは決まってないけれど、開発する上で必要となる機能には◯○だな、と考えるようなイメージ！

### ポリモーフィズム
**継承したコードの一部を変更して利用するための仕組み。**

新しい機能を搭載したいなぁと考えたとき、継承を使ってカテゴリーとしてまとめたコードの中に、似ている機能があったとする。
このとき、コードの一部分のみを変更して利用できるのが**ポリモーフィズム**。

ボタンの例で記述した色を変えたり、大きさを変更するというのはまさにポリモーフィズムの例って事ですね！

# まとめ!

- オブジェクト指向をマスターすると開発・運用効率が上がる!
- 開発後の修正もしやすいコードが作れるようになる！

正直このまとめをしていても30%も理解できているか自信がありません💧
ただ、実装している時に知らず知らずのうちに実行していたことはありました。(継承とかポリモーフィズムは特に)
とにかくフワッとでも、オブジェクト指向のことを理解できた！という人が増えればなと思います。

ではではお疲れ様でした！

### 追記　クラスとインスタンスの関係性
オブジェクト指向とは?
プログラムの動作をある特徴(属性値とメソッド)を持ったパーツの組み合わせで実現するという考え方。
パーツの特徴を定義するのがclass、実際のパーツはインスタンス。インスタンスはclassから生み出される。
大阪リージョンいろいろ

2021年3月2日、いよいよ大阪ローカルリージョンから大阪リージョンへとフルリージョン化されました。気になる点を調べてみました。ネタはゆる〜く追加していこうと思います。

##1. AZs名
###大阪リージョン（ap-northeast-3）
3a 3b 3c と綺麗に並んでいます。

```
% aws ec2 describe-availability-zones --query 'AvailabilityZones[*].ZoneName' --region ap-northeast-3
[
    "ap-northeast-3a",
    "ap-northeast-3b",
    "ap-northeast-3c"
]
```

マネージメントコンソールでEC2を選択しても同じ情報が見れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280358/3bfe7c29-9f25-83a3-df4b-5509b568fac0.png)

###東京リージョン（ap-northeast-1）
利用できない「1b」は欠けて、1a 1c 1d です。

```
% aws ec2 describe-availability-zones --query 'AvailabilityZones[*].ZoneName' --region ap-northeast-1
[
    "ap-northeast-1a",
    "ap-northeast-1c",
    "ap-northeast-1d"
]
```

##2. EC2のping応答時間
JAWS-UGでping大会がありました。その結果を観ると応答時間は地図上の距離ではなく、ネットワーク的な距離に比例していました。
###大阪リージョンのEC2
私がping打った時は平均17.753msです。

```
64 bytes from vvv.wwww.xxx.yyy: icmp_seq=97 ttl=238 time=18.429 ms
64 bytes from vvv.wwww.xxx.yyy: icmp_seq=98 ttl=238 time=18.147 ms
64 bytes from vvv.wwww.xxx.yyy: icmp_seq=99 ttl=238 time=18.911 ms

--- 13.208.173.77 ping statistics ---
100 packets transmitted, 100 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 12.200/17.753/19.775/1.801 ms
```

###東京リージョンのEC2
こちらは平均12.969msでした。

```
64 bytes from aaa.bbb.ccc.ddd: icmp_seq=97 ttl=236 time=14.914 ms
64 bytes from aaa.bbb.ccc.ddd: icmp_seq=98 ttl=236 time=12.851 ms
64 bytes from aaa.bbb.ccc.ddd: icmp_seq=99 ttl=236 time=14.982 ms

--- 18.181.246.228 ping statistics ---
100 packets transmitted, 100 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 8.092/12.969/16.646/2.950 ms
```

##3. マルチリージョン環境の民主化
多くの企業でマルチリージョン（災対環境）を構築するケースが増えると思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280358/325da145-22d9-89c0-de59-eca0a61fdac9.png)

##参考情報
有識者に教えてもらうと勉強になります。ありがとうございます:bow_tone1:

https://jawsug-arch.connpass.com/event/205443/presentation/?utm_campaign=new_event_links_to_group_member&utm_source=notifications&utm_medium=email&utm_content=detail_btn

https://aws.amazon.com/jp/local/osaka-region/
UserDefaultsの利用の際にCodableの変数はvarにしないと毎回値が生成される。

# まとめ

UserDefaultを利用する場合に、Codableなdataで初期化している変数がある場合は、`var`にしないと毎回初期化されてしまいます。

例えば、以下のようなコードだと、UserDefaultからdataを取得しても毎回違うUUIDが生成されます。
この場合はXcodeは忠告を出してくれます。(`Immutable property will not be decoded because it is declared with an initial value which cannot be overwritten`)

```swift:letを利用
struct Item: Codable {
    let id = UUID()
    let name: String
}
```

なので、UUIDも保存した値を使いたい場合はidを`var`にする必要があります。

```swift:varを利用
struct Item: Codable {
    var id = UUID()
    let name: String
}
```



# 実験


## letの場合
オリジナルとUserDefaultからLoadしたときのUUIDが違う。Loadするたびに違う値になってしまいます。

<img width=200 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199256/6261aa83-9d1b-a9da-db5b-932af5464835.png>

## varの場合
同じ

<img width=200 src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199256/7bf3f3bb-2ecd-1368-6697-91056ad2e943.png>


## 利用したコード

```swift
//  Created by Shohei Yamamoto on 2021/03/07.
//

import SwiftUI

struct ContentView: View {
    @State private var itemFetched: Item? = nil

    let item = Item(name: "test")
    let noData = "no data"
    
    var body: some View {
        VStack {
            
            Text("Original")
                .font(.headline)
                .padding()
            Text("ID: \(item.id), Name: \(item.name)")
            
            Text("Loaded")
                .font(.headline)
                .padding()
            Text("ID: \(itemFetched?.id.uuidString ?? noData), Name: \(itemFetched?.name ?? noData)")
            
            Spacer()
            HStack {
                Button("Save", action: saveData)
                Button("Load", action: loadData)
            }.padding()
        }
    }
    
    func saveData() {
        guard let encoded = try? JSONEncoder().encode(item) else {
            return
        }
        UserDefaults.standard.set(encoded, forKey: "Item")
    }
    
    func loadData() {
        if let jsonItem = UserDefaults.standard.data(forKey: "Item") {
            let decoded = try? JSONDecoder().decode(Item.self, from: jsonItem)
            itemFetched = decoded
        }
    }
}

struct Item: Codable {
    let id = UUID()
    let name: String
}


```
叩くと光るLedドラムを作ってみた　〜構想編〜

# まえがき
ある日、知り合いの吹奏楽部の先生から光るドラムを作って欲しいという依頼を受けたのが始まり。こういうこと他にもやりたい人いるんじゃないかなと思い執筆しました。
4記事に分けて掲載していきます。

# つくるもの
「叩くと光るLedドラム」
正確には、ドラムに設置する振動センサーに反応して光るLEDライト。
<blockquote class="twitter-tweet"><p lang="und" dir="ltr"><a href="https://t.co/UeL2QsHKNO">https://t.co/UeL2QsHKNO</a></p>&mdash; Takumi Ishikawa (@umi90) <a href="https://twitter.com/umi90/status/1368406434325532672?ref_src=twsrc%5Etfw">March 7, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

実現したいこととてしは、
1. ドラムを叩くとLEDライトが点灯
2. スマホでLEDライトの色や振動に対する感度を調整可能
です。

# 流れ
[叩くと光るLedドラムを作ってみた　〜構想編〜]()　　<b><font color="red">←　今回</font></b>
叩くと光るLedドラムを作ってみた　〜プロトタイプ編：ブレッドボード検討〜
叩くと光るLedドラムを作ってみた　〜本番編：プリント基板〜
叩くと光るLedドラムを作ってみた　〜アプリ編〜

# 構成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147946/fe3a381a-016e-e9b8-b634-d4c680b4d1cd.png)

基本的には、子機とドラムだけで「叩くと光る」ということは実現されて、プラスアルファの機能のスマホによる制御に向けてスマホと親機を開発。それぞれの役割としては以下の通り。

### 子機
まずはこのシステムの一番の肝となるのがこの部分。構成の図から子機と1つのドラムのみをピックアップしてもう少し詳しく表すとこんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147946/24dcb0ec-62d1-d1e6-ac33-3cffcba7da8d.png)
ドラムには振動センサーとLEDライトが取り付けられていて、子機がそれぞれに繋がっています。
実現したいこととしては、
①振動センサーを介してドラムの振動を検知
②ドラムの振動を検知するとLEDライトを点灯
さらに、
③親機からの指示に従って制御を変更
です。
### 親機
親機の役割としては、２つ。
①スマホからの指示を受信
②親機に繋がっているすべて　or 一部の子機に指示を送信

###スマホ
スマホはの役割は、
①LEDライトの色や振動感度の調整GUIを可能
②親機に調整内容を指示

# 連携方法
- スマホと親機：Bluetooth<br/>
スマホの電力消費も考えてBluetooth
- 親機と子機：Wifi<br />
子機との複数台を考えて扱いやすいWifi

※ 親機と子機はコンセントでつながります。

# おわりに
次からは実際に開発していきます。
「叩くと光るLedドラムを作ってみた　〜プロトタイプ編：ブレッドボード検討〜」
【Hyper】[Windows]デフォルトシェルをcmd.exeからPowerShellに変更する

Windows環境でHyperを利用する際にcmd.exeではなく、PowerShellを利用したい場合に
少しハマったため、メモとして残します。

https://hyper.is/

### 設定ファイルを開く

* 左上の3本の縦並び線のアイコン（ハンバーガーメニュー）-> Edit -> Preferencesをクリック
    * 設定ファイル```.hyper.js```が開く
    * (ショートカット：Ctrlキー + カンマを入力すれば即座に開ける)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93122/d751ba41-d5b0-5870-9c51-6a83797297d4.png)

### shellとshellArgsの内容を変更する

* ポイント
    * shellには、powershellのフルパスを指定
    * shellArgsから--loginを消す


* 変更前

```js
    // PowerShell on Windows
    // - Example: `C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`
    shell: '',

    // for setting shell arguments (i.e. for using interactive shellArgs: `['-i']`)
    // by default `['--login']` will be used
    shellArgs: ['--login'],
```

* 変更後

```js
    // PowerShell on Windows
    // - Example: `C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`
    shell: 'C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe',

    // for setting shell arguments (i.e. for using interactive shellArgs: `['-i']`)
    // by default `['--login']` will be used
    shellArgs: [],
```


shellArgsキー自体をコメントアウトしてしまうと、hyperが起動直後に終了してしまうので要注意です！

### もし起動しなくなったら

設定ファイルは（デフォルトでは）以下の場所にあるため、直接テキストエディタで開いて変更する


``` %APPDATA%\Hyper\.hyper.js ```
NiZ 静電容量無接点式キーボード 製品一覧

#NiZとは
(恐らく)2017年頃から静電容量無接点方式のキーボードを販売している中国メーカー。
中国語で「宇芝」。


#製品一覧
表にまとめたもの↓
[Googleスプレッドシート](https://docs.google.com/spreadsheets/d/12wcgs-wlCvcpTm5STSDTTGfe1aG4WWOeT9OspWfZ7-w/edit#gid=1020406112)

- Atom 66 White
 - 方向キーの「↑」だけ特殊。(Shiftと共存)
![atom66.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1180204/b76becda-5a64-9e04-cfad-eb4f861796bf.jpeg)

- Atom 68 White/Black
 - 66と比べて方向キーが独立している、PgUp/Downキーがある、スペースキーの左側が3キー。
![atom68.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1180204/4a23818e-c4d1-b309-2964-b5d02c247eb1.jpeg)

- Plum 75 White
 - 2018～2019年ごろ発売されていたよう。当時は安価で購入できたよう。
 - ファンクションキーはあるが、方向キーが独立でない。
![plum75.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1180204/7cecf53f-eec5-76ef-8c6d-9489a09c7b64.jpeg)


- Micro 82 White/Black
 - ファンクションキーがある。PgUp/Down, Home/Endキーがある。
![micro82.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1180204/8d7fdd76-1186-b58b-ea6b-c4fc10a82a89.jpeg)



- Micro 84 White/Black
 - 82と比べて、
 - スペースキーの左に+1key(Fn)
 - スペースキーの右に+1key(アプリケーションキー)
![micro84_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1180204/a82922da-e294-a4da-ae6c-7d9f38d6df44.jpeg)



- mini 84 Pro White
 - 公式からは2021/3現在購入不可。
 - Micro84と比べて、スペース左のFnキーと右のアプリケーションキーがない。
 - その分PrintScreenとPause/Breakキーが搭載。
 - ファンクションキーと数字キーの間が詰まっていてスリム。
![mini84pro.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1180204/b36228cd-cbc8-bb5f-7130-2517b1cd9353.jpeg)


- x87 White/Black
 - テンキーレスキーボード。
 - 84に比べてInsとScrlLockとアプリケーションキーが搭載。
![x87.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1180204/79832d1b-56ca-c629-13d9-171f946ceedd.jpeg)


- x108 White
 - フルキーボード。
![x108.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1180204/f35a9416-2ba0-d5c1-2f2e-af906c66ec1a.jpeg)


また、水で丸洗い可能なモデルも87/108keyも存在している。
テンキーと銀軸については本記事未掲載。



#個人的見解
2018～2019年では割と安価で購入でき静電容量無接点キーボードとして購入候補となり得たが、
2021年3月現在ではテレワーク需要もあいまってか価格が高騰している。(モデルも刷新されてるのでそちらも原因と考えられる)
公式での購入だとUSBモデルは1.6万円。Bluetoothモデルだと2万円ほどする。
日本版AmazonではAKEEYOが代理店として販売してるが、こちらも高い。(2万円～)

本来、NiZキーボードのメリットは
・RealforceやHHKB等の国産静電容量無接点より安価で購入できる。
・一般的なUS配列でBluetoothでのワイヤレス接続ができる。
この2点に近い。

以上を踏まえて、今NiZキーボードを買うメリットは
・Bluetooth接続をしたい。
・NiZの打鍵感/打鍵音が好みである。
・キー配置を変更したい。(Windows機のみドライバにて変更可能)
・Cherry軸なのでカスタマイズしやすい。
ぐらいだろうか。

こだわりがなく安く静電容量無接点方式のキーボードを入手したい場合、
NiZの中古やRealforce/HHKBの中古も視野に入れていいと思われる。
サンワサプライも出してるようだが。

##まとめ
以下の「キーボード」は「静電容量無接点式キーボード」と読み替えてほしい。

**・安価で新品、有線、US配列のキーボードを購入したい。**
 → NiZ

**・中古でもいいから安く入手したい。**
 → 型落ちRealforce (HHKBはそこまで値が下がらない。NIZは割高感がある。)

**・60%キーボードがほしい。**
 → HHKB、HHKBの特殊な配列が好みでないならNIZ

**・JIS配列のキーボードがほしい。**
 → NiZ以外

**・Bluetooth接続のJIS配列キーボードがほしい。**
 → HHKB

**・Bluetooth接続のJIS配列のフルキーボードがほしい。**
 → ない

**・Bluetooth接続のUS配列キーボードがほしい。**
 → NIZ,HHKB

以上
「PEP8 online check」をやってみた。実行例

SOで「関数名と変数名を大文字で始めたくはありませんが、」と指摘をうけたので、「PEP8 online check」をやってみた。
エディタで、pep８するのが、普通かも。
「pycodestyle」と言うのが、正しいですか？

(参考)「素因数分解を約数にする。ループの仕方を教えて下さい。」
https://ja.stackoverflow.com/questions/74430/%e7%b4%a0%e5%9b%a0%e6%95%b0%e5%88%86%e8%a7%a3%e3%82%92%e7%b4%84%e6%95%b0%e3%81%ab%e3%81%99%e3%82%8b-%e3%83%ab%e3%83%bc%e3%83%97%e3%81%ae%e4%bb%95%e6%96%b9%e3%82%92%e6%95%99%e3%81%88%e3%81%a6%e4%b8%8b%e3%81%95%e3%81%84

#「PEP8 online check」実行結果
(参考)
http://pep8online.com/
(参考)行番号は、onlineAwkで出力しています。
https://awk.js.org/
'{print NR,$0}'

```python
1 from sympy import *
2 import itertools
3 var('My_Yakusu')
4 def My_SoinsuToYakuSu(My_factorint):
5     k_list = list(My_factorint.keys())
6     v_list = list(My_factorint.values())
7     My_list=list(itertools.product(
8                  list(range(v_list[0]+1)),
9                  list(range(v_list[1]+1)),
10                  list(range(v_list[2]+1))))
11     My_Yakusu = []
12     for i in range(len(My_list)):
13         My_Yakusu.append(  k_list[0] ** My_list[i][0] \
14                          * k_list[1] ** My_list[i][1] \
15                          * k_list[2] ** My_list[i][2] )
16     return sorted(My_Yakusu)
17 
18 print("#sy 90-約数     ",divisors(90, generator=False))
19 print("#sy 90-素因数分解",factorint(90))
20 print("#my 90-約数     ",My_SoinsuToYakuSu(factorint(90)))
21 print("")
22 print("#630は、間違っています。")
23 print("#sy630-約数     ",divisors(630, generator=False))
24 print("#sy630-素因数分解",factorint(630))
25 print("#my630-約数     ",My_SoinsuToYakuSu(factorint(630)))
26 
27 #sy 90-約数      [1, 2, 3, 5, 6, 9, 10, 15, 18, 30, 45, 90]
28 #sy 90-素因数分解 {2: 1, 3: 2, 5: 1}
29 #my 90-約数      [1, 2, 3, 5, 6, 9, 10, 15, 18, 30, 45, 90]
30 
31 #630は、間違っています。
32 #sy630-約数      [1, 2, 3, 5, 6, 7, 9, 10, 14, 15, 18, 21, 30, 35, 42, 45, 63, 70, 90, 105, 126, 210, 315, 630]
33 #sy630-素因数分解 {2: 1, 3: 2, 5: 1, 7: 1}
34 #my630-約数      [1, 2, 3, 5, 6, 9, 10, 15, 18, 30, 45, 90]
```


Check nresults
以下はpythonソースでないですが、「```python」としています。 

```python
Code	Line	Column	Text
E302	4	1	expected 2 blank lines, found 0
E225	7	12	missing whitespace around operator
E201	13	26	whitespace after '('
E502	13	55	the backslash is redundant between brackets
E128	14	26	continuation line under-indented for visual indent
E502	14	55	the backslash is redundant between brackets
E128	15	26	continuation line under-indented for visual indent
E202	15	54	whitespace before ')'
E231	18	27	missing whitespace after ','
E231	19	31	missing whitespace after ','
E231	20	27	missing whitespace after ','
E231	23	27	missing whitespace after ','
E231	24	31	missing whitespace after ','
E231	25	27	missing whitespace after ','
E265	27	1	block comment should start with '# '
E265	28	1	block comment should start with '# '
E265	29	1	block comment should start with '# '
E265	31	1	block comment should start with '# '
E265	32	1	block comment should start with '# '
E501	32	80	line too long (109 > 79 characters)
E265	33	1	block comment should start with '# '
E265	34	1	block comment should start with '# '
W292	35	7	no newline at end of file
```
rails マイグレーションファイルの修正

## マイグレーションファイルの修正
マイグレーションにカラムの追加する機会があったので記事に残そうと思います。
## マイグレーションファイルの確認
まずはマイグレーションファイルの状態を確認します。

```
rails db:migrate:status
```

![Alt text]
(https://gyazo.com/a6a17a8ae23679d2c7c921d09cd19328.png)
upになってます。今回は２番目のplansテーブルにカラムを追加します。
## マイグレーションファイルの修正
今回はロールバックを使用します。

```
rails db:rollback
```
今回は２個目のplansを修正するためrails db:rollbackを2回打ち込みます。
ちなみにSTEP=nのように指定することもできます。

```
rails db:rollback STEP=2
```

ここで一旦マイグレーションファイルがdownになっているか確認します。
![Alt text]
(https://gyazo.com/94faefb56225338eadbe253475651d9f.png)

downになっているのが確認できましたのでマイグレーションファイルを修正します。
修正が終わったら

```
rails db:migrate
```
以上で終了です。
念の為、rails db:statusファイルの状態を確認しましょう。
create-react-appの.envについて

`create-react-app`の`.env`ファイルの扱いについてメモ。

# .envファイルの適用順
以下の順で適用されます。

1. `.env.{NODE_ENV}.local`
1. `.env.local` *NODE_ENVが`test`の場合は適用されません。
1. `.env.{NODE_ENV}`
1. `.env`

NODE_ENVは以下になります。
- npm scriptが`build`のとき、`production`
- `start`のとき、`development`
- `test`のとき、`test`

# .envファイルに設定できる変数(よく使うものだけ)

- `BUILD_PATH`  
    ビルド結果の出力先を指定できます。デフォルトは`build`です。
- `PUBLIC_URL`  
    create-react-appで作ったSPAをルート以外のパスで配信する場合に指定します。デフォルトは`/`です。
- `REACT_APP`プレフィックスのついた変数  

    ```.env:.env
    REACT_APP_MESSAGE=hello
    ```
    ```js:js
    console.log(process.env.REACT_APP_MESSAGE) // -> hello
    ```
【Railsチュートリアル】herokuにデプロイ出来ないのを解消した例

Railsチュートリアルを行っていて、テキスト通りに進めていたはずなのですが、herokuにデプロイ出来ませんでした。
こんなエラーが出ていました。（ちなみにcloud9は使わずにMac OSで開発しています。）

## 本番環境にsqllite3が使われていた

```:ターミナル
remote:  !
remote:  !     Failed to install gems via Bundler.
remote:  !     Detected sqlite3 gem which is not supported on Heroku:
remote:  !     https://devcenter.heroku.com/articles/sqlite3
remote:  !
```

ん？どうやら、本番環境にsqlite3が使われている？？

この記事を参考にしてみました。

- 
 [Rails アプリを初めて Heroku にデプロイしてエラーとなったとき](https://qiita.com/hmmrjn/items/e2dff8036fbbd74f049a)

Gemfileの中身は問題なさそうでした。
 `/config/database.yml`を見てみると、

```:/config/database.yml
production:
  <<: *default
  database: db/production.sqlite3
```

ここが違うようです。



こちらに書き換えました。

```:/config/database.yml
production:
  <<: *default
  adapter: postgresql
  encoding: unicode
  pool: 5
```
これでデータベースのエラーは解消出来ました！

## Bootstrapが上手く読み込まれてない？？
今度は、このようなエラーが出ました。

```:ターミナル
remote:  !
remote:  !     Precompiling assets failed.
remote:  !
```
エラー原因の箇所を見てみると、

```:ターミナル
remote:        Caused by:
remote:        Sass::SyntaxError: File to import not found or unreadable: bootstrap-sprockets.
```
どうやら、bootstrapが読み込まれてないみたい？

gemfileに `gem 'bootstrap-sass'`を追加。
試してみるも、また同じエラー。

- 
[【Heroku/Rails】デプロイで起こる「Precompiling assets failed.」の解決法](https://www.somethinggood.work/36)
こちらの記事を参考にして、

```:config/application.rb
config.assets.initialize_on_precompile = false
```

この記述を追加。
まだ直らず。

他の記事を探してみました。

- 
[Sass :: SyntaxError：インポートするファイルが見つからないか判読できない：bootstrap-sprockets](https://www.it-swarm.jp.net/ja/ruby-on-rails/sass-syntaxerror%EF%BC%9A%E3%82%A4%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%88%E3%81%99%E3%82%8B%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%8C%E8%A6%8B%E3%81%A4%E3%81%8B%E3%82%89%E3%81%AA%E3%81%84%E3%81%8B%E5%88%A4%E8%AA%AD%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84%EF%BC%9Abootstrapsprockets/1049262166/)

そして、こちらのコマンドを試してみた。

```:ターミナル
gem install sprockets
```

そして `bundle install`。

で、

```:ターミナル
git push heroku master
```

を実行。

デプロイ出来ました！！！

## まとめ
今回はcloud9を使わず、自分のMacOS環境で行っていましたが、どこかで手順を間違えていたのかもしれません。
同じようにherokuにデプロイできない方がいれば、試してみてください。
rbenv(○○env) installが使えない時の対処法

#rbenv installが実行できない

rbenvをインストールしたら、rbenv installでRubyをインストールと
他の記事で紹介されていたが、そのままはできなかったので解決方法を記載します。
ちなみに、rbenvはanyenvでインストールしました。

そのままでは、以下のように表示されました。

```
% rbenv install --list
rbenv: no such command `install'
```

#解決方法　install.shを実行する

pluginsの中の、ruby-buildの中にある「install.sh」を実行することで解決します。
まず、ruby-buildに移動して、「ls -a」で見てみます。

```
% cd $HOME/.anyenv/envs/rbenv/plugins/ruby-build/
% ls -a
.       .git       .gitignore     CODE_OF_CONDUCT.md README.md     install.sh       share
..      .github    .travis.yml    LICENSE            bin           script           test
```

install.shがありました。
これをスーパーユーザーで実行します。

```
% sudo install.sh
```

```
% rbenv install --list
  2.5.8
  2.6.6
  ... (あとは省略します)
```

rbenv installが使えるようになりました。

#最後に
私は、nodenvなどでも同じようにインストールが出来なくなっていました。
他のenvでも使えるはずです。

ホームからでも実行するためのコピペ用コマンドです。
(他の人の環境でのrbenvの階層は違うかもしれません)

```
sudo $HOME/.anyenv/envs/rbenv/plugins/ruby-build/install.sh
```

参考文献
https://ogatism.jp/rbenv_install
小ネタ／AWS 大阪リージョンで RDS を使う場合に気を付けること（大阪ローカルリージョン時代から使っている方向け）

タイトルに適合する方がどの程度いらっしゃるのかわかりませんが、とりあえずメモ程度に残しておきます。

# DB サブネットグループが 1AZ で構成できなくなった

RDS の DB サブネットグループは通常複数の AZ を使わないと構成できないのですが、大阪ローカルリージョン時代、特例として（複数サブネットは必要だったものの）1AZ での構成が可能でした。

![old_db_subnet_osaka.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/3cb343c1-ff72-43ab-52f2-1b76b485fbac.png)

大阪がフルリージョン化された後は、新規に 1AZ 構成で作ることができなくなりました。

![new_db_subnet_osaka_ng.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/4fc3ebc4-2a84-63fc-f4cf-38e3621073c7.png)

※既存の DB サブネットグループは従来どおり利用できています。

# 大阪ローカルリージョン時代のインスタンスタイプが選択できなくなった

以前は

 - db.m4
 - db.r4
 - db.t2

の各インスタンスが作成できましたが、現時点で新規作成できるのは

 - db.m5
 - db.r5
 - db.t3

の各インスタンスです。

![rds_osaka_type_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/ed6681a8-ff08-5490-64ef-ac85d7352a15.png)
![rds_osaka_type_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/1ee8f9f8-2c47-be5e-c04f-67deb71afbfa.png)

# ~~購入可能なリザーブドインスタンスは、大阪ローカルリージョン時代に提供されていたインスタンスタイプのみ（2021/03/07 現在）~~

~~一方で 2021/03/07 現在、購入可能なリザーブドインスタンスは、~~

 - ~~大阪ローカルリージョン時代に提供されていたインスタンスタイプのみ~~

![rds_osaka_ri_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/94b59fdc-d988-3907-4a12-6bd415a42b0a.png)

---

**2021/03/09 追記 :**
Oracle・SQL Server については db.m5・db.r5・db.t3 のリザーブドインスタンスも購入できるようです。

---

**2021/03/26 追記：**
MySQL などについても db.m5・db.r5・db.t3 のリザーブドインスタンスが購入できるようになっていました。

~~残るは Aurora のみですね（こちらは残念ながら、サポートから「現時点では予定なし」と聞いていますが、実際にどうなのかは不明です）。~~

---

 - ~~Aurora は対象外~~

![rds_osaka_ri_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/8bd4e567-c860-6666-edec-a5615f930a4e.png)

~~です。~~

~~こちらはそのうち改善されるかもしれませんね。~~

---

**2021/06/01 追記 :**
5月下旬に Aurora も購入可能になりました。

---

**2021/03/09 追記 :**

# RDS for MySQL のスナップショットから Aurora MySQL 互換版のインスタンスを作成することができない

こちらはマネジメントコンソール・CLI ともできないようです。

# ~~Aurora のスナップショットを他リージョン（東京など）からコピーできない（マネジメントコンソールのみ）~~

~~マネジメントコンソールでは、大阪ローカルリージョン時代と同様に、コピー先の選択肢に表示されません。~~

なお、こちらは CLI でコピーできるのを確認済みです。

---

**2021/03/21 追記 :**
マネジメントコンソールからできるようになったのを確認しました。

---
Laravel8で環境ごとに使用する.envファイルを切り替える

開発環境やステージング・本番環境でDBサーバーへの接続先等を切り替えたいと思い、`.envファイル`を環境ごとに分けました。
今回は下記参考サイトを参考に、紹介されてる中の`方法2`の対応で実施した内容をメモします。

- 参考
    - https://qiita.com/mmmmmmanta/items/b992c7d8cd69343b6626


# 環境
- 開発環境
    - docker desktop
- php
    - 7.4.14
- laravel 
    -  8.25.0

# 完成イメージ

最終的にフォルダ構成はこのように変わります。
`.envファイル`を`envディレクトリ`下に、環境毎に用意します。
指定条件は`bootstrap > app.php`に記述します。

## 対応前
※ `[]` はディレクトリ

```
[Laravel]  // Laravelプロジェクトフォルダ
 ├── [app]
 ├── [bootstrap]
 │      └──app.php
 ├── .env
 └── ...
```
## 対応後

```
[Laravel]
 ├── [app]
 ├── [bootstrap]
 │      └──app.php
 ├── [env]
 │      ├──.env.dev
 │      ├──.env.stg
 │      └──.env.prod
 └── ...
```

# 手順

## 1) .envファイルを用意する

プロジェクトフォルダ直下に`envディレクトリ`を作成してください。`.envファイル`を移動してください。
既存の`.envファイル`を複製し、本番（prod）開発（dev）などすぐわかるような名前分けをして`envディレクトリ`に置いてください。

```
[env]
 ├── .env.dev    // 開発（ローカル）環境
 ├── .env.stg    // ステージング環境
 └── .env.prod   // 本番環境
```

また、プロジェクトフォルダ直下にある既存の`.envファイル`は削除してください。


## 2) 切り替え処理

`.envファイル`の読込先は下記ファイルで指定しています。

サーバー情報からホスト名を取得して切り替えています。
下記の例では、開発環境はdockerを使ったローカル環境なので`localhost`を指定しています。

- **修正対象**
  - [プロジェクト]/src/bootstrap/app.php

```bootstrap/app.php
$app = new Illuminate\Foundation\Application(
    $_ENV['APP_BASE_PATH'] ?? dirname(__DIR__)
);

// ↓ 追加
switch ($_SERVER['HTTP_HOST'] ?? 'localhost') {
    // 開発環境
    case 'localhost':
        $app->loadEnvironmentFrom('env/.env.dev');
        break;

    // テスト環境
    case 'staging.maydomain.com':
        $app->loadEnvironmentFrom('env/.env.stg');
        break;

    // 本番環境
    case 'prod.maydomain.com':
        $app->loadEnvironmentFrom('env/.env.prod');
        break;
}
```


## 3) configのキャッシュ再生成
最後にキャッシュを更新し、各環境で正常に画面が表示されることを確認してください。

```
php artisan config:cache
```
デザインカンプ通りの比率でマルチデバイス対応する方法

デザインカンプ（幅640px）にボタン（幅468px）があるとします。
このボタンには上部にマージン（60px）があります。

このデザインカンプの比率を保ったまま、各種デバイスで表示させたいときの計算方法です。

640px以上では固定幅、640px 未満では比率を保ったまま縮尺させるには下記のようにします。

```css:desktop-first.css
.button {
    width: 468px;
    margin-top: 60px
 }
@media only screen and (max-width: 639px) {
  .button {
    width: calc(468vw / 640 * 100);
    margin-top: calc(60vw / 640 * 100);
  }
}
```

割られる数の 468 のところはデザインカンプのボタンの画像幅、割る数の 640 のところはデザインカンプ全体の幅です。

CSS をモバイルファーストに書くのであればこうですね。

```css:mobile-first.css
.button {
    width: calc(468vw / 640 * 100);
    margin-top: calc(60vw / 640 * 100);
 }
@media screen and (min-width:640px) {
  .button {
    width: 468px;
    margin-top: 60px
  }
}
```

この単位と計算方法は padding 、font-size、height、top などの指定にも使えます。
gem configを理解する ~ configを使った定数管理の方法

## 背景
Railsの課題を実施しています。途中で、**「定数の管理には`gem config`を使いましょう」**という指示がありました。「定数管理」という概念がなかったのと、初めて知るgemだったので、調べたことをまとめています。

## なぜ、定数を管理する必要があるのか？

調べたところによると、

- 環境ごとに違う定数を用いたい
- いろいろなところに散らばる定数をまとめたい

というような時に定数管理を用いるそうです。特に大規模アプリケーションだと必要なのだとか。

## 定数管理の方法

定数を管理するgemは数多くあり、パッと調べた限りでも以下のものが出てきました。

- [config](https://github.com/rubyconfig/config)
- [Settingslogic](https://github.com/binarylogic/settingslogic)

gem を使わず、自分で設定ファイルと作られたという方もいました！

[【Ruby on Rails】 gem を使わないで環境毎に定数管理をする](https://techblog.kyamanak.com/entry/2017/07/05/002655)

そのぐらい「定数管理」は必要な概念なんですね〜

## configの特徴

上記で取り上げた２つのgemは、どちらも`yml`形式でファイルを管理するようでした。
両者の公式サイトを見比べる限り、`config`の方が、体系的に定数を管理できる印象を受けました。

DL数は、`config`が1.7k、`Settingslogic`が1.4kと、やや`config`に軍配が上がる模様です。

## 使い方

### インストール
`config`では、`Gemfile`に`gem 'config'`と書いて、`bundle install`後

```sh
rails g config:install
```
 で、以下のファイルが生成・追記されます。
[![Image from Gyazo](https://i.gyazo.com/22cb18d5ee42e051729a30b44a179e6d.png)](https://gyazo.com/22cb18d5ee42e051729a30b44a179e6d)

### 生成されたファイル

生成されたそれぞれの設定ファイルの役割は以下の通りです。

|ファイル名|役割|
|----|----|
|config/initializers/config.rb|configの設定ファイル|
|config/settings.yml|すべての環境で利用する定数を定義|
|config/settings.local.yml|ローカル環境のみで利用する定数を定義|
|config/settings/development.yml|開発環境のみで利用する定数を定義|
|config/settings/production.yml|本番環境のみで利用する定数を定義|
|config/settings/test.yml|テスト環境のみで利用する定数を定義|

なお、インストール時に`.gitignore`に追記されていた内容は以下の通りですので。

```sh
config/settings.local.yml
config/settings/*.local.yml
config/environments/*.local.yml
```
上記の設定ファイル＋これから作成するファイルのうち、`local`で使うものはgithubに上げないようになっているんですね:innocent:

### 定数の使い方
今回は、`config/settings/development.yml`に以下のように書きました。

```yml:config/settings/development.yml
user:
  name: 'Alice'
```
すると、こんな形で変数にアクセスできます。

```sh
[1] pry(main)> Settings.user
=> #<Config::Options name="Alice">
[2] pry(main)> Settings.user.name
=> "Alice"
[3] pry(main)> Settings.user[:name]
=> "Alice"
[4] pry(main)> Settings.user.to_h
=> {:name=>"Alice"}
```

先に挙げた設定ファイルのどこに書いても呼び出し方法は同じようでしたが、ファイル間で値が重複した場合、上にあるものは下にあるもので上書きされるようです。

```
config/settings.yml
config/settings/#{environment}.yml
config/environments/#{environment}.yml

config/settings.local.yml
config/settings/#{environment}.local.yml
config/environments/#{environment}.local.yml
```
これで、うっかり同じ定数を定義してしまっても安心なのですね:relaxed:

## 感想等

確かに、今まで `config/initializer`だったり、`applicatiotn_controller`だったり、色々なところに定数を書いてきましたが、一つにまとまっていると便利かもしれません。

また、`config/initializer`に定数を書いていたときは、このファイルにエラーがあるとアプリ全体が起動しなかったので、大きすぎるエラーを出さない上でも便利なのかもしれないです。

今後、使用している場面を見かけたら、使い方を注目してみようと思います＾＾
画像のプレビュー機能で画像のサイズ調整を実現

プレビュー機能の実装時javascriptで画像にサイズを調整する以外に方法が思いつかずにいてやり方も分からずに作業が止まってました。
しかし画像のサイズの調整についてはcssにさせればいいと言うとに気が付いて
setAttributeを使って取得した画像URL情報を突っ込んだimg要素にidの属性も突っ込んで無事解決しました！。
cssって最強ですね。
Ubuntu20.04[server]でNetworkManagerを使いたい時のTips

## Ubuntu 20.04 ServerでNetworkManagerを使いたいなーって思った話

Ubuntu 20.04 Serverdのデフォだと、ネットワークの設定がめっちゃ面倒だし、
使い慣れてる「nmtui」で設定したかった...がハマりまくって、参考サイトがまるっきり、当てにならず途方に暮れていた...
が、デフォで管理してるネットワークツール「[Netplan][]」の[Netplan configuration examples(コンフィグサンプル)][netplan_ex]に、
すげーお得な情報が記載されていたw

- 手順  
 0. NetworkManagerをインストール `apt install -y network-manager`
 1. 次に`touch /etc/netplan/config.yaml`
 2. 続いて、config.yamlを編集 `vi /etc/netplan/config.yaml`
 3. 最後に`sudo netplan apply`で反映。

```:config.yaml
network:
    version: 2
    renderer: NetworkManager
```

あとは、いつも通り`nmtui`でマネージャーを起動して、編集するだけ...お疲れ様でした。

[netplan]:https://netplan.io/
[netplan_ex]:https://netplan.io/examples/#using-network-manager-as-a-renderer
【PHP】マーカーインターフェイス

# はじめに
interfaceは実装しなくても、動くものを作ることができます。ただ、interfaceを定義することで、コードに縛りが出来き、保守性の高いプログラムができます。今日は、インターフェイスの一つ、マーカーインターフェイスを紹介します。

# マーカーインターフェイスとは
>オブジェクト指向プログラミングにおいて、メソッドやフィールドが一切定義されていないインタフェース。
>[Wikipedia](https://ja.wikipedia.org/wiki/マーカーインタフェース)

# コード
### マーカーインターフェイスを使わない例

```php:php
class AException extends Exception {}

class BException extends Exception {}

try {
    throw new AException('Aの例外処理');
} catch (AException $e) { // AExceptionをキャッチする
    echo $e->getMessage();
} catch (BException $e) { // BExceptionをキャッチする
    echo $e->getMessage();
}

```

上記の場合、`AException`と`BException`の両方をキャッチしないといけません。


```php:php

class AException extends Exception {}

class BException extends Exception {}

try {
    throw new BException('Bの例外処理'); // ←(1)
} catch (AException $e) { // AExceptionをキャッチする
    echo $e->getMessage();
}
// Fatal error: Uncaught BException: Bの例外処理
```
`(1)`でBのExceptionを投げているので、当然BExceptionをキャッチできず、エラーになります。
(ちなみに、`catch (Exception $e)`にすれば動きますが、それではExceptionを拡張した意味がないです）


### マーカーインターフェイスを使う例

```php:php

// マーカーインターフェイス
// 関数もプロパティも定義しない
interface ABException {}

// ABExceptionを実装する
class AException extends Exception implements ABException {}

// ABExceptionを実装する
class BException extends Exception implements ABException {}

try {
    throw new AException('Aの例外処理');
} catch (ABException $e) { // ABExceptionをキャッチできる！
    echo $e->getMessage();
} 
```
`catch (ABException $e)`のように`ABException`をキャッチすることができるようになり、`catch`する内容を明示的に表すことができるようになります！


# おわりに
すぐに使いこなるテクニックではないですが、利用シーンが来たら見返していただけると幸いです。
【Python】ディレクトリ構成をタブ区切りで取得

# ディレクトリ構成を取得
プロジェクト配下の全ファイルを確認するために作成しました。

ディレクトリごとにタブ区切りにしているため、出力したテキストファイルをエクセルにコピー&ペーストすることで列を分けられるようにしました。

# 空のディレクトリを含まない場合(すべての拡張子)

```python:Python

import glob
import re
from pathlib import Path 

# ホームディレクトリを取得
HOME = Path('~').expanduser() 
SAVE_PATH = str(HOME) + '/Desktop/01_file_path.txt'
print('保存場所:' + SAVE_PATH)

# 現在のディレクトリ配下を取得
files = sorted(glob.glob("**/*.*", recursive=True)) # 空のディレクトリを含まない(すべての拡張子)

print('ファイルパス:\n================================================================')
f = open(SAVE_PATH, 'w', encoding='UTF-8')
for file in files:
    # /を/+タブに変換
    file = file.replace('/', '/\t')
    f.write(file)
    f.write("\n")
    print(file)

f.close()

```

## ツリー構成(例)

├ test1/
│　├ a.txt
│　├ b.sql
│　└ test1_1/
│　　　　└ c.md
├ test2/
│　├ d.txt
│　└ e.py
└ test3/ (空)　　　　

## 実行結果
タブ区切りで出力

```
test1/	a.txt
test1/	b.sqlt
test1/	test1_1/	c.md
test2/	d.txt
test2/	e.py
```

# 空のディレクトリを含む場合
11行目を以下に変更する
`glob("**/*.*")`を `glob("**/*")`に変える

```python

files = sorted(glob.glob("**/*", recursive=True)) # 空のディレクトリを含む
```

## ツリー構成
上記と同じ

## 実行結果
タブ区切りで出力

```
test1
test1/	a.txt
test1/	b.sqlt
test1/	test1_1
test1/	test1_1/	c.md
test2
test2/	d.txt
test2/	e.py
test3
```


## まとめ
lsコマンド等で取得して、手動で整形していたのをプログラム化しました。
作業時間が10分の1になりました。
意外と知らないJavaScript 　オブジェクトへのアクセス

# はじめに
タイトル詐欺かもしれません。

エンジニア転職を目指してReactで開発をしている自分が、JavaScriptを復習していて知らなかったことがあったので書きました。初学者向けかと思います。

## 角括弧記法とドット記法はできることが異なる部分がある。
いきなり結論です。
角括弧記法とドット記法とはJavaScriptのオブジェクトへのアクセス方法ですが、角括弧記法とドット記法の異なる部分を発見しました。下記のオブジェクトを使って順々に説明します。

```
    const pet = {
        name: 'ゲン', 
        age: 2,　
        brees: '柴犬'
    };
```
### ドット記法
オブジェクトのプロパティやメソッドに下記のように.(ドット)を使用してアクセスすることができる。

```
pet.age  // 2
```
### 角括弧記法
下記のように角括弧を使ってアクセスすることができる。

```
pet['age'] //2
```

## オブジェクトメンバーの設定にもドット記法と角括弧記法が使える
### オブジェクトのメンバーの値の更新
ドット記法、角括弧記法のどちらでもデータの更新、追加できる。

```
更新
pet.age = 3;
pet["age"] = 3

追加
pet.weight = 7.0;
pet["weight"] = 7.0;
```

## 角括弧記法とドット記法の異なる点
角括弧記法では動的にオブジェクトのメンバー追加ができる。これが新たな発見でした。

下記の変数があったとして、

```
let DataName = 'weight';
let DataValue = 7.0;
```
変数DataNameをプロパティ名として、変数DataValueを値としてオブジェクトのメンバーに追加することができる。下記のように記述します。

```
pet[DataName] = DataValue;
```

ドット記法で、同様のことを実行しようとしてもできません。

おわり

### 出典
https://developer.mozilla.org/ja/docs/Learn/JavaScript/Objects/Basics#setting_object_members

オブジェクト指向説明できるように学習続けます。
Amazon SES で無限ループを作った話

# はじめに
Amazon SESを使って、Eメールメッセージを加工する処理を作った。
構築自体はかなり簡単にできるので、正直なめていた。（反省はしていない）
SESを使うときは、メールの世界のルールを守らないといけない様子

# 構築
### メールの流れ
こういう感じの事がやりたい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185989/555a95cc-98d8-caab-af16-814b2c4487d3.png)

① SESでのドメイン検証：受信をするためにドメイン所有者から許可を受けている事を証明する
② SES受信ルール設定：メールが到着したときの動作を決める（今回の場合Lambdaを起動）
③ Lambda関数内から、SESからメール送信する

<hr>

ここまではドメインやLambdaの知識があれば、比較的簡単にできる。(構築方法は別途)
**受信するメールアドレス** と **送信するメールアドレス** を同じにしておいた（フラグ注意。下記参照）

# メール送信のモニタリングを実装
バウンスが多いと、AWSから「スパムメール発行業者」と認定されるらしい。まぁそりゃそうだ。
こんなに手軽にメールサーバを作れるのに、悪用されたらたまったもんじゃない。

公式サイト等の手順を見ながら、メール送信後、バウンスを検知したらアラートを飛ばすようにしてみる。
[通知を使用した Amazon SES E メール送信のモニタリング](https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/monitor-sending-activity-using-notifications.html?icmpid=docs_ses_console)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185989/90a5cefc-7f6a-3562-27f4-2129f5c5091e.png)



| 項目 | 設定値 |
|:-:|:-:|
| Email Feedback Forwarding:  | Enabled  |
| Bounce Notifications SNS Topic:   | EmailサブスクリプションつけたSNSトピックARN  |

とりあえずこれで。👇こんなイメージになるんだなと。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185989/bd132eef-c82a-6bfe-9f11-71d93bbc062e.png)

テスト用のメールアドレスも準備されている。
[Amazon SES での E メール送信のテスト](https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/send-email-simulator.html)

# 事件
Lambdaからのメール送信先を、テスト用バウンスアドレス"bounce＠simulator.amazonses.com"にして実行。。
実行後すぐに、SNSで指定したメールアドレス宛に通知メールが届いた。
・・・止まらない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185989/17f6aa4b-f9fc-6ed6-969d-a182a2bc510b.png)
200件超えたあたりで、SES > Domains > Notifications の SNSTopicを削除して、ようやく止まる。。

無限ループ？！
Lambdaのログ見てみよう
あああ
（フラグ回収）

# 解説
メール送信した後、SESに対して、”バウンス”・”苦情”・”到着”等のレスポンスが返るらしい。
バウンスを受け取ったとき、SNS経由で別なメールアドレスに通知するようにした。
FeedbackもONにしていた。→ 送信元にも通知するという事だろう。
今回、受信メールアドレスと送信メールアドレスを同じものにしていた。。つまり

SESがメールを受信→Lambda起動してSESでメール送信（テスト用バウンスアドレス）→バウンスがSESに通知される
→SESからSNS経由で、通知される
→ **Feedbackにより、メール送信元に通知される（メール送信元＝SES受信用メールアドレス)** 👈こいつが無限ループ



# 解決策

・ 受信・送信のアドレスは分けないといけない（これは当たり前レベルの話orz）
・ Feedback を Disableにする（SNS通知のみにする。いや…無限ループを避けるためにする設定ではない。。）
・ [E メールのフィードバック転送先](https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/monitor-sending-activity-using-notifications-email.html#monitor-sending-activity-using-notifications-email-destination) ←こちらを参考とする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185989/fc0ec4a6-3b59-6e56-b807-d0297b30f283.png)

# まとめ
メールサーバをミドルウェアで構築していた時により、運用上検討すべき箇所がまとまってきた感。
【初心者向け】引数とは

# はじめに

就職活動の中である会社とカジュアル面談をさせていただいたとき、__「引数とは何か説明してみてください」__と聞かれたのですが、うまく答えられなかったため、反省としてこの記事を書いています。

# 引数とは

関数に渡す値のこと。引数を渡された関数は、引数を使った計算ができます。

たとえば私がxとyを足すだけの関数を作ったとします。

```Swift:Swiftの関数
func sum(x: Int, y: Int) -> Int {
    x + y
}
```

このとき、xとyを__仮引数__と呼びます。xとyの中には何も入っていません。

関数を呼び出して、xに2を、yに3を入れます。

```Swift:関数の呼び出し
sum(x: 2, y: 3) //5が返ってくる
```

このとき、2と3を__実引数__と呼びます。

関数の中で`2 + 3`という計算が行われ、結果として`5`という値が返ってきます。

このように、関数に渡す値を引数と呼びます。

# 引数を使う利点

逆に、引数を使わない関数を考えてみましょう。

常に2 + 3という処理をする関数を作ります。

```Swift:引数を持たない関数
func sum() -> Int {
    2 + 3
}
```

この関数を呼び出しても、常に2 + 3しか処理をしてくれません。極端な例ではありますが、この関数はあまりにも限定的で、使い勝手が良いとは言えないでしょう。

つまり、引数を使うことによって、__その場面ごとに対応できる柔軟な関数を作ることができる__と言えます。

# まとめ

- 引数とは関数に渡す値のこと
- 引数を使うことでさまざまな場面に対応できる関数を作れる
ハーバード大のWEB講座でRを使ったデータサイエンス入門をやってみる Part.4 Vectorsで演算

過去の記事はこちらになります。

[第一回](https://qiita.com/Wataru-Tanada/items/6c201d59d03ce3ea31d9)
[第二回](https://qiita.com/Wataru-Tanada/items/f80bb564f08696e6fbe6)
[第三回](https://qiita.com/Wataru-Tanada/items/68d122a408221ad53223)

これからVectorで演算をやっていくことになります。まあ本格的といっても入門ですが...。

#1.Vectorを組み合わせてみる

前回まではVectorやデータフレームの単体を並べ替えたりデータを抽出しただけでした。例えば以下のように、人口が最大の州を抽出するとか

```
> murders$state[which.max(murders$population)]
[1] "California"
```

Vectorに対する算術演算はエレメントごとに行います。例えばインチ単位の身長のVectorをセンチ単位に変換するには、以下のようになります。

```
#inch 単位の身長データ
> heights <- c(69,62,66,70,70,73,67,73,67,70)
#inch → cm に変換
> heights * 2.54
 [1] 175.26 157.48 167.64 177.80 177.80 185.42 170.18 185.42 170.18 177.80
```

これを先ほどの殺人に当てはめてやってみましょう。統計っぽく10万人あたりの殺人件数を計算してみます。結果は多い順で表示します。

```
> murder_rate <- murders$total/murders$population*100000
> murders$state[order(murder_rate,decreasing = TRUE)]
 [1] "District of Columbia" "Louisiana"            "Missouri"            
 [4] "Maryland"             "South Carolina"       "Delaware"            
 [7] "Michigan"             "Mississippi"          "Georgia"             
[10] "Arizona"              "Pennsylvania"         "Tennessee"           
[13] "Florida"              "California"           "New Mexico"          
[16] "Texas"                "Arkansas"             "Virginia"            
[19] "Nevada"               "North Carolina"       "Oklahoma"            
[22] "Illinois"             "Alabama"              "New Jersey"          
[25] "Connecticut"          "Ohio"                 "Alaska"              
[28] "Kentucky"             "New York"             "Kansas"              
[31] "Indiana"              "Massachusetts"        "Nebraska"            
[34] "Wisconsin"            "Rhode Island"         "West Virginia"       
[37] "Washington"           "Colorado"             "Montana"             
[40] "Minnesota"            "South Dakota"         "Oregon"              
[43] "Wyoming"              "Maine"                "Utah"                
[46] "Idaho"                "Iowa"                 "North Dakota"        
[49] "Hawaii"               "New Hampshire"        "Vermont"     

# 10万人あたりの殺人件数の全国平均 
mean(murder_rate)
[1] 2.779125

```

10万人当たりの殺人件数でいうとカリフォルニアは14位になりました。ちなみに全国平均を出すと10万人あたり2.7人。2億5000万くらいだったので年間7000人くらいが殺人事件の被害者になっているようです。

この後のテストは簡単でした。どっちかというとdefineしなさいとか言われた方が意図わかんなくて困りました。この章はちょっと短すぎるのであとで何か足すかもしれません。でも今日のところは2章終わってしまったのでこのページは終わりにします。第3章では本格的にデータセットを操作したりグラフを作ったりするみたいです。長い序章だった...。

[第五回](https://qiita.com/Wataru-Tanada/items/f69904bdb437f3e22496)へ続きます。
Outlook インテグレーション ⇒ Inbox 機能による営業担当の生産性の向上

１．Inbox 機能を使用して営業担当は何ができますか?
２．Outlook インテグレーションに Inbox を追加するには、何を行う必要がありますか?
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/c125277d-a191-fa28-0189-0967c75d1f64.png)
【Jest】SecurityError: localStorage is not available for opaque originsが出た時

## エラー内容

```bash:エラー内容
 FAIL  test/unit/specs/HelloWorld.spec.js
  ● Test suite failed to run

    SecurityError: localStorage is not available for opaque origins
      
      at Window.get localStorage [as localStorage] (node_modules/jsdom/lib/jsdom/browser/Window.js:257:15)
          at Array.forEach (<anonymous>)
```

## 対応方法

`jest.config.js` に `testURL: "http://localhost/"` を追加

```diff:jest.config.js
module.exports = {
+ testURL: "http://localhost/",
  // ...
}
```

## 参考文献

- [jest : SecurityError: localStorage is not available for opaque origins #2304
](https://github.com/jsdom/jsdom/issues/2304)
- [jestで"SecurityError: localStorage is not available for opaque origins"と言われてテストがコケる](https://qiita.com/abetomo/items/b78af98d4857f55ec22b)
【k8s】deploymentのロールバック方法

## 概要

障害が発生した場合等に、下記手順よりロールバックを行う方法

## 事前準備

- kubectl

## 構文

```bash
kubectl rollout undo [RESOURCE_TYPE] [NAME]
```

## 一つ前のdeploymentにロールバックする方法

以下のコマンドを実行する場合は、ミスがないように注意して下さい🙇‍♂️

```bash
kubectl rollout undo deployment [NAME]
```
STM32CubeIDEを使ってみよう How To STM32CubeIDE 日本語版(18) エンコーダーモーターを使おう2

STM32CubeIDEを使ってみよう How To STM32CubeIDE 日本語版(17) エンコーダーモーターを使おうの続きです。
https://qiita.com/usashirou/items/c3868582a114bfe3f70f
前回は、エンコーダーモーターのエンコーダー値を取得できました。
ただ、このままではどの位移動しているかも回転方向もわかりません。
今回は、回転量と、方向を取得してみましょう。
##変更箇所
今回は、cntをcnt_newという関数にし、 元の値をcnt_oldと置換します。
そして、この差分を計算します。
この結果、前進するとその差分が後退した場合－の差分になります。
###TeraTermの出力の様子
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/8a6f818c-abf0-dba2-42dd-76cb96f3a5be.png)
それではプログラムを見てきましょう。

      cnt_old = cnt_new;
      cnt = cnt_new - cnt_old;

cnt_newをcnt_oldにし、引き算をしています。
これでエンコーダーモーターの移動量を把握することが可能になりました。

##プログラム全容
プログラムは図の通りです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/b83f04c7-2d8c-3b5a-2b43-5fe17d9238fe.png)

```
  /* USER CODE BEGIN 2 */
  HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
  HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);
  HAL_TIM_Encoder_Start( &htim3, TIM_CHANNEL_ALL ); // encoder start
  char msg[] ="Hello STM32\r\n";
  HAL_UART_Transmit(&huart2,(uint8_t *)msg,sizeof(msg),3000);
  int cnt= 0; //
  int cnt_new= 0; //
  int cnt_old= 0; //
  char scnt[100]; //
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
      /*Add Code*/
      __HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,0);
      __HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_2,0);
      cnt_old = cnt_new;
      cnt_new = TIM3 -> CNT; //
      cnt = cnt_new - cnt_old;
      sprintf(scnt, "TIM3 %d\r\n", cnt);
      HAL_UART_Transmit( &huart2, scnt, strlen(scnt) + 1, 0xFFFF);
      HAL_Delay(2000);
      __HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,300);
      __HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_2,0);
      cnt_old = cnt_new;
      cnt_new = TIM3 -> CNT; //
      cnt = cnt_new - cnt_old;
      sprintf(scnt, "TIM3 %d\r\n", cnt);
      HAL_UART_Transmit( &huart2, scnt, strlen(scnt) + 1, 0xFFFF);
      HAL_Delay(2000);
      __HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,5000);
      __HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_2,0);
      cnt_old = cnt_new;
      cnt_new = TIM3 -> CNT; //
      cnt = cnt_new - cnt_old;
      sprintf(scnt, "TIM3 %d\r\n", cnt);
      HAL_UART_Transmit( &huart2, scnt, strlen(scnt) + 1, 0xFFFF);
      HAL_Delay(2000);
      __HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,0);
      __HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_2,0);
      cnt_old = cnt_new;
      cnt_new = TIM3 -> CNT; //
      cnt = cnt_new - cnt_old;
      sprintf(scnt, "TIM3 %d\r\n", cnt);
      HAL_UART_Transmit( &huart2, scnt, strlen(scnt) + 1, 0xFFFF);
      HAL_Delay(2000);
  }
  /* USER CODE END 3 */
```
STM32CubeIDEを使ってみよう How To STM32CubeIDE 日本語版(18) エンコーダーモーターを使おう3に続きます。
https://qiita.com/usashirou/items/8a8f31d92757a16758b9