OmniAICreator/Qiita-1.07M huggingface dataset:
同期処理・非同期処理の違いを例を交えて解説してみた。

##前書き
同期処理や非同期処理の概要をまとめてみました。
コールバック関数、Promise、async / awaitなど今後まとめていきたいと思います。
##同期処理・非同期処理の説明の前に
###PCの計算時間について

|例 |時間  |
|---|---|
|CPUの1サイクル|およそ0.3ナノ秒|
|Floatの足し算|1.2ナノ秒 |
|メモリのデータを参照する速さ|120ナノ秒|
|SSDからのデータの読み取り|100マイクロ秒（マイクロ秒はナノ秒の1000倍） |
|日本からシリコンバレにインターネットでやりとりする時間|100ミリ秒（ミリ秒はマイクロ秒の1000倍）|

####CPUの1サイクルを1秒とした場合

|例 |時間  |
|---|---|
|CPUの1サイクル|1秒|
|Floatの足し算|4秒 |
|メモリのデータを参照する速さ|6分|
|SSDからのデータの読み取り|4日
|日本からシリコンバレーにインターネットでやりとりする時間|およそ10年|


CPUで計算したり、メモリからデータを参照する事と比べて、インターネットを通じてデータを取得するというのは**ものすごく時間がかかる事が分かります**。

##同期処理とは
コードを順番に処理していき、ひとつの処理が終わるまで次の処理は行わない処理の事です。
どんなに時間のかかる処理を行っていたとしても、**同期処理の場合はその処理が終わるまで待ちます。**

二つ例を出してみます。
####ネットワーク通信の場合
同期処理でネットワーク通信を行った場合、時間のかかるインターネット通信が終わってからじゃないと次の処理を行うことができません。
CPUの1サイクルを1秒とした場合、ネットワーク通信は10年かかります。
その間に色々計算できそうですが、10年後にならないと他の処理ができないのでリソース的に勿体無いですよね。

####人間世界の場合
人間世界を例として以下のことをしたいとします。

- お風呂に入る ->自分
- 食洗機で食器を洗う ->食洗機
- 食器を片付ける ->自分

![スクリーンショット 2021-05-04 17.16.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1185431/8fd7d176-2773-8fbf-0c80-fc308505d45f.png)

同期処理の場合だと自分がお風呂に入り終わったら食洗機で食器を洗い、洗い終わったら自分が干すという処理になります。
これだと食洗機が皿を洗ってる間に**自分というリソースは使用されず放置状態になります。**

##非同期処理とは
処理が終わるのを待たずに、**同時に複数の処理を実行することができます。**
誰かに仕事をお願いする事で、自分は他の仕事を進める事ができる仕組みです。
その結果、複数処理を実行する事ができます。
先ほど例にあげたネット通信も非同期で行った場合、ネット通信の結果を待たず、CPUの計算も行う事ができます。

人間世界の例も同様です。
![スクリーンショット 2021-05-04 17.24.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1185431/83df265c-15d4-921a-5c05-45da79e75def.png)
食洗機に頑張って食器を洗ってもらう間に自分はお風呂に入ってしまいます。
結果として同期処理より早く処理を終える事ができます。
このように非同期処理では**誰かに仕事をお願いすることで自分は別の作業を進める事ができ、結果として同時に複数の処理を行う事ができます。**


##参考
<iframe width="560" height="315" src="https://www.youtube.com/embed/OBqj4I5NAEg" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
AWS 学習メモ

この記事はAWS初学者を導く体系的な動画学習サービス
「AWS CloudTech」の課題カリキュラムで作成しました。
https://aws-cloud-tech.com


# メモ 課題1
ごく個人的にメモを作成、体系的に全て説明するためのものではなく、実践の中で気になったポイントだけをまとめています。

### vpc
Virtual Private Cloud
AWSの格サービスへのアクセス制御をする場合に、サブネット単位で役割を分けてルーティングによってアクセス制御が可能になる。
設計するシステム要件によってサービスを選択、まずサブネット構成とセキュリティグループを考えるのが良さげ？

### ebs
Elastic Block Store
EC2作成時に一緒に作るEBSについてはデフォルトで、インスタンスの終了時に同時に削除になるが
後から作成して既存EC2にアタッチする場合、作成時のオプションに項目が存在しなさげ。

#### デバイスのマウント
Linuxでの外部ハードウェアの取り付け操作に関して
⇨参考：https://eng-entrance.com/linux-mount
仮想システムなのでコマンドだけ打ってるとどうも最初はピンとこないが、単純にHDDを増設する際にシステムに認識させるのにはこのような手順が必要になる。ただそれだけ。
そういえば昔windowsでも外付けのUSBメモリなんかでも結構気を使ってた気がするけど最近はOSが手厚くサポートしてくれるおかげで全く意識しなくなってたやつ。

#### ファイルシステムのフォーマット
これもつまり、普通のHDDと同じように適当なフォーマットしてからじゃないとファイルシステムとして使えないよ、ってだけ。
⇨参考：https://eng-entrance.com/linux-make-filesystem

### EC2
Elastic Compute Cloud
サーバーマシンそのもの
#### インスタンス
インスタンスが指すものは、ユーザーがAMI（Amazon Machin Image)から作成した仮想サーバーのことではない。
選択可能なAMIひとつひとつをインスタンスという。イメージファイル＝インスタンス。

#### パブリックIP
インスタンスを停止するごとに新しく割り当てられる。
通常パブリックアクセス可能なサービスを作る場合、そんなのは困るはずなので基本的にEIPを作って割り当てるものと思っていればいいはず。
また、DBなど接続他のシステムがIPを記録していてチェックが入る場合システムの動作に問題が出る場合がある。（WordPressなど)

### IAM
Identity and Access Management
#### ベストプラクティス
⇨参考：[公式](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/best-practices.html)

* ルートユーザーは使わない
* 個別にIAMユーザーを作成してアクセスする
* IAMユーザーをグループ分けする
* 権限は最小限に
* パスワードの定期更新やMFA利用を割り当てて個々のセキュリティを強化する
* ロールによって権限を管理し、ロールの委任権限を設定する
* アクセスキー厳重管理、公開、ダメ、絶対！
* IAMの監視と見直しを継続する

ややこしい用語と概念、**多分一番重要。**
⇨参考：[公式](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_roles_terms-and-concepts.html)

### RDS
Relational Database Service
パスワード自動生成
⇨RDS生成後に表示されるのでメモすればOK
　手動でDBアクセスする際に必要になる。

リードレプリケーションの構成を作るため、複数のAZに跨ったサブネットグループを作成する必要がある。
その際、エンドポイント接続（要は端末個別のパブリックIPではなく、サブネットグループに跨ったDBの集合をひとまとまりのエンドポイントとして扱い、稼働状態に応じてメインサブを動的に繋ぎかえることができる）するために、端末個別のIPではなくエンドポイントを接続設定に使う。（RDS作成時のデフォルトはIPが入っている）

# 遭遇したトラブル
### 問題
EC2インスタンスを reboot したあと ステータスチェック が1/2となりアクセスできなくなった。
SSH接続をしようとするとタイムアウトしてしまう。

### 結論
解決方法、原因不明、EC2インスタンス再作成。
ログをもっときちんと見れば分かったのかも。

### 試したこと
インスタンスの停止⇨起動
⇨参考：[公式](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/TroubleshootingInstances.html)
【初学者による】だからサーバってなんやねん Apache,Nginx,Unicorn,Puma ...

Railsアプリケーションのデプロイ方法を調べていると、
やれWebサーバが～
やれアプリケーションサーバが～
と、とにかくうるさい。
Apach？Nginx？Unicorn？Puma？
ズブの素人にも分かるように説明してくれや、とイライラしたので初学者の目線で簡単に説明。

# WEBサーバとは？
WEBサイトの利用者(クライアント)から送られてくる情報(リクエスト)に対して情報(レスポンス)を返してくれる奴。

例えば、私たちがPCからTwitterで他の人のツイートを見ようとすると、ブラウザ（WEBクライアント）からリクエストを出して、それに対してWEBサーバがツイートを取得してレスポンスを返してくれることによって表示されてるよ。
ちょっと細かく言うとリクエストはHTTPとかHTTPSという形式（プロトコル）で、GETというHTTPリクエストを出す。
同様に、自分でツイートするときにはPOST、削除するときにはDELETEなど
いろいろなかたちでリクエストを出すぞ。

```
このWEBサーバー界の二大巨頭が、NginxさんとApacheさん
```

# アプリケーションサーバ（APサーバ）とは？
Webサーバからもらったリクエストを、プログラミング言語を実行して処理する奴。
処理後、その結果をまたWebサーバへ返えす。
プログラミング言語によってアプリケーションサーバが異なるぞ。

NginxとかPumaとかUnicornアプリケーションを動かそうと思うと、主にPumaがレスポンスを返しているぞ。

```
APサーバの有名人
Rails　＝　Puma / Unicorn
Java　＝　Apache Tomcat
```
ちなみにPHPはAPサーバを使う必要がないらしい。スゲー！
参考：https://qiita.com/andrew954/items/2fa78e9f7f83bd8cb9ac

