OmniAICreator/Qiita-1.07M huggingface dataset:
C#でlog4netを導入する方法

はじめに：
C#プロジェクトを作成した際、log出力用にlog4netを導入することが多いので、
記事として残します。

ステップ1: log4netのインストール
まずは、プロジェクトにlog4netをインストールしましょう。

1.1: NuGetパッケージマネージャーを開きます。
1.2: "log4net"を検索し、該当するパッケージを選択して"インストール"ボタンをクリックします。
1.3: インストールが完了すると、log4netがプロジェクトに追加されます。

ステップ2: log4netの設定
次に、log4netを使用するための設定を行います。

2.1: プロジェクトのルートディレクトリに"log4net.config"という名前の設定ファイルを作成します。
2.2: 設定ファイルに、ログの出力先やログのフォーマットなどを設定します。

例:
```xml
<log4net>
  <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
    </layout>
  </appender>
  <root>
    <level value="DEBUG" />
    <appender-ref ref="ConsoleAppender" />
  </root>
</log4net>
```

2.3: AssemblyInfo.csファイルを開き、以下の行を追加します。

```csharp
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", Watch = true)]
```

ステップ3: ログの使用
log4netの設定が完了したら、ログの出力が可能になります。

3.1: log4netを使用するクラスに、以下の行を追加します。

```csharp
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
```

3.2: ログを出力したい箇所で、以下のようにログを記述します。

```csharp
log.Debug("デバッグメッセージです。");
log.Info("インフォメーションメッセージです。");
log.Warn("ワーニングメッセージです。");
log.Error("エラーメッセージです。");
log.Fatal("致命的なメッセージです。");
```

以上、C#プロジェクトでのlog4netの導入が完了です。ログの設定や使用方法をカスタマイズすることも可能です。
【読み物】ふつうの会社員が考えた「Q.ドーナツの穴に価値をつける方法とは？」の解き方

## 前回までのおさらい

