OmniAICreator/Qiita-1.07M huggingface dataset:
エアコンについて

https://www.youtube.com/watch?v=EsSEFjrDLMU&ab_channel=SHNHIRA

冷房始動時の消費電力経緯です。
一気に上がらずマイルドに上がるところが凄い。
コンプレッサ始動時は20A位行くのかなと思ってました。

200Vのエアコン、暖房運転で外気温が低い時は30A位消費します。うちだけ停電になったので電力会社に調べてもらったら瞬間50Aを超えてて40A契約なのでブレーカ落ちました。
<HR>
これは違うエアコンですが前面(上部)カバー外して清掃もしてみました。

:::note alert
1.コンセントは抜いてください.
2.清掃時に電子部品に水が掛からないようにして下さい.
3.全て自己責任となります.
:::
![346268231_1045502613502342_7106061804863682010_n.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821882/7018c9e9-b2fc-0f22-952f-f2607ffa8c5a.jpeg)
・10年目にしては綺麗な方
![346612543_196337813272251_4486199857169799740_n.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821882/ea0766f6-19a5-6119-9d83-5ef3003112e9.jpeg)

- 上部カバーを外すと清掃が格段にし易くなる。
- 左右、上にはネジ止めはありません。吹き出し口の所か、フィルタを外す時に開けるカバーを開けるとあります。自宅にある、4社5基のルームエアコン全て清掃メンテの為、バラしましたが同様でした。時間も1-2分です。
- 更にやるならドレンパンも外します。これは機種によっては難易度が高い場合があります。この写真の日立製の機器は簡単にできました。
- もっとやるならシロッコファン自体取り外しますがここまでしなくても季節毎に適当に清掃していれば不要でしょう。
- また個人的見解ですが自動清掃機能付きは価格が上がるし、メンテもやり辛くなるのでお勧めしません。
データベース設計の3層スキーマとは？

データベースの3層スキーマは、情報システムのデータ管理の構造と組織を3つの異なる視点でモデル化する方法を示しています。これにより、物理的なデータの実際の配置とアプリケーションやユーザーのデータの見方との間の独立性が保たれます。

1. **外部スキーマ (External Schema)**:
    - **定義**: 外部スキーマは、終端ユーザーや特定のアプリケーションのためのデータベースのビューを提供します。
    - **特徴**: この層は、システムの複数のユーザーが求める異なるデータの表示やアクセス方法を定義します。一つのデータベースには、多くの外部スキーマが存在することができます。
    - **目的**: 終端ユーザーやアプリケーションが必要とするデータの形式や表示方法をカスタマイズして提供します。

2. **概念スキーマ (Conceptual Schema)**:
    - **定義**: 概念スキーマは、データベースの全体的な論理的構造を示しています。
    - **特徴**: この層は、データベース内のすべてのエンティティ、関連、制約などの論理的な構造と関係を定義します。物理的な詳細や特定のユーザーのビューは無視されます。
    - **目的**: データの論理的構造と組織を中立的な視点で表現し、データの整合性と意味を維持します。

3. **内部スキーマ (Internal Schema)**:
    - **定義**: 内部スキーマは、データが物理的にストレージ上にどのように格納されるかを示しています。
    - **特徴**: この層は、物理的なデータの配置、インデックスの使用、アクセスパス、データの物理的な表現などの実際のデータの格納方法を定義します。
    - **目的**: データの効率的な格納とアクセスを実現するための物理的な詳細を管理します。

この3層スキーマのアプローチの利点は、物理的なデータの構造の変更がアプリケーションのロジックやユーザーのビューに影響を与えることなく行える独立性を提供することです。

## なぜ、３層に分けるのか？

3層スキーマに分ける理由は、データベースの設計、実装、および運用における多くの課題と要件を効果的に対処するためです。具体的には、以下のような利点や目的が挙げられます：

1. **独立性の確保**:
    - **物理的・論理的独立性**: 3層スキーマのアプローチを使用すると、データの物理的な格納方法の変更がアプリケーションやユーザービューに影響を与えることなく行えるようになります。この独立性は、データベースの物理的な変更や最適化を容易にし、アプリケーションの変更を最小限に抑えます。
    - **外部・概念的独立性**: ユーザーやアプリケーションが必要とするビューを、データベースの全体的な構造から独立して定義できます。

2. **柔軟性**: 組織の要件や状況が変わるにつれて、データの物理的な格納方法や特定のユーザービューを変更する必要が生じることがあります。3層スキーマは、これらの変更を柔軟に対応できるようにしています。

3. **抽象化**: 3層スキーマは、データベースの複雑さを異なるレベルの抽象化で管理します。これにより、異なる利害関係者（例: DBA、アプリケーション開発者、エンドユーザー）が、それぞれの関心事に焦点を当てて作業を進めることができます。

4. **セキュリティ**: 外部スキーマを使用することで、ユーザーやアプリケーションがアクセスできるデータの部分を制限することができます。これにより、不要なデータへのアクセスを防ぐことができ、セキュリティを向上させることができます。

5. **整合性**: 概念スキーマでは、データベース全体の論理的構造を定義します。これにより、データの整合性、関連性、および制約を一貫して管理することができます。

このような利点を考慮すると、3層スキーマは、データベースの設計と管理の複雑さを取り扱う上で非常に効果的な方法と言えます。
「別のプログラムがこのフォルダーまたはファイルを開いているので、操作を完了できません。」を対処

## はじめに
Visual Studioでサーバーを起動後、プロジェクトを削除しようとしたときに毎回「別のプログラムがこのフォルダーまたはファイルを開いているので、操作を完了できません。」が表示されたため、その対処法について備忘録として残しておこうと思います。

## 参考記事
https://qiita.com/fuk101/items/a862b89380ae75339f37

## 環境
- Windows 10 Pro

## 問題
- 不要になったプロジェクトを削除しようとしたときにこういったダイアログが表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711955/43492488-41bc-01c5-fa38-9533c5ec2d2f.png)

## 対処法
- 標準で搭載されているリソースモニターを使用するため、Windowsの検索ボックスに`resmon`と入力して実行する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711955/69351888-dca2-aba1-5fff-463d2f6f3308.png)

- 以下のようなアプリが起動するはず。。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711955/0e07b3b0-16b2-f932-9ca8-c86e796c8c17.png)

- 原因となっているフォルダ名を検索ボックスに入力して、表示されているプロセスを終了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711955/e59f0152-f0c8-92a9-a895-d6b2d7e031d8.png)

これで、削除・移動ができるようになる。。
ほとんどないとは思いますが、仮に削除・移動ができなかった場合は再起動が必要かもです
Pythonモジュールをインストールせずに試す方法: 使い捨て環境を手軽に構築


## 背景
GitHubに公開されているPythonプログラムを手軽に試したいと思ったことはありませんか？でも、そのためだけにたくさんのモジュールを自分のコンピュータにインストールしたくないこともあるでしょう。また、使い捨てのDocker環境を作成するのも手間がかかります。そんな場合、どうすれば良いのでしょうか？

## 解決策
Pythonの`venv`機能を使って、プロジェクトごとに独立したPython環境を手軽に構築できます。これにより、必要なモジュールを自分のコンピュータ全体にインストールする必要はありません。

## 手順
以下は、使い捨て環境を構築する手順です。以下のディレクトリ構造を仮定します。

```
    ~/program% ls
    auth/               middlewares/        pyrightconfig.json  routes/
    logger.py           models/             repository/         supabase/
    main.py             requirements.txt    utils/
```

1. まず、このプロジェクト専用の仮想環境を`venv`を使って構築します。例えば、`myenv`という名前の環境を作成すると、同名のディレクトリが生成されます。

```
    ~/program% python3 -m venv myenv

    ~/program% ls
    auth/               middlewares/        pyrightconfig.json  routes/
    logger.py           models/             repository/         supabase/
    main.py             myenv/              requirements.txt    utils/
```

２. `myenv`ディレクトリ内の`activate`ファイルを`source`コマンドで指定（Windowsの場合はスクリプトを実行）すると、仮想環境に入ることができます。

```
    # Linux/Mac
    ~/program% source myenv/bin/activate
    # Windows
    myenv\Scripts\activate

    (myenv) ~/program%
```

３. 仮想環境に入ると、プロンプトが `(myenv)` と変わります。この状態で`pip install`を実行すると、モジュールはこの仮想環境にのみインストールされます。

```
    (myenv) ~/program% pip3 install -r requirements.txt
```

４. 仮想環境から抜ける場合は、`deactivate`コマンドを実行します。

 ```
    (myenv) ~/program% deactivate

    ~/program%
```

これで、Pythonモジュールをプロジェクトごとに独立した環境で管理できるようになり、不要な環境へのインストールを回避できます。
Subversion コミットの流れ

こんにちは！

最近ではエンジニアの開発業務でGitHubを使うことが増えてきたと思いますが、まだSubversionを使用している人もいるかと思うので、ここにSubversionの基本的なコミット方法を載せたいと思います。

まずは現在の状況を確認

````
svn status
````

