OmniAICreator/Qiita-1.07M huggingface dataset:
Ljava.lang.Objectの内容確認方法

①、Arrays.toString()で中身が確認できる
System.out.println("row : " +Arrays.toString(row));

②内容取得方法
		
		if(getResultList.size() !=0) {

			for (Object row : getResultList) { 
		        Object[] cells = (Object[]) row;

		        System.out.println("row : " +Arrays.toString(row));

		        BigDecimal a= (BigDecimal) cells[0];
		        String b = (String) cells[1];
		        LocalDateTime update_dt ((Timestamp) cells[2]).toLocalDateTime();
		    }
			
		}
Programmers ハッシュ1番問題_Java、Python、JavaScriptです。

今日はコーディングテスト問題サイトで問題を解いてみたいと思います。

https://programmers.co.kr/learn/courses/30/lessons/42576

参加者全員の配列と、目的地に到着した人数の書かれた配列を2つ受け取ります。
完走できなかった1人を見つけることです。 

##Java
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465875/d9eae90d-2c86-4cec-66f4-cf83fc8624aa.png)

ハッシュマップを利用して問題を解くことが最もベストでしょう。 
でも、私はハッシュマップを考えることができず、従って2配列を並べ替える方法で解きました。 
自分なりに頑張って解いたのですが、ハッシュマップできれいに解き明かすのを見て、まだまだ不足を感じました。

##JavaScript
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465875/c2ad5874-9845-d499-6855-b5f8d28c7670.png)
JavaScriptの場合、マップを利用するよりはsortがあるので、上のように整列して比較するのが早かったと思います。 
マップを書かなければならないという強迫観念によって さらに良くないコードになったようですが
JavaScriptで使ったことのないマップを利用しようと探して勉強しながらコーディングをしたのは、 
本当に大きく役に立ったと思います。


##Python

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465875/38f2febd-0c8e-18e5-2978-26c2e935c115.png)
パイソンを深く扱ったことがなくて、 どんなモジュールがあるのか、 どんな関数があるのか分かりませんでした。
他の人がしたことを見ることで、様々な機能があることが分かりました。
私はsortを利用して解いたし、他の人はcollectionモジュールを利用して、他の人はハッシュ関数を利用して解きましたが、
やはりすごい人が多いということを感じました。
herokuにpushしようと思ったらFailed to install gems via Bundle.と怒られる

# 結論
- herokuとローカル環境での`bundler`のversionを合わせる
- `bundle lock --add-platform x86_64-linux `を実行する

## やったこと
まずはエラー文を読み、

```
remote:        Your bundle only supports platforms ["x86_64-darwin-19"] but your local platform
remote:        is x86_64-linux. Add the current platform to the lockfile with `bundle lock
remote:        --add-platform x86_64-linux` and try again.
```

とあったので、　`bundle lock --add-platform x86_64-linux`を実行するが、エラーが出た。

`Failed to install gems via Bundle.`でググると、「herokuとローカル環境での`bundler`のversionがあっていないことが原因だった」という記事を見つけたので、herokuのbundlerのバージョンと、ローカルのバージョンを確認する。

herokuで使っているバージョンは

```
$ git push heroku
```
を実行したときに表示されていた

```
remote: -----> Ruby app detected
remote: -----> Installing bundler 2.2.16
remote: -----> Removing BUNDLED WITH version in the Gemfile.lock
remote: -----> Compiling Ruby/Rails
remote: -----> Using Ruby version: ruby-3.0.1
```

　の`Installing bundler 2.2.16`らしい。
ローカルでのバージョン確認は

```
$ bundler -v
Bundler version 2.2.17
```
herokuは`2.2.16`、ローカルは`2.2.17`でバージョンが違うかった。

いったん`Gemfile.lock`を削除

```
$ rm gemfile.lock
```

次にherokuとバージョンを合わせたbundlerをインストール

```
$ bundle _2.2.16_ install --without production
```

それから

```
$ bundle lock --add-platform x86_64-linux
```

で

```
$ git add .
$ git commit -m 'bundlerのバージョン変更'
$ git push heroku
```

いけました。

## まとめ
最近エラーが出ても耐性がついてきた。特にRailsは日本語の記事がたくさんあり、だいたいエラー文で調べれば出てくることが多いような気がします。
Super-Linter で JSCPD の ENOTDIR エラーが出たときの対処

## はじめに

[Super-Linter][sl] 便利ですよね！

かつては言語毎にlintの設定を GitHub Actions に一生懸命組み込んでいましたが、 Super-Linter が大概のものは勝手に見てくれます

しかし、新しく対応した linter に急に弾かれるようになったり、相反するルールを見るせいで弾かれたり、時々振り回されることもあります

先日、 Super-Linter を意気揚々と動かしたところ、以下のようなエラーが発生しました

```text
2021-06-10 06:46:08 [ERROR]   Found errors in [jscpd] linter!
2021-06-10 06:46:08 [ERROR]   Error code: 1. Command output:
------
Error: ENOTDIR: not a directory, scandir '/github/workspace/.github/linters/.hadolint.yaml'
    at Object.readdirSync (node:fs:1048:3)
    at readdir (/node_modules/@nodelib/fs.scandir/out/providers/sync.js:39:31)
    at Object.read (/node_modules/@nodelib/fs.scandir/out/providers/sync.js:12:12)
    at SyncReader.scandirSync [as _scandir] (/node_modules/@nodelib/fs.scandir/out/index.js:17:17)
    at SyncReader._handleDirectory (/node_modules/@nodelib/fs.walk/out/readers/sync.js:28:34)
    at SyncReader._handleQueue (/node_modules/@nodelib/fs.walk/out/readers/sync.js:23:18)
    at SyncReader.read (/node_modules/@nodelib/fs.walk/out/readers/sync.js:15:14)
    at SyncProvider.read (/node_modules/@nodelib/fs.walk/out/providers/sync.js:11:29)
    at ReaderSync.walkSync [as _walkSync] (/node_modules/@nodelib/fs.walk/out/index.js:19:21)
    at ReaderSync.dynamic (/node_modules/fast-glob/out/readers/sync.js:13:21) {
  errno: -20,
  syscall: 'scandir',
  code: 'ENOTDIR',
  path: '/github/workspace/.github/linters/.hadolint.yaml'
}
------
```

jscpd め、、、

というわけで、対処した記録です

## エラー原因

`.hadolint.yaml` は Dockerfile の linter である [hadolint] の設定ファイルです

hadolint をローカルで実行するときのため、この設定ファイルをプロジェクトのルートに配置しています

その上で、 Super-Linter からも参照できるように `.github/linters/.hadolint.yaml` にシンボリックリンクを貼りました

これで hadolint が通るはず、と思ったところ、上記エラーに逢いました

[jscpd] はコードの重複を探し出してくれます（ときどきコピペで jscpd に怒られます）

jscpd がシンボリックリンク自体を解析しようとしてエラーになったようです

[Super-Linter の公式 Issue][issue] にもありますが、取り合ってもらえず閉じてますね :cry:

## 対処

というわけで、シンボリックリンクを置くのではなく、 Super-Linter の参照先を変えることにしました

Super-Linter 実行時の環境変数 `LINTER_RULES_PATH` に `.` を指定します

```yaml
      - name: Super Linter
        uses: github/super-linter@v3
        env:
          LINTER_RULES_PATH: .
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```

これでプロジェクトのルート直下にある設定ファイルを参照できるようになります

公式がシンボリックリンクに対応してくれるまでは、こっちの対処しか使えません

どうしてもシンボリックリンクを使いたくなったら、、、その時はまた考えましょう

## 関連

設定ファイルの指定方法を解説してくれている記事です

https://qiita.com/kymmt90/items/c82cc6d5beab4af597db

[sl]: https://github.com/github/super-linter
[hadolint]: https://github.com/hadolint/hadolint
[jscpd]: https://github.com/kucherenko/jscpd
[issue]: https://github.com/github/super-linter/issues/1400
【CakePHP3】特定のControllerだけCSRF保護を無効化する

調べてみると`CsrfProtectionMiddleware`を全体的に無効化していたり、
ルーティング設定に混ぜ込んでいたりするものが多かったのですが
今回はそれ以外の方法で良さそうなものがあったので紹介します。

# まずは結論から

`src/Application.php`で`CsrfProtectionMiddleware`を
`whitelistCallbackメソッド`でCSRF保護しないControllerを指定して読み込ませる。

# バージョン
* CakaPHP 3.9.10
* (CakaPHP 3.8系 でも使えると思います)

# ホワイトリスト登録

