OmniAICreator/Qiita-1.07M huggingface dataset:
エクセルにボタン用意してVBA（マクロ）実行

# 概要

この記事は…
**『エクセルにボタン用意してVBA（マクロ）実行』**
なんて全くやったことないよ、な状態向け。

下記のような簡単なサンプル作るところまで書いてるよ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/d0f2cae8-397c-aff3-4c00-20661d77b92a.png)

# やり方

## 開発タブ

左上『ファイル』。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/c705e177-f2d4-8fd0-dc05-4293f349234f.png)

左下『オプション』。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/c89107b4-19c1-6046-47f9-be7406d33b8a.png)

『リボンのユーザー設定』 ⇒ 『開発』にチェック入れる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/620b217a-2890-b855-b35e-923e14978ac5.png)

## VBA

Alt + F11でVBE開く。

下記のようなコード。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/30ccd334-a29c-087a-7804-685400b70405.png)

```vb
Option Explicit

Private Function TesterDayon()
    MsgBox "押したなお前！", vbInformation, "通知"
End Function
```

できる限りカプセル化したいので、今回はシートの中にPrivateで関数を作成しました。

## ファイル保存

拡張子はxlsmで保存。

## ボタン設置とマクロ登録

『開発』 ⇒ 『挿入』 ⇒ ボタンのアイコン。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/bb596fa4-73fd-0071-b44a-ef6b4748a747.png)

ボタン右クリック ⇒ 『マクロの登録』 。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/2081f0bf-1bc1-5731-4186-3a8851b912d0.png)


```
hogeee.xlsm!Sheet1.TesterDayon
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/958c94a6-0b5d-cc12-4fd1-da504ade3b2a.png)

## ファイル名変更時

ファイル名変更すると『マクロの登録』部分のファイル名も自動で更新される。
（後からファイル名変更してもマクロの登録は書き換えなくてOK）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/6eec579a-62df-f41c-5ec1-6a37c7f69e7f.png)

## ボタン削除

ボタン上右クリックすると下記のような選択状態になる。
そっからDelete押せばOK。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/6972f36d-af82-a87b-d96c-84949b8742e3.png)

# バージョン

Windows 10 Pro 21H2 OSビルド 19045.2311
Microsoft Excel for Microsoft 365 MSO (バージョン 2210 ビルド 16.0.15726.20188) 32 ビット
Pythonで行列を扱うときの基本操作をまとめる

今回はPythonで行列を用いたシミュレーションを行うときに便利な基本操作についてコマンドとその実行結果をまとめる

まずはライブラリのインポート
~~~diff_Python
import numpy as np
~~~
`numpy`を`np`として使います
# 一次元配列の生成
~~~diff_Python
a=np.array([1,2,3])
a
~~~
~~~
array([1, 2, 3])
~~~
# 2つの配列を垂直方向、水平方向へ結合
`vstack`が垂直方向、`hstack`が水平方向
~~~diff_Python
b=np.array([4,5,6])
c=np.vstack((a,b))
d=np.hstack((a,b))
c,d
~~~
~~~
(array([[1, 2, 3],
        [4, 5, 6]]),
 array([1, 2, 3, 4, 5, 6]))
~~~
# 多次元配列の生成と行列の積
~~~diff_Python
e=np.array([[1,3,5],[2,4,6]])
f=np.array([[1,2],[3,4],[5,6]])
np.dot(e,f)
~~~
~~~
array([[35, 44],
       [44, 56]])
~~~
`np.dot(A,B)`で
```math
A×B
```
# 配列の形の確認、変形
~~~diff_Python
g=np.array([[1,2,3],[4,5,6]])
print(g.shape)
g.reshape(3,2)
~~~
~~~
(2, 3)
array([[1, 2],
       [3, 4],
       [5, 6]])
~~~
# 一次元配列への変換と注意
~~~diff_Python
print(g.ravel())
g.reshape(1,-1)
~~~
`reshape(1,-1)`の`-1`は列を自動で最適にしてくれるという意味
~~~
[1 2 3 4 5 6]
array([[1, 2, 3, 4, 5, 6]])
~~~
:::note warn
注意：一次元配列（前者）と行数が1の二次元配列（後者）は違う
:::
# 逆行列の算出とその確認
~~~diff_Python
h=np.array([[1,0,0],[0,2,0],[0,0,3]])
h_inv=np.linalg.inv(h)
np.dot(h_inv,h)
~~~
~~~
array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]])
~~~
:::note info
逆行列と元の行列をかけて単位行列が得られることを確認
:::
# 固有値と固有ベクトルの算出と確認
~~~diff_Python
i=np.array([[0,2],[1,3]])
eig=np.linalg.eig(i)
eig
~~~
~~~
(array([-0.56155281,  3.56155281]),
 array([[-0.96276969, -0.48963374],
        [ 0.27032301, -0.87192821]]))
~~~
1行目`eig[0]`に固有値、2行目`eig[1]`に固有ベクトル
それぞれの固有ベクトルは列で返される
~~~diff_Python
print(np.dot(i,eig[1][:,0]))
eig[0][0]*eig[1][:,0]
~~~
~~~
[ 0.54064603 -0.15180065]
array([ 0.54064603, -0.15180065])
~~~
:::note info
行列$A$の固有値$\lambda$と固有ベクトル$\vec x$について
```math
A\vec x=\lambda \vec x
```
が成り立つことを確認
:::
VBSでDBからレコードを取得する

# 【前提条件】
　・DB構築済み（筆者はSQLServerを使用）
　・DSN設定済み

# 【ソース】
```sample.vbs
'DB接続'
Dim dbConn
Set dbConn = CreateObject("ADODB.Connection")

On Error Resume Next
  dbConn.Open "DSN=######;UID=######;PWD=######"
  If Err.Number <> 0 Then
     'エラーハンドリング
     Wscript.Quit Err.Number
  End If
On Error Goto 0
dbConn.CursorLocation = 2

'レコード取得
Dim dbRs
Set dbRs = dbConn.Execute("実行したいSQL")
Do Until dbRs.EOF
  '取得したレコードにて行いたい処理
  dbRs.MoveNext
Loop
```

# 【あとがき】
　業務でvbsよりDBのレコードを取得する必要があったため、備忘として記載
python venvの基礎基本

## そもそもvenvとは
　venvとはpythonが提供している開発や試験を行うための仮想環境。
　論理的に独立した環境であるため、パッケージによる依存性や互換性に左右されることなく実行が可能です。

#### メリット
- 仮想環境を使い分けることで複数のバージョン・ライブラリーを使用することができる
- pipコマンドによってモジュールの入れ替えや追加が簡単に行える
- 何よりも簡単に作成することができて削除できる手軽さが最大のメリット




#### デメリット
- 仮想環境としてDockerコンテナも選択している場合は仮想化が重複してしまう
　ですが、趣味的にpythonの仮想環境を手軽に利用したい場合はデメリットが特になく利用できると思います！


## 構築方法
### <前提>
(OS) Windows10
(言語) Python3.10.3
(フレームワーク) Django4.0.4
(エディター) VSCode
(ターミナル) Powershell



#### workフォルダの作成
　これから作業するworkファルダを任意の場所に設置します。
　作成方法はコマンドによる作成でも、GUIにてマウスでポチポチと作成するでも問題ありません。 
　私は `C:\Users\ (username) \` 配下に作成しました。
```
C:¥Users¥(username)> mkdir work　 
C:¥Users¥(username)> ls　# workフォルダが作成されたことを確認
work
```

#### 新規venvの作成

```
C:¥Users¥(username)> cd work  # workフォルダへ移動
C:¥Users¥(username)¥work> python3 -m venv myvenv # 新規venvの作成
C:¥Users¥(username)¥work>  # 新規venv（myvenv）が作成されたことを確認
myvenv
```

#### アクティベイト

```
C:¥Users¥(username)¥work> cd myvenv #venvフォルダへ移動
C:¥Users¥(username)¥work¥myvenv> .\Scripts\activate #アクティベイト
(myvenv) ~>
```

#### ログアウト
　作成した仮想環境（myvenv）からログアウトします。

```
(myvenv)> deactivate
```

#### venvの削除
　仮想環境が不要になりましたら以下のコマンドで削除できます。

```
C:¥Users¥(username)¥work> Remove-Item ./myvenv -Recurse -Force
```

## おわりに
　今まで他の言語での開発は多少経験したことがあるが、pythonは初めてであったので仮想環境の構築について備忘録的にまとめてみました。
文字に起こしアウトプットすることで頭が整理され、自身の再確認の良い機会にもなりました。
分かりやすく伝えようと他者の目線も意識し文章構成を考えるようになる点もよいですね。
始めたばかりのため時間はまだかかってしまいますが、続けていきたいと思います！

## 参考サイト
また他にもpythonの仮想環境に種類があるようです。以下も参考にしてみてください。
- https://www.acrovision.jp/career/?p=2254
- https://modernimal.com/venv-python-virtual-environment-5332#venvPython-4
- https://blog.narito.ninja/detail/171/
【保存版】colaboratoryでRによるデータ分析をするための環境構築まとめ

colaborratoryはかなり便利だけど、Rで使う場合は結構不便だったりする。なのでこの記事では、colabでRを使うためのハックをまとめてみた。

# Rランタイムのcolaboratoryにアクセスする

下記のリンクをクリックすれば、Rランタイムのcolabが使える。

https://colab.research.google.com/notebook#create=true&language=r

# パッケージのインストールを爆速化する

Rランタイムのcolabだと、パッケージのインストールが5分くらいかかることもざらだけど、下記のコードで爆速化することができる。

```
x<-installed.packages()
if(any(x[,1]== 'ライブラリ名') == FALSE){
    system("add-apt-repository -y ppa:marutter/rrutter4.0")
    system("add-apt-repository -y ppa:c2d4u.team/c2d4u4.0+") 
    system("add-apt-repository ppa:cran/v8") 
    system("apt-get update") 
    system("apt-get install libnode-dev") 
    system("apt-get install r-cran-ライブラリ名")
}
```

## 参考文献

https://twitter.com/fronori/status/1522421303005036546

# google driveにアクセスする

```
if (file.exists("/usr/local/lib/python3.6/dist-packages/google/colab/_ipython.py")) {
  install.packages("R.utils")
  library("R.utils")
  library("httr")
  my_check <- function() {return(TRUE)}
  reassignInPackage("is_interactive", pkgName = "httr", my_check) 
  options(rlang_interactive=TRUE)
}
```

```R:R
drive_auth(
  email = gargle::gargle_oauth_email(),
  path = NULL,
  scopes = "https://www.googleapis.com/auth/drive",
  cache = gargle::gargle_oauth_cache(),
  use_oob = gargle::gargle_oob_default(),
  token = NULL
)
```
## 参考文献

https://towardsdatascience.com/how-to-use-r-in-google-colab-b6e02d736497

# BigQueryにアクセスする

データ分析ではおなじみのBigQuery。Rではbigrqueryが用意されているがcolabで使う場合は一工夫いる。

```R:R
if (file.exists("/usr/local/lib/python3.7/dist-packages/google/colab/_ipython.py")) {
  install.packages("R.utils")
  library("R.utils")
  library("httr")
  my_check <- function() {return(TRUE)}
  reassignInPackage("is_interactive", pkgName = "httr", my_check) 
  options(rlang_interactive=TRUE)
}
```

```R:R
bq_auth(use_oob = TRUE, cache = FALSE)
```

## 参考文献

https://qiita.com/satoru-ka/items/9699f3b9a7e81a09a3cc

# 日本語フォントを表示させる

日本語そのままだと文字化けしてしまうので下記のコードを打つ。

```R:R
system("apt-get install -y fonts-noto-cjk")