次にファイルをコミットします。

````
svn commit [/ファイル名]
````

````
i
````

をクリックしてコミットの際のコメントを記入します。

そのあとescをクリックして記入を完了し、

````
:w
````

を打ち込んでEnter。

最後に、

````
:q
````

を打ち込むと、パスワードの入力が求められるので、パスワードを入力して完了です。

念のため、再度ステータスを確認してビジョンが最新であればコミット完了です。

今回はだいぶ記事が短くなってしまいましたが、これで終わりにしたいと思います:sweat:

ありがとうございました！
Promiseとかasync,awaitとかtry,catch

### Promise/then か async/await　か
- 非同期処理で、処理を待ってから次のコードを実行したいのは同じ
- 処理が完了を待ってから then を使って次の処理へ進むように記述するか、処理を完了を待っててほしい部分に await を使って記述するかの違い

### ブラウザで試してみて
`やりたいこと` 1 ->（2秒後に）2 -> 3 の順番で表示させたい
- Promise/then を使ったパターン
```JavaScript
console.log('1')

new Promise((resolve, reject) => {
    setTimeout(() => {
        console.log('2')
        resolve()
    }, 2000)  
}).then(() => {
    console.log('3')
})
```

- async/await を使ったパターン
```JavaScript
console.log('1')

const show = async() => {
    await new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log('2')
            resolve()
        }, 2000)  
    })
    console.log('3')
}
show()
```

### try/catch って何をやってるの？
- 例外処理を記述したい時に使う
- tryブロックで何かしらのエラーが起きた時、rejectが呼ばれた時にcatchブロックに進む

### async/await を使う時に、try/catch を使う
`やりたいこと` 1 ->（2秒後に） resultの結果がtrueだったら 2, resultの結果がfalseだったら 10000, -> 3 の順番で表示させたい
```JavaScript
const result = true
console.log('1')

const show = async() => {
    try { // ｔｒｙブロック内で例外が発生したら(rejectが呼ばれたら)catchブロックへ進む
        const res = await new Promise((resolve, reject) => {
            setTimeout(() => {
                if (result) {
                    resolve('2') // 処理の返り値が'2'になる -> resに'2'が代入される
                } else {
                    reject('10000')
                }
            }, 2000)  
        })
        console.log(res) // resolveの返り値が'2'でresに'2'が代入されるためtryブロックが正常に動作したらlogに'2'が表示される
    } catch(e) {
        console.log(e) // rejectが呼ばれた場合は引数に値が渡ってくる
    } finally {
        console.log('3')
    }
}
show()
```

```JavaScript
const result = true
console.log('1')

new Promise((resolve, reject) => {
    setTimeout(() => {
        if (result) {
            resolve('2')
        } else {
            reject('10000')
        }
    }, 2000)  
}).then(val => {
    console.log(val)
}).catch(e => {
    console.log(e)
}).finally(() => {
    console.log('3')
})
```
Terraform で Azure API Management を何度も作り直す時に便利なパージを入れてみた

Azure API Management など、いくつかの Azure リソースは、リソースを削除して一定の期間 Soft Delete な状態になります。おそらく、誤って当該リソースを削除した時にセキュリティ的な観点で、元に戻す必要があるからだと思われます。同じリソース名でクリーンな環境を再度作成したい場合は、Purge してから作成することになります。そこで今回は、Terraform の設定で、リソース削除時に Purge まで行い、再度同じリソース名で作成できるか試してみました。

## 検証用 Terraform コード

```terraform:main.tf
provider "azurerm" {
  features {
    api_management {
      purge_soft_delete_on_destroy = true
    }
  }
}

resource "azurerm_resource_group" "rg" {
  name     = "mnrapifn-rg"
  location = "japaneast"
}

resource "azurerm_api_management" "apim" {
  name                = "mnrapifn-apim"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
  publisher_name      = "test"
  publisher_email     = "test@example.com"
  sku_name            = "Consumption_0"
}
```

## Terraform を実行して動作確認

```bash:bash
$ terraform init

$ terraform plan

$ terraform apply -auto-approve

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

$ terraform destroy -auto-approve

Destroy complete! Resources: 2 destroyed.

$ terraform apply -auto-approve

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
```

## 参考

https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/guides/features-block
【解決】Failed to find Build Tools revision 34.0.0 rc3 

javaプロジェクトとkotlinプロジェクトを統合させるため、環境構築を行なっていた。

kotlinのバージョンを上げたところ

Failed to find Build Tools revision 34.0.0 rc3 のエラーが出た。

Build-Toolsの34.0.0 rc3というバージョンがインスールされていないことが原因らしい。

Tool>SDK Manager>Language&Frameworks>Android SDK>SDK Tools

と開いていって、必要なBuild-Toolsのバージョンにチェックを入れてOKでインストール。

![名称未設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3562838/533bb92a-d7ee-9ced-8f76-083928ca9a72.png)

無事エラー解消;
ASP.NET Core Blazorについて

## 参考記事
https://blogs.jp.infragistics.com/entry/Blazor-Server-vs-Blazor-WebAssembly-Just-the-Facts

https://learn.microsoft.com/ja-jp/aspnet/core/blazor/hosting-models?view=aspnetcore-7.0

## Blazorとは
- 様々な方法でホストできるWeb UIコンポーネント(Razorコンポーネント)を構築するためのWebフレームワーク
- **Razorコンポーネントはサーバー側ではASP.NET Coreで実行できるのに対し、クライアント側ではWebAssemblyベースの.NETランタイム上のブラウザ(Blazor WebAssembly、Blazor WASM)で実行できる**
- ネイティブモバイルアプリやデスクトップアプリでRazorコンポーネントをホストすることもでき、ホスティングモデルが何であっても、Razorコンポーネントを構築する方法は同じ(ソースの流用が可能)
- WebAssemblyはJavaScriptとは異なり、CPU上でネイティブに近い速度で実行されるコンパイル済みソフトウェア


## Blazor Server
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711955/7c05c82f-03ec-f849-5ff5-14c638181f44.png)

- Blazor Serverホスティングモデルを使用すると、コンポーネントはASP.NET Coreアプリ内からサーバー上で実行される。
- UIの更新、イベント処理、JavaScriptの呼びだしは、WebSocketプロトコルを使用して、SignalR接続経由で処理される
- Blazor Serverホスティングモデルの利点
    - ダウンロードサイズがBlazor WebAssemblyホスティングモデルの使用時よりも小さく、アプリの読み込み時間が大幅に短縮される
    - このアプリでは、.NET Core APIの使用を含め、サーバーの機能を最大限に活用できる
    - サーバー上の.NET Coreはアプリの実行に使用されるため、デバッグなどの既存の.NETツールは規定どおりに動作する
    - シンクライアントシステムがサポートされている。たとえば、Blazor Serverは、WebAssemblyがサポートされていないブラウザやリソースが制限されたデバイスで動作
    - アプリのコンポーネントコードを含め、アプリの.NET/C# コードベースがクライアントに提供されない
- Blazor Serverホスティングモデルの制限
    - 遅延時間が長くなる。すべてのユーザーの操作にネットワークホップが関与する
    - オフラインサポートがない。クライアント接続が失敗した場合、対話機能は失敗する
    - 多くのユーザーがアプリを拡張するには、複数のクライアント接続とクライアントの状態を処理するためのサーバーリソースが必要

## Blazor WebAssembly
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711955/7b7f7bdb-f207-f0c5-d93a-7485b40c65f6.png)

- Blazor WebAssemblyホスティングモデルは、クライアント側のWebAssemblyベースの.NETランタイム上のブラウザでコンポーネントを実行する
- Razorコンポーネント、その依存関係、.NETランタイムは、ブラウザにダウンロードされる。
- コンポーネントはブラウザUIスレッド上で直接実行される
- UIの更新とイベントの処理は、同じプロセス内で行われる。
- リソースは、静的コンテンツをクライアントに提供できるWebサーバーまたはサービスに静的ファイルとしてデプロイされる
- ホストされたクライアントアプリは、Web API、gRPC-web、SignalRなどのさまざまなメッセージングフレームワークとプロトコルを経由して、ネットワーク経由でバックエンドサーバーアプリとやり取りできる
- Blazor WebAssemblyホスティングモデルの利点
    - スタンドアロンBlazor WebAssemblyアプリの場合、アプリがサーバーからダウンロードされた後、.NETサーバー側の依存関係がないため、サーバーがオフラインになった場合でも、アプリの機能が存続する
    - クライアントのリソースと機能が完全に活用される
    - 作業がサーバーからクライアントにオフロードされる
    - スタンドアロンBlazor WebAssemblyアプリの場合、アプリをホストするためにASP.NET Core Webサーバーが必要ない
    - Content Delivery Network(CDN)からアプリを提供するなどのサーバーレス展開シナリオが可能
- Blazor WebAssemblyの制限
    - Razorコンポーネントがブラウザの機能に制限される
    - サポートされているクライアントハードウェアおよびソフトウェアが必要
    - ダウンロードサイズが大きくなり、コンポーネントの読み込みにかかる時間が長くなる
    - クライアントに送信されるコードを、ユーザーによる検査や改ざんから保護することはできない