CakePHP4系だと[CookBook](https://book.cakephp.org/4/ja/controllers/middleware.html#csrf)に
> ホワイトリストコールバック機能を使用して、 CSRF トークンチェックを実行する URL をより詳細に制御できます。

とあって実装の仕方を見ても楽そうだったので、CakePHP3系でもできないかなーとコアファイルを眺めていると

```php5:CsrfProtectionMiddleware.php
/**
 * Set callback for allowing to skip token check for particular request.
 *
 * The callback will receive request instance as argument and must return
 * `true` if you want to skip token check for the current request.
 *
 * @param callable $callback A callable.
 * @return $this
 */
public function whitelistCallback(callable $callback)
{
    $this->whitelistCallback = $callback;

    return $this;
}
```

メソッドの名前はちょっと違うけどそれっぽいのがあるじゃないですか。

# 早速使ってみる

```php5:src/Application.php
use Cake\Http\Middleware\CsrfProtectionMiddleware;
use Cake\Http\ServerRequest;

...

    public function middleware($middlewareQueue)
    {
        $csrf = new CsrfProtectionMiddleware([
            'httpOnly' => true
        ]);
        $csrf->whitelistCallback(function (ServerRequest $request) {
            // CSRFチェックしたくないcontrollerを指定
            $skipedControllers = ['SampleApi'];
            if(in_array($request->getParam('controller'),$skipedControllers)) {
                return true;
            }
            // debugkitも除外
            if($request->getParam('plugin') == 'DebugKit') {
                return true;
            }
            return $request;
        });

        $middlewareQueue
            ...
            // `new RoutingMiddleware($this, '_cake_routes_')`
            ->add(new RoutingMiddleware($this))
            ->add($csrf); // <-ミドルウェアのキューに追加

        return $middlewareQueue;
    }
```

これで試すと指定したControllerのみCSRF保護無効にできてました
IF文の中身を調整してAction単位にする等、自分好みのカスタマイズもしやすいです。

`config/routes.php`でも似たようなことはできるんですが、
個人的にはそこにルーティング以外の役割を持たせたくないので
`src/Application.php`のミドルウェア設定部分でやってしまうのがおススメです。

# まとめ

CakePHP3でもホワイトリスト登録でCSRF保護を部分的に無効化できる。
名古屋市の新型コロナウイルスワクチン登録医療機関のPDFをCSV変換

前回のPDFは「Microsoft: Print To PDF」で作成のため文字化け

今回は「eDocument Library」で作成されていたので文字化けせずに変換可能でした

https://www.city.nagoya.jp/kenkofukushi/cmsfiles/contents/0000136/136137/iryoukikan(R30615).pdf

ExcelやWordの場合ファイル保存画面からファイルの種類から「PDF」を選択するだけでPDFに変換できます。

https://www.atmarkit.co.jp/ait/articles/1812/10/news025.html

# プログラム

```
# ダウンロード
wget "https://www.city.nagoya.jp/kenkofukushi/cmsfiles/contents/0000136/136137/iryoukikan(R30615).pdf" -O data.pdf

apt update

apt install python3-tk ghostscript
pip install camelot-py[cv]
```


```python
import camelot
import pandas as pd

tables = camelot.read_pdf(
    "data.pdf", pages="all", split_text=True, strip_text=" \n", line_scale=40
)

dfs = [
    pd.DataFrame(table.data[1:], columns=["登録医療機関名", "住所１", "住所２"]) for table in tables
]

df = pd.concat(dfs).reset_index(drop=True)

df

df.to_csv("output.csv", encoding="utf_8_sig")
```
Xcode環境構築2021H1

# 概要

久しぶりにiOS（と言うかiPad）アプリを作ろうと思ったら環境構築が色々大変だったので、調べたことを残しておく。
公開するつもりがなかったので、エラーメッセージとかちゃんと残してなかった。失敗した。

# GitHub

iOSアプリ開発における環境構築とセットアップ手順.md · GitHub 
https://gist.github.com/kino-puehddby/015ecdee0320e25d81f7e2a27dd5847e

Xcodeでgit機能を使う(プロジェクトの作成からgithubにpushするまで) - Qiita 
https://qiita.com/sakamotoyuya/items/fd6c30e672860ba89759

GitHubにPushができない

xcode - xcodeでGitHubにPushしたいのですが、No remotes availableとなっています。 - スタック・オーバーフロー 
https://ja.stackoverflow.com/questions/39810/xcode%E3%81%A7github%E3%81%ABpush%E3%81%97%E3%81%9F%E3%81%84%E3%81%AE%E3%81%A7%E3%81%99%E3%81%8C-no-remotes-available%E3%81%A8%E3%81%AA%E3%81%A3%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99

個人アクセストークンを使用する - GitHub Docs https://docs.github.com/ja/github/authenticating-to-github/keeping-your-account-and-data-secure/creating-a-personal-access-token

GitHubへの接続がうまくいかない

GitHubで作成して、既存のリポジトリに接続してみた
→　プッシュで権限がないエラー

SSH keyを入れてみる

Generating a new SSH key and adding it to the ssh-agent - GitHub Docs https://docs.github.com/en/github/authenticating-to-github/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent

Adding a new SSH key to your GitHub account - GitHub Docs https://docs.github.com/en/github/authenticating-to-github/connecting-to-github-with-ssh/adding-a-new-ssh-key-to-your-github-account

GitHubで説明されてるEd25519はXcodeでサポートされてない？なんかエラーになった。id_rsaで作って、~/.ssh/configのid_rsaを普通のやつに置き換えた。
id_rsaで作ったものならGitHub上で作ったリポジトリをcloneできた。ので、そこに別で作ったswiftプロジェクトをコピペした。

pushしようとしたらエラーになった。
「remote: error: GH007: Your push would publish a private email address.」

githubのpush時のprivate email関係のエラーを解消する方法
https://zenn.dev/kaluna_hart/articles/github-email-error

何故か「git push」だと成功するけど「git push origin master」だと失敗すると思ったら、masterからmainに変わってるんだった。

git push時のerror: src refspec master does not match anyについて - deepblue
https://deepblue-ts.co.jp/git/git-push-error/

# CocoaPods

【Swift】CocoaPods導入手順 - Qiita 
https://qiita.com/ShinokiRyosei/items/3090290cb72434852460

CocoaPodsの導入と利用 - Qiita 
https://qiita.com/fksk/items/9e5fdc201af4f03f2dec
※「pod init」コマンドはプロジェクトフォルダ（xcodeprojファイルがある場所）で。

# Chartライブラリ

これは自分が作るアプリに入れたいライブラリなので、普通はいらないやつ

SwiftUIでChartライブラリを使ってみた。 | RE:ENGINES
https://re-engines.com/2020/07/27/swift_ui_chart/
※iOSのターゲットバージョンとかも指定した

「framework not found Charts」というビルドエラーが発生するように。

[XCode][Cocoapods]ビルドエラー時の対処法 - Qiita https://qiita.com/nakamurau1@github/items/e4a810e21e626cf6f09a
試したけど直らず

> 今後は生成されたxcworkspaceを開いて編集していかなければならない

これを忘れていて、普通に今までのプロジェクトを開いてたからだった。

ビルドしてみると、それでも「framework not found Charts」というビルドエラーが発生する。なんか触ってると、ターゲットをiOS12にするよとか、何回か聞かれて承認してたらビルドが通った。


これでようやく開発環境が作れた気がする。
コマンドプロンプトで秘密鍵を作りサーバーにアクセス

#概要

Windowsのコマンドプロンプトで秘密鍵と公開鍵を作成し，
コマンドプロンプトのSSHクライアントを使ってサーバーにアクセスする

#公開鍵と秘密鍵の作成

Windowsのコマンドプロンプトを起動．
(画面左下の検索窓から"cmd"もしくは，"コマンド"と検索すれば表示される)
作成場所を聞かれるので，変更する場合は場所のパスを，そのままの場合はEnter.
パスフレーズを聞かれるので，入力.(入力しなくても作成できるが，セキュリティ的には作成した方が良い)

```
$ ssh-keygen -t rsa -b 2048
Generating public/private rsa key pair.
Enter file in which to save the key (C:\Users\stars/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
```

指定したディレクトリに,id_rsaとid_rsa.pubが作成される．(この例では，C:\Users\stars/.ssh/)
id_rsa.pubをサーバーの管理者へ渡す．
id_rsaは，厳重に管理する．(流出するなどした場合は，作り直すこと)

#サーバーへのアクセス

管理者にサーバーを設定してもらったら，コマンドプロンプトからSSHでアクセスできるようになる．

```
$ ssh <サーバーのユーザ名>@<サーバーのIPアドレス>
```

例えば，下記のように

```
$ ssh fuga@192.168.11.1
```
VBA　エクセル　トップ１０にフィルターをかけて別シートにコピー

![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1614609/b3524b6e-cb2b-fc9d-6810-7a50260e7a48.jpeg)
![2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1614609/4d1e8ea9-83a2-afba-80a7-638fb6ff1f66.jpeg)
![3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1614609/7201cfe1-894e-c8c6-975d-364a39fc63a9.jpeg)


```vb
Sub トップテンを抽出()
    Range("A1").AutoFilter _
    field:=9, Operator:=xlTop10Items
End Sub

Sub データをトップ１０シートにコピーする()
    Range("A1").CurrentRegion.Copy
    Sheets("トップ10").Range("A3"). _
    PasteSpecial Paste:=xlPasteAllUsingSourceTheme
    Application.CutCopyMode = False
    Sheets("トップ10").Activate
    Range("A1").Select
End Sub
```
VS Code 1.43 の新機能 - ミニマップの縮尺や背景色の設定変更

https://code.visualstudio.com/updates/v1_43#_minimap-size

# ミニマップの縮尺設定変更
設定 `Editor > minimap: size` を使用してミニマップの縮尺設定を変更できるようになった。設定値は以下のとおり。

- `proportional`（デフォルト値）
    - エディタの行数に関係なく固定の縮尺でミニマップを表示する。エディタの行数がミニマップのサイズを超える場合はミニマップがスクロールする。
- `fill`
    - ミニマップのサイズは固定（スクロールしない）。縮尺はエディタの行数によって可変し、エディタの行数が少ない場合はミニマップ表示は適度に間引かれる。
- `fit`
    - ミニマップのサイズは固定（スクロールしない）。縮尺はエディタの行数によって可変するがエディタの行数が少ない場合でもミニマップ表示は間引かれない。

ログファイルなどの行数の長いファイルを眺めるときに、位置に当たりをつけてジャンプして見たいときにいちいちミニマップをスクロールするのが大変だったので、そんな時にすごく便利になった。

# ミニマップの背景色設定
ミニマップの背景色をカスタマイズできるようになり、さらに透明度（アルファチャンネル）も指定できる。つまりミニマップの背景を透明化できるようになった。
なお設定は設定画面からではなく`settings.json`ファイルの直接編集で行う（設定画面右上の**設定(JSON)を開く**ボタンで開く）。

```json:設定例
{
  "workbench.colorCustomizations": {
    "minimap.background": "#00000055"
  }
}
```

色指定時にRGBの後ろに透過率（上記例では55）を指定すると透明度を設定できる。

色コードの前に表示されている四角にマウスカーソルを合わせると色指定ダイアログが表示されるが、透過率は右から２つめのスライダーを使って変更できる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181011/1b86a349-a8f0-58cd-0b14-fa455fbbb8e4.png)

