OmniAICreator/Qiita-1.07M huggingface dataset:
.NET 5 の移行事例 FAQ編

この記事は、[求ム！Cloud Nativeアプリケーション開発のTips！【PR】日本マイクロソフト Advent Calendar 2020](https://qiita.com/advent-calendar/2020/azure-cloudnative) の 8 日目です（後から追っかけで書いています）。

----

# 目次
本記事は .NET 5 の移行事例についてご紹介します。

1. [.NET 5 の移行事例 FAQ編](https://qiita.com/changeworld/items/20a69613609e37d43085) ← イマココ

2020 年 11 月 10 日、.NET 5 がリリースされました。そんな、.NET 5 への移行について、よくある質問とその回答についてまとめました。

## Q1. 絶対に .NET 5 へ移行しないといけないか？

2020 年 11 月からフレームワークの廃止を開始することから、**必ず移行する必要があります**(*1)。

*1:とはいえ、東証一部上場企業でも EOL な Java 6 や Python 2 を業務の根幹となっているサービスでサポートなしで平気で使い続けている事例を数多く知っているので、そういう意味では移行しないという選択肢も当然ながらあります。

.NET 5 は .NET Core 系列であるため、.NET Core から .NET 5 への移行の場合は比較的簡単です。

## Q2. .NET 5 の移行にかかるコストはどの程度？

.NET 5 はオープンソース開発プラットフォームであり、利用自体にはコストはかかりません。移行作業自体にはコスト（人的リソース、時間的リソース）を要します。コストがどの程度になるのかは、使用している .NET のバージョンによって千差万別なので、一概には言えませんが、古いバージョン程、そのまま置き換えなしでのアップデートができないので、コストがかかります。

## Q3. 移行ってどうだった？

上にも書いていますが、ここのケースによって千差万別です。
以下のケースでは、移行は容易です。

* .NET Core 3.x を使用している

以下のケースでは、移行は容易ではありませんでした。

* .NET Core 3.x を使用していない
* .NET Framework で作ってある

特に後者のケースはかなりしんどかったです（が、しんどさから開放される裏技もあります）。

**9 日目は @changeworld の「[軽量で爆速にコンテナを使える Azure Container Instances !](https://qiita.com/changeworld/items/7589d331774f7188d411)」です。引き続きお楽しみください。**
IntelliJ IDEAのHTTPクライアントで、マルチパートのパラメータやファイルを渡す

# 概要

RubyMineなどのJetBrains系IDEにはREST APIを扱うためのHTTP Clientがついている。
標準的な説明は[公式サイト](https://www.jetbrains.com/help/idea/http-client-in-product-code-editor.html)に載っているが、複数のパラメータを渡すときどうすればいいのかが明記されてない気がしたので、そのメモ。

## 記述方法

```rest-api.http
POST http://localhost/api/v1/upload_image_with_product_id/
Content-Type: multipart/form-data; boundary=WebAppBoundary

--WebAppBoundary
Content-Disposition: form-data; name="product_id"

114514
--WebAppBoundary--

--WebAppBoundary
Content-Disposition: form-data; name="user_id"

810
--WebAppBoundary--

--WebAppBoundary
Content-Disposition: form-data; name="memo"

これこれこういう画像です。
--WebAppBoundary--

--WebAppBoundary
Content-Disposition: form-data; name="file"; filename="comic.png"

< c:\temp\comic.png

###
--WebAppBoundary--

```

単純にパラメータ欄をそれぞれ作ってあげればいいらしい。


## 便利な操作

### テンプレート展開

HTTPクライアントの編集画面で、`ctrl+J` (macだと`⌘+J`かな?)を押すと、リクエストのテンプレートが表示される。
もちろん直接 `mptp`(TAB)とかでも展開できる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23242/8b2b7a26-da7f-3d68-aaa6-5bef454ef95d.png)


### cURLに変換してコピー

リクエストを右クリックして出てくるメニューでは、curlコマンドに変換してクリップボードにコピーできる。地味に便利。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23242/1f9f49ca-3bf7-4f15-00a5-320f3a1fe6c2.png)
ボタンクリック時にslackにメッセージを投稿する処理をzapierのwebhookを使って自動化してみた

#実現したいこと
ボタンクリック時にzapierに飛んで、Aボタンを押した時はslackのchanelAへ、Bボタンを押した時はchanelBへメッセージを投稿する機能。


##trigerの選択
まずはtrigerとなるツールを選択します。
今回の場合は以下のwebhookを選びます。
![スクリーンショット 2020-12-24 13.13.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351843/f378080c-8481-638b-8645-3094d77ff2f4.png)

###choose an event
今回は**Catch Hook**を選択。

###set up trigger
この時点でエンドポイントを自動生成してくれるので、このURLを保存しておきます。

###test trigger
triggerがちゃんと機能するかここでチェックしておきましょう。
先ほど取得した[エンドポイント + "?key=value"]にアクセスしてみてください。(クエリごとに処理を変えるため、クエリパラメータをつけましょう。)
その後テストを確認してみると、以下のようにquerystringが取得できていればok。(今回のクエリパラメータは"?type=hoge")
![スクリーンショット 2020-12-24 13.35.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351843/bcd5087c-03c9-eb33-7810-9c69793fc9d2.png)


##actionの選択
一つの処理のみしたい場合はそのままslackを選択すればいいのですが、今回の場合はボタンごとに処理を分岐させたいので**Path**を選択しましょう。
![スクリーンショット 2020-12-24 13.24.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351843/156a865e-b7cc-1f52-3045-c7ea59558ea5.png)

###分岐条件の設定
分岐の名前をつけて、今回の条件を設定しましょう。typeがAと完全に一致するときにこの分岐に入ります。ボタンクリック時には"type=A"とクエリパラメータを指定してあげます。もう一方の分岐も同様です。
![スクリーンショット 2020-12-24 13.26.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351843/208b3bc7-1bad-c893-8cb4-be52c200af77.png)

###Actionの設定
slackを選択し、action Eventに**send Channel Message**を指定。
あとは、アカウントを指定し、送りたいチャンネルとメッセージを記述すればok。


#参考
今回エンドポイントトリガーとして使用したサンプルコードを記載しておきます。

```sample.html
<!DOCTYPE html>
<html>
  <head>
    <title></title>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <script language="javascript" type="text/javascript">
      function OnButtonClick(type) {
        axios
          .get("endpointを記載してください", {
            params: {
              type: type,
            },
          })
          .then(function (response) {
            console.log(response);
          })
          .catch(function (error) {
            console.log(error);
          });
      }
    </script>
  </head>
  <body>
    <input
      type="button"
      value="send A to slack"
      onclick="OnButtonClick('A');"
    /><br />
    <input
      type="button"
      value="send B to slack"
      onclick="OnButtonClick('B');"
    /><br />
    <br />
    <div id="reusult"></div>
  </body>
</html>

```
Laravel学習

【ブログ詳細表示の流れ】

①詳細表示したいブログのIDでリンクを作って飛ばす
・特定の一つのブログを取得するにはIDを使う
例）１番目のデータを取得したい場合
/blog/1
→1がIDにあたる


②routeでIDを受け取りControllerへ渡す
・web.php
Route::get('/blog/{id}', 'BlogCkontroller@showDetail')
ルートパラメータと呼ばれ、{}で囲むことで定義できる。
この例だと$idという変数で値をControllerに渡せる。


③Modelで該当IDデータを取り出す
・Eloquentメソッドを使う
例）１番目のブログモデルを取得
$blog = Blog::find(1)

例）最初にマッチしたモデルを取得
$bolg = Blog::where('id', '=', '1')->first()


③Viewで表示する
・ControllerのshowDetailから渡す
↓
・詳細表示用のBladeを作って表示

【実践】

①リンクを作る
・編集前

![スクリーンショット 2020-12-24 12.45.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/977597/7e3ff00b-0981-a626-5703-386a8c2c17bd.png)



・aタグでリンク対象を囲み、href=/twitter/twieet/{{ $content->id }}と入力する
・編集後

![スクリーンショット 2020-12-24 13.56.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/977597/78add08d-7edc-8de8-2693-9c655c6ed4e1.png)


②routeを作る
・編集前

![スクリーンショット 2020-12-24 12.53.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/977597/ee067b4d-a56b-5e0c-a180-b867ed43cf6d.png)


・新しくroute処理を作成し、第一引数にツイート一覧の{id}を入力する。@の後ろにshowDetailとし、メソッドを作成する。
・編集後


![スクリーンショット 2020-12-24 13.56.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/977597/aaff0694-dfec-4cc2-de67-0dd27f2adca0.png)




③Controllerを作る

・web.phpで定義したshowDetailを呼び出し、引数に$idを設定する。

・if文を記述し、投稿にデータがない場合はリダイレクトで投稿一覧ページに戻る記述をし、更にSessionにエラーメッセージを持たせ表示する。

・＄contentsで投稿データを取得し、viewメソッドを使いユーザー画面に表示する。
　
![スクリーンショット 2020-12-24 13.57.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/977597/e2560137-b0c1-271e-0b07-db19b42b8033.png)


④詳細画面を作る

・Controllerで設定したエラーメッセージを表示させる。

@if(session('err_msg'))
    <p class='text-err'>{{ 'err_msg' }}</p>
@endif


![スクリーンショット 2020-12-24 13.59.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/977597/8c49d66c-81a7-cacc-df60-7c6087dbc93e.png)



・投稿一覧ページののファイルをコピーし、投稿内容を表示する処理を記述する


![スクリーンショット 2020-12-24 14.01.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/977597/e7716108-8871-3208-199f-335e675236cd.png)
【PHP】Laravel @componentや@includeの第２引数。連想配列でデータを渡す方法。

PHPのコードを確認していて以下のようなコードの処理内容の確認。

```php:
@include('mrgrpcv::items.items', ['items' => $items])
```

通常`@include`はbladeビュー（.blade.php）内で指定したビューを読み込むために使用される。

`@include('ファイル名')`

##名前空間
`@include('mrgrpcv::items.items)`のように、ここではファイル名の指定に**名前空間**が用いられている。

名前空間は`ServiceProviders.php`の`boot`関数内で設定している。


```php:名前空間の設定
    public function boot()
    {   
        $this->loadViewsFrom(__DIR__.'/../../views', 'mrgrpcv');
        $this->publishes([
            __DIR__.'/../../views' => resource_path('views/vendor/mrgrpcv'),
        ], 'mrgrpcv');
    }
```

`/../../views` を　`mrgrpcv`としている。

名前空間の後ろに続く、`items.items`は、`/../../views`フォルダ内の、itemsフォルダの、items.blade.phpファイルを指している。



##第２引数
文献をあさってもなかなか記述が見つからないincludeの第２引数の役割は、類似したものとして、`@component`の第２引数があげられる。

>場合により、コンポーネントへ追加のデータを渡す必要が起きます。そのため、@componentディレクティブの第２引数で、データの配列が渡せます。全データはテンプレート中で変数として利用できます。

>@component('alert', ['foo' => 'bar'])
    ...
@endcomponent

>[Laravel公式ページより](https://readouble.com/laravel/5.5/ja/blade.html)


この第２引数`['foo' => 'bar']`により、componentに対し、値`bar`が格納された変数`$foo`を渡している。



・`['子に渡す変数名' => 渡すデータ]`

<br>
**▼実際のコード**
上記に沿って、実際のコードを見ると、指定したビューファイルの変数`$items`を、includeしたファイルの中で`$items`という変数で使えるようにしている。

`@include('ファイルパス', ['items' => $items])`

名前が同じなのでわかりにくいが、`$items = [1 ,2 ,3]`だとすると、

`@include('ファイルパス', ['items' => [1, 2, 3] ])`と同じ処理になる。

<br>

```php:例
@include('ファイルパス', ['items' => [1, 2, 3] ])

@foreach($items as $item)
  <p>{{$item}}</p>
@endforeach
```

とすれば、画面には以下が表示される。
1
2
3



<br>

##viewヘルパの場合
bladeの`@include`や`@component`と同じく、viewヘルパでも第２引数以降でデータを渡すことができる。

・`view('ファイル名', ['変数名' => 渡すデータ])`

<br>

```php:複数のデータを渡す場合
return view('contents.blog.show',
        [
            'article' => $article,
            'articleStyle' => $articleStyle,
            'latest_articles' => $articles,
            'preview_code' => $preview_code
        ]);
```
続・App Store Small Business Programを申請してみた→結果が出ました

App Store Small Business Programの概要と申請手順については、以下の記事をご参照ください。
[App Store Small Business Programを申請してみた](https://qiita.com/y-some/items/4a18f0e8a805f0d6de83)

この記事は、申請後の結果についてです。

2020/12/23に、Appleから `Welcome to the App Store Small Business Program.` という題名のメールがきました。

そこには英語で以下のような内容が書かれていました。

- 有料アプリとアプリ内課金の手数料が、2021年1月1日から15%になる。
- 2021年に収益が100万米ドルを超えた場合、残りの期間には標準の手数料率が適用される。
- 2020年12月31日以降に、アプリの転出または転入を行った場合は、プログラムの参加資格がなくなる。

ということで、申請は無事に通ったようです。:grinning:
フォーマット変換したい時に見るためのページ (bioinformatics)

主にリンク集です
## マルチ
#### [EMBL-EBI Sequence Format Conversion](https://www.ebi.ac.uk/Tools/sfc/)
Web上のコンバータ、EMBOSS seqret と MView。あらゆるフォーマットが変換可能。
SeqretでInput/Output 可能なフォーマット　[List Formats](https://www.ebi.ac.uk/seqdb/confluence/display/JDSAT/EMBOSS+Seqret+Help+and+Documentation#EMBOSSSeqretHelpandDocumentation-inputformat)

#### [bioconvert](https://github.com/bioconvert/bioconvert)
Pythonプログラム、pip, condaインストール
Available Converters の図を見るとすごいけど動作未確認（すみません）

## Genbank
##### Genbank to FASTA
* perlスクリプト [gb2fasta.pl](https://github.com/santiagosnchez/gb2fasta)
 
* [EMBOSS](http://emboss.open-bio.org/html/use/ch02s07.html) seqret Command line
```seqret in.gbk out.fasta```


##### GFF3 to Genbank
* pythonスクリプト　[gff_to_genbank.py](https://github.com/Snitkin-Lab-Umich/scripts/blob/master/Annotation_utilities/gff_to_genbank.py)


## GFF3, GTF, BED
### [gffread](https://github.com/gpertea/gffread)
Cufflinks から独立してた

##### GFF3 to GTF
```gffread my.gff3 -T -o my.gtf```

##### GTF to GFF3
```gffread -E my.gtf -g my_genome.fa -o my.gff3```

##### GFF3 + Genome to FASTA (exons.fa, cds.fa and protein.fa)
```gffread -E my.gff3 -g genome.fa -w my_exons.fa -x my_cds.fa -y my_protein.fa```

### [BEDOPS](https://bedops.readthedocs.io/en/latest/index.html)
[Data conversion](https://bedops.readthedocs.io/en/latest/content/reference/file-management/conversion.html) （フォーマット変換できるものの説明）
##### GFF3 to BED
```cat my.gff3 | gff2bed > my.bed```
##### GTF to BED
```cat my.gtf | gtf2bed > my.bed```
##### sam to BED
```cat myread1.sam | sam2bed > my.bed```
##### wig to BED
```cat my.wig | wig2bed > my.bed```


## NGS 周り（fastq, bam, sam, wig)
### [Seqkit](https://github.com/shenwei356/seqkit/)
[Usage](https://bioinf.shenwei.me/seqkit/usage/)
##### FASTQ to FASTA
```seqkit fq2fa myreads.fq.gz -o myreads.fa.gz```

### [samtools](https://github.com/samtools/samtools)
##### sam to bam (with sorting)
```samtools sort -O bam -o myreads1.bam myreads1.sam```
##### Make index on bam
```samtools index myreads1.bam```

### [Augustus](https://github.com/Gaius-Augustus/Augustus)
##### bam to wig
```python3 augustus_dir/scripts/bamToWig.py -b myreads1.bam -g genome.fa -o myreads1.wig```
##### BED Graph to wig
```perl augustus_dir/scripts/bedgraph2wig.pl --bedgraphfile=myreads1.bed --outputfile=myreads1.wig```

### BEDOPS
##### wig to BED,　sam to BED
上記参照
Pythonでネストが深くなって読みにくい

# Pythonでネストが深くなって読みにくい
## はじめに
Pythonをかいていて、「ネストが深くて読みにくいなぁ」ってよく思うんですよね。
具体的には以下のような場合です。

```python

for group in groups:
    for member in group.members:
        for article in member.articles:
            for tag in article.tags:
                """
                処理いろいろ
                """
```

もしこれが以下のようになったらステキじゃないですか？


```python

for group, member, article, tag in func(groups):
    """
    処理いろいろ
    """
```

でも「そもそもfor文ってどうやったら自分で制御できるの？」って疑問もあると思うのでそこから解説していきたいとおもいます。


## 実装
Pythonを含め一部のプログラミング言語にはイテレータ(iterator)とジェネレータ(generator)が存在します。
Pythonのものについては以下の記事が参考になります。
[Pythonのイテレータとジェネレータ](https://qiita.com/tomotaka_ito/items/35f3eb108f587022fa09)

今回はこのジェネレータを用いて実装していきます。

まず軽く動作を確認します。

```python

def my_generator():
    yield 10
    yield 20
    yield 30

for num in my_generator():
   print(num)

"""出力結果
10
20
30
"""
```

yieldで渡した値が次々にfor文の引数になっていることがわかります。

これを踏まえてサンプルのgroupsを渡したら、tagまで展開してforの引数に渡してくれる関数を作ります。

```python
def group_generator(groups):
    for group in groups:
        for member in group.members:
            for article in member.articles:
                for tag in article.tags:
                    yield group, member, article, tag


for group, member, article, tag in group_generator(groups):
    print(group)
    print(member)
    print(article)
    print(tag)
```

これでネストの浅いソースコードになりました。
では更にこれを一般化していきます。
```group_generator```を一般化するにあたって、２つ目のfor文以降、ある値から次のIterableなオブジェクトを取り出し、for文で回すという処理が共通しており、再帰的になっていることがわかります。またyeildしている箇所を再帰関数のベースケースとすることでうまく実装できそうです。


![202007_-179.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235240/97e5cea6-d0da-f0ed-52dc-21059207f862.jpeg)

**ある値から次のIterableなオブジェクトを取り出す処理**を```iterable_creators```、**ベースとなるオブジェクト**を```base_iterable```、**再帰的な部分**を```nest_recursive```関数として実装すると以下のようになります。
またジェネレータ関数を関数内部で呼び出す場合は、```yield from```を用います。


```python
def nests(base_iterable, *iterable_creators):
    def nest_recursive(nested_items: Tuple, current_item, level: int):
        try:
            iterable_creator = iterable_creators[level]
            next_iterable = iterable_creator(current_item)
            for next_item in next_iterable:
                new_stuck = (*nested_items, next_item)
                yield from nest_recursive(new_stuck, next_item, level + 1)
        except IndexError:
            yield nested_items

    for root_item in base_iterable:
        yield from nest_recursive((root_item,), root_item, level=0)

```

では実際に使ってみましょう。

```python
iterable_creators = (lambda group: group.members, lambda member: member.articles, lambda article: article.tags)
for group, member, article, tag in nests(groups, *iterable_creators):
    print(group)
    print(member)
    print(article)
    print(tag)

```

ネストがとれて読みやすくなりましたね。
実用性があるかどうかは怪しいですが、ジェネレータの良い勉強になりました。
EC2にrootユーザーでSSHログインする方法

# 用途
SSH SCPでファイル転送を行いたいのに、root権限のディレクトリー宛てなので一般ユーザーではファイル転送が出来ない時など、rootユーザーでログインしてファイル転送したい。

# はじめに
デフォルトの状態ではEC2インスタンスに**rootユーザーでSSHログインする事は出来ない。**

仮に、 `ユーザー：root、 KEY：ec2-userの秘密鍵` でSSHを試みると、

```
Please login as the user "ec2-user" rather than the user "root".
```

と表示され、ログインが出来ない。

# rootユーザーでSSHする方法

まず、rootの公開鍵を確認してみる。
ec2-userでログインを行い、 `sudo su -` コマンドでrootユーザーに切り替え、公開鍵である`authorized_keys`をcatする。

```
[root@aether ~]# cat /root/.ssh/authorized_keys
no-port-forwarding,no-agent-forwarding,no-X11-forwarding,command="echo 'Please login as the user \"ec2-user\" rather than the user \"root\".';echo;sleep 10" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCiris4cDE6BLqS5P・・・・・・

```

　
次にec2-userの公開鍵を確認してみる。

```
[root@aether ~]# cat /home/ec2-user/.ssh/authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCiris4cDE6BLqS5P・・・・・・
```

この2つを見比べると、rootの公開鍵は文字の `ssh-rsa` 以降、ec2-userの公開鍵と同じ文字列であることがわかる。

つまり、`ssh-rsa` までの文字列

```
no-port-forwarding,no-agent-forwarding,no-X11-forwarding,command="echo 'Please login as the user \"ec2-user\" rather than the user \"root\".';echo;sleep 10" 
```

を削除すればec2-userの公開鍵と全く同じになるので、
`ユーザー：root、 KEY：ec2-userの秘密鍵`でSSHログイン可能となる。

# 但し書き
Amazon Linux2では上記方法でrootログイン可能であるが、**Amazon Linux1では何故かこれが出来ない。**
（何故か分かる人いたら教えて頂けると助かります）
フリーな地図

#フリーな地図
地図を使ったアプリを作りたくなったので調査中。

[MAPAC](https://www.map-ac.com/)

[地球地図](https://www.gsi.go.jp/kankyochiri/globalmap.html)

[国土数値情報](https://nlftp.mlit.go.jp/ksj/)

#データ形式
[TopoJson](https://github.com/topojson/topojson)
プルリクエスト送ったら競合してたので解消手順のメモ

#競合してた

改修が完了したソースをpushして、
BackLog上からプルリクエストを送信した。
なんかいつもマージされるの早いのにマージ全然されないな、と思って確認したら競合してた。。。

#解消方法

Git使い始めて1か月程度しかたってないので、
何かやらかさないかひやひやしながら、とりあえず解消方法を調べてみた。

####競合した原因(´；ω；`)

①branch/Aを作成
②branch/Aの改修が終わってプルリク送る。
③branch/Aがmasterにマージされる前にbranch/Bを作成。
④branch/Aのソースに修正が入り、再度プルリク→マージされる。
　→この時点で差が...
⑤マージされる前に作ってしまったbranch/Bの作業完了
⑥branch/Bのプルリク送る
⑦マージされたbranch/Aのソースとbranch/Bのソースで競合。

結果：自分の修正と自分の修正で競合起こしてました(´・ω・`)

####解消手順(｀・ω・´)

①まずはcheckoutコマンドでmasterに移動して、masterから最新のソースを落としてくる。
・git checkout master
・git pull origin master

②作業ブランチに切り替えて、落としてきたソースを作業ブランチとマージする。
・git checkout (作業branch名)
・git merge master
※マージ後に、競合しているファイル名が表示される。

③git statusやgit diffで競合箇所を確認

④競合しているファイルをいい感じに修正

⑤git status
→念のためどのファイルをコミットするか確認
 競合していたファイルがローカルの方が最新で、すでにコミット済みであれば修正後ここには表示されない。

⑥git add （競合しているファイルや、masterから落としてマージしたソース）

⑦git commit -m "なんか競合解消したのが分かるメッセージ"

⑧git push --set-upstream origin (ブランチ名）

以上で完了するはず。

必要であれば再度プルリクエストを送ること、
今回はBackLogでプルリクエスト送信したため、競合解消されたかどうか確認する！
コンポーネント指向とは

# 概要
普段からマークアップ側で意識しているコンポーネント指向のイメージを
テキストで残しておこうと思い書きました。

# コンポーネント指向とは
そもそもコンポーネント指向とは、
webサイトにおける機能毎だったり、パーツ毎に作成し
それらを組み合わせて使うという考え方です。

実際にサンプルのサイトをイメージしながらやるとわかりやすいかもしれないです。

## サンプルのサイト
いらすとやで拾ってきたやつです↓
![website_normal.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163415/6392b5a4-097e-50d3-4a82-e23eaf03383a.png)

## どう分割するか
このサイトをコンポーネント指向で組んでいくと
大きく分けて
- header
- サイドバー
- 記事一覧
- ポップアップ
という感じになるかと思います。

こうすることで仮にこのサイトをトップページだと仮定して
記事詳細ページなどでサイドバーが必要だったり、ポップアップが必要だったりした場合に
サイドバー、ポップアップを使いまわせるようになります。

また、どこまで細かくするかという話もありますが、
このサイトを例にすると

- header
- サイドバー
  - サイドバーの見出し
- 記事一覧
  - 記事のカード
- ポップアップ
  - 記事のカード

サイドバーと記事の見出しは同じ見た目になりそうなので
見出しを1つ作っておけばそれをサイドバーと記事の見出しに使えるし、
記事一覧のカードだけを作れば記事一覧、ポップアップでも記事のカードを使えるようになります。

こうすることで
同じアイテムのはずなのにトップページと○○ページでデザインが違っていたり、
細かいところで余白が若干違ったりという問題が起きてしまいます。
また、パーツを使い回すことで修正漏れなども減らすことができるので開発がしやすくなるかと思います。

## まとめ
最近ではreactやvueでもコンポーネント指向が取り入れられているので
意識してみるといいかもしれません。
第十回

今回は再帰メソッドを用いてフィボナッチ数列を求めるプログラムを作成します．


# フィボナッチ数列とは

フィボナッチ数列は「1番目と二番目の数値は1であり，三番目以降の数値は直前の2数の和である数列」のことであり，以下の漸化式で定義される．

$$  F_{0} = 0$$

$$  F_{1} = 1$$

$$  F_{2} = 1$$

$$  F_{n+2} = F_{n+1} + F_{n} (n \geq 0)$$

フィボナッチ数列は，再帰的な関数を利用して作成することができる．


# 再帰メソッドとは

再帰とは，プログラム上で再度呼び出すことである．例えば以下のようなプログラムがある．

```ruby

def sum(array)
 return 0 if array.empty?
 top=array.shift
 top+sum(array)
end

p sum([1,2,3,4,5]) # =>15

```


# プログラム

それでは初めに第0項と第1項及び第2項を実装するところから始める．

```ruby

def fib(n)
 #第0項の場合
 if n==0 then
  return 0

 #第1項の場合
 else n<=2 and n!=0 then
  return 1  
 end
end
```

次に，第n項の実装を行う．第n項は

$$F_{n}=F_{n-1}+F_{n-2} $$

で求めることができるので

```ruby
def fib(n)
  #第0項の場合
  if n==0 then
   return 0

  #第1項の場合
  else n<=2 and n!=0 then
   return 1

  #第n項( n>2 )の場合
  else
   return fib(n-2)+fib(n-1)
  end
end

for n in 0..10 do
 print 'n=',"#{n} ",' fib=',"#{fib(n)}", "\n" 
end

```

と書けばよい．ここで，実行結果が正しいか否かを検証するために，前回作成したプログラムassert\_equal\_finを用いる．念のため，プログラムのソースコードを以下に記す．

```ruby:assert_equal_fin.rb

require 'colorize'

def puts_vals(expected, result)
  puts "expected :: #{expected}"
  puts "result   :: #{result}"
end
def assert_not_equal(expected, result)
  puts_vals(expected, result)
  print expected != result ?
	  "succeeded in #{__method__}.\n".green :
	  "failed in #{__method__}.\n".red
end
def assert_equal(expected, result)
  puts_vals(expected, result)
  print  case expected == result
	 when true  ; "succeeded in #{__method__}.\n".green
	 when false ; "failed in #{__method__}.\n".red
	 end
end

if $PROGRAM_NAME == __FILE__
  assert_equal(1, 1)
  assert_equal(1, 2)
  assert_not_equal(1, 2)
  assert_not_equal(1, 1)
end


```

それでもって，出力結果の検証部分は以下のようにかく．

```ruby
test=[[0,0],[1,1],[10,55],[30,832040]]
test.each do |index, expected|
  puts assert_equal(expected, fib(index))
end
```

以上より，プログラムの最終形態は以下のようになる．内容としては，フィボナッチ数列の第0項から第10項までを出力し，assert\_equalによっていくつかの項があっているかどうかを検証する．

```ruby:fibonacci.rb
require './assert_equal_fin'

def fib(n)
  if n==0 then
    return 0

  elsif n <=2 and n!=0 then
    return 1

  else
    return fib(n-2)+fib(n-1)
  end
end

for n in 0..10 do
  print 'n=',"#{n} ",' fib=',"#{fib(n)}", "\n"
end

test=[[0,0],[1,1],[10,55],[30,832040]]
test.each do |index, expected|
  puts assert_equal(expected, fib(index))
end

```


# 参考文献

<https://qiita.com/pokotyan/items/53e92a21805f651173aa>



------
 - **source** ~/grad_members_20f/members/NobuakiMori/L10_fibonatti.org
Rails：部分テンプレートについて

# 最初に

**カレンダー企画2020の24日目**
プログラミングの勉強を始めて3ヵ月程経ったので学んだことのメモをアウトプットとして記事に残します。
これからプログラミングの世界に入る人の手助けになれたら嬉しい限りです。
間違っていたり、言葉が違っていたり、誤解されるような言葉があったら教えてください^^
言葉を長々と読みづらかったら申し訳ありません。少しずつなれてがんばります。

## Rails：部分テンプレート（パーシャル）について

これはとても便利です。
教えてもらっている人からも部分テンプレを使っていることをよく褒められた覚えがあるので良いことなのだと思います。まだあまり良さを分かってない^^;（教えてくれる人がよくパーシャルって言ってましたので気取って以降使いますね^^）
私はHTMLの記述でサボれるので使えるところは使いまくっているだけですね。
この楽な方法を知らない人にはぜひ知ってほしい！作業スピード上がります^^

## パーシャルのメリットは？？

素人目線の私が考えるに

1. 記述がとにかく少なくて済むから楽！
2. HTMLの記述が全体的に少なくなるので見やすいかも！
3. 修正する時に修正する箇所が少なくて楽！そして修正漏れがないからさらに良い！


## 1. 記述がとにかく少なくて済むから楽

アプリケーションを作成していて同じ記述をするところをパーシャルを使って記述するので実際のHTMLには1行で済む。
実際に記述するのはパーシャル作成時の1回だけ

とにかく記述を少なくできるのが良い！

## 2. HTMLの記述が全体的に少なくなるので見やすいかも

HTMLには1行で済むので全体的に量が少なくなり見やすいですね。
いっぱい下にスクロールすることがないので見直す時も助かる！

## 3. 修正する時に修正する箇所が少なくて楽！そして修正漏れがないからさらに良い

これが1番嬉しいところ
訂正する時には元のパーシャルだけを訂正すると、すべてにその訂正が適応されるので訂正時も楽！

これを知らないでエラーが起きた時は地獄でした。関連するすべてを訂正するけど漏れていたりと時間がかかったけどパーシャルを使えば1回の訂正ですべてに漏れなくいくので楽です！


## パーシャルの作り方

これも簡単！

1. 共通している記述を探す。
2. 見つけたらパーシャルを作成する。
3. 作成したパーシャルを呼び出す記述を該当箇所に行う

終わり！

```ruby:show.html.erb

<% @posts.each do |post| %>
  <div class="post_<%= post.id %>">
    <%= post.member.name %>
    <%= post.title %>
    <%= post.body %>
  </div>
<% end %>

.
.
.
.


```

```ruby:index.html.erb

<% @posts.each do |post| %>
  <div class="post_<%= post.id %>">
    <%= post.member.name %>
    <%= post.title %>
    <%= post.body %>
  </div>
<% end %>

```

こんな感じてPostのindexとshowがあったとします。
どちらにもPostの一覧表示をしたいのでeach文で行っていたとしたらパーシャルの出番です！

```ruby:views/layouts/_post_index.html.erb

<% posts.each do |post| %>
  <div class="post_<%= post.id %>">
    <%= post.member.name %>
    <%= post.title %>
    <%= post.body %>
  </div>
<% end %>

```

パーシャル作成時には先頭は（_）にするのは忘れずに！名前は適当です（一目見て何かわかる名前が良いと思います。）
あとはインスタンス変数として（@）消しておいた方が幅広く使えます。消さなくてもパーシャルとして動きますが汎用性があるのでは無しのほうです。

```ruby:show.html.erb

<%= render layouts/post_index, posts: @posts %>
```


```ruby:index.html.erb

<%= render layouts/post_index, posts: @posts %>
```

さきほどパーシャル作成の際に（@）を消したのでそれを指定する為に`posts: @posts` をつけてます。
`posts`はインスタンス変数に変えたい場所を指定し、該当するインスタンス変数を記述すればOKです！


たとえば使う場所によっては`posts: @user`になることもあります。
今回の例題ではちょっと無理がありますが^^;

フラッシュメッセージやバリデーションの時はパーシャルを作成して、それぞれ合わせたインスタン変数に書き換えるだけで使えますので便利！


## 最後に

パーシャルは使いこなせるようにもっとなりたいと思っています！
最近知ったのはURL毎で表示する場所を一部変える処理をすればパーシャルできるのでよりパーシャルが増やせそうでワクワクしてます。
あまりに眠いので、さざえさんじゃんけん作ってみた

あまりに眠かったので適当に作ってみた。
エラーハンドリングの処理も書いてません。

```go:sazae-janken.go
package main

import (
	"fmt"
	"math/rand"
	"strconv"
	"time"
)

func main() {
	var you string
	for {
		println("来週も見てくださいね～！じゃん、けんっ")
		println("(グー:1、チョキ:2、パー:3)")
		fmt.Scan(&you)
		if you == "1" || you == "2" || you == "3" {
			break
		}
	}

	switch you {
	case "1":
		println("グー")
	case "2":
		println("チョキ")
	case "3":
		println("パー")
	}

	rand.Seed(time.Now().Unix())
	// Intn()は、引数に数値を渡すと、0~その数値までの疑似乱数をintで返します。
	number := rand.Intn(3) + 1
	// Itoa()で整数を文字列に変換します。
	sazaesan := strconv.Itoa(number)

	switch sazaesan {
	case "1":
		println("グー")
	case "2":
		println("チョキ")
	case "3":
		println("パー")
	default:
		
	}

	switch {
	case you == sazaesan:
		println("あいこ")
	case you == "1" && sazaesan == "2":
		println("勝ち")
	case you == "2" && sazaesan == "3":
		println("勝ち")
	case you == "3" && sazaesan == "1":
		println("勝ち")
	default:
		println("負け!")
	}
	println(`                (⌒(⌒)⌒)
	　　 ／＼＿＿_/
	　　/　／　　 ＼
	　 / ／ ⌒　 　⌒ ＼
	(⌒Ｖ　 (^)　 (^) ｜
	(　(6　　　 つ　 ｜
	(＿｜　　＿＿＿　｜
	　　＼　 ＼＿/　／
	　　　＼＿＿＿／
	`)
	println("ふふふふふふふふふふふふ")
}
```

```terminal
来週も見てくださいね～！じゃん、けんっ
(グー:1、チョキ:2、パー:3)
3
パー
チョキ
負け
              (⌒(⌒)⌒)
        　　 ／＼＿＿_/
        　　/　／　　  ＼
        　 / ／ ⌒　 　⌒ ＼
        (⌒Ｖ　 (^)　 (^) ｜
        (　(6　　　 つ　  ｜
        (＿｜　　＿＿＿　 ｜
        　　＼　 ＼＿/　 ／
        　　　＼＿＿＿／

ふふふふふふふふふ
```
firefoxでmemont.jsを使って日付フォーマット変換するとInvalid dateになる

YYYY-MM-DDで渡されたデータをYYYY年MM月DD日(曜日)のフォーマットへ変換する処理で
moment.jsを使って次のようなコードで処理したところ
chromeでは問題なく変換されたのですが

```
moment.locale("ja");
moment('2020-12-24').format('YYYY年MM月DD日(ddd)');
結果:2020年12月24日(木)
```
firefoxでは

```
moment.locale("ja");
moment('2020-12-24').format('YYYY年MM月DD日(ddd)');
結果:invalid date
```
となってしまう(場合があります)

解決策:
https://stackoverflow.com/questions/34541196/moment-js-gives-invalid-date-in-firefox

文字列2020-12-24を解析するための形式を指定することで、
firefoxでフォーマット変換できるようになります。

```
moment.locale("ja");
moment('2020-12-24','YYYY-MM-DD').format('YYYY年MM月DD日(ddd)');
結果:2020年12月24日(木)
```

以上です。
arXivのトレンドワードをSlack投稿！(論文サーチをもっと楽に！！)

# はじめに
　みなさん、最近のトレンドを論文から知りたいな～というときどうしていますか？
論文を片っ端から読み漁ることができたらそれが理想ですが、論文数は毎日大量に発表されるし、どれを追えばいいのか......
**ということで、arXivで発表されている最近の論文からキーワードを分析し、トレンドワードをslackに投稿する機能**を作ってみました！

#完成例(このようにSlackに投稿します！)
上から順にトレンドワードベスト15を投稿しています！(CS.AIカテゴリー内)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474340/a13ce72d-2d80-c115-f2a2-49f64dbf8bfc.png)

#作成の流れ
1. arXiv API で論文情報を取得
2. TF-IDFを用い、トレンドワードを取得
3. IFTTTを用いて、webhooks経由でslackへ投稿
今回は、カテゴリー「CS(Computer Science)」の中でtf-idfで取得した上位の単語をトレンドワードと定義し、CS.AIのトレンドワードを表示するものを作成します！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474340/1586b9cc-fe9e-8a40-b236-e297ddb8a74b.png)


## 1. arXiv API で論文情報を取得
今回取得する論文としては、arXivが取得することにしました！
理由は、主に2点です。

- 論文としての情報が早い(トレンド性が高い)
- APIが整っているため、データを取得しやすい

arXivAPIでは多くのデータが取得できますが、今回用いるのは、Abstractの文章からトレンドワードを分析していきます！

## 2. TF-IDFを用い、トレンドワードを取得
　今回は、CSのカテゴリーについて、TF-IDFを行いました。ちなみに、CSのサブカテゴリーいくつあるか知ってますか？(著者は数えたことなかったのですが、想像以上でした……)

なんと、40カテゴリー！！
これだけのカテゴリーをイチから見て行っては日どころか年も暮れてしまいますよね(笑)
この事実を知り、より一層この分析を完成させたくなりました！

(参考)
[CSのカテゴリー一覧](https://arxiv.org/archive/cs)


## 3. IFTTTを用いて、webhooks経由でslackは投稿
　[IFTTT](https://ifttt.com/about)を用いて、プログラミング上でリクエストを送るのをトリガーにして、リクエストを受け取ったらSlack へ投稿する仕組みにしている。(結構シンプルな作りで作れるので便利です！)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474340/4108d9b5-7478-d982-4764-0b69f31107c9.png)

##完成
　この3ステップで、arXivのトレンドワードをSlackに投稿することができました！
　下の写真は、上の完成例とは別の日のトレンドワードです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474340/b6b10110-dafc-219b-b172-575843ed440d.png)



#おわりに
　Slackを見るだけで、最近多く出ている論文のテーマは何かな～というのがわかると便利ですよね。論文を読み漁り続けるのは、難しくてこの投稿をチェックするだけならハードルも下がる！と思うので、著者も定期的な情報キャッチアップツールとして使えたらと思っています。
　今回、作成した機能は実際に東海人工知能研究会(TAIR)のSlackで実装しています！学部生・院生で興味のある人がいれば招待できればと思うので、[twitter](https://twitter.com/tairproject)からフォロー+DMでご連絡ください！

※東海人工知能研究会(TAIR)は、東海地区を中心にAI・機械学習に興味のある学生のためのコミュニティです。
CircleCIでgo test結果をレポート出力する

# CicleCIでテスト結果が見づらい問題
テストの数がだんだん増えてくると、どのテストでFAILしたのかが分かりづらくなります。1,000を超えるテストの結果ログから、「FAIL」の文字列を検索して探すでも良いですが、10も20もFAILした場合は、どこでFAILしたかを特定するだけで結構大変です。


# JUnit形式でテストレポートを出力する

[go-junit-report](https://github.com/jstemmer/go-junit-report)というツールを使うことで、go testの結果をJUnit実行結果のXMLフォーマットで出力することができます。

`.circleci/config.yml` のテスト実行するjobに以下を書いていきます。

```yml

# テスト結果を保存するディレクトリを作成
- run: mkdir -p /tmp/test-results

# テスト結果をレポート出力するためのライブラリを取得
- run: go get -u github.com/jstemmer/go-junit-report

# テスト実行とレポート出力
- run: go test -v -race ./... 2>&1 | go-junit-report -set-exit-code=true > /tmp/test-results/go-test-report.xml

# 出力したレポートをCircleCIにテスト結果として保存
- store_test_results:
    path: /tmp/test-results
```

`set-exit-code`というオプションをtrueにしないと、テストがFAILしても`exit 0`が返り、正常終了してしまいます。（`set-exit-code`のデフォルト値はfalse）
今回、go testの結果が1つでもエラーになった場合は、job自体もエラーにしたいため、`-set-exit-code=true`を指定しています。


# 参考
https://circleci.com/docs/ja/2.0/collect-test-data/
iSCSI+LVM環境のシャットダウンが遅延する問題

### 問題
LinuxサーバにiSCSIデバイスを含むLVM VGがあると、システムシャットダウンが遅延・失敗する。

### 状況
Ubuntu 20.04のopen-iscsi + lvmcacheを使用したリモートストレージにデータを置く構成で発生。
open-iscsiでオートログインによりターゲットをsdaにアタッチ、_netdevマウントオプションで起動時は遅延マウントしている。
sdaはLVM PVとしてフォーマットし、ローカルNVMeの一部を混ぜてLVM VGにしている。（lvmcacheに必要なため）

```
# pvs
  PV              VG     Fmt  Attr PSize    PFree
  /dev/sda        remote lvm2 a--  <200.00g      0
  /dev/vda2       vg     lvm2 a--   <40.00g 520.00m
  /dev/vg/cachepv remote lvm2 a--    <5.00g      0
# lvs
  LV      VG     Attr       LSize    Pool         Origin       Data%  Meta%  Move Log Cpy%Sync Convert
  data    remote Cwi-aoC--- <200.00g [cache_cvol] [data_corig] 100.00 12.40           0.00
  boot    vg     -wi-ao----  500.00m
  cachepv vg     -wi-ao----    5.00g
  root    vg     -wi-ao----   30.00g
  swap    vg     -wi-ao----    4.00g
```

このままシャットダウンしようとすると、高頻度でシャットダウンが途中でブロックされ、カーネルスタックトレースが表示されて電源が落ちない。

### 原因

iscsiデバイスの管理は、systemd unit `open-iscsi.service`で行われている。
このunitは`After=network-online.target`によりネットワーク構築後に起動され、シャットダウン中はネットワーク停止前に終了される。
終了時は`blkdeactivate`により自動的に依存ファイルシステムのアンマウントやLVMの非アクティブ化が行われている。

ほとんどの場合これで問題ないが、複雑なlvm構成に関わるすべてを必ずしも対象としてはくれない。
ファイルシステムかLVMのいずれか、あるいは両方を正しい順序でアンマウントしてやらないと、sdaやネットワークスタックが消えたあとにiscsiデバイスにアクセスリトライしようとして恒久的にブロックされてしまう。

### 対処

open-iscsi.serviceのAfterかつ、他の依存serviceのBeforeになるよう、シャットダウン時だけ動くsystemd serviceを作成し、適切な順序でumount/lvchange -anで非アクティブ化しておく。

```
[Unit]
Wants=network-online.target remote-fs-pre.target

# open-iscsiを追加
After=network-online.target iscsid.service open-iscsi.service

# remote/dataが必要なサービスをすべて列挙
Before=snap.lxd.daemon.service snap.lxd.activate.service

DefaultDependencies=no
Conflicts=shutdown.target
Before=shutdown.target

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=-/bin/true

# 依存順にアンマウント・非アクティブ化。
# 他のunitでアンマウントされているかもしれないのでExecStop=- でエラー無視している
ExecStop=-/bin/umount -R /data
ExecStop=-/sbin/vgchange -an remote -vv
ExecStop=-/sbin/lvchange -an vg/cachepv -vv

[Install]
WantedBy=sysinit.target
```

依存関係はopen-iscsi.serviceを引き写した上で、After/Beforeを追加している。 
remote/dataに依存するunitはBeforeに列挙している。いちいち書かなくてすむよう、適当なtargetがないか探してみたが、それらしいremote-fs.targetをAfterで指定しているサービスはほとんどなく適当なものが見つからなかった。
【GAS】リクエストに失敗しました。応答の全文を見るには muteHttpExceptions オプションを使用してください。

Google Apps Script Advent Calendar 2020 6日目

もうとっくに過ぎてしまった日付の Advent Calendar ですが、空いているのも偲びないので投稿することにしました。どうぞよろしくお願いいたします。

# はじめに

今日も今日とて Google Apps Script で API を呼び出していたのですが、タイトルのエラーメッセージが表示されました。( ﾟДﾟ)

今まではこのメッセージが表示されていても、~~割と無視して無理やり~~なんとか解決していたのですが、やっぱりエラーにちゃんと向き合って解決しよう！と思い、調べたので忘れないように書いておくことにしました。

インプット後のアウトプット大事。(*´Д｀)

# muteHttpExceptions オプション

`UrlFetchApp.fetch()` メソッドには `muteHttpExceptions` オプションというものがあり、これを `true` に指定しておくとエラーを吐かずに `HttpResponse` を返してくれます。
なので、帰ってきた `HttpResponse` の中身を見ればどんなエラーか詳細にわかるということですね。(*'▽')

でも、ただオプションを設定するだけではダメです。( ﾟДﾟ)
例外が発生する可能性もあるので、ちゃんと `try ~ catch` をしておきます。

以下のように記述します。

```js:main.gs
function apiRequest() {
  const uri = 'https//.......'
  const options = {
    'method': 'get',
    'headers': headers,
    "muteHttpExceptions" : true,
    "validateHttpsCertificates" : false,
    "followRedirects" : false
  }
  try {
    const res = UrlFetchApp.fetch(uri, options);
    Logger.log(res)
  } catch(e) {
    // 例外エラー処理
    Logger.log('Error:')
    Logger.log(e)
  }
}
```

これでエラー応答の全文を見ることができます。
エラー内容をしっかりと把握して、修正が行えますね！('Д')

# 細かいところ

- validateHttpsCertificates

SSL 証明書のエラーを回避します。
処理が止まらなくなるだけでエラーがなくなるわけではありません。
ログを見て証明書の有効性を確認しましょう。

- followRedirects

エラーが出た際、サイトが指定するリダイレクト先の URL を取得します。
`false` に設定しておくと取得することができます。

# おわりに

ここまでお付き合いいただきありがとうございました。

エラー処理、大事ですよね。
個人開発ばっかりやってるせいで、エラーが出たらログ見ればいいや的な感覚なのですが、あまり良くないと思っています。

エラーが発生した場合に担当者に通知する流れとか、処理を止めない動きとか、意識できるように勉強＆実践あるのみですね。

ではまた！(^^)/

# 参考にさせていただきましたm(_ _)m

[Google Apps Script 公式ドキュメント - Class UrlFetchApp](https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app)
[Google Apps ScriptでWebAPIや外部サイトを取得する指南書](https://officeforest.org/wp/2018/05/04/google-apps-script%E3%81%A7webapi%E3%82%84%E5%A4%96%E9%83%A8%E3%82%B5%E3%82%A4%E3%83%88%E3%82%92%E5%8F%96%E5%BE%97%E3%81%99%E3%82%8B%E6%8C%87%E5%8D%97%E6%9B%B8/)
正規表現リスト

※備忘録としてのメモです
※こちらの情報を参考させていただいております。
https://gist.github.com/nashirox/38323d5b51063ede1d41


#
# 数字
#

# ○全て数値（全角）
/\A[０-９]+\z/

# ○全て数値（半角）
/\A[0-9]+\z/

# ○全て数値（全角,半角）
/\A[0-9０-９]+\z/

# ○全て全角数値（マイナス、小数点）
/\A[ー]?[０-９]+(\．[０-９]+)?\z/

# ○全て半角数値（マイナス、小数点）
/\A[-]?[0-9]+(\.[0-9]+)?\z/

#
# 文字
#

# ○半角アルファベット（小文字）
/\A[a-z]+\z/

# ○半角アルファベット（大文字）
 /\A[A-Z]+\z/

# ○半角アルファベット（大文字・小文字）
 /\A[a-zA-Z]+\z/

# ○半角アルファベット（小文字・数値）
/\A[a-z0-9]+\z/

# ○半角アルファベット（大文字・数値）
/\A[A-Z0-9]+\z/

# ○半角アルファベット（大文字・小文字・数値）
/\A[a-zA-Z0-9]+\z/

# ○全角ひらがな
/\A[ぁ-んー－]+\z/

# ○全角カタカナ
/\A[ァ-ヶー－]+\z/

# ○全角ひらがな、カタカナ
/\A[ぁ-んァ-ヶー－]+\z/

# ○半角カナ
/\A[ｧ-ﾝﾞﾟ]+\z/

# ○漢字
/\A[一-龥]+\z/

# ○全角ひらがな、漢字
/\A[一-龥ぁ-ん]/

# ○全角ひらがな、全角カタカナ、漢字
/\A[ぁ-んァ-ン一-龥]/

# ○全角ひらがな、全角カタカナ、漢字（鬼車）
/\A(?:\p{Hiragana}|\p{Katakana}|[ー－]|[一-龠々])+\z/

#
# 郵便番号
#

# ○郵便番号（ハイフンあり3桁・5桁・7桁）
/\A\d{3}[-]\d{4}$|^\d{3}[-]\d{2}$|^\d{3}\z/

# ○郵便番号（ハイフンあり5桁）
/\A\d{3}[-]\d{2}\z/

# ○郵便番号（ハイフンあり7桁）
/\A\d{3}[-]\d{4}\z/

# ○郵便番号（ハイフンなし3桁）
/\A\d{3}\z/

# ○郵便番号（ハイフンなし5桁）
/\A\d{5}\z/

# ○郵便番号（ハイフンなし7桁）
/\A\d{7}\z/

# ○郵便番号（ハイフンあり・なし両方）
/\A\d{3}[-]\d{4}$|^\d{3}[-]\d{2}$|^\d{3}$|^\d{5}$|^\d{7}\z/

#
# 電話番号
#

# ○電話番号(ハイフンなし10桁)
/\A\d{10}\z/

# ○携帯番号(ハイフンなし11桁)
/\A\d{11}\z/

# ○携帯番号(ハイフンなし10桁or11桁)
/\A\d{10,11}\z/

#
# その他
#

# ○e-mail
 /\A\S+@\S+\.\S+\z/

# ○日付 YYYY-MM-DD
/\A\d{4}-\d{2}-\d{2}\z/

# ○時刻 24h
/\A([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]\z/

# ○時刻 12h
/\A(0[0-9]|10|11):[0-5][0-9]:[0-5][0-9]\z/

# ○URL
/\Ahttp(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w-.\/?%&=]*)?/

# ○クレジットカード(VISA,Master,Diners,Discover,Amex対応)
/\A(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6011[0-9]{12}|3(?:0[0-5]|[68][0-9])[0-9]{11}|3[47][0-9]{13})\z/
意識の高いヘルシープログラマはショートカットアプリを活用する


Hello, World! あーみーです．
夏は朝6時30分に起きてラジオ体操をして，一日を始める意識の高い(笑)生活を心がけていました．
しかしながら，冬の朝はとても寒くめっきり実行できなくなってしまいました．
また，6時30分にラジオつけるって起床時間が合わないと結構辛いです．
そこで，今回はiOSのショートカットアプリを使用して，自分の設定した起床時間になったらラジオ体操の曲が流れ，その後，簡単にブリーフィングをしてくれるショートカットを作成しました．

## 制作物

今回，実際に作ったショートカットは[こちら](https://www.icloud.com/shortcuts/905a910d66094a8881589a768988bbb7)．使用の条件は以下です．

- ラジオ体操の音源がある(Apple Music等)

あとは，ショートカットアプリのオートメーションで，「このショートカットを起床時に実行する」ように設定すれば，朝自分が起きたタイミングでラジオ体操が自動的に流れます．なお，**「実行の前に尋ねる」をオフにしておかないと自動で流れません．**

> 12月25日追記
ショートカットアプリが閉じている場合，長い待機後のアクションは実行されないようです([こちら](http://blog.thetheorier.com/entry/apple-shortcuts-wait#%E3%83%90%E3%82%B0)と同じ状況かな)．つまり，ブリーフィングが再生されません．ショートカットを分けて続けて実行するようにしても長い待機でショートカットアプリが開いていない場合は再生されない様子でした．
デバッグをショートカットアプリを開いたままやっていたので，気づきませんでした．


## プログラム例

![IMG_9323.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210077/58e54e1d-4665-48f9-b1b6-5d4a927b8748.jpeg)


## プログラム説明
各ブロックについて，以下より説明していきます．

**1. デバイス**
最後に自分で設定している音量に戻したいので，取得しておきます．

**2. 音量**
曲を再生したい音量に設定します．
私は，音量が大きくないと起きれないので，65%に設定してあります．ちょっと大きいぐらいです．


**3. ミュージック**
ラジオで流れるように「新しい朝が来た〜♪」で始まる「ラジオ体操の歌」を再生します．

**4. スクリプティング**
「ラジオ体操の歌」の1番がちょうどいいタイミングで終わるのが53秒ぐらいなので，それまでショートカットを待機させます．待機させないと次の曲に進んでしまいます．


**5. ミュージック**
大本命の「ラジオ体操 第1」を再生します．


**6. スクリプティング**
「ラジオ体操 第1」は3分16秒(=196秒)なので，それまで待機させます．

**7. 場所**
ブリーフィングさせたいので，現在地の天気情報を取得します．

**8. テキスト**
7で取得した天気情報の場所の名前が完全な住所になってしまうので，oo県xx市レベルを取得したいので，正規表現で取得します．
現在地の都道府県・市区町村の正規表現は，[こちらの記事](https://qiita.com/zakuroishikuro/items/066421bce820e3c73ce9)のものを参考に取得しています．

**9. テキスト**
喋らせたい文章を書きます．
ここでは，「日付」「現在地の都道府県・市区町村」「天気」「気温」「最高気温」「最低気温」「降水確率」を採用しています．

「日付」のカスタムフォーマットは，`yyyy年MMMdd日EEE曜日`にしています．

**10. 書類**
9で書いたテキストを喋らせます．

**11. 音量**
最初に取得しておいた元の音量に戻します．
戻さないと次何かを再生したときに，とてもビックリします．

## おわりに
この記事では，朝のラジオ体操を自分の起床タイミングで実施したくて作成したショートカットの紹介と説明をしました．
みなさんもよかったらこのショートカットで良い朝を迎えてください．

それでは，Happy Hacking! :smile:
WordPressのwp_head()の余計なmetaを削除する

ワードプレスのテーマtwentytwentyoneを基盤に、wp_head() 挿入時に自動生成される余計なmeta情報を削除する実装を行ったので、備忘録的にこの記事を残す。

# 環境情報

PHP：version 7.3.12
WordPress：version 5.5.3
WPテーマ：twentytwentyone

# 作業

```functions.php
// WPのバージョンを削除
remove_action( 'wp_head', 'wp_generator' );

remove_action( 'wp_head', 'rsd_link' );

remove_action( 'wp_head', 'wlwmanifest_link' );

remove_action( 'wp_head', 'index_rel_link' );

remove_action( 'wp_head', 'parent_post_rel_link', 10, 0 );

remove_action( 'wp_head', 'start_post_rel_link', 10, 0 );

remove_action( 'wp_head', 'adjacent_posts_rel_link_wp_head', 10, 0 );
// metaタイトルを削除
remove_action( 'wp_head', '_wp_render_title_tag', 1);
// 投稿、コメントのフィードに関するlinkタグを削除
remove_action( 'wp_head', 'feed_links', 2 );
// カテゴリごと、タグごと、投稿者ごと、検索のフィードに関するlinkタグを削除
remove_action( 'wp_head', 'feed_links_extra', 3 );

```
Db2にODBC接続する

Db2にDatabaseが作れたら、次はクライアントPCからの接続だ。


まずはサーバーのPORTを開ける作業が必要。
WindowsならばFireWallの設定を変更してTCPの50000を開ける。


次にクライアントPCにODBCドライバをインストールする必要がある。
http://www-01.ibm.com/support/docview.wss?rs=0&uid=swg21385217&loc=ja

IBM Data Server Driver Package (DS Driver) を選択する。
32bit or 64bitの選択は、作成するアプリケーションが32bitならば32bit。
そうでなければ64bit。とする。

DLしてインストール。
この辺は問題なさそう。

DSNで接続テストをして、繋がることを確認しておくといい。




プログラムでは以下のように書く。
driver={IBM DB2 ODBC DRIVER};Database=SAMPLEDB;hostname=192.168.0.61;port=50000;protocol=TCPIP;uid=db2admin;pwd=xxxpassxxx

これでつながる。
黒猫SQLもこの文字列でつながる。
SQL Serverと違って少し項目が多いが気にしない。
これにセキュリティとか考えて増やせばいい。
IPv4とIPv6の優先度を切り替える方法(Windows10) 

# 前置き

この記事は個人的に躓いたものをメモとして残しています。

筆者はIT初心者の為使用している用語が間違っていたり、わかりづらい説明となっている部分もありますがご了承ください。

**※2020年12月に投稿しました。**


# 背景

* Windowsの設定でIPv6は無効化されている。

* localhostを使用してDB接続を行おうと思ったが、localhostがなんとかってエラーが発生して優先度を確認したところ**IPv6の優先度がIPv4よりも高く**なっていた為、優先度変えよってなった。


# 使用PC

Windows 10 Pro


# 対応方法

####➀　cmd(コマンドプロンプト)を起動する。


####➁　自分自身(localhost)にpingを飛ばす。

```
ping localhost 
```

**実行結果**

```
::1 からの応答: 時間 <1ms
::1 からの応答: 時間 <1ms
::1 からの応答: 時間 <1ms
::1 からの応答: 時間 <1ms  
```

**::1** というのはIPv6です。
IPv4の場合は基本的には **127.0.0.1** が返ってきます。


####➂　IPアドレスの優先度を確認する

```
netsh interface ipv6 show prefixpolicies
```

**実行結果**

```
優先順位   ラベル  プレフィックス
----------  -----  --------------------------------
        50      0  ::1/128  ←IPv6
        40      1  ::/0
        35      4  ::ffff:0:0/96  ←IPv4
        30      2  2002::/16
         5      5  2001::/32
         3     13  fc00::/7
         1     11  fec0::/10
         1     12  3ffe::/16
         1      3  ::/96
```

こんな感じに現在のIPの優先度が表示されます。

優先度50に**IPv6[::1/128]**が設定されているため、**ping localhost**コマンドでIPv6が返ってきています。

※今回は**IPv4[::ffff:0:0/96]**が一番上にくるように設定していきます。


####➃　cmd(コマンドプロンプト)を管理者モードで起動する


####➄　IPアドレスの優先度を変更する(要管理権限)

```
netsh interface ipv6 set prefixpolicy ::ffff:0:0/96 50 0
netsh interface ipv6 set prefixpolicy ::1/128 40 1
netsh interface ipv6 set prefixpolicy ::/0 30 2
netsh interface ipv6 set prefixpolicy 2002::/16 20 3
netsh interface ipv6 set prefixpolicy ::/96 10 4
```

**IPv6[::1/128]**の優先度を**40**に、
**IPv4[::ffff:0:0/96]**の優先度を**50**に設定しました。

※今回はIPv4以外の部分も変えていますが、**IPv4[::ffff:0:0/96]の優先度を50以上にするだけ**でOKです。


####➅　変更されているかIPアドレスの優先度を確認する

実際に変わっているか確認しましょう
※実行するコマンドは**➂と同じ**です。

```
netsh interface ipv6 show prefixpolicies
```

**実行結果**

```

優先順位   ラベル  プレフィックス
----------  -----  --------------------------------
        50      0  ::ffff:0:0/96 　←IPv4
        40      1  ::1/128　←IPv6
        30      2  ::/0
        20      3  2002::/16
        10      4  ::/96
         5      5  2001::/32
         3     13  fc00::/7
         1     12  3ffe::/16
         1     11  fec0::/10
```

これで**IPv4の方が優先度が高く**なりました。


####➆　改めて自分自身(localhost)にpingを飛ばす。

```
ping localhost
```

**実行結果**

```
127.0.0.1 からの応答: バイト数 =32 時間 <1ms TTL=128
127.0.0.1 からの応答: バイト数 =32 時間 <1ms TTL=128
127.0.0.1 からの応答: バイト数 =32 時間 <1ms TTL=128
127.0.0.1 からの応答: バイト数 =32 時間 <1ms TTL=128
```

ちゃんとIPv4になってますね！

これでIPv6からIPv4への優先度の変更は完了です:sunny:


#あとがき

今回は自分が詰まったトラブルの対応として**IPv4とIPv6の優先度を切り替える**という手法を書かせていただきました。

筆者はcmdとかナニソレオイシイノ？って感じなので、
このメモが同じようなトラブルで困ってる方の手助けになれば嬉しいです。

では！
サポートエンジニアとして

## 初めに
この記事は[Wanoグループ Advent Calendar 2020](https://qiita.com/advent-calendar/2020/wano-group) の24日目の記事になります。

## サポートエンジニアって？
「サポートエンジニア」という名称は便宜上勝手に命名しました。

業務の内容としては

* お客様から「こうこうこういう対応をしてほしい」などの特別対応をする。
* 営業側の方などから報告を受けた仕様(及び仕様漏れ)の確認、バグ調査などを行う。

など...野球で例えるならどこでも登板して投げる便利屋中継ぎ投手ですね。

## なんでサポートエンジニアになったの？
それまでの経緯として、今までバグ/仕様の調査などが発生した場合は「基本的にチームの一番偉い方に聞く」ような流れになってしまっていました。しかし「偉い方のリソースが奪われてしまうのが良くない」ということになり2020年5月辺りになって、同期のエンジニアと方と一緒に任命されました。

## ココがツライよサポート業務
### 各機能の仕様を理解していないといけない問題
例えば「XXXXの機能おかしくない？」となって調査する場合、

* ウェブページ$P_{now}$から$P_{next}$に遷移する場合、「どのページから」「どのページへ」「どの条件で」遷移するのか理解していないといけない。
* ある操作$X$を行った場合、データのステータスがどのように遷移するのが正しいのか理解していないといけない。

機能の仕様や詳細がわからない場合はソースコードを読み込んだり、開発を担当した方に問い合わせたり、偉い人に聞いたり...特に開発担当者が休暇を取得していたり退職されていたりすると何も言えなくなります。

### 本番DB入りたくない問題
特別対応をする場合は頑張ってデータベースの値を書き換えたりするのですが...ミスをすると最悪お客様のデータをぶっ飛ばしてしまうので心にツライ作業です。
今の時点での心得としては

* 本番DBに入ったら「死ぬ気」で `begin` する。
* `update` などを入力する場合「先に where 以下を入力」してから set を入力する(by 偉い方の教え)。
* 書き込み系のクエリを打つ場合はログを戻って `begin` してるか確認する。

です。もし本番DB作業しないといけなくなってしまったら上記を心得ると良いかもしれません。

## サポートしてて思うこと

### 先駆者(?)の人が凄い
チームには自分よりも前に特別対応を数多くこなしているエンジニアYさんが居ます。素早く正確に特別対応業務などをこなしているところを見ると「すごいな」と思うしかありません。

### 仕様を理解できるチャンス
例えば開発したことのない、もはやまったく知らない機能や仕様について調査を依頼されることもあります。
知らないことなので当然 `grep` することから始まり、時間もかかってしまいますが技術的にも業務的にも新しい発見を見つけるチャンスなのでやってみたいかたはサポートに挑戦してみましょう。

### ドキュメントはまとめよう
特に複雑な問い合わせなどの場合はドキュメントを纏めておくと良いです。
似たような問い合わせが来た場合、「どのように対処すればよいか」「どのソースコード読めばよいか」「わからないときは誰に聞けばいいか」を纏めておくと後でみんなが幸せになれます。

### (番外編)
某ローグライクゲームの「困ったときの巻物」欲しくなります(伝わって欲しい)。体力回復ついでにバグの1つくらい修正して欲しいです。


## 最後に

Wanoは積極的にエンジニア採用を行なっています！
まずはオンラインでVPoEとのカジュアル面談から。お好きな入り口からお気軽にお声がけください！
Wano Recruitページ　https://group.wano.co.jp/recruit/
QiitaJobs　https://jobs.qiita.com/employers/wano-inc/postings/1297
Wantedly　https://www.wantedly.com/companies/wano/projects
Findy　https://findy-code.io/companies/522
【Rails6】SNS（Twitter）シェア機能の実装

#はじめに

記事の閲覧・検索ができるアプリケーションの作成中です。
今回記事の内容をSNS（Twitter）でシェアできる機能を実装しました。備忘録のため記述します。

#環境

Ruby on Rails '6.0.0'
Ruby '2.6.5'
FontAwesome導入

#viewファイルの編集

```ruby:
<a href="https://twitter.com/share?ref_src=twsrc%5Etfw"><i class="fab fa-twitter-square fa-2x"></i></a>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
```

data-text="~"などでオプションをつけることで、ツイートに表示されるテキストの設定などができるようです。

#参考

https://www.howtonote.jp/twitter/button/index4.html

こちらの記事を参考にさせていただきました。ありがとうございました。
Azure PowerShell のセットアップ

AzureをPowerShellにて操作する場合、最初に環境のセットアップが必要になります。

[Microsoft Document - PowerShell ドキュメント](https://docs.microsoft.com/ja-jp/powershell/?redirectedfrom=MSDN)

#Azure Cloud Shellを利用する

最初にAzure Powershellを利用する場合、利用するストレージのセットアップが必要です。

##1．PowerShellを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/683282/adb66c82-08eb-8bd5-9ec9-8e1c96c4b055.png)

##2.リソースグループ名、ストレージアカウント名、共有ファイル名を設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/683282/dc0d274d-9dd2-5d10-d74c-8c05b47128ae.png)

##3.正常に作成されたことを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/683282/04d4c1b2-b16c-2fe7-639f-8fd27fdf6a5f.png)

##参考：Azure Potalでも確認可能
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/683282/12596b92-9f84-128a-45a7-05f46f7d1cc9.png)


#Azure Power Shellを利用する
Windows 10にプレインストールされている、Windows PowerShell ISEを利用します。

参考
[Windows PowerShell のインストール](https://docs.microsoft.com/ja-jp/powershell/scripting/windows-powershell/install/installing-windows-powershell?view=powershell-7.1&viewFallbackFrom=powershell-6)
[PowerShellGet を使用した Windows への Azure PowerShell のインストール](https://docs.microsoft.com/ja-jp/powershell/azure/azurerm/install-azurerm-ps?view=azurermps-6.13.0)
[AzureRM から Az への Azure PowerShell の移行](https://docs.microsoft.com/ja-jp/powershell/azure/migrate-from-azurerm-to-az?view=azps-4.8.0)

##1．バージョンを確認する
＊必要に応じて、バージョンアップしてください。

```powershell
$PSVersionTable
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/683282/8d8088c5-6992-144d-86b5-9683e62b6e4c.png)

##2．Azure PowerShell モジュールのインストール

```powershell
Install-Module -Name AzureRM -AllowClobber
```
[Azure PowerShell Cmdletsのインストール](https://www.microsoft.com/web/handlers/webpi.ashx/getinstaller/WindowsAzurePowershellGet.3f.3f.3fnew.appids)

##3．サインイン

```powershell
Connect-AzAccount -UseDeviceAuthentication
```
https://microsoft.com/devicelogin
にアクセスし、コードを入れる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/683282/5867eb11-13ad-9b12-7859-0caae683399c.png)
Azure Resource Group 作成

<H3>●Power Shellの場合

```powershell
New-AzResourceGroup -Name demoResourceGroup -Location japaneast
```
<H3>●Azure portalの場合

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/683282/37f2deab-53f7-bc6f-a5a4-6697c03fb92f.png)
Rails チュートリアル 第5章 備忘録

第5章の備忘録

##環境
Rails 6.0.3
Ruby 2.6.3

##目次
[1 Railsヘルパー](#1-railsヘルパー)
[2 BootStrap導入](#2-bootstrap導入)
[3 partial](#3-partial)
[4 アセットパイプライン](#4-アセットパイプライン)
[5 ルートURL解説](#5-ルートurl解説)
[6 レイアウトリンクのテスト解説](#6-レイアウトリンクのテスト解説)


###1 Railsヘルパー 

####1.1 link_to

```rails
<%= link_to "Sign up", signup_path, class: "btn btn-lg btn-primary" %>
```
第1引数はリンクテキスト
第2引数はURL
第3引数はオプションハッシュ（必須ではない）
最終的にaタグが生成される

####1.2 image_tag

```
<%= link_to image_tag("image.jpg", alt: "image", width: "300px"), "https://example~~.com/" %>
```
画像を使用する場合は、```image_tag```ヘルパーを追加する。
引数には、画像ファイルのパスと任意のオプションハッシュ(今回はaltとwidth)
最後のURLはクリックした際のリンク先になる。Railsチュートリアルでは公式サイトに飛ぶように設定されている。
**画像は```app/assets/images/```ディレクトリに置いておく！！**

###2 BootStrap導入
Gemfileにbootstrap-sassを追加

```:Gemfile
gem 'bootstrap-sass', '3.4.1'
```

bundle installを実行して、Bootstrapをインストール

```
bundle install
```

使用するscssファイルにBootstrapCSSを追加する

```:app/assets/stylesheets/~~~.scss
@import "bootstrap-sprockets";
@import "bootstrap";
```

###3 partial
コードを単位毎に分割してそれぞれのファイルで管理することで可読性・変更が容易になる。この機能をRailsではパーシャルという。

```:app/views/layouts/_header.html.erb
<header class="navbar navbar-fixed-top navbar-inverse">
  <div class="container">
    .
    .
  </div>
</header>
```
分割するファイル名は、先頭にアンダースコアをつける命名規則がある。


```app/views/layouts/application.html.erb
.
.
  <body>
    <%= render 'layouts/header' %>
    <div class="container">
      <%= yield %>
    </div>
  </body>
</html>
```

パーシャルを追加するときは、```render```ヘルパーを用いる。
また、```'layouts/header'```で、```app/views/layouts/_header.html.erb```ファイルを探してくれる。
**アンダースコアを書かない点に注意！！**



###4 アセットパイプライン
アセットパイプラインとは、CSS, JS, 画像などの静的コンテンツの生産性・管理を強化する機能である。Webpack（JSのアセットをまとめるバンドラー）, Yarn（JSの依存関係を管理するマネージャ）のどちらも正常に動く。

`アセットディレクトリ`、`マニフェストファイル`、`プリプロセッサエンジン`という3つの主要な機能を持っている。今回は最初の2つに関してまとめてみた。

#####アセットディレクトリ
Railsでは3つの標準ディレクトリが使われている。
1. `app/assets` : 現在のアプリケーション固有のアセット
2. `lib/assets` : 自分の開発チームによって作成されたライブラリ用アセット
3. `vender/assets` : サードパーティのアセット（デフォルトでは無し）

個人で開発するときは、`app/assets`がメイン

#####マニフェストファイル
静的ファイル（アセット）をどのように1つのファイルいまとめるのかをRailsに指示するファイルのこと。

```:app/assets/stylesheets/application.css
.
.
*= require_tree .
*= require_self
*/
```
1行目では、`app/assets/atylesheets`内のCSSファイルが`application.css`に含まれることを指示。
2行目は`application.css`自身もその対象に含めることを指示。


###5 ルート（名前付き）URL解説
ルート（名前付き）URLを設定すると、2種類のメソッドでURLを参照することが可能になる。

```
root_path -> '/'
root_url  -> 'https://www.example.com/'
```

基本的には`_path`を使用。
リダイレクト時のときは`_url`を使用（HTTPの標準として、リダイレクト時は完全なURLが要求されるため）


###6 レイアウトリンクのテスト解説

```test/integration/site_layout_test.rb
require 'test_helper'

class SiteLayoutTest < ActionDispatch::IntegrationTest

  test "layout links" do
    get root_path
    assert_template 'static_pages/home'
    assert_select "a[href=?]", root_path, count: 2
    assert_select "a[href=?]", help_path
    .
    .
  end
end
```

流れは、
1. ルートURLにGETリクエスト
2. 正しいページが描画されているかチェック
3. 各ページへのリンクが正しく動くかチェック

**`?`は、後のpathに置換されるのがポイント**
また、個数をオプションで付けることが可能