OmniAICreator/Qiita-1.07M huggingface dataset:
もう迷わない .gitattributes で改行コードを統一

# きっかけ

Gitで差分を見るとき...

```diff
diff --git a/README.md b/README.md
index 21d2221..28086a1 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,3 @@
 Apple
+Banana^M
+
```

というように、差分の行末に ^M が付与されて鬱陶しい場合がある。
Windowsの改行コードがCRLFなのに対し、
Linuxの改行コードはLFになっているため、
GitはCRLFのCR部分を余計なものと見なし、こういった形で表示される。
設定で非表示にすることもできるのだが、
コミットの際に誤って改行コードを混在させないためにデフォルト設定のままにした方が良いと思う。
ただ、改行コードが混在していないかどうかを目視でチェックするのはあまりにも面倒くさい...
改行コードの混在をシステム的に防ぐ方法は無いのだろうか？

# 世の中の人たちはこの問題にどう対処しているのか

Windowsで開発を行い、改行コードの混在問題に直面する機会が多いであろうMicrosoftのリポジトリを見てみる。
<https://github.com/microsoft/vscode-dev-containers>

```shell:.gitattributes
* text=auto eol=lf
*.{cmd,[cC][mM][dD]} text eol=crlf
*.{bat,[bB][aA][tT]} text eol=crlf
*.gif binary
*.jpeg binary
*.png binary
*.gz binary
*.jar binary
```

この例だと、基本的にはLFに寄せて、Windows固有のcmdファイルとbatファイルだけ例外的にCRLFにしている。