ミニマップを表示している時、ミニマップに重なる部分のエディタの表示内容が隠れてしまうのが難点だったが、透明化できることによりミニマップを表示しながらエディタの内容も見れるようになった。

(追記)
v1.61より、ミニマップのテキストの透明度も指定できるようになった。

```json:テキスト透明度設定例
{
  "workbench.colorCustomizations": {
    "minimap.foregroundOpacity": "#000000AA"
  }
}
```

値の指定の仕方は背景と同じだがこちらは透過率(上記の例だとAA)の部分のみ有効でRGBの部分は無視される。
競技プログラミングサイト上のコーディングエディタの種類を調べてみた

## 競技プログラミングサイト上のコーディングエディタの種類を調べてみた

| 競プロサイト名              | エディタの種類  |
|:--------------------------|:--------------|
| AtCoder                   | CodeMirror    |
| AOJ (Aizu Online Judge) β | ace           |
| CodeChef                  | ace           |
| CodeForces                | ace           |
| CodinGame                 | Monaco Editor |
| CSAcademy                 | ace           |
| GeeksForGeeks             | ace           |
| GCJ (Google CodeJam)      | ace           |
| HackerEarth               | Monaco Editor |
| HackerRank                | Monaco Editor |
| paiza                     | ace           |
| SPOJ                      | ace           |
| yukicoder                 | ace           |
※Monaco Editorはキーボードショートカット<kbd><kbd>Alt</kbd>-<kbd>F1</kbd></kbd>を押して表示されるメッセージでMonaco Editorだろうと判定しました  


| エディタ       | リポジトリ                                  |
|:--------------|:-------------------------------------------|
| ace           | https://github.com/ajaxorg/ace             |
| CodeMirror    | https://github.com/codemirror/CodeMirror   |
| Monaco Editor | https://github.com/Microsoft/monaco-editor |

 - それぞれのエディタには様々な便利なキーボードショートカットが用意されているので使いこなせるといいかもしれません(例えば、行削除や行コピーや検索や置換)  
 - aceのキーボードショートカット<kbd><kbd>Ctrl</kbd>-<kbd>,</kbd></kbd>でエディタの振る舞いを変えられるメニューが表示されます(※GCJでは表示されませんでした)  
 - 競プロで使う人もいるオンラインコンパイラでは、IDEONEはace、WandboxはCodeMirror、paiza.IOはaceでした
 



#### リンク

##### aceのキーボードショートカット  
 - wiki https://github.com/ajaxorg/ace/wiki/Default-Keyboard-Shortcuts (最新ではなさそうです)
 - デフォルトのコマンド https://github.com/ajaxorg/ace/blob/master/lib/ace/commands/default_commands.js 
 - 各種キーバインド(emacs,sublime,vim,vscode)  https://github.com/ajaxorg/ace/tree/master/lib/ace/keyboard

##### CodeMirrorのキーボードショートカット
 - デフォルトのコマンド https://github.com/codemirror/CodeMirror/blob/master/src/input/keymap.js 
 - 各種キーバインド(emacs,sublime,vim) https://github.com/codemirror/CodeMirror/tree/master/keymap


#### 余談
 - OSSリポジトリホスティングサービスのGitHubやBitbucketのブラウザ上のファイル編集はCodeMirror、GitLabはMonaco Editorのようです (GistもGitHubと同様にCodeMirror)
 - このようなウェブページに組み込めるエディタのウィジェットの一覧がWikipediaにあります https://en.wikipedia.org/wiki/Comparison_of_JavaScript-based_source_code_editors


aceではキーボードショートカット<kbd><kbd>Ctrl</kbd>-<kbd>,</kbd></kbd>で表示されるメニューは下記のようになります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1656840/e7faf284-25bb-c4fa-e7c2-5156ba814cde.png)

キーバインドを変更できたりします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1656840/5d9d1a93-01e9-c7f9-13a8-59aca59c1515.png)

テーマの変更もできます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1656840/a937062e-013b-fe43-341d-264366a90d98.png)

(※これらはIDEONEでのキャプチャーですが他のaceを使える競プロサイトでも同様にできます)
Laravel キーワード検索機能

Laravelで検索機能を実装したので備忘録として残しておきます。

## やりたいこと
投稿機能を作成して投稿した内容を部分一致検索で検索をかける。


## テーブル
* id
* titiel: 投稿のタイトル
* body: 投稿の内容



## 手順
1.ルーティングの作成
2.検索フォームを作成
3. 検索機能実装


## 2.検索フォームの作成
viewでグリッドシステムを使用してフォームを作成します。

```
    <div class="post-search-form col-md-6">
    <form class="form-inline" action="{{ route('post.index') }}">
        <div class="form-group">
            <input type="text" name="key"  class="form-control" placeholder="キーワードを入力">
        </div>
      <input type="submit" value="検索" class="btn btn-info">
    </form>
    </div>

```

## 3.検索機能の実装

Controlloerで受け取ったキーワードを元に部分一致する投稿の抽出。

```php
    public function index(Request $request)
    {
        $key = $request->key;

        $query = Post::query();
        
        if (!empty($key)) {
            $query->where('title', 'like', '%' . $key . '%')->orWhere('body', 'like', '%' . $key . '%');
        }

        $posts = $query->orderBy('created_at', 'desc')->paginate(10);
        return view('posts.index', compact('posts'));
    }
```
手順

* キーワードの受け取り
* キーワードがあればsql文の`like`を使用して部分一致で一致する投稿の抽出
* 取得した内容をviewへ送る

検索のキーワードをなしにして送ると全件抽出されます。

