OmniAICreator/Qiita-1.07M huggingface dataset:
公式のUnity2D入門をv2020.3でやってみる(2)



[前](https://qiita.com/DiveMasakazu/items/597d5c9f318a28dc7c9b)

機械翻訳の日本語と書いてあったけど、特に問題は感じてない。プログラム部分の解説だけ改善の余地が多少ありそう。

## ワールドを装飾しよう

* 前後の描画方法
* プレハブについて

手前を前に表示するにはプロジェクト設定のグラフィックのカメラ設定でY軸基準。スプライトの設定でソートポイントをピボットにして、位置変更。忘れそう。
「Scene ビューの右上に保存ボタン」とは何か分からなかったが、
`注： Auto Save ボタンはデフォルトでオンになっています`の注意書きがあった。
プロジェクト設定のエディターに「プレハブモード-自動保存を許可」があるので、この設定ぽいのでチェックを外すと確かに「保存」ボタンが出てきた。



## ワールドとのインタラクション　動きをブロックする

* Rigidbodyで物理演算対象にする
* コライダーで衝突判定を付ける
* 衝突時にキー押しっぱなしてる時のブルブルを回避するスクリプトの書き方
* 背景のタイルへのコライダーの追加＋複合コライダー

Rigidbodyで重力、回転の制御
コライダーで衝突判定

`ヒント：シーン内の Ruby のインスタンスに変更を加えたが、プレハブではない場合は、ドロップダウンの Overrides メニューを使用して、プレハブに変更を適用してください。`
間違えてシーンに変更を加えた場合は、シーン側をプレハブに上書きはできるが、プレハブ設定をシーンに上書きは出来ないっぽい。
（シーンから削除して、プレハブをもう一度Assetsから持ってこればいいだけだから？）

ソースコードの解説がパットは分かりにくいけど
最初にキャラを動かすコードを書いた時はTransformを使って位置変更をしていたけれど、
Rigidbodyを持っている場合は同時にRigidbodyの場所も指定してやるとよい。
アプリ本体と物理演算のフレームレート違いを吸収するためにアプリ内で定期的に実行されるFixedUpdate関数でRigidbodyは更新するが、
ユーザの入力は常に監視されているUpdateで行う、という事だと理解した。

あと、Tilemap Collider 2Dは2D物理ではなくタイルマップの中にある。（検索すれば出てくるけど）
複合コライダーは普通に2D物理の中。

## ワールドとのインタラクション　収集アイテム

* 体力を設定するコードを書く
* 体力回復のメソッドを実行するトリガーの設定
* トリガー起動のスクリプトを作成
* getterメソッドの追加

途中のコード解説は簡単なので読み飛ばしたけど、
UnityにはMathf.Clampという便利メソッドがあって

```java:sample
if( health > MAX_HEALTH){ health = MAX_HEALTH; }
```

みたいな事をしなくてもいいっぽいけど、メソッドを探す方法はまだ知らない。

回復アイテム用にスクリプト作成してからアタッチしようとすると、前回同様スクリプトがありませんエラーが発生。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2081290/4811b053-b7c7-06e2-38c8-762758ae88cd.png)
回避方法が分からないのでインスペクターから新しくスクリプトを作成を選んでからフォルダに移動させた。
OnTriggerEnter2D(Collider2D other)
みたいな特殊な関数も、今は他に何があるか分からないが、言われるがまま書いておく。
publicじゃないメソッド呼んでてエラーが出たから修正したけど、後ろに修正のセクションがあった・・・

あとC#は15年くらい前に触って以来（古いJavaの書き方に一番慣れている）だけど、getterはこういう風に書くのか、チュートリアル作った人の流儀なのか分からんかった。
と思ったけど、これはgetterメソッドではなかった。プロパティで、こういう書き方が正しそう。


```C#:sample
    public int health { get { return currentHealth; }}
    int currentHealth;
```

ちょっと便利に使えるみたいなので、とりあえず存在を覚えた。

今回はここまで
Railsチュートリアル 1.4.3 Push時のエラー解決方法

Railsチュートリアル第1章の1.4.3で、Githubへのpush時にエラーが出るようになっているので、
解決方法のメモとなります。

# エラー内容
チュートリアルの1.4.3で下記コマンドを実行するとエラーが発生する。

```sh
$ git push -u origin master
remote: Support for password authentication was removed on August 13, 2021. Please use a personal access token instead.
remote: Please see https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/ for more information.
```

調べてみるとGitHubが2021年8月13日にパスワード認証を廃止したことが原因のようです。
https://news.mynavi.jp/article/20201222-1604003/