※詳しくは前回の記事[「ふつうの会社員がNFTを発行し始めたワケ」](https://qiita.com/Rekt-Order/items/8f2e4de013359311e681)をご覧ください。

ファウンダーのМ氏（著者）は、「ドーナツの穴に関する問題とNFT」について、このように考えました。

本業では無駄を排除しつつも、プライベートの時間では「ドーナツの穴の価値と真剣に向き合う」、表と裏の日々が始まりました。実態のない、しかし確かに実在はする「ドーナツの穴」に価値をつけるには…？この概念は、2021年6月頃に興味を持ちはじめ、やがて深入りすることになる「NFT」と相性が非常にいいことに気づいたのでした。

この考えから、なぜ…ドーナツの穴におじさんを入れることにしたのか？今回は、この極めて重要な決断について、深堀りしてみたいと思います。

## 「ドーナツの穴」とNFT、似た者同士を結びつけるもの

ドーナツの穴とNFTは、「実態がないけれども、実在はする」…物質的にも概念的にも、共通部分があることは、これまでの説明で理解できたと思います。そう、両者はとてもよく似ているんです。１つ１つのドーナツの穴は、そのドーナツに特有のものであり、交換ができない…はずなんです。ショーケースの中に並ぶドーナツから、お気に入りの１つを選ぶとき、ドーナツの形を考慮して選んだ経験はありませんか？ドーナツの形には、その中心部にある「穴の形」がとても大きな影響を与えています。つまり、ドーナツを形で選ぶということは、「ドーナツの穴」を選んでいることに、他ならないのです。


…ちょっとだけ、脱線してしまいました。

これまでの流れから、INPUTは「ドーナツの穴」、OUTPUTが「NFT」になることが、M氏の中で決定していました。問題は、「ドーナツの穴に価値をつける方法」…つまり、「ドーナツの穴」と「NFT」を結びつける「ナニカ」です。

## ドーナツの穴に価値をつける方法
こういう漠然とした抽象的な問題を考えるときには、まずは「具体化」をすることが重要です。実態はないけれども、価値がついている物の例を探してみます。

- 富士山頂の空気の缶詰（密閉された缶詰の中には、富士山頂で採取した空気が入っている）
- CO2の排出権取引（温室効果ガスの排出量削減を目的とした、排出枠の売買）
- 仮想通貨（広い意味では…。デジタルで表される保有数量とトランザクションの履歴で、実態を補う）
- 大人気アイドルがロケで座った席（推しのアイドルがロケで座った席を指定する方も、実は結構いるとか）

ざっと具体例を考えると、こんな感じでしょうか。共通点を考えてみると…「希少性」が鍵となりそうだということが分かります。富士山の山頂は、唯一のものであり、「日本一高い山の空気」はまさに希少。その空気を体験するには、入念な準備やトレーニングを行って、山頂まで苦労して登る必要があります。CO2の排出権も同じです。京都議定書で取り決められた「温室効果ガスの削減」という枠組みの中では、排出できるCO2の上限が決まっています。つまり、需要と供給のバランスから、排出できるCO2の量というのが価値を持つようになった例と言えます。

これらの例の中で、M氏がもっとも参考にしたのは、一番最後の具体例です。ドーナツに近い「浮き輪」という題材を使って、こんなことを考えてみました。

例えば…あの木村拓哉さんが、夏の海で浮き輪に入って、CM撮影をしたとします。この浮き輪を欲しいと思う方は、どれだけいるでしょうか？木村拓哉さんが入ったあの浮き輪だと、誰もが分かるのであれば、欲しいと思う方はたくさんいるはず。これが、全く無名の一般人であれば、そうはならないでしょう。これが浮き輪でなく、「浮き輪の穴」だったとしても、価値を持つことは容易に想像ができます。（希少性という枠組みでの、木村拓哉さんの強さを軽んじてはいけません）

つまり…

➀有名人が「穴」に接触する

➁「接触した」というイベントを、誰もが確認できる

この２つの条件を満たす時、「あの有名人が、あのシーンで入った穴」として、価値を持つ可能性がある。これこそが「ドーナツの穴に価値を持たせるには？」という問いに対する、私の答えでした。

つまり、ドーナツの穴に有名人（有名キャラクター）を入れて、その有名人が「最初に入った唯一の穴」であると定義すること。この方法なら、ドーナツの穴に価値をつけることができそうだ…そう考えたのでした。

この記事は、著者が運営するメディア「ぬるぺでぃあ」でも読むことができます（記事は[コチラ](https://miuradonuts.com/2023/07/03/nft-note005/)）
![](https://miuradonuts.com/wp-content/uploads/2023/06/ヘッダーエリア画像作成.png)
Dockerを小学2年生向けに説明！

システム用語は説明が難しいですよね。今回は小学2年生向けにDockerの説明をしていきます。義務教育を修了した悩める子羊エンジニアの皆様にも参考になれば幸いです。

## Dockerの役割
Dockerは、おもちゃのレゴブロックを思い浮かべてみてください。レゴブロックは、色々な形や色のブロックがありますよね。それぞれのブロックは一つ一つは小さなパーツですが、それを組み合わせることで色々な形のおもちゃを作ることができます。

Dockerも同じような役割を果たします。Dockerは、小さなパーツ（これを「コンテナ」と呼びます）を作ることができ、それらを組み合わせて大きなアプリケーションを作ることができます。

## Dockerの起動までの仕組み
Dockerの起動は、お弁当箱を作るようなものです。まず、お弁当箱（これが「イメージ」です）を用意します。その中に、ごはんやおかず（これが「アプリケーション」です）を詰めていきます。そして、そのお弁当箱を持っていくところ（これが「コンテナ」です）まで運びます。これがDockerの起動までの仕組みです。

## ライフサイクル
Dockerのライフサイクルは、お花が咲く過程を思い浮かべてみてください。まず、種（これが「イメージ」です）を土に植えます。そして、水や日光（これが「Dockerのコマンド」です）を与えて育てていきます。すると、花（これが「コンテナ」です）が咲きます。そして、花が枯れると（これが「コンテナの停止」です）、また新しい種を植えることができます。
Dockerのライフサイクルは、以下の図のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3303132/6a2b8f49-4663-4b46-1f08-425040fde77e.png)

この図では、ユーザーがDockerコマンドを実行するところから始まります。Dockerはそのコマンドに基づいて、イメージを作成したり、コンテナを作成したりします。そして、コンテナはアプリケーションを実行し、その結果をユーザーに返します。最後に、ユーザーがコンテナを停止すると、Dockerはそのコンテナを停止します。

## 仮想化の概念
仮想化の概念は、お部屋の中に仕切りを作ることを思い浮かべてみてください。一つの大きなお部屋があるとします。その中に、仕切りを作って、寝室やリビング、キッチンなど、それぞれ異なる空間を作ることができますよね。それぞれの空間は、他の空間から独立しています。

Dockerの仮想化も同じようなものです。一つの大きなコンピュータ（これを「ホスト」）の中に、仕切り（これが「コンテナ」）を作って、それぞれ異なるアプリケーションを動かすことができます。それぞれのアプリケーションは、他のアプリケーションから独立して動作します。


以上です！本記事はChatGPTさんに多大なサポートを受けました。この記事があなたの力になればうれしいです！
Tarraformを使ってAWSにWebサーバを構築 #7 ~Webサーバが立ち上がる際にWebサーバソフトをインストールするように設定する~

## 目的
EC2にNginxがインストールされた状態を作り出し、ブラウザからデフォルトページが確認できることをゴールとする。
インフラ構築はTerraformでコード化することで再現性、再利用性、速度などが手作業に比べると高い。
[GitHubリンク](https://github.com/keitasato/terraform-nginx)


### 手順
1. [TerraformからAWSリソースを操作できるように設定する](https://qiita.com/kekkepy/items/4185a621e5d3cc75016b)
1. [Terraformをインストールする](https://qiita.com/kekkepy/items/1b3f4f14bbc2d2dc2c9b)
1. [TerraformでEC2サーバを立ち上げてみる](https://qiita.com/kekkepy/items/8b84fc0c39313267a078)
1. [ネットワークを整える(VPC, サブネット, ルーティングテーブル,インターネットゲートウェイ)](https://qiita.com/kekkepy/items/c941c00536af57bae163)
1. [セキュリティグループ(ファイアウォール)を設定する](https://qiita.com/kekkepy/items/47dcda4d9a7a2064382f)
1. [Webサーバ用EC2を立ち上げる](https://qiita.com/kekkepy/items/81bfa5d542c9160d430b)
1. [Webサーバが立ち上がる際にWebサーバソフトをインストールするように設定する](https://qiita.com/kekkepy/items/209f7ddb29fb5af65a6e)

#### 今回の到達点
Webサーバが立ち上がる際にWebサーバソフトをインストールするように設定する

#### Webサーバを立てる準備
- ネットワークを構築する
- ネットワークに許可する通信を設定する
- EC2をプライベートネットワークに所属させて外部からアクセスできるようにする
- EC2にWebサーバソフト(今回はNginx)をインストールする **←今回はここ！**

##### Step1. webserver.tfにインスタンスユーザデータを設定する
EC2インスタンスが初回起動時にroot権限で実行するスクリプト。
今回はシェルスクリプト形式で記述するが、他の形式もあるらしい。
webserver.tfを以下のように変更(末尾にユーザデータを追加)。
```terraform:webserver.tf
# Key pair
resource "aws_key_pair" "keypair" {
  key_name   = "${var.project}-${var.environment}-keypair"
  public_key = file("./kekkepy-keypair.pub")

  tags = {
    Name    = "${var.project}-${var.environment}-web-sg"
    Project = "${var.project}"
    Env     = "${var.environment}"
  }
}

#Web server
resource "aws_instance" "web_server" {
  ami                         = "ami-0cfc97bf81f2eadc4"
  instance_type               = "t2.micro"
  subnet_id                   = aws_subnet.public-subnet.id
  associate_public_ip_address = true
  vpc_security_group_ids      = [aws_security_group.web_sg.id]
  key_name                    = aws_key_pair.keypair.key_name

  tags = {
    Name    = "${var.project}-${var.environment}-webserver"
    Project = "${var.project}"
    Env     = "${var.environment}"
    Type    = "app"
  }

  user_data = <<EOF
#!/bin/bash
sudo dnf update -y
sudo dnf install nginx -y 
sudo systemctl enable nginx
sudo systemctl start nginx
EOF
}
```

##### Step2. 一度環境を破壊する
初回起動時のみ実行されるので、一度EC2インスタンスを含めた今回の環境を破壊しておく。
```
$ terraform destroy -auto-approve
```

##### Step3. 環境を再度構築
```
$ terraform apply -auto-approve
```

##### Step4. Nginxが無事にインストールされているか確認
マネジメントコンソールからEC2インスタンスのパブリックIPアドレスを確認する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1221536/b3e0aced-2e66-66ee-d803-f93992aacb43.png)


パブリックIPアドレスをアドレスバーに入力して接続すると、無事Nginxの「正しくインストールできています」のページが表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1221536/07d9fcac-3fe3-6fc4-a3b2-c7a01a973584.png)

**これにて「Tarraformを使ってAWSにWebサーバを構築」完了！**
[Flutter] FlutterKaigiの運営として、ウェブサイトを作成しました。

![スクリーンショット 2023-07-03 15.30.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/26d7cc95-c1e9-c0b3-dfba-3d998e9a4096.png)



こんにちは。いせりゅーです。今回はとてもいい報告があります。


FlutterKaigiのウェブサイトが公開されました😁

僕は3回目でようやく、運営側として携わらせていただきました！！ずっと前から憧れていたので、とてもウキウキしていました。僕は、Webサイトの制作を担当しました。



# プロフィール

![スクリーンショット 2023-06-13 7.33.21（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/cd816a70-4db0-a8d8-6284-1573a9e9fb2d.png)

# サイト紹介

以下のこちらのサイトがFlutterKaigiのサイトとなります。

https://flutterkaigi.jp/2023/

今回のサイトは、FlutterKaigi３年目の開催にして初めて、デザイナー ([ @n__yumemi さん](https://twitter.com/n__yumemi)) がデザインを作成してくれました！（かっこいい！！）


リポジトリもpublicになっています。

https://github.com/FlutterKaigi/2023


今日のローンチ以降も、多くの機能追加が予定されています。お気づきの点（バグやパフォーマンス改善など）がありましたら、以下リポジトリの issue より気軽に課題を作成いただけますと幸いです!!

https://github.com/FlutterKaigi/2023/issues


# やったこと

### 今回の取り組んだタスク（新規実装）

#### (1)フッターセクションの実装
サイトだと以下の部分となります。メンバーの方が最後の方は修正していただいたので、自分だけではできなかったタスクでした（反省反省）

具体的にはこちらの部分となっております。


![スクリーンショット 2023-07-03 15.30.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/54f74a87-a6f3-7270-c896-f8041f9c3c14.png)

デスクトップだけでなくモバイルの対応も必要で大きさによって位置を変えなければいけなかったのでとても大変でした。ここでは[FlutterLogo](https://api.flutter.dev/flutter/material/FlutterLogo-class.html)などが知らなかったのでとてもいい勉強になりました!!


<b>Pull Requestはこちらになります。</b>

https://github.com/FlutterKaigi/2023/pull/26



#### (2)ヒーローセクションの実装
サイトだと以下の部分となります。メンバーの方が最後の方は修正していただいたので、自分だけではできなかったタスクでした（反省反省）

具体的にはこちらの部分となっております。

![Group 4 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/dc3085d6-cbdd-f0fa-9bc6-c958169f0622.png)


このタスクもとても大変で、レスポンシブ対応はもちろん、フォントの調整とかも意外と大変でした。。普段は適当だったのでしっかりと調整する大切さを知りました。。。


<b>Pull Requestはこちらになります。</b>

https://github.com/FlutterKaigi/2023/pull/42


### 取り組んだタスク（修正等)
これらは小さな修正のため割愛させていただきます。これらも速攻で直して、速攻でレビューしていただきました（感謝）

https://github.com/FlutterKaigi/2023/pull/91

https://github.com/FlutterKaigi/2023/pull/83

https://github.com/FlutterKaigi/2023/pull/82

https://github.com/FlutterKaigi/2023/pull/81


# 感想
- <b>Flutter on the Web</b>を使用して、対応しなればならないこと（レスポンシブ対策など）があり、対応がとても大変でした。
- Widgetの詳しい実装方法を勉強することができました。
- 開発メンバーが優秀すぎて、あまり貢献できないのではないかと思っていましたが、なんとなかった。
- みんなに見てもらえるようなプロダクトが作れてとても幸せ。
- 今後ももりもり開発するぞ！！！

# 最後に

僕の夢の一つであった「Flutter　Kaigiの運営側になる」という夢が叶いました。新卒3ヶ月目で運営側に入れたのはとても嬉しいですし、頑張りたいと思うことができました。

個人開発でも <b>Flutter on the Web</b>を使って個人のサイトを作ってもいいかも！？と思うようになりました😁

これからの運営を応援していただけると幸いです！！！







#### PS.ゆめみのFlutterエンジニア同期５人でユニバーサルスタジオジャパンに行ってきました！！鬼楽しかった！！！


| マリオエリア | ハードロックカフェ | カチューシャ選び |
|-|-|-|
| <img width="250" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/ef428c87-ed0c-d9db-5057-03ae63724f89.jpeg"/> | <img width="250" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/eeeb615e-6b13-3747-281d-79f7d03bd6ab.jpeg"/> | <img width="250" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/ecdbb872-396c-b29b-219e-be555d6bb7c5.jpeg"/> |
【Terraform de Azure】 Terraform 実行時の Killed メッセージの対処方法

### 概要

「Infrastructer as Code」ということで、Terraform を用いて Azure環境上に リソースを作成していましたが、久方ぶりに利用すると「Killed」とメッセージが表示され実行不可となってました。　正常に実行されるために対処した方法を記載いたします（色々な方法があると思いますが、私の場合はこれで問題なくクリアできました）。


### ローカル環境

- macOS Ventura 13.0
- terraform v1.0.11 （エラー前のバージョン）
- terraform v1.5.2 （正常後のバージョン）

---

## Terraform のバージョンを確認してみる

### Killed メッセージの表示

久方ぶりにTerraformを利用しようと、、、、まずは、バージョンを確認を実施。　すると、、、、

```
$ terraform -v   
zsh: killed     terraform -v
```

なんだ、このメッセージは？！　　ということで以下を実行

```
$ brew install tfenv
$ brew unlink terraform
$ brew reinstall tfenv
$ tfenv install 1.5.2
$ tfenv use 1.5.2
```

再度バージョンの確認

```
$ terraform -v        
Terraform v1.5.2
on darwin_amd64
+ provider registry.terraform.io/hashicorp/azurerm v2.93.0
+ provider registry.terraform.io/hashicorp/tls v3.1.0
```

念のため、terraform init も実行してみる

```
$ terraform init

Initializing the backend...

Initializing provider plugins...
- Reusing previous version of hashicorp/azurerm from the dependency lock file
- Reusing previous version of hashicorp/tls from the dependency lock file
- Using previously-installed hashicorp/azurerm v2.93.0
- Using previously-installed hashicorp/tls v3.1.0

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
```

---

### まとめ

これで、以前と同様に Terraform でサクッと Azure環境上にリソースを作成することができるようになりました（[この記事](https://qiita.com/turupon/items/c249680acea136aff42b)を実行確認済）。
Slickでスライド要素が1枚のときはスライドをしない

Slickスライドを使っている時に、スライドが1枚の時だけレイアウトが崩れたのでその時の対応まとめ。

### ■ レイアウト概要
PC表示：3カラム表示で4枚目のカードから矢印が出てスライドする
![スクリーンショット 2023-07-03 15.14.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884345/8d4ee8ed-83b1-2766-895a-8b8eff462040.png)

SP表示：1カラム表示で2枚目のカードから矢印が出てスライドする
![スクリーンショット 2023-07-03 15.21.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884345/edc4dd10-b9aa-91fe-2990-76acf7f6b6c5.png)

## でも1枚の時は1枚で表示したい（スライド解除したい）

2枚以上入っている場合はレイアウトの崩れはないのですが、1枚になった瞬間崩れました....

### 崩れた部分
PC表示：横幅が極端に狭くなる
SP表示：左側に隠れていて何も表示されない

### 調整したこと

1. スライドの枚数を取得する（JS）
1. スライドの枚数が1枚だったら...の分岐を作る（JS）
1. レイアウトの調整をする（css）

今回は.slide-oneというクラスでレイアウトを整え、
スライドが1枚だった時はスライドの親（ulなど）にこのクラスを付与するパターンです。


```slide.css
/* pcの表示 */
.slide-one{
  display: block; /*　横幅が極端に崩れるなら、この記述。ここはinlineでもOK */
}

/* spの表示 */
@media (max-width: 768px) {
  .slide-one .slick-track{
    display: inline; /*　ここはinlineじゃないと表示されない */
  }
}
```

※slickはdisplay:flexだと崩れる場合があるのであまり使わないようにするのがベスト。
※cssは状況に応じて変えてください。あくまでも一例です。

``` slide.js
  // スライドの枚数を取得する
  const slideLength = document.querySelectorAll('.slideCard .slideCard-list"').length;

  // スライドが1枚だったら...
  if(slideLength == 1){
    $('.slideCard').addClass('slide-one');
  }
```

HTMLはこんな感じ↓
```index.html
<ul class="slideCard">
      <li class="slideCard-list">
        <h2 class="slidecard-list__ttl">コンテンツ01</h2>
        <p class="slidecard-list__txt">
          ここにテキストここにテキストここにテキストここにテキストここにテキストここにテキスト
        </p>
        <a href="#" class="slideCard-list__btn">詳細はこちら</a>
      </li>
      <li class="slideCard-list">
        <h2 class="slidecard-list__ttl">コンテンツ02</h2>
        <p class="slidecard-list__txt">
          ここにテキストここにテキストここにテキストここにテキストここにテキストここにテキスト
        </p>
        <a href="#" class="slideCard-list__btn">詳細はこちら</a>
      </li>
      <li class="slideCard-list">
        <h2 class="slidecard-list__ttl">コンテンツ03</h2>
        <p class="slidecard-list__txt">
          ここにテキストここにテキストここにテキストここにテキストここにテキストここにテキスト
        </p>
        <a href="#" class="slideCard-list__btn">詳細はこちら</a>
      </li>
    </ul>
```

## サンプルソースコード
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="YzRQWoX" data-user="orange2929" style="height: 300px; 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/orange2929/pen/YzRQWoX">
  Slickのslide要素が1枚のときはスライドしない</a> by aya (<a href="https://codepen.io/orange2929">@orange2929</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## Slick調整は地味に大変...
Slickだけには止まりませんが、簡単に実装できる反面
細かい調整の際に地味に厄介な部分があるのがプラグインやライブラリの宿命なんのかもしれない...🤔
レンダリングについて（学習用）

## レンダリングとは
指定したリソースをブラウザ画面に表示すること
## レンダリングのフェーズ
大きく分けて4つのフェーズがある
**Loading**: レンダリングをするのに必要な、HTML、CSS、JavaScriptなどを読み込む、
一番最初に読み込まれるファイルはHTMLファイル。そのファイルを解析してDOMツリーを作成する。
**Scripting**: JavaScriptのコードが実行される.
**Rendering**: DOMとCSSOMツリーは組み合わされてレンダーツリーを形成します。レンダーツリーは、表示されるすべての要素（テキストノード、色、スタイルなど）を含むが、表示されない要素（たとえば、display: none;で設定された要素）は含まれない。その後、ブラウザは各ノードの位置とサイズを計算する。これを「リフロー」とも呼ぶ。
**Painting**: 最後に、ブラウザはレンダーツリーに基づいて画面上にピクセルを描画する。これは、テキスト、色、画像、境界線などを含み、ペイントプロセスは、しばしば複数の層にわたって行われる。

## SPAのレンダリング
1. 初期リクエストの送信
1. 初期HTMLとCSS、JavaScriptをサーバーから取得し、ブラウザに返す。
1. ブラウザはHTMLをロードした後、JavaScriptを解析して、最初のビューを描画する。
1. ２回目以降のリクエスト（差分の更新に必要なデータ）
1. サーバー側でJSON形式のデータを用意して、ブラウザに返す。
1. JavaScriptはブラウザのDOMを操作し、初期ビューに対応するコンテンツを生成。これには、フレームワーク（React、Vue.js、Angularなど）のレンダリングシステムが使用される。


SPAすごい！！
実務未経験がJava Gold SE11を約1か月で合格した話【合格体験記】

エピローグとかどうでもいいからさっさと過程を書け。って気持ち、よくわかります。
なのでJavaの資格とは何ぞや？的な話は飛ばします。

<h2>前提知識&経歴</h2>
2022年11月末　業界業種未経験、プログラム未経験未学習からJavaを学べる職業訓練校へ。<br>
↓<br>
2023年1月　ITパスポート 合格(対策期間: 10日)<br>
↓<br>
2023年2月　OSS-DB Silver 合格(対策期間: 3週間)<br>
↓<br>
2023年4月　Java Silver SE11 合格(対策期間: 2週間 + 2週間)<br>
↓<br>
2023年5月末　職業訓練校修了<br>
↓<br>
2023年6月　入社＆研修開始<br>
↓<br>
2023年7月　Java Gold SE11　合格(対策期間: 1か月)　←今ここ<br>
<br>
職業訓練校に在籍していた半年間はJavaの基礎から匿名クラス、Comparable、FWでSpring bootをしました。訓練校でSpringを必死にやったおかげでJava Goldまでの道のりが短かった気がします。(大事)<br><br>
余談ですが、いきなりSpringを踏み込むとほぼ脱落するので要注意です。<br>
慎重に行くならサーブレットの学習を挟みましょう。



<h2>使用した参考書</h2>
<ul>
<li>オラクル認定資格教科書 Javaプログラマ Gold SE11 スピードマスター問題集(通称: 白本)</li>
<li>徹底攻略Java SE 11 Gold問題集［1Z0-816］対応 徹底攻略シリーズ(通称: 黒本)</li>
</ul>

これだけで受かります。紫本は飾りです。<br>
<br>
...気になる方は買うといいと思います。自分は買いましたが不要でした。

<h2>期間</h2>
<b>6/1 ~ 6/8</b><br>
とりあえず白本から。<br>
<br>
<b>オレはッ！！アタマにッ！！インプットするッ！！</b><br>
<br>
そんな強い気持ちで気合を入れてゆっくり隅々まで読んでひとまず一周します。<br>最初は時間をかけましょう。<br>
<br>
<b>6/9 ~ 6/16</b><br>
黒本を1周こなしました。<br>予定では2周終わらせるつもりでしたが、気合いと時間が足りませんでした。<br>
解説は隅々まで読みました。お陰で時間がしこたま食われました。
<br>
<br>
<b>6/17 ~ 6/23</b><br>
黒本2周目、3周目をこなしました。<br>
6/16に実践した模擬試験で思ったより点数が伸びなかったので気合いを入れなおし。
<br>
<br>
<b>6/24 ~ 7/1</b><br>
黒本4周目、5周目をこなしました。ここまでくると選択肢を見れば答えが分かります。(本末転倒)<br>
4周目の時点で自分ができない問題が確定しているので、ただ解くというよりなんでや・・・？という気持ちを持ちましょう。5回目に黒本に載っている全ての問題を解いた際は正答率9割程度でした。<br>
その後に初めてやった白本の章末模試だと7割でした。(ｵｲ
<br>
<br>
<b>7/2</b><br>
試験当日。<br>
あ！この問題、進〇ゼミでやったところだ！みたいな現象が起きます。<br>
試験当日も選択肢を見れば答えが分かる時がちらほらありました。<br><br>
ちなみに、試験結果の正答率は82%でした。<br>
対戦ありがとうございました。

<h2>黒本章末模試の点数割合推移</h2>
黒本の章末にある模擬試験は1週間ごとに行いました。<br>
<br>
<b>6/9</b>　黒本の模擬試験1回目　正答率50%ぐらい(白本ではなく黒本の模擬試験です。)
<br>シッカリ読んだことで割と高めの点数でした。<br><br>
<b>6/16</b>　黒本の模擬試験2回目　正答率55%
<br>まあｲｹﾙｯｼｮ、なんて思ったのもつかの間。気を抜いたら負けだと思います。<br>多少サボったのもあり、合格点に達せず。<br><br>
<b>6/23</b>　黒本の模擬試験3回目　正答率82%
<br>黒本を回した成果が出てきたのでJava Goldの試験を7/2に設定。<br><br>
<b>6/30</b>　黒本の模擬試験4回目　正答率92%<br>
試験前にたたき出した結果がよかったので、間違った問題の穴埋め作業に従事。<br>
クラスが持っているメソッドやフィールドを一旦調べてみる等の工夫が効いた気がします。

<h2>感想・総評</h2>
今回、研修期間中にみっちり勉強できる時間があったのは大きいと思います。<br>
お陰様で32日の勉強期間で取得することができました。<br>
<br>
Streamが難しい割に出る頻度が高いので、しっかりみっちりねっとりと学習しましょう。<br>
実務でStream知識は必須的な話も聞いたことがあるので、参画前の修行として頑張った方がいいと思います。<br>
また、匿名クラスやインナークラスなどの基礎も理解してから挑んだ方が良いように感じました。<br>
あとは黒本を回せばわかってくる問題が多いかな？といった印象です。<br>
<br><br>
ﾁｬｶﾁｬｶと準備して決戦に挑めば未経験でも十分取れます。<br>
この記事を読んで、俺/僕/私でも、、はたまた未経験でもJava Goldまでいけるかも・・・！なんて少しでも感じていただけたら幸いです。自分を信じて進みましょう。いずれ合格を勝ち取れば勝率100%です。<br>
<br><br>
<br><br><br><br><br>
余談・・・<br>
HTMLのタグがよくわからず、使って慣れろ！と言われたのでやってますが難しいデスネ。<br>
本当はｐタグとか使うべきなんでしょうが、<ｂｒ>が使いやすいんじゃ～～！(よくわかっていない)<br>
気が向いたらHTMLの学習もしようと思います。

<table>
<tr><th>今回かかった費用</th><th>円</th></tr>
<tr><th>教材(メ〇カリで購入)</th><th>10000</th>
<tr><th>受験費用</th><th>35200</th></tr>
<tr><th>合計</th><th>45200</th></tr>
</table>
改めて見ると高い・・・
GCEインスタンスの起動停止を良きように自動化

# はじめに
GoogleCloudの環境で、踏み台のためにスペック小さく作っていたのですが、ちょっとコストが気になってきました。
平日にのみ必要なものなので、休日は止めておき平日必要になる前に起動すればよいものです。
もちろんこれを手動でやるのは嫌なので、コストをかけずに自動化しようと思います。

# 結論
- [インスタンススケジュール](https://cloud.google.com/compute/docs/instances/schedule-instance-start-stop?hl=ja)を利用する。
- 起動・停止を同曜日にしないためにはcronでタイミング指定する

# 詳細

## インスタンススケジュール
まさに今回やりたいことにそのまま合致する機能です。
> インスタンス スケジュールを使用するには、起動と停止の動作の詳細を指定したリソース ポリシーを作成し、ポリシーを 1 つ以上の VM インスタンスに接続します。

この機能が出る前であれば、Cloud Schedulerなど別サービスと組み合わせたり、**このVMを起動・停止するための別のサービス**が必要でしたが、インスタンススケジュールがあればここだけで完結します。

## 設定
今回は、①土曜日にVM停止②月曜8:00に起動(いずれも日本時間)で設定していきます。

#### 事前準備
対象となるVMは事前に用意しておいてください。VM自体に特別な設定は不要です

#### 手順(画面から実施します)


1. あらかじめ必要な権限を設定しておきます。
権限を付与するサービスアカウントは、デフォルトで用意された`service-${プロジェクト番号}@compute-system.iam.gserviceaccount.com`です。
権限としては、VMの起動、停止が出来る必要があります。最小限であればそのためのカスタムロールを作っても良いかもしれませんが、ここでは公式ドキュメント記載の通り「 Compute インスタンス管理者（v1）（roles/compute.instanceAdmin.v1）」を付与しておきます。
2. VMインスタンスの画面にて「インスタンス スケジュール」タブがあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2345258/b2f8825a-9ab5-0025-7aa2-96f4e3e442c0.png)
ここから[インスタンス スケジュールの作成]に進みます。

3. 各項目を埋めていきます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2345258/cd8630ec-81b4-e7d1-9e9c-5b3e4d7786bd.png)

繰り返しについては、日、週、月を選ぶことができ、週の場合は曜日を、月の場合は日付を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2345258/45e05fed-6938-3b39-e624-cce98e41213a.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2345258/9f5882ad-84d2-5415-5a51-9903f080f421.png)

基本の設定方法は、時刻と頻度（毎日 or 曜日指定)です。
この場合、指定された曜日で起動と停止をすることになります。

今回のように①土曜日に停止②月曜日に起動にしたい場合は、特定の曜日に起動&停止のセットをやりたいわけではないので、「CRON式を使用」をONにして設定します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2345258/efe2309e-7406-1e31-4137-31879a59b1f6.png)
必要な設定が出来たら[送信]します。
4. インスタンス スケジュールを既存の VM インスタンスに接続する
画面から作成したインスタンススケジュールを選択し、紐づけるインスタンスを選びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2345258/9c0067ec-a34a-8540-2ab7-e65ea7ee69a8.png)

権限付与が出来ていないと以下のようなエラーが出力されるので、権限設定を確認しましょう。
![405a8e65-1685-44ff-620c-f5b77a01a8a6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2345258/5ba5fe76-86df-eca9-857c-5e35e33eb5af.png)
エラーなく作成出来たら完了です

### 動作確認

土曜日の停止、月曜日の起動を待っての確認です。
ログを見ると、土曜00:12頃に停止し、月曜08:12頃に起動したことが見て取れます。
（最大15分のラグがあるとのことです。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2345258/c6713c27-eefc-8168-fe9a-c699b9054315.png)

これで期待通り、任意のタイミングでのVM自動停止、自動起動が出来るようになりました。

## 注意事項
### 各 VM インスタンスに接続できるのは 1 つのインスタンス スケジュールのみ

複数ポリシーの適用はサポートされていません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2345258/51449179-dc94-39e7-9c1a-52658aea938f.png)
複雑な起動・停止ルールを組むとしたらこの機能ではなく、Cloud Scheduler + Cloudd Functionsなどを検討すると良いでしょう。


## 参考
 - [VM インスタンスの起動と停止をスケジュールする | Google Cloud](https://cloud.google.com/compute/docs/instances/schedule-instance-start-stop)
WSL2上にCUIで動作するDockerをインストールする方法


この記事では、Windows Subsystem for Linux（WSL2）上に、CUIで動作するDockerをインストールする方法を説明します。

## 1. WSL2のインストール

まずはWSL2をインストールします。以下の手順で進めてください。

1. PowerShellを管理者権限で開きます。スタートメニューで「PowerShell」を検索し、右クリックから「管理者として実行」を選択します。
2. 以下のコマンドを実行し、WSLと仮想マシンの機能を有効にします。

```powershell
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
```

3.WSL2の更新プログラムを[こちら](https://learn.microsoft.com/ja-jp/windows/wsl/install-manual#step-4---download-the-linux-kernel-update-package)からダウンロードし、インストールします。
4.PowerShellで以下のコマンドを実行し、WSLのデフォルトバージョンを2に設定します。

```powershell
wsl --set-default-version 2
```

5.最後に、Microsoft Storeからお好きなLinuxディストリビューション（Ubuntuなど）をインストールします。

## 2. Dockerのインストール

1.WSL2で動作するLinuxディストリビューションを開きます。
2.以下のコマンドを実行し、Dockerのインストールスクリプトをダウンロードします。

```bash
curl -fsSL https://get.docker.com -o get-docker.sh
```

3.ダウンロードしたスクリプトを実行し、Dockerをインストールします。

```bash
sudo sh get-docker.sh
```

4.Dockerが正常にインストールされたことを確認します。

```bash
docker --version
```

5.Dockerをsudoなしで実行できるようにするため、現在のユーザーをdockerグループに追加します。

```bash
sudo usermod -aG docker $USER
```

6.システムを再起動します。


以上で、WSL2上にCUIで動作するDockerが構築されました。これでDockerコマンドを使ってコンテナの作成や操作が可能になります。
参考になればうれしいです！
すっきりわかるJava入門の要点をまとめてみた

・JVM(Java仮想マシン)とはJavaプログラムを実行するためのソフトウエア。
・elseの後に一行しかない場合は、波かっこは省略可能
・switch文では、break;を処理の末尾に記述する
・switch文で、どのcaseにも該当しない場合に行いたい処理をdefault:下に記述する。
・文字列を比較するときは、「==」ではなく、equalsを使う。
・配列の要素数は、lengthメソッド、ArrayListはsizeメソッドで取得できる。
・メソッドで渡す値を実引数、受け取る変数のことを仮引数と呼ぶ。
・package パッケージ名; で所属させるパッケージ名を決める。
・別のpackageであれば、クラス名が同一でもOK
・import パッケージ名.クラス名; で呼び出す際の入力を軽減できる。
(メソッドを呼び出すときに、メソッドの前にFQCN(完全限定クラス名)を記述する必要がなくなる)
・オブジェクト指向：機能、部品化に着目してコードを記述していく考え方
・コンストラクタとは、インスタンスを生成した直後に自動実行される処理
(クラス名と同一、戻り値がない)
・クラス名にfinalをつけると継承できない
・メソッド名にfinalをつけるとオーバーライドを禁止する。
・継承すると親クラスのコンストラクタが暗黙に実行される。(super();の記述がなくても実行される。)
・抽象クラスに抽象メソッドを定義して、継承した時にオーバーライドして使用する。
・抽象クラスはインスタンス化できない。
・抽象クラスのさらに曖昧度の高いのがインターフェイス
・インターフェースでは多重継承が可能。
・インターフェイス内のメソッドには、処理内容を書かなくて、継承するときにその実装を強制させることができる。
・カプセル化の方法、メンバ(フィールド、メソッド)をprivateにする
（基本的にメソッドはpublicにする。publicで全てのクラスからアクセスできる）
・カプセル化の方法、getterとsetterを使う。
・フィールドをstaticにすると、同じクラスから生成されたインスタンス間で共有できる。
・インスタンスを生成せずに利用するときにstaticを使う。
・Stringクラス　equals, equalsIgnoreCase, length, isEmpty, contains, startsWith, endsWith, indexOf, lastIndexOf, charAt, substring, toLowerCase, toUpperCase, trim, replace
・＋演算子による文字列の連結は、インスタンスの生成を一回ごとに行っているので、繰り返し行う場合は、StringBuilderの方が高速に行える。
・コレクションクラスのHashSetクラスでは、要素は重複が許されない。インデックスがない。
・HashMapクラスは、keyとvalueで格納する。
・例外処理のfinallyで必ず実行する処理を書く。
・try-with-resources文で記述すれば、closeメソッドの記述は不要。
・throwsでメソッド内での例外をスキップできるが、呼び出し側でtry-catch文を記述する義務が発生する。
・throw 例外インスタンス名;で例外を発生させることができる。
Tarraformを使ってAWSにWebサーバを構築 #6 ~Webサーバ用EC2を立ち上げる~

## 目的
EC2にNginxがインストールされた状態を作り出し、ブラウザからデフォルトページが確認できることをゴールとする。
インフラ構築はTerraformでコード化することで再現性、再利用性、速度などが手作業に比べると高い。
[GitHubリンク](https://github.com/keitasato/terraform-nginx)

### 手順
1. [TerraformからAWSリソースを操作できるように設定する](https://qiita.com/kekkepy/items/4185a621e5d3cc75016b)
1. [Terraformをインストールする](https://qiita.com/kekkepy/items/1b3f4f14bbc2d2dc2c9b)
1. [TerraformでEC2サーバを立ち上げてみる](https://qiita.com/kekkepy/items/8b84fc0c39313267a078)
1. [ネットワークを整える(VPC, サブネット, ルーティングテーブル,インターネットゲートウェイ)](https://qiita.com/kekkepy/items/c941c00536af57bae163)
1. [セキュリティグループ(ファイアウォール)を設定する](https://qiita.com/kekkepy/items/47dcda4d9a7a2064382f)
1. [Webサーバ用EC2を立ち上げる](https://qiita.com/kekkepy/items/81bfa5d542c9160d430b)
1. [Webサーバが立ち上がる際にWebサーバソフトをインストールするように設定する](https://qiita.com/kekkepy/items/209f7ddb29fb5af65a6e)

#### 今回の到達点
Webサーバ用EC2を立ち上げる

#### Webサーバを立てる準備
- ネットワークを構築する
- ネットワークに許可する通信を設定する
- EC2をプライベートネットワークに所属させて外部からアクセスできるようにする **←今回はここ！**
- EC2にWebサーバソフト(今回はNginx)をインストールする

##### Step1. キーペアを作成する
SSHでWebサーバにアクセスする際に必要なキーペアを作成しておく。
このキーペアをEC2をTerraformから作成する際に設定しておくことで、適切なキーペアを持つユーザのみがアクセスできるようにする(コマンド実行するとパスフレーズを求められるが何もしないでEnterがオススメ)。
```
$ ssh-keygen -t rsa -b 2048 -f kekkepy-keypair
```
以下2ファイルが作成される。
- kekkepy-keypair(秘密鍵)
- kekkepy-keypair.pub(公開鍵)

秘密鍵のファイル名を「kekkepy-keypair.pem」に変更する。
※ファイル内に全角や日本語があるとエラーとなるので除去しておく。

##### Step2. webserver.tfを作成
EC2インスタンスを作成するための設定を行う。
C:\Users[ユーザ名]\Documents\MyProject\terraform\webserver.tf
```terraform:webserver.tf
# Key pair
resource "aws_key_pair" "keypair" {
  key_name   = "${var.project}-${var.environment}-keypair"
  public_key = file("./kekkepy-keypair.pub")

  tags = {
    Name    = "${var.project}-${var.environment}-web-sg"
    Project = "${var.project}"
    Env     = "${var.environment}"
  }
}

#Web server
resource "aws_instance" "web_server" {
  ami                         = "ami-0cfc97bf81f2eadc4"
  instance_type               = "t2.micro"
  subnet_id                   = aws_subnet.public-subnet.id
  associate_public_ip_address = true
  vpc_security_group_ids      = [aws_security_group.web_sg.id]
  key_name                    = aws_key_pair.keypair.key_name

  tags = {
    Name    = "${var.project}-${var.environment}-webserver"
    Project = "${var.project}"
    Env     = "${var.environment}"
    Type    = "app"
  }
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1221536/4d10d905-f62b-b1a0-74a4-f7711827e18f.png)
GoogleCloud（GCP）のCloud Functions上で動作するPythonからGCE（Google Compute Engine）を起動・停止させる

# 説明
タイトルにある通りです。GoogleCloudのpython用のAPIの説明が分かりづらかったので、載せました。
# 実行環境
GoogleCloudのCloudFunctions(第二世代)
# プログラム
pythonのプログラム。main関数を適宜変更してください。
```python:main.py
import functions_framework
from google.auth import compute_engine
from google.cloud import compute_v1

@functions_framework.http
def main(request):
    # project名
    project = "xxxxxxxxxxxx"
    # ゾーン名（リージョン）
    zone = "asia-northeast1-c"
    # 仮想マシン名
    instance ="xxxxxxxxxxxxxx"
    
    # 仮想マシンを止めるとき
    stop_VM(project,zone,instance)
    # 仮想マシンを起動させるとき
    start_VM(project,zone,instance)
    
    return "200"



def start_VM(project,zone,instance):

    credentials = compute_engine.Credentials()

    Instance = compute_v1.InstancesClient(credentials=credentials)

    Instance.start(project=project,instance=instance,zone=zone)
   

def stop_VM(project,zone,instance):
    credentials = compute_engine.Credentials()

    Instance = compute_v1.InstancesClient(credentials=credentials)

    Instance.stop(project=project,instance=instance,zone=zone)
    
```
ライブラリ関連
```txt:requirements.txt
functions-framework==3.*
google-api-core
google-auth
google-cloud-appengine-logging
google-cloud-audit-log
google-cloud-billing-budgets
google-cloud-compute
google-cloud-core
google-cloud-error-reporting
google-cloud-logging
googleapis-common-protos
grpc-google-iam-v1
grpcio
grpcio-status
```
# 実行方法
Cloud Functionsにデプロイしてください。APIの認証など適宜お願いします。

その後、以下のページへ行きCLOUD SHELLでテストを押せばターミナルが開き、実行できます。
成功すれば、対象のGCEは起動したり、停止したりします

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3373520/40193d1e-fbc3-1b11-299f-6d46001add25.png)

めちゃくそテキトーですが、役に立てばうれしいです
【Flutter】Androidシミュレータにapkインストール

apkファイルをドラッグ＆ドロップでいけます

![スクリーンショット 2023-07-03 16.17.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494487/33aa963e-ae56-0e76-16bf-46d30a54dc14.png)

コマンド打たなくちゃいけないのかめんどくさいなあああああなんて思いつつ、手順の最初にドラッグ＆ドロップをしろってかいてあってやったらアプリとしてそのまま使えたので便利になったなあああなんて思いつつせっかくなので共有です
【JavaScript】データの一部をkeyにリスト型をオブジェクト型に成型する

初心者の備忘。
## やりたいこと
配列をオブジェクトのオブジェクトにする。
~~~
//START
sampleList=[
         {no:1, name:hoge, value:"ほげ"}
        ,{no:2, name:fuge, value:"ふげ"}
        ,{no:3, name:fuga, value:"ふが"}
       ]

//GOAL
sampleObject = {
         1:{no:1, name:hoge, value:"ほげ"}
        ,2:{no:2, name:fuge, value:"ふげ"}
        ,3:{no:3, name:fuga, value:"ふが"}
        }
~~~

## サンプルコード
~~~sanple.js
let sampleObject = {}; //空のオブジェクトを宣言
sampleList.forEach(function(list){
   sampleObject[list.no]=list; 
});
~~~

## ちょっと解説
Object[key名]=value名で、Objectの中に{key:value}のオブジェクトが作られる。
forEachで回すことで、複数の配列をすべてObject型に変更可能。
配列の値を使わずにkey名を決めるなら、通常のfor文でiとかをkeyに充てればよい。
ランダムフォレストを用いたクラスタリングの性能比較（二次元）

## ランダムフォレストを用いたクラスタリングの性能比較（二次元）

前回の記事「[ランダムフォレストはクラスタリングに用いられる](https://qiita.com/RDProm/items/56a199ee57a7e27cf2cc)」ではランダムフォレストを階層型(凝集)クラスタリングに応用する方法を述べたが, 今回はこれが他の一般的なクラスタリングアルゴリズムに比べてどのような性質を示すかを見ていく.

### Scikit-learnの公式ドキュメントと比較する

Scikit-learnの公式ドキュメントでは, いくつかのクラスタリング手法について比較が行われている.

https://scikit-learn.org/stable/auto_examples/cluster/plot_cluster_comparison.html

今回はこれに倣い, クラスタリング手法の一つに今回の「ランダムフォレストクラスタリング(仮)」を追加していく.

## 準備

### RandomForestClusteringクラス

Scikit-learnのコード内で他のクラスタリング手法と同様に扱えるよう, クラスとして定義しておく.

```python
import numpy as np
import matplotlib.pyplot as plt
from sklearn.ensemble import RandomForestClassifier
from sklearn.cluster import AgglomerativeClustering

class RandomForestCustering:

    def __init__(self, n_clusters, classifier_min_samples_split=0.05):
        #self.rng = np.random.default_rng()
        self.rfc = RandomForestClassifier(min_samples_split=classifier_min_samples_split)
        self.m = n_clusters
        self.label_ = []
    
    def fit(self, X):
        ii = np.random.choice(X.shape[0], size=[X.shape[0], X.shape[1]])
        X_gen = X[ii, np.arange(X.shape[1])]
        
        # RandomForest で2値分類
        # オリジナルデータならラベル 1
        X_bin = np.vstack([X, X_gen])
        y = np.hstack([np.ones(X.shape[0]), np.zeros(X.shape[0])])
        self.rfc.fit(X_bin, y)
    
        # オリジナルデータの類似度行列作成
        # T: X_org の各行データが RandomForest の各木でどの葉に落ちるか表す行列, shape=[n, n_estimator]
        # P: 類似度行列, shape=[n, n]
        T = self.rfc.apply(X)
        P = np.mean(T[:, np.newaxis]==T, axis=-1)
        
        # 類似度行列から距離行列を作ってクラスタリング
        # distance matrix に基づくクラスタリングに対応した関数が必要
        # AgglomerativeClustering だと affinity='precomputed' が必要で linkage は 'ward' 以外なら何でも使えるらしい
        k = self.m # クラスタ数
        D = np.sqrt(1-P)
        clst = AgglomerativeClustering(k, metric='precomputed', linkage='average')
        self.labels_ = clst.fit(D).labels_
        return self.labels_
```

### Scikit-learnの[比較スクリプト](https://scikit-learn.org/stable/auto_examples/cluster/plot_cluster_comparison.html)への組み込み


```python
    rfc = RandomForestCustering(n_clusters=params["n_clusters"])

    clustering_algorithms = (
        ("MiniBatch\nKMeans", two_means),
        ("Affinity\nPropagation", affinity_propagation),
        ("MeanShift", ms),
        ("Spectral\nClustering", spectral),
        ("Ward", ward),
        ("Agglomerative\nClustering", average_linkage),
        ("DBSCAN", dbscan),
        ("HDBSCAN", hdbscan),
        ("OPTICS", optics),
        ("BIRCH", birch),
        ("Gaussian\nMixture", gmm),
        ("RandomForest\nClustering", rfc),
    )
```

## 結果

図の一番右にRandomForestClusteringの列が追加されている.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2988004/a2b2bb68-251c-a517-c44b-9e3116519e73.png)


本結果においては, 他の手法に対して優位性があるわけではなさそうである.
また、距離の算出にランダムフォレストの二値分類モデルを利用しているため, そのハイパーパラメータや乱数によって結果が大きく変わる傾向があった.

ただし, 本手法の特徴は

・計算速度がレコード数依存で, 説明変数の次元数によらない
・ユークリッド距離とは異なる指標でクラスタリングがなされる

という部分である.

今回の比較実験においては「二次元かつ視覚評価に頼った比較では本手法の優位性の確認はできない」ということが確認された, といえるかもしれない.
C#/VB.NETでPDFをマージする

複数のPDFファイルを1つのファイルに結合することは、関連する文書、レポート、または資料の組織と管理において大きな利点を持っています。それは可読性を向上させるだけでなく、情報のシームレスな共有を促進します。PDFファイルを一緒に結合することで、複数のファイルを繰り返し開閉する必要がなくなり、時間と労力を節約できます。さらに、このプロセスにより、ファイルの総数が減少し、ファイルの保存とバックアップが簡素化されます。ファイル結合にはソフトウェアを使用する以外に、プログラミングによっても実行できる優れた方法です。この記事では、C#およびVB.NETを使用して複数のPDFファイルを1つのファイルに結合する方法を紹介します。
## プログラム環境
* [Free Spire.PDF for .NET](https://www.e-iceblue.com/Introduce/free-pdf-component.html#.ZH_ihWdByUk)
* Visual Studio 2022

## DLLファイルのインポート
* Visual Studioを開いて新しいプロジェクトを作成します。
* 「Solution Explorer」で「References」を右クリックします。
* 「NuGet Manage Packages」を選択します。
* Free Spire.PDF for .NETを検索してインストールします。
または、この[リンク](https://www.e-iceblue.com/Download/download-pdf-for-net-free.html)から直接ダウンロードすることもできます。
* Visual Studioを開いて新しいプロジェクトを作成します。
* 「Solution Explorer」で「References」を右クリックします。
* 「Add Reference」を選択します。
* 「Browse」をクリックします。
* DLLを検索してインストールしてプロジェクトにインポートします。

## コード
**C#:**
```C#
using System;
using Spire.Pdf;

namespace MergePDFs
{
    class Program
    {
        static void Main(string[] args)
        {

            //ドキュメントのパスを取得する
            String[] files = new String[] {
                "C:\\Users\\Administrator\\Desktop\\PDFs\\sample-1.pdf",
                "C:\\Users\\Administrator\\Desktop\\PDFs\\sample-2.pdf",
                "C:\\Users\\Administrator\\Desktop\\PDFs\\sample-3.pdf"};

            //ドキュメントをマージしてPdfDocumentBaseのオブジェクトを返す
            PdfDocumentBase doc = PdfDocument.MergeFiles(files);

            //結果をPDFファイルに保存する
            doc.Save("Output\\result.pdf", FileFormat.PDF);
        }
    }
}
```
**VB.NET:**
```VB
Imports System
Imports Spire.Pdf
 
Namespace MergePDFs
    Class Program
        Shared  Sub Main(ByVal args() As String)

            'ドキュメントのパスを取得する
            Dim files() As String =  New String() {"C:\\Users\\Administrator\\Desktop\\PDFs\\sample-1.pdf","C:\\Users\\Administrator\\Desktop\\PDFs\\sample-2.pdf","C:\\Users\\Administrator\\Desktop\\PDFs\\sample-3.pdf"}

            'ドキュメントをマージしてPdfDocumentBaseのオブジェクトを返す
            Dim doc As PdfDocumentBase =  PdfDocument.MergeFiles(files) 
 
            '結果をPDFファイルに保存する
            doc.Save("Output\\result.pdf", FileFormat.PDF)
        End Sub
    End Class
End Namespace
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2811193/72ae2e31-49e4-fc3e-283f-3b1bf2d1e909.png)
まず、入力パスを取得します。 次に、**PdfDocument.MergeFiles()** メソッドを呼び出して、これらのファイルをマージします。 最後に、**PdfDocumentBase.Save()** メソッドを使用して、結果を PDF ドキュメントに保存します。
上記の方法を参照して、このライブラリを通じて[PDFを圧縮](https://www.e-iceblue.com/Tutorials/Spire.PDF/Spire.PDF-Program-Guide/Document-Operation/How-to-Compress-PDF-Document-in-C-VB.NET.html)し、PDFに[画像の透かし](https://www.e-iceblue.com/Tutorials/Spire.PDF/Spire.PDF-Program-Guide/Watermark/Add-image-watermark-to-pdf-in-C.html)と[テキストの透かし](https://www.e-iceblue.com/Tutorials/Spire.PDF/Spire.PDF-Program-Guide/PDF-Watermark-Add-Watermark-in-PDF-with-C-VB.NET.html)を挿入することもできます。
[AWS Q&A 365][Fargate]AWSのよくある問題の毎日5選 #89

# 1. AWS Fargateのアカウント設定とは何ですか？
回答: AWS Fargateのアカウント設定とは、AWSアカウントに適用する設定オプションとプリファレンスを指します。これには、リソースの上限、ネットワークの設定、セキュリティの設定などが含まれます。

# 2. AWS Fargateで私のアカウント設定をどのように確認できますか？
回答: AWS Fargateでアカウント設定を確認するには、AWS管理コンソールの「アカウント設定」セクションに移動します。これにより、利用可能な設定の一覧が表示され、必要に応じてそれらを変更することができます。

# 3. AWS Fargateでアカウント設定を変更できますか？
回答: はい、必要に応じてAWS Fargateでアカウント設定を変更することができます。ただし、一部の設定は制限があるか、変更するために特定の権限が必要な場合があります。

# 4. AWS Fargateで変更が必要な一般的なアカウント設定は何ですか？
回答: AWS Fargateで変更が必要な一般的なアカウント設定には、リソースの上限、ネットワーク設定、およびセキュリティ設定があります。例えば、大規模なワークロードを対応させるためにリソースの上限を増やす必要があったり、特定の種類のトラフィックを許可するためにネットワーク設定を変更する必要があるかもしれません。

# 5. AWS Fargateのアカウント設定の変更には制限がありますか？
回答: はい、AWS Fargateの特定のアカウント設定の変更には制限がある場合があります。例えば、一部の設定は特定の権限が必要であったり、特定の地域やアカウントタイプでは利用できないかもしれません。また、特定の設定の変更はAWS環境の他の側面に影響を及ぼす可能性があるため、変更を行う前に注意深く変更を確認することが重要です。
[AWS Q&A 365][Fargate]Daily Five Common Questions #89

# 1. What are account settings in AWS Fargate? 
Answer: Account settings in AWS Fargate refer to the configuration options and preferences that apply to an AWS account. These can include settings for resource limits, network configurations, and security preferences. 

# 2. How can I view my account settings in AWS Fargate? 
Answer: You can view your account settings in AWS Fargate by navigating to the "Account Settings" section of the AWS Management Console. This will display a list of available settings and allow you to modify them as needed. 

# 3. Can I modify my account settings in AWS Fargate? 
Answer: Yes, you can modify your account settings in AWS Fargate as needed. However, some settings may have restrictions or require specific permissions to modify. 

# 4. What are some common account settings that may need to be modified in AWS Fargate? 
Answer: Some common account settings that may need to be modified in AWS Fargate include resource limits, network configurations, and security preferences. For example, you may need to increase your resource limits to accommodate larger workloads, or modify your network configurations to allow for specific types of traffic. 

# 5. Are there any restrictions on modifying account settings in AWS Fargate? 
Answer: Yes, there may be restrictions on modifying certain account settings in AWS Fargate. For example, some settings may require specific permissions or may not be available in certain regions or account types. Additionally, modifying certain settings may have potential impacts on other aspects of your AWS environment, so it is important to carefully review any changes before making them.
condaのactivateになぜか失敗する

# 背景
「ある環境ではcondaを使えるのに、別の環境だと突然使えなくなった…」
最近、この件について時間を溶かしている人を多く聞くので、こちらの記事をまとめました。

問題となるエラーは、condaをactivateした際に発生する以下のものです。
```
Traceback (most recent call last):
  File "/work/hoge/**/miniconda3/bin/conda", line 12, in <module>
    from conda.cli import main
ImportError: No module named conda.cli
```
`/work/hoge/**/miniconda3/bin/python`を立ち上げてcondaをimportしてみると、問題なく実行できます。これは、一体どういうことなのでしょうか？

# 解決法
先に問題の解決方法を挙げますと、以下のどちらかを選んでください。

- 仮想環境を構築するパスの長さを浅く（bin/python含めて127文字以下に）する
- 最新のOSにアップデートする

（他にも良い方法がありましたらお知らせください）

# 原因
エラーメッセージに表示されていたファイルの１行目を見てみてください。
```
$ head -n 1 /work/hoge/**/miniconda3/bin/conda
```
ここで、もしかすると以下のように表示されていませんか？
```
#!/usr/bin/env python
```
本来ならば、ここは
```
#!/work/hoge/**/miniconda3/bin/python
```
となっていて欲しいはずです。もしかして、あなたのケースでは、`**`の部分がかなり長い文字列になっていないでしょうか？　実は、shebangの長さは決まっていて、それ以上長いとOSが処理することができません。そのため、自動で`#!/usr/bin/env python`に書き換わる仕様になっているようです（どちらかというと、エラーを吐いて落ちて欲しいですが…）。

そのshebangの最大長は、以下で確認することができます。
```
$ grep BINPRM_BUF_SIZE /usr/include/linux/binfmts.h
```
Ubuntu 22.04ならこの値は256になっていますが、古いOSだと128になっていることが多いです。このため、上記の問題を解決するためには、OSをアップデートするか、そもそものパスを短くすれば良いということになります。もちろん、最新のOSでもshebangの最大長はありますので、この長さを超えないようにする必要があります。パスの最大長は`BINPRM_BUF_SIZE`より1だけ小さくなりますが、エクスクラメーションマーク（!）の分によるものかと思われます。

# 終わりに
いかがでしたでしょうか。個人的には、もう少し周知されても良い内容なのではないかと思います。GitHubの方ではissueが立っているようなので、今後何かしらの進展があるかも知れません。

初めての記事でお見苦しいところがあるかも知れませんが、皆様の活動の一助となれば幸いです。
ここまでお読みくださり、ありがとうございました。

2023年7月3日　満月


# 参考
https://github.com/conda/conda/issues/12250

https://github.com/conda/conda/issues/977

https://stackoverflow.com/questions/10813538/shebang-line-limit-in-bash-and-linux-kernel
【Data and AI Summit 2023】世界中に聞いた！Databricksで最も興味のある新しい機能は？

# はじめに
6/26 ～ 6/29 の期間、アメリカのサンフランシスコ(＋オンライン)で「データ& AI」における世界最大規模のカンファレンスが Databricks 社主催で開かれました。
現地での参加人数はなんと10000人を超えており、今データ & AI の分野は世界で最高潮に盛り上がっております。
日本でも Chat GPT など自然言語に関するAIは最近非常に話題になっていたりもしますね。
今回はサミットのイベントの中でも特にビッグな講演であるキーノートにて、新しく発表された機能の中で、特にどの機能が興味深かったのかを軽く調査してみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2704291/c6247e57-49c3-d9d1-1a3f-1c2abf6c840d.png)


キーノートは2日間にわたって行われ、詳細は弊社ブログにてまとめておりますので以下からご覧ください。

[キーノート1日目](https://azure-recipe.kc-cloud.jp/databricks_data_ai_summit_2023_keynote_day1/)
[キーノート2日目](https://azure-recipe.kc-cloud.jp/databricks_data_ai_summit_2023_keynote_day2/)


# 調査方法
Databricks Community を利用しました。
Databricks Community とは 全世界の Databricks ユーザーが集まるコミュニティサイトです。
https://community.databricks.com/

こちらでは掲示板のような機能がありまして Databricks に関する疑問について投げかけるとそれをみたコミュニティのユーザーが返答してくれます。

こちら利用して以下のように質問を投げかけてみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2704291/76db5c53-7980-8728-3f72-fe2d1231007b.png)

# 結果

なんと数時間で5件も返答が返ってきました！
では気になる結果についてです。

1位 Lakehouse IQ : 3票
2位 同率: 1票ずつ
・Lakehouse Federation
・Lakehouse AI
・Marketplace
・Mosaic ML

返答は5件ではあったのですが、複数機能を挙げてくださった方がいたため結果的に7票集まりました。それだけ 1つに選びきれなかったということですね！

詳細を見ていくと Lakehouse IQ が3票集め、堂々の1位となりました！

キーノート内で行われた Lakehouse IQ のデモにおいても、プログラムを書かず、自然言語である英語でデータを扱っていた場面はとても盛り上がったように思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2704291/68161783-155b-e10f-29d5-1eabe910a139.png)

やはり海外から見ても生成AIの分野は熱いですね。
今後使っていくのが非常に楽しみです！

# さいごに
今回の Data and AI Summit 2023 ではサンフランシスコまで筆者は現地参加しておりました。
現地にて感じた Databricks を活用して目指したい最先端の姿について、[こちら](https://qiita.com/Tsubasa-Koyama/items/1ec959fb79b3ef80e0f6)で触れさせていただいているため、もしよろしければ一読いただけますと幸いです。
Proxmox7 を試してみる　その１０　Qemu-guest-agent 設定

# いわゆる GA 
ホストOSである Proxmox からシャットダウンが効かないと思っていたら Qemu-guest-agent(GA) をインストールしていませんでした。

![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44540/46296929-5610-a404-d40a-c5a27033e545.png)

# まず Proxmox のVM設定でQemuを有効化する
デフォルトの設定は無効化（VM作成するとき Qemuにチェックなし）されているのでこちらを有効化します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44540/3d358059-f3f1-c9a4-f8e5-e7b9c765e9a8.png)

# Linux の QEMUエージェント
Debian/Ubuntu か Redhat 系によってインストールコマンドが異なるが Qemu-guest-agent(GA) をインストールしてあげればよい。

```bash
Debian/Ubuntu系
$ sudo apt-get install qemu-guest-agent

Redhat系
$ sudo yum install qemu-guest-agent
```

あとはサービスを起動してあげる

```bash
$ sudo systemctl start qemu-guest-agent
$ sudo systemctl enable qemu-guest-agent
```

きたーー

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44540/50ec859f-953a-8b8a-8a3f-3e44f3c0cfa4.png)

# Windows の QEMUエージェント

Windows の QEMUエージェント は、[virtio-win.iso](https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso) の中にありますが少しわかりずらい。32/64ビットによってインストーラが異なるが実行すればよし。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44540/396a26df-7279-42ab-a542-3aebdecb147a.png)

きたーー

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44540/50ec859f-953a-8b8a-8a3f-3e44f3c0cfa4.png)

# 参考にさせて頂いたサイト様

https://pve.proxmox.com/wiki/Qemu-guest-agent

https://blog.hitsujin.jp/entry/2023/05/15/proxmox-createvmwin

https://zenn.dev/northeggman/articles/d7b29c4e2cd7c7
パスワード（半角英数混合必須）のバリデーション

## はじめに

Railsのパスワード設定で保存する際に、
「半角のアルファベットと半角数字が混合でなければならない」場合の
バリデーションを設定する方法について解説します。

※今回はpassword属性に対してバリデーションを実行します。

## 結論

```user.rb
validates :password, format: {
    with: /\A(?=.*?[a-z])(?=.*?[\d])[a-z\d]+\z/i,
    message: 'は英数字の混合である必要があります'
  },on: :create
```

Userモデルに上記の記述を追加する事で、半角英数混合の
バリデーションを設定することが出来ます。
※今回は`on: :create`を指定していますが、合わせて解説していきます。

## 解説

```user.rb
validates :属性の名前, format: {
```

1行目では、validatesでバリデーションを設定する属性の名前を指定します。
今回設定する属性は`password属性`です。
また、format:オプションで正規表現にて特定のパターンについて
合致するか確認してくれます。


```user.rb
with: /\A(?=.*?[a-z])(?=.*?[\d])[a-z\d]+\z/i,
```

2行目では、with:オプションにて正規表現パターンを指定する事が出来ます。
`/\A(?=.*?[a-z])(?=.*?[\d])[a-z\d]+\z/i,`の部分が正規表現になります。
上記正規表現により、`password属性`の値が英字と数字の組み合わせであるかを
チェックしてくれます。

```user.rb
message: 'は英数字の混合である必要があります'
```

3行目では、message:オプションにてバリデーションが失敗した時に
表示されるエラーメッセージをしています。

```user.rb
},on: :create
```
4行目の`on: :create`を設定することでcreateアクションの時のみ
バリデーションが実行されるよう制限することが出来ます。
つまり、既存のレコードの更新時などにはバリデーションは
実行されないという形になります。


## 補足(正規表現について)
正規表現については知識が浅い為、解説できませんでしたが、
正規表現のチェックを行なってくれる[Rubular](https://rubular.com/)というサイトがあるので
興味がある方は覗いてみて下さい！
Pythonからmysqlを操作する

## インストール
```
pip install mysql-connector-python
```

## データベースの作成
```python
import mysql.connector

conn = mysql.connector.connect(host='172.24.20.34', user='root', password='tmcit')
curs = conn.cursor()

curs.execute('CREATE DATABASE my_database')

curs.close()
conn.close()
```

## レコードの全件取得
```python
import mysql.connector

conn = mysql.connector.connect(host='172.24.20.34', user='root', password='tmcit', database='LESSON')
curs = conn.cursor()

curs.execute('SELECT * FROM LESSON_2025')
print(curs.fetchall())

curs.close()
conn.close()
```

```python
curs.execute('SELECT * FROM LESSON_2025')
rows = curs.fetchall()

for row in rows:
  print (row)
```


## データの挿入
```python
import mysql.connector
conn = mysql.connector.connect(host='172.24.20.34', user='root', password='tmcit', database='LESSON')
curs = conn.cursor()

curs.execute('insert into LESSON_2025(LESSON_NAME, ACCEPTED_GRADE)values("理科", 2)')

##コミット作業
conn.commit()

curs.close()
conn.close()
```


## 変数を用いる場合
```python
name="算数"
grade=2
curs.execute('insert into LESSON_2025 (LESSON_NAME, ACCEPTED_GRADE) values (%s, %s)', (name, grade))
conn.commit()
```

## データベースの要素を取りだす
データベースから引っ張ってきたデータはタプル型に格納されて帰ってくるので、添え字で指定する事によって要素の取りだしが出来る。例：row[0]

```python
curs.execute('SELECT LESSON_NAME FROM LESSON_2025')
rows = curs.fetchall()

for row in rows:
  print (row[0])
```
結果
```
root@shoma:/home/shoma/ED# python3 sel.py
2
kokugo
国語
算数
理科
```


## 参考サイト
- https://yuk.hatenablog.com/entry/2014/07/07/235408
jQueryでクリックした箇所のみ要素を隠す・出現させる方法

クリックしたら行に詳細なコンテンツ、別の行をクリックしたら元に戻すにはどうすればいいのかわからなくて困ったので知見をシェアします。
 $('.data__item'). でdivタグのクラス要素を指定し、findでhtml中のclassを見つけ、.cssで display: none or block を書き換えています。
$(this)でクリックした部分のみ書き換えを行っています。


```hide_show.php
<div class="data__item">
    <div class="js-contents-show" style="display: none;">出現</div>
</div>
<div class="data__item">
    <div class="js-contents-hide" style="display: block;">隠す</div>
</div>
<script>
$(function() {
    $('.data__item').on('click', function() {
    $('.data__item').find('.js-contents-show').css('display','none');  
    });
    $('.data__item').on('click', function() {
    $(this).find('.js-contents-show').css('display','block');  
    });
    $('.data__item').on('click', function() {
    $('.data__item').find('.js-contents-hide').css('display','block');  
    });
    $('.data__item').on('click', function() {
    $(this).find('.js-contents-hide').css('display','none');  
    });
});
</script>
```
Raspberry Pi OS + MariaDB + PHP8で軽開発環境作成

![20230704_080019.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458322/484d652a-cb55-8416-a74f-eced2b38a6cd.jpeg)
２年前、新入社員（研修）の開発環境として、
ほぼ自分の趣味ですが、Raspberry Pi 4 + CentOS + MariaDB + PHPを作成しました。
そのまま放置していたのですが、昨今、再び出番となりました。
しかし、CentOSがEOLなので、Rocky LinuxやらAlmaLinuxやらを試しましたが・・・
要はPHP8が動けばいいので、Raspberry Pi OSにしました、その手順記録です。

## SDへOS書き込み
[Raspberry Pi Imager](https://www.raspberrypi.com/software/)を使う。
Raspberry Pi OS(Other)  ⇒  Raspberry Pi OS Lite(64-bit)
一般ユーザー/パスワードは、書き込み前、アプリに設定しておく。
## 初起動後アップデート
```console
$ sudo apt update
$ sudo apt full-upgrade -y
$ sudo apt clean

再起動
$ sudo reboot
```
## rootパスワード設定
```console
$ sudo passwd root
```
### 以降はrootで実行
```console
$ su -
```
## IPアドレスを固定
```console
# vi /etc/dhcpcd.conf
最下部に追記
interface eth0
static ip_address=192.168.xx.xx/24
static routers=192.168.xx.1
static domain_name_servers=192.168.xx.1

再起動
# reboot
```
## Apache
### インストール
```console
# apt install apach2 -y
```
### .htaccess有効化
```console
# vi /etc/apache2/apache2.conf
AllowOverride None ⇒ AllowOverride Allに変更
<Directory /var/www/>
    Options FollowSymLinks
    AllowOverride All
    Require all granted
</Directory>

再起動
# reboot
```
### ディレクトリ所有者変更
```console
# chown 一般ユーザーID /var/www
# chown 一般ユーザーID /var/www/html
```
## PHP8
### 参考（8にする手順）
https://www.hiramine.com/programming/php/install_php8_on_raspi.html
### インストール
```console
# apt install php php-mbstring php-mysql -y

再起動
# reboot
```
## MariaDB
### インストール
```console
# apt install mariadb-server -y
# mysql_secure_installation
```
### 参考（応答部分）
https://qiita.com/airpocket/items/f1dd8e0d32be6075b7de
### DB一般ユーザーとDB作成
```console
rootでログイン
# mysql -ｄｆ root -p

新規DBへの全てのアクセス権限を持った、DB一般ユーザーを登録
> grant all privileges on 新規DB.* to DB一般ユーザーID@localhost identified by 'DB一般ユーザーパスワード';

ログアウト
> exit

DB一般ユーザーでログイン
# mysql -ＤＢ一般ユーザーID -ＤＢ一般ユーザーパスワード

新規DB作成
> create database 新規DB;

ログアウト
> exit
```
### DBバックアップ
```console
# mysqldump -u root -p DB名 > バックアップファイル名
```
### DBリストア
```console
# mysql -u root -p DB名 < バックアップファイル名
```