library(systemfonts)
system_fonts()
```

## 参考文献

https://qiita.com/kota9/items/ef50061ef3d8b4b657ee

# MeCabをダウンロードする

MeCabのダウンロードは下記のようにする。

```
system('sudo apt-get install -y mecab', intern=TRUE)
system('sudo apt-get install -y libmecab-dev', intern=TRUE)
system('sudo apt-get install -y mecab-ipadic-utf8', intern=TRUE)
```

```R:R
install.packages("RMeCab", repos = "https://​rmecab.jp/R") 
```

## 参考文献

https://qiita.com/satoru-ka/items/f47ecd43d9e69d64b0a8


# データサイエンス100本ノックをやりたい

下記のリンクからR用のデータサイエンス100本を動かすことができる。


https://colab.research.google.com/gist/shimizu1010/79cc81f8bb5beb31802fe3a2c08cfc2c/preprocess_knock_r.ipynb

## 参考文献

https://qiita.com/HiroyukiTachikawa/items/53d4cf8bf033734f316c

https://note.com/nmt_rootassist/n/nf70b6e73f673

https://colab.research.google.com/github/rootassist/100knocks-preprocess-inSQLandPython-withColab/blob/master/preprocess_knock_SQL_Colab.ipynb#scrollTo=y5DERH3BIABo
shell script 内でheredocを使い、json文字列を変数代入する

## heredocを受け取り、標準出力する

```sh
var=key
cat << EOS | jq
  {
    "$var": "value"
  }
EOS
```

出力は

```sh
{
  "key": "value"
}
```

heredocは文字列リテラルではなく標準入力として扱われるので、echoではなくcatの引数にする。

## heredocを受け取り、変数に代入する


```sh
var=key
json=$(tr -d ' |\n' << EOS
  {
    "$var": "value"
  }
EOS
)

echo $json
```

出力は
```sh
> {"key":"value"}
```
入門共分散構造分析の実際　朝野・鈴木・小島隆夫先生　講談社サイエンティフィク

```r

#共分散構造分析のパラメータ推定 p.54

data(EuStockMarkets)
dat=data.frame(EuStockMarkets)
dat=dat[1:300,]
XX=matrix(log(as.numeric(unlist(dat))),nrow=nrow(dat))
varmat=cov(XX)

predV=function(x){
a=x[1];b=x[2];sigf1=x[3];sige1=x[4];sige2=x[5];sigx3=x[6]  
A=array(0,dim=c(4,4))
A[2,1]=b;A[3,1]=b;A[3,4]=a
A=A+diag(1,4)
V=diag(c(sigf1^2,sige1^2,sige2^2,sigx3^2))
V=A%*%V%*%t(A)  
return(V)  
}

f=function(x){
V=predV(x)
return(sum(diag(solve(V)%*%varmat))-log(det(solve(V)%*%varmat)))
}



#勾配降下法

param=rep(1,6)
ite=10^(4)
eta=10^(-4)
h=0.001

for(l in 1:ite){
for(s in 1:length(param)){
param_sub=param
param_sub[s]=param_sub[s]+h
param[s]=param[s]-eta*(f(param_sub)-f(param))/h
}  
print(f(param))  
}

#予測された分散行列
predV(param)

#実際の分散行列
varmat

#適合度のカイ二乗検定
p=length(c(diag(varmat),varmat[lower.tri(varmat)]))
q=length(param)
df=p*(p+1)/2-q
kai2=(nrow(XX)-1)*f(param)
qchisq(1-0.05,df)


```
MFC から SVG クラスのパス呼び出しコードサンプル

## MFC と SvgImage のパス出力
MFC(GDI+) の場合以下のようになります。

```cpp
    Gdiplus::Point poly[8];
    int nPoints = 8;
    poly[0] = Gdiplus::PointF(50,50);
    poly[1] = Gdiplus::PointF(100,100);
    poly[2] = Gdiplus::PointF(150,50);
    poly[3] = Gdiplus::PointF(200,100);
    poly[4] = Gdiplus::PointF(250,50);
    poly[5] = Gdiplus::PointF(300,100);
    poly[6] = Gdiplus::PointF(350,50);
    poly[7] = Gdiplus::PointF(400,100);
    Gdiplus::Pen pen(Color(255, 0, 0, 0));
    Gdiplus::GraphicsPath path;
    path.AddCurve(poly, nPoints, 0.5f);
	pGraphics->DrawPath(&pen, &path);
```

SvgImage への書き出しは Gdiplus::PathData クラスを利用するため、 Gdiplus::GraphicsPath を生成してそこから PathData を取得する形になります。
パスは GraphicsPath に書き出しを行うという手順を必要としますが、サンプルコードのカーディナルスプライン曲線だけでなく直線や円形なども同じ GraphicsPath オブジェクトに書き出しできるため、汎用性は高いといえます。

SvgImage に書き出すと以下のようになります。
```cpp
    Gdiplus::Point poly[8];
    int nPoints = 8;
    poly[0] = Gdiplus::PointF(50,50);
    poly[1] = Gdiplus::PointF(100,100);
    poly[2] = Gdiplus::PointF(150,50);
    poly[3] = Gdiplus::PointF(200,100);
    poly[4] = Gdiplus::PointF(250,50);
    poly[5] = Gdiplus::PointF(300,100);
    poly[6] = Gdiplus::PointF(350,50);
    poly[7] = Gdiplus::PointF(400,100);
    Gdiplus::GraphicsPath path;
    path.AddCurve(poly, nPoints, 0.5f);
    Gdiplus::PathData pathData;
    path.GetPathData(&pathData);
    pImage->AddPathData(&pathData);
    pImage->AddAttrStroke(RGB(0, 0, 255), 1, PS_SOLID);
