OmniAICreator/Qiita-1.07M huggingface dataset:
FPVドローン ラップ計測システム【RotorHazard】を作っちゃおう ～その4～

# 7. RotorHazardの初期設定
まずはちゃんと動いているかの確認をします。ブラウザを起動して、上部のアドレスバーに下記URLを入力します。

<img width="500" alt="Qiita-RH188.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500291/d3cf4887-8931-4811-b666-36556ecd1268.png">

RotorHazardの初期画面が出ればOKです。(ここで表示されなければ…何かの作業が漏れているか？エラーですっ飛ばしているのかもしれませんので、振り返りしてみてください。)
そして、一番下の **【Admin / Settings】** を選択します。

![Qiita-RH19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500291/2628cab2-2a55-b659-a794-c558ba3ce2ad.png)

ユーザ、パスワードを聞いてきますが、これは先ほどの設定をした管理者アカウントの文字列を入力します。
そのまま問題がなければ、画面右上の **【Settings】** をクリックしてください。

![Qiita-RH20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500291/945ce586-a9f9-0df9-079e-7487a0cd055a.png)

まず最初に…日本語にしましょう！
**System** を選択すると、赤枠のようにLanguage項目があるので、日本語を選んでください。

![Qiita-RH21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500291/d8efcb00-063b-09c3-f079-c57442b8bf31.png)

これで日本語化ができました。

ちなみにですが…自分が日本語化しているが故にテマエミソなのですが… いつも、表現が適正か？ニュアンスがおかしくないか？を模索していたりします。その為、時期・タイミングや新しいバージョンが出た場合には差し替えをするかもしれません。本家GitHubには修正すればプルリクしますが、更新・反映の遅い場合がありますので、下記に非公式メンテナンス用として日本語辞書ファイルを置いておきます。ファイル名を `language.json` に変更してもらい `RotorHazard-4.1.0-b2¥src¥server` 以下に上書きしてください。そうすれば、新しい日本語辞書ファイルに置き換わります。

https://drive.google.com/drive/folders/1y1OPJHpk9-nOCIxd6A7c21eCx95nd96r?usp=drive_link

# 8. 【start.bat】の配置と簡単起動
起動する際に、わざわざコマンドプロンプトで `RotorHazard-4.1.0-b2¥src¥server` に移動し、そこから `python server.py` って叩くのも…多分面倒かと思います。なので簡単ではありますが、Windowsバッチファイルを作ってショートカットで叩いて起動するという流れの方が良いかも？と思い、参考ではありますが記載したいと思います。実際、完全にサービス(デーモン)として稼働させても良いのですが、私は起動してコマンドプロンプトが出ているコンソールに表示される文字列を確認したいため、この方法を取りました。(音声でしゃべり出す際に、コンソールで文字列表示されるシーンがあったりするので、その確認のため)

```start.bat
@echo off
echo.
set /p "answer= RotorHazardを起動しますか？ [y/N]: "
if /i "%answer%"=="Y" (
	echo.
    echo RotorHazard 起動！
    echo.
    cd /d %~dp0
    python server.py
) else (
    echo RotorHazardの起動をキャンセルしました。
)
pause
```

このstart.batファイルを作成し、その後エクスプローラで右クリック、**【ショートカットの作成】** を選び、デスクトップにで移動をしておきます。そうすればダブルクリックで起動を促せる状態になります。(上記はあえて **起動しますか？** と問いかけるようにしています)
RotorHazardの停止は `Ctrl+C` でプログラムを停止します。

<img width="200" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500291/77af0e04-1196-bfbe-cee2-d5603f81cfda.png">

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500291/fa010324-82b1-5782-aad9-becd9945bf77.png)

こんな感じでデスクトップに配置すると、好きな時に起動したり停止したりと。またこのショートカットアイコンは `RotorHazard-4.1.0-b2¥src¥server¥static¥image¥favicon.ico` を指定することで公式マークが使えるですよー。

つづきはこちら

https://qiita.com/tmac116/items/31b8dcebe86fb13350e9
エンジニア的に嬉しいバグ報告の仕方

システム開発プロジェクトの社内テストが実施され、たくさんのバグ報告や改善要望を頂いた。

その報告を受けて対応を行う時にスムーズに対応を行えるものと、何度か報告者とラリーをしないといけないものなど、報告内容によって対応スピードが大きく変わることに気付いた。

そこで今回の対応を通じて感じたこんなバグ報告の仕方をしてくれたら対応捗る！という報告の仕方について纏めてみた。

# 先に結論・・・こんな内容で報告してほしい！
効果的なバグ報告は、開発プロセスをスムーズに進めるための重要な要素です。
良いバグ報告を行うためには、以下の点を心がけてください。

![スクリーンショット 2024-03-30 13.53.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476743/c928f14a-8ca9-47b6-e120-79b4ea6359ed.png)

詳細かつ具体的に問題を記述する：
発生手順、環境情報、エラーメッセージやログの詳細を提供し、エンジニアが問題を迅速に理解し対処できるようにします。

感情的にならず、客観的に報告する：
バグの存在を非難するのではなく、問題の解決を目指す姿勢で報告を行いましょう。

問題ごとに報告を分ける：
一つひとつの問題に焦点を当てて報告することで、対応の精度を高めます。

積極的なコミュニケーションを心がける：
報告後も情報を更新し、開発チームとの継続的なやり取りを行いましょう。


これらのポイントに注意してバグを報告することで、開発チームは迅速かつ効果的に問題に対処できるようになります。
結果的に、プロジェクトはスムーズに進行し、より良い製品が完成します。

プロジェクトチームの一員として、質の高いバグ報告はプロジェクト成功のために不可欠な貢献となります。

# そもそもバグ報告を受けてエンジニアは何をしているか
バグの報告を受けるとエンジニアはまず事象が再現するかどうかを確認する。
事象が再現しないのであれば、再現するために見落としている条件が無いか、環境依存していないかといったことを調査する。

事象が再現したら、なぜそれが起きているかの仮説を立て、その仮説があっているかを確認するためにコードリーディングをしてみたり、ログやデータベースなど出力内容の確認を行う。

仮説が合っていることが確認できたら、修正を行う。
修正は実際にその動きをさせている部分のコードだけでなく、単体テストのコードも見直して必要に応じて修正を行う。

修正ができたら、事象が発生しなくなっているか、デグレが起きていないか、コードの可読性や汎用性に問題がないかといったことを確認し、プルリクエストを出す。

そのプルリクエストを他のエンジニアにレビューしてもらい、問題がないようあれば環境に反映させて、報告者に修正完了報告を出して対応が完了する。

![スクリーンショット 2024-03-30 13.19.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476743/6c0538a0-4ea9-bc3e-c416-2612823eb327.png)

# 再現や仮説を行う時にどんな情報が必要か

対応の中でも再現や原因特定に時間がかかってしまうと、対応に時間がかかってしまう事が多い。
再現や原因特定のスピードをアップするためには下記のような情報があると良い。

## 発生手順
単にこんなことが起きたよ、というだけだと再現確認に時間がかかってしまうので、可能な限り詳細な発生手順を報告してもらえると素早い対応をすることができる

## 環境情報
特定の環境でのみ起こるバグもあるので、OSやブラウザの情報、デバイスの種類といった環境情報を貰えると特定条件下での事象再現に役立つ

## メッセージやログ
エラーメッセージやログが出力されていた場合には、その内容についても報告をしてもらえると調査がしやすくなる

× → ログインボタンをクリックしたところ、エラーメッセージが表示されてログインができませんでした
○ → ログインボタンをクリックしたところ、「500 Internal Server Error」というエラーメッセージが表示されてログインができませんでした

## スクショや動画
スクショや画面を収録した動画があると齟齬なく事象を確認できるため、調査の助けになる

# その他気をつけてほしいこと

その他、直接多対応スピードを上げる、といったものではないものの気をつけてほしいことをまとめてみた。

## 感情的にならない
バグがあるとイライラしたり、フラストレーションが溜まることは理解できますが、それを報告内容に盛り込まれると受け取った側はほんとにツラいです。

テスターは客観的にならず、自分もこのシステム開発メンバーの一員なんだという主観的な気持ちでテストに取り組み、システムをよりよいものにするためにテストを実施し、バグ報告をしているんだという気持ちになれば自然と感情的な言葉を使わなくなるんじゃ無いかと思います。

## 報告の分割
複数の問題が発見された場合でも、それぞれを個別の報告として分けてほしいです。
一つの報告に複数の問題をまとめてしまうと、それぞれの対応が複雑になり、解決までの時間が長引いてしまいます。

## コミュニケーションを心がける
報告して終わり、ではなく続報があれば積極的に情報を提供したり、対応のレスが無いようであれば状況確認をするといったことを心がけることで誤解や行き違いなどをなくすことができます。

また、対応者からも報告者と積極的にコミュニケーションを取るようにして、報告を上げてくれたことへの感謝を忘れないようにするとチームの雰囲気も良くなると思います。
FlutterプロジェクトでAGP 8系アップデート時に発生したエラーと対応方法

Flutter 3.19.3対応の際、AGP8系にアップデートした際に、直面したエラーとその対応方法を記載します。
同じようなエラーに直面した人の助けになれば幸いです。

