OmniAICreator/Qiita-1.07M huggingface dataset:
【Oculus Integration】開発メモ


## M1 MacでOculus Integrationを入れると落ちる場合の解決方法

`Assets/Standard Assets/Oculus/Spatializer/Plugins/AudioPluginOculusSpatializer.bundle`
を削除する

参考: https://forum.unity.com/threads/macbook-pro-m1-oculus-crash.1017730/

## UI Interactionの方法
* UI Canvasに`OVR Raycaster`コンポーネントをアタッチします。
* UI Canvasの`Graphic Raycaster`コンポーネントを削除します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1161684/780bb99f-c16d-73ef-fcf8-a9f15da53540.png)

* UI Canvasを追加した際に同時に追加された、`EventSystem`オブジェクトを削除します。
* プロジェクトから`UIHelper`Prefabをシーンに追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1161684/bc91aeb7-6193-9622-4499-3daf51e6ebba.png)

* `UI　Helper`の`EventSystem`にある`OVR Input Module`コンポーネントの`Ray Trasform`に使用するコントローラー(`Right Hand Anchor`または`Left Hand Anchor`)をドラッグ&ドロップします。
* `Joy Pad Click Button`をTrigger Buttonにしたい場合、右コントローラの場合は`Secondary Index Trigger`, 左コントローラーの場合は`Primary Index Trigger`を設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1161684/bbf048e8-b04b-39e1-59b5-eeff933faaec.png)

* もし、ポインタまでの軌跡を表示させたい場合には、`UI Helper`の`Line Renderer`コンポーネントを`enable`にします。

## Controllerを表示する (1)
`Prefabs`フォルダーの中の`OVRControllerPrefab`を`ControllerAnchor`の下に追加します。そして、対応するように、Inspector内にある項目で、`Controller`を`L Louch`または、`R Louch`を設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1161684/c6aae3a2-c970-511f-7cb5-ff2bf52362c3.png)

## HandControllerを表示する
`Prefabs`フォルダーの中の`OVRCustomHandLeft`を`LeftHandAnchor`に、`OVRCustomHandRight`を`RightHandAnchor`にアタッチします。
(どちらがいいのかは、わからない)

## Controllerの入力を受け取る
`OVRPlayerController`に`OVRInputListener.cs`をアタッチし、そこで全てのボタンに対する操作を記述していきます。

```c#
void Update()
{
if (OVRInput.GetDown(OVRInput.RawButton.A))
{
    Debug.Log("Aボタンを押した");
}
if (OVRInput.GetDown(OVRInput.RawButton.B))
{
    Debug.Log("Bボタンを押した");
}
if (OVRInput.GetDown(OVRInput.RawButton.X))
{
    Debug.Log("Xボタンを押した");
}
if (OVRInput.GetDown(OVRInput.RawButton.Y))
{
    Debug.Log("Yボタンを押した");
}
if (OVRInput.GetDown(OVRInput.RawButton.Start))
{
    Debug.Log("左手メニューボタンを押した（オン・オフ不安定なので注意）");
}

if (OVRInput.GetDown(OVRInput.RawButton.RIndexTrigger))
{
    Debug.Log("右人差し指トリガーを押した");
}
if (OVRInput.GetDown(OVRInput.RawButton.RHandTrigger))
{
    Debug.Log("右中指グリップを押した");
}
if (OVRInput.GetDown(OVRInput.RawButton.LIndexTrigger))
{
    Debug.Log("左人差し指トリガーを押した");
}
if (OVRInput.GetDown(OVRInput.RawButton.LHandTrigger))
{
    Debug.Log("左中指グリップを押した");
}
}
```
## Joystickで移動する

`OVR Player Controller`PrefabをCameraの代わりに使用すれば、左で前後左右の移動、右で回転の動作が可能です。

## Photonを用いて複数のプレイヤーと移動を同期する

## Objectを掴む

## Objectを掴む(遠距離)
swift基礎の基礎③〜オブジェクトの制約〜


### 備忘録
＜lavelとbuttonを使ってアプリを作るときの注意点＞

①オブジェクトにはx軸とy軸の両方に制約をかけること。
（画面のどこの位置に配置するか）

ここを押し・・・
![スクリーンショット 2021-03-08 12.18.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/782402/d0fbd683-d516-4662-5f4b-f2971ac18b89.png)

Horizontally in ContainerにチェックしてAdd 1 Constraintをするとオブジェクトが真ん中に配置される制約。
どの種類の端末にしても真ん中に配置される。

![スクリーンショット 2021-03-08 12.17.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/782402/5c09c6b4-e633-b2d6-f916-61b1eab89b6f.png)

ここを押すと・・・
![スクリーンショット 2021-03-08 12.23.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/782402/9a5f4225-9edd-1f50-acc1-ce1f637d5bc3.png)

画面の上下左右からどのくらいの位置に配置させるかの制約をつけることができる。
任意で数字をきめ、Add 1 Constraintをすると反映される。

![スクリーンショット 2021-03-08 12.21.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/782402/1d0575ab-05ed-cacf-d2e1-a5a5d25df3ae.png)

### その他
便利なショートカットキー

・画面の二分割するショートカットキー
option + command + control + enter
Excelの列名を列番号の数字に変換するオブジェクトを作りました。 #blueprism

# これを作った理由
F列は6列目、くらいならすぐわかりますが、GF列って何列目かくらいになると、とっさにはわからず……
~~平安絵巻みたいなクソ長い台帳なんか運用しy~~ 

# 冷静に考えてみる
これExcelの列だと思うから、Excelをどうしようとか、セルを左から順に数えてとか、ややこしく考えてしまうんで
この列名ってつまり26進数ですよね？
「〇進数を△進数に変換する」っていうのは算数ドリルの問題とか、プログラミングの練習問題で絶対出てくるやつで

たとえば、8進数を10進数に変換する場合：　264 だったら　$2*8^2 + 6*8^1 + 4*8^0$

っていうやつ。つまり「各桁の数字 × 〇進数の〇を(桁数-1)乗したもの」を全部足してます。
「26進数を10進数に変換する」と思えば、これってただの初級練習問題レベルのお話でした。
だからGF列なら、$7 * 26^1 + 6 * 26^0 = 188$ 列目、ということになるわけです。