```
ギブ＆テイクを読んで

ギブアンドテイク

ギバーが1番成功率が低かった。
他の人を助けるために、自分の成績が低かったのだ
同時に、最も成功しているのもギバーだった

テイカーが成功しても、誰かに妬まれる
ギバーが成功すると、非難はない

「誰もが勝たせようとしてくれれば、勝つのは簡単だ。周りに敵がいなければ、成功するのは簡単になる」

「ギバーであることは100メートル走では役に立たないが、マラソンでは大いに役立つ」

「自分に全く利益をもたらさない人間をどう扱うかで、その人がどんな人間かがはっきりわかる」

テイカー
・プロフィール写真を実物以上に良く見える写真にしている
・フォロワーがやたら多い

社会生活のルール
・遅刻をしない
・努力を惜しまない
・人に親切にする
・道に外れたことをしない

「悪気がなくても、人は自分の貢献を過大評価し、他人の貢献を過小評価する」

才能の正体はやるきだった
粘り強さが最重要

アドバイスを貰うことで、その人から好かれる

フランクリンには「友人を得るための基本ルールがあった」とアイザックソンは書いている。
　それは、「しょっちゅう意見やアドバイスを求めて、彼らの自尊心と虚栄心に訴える」ことで、そうすれば「判断力と知恵を高く評価してもらえるようになる」のだという。

人に助言を求めることが効果を発揮したのは、それが無意識から出た行動であるときだけだった。ギバーはテイカーやマッチャーよりも積極的に、人にものを聞く。ギバーはほかの人のものの見方や意見に心から関心をもっており、聞き上手であると見なされていた。

周囲からサポートを受けることこそ、燃え尽き防止の強力な特効薬だということだ。

自分のためにお金を使っても、幸福度は変わらなかったが、ほかの人のために使った人は、幸福度がかなり上がったと報告しているのだ。
　これは他者志向の与え方であり、助ける相手を自分で選んでい


案の定、両グループともに知能が高い人ほど、総利益はもっとも高かった。バリーらは各グループの利益を分析し、より知能の高い交渉者のほうが自分に有利な取引をしていることを確かめようとしたが、失敗に終わった。もっとも知能の高い交渉者は、「交渉相手に」有利な取引をしていたからだ。
「より知能の高い交渉者は相手の本当の利益を理解できるので、自分が少しばかり損をしてでも、相手の有利になるように取引をまとめるようだ」と、



個人的な意見
結局その領域における愛が強ければギバーになる？
→プロのeスポーツプレーヤーは、そのゲーム自体のコミュニティを大切にするが、ただ遊んでる人は気にしない。

仕事だと思ってコード書いてる人は最低限しかしないが、自分でサービス作って起業したいと考える人はなんでもこなす
Pythonでエージェントベースシミュレーション: 同調バイアス(Mesoudi, 2021)

この記事では、Alex MesoudiのRで書かれたチュートリアルをpythonに翻訳する。
下記の記事では同調バイアスのモデルが紹介されている。

https://bookdown.org/amesoudi/ABMtutorial_bookdown/model5.html

形質の特徴や、誰が形質を持っているのかとは無関係に、集団において多数派を占めている形質が継承される傾向のことを同調バイアスという。。

# エージェントベースシミュレーション

まずは、必要なライブラリをインストールする。

```python:python
import pandas as pd
import numpy as np
import random
import math
import matplotlib.pyplot as plt
!pip install japanize-matplotlib
import japanize_matplotlib
```

コードは次のようになる。

```python:python
def conformist_transmission(N, p_0, D, t_max, r_max):
    output = pd.DataFrame(np.tile(np.nan, (t_max, r_max))) 
    output.columns = ["run_" +  str(i) for i in range(r_max)]
    for r in range(r_max):
        agent = pd.DataFrame(random.choices(["A", "B"], k=N, weights=[p_0, 1 - p_0]), columns=["trait"])
        output.iloc[0, r] = sum(agent["trait"] == "A") / N
        for t in range(1, t_max):
            demonstrators = pd.DataFrame([random.choices(agent["trait"], k=N),random.choices(agent["trait"], k=N),random.choices(agent["trait"], k=N)], index=["dem1", "dem2", "dem3"]).T
            numAs = pd.DataFrame(demonstrators.T == "A").sum().values
            agent["trait"][numAs == 3] = "A"
            agent["trait"][numAs == 0] = "B"
            prob = np.random.rand(N)
            agent["trait"][np.logical_and(numAs == 2,prob < (2/3 + D/3))] = "A"
            agent["trait"][np.logical_and(numAs == 2,prob >= (2/3 + D/3))] = "B"
            agent["trait"][np.logical_and(numAs == 1,prob < (1/3 - D/3))] = "A"
            agent["trait"][np.logical_and(numAs == 1,prob >= (1/3 - D/3))] = "B"

            output.iloc[t, r] = sum(agent["trait"] == "A") / N
    plt.figure(figsize=(10, 5), dpi=100)
    plt.plot(output, label = "trait 1")
    plt.title(f'N = {N}, D = {D}, p_0 = {p_0}')
    plt.xlabel('世代数')
    plt.ylabel("形質Aを持つエージェントの割合")
    plt.xlim([0, t_max])
    plt.ylim([0, 1])
    plt.legend()
    plt.show()
    return output
```

次に、実際にシミュレーションしてみる。

```python:python
data_model5 = conformist_transmission(N = 1000, p_0 = 0.5, D = 1, t_max = 50, r_max = 10)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581047/fc0eefb5-dd62-77df-5279-a9d42c98a161.png)

多数派を占めた形質が人口を占めていくことが分かる。

# 数値シミュレーション

```math
p′=p+Dp(1−p)(2p−1)

```

数値シミュレーションの場合、次のようになる。

```python:python
def conformity_recursion(D, t_max, p_0):
  
    p = np.zeros(t_max)
    p[0] = p_0
  
    for i in range(1, t_max):
        p[i] = p[i-1] + D*p[i-1]*(1-p[i-1])*(2*p[i-1] - 1)
  
    plt.figure(figsize=(10, 5), dpi=100)
    plt.plot(p)
    plt.title(f's = {s}')
    plt.xlabel('世代数')
    plt.ylabel("形質Aを持つエージェントの割合")
    plt.xlim([0, 150])
    plt.ylim([0, 1])
    plt.show()
conformity_recursion(D = 0.1, t_max = 150, p_0 = 0.51)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581047/938f090d-c184-14ee-6353-db7854ba87e3.png)
RSpecで遅いテストをふだんskipして、たまに全部実行する方法

https://twitter.com/isochikuwa/status/1597044717224886272

上のツイートを見て、どうやるのがいいか考えてみました。
以下がその方法です。

遅いテストに`:slow`タグを付けます（名前は`:slow`じゃなくても可）。

```ruby
it 'めちゃくちゃ遅いやつ', :slow do
  # ...
end
```

`.rspec`ファイルに以下の行を追加します。

```erb:.rspec
<%= '--tag ~slow' unless ENV['ALL_RUN'] %>
```

デフォルトでは`:slow`タグが付いているテストは実行されなくなります。

```
# :slowタグが付いているもの以外を実行する
$ bundle exec rspec
```

全テストを実行したいときは環境変数`ALL_RUN`を指定します（`ALL_RUN`以外の環境変数名でも可）。

```
# :slowタグが付いているものも、付いていないものもすべて実行する
$ ALL_RUN=1 bundle exec
```

もしくは`--tag slow`オプションを付けて遅いテストだけを実行することもできます。

```
# :slowタグが付いているものだけを実行する
$ bundle exec rspec --tag slow
```

同じようなことをやろうと思っている人は参考にしてみてください！

## 参考文献

- [\`\-\-tag\` option \- Command line \- RSpec Core \- RSpec \-](https://rspec.info/features/3-13/rspec-core/command-line/tag/)
- [read command line configuration options from files \- Configuration \- RSpec Core \- RSpec \-](https://rspec.info/features/3-13/rspec-core/configuration/read-options-from-file/)
Unknown property: 'composes'


# [エラー]react next.js  「Unknown property: 'composes'css(unknownProperties)」
とある教材でWebサイト構築を勉強中
'composes'スタイルを当てようとしたら
「Unknown property: 'composes'css(unknownProperties)」と表示される。
## 環境
Mac(M1, 2020)
vscode


エラー翻訳・意味
不明なプロパティ: 'composes'css(unknownProperties)
## やったこと
1.vscodeの設定を変更したら解決した。

https://github.com/ebisucom/next-react-website/wiki
Slackのhuddleが勝手にmuteになる問題を解消する

Slackのhuddleが無意識にmuteになっていることがあります。Slackではデフォルトで⌘ + Shift + Spaceのキーボードショートカットでmuteをオンにするものが設定されています。このキーボードショートカットは1Passwordなどのデフォルトキーボードショートカットと重複しています。そのためこの設定を無効にします。

![CleanShot 2022-11-28 at 13.39.08@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7565/c9c6400a-f3f6-93e1-b7fb-c60793d70438.png)

(この設定以外で勝手にｍuteされている可能性もあります)
【Excel】Match関数での文字列検索高速化

# はじめに
ある文字列のセル位置を求めて、ごにょごにょする必要があったので、最初にVBAのFindメソッドを使用したところ処理にあまりに時間が掛かったので、別案のMATCH関数を使用したことを備忘として残しておく。

# MATCH関数の使い方
=MATCH(検査値,検査範囲,照合の型)

# サンプル
||A|B|C|
|:--:|:--:|:--:|:--:|
|1|みかん|いちご|=MATCH(B1, A:A, 0)|
|2|りんご|ぶどう|=MATCH(B2, A:A, 0)|
|3|いちご|れもん|=MATCH(B3, A:A, 0)|
|4|さくらんぼ|||
|5|ぶどう|||
|6|なし|||
|7|おれんじ|||
|8|れもん|||
|9|めろん|||
|10|すいか|||

# 結果
||A|B|C|
|:--:|:--:|:--:|:--:|
|1|みかん|いちご|3|
|2|りんご|ぶどう|5|
|3|いちご|れもん|8|
|4|さくらんぼ|||
|5|ぶどう|||
|6|なし|||
|7|おれんじ|||
|8|れもん|||
|9|めろん|||
|10|すいか|||

# おわりに
なぜこんなしょーもないことを備忘に残しておくかというと、Findメソッドを使用した場合には数時間掛かっていた処理が、MATCH関数を使用した場合には数分で終わったので感動したためである。（実際はその他の関数など組み合わせてごにょごにょした）

# 参考
・https://www.limecode.jp/entry/trap/find-method
・https://officedic.com/excel-vba-highspeed-find/
・https://excel-ubara.com/excelvba4/EXCEL225.html
ESLintとPrettierについて

# ESLintとは
構文の記述間違いや決められたルールに沿ってコードが書かれているかをチェックするツールです。
ESLintを使うことで潜在的なバグを見つけることが可能です。

# ESLintの設定
ESLintではルールによって「エラーにする/警告にする/offにする」というエラーレベルを個別に設定することが可能です。
ルールの設定は、.eslintrc.jsかpackage.jsonファイルで設定されています。
これは環境構築時の設定で変わります。

# ESLintのフォーマット機能
ESLintはフォーマッターとしても利用することができます。
以下は、.vueファイルのscriptタグとtemplateタグのインデント設定です。
.eslintrc.js
```js
"indent": ["error", 4],
"vue/html-indent": ["error", 4]
```
"indent"はscriptタグの設定で、"vue/html-indent"がtemplateタグの設定になります。

# Prettierとは
フォーマッターでコードの整形のみを行ってくれるツールです。
ESLintではチェックを行ってくれましたが、こちらはフォーマットのみです。
※読み方は「プリティア」

# Prettierのフォーマット設定
.prettierrcに設定を記述します。
```
{
  "tabWidth": 4,
  "semi": false,
  "singleQuote": true
}
```

# 参考サイト
https://reffect.co.jp/vue/eslint
[SwiftUI] Textの金額表示を簡単に書く

`¥10,000` のような表記
Swiftでは`Formatter`だったり、`String.localizedStringWithFormat`を使う方法がありますが
SwiftUIのTextであればFormatStyleを使って簡単に表示することができます。


```swift
import SwiftUI