## 参考サイト
[検索機能の作成](https://laraweb.net/tutorial/607/)
[SQL like 前方一致、あいまい検索、エスケープ](https://itsakura.com/sql-select-like)
PHPで関数の引数の順番とかわからなくなったらphp.net見てない？コマンドで出せるんだぜ！

# はじめに
こんにちは。最近使っているマグカップはシナモロールのイラストが書いてあります、筆者です:smile:

さて、最近見つけたんですが、**PHPのコマンド**で関数のリファレンスを出せるのを見つけて感動したので、共有します。

既に知ってますぞという方、尊敬します(ぺっこり45度) :bow:

# 関数のリファレンス参照できるコマンド
**す、素晴らしい！！！**

```sh
$ php --rf array_colmun

Function [ <internal:standard> function array_column ] {

  - Parameters [3] {
    Parameter #0 [ <required> array $array ]
    Parameter #1 [ <required> string|int|null $column_key ]
    Parameter #2 [ <optional> string|int|null $index_key = null ]
  }
  - Return [ array ]
}
```

# 番外編
ほかにもクラスなどのリファレンス参照できるコマンドもあります:+1:

```sh
$ php --help | grep "Show information about" | grep -v function
  --rc <name>      Show information about class <name>.
  --re <name>      Show information about extension <name>.
  --rz <name>      Show information about Zend extension <name>.
```

# おわりに
コマンドで見れても、ものによっては、きっとこれからもphp.netを見に行っちゃうと思います:pray:
それでは！
【初心者】AWSでhttps化（SSL化）時に挑戦。引っかかった所３選。

# ポートフォリオ作成後
AWSへのデプロイが終わったものの、上の`保護されていない通信です`が気に食わなかったことと最近のサイトであまり見ないので、鍵のついた形にしたいと思いました。

## 実行までの手順
1. ACMによるSSL証明書の取得
1. Security Groupの作成
1. ターゲットグループの作成
1. ALBの作成

参考にしたもの

https://qiita.com/nakanishi03/items/3a514026acc7abe25977

https://bsblog.casareal.co.jp/archives/4024

https://aws.taf-jp.com/blog/37623

## 困ったところ３選
### Route53でのレコードの作成時
`検証保留中`となったから時間が経ったらできるかと思ったら、保留中でもドメインをクリックしたら下に出てくる。最初隠れていること。いくら待ってもまだ`検証保留中`の文字。（参考にした記事には`クリックすると下に出てくること`はきちんと書いてありました。）古い記事だとDNS名の登録が書かれていますが今はやらなくてもAWS側でやってくれます※2021年6月時点
### ターゲット登録し忘れ
無事に証明書を発行してもらい、次にロードバランサー（ALB）の作成。ここでターゲットを登録するのですが、ターゲットをクリックして`登録済みに追加`⇦これを押さないと登録されないこと。ただクリックしただけでは登録できません。今までは、選択して次に進めていたのに、このページだけクリックして登録が必要です。
### 設定の反映に時間がかかる
設定したらすぐできると思っていました。これが一番困ったかも知れません。参考にさせていただいた記事には`確認して完了。`とあり、すぐ飛んで確認しても付けたい鍵のマークになっておらず、何か設定が違うのかと何度もやり直しました。
何度も参考のものを読んでもやっていることは間違っていないのに、なんでできないのかと挫けそうな時、最後ダメもとで開いたら付けたかった鍵マークがついていました！！体感では１時間ぐらいかかったかもしれません。（個人差があると思います。悩んでいたから長く感じた？）
## 無事に完了
できた時の感動は悩んだからこそ格別でした。きちんと読むこと。諦めないこと。そんなことを再度確認しました。誰かの参考になったら嬉しいです。
stack machineを愛でる。 その9

#概要

stack machineが、好きだ。
練習問題、やってみた。

#練習問題

zundokoを、表示せよ。

#考え方

乱数の求め方
0から8の乱数を得る。

```
  push  "9"
  rnd
```

#サンプルコード

```
loop  push  "9"
  rnd
  push  "4"
  >
  !
  if  skip0
  push  "a"
  push  "0"
  set
  push  "x"
  push  "x"
  get
  push  "doko "
  add
  set
  jp  loop
skip0  push  "x"
  push  "x"
  get
  push  "zun "
  add
  set
  push  "a"
  push  "a"
  get
  ++
  set
  push  "a"
  get
  push  "4"
  >
  !
  if  skip1
  jp  loop
skip1  push  "x"
  push  "x"
  get
  push  "doko kiyoshi!"
  add
  set
  end


```

#成果物

https://embed.plnkr.co/plunk/7927WaqVehDCxvft


以上。
CodeCommit mbed-os STM32 を使う

Git Mbed AWS 準備する
https://qiita.com/carpenders/items/1a5e4bf2a8d7acc6cba0
windowsからawsのcodecommitに
https://qiita.com/carpenders/items/3688eae3d58c350a2225
Mbed Studio 統合環境で開発するため
https://qiita.com/carpenders/items/684bf02238af51491ecc
STM32CubeIDE HALでペリフェラルを使うため
https://qiita.com/carpenders/items/e0f24abfd4ba5de84816
STM32Timer
https://qiita.com/carpenders/items/8df09885082aece78c3e
STM32CAN
https://qiita.com/carpenders/items/7f921d3ae175d5ac1059
STM32Interrupt
https://qiita.com/carpenders/items/ec9f7d3e64a2a8ada46e
ラインアイ社LANIO調査
https://qiita.com/carpenders/items/976b7d4f1ecaf9dd4e20
TypeScriptにおけるnever型とは

# いきなり本題
TypeScriptにはneverという型が存在するのをご存知でしょうか？

# never型の使い方
こんな風に使います
![スクリーンショット 2021-06-16 10.12.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212159/42cd8e8d-a6c5-5c86-8280-85b54c510f5c.png)

returnNeverメソッドでは例外がthrowされているだけです。つまり、呼び出し元に処理が戻ることは100%ありません。

例えば下記のように呼び出した場合、dontReturnに処理が戻ることはないということですね。
![スクリーンショット 2021-06-16 10.25.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212159/c685d45b-8245-940d-bf43-732b7ee7d5c8.png)

# void型の使い方
では、void型とは何が違うのでしょうか。void型は下記のように使います。
![スクリーンショット 2021-06-16 10.29.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212159/5743d5a0-1bb2-c428-10f9-66353e27257f.png)

returnVoidメソッドではちゃんとreturnされますね。もちろん何らかの値が返るわけではないですが、呼び出し元に処理が戻ります。
![スクリーンショット 2021-06-16 10.36.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212159/d8513808-67de-9103-19c3-8cf05a987c09.png)
beReturnedには処理が戻るはずです。

# never型とvoid型の違い
まとめるとこうなります。

|| 共通点 | 相違点 |
|-|:-:|:-:|
|never|値が返らない|呼び出し元に戻らない|
|void|値が返らない|呼び出し元に戻る|

※ちなみに、どちらも基本的にはメソッドの返り値の型として使います。

今回は以上です。
[Memo] STM8 development

# Overview
Getting started for STM8 development

# References
- [いまさらSTM8](https://qiita.com/kotetsu_yama/items/97c8020f6ffd980d710b)
- [Getting Started with STM8 Microcontrollers](https://maker.pro/custom/tutorial/getting-started-with-stm8-microcontrollers)

# Environment
- Windows 10 (64bit)


# Downloads
1. ST (myST User registration and login are required.)
    1. STVD
        - https://www.st.com/en/development-tools/stvd-stm8.html#get-software
    2. Standard peripherals library
        - STSW-STM8069: STM8S/A Standard peripheral library  
        https://www.st.com/en/embedded-software/stsw-stm8069.html
        - STSW-STM8016:  STM8L15x/16x/05x/AL3Lx/AL31x standard peripheral library  
        https://www.st.com/en/embedded-software/stsw-stm8016.html
2. COSMIC C compiler
    - http://cosmicsoftware.com/download_stm8_free.php


# Installations
1. STVD (ST Visual Develop)
    - Extract zip and execute .exe file.

2. COSMIC C compiler
    -  execute .exe file (`cxstm8_FSE_stm32_32K.exe`).
    - License<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75594/16efb20f-65f8-c628-6252-27b0e6685fb7.png)
<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75594/c593560f-4608-4f32-885c-a606f177488f.png)



3. Standard peripherals library
    - Extract zip


# Setup
1. STVD
    - Set Toolset : Tools > Options...
<br>![Tools>Options...](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75594/9d8159a3-6ab1-4cf0-adac-dd0d78cbde41.png)
<br>![Options](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75594/755fd652-62d3-a721-e725-fba9527de978.png)
<br>![Broese for Folder](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75594/bfcaa32b-5960-c031-4a16-6758c49dfe3b.png)
    - Debug interface
<br>![Debug instrument>target Settings...](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75594/694b192a-7810-e4c5-e71a-d548b97245bc.png)
<br>![Debug Instrument Settings](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75594/bbb72382-610b-580e-131f-b0e7952d55bb.png)

2. COSMIC C compiler
    - copy `license.lic` file (you may receive via email after registration) to `C:\Program Files (x86)\COSMIC\FSE_Compilers\CXSTM8`<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75594/baa3c861-9cff-de5e-03c5-6fdc43780f1c.png)

<!-- ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75594/ee327d85-9360-8391-3bd1-e7d619b9a67b.png)
--> 


# Build: Example

- TODO: will be updated. :-)
docker-compose で php-fpm コンテナのマウントファイル変更時にフリーズする

# 発生した問題の詳細
docker for mac で nginx と php-fpm のコンテナをdocker-composeで実行した時に、php-fpm側のファイルを変更した時に、php-fpmのコンテナがフリーズしてnginxにレスポンスも返さないし、コンテナの終了もできない現象がありました。

# 原因
docker for mac （docker desktop）のバージョンを３．３．３にアップグレードして、Use gRPC FUSE for file sharing の項目のチェックが外れていたいたことで、ホスト・コンテナ間でファイルの共有ができずphp-fpmのコンテナがフリーズ状態になっていたようです。
Use gRPC FUSE for file sharing の項目のチェックを入れることで解決しました。
![スクリーンショット 2021-06-17 7.10.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72832/fcea33a0-dc78-507c-ed87-03d639fd4b9b.png)
cssを使って画面右下に投稿ボタンを作成する

##やりたい事
・twitterのios版みたいに画面右下に投稿ボタンを作成する
・投稿ボタン全体をクリックできるようにする

##完成図

![スクリーンショット 2021-06-17 6.53.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635864/029bef80-752a-42d4-6cf3-9caed456e36d.png)

今回作ったのは右下の空色のボタン

##投稿ボタン(div)全体をクリックできるようにする