## 前提
僕のアプリでは、以下のライブラリを利用していました。

```pubspeck.yaml
environment:
  sdk: '>=3.2.0 <4.0.0'
  flutter: '>=3.19.3'
  
  in_app_review: ^2.0.9
  fcm_config: ^3.5.3
  flutter_local_notifications: ^16.3.2
```

リリースビルドを作成しようとすると以下のエラーが発生しました
```
ERROR: Missing classes detected while running R8. Please add the missing classes or apply additional keep rules that are generated in */build/app/outputs/mapping/productionRelease/missing_rules.txt.
ERROR: R8: Missing class com.google.android.play.core.splitcompat.SplitCompatApplication (referenced from: void io.flutter.app.FlutterPlayStoreSplitApplication.<init>() and 5 other contexts)
Missing class com.google.android.play.core.splitinstall.SplitInstallException (referenced from: void io.flutter.embedding.engine.deferredcomponents.PlayStoreDeferredComponentManager.lambda$installDeferredComponent$1(int, java.lang.String, java.lang.Exception))
```

リリースビルド時のR8エラーに関しては[Gradle / AGP 8系アップデート: 直面したエラーと解決策](https://qiita.com/kilalabu/items/5289fd216c71e1f2d3ed#google-play-core%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E3%81%AE%E4%BE%9D%E5%AD%98%E9%96%A2%E4%BF%82%E3%82%92%E8%BF%BD%E5%8A%A0)を参考に以下を追記しました。

```app/build.gradle
dependencies {
    implementation 'com.google.android.play:core:1.10.3'
}
```

しかし、上記を追記することによって新たにライブラリが重複しているというエラーが出ました
これは、[in_app_review](https://github.com/britannio/in_app_review)が参照している`com.google.android.play:review:2.0.1`が上記で追加した `com.google.android.play:core:1.10.3` と競合しているのが原因でした。
```
Execution failed for task ':app:checkProductionReleaseDuplicateClasses'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.CheckDuplicatesRunnable
   > Duplicate class com.google.android.play.core.common.IntentSenderForResultStarter found in modules jetified-core-1.10.0-runtime (com.google.android.play:core:1.10.0) and jetified-core-common-2.0.2-runtime (com.google.android.play:core-common:2.0.2)
     Duplicate class com.google.android.play.core.common.LocalTestingException found in modules jetified-core-1.10.0-runtime (com.google.android.play:core:1.10.0) and jetified-core-common-2.0.2-runtime (com.google.android.play:core-common:2.0.2)
     Duplicate class com.google.android.play.core.common.PlayCoreDialogWrapperActivity found in modules jetified-core-1.10.0-runtime (com.google.android.play:core:1.10.0) and jetified-core-common-2.0.2-runtime (com.google.android.play:core-common:2.0.2)
     Duplicate class com.google.android.play.core.listener.StateUpdatedListener found in modules jetified-core-1.10.0-runtime (com.google.android.play:core:1.10.0) and jetified-core-common-2.0.2-runtime (com.google.android.play:core-common:2.0.2)
```

解決方法としてappのbuild.gradleに以下を追記しました。
```app/build.gradle
configurations {
    all {
        exclude group: "com.google.android.play", module: "review"
    }
}
```
`com.google.android.play` のライブラリからreviewのをexcludeすることで無事にReleaseビルドが作成出来るようになりました。

### 最後に
走り書きになってしまいましたが、同じ問題に遭遇した方の助けになれば幸いです。
[AWS]AWS認定アカウントをAPNアカウントから個人アカウントに統合した話

## はじめに
退職にあたり、AWS認定情報が紐づけられたアカウントを個人アカウントに移行しました。
このような手続き的な情報は鮮度が重要だと考えているので、2024/3/30時点ではどの方法で可能だったかを書き記しておきます。

## TL;DR
- 他の方が書かれているとおり、https://support.aws.amazon.com/#/contacts/aws-training から申請する
- 以降メールのやり取りとなり、往復約2日ですべてのやり取りが完了した
- 従来の方法から一部微細な変更点はあるが、特に問題なく過去の記事の方法で手続きが完了できる

## 参考にした記事
https://zenn.dev/mn87/articles/a771080c7465a1

https://qiita.com/5hintaro/items/bf355d976d1daf402b48

## 今回のケース
移行元：AWS Partner Network(APN)アカウント
⇒前職ドメインで登録していたアカウント
移行先：AWS Builder ID
⇒統合にあたり新規作成。Gmailを登録した個人アカウント

## 過去記事との相違点
特筆すべき点は、下記2点程かと思います。
フォームからの申請以後はメールで、2ラリー程度の往復をしました。

### 1.申請フォームのFMTが一部更新されていた

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1060458/fb1b7847-cfc7-8884-c693-31aa01a175ae.png)

青枠で示したとおり、**AWS Candidate ID - optional** の項目が追加されていました。
AWS認定ページ(CertMetrics)の右肩に表示されている"AWS"+8桁の数値のことです。
(または、PROFILE/ACCOUNTタブを開き、Account IDsの項目**CERTMETRICS**にも表記されています)
このことを受け、本文にはメールアドレスに加え、移行元と移行先のIDも併記することとしました。
過剰かとも思いましたが念のため。

### 2.サポートからの連絡について
私の場合は、下記のとおりでした。
連絡メールが届いたのは移行元のアドレス=会社のメールアドレスのため、ここは退職時のタイミングによっては注意点かと。
- 送信元：`aws-cs-trainingcertification-form@support.aws.com`
- 受信先：`移行元アカウント(今回で言うところのAPNアカウント)`
- 件　名：`RE:[CASE <Case-ID>] [AWS Training and Certification Form Submission] - certification`

## マージ後の確認
マージしたで！メールが届いた後、CertMetricsを確認すると、
Exam history,Certification stautasやCertification benefits が問題なく引き継がれていることが確認できました。

また、Credly(`admin@credly.com`)からも認定試験バッチの失効と獲得のメールが届きました。
(こちらのメールの方がサポートのマージしたで！メールより数分先に来たので、すぐ反応できましたね)


## 最後に
過去に投稿された記事がいくつかありましたので、申請する際に参考とさせていただきました。
この場をお借りして感謝申し上げます。

また、冒頭にも記載したとおり、過去記事での方法で問題なくマージすることができました。
このような手続き関連のものは時間が経つにつれ変わっていく印象があるので、一定のタイミングで情報を残しておくことが必要と考えた結果、記事としました。
どなたかの参考になれば幸いです。
【Laravel】マイグレーション 任意のカラムを外部キー指定

例えば、usersテーブルがあり、そのテーブルを参照するpostsテーブルがあるとします。
Laravelでは、usersテーブルとpostsを紐づける外部キーは`user_id`と命名するのが一般的でしょう。

usersテーブルの`id`（主キー）とpostsの`user_id`を紐づけを行いたい場合のマイグレーション。
```ruby:sample.php
Schema::table('users', function (Blueprint $table) {
    $table->id();
    $table->string('name');
});

Schema::table('posts', function (Blueprint $table) {
    $table->id();
    $table->foreignId('user_id')
        ->constrained()
        ->onUpdate('cascade')
        ->onDelete('cascade');
});
```


しかし、例えばusersテーブルに会員番号(`user_number`)というカラムがあったとして
`user_number`で外部キー結合を行いたい場合のマイグレーションは以下のようになります。

```ruby:sample.php
Schema::table('users', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->unsignedInteger('user_number')->unique();
});

Schema::table('posts', function (Blueprint $table) {
    $table->id();
    $table->unsignedInteger('user_number');
    $table->foreign('user_number')
        ->references('user_number')
        ->on('users')
        ->onUpdate('cascade')
        ->onDelete('cascade');
});
```
### 注意点
`user_number`の型はusersとpostsで両方とも同じ型にして下さい。
また、予期しないバグを防ぐためusersの`user_number`はユニークにすることをおすすめします。

## usersとpostsを結合する場合
```ruby:sample.php
$posts = Post::join('users', 'posts.user_number', '=', 'users.user_number')
    ->get();
```
GoogleCloudで秘密鍵を作成してみよう


## はじめに

Google Cloud Platform (GCP) では、さまざまなサービスやAPIへのアクセスに秘密鍵が必要となります。この記事では、GCPで秘密鍵を作成する手順を詳しく説明します。このプロセスは、例えばdbt (data build tool) などの外部アプリケーションがGCPのリソースにアクセスする際にも重要になります。

## **ステップ1: GCPコンソールにログイン**

まず、[Google Cloud Console](https://console.cloud.google.com/)にアクセスし、Googleアカウントでログインします。既にプロジェクトを持っている場合は、そのプロジェクトを選択します。そうでない場合は、新しいプロジェクトを作成する必要があります。

## **ステップ2: APIとサービスへ移動**

プロジェクトダッシュボードから、「APIとサービス」ダッシュボードに移動します。

![スクリーンショット 2024-03-21 14.36.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3364428/df49253b-03aa-608d-1a47-ebb23e287686.png)


## **ステップ3: 認証情報を管理**

APIとサービスのダッシュボードの左側にあるメニューから「認証情報」を選択します。次に、「認証情報を作成」ボタンをクリックし、「サービスアカウント」を選択します。

![スクリーンショット 2024-03-21 14.37.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3364428/e567fc93-18e1-d37a-047c-ab9605361d74.png)


## **ステップ4: サービスアカウントの作成**

新しいサービスアカウントの詳細を入力します。サービスアカウント名と説明を適切に設定し、「作成して続行」をクリックします。

![スクリーンショット 2024-03-21 14.37.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3364428/e4d05dff-d712-ce87-f714-0cee51a78382.png)


### **ステップ5: サービスアカウントへのロールの割り当て**

サービスアカウントに必要なロールを割り当てます。これは、アカウントが持つべきアクセスレベルを決定します。例えば、BigQueryへのフルアクセスを許可する場合は、「BigQuery管理者」ロールを選択します。ここでは分かりやすく管理者にしていますが、操作できる範囲を決める重要な部分なので細かい権限を付与するようにしましょう。

![スクリーンショット 2024-03-21 14.37.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3364428/2cb49daa-ac54-087b-d005-3c62a874e5f0.png)

## **ステップ6: 秘密鍵の作成とダウンロード**

ロールの割り当てが完了したら、サービスアカウントの詳細ページに戻り、「キー」タブを選択します。

![スクリーンショット 2024-03-21 14.38.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3364428/69642e19-0530-f451-e212-735ee0e7553e.png)


ここで、「キーを追加」をクリックし、「新しいキーを作成」を選択します。キーフォーマットは「JSON」を選択し、「作成」をクリックすると、秘密鍵が自動的にダウンロードされます。

![スクリーンショット 2024-03-21 14.38.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3364428/031199e2-94f3-ef48-bcec-6ba892941aff.png)

## **重要な注意点**

- 秘密鍵は安全な場所に保管し、決して公開しないでください。
- サービスアカウントに割り当てるロールは、必要最小限に留めることがセキュリティ上重要です。
- また現在はサービスアカウントの情報が外部に漏れた場合の自動削除や警告通知もあるため、必ず有効にしておきましょう。

## まとめ

これで、GCPで秘密鍵を作成するプロセスは完了です。この秘密鍵は、例えばdbtなどのツールでGCPリソースへのアクセスに使用されます。適切な管理とセキュリティ対策を行いながら、これらの強力なクラウドリソースを最大限に活用しましょう。
第3回空戦AIチャレンジで銀メダルと特別賞を獲得した話

防衛装備庁主催の第3回空戦AIチャレンジに参加しました。3ヶ月間苦戦した結果銀メダルで、金メダルまであと一歩で悔しかったけど、特別賞を受賞していただきました。下記で少し思いを共有します。

![ai_2024.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/893830/a5abb68c-0bbf-7641-0775-7b134bcbe2ff.png)

# どのようなコンペ
1. 強化学習で2機対2機の空戦
2. 実際は強化学習を使わずにルールベースだけでも全然OK

# なぜ苦戦した
1. 配布されたソースコードとドキュメントの量が多くて、理解するだけで1週間かかった
2. 座標系について全く知らなくて、ChatGPTに聞きながら3次元ベクトル処理のことを勉強
3. パソコンのスペックがそこまで良くなくて、1回の訓練 + その後の結果確認や検証だけで2-3日かかったので、実装したかったことが多いけど時間がない

# 何のモデルを作った
1. ルールベース + 強化学習、強化学習はやはり限界があるので、ルールベースのオーバーライドを加えると、強化学習がうまく行かない時にも撃墜や墜落などの一番まずい結果がある程度回避できる
2. ルールベースで一部のアクションを制御することによって、強化学習の方で制御するアクションがより精度よく（アクションスペースを細かく分ける）学習できる

# 銀メダル獲得の工夫
1. 配布されたドキュメントを全部読む、基本の基本だけど仕様がわからないと後々苦しくなるだけ
2. 高速のPDCA、モデルを少し改善　⇛　訓練　⇛　検証　⇛　少し改善　⇛　…、1回モデルを大幅に編集すると、結果が良くなっても実際の原因がわからない可能性が高い
3. ネット資料を活用、外国のサイトで実際の戦闘機のスペックシートがあるので、それらを活用して戦闘機の性能を制御

# うまく行かなかった部分
1. 訓練環境で勝率を上がっても、実際のテスト環境・最後の評価環境と違って、勝率がかなり異なる

こちらは各バージョンのモデルで、訓練環境でベスト500回勝率とテスト環境・最後の評価環境のスコア

![Screenshot from 2024-03-30 12-54-52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/893830/bfa01a9d-e28c-f0a6-5c35-cac338a2bc5b.png)


一致しているのは最初のバージョンだけ、特に最後のバージョンは勝率60%を超えても、テスト環境のスコアがなかなか上がらない

原因把握していないけど、このような一致していない場合は、一番改善策が考えにくい

# 特別賞について
サイトにより、「フォーラムにて、コンペの運営円滑化や他参加者のフォローに貢献いただいた方から、最大3名を選定」との記載がありました。フォーラムで上げられた内容の公開はしかねますが、みんなのRL訓練方法・対戦を勝つためのいろんな実装手法・戦闘機関連の共有を見てかなり知識が広がりました。今回の受賞を受けて、今後も積極的に発信していきます。

最後に、いろいろ苦戦したけど、苦労したからこそ勉強になりました。またいつか金メダルをGETします。
SQLのCRUD基本学習 (MySQL)

# `Create`: 新規作成 => `INSERT`文

● `INSERT`文を使う

- `id`は `auto increment`で `PRIMARY KEY`

```sql:sample.sql
INSERT INTO `contacts` (
    `id`,
    `name`,
    `email`,
    `url`,
    `gender`,
    `age`,
    `contact`,
    `created_at`
       ) VALUES(
          NULL,
          'あああ',
          'test@test.com',
          'http://test.com',
          '0',
          '3',
          'テスト',
          NOW()
    );
```

# `Read`: 表示 => `SELECT`文

● `SELECT`文を使う

```sql:sample.sql
SELECT * FROM `contacts`; -- 全てのカラムを取得(ワイルドカート)

SELECT `name` FROM `contacts`; -- nameカラムのみ取得

SELECT `name`, `email` FROM `contacts`; -- nameカラムとemailカラムの取得

-- WHERE句
SELECT `name`, `email` FROM `contacts` WHERE `name` = 'test3'; -- nameが test3 の name とemail を取得
```

# `Update`: 更新 => `UPDATE`文 (上書き)

● `Update`文を使う

```sql:sample.sql
UPDATE `contacts` SET `name` = 'あああいいい' WHERE `contacts`.`id` = 1; -- idの1のnameが上書きされて更新される
```

# `DELETE`: 削除 => `DELETE`文
● `DELETE`文を使う

```sql:sample.sql
DELETE FROM `contacts` WHERE `id` = 2; -- idが2のデータを削除
```

もっと複雑な副問い合わせなどがあるようですが、頑張って覚えないとですね。
ファイル名を日本語でつけた際にNFD正規化された文字をNFC正規化形式に変換したい

## はじめに

日本語を含むファイル名を作成しており、そのファイル名の長さを知りたい時がありました。(もっといい方法があるかも知れませんが、) `wc -m` を使って数えていたところ、濁点・半濁点を含むファイル名だと正しくカウントできていないことが分かりました。調べてみると、NFD正規化されているために、濁点・半濁点を含む文字だと基底文字と結合文字の組み合わせで表現されるため、2 文字扱いになっていることが分かりました。NFC/NFDの違いについては、[ファイルアップロードではNFC/NFD問題に気をつけろ！\~MacファイルシステムにおけるUnicode正規化の闇\~](https://zenn.dev/hacobell_dev/articles/68ccc92bffd6cc) に書かれていますので、ご参照ください。

そこで、NFD正規化されているファイル名をNFC正規化形式に変換するプログラムを書きました。

## 環境

- Python 3.10.13

## 変換プログラムの実装例

参考実装では、プログラムと同じディレクトリに `image` フォルダが存在している前提で、そのフォルダ内にある画像を変換します。

標準出力などはさせていないので、何も表示されなければ成功となります。

なお、[github](https://github.com/ksawaray/util-tools/blob/main/convert-nfd2nfc/convert_nfd2nfc.py)にも上げていますので、適宜ご参照ください。

```python
import os
import unicodedata

dir_path = 'image'

files = os.listdir(dir_path)

for file in files:
    nfc_file_name = unicodedata.normalize("NFC", file).encode("utf-8")
    os.rename(os.path.join(dir_path, file),
              os.path.join(dir_path.encode(encoding='utf-8'), nfc_file_name))
```

## 参考

1. [ファイルアップロードではNFC/NFD問題に気をつけろ！\~MacファイルシステムにおけるUnicode正規化の闇\~](https://zenn.dev/hacobell_dev/articles/68ccc92bffd6cc)
2. [Unicode正規化 #文字コード - Qiita](https://qiita.com/fury00812/items/b98a7f9428d1395fc230)
[Gem][Rails][Postgresql] gem pg がinstallできない (Your version of PostgreSQL (9.2.22) is too old) 解決法



# 概要

Centos 7に Rails にgem 'pg' を入れたい。
そのまま`yum install postgresql-server` だとversion `9.2` が入るが、(以下)
最近の gem 'pg' を使うには `>9.3` である必要があるため、エラー

https://www.postgresql.org/download/linux/redhat/

```
$ bundle install
...
Your PostgreSQL is too old. Either install an older version of this gem or upgrade your database to
at least PostgreSQL-9.2.
Error..
```

# 補足

CentOS 7 にpostgresql-15 installの流れは以下。
```
# Install the repository RPM:
sudo yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm

# Install PostgreSQL:
sudo yum install -y postgresql15-server

# Optionally initialize the database and enable automatic start:
sudo /usr/pgsql-15/bin/postgresql-15-setup initdb
sudo systemctl enable postgresql-15
sudo systemctl start postgresql-15
```
https://support.dbagenesis.com/post/postgresql15-on-centos-7


もし古い `postgresql` が残っていたら削除

```
$ yum list installed | grep postgre
postgresql.x86_64                15.6-1PGDG.rhel7              @pgdg
postgresql-devel.x86_64          15.6-1PGDG.rhel7              @pgdg
postgresql-libs.x86_64           15.6-1PGDG.rhel7              @pgdg
postgresql-server.x86_64         15.6-1PGDG.rhel7              @pgdg

$ sudo yum remove postgresql postgresql-libs -y
```

## 補足
再度、CentOS 7 に入れようと思ったら、
gem `pg` に必須の postgresql-devel.x86_64 が上手く入らなかった..
->
以下 URLで `postgresql-devel` を検索して
↑で入れた version 15.6-1PGDG.rhel7
例えば、`postgresql15-contrib-15.6-1PGDG.rhel7.x86_64.rpm`
のURL をコピーし yum insatll..
https://download.postgresql.org/pub/repos/yum/15/redhat/rhel-7-x86_64/

```
sudo yum install https://download.postgresql.org/pub/repos/yum/15/redhat/rhel-7-x86_64/postgresql15-devel-15.7-1PGDG.rhel7.x86_64.rpm

```

# 解決法

(↑で) 最新の version 15を入れた後、
以下で confiを指定して、実行すれば bundle install が通る


```:bash
$ bundle config build.pg --with-pg-config=/usr/pgsql-15/bin/pg_config # 15 が入っている前提
$ bundle
...
OK
```
PHP(7.1.33) 学習 備忘録 - preg_replaceの"\\1"

とある案件でPHPを触れて、学んだことを書いておく。

# preg_replace

https://www.php.net/manual/ja/function.preg-replace.php

PHPの正規表現を使った置換`preg_replace`の置換後文字列に`\\1`というのが使われていましたが、知らなかったので調べました。
正規表現としては、`$1`と同じく部分置換をするときに使うものです。


```php
<?php
$str = 'スズキ タロウ';

var_dump($str);
$str = (preg_replace("/(スズキ) (タロウ)/","\\2 \\1", $str));
var_dump($str);
?>
```
[実行結果](https://php-play.dev/?c=DwfgDgFmBQAkDOAXATgAgLyoOSE6GQXQyC1DKoP0MgtwyBlDFgNzTQBuAhsgPoAmArgLZgAUCKAShr80mHmGQBTAObMpYADYMAxpJ4AiAPQ98BAah5lyAzeoA06gDqWATKmsBGc6hECh9Jmy69XNEAD4gA&v=7.1&f=console)

公式からは `\\1`より`$1`を推奨しているので、もし使う場合は`$1`がおすすめです。
一般的な正規表現では、`$1`が使われていて`\\1`のほうはPHPの独自のものだと思います。

# メモ

## ブラウザでの実行環境

コードを試したい場合は使ってください。バージョンを指定できるのでバージョンによって動かないものを確認できます。

[PHP Playground(7.1)](https://php-play.dev/?c=DwfgDgFmBQD0sAICmAPAhgWzAGyQgxgPYAmS0kYAlgHYBmhAFAJQDcQA&v=7.1&f=html)
Scalaの特徴 - 自分がなぜScalaを選ぶか

Scalaの特徴ってなんだろう？もし今自分が言語に対して求めることにフラットで考えるなら、なぜScalaを選ぶのだろう？

# 選ぶ理由

## Javaがベースである

一番はこれかもしれない。慣れ親しんだJavaの考え方をベースにロジックを組むことができる。喋り慣れている言語でロジックを考えるほうが、思考の変換をせずに済む。

## 関数型がある

これによりボイラープレートコードが極端に減る。JavaやKotlinにもあるけど、Scalaのほうが書いていて手に馴染む感がある。アンダースコアも、慣れればとても直感的に思える。直感的なものは思考の邪魔をしない。

## コンパイル後の安心感がある

JavaよりもScalaのほうが、コンパイラでバグを見つけてくれるので、実行時にめったに落ちない印象がある。静的型付けやOption型、ローンパターン(scala.util.Using)とかがそれに貢献している印象がある。

## sbtが便利

大きなものから小さなものまで、異なるアーキテクチャ向けのものまでなんでも対応できちゃう。自分は好きすぎて、Javaのプロジェクトもsbtで管理してる。

## REPLが便利

初めて触ったreplがこれなのでバイアスがあるかもしれない。ちょっとしたjavaプログラム(substringの挙動とか、regexの挙動とかoffsetDateTimeの挙動とか）を調べたいときに便利。ammだと外部ライブラリを import ivy でサクッとインポートできて便利。

# 中立

逆に自分が選定基準じゃないもの

## 圏論ベースで書けること

自分が圏論を勉強していないから、読めないだけってのはある。思考のベースが圏論になると、その考え方も変わるのかもしれない。今のところはflatMapだけでも十分にコードが書けてしまうため勉強のモチベーションがない。

# 選ばない理由

Scala を選ばない理由はなんだろうか。

## プラットフォームによってScala以外の適切な言語がある

iOSならswift, Androidならkotlin, UnityならC#など、プラットフォームに最適化された言語があるならそっちのほうが良さそう。GASとかも、やろうと思えばscala.jsとか書けるかもしれないけど、環境構築の労力と見合うのか微妙っぽくてやれてない。

## 依存関係地獄になる

主に既存アプリの問題。最新のScalaを使っていると問題ないけど、特にScala2系のバージョン間の互換性のなさ、それによるライブラリ選定に嫌気が差す。既存プロダクトは歯を食いしばってバージョンアップするか、機能を切り出して単機能アプリとして独立させるか（稀にそのタイミングで別言語になってしまうことも...）する必要があったりする。Scalaが流行った当時はまだオンプレ時代で単機能アプリが現実的じゃないからモリモリ多機能重鈍アプリになりがちっていうのもあったのかも。

## ライブラリが多い

Scalaはその言語仕様から、何でも（？）書ける言語になっており、主要なJSONパーサーだけでも乱立する状況になってしまった。そのため「Scalaでプログラムを書くぞ！」と息巻いても、直後にライブラリ選定をせまられる。これはScalaを知らない初心者にとって高いハードルだ。Scalaを知らないのにライブラリ選定なんてできるわけがないし、ライブラリに任せたいってことはそれが主な関心事ではないので、そこで時間取りたくないし、取られるのも辛い。

## ライブラリが廃れる

Scalaのライブラリは、アーリーアダプターの貢献によるところもあり（ありがとうございます）、そういうライブラリは言語のバージョンアップについていけず、最新バージョンでは使えない（＝廃れてしまった）ものがあったりする。OSSならプルリク出してみるのも手だが、マージされるかはわからない。本体側での対応が難しいなら、フォークして自プロジェクトで管理する必要も出てくる。Javaだとあまりそのような事象に出会わないので、その辺は手間だ。

## コミュニティが不穏

日本だとScalaMatsuriとかわいわいランドとかあって個人的にはとても好きなのだけど。（海外では）コミュニティ内外で衝突があったっていうニュースをよく聞く（バイアスがあるかもしれない）。当事者じゃないので背景も温度感もわからず、Scalaをやるうえでその話題にどう接すれば良いのか（or スルーすれば良いのか）がわからない。

## ウェブに（日本語）リソースが少ない。

Kotlinとかと比べると、ググったときの情報とかが少ない気がする。Scala系は自分が知る限りDiscordに閉じている傾向があって、何か知りたいときにGoogleやTwitterではなくDiscordで聞く、っていうのはハードルを感じるかもしれない。少なくとも自分はDiscordあまり使わないので抵抗を感じる。

# 感想

言語や周辺ツールだとかなり便利なものが揃っているので、手軽に始めやすいってのがある。一方で運用面を考えるとちょっと考慮事項が増えたりもする。ただ、運用面の考慮事項はScalaに限った話ではなく、他の言語でも大なり小なりあるので、そこが大きなデメリットになることは少ない気がしている。バージョンギャップはPythonやRubyなんかでも聞くし、コミュニティの話はRustとかでも見かけたし、ウェブのリソースが少ないのはDiscordに対するジェネレーションギャップな気がしてならない（若い人はDiscordよく使ってる気がする）（老害発揮中）。となるとデメリットが打ち消されてメリットだけが残り、それなりの速さで高級言語が書けて、maven repositoryに過去資産が豊富で、jsやネイティブにもビルドできるってなると、とりま初手Scala選んでおいて、Scala-CLIとかでロジック実験しつつ、プラットフォーム選ぶなら翻訳する、みたいな動きが楽だと思っている。

なんだかんだ書いたけど、結局はScalaが一番手に馴染んでて書きやすいってのが大きいかな。
UiPathを個人利用でインストールする

以前、PowerAutomateを使ってロボットを作ってみたが、今回はUiPathに挑戦。

UiPathの教材本を読みながら挑戦してみたが、初回準備で躓いたので、同じように躓く人向けにまとめ。（2024/3/21時点）




# UiPathのダウンロードから起動まで



###### 1.Yahooの検索エンジンから「UiPath　個人利用」と検索してhitした以下サイトへアクセス

[UiPath　サイトURL](https://www.uipath.com/ja/pricing)
![001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523511/9cf4b17a-de3f-12e4-e383-b1cd923c4238.jpeg)


###### 2.ページを下にスクロールし、「無償でスタート」をクリック。
![002.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523511/56228dd0-b15d-7387-d5cb-1d41f66bd425.jpeg)

###### 3.クリック後の画面ロード中は以下のような描写
![003.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523511/c4df8c68-57f6-b62b-9aac-8e0888db42d4.jpeg)
###### 4.ユーザー情報を求めてくるので、入力
![004.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523511/2257dc2c-bdc4-44bb-ecaa-aab1bcdc746a.jpeg)
###### 5.クラウド組織を作成のため、任意情報を入力
![005.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523511/1d5ccb4f-b514-b88f-e87d-6940dc73713d.jpeg)
###### 6.完了すると以下画面が表示されます。
![006.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523511/c53a5e5e-5a93-af36-4bd7-045b6e2bdd7c.jpeg)
###### 7.ページ右上の「Studioをダウンロード」をクリックする
![007.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523511/48b5ac19-b6f9-6245-fc8e-78bcc34f9fb4.jpeg)
###### 8.ファイル容量が1GBほどあるので、完了まで少々かかる場合あり
![008.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523511/f646c339-05c9-4e45-9c68-2cf871293e5d.jpeg)
###### 9.設定変更なければ、ダウンロードフォルダにファイル
![009.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523511/ca1de722-fdf9-2b1b-8ccd-22cdaf84b64f.jpeg)
###### 10.右クリック⇒インストール　をクリック
![010.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523511/c3cfc4fd-3a44-2a74-896e-732fd43e9e6d.jpeg)
###### 11.クイックを選択
ライセンス契約の条件に同意します。をチェック
インストールをクリック
![011.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523511/72d2de3b-3ed4-6caa-b6f8-e1c0f936d0e1.jpeg)
###### 12.セットアップ完了すると以下画面表示
「UiPath Studioを起動」をクリック
![012.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523511/e632b3e9-b5a3-db60-4a61-281a1697a46b.jpeg)
###### 13.スタートメニューから
「UiPath Studio」をクリック
![013.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523511/9375b5c0-1d7f-e45f-d1a7-013e3bf1c897.jpeg)
###### 14.以下のUiPathアプリ開けば完了
![014.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523511/b939e107-14a7-85b6-0782-7c21b133ab80.jpeg)




活用例、機能面に関する紹介記事は後日投稿予定。
働きながら個人開発をするメリット〇選

![スクリーンショット 2024-03-30 12.32.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/bae096a5-6b10-07ef-7b21-0ccd832227d2.png)


こんにちわ。いせりゅーです。

今回は、「働きながら個人開発をするメリット〇選」について話していこうと思います。


# メリット1つ目：稼がなきゃいけないと思わなくてもいい
生活しなくてはいけないと思うと、どうしてもアイデアが出せなかったり、このアイデアじゃ稼げないなどと思ったりしてしまうことで、前向きに個人開発に挑みづらいのではないかと考えています。
働いていると、お金はちゃんと稼げているので、「ヒットすればいいかな」などと気軽なアイデアからプロダクトを作れたりします。
僕の場合はアプリを53個リリースしていますが、どれもヒットすればいいかなと思いながら作っていたので安心してシンプルアプリがたくさん作れました💦


# メリット2つ目：アウトプットとして開発できる

働き始めるとアウトプットがなかなかうまくいかないのではないかと考えています。僕自身も働いているとたくさんの情報をインプットします。
その情報をどこでアウトプットすればいいかは様々なやり方があると思います。記事を書いたり、勉強会などで登壇したり色々あると考えられますが、個人開発でアウトプットするのはおすすめです。




# メリット３つ目：業務の質の向上ができる

個人開発で得た知見などを業務でも活かせられるという点もとてもいいメリットだと思います。逆に業務で学べたことも活かせる場合が多いと思います。業務では導入できなかったものなどを個人開発に取り込んでみるなど自由にできると思っています。


# 最後に
以上３つあげさせていただきましたが、正直なところ忙しい.....と感じ始めました。個人開発は好きで作りたいを第一に考えることがとても大切なのかなとボソボソと考えています。

もし、他にもあれば書きますね
GitHub Action で「Create Artifact Container failed: Artifact storage quota has been hit. Unable to upload any new artifacts.」と出たときの解決策

### 問題
ストレージ容量（無料プランの場合500MB/月）を使い切ると、__`Create Artifact Container failed: Artifact storage quota has been hit. Unable to upload any new artifacts.`__ というエラーが出てGitHub Actionsを正常に実行できなくなる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2059946/a5b3d1e9-8992-e95f-d726-9b84fc98ab47.png)


### 対策1：古いArtifactを削除する
古いArtifactを削除するActionを追加して、ストレージ容量を節約する。
```yml:.github/workflows/artifacts_cleanup.yml
name: 'artifacts cleanup'
on:
  # 毎日0時に自動実行
  schedule:
    - cron: '0 0 * * *' # UTC
  
  # 手動実行
  workflow_dispatch:

jobs:
  delete-artifacts:
    runs-on: ubuntu-latest
    steps:
      - uses: kolpav/purge-artifacts-action@v1
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          expire-in: 30 minutes
```

Actionは毎日0時に実行される他、以下のように手動実行することもできる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2059946/c5bb2b29-1ef2-8562-b62a-e3a692997398.png)


### 対策2：有料プランに変更する
ストレージ容量は、Teamプランなら2GB/月、Enterpriseプランなら50GB/月に増える。また、$0.25/GBでストレージ容量を追加できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2059946/92caef15-4878-2760-050d-07711e0dc6ed.png)


### 参考文献
https://github.com/features/packages

https://qiita.com/SnowCait/items/7a30ff80be70a739915c
Vue3学習忘備録

# 概要
主にVue2→3の変更点について学んだことの忘備録。

# API スタイル
Vue2：OptionsAPI
Vue3：CompositionAPI / OptionsAPI

Vue3では新しくCompositionAPIが新設された。
CompositionAPIになった理由：ざっくりいうと責任や責務がバラバラになってたものが、関心ごとにまとまる。

![composition-api-after.GV7JGP99.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140953/d7b50a1e-9c91-a421-d0b3-3234c8ac17da.png)

引用：[Composition API に関するよくある質問 - なぜ Composition API なのか？| Vue.js](https://ja.vuejs.org/guide/extras/composition-api-faq#why-composition-api)

# ライフサイクル

![lifecycle.DLmSwRQE.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140953/2a40522c-ebaa-72e5-27cf-5f552488eedc.png)

- `created`までは親→子、`mounted`までは子→親の順で呼び出される
- 〜`Mounted`でDOM構築など終わり実際に画面上に表示される
- スクリプト内やテンプレート内のリアクティブな値が変更されると再レンダリング

1番目についての補足として、親から呼び出されたコンポーネントは「Has pre-compiled template?」の分岐で子コンポーネントが呼び出され、子コンポーネントのマウントが完了してから親のマウントが呼び出される。
なので親コンポーネントのマウント処時に初期値などを設定して子コンポーネントで取り出そうとするとエラーになるので要注意（ここで若干ハマった。。）

引用：[ライフサイクルフック | Vue.js](https://ja.vuejs.org/guide/essentials/lifecycle)
参考：[Composition API: ライフサイクルフック | Vue.js](https://ja.vuejs.org/api/composition-api-lifecycle)

# コンポーネント間の受け渡し
親子コンポーネントで値を受け渡す場合の使い方について。(Props/Emit)
Props...親→子
Emit...子→親

### 使い方1
script setupブロック内で利用する場合、defineProps()/defineEmits()で定義して利用する。

```vue
<script setup>
const props = defineProps({
  foo: String
})
 
const emit = defineEmits(['change', 'delete'])
</script>
```

参考：https://ja.vuejs.org/api/sfc-script-setup#defineprops-defineemits

### 使い方2
setup() フックを利用する場合、setupの引数として受け取ることもできる。
第一引数はprops, 第二引数はemit含めたcontextオブジェクト。

```javascript
export default {
   props: {
    title: String
  },
  setup(props, context) {
    console.log(props.title)
    console.log(context.emit)
  }
}
```

参考：https://ja.vuejs.org/api/composition-api-setup.html#accessing-props


# 状態管理
状態管理とはコンポーネント間のバケツリレーをしなくていいように値を管理してくれるもの。
Vue2ではVuex(store)がデファクトスタンダートだけど、Vue3でprovide/injectの機能が提供された。

### provide

祖先のコンポーネントで、状態管理として提供するものを定義する。
第一引数にキー、第二引数に値。

```javascript
const count = ref(0)
provide('count', count)
```

### inject
子孫のコンポーネントで、利用したいコンポーネントに値を注入する。
第一引数にキー、第二引数にデフォルト値(省略可)。

```javascript
const count = inject('count')
console.log(count.value)
```

参考：[Composition API: 依存関係の注入 | Vue.js](https://ja.vuejs.org/api/composition-api-dependency-injection)

# リアクティビティ
### ref()

```javascript
const count = ref(1)
```

countオブジェクトそのものはconst(再代入不可)だけど、中のプロパティに関しては再代入できるリアクティブな値。
ref形式はオブジェクトで値が渡ってくるので、値のプロパティを取り出す際は.valueを指定する必要あり。
似たようなものにreactive()があるけど、オブジェクトしか扱えなかったり色々制約があるのでrefの方が正直使い勝手が良さげ。

### computed()
書き方は変わるけど基本的に挙動はVue2と同じ。
関数で算出したリアクティブな値を返してくれる。

```javascript
const plusOne = computed(() => count.value + 1)
console.log(plusOne.value)
```

参考：[リアクティビティー API: コア | Vue.js](https://ja.vuejs.org/api/reactivity-core#computed)

# おわりに
若干ブランクがあったのでVueについて改めて勉強しました。フロントは移り変わりが激しいですね。
個人的にはVue3の書き方はぱっと見のコードが把握しやすくなったように思います。
業務ではVue3/Nuxt3/Vuetify3への移行をまとめてやっていってるので破壊的変更多くて大変です。。
Nuxt3は今年度でEOL予定って噂も聞いたりしましたが...まぁその時はその時で。
今後もがんばります〜。

おしまい。
未経験40代は手始めにLinuC レベル1から

# はじめに
未経験で40代からSESに転職して、自分を売るために取得したのがLinuCでした。Windowsは多少使えるけどLinuxは名前を聞いたことがある程度、そんなところからのスタート。まずはレベル1。

# LinuC レベル1は参考書とPing-tで
何もわからないので先ず参考書から。認定教材にも指定されている翔泳社の「Linux教科書 LinuCレベル1」、あずき本と呼ばれる定番の参考書です。学校のテストと違い、ここから出題されるというものではないので情報量を増やす必要があります。解説の充実した問題集があればと探して見つけたのがPing-tです。安価で問題量も多く、ネットでの評価も高い。

LinuC レベル1 認定教材

https://linuc.org/measures/textbook/#01

Ping-tのプレミアムプランはコスパがいい

https://mondai.ping-t.com/g/contents/premium_plan_introduction

LinuCの認定教材は増えていますね。参考書は自分が読みやすいものを選ぶといいでしょう。

# どのくらいやるといいのか
あずき本は2回転しました。Ping-tは隙間時間を利用して10問ずつ問題演習を3回転、土日のまとまった時間で模擬試験を5回。試験の合格が最優先ならPing-tで問題を解きまくることに重きを置くといいです。

# Ping-tの問題演習はどうやるのが効率的か
Ping-tの問題演習は分野別に選択したり問題数を指定して出題させることができます。以下のようにして問題演習していました。

1. 未出題にチェックを入れる
1. 一つの分野にチェックを入れる
1. 問題数を10問にしてスタート
1. 回答はせず「正解」、「参考」だけ読んで終わる
1. この分野の未出題数が0になるまでやる
1. 未出題のチェックを外す
1. 問題数をALLにしてスタート
1. 今度は「正解」、「参考」を見ずに回答する
1. 誤答が0になるまでALLで繰り返し出題する

これを全分野一つずつ順にやっていきました。初めのほうの分野は時間の経過とともにうろ覚えになってくるので3回転くらいやります。

# 受験日はいつがいいのか
確実な自信が持てるくらいになってからがいいだろうと思って余裕を持たせてかなり先の日を予約するのはいまいちです。学習スケジュールから問題演習の詰込みができた頃合いにするのがベストです。惰性の余裕期間を作るより熱いうちに打てです。

# さいごに
LinuCは参考書を読んでPing-tの問題演習をやりこんで、時間があればVirtualboxなどでLinux環境を構築して実際にコマンドを打って確認していけば未経験でも3カ月ほどで確実に合格ラインに到達します。そして、レベル1、レベル2、レベル3と間を置かずにどんどん進めていくのがおすすめです。LinuCで、Windowsだけじゃない付加価値の高いエンジニアになりましょう。誰でもなれるのですから。
そう、約半世紀ずっーーーーーと引きこもりで地球から一歩も出ていない石ころでも。

VirtualboxでLinuxを試そうというときはLinuCの認定機関LPI-Japanの公開しているLinuxサーバー構築標準教科書を参考に！

https://lpi.or.jp/news/press/page/20240201_01/
じゃんけんを使っての無限小の考察と2台の等価のコンピュータのサーバー・クライアント決定

infinitesimal.py
じゃんけんを使っての無限小の考察をするシミュレーションプログラム
二人でじゃんけんをすると結果は、自分が勝ち、相手が勝ち、あいこ、のいずれかです。
この３つの場合は等しく1/3の確率で現れます。
あいこの場合、勝負が付くまでじゃんけんをすることにすると
lim n→∞　Π(i=1,n)1/3=0
で、永遠に勝負がつかない可能性は、極限の数式上は0ですが、そういう場合も存在し、確率は無限小と言えます。
ヨハネの黙示録のラストに、「見よ、私はすぐに来る」とありますが、キリストは永遠に待っても来ない可能性があります。
この問題は、ネットワーク通信に於いて2台の等価のコンピュータのサーバ、クライアントを乱数で決定する時にも存在します。乱数で決定しようとすると、コンピュータはブラックボックスなので、この問題は厳密には解決不能ですが、十分な回数試行をすると、実用上は十分です。
CPU IDやIPアドレスのようなアイデンティティを利用するとこの問題は解決します。
IPアドレスが分かれば、pingを打って、応答が返ってくれば、相手が繋いでることが分かります。それから、おもむろにサーバ、クライアントを決定すればよいでしょう。
サーバ、クライアント決定は、ネットワークゲームのプレイヤー先攻、後攻決定と同じです。
複数のプレイヤーのIDが必要ならば、CPU IDやIPアドレスの大小関係を利用すればよいでしょう。

インターネット関係の本を読んでいたら、コンピュータがサイコロを振ることが載っていましたが、このことかどうか分かりません。

## 検証プログラム

truerand.py モジュールを使っています

https://qiita.com/fygar256/items/657719d5670f4534401f

```infinitesimal.py
#!/usr/bin/python3
import truerand
te=[ 'パー','チョキ','グー' ]
def game(a,b):
    if a=='パー':
        if b=='パー':
            return 'draw'
        elif b=='チョキ':
            return 'lose'
        else:
            return 'win'
    elif a=='チョキ':
        if b=='パー':
            return 'win'
        elif b=='チョキ':
            return 'draw'
        else:
            return 'lose'
    else: # a=='グー'
        if b=='パー':
            return 'lose'
        elif b=='チョキ':
            return 'win'
        else:
            return 'draw'

def main():
    while True:
        self=te[truerand.rand(1)%3]
        opp=te[truerand.rand(1)%3]
        result=game(self,opp)
        print(f"自分:{self} 相手:{opp} 結果:{result}")
        if result=='draw': # あいこ
            continue
        break

if __name__=="__main__":
    main()
```
FPVドローン ラップ計測システム【RotorHazard】を作っちゃおう ～その3～

# 5. RotorHazardのインストール
### インストール後の確認
Python for Windowsをインストールしたら、バージョン確認等のコマンドでPathもちゃんと有効かを確認していきましょう。

![Qiita-RH11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500291/5c3538bb-f3ab-16ae-4293-ffee57861afb.png)

![Qiita-RH12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500291/c8e7de8a-1f6e-921f-679c-fc4dc94f3b87.png)

そのまま `C:¥RotorHazard-4.1.0-b2¥src¥server` のパスでコマンドプロンプトが起動します。
![Qiita-RH13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500291/2e3f3c21-0c6c-4355-fb59-b26b19a5b200.png)

ここで `python` とだけ打ち込みEnterし、下記のようにバージョン情報のお返事が返ってくればOKです。
![Qiita-RH14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500291/6b67938c-8fa8-b942-8700-c6c453e14a6d.png)

### RotorHazardプログラムのインストール
動きが確認できたら `ctrl+Z` なのでPythonのモードから抜け、先ほどのコマンドプロンプトにて下記を打ち込んでください。
```
python -m pip install -r reqsNonPi.txt
```
インストールがスタートしますと、意外と時間はかかりますのでゆっくり眺めてくださいねｗ ワイの環境では、後半途中でWarningが出ましたが、重要ではないかな？と思いスルーしてしまっています。

![Qiita-RH15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500291/c8ec3fcd-653c-7690-8e7f-236d9e19aaab.png)

WARNINGメッセージは下記が出ていました。
``` WARNINGメッセージ
WARNING: The script wsdump.exe is installed in 'C:\Users\mac\AppData\Roming\Python\Python311\Scripts' which is not no PATH.
Consider adding this directory to PATH or, if you prefer to suppress this warning. use --no-warn-script-location.
```

# 6. RotorHazardシステムの起動
### 設定ファイル (config.json) の準備と編集
いよいよRotorHazardシステムを起動しますが、最初にベース設定を実施します。エクスプローラで `RotorHazar¥src¥server` 以下にある `config-dist.json` を見つけてコピー、ファイル名を `config.json` に変更します。

![Qiita-RH17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500291/655b0c88-079f-eb0c-bc8b-d22921dd2221.png)

そしてこの `config.json` ファイルを開いてまずは内容を確認します。
4行目、5行目はご自身が忘れないような管理者アカウントを記載してください。(セキュリティ上、必ず変更しましょう)

![Qiita-RH18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500291/09aa8dce-ff8f-f59a-91f1-7224dde59a55.png)

### RotorHazardプログラムの起動
先ほどのコマンドプロンプトを用いて下記コマンドを打ち込みましょう。
```
python server.py
```

初期の起動では、Windows Defender Firewallが反応してポップアップが表示されるものと思います。ここは素直に **【アクセスを許可する】** をクリックしてください。

![Qiita-RH16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/500291/b78aa047-e94a-55d1-f42c-60d4d94eb855.png)

つづきはこちら

https://qiita.com/tmac116/items/8c443b2a71778d4f68c6
Salesforce備忘録　キャンペーンについて 

Salesforce認定アドミニストレーター試験を受けるために過去問を解いていると, こんな問題があった.

#### Q. キャンペーンを新規作成したいが作成できません. 作成できない理由はどれですか？

これに対する選択肢は以下の通り.

A オブジェクトの作成権限がない
B マーケティングユーザーが無効化
C キャンペーンチームに追加されていない
D 主キャンペーンソースの指定がない

解答は, Bだった.

僕はこれの類題を解いたことがあったから, 選択肢を見てBだと判断し, 一応, その通りだった.
けれど, 「マーケティングユーザーってなんだっけ？」「キャンペーンとは？」に, スパッと答えられないのが現状であることに気がついたから, ここに備忘録としまとめていこうと思う.

そもそも先の設問の解説して, キャンペーンを作成または編集するには, マーケティングユーザ権限が必要である. これが無効だと作成ができないので, 設問のような状況で対応すべきは, マーケティングユーザを有効にしてあげることなのだ.

### キャンペーンとは

キャンペーンとは, マーケティング活動によって発生した見込み顧客の連絡先や反応, 商談数と結果, 獲得できたセールスパイプラインなどを詳細に追跡するためのツールである(引用: https://www.ccc.seraku.co.jp/service/columns/salesforce/02/95/). 

つまりは, 英語でいうキャンペーンの意味である組織的な運動や宣伝活動, これをSalesforceに置き換えるとマーケティング活動による効果を追跡するためのツールであるということで, 自分の中に落とし込んだ.
FargateのエフェメラルストレージをDatadogで監視する

## Fargate タスクエフェメラルストレージについて

- ECS FargateのLinuxプラットフォーム1.4.0以降のECSタスクに対して、デフォルトで20GiBのエフェメラルストレージが割り当てられます
- `ephemeralStorage`パラメータを設定する事で、最大200GiBまで増やす事が可能です

> プラットフォームバージョン 1.4.0 以降を使用している Fargate でホストされている Amazon ECS タスクは、デフォルトで、最低 20 GiB のエフェメラルストレージを受け取ります。エフェメラルストレージの総量は、最大 200 GiB まで増やすことができます。これを行うには、タスク定義内で ephemeralStorage パラメータを設定します。

参考：[Fargate タスクエフェメラルストレージ](https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/fargate-task-storage.html#fargate-task-storage-linux-pv)

## エフェメラルストレージのモニタリング

また、ECS FargateのLinuxプラットフォーム1.4.0以降から、ストレージ利用のモニタリングが可能となっています

参考：[AWS Fargate、ストレージ利用のモニタリングのサポートを追加](https://aws.amazon.com/jp/about-aws/whats-new/2022/11/aws-fargate-monitoring-storage-utilization/)

## Datadogでのモニタリング

Fargateのエフェメラルストレージについては

- 予約値
  - `ecs.fargate.ephemeral_storage.reserved`
- 使用量
  - `ecs.fargate.ephemeral_storage.utilized`

をDatadogのダッシュボード内で指定することで、モニタリングが可能です

[Amazon ECS on AWS Fargate - メトリクス](https://docs.datadoghq.com/ja/integrations/ecs_fargate/?tab=webui#%E3%83%A1%E3%83%88%E3%83%AA%E3%82%AF%E3%82%B9)

なお、Datadog以外にもContainer InsightsやFargateコンテナ内から確認が可能です

[AWS Fargateがストレージ容量を監視できるようになりました](https://dev.classmethod.jp/articles/aws-fargate-monitoring-storage-utilization/)
自分なりのブルーロックから学ぶプログラミング学習の本質


![スクリーンショット 2024-03-30 10.28.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/96e5d0d4-a49e-4e48-f945-3928ddc28973.png)


:::note info
<b>はじめに</b>
この記事は「ポエム」に近い記事となっております。主観が多くあるため、一つの意見だと思っていただけると幸いです🙇
:::




## 記事投稿の背景

- 僕ががプログラミングを学習しているとき、モチベーションの変動に疑問を感じました。一体何が原因なのだろうか。
- 技術習得に不安を感じ、この先自分ややっていけるのかなと不安になったりすることがある。
- 1ヶ月前まで難しいと思った技術が不安を感じずに、生き生きしながらコードを書けることができた。
- ブルーロックを読んでいてそういえば、モチベーションについて話をしていたような気がして調べてみた


## ブルーロックで学ぶ学習の本質

![manga_847.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/9bd74d0c-004e-f02f-80a2-dab0edb2d663.jpeg)


- <b>FLOW</b>は、人が最適な経験を通じて得る完全な没頭状態を指します
  - 人間は何かに集中し、時間を忘れて夢中になることがある
  - その行為を楽しみ脳がワクワクしている状態

## FLOWに入る条件

- 目の前のタスクが<b>「挑戦的な集中」</b>を必要とすること。
  - タスク自体は、自分にとって適度な難しさの目標であること
- ここで大切なのは、<b>「挑戦レベル」</b>と<b>「能力レベル」</b>のバランスになる。


#### 自分の能力の高さに対して挑戦が低い場合は、人間は楽しさを感じられるずに「退屈になる」

<img width=50% src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/b3f2130c-7008-456b-ebb8-40a0de920869.png">


#### 挑戦する目標が能力よりも高すぎる場合は、成功する可能性が信じられず、集中を切らし、人間は不安になる

<img width=50% src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/67432f79-29bf-9195-d50a-06dd9be533cb.png">


結論として、退屈や不安の状態では、学びの喜びは得られません。


## FLOWをプログラミング学習に捉えてみる

プログラミング学習も、上記で述べたFLOWの条件と同様に、挑戦レベルと能力レベルのバランスが大切です。プログラミングは、コードを書き、問題を解決することを中心に行われますが、その過程で最適な経験を得ることが重要となると思います。



#### 退屈
- 簡単すぎるタスクや、すでに理解している内容のみを繰り返して学習している場合、学習者は退屈に感じる場合がある。

#### 不安
- 自分のスキルに対して難易度の高すぎるタスクに飛び込むと、学習者は圧倒され不安に感じる場合がある。


### まとめ

- プログラミング学習においても、挑戦レベルと能力レベルのバランスは非常に重要です。適切なバランスを保つことで、学習者はプログラミングに対する喜びや達成感を感じ、継続的にスキルアップを目指すことができます。最終的には、このFLOWの状態を維持しながら、自分の能力と目標を常に調整し、プログラミングの世界での成功を追求することが重要です。
- 僕もいいモチベーションの維持に努めようと思いました。
Pythonで「現在の日付と時刻の値を持つインスタンスを作成する」の動作を確認してみた

# 概要

Pythonで「現在の日付と時刻の値を持つインスタンスを作成する」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/python/date/index3.html

# 実装

以下のファイルを作成しました。
```sample.py
import datetime
print(datetime.date.today())
print(datetime.datetime.now())
tokyo_tz = datetime.timezone(datetime.timedelta(hours=9))
print(datetime.datetime.now(tokyo_tz))
ny_tz = datetime.timezone(datetime.timedelta(hours=-4))
print(datetime.datetime.now(ny_tz))
```

以下のコマンドを実行しました。
```
$ python3 sample.py 
2024-03-30
2024-03-30 10:23:47.981617
2024-03-30 10:23:47.981654+09:00
2024-03-29 21:23:47.981668-04:00
```

# まとめ

何かの役に立てばと。
【備忘録】Next.jsでPlotly.jsを使う

素のReactとNext.jsで若干書き方に違いがあった。
地味につまずいたのでメモ。
筆者はReact・フロントは門外漢。


dashさまさまだと思った。

https://github.com/plotly/react-plotly.js

https://github.com/plotly/plotly.js

https://plotly.com/javascript/react/


# 要約

- 行頭の`'use client'`を指定する
- Next.js selfが定義されていないとか言われるのでimport変える
    - https://github.com/plotly/react-plotly.js/issues/272
- TypeScript使うときは型定義ファイルもinstallする
- selected, onclickイベント取得がバグってる？？
    - https://github.com/plotly/react-plotly.js/issues/116
- pythonで`fig.to_json()`したデータを使えば簡単にPlotが再現できる(た)
    -  がしかし型…

# 変更の要約

ほとんどこの人の記事ママ

Next.jsで扱うための変更とかだけ書く

https://qiita.com/aktr996/items/f3483c9fc17cf0ad3c10

行頭〜importを以下のように書き換える。

~~~typescript
'use client'
import React from 'react'
import dynamic from 'next/dynamic'
const Plot = dynamic(() => import("react-plotly.js"), { ssr: false, })
import {PlotParams} from 'react-plotly.js'
import {Layout, PlotData} from 'plotly.js'
~~~

return

イベントもこんな感じで書けば取得できるらしい

onselectedは動かないが、onselectingだと良いとか…

https://github.com/plotly/react-plotly.js/issues/116

~~~jsx
  return (
    // <Plot data={allData} layout={layout1} />
    <Plot
        data={allData}
        layout={layout1}
        onHover={(data)=>{console.log(data)}}
    />
  )
~~~

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3472791/b748298f-af1c-915d-aafd-00ef63689396.png)

## memo：　プロジェクトの作成

~~~bash
npx create-next-app --ts test-app
#...etc...
cd test-app
npm i plotly.js react-plotly.js
npm i --save-dev @types/plotly.js @types/react-plotly.js

cat << EOF > app/page.tsx
import ThreeGraph from "./threegraph";

export default () => {
  return(
    <div>
      <ThreeGraph />
    </div>
  )
}
EOF

touch app/threegraph.tsx
# 上の内容をコピペ
~~~

# 参考

https://qiita.com/aktr996/items/f3483c9fc17cf0ad3c10

https://github.com/plotly/react-plotly.js/issues/116

https://github.com/plotly/react-plotly.js/issues/330

https://github.com/plotly/react-plotly.js/issues/272
[Flutter x Supabase] Supabaseでsign in with appleを実装してみる

![スクリーンショット 2024-03-30 9.44.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/3567a9cc-1eed-82c9-ccbf-87533fe47fb6.png)



こんにちは。いせりゅーです。
バタバタしており、なかなか記事を書けずにいました。そもそも個人開発すらできずにいました。ようやく落ち着けることができたので、少しずつ再開していこうと思います。


## Sign in with Apple利用のためのセットアップ

詳しいセットアップ方法はこちらの記事を参考にさせていただきました。とてもわかりやすかったので掲載させてただきます🙇

https://zenn.dev/dk96424/articles/e40f8184748d04


## 実装に必要なPackageをインストール
- <b>supabase_flutter</b>
  - supabaseを使用するためのPackages

https://pub.dev/packages/supabase_flutter

- <b>sign_in_with_apple</b>
  - appleログインのためのPackages

https://pub.dev/packages/sign_in_with_apple

- <b>crypto</b>
  - SHA-256 ハッシュを計算するために使用

 https://pub.dev/packages/crypto

```shell
flutter pub add supabase_flutter
flutter pub add sign_in_with_apple
flutter pub add crypto
```

## appleのログインの実装をする

Supabaseのドキュメントに沿って記載してみました。他にも変更したところがあると思うので、こちらで閲覧できます。

https://supabase.com/docs/reference/dart/upgrade-guide?version=2.0x


```dart
import 'package:crypto/crypto.dart';
import 'package:sign_in_with_apple/sign_in_with_apple.dart';
import 'package:supabase_flutter/supabase_flutter.dart';

Future<AuthResponse> signInWithApple() async {
  // Supabase SDK を使用してランダムな nonce を生成する
  // Nonce はセキュリティ目的で使用する
  final rawNonce = supabase.auth.generateRawNonce();
  // 生成された nonce を SHA-256 ハッシュ化する
  final hashedNonce = sha256.convert(utf8.encode(rawNonce)).toString();

  // Appleのサインインウィジェットを表示し、ユーザーに認証を要求する
  // 指定されたスコープや nonce を含む認証情報を返す
  final credential = await SignInWithApple.getAppleIDCredential(
    scopes: [
      AppleIDAuthorizationScopes.email,
      AppleIDAuthorizationScopes.fullName,
    ],
    nonce: hashedNonce,
  );

  final idToken = credential.identityToken;
  if (idToken == null) {
    throw const AuthException(
        'Could not find ID Token from generated credential.',
    );
  }
  
  // 取得した ID トークンと nonce を使用して、Supabase を介してユーザーを認証する
  return signInWithIdToken(
    provider: OAuthProvider.apple,
    idToken: idToken,
    nonce: rawNonce,
  );
}
```


# 注意点
- 昔から使っていた方は、Postgres Versionのバージョンをあげないと以下のエラーが出るらしいです
- 解決策としては、`Settings > Infrastructure > Upgrade Postgres Version to 15.1.1.16`からアップグレードするとうまくいきました
```terminal
AuthApiError: Bad ID token
```
詳しいリンク↓

https://github.com/supabase/gotrue/issues/1401



### `Unacceptable audience in id_token`のエラーになる

#### 発生条件
- 同じメールアドレスを使用して、ログインをすると上のエラーが発生しました
- Appleログインを試みたとき

やってみたこと
- 「Apple でサインイン」をオフにして再度オンにした


https://github.com/supabase/gotrue/issues/1233
【AWS】 RDS for MySQL のパラメータ変更による再起動の有無を知りたい


## 解決したいこと

RDS for MySQL の全般ログとスロークエリログを CloudWatch Logs に出力したい。  
パラメータの変更が必要なのは分かったが、変更を反映するために再起動が必要かを知りたい。


## 調べたこと

全般ログ（general_log）とスロークエリログ（slow_query_log）のいずれも適用タイプは`Dynamic`のため再起動は必要ありません。`log_output`については後述します。

![general_log適用タイプ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3309107/d5cc9552-b3b4-0692-c701-74e9cd7118fc.png)

![slow_query_log適用タイプ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3309107/bdc7b013-2e70-dfeb-2914-fb4ef8867749.png)

![log_output適用タイプ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3309107/d86bb1d1-5c61-4e19-0a3d-944d445c1b75.png)

:::note info
監査ログはオプションです。 オプショングループで`MARIADB_AUDIT_PLUGIN`オプションを追加する必要があります。[1]

![RDSオプションの追加.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3309107/7405f12d-46c4-4513-ddb2-af5629bdf2fa.png)

:::

## やってみた
- RDS パラメータグループで全般ログとスロークエリログのパラメータ値を変更後に再起動が起きないことを確認
- CloudWatch Logs にログが出力されたことを確認

### 1. RDS のログの出力設定を確認

`全般ログ`と`スロークエリログ`にチェックが入っています。
![ログのエクスポート.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3309107/97cb5a23-3a5f-bf45-6f72-d692714db53c.png)


### 2. パラメータグループを作成
デフォルトのパラメータグループは変更できないため、カスタムパラメータグループを作成します。

![パラメータグループの作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3309107/5cfafedc-945c-fe3f-2412-a63d3d647cea.png)


### 3. パラメータグループをデフォルトから変更

上記 2. で作成したカスタムパラメータグループを選択します。

![DBパラメータグループを変更.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3309107/27bcdf4c-7380-00e8-e118-9abe6513e462.png)


### 4. パラメータを以下の値に変更

`general_log`と`slow_query_log`の値を`1`に変更します。 
あわせて、`log_output`の値を`TABLE`から`FILE`に変更する必要もあります。[2]  

| ログタイプ       | パラメータ名           | パラメータ値    | 
| ---------------- | -------------------- | :-------------: | 
| 全般ログ         | general_log          | 1         | 
| スロークエリログ | slow_query_log       | 1          | 
| ログ出力 | log_output  | FILE         | 



### 5. 再起動は起きませんでした

### 6. CloudWatch Logs にログが出力されたことを確認

`general`と`slowquery`それぞれロググループが作成され、ログが出力されました。

![ログ出力を確認.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3309107/47596cec-760b-8c98-bdb8-a98ea02ebe92.png)

:::note info
ロググループは自動的に作成されるため、あらかじめ作成する必要はありません。
:::


## 参考資料

[1] [MySQL に対する MariaDB 監査プラグインのサポート - Amazon Relational Database Service](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/Appendix.MySQL.Options.AuditPlugin.html#Appendix.MySQL.Options.AuditPlugin.Add)

[2] [Amazon CloudWatch Logs への MySQL ログの発行 - Amazon Relational Database Service](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_LogAccess.MySQLDB.PublishtoCloudWatchLogs.html)

[3] [MySQL を実行している Amazon RDS DB インスタンスのログを有効にしてモニタリングする | AWS re:Post](https://repost.aws/ja/knowledge-center/rds-mysql-logs)
フロントエンドの役割・DOMについて簡単なまとめ

## 概要
- 簡単にフロントエンドについてまとめる機会があったため、参考程度にスライドを置いておきます
- フレームワークの説明に関しては口頭であったため情報なしですが、新しく始めるのであればReact.jsが良いだろうと結論付けました
## スライド
<iframe src="https://docs.google.com/presentation/d/184xvIJe4r1j6M6qXSUqNf6Yd7z-u1lKIFHsokADz5lI/embed?start=false&loop=false&delayms=3000" frameborder="0" width="960" height="569" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>

## 以下より画像を利用しています
https://loosedrawing.com/