struct SwiftUIView: View {
    let price = 1_000_000_000
    var body: some View {
        Text(price, format: IntegerFormatStyle.Currency.currency(code: "JPY"))
            .foregroundColor(.red)
            .fontWeight(.bold)
    }
}

struct SwiftUIView_Previews: PreviewProvider {
    static var previews: some View {
        SwiftUIView()
    }
}

```

![スクリーンショット 2022-11-01 11.37.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1734199/bb962719-ff56-8e84-c4a2-a413e2af19ec.png)

省略して記載する方法を教えていただいたので記事修正しました。こっちのほうが簡単ですね。感謝🙇‍♀️

```swift
Text(price, format: .currency(code: "JPY"))
```

### 環境
Xcode 14.0.1
iOS 15.5以上
[SwiftUI] @Stateを使ったViewで"'~View' initializer is inaccessible due to 'private' protection level"のエラーが発生する場合の対策


## 概要
Gridを使った以下のようなViewを作成している際にPreviewで`'ColorsView' initializer is inaccessible due to 'private' protection level`のエラーが発生した。

#### 環境
Xcode 14.0.1

```swift
struct ColorsView: View {

    @State var colors: [Color]
    private var columns: [GridItem] = Array(repeating: GridItem(.flexible(), spacing: 16), count: 2)

    var body: some View {
        
        ScrollView(.vertical) {
            LazyVGrid(columns: columns, alignment: .center, spacing: 16) {
                ForEach($colors, id: \.self) { color in
                    color
                        .wrappedValue
                        .frame(height: 150)
                }
            }
            .padding()
        }
    }
}

struct ColorsView_Previews: PreviewProvider {
    
    @State static var colors: [Color] = [.red, .blue, .yellow, .green, .pink, .purple, .orange]
    
    static var previews: some View {
        ColorsView(colors: colors)
    }
}

```

![スクリーンショット 2022-11-01 10.51.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1734199/8da11169-4188-c845-2335-24cb428b90d9.png)


## 解決方法
`@State`変数、同じstructの変数がvarであるため発生していた模様。letに変えて解決.。
```swift
    private let columns: [GridItem] = Array(repeating: GridItem(.flexible(), spacing: 16), count: 2)
```
varであっても初期化されているのだから問題ないような...

### 別の方法
イニシャライザを使い初期化
```swift
    @State private var colors: [Color]
    private var columns: [GridItem] = Array(repeating: GridItem(.flexible(), spacing: 16), count: 2)

    init(colors: [Color]) {
        self.colors = colors
    }

```
イニシャライザを使う方法であれば`@State`の変数もprivateにでき、別の変数もvarのままで使える。
多分こっちが正解
[SwiftUI] TextFieldのmodifierに@FocusStateのProperty Wrapperを渡す


## 概要
TextFieldのmodifierを使用してキャンセルボタン付きのTextFieldを作る。
キャンセルボタンを押すとフォーカスを外してキーボードが閉じるようにする。

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1734199/49790109-fde5-7443-cb47-002f87dc75bf.gif">


### 環境
Xcode 14.0.1
iOS 15.5以上

## `@FocusState`のProperty WrapperをModifierに渡す
TextField側では`@FocusState`だがModifier側では`@FocusState.Binding`をつける
```swift
@FocusState.Binding var isFocused: Bool
```

#### 作成したModifier
```swift
import SwiftUI

struct CancelModifier: ViewModifier {
    @FocusState.Binding var isFocused: Bool
    @State private var showCancelButton: Bool = false

    func body(content: Content) -> some View {
        HStack {
            content
            
            if showCancelButton {
                Button {
                    isFocused = false
                } label: {
                    Text("キャンセル")
                        .foregroundColor(.primary)
                }
                .transition(.move(edge: .trailing))
            }
        }
        .onChange(of: isFocused) { isfocused in
            withAnimation {
                showCancelButton = isfocused
            }
        }
    }
}
```

#### 使い方
```swift
struct ContentView: View {
    @State private var text: String = ""
    @FocusState private var isTextFieldFocused: Bool

    var body: some View {
        
        VStack {
            TextField("Placeholder", text: $text)
                .focused($isTextFieldFocused)
                .modifier(CancelModifier(isFocused: $isTextFieldFocused))
                .textFieldStyle(.roundedBorder)
                .autocapitalization(.none)
                .padding(.horizontal)
            
            Spacer()
        }
    }
}

```

キャンセルボタンに`.transition(.move(edge: .trailing))`を指定すると右から出てきて右からでていくトランジションをつけることができていい感じになります。

## 補足
プレビューではキーボードが出ないため？ orフォーカスが正しくとれない？ため動作確認できませんでした。
Python　Flask　参考サイト

# 公式ドキュメント
https://msiz07-flask-docs-ja.readthedocs.io/ja/latest/


# 参考サイト
https://study-flask.readthedocs.io/ja/latest/index.html#

https://aiacademy.jp/media/?p=57

https://tanuhack.com/category/python/flask/

# 参考動画
https://www.youtube.com/watch?v=VtJ-fGm4gNg

https://www.youtube.com/watch?v=EQIAzH0HvzQ

https://www.youtube.com/watch?v=jP7p2okKdJA

https://www.youtube.com/watch?v=Qr4QMBUPxWo

https://www.youtube.com/watch?v=Z1RJmh_OqeA

https://www.youtube.com/watch?v=bzbrpkbjWe8

https://www.youtube.com/watch?v=mW0_60SRr3s&list=RDCMUC0xRMqPOyRNPTaL6BxhbCnQ&index=3

https://www.youtube.com/watch?v=Gyy1tzwenc8

https://www.youtube.com/watch?v=dam0GPOAvVI
Unity LineRenderer SetPositions 同じ頂点 入らない

## 状況

スクリプトから、LineRenedererコンポーネントのPositionsにSetPositions()を使って複数の値を入れようとしてるのに、2つまでしか入らない！！！
おかしいだろ！！！


~~~C#:TestLineRenderer.cs
Vector3[] array = new Vector3[5]{Vector3.zero,Vector3.one,Vector3.zero,Vector3.one};
_lineRenderer.SetPositions(array);

※このコードはイメージです
~~~
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540890/0abe6581-3dc0-1cb3-2cbb-8bc2f39c64a9.png)

SetPositionsに流し込む値は5個あるのに2個しか入らない・・・

VisualStudioにブレークポイント張ってLineRendererの中身見ても同じ・・・2個までしか入ってない・・・

## 解決策
SetPositions()を行う前に，positionCountの値を変えたらいけます！！！！

~~~C#:TestLineRenderer.cs
Vector3[] array = new Vector3[5]{Vector3.zero,Vector3.one,Vector3.zero,Vector3.one};

//ここを追加や！！
_lineRenderer.positionCount = array.Length;

_lineRenderer.SetPositions(array);

※このコードはイメージです
~~~

## 原因

positionCountの値がSetPositionsで入れることができる最大の値だそうです！！！
それ以上はァ！！すべてェ！！！無視されます！（無慈悲）


そしてなんとこれはUnity公式のリファレンスに書いてあります！！！

https://docs.unity3d.com/ja/2018.4/ScriptReference/LineRenderer.SetPositions.html


見てないやつおる！？！？！いねぇよなぁ？？？！！
~~ここにおるでw~~




はい。
複数項目の入力値を配列でstate管理したい

# はじめに
グラフの描画などで複数の入力値を1つにまとめて管理したい状況があったので簡単にまとめてみます。

# やりかた
①型を定義
②配列をstateで定義
③各項目をstateで定義
④各項目の入力値を配列に追加する
``` 
type Datas = {
  height: number;
  age: number;
};