また、改行コードの統一について言及しているページを探してみたところ、MicrosoftによるVSCodeのドキュメントがヒット。
[Visual Studio Code Remote Development Troubleshooting Tips and Tricks](https://code.visualstudio.com/docs/remote/troubleshooting#_resolving-git-line-ending-issues-in-wsl-resulting-in-many-modified-files)
該当部分をGoogle先生に翻訳してもらうと、
>コンテナー内のGit行終了の問題の解決（多くの変更されたファイルが発生します）
WindowsとLinuxは異なるデフォルトの行末を使用するため、Gitは、行末以外に違いがない多数の変更されたファイルを報告する場合があります。これを防ぐために、.gitattributesファイルを使用して、またはWindows側でグローバルに行末変換を無効にすることができます。
>通常 .gitattributes、リポジトリ内のファイルを追加または変更することが、この問題を解決するための最も信頼できる方法です。このファイルをソース管理にコミットすると、他の人を助け、必要に応じてリポジトリごとに動作を変えることができます。たとえば、以下を .gitattributes ファイルにリポジトリのルートに追加すると、CRLFを必要とするWindowsバッチファイルを除いて、すべてが強制的にLFになります。

```shell:.gitattributes
* text=auto eol=lf
*.{cmd,[cC][mM][dD]} text eol=crlf
*.{bat,[bB][aA][tT]} text eol=crlf
```

やはり基本はLFで、Windows固有のファイルだけCRLFにしている。

他のリポジトリも見てみると、
<https://github.com/microsoft/vscode>

```shell:.gitattributes
* text=auto

LICENSE.txt eol=crlf
ThirdPartyNotices.txt eol=crlf

*.bat eol=crlf
*.cmd eol=crlf
*.ps1 eol=lf
*.sh eol=lf
*.rtf -text
```

あれ？今度はちょっと違う
まあ * text=auto によってリポジトリでLFに変換されるので、結局内部的にはLFになるんだけども
個人的には eol=lf でLFで統一する方がシンプルで分かりやすいんじゃないかと思った。
ところで、ps1ファイルが eol=lf と指定されているのがちょっと意外だった。
そういえば、先程の例でもps1ファイルはCRLFに変換されていなかったので、どうやらps1ファイルの改行コードはLFらしい。
本題からは少し話が逸れるが、binaryファイルを明示的に指定する必要はあるんだろうか？
そうしていないリポジトリもたくさんあるのを考えると、わざわざ明示的に指定する必要はないような気もする。
ユーザーの側がバイナリファイルを全て記載するのは手間がかかりすぎるし、そこらへんはGit側で判断して上手いことやってくれているんじゃないだろうか？分からないけど

## 結論

### 基本的にLFで統一して、cmdファイルとbatファイルだけCRLFにする

```shell:.gitattributes
* text=auto eol=lf
*.{cmd,[cC][mM][dD]} text eol=crlf
*.{bat,[bB][aA][tT]} text eol=crlf
```
【React】JSON形式の日付データを綺麗に整形して表示する

## はじめに
ReactとRails APIで掲示板を作っている際に、APIからjson形式で受け取った日付データを綺麗なフォーマットにするのに少し躓いたので自分なりの解決策を共有できたらと思います。
##目標
たとえば何か新規投稿を作ったとき、そのcreated_atデータは
2021-06-25T14:17:39.921Zのようなフォーマットになります。これを
2021/6/25 23:17のような形式に整形したいです。

##コード

```Post.js
handleToDate=(date)=>{
        date = new Date(date);
        if(date.getMinutes() < 10){
            date = date.getFullYear()+"/"+(date.getMonth()%12+1)+"/"+date.getDate()+" "+date.getHours()+":0"+date.getMinutes()
        } else {
            date = date.getFullYear()+"/"+(date.getMonth()%12+1)+"/"+date.getDate()+" "+date.getHours()+":"+date.getMinutes()
        }
        
        return date;
```
こちらの関数でフォーマットを変更します。

まずは受け取ったjsonデータをnew Date()で日付のデータとして認識させます。

そこからgetFullYear(),getMonth(),getDate(),getHours(),getMinutes()関数でそれぞれ年、月、日、時間、分の情報を取得します。

細かいこととして、getMonth()で取得した月はなぜか実際の月-1されるようです。そのため+1で補正しています。12月のときには1月となるようにしています。また、分が一桁のとき0を先頭につけるようにしています。

## 活用
例として

```App.js
return(
  <div>
      {this.handleToDate(this.post.created_at)}
  </div>
        );
```
このようにrender内で書いてあげることでうまく表示できます。

RailsでもAPIを介さない場合であればstrftime()を使うことで簡単に便利に日付フォーマットを指定できるようです。
pcapファイルをrosbagファイルに変換する

# はじめに
初投稿です。拙い点ご容赦ください。
また、ROS初心者のため間違えているところ等ありましたらご指摘いただけますと幸いです。

以下、velodyne LiDARなどから得られるpcapファイルをrosbagファイルに変換する手順です。
velodyneドライバをビルドした後に変換処理を行うという流れになります。

#環境
OS：Ubuntu 18.04 LTS　
ROS：Melodic

# velodyne_driverのビルド

すでにROS自体のインストールは完了している前提で、リポジトリからgit cloneしてきたものをビルドするまでに行った手順は以下のようになります。なお、ビルドはcatkin buildではなくcatkin_makeで行いました。

###catkinワークスペースの作成

```
mkdir -p ~/catkin_ws/src
cd ~/catkin_ws/src
catkin_init_workspace
```

###velodyne_driverのgit clone

```
cd ~/catkin_ws/src
git clone https://github.com/ros-drivers/velodyne
```

###catkin_makeでビルド

```
cd ~/catkin_ws
catkin_make
```

### エラー
ここで以下のようなエラーが発生しました。

```
velodyne/velodyne_driver/src/lib/CMakeFiles/velodyne_input.dir/build.make:62: recipe for target 'velodyne/velodyne_driver/src/lib/CMakeFiles/velodyne_input.dir/input.cc.o' failed
    make[2]: *** [velodyne/velodyne_driver/src/lib/CMakeFiles/velodyne_input.dir/input.cc.o] Error 1
    CMakeFiles/Makefile2:5260: recipe for target 'velodyne/velodyne_driver/src/lib/CMakeFiles/velodyne_input.dir/all' failed
    make[1]: *** [velodyne/velodyne_driver/src/lib/CMakeFiles/velodyne_input.dir/all] Error 2
```

### 解決法
調べてみるとどうやらライブラリの依存関係の問題のようです。
https://github.com/ros-drivers/velodyne/issues/319

rosdepを使います。もしインストールしてなければ、Melodicの場合以下のようにインストールします。

```
sudo apt install python-rosdep
```

rosdep installを実行します。

```
rosdep install -i --from-paths ~/catkin_ws/src/velodyne
```

改めてcakint_makeをしたところ、ビルドが成功しました。

```
cd ~/catkin_ws
catkin_make
```

# 変換処理
いよいよpcapファイルをrosbagファイルに変換します。pcapファイルの名前をsample.pcap、rosbagファイルの名前をsample.bagと仮にします。
sample.pcapの場所は~/catkin_ws/src/velodyne/、sample.bagを出力する場所も~/catkin_ws/src/velodyne/とします。

これからターミナルのタブをたくさん開きながら進めていきます。

###1つ目のタブ

```
roscore
```

###2つ目のタブ

```
roslaunch velodyne_pointcloud 32e_points.launch pcap:=$(pwd)/sample.pcap readonce:=true
```

###3つ目のタブ

rosbag recordでROSトピックの取得を行います。
-O sample.bagでファイル名sample.bagの指定、/velodyne_pointsで今回取得するROSトピックであるvelodyne_pointsトピックの指定を行います。

```
rosbag record -O sample.bag /velodyne_points
```

というわけで合計3つターミナルのタブを開いて実行しています。

適当に時間が経ったところでrosbag recordのタブをCtrl+Cで停止するとsample.bagが出力されます。

停止せずに放置しているとsample.bagのファイルサイズがどんどん大きくなってしまうため、
pcapファイルを取得したときの計測時間を予め記録しておいてその時間で止めました。

(他により良い方法をご存じの方がおられたら教えていただけると幸いです。)


# 参考文献
- [Convert a Velodyne PCAP file into a ROS bag file](https://dominoc925.blogspot.com/2019/08/convert-velodyne-pcap-file-into-ros-bag.html )
- [Convert Raw Velodyne VLP16 pcap to bagFile](https://answers.ros.org/question/213080/convert-raw-velodyne-vlp16-pcap-to-bagfile/ )
- [catkin_make error](https://github.com/ros-drivers/velodyne/issues/319 )　
- [rosdep使おうよ](https://qiita.com/strv/items/ccd89c55957bd8dfada0 )
- [ROS講座11 gitリポジトリ](https://qiita.com/srs/items/25a56a6abda41dcf396e )
Windows11アップグレード要件

#厳しいアップグレード要件
今年後半にも提供されるという噂のWindows11。
ハードウェアの要件さえ満たしていれば無償アップグレードだそうだ。
ということで個人的に要件をメモしておく。
#CPU
###Intel
第８世代Core/Celeron/Atomシリーズ以降
まずこの時点で脱落PC多数。2016年以前に購入したPCはほぼアウト。
###AMD
Ryzen 2000シリーズ以降と一部のAthron
AMDの場合はさすがにPhenomIIを使ってる人はいないと思うので
インパクトは小さいだろう。だが初代Ryzenは脱落。チーン。
Ryzen1000番台と2000番台ってソケット互換性あったっけ？
#BIOS（または一部CPU）
UEFIのセキュアブート必須。
レガシーブートでUEFIセキュアブート対応可能ならBIOS設定を変更。
CPUまたはマザーボード搭載ハードウェアのTPM2.0対応必須。
TPMとはCPUと独立して動作するハードウェアによるセキュリティ機構。
#その他
CPU 1GHz以上64bitモード必須（32bit Windowsは切り捨て）
メモリ4GB以上
ストレージ64GB以上
まあこのへんはどうってことない。
#総合
マイクロソフトは中古業者を滅ぼすつもりだろうか。
非対応PCやCPUパーツをどうしろというのだろう。
Linux専用マシンにでも生まれ変わらせろと言うのだろうか。
UEFIセキュアブートくらいならi7 4770のうちのPCでもできそうだが
CPU世代で切り捨てられたらどうしようもない。
特に企業ユーザなんかはクレームの大合唱ではないだろうか。
もう少しCPU要件を緩和してくれることを期待しよう。
日時にまつわるLambdaのエラー

# 時間にまつわるlambdaのエラー
社内用に作成した処理が、ローカルでは稼働していたが、
Lambda上でエラーが発生し、機能したい状態となっていました。

## やっていたこと
①会社のメールアドレス宛に問い合わせメールが届き、
　問い合わせ用アドレスのメールボックスにメールが蓄積

②pythonのライブラリ、seleniumを使用してメールの情報を取得し、
　googleのスプレッドシートへ「問い合わせ日時」、「問い合わせ内容」、
　「問い合わせ者の氏名」等を転記

③上記の処理をlambda上で10分おきに定期実行

④スプレッドシート上の最新の問い合わせの日時と、
　現在の時間を照らし合わせ、その間の時間に届いたメールの内容を取得し、
　転記する処理を実行
【例】
シート上の最新の問い合わせ日時
→2021/04/01 12:14:38

lamda上の処理が実行された時間
→2021/04/01 12:24:35

上記の場合、4/1の12時14分39秒から、
同日の12時24分35秒の間に届いたメールがあれば、
シートに転記がされる。


## エラーの内容
<strong>エラーの種類：unexpected alert open<strong>

## エラーの原因
<strong>ローカルのPC上での時間と、Lamda上での時間に差異があったため</strong>
①ローカルのPCでの実行の場合
スプレッド上の時間と処理の実行時間に差異が無い

②lambda上での実行の場合
スプレッド上の時間→日本時間
処理の実行の時間→アメリカ時間
<strong>スプレッド上の最新日時が4/1であるが、
lambda上での実行時間が3/31になるという事態が生じていた</strong>

## エラーの解決策：環境変数の設定
![4nso11rgsr146515b6sr1g6s105.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1703246/62be313d-0aa3-6621-e5d3-0bf966a54008.png)
<strong>【設定→環境変数→キーにTZ、値にAsia/Tokyoを設定】</strong>
→lambda上での実行時間とスプレッド上の最新時間、
　どちらも日本時間になり、lambda上で処理が回るように
Excelで均等割り付けができない！

そんな時は優先言語の設定で日本語優先にすることで解決しました。
Excel使いたくないといいつつ抜け出せない日々...orz

情報源：
https://answers.microsoft.com/ja-jp/msoffice/forum/msoffice_excel-mso_winother-mso_2016/%E3%82%A8%E3%82%AF%E3%82%BB%E3%83%AB2016%E3%81%A7/23a65836-936d-443d-8325-0eef66b32eca

ファイル > オプション > 言語 より以下のように設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26413/d0538d0e-fb71-4da4-eeb5-f98a92ce2331.png)
python FastAPI を使ってみた

##はじめに
高速で有名なpythonのフレームワークのfast apiのチュートリアルをやってみました。
pythonのフレームワークはflaskくらいしか経験なかったんですが、非常に簡単に立ち上げが出来ました。
※公式のチュートリアルに沿って実施しています。



## 環境
 - lenovo Ideapad Duet(Chroome book)
 - Debian GNU/Linux 10 (buster)
 - python 3.7.3
 

## インストール
以下コマンドでインストールしていきます。
稼働させるにはUvicornもしくはHypercornと呼ばれるASGIサーバーソフトウェアのインストールが必要だそうです。

```bash
pip install fastapi
pip install uvicorn[standard]
```
ここではuvicornを使用します。

## エンドポイントの作成

```python:main.py
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {"Hello": "World"}


@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = None):
    return {"item_id": item_id, "q": q}

```

## アプリケーション起動

```
uvicorn main:app --reload
```

http://127.0.0.1:8000/
にアクセス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698646/2ff30c5c-f705-c196-b86e-9fbdfb34531e.png)

### GET

関数の引数ですが、
アノテーションのURLに{変数名}を指定することでパス内にパラメータを設定することができ、
その他はクエリストリングから取得するようです。

```python
@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = None):
    return {"item_id": item_id, "q": q}
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698646/25e1bf83-3ec8-38ea-c709-8802bbec8a94.png)


### POST(PUT)

POST,PUTはリクエストBodyから取得するようです

```bash
curl -X POST -H "Content-Type: application/json" -d '{"name":"testItem", "price":"100","is_offer":true}' localhost:8000/items/5
{"item_name":"testItem","item_id":5}
```


```python
from pydantic import BaseModel

class Item(BaseModel):
    name: str
    price: float
    is_offer: bool = None

@app.post("/items/{item_id}")
def update_item(item_id: int, item: Item):
    print(item)
    return {"item_name": item.name, "item_id": item_id}

```

## ドキュメント自動生成

swaggerUI,redoc形式のdドキュメントが自動生成されるのが便利ですね。

### swagger

/docs

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698646/5b8b1600-f03d-6c05-5c95-151519efc48b.png)


### redoc

/redoc

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698646/5dda7dc5-2238-182f-1a29-5112b95dbb75.png)


自動生成されるドキュメントはどのようにカスタマイズするのか等は今後記事にできればと思います。
ArcGIS Platform で 1km メッシュ別将来推計人口のベクタータイルを Mapbox GL JS で表示してみる。

今回は、国土数値情報で公開されている 1km メッシュ別将来推計人口（H30国政局推計）（shape形式版）を使用して、Mapbox GL JS で表示してみたいと思います。1kmメッシュ別将来推計人口（H30国政局推計）のデータを使用するに当たって、ArcGIS Platform にデータを登録して、登録したデータに対してベクタータイルを作成します。最後に作成したベクタータイルを Mapbox GL JS で表示しました。

<img src="https://cdn-ak.f.st-hatena.com/images/fotolife/f/freedom0625/20210523/20210523142936.png" alt="ArcGIS Platform" title="" class="hatena-fotolife cboxElement" itemprop="image">

1kmメッシュ別将来推計人口（H30国政局推計）データは、全国で提供されており、今回は岐阜県のデータを使用しました。属性情報として、2050 年までの将来推計のデータがあり、2030年の属性データを表示しました。属性情報のデータ項目一覧はこちらで確認できます。

https://nlftp.mlit.go.jp/ksj/gml/datalist/KsjTmplt-mesh1000h30.html

ArcGIS Platform は Esri が提供している PaaS（Platform as a Service）のサービスで、開発者アカウントを作成すれば、ある一定枠までは無償で使用することができます。もちろん、今回は無償の範囲で行いました。全体のソースは、GitHub にもアップしました。

https://github.com/valuecreation/mapbox-gl-js-samples/blob/master/20210522/index.html

詳細は、以下のブログをご参照ください。

https://freedom-tech.hatenablog.com/entry/2021/05/23/151940
ArcGIS Platform で ベクタータイル ベースマップ を ArcGIS API for JavaScript で表示してみる。


Esri 社では背景地図として、ベクタータイル ベースマップを提供しており、グローバルとして提供しているため、世界中の地図を使用することができます。そのため、地図上で表示している言語も開発者が任意にして使用することもできます。

Esri社 のベクタータイル ベースマップのリファレンスも提供されており、例えば、このドキュメントの 35 ページに記載されている手順の「root.json」ベクタータイル スタイルファイルを編集することで言語の設定などを変更することが可能です。

Esri Vector Basemap Reference Document (v2)
https://esri.maps.arcgis.com/home/item.html?id=c908722b0841404ba6a87d6221f201e4

また、ArcGIS Vector Tile Style Editor も提供しているため、地図のデザインを自由に変更したりしてオリジナルの地図を作成することも可能です。

https://developers.arcgis.com/vector-tile-style-editor/

デフォルトでは、Esri社が ArcGIS Online を利用してアクセスできるさまざまなベクター ベースマップを提供しています。今回は、そこで提供している背景地図を ArcGIS API for JavaScript を使用して表示しましたので、その手順について紹介したいと思います。背景地図の使用では、API キーを使用しました。

詳細は、以下のブログをご参照ください。

https://freedom-tech.hatenablog.com/entry/2021/05/16/232826
Mapbox Geocoding API（Mapbox JavaScript SDK）を利用してみた！

Ruby on Rails で JavaScript を使用しているのですが、今回 Rails 側で登録済みの住所からジオコーディングをして地図に表示するという要件があり、Mapbox の Geocoding API を使用しました。もともと 管理者用の画面では、地図を使用している機能があり、Mapbox GL JS を使用しているため、Mapbox の Geocoding API を試しに使用してみました。今回は、Geocoding API を利用するために Mapbox JavaScript SDK を使用してみましたので、簡単に実装方法について紹介したいと思います。

詳細は、以下のブログをご参照ください。

https://freedom-tech.hatenablog.com/entry/2021/05/09/231704
イベント報告（Web API LT会 ）

先日久しぶりにイベントに参加して、LT（ライトニングトーク） をしました。 コロナのため参加はもちろん ZOOM での参加でした。

https://rakus.connpass.com/event/208444/

テーマは「Web API」の LT（ライトニングトーク：1人5分程度）でした。 LT（ライトニングトーク）は API（Application Programming Interface）をテーマに行い、API に関わることならなんでもOK！ということで、自分は、最近触っている PaaS の ArcGIS Platform について発表させていただきました。

https://freedom-tech.hatenablog.com/entry/2021/05/08/203416
はしご備忘録

```
c# Ladder.cs

	public void InitLadder(GameObject _LadderObject)
	{
		//重力off　梯子オブジェクトのx座標をプレイヤーのx座標にあわせる  トリガーにする(床貫通用)
		g_Rb2D.gravityScale = 0.0f;
		transform.position = new Vector2(_LadderObject.transform.position.x, transform.position.y);
		GetComponent<BoxCollider2D>().isTrigger = true;

                //最大ｙ値=梯子オブジェクトの中心y座標+梯子のローカルスケール/2+プレイヤーのローカルスケール/2
		MaxLenLadder = _LadderObject.transform.position.y + _LadderObject.transform.localScale.y * 0.5f
                               + transform.localscale.y*0.5f;
		MinLenLadder = _LadderObject.transform.position.y - _LadderObject.transform.localScale.y * 0.5f
                                +transform.localscale.y*0.5f;
	}

    void UpdateLadder()
	{
        float MovementY=Input.GeyAxis("Horizontal");
        //上り
		if (MovementY> 0.0f)
		{
			if (MaxLenLadder > transform.position.y)
			{
				transform.position += new Vector3(0, 0.03f);
			}
		}
        //下り
		else if (MovementY < 0.0f)
		{
			if (MinLenLadder < transform.position.y)
			{
				transform.position -= new Vector3(0, 0.03f);
			}
		}
	}

	public void UninitLadder()
	{
		//重力on トリガーオフ
		g_Rb2D.gravityScale = 1.0f;
		GetComponent<BoxCollider2D>().isTrigger = false;
	}
```
最大最小のところがややこしい気がするので図で表示（緑の枠が当たり判定）

![はしご.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/788590/69a55711-16eb-f8b1-5fbb-0c35e6c55378.png)

使い方
足がはしごの当たり判定にふれたとき、～キーが押されたらInitLadder()呼び出し
UpdateLadderをUpdateで呼び出し(ほかの操作をしないようにする)
足がはしごにふの当たり判定れたとき、～キーが押されたらUnInitLadder()呼び出しで上り下り終了
MAMP環境でLaravelインストール後の初期設定

# はじめに

タイトル通り、
MAMP環境でLaravelインストール後の初期設定について
書いていきます。

# 本題

まずは、
MAMP環境という事で
MAMPを起動し、MAMPのWEBページに行きます。
Tools->phpMyAdminと進み
Newをクリックしデータベース名を決め
データベースを作ります。

その後、

エディターでインストールしたLaravelを開くと
ディレクトリが並んでます。
そこに、
.env というファイルがあるので開きます。

そこで、

* APP_NAME=　アプリ名

* DB_PORT=8889

* DB_DATABASE= データベース名

* DB_PASSWORD= root

と記述します。

その下に
DB_SOCKET=/Applications/MAMP/tmp/mysql/mysql.sock
を追記します。

この設定方法は、
![スクリーンショット 2021-06-28 21.48.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/860867/30cd6bda-9a11-b164-afda-c2042b223cbd.png)
MAMPのWEBページにて確認できます。

この通りにしてね！って事です。

これで.envの設定は完了です。

# 次に
ディレクトリの
config -> app.php へと進み
７０行目に

```
'timezone' => 'UTC'
```
とあるので、それを

```
'timezone' => 'Asia/Tokyo'
```

に書き換えます。

次に
８３行目

```
'locale' => 'en'
```

これを

```
'locale' => 'ja'
```

に書き換えます。


以上で簡単な初期設定は完了です。
【Vue.js】複数要素を切り替えるトランジションでの注意　key属性とmode属性

## はじめに
仕事で使う事になったので1からVue.jsについて学んだ。
ちゃんと覚えておかないとまずそうな事を備忘録として1つ1つ残しておく。

## 複数要素を切り替えるトランジションの注意　key属性とmode属性
複数の要素で表示・非表示を切り替える際にトランジションを実装する際には、以下の2点に注意する必要がある。

- key属性を付与する
- mode属性でmodeを指定する

### key属性を付与する
実際にまず、key属性を付与しないとどうなるかを見ていく。
key属性を付与しない場合、Vue.jsの効率的な描画を行う仕組みによりタグが同じであればその中身だけを切り替える事をするため、要素そのものが消えたり現れたりする動きにならず、トランジションが機能しない。
※これは[【Vue.js】v-forを使う時の注意点 key属性](https://qiita.com/yuta-katayama-23/items/ea5df45d93d2bed8b42c)で扱った内容と同じ事象。
![ezgif.com-gif-maker (21).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/24b993e3-e009-e799-753b-260d255daddc.gif)
動画のソースコードは以下。

```vue:App.vue
<template>
  <div class="main">
    <button type="button" class="btn btn-primary" @click="show = !show">
      切り替え
    </button>
    <transition name="fade">
      <p v-if="show">さよなら</p>
      <p v-else>こんにちは</p>
    </transition>
  </div>
</template>

<script>
export default {
  data() {
    return {
      show: true,
    };
  },
};
</script>

<style scoped>
.fade-enter {
  opacity: 0;
}
.fade-enter-active {
  transition: opacity 2s;
}
.fade-leave-active {
  transition: opacity 2s;
}
.fade-leave-to {
  opacity: 0;
}
</style>
```

この問題を解決するには、`key属性`を付与し、Vue.jsにそれぞれのpタグの要素が別物であるという事を教えてあげればいい。
すると、以下の動画のようにトランジションが効いた状態にはできる。
※が、少し変な動きになっているので、これを次のセクションの[modeを指定する](#modeを指定する)で解決する。
![ezgif.com-gif-maker (22).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/2f360762-e0f3-f683-81f8-e42cf7781da0.gif)
動画のソースコードは以下。

```vue:App.vue
<template>
  <div class="main">
    <button type="button" class="btn btn-primary" @click="show = !show">
      切り替え
    </button>
    <transition name="fade">
      <p v-if="show" key="bye">さよなら</p>
      <p v-else key="hello">こんにちは</p>
    </transition>
  </div>
</template>

<script>
export default {
  data() {
    return {
      show: true,
    };
  },
};
</script>

<style scoped>
.fade-enter {
  opacity: 0;
}
.fade-enter-active {
  transition: opacity 2s;
}
.fade-leave-active {
  transition: opacity 2s;
}
.fade-leave-to {
  opacity: 0;
}
</style>
```

### mode属性でmodeを指定する
[上記](#key属性を付与する)で、トランジションを機能させた際に切り替えボタンをクリックした後、`こんにちは→さよなら`の両方が表示されてしまっていた。
これは、複数の要素を切り替える際のトランジションでは何もしないと、要素が現れる・消えるのが同時に起きてしまい、それぞれ`opacity 2s`で消えるまでに2s・現れるまでに2sかけてトランジション(アニメーション)が動くので両方の要素が画面上に表示されてしまうため。
これを解決するには、`mode属性`を指定する。具体的には、現れてから消える・消えてから現れるのいずれかの動きをするように指定する。

- `mode="out-in"`：消えてから現れる
- `mode="in-out"`：現れてから消える

このmode属性は`<transition name="fade" mode="out-in"></transition>`のようにtransitionタグの中に書く。

`mode="out-in"`を指定した時のトランジションの動きは以下の動画のようになる。
![ezgif.com-gif-maker (23).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/de23f79a-acc4-2c39-fba0-0e39f5864c4d.gif)
`mode="in-out"`を指定した時のトランジションの動きは以下の動画のようになる。
![ezgif.com-gif-maker (24).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/02dd1a6b-374e-006c-e74c-72e70818c798.gif)

ソースコード全体は以下。

https://github.com/yuta-katayama-23/intro-vuecli/commit/6ab53c90b51606a9790843626d37dae073970079

## Vue.jsの勉強メモ一覧記事へのリンク
Vue.jsについて勉強した際に書いた勉強メモ記事のリンクを集約した記事。

- https://qiita.com/yuta-katayama-23/items/dabefb59d16a83f1a1d4
[Bootstrap]ボタンにリンクを埋めるにはどうしたらいいのか

<h1>Bootstrapで作ったボタンをリンクに！</h1>

以下のコードで、Bootstrapで作成したボタンがリンクになりました。

```
 <div class="button" style="margin:10px 15px;">
　　　　<%= link_to "Log in",new_user_session_path,class:"btn btn-primary btn-block"%>
　</div>
       
<div class="button" style="margin:0 15px;">
<%= link_to "sign up", new_user_registration_path,class:"btn btn-secondary btn-block"%>
</div>
```

ボタンを押すと、log inページ、sign upページへ飛ぶようになりました。

 ![スクリーンショット 2021-06-28 21.55.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633266/ede7d849-7ffd-83e8-4864-646016a35b89.png)


以下は、ここに至るまでの失敗です。。


<h2>失敗..その１ ボタン全体がリンクにならない</h2>

コード

```
<button class="btn btn-secondary btn-block" type="button"><%= link_to "sign up", new_user_registration_path %></button>
```

画面　ボタンはできたし、リンクも埋めた..なんか青くなってる...
:frowning2:ボタンの余白（文字以外のところ）押してもリンクには飛んでくれない状態...
![スクリーンショット 2021-06-28 21.42.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633266/12778a6f-acb8-2fe9-528a-d234330b0962.png)

多分、ボタンを作って、その中にリンクを作ってるからダメなんだろうな。


<h2>失敗..その２ ボタンの中にボタンができた...</h2>

```
<button><%= link_to "Log in",new_user_session_path,class:"btn btn-primary btn-block"%></button>
```
こんな感じ↓↓ ボタンタグで囲ったからボタンが出来てしまったよう。。

![スクリーンショット 2021-06-28 21.48.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633266/6feafce2-f306-2785-0daf-fd5b670e6258.png)
Linux ディレクトリの隠しファイルも含めて表示するコマンド

# 目的

- ディレクトリにあるファイルを隠しファイルも含めて表示するコマンドをメモ的にまとめる

# 方法

- 下記コマンドを実行する

    ```terminal
    $ ls -laF
    ```
標準入出力で簡単にLinux音声処理プログラミング1

## 書いてる人

エンジニアではありません（Qiitaの定義ならかろうじてエンジニア？）
ただのオーディオマニアです。
プログラミングについての教育は受けたことのない素人です。

## はじめに

音声処理のプログラミングをすることが目的なので車輪の再発明は気にしません。
実用になるプログラムを目指します。
実用とは、オーディオマニアがそれなりのシステムで再生するのに実用になる、という意味で、音楽作成・録音や、売り物になるプログラムという意味ではありません。

## やりたいことは簡単なのに...

例えばステレオ2ch音声をモノラル音声にするプログラムを書きたいとします(soxで簡単にできるけど)。
やることは簡単で、両チャンネルを（Lch+Rch)/2 にするだけです。
どうしたら良いでしょう？
入力ファイルはwav? flac?　それともmic?
できればGUIで対象ファイルを選択したいし、インターネットラジオも再生したい。
サンプリング周波数は？ BitDepthは？
考え出すとキリがありません。
どんどん面倒になっていきます。

## 入力再生は別のプログラムに任せよう！

やりたいのは音声信号を処理する部分だけなので、それ以外は別のプログラムに任せましょう。
それには別のプログラムからデータを受け取り、別のプログラムにデータを送る必要があります。

## 標準入出力

Unix系には標準入出力という便利なものがあります。データの入出力にはこれが一番簡単です。なんたって「標準」ですから。

## Linuxで標準入出力ができる音声系プログラム

sox、aplay、arecord、mpd、bruteFIR など
標準入出力を使うだけで色々なプログラムと連携が取れます。

## 音声データのフォーマット

### サンプリング周波数

よく使われるのは 32kHz、44.1kHz、48kHz、88.2kHz、96kHz、176.4kHz、192kHzなどです。DSDは面倒なので無視します。

## BitDepth

音楽でよく使われるのは16bit・24bit・32bit (signed int)、最近なら32bit floatなんてのもある。
CDは16bitで十分な音質だけど、ディザをかけないと音質低下したりするので面倒。
24bitは十分な音質で対応DACも多いけど大抵のプログラミング言語には24bit整数がないのでやはり面倒。
というわけで32bit整数でやり取りするのが良さそう。

## データの並び順

2ch 32bitのステレオデータは大抵の場合LittleEndianでLch,Rch,Lch,Rch...と交互にそれぞれ4byteが並びます。
ソフトによってはBigEndianが選べるものもあります。

# 実際の連携

例えばtest.flac を 自作のプログラム sampleprogram で処理するにはSoxの出力をパイプで受けてパイプでaplayに送れば再生できます。

自作プログラム入出力のの音声データフォーマットは32bit44.1kHzに決め打ちにして、前後のプログラムに対応してもらうことにします。

```
sox test.flac -r 44100 -t raw -c 2 -e s -b 32 - | sampleprogram | aplay -t raw -c 2 -r 44100 -f S32_LE
```

こんな感じにすればOKです。

次回は実際に簡単なプログラムを書いてみます。
Rustのtrait(トレイト)について


## トレイトとは

トレイトとは任意の型であるSelfに対してメソッドを定義でき、共通の振る舞いを実装できる機能です。

トレイトは「任意の型=あらゆるデータ型」に実装することができ、多言語のインターフェースや抽象クラスのような役割を果たします。

## 使い方

※ここでは[Rust By Example](https://doc.rust-jp.rs/rust-by-example-ja/trait.html)からコードを引用し、解説を加えます。

##### トレイト定義

```rust
// Animalというトレイトを定義します
trait Animal {
    // スタティックメソッド(コンストラクタ)のシグネチャ。　`Self` はこのトレイトを実装している型になる。
    fn new(name: &'static str) -> Self;

    // インスタンスメソッドのシグネチャ。これらの関数は文字列を返す。
    fn name(&self) -> &'static str;
    fn noise(&self) -> &'static str;

    // メソッドのデフォルトの挙動を定義することもできる。(もちろんしなくても良い)
    fn talk(&self) {
        println!("{} says {}", self.name(), self.noise());
    }
}
```


##### トレイトを型に実装

```rust
struct Sheep { naked: bool, name: &'static str }

// 上で定義した`Animal`というトレイトを`Sheep`に実装する。
impl Animal for Sheep {
    // `Self`は実装対象の型: ここでは`Sheep`
    fn new(name: &'static str) -> Sheep {
        Sheep { name: name, naked: false }
    }

    fn name(&self) -> &'static str {
        self.name
    }

    fn noise(&self) -> &'static str {
        if self.is_naked() {
            "baaaaah?"
        } else {
            "baaaaah!"
        }
    }
    
    // デフォルトのトレイトメソッドはオーバーライドすることができる。
    fn talk(&self) {
        // 例えば、静かに熟考させてみる。
        println!("{} pauses briefly... {}", self.name, self.noise());
    }
}

fn main() {
    // この場合、型アノテーションが必須。
    let mut dolly: Sheep = Animal::new("Dolly");

    dolly.talk();
}

```

##### 実行結果

```shell
Dolly pauses briefly... baaaaah!
```

トレイトの実装に成功しました。

次に、トレイトメソッドは任意の型のトレイトメソッドでないメソッドからでも呼び出せます。

```rust
impl Sheep {
    fn is_naked(&self) -> bool {
        self.naked
    }

    fn shear(&mut self) {
        if self.is_naked() {
            // メソッドをある型に実装する際に、その型のトレイトメソッドを
            // 使用することができる。
            println!("{} is already naked...", self.name());
        } else {
            println!("{} gets a haircut!", self.name);

            self.naked = true;
        }
    }
}

fn main() {
    let mut dolly: Sheep = Animal::new("Dolly");

    dolly.talk();
    dolly.shear();
    dolly.talk();
    dolly.shear();
}
```



##### 実行結果

```shell
Dolly pauses briefly... baaaaah!
Dolly gets a haircut!
Dolly pauses briefly... baaaaah?
Dolly is already naked...
```



ここで、is_naked()やshare()を上記の```impl Animal for Sheep {}```に追加すればいいと思った人もいるかもしれませんが、

これらはAnimalのトレイトメソッドではないためコンパイルエラーが起こります。

```shell
  Compiling playground v0.0.1 (/playground)
error[E0407]: method `is_naked` is not a member of trait `Animal`
  --> src/main.rs:49:5
```

以上になります。

今回[Rust by Example(RBE)](https://doc.rust-jp.rs/rust-by-example-ja/trait.html)を参考にしたのですが、補足を自分なりに少し加えただけになっています。

気にされる方がいましたらこちらの記事は無視していただけると幸いです。

今後、トレイト境界やサブトレイトについても追記予定です。

## 参考記事
https://doc.rust-jp.rs/rust-by-example-ja/trait.htm
【Excel】F1のヘルプを閉じる＝Ctrl＋Space → C

##概要
Excelで`F1`を押すと開くヘルプのウィンドウを、キーボード操作で最速で閉じる方法を紹介する。
(Excel2016で動作確認)

##効果
`F2`や`半角/全角`を押そうとして、`F1`を押してしまった時のイライラを解消する。

これ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464218/9f937fc6-a4ef-327a-6d86-03c7879fa107.png)

##対策：Ctrl＋Space → C
まず、`Ctrl＋Space`の同時押しで、メニューを表示する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464218/e510f4d1-522c-c48d-3de5-aa84d54175ed.png)

続いて、閉じるの`C`(Close)を押すと、ヘルプが閉じる。
`Ctrl＋Space` → `↑` → `Enter` でもいける。

###注意点
ヘルプのウィンドウがアクティブになっていないと、`Ctrl＋Space`が列選択になってしまう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464218/d6063af9-6473-2e4f-45f3-2ede3cfa09cd.png)

その場合は、不本意ながらもう一度`F1`を押して、ヘルプのウィンドウをアクティブにしたうえで、再度`Ctrl＋Space` → `C`。

##参考：他の対策
####F1キーに別のマクロを割り当てる
https://www.mathkuro.com/windows/best-practice-for-disable-excel-f1/
https://excel-kaikei.com/kowaza004/
サクラエディタで同じようなことをしている。
####専用ソフトをインストールする
https://windows10-help.com/1338/
その名も「F1ブレイカー」。社用PCの場合は、インストール可否を要確認。
####物理的に破壊する
https://excel-kaikei.com/kowaza004/#toc6
社用PCの場合は、破壊可否を要確認。
Python, Selenium　取得したbuttonのWebElementがクリックできるかどうかを判断する方法

# 取得したbuttonのWebElementがクリックできるかどうか

`element_to_be_clickable()`で取得できると思ったんですが、だめでした。
`is_enabled()`を使えば良いようです。

```py
button = driver.find_element_by_css_selector('#app > div:nth-child(2) > div > div.animation-content > div > footer > div > button')
if button.is_enabled():
    button.click()
```

## 参考

[7. WebDriver API — Selenium Python Bindings 2 documentation](https://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.remote.webelement)
記号と読みやすさ ― J 言語入門

J 言語では記号が多用されます。角括弧 `[ ]` や波括弧 `{ }` に至っては、「開く」「閉じる」の対応も無く、バラバラに使われます。また、`<` `<.` `<:` のように `.` や `:` を繋げると別の機能を表し [^1] 、`i.` のようにアルファベットも使われます。

(そのため、可読性が良くないと評されることが よくあります。)

J 言語が基本的な機能 (プリミティブ) を記号で表すのには、理由があります。

単に短く書けるというのも一つの利点ですが、それだけではありません。

もし、`i.` (dyad) の代わりに `index_of` という名前の verb が標準ライブラリに用意されていたとします。次のコードは何を実行するでしょうか。

```j
3 7 2 index_of 7
```

本当に常に `3 7 2 i. 7` と同じ振る舞いをするでしょうか。同じファイルの中に固有の `index_of` の定義があるかもしれませんし、別のライブラリの verb を使っているかもしれません。

J は静的型付けの言語ではないので、変数名は常に動的に解決されます。また、変数はミュータブルで、noun も verb も modifier も代入することができます。

記号が使われるのには、言語の中心的な機能と**変数名が衝突してしまうことや、再代入が起きることを予防する**意味があります。

さらに、これらの記号は文脈によらず [^2]「共通の語彙」の役割をするので、他人の書いたコードを読む上では**むしろ理解を手助けする**ものになります。

---

\[ [目次](https://qiita.com/unsigned-wrong-wrong-int/items/e15a87999cedfc6b9ced) \]

[^1]: 単語の変化になぞらえて inflection (屈折・語形変化) と呼ばれます。
[^2]: どんな変数が定義されているか、どんなライブラリを使っているかに関係なく。
QGISを使った建物占有率メッシュデータの作り方

# 概要
件名のとおりです。

# 手順

## 手順１
建物ポリゴンデータを入手。ここでは国土基盤地図情報の「建築物」のデータを利用しました。「基盤地図情報ビューア」を利用して必要箇所のshpファイルを作成し、それをQGISで読み込みました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90108/3d1b899b-a650-618f-e5c3-af0d080aff6d.png)


## 手順２
次に建物占有率を設定するメッシュを作成します。メッシュは外部ファイルから読み込む方法もありますが、ここでは「ベクタ＞調査ツール＞グリッドを作成」を利用して作成しました。今回作成したメッシュ作成条件は以下。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90108/39ac20ad-9f4f-840a-837f-2d757e3805bf.png)

こんな感じのメッシュができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90108/7c664d0a-d3be-0d14-714c-bddd91506e64.png)


## 手順３
次に建物ポリゴンをメッシュと関連づけるために、建物ポリゴンをメッシュで分割します。「プロセッシング＞
＞ツールボックス＞ベクタオーバーレイ＞交差」で以下の条件で「実行」します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90108/9eaaeec0-7fee-c6ab-3d83-0819e702a178.png)

すると以下ようにメッシュ形状で分割さたれた建物ポリゴンのデータが作成されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90108/0bdfaeea-40d8-0193-69ab-9066ea58b104.png)

## 手順４
次に分割されたポリゴンの面積を設定します。手順３で作成されたデータを右クリックし、「属性テーブルを開く」で属性テーブルを開き、「フィールド計算機を開く」をクリックし、各ポリゴンの面積を設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90108/0578d7bb-7533-7606-a381-8f259bcdb3ab.png)

属性テーブルの最も右端に"bill_area"が追加されていることを確認してください。ちなみに、"id_2"は手順３で利用したグリッドデータのidが設定されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90108/43169c3f-4ab8-0eb3-86d5-2f669e0982be.png)

## 手順５
次に手順２で作成したグリッドデータと手順４で作成したデータを関連づけます。「プロセッシング＞ツールボックス＞ベクタ一般＞属性テーブルで結合」で以下の条件で「実行」します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90108/63efbaf3-4ed1-1168-ff7f-205dce36033b.png)

上の操作では、グリッドデータにポリゴンを格子線で区切ったデータ（交差データ）を結合しているため、ポリゴンが重なっていない格子には何もマッチしないため、以下のようなメッセージが表示されますが問題ありません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90108/940ab93b-8dea-e709-728f-fd579b2b2aa7.png)

## 手順６
次に出力レイヤを右クリックして属性テーブルを開き、「フィールド計算機を開く」をクリックし、建物占有率を設定します。結合されたテーブルには既に各格子に含まれる建物の面積が"b_area"として設定されているはずです。また各格子（セル）の面積は"$area"で算出することができます。

ここ注意しなければいけないことがあります。それは一つもポリゴンがマッチしなかった格子（セル）の"b_area"にはNULLが入っていることです。それに配慮して以下の計算式で建物占有率を算定します。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90108/c35c865f-ac91-dbf9-07a3-2a4043be0bcd.png)

属性テーブルを閉じて、出力レイヤを右クリックしてプロパティから値を表示して確認してみてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90108/7e0fe44f-2c2f-60d4-b7e7-c686f470cbbd.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90108/fd13f0b0-899c-6b95-da3a-19d2cfbd7dd8.png)

上記設定とすると以下のように表示されるはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90108/134b4b3f-0527-abeb-5de3-b07bf4e96913.png)

元データの建物ポリゴンと比較しても合理的な数値を確認することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90108/305976eb-37c2-b5aa-b2e8-57f0b336abe8.png)

以上です。
氾濫計算などで各メッシュの建物占有率を算出したい場合には、QGISが使えますね！格子数や建物数が増えた場合がかなり処理速度が遅くなることが予測されますが、どうでしょうか？？
「2本の線分が交差しているか調べる」を参考にPythonのsympyでやってみた。

(オリジナルポスト)

https://qiita.com/tydesign/items/405f1345a437b03b6403

#sympyを使って(intersection)
交点が線分の間にあれば、交差です。

```python
from sympy import *
def myKyoriHantei(ax,ay,bx,by,cx,cy,dx,dy,kx,ky):
    ans = "Nil"
    Lab=sqrt((ax-bx)**2+(ay-by)**2)
    Lcd=sqrt((cx-dx)**2+(cy-dy)**2)
    if (sqrt((kx - ax) ** 2 + (ky - ay) ** 2) <= Lab and \
        sqrt((kx - bx) ** 2 + (ky - by) ** 2) <= Lab and \
        sqrt((kx - cx) ** 2 + (ky - cy) ** 2) <= Lcd and \
        sqrt((kx - dx) ** 2 + (ky - dy) ** 2) <= Lcd
        ):
     ans="T"
    return ans
def myKousaHantei(lineSeg):
    (myAx, myAy), (myBx, myBy), (myCx, myCy), (myDx, myDy) = lineSeg
    PA, PB = Point(myAx, myAy), Point(myBx, myBy)
    SAB = Segment(PA, PB)
    PC, PD = Point(myCx, myCy), Point(myDx, myDy)
    SCD = Segment(PC, PD)
    ans=SAB.intersection(SCD)
    if(ans==[]):
        return "Nil"
    myKx=SAB.intersection(SCD)[0][0]
    myKy=SAB.intersection(SCD)[0][1]
    return myKyoriHantei(myAx, myAy, myBx, myBy, myCx, myCy, myDx, myDy, myKx, myKy)
# 例1
lineSeg=((2,3),(11,12),(10, 5),(3,11))
print('# 例1 (lineSeg:IsIntersect) ->',lineSeg,'->',myKousaHantei(lineSeg))
# 例2
lineSeg=((2,3),( 5,12),(10, 5),( 8,11))
print('# 例2 (lineSeg:IsIntersect) ->',lineSeg,'->',myKousaHantei(lineSeg))
# 例3
lineSeg=((2,3),( 5,12),(10, 5),( 6, 8))
print('# 例3 (lineSeg:IsIntersect) ->',lineSeg,'->',myKousaHantei(lineSeg))
# 例4
lineSeg=((2,3),(11,12),(10, 5),( 8, 9))
print('# 例4 (lineSeg:IsIntersect) ->',lineSeg,'->',myKousaHantei(lineSeg))
# 例5
lineSeg=((2,3),( 4, 9),(10, 5),( 5,12))
print('# 例5 (lineSeg:IsIntersect) ->',lineSeg,'->',myKousaHantei(lineSeg))
# 例6
lineSeg=((2,3),( 7,12),(10, 5),( 7,12))
print('# 例6 (lineSeg:IsIntersect) ->',lineSeg,'->',myKousaHantei(lineSeg))
# 例1 (lineSeg:IsIntersect) -> ((2, 3), (11, 12), (10, 5), (3, 11)) -> T
# 例2 (lineSeg:IsIntersect) -> ((2, 3), (5, 12), (10, 5), (8, 11)) -> Nil
# 例3 (lineSeg:IsIntersect) -> ((2, 3), (5, 12), (10, 5), (6, 8)) -> Nil
# 例4 (lineSeg:IsIntersect) -> ((2, 3), (11, 12), (10, 5), (8, 9)) -> T
# 例5 (lineSeg:IsIntersect) -> ((2, 3), (4, 9), (10, 5), (5, 12)) -> Nil
# 例6 (lineSeg:IsIntersect) -> ((2, 3), (7, 12), (10, 5), (7, 12)) -> T
```
#sympyを使って(solve)
質問中

https://ja.stackoverflow.com/questions/77856/2%e6%9c%ac%e3%81%ae%e7%9b%b4%e7%b7%9a%e3%81%ae%e4%ba%a4%e7%82%b9%e8%a8%88%e7%ae%97%e3%82%92solve%e3%81%a7%e3%82%84%e3%81%a3%e3%81%a6%e3%81%bf%e3%81%9f%e3%81%84
Route 53 Resolver DNS FirewallでDNSクエリをBLOCKしてみる

# Route 53 Resolver DNS Firewallとは？
AWS VPCに標準で備わっているDNSサーバであるRoute 53 ResolverでDNSクエリ(名前解決)を制御する機能です。
この機能を使用すると任意のドメイン名に対する名前解決を不可にして許可されたサイト以外へのアクセスを禁止するといったことが可能となります。

# 設定項目
Route 53 Resolver DNS Firewallの設定項目としてはざっくり以下となります。

**・ドメインリスト**
名前解決を許可、または拒否したいドメイン名のリストです。
`www.hogehoge.com` のようなFQDNでの指定や `*.hogehoge.com` のようにワイルドカードの使用も可能。
AWS独自調査による危険ドメインがリスト化されているマネージドのドメインリストも利用可能ですがこのドメインリスト内の具体的なドメイン名はユーザ側では確認できません。

**・ルールグループ**
制御内容の設定となります。
ドメインリストで指定したドメイン名に対するDNSクエリにどのような制御を行うかを設定します。
アクションという設定項目で以下3つの何れかを指定して制御を有効にします。
　ALLOW・・・DNSクエリを許可。通常の名前解決の動作と同じ動き。
　ALERT・・・DNSクエリを許可。通常の名前解決の動作と同じ動きをするがログにアラートが記録されます。
　BLOCK・・・DNSクエリをブロックしてDNSクライアントに特定のレスポンスを返します。

BLOCKを指定した場合、Route 53 ResolverがDNSクライアントに返すレスポンスを以下の3つから選択できます。
　NODATA・・・DNSクエリに対する有効なレスポンスが無いという結果を返す。
　NXDOMAIN・・・ドメインが存在しないという結果を返す。
　OVERRIDE・・・DNSシンクホールの機能。任意のレスポンスをDNSクライアントに返す。

# BLOCKの挙動確認
Route 53 Resolver DNS Firewallを設定したVPC内のEC2から検証用ドメインの `www.skawamura.link` に対するクエリがBLOCKされた場合のレスポンスを確認してみました。
DNSクライアントにはnslookupコマンドを使用。
ドメインリストは以下画面キャプチャの通りに設定。
![DOMAINLIST.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268065/823d18e1-5117-4ab2-68eb-61cae5d9a3f2.jpeg)


**・BLOCK無しの場合**
通常の名前解決の挙動と同じく `www.skawamura.link` に対応するIPアドレスがレスポンスとして返ってきます。
![NOBLOCK_2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268065/e1d6bfda-9094-9ced-b9eb-e136535804c8.jpeg)
<br>
**・NODATAの場合**
レスポンスにNODATAを指定します。
![BLOCK_NODATA.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268065/247f1aec-cbb6-8219-c494-ded6bc7ae4c7.jpeg)
nslookup実行結果は「No answer」となりました。
![BLOCK_NODATA.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268065/b69eeba6-1348-cdc9-e5d4-3d42455aec36.jpeg)
<br>
**・NXDOMAINの場合**
レスポンスにNXDOMAINを指定します。
![BLOCK_NXDOMAIN.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268065/2b6114f5-7e1b-ae8d-13e8-7d8a5463239e.jpeg)
nslookup実行結果は「NXDOMAIN」となりました。
![BLOCK_NXDOMAIN.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268065/92c52246-660d-26c1-fa14-83aa85089eda.jpeg)
<br>
**・OVERRIDEの場合**
「アクション」でOVERRIDEを指定してレスポンスに `www.google.com` を設定します。
![BLOCK_OVERRIDE.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268065/0034e8ab-edda-d03c-82d7-92ed76c61499.jpeg)
nslookup実行結果に `www.google.com` に対応するIPアドレスが返ってきました。
![OVERRIDE_2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268065/04ad91e8-351d-6697-11f4-4869d971d294.jpeg)

# まとめ
インターネット上の特定のサイトへのアクセスを制御したいというような要件がある場合、Route 53 Resolver DNS Firewallを使用すれば簡単にアクセス制御を行うことが可能です。
但しこの機能の制御対象はあくまで**Route53 Resolverを利用している場合のDNSクエリ**なのでRoute53 Resolver以外のDNSサーバを使用していたりIPアドレス指定で通信している場合はアクセス制御はできません。
IPアドレスやプロトコルでの制御が必要な場合はセキュリティグループやネットワークACL、Network Firewallの利用を御検討下さい。
EDA-累積分布関数(CDF: Cumulative Distribution Function)

## 累積分布関数(CDF: Cumulative Distribution Function)とは

確率変数Xがある値x以下(X <= x)の値となる確率です。
例えばサイコロを投げたときに「出る目が4以下となる確率」や「出る目が4から6の目が出る確率」といった、ある範囲の確率を求めるときに使用します。

[確率質量関数(PMF: Probability Mass Function)](https://qiita.com/fastso/items/e09a80df4bd680e29e46)との区別：

* PMFはある値xを得る確率
* CDFはある値x以下の値を得る確率

## CDFプロット

```python
import numpy as np
import seaborn as sns

pmf = df['col'].value_counts(normalize=True).sort_index()
cdf = np.cumsum(pmf)

fig, ax = plt.subplots()

ax.plot(pmf.index, pmf.values, label='PMF')
ax.plot(cdf.index, cdf.values, label='CDF')

ax.legend()
plt.show()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260307/af70193d-90b9-e05d-3759-118561c8e53b.png)
kali linux mount/umount

備忘録としてまとめた。

GUIであれば、USBを差せばWindowsと同じように自動的にマウントしてくれるので、初心者のうちはあまり意識しないコマンド。

<マウントされた状態>
![GUI_mount_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/975449/a9d5faad-38fb-6ad7-eadc-8a3c9b264bf9.png)
<マウントされていない状態>
![GUI_umount_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/975449/c40650a4-5130-8a6d-2452-4040a86889d8.png)


しかし、CUIではオートマウント機能はない。したがってmount/umountコマンドを使用して操作する必要がある。実行にはroot権限必須なので、現在一般ユーザならば、コマンドの前に"sudo"をつけて使用すること。

※デバイス名の確認には「__fdisk -l__」を使用する。これでハード的に認識している外部ハードディスクの名前を確認することができる。

「/etc/fstab」：マウント設定ファイル
「/etc/mstab」：マウント状況記録ファイル
#mount
1) デバイスをマウントポイントにマウントする
\#__mount [オプション] デバイス [マウントポイント]__
※マウントポイントは存在するディレクトリである必要がある。たとえば、マウント先の下に新たにディレクトリを作成してその下にマウントすることはできない。

2) ファイルシステムの種類を指定してマウントする
\#__mount -t ファイルシステムの種類 デバイス マウントポイント__
※OSが認識できるファイルシステムの一覧は「/proc/filesystems」で確認可能。

ex.\#mount -t vfat /dev/sdb1 /usr/local/data1
↑一般的にUSBで使用されるファイルシステムfat32に対応するvfatを指定してマウントする
ex.\#mount /dev/sdb1 /usr/local/data1
↑ファイルシステムの種類を自動判別してマウントする

3) 現在マウント中のデバイスをラベル付きで表示
\#__mount -l__