Railsチュートリアルでは、HTTPSを選択するように指示されているためにエラーが発生します。
そのため、Railsチュートリアルでは、「[もうひとつのSSHオプションは中級ユーザー向けなので、SSH鍵の生成や設定を問題なくできる方はそうしていただいて構いません。](https://railstutorial.jp/chapters/beginning?version=6.0#cha-1_footnote-26)」と記述されているのでSSHオプションでのやり方を説明します。

# SSHオプションでの設定方法
## SSH 公開鍵の作成
SSHで接続するには、Githubに登録する公開鍵の作成が必要となるので、下記コマンドを実行して公開鍵を作成します。

```sh
$ cd ~/.ssh
$ ssh-keygen
$ cat ~/.ssh/id_rsa.pub
```

詳しくは[こちら](https://git-scm.com/book/ja/v2/Git%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC-SSH-%E5%85%AC%E9%96%8B%E9%8D%B5%E3%81%AE%E4%BD%9C%E6%88%90)が参考になりました。

## Githubに公開鍵を登録する
https://github.com/settings/keys のページから登録出来ます。

右上にある`New SSH key`ボタンをクリックします。
![スクリーンショット 2021-09-27 21.23.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399993/0a4ff532-af01-b79c-5e10-e45a6e6e77a3.png)

「Title」には任意の名前を、Keyには、`$ cat ~/.ssh/id_rsa.pub`を実行時に表示された公開鍵を貼り付けます。
記述出来たら`Add SSH key`をクリックして登録完了です。
![スクリーンショット 2021-09-27 21.25.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399993/559c701d-2081-88e1-3e79-32fcdb5e61e8.png)

## gitのリモートoriginを変更する
Railsチュートリアル通り進められている方だとエラーが出た時点で、
下記コマンドを実行済みのためHTTPSでリモートoriginに追加されています。

```sh
$ git remote add origin https://github.com/<あなたのGitHubアカウント名>/hello_app.git
```

そのため下記コマンドを実行して、SSHで設定し直します。

```sh
$ git remote set-url origin git@github.com:<あなたのGitHubアカウント名>/hello_app.git
```

正しく変更が出来ていた場合、下記コマンドを実行すると下記のような表示になるはずです。

```sh
$ git remote -v
origin  git@github.com:<あなたのGitHubアカウント名>/hello_app.git (fetch)
origin  git@github.com:<あなたのGitHubアカウント名>/hello_app.git (push)
```

## Githubリポジトリにpushする
下記コマンドを実行して、Githubにコードが反映されていれば成功です。

```sh
$ git push -u origin master
```
Bolt+CDK+PythonでSlackBotを作る

# この記事はなに？

前回こんな記事を書きました。

https://qiita.com/sisii00/items/4e82d672b0ed63abfc7d

そして、このまえBoltのコードを読んでたらずっとシンプルに作れることがわかったので記事にしました、という話です😅

# 使うライブラリー

- [AWS CDK](https://aws.amazon.com/jp/cdk/)
- [Bolt](https://github.com/slackapi/bolt-python)

# 実際のコードはこんな感じ

## Stack側

```python:app.py
import os

from aws_cdk import core
from aws_cdk.aws_apigateway import LambdaIntegration, RestApi
from aws_cdk.aws_lambda import Runtime
from aws_cdk.aws_lambda_python import PythonFunction

class CdkBoltHelloWorldStack(core.Stack):
    def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)
        lambda_ = PythonFunction(
            self, f"HogeLambda", entry="lambda", handler="handler", runtime=Runtime.PYTHON_3_8,
        )
        api = RestApi(self, f"HogeApi")
        api.root.add_method("POST", LambdaIntegration(lambda_))

app = core.App()
env = core.Environment(account=os.getenv("CDK_DEFAULT_ACCOUNT"), region=os.getenv("CDK_DEFAULT_REGION"))
CdkBoltHelloWorldStack(app, APP_NAME, env=env)
app.synth()
```

RestAPIタイプのルート直下にPOSTで統合レスポンスのLambdaを作ります。

## Lambda側

```python:lambda/index.py
from slack_bolt import App
from slack_bolt.adapter.aws_lambda import SlackRequestHandler

app = App(
    signing_secret="** SlackのSigningSecret **", # 適宜入力  
    token="** SlackのBotUserOAuthToken **", # 適宜入力
    process_before_response=True
)

@app.message("hello")
def message_hello(message, say):
    say(f"Hey there <@{message['user']}>!")

def handler(event, context):
    return SlackRequestHandler(app).handle(event, context)
```

依存パッケージはBoltのみ！！

```text:lambda/requirements.txt
slack-bolt==1.7.0
```

---

以上です！

後はデプロイして発行されたエンドポイントをSlackのEvent SubscriptionsのRequest URLに登録すれば完了です！

内容が少し違いますが、リポジトリはこの辺です！

https://github.com/sisi100/cdk_bolt_hello_world_2
【phpunit】Rule for method name is not defined, cannot define rule for parameters without oneはモックについてのメソッド定義順序が違うからかも！

phpunitでテストコードを書いている際にタイトルのエラーが表示されました。

# ■エラー内容
データプロバイダーを使ってテストを書いていました。
下記がエラーメッセージです。

```.s
Rule for method name is not defined, cannot define rule for parameters without one

WARNINGS!
Tests: 4, Assertions: 0, Warnings: 4.
/var/www/ap # ./vendor/phpunit/phpunit/phpunit ./tests/Unit/app/Http/Models/UserModelTest.php
PHPUnit 8.5.8 by Sebastian Bergmann and contributors.

WWWWWW                                                              6 / 6 (100%)

Time: 20.17 seconds, Memory: 34.00 MB

There were 6 warnings:

1) Tests\Unit\App\Http/Models/UserModelTest::getName with data set "UserName null error" (1, '1', true)
Rule for method name is not defined, cannot define rule for parameters without one
...(以下略)
```

`data set "UserName null error" (1, '1', true)` という部分はデータプロバイダーで作成したテストケースについての内容です。

getName with **data set** "UserName null error" (1, '1', true)
**Rule for method name is not defined, cannot define rule for parameters without one** という内容からテストケースの命名方法が良くないのか？と考えていました。しかし、全く見当違いでした。

# ■原因
method()より前にwith()を呼び出していた。

# ■解決：createMock()の後にmethod()を呼び出す

■修正前

```.php
$adapterMock = $this->createMock(adapter::class);
$adapterMock->expects($this->once())
    ->with('name') 　　// ここと
    ->method('get') // ここを入れ替える
    ->willReturn('taro');
```

■修正後

```.php
$adapterMock = $this->createMock(adapter::class);
$adapterMock->expects($this->once())
    ->method('get')
    ->with('name')
    ->willReturn('taro');
```

# ■さいごに
エラーメッセージに該当の行数が書かれていなかったので、原因が分かるまでに少し時間がかかってしまいました。

mock作成後に、モック化するメソッドを指定する前にwith()で引数を指定しようとしたため、今回のエラーメッセージである`Rule for method name is not defined, cannot define rule for parameters without one（メソッド名のルールが定義されていません。パラメータのルールを定義できません。`）
というように出ていたようです。

それでは！
GitHubで認証時の個人アクセストークンを記憶させる

# はじめに

今までLinux環境でGitHubに認証するとき毎回パスワードを手打ちしていた人向け


## 結論：入力した認証情報を保存する (Linux)

保存方法はどっちか選ぶ

### 常駐プロセスに一時記憶

```
$ git config --global credential.helper cache
```

### ファイルに保存（平文）

```
$ git config --global credential.helper store
```
保存先は指定できるが無指定だと`~/.git-credentials`に保存される

# いちおう背景

最近になって GitHub に`git push`するとき、なにか注意を受けていることには薄々気付いていた

```
$ git push
Username for 'https://github.com': mtkhs
Password for 'https://mtkhs@github.com':
remote: Support for password authentication was removed on August 13, 2021. Please use a personal access token instead.
remote: Please see https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/ for more information.
```
「パスワード認証はサポートされなくなるから個人アクセストークンに切り替えてね」と

われわれに残された道は

1. 公開鍵で認証する
2. 従来のパスワード認証の代わりに「個人アクセストークン」で認証する

個人アクセストークンは、めっちゃ長いパスワード（自動生成される）で
付与する権限は自分で選べるが権限を限定してセキュアに運用しようねって感じ
（トークンは「ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx」みたいな感じ）

さすがにこれを毎回手打ちすることはムリなので認証情報を保存させようと考えたわけ

# 解決策

`credential.helper` を設定すると認証情報を管理させられる！
設定するコマンドは以下

```
$ git config --global credential.helper [ほにゃらら]
```

`[ほにゃらら]`はOS環境によって、Macなら`osxkeychain`、Windowsなら`wincred`や`manager`なども選択できる
mockitoのverifyでany()と引数指定を混ぜて使いたい

## 詰まった事象

```java
verify(service).hogehoge(any(), any()); // OK
verify(service).hogehoge("fuga" , "piyo"); // OK
verify(service).hogehoge(any(), "piyo"); // NG
```

## 解決策

Matcherを使いましょう。

```java
verify(service).hogehoge(any(), eq("piyo"));
```

実はエラーログに親切に書いてありました。

```
This exception may occur if matchers are combined with raw values:
    //incorrect:
    someMethod(anyObject(), "raw String");
When using matchers, all arguments have to be provided by matchers.
For example:
    //correct:
    someMethod(anyObject(), eq("String by matcher"));
```
Web サービスのサーバー構築で躓いたところ(日本語を表示)

#日本語出力

これ、本当につまづきました…

Hello,Worldは英語なので問題なかったのですが、
こんにちはと出力させるのが大変でした…

#失敗したコード

教本にあるのをそのままコピーしたのですが、全然ダメでした
改行を変えたり、属性を変えてもダメで…

```python
#!/usr/local/bin/python

import sys

sys.stdin = open(sys.stdin.fileno(),  'r',
               encoding='UTF-8')
sys.stdout = open(sys.stdout.fileno(), 'w',
               encoding='UTF-8')
sys.stderr = open(sys.stderr.fileno(), 'w',
               encoding='UTF-8')

print("Content-Type: text/html; charset=UTF-8")
print("")

print("<html><body><h1>")
print("賢い子は父親を喜ばせ，愚かな子は母親を悲しませる。")
print("</h1></body></html>")
```

#解決方法

2行目に＃ coding: utf-8を追加することが必要でした。
下記のsys.系はpython3.x系のようで、デフォルトがpython2.xのさくらのクラウドでは、
機能しなかったようです。


```python
#!/usr/local/bin/python
# coding: utf-8

import sys

#sys.stdin = open(sys.stdin.fileno(),  'r',
#               encoding='UTF-8')
#sys.stdout = open(sys.stdout.fileno(), 'w',
#               encoding='UTF-8')
#sys.stderr = open(sys.stderr.fileno(), 'w',
#               encoding='UTF-8')

print("Content-Type: text/html; charset=UTF-8")
print("")

print("<html><body><h1>")
print("賢い子は父親を喜ばせ，愚かな子は母親を悲しませる。")
print("</h1></body></html>")
```
8080ポートの切断 タスクをkillする方法【WindowsPowerShell】

##WindowsPowerShellを開く

##プロセスIDを調べる
PS C:\Users\hoge> netstat -ano | findstr 8080

```:コマンドライン入力
netstat -ano | findstr 8080
```
```:コマンド実行結果
  TCP         0.0.0.0:8080           0.0.0.0:0              LISTENING       4768
  TCP         [::]:8080              [::]:0                 LISTENING       4768
```
|ポイント|解説|備考|
|----|----|----|
|LISTENING  4768|プロセスID<br>このID(4768)は<b>毎回違う</b>ので、都度調べる。||

##調べたプロセスIDをtaskkillする
PS C:\Users\hoge> taskkill /F /pid 4768

```:コマンドライン入力
taskkill /F /pid 4768
```
|ポイント|解説|備考|
|----|----|----|
|pid|プロセスID||


```:コマンド実行結果
成功: PID 4768 のプロセスは強制終了されました。
```
##確認
PS C:\Users\hoge> netstat -ano | findstr 8080

```:コマンドライン入力
netstat -ano | findstr 8080
```
```:コマンド実行結果【何も返ってこなければ成功】
PS C:\Users\hoge>
```
[iOS]Firebase Analyticsのみを使う場合App Tracking Transparency によってユーザーに許諾を得る必要があるか？

- [Ad Support Frameworkを導入](https://firebase.google.com/support/guides/analytics-adsupport?hl=ja)している場合
    - IDFA(広告識別子)を収集しているので、ATTによる許諾が必要。
- Ad Support Frameworkを導入していない場合
    - iOS11をサポートしている場合
       - [iOS11だと明示していないのに内部的にAd Support Frameworkを使用しておりIDFAを収集してしまうらしい](https://github.com/firebase/firebase-ios-sdk/issues/1686)。そのため、info.plistの`FIREBASE_ANALYTICS_COLLECTION_DEACTIVATED`をtrueとするか、podfileで`pod 'Firebase/Analytics'`の代わりに`pod 'Firebase/AnalyticsWithoutAdIdSupport'`を用いるなどしてIDFA収集を阻止できる。阻止しない場合許諾が必要になってしまう。 https://firebase.google.cn/docs/analytics/configure-data-collection?platform=ios#re-enable_personalized_advertising_features
    - iOS11をサポートしない場合
       - IDFAを収集しないため許諾は不要。Firebase側の意図した動作となるよう、Firebase/analyticsは常に最新版を用いること。

https://dev.classmethod.jp/articles/firebase-analytics-crashlytics-ios14/
mecab-python で no such file or directory: c:\mecab\mecabrc

# 発生事象

以下のようなスクリプトを書いて実行。

```python:sample.py
import MeCab

mecab = MeCab.Tagger()
sent = "プログラミングスクール詐欺に騙されないための教育って何が必要なんだろう？"
print(mecab.parse(sent))
```

実行時に以下のエラーが出て止まってしまう。

> [ifs] no such file or directory: c:\mecab\mecabrc

# 環境

* Python 3.9.6
* mecab-python             1.0.0
* mecab-python3            1.0.4

※mecab-pythonをインストールすると依存関係でmecab-python3がインストールされるので、`pip install mecab-python`だけでＯＫ。

# 原因・対策

このエラーメッセージだとさっぱりわからないが、辞書がインストールされていないために出ているエラー。
辞書をインストールする必要がある。

```
pip install unidic-lite
```

# 結果

```
プログラミング  プログラミング  プログラミング  プログラミング-programming      名詞-普通名詞-サ変可能
        4
スクール        スクール        スクール        スクール-school 名詞-普通名詞-一般                      2
詐欺    サギ    サギ    詐欺    名詞-普通名詞-一般                      1
に      ニ      ニ      に      助詞-格助詞
騙さ    ダマサ  ダマス  騙す    動詞-一般       五段-サ行       未然形-一般     2
れ      レ      レル    れる    助動詞  助動詞-レル     未然形-一般
ない    ナイ    ナイ    ない    助動詞  助動詞-ナイ     連体形-一般
ため    タメ    タメ    為      名詞-普通名詞-副詞可能                  2
の      ノ      ノ      の      助詞-格助詞
教育    キョーイク      キョウイク      教育    名詞-普通名詞-サ変可能                  0
って    ッテ    ッテ    って    助詞-副助詞
何      ナン    ナニ    何      代名詞                  1
が      ガ      ガ      が      助詞-格助詞
必要    ヒツヨー        ヒツヨウ        必要    名詞-普通名詞-形状詞可能                        0
な      ナ      ダ      だ      助動詞  助動詞-ダ       連体形-一般
ん      ン      ノ      の      助詞-準体助詞
だろう  ダロー  ダ      だ      助動詞  助動詞-ダ       意志推量形
？                      ？      補助記号-句点
EOS
```

# 参考

https://github.com/SamuraiT/mecab-python3/issues/55
classのprivate functionの呼び出し

classのprivate functionを呼びたい。

まずクラスFooを定義する。

```javascript
class Foo {
    func1() {
        console.log('func1が呼ばれました');
        this.#func2();
    }
    #func2(){
        console.log('func2が呼ばれました');
    }
}
```

で呼び出し処理。これで呼べる。

```javascript:call.js
$(function(){
let obj = new Foo();
obj.func1();
});
```

次にjqeuryのblur内で呼び出す。これは手こずった。

```html:index.html
    <p>名前：<input type="text" id="text" size="40"></p>
```

テキストボックスのフォーカスが外れた時。

```javascript:call.js
let obj = new Foo();
$('#text').blur(obj.func1.bind(obj));
```

このケースではthis.#func2();呼び出し時にthisがFooオブジェクトを指していないので、thisがFooオブジェクトを指すようにbindしてあげる。

昨日勉強したbindが早速役に立った。
RSpecの  to be_blank ,to be_present とto be_truthy,to be_falseyなどのmatcherについて

# matcherとは
RSpecでテストをする時、こういう風に動いて欲しいと期待をしてその通りに動いたかを
確認するためのものです。
例えば

```rb
expect(100 + 300).to eq 400
```
 とあったとします。
これは100 ＋ 300は400と期待(expect)をし、この答えがきたしていたものと等しい(eq)かを
確認しています。

この***eqがmatcher***です。

　下ではmatcherの種類を一部紹介します。

# to be_blankとto be_present
最初にto be_blankから説明します。
これは***~は存在しない***というmatcherです。
例えば

```rb
 expect(article[:title]).to be_blank
```
これは***articleにはtitleは存在しないと期待したテスト***になります。

次にto be_presentについてです。

```rb
 expect(article[:user_id]).to be_present
```
これは***articleにはuser_idは存在すると期待したテスト***になります。



⚫︎補足 beの意味
beは等号や不等号など大小を調べるときに使うみたいです。
等号・不等号なしでも上のようもにかけます。
詳しくは下の資料からも参考にしてみてください。


# to be_truthyとto be_falsey
to be_truthyから説明します。
これは戻り値をtrueで返すmatcherです。

```
# 入力しなければならないものがあるので保存できる（結果はtrue）
staff.name = 'Tom'
user.job = 'programmer'
expect(staff.save).to be_truthy

```
***staffは保存できると期待してtrue（保存できる)とテスト***をしています。


最後にto be_falseyを説明します。

```
# 何も入力されていないので保存できない（結果はfalse）
expect(staff.save).to be_falsey 

```
***staffは保存できないと期待して保存できない(結果はfalse)ことをテスト***しています。


⚫︎補足　to be_trueと　to be_false
上の２つは***true もしくは false でなければいけない***ものです。
to be_truthyとto be_falseyはtrueっぽい、falseっぽいでもテストをできるみたいです。

matcherについてもっと詳しく知りたい方は下の参考資料から確認してください。


⚫︎参考資料
https://qiita.com/jnchito/items/2e79a1abe7cd8214caa5
https://qiita.com/idaida_idaida/items/eda4a29e5ece5122611b
KPT アンチパターン 〜失敗事例紹介〜

# はじめに

[KPT (Keep/Problem/Try) 等のふりかえりで、K (Keep) ネタを増やすみんなの工夫](https://togetter.com/li/1779314) というのを見て「あるある」と思ったので、KPTをやってみてこれはよくなかったとか、これは失敗だったなぁという自分の経験をまとめてみます。
振り返りの手法としては、KPT、YWT、Fun/Done/Lean、Celebration Gridなどがありますが、一番有名なのはKPTなのかもしれないですね。

#失敗その1 Tryが振り返りの度に溜まっていく
個人的にKPTあるある第1位はこれじゃないかなと思います。特に振り返りの経験が少ないと、たくさん改善しようと思いTryをたくさん考えてしまいます。忙しかったりすると実際にTryが行われる訳でもなく…次回の振り返りでさらにTryが積まれ、実施される事のないTryがたくさんある状態になりがちです。また、Problemが並ぶとエンジニア的には課題には解決策を考え無いといけないと思いがちな所為もあると思います。
Tryがどんどん積み上がっていくのは精神的にも嬉しくないですし、振り返りしても改善が行われないので振り返り自体が無駄なのでは？という意見が出たりもします。

### 対策
個人的には以下が有効だと考えます。

- たくさんTryを考えるのではなく、実行されると一番効果がありそうなTryに絞る
- 実施されないTyrは一旦タスクから削除する（実施されないと問題な場合は再度Problemとして上がってくる事が多い）

#失敗その2 Tryが実施されない
Tryの数を少なくしたり重要なものに絞ったりしても、忙しくて実施されないという場合があります。実施されないと何も状況は変わらないので、こちらもその1と同じように振り返り無駄なのでは？といった意見が出たりします。また、実施不可能な事をTryにしていたり、最初のアクションが不明瞭なままTryにしているケースもあります。

### 対策
個人的には以下が有効だと考えます。

- Tryの実施に時間と期日を割り当て、とにかく期日までには実施する
- 実施可能なTryにする
- 粒度が荒かったり、簡単には実現できない時はまず最初のアクションと期日を決める

#失敗その3 KPT（振り返り）に時間がかかる
炎上プロジェクトの途中で振り返る場合は、時間をかけてProblemを議論するのがいいと思いますが、プロダクトチームで定期的に振り返りを行なっている場合、ファシリテーターが時間配分を考えず深堀りしているとMTGの時間が長引いてしまいがちです。また、潜在的な問題が多いのに振り返りの間隔が長いと単純にProblemが多く、話すのに時間がかかってしまいます。

### 対策
個人的には以下が有効だと考えます。

- ファシリテーターはタイムキーピングしつつ深堀りするトピックを選ぶ
- KPTの開催間隔が妥当なのか検討する

#失敗その4 KPTの時間がしんどく（ツラく）なる
これは冒頭のKeepを増やす案を募集しているのと一緒ですが、毎回Problemについて会話しているとTryを実施していても改善を感じにくくなってきます。問題が毎回発生しているチーム=ダメだ…ってなりがち。プロダクトチームで定期的にKPTを実施しているとこんなパターンに陥りがち。反省するのも悪くはないですが、程々に。単に運が悪い時もあります。

### 対策
個人的には以下が有効だと考えます。

- ポジティブに振り返りを実施する
- Keepの時間を増やし良いところや改善点を認識する
- YWT、Fun/Done/Lean、Celebration Gridなど別に手法に変える

#失敗その5 Keepがあまりでない
定期的にKPTをするとなると、Keepが大事になってきます。ただし、Keepを続けたい事にしてしまうとあまり出てこなかったりもします。

### 対策
個人的には以下が有効だと考えます。

- ポジティブに振り返りを実施する
- 感謝を伝える、よかった事やポジティブになれるような事も記載する
- YWT、Fun/Done/Lean、Celebration Gridなど別に手法に変える

#失敗その6 外から来た人がダメ出しをして人間関係が険悪になる
わりとパンチのあるネタです。とあるプロジェクトが上手くいっていなかったのでKPTを実施し、Problemを洗い出す。こう聞くと良さそうですが、その洗い出し方や指摘の仕方が悪いと「アイツの言っていることは正しいが、一緒に仕事をしたくない」という状態になります。似たようなものに、ややトラブっているプロジェクトに新しいPjMがやってきて課題をビシバシと指摘し厳しく対策を要求したら「あのPjMとは一緒に仕事ができません」となったプロジェクトを見た事があります。まぁ、そのプロジェクトはその後僕がPjMする羽目になったんですが…。似た事例としては組織のマネージャーなどでも見た事があります。転職や異動で新しくやってきた人が、過去の事情を知らずにダメ出しをしまくり、あの人とは仕事ができません、となるパターンです。我々はみな人間なので関係性が大事ですね。

### 対策
個人的には以下が有効だと考えます。

- 伝え方に気をつける
- 関係性に気をつけ、過去の事情も考慮する

#失敗その7 振り返ろうとしたが、思い出せない
KやPを書こうとした時に「あれ、なんだっけ…」、「なにかあったけど思い出せない…」となる時があります。これには大体二つのパターンがあって、「期間が長すぎるので何があったのかもう思い出せない」パターン、これは長いプロジェクトをやっていると細かい事などを忘れてしまったり、プロジェクトが完了してしばらく日数が経ってから振り返ろうとする時に起こりがちです。もう一つのパターンとしては、「色々起きたので忘れてしまう」パターンです。色々なことが起きると印象の強い事は覚えていますが、そうでない事は忘れてしまいます。例えば、障害の対応について振り返ろうとすると細かい時系列は解らなくなってしまったり、2週間に1度振り返っている時に、直近で障害が起きるとその事はよく覚えているものの、「先週ってなにやったっけ…」となりがちです。

### 対策
個人的には以下が有効だと考えます。

- 時系列で起きたイベントを事前にまとめ、それを見ながら振り返る

長いプロジェクトなら月毎にイベントをまとめておくとか、障害時ならば発生時刻から終了時刻までに行った対応があると振り返りやすいです。

#おわりに
あまりまとめた事がなかったので、まとめてみました。
いかがでしたか？

また何か思い出したり、やらかしたら追記したいと思います。

2021/10/06 その7追記
Unity Animation CurveのConstantカーブを設定したい

# 初めに
Unity Animation Curveでアニメーションをスクリプトで登録する

```c#
Keyframe(0, 1.0f);
```
こんな感じで、ただ、デフォルトだと下記のようなLinearかSmoothみたいになってしまう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37068/1311a7eb-1fb0-4537-3f24-224cbb5fff78.png)


## 値をConstantで設定したい
今回は下記のようにパキっとしたい！
青で囲ったみたいなな
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37068/ccf0ae66-aae5-3dd1-4f52-fb9180498776.png)

検索すると出てくる。。

### Unity questionsで 解決

https://answers.unity.com/questions/253837/can-i-set-an-animationcurve-keyframes-interpolatio.html

ここにかいてあるのは、Keyframeの第３，４引数のinTangentとoutTangentにinfinityを設定すれば良いと書いてある

https://docs.unity3d.com/ja/current/ScriptReference/Keyframe.html



#### スクリプトを下記のようにする

Keyframeの第３，４引数の値を

```c#
Keyframe(0, 1.0f, float.PositiveInfinity, float.PositiveInfinity)
```

floatのInfinityであるMathfで宣言されているInfinityは同じ値を指しているので、どちらでもいいです。
float.PositiveInfinity
Mathf.Infinity

スクリプトでKeyframeしていするとConstantのチェックボックスにはなってはいないが
値はConstantを同じになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37068/8eda751a-bb56-fa2d-9ca4-aa12d75d66ce.png)

##### 最後に
今回もgoogle先生に聞くだけで解決されたのは、嬉しい！
実装がある程度経っているのは、調べると出てくるはいいですね～！！
Dockerfile作成時、キャッシュをうまく使う

# はじめに
本記事では、Dockerfile作成時にキャッシュをうまく使う方法をアウトプットします。
Dockerマスターになりたいので、誤りがあればご指導ください。(他力本願かて)

Dockerfileについては、以下も参照ください。

https://qiita.com/mkato1013/items/f89ace069155a808cadf

# 準備

```dockerfile
FROM ubuntu:latest

RUN apt-get update
RUN apt-get install <パッケージ>

CMD ["bin/bash"]
```

とします。

FROMで、`ベースになるimage`を決定します。
今回は、`ubuntu`にします。

その後、Ubuntuでは、`apt-get`というコマンドでパッケージ管理します。

- `RUN apt-get update`では、新しいパッケージリストを取得できます。
- `RUN apt-get install <パッケージ>`で、パッケージをインストールできます。

## キャッシュを利用する
`RUN やりたいこと`をどんどん記述してしまうと、
その分`layer`が積まれていっぱいになります。
`build`をする毎に、処理に時間がかかってしまいます。

つまり、`まとめてRUN`すれば、省エネすることができます。

```dockerfile
FROM ubuntu:latest

RUN apt-get update
RUN apt-get install -y <パッケージ>

CMD ["bin/bash"]
```

これは、

```dockerfile
FROM ubuntu:latest

RUN apt-get update && apt-get install -y <パッケージ>

CMD ["bin/bash"]
```

で、書くことができます。

パッケージは１つとは限らないので、`\(バックスラッシュ)`を使って、
より見やすく書くことができます。

```dockerfile
FROM ubuntu:latest

RUN apt-get update && apt-get install -y \
    <パッケージ1> \
    <パッケージ2> \
    <パッケージ3>

CMD ["bin/bash"]
```

と書くことができます。


`RUN`の内容の変更点がなければ、
`docker build .`をしても、`キャッシュを使って`処理を早く終了することができます。

つまり、パッケージをインストールして、うまくいったものについては、
`<パッケージ> \`と、どんどん追加していくことが良いと考えられます。

```dockerfile
RUN apt-get update && apt-get install -y \
    <パッケージ1> \
    <パッケージ2> \
    <パッケージ3>
RUN apt-get install -y <パッケージ4>

<パッケージ4>が問題なければ、

RUN apt-get update && apt-get install -y \
    <パッケージ1> \
    <パッケージ2> \
    <パッケージ3> \
    <パッケージ4>

と付け足していく。

これを繰り返し、
完成品ができれば、
締めくくりとして、RUNをひとまとめにして、「build」します。
```

パッケージについては、
私的に、さらに分かりやすい方が良いと思ったので、アルファベット順でも良いのかなと思います。

以上です。

# 終わりに
何事においてもデータ容量は、小さい方が良いと思います。
今回のように、キャッシュをうまく使い、省エネをしていきたいです。

私のような初学者の方々は、
Dockerを使いまくってデータ容量がすごいことになっていると、
よく耳にします。

何においても、プログラミングは`可読性`は大事なのですね。

以下今回の参考サイトです。
[Dockerfile に apt, apt-get, source コマンドを書く時のTips](https://tech-blog.cloud-config.jp/2019-09-09-dockerfile-apt-apt-get-source-tips/)
[Dockerfile のベストプラクティス](https://docs.docker.jp/engine/articles/dockerfile_best-practice.html)
[Dockerfileの書き方と使い方](https://blog.codecamp.jp/docker-file-how-to)

明日も頑張ります！
【第一回】コロナ禍だから何かできることをー　自宅療養者連絡ツール　ー

#まえがき
###お前の力はこんなもんじゃないだろう！
>「 国を変えるのは、政治家じゃない、サラリーマンだ！」

（エンゼルバンク）

まだまだ技術力不足で自分一人では実現不可能だったので公開します。
こんな時代だからこそ人を豊かにする道具をもっと作っていけたらいいなって思ってます。

#実装イメージ図
LINEを利用して保健所の担当者の負担を軽減するとともに、自宅療養者はいつでもつながっている安心感を持たせるためのツールイメージです。

![2021_09_03 7_27 Office Lens.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/744261/c70538e9-0267-d49d-e0c9-66493779a7ca.jpeg)

#実装イメージ図
担当者と自宅療養者とのLINEの連携部分は完成しました。
次回、第二回で設定方法を説明します。

それに合わせて、担当者が操作するPC画面も併せて開発していきます。

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

#コロナ禍だから何かできることをー　自宅療養者連絡ツール　ー
->>[【第一回】実装イメージ図と動画](https://qiita.com/STYLE-D/items/743bbecae1c52be15505)
[【第二回】LINEからデータを取得して返すまでの流れ](https://qiita.com/STYLE-D/items/9e0addd8df44be8590b7)
[【第三回】LINEからデータベースまでの流れ](https://qiita.com/STYLE-D/items/345e9142948c00330e71)
[【第四回】データベースへの更新までの流れ](https://qiita.com/STYLE-D/items/8af17d7f94f5c351ede0)
[【第五回】ユーザー登録の仕組み-LINEbotの設定部分](https://qiita.com/STYLE-D/items/a745bd5faeb68caa1d7c)
[【第六回】ユーザー登録の仕組みLIFFで表示する画面の開発](https://qiita.com/STYLE-D/items/321038c8028eb9e9231f)
[【第七回】データベースの構造](https://qiita.com/STYLE-D/items/71085dc9a04042f33f0e)
[【第八回】WEB画面上でできる機能](https://qiita.com/STYLE-D/items/c32e9098a3948e8f32f2)
[【第九回】まとめ](https://qiita.com/STYLE-D/items/77eb6a8e61ae2201565f)
[M1 mac] command not found brew

M1 macに変えた途端にこのエラーが出てしまい``` command not found brew```と出てしまい、エラーが出てしまいました。

このエラーを解決の仕方はパスを通してあげればいいだけです（これ以外にも原因があるかもしれませんが私はこのやり方で解決しました！）

まずはパスの確認をします。

```
echo $PATH

//実行結果
/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
```

このように```/opt/homebrew/bin```と記述されてればいいのですが私の場合はこのような表示になっておらずこれが原因だったようです。

まずはshellコマンドを実行して自分のシェルを確認しましょう！

```
echo $SHELL

//実行結果（下記のどちらかが表示されるはず。）
~/.zshrc
~/.bash_profile
```

上記に表示されたファイルを```vi```コマンドで開いて下記のようにパスの設定をします。

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

あとは```source```コマンドで設定した内容を読み込んであげれば大丈夫なはずです！

<h1>余談</h1>
そもそもなんでこんなことが起こったのかというとどうもm1になってからintelの時のインストール先のディレクトリ先が変わってしまったのが原因らしいです。
【Laravel6】Seederで一度に複数テーブルへダミーデータ投入

バージョン：Laravel 6.20.32

FactoryとSeederを使って一度に複数テーブルにダミーデータを投入する。
Factoryでfakerを使ってランダムにダミーデータ生成、Seederでそれを実行。
さらにそれをDatabaseSeederでループして実行。

ordersテーブルとorders_detailsテーブルの2つのテーブルに対して、一度にダミーデータを入れてみる。

## FactoryとSeederの用意
### ordersテーブル
OrderFactory.php

```
<?php

/** @var \Illuminate\Database\Eloquent\Factory $factory */

use App\Models\Order;
use Faker\Generator as Faker;

$factory->define(Order::class, function (Faker $faker) {
    return [
        'order_name01' => $faker->lastName,
        'order_name02' => $faker->firstName,
        ...
    ];
});
```

OrderSeeder.php

```
<?php

use Illuminate\Database\Seeder;

class OrderSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        factory(App\Models\Order::class, 1)->create();
    }
}

```

### order_detailsテーブル
OrderDetailFactory.php

```
<?php

/** @var \Illuminate\Database\Eloquent\Factory $factory */

use App\Models\OrderDetail;
use App\Models\Order;
use Faker\Generator as Faker;

$factory->define(OrderDetail::class, function (Faker $faker) {
    return [
        'order_id' => Order::max('id'), // ordersテーブルのidの最大値
        'product_id' => $faker->numberBetween(1,5),
        ...
    ];
});
```

OrderDetailSeeder.php

```
<?php

use Illuminate\Database\Seeder;

class OrderDetailSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        factory(App\Models\OrderDetail::class, 2)->create();
    }
}
```

OrderDetailSeeder.phpに関しては2回実行としているので、ordersテーブルの1レコードあたり、order_detailsテーブルには2レコード作成される。

## DatabaseSeeder.phpの記述
DatabaseSeederにて、makeOrderというメソッドを作り、それを50回実行するようにする。
makeOrderメソッドでは、OrdesSeederとOrderDetailSeederを呼び出す。
結果、ordersテーブルには50レコード、order_detailsテーブルには100レコード作成される。

```
<?php

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{

    /**
     * Seed the order relation database.
     *
     * @return void
     */
    public function makeOrder(int $count){
        for ($i = 0; $i < $count; $i++){
            $this->call([
                OrderSeeder::class,
                OrderDetailSeeder::class,
            ]);
        }
        return;
    }

    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        $this->makeOrder(50);
    }
}