````ruby:show.html.erb

<a href="/">
  <div class="post-btn">
    <i class="fas fa-plus"></i>
  </div>
</a>
````

やり方を調べたらdiv全体をaタグで囲めばいいとあって驚きました。
ちょっと違和感がありますがちゃんと動いてるし実装も簡単なのでこれで良しとします。

##ボタンを所定の位置に固定する

````application.scss

/* 投稿ボタン */

.post-btn {
  position: fixed;
  bottom: 10%;
  right: 25%;
  width: 70px;
  height: 70px;
  line-height:70px;
  color:white;
  font-weight: bold;
  font-size: 30px;
  background: aqua;
  border-radius: 50%;
  text-align: center;
}
````

position: fixed;
bottom: 10%;
right: 25%;
により要素を下から10%、右から25%の位置に固定

line-heightとheightを同じ値にすることによってボタン内の文字(+)をちょうど真ん中の高さに持っていく事ができます。
Oracle実験室 

私が勉強中のOracle Databaseについてのメモです。

# Oracle実験室 / Oracle Restart環境構築 (19.3)
https://qiita.com/Que-sera-sera/items/df2a5f53953ea500f333

# Oracle実験室 / Oracle データベース各種操作
https://qiita.com/Que-sera-sera/items/862c77963b841a95ba95
Seleniumを最新ドライバーで実行する方法

以前から嘆いていた、定期的にWEBドライバを差し替えないと問題が
`webdriver-manager`を使用すると解決することがわかりました！

詳細はこちらで確認できます。
https://pypi.org/project/webdriver-manager/


まずはさっそくインストールしていきます。

```
pip3 install webdriver-manager
```


ドライバの起動は次のように書くと実行できます。

```py:Seleniumの起動
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager

driver = webdriver.Chrome(ChromeDriverManager().install())

url = ''
driver.get(url)
```

これで、たまに使うときの再インストールの手間をなくすことができます。
【5分でできる】はじめてのgit alias設定方法

# この記事はなに？

* gitのaliasをはじめて設定する人向けの記事です。
* 派生して、新卒や新メンバーの受け入れで教育担当になった人が、「この記事見て設定しておいて」ができる記事になるといいな。
* 「[3000文字Tips - 知ると便利なTipsをみんなへ届けよう](https://qiita.com/official-events/d523df99d6479293ffa7)」への投稿記事
* 対象読者
    * はじめてaliasの設定をする人
    * 非エンジニアだけれどコマンドでgit操作することになった人
    * 新卒などの教育担当になった人

# aliasとは

簡単に言うと短縮コマンドを設定できます。

例えば、`git status -sb`というコマンドを私は良く使います。
これを `git st`と打てば `git status -sb` の内容が実行されるように設定しています。

gitのコマンドはオプションを付けることでより便利に利用できます。
ですが、コマンドとオプションを補完なしで毎回入力するのは面倒です。
（※補完する方法は別途ありますが、今回は触れません）

頻繁に使うコマンドを設定しておくと毎日のgit操作が快適になりますよ。
短縮の形も人によって違うので、ぜひ自分が使いやすい形をみつけてください。

## :beginner: gitに不慣れな方への補足

`git status`とそのオプションについて軽く説明します。
知っているよという方は読み飛ばして、[次の章](https://qiita.com/gilly/items/23ce8ca2fb4787fec002#設定方法)へ進んで問題ありません。

`git status`と打てば、ローカルで変更されたファイルを確認できます。

```{shell-session:git statusの表示結果例}
On branch [ブランチ名]
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)

    modified: [変更ファイル名]

```

でも正直表示が長いので、私は`git status -sb`というオプションを利用して、省略表示をしています。
オプションの内容を簡単に説明すると、`-s`でstatusで表示される内容を短縮し、`-b`でbranch名を表示します。

表示結果は下記のようになります。

```{shell-session:git status -sbの表示結果例}
## [ブランチ名]
 M [変更ファイル名]

```

毎回 `git status -sb` と打つのは手間なので、`git st` と打てば `git status -sb` が実行できるようにaliasを設定しています。

# 設定方法

ここからは設定方法について解説します。

## 前提

* gitをインストールしている
* 隠しファイルを見れるようにしている ※エディタで編集したい人

## 設定ファイルを開く

aliasを設定する場所は、反映させたい範囲によって異なります。

|反映させたい範囲|設定ファイル|備考|
|---|---|---|
|システム全体|/etc/gitconfig|利用しているパソコン全体で使えます|
|ユーザー|~/.gitconfig|ログインしているユーザーで使えます|
|リポジトリ|リポジトリルートディレクトリ/.git/config|操作しているリポジトリ配下で使えます|

複数箇所に書いた場合、優先度は `システム全体 < ユーザー < リポジトリ` となります。

今回は `~/.gitconfig` で解説をしていきたいと思います。

### コマンドで開く

ターミナルなどのCUIで操作したい方は、下記のコマンドでファイルを開けます。

```shell-session
git config --global --edit
```

### エディタで開く

VScodeなどのエディタで開きたい方は、隠しファイルを閲覧できる状態にしてからファインダーから直接VScodeで開いてください。

|Macの場合|Winの場合|
|---|---|
|~/.gitconfig|C:\\\Users\\{username}\\.gitconfig|

## 設定する

初めて `.gitconfig` を開いた時は何も書いてないと思います。
ここに自分でaliasを書き足していきましょう。

すでに何かしら記入してある場合は、続きに記入してください。

最初に `[alias]` と記入してセクションを宣言します。
aliasの記入方法は `短縮コマンド = 通常のコマンド` と記入してください。

例えば先に説明した `git status -sb` のaliasは下記のように書きます。

```ini:~/.gitconfig
[alias]
    st = status -sb
```

設定が完了したら、保存すれば使うことが可能です。
ターミナルなどでお試しください

## :beginner: 何から設定したらいいかわからない方向け

私が思う、最初に登録をおすすめするaliasはこちらです。
良ければご活用くださいませ。

```ini:~/.gitconfig
[alias]
  st = status -sb
  co = checkout
  br = branch
  ft = fetch
  loga = log --graph --oneline
```

Qiita内にもaliasの記事がいっぱいあるので、とても参考になります。
何かしらこの記事がお役に立てたら幸いです
【備忘録】【Rails】多対多の関係のモデル実装（タグ編）

自分用のメモです。
Railsで多対多の関係性を使って、タグ機能を実装する手順を残しておきます。

# モデル
記事投稿の情報をもつTweetモデル、
タグの情報を持つTagモデル、
その2つを繋ぐ中間テーブルとしてTweet_Tag_Relationモデルを作成します。

1つのTweetは複数のTagを持ちえ、1つのTagは複数のTweetを持つ関係とします。

# 多対多を実装した経緯

TweetとTagが "複数 - 複数" 、つまり多対多の関係になっており、
中間テーブルというものを作りデータを管理する必要が出たため。

ER図

![スクリーンショット 2021-06-16 16.23.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/985164/54827185-e780-b9b1-c146-e9f3e8161007.png)



# 下準備

#tweetモデル作成

```ruby:ターミナル
$ bundle exec rails g model tweet
```

# マイグレーションファイルを編集

```ruby:
class CreateTweets < ActiveRecord::Migration[6.0]
  def change
    create_table :tweets do |t|
      t.string :name
      t.string :text
      t.timestamps
    end
  end
end
```

# マイグレーションを実行

```ruby:ターミナル
$ bundle exec rails db:migrate
```

# tagモデル作成

```ruby:ターミナル
$ bundle exec rails g model tag
```

# マイグレーションファイルを編集

```ruby:
class CreateTags < ActiveRecord::Migration[6.0]
  def change
    create_table :tags do |t|
      t.string :name, null: false

      t.timestamps
    end
  end
end
```

# マイグレーションを実行

```ruby:ターミナル
$ bundle exec rails db:migrate
```

# tweet_tag_relationモデル作成

```ruby:ターミナル
$ bundle exec rails g model tweet_tag_relation tweet:references tag:references
```

# マイグレーションを実行
```ruby:ターミナル
$ bundle exec rails db:migrate
```



# 各モデルを編集

```ruby:app/models/tweet.rb
class Tweet < ApplicationRecord
  has_many :tweet_tag_relations
  has_many :tags, through: :tweet_tag_relations
end
```

```ruby:app/models/tag.rb
class Tag < ApplicationRecord
  has_many :tweet_tag_relations
  has_many :tweets, through: :tweet_tag_relations
end
```

```ruby:app/models/tweet_tag_relation.rb
class TweetTagRelation < ApplicationRecord
  belongs_to :tweet
  belongs_to :tag
end
```

モデルの実装は以上。
【Php】validationについて-1

# 初めに
phpのvalidationについて学習した内容のoutput用記事です。

※内容に間違いなどがある場合はご指摘をよろしくお願いします。
※こちらの記事はあくまでも個人で学習した内容のoutputとしての記事になります。

前回の記事:
https://qiita.com/redrabbit1104/items/a6e57aa1fd1771ef90ff
https://qiita.com/redrabbit1104/items/a3eaf2bba51fac0b3c51

# validationとは
ユーザーがフォームなどから入力した値がデータベースに保存される値として望ましいものかどうかをチェックすること。例えば、emailアドレスなのに＠が無いと正しいものとは言えないので、validationを掛けて入力値をチェックする。

# 使ってみる
まずはvalidationをチェックする関数を作ります。チェック項目は色々ありますが、最初に名前の入力が空のままだった場合にerrorメッセージを表示するようにします。この関数の引数$filter_valueには\$_POSTが入るようにします。また、empty()関数で入力値\$filter_valueのキーの値が空だった場合に\$messagesという配列にユーザーの入力を促すメッセージを格納します。

```php
function validation($filter_value){   //$filter_valueには$_POSTが入る
    
    $messages = [];

    if(empty($filter_value['input_name'])){
        $messages[] = '氏名は必須です';
    }

    return $messages;    //$messagesを戻り値にする
}
```
この関数にユーザーからの入力値\$_POSTを引数として代入し、その結果を\$error_messagesという変数に格納します。

```php
$error_messages = validation($_POST);
```
こうすることによって、入力値が問題があった場合にだけ、エラーメッセージを変数として保存しておくことができます。

画面の切り替えのところにこの$error_messagesが無い（エラーがない）条件を追加してあげます。

```php
if (!empty($_POST["btn_submit"]) && empty($error_messages)) {
    $page_flag = 1;
}
```
それから入力画面にもエラーがあった場合にはエラーメッセージが表示されるようにします。この時に\$error_messagesが空でない条件に加え、$_POSTの'btn-confirm'キーが存在する、つまり送信ボタンが押された場合にのみメッセージが表示されるようにします。

```php
<?php if (!empty($error_messages) && !empty($_POST['btn_confirm']))
  echo var_dump($error_messages);
?>
```
var_dumpで\$error_messagesを表示してみると、次のように連想配列という形でエラーメッセージが入っていることが分かります。

![スクリーンショット 2021-06-16 7.49.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/fa84d134-b94e-e704-1c1c-b25b8379caeb.png)

# 参考サイト
https://qiita.com/mpyw/items/346f1789ad0e1b969ebc
stack machineを愛でる。 その8

#概要

stack machineが、好きだ。
練習問題、やってみた。

#練習問題

fizzbuzzを、表示せよ。

#考え方

剰余の求め方
iの３の剰余が０ならばskip0へ飛ぶ。

```
  push  "i"
  get
  push  "3"
  %
  push  "1"
  >
  if  skip0

```

#サンプルコード

```
  push  "x"
  push  ""
  set
  push  "i"
  push  "0"
  set
loop  push  "i"
  push  "i"
  get
  ++
  set
  get
  push  "i"
  get
  push  "15"
  %
  push  "1"
  >
  if  skip2
  push  "i"
  get
  push  "5"
  %
  push  "1"
  >
  if  skip1
  push  "i"
  get
  push  "3"
  %
  push  "1"
  >
  if  skip0
  push  "x"
  push  "x"
  get
  push  "i"
  get
  add
  set
  push  "x"
  push  "x"
  get
  push  " "
  jp  skip3
skip0  push  "x"
  push  "x"
  get
  push  "fizz "
  jp  skip3
skip1  push  "x"
  push  "x"
  get
  push  "buzz "
  jp  skip3
skip2  push  "x"
  push  "x"
  get
  push  "fizzbuzz "
skip3  add
  set
  push  "i"
  get
  push  "100"
  >
  if  loop
  end


```

#成果物

https://embed.plnkr.co/plunk/DaRB6BAejIqZOjNA

以上。
JetBrains IDE でインデントの調整をする

## やり方
複数行の場合は複数行選択してから

### 右にずらす
`tab`

### 左にずらす
`shift` + `tab`

## 検証環境
```
PyCharm 2021.1.1 (Professional Edition)
Build #PY-211.7142.13, built on April 21, 2021
Licensed to XXXXXXXXX / xxxxxxxxxxxxxx
You have a perpetual fallback license for this version.
Subscription is active until XXXXXXXXXXXXX.
Runtime version: 11.0.10+9-b1341.41 amd64
VM: Dynamic Code Evolution 64-Bit Server VM by JetBrains s.r.o.
Linux 5.8.0-55-generic
GC: G1 Young Generation, G1 Old Generation
Memory: 2048M
Cores: 16
Non-Bundled Plugins: org.jetbrains.plugins.vue (211.7142.13)
Current Desktop: ubuntu:GNOME
```

## 参考
https://intellij-support.jetbrains.com/hc/en-us/community/posts/206360699-Indent-Selected-Text-Left-Right?page=1#community_comment_207423449
Notionにdraw.ioの図を表示させる

# はじめに
この記事は、掲題のことをやりたく、やり方を調べた結果になります。

* やりたいこと
    * Notionに、draw.ioで描いた図を埋め込みたい。 
    * 但し draw.io 側では、複数ページの図が存在し、その内の１ページを埋め込み表示させたい。

# 参考した記事
* @shotatさんの「[Notionとdraw.ioを連携させる](https://qiita.com/shotat/items/f51ca20dbea74645c3f6)」記事を参考させて頂いて、draw.io に作成図面が１ページだけの場合は、上手く埋め込み表示ができました。
* その後、draw.io上で、図面のページを複数追加して、再度、その中の１つの図面を埋め込もうとすると、Notionで図面が見えず、如何しても、下記の画面のように、draw.io ビューアへのリンクだけを埋め込むことになる。いろいろ試行錯誤の結果、上手くやれる方法が分かった。

* 下記の図は、埋め込めなかった時の画像でした。一応、リンクをクリックすれば、別画面で図面は表示されるが、Notionに埋め込み表示ではなかった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384023/3056c8f7-06fc-7448-d62d-e328f94fc0a8.png)

# 解決策
* 解決策は簡単で、基本的に、@shotatさんの記事通りの設定でよかったのですが、下記の設定画面で、<b>"All Pages"のチェックを外す</b>と、draw.io に複数ページが存在しても、表示したい１ページの画像は、Notionに上手く埋め込み表示ができるようになった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384023/213fd6fd-6fb4-bf47-e0b7-72b819d5c21c.png)

# 手順の概要
1. (draw.ioの操作) メニューから以下の順に、埋め込む先の形式をNotionを選択する
   File -> Embed -> Notion を選ぶ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384023/c88981c9-adfb-cb9d-0d12-95d7e013f3ed.png)