マウントの設定は「/etc/fstab」に記載してあるので、適宜カスタマイズすること。マウントオプションを指定しなかった場合は、このファイル内に記載している「defaults」扱いとなる。

#umount
1) デバイスをアンマウントする
__\#umount デバイス名__

2) マウントポイントにマウントされているデバイスをアンマウントする 
__\#umount マウントポイント__

3) マウント状況記録ファイル「/etc/mtab」に記述された全てのファイルシステムをマウントポイントからアンマウントする（/procデバイスは除く)
__\#umount -a マウントポイント__

4) 指定した種類のファイルシステムのみをアンマウントする
※同じマウントポイントに複数のデバイスがマウントされていた場合、指定外の種類のファイルシステムは触らないということ
__\#umount -t ファイルシステムの種類__
ex. \#umount -a -t msdos
↑マウントオプションの指定がないので、「/etc/mstab」に記載されているすべてのmsdos形式のファイルをアンマウントする


#USBのmount/umount
以上をふまえ、USBのmount/umountをやってみる。
現在ログインしているのは一般ユーザkaliである。
GUIでUSBを差すとデスクトップ上にアイコンが表示されるので、カーソルオンしてみるとご丁寧にマウントポイントが表示される。Terminalを開いて、マウント先にアクセスしてみると、ユーザ名のディレクトリの他、cdromとcdrom0があった。kaliではデフォルトのマウントポイントは「/media/[user]」のようだ。
差した直後はマウントされた状態なので、ここからアンマウントしてみる。