```

## Seederの実行
artisanコマンドでDatabaseSeederを実行。

```
php artisan db:seed
```
Rails-ERDの使い方

#Rails-ERDとは
railsを使ってER図を自動生成するものです。

＊ER図とは
ER図（Entity Relationship Diagram）と言ってデータベースを考える際の設計図みたいなものです。
ER図を作成することにより、データベースの関係を図にまとめてわかりやすくなります。

詳しくは下の資料からご覧ください。
https://it-koala.com/entity-relationship-diagram-1897#ER

#Rails-ERDの導入法
まずは***Graphviz（グラフビズ）***というグラフ描画ツールを導入します。
Homebrewで導入する場合は下のコマンドを使います。

```
$ brew install graphviz

```
この後Gemfileの中に導入します。

```Gemfile

group :development do
  gem "rails-erd" # 追加 
end

```
この後、bundle installで導入をします。

#ER図を出力

以下のコマンドを使います。

```
$ bundle exec erd 
```

これでER図が出力されます。

erd.pdfができるのでここからER図を確認できます。

⚫︎参考資料
https://tanarizm.com/rails-erd
バッチファイルで、tail -fのようにログを監視する（PowerShellを使用）

Y子です。

ログファイルなどのテキストファイルを常時監視したい場合、UNIX/Linuxの世界では `tail -f` という便利なツールがありますが、Windowsでも `PowerShell` を使えば同じことが簡単に実現できてしまいます。
バッチファイルにしておけば、毎回コマンドを調べる手間もありません。

# 概要
UNIXの`tail -f`と同じことを、Windowsの`PowerShell`を使って実現します。
ショートカットを`sendto`フォルダに置けば、右クリックで簡単に実行できます。
_【[確認環境：Windows 10 Home (Bld. 19042.1165)](https://qiita.com/koiwaiwaiko/items/ef2d457ae1e1a7c8b698 "Windows10のバージョンを確認・表記する")】_

# コード
```bat:tail_powershell.bat
powershell Get-Content -Wait -Tail 5 -Path %1
```

```:実行結果（例）
> tail_powershell.bat C:\httpd\Apache24\logs\access.log
127.0.0.1 - - [27/Sep/2021:19:02:05 +0900] "GET /htdocs/test/test.php?pref=tokyo HTTP/1.1" 200 1132638
127.0.0.1 - - [27/Sep/2021:19:02:07 +0900] "GET /favicon.ico HTTP/1.1" 404 196
127.0.0.1 - - [27/Sep/2021:19:02:27 +0900] "GET /htdocs/test/test.php?prefj=%E6%9D%B1%E4%BA%AC%E9%83%BD HTTP/1.1" 200 30451
127.0.0.1 - - [27/Sep/2021:19:24:49 +0900] "GET /htdocs/photos/album.php HTTP/1.1" 401 381
127.0.0.1 - - [27/Sep/2021:19:24:49 +0900] "GET /htdocs/photos/album.php HTTP/1.1" 200 707
127.0.0.1 - - [27/Sep/2021:19:24:49 +0900] "GET /favicon.ico HTTP/1.1" 404 196
```
（※上記例のログはてきとうです…）
バッチファイルの第1引数（`%1`）を`-Path`に渡すことで、ログファイルを開いています。
`-Tail`に渡している数字は、最初に開いたときに表示する行数です。この数字に関係なく、最新のログがリアルタイムに追加表示されていきます。

# 使い方
いろいろな使い方があると思いますが、下記に例を紹介します。

* 上記のバッチファイルに、マウスでログファイルをドロップする
* SendToフォルダ（「ファイル名を指定して実行」に`shell:sendto`で開く）に、上記バッチファイルのショートカットを置き、右クリックメニューの「送る」からログファイルを開く
* 拡張子「log」のファイルを、上記バッチファイルに関連付け、ダブルクリックで開く

# おわりに
ログを出力するソフトを作ったり、運用時にログを監視する際に、便利な技です。
tailしてくれるフリーソフトもありますが、この方法で全く支障ない気がします。
AtCoder Beginner Contest 210

##[A - Cabbages](https://atcoder.jp/contests/abc210/tasks/abc210_a)

O(N)

```C++:C++
#include <bits/stdc++.h>
 