export const Hoge = () => {
  const [datas, setDatas] = useState<Datas[]>([]);

  const [height, setHeight] = useState("");
  const [age, setAge] = useState("");

  const onClickButton = () => {
    if (height !== "" && age !== "") {
      setDatas([
        ...datas,
        {
          height: Number(height),
          age: Number(age),
        },
      ]);
    }
    setHeight("");
    setAge("");
  };
// onClickButtonの処理をどこかに追加する
return (<div>hoge</div>);
};


```

# おわりに
データ管理の基本系は何も考えずに実装できるようになりたいです。
OSError: libcusparse.so.11: cannot open shared object file: No such file or directory　のメモ

pytorch_geometric を 使ったときに、
export LD_LIBRARY_PATH="your_miniconda_path/lib:$LD_LIBRARY_PATH"
というエラーが出たときの対処法

原因は、_LD_LIBRARY_PATH　という環境変数のフォルダに、
libcusparse.so.11　がないというもの。

下記を実行して、nvidia-cuda-toolkitをいれる
~~~sh
$ apt install nvidia-cuda-toolkit
~~~

findで、libcusparse.so.11の場所をさがす
~~~
$ find / -name "libcusparse.so.11"
/usr/lib/x86_64-linux-gnu/libcusparse.so.11
~~~

下記で環境変数にlibcusparse.so.11の場所を追加
~~~
$ export LD_LIBRARY_PATH="/usr/lib/x86_64-linux-gnu/:$LD_LIBRARY_PATH"
~~~
ゲーム業界の新人テスターについて

# はじめに
どうも、AIQVE ONEの教育担当者です。

今回ゲーム業界の新人テスターについてお話しさせていただきます。

まずは採用について少し触れておきますね。
多くのゲームテスト会社は経験者はもちろんのこと、未経験者の採用も行っています。
未経験者で採用されてた方の中には製造業や飲食サービス業、
不動産業など他業種からの転職者も多くいます。
かくいう私も、他業種をいくつか経験して現在に至っています。
未経験だからといって転職をあきらめている方、心配はいりません！
むしろ、今までのご経験を活かしてほしいと思っています。
![2020032504.jfif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2960680/d0dbb788-42a7-ef55-eb57-676a65180a0c.jpeg)

# ゲーム業界についてお話しします
当社は検証会社でテストをメイン業務としており、
その大半はゲームのテストを行っています。
ゲーム業界の企業で働く方の平均年齢は約35歳といわれています。
（他業界の平均年齢は41歳といわれています）
他の業界と比べてゲーム業界が若い人が多い理由としては、
業界自体が新しく、健康で時間に左右されず変化に適応しやすい人が
求められている等が考えられます。
![company_white_kigyou.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2960680/60ea672b-8181-aea1-e149-f1cd2d7c5178.png)

# どういう方が入社されるのか
業界自体、年齢が若い方が入社されるケースが多いのですが、
ほとんどのゲームテスト会社の求人広告では、
下記のようなフレーズを目にすることがあります。

・ゲーム好き集まれ
・ゲームをすることが仕事です
・誰でもできる簡単な仕事です

このようなイメージが強い為、異業種、未経験者の募集が多くなり
中には社会人経験が少ない方も入社されます。
　そのため、テスト技術はもちろん、コミニュケーションやコンプライアンス、
ヒューマンスキルなどが重要視されています。
![ダウンロード (10).jfif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2960680/148105f9-35e5-422e-02e4-9d6a0eb0d647.jpeg)

# どういう人材を育てるのか？
業務はチームで作業していくので、勤怠（遅刻欠勤）や仕事に対する姿勢や行動など
一般的な常識やビジネスマナーも必要ですし、開発の方と共有の会話をするための
ドメイン知識やソフトウェアテストなどのテストについての話ができるように
ならなければなりません。

当社ではそういったビジネスマナーやコミュニケーションといった「ヒューマンスキル」
ITやゲームについての知識を磨くための「ドメインスキル」
JSTQB（当社ISTQB platinum partneに認定）の考え方を取り入れた「テストスキル」
の3つの要素を合わせた弊社独自の研修を行っています。
![images (5).jfif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2960680/175b8cd3-a00c-28b1-fab1-3635f1821212.jpeg)

# さいごに
専門知識とマインドや社会人としての基礎力を常に”アップデート”し続ける人材を
育てるのが課題だと感じている今日この頃です。
Neo4jを調べてみて良さそうだと思った点

# 前書き
メタップスアドベントカレンダー第一日目の記事です。
Neo4jのドキュメントやグラフデータベースの概要をいくつか読んで、良さそうだな、と思った点をピックアップして書き下します。
また、グラフデータベースとはなんぞやについてはいっぱい記事があるので書きません。

名前と概要を読んだことがあるくらいしか知らないグラフデータベースを、少し掘り下げて調べました。
最短経路検索やSNSの繋がりの分析などに使われるということで、あまり身近ではないと思っていましたが、調べていくと意外と使う機会もありそうな気がしてきます。

# カテゴリ検索
[参考](https://neo4j.com/developer/cypher/guide-sql-to-cypher/#_product_categories)
これはなかなかすごいと思います。SQLではこんな感じになってしまうところを
```SQL
SELECT p.ProductName
FROM Product AS p
JOIN ProductCategory pc ON (p.CategoryID = pc.CategoryID AND pc.CategoryName = "Dairy Products")