__1) まずはマウントポイント指定でアンマウント__
\#sudo umount /media/kali
アイコンが薄くなったのを確認する。ここで「fdisk -l」でUSBデバイスの名前を確認する。
![fdisk_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/975449/a915e856-9788-7055-5021-2e2f36547bff.png)
どうやら__"/dev/sdd1"__として認識されているようだ。(※パーティション番号まで入れる)
__2) 再びマウントしてみる__
\#sudo mount /dev/sdd1 /media/cdrom
しかし、lsで確認するとcdromにはマウントされず、cdrom0にマウントされた。
どうやらcdromはcdrom0のシンボリックリンクらしい。
![cdrom_ll.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/975449/434773b1-5337-0652-927d-32a986a476a3.png)
__3) 今度はデバイス名指定でアンマウントしてみる__
\#sudo umount /dev/sdd1

__参考サイト__
(https://www.atmarkit.co.jp/ait/articles/1802/15/news035.htmlhttps://www.atmarkit.co.jp/ait/articles/1802/15/news035.html)
(https://www.atmarkit.co.jp/ait/articles/1802/16/news025.html)
LogNotTimberの注釈を非表示にする方法

過去の担当者が全員いなくなっているプロジェクトを保守したときのお話。

おそらく当初は``android.util.Log``（以下``Log``表記）で運用されていたが、どこかで誰かが[Timber](https://github.com/JakeWharton/timber)を導入したのでしょう。**自分の担当した部分だけ**に。
Timberと``Log``が共存するとどうなるかというと、**``Log``すべてに黄色波線が引かれます。**
前述の通り、このプロジェクトは``Log``から始まったプロジェクトのため、圧倒的に``Log``の方が多いため波線がいたるところに引かれていました。これではコード中にノイズが多く、コードリーディングの効率が下がってしまいます。

というわけで方法を探しました。

## Lint自体をオフにする
``Log``の存在確認自体をオフにする方法です。
有効にTimberを利用できていれば``Log``の置換漏れを発見できなくなるメリットはありますが、今回は正常化させる工数的余裕がないので無視します。

> Preferences | Editor | Inspections

の「Logging call to Log instead of Timber」のチェックを外して適用すれば波線は引かれなくなります。

![スクリーンショット 2021-06-28 16.52.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177297/2d9b6c7a-adaa-2253-e617-88ce8eb060f9.png)

## ``@SuppressLint()``を利用する
``Log``が含まれているメソッドor関数にアノテーションを付与する方法です。

```kotlin
@SuppressLint("LogNotTimber")
fun foo() {
    Log.d("bar")
}
```

これで波線は引かれなくなります。

### お気持ち
Android Studioが提案してくるので紹介しましたが、個人的には好きでない方法です。理由としては

- 各メソッドor関数に全て記述する必要がある
- 例外を握りつぶしているのと同じ。致命的な見逃しが起こりうる

の2点です。面倒くさい上にトラブルの種を埋めることはしたくないので基本的にやりません。


## おわりに
他にやり方があれば知りたいです。たとえばプロジェクトごとに特定のLintをオフにする方法とかがあれば。

最後に一言、
既存部分に影響のあるライブラリを追加する場合はきっちり全て対応するか、あきらめて既存の方法に従え！
ありがとうございました。
mysqlの Slave_IO_Running と Slave_SQL_Running の違い

## 勉強前イメージ

どっちもyesだよね、って確認するやつ
今更ながらちゃんと確認。
IO_Running → masterのポジション認識？
SQL_Running → slaveに適応した？

## 調査

### Slave_IO_Running

マスターのバイナリログを読み取るためのI/Oスレッドが実行しているかどうか。

内部的には `MYSQL_SLAVE_NOT_RUN` 、 `MYSQL_SLAVE_RUN_NOT_CONNECT` 、 `MYSQL_SLAVE_RUN_CONNECT` で表されます。

- MYSQL_SLAVE_NOT_RUN
	- I/Oスレッドが実行されていません。
	- Slave_IO_Running : No になります。
- MYSQL_SLAVE_RUN_NOT_CONNECT
	- I/Oスレッドは実行されていますが、masterに接続されていません。
	- 5.1,5.5,5.6 : Connecting になります。
- MYSQL_SLAVE_RUN_CONNECT
	- I/Oスレッドが実行されており、masterに接続されている。
	- Slave_IO_Running : Yes になります。

### Slave_SQL_Running

SQLスレッドが起動しているかどうか。
slaveのSQL処理が実施しています。

## 勉強後イメージ

Slave_IO_RunningってConnectingになるのか・・・
イメージとは合ってたけど、IO_Runningがちょっと違った。
masterポジション確認だけじゃなくて、masterのポジションを確認するi/oが起動しているかどうかも入るのか・・・

## 参考

- [SHOW SLAVESTATUSステートメント](https://dev.mysql.com/doc/refman/5.7/en/show-slave-status.html)
- [SHOW SLAVE STATUS 構文](https://dev.mysql.com/doc/refman/5.6/ja/show-slave-status.html)
IAMユーザーのCodeCommit Git 認証情報をcliで作成する

Git認証情報をcliで作成したいのだが、公式サイトにコマンドが見当たらず(見つけられず)直接問い合わせをした結果を共有。

https://docs.aws.amazon.com/codecommit/latest/userguide/setting-up-gc.html


Git認証情報作成コマンド

```
aws iam create-service-specific-credential --user-name <メールアドレス> --service-name codecommit.amazonaws.com
```

上記コマンドでGit認証情報を作成できる。
ついでにcodecommit用のIAMポリシーも作成。

CodeCommitFullaccessのIAMポリシー

```
aws iam attach-user-policy --user-name <メールアドレス> --policy-arn　arn:aws:iam::aws:policy/AWSCodeCommitFullAccess
```

cliでユーザーを作成した時はコンソールログイン権限とkey/secは発行されないので、
必要な場合は別途要作成

```
$ aws iam create-user --user-name <メールアドレス>
{
    “User”: {
        “UserName”: “hogehoge”,
        “Path”: “/”,
        “CreateDate”: “********”,
        “UserId”: “********”,
        “Arn”: “arn:aws:iam::********:user/hogehoge”
    }
}
```

これらをいい感じにscript化すればユーザー作成がサクッと出来る。
railsで「The asset "application.js" is not present in the asset pipeline. 」とエラーが出てしまった話

現在プログラミングの勉強をしており、表題のエラーに遭遇してしばらく止まってしまってましたがこの度問題解決できましたので記録としてまとめたいと思います。

railsのローカル環境での学習中に表題のようなエラーに直面しました。

アプリケーションのヘッダー部分のメニュー画面をjsを使って選択した際に動くようにしようとしましたら

```html:_head.html.erb
The asset "application.js" is not present in the asset pipeline. 
```
と言う風にJavascriptファイルが無いよって怒られてしまいました。

調べるとどうやらrailsのバーションの違いのようです、rails5.XXの場合だとjsファイルが

```
app/assets/javascript

```
とあるのに対して

rails6.XXだとファイルの階層が違くて

```
app/javascript/pack

```
とあり場所が異なることに気づきました。

なので下気のように変換して該当のjsファイルを読み込めるようにして無事に動きました。

```
<%= javascript_pack_tag 'application', 'data-turbolinks-track' => true %>

```

参考にしたコードで使用されていたrailsのバージョンが5.XX系だったのが原因です
なるべく低コストでTwitter Botを自作する

# 概要
無料でTwittter Botを作れるサービスもあるようですが、色々細やかな運用に耐えるようにするには自作したほうがいいだろうということで、なるべく低コストでTwitter Botを作ってみた。

# 環境
AWS Lambda(Python3.8)
tweepy
DynamoDB
Twitter

# 全体の流れ

1. Bot用のアカウント作成
1. Twitter API 使用のためのキー類を取得
1. DynamoDBにデータを登録
1. Lambda関数を作成する

# Bot用のアカウント作成
これが地味に一番めんどくさいです。
[ここ](https://twitter.com/)からアクセスして「アカウント作成」を押してアカウントを作りましょう。
色々英語で聞かれますが、そこは良しなに。

# Twitter API 使用のためのキー類を取得
アカウントを作成したら、ログインしたままで[Twitter Developers](https://developer.twitter.com/en/portal/dashboard)にアクセスして、左のサイドメニューから「Projects & Apps」を選択して「Overview」を選択して「New Project」を押して必要事項を入力して、必要な値を取得する。
後でLambda関数内で使用するのでメモっておく。

# DynamoDBにデータを登録
単純なランダムでツイートしてもいいんだけど、ちょっと重みをつけたかったんで、DynamoDBのテーブルは以下のよう構造にしてデータを適当にいくつか登録。weight は整数であれば何でもいい、数字が大きいほど重みが強いのでツイートされる確率が高くなる。
テーブル名はtweetsにした。

| カラム | 型 | 説明 |
|:-:|:-:|:-:|
| hash | String | プライマリキー  |
| text | String | ツイート内容  |
| weight | Number | 重み  |

# Lambda関数を作成する
Twitter APIのドキュメント読んでもわかりにくいので tweepyというライブラリを使わせてもらうことにした。
が、Lambdaは外部ライブラリを使うのがめちゃくちゃめんどくさいのでLambdaのレイヤーの機能を使うことにした。

## 流れ
1. ラムダ関数をつくる
1. DyamoDBにアクセスできるポリシーを付ける
1. レイヤーでtweepyを導入する
1. Event Bridgeで定期実行を設定する

### ラムダ関数をつくる
適当に名前を付けてランタイムにPython3.8を選択、「関数の作成」ボタンを押して関数を作成。
コードは以下のような感じだけど、tweet関数のなかのキーは先ほど取得したものを使用する。

```python3
import json
import random
import boto3
import tweepy


def lambda_handler(event, context):
    text = random_choice_text()
    tweet(text)
    
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }


def tweet(text: str):
    auth = tweepy.OAuthHandler(<api key>, <api secret key>)
    auth.set_access_token(<access token>, <access token secret>)
    api = tweepy.API(auth)
    api.update_status(text)
    

def random_choice_text() -> str:
    db = boto3.resource('dynamodb')
    table = db.Table('tweets')
    res = table.scan()
    items = res['Items']
    
    texts = []
    weights = []
    for item in items:
        texts.append(item['text'])
        weights.append(int(item['weight']))
    return random.choices(texts, k = 1, weights=weights)[0]
```

###  DyamoDBにアクセスできるポリシーを付ける
LambdaからDynamoDBにアクセスする権限が必要なので、出来上がったロールに「AmazonDynamoDBFullAccess」のポリシーをつける。ちゃんと運用する場合はポリシー作って最低限のアクションだけに絞る。

### レイヤーでtweepyを導入する
Layersを選択して、「Layerの追加」ボタンをクリック。
![tweet-bot - Lambda - Google Chrome 2021_06_28 20_23_08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65020/bc8e3676-dcba-d14b-202e-b724f332c3cc.png)

「ARN を指定」を選択して「arn:aws:lambda:ap-northeast-1:770693421928:layer:Klayers-python38-tweepy:1」を入れて「追加」ボタンをクリック。
これでLambda関数からtweepyをimportして使えるようになる。

### Event Bridgeで定期実行を設定する
「トリガーを追加」ボタンをクリックして「EventBridge」を選択、「新規ルールの作成」を選択してルールタイプで定期実行を設定する。
AWSのcron式は[ここ](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/services-cloudwatchevents-expressions.html)をみればだいたい必要なことができる。


# まとめ
DynamoDBとかLambdaは無料枠があるのでほぼほぼ無料で自作のTwitter Botが作れる。

色々書いたけど Terraform に起こしたから、こっち使うのが楽かも。
https://github.com/nittyan/twitter-bot
rails6.0へ更新後, solidusのクラスでInitialization autoloaded the constantsのwarningが出た際の対処

rails 6.0.0
solidus 2.11.9
zeitwerk使用

test environmentの時だけ下記の様なwarningが出るようになっていた。

```ruby
DEPRECATION WARNING: Initialization autoloaded the constants Spree::AuthConfiguration, MailLogObserver
```

特にconfig/initializerで何かしているわけでもない、solidus側のissue等確認しても出ている場合は自分のコードに何かあるという事しか書いてなかったので原因が不明だったが、warning発生前後をチェックするとapp:update時に`config/environments/test.rb`のcache_classesをfalseにしていた。
trueにすることでwarningが出なくなるのを確認, solidusは最終的に関係無かった。

修正前

```ruby:config/environments/test.rb
require "active_support/core_ext/integer/time"

Rails.application.configure do
  # Settings specified here will take precedence over those in config/application.rb.
  config.cache_classes = false
  # etc...
end
```

修正後

```ruby:config/environments/test.rb
require "active_support/core_ext/integer/time"

Rails.application.configure do
  # Settings specified here will take precedence over those in config/application.rb.
  config.cache_classes = true
  # etc...
end
```

ただアップグレードガイドのこの部分に引っかからなかったのがまだ分かりきってないので調べる。
> spring gemは、アプリケーションのコードが変更されると再読み込みします。test環境では、そのために再読み込みを有効にしておく必要があります。

参考

- https://railsguides.jp/upgrading_ruby_on_rails.html#spring-gem%E3%81%A8test%E7%92%B0%E5%A2%83%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6

- https://qiita.com/jnchito/items/c72fd6bea81eb5417e3f