#define rep(i,n) for(int i=0; i<(n); ++i)
#define fixed_setprecision(n) fixed << setprecision((n))
#define execution_time(ti) printf("Execution Time: %.4lf sec\n", 1.0 * (clock() - ti) / CLOCKS_PER_SEC);
#define pai 3.1415926535897932384
#define NUM_MAX 2e18
#define NUM_MIN -1e9
 
using namespace std;
using ll = long long;
using P = pair<int,int>;
template<class T> inline bool chmax(T& a, T b){ if(a<b){ a=b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b){ if(a>b){ a=b; return 1; } return 0; }

int main() {
    int N, A, X, Y;
    cin >> N >> A >> X >> Y;

    int res=0;
    rep(i, N){
        if(i<A) res+=X;
        else res+=Y;
    }
    cout << res << endl;

    return 0;
}
```

##[B - Bouzu Mekuri](https://atcoder.jp/contests/abc210/tasks/abc210_b)

O(N)

```C++:C++
#include <bits/stdc++.h>
 
#define rep(i,n) for(int i=0; i<(n); ++i)
#define fixed_setprecision(n) fixed << setprecision((n))
#define execution_time(ti) printf("Execution Time: %.4lf sec\n", 1.0 * (clock() - ti) / CLOCKS_PER_SEC);
#define pai 3.1415926535897932384
#define NUM_MAX 2e18
#define NUM_MIN -1e9
 
using namespace std;
using ll = long long;
using P = pair<int,int>;
template<class T> inline bool chmax(T& a, T b){ if(a<b){ a=b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b){ if(a>b){ a=b; return 1; } return 0; }

int main() {
    int N;
    cin >> N;

    string S;
    cin >> S;

    int res=0;
    rep(i, N){
        res++;
        if(S[i] == '1') break;
    }

    if(res%2==1) cout << "Takahashi" << endl;
    else cout << "Aoki" << endl;

    return 0;
}
```

##[C - Colorful Candies](https://atcoder.jp/contests/abc210/tasks/abc210_c)

O(N)
O(N)で処理を行うためには、pushされる要素とpopされる要素をmapで管理します。
現在の種類集をカウントし、最も大きいカウントを保持することで解答を得られます。

```C++:C++
#include <bits/stdc++.h>
 
#define rep(i,n) for(int i=0; i<(n); ++i)
#define fixed_setprecision(n) fixed << setprecision((n))
#define execution_time(ti) printf("Execution Time: %.4lf sec\n", 1.0 * (clock() - ti) / CLOCKS_PER_SEC);
#define pai 3.1415926535897932384
#define NUM_MAX 2e18
#define NUM_MIN -1e9
 
using namespace std;
using ll = long long;
using P = pair<int,int>;
template<class T> inline bool chmax(T& a, T b){ if(a<b){ a=b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b){ if(a>b){ a=b; return 1; } return 0; }

int main() {
    int N, K;
    cin >> N >> K;

    vector<int> A(N);
    rep(i, N) cin >> A[i];

    map<int, int> mp;
    int res=0;
    int res_max=0;
    for(int i=0; i<N; i++){
        if(mp[A[i]]==0) res++;
        mp[A[i]]++;
        if(i>=K){
            mp[A[i-K]]--;
            if(mp[A[i-K]]==0) res--;
        }
        res_max = max(res, res_max);
    }
    cout << res_max << endl;

    return 0;
}
```
【Laravel】すでに作成済みのテーブルからマイグレーション作成

すでに作成済みのテーブルからLaravelのマイグレーションファイルを作る方法。
[migrations-generator](https://github.com/oscarafdev/migrations-generator)を使用する。
Laravel 6/7/8に対応。

## composerのrequireコマンドでパッケージを追加
composerでrequireコマンドを実行。

```
composer require "oscarafdev/migrations-generator" --dev
```

## migrations-generatorでマイグレーションを作成

すべてのテーブルからマイグレーションを作成

```
php artisan migrate:generate
```

指定したテーブルからマイグレーションを作成（複数指定可能）

```
php artisan migrate:generate table1,table2,table3,table4,table5
```

特定のテーブルを除外することも可能

```
php artisan migrate:generate --ignore="table3,table4,table5"
```

デフォルトではMySQLなので、他を使用の場合は、オプションで指定する。

```
php artisan migrate:generate --connection="connection_name"
```

その他、気になったらヘルプを見る。

```
php artisan help migrate:generate
```
原因結果グラフ法における制約 (Constraint)関係のチートシート

# 覚えておくべき制約の種類 (type of constraint)

[原因結果グラフ法](https://www.itmedia.co.jp/im/articles/1111/07/news199.html)の覚えておくべき制約を以下に示します。
文献によっては他のものも示されていますが、以下のものだけを憶えておけば困らないです。（これだけで同じことを表現できます。）
表記方法及び図の一部はニフティの加瀬氏が作成された[CEGTest](https://softest.jp/?page_id=13)によるものを用いています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246520/7b5ae09f-f568-cd18-8f93-f02c15cc070c.png)

# 3ノードの場合のONE制約, EXCL制約, INCL制約とデシジョンテーブル（真偽値表）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246520/d2ef3697-9a0b-4573-6a95-f28b0282f609.png)

# 3ノードの場合のREQ制約とデシジョンテーブル（真偽値表）の例

REQ制約とMASK制約の場合は方向性が意味を持つので、二つの場合の例示になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246520/53f7aef9-8d0b-d4be-066a-7a41a2036656.png)

# 3ノードの場合のMASK制約とデシジョンテーブル（真偽値表）の例

REQ制約と同じく、MASK制約の場合も方向性が意味を持つので、二つの場合の例示になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246520/e699c785-e0d3-7d37-5e6d-bee73d79df4a.png)

# 原因結果グラフ法における「制約 (Constraint)関係」の定義について

原因結果グラフ法が、その中で「制約」について特別に定義を与えるようなことはしていないようです。
この技法の外側で一般に「制約」と呼ばれるような関係が既にあり、それを分類したり扱うための方法を示すというスタンスであると解釈できます。

# 技法における「制約」の効果

- 「制約」により、あり得ない組み合わせがデシジョンテーブルに出現することを防ぐことができます。
    - 「制約」を描き込むことで、デシジョンテーブルに出てくるテスト数が減ることになります。
    - しかしそれは結果であって、減らすために「制約」を描き込むと考えるべきではありません。

# 「制約をかける」という表現

「原因ノードや中間ノードがとり得る組み合わせに制限をかけること」を「制約をかける」とも表現します。

# 「制約をかける」際に注意するべきこと

- この技法においては、結果ノードに対して制約はかけられないことに注意してください。
    - 結果に制約をかけたくなるかもしれませんが、その場合は、代わりにそれと同じ効果が得られるような別の制約を原因や中間ノードに対してかけるようにします。
- 論理関係で表されていることについて、制約関係を改めて描き込む必要はないです。
    - というか、同じことをどちらでも表現できる場合、論理関係で表すべきか、制約関係で表すべきかは、どのように実装するつもりなのかという設計によって決まることであるべきです。詳しくは長くなるので別稿に示します。

# おわりに

ONE制約, EXCL制約, INCL制約については、これ以上にあまり説明を要しないように思われます。
EXCL制約の全てが偽(F)の場合を一つの選択肢として含めることで、ONE制約に置き換える手も使えます。

一方、REQ制約とMASK制約については、もう少し丁寧に説明しておくべきことがあると思っています。それぞれにそれなりの分量が必要であり、また双方の関係性についても説明する必要があるので、それについては別稿にしたいと思います。

一通り理解した人にしかわからない内容になってしまっていると思いますが、だからタイトルがチートシートになっていると了解していただけると幸いです。
VSCodeでJavaのimport文自動整理

VSCodeでSpring開発って簡単かな？と試しにやってみたら、めっちゃ快適やん。
ソースコード保存で自動コンパイルかかるし、devtoolsのおかげでコード自動反映もできる。
しかもプラグインでSpring Bootプロジェクトのウィザードまでついてるやん。

# 本題

Java屋さん大好きEclipseなら`Ctrl` + `Shift` + `O`でimport文を自動整理してくれるけど、
VSCodeはどうやるんかいなっと。

調べたところ、
`Alt` + `Shift` + `O`
でできた。

めっちゃ似てる。ありがたい！
これは今後Java開発はVSCode推しやな。

環境構築方法も今度まとめる！
railsサーバーを停止せずにターミナルを閉じてしまった時の対処法

# ターミナルを閉じずにサーバーを止めた時
処理をしている時、サーバーを止めずにターミナルを閉じると以下のエラーが出ます。

```
Address already in use - bind(2) for "0.0.0.0" port 3000」

```

```
A server is already running. Check /Users/taro/git/hello_world_rails/tmp/pids/server.pid.
Exiting

```
のようなエラーが出ます。

この状態だと ```control + c```　でサーバーを止めても、処理は続いていることになります。

# 現在動いてるプロセスを確認する
サーバーが動いている時、```プロセスID```というものがあります。
これを下のコマンドで調べる必要があります。

```
$ lsof -i:3000

```
⚫︎補足
***3000はポート番号***です。
ポート番号の説明は下の記事から確認してください。

https://pikawaka.com/rails/rails-s/#%E3%83%9D%E3%83%BC%E3%83%88%E7%95%AA%E5%8F%B7%E3%82%92%E5%A4%89%E6%9B%B4%E3%81%99%E3%82%8B


そうすると下のような表示が出ます。

```
COMMAND   PID             USER   FD   TYPE              DEVICE SIZE/OFF NODE NAME
ruby    70515     taro    13u  IPv4  0xdf4c50ba54cadac7      0t0  TCP localhost:hbci (LISTEN)
ruby    70515     taro   15u  IPv6 0xdf4c50ba63f7e187      0t0  TCP localhost:hbci (LISTEN)

```
上のの```PID　70515```がプロセスIDです。***このIDは毎回変わります。***

# サーバーを停止する方法
下のコマンド実行します。

```
$ kill 70515

```
これで***サーバーが止まります。番号は毎回変わるので注意***してください。

もし***上のやり方で止まらない場合は-9を使ってください***。強制オプションです。
```
kill -9 70515
```

下のコマンドで止まったか確認できます。

```
$ ps -ax | grep ruby

```

# コンテナ内に入ってしまった時
今この状態です。
```
% make bash
docker compose run --rm api bash
bash-5.1# lsof -i:3000
1       /bin/bash       0       /dev/pts/0
1       /bin/bash       1       /dev/pts/0
1       /bin/bash       2       /dev/pts/0
1       /bin/bash       255     /dev/pts/0
bash-5.1# bundle exec rails s
=> Booting Puma
=> Rails 7.0.8 application starting in development 
=> Run `bin/rails server --help` for more startup options
A server is already running. Check /opt/app/tmp/pids/server.pid.
Exiting 
```
このようにrailsサーバー起動しません。その時に以下のやり方で対処しました。
まず```lsof -i:3000```の結果からは、***ポート3000を使用しているプロセスが表示されていません。***
しかし、rails sを実行した際に
```
A server is already running. Check /opt/app/tmp/pids/server.pid. Exiting
```
というメッセージが表示されており、サーバーが既に起動していると判断されています。

```
rm tmp/pids/server.pid
```
サーバーが正しく停止されなくてserver.pidファイルが残っている可能性があったので。
手動で削除してから再度rails sを試してみました。

その後に
```
docker compose down
docker compose up -d
```
などで再起動しました。後ブラウザが更新されていなかったので更新しました。(これが原因かは不明ですが)


# 参考資料

https://qiita.com/Toshimatu/items/78b5c3f8c6578d807e09

https://pikawaka.com/rails/rails-s
【python】内包表記について①(リストと辞書)[py_01_20210927]


###はじめに
pythonではリストの作成などの繰り返し処理を1行で表現できます。

###実行環境
pycharm　2021.2(python3.10)


###コード１
加算した数値の乗算したリストを作成します。通常の書き方と内包表記の違いを見ていきます。

```python
l = []
for i in range(1, 11):
    l.append(i ** 2)
print(l)
実行結果>>>[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
```

<font color="#56c502"><b>内包表記の例</b></font>

```python
[i ** 2 for i in range(1, 11)]
```

#####一応解説
rangeメソッドを使用してリストを作成。
内包表記では操作対象のリストを表す変数、また、appendメソッドを書くことなく、繰り返し対象とリストに追加される内容を記述するだけでリストを作成することができます。

###コード２
リストを組み合わせて辞書を作成します。

```python
pets = ['dog', 'cat', 'bird']
petList = {}

for pet in pets:
    petList[pet] = len(pet)

print(petList)
実行結果 >>>{'bird': 4, 'dog': 3, 'cat': 3}
```

<font color="#56c502"><b>内包表記の例</b></font>

```python
pets = ['dog', 'cat', 'bird']
{p: len(p) for p in pets}
```

#####一応解説
リストpetsの各要素を辞書のキー、要素の文字列長を値とする辞書を作成しています。


今回はここまで。
React Server Componentsとは

重いJSバンドルや、バックエンドのデータリソースへのアクセス性など、さまざまな課題を解決するためのソリューション。
簡潔に言えば、サーバ側で実行されるReactのコンポーネントです。 

Server ComponentとClient Componentをシームレスに結合させ、クライアントとサーバ側をまたがってアプリ構築ができる・・・といった説明がされています。

公式の資料は以下です、
- [公式ブログと説明動画](https://reactjs.org/blog/2020/12/21/data-fetching-with-react-server-components.html)
- [RFC](https://github.com/josephsavona/rfcs/blob/server-components/text/0000-server-components.md#capabilities--constraints-of-server-and-client-components)
- [demo project](https://github.com/reactjs/server-components-demo)


### 特徴

サーバー側で実行されるServer Componentと、クライアント側で処理されるClient Component(これまで作成していたコンポーネントと同様のもの)を組み合わせて構築します。
それぞれ`xxx.server.jsx`と`xxx.client.jsx`といった命名ルールを採っています。

- サーバ側で実行されるコンポーネントは、当然サーバーサイドの資源にアクセスできる
    - 新たにAPIエンドポイントを作ったりせず、直接DBアクセスなどができる
    - 処理された結果のコンポーネントを直列化し、ストリーミングレスポンスする
    - サーバ側コンポーネントと、その依存ライブラリはクライアント側スクリプトにはバンドルしないため、バンドルサイズが削減できる

といった特徴があります。

### SSRとの違い

SSRはレンダリング後の「HTML」をレスポンスされます。

一方、Server ComponentsではClient componentの情報とDOMツリーのようなものがJSONっぽく返ってきます。

[demo project](https://github.com/reactjs/server-components-demo)で試してみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408437/f9ee0182-242d-0a6b-124f-a826b396446e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408437/6e3dd239-5252-e8e4-b8f2-c17dd100af04.png "レスポンス部分の拡大")

このJSONっぽく直列化された情報をクライアント側でhydrate的なことをしているようですね。
サーバー側の処理では、ルートのサーバーコンポーネント以下の子要素を全てレンダリングしてレスポンスするようなことがRFCには書いてあります。

レスポンスされるのはコンポーネント情報であるため、Reactを利用してすでに画面で表示している内容とマージして、クライアント側のレンダリングを行うことができる。
このため、クライアント側で状態を維持しつつ、何度もServer Componentの再取得できる。
これがSSRとの違いのようです。

[説明動画](https://www.youtube.com/watch?v=TQQPAU21ZUw&t=1500s)でもSSRとの違いについて触れています。また、SSRとの併用についても軽く言及していました。

ちなみにこのレスポンス内容、demo projectの初期表示時で3kb強、Noteを選択時で4kb程ありました。
前述したようにルートのサーバーコンポーネント以下の子要素を全てレンダリングしているため、それなりのサイズになっているようです。
複雑なUIで適当にやると普通にAPIを使うのに比べて、通信量がかなり増えそうてしまいそうです。
（画面の一部のみ再取得できるように検討している、との話はあります）


### server componentとclient componentの制約

[RFC](https://github.com/josephsavona/rfcs/blob/server-components/text/0000-server-components.md#capabilities--constraints-of-server-and-client-components)に書かれています。
Server componentでは状態を持てない、useEffectなども使えない、Client component側ではServer componentをインポートできない・・・など、制約があるようです。
言われてみればそうでしょうね、といった感じの内容ではありますが。


サーバ側でもクライアント側でも使えるShared componentもあります。
当然、Server/Client component両方の制約が適用されます。

### 感想

webとJavaScriptは現状深い関係なので、JavaScriptだけで完結できるというメリットはありそうです。
ただ現状の情報だけだと手を出しづらい気がします。
結構複雑だし、状態管理やコンポーネント構成などもこれまでの開発とは大きく変わるような気がします。
もちろん、まだ開発段階なので今後もっと使いやすくなる可能性はありますが。

また、特に情報量の多い画面構成だと、前述したようにServer componentのレスポンスが大きくなってしまいそうなので、うまく設計してやる必要がありそうです。
その場合、キャッシュの管理も複雑になる可能性もあります。（demoではnotesの取得をキャッシュする処理が入っていました）

バックエンドの規模が小さく、動的コンテンツの表示を早くしたい・・・といった場合に適している感じでしょうか。
「シンプルなアプリなのでフロントエンド・バックエンドまとめて書きたい。JavaScriptオンリーで」なんて場合には最適になるのかもしれません。
Workato：ループ処理で実行タスク数が多くなりがちなレシピをRubyコネクターを利用して解決する

# はじめに

Workatoで件数の多いデータをループで処理しようとすると、実行タスク数が多くなってしまうという問題があります。例えば、タスクベースのプランを契約されている場合や、タスクベースではないがFair use limitに抵触するほど実行タスク数が多い状態である場合は、実行タスク数が減るようにレシピの改善が必要となります。しかし、処理や運用を工夫しても、処理対象のデータ件数が減らないということもあろうと思います。

例えば、以下のようなAというLookup Tableと、BというLookup tableが存在するとします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64876/449fff15-4c76-b3d4-969c-5579eca8fd0f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64876/0c35cde8-0abf-518e-5c1b-b54f22cb3faa.png)

これらのテーブルを比較するためのレシピを作成すると、次の通りとなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64876/a3ed074a-8a68-4ad9-8ebb-8cd74378131c.png)

本レシピを実行し、上に示したテーブル同士の比較処理を行った場合、タスク使用量は19となります。タスク使用量は、テーブルのレコード数が増えれば、その件数に合わせて増加します。つまり、データ件数が多ければ多いほどタスク使用量において不利なレシピとなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64876/123b5abe-5bbd-a794-a577-ca82e43bcc2d.png)

# 対応方法

もしノーコードに拘らなければ、Rubyコネクターを利用することで、タスク使用量を減らすことができます。
Rubyコネクターでレシピを実装した場合、次の通りとなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64876/71a5df1e-a895-ac42-c03d-121614257cd1.png)

このレシピを実行して、同様にテーブル同士の比較処理を行った場合、タスク使用量は3となります。また、このレシピの場合はデータ量にかかわらずタスク使用量は一定となります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64876/d53854c5-83d1-0539-536a-04ceb40c0eac.png)

このレシピでは、ループ処理は4ステップ目のRubyコネクター内で行われます。Rubyコネクターは、コネクター内に定義されたコードにかかわらず、実行タスク数は1タスクで済みます。これにより、使い方次第で実行タスク数を大幅に削減することが可能です。Workatoのタスク実行数にお悩みの方は是非Rubyコネクターの利用をご検討ください。

コード例は以下を参考ください。


## コード例
```ruby
diff_a = parse_json(input['diff_a'])
diff_b = parse_json(input['diff_b'])

result = []

# AテーブルとBテーブルを比較する
diff_a.each { |value|
  is_exists = false
  diff_b.each { |value2|
    if value['entry']['col1'] == value2['entry']['col1'] && value['entry']['col2'] == value2['entry']['col2']
      is_exists = true
    end
  }
  
  if ! is_exists
    # Bテーブルに存在しないレコードを出力する
    result.push({
      'email': value['entry']['col1'],
      'group': value['entry']['col2'],
      'exist_table': 'diff_a'
    })
  end
}

# BテーブルとAテーブルを比較する
diff_b.each { |value|
  is_exists = false
  diff_a.each { |value2|
    if value['entry']['col1'] == value2['entry']['col1'] && value['entry']['col2'] == value2['entry']['col2']
      is_exists = true
    end
  }
  
  if ! is_exists
    # Aテーブルに存在しないレコードを出力する
    result.push({
      'email': value['entry']['col1'],
      'group': value['entry']['col2'],
      'exist_table': 'diff_b'
    })
  end
}


{
  result: result
}
```
GraphQL-Rubyでenum(列挙型)を使う方法

# はじめに
GraphQl-Rubyでenumを使う方法についての解説です。
間違っている箇所等ございましたらコメントで指摘いただけると助かります。

# Enum(列挙型とは？？)
詳しくはこちらの記事(自分が書いたもの)に書いてあります。
https://qiita.com/nisitin/items/94720f8dae3be39ae5d2

一部抜粋して説明するとenumは[列挙型]と言われるもので[列挙型]とは何かというと、プログラミング言語やデータベース管理システムなどにおけるデータ型の一つとされています。また複数の異なる定数を一つの集合として定義するものでもあります。

# Railsのenum使うよね？？
僕は少し前にRailsのenumの使い方について学んで、そこから馬鹿の一つ覚えのようにenum使えそうじゃない？？と思うようになりました。そこでGrapqQL-Rubyを使ってapi開発をしてたときにここでも使いたい！！と思い馬鹿の一つ覚えのように使おうとしました。

そして調べてみるとenumで定義している文字列はGraphQLでは識別子として書き込まれて返ってくる値としては

```enum.rb
enum pc: { mac: 0, windows: 1 }
```
このような定義をするとgraphiqlでは0か1の値しか返ってきません。
作成者はわかるかもしれませんが、他の作業する方がいた時に毎回調べて作業するのは骨の折れる作業だと思います。

そこでこれらを解決する方法があり、それは何かというとGraphQL側にも同様にenumを定義してあげるということです。
具体的な方法はgraphql/typesの中のbase_enum.rbを継承するenumファイルを作成してあげるてそこで定義するということです。

上記の例で言うと

```pc_enum.rb
module Types
  class PcEnum < Types::BaseEnum
　　#二つ目のvalueにenumで既に設定されている文字列を定義する
　　#ここではわかりやすく一つ目のvalueを大文字で返すようにしています　　
    value "MAC", value: "mac"　
    value "WINDOWS", value: "windows"
  end
end
```
このように定義してあげて

```profile_type.rb
module Types
  class ProfileType < Types::BaseObject
    field :age, Int, null false
    filed :pc, Types::PcEnum, null true
  end
end
```
と定義してあげることでGraphQLでもenumを使って開発をすることができます！！



# 参考文献
https://graphql-ruby.org/type_definitions/enums
【新人SE】JSPの基本

#JSPの基本

##JSPとは
サーブレットクラスを記述する代わりに、**JSPファイル**を使用することで簡単になる。

JSPファイルは、リクエストされるとサーブレットクラスに変換される。
JSPを使用すると、HTMLの出力が非常に楽になる。（HTMLの中にJavaのコードを埋め込む）


#JSPの構成要素
##スクリプトレット
JSPにJavaのコードを埋め込める。
構文はこちら。

```jsp
<% Javaのコード %>
```

##スクリプト式
変数やメソッドの戻り値を出力できる。
System.out.println()と同じ役目。
基本構文はこちら

```jsp
<%= Javaのコード %>
```

##コメントアウト


```jsp
<%-- Javaのコード --%>
```


##pageディレクティブ
contextTypeやimportなど、JSPの設定を行う。

```jsp
<%@ page 属性名="値" %>
```
※Eclipseは自動で書いてくれる。


#JSPファイルの実行
##JSPファイルの保存場所
保存先はHTMLファイルと同じな場所に保存する。
適用されるURLもHTMLと同じ。

```
http://<サーバ名>/<アプリケーション名（プロジェクト名）>/<ルートからのパス>
```

## JSPファイルの500ページ
基本的にページに表示されているメッセージを参照する。
JSPファイルの内容は、変更したら次のリクエストからすぐに結果に反映される。
サーバの再起動は不要です。
Dorakovのオプションには気を付けろ！

![drakov-2.0.1](https://img.shields.io/badge/drakov-2.0.1-brightgreen)

API blueprintでモックしたい時にお世話になるDrakovですが、オプションがカオスなので（バージョンアップでなおるかもですが）現状注意が必要なものだけメモっておきます。

## --public オプション
docker上で起動したdrakovを、PCのターミナルからlocalhostでアクセスしたい時などに使います。

`--public`だけだとpublicオプションが有効になりません。。

```bash
# NG
$ drakov --public -f api/*.apib 
# OK
$ drakov --public true -f api/*.apib 
```

`--public true`とすることで、起動時に`PUBLIC MODE running publicly`と出力され、有効になります。

## -f オプション

読み込むapibを指定するオプションですが、複数ファイルを読み込む時注意が必要です。
下記で起動すると、`# Data Structures`を別ファイルに宣言している場合、起動できません。

```bash
$ ls -1 api/*.apib
data.apib   <- ここに共通のData Structuresを記載しているとする
group01.apib
group02.apib
. . .

# NG
$ drakov -f api/*.apib

# OK
$ drakov -f <(cat api/*.apib)
```

そういう場合は、bash力で切り抜けれます。

## -D オプション

`/drakov`にアクセスすると、利用可能なエンドポイントの一覧を表示してくれるオプションです。


```bash
# NG
$ drakov -D -f api/sample.apib 
$ drakov -D true -f api/sample.apib 

# OK
$ drakov -D 1 -f api/sample.apib 
```

信じられないかと思いますが、これでやっと正常に動作します。

さらに複数ファイルを読み込んでいる場合は、-f で横着をすると一覧表示してくれません。
一旦一時ファイルに出力してから指定してあげてください。

```bash
# NG
$ drakov -D 1 -f <(cat api/*.apib)

# OK
$ cat api/*.apib > /tmp/all.apib
$ drakov -D 1 -f /tmp/all.apib
```
WordPress公式Dockerイメージセッティング個人用メモ

# 前提
最近（といってももう4ヶ月くらい前から）結構ドラスティックに変化している感があり忘れるので
WordPressの公式Dockerイメージの使い方をざっくりメモしておきます。

# 構成
プロキシ(nginx)コンテナ → WPコンテナ → MySQLコンテナ → データ永続化コンテナ（BusyBox)
プロキシは本番と同じURLで開発したいので設定しています。

そしてローカルにwp-contentディレクトリ以下のファイル、etcディレクトリ以下サーバ設定関連ファイル
etcphpディレクトリ以下PHP設定関連ファイルをバインドマウントしています。

またdocker-entrypoint.shに独自のシェルスクリプトを追加して
wp-cliインストール、wordpressインストール、パーマリンク設定、パーミッション設定などを自動化しています。
（プラグインインストールアップデートも組み込んでいたが毎回ダウンロードするのが重いのとバグることが多かったので止めてあらかじめローカルに用意してバインドマウントする形にしました。）
この自動化をすることでdocker compose up -dしたらすでにwpサイトが立ち上がっている状態で起動できます。

# ざっくりの使いかた
[公式のGitリポジトリから](https://github.com/docker-library/wordpress/tree/9954966feffdaf39082609816f896c2e3f75f0db/latest/php7.4/apache)
3つのファイルをダウンロードしてローカルのDockerディレクトリ（任意の場所）に配置します。
※私の場合ここでdocker-entrypoint.shにシェルスクリプトを追記します。

[公式のDockerHub](https://hub.docker.com/_/wordpress) を参考に
docker-compose.ymlを作成します。

# 変更されたポイント
たしか4ヶ月前くらいに突如現れたwp-config-docker.phpというファイルですが以前はありませんでした。
これは何をしてくれているかというとdocker-compose.yml内でmysqlのデータベースユーザー名や
データベースパスワードなどの情報をwp-config.phpで自動的に読み込めるようにしてくれています。
なのでこのファイルは**Dockerfileやdocker-compose.ymlと同じ階層に置いておかなければなりません。**

またdocker-compose.yml内で
**WORDPRESS_DB_HOST
WORDPRESS_DB_USER
WORDPRESS_DB_PASSWORD
MYSQL_DATABASE
MYSQL_USER
MYSQL_PASSWORD**
が指定できるようになったのもこの変更があったタイミングだと思います。
以前は立ち上げ時は手動かブラウザかシェルスクリプトかという感じで
WORDPRESS_DB_PASSWORD
MYSQL_PASSWORD
だけ設定していました。

# 所感
docker-compose.ymlで指定できるのはかなり楽で良いと思います。
日本語情報がまだこの辺は少ないのと個人的備忘録として残しておきます。