OmniAICreator/Qiita-1.07M huggingface dataset:
【SQL書籍勉強会】SQLとは？

## 背景

学習コミュニティで書籍勉強会を主催してみました。
概要は以下の通り。
・[スッキリわかるSQL入門](https://www.amazon.co.jp/%E3%82%B9%E3%83%83%E3%82%AD%E3%83%AA%E3%82%8F%E3%81%8B%E3%82%8BSQL%E5%85%A5%E9%96%80-%E7%AC%AC2%E7%89%88-%E3%83%89%E3%83%AA%E3%83%AB222%E5%95%8F%E4%BB%98%E3%81%8D-%E3%82%B9%E3%83%83%E3%82%AD%E3%83%AA%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E4%B8%AD%E5%B1%B1%E6%B8%85%E5%96%AC/dp/4295005096)を読み、自分なりの解釈でまとめてみる
・メンバー四人で各１章ずつを担当して読み、Qiita等でまとめて発表
・全12章あるので3日程で1周。


## なぜやるのか
プログラミング学習に加えて現職があるため、一人でやるのは非効率。そこで、1種類の本を各自で購入して、1章ずつ読みアウトプットしてしまえば短い時間で多くのインプットができるのではと考えました。
人が集まりやすいようにSQLやWEBの基本など、どの言語においても共通するテーマで企画しました。

本を読んだ内容を自分なりの解釈と言葉でまとめたので剽窃等には配慮しておりますが、
問題ありましたら修正/削除しますのでコメントいただければ幸いです。


## SQLの基本知識

### データベースとは
データベースにはさまざまな種類があります。

・リレーショナルデータベース(RDB)
・オブジェクト指向データベース
・分散データベース　　　　　　　　　…など。

現在、幅広く普及しているのはRDBです。
MySQLやPostgreSQLもRDBです。
表形式のデータベースでExcelによく似ています。

- 構造

・table： 表のこと
・column：列(カラム/フィールド)
・row: 行

1行に1データとしてカウントし、列は要素(id, age, nameなど）が入る。
→このデータの集合体から自在にデータを出し入れ/加工するためにSQLを使う。

ちなみにExcel等のスプレッドシートとの違いは以下の通りです。

||DB|Excel|
|---|---|---|
|データ量|すごい多い|MAX 4GB|
|操作方法|SQL|関数等|
|アクセス権|多数|1ユーザー|


### データベース管理システム(DBMS)

DBMS(database management system)とは、データベースを扱うためのツールです。
厳密にいえば、SQLはこのDBMSに送っていて、DBMSは送られたSQLを元にデータベース内のデータを探したり加工したりしてくれます。


### リレーショナルデータベース管理システム(RDBMS)

これがWEB開発を学習していると必ず知ることになる MySQLやPostgreSQLのこと。
つまり、リレーショナルデータベースを扱うためのソフトウェアのこと。


## まとめ

つまり、WEB開発における<b>データベース</b>とは
<b>「RDBという入れ物」</b>　から<b>「DBMSというSQLによって動く道具」</b>を使ってデータを加工したり出力したりする<b>「RDBMSというソフトウェア」</b>のこと。
SQLとはDBMSを動かすためのもの。

## 参考
・[スッキリわかるSQL入門](https://www.amazon.co.jp/%E3%82%B9%E3%83%83%E3%82%AD%E3%83%AA%E3%82%8F%E3%81%8B%E3%82%8BSQL%E5%85%A5%E9%96%80-%E7%AC%AC2%E7%89%88-%E3%83%89%E3%83%AA%E3%83%AB222%E5%95%8F%E4%BB%98%E3%81%8D-%E3%82%B9%E3%83%83%E3%82%AD%E3%83%AA%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E4%B8%AD%E5%B1%B1%E6%B8%85%E5%96%AC/dp/4295005096)
・[ORACLE データベースとは](https://www.oracle.com/jp/database/what-is-database/)
・[「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](https://wa3.i-3-i.info/word11770.html)

## メンバー記事
・[SQL入門のまとめ①](https://qiita.com/akihiro-cmd/items/accd46b406fd158ab05f)
・[【SQL】基本文法とデータ型](https://qiita.com/Issei_401/items/1ecb68f448f6dea86e7b)
・[【SQL】4大命令ってなんだっけ？](https://qiita.com/Issei_401/items/6f442acb021deffa7c2f)


## 別の回で使った記事
・[SQLの集計](https://qiita.com/vit_udon_husqy/items/3bec7ec5a5a9416e3b61)
実行パーミッションのついたシェルスクリプトを自動作成するシェルスクリプトを作ってみた

# 背景
[新しいLinuxの教科書](https://www.sbcr.jp/product/4797380941/)を参考にシェルスクリプトの勉強をしていたのですが、
毎回``` chmod +x```で実行パーミッションを付与するのが面倒だったので、作成されたシェルスクリプトに実行パーミッションを自動付与するシェルスクリプトを作ってみました。

# シェルスクリプト作成
早速、シェルスクリプトを作成していきます

```shell
$ vim autox.sh
```

```autox.sh
#!/bin/bash

if [ -n "$1" ]; then
    cd ~/bin	
    filename=$1
    scriptname="$filename".sh
    touch $scriptname
    chmod +x $scriptname
    vim $scriptname
else
    exit 1
fi
```

どうなってるかはコメント付きで後で書きます
このシェルスクリプトの使い方は、(xxxx).shのxxxx部分の名前にしたいファイル名を引数に取ってシェルスクリプトを実行する　といった形になります

```shell
$ chmod +x autox.sh
$ ./autox.sh
$ echo $?
1
$ ./autox.sh testfile
$ ls -l
# (中略)
-rwxrwxr-x. 1 hoge hoge  12 Jul 11 08:01 testfile.sh
```

引数なしでautox.shを実行するとファイルは作成されず、終了ステータスは1を返しています
引数にファイル名を取ってautox.shを実行すると(ファイル名).shが作成され、実行パーミッションが付与されます。
(vimの編集画面に入ると思います)

## シェルスクリプトの説明
以下にコメント付きでシェルスクリプトを書いていきます

```autox.sh
#!/bin/bash

if [ -n "$1" ]; then # 引数が空文字列ではない場合、
    cd ~/bin	# ~/binに移動し、
    filename=$1   # 変数filenameに引数を代入し、
    scriptname="$filename".sh   # 変数scriptnameに(ファイル名).shを代入し、
    touch $scriptname　  # (ファイル名).shを作成し、
    chmod +x $scriptname   #　　(ファイル名).shに実行パーミッションを付与し、 
    vim $scriptname   # (ファイル名).shの編集画面に遷移する
else   # 引数が空文字列の場合、
    exit 1    # 終了ステータスを1にする
fi
```

上記のような処理になるシェルスクリプトになっています


### まとめ
こんな簡単なシェルスクリプトでも面倒な作業は自動化できるよ！というお話でした。
誰かしらの役に立てば幸いです。

### 参考文献
[新しいLinuxの教科書](https://www.sbcr.jp/product/4797380941/)
react-create-appで作成したとき、jestのカバレッジから特定のファイルを除外する方法 

### やりたいこと
jestのカバレッジ取得する際に、必要のないファイルは無視するようにする。

### 本題

`package.json`に以下を追加する

```js
{
 "jest": {
    "coveragePathIgnorePatterns": [
      "./src/hoge.ts", //除外したいファイルのパスを指定する
　　　　　　　　　　　　"./*.stories.tsx" //ワイルドカードでの指定も可能
    ]
  }
}
```

カバレッジを取得するコードはこれ👇

```shell
react-scripts test --watchAll=false --coverage
```

参考にしたサイト👇

https://github.com/facebook/create-react-app/issues/1455
Djangoで詰まったエラーまとめ


#1, websocketの導入

```
myapp 
   └── myapp 
         ├── myapp 
         |     ├── urls.py
         |     └── settings.py
         |
         ├── chat  
         |     ├── urls.py
         |     └── consumers.py
```

こんな感じのサーバを作ってたとき(結構省略している)
中身の詳細→https://poyo.hatenablog.jp/entry/2018/05/17/224247
websocketを取り入れたサーバ作りたいな〜と思い


%pip3 install channels
を実行し、
"INSTALLED_APPS"に"channels"を追加すると

```
CommandError: You have not set ASGI_APPLICATION, which is needed to run the server.
```


"ASGI_APPLICATION"が設定されていないというエラーが出るので、例のサイトを参考にして
myapp/settings.pyに入れてみる。

```
ASGI_APPLICATION = 'myapp.routing.application'
```

しかし、またエラー

```
django.core.exceptions.ImproperlyConfigured: Cannot import ASGI_APPLICATION module 'myapp.routing'
```

ここでroutingをasgiにすると

```
ASGI_APPLICATION = 'myapp.asgi.application'
```

うまくいく

```
Django version 3.2.4, using settings 'myapp.settings'
Starting ASGI/Channels version 3.0.3 development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
```

理由は分からない。

#2, redis-serverを立ち上げる
せっかく動いたのにまたエラー

```
ConnectionRefusedError: [Errno 61] Connect call failed ('127.0.0.1', 6379)
WebSocket DISCONNECT /ws/chat/aa/ [127.0.0.1:51813]
```

調べたところによるとredis-serverが動いていないことが原因らしい
%pip3 install channels_redis
%brew install redis-server
%redis-server
^Z
これでデーモンで動いてくれる

さらにsettings.pyにも色々書き込む

```
CHANNEL_LAYERS = {
    'default': {
        'BACKEND': 'channels_redis.core.RedisChannelLayer',
        'CONFIG': {
            "hosts": [('127.0.0.1', 6379)],
        },
    },
}
```

これで動きました(結果が載せられなくてすいません)
redis-serverは基本的に6379というポート番号を使うんですかね
psコマンドで確認できます

また、redis-serverを止めたいときは
%kill -9 redis-server

#3, 実はまだ解決できていないエラー
channel layerを有効化しようと例のサイトを参考にして
chatのconsumers.pyのChatConsumerというクラスを更新していたところ

```
await self.channel_layer.group_add(
      self.room_group_name, self.channel_name
)
```

何度やってもここのコードでwebsocket disconnectとなってしまう
同期、非同期も試したが意味なし
self.channel_nameの中身に原因がありそうで
print(self.channel_name)を書き足して実行してみるが

```
specific.2cdf4c3db1e14e28b30e1baac0f78305!f6f0c02fca0c46c0a5e4d
```

なんかよく分からない文字列

誰か助けてください
Gitを最新版に変更出来ない時に見る記事

前のバージョン(1.8系)からバージョンアップを試みたのですが、
アップデートしてもまた1.8系に戻ってしまったので、その時参考にした記事を記録として残します。
今回はCentOS7で行った。

以下の記事を参考にする前に古いバージョンのgitをアンインストールしておく。やらなくても良いと思うが、一応。

```sh
sudo yum remove git
```
完了したら以下の記事を参考にして、Gitをアップデートする。

[CentOS7 に最新版の Git をインストールする方法](https://qiita.com/tomy0610/items/66e292f80aa1adc1161d)

上の記事を参考にしたが、バージョンがまた前のバージョン(今回だと1.8系)に戻ってしまった場合は、以下の記事を参考にする。
パスの順番が悪さをしているようなので、そこを修正する。

[Git を1.8.3から2系にバージョンアップできない](https://teratail.com/questions/162809)

VMを再起動したときに、パスの変更を残しておきたいなら
.bash_profileにパスを記載する

```sh
cd ~
vi .bash_profile
```

.bash_profileのファイルが開くので
fiの下にパスを書く

```sh
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi
# この下に書く
PATH=/usr/local/bin:$PATH

# 既にこの下が書かれていれば書かなくて良い、書かれていなければ書く
export PATH
```

以上で完了
Git基本まとめ

## Git・ソースツリーまとめ
Gitの考え方をメモベースで残していこうと思います。
上が最新になるように追記

- forkとは他人のリポジトリを自分のアカウントのリモートリポジトリにコピーすること
[参考URL](https://qiita.com/matsubox/items/09904e4c51e6bc267990)
- メインのリポジトリを基本originと命名する。
- バージョン管理したくないときは.gitignoreファイルにファイル名を記載する。
- 例：自動生成されるファイル、パスワードファイル
- ローカルにはワークツリー、ステージ、リポジトリの3段階のフェーズがある。★★大事
- リモートリポジトリは複数登録することができる
- フェッチとプルはどっちを使うべきなのか？→基本的にフェッチがおすすめ、プルは挙動が特殊
- プルの注意点→今いるブランチに統合されるため
- 並行して複数機能を開発するためにあるのがブランチ
- ブランチがあることで他の修正の影響を受けないですむ
- コミットはスナップショット。それが時系列順に連なる。
- ブランチはコミットを指したポインタ
- コミットしたらブランチが指すコミットファイルが最新に変わる
- .gitフォルダ（隠しフォルダ）が入っていたらリポジトリに設定されている
- チェックアウトすると、指定した時点のデータを作業ディレクトリにロードできる
- フォークとは他人が公開しているリモートリポジトリを、自分のアカウントにコピーできる機能のこと
- ブランチとはポインタのこと
- ブランチの移動はチェックアウトを使う
- マージでブランチを統合する
- ダウンロードしてローカルリポジトリに反映させたいときはプル
- コンフリクトした場合はエディタで修正して再コミットする
- 除外するファイル例
 - .DS_Store macOSが自動で生成
 - Thumbs.db WindowsOSが自動で生成
- リバーととはコミット１件を逆適用することができる、反対の内容で新規コミットをつくることで過去の変更を取り消す
- スカッシュはコミットをまとめたい時に使う
- プル＝フェッチ＋マージ
- リモートリポジトリの最新情報は取得したいけど、まだローカルブランチには反映させたくないときはフェッチを使う
- スタッシュ
 - 作業途中の内容（未コミット）を一時的に避難
 - 割り込み作業を終えたら、変更内容を復元
- タグを付けることで履歴上の重要ポイントに目印をつけることができる
- detached HEAD状態＝どのブランチにも所属しない状態（HEADタグが出る）
zsh + macOS + Visual Studio Code Terminalで単語間のカーソル移動

# 結論
Option + 矢印キー

#余談
特に何も設定しなくても Esc + F or B で移動できるが押しにくすぎる
少し調べるとiTerm使ってる場合の設定方法ばっかり出てくる(今まではこれでCtrl + F or Bに設定してた)
Visual Studio Code Terminalで楽に設定できないか調べると、何も設定しなくともまさかのOption + 矢印キー...
もしやと思ってCmd + 矢印キー試すとCtrl + A or Eと同じ動きをしてびっくりドンキー

# 余談2
ググる過程で見つけた Option + クリック も、
任意の場所に一瞬でカーソルを飛べるので便利

# 一応確認時のバージョン
- zsh 5.8 (x86_64-apple-darwin20.0)
- Visual Studio Code Version: 1.58.0
- macOS Big Sur Version 11.4
【Linux】viの使い方

####My Profile
プログラミング学習歴②ヶ月目のアカウントです！
プログラミングスクールで学んだ内容や自分が躓いた箇所等のアウトプットの為に発信しています。
また、プログラミング初学者の方にわかりやすく、簡潔にまとめて情報共有できればと考えています。
もし、投稿した記事の中に誤り等ございましたら、コメント欄でご教授いただけると幸いです。　



#対象者

* viの使い方が知りたい方


#目的

* viを使ってサーバー上でテキスト編集できるようになる

#実際の手順と実例
###1.viとは
* viとはUNIX系のOSにインストールされたテキストエディタです
* 根本思想は「ひたすら速く」
* 操作に慣れれば使いやすいかも、、、、、？


###2.実際の操作
*　コマンドモードと編集モードの２つがある
*　escでコマンドモードへ
*　ｓ　や　i を押すと編集モードなります

下記コマンドで起動します
まずサンプルテキストとしてechoを編集します

``````
$ echo -e "abc\ndef\nghi\njkl" > /tmp/hello_vi.txt
`````

``````
$ vi /tmp/hello_vi.txt
``````

これで起動完了です！


###3.編集の仕方

`````
→　移動は　ｌ
↑　移動は　ｋ
↓　移動は　ｊ
←　移動は　ｈ
``````

でカーソル移動します。

以下はコマンド一覧です

yy: コピー　→　３行コピーしたい場合:３yyと入力
p : 貼り付け
dd: 削除
u :直前の操作取り消し
０ :行頭へ移動
＄ :行末へ移動
:q! : 終了
:wq :　保存して終了




#参照

https://eng-entrance.com/linux-command-vi
【WordPress】「前（次）の記事へ」が1つ前（次）の記事にリンクしない

WordPressで「前の記事へ」や「次の記事へ」を表示する際は`get_previous_post()`と`get_next_post()`を使って記事リンクなどを表示しますが、
タクソノミー指定もしていないのに全ての記事が順番に表示されず、いくつかの記事を飛ばしてしまうことがあります。

この思わぬ落とし穴と対処方法について解説します。

##はじめに結論
記事の「**投稿日**」を見直してください。

![スクリーンショット 2021-07-11 20.22.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253923/f1dec00b-a848-1937-4bd0-7a32009f8882.png)

開発中はテスト記事を複製して量産することがあると思いますが、
複製された記事は投稿日が全て同じになります。

複数投稿でこの投稿日時が同じ場合、「前の記事（get_previous_post）」「次の記事（get_next_post）」として判定される投稿は、
**同じ投稿日時の記事の中で「前」は一番上（最新）の投稿、「次」は一番下（最後）の投稿だけを表示します。**

そのため、不規則にいくつかの記事を飛ばしてしまうような動きをすることがあります。

#「前の記事へ」「次の記事へ」を表示する方法
まず、前後記事リンクを表示する際はこのように記述します。


```single.php
<?php
  $prev_post = get_previous_post(); // 前の投稿を取得
  $next_post = get_next_post(); // 次の投稿を取得
  if( $prev_post || $next_post ): // どちらか一方があれば表示
?>
<nav class="page-nav">
<?php if( $prev_post ): // 前の投稿があれば表示 ?>
  <a href="<?php echo get_permalink( $prev_post->ID ); ?>" class="prev-link">
    <span>前の記事へ</span><br /><?php echo get_the_title( $prev_post->ID ); ?>
  </a>
<?php endif; ?>
<?php if( $next_post ): // 次の投稿があれば表示 ?>
  <a href="<?php echo get_permalink( $next_post->ID ); ?>" class="next-link">
    <span>次の記事へ</span><br /><?php echo get_the_title( $next_post->ID ); ?>
  </a>
<?php endif; ?>
</nav>
<?php endif; ?>
```

参考） https://hirashimatakumi.com/blog/3764.html

通常はこれで問題なく前後記事リンクが表示されます。
この書き方は間違っていませんのでご安心ください。

しかし、それでも結論で書いたように同一日時の投稿がある場合は全ての記事を順番に表示してくれません。




#`get_previous_post`と`get_next_post`の「前」、「次」の定義

公式にはこのように記載されています。

>```single.php
get_previous_post( bool $in_same_term = false, int[]|string $excluded_terms = '', string $taxonomy = 'category' )
```
Retrieves the previous post that is adjacent to the current post.（翻訳：現在の投稿に隣接する前の投稿を取得します。）
https://developer.wordpress.org/reference/functions/get_previous_post/

---------

>```single.php
get_next_post( bool $in_same_term = false, int[]|string $excluded_terms = '', string $taxonomy = 'category' )
```
Retrieves the next post that is adjacent to the current post.（翻訳：現在の投稿に隣接する次の投稿を取得します。）
https://developer.wordpress.org/reference/functions/get_next_post/

この書き方がとても曖昧ですが、
「**隣接**（adjacent）」とは、どうやら同一投稿タイプ内の「**投稿日**」を基準に隣ということのようです。

そのため、前後は隣接するID基準などではなく、日時的に古い投稿、新しい投稿を指します。

#記事複製などで同じ投稿日時がある場合は…
サイト開発時、表示チェックなどで記事を大量に複製してみる場合は、
とても面倒ですが、複製後に手動で投稿日を1分以上ずらしてください。
GatsbyでMarkdown内で独自コンポーネントを作成して使用する

# はじめに
こんにちは。雨雲レーダー見ていて、ギリギリ降らないなと普段してたら、一気に降ってきて、久々に全力ダッシュしました。無謀にもびしょ濡れになりました、筆者です:sob:

さて、今回はContentfulで管理しているブログの記事内に、独自コンポーネントをContentfulから挿入したいので、その対応を行ったので、記事にしました。
参考になれば幸いです！


# GatsbyでMarkdown内でコンポーネントを使う
以下を使って実装していきます。

https://www.gatsbyjs.com/plugins/gatsby-remark-component/

## 1. プラグインをインストール
npmの方はこちら↓

```sh
$ npm install gatsby-remark-component rehype-react
```

yarnの方はこちら

```sh
$ yarn add gatsby-remark-component rehype-react
```

### インストール有無を確認
念のためインストールできているか確認 :eyes: 

```sh
$ npm ls --depth=0 | grep -P "rehype-react|gatsby-remark-component"

├── gatsby-remark-component@1.1.3
├── rehype-react@6.2.1
```

## 2. gatsby-config.jsを編集

```diff:gatsby-config.js
module.exports = {
  plugins: [
    {
      resolve: `gatsby-transformer-remark`,
      options: {
        plugins: [
+           `gatsby-remark-component`,
        ],
      },
    },
  ],
};
```

## 3. 独自コンポーネント作成
画像とタイトルだけの記事のアイテムをイメージしています。

```js:src/components/CustomComponent.js
import React from 'react'

const CustomComponent = props => (
  <div>
      <p>Custom Component!!!!</p>
  </div>
)

export default CustomComponent
```

## 4. 3で作成したコンポーネントの読み込み

```diff:src/components/PageBody.js
  import React from 'react'
+ import CustomComponent from "../components/CustomComponent"
+ import RehypeReact from "rehype-react"

  ...
  ...
  ...

  const PageBody = props => {
+   const renderAst = new RehypeReact({
+     createElement: React.createElement,
+     components: { "custom-component": CustomComponent }
+   }).Compiler

    return (
-    <Body
-      dangerouslySetInnerHTML={{ __html: props.body.childMarkdownRemark.html }}
-    />
+    <Body>
+      {renderAst(props.body.childMarkdownRemark.htmlAst)}
+    </Body>
    )
  }

  export default PageBody
```

## 5. 4で`renderAst`に渡している`htmlAst`をGraphQLの取得項目に追加

```diff:src/templates/post.js
  export const query = graphql`
    query($slug: String!) {
      contentfulPost(slug: { eq: $slug }) {
        title
        slug
        metaDescription {
          internal {
            content
          }
        }
        publishDate(formatString: "MMMM DD, YYYY")
        publishDateISO: publishDate(formatString: "YYYY-MM-DD")
        tags {
          title
          id
          slug
        }
        heroImage {
          title
          fluid(maxWidth: 1800) {
            ...GatsbyContentfulFluid_withWebp_noBase64
          }
          ogimg: resize(width: 1800) {
            src
          }
        }
        body {
          childMarkdownRemark {
            timeToRead
            html
+           htmlAst
            excerpt(pruneLength: 320)
          }
        }
      }
    }
  `
```

## 6. Markdownにコンポーネントを書く

```md
<custom-component></custom-component>
```

## 7. ビルドする
ビルドします！

# おわりに
やってて気づいたんですが、文字列はpropsで渡せるのですが、画像を渡した際にgatsby-image等に噛ませられないなと、思いました :thinking:

理想は画像も噛ませたいのですが、それには別の方法を考える必要がありそうです :innocent: 
続報をお待ち下さい :pray:

それでは！
[kotlinメモ][LocalDate] 期間が連続しているかを判定したい

## 2021/07/14追記

https://qiita.com/sdkei/items/d452a072ffe5a1b4f7e1

↑かなりスマートにまとまった改善案がありますので、
是非そちらをご覧ください。

---

## はじめに

期間のリストに対し、リスト内の個々の期間を結合した際に歯抜けが出ないかを確認するものです。
リスト内での期間の重なりは許容するものとします。 
例1: `1/1~1/15` と `1/16~1/30` は連続しているのでOKとする
例2: `1/1~1/15` と `1/12~1/30` は一部重なってるけどOKとする
例3: `1/1~1/15` と `1/17~1/30` は歯抜け(1/16)があるのでNGとする

## 用語定義

* 期間
    * ここでは `java.time.LocalDate` 型の開始日と終了日のペアのこと

```kotlin
// 例
    // String->LocalDate変換を逐一書くのが面倒なので拡張関数化します
    val formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd")
    val String.toLocalDate(): LocalDate = LocalDate.parse(
        this, formatter.withResolverStyle(ResolverStyle.STRICT)
    )

    // 期間のリスト
    val ranges = listOf(
        "2020-01-01".toLocalDate() to "2020-01-02".toLocalDate(),
        "2020-01-03".toLocalDate() to "2020-01-04".toLocalDate(),
        "2020-01-05".toLocalDate() to "2020-01-31".toLocalDate(),
        "2020-02-01".toLocalDate() to "2020-02-28".toLocalDate()
    )
```

## コード

```kotlin
    /** 複数の期間が重なるか連続する */
    fun overlaps(vararg ranges: Pair<LocalDate, LocalDate>): Boolean {
        if (ranges.size < 2) return true
        ranges.sortBy { (start, _) -> start }
        if (overlaps(ranges[0], ranges[1])) {
            val (aStart, aEnd) = ranges[0]
            val (_, bEnd) = ranges[1]
            val laterEnd = if (aEnd.isAfter(bEnd)) aEnd else bEnd
            return overlaps(
                Pair(aStart, laterEnd),
                *ranges.slice(2 until ranges.size)
                    .toTypedArray()
            )
        }
        return false
    }

    /** 2つの期間が重なるか連続する */
    fun overlaps(
        aRange: Pair<LocalDate, LocalDate>, bRange: Pair<LocalDate, LocalDate>
    ): Boolean {
        val (aStart, aEnd) = aRange
        val (bStart, bEnd) = bRange
        // 期間Aの開始日 <= 期間Bの終了日+1 && 期間Bの開始日 <= 期間Aの終了日+1
        return aStart.isBefore(bEnd.plusDays(2)) 
            && bStart.isBefore(aEnd.plusDays(2))
    }
```

## 考え方

説明下手なので図示します。
色違いの帯が、それぞれの期間を表しています。
帯の左端が開始日、右端が終了日と考えてください。
![SS 2021-07-11 20.20.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190979/7c080093-6a9c-3497-e703-657e2b4d60a4.png)
まず開始日が若い順にソートします。
![SS 2021-07-11 20.20.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190979/0dfb9fd8-26f2-3d0b-6c2e-5a4fa9ef3e48.png)
期間リストからindex0とindex1を抜き出し、連続あるいは重複していることを確認して結合します。
この際、期間に歯抜けがあったら中断してfalseを返します。
結合できたら、結合した期間とindex2以降の残りの期間とでリストを作り直し、
そのリストに対して上記の結合操作を、リストのサイズが1になるまで続けます。
![SS 2021-07-11 20.22.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190979/d7f6ce91-7325-0863-cd79-9ad5c1b6cf61.png)
リストサイズが1になるまで無事結合できれば、連続しているとみなしてtrueを返します。

## 最後に

まず間違いなく、これよりいい手法が存在すると思います。色々イマイチです。
が、探した範囲では見つからなかったので、自前で組みました。
~~そもそも需要が皆無なのかもしれない~~

改良案・代替案等ありましたら、どうぞよろしくおねがいします。
日々の作業ログファイルとフォルダを作成するバッチファイル

# day.bat
## about
毎朝、１回走らせて、YYYYMMdd.logファイルとYYYYMMddフォルダを作成する。
また、ログファイル、フォルダファイルのショートカットを必要な箇所に設置する。

```batchfile
@echo on
set local
set dt=%date:~0,4%%date:~5,2%%date:~8,2%

REM ログファイル、日々ファイルを作成したい任意のフォルダを設定する
set WORK_ROOT=C:
set LOGDIR=%WORK_ROOT%\@logs
set FILEDIR=%WORK_ROOT%\@files

set TODAYLOG=%LOGDIR%\%dt%.txt
set TODAYDIR=%FILEDIR%\%dt%

set COMDIR="C:\@tool\cmd"

set TODAYLOG_LNK=%COMDIR%\tl.lnk
set TODAYDIR_LNK=%COMDIR%\tf.lnk

REM パラメータがなく、ログファイル、フォルダが存在する場合処理なし
IF "%~1"=="" IF exist %TODAYLOG% IF exist %TODAYDIR% (goto FILE_EXIST)

:NOT_FILE_EXIST
echo "NOT_FILE_EXIST"

REM 実態作成
mkdir %TODAYDIR%
echo %date% > %TODAYLOG%

REM 昨日分のショートカット移動
move %TODAYLOG_LNK% %COMDIR%\tly.lnk
move %TODAYDIR_LNK% %COMDIR%\tfy.lnk

REM フォルダショートカット作成
powershell -Command "$wsh=New-Object -ComObject Wscript.Shell;$sc=$wsh.CreateShortCut('%TODAYDIR_LNK%');$sc.TargetPath='%TODAYDIR%';$sc.save()"

copy %TODAYDIR_LNK% "C:\Users\"%USERNAME%"\Documents\今日のフォルダ.lnk"
copy %TODAYDIR_LNK% "C:\Users\"%USERNAME%"\Downloads\今日のフォルダ.lnk"

REM ログファイルショートカット作成
powershell -Command "$wsh=New-Object -ComObject Wscript.Shell;$sc=$wsh.CreateShortCut('%TODAYLOG_LNK%');$sc.TargetPath='%TODAYLOG%';$sc.save()"

:FILE_EXIST
echo "FILE_EXIST"
exit
```
Unity、NavMeshAgentをつけたオブジェクトをOVR Grabbableしたい場合

Unityで、Nav Mesh Agentをつけた動物をOVR Grabbable対象にしようと思った際にかなり苦戦したのでメモ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34650/4ee4a17d-96d1-5ecf-ee10-03651ef1bb37.png)

# 状況（課題）
* Nav Mesh AgentをつけたゲームオブジェクトをOVR Grabbableでつかめるようにしたい
* しかし、Nav Mesh Agentが有効だと掴めない

# 対応
* Nav Mesh Agentを動的にON/OFFする

# 具体例
* Box Colliderを大きめに設定し、Is TriggerをONにしておく

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34650/97230c70-89a8-8d36-5a0b-0e307f1ad08f.png)

* スクリプト内のOnTriggerEnterで、OVR Playerが近づいたらNav Mesh AgentをOFFにする

```
//NavMeshAgentを取得するための変数
NavMeshAgent m_navmeshagent;

//プレイヤーが近くにいない場合は再び動き出させるためのinvoke関数用のフラグ
bool m_invoke_to_reStartAfterOnCollisionEnter;

void Start()
    {
        //NavmeshAgentを太く
        m_navmeshagent = this.GetComponent<NavMeshAgent>();
　　}

private void OnTriggerEnter(Collider collider)
    {
  //OVR Playerかどうかをタグで判定。この場合は「Player」タグがついているとする
        if (collider.transform.gameObject.CompareTag("Player") && !m_invoke_to_reStartAfterOnCollisionEnter)
        {
            m_invoke_to_reStartAfterOnCollisionEnter = true;

　//Navmesh AgentをOFFにする
            m_navmeshagent.ResetPath();
            m_navmeshagent.enabled = false;

　//Navmesh Agentを再び有効にするためのInvoke。この場合は10秒後に有効にする
            Invoke("ReStartAfterOnCollisionEnter", 10);
        }
    }

    private void ReStartAfterOnCollisionEnter()
    {
        m_navmeshagent.enabled = true;
        m_invoke_to_reStartAfterOnCollisionEnter = false;
    }
```
【第7章】Railsチュートリアルでエラーメッセージに対するテストが書けなかったので復習した

[Railsチュートリアル第7章(第6版)](https://railstutorial.jp/chapters/sign_up?version=6.0#cha-sign_up)-7.3.4.1 演習- でエラーメッセージに対するテストコードの意味が分からず書けなかったので、この機会に復習した。


```
-エラーメッセージをテストするためのテンプレート-
assert_select 'div#<CSS id for error explanation>'
assert_select 'div.<CSS class for field with error>'
```
#①assert_selectメソッド
assert_selectメソッドは様々な指定方法がある。このことがすっかり頭から抜け落ちていたので第5章に戻って再確認。

|Code|マッチするHTML|
|:----|:----|
|assert_select "div"|\<div>foobar\</div>|
|assert_select "div", "foobar"|\<div>foobar\</div>|
|assert_select "div.nav"|\<div class="nav">foobar\</div>|
|assert_select "div#profile"|\<div id="profile">foobar\</div>|
|assert_select "div[name=yo]"|\<div name="yo">hey\</div>|
|assert_select "a[href=?]", '/', count: 1|\<a href="/">foo\</a>|
|assert_select "a[href=?]", '/', text: "foo"|\<a href="/">foo\</a>|

assert_select "div.ほげほげ"はclass属性、
assert_select "div#ふがふが"はid属性をマッチさせることが出来る。

#②パーシャル（partial）
今回のエラーメッセージはユーザー登録失敗時に出力される。
ユーザー登録のViewにおいてエラーメッセージのパーシャルを出力するようにしている。

```
<%= render 'shared/error_messages' %>
```
ここでは、'shared/error_messages'というパーシャルをrender（描画）している。
```render```はRailsヘルパー。

```
-フォーム送信時にエラーメッセージを表示するためのパーシャル-
<% if @user.errors.any? %>
  <div id="error_explanation">
    <div class="alert alert-danger">
      The form contains <%= pluralize(@user.errors.count, "error") %>.
    </div>
    <ul>
    <% @user.errors.full_messages.each do |msg| %>
      <li><%= msg %></li>
    <% end %>
    </ul>
  </div>
<% end %>
```
つまりエラーメッセージが出力されたときにマッチするのは、
***assert_select "div.alert"***
***assert_select "div#error_explanation"*** である。

#まとめ
第5章を復習することで、エラーメッセージに対するテストが書けた。
Powershellを使ったWindows作業ディレクトリ自動化ツール

Powershellを使ってWindows OSで何か作業をするときの作業ディレクトリ自動化ツールを開発いたしました。

```Powershell
#日付を取得する。
$date = Get-Date -Format "yyyyMMdd"
#作業用フォルダー名を取得する
$DIR_PATH = "C:\work\$date"
#作業用フォルダーを作成する
mkdir $DIR_PATH
#正しくmkdirコマンドができたか確認する
if ($? -eq "True")
{
    echo "Success"
}
else
{
    echo "Failure"
    exit 1
}
#フォルダーの存在確認
if (Test-Path $DIR_PATH){
    echo "Success make Folder"
} else {
    echo "Not success make Folder"
    exit 1
}
exit 0
```

Powershellを使った自動化ツールを色々作成しています。今回は作業フォルダーの自動化ツールを記事にしました。
Gitコマンドまとめ

## Gitコマンドまとめ
記載のないコマンドありましたらコメントでお願いします。

|コマンド 　　　　| 挙動 | 備考 |ソースツリー| 
|:-----------|:------------|:------------|:------------|
| git add | ステージに追加 |.をつけるとカレントディレクトリすべてのファイルをステージに追加||
| gitmoji -c | git文字が使える |手順はgit addのあとに打ち込む|[詳しくはこの記事を参照](https://zenn.dev/ogakuzuko/articles/a160fdd8b4b3b8)|
| git commit | リポジトリに追加 |||
| git diff | git addする前の変更差分 |||
| git diff --staged | git addした後の変更差分 |||
| git diff --name-only | 変更したファイルの差分 |||
| git log | 変更履歴の確認 | 最新の方から表示される、-pで変更履歴を確認 ||
| git rim <ファイル名>| ファイルごと削除 |ワークツリー、リポジトリどちらも削除される||
| git rim -r <ディレクトリ名>| ディレクトリごと削除 |||
| git rim --cashed <ファイル名>| ワークツリーには残したいけどGitから削除したい |リポジトリのみ削除される||
| git status| ファイルの変更を確認 |||
| git mv <旧ファイル> <新ファイル>|ファイルの移動を記録する|||
| git remote add origin <githubのurl>|githubにアップする|originにすることで今後urlが要らなくなる||
| git push origin master| リモートリポジトリへ送信する |ローカルからリポジトリに送ることをプッシュという||
| git push -u origin master| 次回以降 git push のみでOK |||
| git config --global alias.ci commit| コマンドに別名をつける |--globalをつけるとPC全体のという意味になる||
| git checkout-- <>| ワークツリーの変更の取り消し |--はブランチ名とファイル名を区別するため、裏では変更されていないステージの状態をワークツリーに反映する||
| git reset HEAD <>| ステージした（git add）の変更の取り消し|ワークツリーの変更はとり消されない、裏ではリポジトリの状態（**最新の**）をステージに変更されている||
| git commit --amend|直前のコミットをやり直す|リモートリポジトリにPUSHした変更はやり直してはだめ||
| git rimote|リモート情報を表示する|URLを表示（-v）||
| git rimote add <リモート名> <リモートURL>|リモートリポジトリの新規登録|今後は<リモート名>でリポジトリを取得、アップしたりすることができる||
| git fetch <リモート名>|リモートから情報を取得する|リモートリポジトリからローカルリポジトリに反映する※ワークツリーには反映されない、remotes/リモート/ブランチ||
| git merge|ローカルリポジトリからワークツリーに反映|||
| git branch -a|リポジトリの確認　＊が今いるブランチ|||
| git pull <リモート名> <ブランチ名>|プルとはリモートリポジトリから一度でワークツリーに反映したい時使う！フェッチ＋マージと同じ|||
| git remote show <リモート名>|リモートの詳細情報を取得!|||
| git remote rename <旧リモート名> <新リモート名>|リモート名変更|||
| git remote rm <リモート名>|リモート削除|||
| git branch <ブランチ名>|ブランチを作成するだけで切り替えはしない|||
| git branch|ブランチの一覧表示、-aをつけるとリモートリポジトリのブランチも表示|||
| git checkout <既存のブランチ名>|ブランチの切り替え|||
| git checkout -b <新規ブランチ名>|ブランチを作成して切り替えまで行う|||
Integromatで個人のGmailアカウントを接続してみた


( *՞ਊ՞*)ﾉ ｵｲｽｰ　ｷﾀ━(ﾟ∀ﾟ)━!

Integromatで個人のGmailアカウントを接続するためには、
「Google Cloud Platform」での設定が必要だったので、備忘録も兼ねて記事にしました。

Integromatの[YouTubeチャンネル](https://www.youtube.com/watch?v=ZbpXTwo1Fjc "Integromat")に方法は載っていたんですが、最近動画制作をはじめたこともあり、その勉強も兼ねて説明動画も作成してみました。テキストより動画を参考にしたい方は動画をご覧ください。

<iframe width="560" height="420" src="https://www.youtube.com/embed/Z2wgS9Dry7s" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>


## Google Cloud Platformの設定

はじめてGoogle Cloud Platformを利用する方は、
まずは、[Google Cloud Platform](https://cloud.google.com/"Google Cloud Platform")でアカウント登録を進めてください。

### プロジェクトの作成
Google Cloud Platformで、今回利用するプロジェクトを作成します。
![IntegromatでGmailアカウント接続する方法.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/766839/84fb2f3f-47d2-3bce-28db-6494f346bf9e.gif)



### Gmail APIの追加
1. サイドバーからダッシュボード画面に移動する
プロダクト＞APIとサービス＞ダッシュボード
![Gmail APIの追加_1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/766839/c468c1ac-0635-6d6d-27b5-61b36c35f77e.gif)



1. Gmail APIを有効化する
![Gmail APIの追加_2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/766839/d5f29277-3edc-3d40-2726-9e55da87797e.gif)


### OAuth同意画面の設定
1.OAuth同意画面の設定ページへ移動する
プロダクト＞APIとサービス＞OAuth同意画面
ユーザー選択は、「外部」を選択してください。

2.アプリ登録の編集
以下の各項目に情報を入力してください。
・アプリ名：Integromat(適当)
・ユーザーサポートメール：hogehoge@gmail.com（ご自身のメールアドレス）
・承認済みドメイン：integromat.com
・デベロッパーの連絡先情報：hogehoge@gmail.com（ご自身のメールアドレス）
![Integromat_アプリ登録編集.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/766839/874b5fe3-6007-3a16-7c7e-f22ad1978023.png)


3.スコープの追加
「スコープを追加または削除」ボタンから、以下の画像に表示されている、７つを追加してください。
![Gmail API.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/766839/616553c8-2acf-ce24-bb72-609ab5b2ff8e.png)


4.テストユーザーの追加
hogehoge@gmail.com（ご自身のメールアドレス）



### 認証情報の作成
認証情報＞認証情報を作成＞OAuthクライアントID
以下の3点を入力してください。
・アプリケーションの種類：ウェブアプリケーション
・名前：Intergromat（適当）
・承認済みのリダイレクトURI：https://www.integromat.com/oauth/cb/google-restricted

![Integromat_認証情報.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/766839/371bf524-8ed4-25e0-f691-fd2eb8edb964.png)

結果、OAuthクライアントが作成されます。
これらの情報をIntegromatとGmailを接続する際に利用します。
![認証情報のIDとシークレット.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/766839/fe664f4a-2835-6a60-7bc1-0b5678358b4a.png)



## Integromatの設定
はじめてIntegromatを利用する方は、
まずは、[Integromat](https://www.integromat.com/?pc=wearenocoders"Integromat")でアカウント登録を進めてください。

### Gmailモジュールの設定
ダッシュボード＞シナリオエディター
Gmailモジュールを設定してください。
![Gmailモジュール.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/766839/aac8dfb8-f3d0-2729-face-18962edfac1f.gif)


### 認証情報の入力
ADDボタン→Show Advanced settingsにチェックを入れて表示された項目に
OAuthクライアント作成時に表示されたクライアントIDとクライアントシークレットを追加してください。

入力後に「Continue」ボタンをクリックしたら完了です＼( ‘ω’)／ﾋｨﾔｯﾊｧｧｧｧｧｧｧｱ！！！



## おわりに
できる限りGIF画像で作成しようと意気込んで初投稿をしようとしたら、
Qiitaって、投稿できる画像の容量が決まっているんですね。。。（泣

これからはいろんなツールの使い方系の記事をぼちぼち投稿しようと思います。

(·:ﾟдﾟ:·)ﾊｧﾊｧ　　ᕙ( ͡° ͜ʖ ͡°)ᕗ
Linux OSの管理ツール Cockpit仮想マシン　後編

[前回](https://qiita.com/fy406/items/ab5ba5d27500b52cc8e6)の続きです。
今回はCockpit仮想マシンの使い方を説明します。

Cockpit-machineを導入すると、CockpitのGUI上で「仮想マシン」の項目が追加されます。
![cp01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/858317/56c5faed-858d-5d53-c21d-43b34f6dcf72.png)

仮想マシンを新規作成するには、上記画面にて`Create VM`をクリックします。
すると以下のような画面が表示されます。

![cp02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/858317/8277b041-877d-626f-acad-b255498b8df5.png)

各項目については以下の通りです。
ちなみにインストール可能なOSはLinux系OSだけではなく、Windowsも可能です。
Mac系についてはOSイメージを持っていないので不明です。

```
1.Connectionは、ひとまずデフォルトのままで良い
2.Nameは仮想マシン名を入力する　※ここで設定した仮想マシン名は仮想マシンのホスト名として設定される訳ではない
3.Installation Source TypeはOSイメージの指定方法を選択する
　ホストマシンにOSのイメージファイルをコピーしていればデフォルトのLocal Install Mediaでよい
4.Install SourceにはOSイメージファイルの場所をフルパスで指定する
5.Storageもデフォルトで良い
6.Sizeは仮想マシンに割当するストレージ容量を指定する　※CentOSの場合は最低でも10GB以上必要
7.Memoryは仮想マシンに割当するRAMの容量を指定する
8.OS Vendorにはインストール対象のOSを選択する
9.Operating Systemにはインストール対象OSのバージョンを指定する　※CentOS 7の場合は7
```

設定できましたら、`Create`ボタンをクリックします。
すると画面内に作成した仮想マシンが追加されていますので、それをクリックし、仮想マシンの情報を表示させます。
Overviewには仮想マシンのRAM容量や仮想CPUの割当数等が表示されます。

![cp03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/858317/8658944d-09b3-a5a9-4dff-ad63cdbcd18f.png)
Usageには仮想マシン起動後のCPUとRAMの使用率が表示されます。
当然、起動していない状態だと以下のように0%のままです。
![cp04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/858317/9ab9a399-76c8-18ef-335d-cdc14cc0b22b.png)
Disksには仮想マシンに割当しているストレージの情報が記載されています。
ここで新しくストレージを追加する事もできそうです。
![cp05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/858317/65b0853d-e873-a174-d104-f82d07955280.png)
Network Interfacesでは仮想マシンで使用しているネットワークインターフェースの情報を表示します。
![cp06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/858317/636cb601-fb2b-392d-76c8-1f1db4984bbe.png)
Consolesでは仮想マシンの操作をするためにCUIやGUIの画面を表示させる事ができます。
停止させている状態だと以下画面のように何も表示されません。
画面右側にある`Install`ボタンをクリックしますと、仮想マシンのインストールが開始されます。
インストールの操作は、このConsoles画面で実施します。
インストールの操作自体は対象仮想マシンのOSにより異なります。
なお、仮想マシンのインストール後は`Install`ボタンが`Start`ボタンに変わります。`Start`ボタンをクリックしますと仮想マシンが起動されます。
![cp07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/858317/0037b7f5-9cc1-415d-e2a8-01e2e5cd2da8.png)

Cockpit-machineの使い方は以上となります。
AtCoder 精選過去問を解いてみた Part 3【Ruby】

#【AtCoder 精選過去問を解いてみた Part 3】

何番煎じかわかりませんが、@drkenさんの[AtCoder に登録したら次にやること ～ これだけ解けば十分闘える！過去問精選 10 問 ～](https://qiita.com/drken/items/fd4e5e3630d0f5859067)をRを解いてみました。

詳細な解説は、@drkenさんの記事を参照ください。
LGTM6000超えの優良記事です。

Rubyを用いて、過去問を解きました。
解答に誤りなどありましたらご指摘いただけますと幸いです。

## 第7問 : [ABC 085 B - Kagami Mochi](https://beta.atcoder.jp/contests/abc085/tasks/abc085_b) （200点）

**問題文**
X段重ねの鏡餅(X ≥ 1)とは、枚の円形の餅を縦に積み重ねたものであって、どの餅もその真下の餅より直径が小さい（一番下の餅を除く）もののことです。
例えば、直径10、8、6センチメートルの餅をこの順に下から積み重ねると3段重ねの鏡餅になり、餅を一枚だけ置くと1段重ねの鏡餅になります。
あなたはN枚の円形の餅を持っていて、そのうちi枚目の餅の直径はdiセンチメートルです。
これらの餅のうち一部または全部を使って鏡餅を作るとき、最大で何段重ねの鏡餅を作ることができるでしょうか。

**制約**
・1 ≤ N ≤ 100
・1 ≤ di ≤ 100
・入力値はすべて整数である。

```ruby:Ruby
# 整数の入力
n = gets.to_i
ans = n.times.map { gets.to_i }
# 「何段積み上げられるか」を出力
# uniqメソッド：配列から重複を取り除く
puts ans.uniq.length
```

## 第8問 : [ABC 085 C - Otoshidama](https://beta.atcoder.jp/contests/abc085/tasks/abc085_c) （300点）

**問題文**
日本でよく使われる紙幣は、10000円札、5000円札、1000円札です。
以下、「お札」とはこれらのみを指します。
お年玉袋にはお札がN枚入っていて、合計でY円だったそうですが、嘘かもしれません。
このような状況がありうるか判定し、ありうる場合はお年玉袋の中身の候補を一つ見つけてください。
なお、お年玉袋は十分大きかったものとします。

**制約**
・1 ≤ N ≤ 2000
・1000 ≤ Y ≤ 2×10の7乗
・Nは整数である。
・Yは1000の倍数である。

```ruby:Ruby
# スペース区切りの整数の入力
n, y= gets.chomp.split.map(&:to_i)
# ありえない場合の初期値：-1
xi, xj, xk = -1, -1, -1
# nまで繰り返す。
(0..n).each do |i|
    (0..n - i).each do |j|
       if i * 10000 + j * 5000 + (n - i - j) * 1000 == y
        xi, xj, xk = i, j, n - i - j
       end
    end
end
# 出力
puts "#{xi} #{xj} #{xk}"
```

## 第9問 : [ABC 049 C - Daydream](https://beta.atcoder.jp/contests/abc049/tasks/arc065_a) （300点）

**問題文**
英小文字からなる文字列Sが与えられます。 
Tが空文字列である状態から始め、以下の操作を好きな回数繰り返すことで、S = Tとすることができるか判定してください。

　・Tの末尾に dream dreamer erase eraser のいずれかを追加する。

**制約**
・1 ≤ |S| ≤ 10の5乗
・Sは英小文字からなる。

```ruby:Ruby
# データの入力
s = gets.chomp.to_s
# %w：配列を要素はスペース区切りで作る。
# gsub：マッチした部分をすべて置換
%w(eraser erase dreamer dream).each{ |w| s = s.gsub(w," ") }
s = s.gsub(" ","")
# 出力
puts s == "" ? "YES" : "NO"
```

##おわりに。

今回は、第10問は解くのをやめました。
まだまだ理解が浅いので復習します。
その後、第10問を解きます

[Part 1【練習〜第3問】](https://qiita.com/uejima_haruki/items/e594e48c897690567919)
[Part 2【第4問〜第6問】](https://qiita.com/uejima_haruki/items/2bb78d8ce958a7d8e658)

##参考

[AtCoder に登録したら解くべき精選過去問 10 問を Ruby で解いてみた
](https://qiita.com/d_nishiyama85/items/f79e034f6dcd4175cdc1)[AtCoder に登録したら解くべき精選過去問 10 問を Ruby・Crystal の両方で動くコードで解いてみた](https://qiita.com/universato/items/8a6c311b4db5615fc50a)

ありがとうございました。
AtCoder 精選過去問を解いてみた Part 2【Ruby】

#【AtCoder 精選過去問を解いてみた Part 2】

何番煎じかわかりませんが、@drkenさんの[AtCoder に登録したら次にやること ～ これだけ解けば十分闘える！過去問精選 10 問 ～](https://qiita.com/drken/items/fd4e5e3630d0f5859067)を解いてみました。

詳細な解説は、@drkenさんの記事を参照ください。
LGTM6000超えの優良記事です。

Rubyを用いて、過去問を解きました。
解答に誤りなどありましたらご指摘いただけますと幸いです。

## 第4問 : [ABC 087 B - Coins](https://beta.atcoder.jp/contests/abc087/tasks/abc087_b) （200点）

**問題文**
あなたは、500円玉をA枚、100円玉をB枚、50円玉をC枚持っています。 
これらの硬貨の中から何枚かを選び、合計金額をちょうどX円にする方法は何通りありますか。
同じ種類の硬貨どうしは区別できません。
2通りの硬貨の選び方は、ある種類の硬貨についてその硬貨を選ぶ枚数が異なるとき区別されます。

**制約**
・0 ≤ A,B,C ≤ 50
・A + B + C ≥ 1
・50 ≤ X ≤ 20,000
・A,B,Cは整数である。
・Xは50の倍数である。

```ruby:Ruby
# 整数の入力
a, b, c, x = 4.times.map { gets.to_i }
cnt = 0
# それぞれ繰り返す。
(0..a).each do |i|
    (0..b).each do |j|
        (0..c).each do |k|
            # それぞれの和が、xと同じになるか。
            cnt += 1 if i * 500 + j * 100 + k * 50 == x
        end
    end
end
# 「合計金額をちょうどにするcnt通り」を出力
puts cnt
```

## 第5問 : [ABC 083 B - Some Sums](https://beta.atcoder.jp/contests/abc083/tasks/abc083_b) （200点）

**問題文**
1以上N以下の整数のうち、10進法での各桁の和がA以上B以下であるものの総和を求めてください。

**制約**
・1 ≤ N ≤ 10の4乗
・1 ≤ A ≤ B ≤ 36
・入力は全て整数である。

```ruby:Ruby
# スペース区切りの整数の入力
n, a, b = gets.chomp.split.map(&:to_i)
ans = 0
# nまで繰り返す。
(1..n).each do |i|
    # 文字列に対して、charsメソッドは、1文字ずつ分割
    s = i.to_s.chars.map(&:to_i).sum
    ans += i if a <= s && s <= b
end
# 「n以下の整数のうち、各桁の和がa以上b以下の総和」を出力
puts ans
```

## 第6問 : [ABC 088 B - Card Game for Two](https://beta.atcoder.jp/contests/abc088/tasks/abc088_b) （200点）

**問題文**
N枚のカードがあります。i枚目のカードには、aiという数が書かれています。
AliceとBobは、これらのカードを使ってゲームを行います。
ゲームでは、AliceとBobが交互に1枚ずつカードを取っていきます。Aliceが先にカードを取ります。
2人がすべてのカードを取ったときゲームは終了し、取ったカードの数の合計がその人の得点になります。
2人とも自分の得点を最大化するように最適な戦略を取った時、AliceはBobより何点多く取るか求めてください。

**制約**
・Nは1以上100以下の整数
・ai(1 ≤ i ≤ N)は1以上100以下の整数

```ruby:Ruby
# 整数の入力
n = gets.to_i
# スペース区切りの整数の入力し、昇順に並び替えて、逆順にして、大きい順にする。
a = gets.chomp.split.map(&:to_i).sort.reverse
ans = 0
#　eachループで回しつつ、それぞれのデータに番号を振る
# even?：偶数であれば真を返す。
a.each_with_index{|item,i| ans += i.even? ? item : -item }
# 「得点差」を出力
puts ans
```

##おわりに。

Part1よりも難易度が上がった気がします。
以降の問もやっていきます。

[Part 1【練習〜第3問】](https://qiita.com/uejima_haruki/items/e594e48c897690567919)
[Part 3【第7問〜第9問】](https://qiita.com/uejima_haruki/items/3981236950c04d565874)

##参考

[AtCoder に登録したら解くべき精選過去問 10 問を Ruby で解いてみた
](https://qiita.com/d_nishiyama85/items/f79e034f6dcd4175cdc1)[AtCoder に登録したら解くべき精選過去問 10 問を Ruby・Crystal の両方で動くコードで解いてみた](https://qiita.com/universato/items/8a6c311b4db5615fc50a)

ありがとうございました。
AtCoder 精選過去問を解いてみた Part 1【Ruby】

#【AtCoder 精選過去問を解いてみた Part 1】

何番煎じかわかりませんが、@drkenさんの[AtCoder に登録したら次にやること ～ これだけ解けば十分闘える！過去問精選 10 問 ～](https://qiita.com/drken/items/fd4e5e3630d0f5859067)を解いてみました。

詳細な解説は、@drkenさんの記事を参照ください。
LGTM6000超えの優良記事です。

Rubyを用いて、過去問を解きました。
解答に誤りなどありましたらご指摘いただけますと幸いです。

## 練習 ： [A - Welcome to AtCoder](https://atcoder.jp/contests/practice/tasks/practice_1)

**問題文**
整数a,b,cと文字列sが与えられます。 a+b+cの計算結果と文字列sを並べて表示してください。

**制約**
・1 ≤ a,b,c ≤ 1,000
・1 ≤ |s| ≤ 100

```ruby:Ruby
# 整数の入力
a = gets.to_i
# スペース区切りの整数の入力
b, c = gets.chomp.split.map(&:to_i)
# 文字列の入力
s = gets.chomp
# 出力
puts "#{a+b+c} #{s}"
```

## 第1問 : [ABC 086 A - Product](https://beta.atcoder.jp/contests/abc086/tasks/abc086_a) （100点）

**問題文**
二つの正整数a,bを見つけました。aとbの積が偶数か奇数か判定してください。

**制約**
・1 ≤ a,b ≤ 10000
・a,b：整数

```ruby:Ruby
# スペース区切りの整数の入力（1行に複数の数値が入力された時の鉄板）
a, b = gets.chomp.split.map(&:to_i)
# 偶数奇数を判定する組み込みメソッド
puts (a * b).odd? ? 'Odd' : 'Even'
```

## 第2問 : [ABC 081 A - Placing Marbles](https://beta.atcoder.jp/contests/abc081/tasks/abc081_a) （100点）

**問題文**
1,2,3の番号がついた3つのマスからなるマス目を持っています。
各マスには0か1が書かれており、マスiにはsiが書かれています。
1が書かれたマスにビー玉を置きます。 
ビー玉が置かれるマスがいくつあるか求めてください。

**制約**
・s1,s2,s3：1あるいは0

```ruby:Ruby
# N行のデータの入力
n = gets.chomp.to_s
# 「1」をカウントする
puts n.count("1")
```

## 第3問 : [ABC 081 B - Shift Only](https://beta.atcoder.jp/contests/abc081/tasks/abc081_b) （200点）

**問題文**
黒板にN個の正の整数A1,...,ANが書かれています。
黒板に書かれている整数がすべて偶数であるとき、次の操作を行うことができます。
　・黒板に書かれている整数すべてを、2で割ったものに置き換える。
最大で何回操作を行うことができるかを求めてください。

**制約**
・1 ≤ N ≤ 200
・1 ≤ Ai ≤ 10の9乗

```ruby:Ruby
# N行のデータの入力
n = gets.chomp.to_s
# スペース区切りの整数の入力
a = gets.chomp.split.map(&:to_i)
cnt = 0
# 全てが偶数であるか判定する：all?
while a.all?(&:even?) do
    a = a.map { |t| t / 2 }
    # インクリメント
    cnt += 1
end
# 「2で割れた回数」を出力
puts cnt
```

##おわりに。

この記事の問は、まだ理解がしやすかったです。
以降の問もやっていきます。

[Part 2【第4問〜第6問】](https://qiita.com/uejima_haruki/items/2bb78d8ce958a7d8e658)
[Part 3【第7問〜第9問】](https://qiita.com/uejima_haruki/items/3981236950c04d565874)

##参考

[AtCoder に登録したら解くべき精選過去問 10 問を Ruby で解いてみた
](https://qiita.com/d_nishiyama85/items/f79e034f6dcd4175cdc1)[AtCoder に登録したら解くべき精選過去問 10 問を Ruby・Crystal の両方で動くコードで解いてみた](https://qiita.com/universato/items/8a6c311b4db5615fc50a)

ありがとうございました。
gnuplotでヒストグラムをつくる

ヒストグラムを書くとき、gnuplotを使えばソフトは必要ないし、プログラムも書く必要ないので楽。
大学の授業でボックスミュラー法の確認のために使った。また何をしているのか調べるのが面倒なのでメモ。

gnuplotを起動して以下を入力すればおっけー。
```hoge.dat```が入力データ。

```
set style fill solid
filter(x,y)=floor(x/y)*y
plot "hoge.dat" u (filter($1,0.01)):(1) smooth frequency with boxes
```

まず、```set style fill solid```でスタイルを図形塗りつぶしに変更。
後に行う箱プロットの中身を塗りつぶす。

次に、```filter(x,y)=floor(x/y)*y```でフィルタを定義。
このフィルタは関数のようなもので、```x```を```y```の幅に丸めることができる。
例えば、0.11245のような値を0.01幅で丸めるとき、```x/y```で11.245にしたものを```floor```で11にして、再度0.01倍することで0.11に丸めている。

最後に、```plot "hoge.dat" u (filter($1,0.01)):(1) smooth frequency with boxes```でヒストグラムのプロット。
```u```は```using```の略記。
```smooth frequency```で```u a:b```とすれば、「同じaが現れれときそのaの登場回数につき頻度をb増やす」といったことが実現できる。
今回はここでの```x```に```filter```を使って、データを0.01幅で丸めたものが等しければその値に属する頻度を1増やしている。
```with boxes```で頻度の箱を表示しておしまい。


こんな感じになる。
![kadai13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563211/e602feaf-2f47-2a18-e898-68f39e885ff9.png)
【CSSフレームワーク "Zurb Foundation"】を使って超シンプルなフォーム画面を作成する

Zurb社のCSSフレームワーク "Zurb Foundation"を使って超シンプルなフォーム画面を作成します。

CSSフレームワークはいろんな種類があって普段使っているBootstrap以外でも、他のフレームワークのお作法やクセを知っておくことは重要だと思いめちゃくちゃシンプルですがサンプルを作りました。

```sample.html
<!DOCTYPE html>
<meta>
<head>
<!--Foundation 共通-->
<!-- Compressed CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/foundation-sites@6.6.3/dist/css/foundation.min.css" integrity="sha256-ogmFxjqiTMnZhxCqVmcqTvjfe1Y/ec4WaRj/aQPvn+I=" crossorigin="anonymous">

<!-- Compressed JavaScript -->
<script src="https://cdn.jsdelivr.net/npm/foundation-sites@6.6.3/dist/js/foundation.min.js" integrity="sha256-pRF3zifJRA9jXGv++b06qwtSqX1byFQOLjqa2PTEb2o=" crossorigin="anonymous"></script>
<!--個別ファイル-->
<link rel="stylesheet" href="./index.css" />
</head>
<body>
    <!--グリッドシステムを導入する-->
    <form>
        <div class="grid-container">
        <div class="grid-x grid-padding-x">
            <div class="medium-6 cell">
                <!--名前（姓）のLabelセクション-->
                <div class="firstNameLabelArea">
                    <label class="firstNameClass">
                        名前（姓）
                    </label>
                </div>
                <!--名前（姓）のInputセクション-->
                <div class="firstNameInputArea">
                    <input type="text" class="firstNameInputClass" id="firstNameInput" />
                </div>
            </div>
            <div class="medium-6 cell">
                <!--名前（名）のlabelセクション-->
                <div class="lastNameArea">
                    <label class="lastNameLabelClass">
                        名前（名）
                    </label>
                </div>
                <!--名前（名）のInputセクション-->
                <div class="lastNameInputArea">
                    <input type="text" class="lastNameInputClass" id="lastNameInput" />
                </div>
            </div>
        </div>
        </div>
    </form>
</body>

</html>
```

CSSフレームワークをしっかりと使いこなすことが出来れば、費用の大半は人件費と言われる経費の削減にも貢献できると思っているのでBootstrap以外のフレームワークの知識や技術を吸収していきます。

【完成例】
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1169664/af9aaf37-070c-e040-4d83-1c4e42cd821d.png)

【Zurb Foundation フォームの公式サンプル】
Forms
URL:https://get.foundation/sites/docs/forms.html

以上です。
一つの画面で縦と横スクロールできるようにする


## 前提
- Flutter 2.2.0 stable

## 縦と横スクロールを行うには
- このWidgetを使います
    - CustomScrollView
    - SliverChildBuilderDelegate

## 注意点
- リストアイテムの高さを指定する必要があるようです。
    - CustomScrollViewをSizedBoxでラップして
        - 仮に `height: 50,`　と指定しています

## こんな感じになります

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267662/8945e03a-b349-291e-0025-da6e43b4e1d3.gif" width="400">


## 作ったWidget

- 縦 50個
- 横 50個

```

class MultiCustomScrollView extends StatelessWidget {
  const MultiCustomScrollView({Key? key}) : super(key: key);


  @override
  Widget build(BuildContext context) {
    return Expanded(
      child: CustomScrollView(
        scrollDirection: Axis.vertical,
        slivers: [
          SliverList(
            delegate: SliverChildBuilderDelegate(
              (BuildContext context, int verticalIndex) {
                return SizedBox(
                  height: 50,
                  child: CustomScrollView(
                    scrollDirection: Axis.horizontal,
                    slivers: [
                      SliverList(
                        delegate: SliverChildBuilderDelegate(
                          (BuildContext context, int horizontalIndex) {
                            return SizedBox(
                              height: 50,
                              child: Padding(
                                padding: const EdgeInsets.all(8.0),
                                child: Text(
                                  'test${(verticalIndex + 1) * (horizontalIndex + 1)}',
                                ),
                              ),
                            );
                          },
                          childCount: 50,
                        ),
                      ),
                    ],
                  ),
                );
              },
              childCount: 50,
            ),
          ),
        ],
      ),
    );
  }
}

```

以上です。
【論文紹介】Transformerを用いた自動要約タスクの事前学習：PEGASUS


## はじめに
[Transformer](https://arxiv.org/abs/1706.03762)を用いた自動要約モデル「[PEGASUS](https://arxiv.org/abs/1912.08777)」についてまとめました。
難易度が高いタスクとされていた自動要約においても、Transformerの学習方法を工夫することで人の手による要約と遜色ないレベルに達しています。

## 要約を作成する方法
自動要約には主に抽出型(Extractive)と抽象型(Abstractive)の2つのアプローチがあります。

## 抽出型
抽出型は、要約対象の文章の中から重要と思われる文を抽出して要約を作成するというアプローチです。文を抜き出しているだけなので変な文になる心配はありませんが、自然な要約文にはなりにくいです。

## 抽出型
抽象型は、機械翻訳にも用いられるEncoder-Decoderモデルなどを利用して、文章の意味を汲み取ったうえで(=抽象化した上で)適切な要約を作成する手法です。自然な要約を作成できるメリットはありますが、難易度は高いです。

## アーキテクチャ

### モデル
[BERT](https://arxiv.org/abs/1810.04805)の事前学習は Masked Language Model (MLM) と呼ばれる、入力単語の一部をマスクトークンに変えてモデルに入力し、その単語を前後の文脈から予測する方法をとっています。
<img width=500 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614092/0a114e7d-9f91-1c57-079a-fbe2756d3b45.png">

この研究では**抽象型の要約モデル**を作成しています。事前学習としてMLMに加えて、Gap Sentences Generation (GSG) という、文にマスクをかけて予測する方法をとっています。初見では要約タスクと関係ないのでは？と思いましたが、冷静に考えると、BERTでMLM事前学習を行ったあとに文書分類を行う場合も、事前学習と主タスクがあんまり関係ない気がしました。論文では色んな方法を試した結果、事前学習として最善手だと言っています。
![image1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614092/f786d81e-f9c3-614f-2ab3-cdb6bcffa6e5.gif)
画像元：https://ai.googleblog.com/2020/06/pegasus-state-of-art-model-for.html


モデルは以下のようになっており、真ん中の文をDecoderで予測しつつ、MLM学習をEncoderで行っています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614092/d1c42402-08eb-5011-c5e4-3dc8950e17a5.png)

### 事前学習用データ

* C4：３億5000万件のweb page
* HugeNews：15億件のニュース文章

事前学習と主タスクのドメインが似ている方が高い要約精度だったそうです。
例えば、twitterのテキストで事前学習を行うと主タスクは砕けた表現に強いだろうし、ニュース文章で事前学習を行うと主タスクは堅めの文章に強いというイメージです。

## 評価指標
生成された要約文と人が書いた要約文の近さを測るために**ROUGE1-F1**を使います。ROUGEについては[こちら](https://qiita.com/icoxfog417/items/65faecbbe27d3c53d212)が詳しいです。翻訳で使われるBLEUもそうですが、基本的に人の評価と相関の高い評価指標が用いられます。

## 結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614092/7e80c572-50ea-cf6b-b84d-c1f51ddb640c.png)

12件の要約データセットに対してSOTAを達成しています。

## おわりに
文生成タスクにも事前学習が猛威をふるっていて驚きました。要約タスク以外にも色んな応用があると思います。
M1 Macをセットアップする

# 環境

MacBook Air (M1, 2020)

# Homebrew

https://brew.sh

トップページのコマンドをコピーする。

Terminal.appを開き、コピーしたコマンドをペーストする。

パスを通すように言われるが、既存のシェルは使わないので、一旦無視する。

`/opt/homebrew/bin/brew install` で必要なものをインストールする。

ここでは、`zsh`、`git`、`tig`、`vim`、`rcm`、`fzy`、`coreutils`、`curl`をインストールする。

```
/opt/homebrew/bin/brew install zsh git tig vim rcm fzy coreutils curl
```

# 使用するシェルの切り替え

既存のシェルから、HomebrewでインストールしたZshに切り替える。

```
sudo vim /etc/shells
```

追記する: `/opt/homebrew/bin/zsh`

下記コマンドでシェルを切り替え、シェルを再起動する。

```
chsh -s /opt/homebrew/bin/zsh
```

# 好みのdotfilesをインストール

ここでは、[lowerworld](https://github.com/lowerworld)さんのdotfilesを使用する。

```
git clone --recursive https://github.com/lowerworld/dotfiles.git .dotfiles
```

リポジトリにsubmodulesを含むので、`--recursive`オプションを付けてホームディレクトリ配下の`.dotfiles`ディレクトリにクローンする。

Zshの設定ファイルのシンボリックリンクを作成し、シェルを再起動する。

```
ln -s .dotfiles/tag-zsh/zshrc .zshrc
```

シェルを再起動すると設定ファイルが読み込まれ、不足しているプラグインのインストールが行われる。

```
- zsh-users/zsh-completions: not installed
- zsh-users/zsh-syntax-highlighting: not installed
- yous/vanilli.sh: not installed
- b4b4r07/enhancd: not installed
[zplug] Start to install 4 plugins in parallel

 ✔  Installed!            zsh-users/zsh-completions
 ✔  Installed!            zsh-users/zsh-syntax-highlighting
 ✔  Installed!            b4b4r07/enhancd
 ✔  Installed!            yous/vanilli.sh

[zplug] Elapsed time: 2.2501 sec.
 ==> Installation finished successfully!
```

# Homebrewのパスを通す

下記コマンドを実行:

```
export PATH=/opt/homebrew/bin:${PATH}
```

これでHomebrewでインストールした`rcm`にもパスが通ったので、他のdotfilesもインストールする。

```
rcup -t homebrew
rcup -t vim
```

`.gitconfig`をシステム全体で有効にする。

```
cp .dotfiles/.etc/gitconfig /opt/homebrew/etc
```

# エイリアスの設定

ホームディレクトリ配下の`.config/zshrc.d`に移動し、`aliases.zsh`を編集する。

```
vim aliases.zsh
```

追記する: `alias ls='gls'`

シェルを再起動すると、`ll`コマンドが使えるようになる。
【CSSフレームワーク TailWind CSS】"グリッドシステム"を使った超シンプルなサンプルを作る。

CSSフレームワーク"tailwindcss"でグリッドシステムを使ったサンプルについてです。

皆さんもなじみ深いメジャーなCSSフレームワーク『Bootstrap』ではwebページを12等分に分割して開発する"グリッドシステム"が採用されています。

この"グリッドシステム"を活用するメリットとして"シンプルで開発や改修しやすい"という理由が挙げられます。
少ないコ－ドでユーザフレンドリーなWebサイトを開発するためには"グリッドシステム"という考え方が不可欠です。

今回は"tailwind css"というフレームワークを使って"グリッドシステム"を活用した超シンプルなサンプルを作ってみました。

```sample.html
<!Doctype html>
<html>
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <!--tailwind cssをCDN経由で読み込み-->
  <link href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet">
</head>
<body>
  <div class="container mx-auto">
    <!--/*2行分の行を取得する*/-->  
    <div class="grid grid-rows-2">
        <!--/*2分割したカラム幅を取得する。*/-->
        <div class="grid grid-cols-2">
            <!--名前（姓）のエリア-->
            <div class="firstNameArea">
                <!--Labelエリア-->
                <div class="firstNameLabelArea">
                    <label class="firstNameClass">名前（姓）</label>
                </div>
                <!--inputエリア-->
                <div class="firstNameInputArea">
                    <input type="text" class="firstNameInputClass border border-black" id="firstNameInput" placeholder="名前（姓）"/>
                </div>
            </div>
            <!--名前（名）のエリア-->
            <div class="lastNameArea">
                <!--Labelエリア-->
                <div class="lastNameLabelArea">
                    <label class="lastNameClass">名前（名）</label>
                </div>
                <!--inputエリア-->
                <div class="lastNameInputArea">
                    <input type="text" class="lastNameInputClass border border-black" id="lastNameInput" placeholder="名前（名）"/>
                </div>
            </div>
        </div>
    </div>
  </div>
</body>
</html>
```

普段触っているBootstrap以外にも他のCSSフレームワークでもサンプルを作成することで各フレームワークごとのクセを理解しつつ技術力をもっともっと上げたいと思っています。


【表示結果】
![画像4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1169664/8d17f2b1-7b35-d44c-990f-7e9bd28c1252.png)

【参考サイト】
■tailwindcss Grid Template Rows
URL:https://tailwindcss.com/docs/grid-template-rows

■tailwindcss Grid Template Columns
URL:https://tailwindcss.com/docs/grid-template-columns