2. (draw.ioの操作) 下記の画面が現れるが、「All Pages」のチェックを外す。ほかの項目は、適当に設定、特に埋め込みの効果に影響がみられていない。その後、Createボタンをクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384023/26c081d9-1b49-d9de-4bc0-c3d574765171.png)

3. (draw.ioの操作) 下記の画面が表示されるので、COPYボタンで、埋め込み用のリンクをコピーしておく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384023/045a467a-d154-380b-34ef-6754f9fc79c3.png)

4. (Notionの操作) 引き続き、Notion側の操作にはります。埋め込みたい箇所に、以下のようにEmbedを選ぶ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384023/ccd5f25f-d6af-7b0c-eb09-95cad419d344.png)

5. (Notionの操作) 次の画面が表示されるので、draw.ioで取ったリンクをEmbed linkの欄にペーストして、Embed linkのボタンをクリックすると完成です。

# 結果纏め
* この記事は、draw.ioの複数ページからある１ページの図面をNotionに埋め込める方法を説明した。最終的にできた感じは、下記の図のようになりました。（本文終了）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384023/3c1be119-dce4-decc-5d1d-29283e2ec619.png)
Reactに漬かっていた私がVue3に挑戦して感じたこと


# Vue3に挑戦したきっかけ
タイトルでも書いた通り、これまでメインで使っていたのはReactだったのですが、
そんな中、新卒1年目に勉強の一環で作ったjQueryのシステムを新しくすることになりました。
何を使っても良いという状況だったので、何で作り直すか考えてみたところ、

- 今回はReact以外のものに挑戦してみたい
- ドキュメントが分かりやすそう
- ググったら参考になるものが沢山出てきそう
- TypeScriptに対応している

という4点から、Vueに挑戦することにしました。
ちょうど、Vue3が出たタイミングで、
TypeScriptの対応も手厚くなっているという話だったので、
「よしこれはいっちょ使ってみるか…！！」という思いもあり、決意。

一通り、開発も終わったので、Reactと比較して感じたVueの感触を以下にまとめていきたいと思います。

#Vueの良かった点
## 1.HTML/CSS/Javascriptを1つのファイルにまるっとかける
Reactだと、CSSファイルは別置きが基本となっているのに対し、
Vueでは、1つののファイルにCSSも含めて書くことができます。
自分で書いたクラス名を確認するにも、1つのファイル内で確認できるので見やすいですね。

CSSメタ言語(scssやless等)の導入も

```vuejs:CSSメタ言語導入
<style lang="scss">
...
</style>
```

で済んでしまうのも良き点です。

## 2.ルートに複数の要素を置ける

これはVue3で新しくなったポイントらしいです。