なおPumaもApache Tomcatも簡易的なWebサーバ機能がついてるけど、
大きな負荷には耐えられないから本番環境には使えないぞ。


##### 静的なサイトならWEBサーバだけでも作れるよ
HTMLとか画像を表示するだけの静的なサイトならWEBサーバだけでも作れる。
ただプログラミング言語を使ってPOSTだとかDELETEだとかの機能をつけるとAPサーバも必要になるぞ
Streamlit Docker on Heroku 

#TL;DR
[公式のデプロイドキュメント](https://discuss.streamlit.io/t/streamlit-deployment-guide-wiki/5099)に色々載っているのでその通りにやりましょう

# やったこと
- streamlitのお触り
- streamlit on docker
- Herokuへのデプロイ

## Streamlitとは
pythonだけで簡単にアプリケーションを作れるフレームワーク。フロントエンドの知識なくてもオッケー。
インタラクティブな機能はもちろん、matplotlib、plotly、bokehなど一通り可視化ツールのサポートをしてるので、可視化結果を見せるのが非常に楽。
※Dashとかも似たようなものらしいですが、Streamlitはより単純に、素早く書けるのがメリットのようです。その分柔軟性は低い？とか（比較検証はしてません）

## できたもの
NBAのスタッツ（2018~19）とサラリー（2019~2020）を可視化。
こんな感じで見れる。
![ezgif.com-gif-maker.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278943/bfaed3db-9814-4ecb-7650-37a16a316a11.gif)

アプリはここにあります
https://demo-lit-app.herokuapp.com/

コードはこっち
https://github.com/iusami/demo-streamlit-heroku

## 未解決の話
- cache機能があるのでそれで`plot`部分を高速化できないかなと思ったが、エラーが出て上手く動作しなかった。
    - ページの遷移を行うために`_SessionState`を使ってるので単純にはキャッシュできないっぽい。
- データをコンテナに込めてしまっているが、ほんとはどこかからダウンロードするようにしたい。（データサーバを用意するのがめんどくさかった。）

## 今後やってみたいこと
- 機械学習使ったインタラクティブなアプリを作れそう。パラメータ変更、学習、推論までおそらく全部実装できる。


## 参考文献
- https://docs.streamlit.io/en/stable/index.html
- https://discuss.streamlit.io/t/streamlit-deployment-guide-wiki/5099
- https://github.com/ash2shukla/streamlit-heroku
GitHub ActionsでCloud Foundry（IBM Cloud）のデプロイを行う


前に書いたようにCloud Foundryのデプロイが遅すぎるのでGitHub ActionsでCIデプロイをすることにしました。

> [Cloud Foundry（IBM Cloud）にDiscord BOTをデプロイしようとした際にハマったメモ](https://qiita.com/n0bisuke/items/d61912cccfac21447650)

## ibmcloud CLIをインストールしてpushコマンドまで

`cf push`までの流れをまとめるとこんな感じです。

> [IBM CloudでNode.jsアプリケーションをデプロイするまでの流れ](https://qiita.com/n0bisuke/items/4c29aad3696edcc627f2)

* ibmcloudとcfプラグインのインストール

```bash
$ curl -fsSL https://clis.cloud.ibm.com/install/linux | sh
$ ibmcloud cf install
```

* ログインとpush

```bash
$ ibmcloud login -u USERNAME -p PASSWORD -r リージョン
$ ibmcloud target --cf
$ ibmcloud cf push
```

`ibmcloud login -sso`とするとブラウザ経由でワンタイムパスを入れたり、リージョンをコマンド入力待ちになるためCI利用はしにくいですが、-u / -p / -rなどを指定して実行することでCIでも利用できます。

## GitHub Actionsのログをマスクする

パスワードなどはシークレットに登録すれば良いですが、ログにIDなどが表示されます。
ログを一部表示にします。

```yml
    - name: add-mask
      run: |
        echo "::add-mask::${{ secrets.IBMCLOUD_TEST }}"
        echo "::add-mask::${{ secrets.IBMCLOUD_USER_ID }}"
        echo "::add-mask::${{ secrets.IBMCLOUD_USER_PASS }}"
        echo "::add-mask::${{ secrets.IBMCLOUD_USER_ACCOUNT_ID }}"
        echo "::add-mask::${{ secrets.IBMCLOUD_USER_NAME }}"
```

[GitHub Actionsのログをマスクするメモ](https://qiita.com/n0bisuke/items/fcaf38b26f84dc6898d3)の記事にまとめました。

## yml全体

```node.js.yml
name: Node.js CI

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  build:

    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [15.x]
        # See supported Node.js release schedule at https://nodejs.org/en/about/releases/

    steps:
    - uses: actions/checkout@v2

    - name: add-mask
      run: |
        echo "::add-mask::${{ secrets.IBMCLOUD_TEST }}"
        echo "::add-mask::${{ secrets.IBMCLOUD_USER_ID }}"
        echo "::add-mask::${{ secrets.IBMCLOUD_USER_PASS }}"
        echo "::add-mask::${{ secrets.IBMCLOUD_USER_ACCOUNT_ID }}"
        echo "::add-mask::${{ secrets.IBMCLOUD_USER_NAME }}"        

    - name: ibmcloud cli install
      run: |
        curl -fsSL https://clis.cloud.ibm.com/install/linux | sh
        ibmcloud cf install
            
    - name: ibmclound login
      run: ibmcloud login -u ${{ secrets.IBMCLOUD_USER_ID }} -p ${{ secrets.IBMCLOUD_USER_PASS }} -r us-south

    - name: ibmclound target --cf
      run: ibmcloud target --cf
    
    - name: ibmclound cf push
      run: ibmcloud cf push

    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v2
      with:
        node-version: ${{ matrix.node-version }}
    - run: npm install && npm start
```

これでGitHubにPush後にCI側でIBM Cloudにデプロイしてくれるようになりました。
Python | range() vs np.arange() 

###range(start, stop[, step]) -> range object
```
>>> range(0,5) 			 	
range(0, 5)   
>>> c = [i for i in range(0,5,2)] 	 
>>> c
[0, 2, 4]
```
###arange([start,] stop[, step,], dtype=None) -> ndarray
```
>>> np.arange(3,7,2)
    array([3, 5])
```
[SQL] LeetCodeの無料問題集を活用して、SQLを使いこなし（5）

#181 Employees Earning More Than Their Managers
![Q181.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1082021/42fb707b-0a54-9add-f4a6-1e3b0b953b47.png)

##質問
Employeeテーブルは、従業員のID、給料と彼らのマネージャーIDを含まれています。
Employeeで給料はマネージャーより高い従業員を探します。

##Code
```SQL
SELECT a.NAME as Employee
FROM Employee a
LEFT JOIN Employee b
ON a.ManagerID=b.ID
WHERE a.Salary>b.Salary
```

##Result
![Q181_result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1082021/b210a8ad-4e6a-b04d-5ff9-34b38d39440b.png)
もし事業責任者がデータ分析のために『SQL』を学んだら（第一章）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280581/ed3e3891-3e47-23f2-cdb0-395aef8f813e.png)


## これはなに
* SQLを学ぶ過程で、知識として定着したいことをQiitaにまとめて行こうと思います
* 僕と同じようにSQLをこれから学ぼうとしている人、学び始めた人にとって有益な情報になれば幸いです


## SQLを学ぼうと思ったきっかけ
* エンジニアに依頼せずに、自分でデータを抽出し、分析したいと思ったからです
    * 仮設を立証、ないしは検証するためにデータを分析したい、実施した施策の効果測定のためにデータを見たいと思うことが多々あります
    * その目的を持っている人自身がやり遂げることは仕事の生産性を高めると考えています
        * 部分的な依頼は目的を見失いやすく、かといって目的を丁寧に共有してまで実施する仕事かと言えば、そうではないかもしれません
* 責任者である自分がサボらずに生産性を高める努力をすることが、メンバーにも波及すると信じているから
    * やはり責任者の振る舞いは少なからず組織に影響すると考えています
    * その人間が経験だけで仕事をし、新たな勉強をしないと、組織にもその状況が蔓延してしまうのではないか
    * メンバーに成長や努力を求める前に、自分が先頭に立って求める振る舞いを実行する
        * やってみせ　言って聞かせて　させてみて　誉めてやらねば　人は動かじ

## 学びのゴール
* サービスの現状を知りたいと思ったときに、データを抽出出来る
    * 「今の会員全体の属性データを見たい」が実現できる
* あの施策はうまくいったのか？と思ったときに、データを抽出出来る
    * 「あの施策を実施する前と後で、WAUの人数がどう変わったのかが見たい」が実現できる
* これはマジックナンバーになりえるんじゃないか？と思ったときに、データを抽出出来る
    * 「この数値が○以上だと、ユーザーはアクティブになるのでは？見てみたい」が実現できる

ということで、少しずつですが学んでいきます

## 基礎用語の説明
* データベース：表の集まり

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280581/e27e4a97-a219-ec97-be17-58d81df3ee16.png)


* テーブル：表

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280581/bff30646-2233-bdcf-5546-5c249bd60223.png)


* カラム：列

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280581/8ccb533c-1268-1295-57ba-688d78f0a545.png)