-  Blazorでは、Ahead-Of-Time(AOT)コンパイルがサポートされており、.NETのコードをWebAssemblyに直接コンパイルできる
NotActionを用いて特定操作以外を拒否するIAMポリシーを作成する

環境構築を行う際、開発担当者にAdministrator権限が必要なことがあります。
しかし、CloudTrail等、セキュリティ関連の設定を勝手に変更されては困ります。
そこで、NotActionを用いてCloudTrailの読み取り以外の操作をすべて拒否するIAMポリシーを作成し、アタッチすることにしました。

~~~
{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "DenyCloudTrail",
			"Effect": "Deny",
			"NotAction": [　
				"cloudtrail:List*",
				"cloudtrail:Get*",
				"cloudtrail:Describe*"
			],
			"Resource": "arn:aws:cloudtrail:*:*:*"
		}
	]
}
~~~
ポイントは、以下のようにResource部分を詳細に記述することです。
~~~
"Resource": "arn:aws:cloudtrail:*:*:*"
~~~

Resource部分を"*"にすると、CloudTrail以外の全サービスの権限が明示的に拒否されるため皆さんも注意してくださいね。
~~~
"Resource": "*"
~~~
音楽付きの歌声生成モデルを作りたい。

日本の大学に通うしがない大学二年の樹と申します。
Twitterで投稿したり、GitHubにレポジトリを上げたりしてるので、いいねやスター、フォローいただけると嬉しいです。

最近、歌詞やジャンルを指定して音楽付きの歌声を生成するモデルが出てきました。
この最初は私が知る限り(他にありましたら教えてください。)では、OpenAIから出たJukeBoxです。
しかし、JukeBoxから生成された歌声は歌として歌えていない、サンプリング速度が長すぎるなどといった欠点があり、ながらく音楽付きの歌声生成モデルは無かったような気がします。

しかし、最近になりbarkを制作したSunoからchirpという音楽付きの歌声生成モデルが出ました。
サンプリング速度もJukeboxに比べ、早くなり歌詞通りに歌声を生成でき、そこから私もこの分野に興味を抱き始めこれが私もできないかと模索しています。

で、今回は私が考えた、モデルのアーキテクチャを紹介します。このモデルについてのコメントなどもいただけると嬉しいです。

![main_architecture.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2988648/d62be68d-56e1-dca2-ec3e-6aef8e20ba53.jpeg)

手書きですが、モデルアーキテクチャはざっくりとこういったもので、さらなる詳細は以下のレポジトリにまとめました。
コードもあります。
https://github.com/0417keito/UTAUTAI

まず、SPEARTTSの手法にしたがい、歌詞からセマンティックトークンを取得するモデルを構築します。
セマンティックトークはMERTと呼ばれるMLMを音楽理解のために訓練されたモデルからの表現をkmeans量子化したものを取得し、クラスタサイズは量子化器のコードブックサイズに合わせます。
そして、歌詞からセマンティックトークンを取得するモデルにはTransformerベースのデコーダーを使用し、歌詞とセマンティックトークンとのマッピングを学習します。

次に、SPEARTTSではTTSなのでトランスクリプトからセマンティックトークンを取得するのみでよかったが、音楽付きの歌声生成においては歌詞からのセマンティックトークンだけでは無く音楽からのセマンティックトークも必要では無いのかと考え、学習時には音楽から取得した、MERT unitを使用します。
しかし、推論時には勿論のことこの音楽から取得したMERT表現は使用することはできません。使用できるようにすれば、それはそれで入力された音声と歌詞をアライメントして音楽を生成するモデルに使えるかもしれませんが、今回は入力はテキストのみとしているので、PromptTTS2の手法に触発されてこの音楽から取得したMERT表現を入力されたプロンプトから生成するといったモデルを作ります。
それが、(2)のStyle Moduleです。
Style Moduleはまず、BERTによってプロンプトから取得された表現をkeyとvalueとし、学習可能なqueryによってプロンプト表現を抽出します。そして、それを条件としてVariation Netと呼ばれるTransformerベースの拡散モデルによってMERT表現というのを生成することを目指します。

このようにして得られた、セマンティックトークンを条件としてSoundstormと呼ばれる高品質な精度でセマンティックトークンからアコースティックトークンを生成するモデルによって、このタスクを満たせるのではと考えました。

しかし、このモデルにはいくつか欠点があり、歌詞からセマンティックトークンを取得するのに自己回帰モデルを、プロンプトからMERT表現を取得するのにDiffusionモデルを使用しているのでかなり生成速度が遅いです。
それを解決するのに、Consistency Modelなども視野にはいれています。

これで、以上が私が考えたモデルアーキテクチャの説明です。
コードなどはhttps://github.com/0417keito/UTAUTAI
においてあります。
ご興味いただけた方、コメントなどいただけると嬉しいです。
進捗がありましたら、次にも上げていく予定なのでよろしくお願います。
Webサーバ構築手順

# 背景
現在Windows内でLinux(Debian)を構築しその中でとあるプログラムを稼働させている。
上記プログラムをHTTPリクエスト経由で実行できるようにVM内にHTTPサーバを構築したい。

# 環境
HostPC : Windows11
VM : Debian 11.6

# 前提
- Linux環境は構築済
- 当該環境のターミナルが触れる状態である

# インストールするソフトウェア
nginx 
※apacheは使用したことがあるため、今回はnginxを触ってみる

# 構築手順
### 1. Nginxのインストールコマンドを実行する
```
$ sudo apt update
$ sudo apt install nginx
```

### 2. インストール確認
```
$ nginx -v
$ nginx version: nginx/1.18.0
```
    
### 3. 外部接続確認
Windows(ホストPC)側のブラウザからWebサーバーへアクセスしてみる。
`接続URL : http://{LinuxのIPアドレス}`
※LinuxのIPアドレスが不明な場合は以下のコマンドで調べる
`$ ifconfig`

#### ブラウザで表示されるページ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3092942/bd723fb8-5995-b361-5425-2f66631d8496.png)

### 4. 自動起動設定
VM起動時にNginxも起動するように設定

4.1 自動起動設定を確認する。※enableの場合は4.2以降の実施はしなくてもよい。
```
$ systemctl is-enabled nginx.service
$ disabled
```

4.2 enableへ変更するコマンドを実行する
```
$ sudo systemctl enable nginx.service
Synchronizing state of nginx.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable nginx
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /lib/systemd/system/nginx.service.
```

4.3 再度自動起動設定を確認する。※enableに変更されていればOK
```
$ systemctl is-enabled nginx.service
$ enabled
```

これで簡易的ではありますが、Webサーバ構築については以上です。

### 終わりに
第一弾として、構築までの手順を記載してみました。
業務ですでに構築済のWebサーバをさわったことはありましたが、構築したことはなかったのでこの機会に実施してみましたが、思いの他簡単でしたね。
※細かい設定等をするとまた違うとはおもいますが、、

背景にも記載した通り、最終的に実施したいことはHTTP経由でLinux内の指定したプログラム
を実行することなので、うまくいけば次回はそこまで記載してみたいと思います。

### 2023/10/29 追記
この後実施したいことをすでに記載されている記事がありました。
https://qiita.com/haniokasai/items/3d7e1e1c74e704217523

後、調べていくうちに思いましたが、今回やりたかったことに対していえばブラウザの画面表示が必要ないので、NodeのExpress等でAPIサーバーを構築してあげる方がよかったですね。
勉強になりました。

ではまた機会があればノシ
Promiseとかresolveとかthenとか

### 同期処理とは？
上から順番に処理が実行される、いわゆる通常の処理。
前の処理が終わったら、次の処理が実行される。
前の処理が実行されないと次の処理が実行されない。

### 非同期処理とは？
上記の逆

### 処理の完了を待ってから次の処理へ進みたい。どうすればいい？
`やりたいこと` 1 ->（2秒後に）2 -> 3 の順番で表示させたい
```JavaScript
// NGパターン
console.log('1')

setTimeout(() => { // ただのsetTimeout関数が呼ばれているだけで、処理の完了を待って！って記述はない
    console.log('2')
}, 2000)

console.log('3')
```

```JavaScript
// NGパターン
console.log('1')

new Promise(() => { // 非同期っぽく書いてるけどresolveを書いてないから処理が完了したタイミングが明示できない
    setTimeout(() => {
        console.log('2')
    }, 2000)  
}) // thenで繋げないと処理が完了した後に実行したい指示が明示できない

console.log('3')
```

```JavaScript
// NGパターン
console.log('1')

new Promise((resolve, reject) => {
    setTimeout(() => {
        console.log('2')
        resolve()
    }, 2000)  
}) // resolveを書いてるけど、完了後に'3'を表示したいならthenで繋いで処理を記述しないと意図通りの動作はしない

console.log('3')
```