JOIN ProductCategory pc1 ON (p.CategoryID = pc1.CategoryID
JOIN ProductCategory pc2 ON (pc2.ParentID = pc2.CategoryID AND pc2.CategoryName = "Dairy Products")

JOIN ProductCategory pc3 ON (p.CategoryID = pc3.CategoryID
JOIN ProductCategory pc4 ON (pc3.ParentID = pc4.CategoryID)
JOIN ProductCategory pc5 ON (pc4.ParentID = pc5.CategoryID AND pc5.CategoryName = "Dairy Products")
```

cypherだとこんな感じで書けるそうです。
```cypher
MATCH (p:Product)-[:CATEGORY]->(l:ProductCategory)-[:PARENT*0..]-(:ProductCategory {name:"Dairy Products"})
RETURN p.name
```

階層構造を持ったカテゴリーをRDBで扱うと階層構造が増えるほどにクエリがめんどくさくなりますね。階層構造を増やすにはクエリに手を入れなければなりませんし…。アプリケーション側で再帰的に取得していけば処理自体はシンプルにかけますが、ソートしたり検索しようとした場合全くスケールしないものになってしまいそうです。カテゴリ分けの機能を入れるなら、分類するアイテムをグラフデータベースに連携してカテゴリーはグラフデータベース側で管理するというのは良いかもしれません。階層構造を扱うと場合でいうと、組織図のようなものにも使えるかもしれません。
ただ、データベース間で連携するべきものが増えるたり連携が双方向になったりすると、データの整合性を取る事が非常に煩雑になりそうです。カテゴリーの例で言えば、カテゴリーに関連するデータはRDB側には置かないようにする、など制限を設けると良さそうに思います。

# 推薦
[参考](https://github.com/neo4j-graph-examples/recommendations)

クエリの書き方が結構簡単でいいです。
Aさんが観た映画と同じものを観た人が観た別の映画みたいなクエリを描きやすいです。
```cypher
MATCH (u:User {name: 'A'})-[:WATCHED]->(:Movie)<-[:WATCHED]-(:User)-[:WATCHED]->(m:Movie)
RETURN m.title
```
直感的にもわかりやすい。
また方向を無視して3回辿れば同じ情報に出会えるので、以下でも同じ結果になりそうですね。簡潔。
```cypher
MATCH (:User {name: 'A'})-[:WATCHED*3]-(m:Movie)
RETURN m.title
```

SQLで書くと煩雑になるので、こういう関連を辿った検索する場合は重宝しそうです。以下のような感じ。。？
```SQL
SELECT MOVIES.TITLE FROM WATCHED
INNER JOIN WATCHED W2 ON WATCHED.MOVIE_ID = W2.MOVIE_ID AND W2.USER_ID != :A_USER_ID
INNER JOIN MOVIES ON W2.MOVIE_ID = MOVIES.ID
WHERE WATCHED.USER_ID = :A_USER_ID
```

クエリが書きやすいと分析もしやすいので、こういったデータはグラフデータベースに流し込んでおくと良さそうです。

あとcorrect関数は地味に便利そうでした。SQLには似たようなものあったか覚えていませんが、collect集計関数は配列を返してくれます。これはgraphデータベースのメリットというよりはcypherのメリットですが。
```cypher
// Find similar movies by common genres
MATCH (m:Movie)-[:IN_GENRE]->(g:Genre)
              <-[:IN_GENRE]-(rec:Movie)
WHERE m.title = 'Inception'
WITH rec, collect(g.name) AS genres, count(*) AS commonGenres
RETURN rec.title, genres, commonGenres
ORDER BY commonGenres DESC LIMIT 10;
```

# 感想
クエリがすんごい便利だな！と思います。関連データを持っていて、検索したいのであれば導入してみるのもありかなと思いました。
パフォーマンスに関しては、関係もモデル化しているから早いんだ！みたいに言われていますが、RDBでもちゃんとインデックスはればそこそこいけるのでは。。？という気もします。内部的にどうなっているのかまだよくわからないのでなんとも言えません。検証とかしてみたいですね。
ただ、正直サービスが小さいうちはデータが分散するし運用コストも学習コストもかかるので効率を考えれば採用はしたくないですね。将来的にグラフデータベースのノウハウは貯めておくと役立ちそうなので、そういう意味では使ってみたいなぁと思います。
とりあえず、もう少し調べたいです。
「Linux」の基礎知識

# Linuxとは
CPU、メモリ、ハードディスク、ディスプレイ、キーボード、周辺装置に至るまで、パソコンに入っているすべてのハードウェアを管理しているOSの一種です。WindowsやiOSとは異なり、Linuxはサーバー用、組み込み器用などの幅広い場所で使用されているのが特徴です。

## カーネル
OSの中核部分として機能するソフトウェアです。CPU、メモリ、ハードディスクなどのハードウェアをソフトウェアが直接触るのではなくて、カーネルが代わりにやってくれます。

## シェル
人からの入力をコンピュータに伝えるプログラムです。コマンドプロンプトやターミナルがシェルになります。

## Linuxの操作方法
操作方法は2つあります。1つ目は、サーバーのコンピュータから直接操作するコンソール。もう1つはコンピュータを遠隔利用することを可能にするターミナルです。

## ディレクトリの一覧
ディレクトリとは、ファイルが保存されている場所です。Windowsのフォルダと同じものです。Linuxのディレクトリ構造は、ルートディレクトリを頂点とした構造になっていまます。その下には様々なディレクトリがあります。
例）
bin: 一般ユーザーが使用できるコマンドの実行ファイル
etc: システム設定ファイル
home: ユーザーのホームディレクトリ
root: rootのホームディレクトリ
var: アプリケーションを動作する上で作成されたログなどを格納したファイル
usr: 各種アプリケーションと、それに付随するファイルを格納
lib: ライブラリファイル

## 絶対パス・相対パス
絶対パスとは、最上階層から目的のファイルまでの場所を示したパスです。
相対パスとは、今いる階層を基準として目的のファイルまでの場所を示したパスです。

## 代表的なコマンド
### ファイル・ディレクトリの基本操作
#### ls 
現在自分がいる階層のデータを表示。-al コマンドをつけると、隠れているファイルを含めた詳細な情報を表示します。
#### cat ファイル名
ファイルの内容を表示。
#### cd ディレクトリ名
指定したディレクトリに移動。cdの後に..がついていた場合、一つ上のディレクトリに移動します。
#### cp ファイル名　デイレクトリ名
ファイルをディレクトリにコピー。
#### echo "文字列" > ファイル名
文字列をファイル名に入力。
#### mkdir ディレクトリ名
ディレクトリを作成。
#### mv ファイル　ディレクトリ名
ファイルをディレクトリ名に移動。
#### pwd 
現在位置を表示。
#### rm ファイル(ディレクトリ）
指定したファイルやディレクトリを削除。

### ユーザ管理
#### groupadd グループ名
グループの作成
#### groupdel グループ名
グループの削除
#### groups　ユーザ名
指定ユーザが所属するグループ一覧
#### passwd ユーザ名
指定したユーザのパスワード変更
#### useradd ユーザ名
ユーザ作成
#### userdel ユーザ名
ユーザ削除

### パーミッション管理
#### chgrp グループ　ファイル名
指定したファイルの所有グループの変更
#### chmod アクセス権　ファイル名
指定したファイルのアクセス権を変更 
#### usermod -G グループ名 ユーザ名
作成したグループにユーザを加入

参考記事
https://qiita.com/shisama/items/5f4c4fa768642aad9e06
https://qiita.com/49497974m/items/919985f3a6f6a6b19ee8
https://qiita.com/uguis410/items/f9e82350d5d49a300491
https://qiita.com/kazuki-ayimon/items/57c3fd6eb71774e896ed
https://qiita.com/tatsuya4150/items/f830c9b2ae33275aef42
https://qiita.com/masato930/items/6031785e23d8fdbb1a5a
https://qiita.com/larcmiya/items/a79e8ab5b0f42fde6748
https://qiita.com/shin4488/items/eb5cd6db669380fae774
https://qiita.com/_old_boy_/items/213e6d77fa1922b4fb11
fluxcdを導入してk8sイメージの更新を自動化した

こんにちはGANMA開発エンジニアのorehahtiyaです。これは [FLINTERS advent calendar 2022](https://qiita.com/advent-calendar/2022/flinters) 6日目の記事です。

この記事ではfluxcdを導入してk8sイメージの更新を自動化したことについて説明します。これによってGANMAアプリのデプロイを少し楽にすることができました。

## fluxcdとは
[fluxcd](https://fluxcd.io/)はk8s上で動作するアプリを[GitOps](https://www.gitops.tech/)形式でデプロイしやすくするためのツールです。

GitOptsとはインフラの設定コードをgitリポジトリ上で管理(IaC)しgit上の操作(commitやmerge等)が行われたタイミングで自動的に実際のインフラとの同期を取るという考え方です。インフラの状態をロールバックしたい場合なども、インフラを直接操作するのではなく設定コードを管理しているgitレポジトリでrevertなどを行いロールバックします。他のGitOpsの考え方を採用しているツールとしては[Argo CD](https://argo-cd.readthedocs.io/en/stable/) などがあります。

またfluxcdには設定コードと実際のインフラとの間の状態を同期する機能の他にもimage registryを監視して設定コードに書かれた[イメージタグを自動で書き換える機能](https://fluxcd.io/flux/guides/image-update/) もあります。

設定コードと実際のインフラとの間の状態を同期する部分に関してGANMAでは[helmfile](https://github.com/helmfile/helmfile) を使用しているため、今回はイメージタグを自動で書き換える機能だけを使いデプロイの自動化を進めました。

## GANMAでのデプロイ手順

![flux導入前.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172286/6dbddf17-d508-c269-466e-e8f50afd3143.png)

GANMAで運用しているアプリは大多数がk8sで運用されていて、上図のような手順でデプロイを行っています。

1. app repositoryのメインブランチにマージリクエストがマージされると自動でgitlab jobのタスクがトリガーされコンテナイメージのビルドとECRへのプッシュが行われます。
2. デプロイ担当者がpushされた最新イメージのタグを確認します
3. 2で確認したタグでk8s config repositoryに記述されているイメージタグを書き換えます。
4. k8s config repositoryのgitlab jobをトリガーし、helmfile applyを実行して設定コードの変更をEKS Clusterに反映させます

GANMAは[Deploymentリソース](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) を使ってデプロイを行っているので 3ではDeploymentリソース中の `.spec.template.spec.containers.image` の箇所を書き換えます。

## fluxcdによるデプロイ手順の改善

![flux導入後.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172286/dc96b7cd-b40e-bc0d-633e-af10e8b30010.png)

fluxcdを使って上図のようにデプロイ手順を改善しました。図の通り手順2と3をfluxで自動的に行うようにしました。

実際にはfluxcd自体もEKS Cluster上で動作しているのですが、分かりやすさのために図では別々にしています。

fluxcdは定期的にECR registryをscanし新しいイメージタグが発見されたタイミングで、k8s config repositoryにタグを書き換えるコミットを行います。どのようなポリシーで設定コード中のどの部分に書かれているイメージタグを書き換えるのかはマーカーによって指定します(https://fluxcd.io/flux/guides/image-update/#configure-image-updates) 。

fluxcdのインストールや詳しい設定方法は公式ドキュメントを参照してください(https://fluxcd.io/flux/guides/image-update/) 。

## まとめ

fluxcdを導入することによりデプロイの手間を減らすことができました。また自動化によって人的ミスも起こりにくくなったと思います。 k8sを使っていてデプロイを宣言的＆自動的に行いたい方はfluxcdやArgo CDなどのGitOpsツールの導入を検討してみると良いと思います。

## 参考
* https://fluxcd.io/
作業中の変更を一時退避させる git stash ハンズオン

# 背景
プルリクを出している最中に別の作業をしていたり、コミットしたくないけどとりあえずどこかに保存させておきたい場合に使えるstashを使うと便利なのを紹介したい

# 覚えて欲しいコマンドと効果

```bash
git stash -u # untracked file を含めて退避する

git stash list # 一覧表示をする

git stash pop # 最後のshashを退避から取り出し、対比場所から削除する
```

# 使ってみた

ブランチの準備

```bash
git switch -c branch_a
```

test_a.mdを作成後、以下のようにファイルを保存する。
```markdown:test_a.md
# aでの作業

branch_aで作業しました

```

stashをする
```bash
git stash -u
# Saved working directory and index state WIP on branch_a: xxxxxx add workspace setting
```

これでworkspaceの変更分がstash領域に保存される。

ちなみにstashの一覧を確認するコマンドはこれ。

```bash
git stash list
```

続いて別のブランチに移動

```bash
git switch main # mainブランチに移動して
git switch -c branch_b # branch_b ブランチを切る
```

test_b.mdを作成後、以下のようにファイルを保存する。
```markdown:test_b.md
# bでの作業

branch_bで作業しました

```

branch_bでの作業をコミットする

```bash
git add .
git commit -m "add test_b.md"
```

branch_aに切り替えて、退避した変更を戻す
```bash
git switch branch_a
git stash pop
```

すると退避させた変更がworkspaceに戻ってくる。

これを実行するとstashの一覧からは消えるので、`git stash list`をしたらbranch_aのstashは削除される。

# 補足

## stashにメモを残す

stashするだけだと最後のコミットのメッセージが表示されるが、任意のメモを残すこともできる。

コマンドは以下。

```bash
git stash save "任意のメッセージ" -u
```

listを確認すると
```
stash@{0}: On main: 任意のメッセージ
```
のように`stash@{ID}: ブランチ: "メッセージ"`と表示される。


## 退避した変更を戻すコマンドについて
退避した変更を戻す方法はもう一つあり
```bash
git stash apply stash{0}
```
でも可能。

applyとpopの差は
- apply: 退避した差分をworkspaceに戻してもstashした内容を削除しない
- pop: 退避した差分をworkspaceに戻してもstashした内容を削除する


個人的なおすすめとしてはapplyは使わないようにして、popを使うこと。
理由としては
- 削除するの忘れて大量のstashがあるとわからなくなる
- 複数の作業を並列するとはいえ1人で3つ以上の作業が同時に走らせることはあまりない

という感じで、最近は [覚えて欲しいコマンドと効果](#覚えて欲しいコマンドと効果)の3つだけで事足りるようにしている。

## 複数のstashがある時のpopの挙動について
pop は引数に名前を指定せずに使用可能で、複数のstashがある場合は**最後にstashした内容**がworkspaceに反映される。

つまり
```bash
$ git stash list
stash{0} ... # 後のstash
stash{1} ... # 先のstash
```
とある時に `git stash pop` を実行すると stash{0}がworkspaceに反映される。
ERROR: Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/info": dial unix /var/run/docker.sock: connect: permission deniedの解決方法

## 権限を付与する
タイトルのようなエラーが出た際には、以下のように権限を付与する。
```bash
$ sudo chmod 666 /var/run/docker.sock
```

## 結果を確認する
成功したかどうかを確認するには以下のコマンドを実行する。
```bash
$ docker ps
```
以下の様に出力されれば成功。
```bash
~$ docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
Dockerを用いたnode.jsの実行環境構築

Dockerを用いてnode.jsの実行環境を構築しました．
nodejsのbase imageをpullせずに，ubuntuのbase imageにnode.jsをインストールする形で構成しました．

#フォルダの構成
```text
├─Dockerfile
└─bash
    └─nodesource_setup.bash
```

# ファイルの内容
```Dockerfile:Dockerfile
FROM ubuntu:20.04

ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends \
    apt-utils sudo git curl vim unzip openssh-client wget gnupg2 lsb-release software-properties-common \
    build-essential cmake \
    libopenblas-dev \
    libglib2.0-0 \
    libsm6 \
    libxext6 \
    libxrender-dev

# node.jsインストール
WORKDIR /root/
RUN curl -sL https://deb.nodesource.com/setup_14.x -o nodesource_setup.sh
COPY ./bash /root/
RUN ["/bin/bash", "/root/nodesource_setup.bash"]
RUN sudo apt install -y nodejs

RUN sudo apt-get update && \
    sudo apt-get upgrade -y

RUN npm install express
```

```bash:nodesource_setup.bash
sudo bash nodesource_setup.sh
```

# Build
```bash
cd /path/to/project_dir
docker build -f ./Dockerfile .
```
# 備考
ちなみに，ubuntuのOSに直接aptでインストールする場合は，以下のコマンドで実行できます．
```bash
sudo apt-get install -y nodejs npm
```

# 参考
https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-ubuntu-20-04-ja
【Unity】parentプロパティで親オブジェクトを取得する

__parentプロパティで一つ上の親オブジェクトを取得することが出来る。__

```
GameObject obj = transform.parent.gameObject;
```
transform.parent.gameObjectで親を取得。

__parentを重ねると親の親を取得できる__
```
GameObject obj = transform.parent.parent.gameObject;
```

例
```
public class SphereScript : MonoBehaviour
{
    private GameObject testObj;
 
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.S))
        {
            testObj = transform.parent.gameObject;
        }
    }
}
```
PlantUMLのエラー [VSCodeアドイン]

## エラー内容
 
PlantUMLでプレビューしたときに以下のエラーが表示される。

```text:エラー内容
Warning: the fonts "Times" and "Times" are not available for the Java logical font "Serif", which may have unexpected appearance or behavior. Re-enable the "Times" font to remove this warning.
```
![スクリーンショット 2022-11-28 12.03.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/987057/6087791a-96a2-329b-26fd-66e9deeb757b.png)


## エラー解決策

Mac上に「Times」というフォントが入っていないことで警告がでている状況。

以下のサイトからダウンロードし、Mac 上で FontBook を開きダウンロードしたフォントを追加することで解消される。

https://www.freebestfonts.com/timr45w-font#google_vignette
【Laravel×React】npm run watchでファイルの修正が反映されない

## 問題

`npm run watch`でファイル修正・保存した箇所をブラウザ上で確認したいができない。
再コンパイルが起きていない模様。


## 対策
`npm run watch-poll`を使う。

使用している環境によっては、`npm run watch`が正しく動作しないことがあるようです。

## 補足
`npm run watch`と`npm run watch-poll`の違い。

`npm run watch`：　ファイルの変更をみている。 (特定の環境の場合は上手くいかない)
`npm run watch-poll`：　変更を 1秒単位などで定期的に確認をする。

※watch：ファイルを監視し、ファイルの変更があった時に差分だけをトランスパイル先に
　　　　　アップロードしてくれる。


```php:package.json
    "scripts": {
        "dev": "npm run development",
        "development": "mix",
        "watch": "mix watch",
        "watch-poll": "mix watch -- --watch-options-poll=1000",　-①
        "hot": "mix watch --hot",
        "prod": "npm run production",
        "production": "mix --production",
        "start": "webpack -w --config webpack.dev.config",
        "build": "webpack --config webpack.pro.config"
    }
```

①"–watch-options-poll=1000"オプションが追加されていて、1000ミリ秒（1秒）ごとに
　ファイルの変更を強制的に見にいくという動作をする。

　使っているPCのスペックによっては1秒ごとだと、負荷が重い可能性があるので、
　適宜秒数は変えましょう。　(下記サイトが非常にわかりやすいです。)
　[Laravel-mixのnpm watch-pollのcpu負荷が重いのでwatch-pollの間隔を変える](https://qiita.com/rabbitbeef/items/bd8edf37104fda367a7d)

## 参考文献
https://programming.sincoston.com/laravel8-npm-run-watch-not-work/
NextjsにBootstrapを導入する方法

Nextjsにbootstrapを導入する方法は、以外と簡単です。

yarn add bootstrap

これで最新のBootstrapが導入されます。
最新のものに更新する場合は、

yarn upgrade bootstrap --latest

です。
これで、Nextjsにbootstrapのモジュールが入ったわけです。
このモジュールを利用して実際にプログラムを書いていきます。

通常、bootstrapは全てのページで読み込みますので
_app.js
にbootstrapを使う旨を宣言します。

Nextjsでは、_app.jsってファイルが、共通で読み込まれるページです。
これは、pageのフォルダーの中にあると思いますが、ファイルの一番上に、下記の１行追加します。

import 'bootstrap/dist/css/bootstrap.min.css';

これで、bootstrapがすべてのページで使えるようになります。

簡単でしょ。
[Mac版] VSCodeで"PlantUML"の環境構築

# PlantUMLとは

PlantUML は、以下のような`UMLをテキストベースで素早く作成する`ためのオープンソースです。

- シーケンス図
- ユースケース図
- クラス図
- オブジェクト図
- アクティビティ図
- コンポーネント図
- 配置図
- 状態遷移図（ステートマシン図）
- タイミング図

またUML以外にも以下のような図も対応してます。

- JSON data
- YAML data
- Network diagram (nwdiag)
- ワイヤーフレームによるグラフィカルインターフェース、UIモックアップ（salt）
- アーキテクチャ図
- 仕様及び記述言語 (SDL)
- Ditaa
- ガントチャート
- マインドマップ
- WBS図(作業分解図)
- AsciiMath や JLaTeXMath による、数学的記法
- ER図

**公式サイト**

https://plantuml.com/ja/

# PlantUMLのメリット

- `テキストエディタで書くこと`ができる（VSCode等）
- 作成・修正・流用`(コピペ)が簡単`にできる
- テキストで管理するため、`Git等で変更前後での差分`がわかりやすい
- UMLのレイアウト調整の工数を削減することができる
- テキストベースなので`ファイルサイズが軽量`

# 環境構築

## PlantUMLで必要となるソフトウェアをインストール

PlanutUMLを動かすために、`JavaとGraphviz`をインストールします。

`Java` :PlantUMLを動かすためのプラットフォーム
`Graphviz` : PlantUMLでは図の位置計算で必要となる

### Javaをインストール

```bash
brew install --cask adoptopenjdk
```

インストールが出来たか確認します。
以下のコマンドでバージョンが表示されたらインストール完了です。

```bash
java --version
```

↓バージョン確認結果の例
![Monosnap 拡張機能: PlantUML 2022-11-28 11-30-15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/987057/5fe36d04-d381-024d-225f-a81db4af6c75.png)


### Graphvizをインストール

以下のコマンドでGraphvizをインストールします。

```bash
brew install graphviz
```

### VisualStudioCode（VSCode）でプラグインを追加

VSCodeでPlantUMLのプラグインを追加します。

1. 画面左側のタブからExtensionsを選択して検索ボックスに「`PlantUML`」と入力
2. 一番上に「PlantUML」が表示されるので「`Install`」ボタンをクリック
3. インストールが完了したらVSCodeを再起動

![Monosnap 拡張機能: PlantUML 2022-11-28 11-26-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/987057/98eb7601-d4e4-f05a-f4d0-acb901415486.png)

### 動作確認

1. 新しいファイルを作成し、以下のテキストを入力します。
    ```md
    @startuml
    title シーケンス図
    クライアント -> サーバ: リクエスト
    サーバ --> クライアント: レスポンス
    @enduml
    ```

2. `⌥ (Option) + d` キーを押し、PlantUML Previewの画面が表示します。
    以下のような表示になれば、正常に動作できています。
    ![Monosnap PlantUML プレビュー 2022-11-28 11-42-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/987057/22e106d1-8fbd-3a6a-8f1d-d792bb611a8b.png)


### PlantUML 参考サイト

- PlantUML公式リファレンス

https://plantuml.com/ja/

https://pdf.plantuml.net/PlantUML_Language_Reference_Guide_ja.pdf

- PlantUML入門①: シーケンス図の書き方

https://applis.io/posts/plantuml-sequence-diagram
Gitのパーソナルトークンが切れたとき（更新時）の対処…の落とし穴だったところメモ

# はじめに

```:うまくいかないパターン
% git fetch
remote: Invalid username or password.
fatal: Authentication failed for （略)
```


ほとんどの人は以下のURLで解消すると思います。
https://qiita.com/gin_teacher/items/d52a25fb5ca9fed3108a

似たような記事もいくつか参照しました。
https://zenn.dev/yuri0427/articles/9587ae6a578ee9
※ "git push origin"は流石にアレなので基本的には"git fetch"のほうがいいと思う

1. キーチェーンをクリア（または更新する）
1. git config -global で要素を更新する

普通はこのあたりを実施することで再度権利情報（usernameとかpasswordの確認）確認が登場して、そこで新しいトークンをパスワードとして入れればいいと思います。

自分の場合ここで何をやっても解消せず、キーチェーン以外の各所のキャッシュクリアなどを経てもまだ再更新されない状態になったので、解消のための確認を一応メモがてら残しておこうかと。

# 確認したほうがいい点

> % git remote -v


```:結果の例
% git remote -v 
origin  git:{古いトークン}@github.com/hoge.git (fetch)
origin  git:{古いトークン}@github.com/hoge.git (push)
```
みたいに、remote時点でトークンが埋まっていることがある。何故か自分がそうだった。
※GitHub　EnterpriseのURLを差し替えて書いたため、名前やトークンの位置は異なるかもしれない。

もちろん新しいトークンに差し替えても動くが、次回更新時に再度引っかかるので、パスからトークンを除去しておくのが正解かと思われる。

手元で２パターンをCLI（ターミナル）とInterlliJから試したが、どちらも以下のように成功した。

- 新トークンを入れた場合、そのまま処理成功
- トークン部（コロンも）を除去した場合、権利情報入力が出てきたので、ここで新トークンを入れたあと処理成功

# 確認経緯
キーチェーンをクリアしても駄目（権利情報確認なしに接続不可）だったので、最初はInterlliJのキャッシュや接続情報が古くて出ないのだと思っていたが、ココをいくら飛ばして再設定しても出てこない（GitHubでトークンを再設定するのをInterlliJ経由でやっても不可）。
念のためCLIで打ったが状況が変わらない。

PCそのものを再起動しても駄目で、念のため１晩おいたが当然状況変わらず。

一晩おいたことで冷静になったので、ファイルを退避して再度リポジトリを掘り直してみようと思い、"git remote -v"で今の設定URLを確認。

あれ？このURLトークン埋まってない？多分古いっぽいから新しいトークンに差し替えよう→動いた。

流石にトークン埋めてると次の更新でまたややこしいから除去しておいたほうがいいかな→権利情報確認出た。

# 最後に
行き詰まったらお茶飲んだりでリフレッシュして「ココは大丈夫」の思い込みを減らしたり、切り分けられそうな原因を少しでも気づく限りほっていくほうがいいっすね。
最初の設定時になんでトークンが埋まったのかは謎でしたが、思い返してもしょうがないので仕事に戻ります。

万一別の誰かが同じことで引っかかった際には自分みたいに半日飛ばさずこの記事にたどり着けますように。
ネットの記事で紹介されているServiceクラスの違和感

## 経緯


UserControllerに色々書いてたらFatControllerになっちゃったよ・・・・
解決方法無いか調べてみるか....

ん？Serviceクラスを作って処理を分離させよう！?

UserControllerからビジネスロジックをUserServiceに分離した！！
これでFatController問題は解決だ!!

.....ん？？

## 課題

あれ？処理は分離できたけど、ビジネスロジック部分をごっそり移動させたFatServiceが出来上がった...

## 解決策

### ユースケースごとに処理を分ける

例えばユーザーを登録する処理をUserControllerに全部書いていた場合

``UseCases\User\Create.php``

にロジックを分離し、controller側から呼び出す。

> 実際は主語のでかいServiceクラスを
Hoge/HogeXXXXService
という具合に分離しました。

### 疑問

- Serviceクラスとの使い分け
    - 引用に書いた解決策は,ServiceクラスをUseCaseもどきのように扱う解決策。
        - UseCaseそのものはUseCaseに、ある程度汎用的な処理そのものはServiceクラスに書く？？

### 備考

Serviceクラスを作ってみよう！みたいな記事、ごっそり処理を移動させただけで根本的な解決をしていないものが多い気がする。

❌ FatController内の処理をServiceクラスに分離しよう！！
🟢 FatController内の処理をUseCase毎でServiceクラスに分離しよう！！

の方が良い気がする。

PS:デメテルの法則を良い感じに守ろうとServiceから他のServiceを呼ぶのを禁止にしたら、それはそれで問題が色々出てきたので最近そのルール辞めました。

## 参考記事
https://cloudsmith.co.jp/blog/backend/laravel/2022/03/2052565.html

https://qiita.com/joker1007/items/25de535cd8bb2857a685

https://qiita.com/br_branch/items/37cf71dd5865cae21401
livewire プロパティで使える型について


## 扱える🟢
### string
- 使う場面はあんまり無い
    - null許容型を使う時は宣言時にnullを入れよう
### int
- 文字列以外を入れると当然エラーが起きる
    - 型を指定せずにプロパティを宣言し、その値を使う時にintにキャストして使うのが良いと思う

### bool
- 空文字や0の時にfalse
    - 'false'という文字列はダメ

:::note warn
初期化の必要あり
```php
public bool $flag = false;
```

:::

### array
- ネストしてライフサイクルフックを扱える(以下記述)

```php
public $hogeArray = ['title' => null,'content' => null ]

public function updatedHogeArrayTitle()
{
  //titleが変更された時に動く処理
}

```

### Model

- ネストしてライフサイクルフックを扱える(以下記述)

```php
public Hoge $hoge;

public function mount()
{
  $this->hoge = new Hoge();
}

public function updatedHogeTitle()
{
  //hogeモデルのtitleプロパティが変更された時に動く処理
}

```

### EloquentCollection
- 勝手に配列に変換されないので使える
  - 但し罠もある（以下記述）
```php
$this->hogeModels->push(new Hoge());
```
pushした場合、pushしたHogeオブジェクトは何のDBから取ってきたかの情報が無い為エラーが発生する。
次回の記事で書きます。

## 扱えそうで扱えない❌

### SupportCollection
- フロント側のプロパティをPHP側のプロパティに変換する際、強制的に配列に変換される為。

### Modelを内包したarray
- フロント側のプロパティをPHP側のプロパティに変換する際、強制的に配列に変換される為。
    - EloquentCollectionは対応している為、同じModelクラスを取り扱うのであればそちらが良いだろう。

対処法はまた記事に書く

### CarbonやDate
- 強制的に文字列になる為