* レコード：行

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280581/6546512d-8342-5c29-f929-ecccf62f8565.png)


* クエリ：SQLを実行するときにデータベースに送る命令文のこと



## データ抽出の基本クエリ

```
SELECT
    カラム名
FROM
    テーブル名
;
```

* データを抽出するときは、SELECT文を用いる
* SQLで文を書くときの基本
    * SELECT、FROMは大文字で書くことが多いが、小文字でも可
    * 文末には、セミコロンで終わる
    * 取得したいテーブル名、カラム名を書く
    * 複数のカラムを取得したい場合は複数カラム名を書き、カンマでつなぐ


## データの絞り込み

```
SELECT
    カラム名
FROM
    テーブル名
WHERE
    条件
;

```

* データを絞り込むときは、WHERE句を用いる
* 条件の書き方はたくさんあるので適宜調べるほうがいい
* カラムを全て取得したい場合は、アスタリスクを用いる
* 基本的にはご法度で、使う際はLIMITと一緒に使う（後述）
* 文字列を使う場合は、シングルクォーテーションを用いる
    * <details>
    <summary>条件の具体例</summary>
    <dl>
        <dt>何かと同じ</dt>
        <dd>`name = 'Increments株式会社' `</dd>
        <dt>大きい、小さい①</dt>
        <dd>`contribution >= 10`</dd>
        <dt>大きい、小さい②</dt>
        <dd>` created_at < '2020-09-18'`</dd>
        <dt>リストにあるかどうか</dt>
        <dd>` tag_name IN ('PHP', 'Laravel')`</dd>
        <dt>データが空かどうか①</dt>
        <dd>` contract_concluded_at IS NULL`</dd>
        <dt>データが空かどうか②</dt>
        <dd>` contract_concluded_at IS NOT NULL`</dd>
        <dt>条件を複数使いたいとき</dt>
        <dd>`contribution >= 10 AND created_at < '2020-09-18'`</dd>
    </dl>
</details>

## SQLを書くときの心構え
* どういうデータがあるか確認する
    * テーブル名とカラム名が書いてあるものの、どういう状態で保存されているかわからないことが多い
    * 最初に以下のような感じで、中身を確認してみるといい
    * `LIMIT 数字` で、数字の数だけデータを取得することができる

```
SELECT
    *
FROM
    テーブル名
LIMIT 10
;
```

* エラー文をしっかり読む
    * 例えば ` line 2:5: 'nane' cannot be resolved` と書いてある場合
    * エラーが起きているのは2行目
    * nameというものが読めないと言っている


## おまけ
社内で利用しているTreasureDataはRDBではなく列指向DBなので、使うカラムを絞ることでビッグデータに対しては高速にクエリを走らせることができる。が、逆にいうと*を使うと定数倍で検索処理が重たくなる。
なので基本的にRedashで分析したいときは * を使うのはご法度です。使うカラムだけ指定するのが望ましい。

https://qiita.com/y-ken/items/31238bd71fbc04f77c60
GitHub Actionsのログをマスクするメモ


パスワードなどはシークレットに登録すれば良いですが、ログにIDなどが表示されてしまうので非表示にします。