```JavaScript
// OKパターン
console.log('1')

new Promise((resolve, reject) => {
    setTimeout(() => {
        console.log('2')
        resolve()
    }, 2000)  
}).then(() => {
    console.log('3')
})
```

### 処理の結果次第で出力する内容を変えたい。どうすればいい？
`やりたいこと` 1 ->（2秒後に） resultの結果がtrueだったら 2, resultの結果がfalseだったら  10000,  -> 3 の順番で表示させたい
```JavaScript
const result = true
console.log('1')

new Promise((resolve, reject) => {
    setTimeout(() => {
        if (result) {
            resolve('2')　// resultがtrueだったらthenに繋いで、thenの引数には'2'が渡る
        } else {
            reject('10000')　// resultがfalseだったらcatchに繋いで、catchの引数には'10000'が渡る
        }
    }, 2000)  
}).then(val => {
    console.log(val)
}).catch(e => {
    console.log(e)
}).finally(() => {
    console.log('3')
})
```
PythonでTLEした時に、Pythonだから無理と諦める前に試す事

PyPyを使ってます。
オーダーとしては、問題ないアルゴリズムなのに、TLEになってしまった問題がありました。
やっぱりC++でないとだめなのかなぁ。と思ったんですが、試行錯誤した結果、ACする事ができたので、メモしておきます。

問題

https://atcoder.jp/contests/abc265/tasks/abc265_e

O(N^3)の計算量
N=300、9000000=9*10^6
制限時間が3秒なので、計算量の大きめの問題

# TLEになったコード

```python
MOD = 998244353

N,M = TII()
d = TII()
xy = set([TII() for _ in range(M)])

def add(a,b):
    return (a[0]+b[0], a[1]+b[1])

move_d =[]
for i in range(3):
    move_d.append((d[i*2],d[i*2+1]))

count_pos = defaultdict(int)
count_pos[(0,0)] = 1
for i in range(N):
    next_count_pos = defaultdict(int)
    for pos,val in count_pos.items():
        for m in move_d:
            next_pos = add(pos,m)
            if next_pos in xy:
                continue
            next_count_pos[next_pos] += val
            next_count_pos[next_pos] %= MOD
    count_pos = next_count_pos
    # print(count_pos)

ans = sum(count_pos.values()) % MOD
print(ans)
```
# 対策前の結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532235/8eb9367f-7bfe-85bd-fc3b-8859136bcbc3.png)

# 関数呼び出しをインライン化

PyPyの関数呼び出しは遅いとよく聞きますが、まさにこれでした。
インラインに書き換えました。

```diff_python
     next_count_pos = defaultdict(int)
     for pos,val in count_pos.items():
         for m in move_d:
-            next_pos = add(pos,m)
+            next_pos = (pos[0]+m[0], pos[1]+m[1])
             if next_pos in xy:
                 continue
             next_count_pos[next_pos] += val
```

これは効果が絶大でした。
この処理は、ループ一番中側なので、N^3回実行されます。為影響が大きい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532235/5aff74c4-11fd-4c2d-cb20-1bfec5faa42a.png)

しかし、あと一歩です。

# 辞書の参照回数の削減

参照回数の減らし方は、コードをみていただいた方が早いと思います。

```diff_python
             # next_pos = add(pos,m)
             if next_pos in xy:
                 continue
-            next_count_pos[next_pos] += val
-            next_count_pos[next_pos] %= MOD
+            next_count_pos[next_pos] = (next_count_pos[next_pos] + val) % MOD
     count_pos = next_count_pos
     # print(count_pos) 
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532235/a7c677b6-165f-6b80-71a3-a3d4f3dd4391.png)

辞書のアクセスはO(logN)。O(N)に比べれば小さいですが、実行回数の多い場合、無視できません。
記述が楽なので、特に気にせず、2行にしてました。配列のアクセスだったらO(1)なので、誤差だったんですが、そうはいきませんでせいた。
勉強になりました。

実行時間は2043 msで余裕でクリア。

# おまけ　dict/defultdict/Counterの比較

辞書の参照回数を減らす。分かってしまえば当たり前の結果でしたが、これにたどり着く前に、defultdictが遅いのではないか？とおもい、このあたりも試行錯誤しました。

同じ条件で、dict/defultdict/Counterを変えてみて測定した結果です。

|変更点| 実行時間|
|------|--------|
|dict|2105ms|
|defultdict|2043ms|
|Counterに変更|2520ms|

上記の結果では、defultdictの方が速い結果になっていますが、ジャッジ毎のばらつきがあり、dictとdefultdictでは、有意な違いはなさそうです。
defultdictは無罪でした。Counterは20%程度遅いようでした。

dictに比べて、defultdictが速度的に不利になる事はなさそうなので、今後も気にせず使っていこうと思います。

# まとめ

TLEになった時は、計算量を見積もって、アルゴリズムに問題ないか確認するのが基本ですが
Pythonの場合、実行回数が多い（10^7くらいでしょうか)部分は次の点に注意

- 関数を呼び出さない
- 辞書の参照などO(logN)を不要に行わない。 %=　等の記述に注意
DockerのビルドしまくったせいでwindowsでCドライブ急に0バイトになったので解決してみた

# 起きたこと
環境構築のほぼ全てを行うシェルを実装してて、Dockerが絡むので当然動作確認としてビルドしまくるわけだが、ビルドする中で作成されるOracleの表(テーブル的な)が突然作成されなくなった。Dockerのログ見たら「no space left on device」といういろんなところでよく見るエラーが起きていた。
残り30～40GBぐらいは残っていたはずだが、、、って思ったら衝撃のスクショ

残り0バイト。こんなの始めてみた。


![スクリーンショット 2023-10-28 133117.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179803/96cb6e06-d4ae-fe3c-56b6-89deefcca0d3.png)

とくに最近大きなファイルはダウンロードしていないので、Dockerのビルドめっちゃ繰り返してたしまずDockerを疑っていろんなワードでググった

# 原因

調べたら、この記事で以下のようなことが書かれていて、
https://wand-ta.hatenablog.com/entry/2018/12/06/123229
```
docker build とかやってると、あれよあれよと減っていく
```

ちょうど僕もビルドツールの移行作業をやっていたのでかなり頻繁にビルドコマンドを使っていた。完全にDockerが原因だ

Docker Desktop開いたら、imagesの数がドンでもない数になっていた。


# 解決方法
①いったんimagesとVolumesを全て削除
②エクスプローラーのクリーンアップ

これやったら、0バイトから約40GB空いた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179803/e8dfc7b8-1a0b-9b47-1ca6-d5585a8f2317.png)
Javaのデータ構造の選定でいつも迷ってしまう。

いろいろあるからね、しょうがないよね？

:::note warn
注意
* 当記事では、私が普段よく使うデータ構造の話だけをしています。当記事で触れられていない技術もこの世にはたくさんあります。
* 当記事には「これはあまり使わない」や「こうすればよさそう」といった個人的見解が多く含まれていますが、これは普段私がコーディングしている現場での話であり、私にとって無用なものも私以外にとっては有用かもしれません。
:::

# List（リスト）

* <font color="tomato">**ArrayList**</font>
    * いつものやつ。
* <font color="tomato">**LinkedList**</font>
    * 連結リストなので先頭要素のremoveとかが高速、だがあまり使わないかも。

配列に慣れちゃうと、`list.add(5, "hoge");` みたいな感じで途中挿入できることを忘れがち。

# Set（集合）

* <font color="tomato">**HashSet**</font>
    * 高速。普段はこっちを使う。
* <font color="tomato">**TreeSet**</font>
    * アイテムが自動的にソートされており、lower()やhigher()が使える。

Setは重複を持てない。既に持っているアイテムを再びaddしても何も起きない（例外発生もしない）。
addした順序も覚えていない（get()のようなメソッドが無い）。
Listと比べるとcontainsやremoveが高速。

# Map（連想配列）

* <font color="tomato">**HashMap**</font>
    * いつものやつ。put順序は覚えていない。
* <font color="tomato">**LinkedHashMap**</font>
    * put順序を覚えている。
* <font color="tomato">**TreeMap**</font>
    * put順序は覚えず、キーで自動的にソートされる。

`map.entrySet()` のfor文で中身列挙する際、上記のどれを使っていたかによって順序が異なる。

ちなみに当たり前だがキーは重複できない。既に持っているキーを再びputすると、バリューが上書きされる。

# Deque（両端キュー／デック）

* <font color="tomato">**ArrayDeque**</font>
    * スタックとしてもキューとしても使えるやつ。
    * スタックっぽく使うなら…
        * push()で先頭に追加、peek()で先頭を見るだけ、pop()で先頭を削除。
    * 両端キューっぽく使うなら…
        * addFirst()やaddLast()で追加、peekFirst()やpeekLast()で見るだけ、pollFirst()やpollLast()で削除。

Queueを拡張して作られたのがDequeとのこと。特別な理由がない限りDequeを使えばよさそう（Queueは使わなくてよさそう）。


いったん以上。
【img2prompt＋Bing ImageCreator】イメージからプロンプト作成できる。


　どうも、カーブミラーです。

　今回は、イメージからプロンプト作成できるサイトのご紹介です。

:::note info
本記事は、ChatGPT（無料版）で
行なっております。GPT4での確認
はできておりません。あしからず。
:::

　ChatGPT＋DALL-E3の
　　組み合わせは、
　　　羨ましいです。

　私は、
　　無料版なので、
　　　人が使っているのを
　　　　指を咥えて、
　　　　　見ているしかありません。

　とはいえ、
　　MicrosoftBing＋ImageCreatorも
　　　そこそこに使える、と
　　　　言えたら、いいのですが……

　画像解析は、
　　いろんな理由から
　　　負けています。

　まぁ、理由は、
　　押して図るべし。

　また、
　　GoogleBardも
　　　画像を取り込めますが、
　　　　人物画像は、削除されます。

　そんなこんなで、
　　困っていました。
***
　ネットで
　　探して、
　　　見つけたのが
　　　　今回のサイトです。
[img2prompt](https://replicate.com/methexis-inc/img2prompt)

　これは、
　　無料で使えます。

　カメラ画像や
　　画像ファイルを
　　　アップして、
　　　　Submitするだけで、
　　　　　Promptが作成されます。

　そのPromptを
　　画像生成AIに
　　　食わせれば、
　　　　元画像に似た画像が
　　　　　生成されるはず。

　では、
　　やってみましょう。
***
　まずは、
　　こちらの画像を
　　　アップします。
![_89d165f4-225b-4a37-83b9-392523432792.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/1922a504-7460-b161-4a23-bafdaa75e2c7.jpeg)

　で、作成されたPromptは
　　以下のとおり。
```Text:生成されたPrompt
a girl wearing headphones and a t - shirt, cyberpunk art by Wang Yuanqi, cgsociety, futurism, anime aesthetic, future tech, anime
```

　翻訳すると
「ヘッドホンとTシャツを着た少女、王元基によるサイバーパンク・アート、CGS社会、未来派、アニメ美学、未来技術、アニメ」

　ううむ、なんか違う気が……。

　まぁ、
　　ImageCreatorに
　　　食べさせてみますか。
***
　で、出来上がったのが
　　こちら。
![Screenshot_20231028-124739~2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/e74c1fd0-43a8-59cf-3ef5-61933a0300a8.png)


　まぁ、
　　こうなるでしょうね。

　自分としては
　　不満足ですが、
　　　今回は、ここまで。
Terraform でできそうでできないこと

## はじめに

この記事は Terraform は使えない、ということを言おうとする意図は全くありません。むしろ、私自身は今まで鬼のように大変だった gcloud を呼び出す shell 作りがなくなるので、積極的に使っています。

## Terraformによるインフラストラクチャの革新（by ChatGPT）

Terraformは、HashiCorpによって開発されたオープンソースのインフラストラクチャアズコード（IAC）ツールであり、その便利さと効率性から世界中のエンジニアに広く採用されています。本作文では、Terraformの便利さに焦点を当てて詳細に解説します。

* 一貫性と再現性:

Terraformを使用する最大の利点の一つは、インフラストラクチャをコードとして管理できる点です。これにより、環境の一貫性が保たれ、エラーのリスクが低減します。また、コードとして保存されているため、必要に応じて簡単に再現やロールバックが可能です。

* クロスプラットフォーム対応:

Terraformは複数のクラウドプロバイダをサポートしており、AWS、Google Cloud、Azureといった主要なクラウドプラットフォームに対応しています。これにより、異なるクラウドプロバイダ間での移行やマルチクラウド環境の管理が容易になります。

* コラボレーションの向上:

Terraformのコードはバージョン管理システムと連携することができるため、チームメンバー間でのコラボレーションがスムーズに行えます。コードレビューや変更履歴の追跡が可能となり、より品質の高いインフラストラクチャを構築できます。

* 自動化と効率化:

Terraformを使用すると、手動でインフラストラクチャを構築する手間が省け、大幅な時間の節約が可能です。また、エラーのリスクを低減しながら一貫性を保つことができるため、運用の効率化に繋がります。

* コストの最適化:

Terraformはリソースの利用状況を可視化し、過剰なリソースの削減を容易にするため、コストの最適化に寄与します。不要なリソースの削減はコスト削減だけでなく、環境に対する負荷の軽減にも繋がります。

* まとめ:

Terraformはその一貫性、クロスプラットフォーム対応、コラボレーションの向上、自動化、コスト最適化といった様々なメリットを提供しており、インフラストラクチャの管理を効率的かつ効果的に行うための強力なツールとなっています。これにより、エンジニアはよりクリエイティブで革新的な作業に集中することができ、企業全体の競争力を高めることが可能です。


## できそうでできないこと

GCP に新規にプロジェクトを作ってそこで Cloud Run を建てたい、と考えて次のような .tf を作ってみた

```
provider "google" {
}