```vuejs:ルートに複数の要素を置ける
<template>
  <header>...</header>
  <main>...</main>
  <footer>...</footer>
</template>
```

これまでだと、div等でラップしなければいけなかったところが、
上の書き方でも通るようになり、書く必要がなくなりました。

~~Reactだと、divでのラップが必要になってくるので、比較すると無駄な要素がなくて良いです。~~
Reactでも、同様に書けるようです！(コメントでご指摘くださった@Munchkinさんありがとうございます！)
(勉強不足でしたが、おかげでReactのが好きだなぁという最後の結論を強めることとなりました…笑)

> [正式リリース前に総予習!! Vue3の変更点まとめ](https://qiita.com/ryo2132/items/3d0379e85c38a9a5b355)

## 3.reactiveな値(Reactでいうところのstate)の定義が楽

Reactと比較すると、リアクティブな値の書き方についてはVueの方が間違いなく簡潔です。
まずはReact。

```react:Reactでのstateの定義
const [loading, setLoading] = useState<boolean>(true);
```

次にVue。

```javascript:Vueでのリアクティブな値の定義
const loading = ref(true);
```

一目瞭然ですね。
Vueだと、値を更新するための関数を一緒に定義する必要がないので、簡潔に書くことができています。
また、型定義についても同様で、
わざわざ明示せずとも、Booleanであることを判断してくれます。
ちなみに、Vueで値を更新したいときは

```javascript:Vueでのリアクティブな値の更新
loading.value = false;
```

これで済みます。めっちゃ楽。

#Vueのあんまりな点
## 1.templateタグ内で使いたい関数や変数をreturnしないと使えない

```javascript:returnしないとtemplateタグ内で使えない
  setup() {
    const loading = ref(true);
    // returnの中にloadingを含めないと、templateタグ内で使えない
    return { loading }
  }
```
上記の通り、一度定義した変数(もしくは関数)はreturnしないと、templateタグの中で使えません。
Reactだと一度定義した変数については、特にreturnする必要もなく、jsxの中ですぐに使えます。

## 2.templateタグ内で型が効かない

例えば、以下のようにbookオブジェクトを定義します。

```javascript:オブジェクトの定義
  setup() {
    const book = {
        title : 'aaa',
        author : 'bbb',
    };
    return { book };
  }
```

それを下記のようにtemplateタグ内で使おうとすると、

```vuejs:templateタグ内で型が効かない
<template>
  <div> { book. } </div>
</template>
```
`book.`とかいた段階で、
`title`と`author`がサジェストされてきてほしいところ
これが出てこないです。
悲しい…。
Reactだと、この悩みが一切なかったので、やはりTypeScriptとの相性はReactの方が良さそうだなぁと感じました。

## 3.拡張機能を入れていても補完がいまいち(な気がした)

VScodeを使って開発していたのですが、
Reactで開発を進めていた時には気にならなかった補完が、
Vueだとしっくりこない感じがしたというかなりふわっとした、いまいちポイントです。
(言語化できないことを入れるなというクレームが出てきそうですが、一個人の意見ですのでお許し下さい...)
ちなみにですが、拡張機能はveturを入れていました。

# ReactとVueを比較してみた結果
個人的には、Reactの方が良いなぁという結論。
特に補完とtypescriptとの相性が気になりました。
Vueで良い点として挙げた部分が、「それがないと生きていけないんだ…！」となるくらいのポイントではなかったからというのもありますかね。


# 次の投稿では...
ReactとVueの対応表なんて作れたら良いなと思いました。
忘れない内に投稿できるよう頑張ります。

最後まで読んでくださった方々ありがとうございました。
[Ruby]print,puts,p,printf メソッドの違い

# はじめに
Ruby初学者です。
本記事はコンソール画面に文字を出力できるprint, puts, p ,printf の違いについて解説したものです。

## 使い方

#### 1. printメソッド
printは以下のように改行を入れずに引数に指定した値を出力します

```
print 'おはようございます'
print '僕の名前は'
print '太郎です'

# 実行結果
おはようございます僕の名前は太郎です
```

#### 2. putsメソッド
putsメソッドは末尾に改行が入り出力されます

```
puts 'おはようございます'
puts '僕の名前は'
puts '太郎です'

# 実行結果
おはようございます
僕の名前は
太郎です
```

#### 3. pメソッド
pメソッドは型情報を一緒に出力します。

```
p '明日の降水確率は'
p 50
p '%です'

# 実行結果
'明日の降水確率は'
50
'%です'
```
数字はそのまま出力され、文字列は`""`で囲まれていることがわかります。

#### 4. printfメソッド
printfは以下のような形式で入力します。
`printf( "フォーマット", 表示させたい値 )`

```
printf('僕の名前は %s %d 歳です', '太郎', 30)

# 実行結果
僕の名前は 太郎 30 歳です
```
[受託開発]開発者が未経験のプログラミング言語を扱う際に注意すべきこと

ここでは、受託開発の現場で、
開発者が未経験のプログラミング言語を扱う際に注意すべきことを記載します。
プロマネの観点と開発者の観点、それぞれで注意すべきことも併せて説明します。

僕は現在、プロマネを中心に仕事をしており、開発現場で日々発生する課題やリスクの対応を行っています。実際に、開発現場が技術的なトラブルで進捗が止まっている場合、僕自身がプログラミングをすることも度々あります。(プログラミングが好きということもありますが)

その経験をここで共有できればと思います。

なお、純粋に効率的なプログラミングの始め方について知りたい方は、こちらが参考になります:
[プログラミングを始めたいけど、始め方が分からないあなたへ](https://kennyshroff.com/it/dev/how-to-start-programming/)


# 受託開発における、経験者不在のプログラミング言語で開発する危険性

受託開発では、開発案件を受注する前に、開発規模を見積もります。
この見積もりに基づき、スケジュールが組み立てられ、いつまでに納品できるかが決まります。
    
この方法がうまくいくのは、開発経験のあるプログラミング言語が見積もりのベースにある場合です。
開発経験のないプログラミング言語をベースにした見積もりやスケジューリングの場合、経験上、うまくいかないことが多い様に感じます。(過去には、見積もり額の10倍のコストがかかったことも・・・笑)

## 開発が始まる前に取れる行動

ではどうするのか。
    
使い慣れたプログラミング言語をベースとした見積もり根拠の場合、プロジェクトが炎上するのは、ほぼ間違いなしです(涙)。

見積もりがお客様に飛んでいく前に、プロマネ側と開発者側、それぞれで取れる行動があると思います。

### プロマネ側で取れる行動

- 開発言語を変える
      そもそも、経験者が多いプログラミング言語での開発にできないか調整する。
      お客様からのリクエストであれば、お客様・開発・営業・品質管理などを巻き込む。
      また、お客様に、このまま受注した場合のリスクを説明する。
      また、リスクが顕在化した場合の追加費用の負担元を予め調整しておく。

- 見積もり工数を増やす
      開発工数を見積もる時、必ずリスク分を上乗せします。
      このリスク分を見積もり総工数の1.5倍や2倍にする。期間も2倍に延長できるのであれば、延ばす。

- 経験者にプロジェクト参画してもらう
      協力会社様に経験者を派遣してもらうか、期間に余裕があれば、経験者を採用して、プロジェクトに参画してもらう。


### 開発者側で取れる行動

- 開発言語を変える
      プロマネ側同様、開発側も、開発言語を変える様に動く。
      お客様からのリクエストであれば、お客様との調整にも積極的に参画する。

- プログラミング言語を短期間で習得する
      会社の予算で、プログラミング言語を学べるスクールに通う、また、
      書籍を購入して、独学。
      
- 該当のプログラミング言語で組まれたオープンソース製品をまねる
      既に該当のプログラミング言語で組まれたアプリのソースが公開されているのであれば、
      そこから学ぶ。

# それでも開発が始まる場合(涙)

残念ながら、未経験のプログラミング言語で開発が始まる場合、
プロマネ側・開発側の双方でリスクを明確にしておき、ステークホルダ(特にお客様)に
リスクを十分に理解しておいてもらいましょう。
    
また、定期的にお客様との定例会でリスクの分析状況を報告し、リスクが顕在化した場合は、ステークホルダと調整できる様にしておきます(要は、開発側だけで抱え込まない様にする、責任の所在を明確にしておく)

以上、受託開発の現場で、開発者が未経験のプログラミング言語を扱う際に注意すべきことを記載しました。少しでも同じ状況に遭遇する方の手助けになればと思います。

なお、繰り返しになりますが、純粋に効率的なプログラミングの始め方について知りたい方は、こちらが参考になります:
[プログラミングを始めたいけど、始め方が分からないあなたへ](https://kennyshroff.com/it/dev/how-to-start-programming/)
Ubuntu 20.04 LTS (Amazon EC2)に最新のNginxをインストールする

ざっくりAmazon EC2でUbuntuを選択したときに最新のNginxをインストールできない問題を解決する方法をまとめました。Linuxそこまで触ったことなくてもいける感じに解説を入れているので、最後まで見て試していただけると幸いです。

## 環境

- Ubuntu 20.04 LTS (Amazon EC2)


## 方法

### 初手

sudo打ちまくりは面倒なので、環境構築の時は権限変更しといた方がいいと思います。(今回のはどれもsudo使います)

```
$ sudo su -
$ apt update && apt upgrade
```

### 初期段階でパッケージ確認

以下のコマンドで、今`apt install nginx`と入力すると何がインストールできるか確認します。

```
$ apt show nginx

Package: nginx
Version: 1.18.0-0ubuntu1.2
Priority: optional
Section: web
Origin: Ubuntu
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Original-Maintainer: Debian Nginx Maintainers <pkg-nginx-maintainers@lists.alioth.debian.org>
(以下略)
```

見ての通り、Nginx1.18.0しかインストールできない状態です。2021年6月現在安定版の最新バージョンは1.20.1なので、これをインストールできるように設定していきます。


### NginxのPGPキーを取得

Nginxをインストールするのに必要なPGPキーを取得します。(wget行うときは基本`/tmp`か`/var/tmp`へ移動しましょう。どっちに行くかは宗派があるのでお任せします)

```
$ cd /tmp
$ wget https://nginx.org/keys/nginx_signing.key
$ apt-key add nginx_signing.key
```

Nginx公式リポジトリの署名確認を行える状態になりました。これでインストール時のエラーを解消できます。


### Nginx公式リポジトリの登録

[Nginx公式ページ](https://www.nginx.com/resources/wiki/start/topics/tutorials/install/#official-debian-ubuntu-packages)にあるやり方の通りにファイルを作成します。今回使用するUbuntu 20.04 LTSでは`focal`を使用してください。

```
$ cd /etc/apt/sources.list.d/
$ vi nginx.list  <- 新規作成。名前は何でもいいです。
```

```/etc/apt/sources.list.d/nginx.list
deb https://nginx.org/packages/ubuntu/ focal nginx
deb-src https://nginx.org/packages/ubuntu/ focal nginx
```

リストファイルを保存したら再読み込みします。

```
$ apt update
```

ここまで出来たら、始めと同じコマンドを使用してどのバージョンがインストールできる状態か確認します。

```
$ apt show nginx

Package: nginx
Version: 1.20.1-1~focal
Priority: optional
Section: httpd
Maintainer: NGINX Packaging <nginx-packaging@f5.com>
```

これでaptコマンドで最新版のNginxをインストールできる状態まで持って行けたので、いつも通りのインストールを行います。

```
$ apt install nginx
```

### サービス起動

この段階ではまだ起動できていない状態なので、サービス起動の設定をしていきます。

```
$ systemctl enable nginx     <- nginxサービスの自動起動設定
$ systemctl daemon-reload    <- 設定ファイルの再読込
$ systemctl start nginx      <- サービス起動
```

これでEC2のパブリックIPにアクセスすればNginxの画面が出てくると思います。

![2021_06_17_01_35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1033462/1903c898-fc25-6417-0f26-d17a226ca782.png)

お疲れさまでした！

## 参考

- [Install | NGINX](https://www.nginx.com/resources/wiki/start/topics/tutorials/install/)
C#のWebBrowserコントロールでマウスの戻る・進むボタンに対応する

#はじめに

Windows Forms上でウェブページを表示するためのコントロールとしてSystem.Windows.Forms.WebBrowserクラスが標準で用意されています。
しかし、なぜか5ボタンマウスに付いている「戻るボタン」「進むボタン」を押してもページが切り替わりません。
WebBrowserコントロールでマウスの戻る・進むボタンに対応させる方法を紹介します。

#対処方法
WebBrowserクラスは、MouseDownイベントによるイベントハンドリングができない。そのためMouseEventArgsのButtonプロパティの値がMouseButtons.XButton1とMouseButtons.XButton2であるかどうかで判定する方法は使えない。その代わりにウィンドウメッセージを捕捉することにする。

WebBrowser上でマウスの「戻るボタン」「進むボタン」が押されるとWM_APPCOMMANDメッセージが発生する。そこでWebBrowserクラスを継承し、WndProcメソッドをオーバーライドしてWM_APPCOMMANDメッセージを捕捉することで「戻るボタン」「進むボタン」が押されたことを検知できる。

さらに押されたボタンの種類を調べるためにm.LParamからGET_APPCOMMAND_LPARAMメソッドによって押されたボタンの種類を演算して求める。

```cs
	public class WebBrowserEx : System.Windows.Forms.WebBrowser
	{
		const short BROWSER_BACKWARD = 1;
		const short BROWSER_FORWARD = 2;
		const int WM_APPCOMMAND = 793;
		protected override void WndProc(ref Message m)
		{
			if (m.Msg == WM_APPCOMMAND)
			{
				switch (GET_APPCOMMAND_LPARAM(m.LParam))
				{
					case BROWSER_BACKWARD:
						GoBack();
						return;
					case BROWSER_FORWARD:
						GoForward();
						return;
				}
			}
			base.WndProc(ref m);
		}
		private int GET_APPCOMMAND_LPARAM(IntPtr lParam)
		{
			return (int)(lParam.ToInt64() >> 16) & 0xFFF;
		}
	}
```

あとは、WebBrowserクラスをWebBrowserExクラスに置き換えてインスタンスを作成すれば、戻る・進むボタンの操作に応じてウェブブラウザ内のページが切り替わる。

# WebView2では標準で対応
新しいEdgeに準拠したWebView2では、「戻るボタン」「進むボタン」に対応しているので、最新のWeb標準にも準拠しているWebView2を今後は使うべきだと思います。

https://docs.microsoft.com/ja-jp/microsoft-edge/webview2/
各種出力


## 各種IDの出力


```
HUB ID
hub_id:{{ hub_id }}

ページID
content_id: {{ content_id }}

ブログID
group.id：{{ group.id }}
```

## ページ情報

```
タイトル
content.name: {{ content.name }}

ディスクリプション
content.meta_description: {{ content.meta_description }}

URL
content.absolute_url: {{ content.absolute_url }}

投稿日
content.publish_date: {{ content.publish_date }}

更新日
content.updated: {{ content.updated }}

アイキャッチ
content.post_list_summary_featured_image: {{ content.post_list_summary_featured_image }}

アイキャッチ
content.featured_image: {{ content.featured_image }}

著者
content.author_name: {{ content.author_name }}


```


## ブログ情報

```
ブログURL
group.absolute_url: {{ group.absolute_url }}

ブログタイトル
group.public_title: {{ group.public_title }}

アナリティクスコード
hubspot_analytics_tracking_code:{{ hubspot_analytics_tracking_code }}


```
配列型ループ（forEach）+ await

こんにちは。
配列型オブジェクト（下記）に対して指定関数の```forEach```ループ実行を行いました[^1]。

* 配列（array）
* 配列型（array-like）
* 反復可能型（iterable）

```javascript
[...array_like].forEach(doFunc);
Array.from(array_like).forEach(doFunc);
for (const e of array_like) {doFunc(e)};
```

#### await 動作としたい場合

ただしループ内で個々を```await```動作としたい場合は下記のようにするとのことです[^2]（```forEach```は使わずに）。


* ```reduce```利用
* ```for ( of )```利用

```javascript
array_like.reduce(async (p, e) => {
  await p || await wait();
  doFunc(e);
}, 0);

(async () => {
  for (const e of array_like) {
    await wait();
    doFunc(e);
  }
})();

// const wait = () => new Promise(resolve => setTimeout(resolve, 0));
```


[^1]: \ ```forEach```は配列を対象としますので、そうではない配列型オブジェクトに対しては、```array_like.forEach(doFunc)```とは書けません。

[^2]: 参考：「[async/awaitを、Array.prototype.forEachで使う際の注意点、という話](https://qiita.com/frameair/items/e7645066075666a13063)」
マイグレーション主なコマンド【rails】

##記事の概要
>rails初学者の自分用に、マイグレーションに関する主なコマンド操作をまとめました。
同じく初学者の誰かのお役に立てたら幸いです。



##主なコマンド一覧

```:①最新までマイグレーションを適用する
rails db:migrate
```

```:②どこまでマイグレーションが適用されているか確認する
rails db:migrate:status
```
```:③特定のバージョンまでマイグレーションが適用された状態にする
rails db:migrate VERSION=○○○ 
#○○○にはマイグレーションファイル名頭についている数字（日時）の部分を指定する
```
```:④バージョンを一つ戻す
rails db:rollback
```
```:⑤バージョンを指定したステップ数まで戻す
rails db:rollback STEP=○
#○は戻したい数
```
```:⑥バージョンを1つ戻してから1つあげる
rails db:migrate:redo
```

###補足
>⑥のdb:migrate:redoコマンドは、ロールバックと再マイグレーションを一度に実行できるショートカットみたいです。
複数バージョンに対してこれを行いたい場合は、db:rollbackコマンドの場合と同様にSTEPパラメータを指定することもできる。（らしいけど自分はまだ試したことがあるません）。

###参考
・https://railsguides.jp/active_record_migrations.html
・『現場で使えるRuby on Rails5速習実践ガイド』