マスクする方法は公式ドキュメントにある[ログ中での値のマスク](https://docs.github.com/ja/actions/reference/workflow-commands-for-github-actions#masking-a-value-in-log)を見ると書いてます。

## add-maskで指定

`echo "::add-mask::HOGEHOGE"`を実行することでマスクできます。

以下のスクショはGitHub Actions上でのIBM Cloudのデプロイのログですが、パスの一部が***に書き換わってます。

> ![スクリーンショット 2021-05-04 17.34.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/fc868d71-1202-8de3-fe8d-2014495b8295.png "スクリーンショット 2021-05-04 17.34.35.png")


## シークレットを利用してマスクする

実際のところは非表示にしたい文字列自体をシークレットに登録すると思います。

`echo "::add-mask::${{ secrets.PASSWORD }}"`

といった感じで登録したシークレットの値を元にマスクできます。

```yml
    - name: add-mask
      run: |
        echo "::add-mask::${{ secrets.IBMCLOUD_TEST }}"
        echo "::add-mask::${{ secrets.IBMCLOUD_USER_ACCOUNT_ID }}"
```

> ![スクリーンショット 2021-05-04 17.27.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/76220c33-b998-49e4-4060-e428251e176b.png "スクリーンショット 2021-05-04 17.27.25.png")
Laravelのbladeで現在のURLによって条件分岐させる方法


LaravelでWebアプリを作っていると、テンプレートファイル（bladeファイル）内でURLによって条件を分岐させたいという場合があると思います。

例えばNavはすべて同じものを使いたいがURLによって表示させる項目を変えたい場合など。

方法は二つあるのでメモ用に書いておきます。


##①Request::is()

一つ目は「Request::is()」を使う方法。
()の中にドメイン後のURLを記述するだけ。

```php
@if(Request::is('users'))
        <p>hogehoge</p>
@endif
```

このようにすれば「https:://ドメイン名/uesrs」にアクセスした時にif文内の処理が表示される。

##②Request::routeIs()
こちらは()の中にルーティング名を記述するだけ。

```php
@if(Request::routeIs('users.show'))
        <p>hogehoge</p>
@endif
```
<br>
web.phpでルートに名前を付けておけば使用できます。

```php
Route::get('users', 'UsersItemController@index')->name('users.show');
```
<br>
<br>




参考記事

https://shiro-changelife.com/laravel-url-judge/
ALIASレコードについて


## 前提
Zone Apexには、CNAME設定ができない。
hoge.example.comでいうexample.comのようなサブドメインがないものをZone Apex（ネイキッドドメインともいう）。
RFCの規定で、CNAMEは他のレコードと共存できないとされているため、
最低でもNS（ネームサーバ）レコードが必要なので、CNAMEを設定することはできない。

そんなZone ApexでELBのようなものを、CNAMEで登録したい場合に、ALIASレコードというものがある。


## ALIASレコード(Route53)
* エイリアスレコードで登録することで、実際にはELBにはIPアドレスがあるので、それと紐付けることで設定している
* AWSのサービスにはELBのようにIPアドレスが自動的に変更されるものにもよしなに対応する
* 外部のDNSからはIPアドレスとして見える
* 設定自体は、コンソールからCNAMEのようにできる


### 参考
https://dev.classmethod.jp/articles/amazon-route-53-alias-records
[CDN とCNAME Apexドメインの制限 \| REDBOX Labo](https://blog.redbox.ne.jp/cdn-cname-apex.html)
[CNAME を巡る 2/3 のジレンマ - 鷲ノ巣](https://tech.blog.aerie.jp/entry/2014/09/09/162135)
【QNAP】QNAPのNASにPython環境を構築

# はじめに
自宅でQNAPを使用しているのですが、勉強がてらPythonを常時動かす環境が欲しいと思い構築してみました。
備忘録として記事を残します。

#確認環境
* QNAP：TS-230
* ファーム：4.5.3

#手順
①QNAP側でPythonをインストールする
　App Centerより、Pythonをインストール
　※おそらくApp CenterでインストールしなくてもPython2系は使用できる可能性あり
　（この確認を行った際はApp CenterでPython3系をインストールした後だったので未確認）

②QNAP側でSSH接続を許可する
　コントロールパネル→ネットワークとファイルサービス→Telnet/SSHより、「SSH接続を許可する」をチェック

③SSH接続ソフトでQNAPに接続する
　TeraTerm等の任意のソフトで接続する
　※②で許可した管理者ユーザーのみ接続可能

④接続後、以下のメニューが出てくるので、「Q」を押下する

 ```
  +-------------------------------------------------------------------------+
  |  Console Management - Main menu                                         |
  |                                                                         |
  |  1: Show network settings                                               |
  |  2: System event logs                                                   |
  |  3: Reset to factory default (password required)                        |
  |  4: Activate/ deactivate a license                                      |
  |  5: App management                                                      |
  |  6: Reboot in Rescue mode (w/o configured disk)                         |
  |  7: Reboot in Maintenance Mode                                          |
  |  Q: Quit (return to normal shell environment)                           |
  |                                                                         |
  +-------------------------------------------------------------------------+
 ```

⑤さらに確認してくるので「Y」を押下する

 ```
  +-------------------------------------------------------------------------+
  |  Main > Quit                                                            |
  |                                                                         |
  |  Are you sure you want to exit the console menu and return to normal    |
  |  shell environment? (Y/N)                                               |
  |                                                                         |
  +-------------------------------------------------------------------------+
 ```


⑥インストールされているPythonバージョンの確認コマンドを実行し、インストールされていることを確認する

 ```
python -V
 ```

#最後に
実際にスクリプトを動かす際は以下のページを参考にしてください。

[TS-220のcronでPythonスクリプトを実行](https://qiita.com/sawadyrr5/items/37c8c3eb383548732532)


#参考にしたサイト
[QNAPのNASにPython3/numpy/pandas環境を構築する](http://yasumonoe.hateblo.jp/entry/2017/03/09/163350)
JavaScript 文字列を反転させたい。結合文字とサロゲートペア対応。

文字列を反転させたい｜nona｜note
https://note.com/ttuusskk/n/n6f874b0274bd

反転させたい人は多いらしい。スジャータをタ～ジャスに変えたいとかなんとか。しらんけど。

こんなふうにやろうよね。ってことのようです。

```js
const split = require('graphemesplit'); // npm i graphemesplit

const str0 = '👨‍👩‍👧‍👦🌕の夜に𩸽食べたい'
const str1 = str0 + 'がき';
const str2 = str0 + "\u304b\u3099\u304d";

console.log(str1);  // 👨‍👩‍👧‍👦🌕の夜に𩸽食べたいがき
console.log(str2);  // 👨‍👩‍👧‍👦🌕の夜に𩸽食べたいがき

console.log(
  '👨‍👩‍👧‍👦'.length,
  '🌕'.length,
  '𩸽'.length,
  str0.length, str1.length, str2.length
); // 11 2 2 11 13 14

// NG
console.log(str1.split('').reverse().join('')); // きがいたべ食��に夜の�🁦�‍��‍��‍��
console.log(str2.split('').reverse().join('')); // ぎかいたべ食��に夜の�🁦�‍��‍��‍��

// NG
console.log([...str1].reverse().join('')); // きがいたべ食𩸽に夜の🌕👦‍👧‍👩‍👨
console.log([...str2].reverse().join('')); // ぎかいたべ食𩸽に夜の🌕👦‍👧‍👩‍👨

// better
console.log([...str1.normalize()].reverse().join('')); // きがいたべ食𩸽に夜の🌕👦‍👧‍👩‍👨
console.log([...str2.normalize()].reverse().join('')); // きがいたべ食𩸽に夜の🌕👦‍👧‍👩‍👨

// good
console.log(split(str1).reverse().join('')); // きがいたべ食𩸽に夜の🌕👨‍👩‍👧
console.log(split(str2).reverse().join('')); // きがいたべ食𩸽に夜の🌕👨‍👩‍👧‍

```

# 参考
文字列を1文字ずつ配列化（サロゲートペアを考慮） - Qiita
https://qiita.com/sounisi5011/items/aa2d747322aad4850fe7

Unicode と JavaScript の文字列について - Object.create(null)
https://susisu.hatenablog.com/entry/2017/01/25/023338

JavaScriptで絵文字とサロゲートペアと結合文字とgrapheme clusterを正しく扱うのに少し苦労した話 - Qiita
https://qiita.com/amanoese/items/68bb9999829de4323302

文字とは何か？IchigoJam絵文字対応とUnicodeの旅、結合文字対応の文字分割ライブラリJavaScript対応版公開！ #js #IchigoJam / 福野泰介の一日一創 / Create every day by Taisuke Fukuno
https://fukuno.jig.jp/2831

JavaScript における文字コードと「文字数」の数え方 | blog.jxck.io
https://blog.jxck.io/entries/2017-03-02/unicode-in-javascript.html
CentOS7 でユーザー追加から、sudo設定、SSHのrootログイン禁止までの手順

外部公開サーバーでは、sudo設定、SSHのrootログイン禁止は
セキュリティ上、必須な設定だと思われます。
恥ずかしながら、実は設定していなかった為、作業手順のまとめ

##■ユーザー追加

#####①新規ユーザー追加

~~~
# useradd -c "Guest Add User" -d /home/userA -s /bin/bash userA
~~~

useradd -c "[コメント]" -d [ホームディレクトリ] -s [シェル] [ユーザー名]
 


#####②ユーザーパスワード設定

~~~
#passwd userA
~~~

passwd [ユーザー名]


##■sudo設定

対象ユーザーを､「wheel」グループに追加

~~~
# usermod -G wheel userA
~~~
usermod -G wheel [ユーザー名]


#####｢wheel｣グループのユーザが｢sudo｣を利用できるように設定を変更

~~~
# visudo
~~~

#####↓以下の部分がコメントアウトされていなければ、コメントアウト

~~~
## Allows people in group wheel to run all commands
# %wheel ALL=(ALL) ALL
~~~

~~~
%wheel ALL=(ALL) ALL
~~~


##■SSHのrootログインを禁止

設定ファイルの変更

~~~
# vi /etc/ssh/sshd_config
~~~

↓私の環境では、38行目

~~~
LoginGraceTime 15s
#PermitRootLogin yes
#StrictModes yes
~~~

↓以下のように設定変更

~~~
PermitRootLogin no
~~~

設定ファイルの保存後､構文チェック

~~~
#sshd -t
~~~
エラーにならないことを確認

#####sshdの設定反映  ※!!ログオフした時点から、rootでログインできなくなるので注意

~~~
# systemctl restart sshd.service
~~~


#####※sshdログインユーザーは、以下のファイルで設定

#####①/etc/pam.d/sshd　の設定
```/etc/pam.d/sshd
account    required    pam_access.so  ##追加
```

#####②/etc/security/access.conf　の設定
```/etc/security/access.conf
+ : user1 : 168.192.
+ : user2 : 172.0.0.
+ : user3 : ALL    ## 全てのIP
- : ALL : ALL
```
※↑但し、私の環境では、外部からの接続時、ファイアーウォールのIP＝1つの処理になって
　　しまう事が判明、このIP制御は機能しませんでした。
　　(どの外部IPから来ても、＝ファイアーウォールのIPと処理されていました。)

####■WinSCPの追加設定
↓いざという時にWinSCPでの重要ファイルの操作が不便な為、WinSCPでも特定ユーザーで
root権限でのファイル閲覧編集を可能にする事に
[WinSCPで特定ユーザーでもroot権限でファイル閲覧編集を可能にする方法](https://qiita.com/0to9/items/08e8becfff3f8c4e3629)

----

#####参考にさせていただいたページ
https://qiita.com/Zen-GoTo-May/items/3aab7b6c76e8a857e717
https://manual.sakura.ad.jp/vps/support/security/sudo.html
https://webkaru.net/linux/ssh-prohibit-root-login/
https://cloudpack.media/1101
WSL2のapt installエラー発生時にやったこと

#はじめに
ゼロからのOS自作入門( https://book.mynavi.jp/ec/products/detail/id=121220 )の学習中に、"qemu-img create -f raw disk.img 200M" の実行でつまづいたので、エラーの内容と解決までにやったことを共有します。
#エラー内容
Ubuntuのコンソールにて、qemu-imgを実行すると、qemu-utilsのインストールをうながされる。

```sh
$ qemu-img create -f raw disk.img 200M
Command 'qemu-img' not found, but can be installed with:
sudo apt install qemu-utils
```
$ sudo apt install qemu-utils を実行すると、下記のエラーが発生しました。

```sh
Err:1 http://security.ubuntu.com/ubuntu focal-updates/main amd64 qemu-block-extra amd64 1:4.2-3ubuntu6.12
  404  Not Found [IP: 91.189.88.142 80]
Err:2 http://security.ubuntu.com/ubuntu focal-updates/main amd64 qemu-utils amd64 1:4.2-3ubuntu6.12
  404  Not Found [IP: 91.189.88.142 80]
E: Failed to fetch http://security.ubuntu.com/ubuntu/pool/main/q/qemu/qemu-block-extra_4.2-3ubuntu6.12_amd64.deb  404  Not Found [IP: 91.189.88.142 80]
E: Failed to fetch http://security.ubuntu.com/ubuntu/pool/main/q/qemu/qemu-utils_4.2-3ubuntu6.12_amd64.deb  404  Not Found [IP: 91.189.88.142 80]
E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?
```
$ sudo apt install default-jre を実行しても同様のエラーが発生し、qemu-utilsのインストールができません。
#解決までにやったこと
下記のブログを参照させていただき、apt-getの利用リポジトリを日本サーバーへ変更しました。

https://hotate-issimo.hatenablog.com/entry/2019/06/17/233000

https://qiita.com/fkshom/items/53de3a9b9278cd524099

リポジトリを変更した後、 sudo apt-get update実行後に、sudo apt install qemu-utilsを再度実行すると正常にインストールできました。
Rubyの安全参照演算子や範囲演算子についてまとめた

Railsを勉強していて、JavaやPythonでは見かけない演算子に出会したため、
見かけないものにフォーカスしてRubyの演算子をまとめました。

## 論理演算子系

### 安全参照演算子（safe navigation operator）
```Ruby
item = a&.method
```

Ruby2.3.0から使用可能になった演算子です。
「ぼっち演算子」とも呼ばれます。他の言語では「Null条件演算子」と呼ばれているようです。

変数aがnilであるとき、a.methodを通常通り実行しようとするとnilなものを呼び出そうとしてエラーになります。
このエラーを避けるためにこの演算子を使います。
挙動としては、aがnilであればnilが返され、aがnilでなければa.methodが実行されその結果が返されます。

## 範囲演算子
```Ruby
(1..5).to_a     #=> [1, 2, 3, 4, 5]
(1...5).to_a    #=> [1, 2, 3, 4]
```

Rangeオブジェクトを省略する形で実装されているのが範囲演算子です。
Rangeオブジェクトでは、Range.new(1, 5)とインスタンスを生成する形で利用しなければなりませんが、範囲演算子では1..5で済みます。

「..」「...」の2種があり、前者は終点を含み、後者は終点を含みません。
また、abcなどの文字列でも、次の値を持つシリアルなものであれば範囲演算子を利用可能です。

以上、JavaやPythonでは見かけなかった演算子についてまとめました。
ググったところCやPerlなど様々な言語で実装されているようです。私がたまたま知らなかっただけでした・・・。
また何かあれば追記しようと思います。

## 参考

たのしいRuby第5版
https://www.sbcr.jp/product/4797386295/

現場で使えるRubyonRails5速習実践ガイド
https://book.mynavi.jp/ec/products/detail/id=93905

Wikipedia Null条件演算子
https://ja.wikipedia.org/wiki/Null%E6%9D%A1%E4%BB%B6%E6%BC%94%E7%AE%97%E5%AD%90
AtCoder Beginner Contest 178 C問題

AtCoderを始めましたが、ABCのA・B問題はほぼ解ける、C問題は運が良ければ解けるというレベルです。
まずはC問題を難なく解けるというの目標に、まずは過去問のC問題までをどんどんやっていってます。

自力では解けなかった問題を、解説を見て、理解した内容の整理とその結果のコードを書いていきたいと思います。

#問題

https://atcoder.jp/contests/abc178/tasks/abc178_c

>長さ N の整数の列 A_1,A_2,…,A_N であって以下の条件をすべて満たすものはいくつありますか。

>・0 < A_i < 9
>・A_i=0 なる i が存在する。
>・A_i=9 なる i が存在する。

>ただし、答えはとても大きくなる可能性があるので、10^9+7 で割った余りを出力してください。</quote>

#解けなかった原因
総当たりでは、計算量がかかりすぎるがので、それ以外の方法が必要

#解説を見て理解した内容
包除原理を適用して計算する
<ol>
<li>長さNの整列の組み合わせは、10のN乗</li>
<li>i=0が存在しない組み合わせは、9のN乗</li>
<li>i=9が存在しない組み合わせは、9のN乗</li>
<li>i=0とi=9両方が存在しない組み合わせは、8のN乗</li>

10のN乗(1) - 9のN乗(2) - 10のN乗(3) + 8のN乗（4)
で組合せ数が求まる

#ACしたコード
```python

N = int(input().strip())

print( (10**N - 9**N - 9**N +8**N) % (10**9+7) )
```
TabBarControllerにViewを追加する

#はじめに
ツールバーでViewが追加できる項目があるかなと思ったら見当たず、調べた結果GUI操作で設定できました。
UITabBarControllerの仕様が面白いなと思ったので記事を書きました。
自分の学習メモ替わりに書いているので内容は薄いです。ですが初心者向けに具体的な手順を解説していきたいと思います。

#作ったサンプル
こんな感じです

![スクリーンショット 2021-05-04 15.45.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1222455/8f3cd962-392a-ebc0-a4f7-0a9c030054a6.png)

https://github.com/eueuG/TabBarControllerSample

#実践

新しくstoryboardファイルを作ったら、そこに画面右上のプラスボタンをクリックして、そこからTabBar Controllerをドラッグしてきましょう。

![スクリーンショット 2021-05-04 16.04.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1222455/be32b673-04bc-30bf-05c2-8b3a3a64881b.png)


生まれたばかりのTabBarControllerが表示されるはずです。
先ほどのような３画面にするため、もう一つViewを追加します。


TabBarControllerを追加したのと同様の手順でViewControllerを持ってきます。
したの画像のように画面が合計４つ表示されていれば大丈夫です。

![スクリーンショット 2021-05-04 16.09.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1222455/bb3f0cac-091f-cb3b-a705-571a71eb5381.png)

そしてTabBarControllerのTabBarに３つ目のItemが表示されるように追加するやり方は、したのようにやります。

![タイトルなし.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1222455/d421a35f-6c97-4ffa-5f00-0b2fc7452c5f.gif)

まずTabBarControllerを選択し、上部左の黄色い丸いマークを、controlキーを押しながら追加したいViewControllerへとドラッグします。
指を離すとメニューが表示されるので、Relationship Segueの下、ViewControllersを書いてあるところをクリックします。
これでTabBarControllerに画面が追加されます。

以上です。
Swift言語 一定の範囲内でループする数値

# コピペ用

例えば **99** の次が **0** で,  逆に **0** の前が **99** のようにしたい時に使う。

増加: ... 97 < 98 < 99 < 0 < 1 < 2 ...
減少: ... 3 > 2 > 1 > 0 > 99 > 98 ...

```extension_Int.swift
extension Int {

    /// looped value in range
    func looped(in range: ClosedRange<Self>) -> Self {
        let min = range.lowerBound
        let max = range.upperBound
        if self < min {
            return max - ((min - self - 1) % (max - min))
        }
        else if max < self {
            return min + ((self - max - 1) % (max - min))
        }
        else {
            return self
        }
    }
}
```

# 使い方

一度ループを無視した計算をした後に、 ```.looped(in:)``` を使う

99 + 1 = 100
0 - 1 = -1

```swift
let a = 100.looped(in: 0...99)
// a: 0

let b = (-1).looped(in: 0...99)
// b: 99
```

# さいごに

99 + 300 のように、ループが何周も回っている場合にも対応しています。
自動でループする型を作りたい人は ```@propertyWrapper``` と組み合わせれば良さそうですね。
Do!コン用資料(限定公開)そのに：toioもくもく回進捗のお話

# 5/4(火)のtoioもくもく回における進捗状況

# 主処理における、メソッド単位で定義ブロックの設計
## 目的
- プレイヤーの改造のしやすさ

## スクショ
- 図①
![スクリーンショット 2021-05-04 16.32.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/4be0c310-e963-8642-373c-c765ea60deff.png)

- 図②：衝突回避スクリプトの実装
![スクリーンショット 2021-05-04 16.33.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/4d05d930-acad-052e-26d2-17a96a8bc9a3.png)

# 残課題
## 下図参照
- 指定の座標まで到達しないと、次のスクリプトが機能しない。
- そのため、別のやり方として、相手のキューブの向きを動的に取得できる状態で、自キューブを動かしたい。
![スクリーンショット 2021-05-04 16.39.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/90f4d5d5-9ec7-4f5a-ad0c-695e57e4936d.png)

![スクリーンショット 2021-05-10 22.12.49のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/183fc2fe-fffe-ad25-87e8-727b8fd910e2.png)
JavaScriptの基礎を改めて Part2

*  [前回のPart1](https://qiita.com/hkobashi/items/26fadf6944934f8a8176)同様にJavaScriptの新たな気づきや重要だと感じた点をまとめる。

# 破壊的、非破壊的なメソッドについて
* 参照するデータに対して直接的な変更が入るメソッドは破壊的メソッドに分類される　。

```javascript:例1
const array = ["A", "B", "C"];
console.log(array);
>> ["A", "B", "C"];

const addedArray = array.push("D");
// pushメソッドは指定した配列に引数を加えるメソッド
console.log(array);
>> ["A", "B", "C", "D"];
// 配列arrayに直接的な変更が入っている。
```

* 対して参照するデータに対して直接的な変更が入らないメソッドは非破壊的メソッドに分類される。

```javascript:例2
const array = ["A", "B", "C"];
console.log(array);

const newArray = array.concat("D");
// concatメソッドは指定した配列をコピーしたものに引数を結合させるメソッド
console.log(newArray);
>> ["A", "B", "C", "D"]
console.log(array);
>> ["A", "B", "C"]
// 配列arrayに対して直接的な変更が入っていない
```
* JavaScriptにおける破壊的、非破壊的メソッドはメソッド名から区別できず、破壊的メソッドは意図しない動作（副作用）が起こりうる。<br>
そのため破壊的メソッドか否かは開発時点で引数にした配列に対してconsole.logメソッド等で確認する必要がある。<br>
対策として破壊的メソッドでプログラムを記述した際は破壊的メソッドである旨を<br>
コメントアウトすることで問題発生時の切り分けを手助けするとよい。

```javascript:例3
const removeIndex = (array, index) => { 
    array.splice(index, 1);
    // spliceメソッドは配列arrayの指定したindexに対応したデータのみを削除した配列を返す
    return array;
}

const array = ["A", "B", "C"];
console.log(array);
>> ["A", "B", "C"]
// この時点では配列arrayにremoveIndex関数を実行していないためすべての要素が返ってくる。

const newArray = removeIndex(array, 1);
// 変数newArrayにremoveIndex関数の実行結果を定義。
console.log(newArray);
>> ["A","C"]
// removeIndex関数によってarray[1]が削除されるconsole.log(array);
>> ["A","C"]
/* spliceメソッドは配列に対して破壊的な変更を加えるため、
   removeIndex関数によって配列arrayにも影響を及ぼす。*/
```

* もう一つの対策は破壊的メソッドの引数に予め非破壊的メソッドでコピーした配列を指定することである。

```javascript:例４
const removeIndex = (array, index) => { 
    array.splice(index, 1);
    return array;
}

const array = ["A", "B", "C"];
const copiedArray = array.concat();
// concatメソッドは引数なしだと指定した配列（今回ならarray）をコピーしてくれる。
console.log(array);
>> ["A","B","C"]
console.log(copiedArray);
>> ["A","B","C"]

const newArray = removeIndex(copiedArray, 1);
// removeIndex関数の引数にconcatメソッドでコピーした配列を指定。
console.log(newArray);
>> ["A","C"]
// copiedArray[1]を削除した配列が返ってくる
console.log(array);
>> ["A","B","C"]
// 配列arrayに対してはremoveIndex関数を実行していないため副作用なし。
```

# メソッドチェーン
* 配列に対してメソッドを連続して行うこと。<br>
メソッド毎に変数に対して結果を定義する手間を省くことができる。<br>

```javascript:例５
const array = [
    { name: "Tanaka", age: 10 },
    { name: "Suzuki", age: 12 },
    { name: "Kobayashi", age: 20 },
    { name: "Takeuchi", age: 33 },
    ];

const sortAge = array
.filter(data => data.age <= 15);
// filterメソッドで配列array内のageが１５以下のオブジェクトを抽出。
.map(data => data.name);
// filterメソッドで抽出されたarrayに対してmapメソッドで指定したプロパティを取得。

console.log(sortAge);
>> ["Tanaka", "Suzuki"]
// ageが１５以下のオブジェクトのnameを取得。
```

* 複数の処理をメソッドチェーンで一連の処理として記述することができるが、  
記述が長くなりすぎると可読性が落ちるため適度な単位(段落)をメソッドチェーンで  
記述することを意識する必要がある。  
（処理１〜３０　=>　処理（１〜１０）、処理（１１〜２０）、処理（２１〜３０）で区分けするイメージ）
SQL〜主キー、外部キー、複合キーとは？〜

## はじめに
プログラミング学習の序盤に理解に苦しんだ主キー、外部キー、特に複合キーについて
初学者向けにまとめた。

## 主キー
主キーはテーブル内のレコードひとつひとつを識別できるようにキーとなる情報を含んだカラムである。
例えば学籍番号やマイナンバーが挙げられる。

- 学生テーブル

| 学籍番号 | 氏名　|
|:-----:|:-----:|
| 00001 | 野原しんのすけ　|
| 00002 | 風間トオル　|
| 00003 | 桜田ネネ　|
| 00004 | 佐藤マサオ　|
| 00005 | ボーちゃん　|

## 外部キー
外部キーはテーブルとテーブルを関係づけるため、他のテーブルの主キーを参照するカラムである。
以下の例だと学生テーブルの学籍番号と学部テーブルの学部IDが主キー、学生テーブルの学部IDが外部キー
となる。

- 学生テーブル

| 学籍番号 | 氏名　|　学部ID　|
|:-----:|:-----:|:-----:|
| 00001 | 野原しんのすけ　|　1　|
| 00002 | 風間トオル　|　2　|
| 00003 | 桜田ネネ　|　3　|
| 00004 | 佐藤マサオ　|　1　|
| 00005 | ボーちゃん　|　3　|

- 学部テーブル

| 学部ID | 氏名　|
|:-----:|:-----:|
| 1 | 経済学部　|
| 2 | 法学部　|
| 3 | 工学部　|

## 複合キー
主キーはひとつひとつのレコードを識別できるようでなければならないが、一つのカラムでは識別できないが
複数のカラムを組み合わせるて主キーとして識別できるようにしたのが複合キーである。
例えば、プロ野球チームの全球団の選手一覧のテーブルがあるしたら、背番号カラムだけでは他のチームに
同じ背番号の選手がいた場合に、識別できない。背番号カラムに加えて、球団を識別するための球団IDという
カラムと組み合わせることにより、選手個人を識別できる。
【React】create-react-appは外部ディスクで実行してはいけないという戒め

Reactのローカル環境を構築して、いざアプリを作成しようとした際にエラーでハマった。

結論
create-react-appコマンドはローカルディスク上で実行しましょう。

エラー内容は以下。

```
$ npx create-react-app my-app

Creating a new React app in /Users/XXX/Box/Programming/JavaScript/my-app.

Installing packages. This might take a couple of minutes.
Installing react, react-dom, and react-scripts with cra-template...

npm ERR! cb() never called!

npm ERR! This is an error with npm itself. Please report this error at:
npm ERR!     <https://github.com/npm/cli/issues>
```

cb()という関数が呼ばれてないというエラーが発生している模様。

アタッチしているBOXドライブ上にあるフォルダ配下でアプリを作成しようとした結果、上記のエラーが発生した。

ローカルディレクトリのダウンロードフォルダ内で同様のコマンドを実行したところ問題なくアプリ作成ができたので、BOXドライブ上とローカルディレクトリ上で出来ることが違うっぽい・・・？

BOXドライブはPCにアタッチされてるから特に問題なく使用できると思ったんだけど、そうではないらしい。
【2021】全チャンネルに招待してくれるSlackBotを作ってみた

こちらの記事を参考にして「**全チャンネルに招待してくれるSlackBot**」を作ろうと思いましたが、slackAPIの変更があったりしたので、その部分を加筆したいと思います。

https://qiita.com/divideby_zero/items/bec36b15004751ead0d9#%EF%BC%94gas-%E3%81%8B%E3%82%89-%E3%83%81%E3%83%A3%E3%83%B3%E3%83%8D%E3%83%AB%E3%81%AB%E7%99%BA%E8%A8%80%E3%81%99%E3%82%8B

まず、上の記事の0~3はそのまま現在も使えるので大丈夫です。

問題は4の[GAS から チャンネルに発言する](https://qiita.com/divideby_zero/items/bec36b15004751ead0d9#%EF%BC%94gas-%E3%81%8B%E3%82%89-%E3%83%81%E3%83%A3%E3%83%B3%E3%83%8D%E3%83%AB%E3%81%AB%E7%99%BA%E8%A8%80%E3%81%99%E3%82%8B)の部分で、紹介されているslackのAPIを叩けるライブラリは古く、2020年のslackAPIの変更に対応できてないのでチャンネル一覧の取得や、チャンネルへの招待のAPIが動きません。

なので、記事の5,6ではそのライブラリを使ったコードで紹介されていますが、今回僕はslackAPIをそのまま叩くコードに書き換えて実行しました。

以下のgistがサンプルコードです。

https://gist.github.com/kboy-silvergym/e0fd8b91f4c982462133a0ed1c166182

今回はFlutter大学のslackで使うため、全てのチャンネルではなく、timesというチャンネルに全て招待されるBOTにしてみました。

こんな感じで動きます。

![スクリーンショット 2021-05-02 16.53.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111366/97756929-120b-8a47-7f50-fc1a119db099.png)


是非、元ネタのqiita記事も参考にしつつ、コード部分は私の書いたやつを参考にして、slackBOTを作るのに役立ててもらえたら嬉しいです。

以上
Ruby on Railsインストール時のエラー

# 概要
Ruby on Railsをインストールする際に下記のようなエラーが発生しインストールが出来ませんでした。

### gem install rails実行時のエラー内容

```console:console
> gem install rails
Temporarily enhancing PATH for MSYS/MINGW...
Building native extensions. This could take a while...
ERROR:  Error installing rails:
        ERROR: Failed to build gem native extension.

    current directory: C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/websocket-driver-0.7.3/ext/websocket-driver
C:/Ruby30-x64/bin/ruby.exe -I C:/Ruby30-x64/lib/ruby/site_ruby/3.0.0 -r ./siteconf20210504-17032-oj9pk4.rb extconf.rb
creating Makefile

current directory: C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/websocket-driver-0.7.3/ext/websocket-driver
make DESTDIR\= clean
C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/make-0.3.1/bin/make:4:in `<top (required)>': undefined local variable or method `make' for main:Object (NameError)
        from C:/Ruby30-x64/bin/make:23:in `load'
        from C:/Ruby30-x64/bin/make:23:in `<main>'

current directory: C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/websocket-driver-0.7.3/ext/websocket-driver
make DESTDIR\=
C:/Ruby30-x64/lib/ruby/gems/3.0.0/gems/make-0.3.1/bin/make:4:in `<top (required)>': undefined local variable or method `make' for main:Object (NameError)
        from C:/Ruby30-x64/bin/make:23:in `load'
        from C:/Ruby30-x64/bin/make:23:in `<main>'

make failed, exit code 1
```

# 対処方法
結論から言うと、"gem uninstall make" を実行してmakeをアンインストールすれば解決しました。
VSCodeの拡張機能でRuby on Railsをインストールしていたことが原因かもしれません。

makeをアンインストール後に、再度Railsのインストールを実行したところ、無事インストールが完了しました。

```console:console
> gem uninstall make
Remove executables:
        make

in addition to the gem? [Yn]  y
Removing make
Successfully uninstalled make-0.3.1

> gem install rails
Temporarily enhancing PATH for MSYS/MINGW...
Building native extensions. This could take a while...
Successfully installed websocket-driver-0.7.3
Building native extensions. This could take a while...
Successfully installed nio4r-2.5.7
Successfully installed actioncable-6.1.3.1
Successfully installed rails-6.1.3.1
Parsing documentation for websocket-driver-0.7.3
Installing ri documentation for websocket-driver-0.7.3
Parsing documentation for nio4r-2.5.7
Installing ri documentation for nio4r-2.5.7
Parsing documentation for actioncable-6.1.3.1
Installing ri documentation for actioncable-6.1.3.1
Parsing documentation for rails-6.1.3.1
Installing ri documentation for rails-6.1.3.1
Done installing documentation for websocket-driver, nio4r, actioncable, rails after 1 seconds
4 gems installed
```

# 参考URL
https://stackoverflow.com/questions/59310599/undefined-local-variable-or-method-make-when-installing-therubyracer-on-macos
Spring bootでクライアントからの通信確認試みるも待ち合わせできなかった話

http通信の待ち合わせがしたいのですが実行してもspringアプリが終了してしまいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630191/83952553-606a-f6dc-3472-8b388f685177.png)



コントローラークラスのアノテーションをクイックフィックスで直した際に追加した依存がまずかったようです。まずいのは下記の部分

```pom.xml
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>5.3.6</version>
		</dependency>

```

正しくはこちら

```pom.xml
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
```
Vue.js~v-for~

#概要
JSでは、イベント(ユーザーがクリックしたときなど)に処理(イベントハンドラーと言います)が始まります。
その際に、クリックイベントを取得することにより実行することができました。Vue.jsでも記述は多少異なりますが仕組みは変わりません。
繰り返し処理についての記事です。

#繰り返し処理
Vue.jsでは、繰り返し処理の際に[v-for]を使用します。

#HTML

```index.html
<ul>
  <li v-for="list in lists">{{ list }}</li>
</ul>
```
構文は以下のようになります。

```
v-for="仮変数 in 任意の配列"
```
配列listsから順に要素を取り出します。
マスタッシュ構文に変数listを格納します。
このlistの中にlistsの配列の中身がなくなるまで繰り返し処理されます。


#Vue

```index.js
data:{
  lists:[
    'list1',
    'list2',
    'list3'
  ]
}
```

#index番号

インデックス番号を取得します。

```index.html
<ul>
  <li v-for="(list,i) in lists">{{ list + i }}</li>
</ul>

//list1 0
//list2 1
//list3 2
```

配列要素+インデックス番号で取得することが出来ます。

#番外編for文

```index.js
<span v-for="i in 10">{{i }}</span>

//12345678910
```
[SQL] LeetCodeの無料問題集を活用して、SQLを使いこなし（4）

#Q180 Consecutive Numbers
![Q180.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1082021/584a6942-185f-b1e3-cad1-948643b272a7.png)

##質問
少なくとも3回<b>連続</b>して表示される数値を検索します。 

##Code書き方のHint

連続表示される数値を探すので、1行目の数字は2行目、３行目の数字と比較して、一致すれば、その数字は求められるのです。
数字の後ろの値を取得するため、ここはLEAD関数を使います。

REF:https://dev.mysql.com/doc/translation-refman/8.0/ja/functions.html#function_lead

>LEAD(expr [, N[, default]]) [null_treatment] over_clause

LEAD関数: n個後の行を取得する
LEAD(列名,n行）　over(...)

##Code
```SQL
SELECT DISTINCT Num AS ConsecutiveNums 
FROM(SELECT Num,
    LEAD(Num,1)over()as Num1,
    LEAD(Num,2)over()as Num2
    FROM Logs) T
WHERE T.Num=T.Num1 AND T.Num=T.Num2;
```

##Result

![Q180_result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1082021/6994e549-6921-5202-05ec-9664dfcb3895.png)
ルーティングを理解する

#ルーティングの役割
ルーティングはコントローラーを繋ぐ役割を持っていて、以下の順番で処理を行う。

```
①URLを検索(リクエスト)
②ルーティング
③コントローラー
④ビュー
⑤レスポンスを返す
```
#ルーティング理解する

```
公式
get "URL" => "コントローラー名#アクション名"
```

```
実践
ブラウザから、「localhost:3000/home/top」というURLが送信された時

Rails.application.routes.draw do
  get "home/top" => "home#top"
end

上記のように記述すると、homeコントローラーのtopアクションで処理されるようになる。

⚠︎ "home/top"はURLを表している
⚠︎ "home#top"は"コントローラー名#アクション名"

もし、上記のようなルーティングの記述がしてあるのに、「localhost:3000/home/hello」を送信すると、
ルーティングエラーが起きる。これは、URL(home/hello)に対応するルーティングが存在しないためである。
```
ブロックチェーンまとめ

<h1>ブロックチェーンまとめ</h1>

業務でブロックチェーンに携わるようになったため、昨年から色々と調べていたので、
自分なりにしらべてまとめた結果をslideshare(初投稿)してみました。

ブロックチェーンを取り巻く環境の変化は、凄まじく1年前と今とでもだいぶ状況が変わってきている。
(日本でも、民間と日銀がそれぞれ主導となってデジタル通貨の実証実験を始めたりするなど。。)

暗号資産についても、polkadotが上位に食い込んできたり、イーサリアムで大型アップデートが行われたりと
人間がコロナで縛られている間も技術はめざましく進化していることを実感しました。

まだ調べなきゃいけないことや勉強しなければならないことは山ほどあるが、まずは一旦アウトプットしてみようと
考えてスライドを投稿してみました。初投稿なので、見苦しいところもあるかと思いますが、よろしくお願いいたします。

※これからも勉強していくので、適宜更新・修正して行きたいと考えています。

https://speakerdeck.com/mashharuki/burotukutienmatome?slide=75

https://www2.slideshare.net/HarukiKondo/ss-247675477
グローバルIPを確認するサイトで安心できるのはどこ？

##経緯
業務でCircleCIを導入することになりました。
ただ、EC2にIPアドレス制限をかけていたため、
ホワイトリストにIPアドレスを追加する必要があります。

1.サーバーから現在のグローバルIPを確認
2.CircleCIからEC2のセキュリティグループにグローバルIPを追加
3.SSHで接続

一連の動作の実装が完了したところで再度実行。
なぜかグローバルIPが取得できず動かない...

グローバルIPの取得方法

```
curl ifconfig.me
```

確認したところ、ifconfig.meのサーバーが落ちていました。
![スクリーンショット 2021-04-27 18.46.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242259/11cb4a96-0248-b8ae-e6c9-54d1c8a878c1.png)

グローバルIPはサーバーが持っていない情報です。
そのため、サーバーが自分のグローバルIPを確認するには、他のウェブサイトから確認してもらい、その値を返してもらう必要があります。

今回は、ifconfig.meというサイトに確認してもらうようプログラムを組んでいましたが、ifconfig.meのサーバー自体が落ちていました。
「グローバルIPを確認する方法」で調べると、
`curl ifconfig.me`で調べられるという記事がいくつも出てきましたが、ifconfig.meというサイトの運営元はどこで、どの程度の信頼性があるかは確認できませんでした。

他サイトに頼るコマンドを書くのであれば、そのサイトが安全だとある程度保証されている必要があるでしょう。

なので今回グローバルIPを返してくれるサイトをいくつか調べてみました。
そもそも、固定IPアドレスを設定できるのであれば、そのようにすべきでしょう。
ただ、今回はCircleCIで動かすため、CircleCIのIPアドレスは固定できません。
なのでより安全、安心なサイトを選び、より確実にグローバルIPアドレスを確認できる方法を検討しました。

## サイト一覧
グローバルIPアドレスを返してくれるサイトは以下です。

###【URL】http://inet-ip.info/
【運営元】不明
【備考】
GitHub上でソースコードが公開されている。（2021/05現在スター5つ）
https://github.com/masahide/inet-ip.info
【使用方法】

```
curl http://inet-ip.info/
```

###【URL】http://globalip.me/
【運営元】不明
【使用方法】

```
curl http://globalip.me/
```


###【URL】http://api.ipify.org/
【運営元】https://www.ipify.org/
【備考】
GitHub上でソースコードが公開されている。（2021/05現在スター1.1k）
https://github.com/rdegges/ipify-api

【使用方法】

```
curl http://api.ipify.org/
```

###【URL】https://ipinfo.io/ip
【運営元】https://ipinfo.io/about
【備考】
一ヶ月あたり200億のAPIリクエストがある。
10万人以上の開発者、事業者が使っている。
毎秒1万以上のリクエストがサーバーに来ている。

【使用方法】

```
curl https://ipinfo.io/ip
```


###【サイトURL】https://ipecho.net/plain
【運営元】https://ipecho.net
【使用方法】

```
curl https://ipecho.net/plain
```

###【URL】ident.me
【運営元】https://api.ident.me/
【備考】
一度目の実行結果と2度目の実行結果が違う...
（*には数字が入っていました。念の為ボカした。）

```
$ curl ident.me
121.103.***.**%  
$ curl ident.me
240b:11:ac1:b300:**ff:***d:*fed:f**d% 
```

###【URL】https://ifconfig.me
【運営元】不明
【使用方法】

```
curl https://ifconfig.me
```

###【URL】http://ipconfig.io/
【運営元】不明
【備考】
GitHub上でソースコードが公開されている。（2021/05現在スター3k）
https://github.com/mpolden/echoip
【使用方法】

```
curl http://ipconfig.io/
```

###【URL】https://domains.google.com/checkip
【運営元】https://domains.google.com
【備考】
Googleが運営している。

【使用方法】

```
curl https://domains.google.com/checkip
```

###【URL】https://checkip.amazonaws.com
【運営元】https://aws.amazon.com/
【備考】
Amazonが運営している。
【使用方法】

```
curl https://checkip.amazonaws.com
```

###【URL】ipaddr.show
【運営元】不明
【使用方法】

```
curl ipaddr.show
```

###【URL】http://httpbin.org/ip
【運営元】http://httpbin.org
【備考】
GitHub上でソースコードが公開されている。（2021/05現在スター9.8k）
https://github.com/postmanlabs/httpbin
返り値はJSON形式
【使用方法】

```
curl http://httpbin.org/ip
```

###【URL】http://ipaddr.ga/
【運営元】不明
【使用方法】

```
curl http://ipaddr.ga/
```

## 結論
1.GitHubでOSSとして公開されている。
2.有名な企業が運営している。
いずれかの条件を満たしていればある程度信頼できそうですね。
Dockerメモ/画像補間/samba

日記: Docker/DockerHub関連
====

環境
---
OS: ubuntu 20.04 intel 64bit / Windows 10 Hyper-V
- sudo snap install docker

DockerHub
--- 
例: 
- accountId: kyoyap
- repositoryId: `riot-stress`
- tagName: `R1`

#### DockerHub リポジトリ作成
1. https://hub.docker.com/ にログイン
2. Create Repository Button> Name:`riot-stress` > Create

#### Dockerイメージ作成/ビルド
build tagをDockerHubに合わせる
```
git pull https://github.com/kyoya-p/riotProj
cd riotProj/Trial
sudo docker build -t kyoyap/riot-stress:R1 .
```

#### DockerHubへのアップロード
```
sudo docker login
sudo docker push kyoyap/riot-stress:R1
sudo docker logout
```

サンプルDockerイメージ
---

#### [既存サイトのHTTPS化]() - [Certbot](https://certbot.eff.org/)/[https-portal](https://hub.docker.com/r/steveltn/https-portal/)


#### [sambaでファイル共有](https://github.com/kyoya-p/home/tree/master/devenv/smb)
```
sudo docker run -d -v ~:/mount -p 445:445 kyoyap/devenv:smb
```
- `$HOME` を `\\HOST\public` 以下に公開(注意!)する。


#### [画像補間](https://github.com/kyoya-p/home/tree/master/devenv/sig2017) - [SIGGRAPH論文](http://iizuka.cs.tsukuba.ac.jp/projects/completion/ja/)[/Docker元ネタ](https://ja.takp.me/posts/great-image-completion-siggraph-paper/)
```
sudo docker run --rm -v `pwd`:/host /kyoyap/devenv:image-complement ${image} ${mask}
```
- 画像ファイル/MASKファイルはRGB(3Byte/pixel)のPNG/Jpegファイル。
    - カレントディレクトリ以下に置く
- maskfileの黒(0x000)以外の部分を補完する
- 出力結果は ${image}.out.png が生成される
投稿画像を横並びで表示する

#はじめに

現在Railsにてスキンケア用品に対して、自由にクチコミ投稿ができるポートフォリオサイト作成中です。
その中で登録した商品をECサイトのように、2列や3列に分けて表示したいと思い、実装しました。
今回はbootstrpを使用して、簡単に並べたいと思います。

![スクリーンショット 2021-05-04 11.01.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1340120/817ff94d-34bd-a907-89c3-cccecac40367.png)

これを…

![スクリーンショット 2021-05-04 11.02.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1340120/551bf934-6b05-7ede-e629-b7c5212af540.png)

こう！

この記事は以下に移行しました。
https://yoyoyo39.com/bootstrap-side-by-side/
Bootstrap 5のレンジが、Safariで表示がおかしくなる原因と対処法

Bootstrap5で開発していたアプリを、Safariで表示したところレンジのスタイルが適用されなかったので、その原因と対処法をご紹介します。

#Sassでの読み込み時に発生
CDNや`bootstrap.min.css`、`bootstrap.css`からBootstrapを読み込んでいる場合は、この不具合は発生しません。
※Bootstrapは頻繁に更新されているので、今後、このような環境でも不具合が発生する恐れがあります。
`bootstrap.scss`から読み込んだ場合に、この不具合が見られました。

#どういうことなのか
bootstrapのレンジのスタイルが、Safariで反映されない。

Chrome（正常）↓
![Chromeの正常なレンジ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1172197/55f76eb0-8db1-688d-3dfd-0df9e3153ebf.png)
Safari↓
![Safariの表示がおかしいレンジ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1172197/e9fba63d-abcb-cec2-fee8-8afaca4c729d.jpeg)

# 原因
Safariなどのブラウザでは、デフォルトのスタイルを無効化するCSSのプロパティである、`appearance`にベンダープレフィックス[^1]をつけなくてはならないが、Bootstrap 5のSassではベンダープレフィックスがついていないため。
ちなみに、`appearance`はMDNによれば、まだ「実験的な機能」とのことです。
[^1]: 特定のブラウザでしか使えない、試験段階のプロパティの頭につく`-webkit-`や`-moz-`などの識別子のこと。将来的にCSSの正式な仕様となれば不要になりますが、ベンダープレフィックス付きのプロパティにしか対応していない古いブラウザに対応させるため、ベンダープレフィックス付きのプロパティを併記することがあります。

>Experimental
これは実験的な機能です。
本番で使用する前にブラウザー互換性一覧表をチェックしてください。
*[appearance (-moz-appearance, -webkit-appearance)](https://developer.mozilla.org/ja/docs/Web/CSS/appearance) by [MDN contributors](https://developer.mozilla.org/ja/docs/Web/CSS/appearance/contributors.txt) is licensed under [CC-BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/)*

現時点での対応状況は以下リンクから見られます。
2021/05/04時点では、

- Chrome、Firefox、Edgeでは`appearance`単独でも機能する
- Safariはベンダープレフィックスが必要
- IEは、11も含めて完全に非対応

とのことです。

IEが完全に非対応とのことですが、最近はEdgeがChromiumを採用したことなどから、IEのサポートを打ち切るサイトも増えてきているので、あまり気にしなくても良いと思われます。

https://developer.mozilla.org/ja/docs/Web/CSS/appearance#browser_compatibility

#対処法
以下のCSSをBootstrapを読み込ませた後に追記します。

```css:mystyle.scss
input[type="range"]{
/*レンジ全体のスタイルを整える*/
  appearance: none; /*デフォルトのスタイルを無効にする*/
  -webkit-appearance: none;/*Webkitの古いブラウザでデフォルトのスタイルを無効にする*/
  -moz-appearance: none;/*古いFirefoxでデフォルトのスタイルを無効にする*/
}
input[type="range"]::-webkit-slider-thumb {
/*Webkitブラウザでのレンジのツマミ部分のスタイル*/
  -webkit-appearance: none; 
  appearance: none;
}
input[type="range"]::-moz-range-thumb {
/*Firefoxでのレンジのツマミ部分のスタイル*/
  -moz-appearance: none;
  appearance: none;
}
```

対処後は、Safariでも正常に表示されました。
![Safari(対処後)](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1172197/10df533f-65dc-4e1e-53dc-0ba6f7d73c53.jpeg)

#Bootstrap側でこの問題は修正されるのか
[この問題を修正したというPull Request](https://github.com/twbs/bootstrap/pull/33671)があったので、近いうちにこの不具合が修正されたものがリリースされると思われます。
（2021/05/04時点での最新版はv5.0.0-beta3なので、v5.0.0-beta4で修正されると思われます。）
そのため、Bootstrapのアップデートがないか定期的にチェックされることをおすすめします。

https://github.com/twbs/bootstrap/releases

ちなみに、GitHubでコードを管理している場合は、Dependabotを使うとBootstrapなどのパッケージ[^2]のアップデートを自動で確認し、Pull Requestを出してくれます。
[^2]: Bootstrapなどの、サードパーティのソフトウェアを指します。`package.json`などのようなファイルには、インストールされたパッケージの名称・バージョンなどが記載されています。
<br>
Dependabotの設定方法についての記事を書きましたので、合わせてご覧ください。

https://qiita.com/r-40021/items/2f378581a0c8765c206c


# フロントエンド強化月間
5/31まで、Qiitaでは「フロントエンド強化月間」を行っています。この記事も、「フロントエンド強化月間」に合わせて執筆されたものです。

https://qiita.com/official-events/b9ad63394fa2635dfca9

# 参考
CSSの`appearance`について

https://developer.mozilla.org/ja/docs/Web/CSS/appearance

Bootstrap (GitHub)

https://github.com/twbs/bootstrap