resource "google_project" "new_project" {
	name		= "JD"
	project_id	= "John Doe..."
}

resource "google_project_service" "cloud_run" {
	project		= google_project.new_project.project_id
	service		= "run.googleapis.com"
}

以下略

```

動かすと以下のエラーになる

```
 Error: Request `Enable Project Service "run.googleapis.com" for project "John Doe..."` returned error: failed to enable services: failed on request preconditions: googleapi: Error 400: Billing account for project 'XXXXXXXX' is not found. Billing must be enabled for activation of service(s) 'run.googleapis.com,artifactregistry.googleapis.com,containerregistry.googleapis.com' to proceed.
```

要するに「請求アカウントがプロジェクトに結びついていないので、Cloud Run API を有効化できない。」とのこと。
請求アカウントをプロジェクトに結びつける terraform はなさそう。ChatGPT に聞いてみると

* プロジェクトに請求アカウントを紐付ける操作は直接Terraformでは実行できません。これはセキュリティと認証の観点からGoogle Cloudが制限を設けているためです。

そりゃそうだ。
というわけで残念ながらプロジェクトの作成からデプロイまで一気通貫とはいきませんでした。
LaravelのDIコンテナを単体(standalone)で使う方法と利用ケース

## まえおき

LaravelのDIコンテナって単体で使ってええんやろか、
いや[repository](https://github.com/illuminate/container)にドキュメントもないからやめといた方がええか...
と思ってた所rectorの記事を見かけて、事例あるやんと思い書き起こしました。


## LaravelのDIコンテナを単体利用している事例

自動リファクタリングツールの[Rector](https://github.com/rectorphp/rector)において、SymfonyのDIコンテナからLaravelのDIコンテナに移行した事例があり、大きいOSSで実施されているので安心感があります。

[Rector 0.18 - From Symfony Container to Laravel and How to Upgrade your Extensions](https://getrector.com/blog/rector-018-from-symfony-container-to-laravel-and-how-to-upgrade-your-extensions)

記事によるとSymfonyのDIコンテナと違い下記のメリットがあるようです。
- 依存関係の遅延ロードができ、パフォーマンス的に優位性がある
- PHP8系PHP7系とでコードの差が少ない点

確かにSymfony5系から6系のバージョンアップでかなりコードを修正したようなので、PHP7で動かす前提があるRectorではメリットのある改修のようです。


## インストール

```bash
$ composer require illuminate/container
```

## 使い方

依存関係の定義がない場合、型定義をRelfectionClassで読み取って自動でautowireしてくれます。
`new Container`するだけ、簡単ですね！

```php
use Illuminate\Container\Container;

require_once __DIR__ . '/../vendor/autoload.php';

class NoDependenciesService
{
    public function say(string $string): void
    {
        echo $string;
    }
}

class ManyDependenciesService
{
    public function __construct(private NoDependenciesService $service)
    {
    }

    public function say(string $string): void
    {
        $this->service->say($string);
    }
}