# 必要なもの
まず、計算するためにA～Zを1～26の数字に変換しないといけないんですが
[半角大文字をAscで変換した文字コード](https://docs.microsoft.com/ja-jp/dotnet/api/microsoft.visualbasic.strings.asc?view=net-5.0)から64引いたら、ちょうどいい数字になります。なのでこれを使います。
下表は、文字に対応する文字コードと、そこから64引いた数字です。
![文字コード表.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142092/4cab7b8a-5c54-7da7-7628-d87b52d5bc96.png)
[英文字を文字コードに変換するのはAscで、MicrosoftDocの説明はこちら](https://docs.microsoft.com/ja-jp/dotnet/api/microsoft.visualbasic.strings.asc?view=net-5.0)
[階乗はこれを使います。MicrosoftDocの説明はこちら](https://docs.microsoft.com/ja-jp/dotnet/api/system.math.pow?view=net-5.0)
[列名の英文字を1文字ずつにバラして計算するので、バラして配列に入れるのがこれ。MicrosoftDocの説明がこちら](
https://docs.microsoft.com/ja-jp/dotnet/api/system.string.tochararray?view=net-5.0#System_String_ToCharArray_System_Int32_System_Int32_)


# これを踏まえて作ったオブジェクト
入力引数はColAlpha、出力引数はColNum。
![入力引数.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142092/0348b88e-f1b6-6f02-cde5-187b5a3c4d15.png)
![出力引数.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142092/9424414e-46aa-d7e6-4e2d-4d7b56c1e77c.png)
InitializeのNamespace Importsに、System.IOとMicrosoft.VisualBasicを足しておいてください。（上で挙げたメソッドを使うために必要）
![コードオプション.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142092/bcd1f2a1-4293-9223-9f1c-5fc5874d4db9.png)

フロー。コードステージに入る前に、列名が半角大文字英字のみになるように予めチェックとか変換とかをしておきます。
![フロー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142092/baba3dfe-cb3e-8948-c583-e882404080e9.png)
「文字種確認」ステージで、3桁までの半角英字でないものはNGとしています。
正規表現でチェックするのに使っているVBOは[AVO.RegEx。DXのここに置いてあるやつをインポートするだけ。](https://digitalexchange.blueprism.com/dx/entry/3593/solution/avoregex)
![文字種確認.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142092/8b15af29-0472-c95c-8b60-ed8d5450ecba.png)
大文字にするのは関数で
![大文字に.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142092/8e410e78-1f5b-f454-0b5c-2a311f6c167c.png)

コードステージの中身。事前に入力引数をクリーンにしているのであり得ないはずですが、もし半角英数大文字以外が入ってきたら0を返します。
![コード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142092/3bf0ec78-18ef-ef80-411b-717bef33cf89.png)

```vb
' 列名をバラす
Dim aryColAlpha As Char() = ColAlpha.ToCharArray()
' 桁数-1
Dim cntMul As Integer = ColAlpha.Length - 1

For Each c As Char In aryColAlpha
	' 英字(A～Z)を数字(1～26)に変換
	Dim Currentc As Integer = Asc(c) - 64
	' 半角英大文字でなかった場合は0を返して終了する
	If Currentc < 1 Or Currentc > 26 Then
		ColNum = 0
		Exit For
	End IF

	ColNum += Currentc * CType(Math.Pow(26, cntMul), Integer)
	cntMul -= 1
Next
```

# 終わりです
これはただ「〇進数を△進数に変換」してるだけなので、Blue Prismに限らず、UiPathとか他のツールなりなんなりでも普通に使えるお話です。
PyTorch Tensorをprintで要約表示させないようにする

#はじめに
PyTorchのTensorの中身をprintすると、いい感じに要約表示してくれるが、全部表示させたいときもある。
numpyで全部表示させる方法はググるとすぐでてくるが、PyTorchのTensorについてはすぐに見つからなかったのでメモっておく

#方法
以下のようにset_printoptionsのidgeitemsを指定する。

```python
torch.set_printoptions(edgeitems=1000)
```

これは最初と最後にようやく表示される配列の要素の数の設定であるが、これを大き目の値に設定しておけば、配列の要素をずらっと表示させることが可能だ。

set_printoptionsメソッドは他にも色々設定できるようなので、参考文献を見てほしい。

#参考
https://pytorch.org/docs/stable/generated/torch.set_printoptions.html
AWSへデプロイ後にユーザー情報が更新できない現象への対処法

#AWSへデプロイ後に、user.saveでユーザー情報が保存できない現象についての対処法
とあるプログラミング学習サイトを利用してRailsを学び、作成したアプリケーションをサーバーへデプロイしたところまでは良かったのですが、その後作成したユーザーのアイコンを変更できない現象に遭遇しました。手探りでの対処で苦戦しましたので、同じことを繰り返さないためにも投稿に残したいと思います。

##現象が発生した元のコード

```ruby:app/controllers/users_controller.rb
  def update
    @user = User.find_by(id: params[:id])
    @user.name = params[:name]
    @user.user_id = params[:user_id]
    @user.email = params[:email]
    if params[:image]
      @user.image_name = "#{@user.id}.jpg"
      image = params[:image]
      File.binwrite("public/user_images/#{@user.image_name}", image.read)
    end
    if params[:password] != nil
      @user.password = params[:password]
    end
    if @user.save
      flash[:notice] = "ユーザー情報を編集しました"
      redirect_to("/users/#{@user.user_id}")
    else
      render("users/#{@user.user_id}/edit")
    end
  end
```

このコードでローカルではうまくいっていたのですが、サーバーへデプロイ後はユーザー画像のみ保存されて、MySQLのデータは更新されませんでした。

##試したこと
エラーが吐き出されていないか確認しましたが、log/production.logにはエラーらしきものはなく、mysql.logを確認しようとしましたがどこにあるのかわからず、できませんでした。

このためはじめはrails consoleで状況を確認しようとしましたが、RDSのデータベースには接続されていないのか、users = User.allでユーザー情報を取得しようとしても、users.count = 0の状態でした。

そこで直接MySQLへログインして、テーブルのデータをSQLで更新してみたところ、こちらはできましたので、MySQLを使用して更新する方法を取ることにしました。

##現象が改善した後のコード

```ruby:app/controllers/users_controller.rb
  def update
    id = @current_user.id
    updated = 0
    update_name_sql = "update users set name = '#{params[:name]}' where id =#{id};"
    updated = ActiveRecord::Base.connection.execute(update_name_sql)
    update_email_sql = "update users set email = '#{params[:email]}' where id =#{id};"
    updated = ActiveRecord::Base.connection.execute(update_email_sql)
    if params[:image]
      update_image_name_sql = "update users set image_name = '#{id}.jpg' where id =#{id};"
      updated = ActiveRecord::Base.connection.execute(update_image_name_sql)
      image = params[:image]
      File.binwrite("public/user_images/#{id}.jpg", image.read)
    end
    if params[:password]
hashed_password = BCrypt::Password.create(params[:password])
      update_password_sql = "update users set encrypted_password = '#{hashed_password}' where id =#{@current_user.id};"
      ActiveRecord::Base.connection.execute(update_password_sql)
    end
    if updated =! nil
      flash[:notice] = "ユーザー情報を編集しました"
      redirect_to("/users/#{@user.id}")
    else
      flash[:notice] = "データベースへの保存に失敗しました"
      render("users/edit")
    end
  end
```

SQLを直に作成して、ActiveRecord::Base.connection.execute(SQL)でMySQLのデータベースを直接更新する方法へ変えました。
(パスワードに関してもトラブルがありましたので、直接暗号化してから保存するコードに書き換えました)

##まとめ
プログラミング学習サイトの良いところは、手軽に言語の学習に手をつけられるところですね。しかし現実には実用レベルに達するためにいくつもの壁を越えなければいけないものなのだと実感しています。ローカルでは動いていたけれど、サーバー環境ではうまくいかないことが普通にあるのだとわかりました。これに懲りずにポートフォリオ作りに励もうと思います！
Laravel8でログファイルにデバッグする

Laravel8でログファイルにデバッグする方法をサクッと解説します。

ajax通信とかで処理する時は、便利ですよねーってやつなので、ぜひ知っておきましょう。

##envファイルの書き換え

下記のように編集しておく

```.env
LOG_CHANNEL=single
LOG_LEVEL=debug
```

##ログファイルにデバッグする

```
use Illuminate\Support\Facades\Log;

//省略

public function test(){
    Log::debug('test');
}
```

これで`/storage/logs/laravel.log`に出力されてるはず。

おしまい。簡単。
CRL（証明書失効リスト）ってなに？

応用情報技術者試験の過去問でCRLについての問題があったので、簡単にメモします。

##CRLとは
CRL（Certificate Revocation List）は日本語では**証明書失効リスト**といいます。
CRLとは有効期限内であるにもかかわらず、秘密鍵の漏洩、紛失、証明書の被発行者の規則違反などの理由により失効したディジタル証明書が列挙されたリストのことです。認証局、検証局が管理しています。

##登録されている情報
CRLには失効した証明書の**シリアル番号**と**失効日時**が登録されています。



##有効期限について
CRLに登録されている証明書は有効期限の満了時点でCRLから抹消されます。
有効期限を過ぎたディジタル証明書は無効とみなされ使用できたないため、その情報を公表しなくても問題ないからです。
SQLのGRANT文

応用情報技術者試験の過去問で、SQLのGRANT文を初めて知ったので、簡単にメモしておきます。

##GRANT文の役割
**GRANT文**は、1人または複数のユーザにオブジェクト（テーブル、ビュー、シーケンス）に関する特定の権限を付与するSQL文です。例えばテーブルに対し，表への問合せ，更新，追加，削除などの操作権限を付与します。

##使い方
```sql
GRANT 権限名 ON オブジェクト名
　　　　TO ユーザ
　　　　[ WITH GRANT OPTION ] ;
```

**権限名**は以下から指定します。
・SELECT：参照
・INSERT：行の追加
・DELETE：行の削除
・UPDATE：値の変更
・UPDATE（列名）：特定列の値の更新
・ALL PRIVILEGES：上記全て
※カンマ区切りで複数選択可

**オブジェクト**は、テーブル名、ビュー名を指定します。

**ユーザ**は該当権限を与えるユーザを指定します。
ユーザー名、ロール名、PUBLIC（すべてのユーザ）を指定できます。

該当権限自体を別のユーザに与える権限も合わせて付与する場合は、
WITH GRANT OPTIONを指定します。
※省略可


##アクセス権限を取り消す場合
ちなみにアクセス権限を取り消すには、**REVOKE文**を使用します。

```sql

REVOKE 権限名 ON オブジェクト名
　　　　FROM ユーザ
```
React+springbootお試し実装参考サイトリンク

react 環境構築
https://qiita.com/rspmharada7645/items/25c496aee87973bcc7a5

springboot お試しAPI
https://qiita.com/Haru_3/items/319b626afcfe8131ad43

reactで画面から呼び出し
https://qiita.com/Haru_3/items/d1644226682dfbc3a9a3
【unity】VRでマルチゲームを作るためのネットワークエンジンの特徴比較

#はじめに
VRでマルチゲームを作ろうとしているのですが、それぞれのネットワークエンジンの特徴がわからなかったのでまとめてみました。

#1.photon
![ダウンロード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474440/4b2b10af-6ba2-d605-6ce9-21c20ff0c6a0.png)
[公式サイト](https://www.photonengine.com/ja-JP/Photon)

###メリット
- 英語日本語とも情報量が多い
- 20CCU,転送量60GBと他ネットワークエンジンと比べて多い

###デメリット
- 1秒間に500メッセージの制限がある



#2.モノビットエンジン
![ダウンロード (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474440/305cf2b0-3fda-e12f-9e87-858ae2d5f752.png)
[公式サイト](https://www.monobitengine.com/)

###メリット
-　国産ネットワークエンジンだから公式開発者コミュニティが日本語
-　公式の対応が早い
-　メッセージの制限がない(重要)
-　VRボイスチャット機能がある

###デメリット
- photonと比べると情報量が少ない
- まだ海外へ対応はされていない？



#3.strix
![ダウンロード.jfif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474440/c5c4dc46-f52a-ca05-4433-7145e12e95e4.jpeg)

###メリット
- prehabを置くだけでログインができるなど実装が簡単

###デメリット
- 情報量が圧倒的に少ない
- ルーム機能はない
- 一般的なネットワークエンジンとは仕様がかなり異なる

#まとめ
一般的なマルチゲームが作りたい！
→ **ネットの情報量の多いphotonがおすすめ**

VRゲームや物理演算を頻繁に行うゲームを作りたい！
→ **メッセージの制限がなく、VRボイスチャット機能があるモノビットエンジンがおすすめ**

単純なマルチゲームを手早く実装したい!
→ **学習コストの低いstrixがおすすめ**

#最後に
自分はVRマルチゲームをつくりたいので**モノビットエンジン**を使ってみます！

**ひびきんぐ**([@hibiking3456789](https://twitter.com/hibiking3456789))といいます!
仕事と趣味の両方でXR三昧。最近はVRマルチゲーム作ってます。
XR開発のことを発信しているのでよければフォローしてください！
###プチ宣伝

私たち[DENDOH Inc.](https://dendoh.co.jp/)ではARを用いた購買体験や、3Dクリエイター向けのサービスを開発しています。
一緒に働きたい方、学生でインターンしたい方をエンジニアに限らず募集しています！
興味のある方は[ひびきんぐ](https://twitter.com/hibiking3456789)のDMまでお声掛けください！

#参考にしたサイト
- [VR/ARで使いたいUnity対応マルチプレイゲーム用BaaSを比較する](https://medium.com/kadinche-engineering/unity%E5%AF%BE%E5%BF%9C%E3%83%9E%E3%83%AB%E3%83%81%E3%83%97%E3%83%AC%E3%82%A4%E7%94%A8baas-1c5d1861c335)
- [PhotonCloudPun2 vs MonobitEngine vs StrixCloud](https://junyablog.site/photoncloudpun2-vs-monobitengine-vs-strixcloud/)
- [Unityでオンラインゲームを作れるPhotonのすすめ](https://aizu-vr.hatenablog.com/entry/2020/06/28/Unity%E3%81%A7%E3%82%AA%E3%83%B3%E3%83%A9%E3%82%A4%E3%83%B3%E3%82%B2%E3%83%BC%E3%83%A0%E3%82%92%E4%BD%9C%E3%82%8C%E3%82%8BPhoton%E3%81%AE%E3%81%99%E3%81%99%E3%82%81-)
【Python】jinja2を使ってtemplateを読み込みたい

### はじめに
<バージョン>
python: 3.7.9

　以下のような、jinja2テンプレートとymlを組み合わせるにはどうすればいいでしょうか？
[参考記事(1つ目)](https://blog.monophile.net/posts/20171127_yaml_jinja2.html)のように、ymlを引数としてpythonに渡すコードは見つかったのですが、
pythonコードの中で完結しているものがなかったので作ってみました。

```jinja:test.j2
var1: {{ var1 }}
var2: {{ var2 }}
```

```yaml:test.yml
---
var1: test1
var2: test2
```

### 1. サンプルコード
　コードにあるように「with open」を使えば、ymlを引数としてpythonに渡す必要が
無くなるようです。

```python:template.py
#!/usr/bin/env python3
# coding: utf-8
import sys, yaml, jinja2

# define variable
base_dir = '/home/ec2-user/test'
j2_dir   = base_dir + '/j2'
yml_dir  = base_dir + '/yml'

# import j2 template
_loader      = jinja2.FileSystemLoader(j2_dir, encoding='utf-8')
_environment = jinja2.Environment(loader=_loader)
_template    = _environment.get_template("test.j2")

# import yaml and render
with open(yml_dir + '/' + 'test.yml') as import_yml:
  sys.stdout.write(_template.render(yaml.load(import_yml)))
```

### 2. ディレクトリ構成
　ファイルは以下の構成にしてください。

```text
.
├── template.py
├── j2
│   └── test.j2
└── yml
    └── test.yml
```

### 3. 実行結果
　想定通り、jinja2を使ってymlとtemplateを組み合わせることが出来ました。

```text:出力
[ec2-user@ip-<ip-addr> test]$ python template.py
var1: test1
var2: test2
```

### 参考資料
[PythonでYAMLを読み込んでJinja2で整形する](https://blog.monophile.net/posts/20171127_yaml_jinja2.html)
[【PyYAML VS ruamel.yaml】PythonからYAMLファイルを触ってみた](https://dev.classmethod.jp/articles/getting-started-with-pyyaml-and-ruamel-yaml/)
Vue.jsコンポーネントの記述順序(options order)の表

[本家スタイルガイド - コンポーネント/インスタンス オプション順序](https://jp.vuejs.org/v2/style-guide/index.html#%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88-%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9-%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3%E9%A0%86%E5%BA%8F-%E6%8E%A8%E5%A5%A8)の転記。スクロールしないで読めるように。

分類 | オプション
--- | ---
1. 副作用 | el
2. グローバルな認識 | **name**, parent
3. コンポーネントの種類 | functional
4. テンプレートの修飾子 | delimiters, comments
5. テンプレートの依存関係 | **components**, directives, filters
6. 合成 | extends, mixins
7. インタフェース | inheritAttrs, model, props/propsData
8. ローカルの状態 | **data**, **computed**
9. イベント | watch<br>beforeCreate, created, beforeMount, mounted, beforeUpdate, updated, activated, deactivated, beforeDestroy, destroyed
10. リアクティブではないプロパティ | **methods**
11. レンダリング | template/render, renderError

※何となくよく探しそうなやつは太字で
テレワーク中　プロジェクトを成功させる為にやったこと

# はじめに
今のプロジェクトは大体こんな感じで、非対面からPJがスタートしました。   

- 4人での小規模システム開発PJ（PJ中メンバーと直接会う事は0）
- ほぼ新規開発
- ウォーターフォール型
- 約半年間の期間

# やったこと
テレワーク推奨の今、非対面プロジェクトで色々試してわかったこと。


## チケット管理
非対面での円滑なPJの進み方はチケット管理がとても重要です。
チケット管理は何で管理するかよりも、どう使うかが重要だと思います。 ※私のPJではかんばん方式なシンプルなチケット管理ツールを採用しました。
※余計に手間がかかる事や使いにくいといった場合はチケット管理ツールを変更する対応も検討してみましょう。

チケットのかんばんステータスは以下で実施しました。
`[申し送り] [課題] [未実施] [作業中] [REV] [保留] [完了]`

その他以下のラベリングもしていました。
`[要件定義] [設計] [製造] [試験]`

##### チケットの明確なゴールを設定   
調査するチケットなのか、実施するチケットなのか。明確でないチケットはずっと溜まってしまいクローズする事が難しくなる。 また期限設定も重要

##### チケットに担当者を設定
担当者のいないチケットは対応・クローズされずに残ってしまう。
しっかりと担当者を決めましょう。

##### チケット運用フローを設定
私のPJの場合以下のようなフローを取っていました。
起票：メンバー
未実施→実施中：メンバーor管理
作業中→REV：実施者
REV→作業中：管理者
REV→完了：管理者
※デイリーでチケット移動する事も多かった気もします。

##### チケットマスターを決める
チケット棚卸をする人を決めましょう。
チケットマスターは週に一回は棚卸を実施してチケットを整理しましょう。（PJリーダーなど全体のチケットを管理できる人が最適）

##### チケットは起票は気軽に  
課題・調査・修正等気づいた件はすべてチケットに起票しましょう。
チケット化しないと、それについての議論をする機会が無くなってしまう。
`「No Ticket, No Work」`


## デイリーミーティング　
私のPJでは毎日朝一で実施していました。
デイリーでは作業中からREVと課題の順でチケットを見ながら進めていき
・担当のチケットでは（作業中の場合）
　やったこと、やること、課題、進捗はどうか、困っていることを簡潔に言う方式でミーティングをしていました。

##### デイリーの時間は決めない
当初は30分程と時間を定めてやっていたが、テレワークの最大の問題はコミュニケーション不足でした、
デイリー以外で話す場が無いため、デイリーの時間を多めに取りコミュニケーションの障壁を無くす事が重要だと感じました。
※ただ基本は30分程度で終わる事が多かったです
※実際長くやる必要はありませんが、最低でも1時間の時間は各自確保しておく事


##### 個別で話す内容と全員に話す内容は分ける
無駄な時間を作らないため
「デイリー後に会話しましょう」が大事でした。

##### できれば朝一で実施
朝やることにより、その日のスケジュールが整えやすい。※詰まっていて、誰かにフォローして欲しい場合など、「デイリーの後で」や「午後から」なんて感じで早く解決できる。

##### 進行役を交代制にした
デイリーの進行役を全員が持ち回りで進行する工夫をした。
そのおかげで、メンバー全員が周りを見れる事ができるようになり、PJの円滑性が増したと感じました。


## レビュー
##### 細かい単位で行う
コミュニケーション不足な感じがあり、2度手間が多く発生していた。
チャットで処理構想を決めてもらってからコーディングするなど、段階的に認証プロセスを踏んで2度手間を防ぐようにした。
[開発の場合]
旧：　実装 → レビュー
新：　処理構想 → レビュー① → 実装 → レビュー②


##### デイリーの空いた時間を有効活用（仮レビュー）
デイリーが早く終わった場合は、レビューの指摘を下げるような勉強会としてチームの生産性を上げる場として有効活用した。
・処理構想を一緒に考えたり
・ソースを見ながらリファクタリングをしたり
・ソース全体を見ながら修正したい所などを話しあったり


## 振り返りをする ←最も重要
良かった点・悪かった点（改善点）を話し合う。※KPT法などと呼ばれていたりもする
実施ペースは月1ペースが望ましい。

振り返りをすることにより、メンバー全員がPJを良くしていこうといった動きが広まりとても重要な場だと感じました。

## その他
- 使いにくいチャットツールを変えた  
　ビデオ会議ツールでのチャットコミュニケーションの形成は無理でした。。
- チャットツールのチャンネルを用途毎に作成   
　　作業用・勤怠用・git用・大事なメモ用など各ジャンル毎のチャンネルを作成
- 静的検証ツールでのバグを減らした（ESLint）
- ソース管理でのチームの開発効率を上げた（git）
画像を投稿するときに、undefined method `images' for nil:NilClassになってしまう問題を解決する

今回、Active Storageを使って、画像を投稿する機能を作りました。
しかし、投稿自体はあるものの、投稿から投稿一覧に遷移するときに、タイトルのエラーになってしまうという問題にぶち当たりました。

結論から言うと、viewの引数の指定が間違っていたためです。なので、そこを修正してあげることで解決しました

以下、投稿一覧ページの、がぞうを表示する部分です

```
   <% if @post.images.attached? %>
         <div class = 'images'>
         <% @post.images.each do |image| %>
         <%= image_tag post.images %>
         </div>
         <% end %>
         <% end %>
```

こちらを間違えてしまってしました。

それを、こういった形に修正しました。

```
<% if post.images.attached? %>
    <div class = 'images'>
    <% post.images.each do |image| %>
    <%= image_tag image %>
    </div>
    <% end %>
    <% end %>
```

このように、インスタンス変数を指定していいたのですが、それらを取っ払い、`image_tag`の部分の`images`を、`image`に変えました。

#参考記事
https://teratail.com/questions/325045#reply-452097
Github に草を生やす

原則：フォークされたリポジトリではなく、独立したリポジトリでのイシューやプルリクエストであること。

コミットがコントリビューションとしてカウントされるには以下の全ての条件が満たされる必要がある。
①コミットに使用されるメールアドレスがGitHubアカウントと連携されていること
②フォークされたリポジトリではなく、独立したリポジトリでコミットされること
③デフォルトブランチもしくはProject Pages sitesでのコミットであること





自分はずっとmasterブランチで更新していたので草が生えてなかった。
ハッシュについての基礎知識

#hashについて
シンボルを使ったキーの記述方法は、キーの後にコロン:をつけて定義する

```
hash = { キー: 値}
```
ハッシュをシンボルで記述すると、コード上では文字列のように見えるが、内部的には数値として処理される。数値として扱われるので、処理速度が速くなることと文字列としての役割も果たします。よって、ハッシュのキーにはシンボルを用いることが多い。

ハッシュのキーを取得するにはkeysメソッド、値を取得するにはvaluesメソッドを使用し取得する。

オブジェクト.keysで、ハッシュに含まれるキーを取得する。

```
hash = { one: 1, two: 2, three: 3 }

puts hash.keys
one
two
three
```
オブジェクト.valuesで、ハッシュに含まれる値を取得する。

```
hash = { one: 1, two: 2, three: 3 }

puts hash.values
1
2
3
```
文字列から数値に変えてフォーマットする

数値を文字列にするパターンはあったのに、文字列から数値に変えてフォーマットするパターンがなかったので作成します。


   let a = Int(文字列の変数名etc)
   String(format: "%05d", _a))

やることは2つ

文字列をInt型に変換
Intでフォーマット

できないって場合

型を調べてください。
オプショナル型ならif letのなかでやるとうまくいくと思います。

   let a = Int(文字列の変数名etc)
    if let _a = a{
        String(format: "%05d", _a))
    }
MAMPでローカルにhttps通信する方法【メモ】

メモっときます。

```
brew install openssl
```

```
cd /Applications/MAMP/conf/apache/
```

```
mkdir tls
```

```
cd tls
```

```
openssl genrsa -out server.key 2048
```

```
openssl req -new -key server.key -out server.csr
```

returnキー押しまくって、下記のところだけ変更する。

```
Common Name (eg, fully qualified host name) []:localhost
```

```
openssl x509 -req -days 365 -signkey server.key -in server.csr -out server.crt
```

```
rm server.csr
```

```
vim /Applications/MAMP/conf/apache/httpd.conf
```

開いたファイルの下記のコメントアウトをはずす。（下の方にある）

```
# Secure (SSL/TLS) connections
↓ここ
Include /Applications/MAMP/conf/apache/extra/httpd-ssl.conf
```

```
vim /Applications/MAMP/conf/apache/extra/httpd-ssl.conf
```
下記の4箇所を下記のように変更
```
DocumentRoot "/Applications/MAMP/htdocs"
ServerName localhost

SSLCertificateFile "/Applications/MAMP/conf/apache/tls/server.crt"

SSLCertificateFile "/Applications/MAMP/conf/apache/tls/server.crt"
```

ファイルに問題ないか確認。

```
/Applications/MAMP/Library/bin/apachectl configtest
```

下記のように出ればOK。

```
Syntax OK
```

下記のようなエラーが出ることもある。

```
Invalid command 'SSLMutex', perhaps misspelled or defined by a module not included in the server configuration
```
そのときは'/Applications/MAMP/conf/apache/extra/httpd-ssl.conf:'の97行目を下記のように変更。

```
Mutex default
```

##参考記事
・https://webgroove.work/mamp-local-openssl-tls-csr/
・https://yuki.world/mamp-invalid-sslmutex/
アニメーション

アニメーションをまとめます。

##チェックボックス

###チェックマークがいい感じにつく

![ezgif.com-gif-maker.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560864/1d85f595-0953-6a6d-bb87-8112a7e51b1a.gif)


```html
<input type="radio" name="test" id="test1">
<label for="test1">チェックボックス</label>
```

```css
input[type="radio"] {
    display: none;
}

input[type="radio"]+label {
    display: block;
    position: relative;
    padding-left: 25px;
    margin-bottom: 0px;
    cursor: pointer;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
}

input[type="radio"]+label:last-child {
    margin-bottom: 0;
}

input[type="radio"]+label:before {
    content: '';
    display: block;
    width: 15px;
    height: 15px;
    border: 1px solid #6cc0e5;
    position: absolute;
    left: 0;
    top: 3px;
    opacity: .8;
    -webkit-transition: all .12s, border-color .08s;
    transition: all .12s, border-color .08s;
}

input[type="radio"]:checked+label:before {
    width: 10px;
    top: -1px;
    left: 5px;
    border-radius: 0;
    opacity: 1;
    border-top-color: transparent;
    border-left-color: transparent;
    -webkit-transform: rotate(45deg);
    transform: rotate(45deg);
}

```

##ツールチップ

```html:text.blade.php
<button type="button" class="btn--circle btn--circle-c btn--shadow tooltip1 bookshelf_store_js" data-id="{{ $novel->id }}">
    <i class="fas fa-book-medical"></i>
    <div class="tooltip_content">本棚に追加</div>
</button>
```

```sass:text.scss
//ツールチップ
.tooltip1 {
    position: relative;
    cursor: pointer;
    display: inline-block;

    i {
        margin: 0;
        padding: 0;
    }

    & .tooltip_content {
        display: none;
        position: absolute;
        margin: 1.5em 0;
        padding: 7px 10px;
        min-width: 120px;
        max-width: 100%;
        color: #555;
        font-size: 0.9rem;
        background: #FFF;
        border: solid 2px $border_color;
        box-sizing: border-box;
        box-shadow: 1px 1px 5px $border_color;
        z-index: 2;

        &:before {
            content: "";
            position: absolute;
            top: -24px;
            left: 50%;
            margin-left: -15px;
            border: 12px solid transparent;
            border-bottom: 12px solid #FFF;
            z-index: 2;
        }

        &:after {
            content: "";
            position: absolute;
            top: -30px;
            left: 50%;
            margin-left: -17px;
            border: 14px solid transparent;
            border-bottom: 14px solid $border_color;
            z-index: 1;
        }
    }

    &:hover .tooltip_content {
        display: inline-block;
        top: 35px;
        left: -40px;
    }

}
```
Map box　アカウント解除方法

MAP boxをどんなもんか触ってみたいと思い会員登録してみたものの、
あんまり使い方もわからず必要になるときもあまりないだろうと思い、アカウントの削除したので、削除の場所を記載します。

<strong>MAPBOX　URL</strong>
https://www.mapbox.jp/

<strong>MAPBOXとは</strong>
Mapboxとは、アメリカ合衆国で2010年に設立した地図プラットフォーム提供会社です。設立以来、カスタムマップの分野で急速に拡大を続けています。2019年7月に日本市場に参入し、Yahoo!地図などに採用されています。2020年3月には、ソフトバンクと合同で日本での拠点、「Mapbox Japan JV」を設立しました。今後は日本でのサービス普及に力を入れていくと考えられています。
(引用:https://biz.kkc.co.jp/mapbox_blogdetail/2020071401/)


<strong>MAPBOX　アカウント削除の場所</strong>

![2021-03-04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939082/6eb44ba3-01c0-8c40-1ded-daf07103b66f.jpeg)
１）右上ナビの　「設定」

![2021-03-04-2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939082/d14ae664-5b0c-7e57-32da-e2ee64c02b50.jpeg)
2)左メニューのプロフィール　→　「アカウントを削除する」　ボタンをクリック

![2021-03-04-3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939082/cd4137b0-e6a8-244a-d0ba-e8526e037f1d.jpeg)

アカウントを削除するウィンドウが出てくるので　「はい、アカウントを削除します」　をクリック
するとログイン画面に変わります。　こちらでアカウント削除が完了します。

また登録したメールに削除しましたのメールも来ます。


<strong>設定とアカウントアクセス　のガイドはこちら</strong>
https://docs.mapbox.com/accounts/guides/settings/

散々探したけど、意外とわかりやすい場所にありました（^^;）問い合わせまでしたのに。
ほったらかしてもよかったんですが、最近は使わないものは整理しよう！を心がけているので必要になったらまた登録しようかな。
会員登録しただけのものって無数にあるから管理しきれなくなってるので怖いです。
海外サイトなので翻訳機能が向上しているとはいえ英語できない民にはハードルたかいです。
Azure 記事のポータル

# 投稿記事のポータル
私が寄稿したAzure記事のポータルです

## IaaS(仮想マシン・NW関連）
【VM】
・[【VM002】Azure 仮想マシンを設計する（ディスク編）](https://qiita.com/clam_chowdeeer/items/6858d466af5597e4166b)
・[【VM003】Azureを仮想マシン設計をする（ネットワーク編）](https://qiita.com/clam_chowdeeer/items/1d591e17de425178472b)

【NW】
・[【NW001】仮想ネットワーク（VNETのみ）を設計する](https://qiita.com/clam_chowdeeer/items/cdca77fc78b852cf901d)
・[【NW003】Azure ロードバランサを設計する]
(https://qiita.com/clam_chowdeeer/items/b98a7e8d95e7d3b5d70e)

## トラブルシューティング関連
・[【QA・障害001】Azure Portalで表示名が文字化け（チェコ語）](https://qiita.com/clam_chowdeeer/items/f9087a4cbcfbed47d496)
・[【QA・障害002】リソースグループ単位でのリソース削除ができない(Delete Vault)](https://qiita.com/clam_chowdeeer/items/9433088a0fdd74fc8a5a)

## その他
・[Azureの障害情報の照会ができるサイト]
(https://qiita.com/clam_chowdeeer/items/eb006bdd3f9faf0839eb)
・[Azure 管理グループ、サブスクリプションを設計する](https://qiita.com/clam_chowdeeer/items/2fae87e59f0eb65f6afa)
・[Azure リソースグループを設計する](https://qiita.com/clam_chowdeeer/items/29dd4ee108de1938d1e6)
・[AWSとAzureの差異について](https://qiita.com/clam_chowdeeer/items/43a48458a4c37b76b31e)
・[Azure SSHキーを設計する](https://qiita.com/clam_chowdeeer/items/70d1176f79ff15680b3a)
・[Azure 命名規則を設計する]
(https://qiita.com/clam_chowdeeer/items/7da2ae77bc0cf5f255dd)
Android API29未満で getRawX(index)をする(回転、拡大、縮小に対応)

## getX()とgetRawX()

MotionEventにはgetX()とgetRawX()という異なるメソッドがあります。
(もちろん同様にy座標に関するメソッドもあります)

この２つのメソッドの違いは、getX()はEventの対象となるViewのローカル座標、getRawX()はスクリーン上の座標を取得するという点になります。

## getRawX()とgetRawX(index)

API29からgetRaw(index)というメソッドが追加されました。
MotionEventではタッチされている座標(pointer)が複数ある場合があり、indexを指定することでpointerごとの座標を取得することができます。

しかし、getRawX(index)はAPI29から追加されたメソッドのため、API29未満では自分で計算を行うことになります。
API29未満にもgetX(index)というメソッドがあります、これは指定したindexのpointerのローカル座標を取得するメソッドです。このメソッドを利用して計算をします。

## ローカル座標からスクリーン座標への変換

具体的なコードは以下になります。
Viewが回転、拡大、縮小していた場合にも正しい座標が取得できるようになっています。
回転、拡大、縮小が不要な場合には該当のコードを削除してください。

``` kotlin
private fun getRawPoint(view: View, event: MotionEvent, index: Int): PointF {
    val location = intArrayOf(0, 0)
    view.getLocationOnScreen(location)
    var x = event.getX(index) * view.scaleX
    var y = event.getY(index) * view.scaleY
    var angle = Math.toDegrees(atan2(y.toDouble(), x.toDouble()))
    angle += view.rotation.toDouble()
    val length = hypot(x, y)
    x = (length * cos(Math.toRadians(angle))).toFloat() + location[0]
    y = (length * sin(Math.toRadians(angle))).toFloat() + location[1]
    return PointF(x, y)
}
```

scaleが変更されていた場合を考慮し、x, yの値にscaleをかけています。
また、回転していた場合を考慮し、アークタンジェントを求めるatan2(y, x)を利用して座標から角度を求めrotationと合計しています。
解説のため下図を用意しました。
rotationでαの角度、atan2(y, x)でβの角度を求めています。
lengthが三角関数の斜辺となりα + βが三角関数のθとなるのであとはsin、cosで座標が求められますね。

![スクリーンショット 2021-03-08 10.35.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40873/a96b303a-8c1f-6431-edae-4c96be49dff3.png)

API29未満でMotionEventからスクリーン座標を取得したいときにお使いください。
REST編　3

# RESTとハイパーメディア

Webはリンクをたどりながら様々なリソースへとアクセスしていきます。
この特徴のことをRESTでは「**アプリケーション状態エンジンとしてのハイパーメディア**」と呼びます。

アプリケーション状態とは、例えばソーシャルブックマークアプリケーションの利用者が持つ状態のことで、「ブックマーク一覧を表示している」「ブックマークに追加しようとしている」などが状態の具体例だ。
つまり、**アプリケーション状態はリンクをたどることで遷移するもの**だ。

このように**リソースをリンクで接続することで一つのアプリケーションを構成する**という考え方は、
「接続性(Connectedness)」という。
# RESTと分散システム
RPCなどの分散オブジェクトでは関数をメソッド単位でサーバ側の処理を呼び出すので、呼び出し回数がものすごい量になり、システム全体の性能劣化を引き起こす。
その一方で
RESTに基づいたWebサービスはリンクをたどることでアプリケーションを実現します。
RESTに基づいたWebサービスで扱われるリソースは、RPCの関数でやりとりされるデータよりも粒度は大きいため、性能劣化を抑えることができる。

この性能劣化の問題だけではなく、分散オブジェクトはサーバごとに別々のインターフェースを持ち、個々のインターフェースはプログラムライブラリのインターフェースをベースに開発することが多いという問題がある。これは、機能追加してバージョンアップするたびにメソッドが増えたりメソッドの引数や戻り値が変わったりしてAPIの互換性がなくなってしまう。既存クライアントをすべて同時に更新しなくてはならない。Webのような大規模システムでは非現実的といえる。

その一方で、RESTではHTTPをインターフェースとして固定することでそのような互換性の問題は発生しない。
windows起動時にWSLのssh serverを起動する

# Table of Contents 
- windowsに入っているWSL OS listの確認
- デフォルトのwslのOSを指定する。
- port fowardするshファイルを作成
- sshを起動するshファイルの作成
- ssh起動するbatファイルを作る
- タスクスケジューラにsshを起動するタスクを作成

## windowsに入っているWSL OS listの確認
wslconfig.exeを使ってOS listを作成

```
> wslconfig.exe /list
Linux 用 Windows サブシステム ディストリビューション:
Ubuntu-20.04 (既定)
docker-desktop-data
docker-desktop
```

## デフォルトのWSLのOSを指定する。
上記方法で確認したOS listからwindows側からいじりたいOSを設定する。

```
> wslconfig.exe /setdefault Ubuntu-20.04
```

## port fowardするshファイルを作成
`/opt/port-foward.sh`に以下のコードを書いたものを作る

```/opt/port-foward.sh
#!/bin/bash
IP=$(ifconfig eth0 | grep 'inet ' | awk '{print $2}')
netsh.exe interface portproxy delete v4tov4 listenport=22
netsh.exe interface portproxy add    v4tov4 listenport=22 connectaddress=$IP
```

## ssh起動するbatファイルを作る
`/opt/start_ssh.sh`にsshを起動するコードを作る
自分の環境だと最初に`/run/sshd`を作成しないとsshdが起動できなかったので作成している。

```/opt/start_ssh.sh
#!/bin/bash
mkdir /run/sshd
/usr/sbin/sshd
```

## ssh起動するbatファイルを作る
任意の場所にbatファイルを作成する。

```wsl_ssh_start.bat
wsl -u root --exec /bin/bash /opt/port-foward.sh
wsl -u root --exec /bin/bash /opt/start_ssh.sh
```

## タスクスケジューラにsshを起動するタスクを作成
以下の記事が詳しく画像付きで解説しているので引用させていただきます。
https://qiita.com/gengen16k/items/18262af0781fd32fc9cd#%E3%82%BF%E3%82%B9%E3%82%AF%E3%82%B9%E3%82%B1%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%A9%E3%81%AE%E8%A8%AD%E5%AE%9A
Google Driveで共有設定が適切に設定されているかドライブのファイル・フォルダを一覧で調べる方法

# Google Driveで共有設定が適切に設定されているかドライブのファイル・フォルダを一覧で調べる方法

30分くらいで作ったやつを貼っておく。
かんたんなスクリプトなのでもっと良さそうな改良版あればコメント欄なり、自分で記事お願いします！

「2021年１月６日、福岡県の新型コロナウイルス感染症陽性者に関する個人情報の漏えい」がありましたが、この漏洩事案がGoogle Driveによるものだとは存じ上げないのですが、SaaSのドライブを利用するユーザーが増えてくると（絶対数が増える）と、共有設定を間違えるニュースが増えてくると思います。

なのでDriveのファイルとフォルダが適切に共有設定されているか確認しましょう、ってお話。

## データ



```js
const results = [];

function doGet() {
  writeInforInFolder(DriveApp.getRootFolder());
  const text = results.join("\n");
  Logger.log(text);

  // Webアプリとして導入するならこんな感じ？
  // return HtmlService.createHtmlOutput(text);
}

function writeInforInFolder(folder) {
  if(!folder) return;
  
  // フォルダ以下ファイルをすべて取得
  const files = folder.getFiles();
  while(files.hasNext()) {
    const file = files.next();
    results.push(`FILE,${file.getName()},${file.getSharingAccess()},${file.getUrl()}`)
  }

  // フォルダ配下のフォルダを取得
  const folders = folder.getFolders();
  if (!folders) return;
  while(folders.hasNext()) {
    const folder = folders.next();
    results.push(`FOLDER,${folder.getName()},${folder.getSharingAccess()},${folder.getUrl()}`)
    // 更に下のフォルダを検索するため再帰処理
    this.writeInforInFolder(folder)
  }
}
```

- 権限を取得とかもろもろの許可が必要


CSV形式のテキストで出力されるので、3列目がANYONEとかANYONE_WITH_LINKになっているのは確認したほうがいいと思います。

```csvs
// 出力例
// 長すぎるとエラーでるので、
// return HtmlService.createHtmlOutput(text);のとこコメントアウト外してWebで見たほうがいいかも
Logging output too large. Truncating output. 

// folderとfile,名前,url
FOLDER,test,PRIVATE,https://script.google.com/d/sample
FILE,無題のプロジェクト,PRIVATE,https://script.google.com/d/1i
```

権限は以下を確認してください。
https://developers.google.com/apps-script/reference/drive/access

- ANYONE (誰でも見れる)
- ANYONE_WITH_LINK(リンク知っている人全員)
- DOMAIN (自社のGsuiteワークスペースの人のみ)
- DOMAIN_WITH_LINK(自社のワークスペースの人でリンク知っている人のみ)
- PRIVATE (自分のみ)


基本的に機密情報は、ANYONE,ANYONE_WITH_LINKだと合うと、特に気密性高い情報はDOMAINもDOMAIN_WITH_LINKもだめかも。
気密性の高いファイルは、PRIVATEにして、必要な人だけ個別で追加していくスタイルがよいかと。
TerraformでAWS 大阪リージョンを使う設定

## 現状

これを書いている2021年3月8日現在、本家からは大阪リージョンに対応したAWSプロバイダーがリリースされています。
[aws-provider no support for ap-northeast-3 region that became generally available on 1/03/21 #17882](https://github.com/hashicorp/terraform-provider-aws/issues/17882)

```
This has been released in version 3.31.0 of the Terraform AWS provider. 
Please see the Terraform documentation on provider versioning or reach out if you need any assistance upgrading.
For further feature requests or bug reports with this functionality, please create a new GitHub issue following the template for triage. Thanks!

（これは、TerraformAWSプロバイダーのバージョン3.31.0でリリースされています。
プロバイダーのバージョン管理に関するTerraformのドキュメントを参照するか、アップグレードについてサポートが必要な場合はお問い合わせください。
この機能に関するその他の機能リクエストまたはバグレポートについては、トリアージのテンプレートに従って新しいGitHubの問題を作成してください。
ありがとう！）
```

というわけで、AWSプロバイダーのバージョンを3.31.0以上にアップグレードすればいいです。

## 設定



```terraform
provider "aws" {
  region = "ap-northeast-3"
}

terraform {
  required_providers {
    aws = "3.31.0"
  }
}
```

バックエンドにS3を使用している場合は、S3バックエンドのバリデーションで引っかかるので、 `skip_region_validation = true` が必要になります。

```terraform
provider "aws" {
  region = "ap-northeast-3"
}

terraform {
  backend "s3" {
    bucket = "xxxxxxxxxxxx"
    key = "xxxxxxxxxxx"
    dynamodb_table = "xxxxxxxxxx"
    region = "ap-northeast-3"
    skip_region_validation = true
  }
  required_providers {
    aws = "3.31.0"
  }
}
```

上記内容で設定した後

```
$ terraform init
```

で、使えるようになるはずです。
メモとして書いたけど、そのうち必要なくなる内容ですね。
【VM003】Azureを仮想マシン設計をする（ネットワーク編）

# Azure仮想マシン作成時のNWパラメータについて考慮すべき点はなに？
仮想マシンのNWの設定パートですが、いまいち直感的に判断できないので各パラメータについて確認した内容を説明します。

## ネットワークインタフェース
[仮想ネットワーク]
仮想ネットワークを指定。仮想マシンと同じリソースグループの地域と同じものしか選べない。マジかよ。

[サブネット]
仮想ネットワーク内に存在するサブネットを指定。

[パブリックIP]
なし：パブリックIP無で設定
既存のパブリックIP：すでに作成済みパブリックIPを仮想マシンに割り当て。
新規作成：新たにパブリックIPを作成。新規作成でを選ぶと以下パラメータ入力が必要。SKUはStandardの方が使える機能が多い。Standardだと自動的にPIPが静的IPになる。ルーティングの優先順位は、このIPへの接続が発生した場合になるべくMicrosoftのグローバルNWを使うか、インターネットを使うかの指定。前者のほうがコストがかかった気がする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1111921/8e7bd414-be33-5f87-d2b0-c25698ababcf.png)

[NIC ネットワーク セキュリティ グループ]
どのセキュリティグループに参加させるかの指定。
セキュリティグループは受信や送信の許可拒否を定義しているもの。

[パブリック受信ポート]
インターネット経由で直接該当仮想マシンにアクセスさせたい場合に、どのポートを開放するかの指定。インターネットからAzureへアクセスするときの踏み台サーバとかならRDPやSSHを開放しておいて、インターネットへサービスを展開するサーバならHTTPSとか指定する感じだと思われる。
80,443,22,3389しかないのが謎。

[高速ネットワーク]
NWが早くなる。費用次第だが、MS社サイトは記載みつからない。一般サイト上だと”無料”とあったのでそれが事実なら絶対に有効化させておくべきだと思う。

[負荷分散]
仮想マシンを既存の
アプリケーションゲートウェイ（L7ルーティングするロードバランサ）か
Azure Load balancer（仮想マシン、IPアドレスベース）か
に参加させる際に指定。
PHP 配列で複数の値をpostする方法

#formでpost時配列で値を渡す方法

例）
index.php

```html


<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <form action="eat.php" method="post" >
  <select name="lunch[]" id="" multiple>
  <option value="pork">buta</option>
  <option value="befe">ushi</option>
  <option value="dog">inu</option>
  <option value="chcken">tori</option>
  <option value="snake">hebi</option>
  </select>
  <input type="submit" name='subnit'>
  </form>
</body>
</html>
```

eat.php

```php

<?php 
$a = $_POST['lunch'];
if(isset($_POST['lunch'])){
    foreach($_POST['lunch'] as $choice){
      print "you want $choice .<br/>";
    }
  }

```

結果
![スクリーンショット 2021-03-08 10.52.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/819dbf76-2f1e-3c7f-8b4d-72e37e950b60.png)
3つの値をshiftで選択すると、、

![スクリーンショット 2021-03-08 10.52.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/670884/94cb12fd-e037-e95a-612b-55ee0b94294b.png)


上記の表示がされる。

##ポイント
selectタグのname属性を```name='lunch[]'```と```[]```にしている。
これが無くて```name='lunch'```では複数をshiftで選択してpostしても複数の値を$_POSTで取得できない。
カラムから外部キーを削除する

アプリを作成している中で外部キーを削除する必要が出てきたので今後のためにも記事を残します。

/schema.rb

```
 create_table "behavior_histories", force: :cascade do |t|
    t.bigint "care_recipitent_id"
    t.date "behavior_history_date", null: false
    t.text "action_record", null: false
    t.time "behavior_time", null: false
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.bigint "family_id"
    t.index ["family_id"], name: "index_behavior_histories_on_family_id"
    t.index ["care_recipitent_id"], name: "index_behavior_histories_on_care_recipitent_id"
```

この中の外部キーであるcare_recipitent_idを削除します。


###migrationファイルの作成

```
rails g migration remove_foreign_key_to_behavior_histories
```

###外部キーの削除

```
class RemoveForeignKeyToBehaviorHistories < ActiveRecord::Migration[6.0]
  def change
    remove_foreign_key :behavior_histories, :care_recipitents
    remove_reference :behavior_histories, :care_recipitent, index: true
  end
end
```

rails:db:mirateで削除されていることを無事確認。
※remove_foreign_keyとremove_referenceの順序を変えるとうまくいかないため注意してください。


###外部キーを追加したい場合

```
class AddReferencesToAddresses < ActiveRecord::Migration[6.0]
  def change
    add_reference :addresses, :family, foreign_key: true
  end
end
```


参考：[references型のカラムを後から追加・削除](https://www.y-hakopro.com/entry/2019/11/12/references%E3%81%AE%E3%82%AB%E3%83%A9%E3%83%A0%E3%82%92%E5%BE%8C%E3%81%8B%E3%82%89%E8%BF%BD%E5%8A%A0%E3%83%BB%E5%89%8A%E9%99%A4%E3%80%90Rails%E3%80%91)
REST編２

# クライアント/サーバ（RESTの基本）

webはHTTPというプロトコルでクライアントとサーバが通信するクライアント/サーバのアーキテクチャスタイルを採用しています。下図参照
![we_we_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/978289/41915542-3967-2591-2c75-c5037f60cd17.png)

クライアント/サーバの利点は、単一のコンピュータ上ですべての処理をするのではなく、
**クライアントとサーバの二つに分離して処理すること**

これにより、クライアントを**マルチプラットフォーム**にすることができる。

例えば、現在のwebはPCだけでなく携帯電話だけでなくゲーム機からもアクセスすることができる。

クライアントはUIを担当し、

サーバはデータストレージを担当する。

→複数のサーバを組み合わせることで可用性を広げることができる。


# クライアントサーバの設計モデルに諸々を追加してRESTを構成する

ここでいう諸々とは、

- ステートレスサーバ
- キャッシュ
- 統一インターフェース
- 階層化システム
- コードオンデマンド


## ステートレスサーバ

ステートレスは、「**クライアントのアプリケーション状態をサーバで管理しない**」こと

アプリケーションの状態を管理しないことの利点は、**サーバ側の実装を簡略化できること**

逆にHTTPをステートフルにするのが、Cookie。
これはRESTの理論的には間違いであるが、Cookieがやめるべきであるわけではない。

ステートレスサーバが加わると、
クライアント/ステートレスサーバとなる。
毎回リクエスト通りの出力が返ってくるということだ。

![statelessserver.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/978289/361e8648-515c-dfca-341e-6e563772587e.png)

## キャッシュ

キャッシュは**「リソースの鮮度に基づいて一度取得したリソースをクライアント側で使い回す」**ということ

キャッシュの利点は、「**サーバとクライアントの間の通信を減らすことで、ネットワーク帯域の利用や処理時間を縮小しより効率的に処理できること**」

キャッシュを追加すると、
クライアント/キャッシュ/ステートレスサーバとなる。
![cf7d30e1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/978289/5a9128c7-c6a4-3f07-2aee-6ac06dd70c03.png)

## 統一インターフェース

統一インターフェースは**「URIで指し示したリソースに対する操作を統一した限定的なインターフェースで行うこと」**

インターフェースに制限を書けることで、全体のアーキテクチャスタイルがとてもシンプルになり、
インターフェースを統一することで、クライアントとサーバの実装の独立性が向上する。

統一インターフェースを追加すると、
統一/クライアント/キャッシュ/ステートレスサーバとなる。
![db9e9314.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/978289/803c7f72-55c7-8812-ce83-e138d3861f91.png)

## 階層化システム
統一インターフェースの利点の一つに、階層化しやすいという点がある。
例えば、サーバとクライアントの間にロードバランサを設置して負荷分散したり、プロキシを設置してアクセスを制限したりする。


クライアントからするとサーバもプロキシも同じインターフェースで接続できるので接続先がサーバからプロキシに代わったことを意識する必要はありません。
これはサーバやプロキシなど各コンポーネント間のインターフェースをHTTPで統一しているから実現することができる。

![da9dc342.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/978289/1c3d635d-af98-db37-50fd-8de7700e4dbd.png)

このようにシステムをいくつかに改装に分離するアーキテクチャスタイルを階層化システム(Layered System)という。

階層化システムを追加すると、
統一/階層化/クライアント/キャッシュ/ステートレスサーバとなる。

## コードオンデマンド
コードオンデマンドは、**プログラムコードをサーバからダウンロードしクライアント側でそれを実行するアーキテクチャスタイル**。

例えば、JavascriptやFlashやJavaアプレットなどがこれに該当する。

コードオンデマンドの利点は、クライアントを後から拡張することができること。
クライアントプログラムにあらかじめ用意された機能だけでなく新しい機能を追加していける。

欠点は、ネットワーク通信におけるプロトコルの可視性が低下すること。

HTTPというアプリケーションプロトコルに従って通信している場合は通信の意味やアクセスするリソースは明白ですが、コードオンデマンドを用いてプログラムをダウンロードしクライアント側で実行してしまうと、アプリケーションの可視性が低下する。

コードオンデマンドを追加すると、
統一/階層化/コードオンデマンド/クライアント/キャッシュ/ステートレスサーバとなる。
![a0dd5e7e.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/978289/7b1cf707-92e0-adb2-13d6-5f20529c00bc.png)

この統一/階層化/コードオンデマンド/クライアント/キャッシュ/ステートレスサーバこそが、
RESTなのです。
VSCodeでAsciiDocからPDFを作成するときに画像が表示されない

## TL;DR
### 対策①
絶対パスで画像を指定するといいよ！

```asc:sample.adoc
image::/C:/Users/YOU_NAME/Documents/figure01.png[]
```

### 対策②
`AsciiDoc`機能拡張のオプション項目`Use Workspace Root`にチェックを入れておいて、相対パスで画像を指定するといいよ！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76242/79223e1f-a30f-dfd6-55a5-3c5704bd3866.png)

```asc:sample.adoc
image::figure01.png[]
```

## 環境

**OS**: Windows10 Home 20H2
**VSCode**: 1.54.0
**VSCode Extention**: AsciiDoc v2.8.7
~~**wkhtmltopdf**: v0.12.6.20210114~~ ←今回は使用していませんでした

## 現象

相対パスで画像表示しようとするとプレビューには表示されますが、PDF 出力したときに画像が抜けている状態になっている。

## 原因

~~不明。~~
編集中のファイルに対してカレントフォルダの設定が編集中のファイルのあるフォルダに指定させていなかったため。

## 謝辞

@gemmaro さんの[コメント](https://qiita.com/hidao/items/5f2b89f9e57d9b05cac4#comment-d2e23eacd21d10871ffa)に着想を得て、ちょっと違う形になりましたが修正前の記事よりよい内容になりました。
この場を借りて感謝申し上げます。
Git branch・mergeについてイラスト付きで説明

こんにちは、まゆみです。

今回の記事では、Gitで使うbranch について書いていきます。

<font color="SaddleBrown">branch = 枝</font>

という言葉が示している通りbranchとは

>今取り組んでいるプロジェクト(メインブランチ)から枝分かれさせ、新しい枝を作ることができる機能です。

その枝分かれさせたbranchのコードが上手く実行されるかどうか？を確かめて全てが上手くいくと分かった後、メインのプロジェクトに戻すことができます

イラストにすると下記のようになります

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/1788c848-13a4-cde1-5238-2991567b9fe2.png)


枝分かれさせたbranch は

<ul>

<li>メインのbranch と同時に並行してコードを書き換えることができるし</li>

<li>書き換えたあとのコードを試してからメインのbranch と一緒にする(merge)ことができます</li>


</ul>

ではさっそくbranch の使い方を見ていきましょう

#branchの使い方

##branch を作ってみる

コマンドラインに

```
git branch 好きなbranch名
```

と入力すると、メインのbranch から枝分かれした新しいbranch を作ることができます


次に

```
git branch 
```

とコマンドラインに入力すると、今自分が

>メインのbranch にいるのか？

>または新たに作ったサブのbranch にいるのか？

を確かめることができます

今回、例としてseparate-file というbranch をメインとは別に作ってみました。


git branch で確かめると、master の前に＊がついているのが確認できると思います



![スクリーンショット 2021-03-08 095602.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/3257aaed-8584-ee55-e5ff-7e1c7710883e.jpeg)

これは、今あなたはまだメインのbranchで作業をしているということを示しています。

##新たなbranchに移動する

今、あなたはメインのbranchの方にいるので新たなbranch の方に移動しましょう

```
git checkout 新たなbranch名
```
エンターキーを押した後、コマンドラインに

『Switched to branch "branch名"』と表示されれば、OKです。


##実験してみよう

コマンドラインに『git checkout (branch名)』とうつと、メインのbranch とサブで作ったbranch を行き来できることが分かりました。

では、サブで作ったbranchの中にあるファイルを開いて、ファイルの中のコードやテキストを変えてみましょう。

そして『git checkout master』でメインのbranchに戻りファイルを開いてみてください。

以前のままファイルの内容は<font color="Red">変わっていない</font>はずです。

##サブのbranchで書き換えた内容が気に入った！

サブのbranchで書き換えたコードが上手く実行された！

ではそれをメインのbranchと一緒にしたいですよね。

>①コマンドラインに『git checkout master』と打ち込みメインのbranchにスイッチさせる

>②『git merge　(メインbranchと一緒にしたいサブbranch 名)』とコマンドラインに打ち込み、サブのbranchをメインのbranchと一緒にする

merge が成功すると下記のように表示されます。(ちなみに私はWindows を使っています)

![スクリーンショット 2021-03-08 102521.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/31ee668d-e74e-a432-0b93-48b5a33d628c.jpeg)

※merge が終わったあとも、サブのbranch は消えません。

##GitHubにアップロードする

書き換えたファイルをGitHubにアップロードしましょう

```
git push origin master -u
```

(GitHubへのアップロードがいまいち分からない人は[こちらの記事](https://qiita.com/Mayumi_Pythonista/items/9e747283f8df97fb45c4)を参考にしてください。)

#まとめ

今回は、他の人とコラボする時などにも役に立つ『branch・merge』について解説させていただきました。

お役に立てれば幸いです。<(_ _)>
初学者のJavaScript　開閉機能のプログラミング

##jQueryでtoggleClassメソッドを利用した開閉機能
```javascript
  $(document).ready(function(){
    $('#button').on('click', function(){
      $('#hoge').toggleClass('show');
    });
  });
```
HTML要素のhoge(ID名)にtoggleClassでshowをクリック時に追加、削除するプログラム。クラスセレクタshowにCSSを記述しておくことで、表示/非表示をクリック時に切り替えることができる。

```CSS
showのCSS
.show {
  transform: translate3d(-300px, 0, 0);
}

アニメーション
#hoge {
  transition: transform 0.3s;
}
```
showが付加されるとページ全体が左に300px移動する（-300px）。すると、ページ左に見切れているサイドメニューがページ全体がスライドすることで見られるようになる仕組み。transitionによってアニメーションを付加している。

## さいごに
プログラミングの初学者です。その日に学んだことを学習の一環としてアウトプットしています。より深く学習していきたいと考えておりますので、ご指摘等いただけますと幸いです。

参考図書：確かな力が身につくJavaScript「超」入門　第２版　著者：加納祐東
生産現場IoTへの挑戦 #3.5　~没資料公開~

ちょっとしたプレゼン資料作ったのですが、キャンセルになったのでここで公開。

<iframe src="https://docs.google.com/presentation/d/e/2PACX-1vSJRY5INWxfb65FFjYi-wcc6D8Xk9sjM8WUGskdCXrJt2nvOwx-_mdqN8EXoq90kCY1GEUAYztVb-w2/embed?start=false&loop=false&delayms=3000" frameborder="0" width="960" height="569" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>
WSL2上のUbuntuでdocker/docker-composeを利用する

# はじめに
Windows環境でDockerを動かすために[Docker for Windowsの概要と導入](https://qiita.com/na-777/items/bbc07a40c9802a990abd)を実施しましたが、PowerShell自体にどうも慣れません...。WSL2のUbuntu上で操作できたほうが色々楽です。今回はWSL2のUbuntu上でdockerをインストールして動かしてみます。

ちなみに[Docker Desktop WSL 2 backend | Docker Documentation](https://docs.docker.com/docker-for-windows/wsl/)のようにWindowsのDocker DesktopのバックエンドをWSL2にするものではなく、あくまでWSL2のUbuntuにdockerを入れるだけです。
# 環境
- OS: Windows10 Pro 64bit
    - Version: 1909
    - OS build: 18363.1256
- WLS2
    - Ubuntu 20.04

# dockerインストール
Ubuntuにdockerインストールするのと同じなので、下記の公式ドキュメントを利用します。
参照：[Install Docker Engine on Ubuntu | Docker Documentation](https://docs.docker.com/engine/install/ubuntu/)

```shell-session:WSL2コマンドライン
# 古いバージョンのパッケージの削除
$ sudo apt-get remove docker docker-engine docker.io containerd runc

# aptパッケージの更新と、aptリポジトリを登録するために必要なパッケージのインストール
$ sudo apt-get update
$ sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common

# Docker公式のGPGキーの追加
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

# 先程登録したGPGキーが正当なものであるかをfingerprintからチェック
$ sudo apt-key fingerprint 0EBFCD88
pub   rsa4096 2017-02-22 [SCEA]
      9DC8 5822 9FC7 DD38 854A  E2D8 8D81 803C 0EBF CD88
uid           [ unknown] Docker Release (CE deb) <docker@docker.com>
sub   rsa4096 2017-02-22 [S]

# リポジトリの追加
$ sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"

# aptパッケージの更新と、dockerのインストール
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io

# インストールできているか確認
$ docker --version
Docker version 20.10.1, build 831ebea

# サービスの状態を確認
$ service docker status
 * Docker is not running

# not runnningの場合はスタートさせる
$ sudo service docker start

$ service docker status
 * Docker is running

# テスト
$ sudo docker run hello-world
```

インストール後、sudoなしでdockerコマンドを実行できるように設定します。
参考：[Post-installation steps for Linux | Docker Documentation](https://docs.docker.com/engine/install/linux-postinstall/)

```shell-session:WSL2コマンドライン
$ sudo groupadd docker

$ sudo usermod -aG docker $USER

$ newgrp docker

# sudo なしでdockerコマンドを起動できるかチェック
$ docker run hello-world
```

# docker-composeのインストール
更にdocker-composeもインストールします。
参照：[Install Docker Compose | Docker Documentation](https://docs.docker.com/compose/install/)

```shell-session:WSL2コマンドライン
# curlを利用して安定版をダウンロード
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

# 実行権限を付与
$ sudo chmod +x /usr/local/bin/docker-compose

# シンボリックリンクの作成
$ sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose

# テスト
$ docker-compose --version
docker-compose version 1.27.4, build 40524192
```

# 最後に
VM上でDockerってパフォーマンス的にどうなのかな...とは思いつつ慣れたLinuxのコマンドラインでDocker環境を構築できるのはやっぱり良いですね。
一通りインストールできたので次はRailsでも動かしてみます。
laravelアプリ作成時のコマンド実行で非常に時間がかかるのでダウンロードの詳細を出力してみる

# 目的

- laravelアプリ作成時のコマンドが全然終わらないので詳細を出力するオプションをつけて実行してみた

# 環境

- ハードウェア環境

| 項目 | 情報 |
| --- | --- |
| OS | macOS Catalina(10.15.5) |
| ハードウェア | MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports) |
| プロセッサ | 2 GHz クアッドコアIntel Core i5 |
| メモリ | 32 GB 3733 MHz LPDDR4 |
| グラフィックス | Intel Iris Plus Graphics 1536 MB |

- ソフトウェア環境

| 項目 | 情報 | 備考 |
| --- | --- | --- |
| PHP バージョン | 7.4.8 | Homebrewを用いてこちらの方法で導入→[Mac HomebrewでPHPをインストールする](https://qiita.com/miriwo/items/cd54077aad7e139cf518) |
| Laravel バージョン | 6.X | commposerを用いてこちらの方法で導入→[Mac Laravelの環境構築を行う](https://qiita.com/miriwo/items/adaaaeecae69d6392e08) |
| MySQLバージョン | 8.0.19 for osx10.13 on x86_64 | Homwbrewを用いてこちらの方法で導入→[Mac HomebrewでMySQLをインストールする](https://qiita.com/miriwo/items/ef6a064bc545fbea29d9) |
| Node.jsバージョン | v8.9.4 | Homwbrewを用いてこちらの方法で導入→[Mac HomebrewでNode.jsをインストールする](https://qiita.com/miriwo/items/73d1546220f1c091a7d5) |

# 情報

- 筆者はMacに直接laravelアプリ動作環境を構築してlaravelアプリの作成を行った。

# 困りごと

1. 下記コマンドを実行してlaravel8のアプリを作成しようとしたが全然処理が完了しない。

    ```terminal
    $ composer create-project "laravel/laravel=8.*" todos
    ```

# ダウンロード進捗状況を逐一出力するようにしよう

1. `-vvv`というオプションを付けることによりコマンドの作業進捗が出力される。

    ```terminal
    $ composer create-project "laravel/laravel=8.*" todos -vvv
    ```

1. フリーズすることもなく着々と依存性の解決とパッケージのダウンロードが行われていた。これなら時間が解決してくれそうなので気長に待つこととする。