(new Container())->get(NoDependenciesService::class)->say('yes'); // yes
(new Container())->get(ManyDependenciesService::class)->say('awesome!!'); // awesome!!
```

他の設定に関しては[公式ドキュメント](https://laravel.com/docs/master/container)を参照してください！

## SerivceProvidersを使えないのか？

Laravelをフレームワークとして利用していると[Service Providers](https://laravel.com/docs/master/providers)と呼ばれる仕組みによって、依存関係の定義をしており、開発者が依存関係の定義を追加する場合ここに追加すれば良いのですが、DIコンテナを単体利用する際はService Providersは利用できないようです。

理由としては下記の2点で

- `illuminate/container`に`Illuminate\Support\ServiceProvider`が入っていない
- `Illuminate\Support\ServiceProvider`が`\Illuminate\Contracts\Foundation\Application`に依存しており、このクラスの具象がフレームワーク側にしかない

要するにServiceProviderを使いたかったらフレームワークとしてLaravelを使った方が早そうですね。

## 依存性管理をどこでやるか（SerivceProvidersの代用）

[Recotor](https://github.com/rectorphp/rector/blob/main/src/DependencyInjection/LazyContainerFactory.php)のように独自で依存関係の定義をするクラスを作成しないといけないようですね。

該当箇所↓
https://github.com/rectorphp/rector/blob/main/src/DependencyInjection/LazyContainerFactory.php

ここを頑張ってでも`illuminate/container`を使いたいかが一番導入のポイントになりそうです（がんばりポイント）

## 単体利用が活躍しそうなユースケース

- PHP8への移行やLaravelへの移行を見越して単体で導入するケース
- フレームワークを入れるほどの開発ではないが、DIコンテナだけ使いたいケース
- LaravelのDIコンテナが使い慣れている開発者が多い開発現場

## まとめ

有名プロダクトで使われていると「あっ俺も使おっと」ってなりますね！！！

つまりRectorはすごい！！（プロジェクト的にも内部構造的にも）
Rectorの[ブログ](https://getrector.com/blog)を定期的に読み漁ったら収穫がある！！
FlutterでWebリンク、ユニバーサルリンク、アプリリンクを統一的に扱いたい

# 結論

``` dart
setUrlStrategy(PathUrlStrategy()); 
```

を設定するとOK!

# やりたいこと

Flutterで `go_router` 等でルーティングすると、Webでは以下のようなURLになりますね。

```
https://example.com/#/pages/1
```

Flutter Webをホスティングし上記URLをクリックすると、URLがハンドリングされ `go_router` で設定したパスに飛びます。同一のFlutterアプリをモバイル向けに公開している場合、アプリインストール済の端末ではブラウザではなく、アプリ側で開いてほしいということがあります。

http[s]から始まるURLをアプリでハンドリングするには、iOSでは「universal link」、Androidでは「app link」という仕組みを利用する必要があります。
アプリリンクやユニバーサルリンクの設定方法については下記参照してください。Androidは `AndroidManifest.xml` 、 iOSは `info.plist` を編集する必要があります。また、Androidは `assetlinks.json` 、iOSは `apple-app-site-association` をホスティングする必要があります。詳細は今回は割愛。ここまでは設定できているとします。

https://docs.flutter.dev/cookbook/navigation/set-up-app-links

https://docs.flutter.dev/cookbook/navigation/set-up-universal-links

# 何が動かないか

ところが、上記設定してもうまくリンクは動いてくれませんでした。アプリは開くのですが、その後のハンドリングがうまくいかず、どのパスを設定してもアプリトップが開いてしまうのです。Githubを眺めると、 `go_router` ではfragmentとURLのパスは区別するとありました。すなわち `https://example.com/#/pages/1` と `https://example.com/pages/1` を区別するということです。

https://github.com/flutter/flutter/issues/134933

これは困りました。 `#` なしではアプリ側は問題ないかもしれませんが、今度はWeb側が動作しなくなるからです。

# `#` を消す

実はWebのパスから `#` を消去するオプションがありました。　[巷では](https://medium.com/@savangangani/remove-from-the-url-in-flutter-a7e776cf953e) `setUrlStrategy(PathUrlStrategy());` を使えとよく言われますが、これはモバイル版ではビルドすることができません。様々なワークアラウンドがありますが、実は最終的には公式ドキュメントにある `usePathUrlStrategy();` を用いればモバイルでもビルドができました。

https://docs.flutter.dev/ui/navigation/url-strategies

``` dart
void main() {
  usePathUrlStrategy();
  runApp(ExampleApp());
}
```

これを用いて下記リンクを開くと..

```
https://example.com/pages/1
```

Webでは当該ページがブラウザで開き、インストール済端末からだとアプリで開くことができるようになりました！

# これを使ったアプリ

上記使ったアプリを公開しております。割り勘を行うことができるアプリです！

https://play.google.com/store/apps/details?id=com.guntamania.seisanchan

https://apps.apple.com/us/app/%E7%B2%BE%E7%AE%97%E3%81%A1%E3%82%83%E3%82%93-%E3%82%B7%E3%83%B3%E3%83%97%E3%83%AB%E5%89%B2%E3%82%8A%E5%8B%98%E3%82%A2%E3%83%97%E3%83%AA/id6444388748

# その他TIPS

Web側はFirebaseでホスティングしているのですが、 `firebase.json` を下記のようにしておくと、　`assetlinks.json` と `apple-app-site-association` を `web/.well-knwon` におくだけでこれらをホスティングすることができます。あまりWebになかったので、ぜひどうぞ！

``` json
{
  "hosting": {
    "public": "build/web",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "headers": [
      {
        "source": "/.well-known/assetlinks.json",
        "headers": [
          {
            "key": "Content-Type",
            "value": "application/json"
          }
        ]
      },
      {
        "source": "/.well-known/apple-app-site-association",
        "headers": [
          {
            "key": "Content-Type",
            "value": "application/json"
          }
        ]
      }
    ],
    "rewrites": [
      {
        "source": "/.well-known/assetlinks.json",
        "destination": "/.well-known/assetlinks.json"
      },
      {
        "source": "/.well-known/apple-app-site-association",
        "destination":"/.well-known/apple-app-site-association"
      },
      {
        "source": "**",
        "destination": "/index.html"
      }
    ]
  }
}
```
【Java】とは一体なんだ？

## はじめに

現在Javaと奮闘しているマクドと言います。そもそもJavaとは一体なんだ！って思ったので執筆してみました。触り程度ですが最後まで読んでいただければ幸いです！

## 概要

JavaとはOracle社が提供しているプログラミング言語です！(元々はサン マイクロシステムズ社)

世界中で多く使われている人気のプログラミング言語。三大言語は(Java、C++、Python)らしい！←初めて知りました。
Javaは「Write once, Run anywhere」というキャッチフレーズがあり、「一度書けば、どこでも使える」という意味があり、Javaで開発すればWindowsやMacなどのOSを問わずプログラムが実行されます！

補足：間違いやすい言語にJavaScriptがありますがJavaとは別になります！注意しましょう。

![スクリーンショット 2023-10-16 18.41.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/949345/b328636d-c61e-8dcc-4f29-8d1f29efda2e.png)

↑アイコンが銭湯マークみたいですね。笑

## 特徴

### オブジェクト指向の言語

- Javaはオブジェクト指向のプログラミング言語です。オブジェクト指向とはプログラミング言語をモノとして捉えてモノとモノの関係性を定義することで、組み立ていく考え方です。
Java以外のオブジェクト指向プログラミング→Python、Ruby、C#など

### 処理速度が速い

- Javaはプログラミング言語の中で処理速度はトップクラスです。理由は起動時にコンパイルを必要とするコンパイラ言語であるからです。
コンパイルとはプログラムを実行するために、マシンが処理可能なファイルに変換することです。

### 技術的に安定している

- Javaは世界中で使っている人が多いため、バグが起こっても修正しやすく安定しています。
大規模システムの開発を得意としています。

## メリット

### プラットフォームに依存しない
- Javaはプラットフォームに依存せずに実行可能です。Javaはプログラムを実行する際にJava仮想マシン(JVM)に様々なプラットフォームで実行可能な形式に変換します。
プラットフォームに依存しないことはOSや端末で動作させることができると言えます！

### 求人数が多く就職や転職に有利

- JVM上で実行することから、セキリュティ性が高く、金融機関のような厳しいセキュリティが求められる業務システムでも利用されます。他のプログラミング言語と比べても、Javaの需要は今後も高く、転職にも有利になると思います

## デメリット

### 小規模システム開発には向いていない

- Javaは1人で作成するようなプログラムや小規模システム開発には向いていません。理由はJavaの強みである拡張性や再利用性が上手く活かせないことがあります。

### 環境構築が大変

- Javaはインストールするツールが多かったり、利用しているOSによってインストールするものが異なるなど躓く原因かと思います。

### 学習コストがある

- Javaは高性能な分、コーディングに関するルールや難しい記述が多く、難易度が高い言語だと思います。C++やC#などは構文の構造が似ているため、これらの言語を既に習得している人は向いてると思いました。

## 所感

私はJavaを学び始めたばかりですが今の所分かりやすく学習できていると思います(Rubyでの経験あり)
これからはJavaSilverの資格勉強を始めようと思います！皆さん何か投稿やアドバイスなどあれば、コメントいただけたら幸いです！!
Scalaのimplicit valは戻り型を明示しよう

タイトル通りです。

# `implicit val`とは？

scalaには、単に変数宣言するだけではなく、「暗黙の値」を定義することができます。

```scala
implicit val a: String = "a"
```

このように宣言すると、これが宣言されたスコープにいたり、この宣言をインポートした時、aの値を明示せず、暗黙的に使うことができます。

```scala
def m()(implicit a: String): String = {
  s"implicit a = $a"
}

import a // ここで暗黙の値をインポート

m()(a) // 通常はメソッドを呼ぶためには引数をすべて設定する必要があるが、

m() // 暗黙の引数は、そのスコープにある暗黙の値を探そうとする。
```

# `implicit val`の型を省略すると警告が出る

暗黙の値は通常の変数宣言と同様に、型を省略することも可能です。

```scala
implicit val a = "a"
```

scala 2.13.11から、暗黙の値の型を省略すると警告が出るようになりました。

```
Implicit definition should have explicit type (inferred String)
```

https://github.com/scala/scala/pull/10083

暗黙の値を生成する時に、複雑な関数の戻り値だったりした場合、意図しない型に推論されて、暗黙の引数の解決ができなくなることがあるので、型を明示することは良いことだと思います。

# 今週あったこと

10/25にplay2.9が出ました。play2.9はscala xml2系に依存するようになったため、scoverageも最新バージョンを使えるようになって、scalaも最新バージョンを使えるようになりました。今まではscala 2.13.8でしたが、これでscala 2.13.12にアップデートできます。

対象のプロジェクトでは、play jsonのFormatを定義する際に、型定義を省略していました。

```scala
implicit val format = Json.format[ACaseClass]
```

これは警告対象です。なお、対象のプロジェクトでは`-Werror`でコンパイルしていたため、警告はコンパイルエラーとして報告されます。直すには下記のようにします。

```scala
implicit val format: Format[ACaseClass] = Json.format
```

いろんなjsonを扱うプロジェクトだったので、この書き換えが400ファイルくらいありました。しんどかったです。褒めて。

(quickfixも使えるらしいですが、quickfixだとFormatじゃなくてOFormatになりそうだったので、試してません...）

# まとめ

- implicit valには戻り型を明示しましょう。これにより暗黙の値の型が確定するので、暗黙の引数の解決が安定します。
- implicitに限らず、特に公開変数には可能な限り戻り型を明示しましょう。型が確定することで公開変数を扱いやすくなります。
- scala 2.13.xの警告はscala 3.xではエラーになることがあります。scala 2.13.xの警告はできる限り潰しておきましょう。
AstroでTwitterの埋め込みコンポーネント作成例

[Astro]でTwitterの埋め込みを行うシンプルなコンポーネントの例です。

[Hugo]からAstroへの移行作業において、Hugoの[Shortcodes]と同様にショートハンドでツイートを埋め込むコードが必要になったため作成しました。

## 環境

```md
- astro: ^3.4.0
```

## コード

### Astroコンポーネント

```astro:src/components/Twitter.astro
---
interface Props {
  url: string;
}
const { url } = Astro.props;

const base = "https://publish.twitter.com/oembed";
const baseUrl = new URL(base);
baseUrl.searchParams.set("url", url);
baseUrl.searchParams.set("omit_script", "true");

const tweet = await fetch(baseUrl.toString())
  .then<{ html: string }>((res) => res.json())
  .catch((err) => null);
---

{
  tweet && (
    <>
      <div set:html={tweet.html} />
      <script
        async
        src="https://platform.twitter.com/widgets.js"
        charset="utf-8"
        crossorigin="anonymous"
      />
    </>
  )
}

```

### 使い方

```astro:src/pages/hoge.astro
---
import Twitter from "../components/Twitter.astro";
---

<Twitter url="https://twitter.com/J_League/status/1710914053265334445" />
```

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">／<br>無回転炸裂！！！<br>スーパーゴラッソ！！！！！<br>＼<br><br>🎦 ゴール動画 <br>🏆 明治安田生命Ｊ２リーグ　第38節<br>🆚 千葉vs水戸<br>🔢 0-1<br>⌚️ 23分<br>⚽️ 鵜木　郁哉（水戸)<a href="https://twitter.com/hashtag/%EF%BC%AA%E3%83%AA%E3%83%BC%E3%82%B0?src=hash&amp;ref_src=twsrc%5Etfw">#Ｊリーグ</a><a href="https://twitter.com/hashtag/%E5%8D%83%E8%91%89%E6%B0%B4%E6%88%B8?src=hash&amp;ref_src=twsrc%5Etfw">#千葉水戸</a> <a href="https://t.co/bHISGDd3qp">pic.twitter.com/bHISGDd3qp</a></p>&mdash; Ｊリーグ（日本プロサッカーリーグ） (@J_League) <a href="https://twitter.com/J_League/status/1710914053265334445?ref_src=twsrc%5Etfw">October 8, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 解説

[TwitterのoEmbed API][oEmbed API]を利用し、レスポンスから得た`html`要素をAstroの[set:html](https://docs.astro.build/ja/reference/directives-reference/#sethtml)で`<div>`要素に挿入しています。不必要なラッパーの追加を避けるために`<Fragment set:html={tweet.html} />`という書き方も可能ですが、この方法だとクラスなどでスタイルを与えることができません。

Fetch APIのエラー処理では複雑なことを行わず`null`だけを返すことで、何も描画されないようにします。お好みでエラーメッセージの追加などを行ってください。

またこの例では`widgets.js`を読み込みTwitterのデフォルトのスタイルを適用していますが、自作のスタイルを適用したりパフォーマンスを向上させたい場合は不必要なので削除してください。

[oEmbed API]

以上、Twitter埋め込みのシンプルなAstroコンポーネントの例でした。

[Astro]: https://astro.build/
[Hugo]: https://gohugo.io/
[Shortcodes]: https://gohugo.io/content-management/shortcodes/#tweet
[oEmbed API]: https://developer.twitter.com/en/docs/twitter-for-websites/oembed-api#item1
plunkerでjszip

# 概要
plunkerでjszipやってみた。
解凍してみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/add7bff3-91ef-87bd-ad86-a959457a6d57.png)


# サンプルコード

```
'use strict'
const fileListUl = document.getElementById('file-list')
const updateFileName = (fileName) => document.getElementById('file-name').innerHTML = fileName
const clearResult = () => {
  updateFileName('')
  fileListUl.innerHTML = ''
}
const loadZip = async (f) => {
  updateFileName(f.name)
  const zip = await JSZip.loadAsync(f)
  zip.forEach((relativePath, zipEntry) => {
    const div = document.createElement('div')
    div.innerHTML = zipEntry.name
    div.title = relativePath
    div.onclick = async () => {
      const stringContent = await zipEntry.async('text')
      document.getElementById('inner-file-name').innerHTML = zipEntry.name
      document.getElementById('file-content').innerHTML = stringContent.replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('"', '&quot;').replaceAll("'", '&#039;');
    }
    fileListUl.appendChild(div)
  })
}
document.getElementById('file').onchange = (evt) => {
  clearResult()
  loadZip(evt.target.files[0])
}

```

# 成果物

https://embed.plnkr.co/plunk/UrhL8Q0Ja5JCtmFS


以上
cscの作法 その448

# 概要
cscの作法、調べてみた。
sevenzipsharp.dll使ってみた。
ファイル情報を表示してみた。

# サンプルコード

```
using System;
using System.IO;
using SevenZip;

namespace App
{
	class test0 {
		static void Main() {
			SevenZipBase.SetLibraryPath("7z.dll");
			SevenZipExtractor extractor = new SevenZipExtractor("archive.7z");
			Console.WriteLine("FileName; " + extractor.FileName);
			Console.WriteLine("Format; " + extractor.Format);
			foreach (var pair in extractor.ArchiveProperties)
			{
				Console.WriteLine(pair.Name + ": " + pair.Value);
			} 
		}
	}
}
```

# コンパイル手順

```
csc 7z2.cs /platform:x86 /reference:sevenzipsharp.dll


```

# 実行結果

```
>7z2
FileName; archive.7z
Format; SevenZip
Headers Size: 122
Method: LZMA2:12
Solid: False
Number of blocks: 1


```

以上。
Pythonで「エスケープシーケンスを使用する」の動作を確認してみた

# 概要

Pythonで「エスケープシーケンスを使用する」の動作を確認してみました。以下のページを参考にしました。

https://www.javadrive.jp/python/string/index2.html

# 実装

以下のファイルを作成しました。
```sample.py
print("こんにちは。\nお元気ですか？\nそれではまた。")
print('Tom\'s toy')
print("I will go to the amusement park with \
my children tomorrow")
```

以下のコマンドを実行しました。
```
$ python3 sample.py 
こんにちは。
お元気ですか？
それではまた。
Tom's toy
I will go to the amusement park with my children tomorrow
```

# まとめ

何かの役に立てばと。
【bash】root権限をローカルユーザーに切り替えるコマンド


# Command

:::note alert
用法・用量を守って正しくお使いください。
責任は負いかねます。
:::

指定したディレクトリorファイルの所有権を、現在のユーザーに変更します。

```bash
sudo chown -R $(whoami):$(whoami) <ディレクトリ or ファイル名>
# ex.) sudo chown -R $(whoami):$(whoami) root_file.txt
```
[ServiceNow] ScriptでUserの初期Passwordを一括設定して通知する

# はじめに
Scriptで、Userに初期パスワードを設定しつつ、そのパスワードを通知できるようにEventを生成する例を紹介します。

# Script
あまり出来の良いScriptではありませんが、本質的な事を捉えます。

ここでは、

1. abel.tuterに初期パスワード「ServiceNow123!」
1. abraham.lincolnに初期パスワード「ServiceNow456!」

を設定しています。

ポイントは、passwardフィールドの設定にGlideRecordのsetDisplayValueメソッドを使用することです。
初期パスワードという想定なので、password_needs_resetフィールドはtrueに設定します。
最後にEvent Queにuser.initialpassword.setというEventを生成します。user.initialpassword.setは事前定義しておきます。ここでは、Eventの処理は割愛します。


```JavaScript:Script
var arrUser = ["abel.tuter","abraham.lincoln"];
var arrPass = ["ServiceNow123!","ServiceNow456!"];

var grUser = new GlideRecord("sys_user");

for (var i = 0; i < arrUser.length; i++) {
    grUser.addQuery("user_name", arrUser[i]);
    grUser.query();
    if (grUser.next()){
        // Set an initial password to a user.
        grUser.user_password.setDisplayValue(arrPass[i]);
        grUser.password_needs_reset=true;
        grUser.setWorkflow(false);
        grUser.update();

        // Generate an event with the event registry "user.initialpassword.set".
        gs.eventQueue("user.initialpassword.set",grUser,grUser.email,arrPass[i]); 
    }
    grUser.initialize();
}
```

UserとPasswordの対を二次元配列にする手もあります。定義の例としては、次のようになります。

```JavaScript:Script
var arr2UserPass = [
    ["abel.tuter","ServiceNow123!"],
    ["abraham.lincoln","ServiceNow456!"]
];
```

UserとPasswordの組み合わせは事前にExcel等で整備して、Scriptにハードコードするようになっていますが、PasswordをScriptでランダム生成するような関数を作っても良いかもしれません。その場合、ユーザーにどのようなパスワードを通知したか、ログを残す必要があるかもしれません。
また、そのログもそうですし、通知用に生成したEventには、パスワードが平文で記録されているので、セキュリティの観点から手当てが必要になるかもしれません。
Cloudflare workersの空きサブドメイン(○○.workers.dev)を検索

管理画面でも検索できます
<p class="codepen" data-height="520" data-default-tab="result" data-slug-hash="ZEwbxKW" data-user="04" style="height: 520px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/04/pen/ZEwbxKW">
  Cloudflare subdomain checker</a> by John Doe (<a href="https://codepen.io/04">@04</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

`hogehoge.workers.dev`の`hogehoge`部分を検索できます。

```javascript:worker.js
export default {
  async fetch(request, env, ctx) {
    const subdomain = new URL(request.url).pathname.slice(1)
    const response = new Response('', await fetch(`https://www.${subdomain}.workers.dev/`))
    response.headers.set('Access-Control-Allow-Origin', '*')
    return response
  }
}
```

管理画面でサブドメイン変更できます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/c9fe3cda-c4a5-a6d9-87bd-fb6f330f2fce.png)

プログラムでサブドメインを探すこともできます

```javascript
const n = 2
const chars = '0123456789abcdefghijklmnopqrstuvwxyz'
const charSet = [...Array(n).keys()].map(i => [...chars + (i>0 && i<n-1 ? '-' : '')])
for await (const subdomain of charSet.reduce((a,b)=>a.flatMap(x=>b.map(y=>x+y)),[''])) {
    const res = await fetch('https://dash.cloudflare.com/api/v4/accounts/{account_id}/workers/subdomains/' + subdomain)
    console.log(subdomain, res.status)
    const sleep = msec => new Promise(resolve => setTimeout(resolve, msec));
    await sleep(1000);
}
```
`graphql-ruby`で`Dataloader`を使う

# やる事

1. `graphql-ruby`で`Dataloader`を使用する宣言
2. `Dataloader`は`model`の`associations`を事前読み込みする処理を実装
3. 実装した`Dataloader`を`Type`クラスで仕様します

https://github.com/Shopify/graphql-batch/tree/main

## 1. `graphql-ruby`で`Dataloader`を使用する宣言

`app_schema.rb`で`dataloader`を有効化します。

```diff:app/graphql/app_schema.rb
class AppSchema < GraphQL::Schema
+  use GraphQL::Dataloader

  disable_introspection_entry_points unless Rails.env.development?
  
  query(QueryType)

  max_complexity 200
  max_depth 30
  default_page_size 50
  validate_max_errors 100
end
```

## 2. `Dataloader`は`model`の`associations`を事前読み込みする処理を実装

`graphql-batch`gemのリポジトリに`ActiveRecord`の`Preloader`を扱うサンプルがあったので参考に以下のように`graphql-ruby`が提供している`dataloader`機能で実装します

https://github.com/Shopify/graphql-batch/blob/main/examples/association_loader.rb

```ruby:app/graphql/active_record_preloader.rb
# frozen_string_literal: true

class ActiveRecordPreloader < GraphQL::Dataloader::Source
  attr_reader :model, :association

  def initialize(model, association)
    @model = model
    @association = association
  end

  def fetch(records)
    validate!(records)
    ::ActiveRecord::Associations::Preloader.new(records:, associations: association).call
      records.map { |record| record.public_send(association) }
    end
  private

  def validate!(records)
    raise TypeError, "loader can't load association for #{model}" unless records.all? { |r| r.is_a?(model) }

    return if model.reflect_on_association(association)

    raise ArgumentError, "No association #{association} on #{model}"
  end
end
```

### 3. 実装した`Dataloader`を`Type`クラスで仕様します

以下のように、`dataloader.with`メソッドの引数に

- 作成した`ActiveRecordPreloader`
- `ActiveRecord`の`model`
- `model`に紐づく`preload`したい`association`

を指定します

```ruby:app/graphql/user_type.rb
class UserType < Types::BaseObject
  field :email, String, null: false
  field :user_post, UserPostType, null: false

  def profile
    dataloader.with(ActiveRecordPreloader, ::User, :user_post).load(object)
  end
end
```

# 参考

- https://graphql-ruby.org/dataloader/dataloader.html
- https://graphql-ruby.org/dataloader/adopting.html#comparison-fetching-objects-in-sequence-dependent

# 環境

- ruby 3.2.2
- rails 7.0.8
- graphql 2.1.0
Github Pagesでwebサイトを公開する方法

# Github Pagesとは
Github Pagesとは、GithubのリポジトリからHTML,CSS,Javascriptファイルを直接取得し、webページを無料で公開できるサービスです。

# 手順
## 1. Githubにリポジトリを作成する

　　Newボタンをクリックする

![スクリーンショット 2023-10-27 20.35.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3541829/b87f4e0a-004d-280f-219b-9130d7109305.png)

 リポジトリ名を入力する。今回は**test**というリポジトリを作成します
　　　　↓
 Public(公開)を選択する
　　　　↓
 Create repositoryをクリックする
　　　　↓
 リモートリポジトリ作成完了です

![スクリーンショット 2023-10-27 21.08.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3541829/36b940ca-e383-c9a6-5bd1-6fba0581b044.png)

## 2. ローカルでファイル作成(index.html)して、リモートリポジトリにpushする

- まず最初に先ほど作成したリポジトリを開き、URLをコピーしておく

![スクリーンショット 2023-10-27 22.22.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3541829/b1d97056-fc2e-091c-a2df-60746fcf45d6.png)

　
 vscodeでターミナルを開き、作業ディレクトリに移動します
　　　↓
 ターミナルにて、`git clone (コピーしたURL)`を入力する
 　　　↓
 `cd test`でtestファイルに移動する
　　　↓
サイトで公開する**index.html**ファイルを作成する
 `git add index.html`
  `git commit -m "index.htmlを作成"`
  `git push  origin main`を順番に入力する
  
  これでリモートリポジトリに反映完了
  
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3541829/aaab4258-fb22-3c58-44a4-98e317168f43.png)


  ## 3. GithubPagesの設定
  testリポジトリを開き、右上にある`settings`をクリックする
  
![スクリーンショット 2023-10-28 9.42.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3541829/36cafce7-4ecf-2342-09a0-35faafc972b0.png)

pagesをクリック

![スクリーンショット 2023-10-28 9.49.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3541829/2237bdf1-fb8b-1b4c-1009-af0aba851bc8.png)
Branchをmainにする

![スクリーンショット 2023-10-28 10.16.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3541829/2b168ab1-0e41-8fb5-6891-ed92e6aab91b.png)

saveを押して完了です
↓
しばらく待ってリロードすると、このような画面が表示されたらサイト公開完了です。
visit siteをクリックする


![スクリーンショット 2023-10-28 10.29.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3541829/88910dee-f514-f8c7-2510-04507450a768.png)


 表示できました。これでGithub Pagesの設定完了です
  ![スクリーンショット 2023-10-28 10.35.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3541829/ab6726e7-9622-aa1a-5756-5ba2be9e778c.png)
TablePlusでAccess denied

Laravelでのアプリ開発でMariaDBへの接続をしようとした際に、以下のエラーが発生した際の対処方法を記載します。

## 事象

```
Access denied for user 'root'@'localhost' (using password: YES)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920045/d3eea392-d4c7-2926-a7a1-2da416fa5435.png)

## 対処方法

1  .envにFORWARD_DB_PORT=33060 を追記

localに既に作成していたMySQLのPORT3306と干渉していたため、新たにポート番号を別途追記します。

2   sailコマンドで再起動。