OmniAICreator/Qiita-1.07M huggingface dataset:
[GCP]IAMの概要

# 概要
GCPでは、各[リソース](https://qiita.com/WisteriaWave/items/4a2ae5878b48e4de1f4f)(組織, フォルダ, プロジェクト, サービス)に対して誰がどのようなアクセス権限を持つのかを、「1リソースに対して1ポリシーを設定する」ことで実現する。

上位リソースのポリシー設定(=アクセス権限の設定)は、下位リソースに引き継がれる。
ポリシーは複数の要素から構成され、図にすると以下のような形になる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59542/a74c4216-2062-838d-1699-42f849cf81ec.png)

図中に登場する用語は、以降で説明する。

## パーミッション
対象リソースに対するアクセス権限の最小単位。

## ロール
複数のパーミッションを1つにまとめたもの。
GCP側で用意してくれている「基本ロール」、「事前定義ロール」の他、自分で定義する「カスタムロール」というくくりがある。

ロールに含まれるパーミッションを検索するには [IAM basic and predefined roles reference](https://cloud.google.com/iam/docs/understanding-roles)
逆に、パーミッションが含まれるロールを検索するには [IAM permissions reference](https://cloud.google.com/iam/docs/permissions-reference)
を確認するとよい。


## プリンシパル
以下の総称である。

- Googleアカウント(= 人が使う)
- [サービスアカウント](https://qiita.com/WisteriaWave/private/01bb0a884b4d8bcd9fbc)(= システムが使う)
- 認証済みのユーザー(Googleアカウント, サービスアカウント)
- 全ユーザー
- Googleグループ(Googleアカウント, サービスアカウントをまとめたもの)


以前は「メンバー」と呼ばれていた模様。
( Terraform の IAM 関連のフィールド名なんかにも、その名残が見受けられる)


## バインディング
1リソース(組織, フォルダ, プロジェクト, サービス)の1ロールに対して複数のメンバーを紐づけること。
これにより、対象リソースに対してどのような操作がどのプリンシパルにも認められているのかを設定する。

## ポリシー
1リソースに対する全てのバインディングの集合のこと。
1リソースに設定できるポリシーは1つのみ。
上位リソースのポリシー設定は、下位リソースに継承される。

**参考**

https://cloud.google.com/resource-manager/docs/cloud-platform-resource-hierarchy?hl=ja

https://zenn.dev/nananaoto/articles/3b1b12a1c9db5ad2cfac


https://blog.g-gen.co.jp/entry/iam-explained#Google-Cloud-%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E7%AE%A1%E7%90%86

https://kaito-two.hatenablog.com/entry/2020/08/30/120000
RDSを理解するための考察①

## サブネットグループとは
簡単にいうと、サブネットグループはRDSインスタンスの「配置を決める」ためのものであり、可用性を高めるために使われる

サブネットグループには、アベーラリティゾーン（AZ）に属するサブネットが含まれており、RDSインスタンスがどのサブネットに配置されるかを決定します。これにより、1つのAZで障害が発生した場合でも、他のゾーンにフェイルオーバーでき、RDSの高可用性が確保される

ふむふむ。

他にもグループってあるよね？そう、セキュリティグループです！

## セキュリティグループとは
簡単にいうと、セキュリティグループはファイアウォールの役割！！
許可設定のみが可能で、拒否設定はありません。逆に、ネットワークACLでは許可と拒否の両方を設定できます。

セキュリティグループは、インバウンド（受信）とアウトバウンド（送信）のネットワークトラフィックを制御し、RDSやEC2インスタンスが外部や他のリソースからどのようにアクセスされるかを管理します。IPアドレスやポート番号ごとに許可ルールを設定し、何も設定されていないトラフィックは自動的に拒否されるのでご注意を！

他にも、パラメータグループ（データベース設定の管理）やオプショングループ（追加機能の管理）などのグループがありますが、まずはここまで！

理解度上げます！！
Webエンジニア「Kotlin」を学ぶ

現在Webエンジニアとして受託企業で働いているものです。
この度、転職を機にAndroidアプリエンジニアへキャリアチェンジをすることになったため、備忘録としてKotlinの学習記録を残すために投稿しています。
この記事ではKotlinとはどのような言語なのかということについてまとめています。

# Kotlinとは何か？
JetBrains社によって開発されたモダンなプログラミング言語。
2017年にGoogleからAndroid開発の公式言語として採用されており、Android開発において非常に人気が高い言語になっている。
また、マルチプラットフォームをサポートしており、JVM, Android, JavaScript, ネイティブ向けのコードをコンパイルすることができる。そのため、1つのコードベースから複数のプラットフォームに対応したアプリケーションを構築することができる。

# Kotlinの持つ特徴
### 静的型付け言語
- コンパイル時に型がチェックされるため、型安全性が高く、実行時のエラーリスクが減少し、信頼性の高いコードを書くことができる
- 型推論により、型を省略することも可能だが明示的に指定することで可読性が向上する

### Javaとの完全互換性
- KotlinはJVM(Java仮想マシン)上で動作するため、Javaと互換性がある。KotlinとJavaのコードは同じプロジェクト内に混在することができ、Javaライブラリもそのまま使用できる
- Javaに比べ、同じタスクを実現するコード量が少なくなる。冗長なコードを避け、より直感的で分かりやすい構文を持っている

### NULL安全
- nullによる例外（NullPointerException）を防ぐための仕組みが組み込まれているため、nullの存在を考慮した安全なコードを書くことができる

### オブジェクト指向、関数型プログラミングのサポート
- Kotlinでは、オブジェクト指向プログラミングと関数型プログラミングの両方をサポートしている
- 高階関数やラムダ式など、関数型プログラミングの要素を取り入れることでコードの柔軟性が高まる

### 拡張関数
- 既存のクラスに対して新しいメソッドを追加することができる
- Javaのようにクラスを継承せずに、クラスを拡張してメソッドを追加することができるため、コードの再利用性が高まる

### デフォルト引数と名前付き引数
- デフォルト引数と名前付き引数をサポートしており、関数の呼び出し時に引数を柔軟に指定できるため、関数のオーバーロードを減らしコードの簡潔さを保つことができる
集めよう、無料Credlyバッジ

## 飽き性学習者に捧ぐ
皆さん、学習してますか？エンジニアライフは終わりなき学習アンド学習の旅だと思います。
しかし、ただ勉強するだけだと飽きがきちゃいませんか？僕は飽き性なんでめっちゃ飽きます。スモールステップのゴールやご褒美があるとちょっと頑張れます。
そんな現金なタイプのエンジニアにおすすめしたいのがCredlyでのバッジ集めです。
この記事は、無料Credlyバッジコレクターの筆者が無料でバッジを取得できるコースを紹介する記事です。
現在進行形で探索中なのでみつけ次第更新していきます。

## Credlyとは？

https://info.credly.com/

Pearsonによるデジタル資格の管理プラットフォームです。
様々なベンダーは資格認定やハンズオンを完了した人に修了証（この修了証をバッジと呼ぶ）を発行しますが、このプラットフォームに参加しているとここで一元管理できるようになります。
この手の資格管理プラットフォームでCredlyは最大手です。
有名どころでは、AWS、CNCF、GCPなどの認定プログラムがCredlyでのバッジを配布しています。それらのベンダー資格を受験したことがある人は名前を聞いたことがあるかもしれません。

### バッジ集めると何がうれしいの？
就職活動をするときに自分のプロフィールページをPublicにすることで、採用担当者に「自分はこんなスキルをもってるよ」というのをわかりやすく伝えることができます。
あとは自己満！バッジが増えると嬉しい！

### お金はかけたくない
とはいえ、ここに参加しているベンダー資格の受験料は非常に・非常に高価です。お金はかけたくないじゃないですか。
無料でバッジを増やしましょう。というのが本稿の趣旨です。
以下に、無料でバッジを取得できるコースをご紹介します。ぜひバッジ増やししましょう。

## 無料で取得できるバッジを提供する学習コース一覧

### Datadog Learning Center
https://learn.datadoghq.com/

名前の通り、Datadogのラーニングコースです。ラーニングパスを修了することで無料でバッジを取得できます。ラーニングパスは現在3つ提供されています。
それとは別に有料の資格もあります。

### APIsec University
https://www.apisecuniversity.com/

名前の通りセキュリティのコース。
現在9つのコースがあり、それらを修了することでバッジを取得できます。
有料資格と、有料講座に参加することでもらえるバッジもあり。

### AWS Skill Builder

https://explore.skillbuilder.aws/learn/course/external/view/elearning/11458/aws-cloud-quest-cloud-practitioner

有料バッジが多いのですが、AWS Cloud Quest: Cloud Practitionerを完了すると無料でバッジがもらえます。

### Cognitive Class
https://cognitiveclass.ai/

IBMによる無料学習サイト。無料と言いつつ他サイトとの提携コースも紹介しているため実際は一部有料です。
バッジを貰えないコースもあるものの、ほとんどのコースを修了するとバッジがもらえます。
内容はAI、クラウド、コンテナ、Kubernetesなどかなり幅広いです。

### Cisco Networking Academy
https://www.netacad.com/catalogs/learn

主にセキュリティエリアのコース。
無料コースがいくつかあり、バッジを提供しています。

### Saylor Academy
https://learn.saylor.org/

コンピューターサイエンス以外にもいろいろな科目を無料で学べるコース。
ただ、コース一本が大学単位相当の仕上がりになっているため、かなり重厚です。バッジを取るのに時間がかかる。

### CertiProf
https://certiprof.com/pages/free-new-entry-level-certification

どれほどのものかは不明。無料の試験を受けるとバッジがもらえる。

見つけ次第追記します。
[SQLServer]読み取り専用モードに変更する方法と注意点


# 概要

DBのリプレースなどでデータを別DBに移行する場合、様々な戦略が考えられます。
もっともシンプルな戦略としては、データのバックアップの取得・復元や、データのエクスポート・インポート機能によって移行する方法ですが、DBに対するあらゆる更新処理を停止してデータの静止点を作る必要があります。
その場合なんらかの方法で確実にデータが更新されない状況を作る必要があります。単にアプリケーションの処理を停止するだけでは止め忘れなど意図しない更新がかかってしまうリスクは拭えません。

SQLServerの機能としてRead Only(読み取り専用)モードがあります。
これを利用することで、SQLServerの機能として確実に静止点を取ることができ、安心してデータ移行やメンテナンス作業を行うことができます。


# 読み取り専用モードへの変更方法

SQLServer公式のGUIツールであるSSMSまたはSQLコマンドから実行することができますが、SSMSのGUIから操作することをお勧めします。

読み取り専用に切り替えるためには、そのDBに対してすべてのセッションを一時的に全てkillする必要があり、１つでもクエリが実行中で時間がかかっていると、ロックが取れず読み取り専用に切り替えることができません。
しかしGUIから操作する場合、内部的にセッションをすべて切ってくれるため確実に切り替えることができます。

## GUIから行う場合

データベース > プロパティ >　オプション から「読み取り専用データベース」
FalseからTrueに切り替え
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79236/137088a2-f587-0c4a-1d53-e8ec02b01606.png)


OKを押すと接続を切るかの確認が出るので「はい」を押すと開始します。
![Pasted Graphic 9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79236/3e893438-ad6a-ee0a-e079-1d2aff27af96.png)


## コマンドで行う場合

SSMS上での操作をスクリプト生成しましたが、これにはセッションのKILLは含まれていません。

```
-- To Read Only
use [master];
GO
USE [master]
GO
ALTER DATABASE [******] SET  READ_ONLY WITH NO_WAIT
GO

GO

```

ある程度アクセスのあるDBであれば以下のようにエラーになってしまいます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79236/52f65444-ae14-7de9-1818-6002c262c962.png)


SET LOCK_TIMEOUTを付けることでロック解放待ち時間を制限できるかと思いましたが、
ALTER DATABASEでは指定できないので使えません。

```
CREATE DATABASE、ALTER DATABASE、および DROP DATABASE ステートメントでは、SET LOCK_TIMEOUT の設定は無視されます。
```
https://learn.microsoft.com/ja-jp/sql/t-sql/statements/set-lock-timeout-transact-sql?view=sql-server-ver16#remarks


# 注意点：切り替え時のダウンタイムについて

モードを切り替える際にDBに対してダウンタイムが一時的に発生します。
ダウンタイムが発生すると、参照処理に影響が出るため、このダウンタイムは注意しなければなりません。

あるDBリプレース時、検証環境で5~7秒程度瞬断することを確認していましたが、本番環境の作業では3分ほど長期間のダウンタイムが発生してしまいました。

原因は、内部のバッファキャッシュのサイズの違いによるものでした。
読み取り専用モードに切り替える際、対象DBのバッファキャッシュをクリアする処理が内部的に実行されます。

本番DBなど検証環境よりも大量のメモリを確保しており、数百GB単位でバッファプールにデータが乗っている場合注意が必要です。

また、サーバーの負荷によっても所要時間が変わりそうなので注意してください。


# まとめ

SQL Serverの読み取り専用モードは便利な機能ですが、以下の注意点に気をつけましょう。
- 全てのセッションを確実に切るためSSMSから行う
- ダウンタイムが発生する
- ダウンタイム時間はバッファキャッシュのクリア時間に比例する

検証環境では本番同等のデータ量で検証していましたが、メモリ量や実際のワークロード下での検証はできていませんでした。
ダウンタイムが数秒でも発生する作業は、例え数秒だとしても影響があるとないでは大きく違います。
検証環境では数秒程度の影響でも、その所要時間は何によって決まるのか、原因は何かを事前に確認しておき本番環境でもその時間で終わることを確認できるとよかったです。あらためて良い教訓になりました。

リプレースやメンテナンス時には非常に便利な機能なので、皆さんも読み取り専用機能を使ってみてください！
Unity Localizationを便利に実用化してみよう。前段編【hako 生活の休日】

:::note
この記事は前段の記事となります。
具体的な解決策は次の記事から。

:::

次の記事

https://qiita.com/clrfnd/items/edf03f018e52063d57cd


# 背景：ローカライズって面倒だよね
現代のインディーゲームのパブリッシュにおいて、ローカライズは必須となってきていますよね。
開発者としては、ローカライズがない前提の開発であれば、テキストを直接インスペクターに書き込んだりスクリプトに直書きしたいところです。ただし、そんなハードコーディングしたゲームをパブリッシャーさんや翻訳者さんに持ち込んだら、おそらく苦い顔をされることでしょう。

# これまで完成させたゲームの場合
さて、僕がUnityで作ったゲーム（以下）ではどうしていたかといいますと、基本的には独自に実装していました。

### 1. アンリアルライフの場合

https://www.unreal-life.net/

こちらはアドベンチャーゲーム。9ヶ国語に対応しています。テキストは10万字ぐらい。

2019年ぐらい？当時主流だったエクセルインポーターを使用していました。
xlsxで管理していました。

▼たしかこれ

https://studioclips.jp/Unity/Excel/unit%E3%81%A7%E3%82%A8%E3%82%AF%E3%82%BB%E3%83%AB%E3%81%8B%E3%82%89%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%82%80%E6%96%B9%E6%B3%95.html


### 2.ghostpia シーズンワンの場合
こちらはノベルゲーム。4ヶ国語に対応しています。

https://ghostpia.xyz/

NuGetから必要なパッケージを取り込んで、Google APIを直接たたいて作りました。

▼近そうな記事

https://zenn.dev/happy_elements/articles/4bf35bd1690052


## Unity Localizationの便利さ
近年は毎度まいど独自に実装していたり、アセットを購入す必要もなくなってきてますね。
Unityが公式にローカライズ用のパッケージを用意してくれているからです。

https://docs.unity3d.com/ja/2022.3/Manual/com.unity.localization.html

みなさんも一度は導入を検討したことがあるかもしれませんが、実際の使いやすさはどうでしょうか。以下はいち開発者の所感となります。

## Unity Localizationの実用性
ローカライズの基本的な実装のほとんどを担ってくれているのが本当にありがたいです。
良い点を挙げたらきりがないですが、

1. ロケーションのアレコレを全部やってくれてる
2. CSV、SpreadSheetとのシート連携が容易
3. Smart機能で変数や単位の表現拡張もできる
4. 標準パッケージなので安心。技術を共有しやすい
5. etc...

といった感じでしょうか。


### 1.CSV、SpreadSheetとのシート連携が容易
翻訳者さんとは基本的にSpreadSheetでやり取りしたいので、割と必須です。
シートからエディタへのPullだけでなく、エディタからシートへのPushもできます。

###  2.ロケーションのアレコレを全部やってくれてる
言語の切り替えも容易です。

### 3.Smart機能で変数や単位の表現拡張もできる
日本では「1日、2日、3日」と表現するが英語では「first day, second, day third day」になるなど

### 4.標準パッケージなので安心。技術を共有しやすい
リリースしてからの言語追加を別のエンジニアさんに任せることも多いはず。

そんな夢のようなパッケージですが、実用性は…？と聞かれるとあと一歩…！と思うところがあります。ありがたいことに**機能がめっちゃ多い**ので、小さいプロジェクト等では機能過多かも…？と思うことも多いんじゃないでしょうか。

# Unity Localizationの思うところ…
Unity Localizationを導入してみてしばらく使ってみたところ、心理的障壁になっているなと感じる部分がいくつかありました。
- StringTableCollection
    - 設定や設計思想をとらえるのが少し難しい
        ⇒これはしょうがない
    - ①いつでもすぐにPullしたい（Pushはいいかな）
    - ②いつでもすぐにスプレッドシートを開きたい
- LocalizedString
    - ③Smartのチェックがめんどくさい
    - ④ドロワーが重い
    - ⑤（コード上）変数のセットがめんどくさい
- できたらいいな～という点
    - シートに話者情報やコマンドを書き込める列を作りたい
    
シンプルに **機能過多な部分** があり、ちょっと使用感のカロリーが高めです。インディーゲーム製作に限る部分もありますが、やはりスムーズに使用するには**エディター上での手数**が重要になってきます。
ということで、時間があるときにそれぞれの解決法について、書いていこうと思います。
# 次の記事

https://qiita.com/clrfnd/items/edf03f018e52063d57cd

https://qiita.com/clrfnd/items/8c80a6fd148179101771
Unity+MIDIで音ゲーを作るならコレ！(1)

### 音ゲー?
<img width="120" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/af47caff-9b4b-6a56-9376-78ff0d050881.png">


ということで、まずはこれを見てください。
<iframe width="560" height="315" src="https://www.youtube.com/embed/RFZlhxCL1eo?si=tZLKyOMnSRlUR9KN" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

音はmp3ではなく、MIDIファイルをリアルタイムで演奏しています。

これは **Maestro - Midi Player Tool Kit -FREE** という無料のアセットに入っているデモです。

使い方にはやや癖があります。また、力業で鳴らしているためか、一時停止をかけたりデバッグでブレークポイントを張ったりすると壊滅的な音階になったりしますが、それを差し引いてもあまりある簡単さで音を出すことができ、かつ、リズムに合わせてオブジェクトを表示する等を行うことができます。

### まずはアセットをダウンロード
https://assetstore.unity.com/packages/tools/audio/maestro-midi-player-tool-kit-free-107994

こちらのアセットを取得して、Unityでインポートします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/25a6a504-fa46-2aa3-d2d2-2b3d20c768b7.png)

### MidiFilePlayer Prefabをシーンに追加する
新しいシーンを作成したら、MidiFilePlayer Prefabをシーンに追加します。

Projectタブのすぐ下の段にある検索フォームに 'midi' のように入力すると見つけるのが簡単になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/4414fe1d-31ef-b5d4-d79a-b2bd773f936d.png)

### 再生する
再生すると、MidiFilePlayerにプリセットされたMIDIファイルが演奏されます。
<iframe width="560" height="315" src="https://www.youtube.com/embed/z6S6Dtxr2ok?si=J31d-CNX0qLsEkXK" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

### 自分で用意したMIDIファイルを使用するには
MIDIファイルを鳴らすのにMIDIファイルがない？
そんな時は配布されているMIDIファイルを用意しましょう。
MIDIファイル配布サイトをまとめてくださっている方がおられたので、自分はそちらからMIDIファイルを取得しました。

https://note.com/gogotea_love/n/n87132d20beb3

### MIDIファイルをインポートする
このアセットでは、MIDIファイルをインポートしてから使用します。
メニューから　Maestro > Midi File Setupを選択し、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/5de5a8e8-a1d9-22d3-5b53-a2ac01c0737e.png)

Add a Midi Fileボタンを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/03d068dd-16eb-c416-871e-1fc8ca88d993.png)

適当なMIDIファイルを選択すると、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/546b5c70-e513-a4f3-35be-c37055d75bce.png)

ファイルがインポートされ、リストに追加されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/889c8dd8-971c-4f31-8b5b-6f73e9eca4d0.png)

追加したMidiFilePlayer Prefabをクリックし、InspectorウインドウのSelect MIDIをクリックするとMIDIファイルのリストが表示されるので、先ほどインポートしたMIDIファイルを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/f455a0ed-661d-4e9a-7d8c-59cb919c496e.png)

正しく選択されたのを確認し、Select a MIDI Fileウインドウを閉じます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/59c1036b-6aba-3929-e158-44f7f059f87d.png)
再生すると、自分で用意したMIDIファイルが演奏されます。

### 今回はここまで
[次回](https://qiita.com/ELIXIR/items/a20ba6aeb1b0964b638c)は音ゲーの要素、テンポに合わせて何かをする、というのを行う予定です。
Amazon RDSについて勉強してみた

## 前提
- SAA-C03合格済み！
- 合格までの道のりは[こちら](https://qiita.com/ryotabaske13/items/e81e61e98235aa284933)を参照してみてください
- SAA合格はしたけど、知識定着のために定期的に記事を書くことにしました
- 新しく業務でRDSを使うことになりそうなので勉強したことをまとめる

## RDSとは
- AWSクラウドでリレーショナルデータベースを利用することができるマネージドサービス
- IBM Db2、MariaDB、Microsoft SQL Server、MySQL、Oracle Database、PostgreSQLなどデータベースエンジンを使用することができる

## リレーショナルデータベースとは
- データを表形式で保存する
- 表形式で保存された複数のデータを関連づけて使用、管理できる
- テーブル(表)の各行は、キーという一意のIDを持っている
- [参考](https://www.oracle.com/jp/database/what-is-a-relational-database/)

## RDSで利用できるRDBMS
- オンプレミスで使っているものをそのままAWS環境へ移行することができる

- Amazon Aurora
  - AWSが構築したRDBMS
  - MySQL、PostgreSQLと互換性がある
  - バックアップ機能が強固である
- MySQL
- MariaDB
- Oracle Database
- SQL Server
- PostgreSQL

## RDSの主な機能
### 自動バックアップ
- デフォルトで、7日間の自動バックアップを取得できる
- バックアップ期間は35日間まで設定できる
- データを消失してしまったり、障害が発生したりしてしまっても、特定の地点のデータに戻すことができる

### リードレプリカ
- リードレプリカと呼ばれる読み取り専用データベースを作成することで、大量のリクエストが来た場合もパフォーマンスを落とすことなく処理できる
- また、オリジナルのデータベースにリクエストが集中しないように、負荷分散を実現することもできる
- [参考](https://aws.amazon.com/jp/rds/features/read-replicas/)

### 暗号化
- 利用開始時に暗号化オプションを有効にするとデータを暗号化することができる
- [AWS KMS](https://docs.aws.amazon.com/ja_jp/kms/latest/developerguide/overview.html)や[AWS CloudHSM](https://aws.amazon.com/jp/cloudhsm/)といった暗号化サービスを使うことができる

### マルチAZ
- 複数のアベイラビリティゾーンにDBを設置することで、高い可用性を実現できる
- スタンバイDBインスタンス(バックアップ用のDB)をプライマリDBインスタンス(オリジナルのDB)とは別のAZに配置する。もしプライマリDBに障害が発生した場合、スタンバイDBインスタンスに切り替えることでサービスへの影響を抑えられる
- [参考](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/Concepts.MultiAZ.html)

## 参考資料
- https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/Welcome.html
Next.js + swc/jestでESMのライブラリを使用したコンポーネントのテストに失敗する時の対処法


# 状況
Next.js を使用したアプリケーションのテストで、transformには　`swc/jest` を利用している。
テストコードの中で、 `testing-library` の `render()` で
`react-markdown` を内部で利用しているコンポーネントをrenderすると、エラーが出てしまう。

```
    Jest encountered an unexpected token

    Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.

    Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.

    By default "node_modules" folder is ignored by transformers.

    Here's what you can do:
     • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it.
     • If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/configuration
    For information about custom transformations, see:
    https://jestjs.io/docs/code-transformation


    SyntaxError: Unexpected token 'export'
```

これは `react-markdown` がESMであることに由来しているようだ。

# 環境
    "@swc/core": "1.4.5",
    "@swc/jest": "0.2.36",
    "@testing-library/jest-dom": "6.4.2",
    "@testing-library/react": "14.2.2",
    "jest": "29.7.0",
    "typescript": "5.2.2"


# 対処

https://github.com/vercel/next.js/issues/40183#issuecomment-1979587339
こちらの方法を参考に、 `jest.config.js` を書き換えることで回避できた :tada: 

```jest.config.js
const nextJest = require('next/jest')

const createJestConfig = nextJest({
  dir: './',
})

const esModules = [
  'react-markdown',
  'swiper',
  // その他ESMのものを記述
].join('|')

const customJestConfig = {
  cacheDirectory: 'node_modules/.cache/jest',
  moduleNameMapper: {
    '^~/(.*)$': '<rootDir>/src/$1',
    '^@/(.*)$': '<rootDir>/$1',
  },
  testEnvironment: 'jest-environment-jsdom',
  transform: {
    '^.+\\.(t|j)sx?$': [
      '@swc/jest',
      {
        jsc: {
          transform: {
            react: {
              runtime: 'automatic',
            },
          },
        },
      },
    ],
  },
  extensionsToTreatAsEsm: ['.ts', '.tsx'],
  setupFilesAfterEnv: ['./jest.setup.js'],
  // 〜以下略〜
}

module.exports = async () => ({
  ...(await createJestConfig(customJestConfig)()),
  transformIgnorePatterns: [`<rootDir>/node_modules/(?!${esModules})/`],
})

```

`transformIgnorePatterns` を　`createJestConfig()`の外側で後から上書きするのがポイントらしい。
https://github.com/vercel/next.js/issues/36077#issuecomment-1096635363



# 参考
- https://zenn.dev/t_yng/scraps/d701cdae1071fd
- https://blog.lycolia.info/0219
- https://community.redwoodjs.com/t/react-markdown-typescript-jest/4680/7
【AWS,Python】LambdaとAPI Gateway でJSONを返すAPIを作る

# API Gatewayを使ってAPIを作成する

![Screenshot 2024-09-06 130825.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722467/6079dc08-288a-0198-989a-d6fd0ccfbdad.png)


LambdaでJSONファイルを作成する関数がすでにあるので、この関数を利用してAPIを作成します。

https://qiita.com/otaruit/items/44b487e45e5bb6247376

## 1.API GatewayでREST APIの作成
AWSでAPI Gatewayをひらき、「APIを作成」をクリック
![Screenshot 2024-09-05 124626.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722467/314ee254-ccc0-28fe-87ea-342ccc8da614.png)

## 2.REST APIを選択、構築
![Screenshot 2024-09-05 124648.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722467/728ddf8e-643f-cc61-39c4-e71acddd73ad.png)

## 3.新しいAPIを選択、API名記入が終わったら作成
![Screenshot 2024-09-05 124742.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722467/44c2fb14-3f64-db77-fabc-db367c2564bd.png)

## 4.API作成が完了、「リソースを作成」をクリック
![Screenshot 2024-09-05 124813.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722467/e36ed186-f5e6-d896-e5f6-4a25ef84a7e7.png)


## 5.リソース名入力、CORSチェック、「リソースを作成」
CORSは
「ブラウザで実行されているスクリプトから開始されるクロスオリジン HTTP リクエストを制限するブラウザのセキュリティ機能」
だそうです。
この設定がないと、異なるドメインから呼び出すことができなくなるようです。

https://dev.classmethod.jp/articles/amazon-api-gateway-cors/

![Screenshot 2024-09-05 124921.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722467/41638ddc-726a-9457-0a29-9495e0f3f86f.png)

## 6.メソッドを作成
![Screenshot 2024-09-06 125423.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722467/c6ffa879-a444-b881-c9ba-b9d57e92c630.png)

## 7.詳細を設定
メソッドタイプ：GET
統合タイプ：Lambda
Lambdaプロキシ統合：チェック（画像では未チェックですが必要）
lambda関数：lambdaで作成した関数を指定してください

![Screenshot 2024-09-05 125742.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722467/3de52c7b-b6c2-337f-67f0-b24c5b7ad87c.png)

## Lambdaの方の設定
API Gatewayは以上で完了ですが、Lambdaの方で以下も対応が必要です。

### 1.設定→一般設定→編集をクリック

![Screenshot 2024-09-05 125251.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722467/5413650c-8cca-4937-914f-f2d95313e6a7.png)

### 2.タイムアウトを１０秒以上に設定する
時間が短いと実行が完了できずエラーになるので10秒以上に設定してください。
![Screenshot 2024-09-05 125310.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722467/5b2b91b7-b5aa-3e5e-100a-84f22a36b993.png)

### 3.設定→アクセス権限→ロール名をクリック

![Screenshot 2024-09-05 125609.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722467/13ea88ea-5163-e3d8-c040-2a2187f82b39.png)

# API Gatewayとつながりました

![Screenshot 2024-09-05 125859.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722467/1dd9ab95-78d4-8461-3bc7-55b72dbfdbca.png)

# テストしてみる
ステータスコード200で成功です。

![Screenshot 2024-09-06 130357.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/722467/14ec8224-2086-2115-1ab3-aba24613d5ed.png)
Railsでプロジェクトルートディレクトリのパスから辿れるようにする

# 概要
- スクリプトを実行するときに外部ファイルが必要な場合が多々ある
- どこに置く？となると、`~/tmp/` が良いんじゃなかろうかと
    - https://railsdoc.com/rails_base
- スクリプトからどうやって取得する？で教えてもらった話の備忘録


# 結論

`Rails.root.join` を利用しましょう

```ruby
csv_path = Rails.root.join('tmp', 'file_name.csv')
```

コンソールでいじるとこんなオブジェクトが返ってきます（僕の環境下ではDocker利用しており、プロジェクトルートディレクトリが`/app`にしているので、`/app`が表示されています）

```ruby
$ rails console
[1] pry(main)> Rails.root
=> #<Pathname:/app>
[2] pry(main)> Rails.root.join
=> #<Pathname:/app>
[3] pry(main)> Rails.root.join('tmp')
=> #<Pathname:/app/tmp>
[4] pry(main)> Rails.root.join('tmp', 'test.csv')
=> #<Pathname:/app/tmp/test.csv>
```
Rails - 間違ったマイグレーションを環境に反映してしまった時のリカバリ方法

# 前提

稼働している環境に対して、間違ったマイグレーションを反映してしまった場合
( PRのマージ先を間違った場合など )

今回は誤ったテーブルを新規作成してしまったケースで考える

# STEP 1 - コードの修正

まずは誤ったコードをRevertするなどして、正しい状態に戻してデプロイする

最低限 `schema.rb` に記録されている「最新のマイグレーション時刻」は元に戻す必要がある

```diff
- ActiveRecord::Schema[7.2].define(version: 2024_09_06_123701) do
+ ActiveRecord::Schema[7.2].define(version: 2024_09_05_100123) do
```

# STEP 2 - DBのリカバリ

DBを正しい状態に戻す

この例ではSQLを直接実行して、誤って作られてしまったテーブルを削除する

```sql
DROP TABLE IF EXISTS example_table
```

Rails経由で実行する場合は rails console / rails runner を使うと手軽に実行しやすい

```sh
rails runner "ActiveRecord::Base.connection.execute('DROP TABLE IF EXISTS example_table')"
```

# STEP 3 - DBのリカバリ ( schema_migrations )

誤って記録された分の schema_migrations のレコードを削除する

Rails は `schema_migrations` というテーブルでマイグレーション履歴を管理しているので、レコードの状態を正しくする

例:

```sh
DELETE FROM schema_migrations WHERE version = "20240906123701"
```

Rails経由でやる場合は以下

```rb
rails runner "ActiveRecord::Base.connection.execute('DELETE FROM schema_migrations WHERE version = \"20240906123701\"')"
```



# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# プロフィール・経歴

https://github.com/YumaInaura/YumaInaura
GitHubへのPush権限がない場合にやるべきこと

## 1. 問題の発生
GitHubでリポジトリにコードをプッシュしようとすると、`403 Forbidden` エラーが表示される場合があります。エラーメッセージは次のようなものです。

```bash
remote: Permission to <ユーザー名>/<リポジトリ名>.git denied to <別のユーザー名>.
fatal: unable to access 'https://github.com/<ユーザー名>/<リポジトリ名>.git/': The requested URL returned error: 403
```

これは、リポジトリに対するプッシュ権限がない場合に発生します。以下の手順で解決できます。


## 2. Personal Access Token（PAT）の生成

GitHubでのパスワード認証は廃止されており、Personal Access Token（PAT）を使用して認証します。以下はPATを生成する手順です。

1. **GitHubにログイン**し、右上のプロフィールアイコンをクリック。
2. 「**Settings**」→「**Developer settings**」を選択。
3. 「**Personal access tokens**」→「**Generate new token**」をクリック。
4. 必要なスコープ（例: `repo`）を選択し、トークンを生成します。
5. トークンを生成したらコピーし、安全な場所に保存します。**トークンは一度しか表示されません**ので注意が必要です。

---

## 3. リモートURLの更新

次に、生成したトークンを使ってリモートURLを更新します。以下のコマンドを実行して、リモートリポジトリのURLを設定してください。

```bash
git remote set-url origin https://<GitHubユーザー名>:<PAT>@github.com/<GitHubユーザー名>/<リポジトリ名>.git
```

例として、GitHubユーザー名が `RRR` で、PATが `555` の場合は次のように実行します。

```bash
git remote set-url origin https://RRR:555/RRR/rrr.git
```

## 4. リモートにプッシュ

リモートURLを更新したら、リモートリポジトリにプッシュします。

```bash
git push origin main
```


## 5. ブランチを使って `main` を汚さない方法

`main` ブランチを直接汚したくない場合は、新しいブランチを作成して作業することを推奨します。`git switch` コマンドを使ってブランチを切り替えましょう。

#### 5.1 新しいブランチの作成

次のコマンドで新しいブランチを作成し、そのブランチに切り替えます。

```bash
git switch -c <新しいブランチ名>
```

例:
```bash
git switch -c feature-update
```

`-c` は **create（作成）** の意味で、指定したブランチが存在しない場合に新しいブランチを作成して切り替えるオプションです。

---

## 6. 変更内容をコミット

新しいブランチで作業した後、次のコマンドで変更内容をコミットします。

```bash
git add .
git commit -m "Add new feature"
```


## 7. リモートにブランチをプッシュ

新しく作成したブランチをリモートリポジトリにプッシュします。

```bash
git push origin <新しいブランチ名>
```

例:
```bash
git push origin feature-update
```

## 8. `main` へのマージ

作業が完了し、コードのレビューやテストが問題なければ、`main` ブランチにマージすることができます。

#### 8.1 `main` ブランチに戻る

まず `main` ブランチに戻ります。

```bash
git switch main
```

#### 8.2 マージを実行

次に、作業したブランチを `main` にマージします。

```bash
git merge <新しいブランチ名>
```

例:
```bash
git merge feature-update
```

#### 8.3 最終プッシュ

最後に、`main` ブランチをリモートリポジトリにプッシュします。

```bash
git push origin main
```
## まとめ
GitHubへのプッシュ権限がない場合は、以下の手順で解決できます。

Personal Access Token（PAT）を生成し、リモートリポジトリのURLを更新。
リモートリポジトリにプッシュするために適切な権限を設定。
main ブランチを直接変更したくない場合、新しいブランチを作成して作業し、そのブランチでコミットとプッシュを行う。
作業が完了したら、main ブランチにマージして最終的にリモートにプッシュ。
これにより、main ブランチを保護しながら、GitHubでの作業がスムーズに進められます。PATの使用とブランチ管理によって、権限問題を解決し、安全にコードを管理することができます。
【ChatGPT＋Code Interpreter】で画像内の吹き出しを認識して、赤枠で囲みます。


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

　今回は、画像内の吹き出しを認識して、赤枠で囲みます。

:::note info
本記事は、ChatGPT（有料版）
で行なっております。画像は
あります。　あしからず。
:::

　まずは、ニュースです。

　OpenAIは
　　高額なサブスクリプションプランを
　　　検討しているそうです。
　　　　[ChatGPT研究所ポスト](https://x.com/ctgptlb/status/1831715486641615280?t=MnMD34NbvFseCUEAq_FDhQ&s=19)

　GPT-Nextは
　　それだけ能力が
　　　高いのでしょうね。
***
　さて、本題です。

　今回は、
　　画像内の吹き出しを
　　　認識して、赤枠で囲みます。

　ChatGPTに
　　ふつうに指示しても
　　　それなりの位置や大きさで
　　　　赤枠を描いてくれます。

　しかし、
　　確実な形を求めているのに
　　　こんな精度では
　　　　いただけません。

　なんとかできないかと
　　ずっとあれこれやってきました。

　ようやく
　　形になりましたので
　　　記事にしました。

　今回使用したのはこちら。
　　DALL-E3で描いた画像です。
　　　吹き出しがありますね。
　　　　これを認識してもらうわけです。
![1725593863061.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/6f2e8f5b-f641-a249-a40a-738ec8d14bda.jpeg)

　手順は
　❶GPT-4oであることを確認
　❷画像をアップロード
　❸Prompt入力
```Text:吹き出しに赤枠Prompt
OpenCVを使用して、画像内の白い領域を検出し、その領域を輪郭として抽出してください。その後、検出された白い領域の中から最も大きい矩形を特定し、その矩形の周りに赤い枠を描画してください。
```
　❹送信
　❺ダウンロードリンクが表示

　これで作成されたのがこちら。
![1725593883868.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/9873020c-ad26-522f-5f03-2967bb54fc50.jpeg)

　ChatGPTさんに
　　このPromptの説明を
　　　してもらいます。
***
***ChatGPT***
### 実施した手順:
1. **白領域の検出**: OpenCVを使用し、画像内の白い領域を検出。画像をグレースケールに変換し、しきい値を設定して白い部分を明確に区別しました。
2. **輪郭検出**: 検出した白い領域の輪郭を検出し、領域全体に多角形の赤枠を描画しました。
3. **領域内の矩形検出**: 検出された白い領域の中で、最も大きい矩形を特定し、その領域に赤い枠を描画しました。
4. **最終調整**: 輪郭の中から最大の領域を囲む矩形だけを描画し、最終結果として提示しました。
***

　いやぁ、
　　長かったです(^_^;)qﾌｷﾌｷ

　“手法を変える”ように
　　指示したことで、
　　　うまく行きました。

　これでようやく
　　次の段階に進めます。

　みなさんの
　　作品制作の糧に
　　　なれば、幸いです。

　今回は、ここまで。
EC2でExpressサーバーとNginxを使用したリバースプロキシの作成

## アジェンダ
Expressサーバーを作成し、Nginxからそのサーバーにリクエストをプロキシしてレスポンスを返すまでの手順を簡単にまとめます。
Nginxはリバースプロキシとして動作し、外部からのリクエストをExpressサーバーに転送します。

## 1. Expressサーバーの作成
まず、EC2インスタンス上でNode.jsとExpressをセットアップし、簡単なExpressサーバーを作成します。

### Node.jsとnpmのインストール
```bash
sudo apt update
sudo apt install nodejs
sudo apt install npm
```

### Expressサーバーの作成
```bash
mkdir my-express-app
cd my-express-app
npm init -y
npm install express
```

### `app.js`ファイルの作成
次のコマンドで`app.js`ファイルを作成し、vimエディタを使用して編集します：
```bash
vim app.js
```

`app.js`というファイルを作成し、次のコードを記述します：
```javascript
const express = require('express');
const app = express();

app.get('/', (req, res) => {
  res.send('Hello from Express!');
});

const port = 3000;
app.listen(port, () => {
  console.log(`Server is running on port ${port}`);
});
```

エディタを保存して終了するには、`:w`で保存し、`:q`でvimを終了します。

### Expressサーバーの起動
```bash
node app.js
```
これで、`http://localhost:3000`でExpressサーバーが稼働しているはずです。

## 2. Nginxの設定
次に、Nginxをリバースプロキシとして設定し、Nginx経由でExpressサーバーにリクエストが届くようにします。

### Nginxのインストール
```bash
sudo apt install nginx
```

### Nginxの設定ファイルを編集
設定ファイルは`/etc/nginx/sites-available/default`にあります。以下のようにリバースプロキシの設定を追加します。

```bash
sudo vim /etc/nginx/sites-available/default
```

`server`ブロックに以下を追加します：
```nginx
server {
    listen 80;

    server_name your_server_domain_or_IP;

    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}
```

ここで、`your_server_domain_or_IP`はEC2インスタンスのパブリックIPやドメインに置き換えます。

### Nginxの再起動
設定を有効にするためにNginxを再起動します。
```bash
sudo systemctl restart nginx
```

## 3. 動作確認
ブラウザでEC2インスタンスのパブリックIPにアクセスし、NginxがExpressサーバーからのレスポンスを正しくプロキシしているか確認します。

```bash
http://your_ec2_public_ip
```
`Hello from Express!`と表示されれば成功です。

## 最終的なWebサーバーインスタンス内のディレクトリ構成

```
/home/ubuntu/my-express-app
├── app.js               # Expressサーバーのエントリーポイント
├── node_modules/         # npmモジュール
├── package.json          # npmプロジェクトの設定ファイル
└── package-lock.json     # 依存関係の詳細
```

Nginxの設定は次の場所にあります：
```
/etc/nginx/sites-available/default  # Nginxのリバースプロキシ設定
```

## 補足
- **NginxとExpressの役割**: Nginxはリバースプロキシとして動作し、クライアントからのリクエストをExpressに転送し、Expressのレスポンスをクライアントに返します。
- **リバースプロキシの理由**: Nginxは高性能なリクエスト処理ができ、セキュリティや負荷分散、SSLターミネーションなどの機能を提供するため、Node.jsのアプリケーションを直接公開するのではなく、Nginx経由で運用するのが一般的です。
ARK: Survival Ascended(ASA)のAberration（アベレーション）へのMAP切り替え方法

# 1.はじめに
この記事はConohaや自宅サーバーなどで立てた非公式サーバーのARK: Survival Ascended(以下ASA)のマップをAberration（アベレーション）へ切り替える方法になります。

Conohaでサーバーを立てたい場合は以下の記事を参照ください。
(2024/09/06 動作確認済み)

:::note info
[ConohaでのASAサーバーの立て方（リンク）](https://qiita.com/HAKOTEN/items/0e7d7f9487fc82d0ee55)
:::

# 2.サーバーのアップデートを実施
TeraTermでサーバーに接続して以下コマンドを実行していきます。


```:サーバーの停止
sudo systemctl stop ark-island
```
```:サーバーのアップデート
sudo -u steam /usr/games/steamcmd +login anonymous +app_update 2430930 validate +quit
```

サーバーのアップデート完了画面
![インストール.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3716588/c70587ea-0133-79fa-c420-6743dfb434f7.png)



# 3.起動用のサービスを作成
#### ①Aberrationの起動用のサービスを作成します。

```:サービスのディレクトリに移動
cd /etc/systemd/system
```
```:サービスを複製
cp ark-island.service ark-Aberration.service
```
※今回は分かりやすいようにMapの名前で付けていますが、なんでも大丈夫です。



#### ②viコマンドで作成したサービスを編集します。

```:サービスを編集
vi ark-Aberration.service
```

##### ※viコマンドは「i」で編集モード、「Escキー」を押してから「:wq」でファイル保存できます

![service.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3716588/8685c65d-ee39-719f-a2bf-11979b243302.png)


[修正箇所]
ExecStart=/home/steam/.steam/compatibilitytools.d/GE-Proton8-21/proton run ArkAscendedServer.exe **Aberration_WP**?listen~~~~
※大文字部分がMapIDになるのでこちらを以下のMapIDに変更します

```:AberrationのMapID
Aberration_WP
```

編集後に保存し、これでAberration用のサービスができました。

:::note info
他のMAPで遊びたい場合は、こちらのサービスを停止して他MAPのサービスを起動することで遊ぶことができます
:::


# 4.起動サービスの変更

サービスを作っただけでは、再起動すると元々起動しているマップが立ち上がってしまうので、自動起動の設定を変更します。

```:自動起動サービスの確認
systemctl list-unit-files -t service
```
##### ※Ctrl+Cで抜けれます

![unit.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3716588/69ad0892-aaeb-7dde-6b44-3dfae50c11aa.png)

enabled = 起動
disabled = 起動しない

```:サービスの自動起動無効化
systemctl disable 〇〇〇〇.service
```

```:Aberrationサービスの自動起動有効化
systemctl enable ark-Aberration.service
```

最終的に以下のようになっていればOKです
![unit-ok.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3716588/a812f61e-b832-1683-66a0-9653b66d9a64.png)


最後に以下のコマンドでサーバーのサービス起動設定を更新できます。
```:デーモンのリロード
sudo systemctl daemon-reload
```


# 5.動作確認

手動でサーバーを起動して動作確認を行ってください。

```:サーバーを起動する
sudo systemctl start ark-Aberration
```

```:サーバーを再起動する
sudo systemctl restart ark-Aberration
```

```:サーバーを停止する
sudo systemctl stop ark-Aberration
```

# 6.免責事項
:::note alert
本記事からのリンクなどで移動したサイトで提供される情報、サービス等について一切の責任を負いません。

また本記事のコンテンツ・情報について、できる限り正確な情報を提供するように努めておりますが、正確性や安全性を保証するものではありません。情報が古くなっていることもございます。

本記事に掲載された内容によって生じた損害等の一切の責任を負いかねますのでご了承ください。
:::
頑張れFlutter実装

## 目的・背景
今日はFlutterでWindows desktopアプリを作るべく，Flutterの実装のまでを完成としています．なお著者はITエンジニアを目指す．駆け出しの大学生ですので，文法や文章の構成など至らない点があると思いますが，教えていただけると成長できるので，バシバシ指摘していただけると幸いです．炎上だけは勘弁です．以下参考にしたサイトです．
 
 >https://zenn.dev/kazutxt/books/flutter_practice_introduction

 ## 進捗
 ここでは簡単な進め方は上記のとおりです．
- [x] 1\.必要なフォルダ（Flutter,Android Studio, VScode）をインストールする
- [x] 2\.それぞれのフォルダを適切な場所（ほとんど任意だが，Program　Fliesなど管理者権限がある場所においてはならない場所がある）
- [x] 3\.Pathを通す．
- [x] 4\.コマンドパレットで「Flutter:New Project」 >> 「aplication」を選択する．
- [ ] 5\.出現したコードをデバック.　ターミナルで「Flutter run」とするか，ステータスバーにあるdeviceをwindowsに変更して「Ctrl＋Shift＋D」でデバック
## 問題発生
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3807183/45370c1c-3ea4-375b-d62f-2a22fc9c64e0.png)

とりあえずエラーコードは**error MSB8066**であることが分かった．ついでに，
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3807183/5c39e17e-4a9e-e8d3-3ec8-336ce9f23277.png)
ふむふむ，自分で書いてないから何とも言えんが，とりあえず問題と関係ありそうなのは**templeCodeRunnerFlies**が分からないってところかな？（英語無いから見当違いだったら申し訳ありません）とりあえず，[files_names](https://dart.dev/tools/diagnostic-messages)のURLが関係する感じかな．
 ## 結果
 できた！！！
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3807183/eb604222-5961-f450-d817-df60406cedb8.png)
問題はOndriveの同期が問題だと考える．OneDriveからuser直下に新たなフォルダを作成し，その中でビルドしたらできた．
## 下記に行ったことを示す
 ### 前提
flutter doctorなどでビルドは有効化されており，他のブラウザ環境では実装できた．また
```
flutter clean
flutter build windows
```
を実行した結果，windowsのビルドが出来ないことが分かり，windowsのビルドに関係する部分だけが問題があるのではないかと推測した．
 [files_names](https://dart.dev/tools/diagnostic-messages)を踏んだ結果としてあまり関係ないようなことが書かれていた．
 >ファイル名 ファイル名 '{0}' は、lower_case_with_underscores 識別子ではありません。
>説明 アナライザーは，ファイル名に.dartlower_case_with_underscores が使用されていない場合にこの診断を生成します。
>例 ファイルSliderMenu.dart名が UpperCamelCase 規則を使用しているため、この診断が生成されます。

エラーコード：**error MSB8066**について調べた結果．Cmakeをいれてないことが判明，とりあえずインストール．
これでもその後ビルドしたらできなかった．

## 今後の展望
 これからはアプリ開発を通してITエンジニアとしての腕を磨いていこうと思います．次の目標としては，タイピング用のアプリ開発を目標にテストコードや例外処理を勉強した後に本格的な開発を進めていきたいと思います．
 
 この記事が少しでも他の方の役に立つことが出来れば幸いです.
指定したフォルダにあるファイルを再帰的に探索したい

指定したフォルダの配下にあるファイルを再帰的に探索し、ファイルパスの一覧を配列に格納したい場合、たとえば以下のようなサブルーチンを定義すればよいです。

```vb
' 指定したフォルダの配下にあるファイルパスの一覧を取得し、filePaths配列に格納する
' サブフォルダがある場合も再帰的に探索する。
Sub walkFileTree(folderPath As String, ByRef filePaths As Collection)
    Dim FSO, childFile, childFolder
    Set FSO = CreateObject("Scripting.FileSystemObject")
    
    ' 指定したフォルダの直下にファイルがある場合、そのパスをfilePaths配列に格納する
    For Each childFile In FSO.GetFolder(folderPath).Files
        filePaths.Add childFile.Path
    Next childFile
    
    ' 指定したフォルダの直下にフォルダがある場合、そのフォルダを頂点に再帰的に探索を行う
    For Each childFolder In FSO.GetFolder(folderPath).SubFolders
        walkFileTree childFolder.Path, filePaths
    Next childFolder
End Sub
```

使用例です。次のような構成の`C:\START`フォルダがあるとします。

```
C:\>tree start /F
フォルダー パスの一覧:  ボリューム Windows
ボリューム シリアル番号は ACA7-872F です
C:\START
│  a.txt
│
├─dir1
│      b.txt
│      c.txt
│
└─dir2
    │  d.txt
    │
    └─dir3
            e.txt
            f.txt
```

`C:\START`フォルダ配下のファイルパス一覧を再帰的に取得したい場合、`walkFileTree`サブルーチンを以下のように利用します。

```vb
Sub Main()
    Dim folderPath As String
    Dim filePaths As Collection
    
    folderPath = "C:\START"
    Set filePaths = New Collection
    
    Call walkFileTree(folderPath, filePaths)
    
    Dim filePath As Variant
    For Each filePath In filePaths
        Debug.Print filePath
    Next filePath
End Sub
```

実行結果は以下のようになります。

```
C:\start\a.txt
C:\start\dir1\b.txt
C:\start\dir1\c.txt
C:\start\dir2\d.txt
C:\start\dir2\dir3\e.txt
C:\start\dir2\dir3\f.txt
```
Qiita アップデートのお知らせ - 2024年8月

![Qiita アップデートのお知らせ - 2024年8月](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88/2828a1e2-f2a5-ef32-710a-6a31e16136de.png)

## はじめに

Qiitaでは、エンジニアのみなさんからの声をもとに、日々開発を続けています。
この記事では、2024年8月にリリースした内容を紹介します。

Qiitaでアップデートやバグ修正をリリースしたら、[リリースノート](https://qiita.com/release-notes)、[Qiita 公式 Twitter](https://twitter.com/Qiita)、[Qiita Blog](https://blog.qiita.com/)でお知らせしています。

また、Qiitaへの質問や機能の要望などがありましたら、[Qiita Discussions](https://github.com/increments/qiita-discussions) へご投稿ください。

## スクロールバーの色を見やすいように変更しました

![変更前後のエディタのスクリーンショット。スクロールバーの色が変更前は薄いグレーで、変更後は濃いグレーになっている](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88/c10dabb7-1b28-77bf-ffcd-acc6550c8153.png)

2024年8月29日 リリース

スクロールバーの色が背景とのコントラスト比が低く見づらかったため、コントラスト比を高くして見やすくなるようにしました。

## 絵文字パネルが矢印キーで移動できるようにしました

![絵文字パネル内を矢印キーで移動している様子](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88/a888ed5f-7545-8491-1a3d-7a9a5605f127.gif)

2024年8月15日 リリース

絵文字パネルにて、絵文字カテゴリーや絵文字一覧の移動が矢印キーでできるようになりました。

- 絵文字カテゴリーは左右の矢印キーでカテゴリー内の移動ができ、上の矢印キーで絵文字パネルの開閉ボタン、下の矢印キーで絵文字一覧への移動ができます。
- 絵文字一覧は上下左右の矢印キーで移動ができます。
- また、TABキーで絵文字パネルの開閉ボタン、絵文字カテゴリーと絵文字一覧の移動ができます。

## エディタで使えるキーボードショートカットの記事を作成しました

https://qiita.com/Qiita/items/aeb096015934e1905065

Qiitaの記事・質問執筆に役立つ便利なキーボードショートカットをまとめました！
ぜひご活用ください。

## 検索結果ページに検索結果件数の表示を追加しました

![変更前後の検索結果ページのスクリーンショット。変更後は「124件の検索結果 1~20件目を表示中」というテキストが追加されている](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88/beaafbae-6cd4-68e5-776a-b88bbe9690e8.png)

2024年8月15日 リリース

記事・質問の検索結果ページに検索結果件数と現在のページで表示中の件数の表示を追加しました。

## 検索結果一覧の記事カードのアクセシビリティを一部改善しました

![変更前後の記事カードのスクリーンショット。コメントのアイコンの色が変更前は薄いグレーで、変更後は濃いグレーになっている](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88/0b8c0762-63a2-81d2-1d63-b9e60723bafd.png)

2024年8月7日 リリース

コントラスト比が低いアイコンの色をAA基準が達成できるように変更しました。
ユーザーアイコンのリンクに読み上げがなかったため、読み上げを追加しました。

## 記事投稿完了時のモーダルウィンドウにQiitaの機能についての紹介を追加しました

![モーダルウィンドウのスクリーンショット](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88/914c524d-3324-3b8b-2ebe-5f3cda4c2719.png)

2024年8月19日 リリース

記事投稿完了時に表示されるモーダルウィンドウに、Qiitaの機能紹介を追加しました。
興味のある機能があれば、ぜひお試しください！
VBAエキスパート対策となりそうなものリスト

VBAエキスパート対策として何をしたらよいでしょうか？今回はそのヒントとなるものにしました。YouTubeが充実していますのでそれを手本に取り組むとよいと思います。

VBAエキスパート　ベーシック編の教科書はこちら

https://aoten.jp/store/detail.html?c1=%E8%B3%87%E6%A0%BC%E5%AF%BE%E7%AD%96%E6%95%99%E6%9D%90&c2=VBA%E3%82%A8%E3%82%AD%E3%82%B9%E3%83%91%E3%83%BC%E3%83%88&no=a2800i_v190530

【Excel VBAエキスパート・ベーシック試験 合格講座】

https://www.youtube.com/watch?v=rp9ckmnUBKA&list=PLzW25jfHEVP5cEvzoBwL45tuar3ec6MHv


スタンダート編はこちら

https://aoten.jp/store/detail.html?c1=%E8%B3%87%E6%A0%BC%E5%AF%BE%E7%AD%96%E6%95%99%E6%9D%90&c2=VBA%E3%82%A8%E3%82%AD%E3%82%B9%E3%83%91%E3%83%BC%E3%83%88&no=a3000i_v190726


【Excel VBAエキスパート・スタンダード試験 合格講座①】

https://www.youtube.com/watch?v=nsk_Mvdbnqo&list=PLzW25jfHEVP7E8j43ef4JX2HnTbY2VzFo

【VBA講座】

https://www.youtube.com/watch?v=zi4N65IGEvs&list=PLQIkoaSzi9Z9n2cbsvaCd_T4rOflUOQ5G
プログラマーが陥る悪癖とは 

# はじめに
長年、プログラミングをしていても、この悪い癖が時々、出てきます。
どういう状況の時に、出てくるかといいますと、デバックをしているときです。
一応、頭の中で考えている仕様がありますので、それに基づいてプログラミングをします。
そこで、動作確認のため、デバッグを始めます。ここで、エラーが出ます。
ここからです。悪戦苦闘が始まります。
対象としているロジックは、静的な処理ではなく、動的処理です。
特に、イベントリスナーのお化け状態のロジックになるとお手上げです。
今回のロジックは、あるブログにyoutubeの動画を複数埋め込んでいるページが対象です。
行いたいことは、各動画にリピートを追加することです。これは、比較的楽にプログラミングができました。
次に行いたいことが、問題のロジックです。
動画が複数ありますが、それらに対して、ある連携処理を行う時に発生します。
(1)リピート追加後の各動画はすべて一時停止しています。
(2)次に、いずれかの動画を選択して再生ボタンをクリックして再生します。選択した動画は再生できます。
(3)次に、その状態で、他の動画を再生します。この時、前回の再生している動画は、動的(自動)に、一時停止させたいのですが、これが曲者で、中々、一時停止させるプログラミングがうまく行きません。
ここからが、悪戦苦闘のはじまりで、タイトルにもありますが、悪癖が出てきます。
この顛末について、以降で詳述したいと思います。

# 一つの動画のみ再生状態にして、他の動画は一時停止状態にする方法
機能としては、考えやすいのですが、いざ、コード化しようとすると大変難解です。
あるブログに複数の動画を埋め込むことは、ブログの機能を使用すれば楽にできます。ただ、この機能では、上述した機能はついていません。
自動ではできず、手動で再生、一時停止します。
そのため、その機能を自動化しようとして問題にあたっています。
### 現状の実装スペックは
現在の処理方法を示します。
この自動「一時停止」機能を行うためのプラグインを作成しています。
このプラグインのメイン処理は、youtubeの動画プレーヤーの下部にあるコントロールの再生/一時停止ボタンに機能を追加することです。
このボタンはトグルになっています。クリックするたびに再生と一時停止を繰り返します。手動では、問題なく動作します。

今回は、これに、プラグインの機能を使用して、一部を自動化しようとしています。

埋め込みの動画が複数ある場合、それらの連携動作させようとすると途端に難しくなります。ある埋め込み動画から、別の埋め込み動画を操作させる方法として、今テストしている方法は、executeScript()を使用して埋め込み動画プレーヤーのコントロール部を自動操作することです。executeScript()を使うことで、再生/一時停止ボタンをアクセスすることができます。このスクリプトの中で、再生/一時停止ボタンのクリック動作をclick trigger()しています。

このボタンをclick trigger()することはできますが、ここで、一番の問題があります。このボタンはトグルになっています。
そのため、今の状態を見て、再生するか、一時停止するかの判断が必要です。このステータスを見る方法は、
ボタンのオブジェクトを取得して、その中に定義しているプロパティを見ています。

``` background.js
//抜粋(executeScript())
let aa = document.querySelectorAll(".ytp-play-button.ytp-button.ytp-play-button-playlist");
console.log(document.URL);
if(aa[0].ariaLabel.indexOf("一時停止")!==-1){
    alert("一時停止のため、何もしません。 "+a+" "+b);
    console.log("一時停止のため、何もしません。 "+a+" "+b);
    //何もしない。
    //alert("何もしません。"+args);
}else{
    //今のボタンが再生中の時は、     
    //トリガーを実行して、反転して、一時停止にする。
    //このトリガーは、プレーヤー側のボタン処理に対して実行
    alert("ここで、ボタンのclickトリガーを実行 "+a+" "+b);
    console.log("ここで、ボタンのclickトリガーを実行 "+a+" "+b);
    let  ee = jQuery.Event('click');
    $('.ytp-play-button.ytp-button.ytp-play-button-playlist').trigger(ee);
    //return false;
}
```
ここの処理がうまく行けば、問題は解決します。
しかし、いろいろ試行錯誤してもまだ、解決できていません。

ここで、今回の主要テーマである悪癖について記述します。
プログラミングは、仕様に基づいてコーディングして行くことですが、
仕様でも詳細レベルになると、細かいところまでは、中々記述できません。詳細設計書を書く段階では、実際にコード化して落とし込み、デバッグをして動作確認しないと書けない部分が多々あります。
そうなると、詳細設計書が存在しても、コード化してみないと確認できないことが出てきます。

そこからがプログラミングの本領を発揮するところです。
詳細設計書は、あくまでも考え方をドキュメント化したもので、新規にプログラミングして行く場合の指針のようなものです。
開発が終わると納品ドキュメントを作ります。それには動作確認できた結果を詳細設計書として書きますので、正しいかは別として、動作確認できた結果を記述したものです。

プログラマーが陥る悪癖についてですが、それは、つじつま合わせになりやすいということです。どういうことかと言いますと、デバッグをしていると何とか動作させようとして、フラグやスイッチをあっちこっち弄り回して見かけ上は動作するようになることです。
これは、大変な誤りで、後々、大事故につながることもあります。よく、基幹システムでシステムダウンをすることがありますが、おそらく、こまようなことが起こっているのかもしれません。

納期が迫り、何とか納品しなければとの思いで、つじつま合わせで完成させるとおそらくこのようなことが起こるのではと危惧します。

今のプラグインは趣味で、作成しています。つじつま合わせのコードにならないようにと思って作成しています。

# あとがき
まだ、このプラグインは完成していません。なんとか、このスペックを実現させたく、頑張っています。
基本情報技術者試験 合格までにやったこと（勉強期間2か月）

基本情報技術者試験、なんとかぎりぎりの点数で合格する事ができました！
（科目A:640点 科目B:615点）
ぎりぎりの身分で恐縮ですが、備忘録&どなたかの背中を押せればと思い、ここにやったことを残しておきたいと思います。

# 1.筆者について
・フロントエンドエンジニア2年目（コーダーに近い&短時間勤務）
・取得している資格:HTML5プロフェッショナル認定試験 レベル1（去年の夏ごろ取得）
・転職経験多め
・ロースキル
・勉強嫌い
・子持ち主婦

# 2.なぜ資格取得を目指したか？
・少しでも知識をつけて、スキルアップしたい！
・資格手当もらいたい！
・今後の転職に有利になりそう！

# 3.合格までの経緯
2023年9月に試験申し込み⇒勉強開始するも、暗記できる気がしない。面白くない。
地道に学習するも、何度も試験日変更を繰り返してから、挫折。
そのまま翌年6月ぐらいまで、仕事でいっぱいいっぱいとなり、資格どころじゃない。
気づけば、受験期日が2024年9月1日と判明。
しぶしぶ6月末ごろから本腰を入れて、勉強を始める。

# 4.勉強方法の模索と解決策
### 問題① 暗記ができない。
暗記以前に、よく分からないワードばかりで意味が分からん。
とりあえず暗記しないとどうしようもないので、暗記方法を調べることに。
で、たどり着いたYoutubeがこちら↓
<iframe width="100%" height="auto" src="https://www.youtube.com/embed/DDGVsAWgdYc?si=HjW2hPAIVCaq8ZM9" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

この方法がハマり、暗記できる事に、喜びを感じ始めて楽しくなってくる。
このような動画が出していただいて、感謝しきれません！ありがとうございます！

### 問題② まとまった時間が確保できない。
基本情報技術者試験の詳細を確認。
科目A⇒過去問をひたすら解く＝アプリがあるので、隙間時間で解ける。
科目B⇒プログラムの流れ・アルゴリズムの根本を理解する＝まとまった時間が必要。

実際、科目Aは隙間時間で解いて覚えれました！
科目Bは理解できるまで、それなりにまとまった時間（問題にもよりますが、1問につき30分～1時間）が必要です。
考え方として、まとまった時間を確保しよう！と考えるより、事前に計画を立てて『今日は3問絶対やろう！』とした方が無理やりにでもどこかで時間を確保しようと動けました。

★科目Aの過去問対策は[過去問道場](https://www.fe-siken.com/fekakomon.php "過去問道場")がおすすめです！
隙間時間でさくさくでき、アカウント作成してログインすることで、間違った問題のみチェックをつけて復習もできます。

### 問題③ アルゴリズムが辛い。
基本情報試験が新制度になってから、科目Bは必ずアルゴリズム問題を解くことになります。
私自身、アルゴリズムが苦手で大変苦戦したのですが、同じような方は、とりあえず難問は最初から捨てましょう！
捨てた上で、基本問題を確実に解けるように何度もトレースしましょう。
計算間違いなどはやればやるほど勝手に精度が上がると思うので、プログラムをしっかり追えるように、ひたすら解きます。


おすすめの本はこちら↓
# [令和06年 基本情報技術者 パーフェクトラーニング過去問題集](https://www.amazon.co.jp/E4-BB-A4-E5-92-8C07-E5-B9-B4-E5-9F-BA-E6-9C-AC-E6-83-85-E5-A0-B1-E6-8A-80-E8-A1-93-E8-80-85-E3-8/dp/4297144255/ref=dp_ob_title_bk "令和06年 基本情報技術者 パーフェクトラーニング過去問題集")
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/909809/0d036b7f-112e-23ea-f22a-f89ba72e4ef9.png)
科目Aはサブとして、科目Bはがっつりこちらの本にお世話になりました。
コツやポイントがまとまっていて、とても分かりやすく見やすかったです。
★最新のものは、2024年10月2日発売の様です。

分からないな～となった時は、この方のYoutubeがおすすめです↓
# 文系でもわかる! IT勉強会
https://youtube.com/@bun_ai?si=Uzc7Epp8LMg4mAEs

過去問・よく出てくるアルゴリズムの解説を、一から分かりやす～く、かみ砕いて説明してくれています。
大変お世話になりました。ありがとうございます！！

# 5.試験日当日のポイント3つ
### ポイント① 問題の取捨選択
確実に解ける問題から手をつけると、焦らずに済むので、まずは分かる問題を確実に解答していきましょう。
『あとから見直す』的なボタンがあるので、それを活用しました。

### ポイント② 時間配分を考える
科目Bでは、全て解くには確実に時間が足りません。
なので、最初に時間配分を考えて、スムーズにトレースができる問題から手をつけます。
（初見でスムーズにいけそう！と思った問題でも、トレース途中で混乱した問題は後回しにしたりしました。）

### ポイント③ 休憩をしっかり取ろう
科目Aと科目Bの休憩時間は10分です。
科目Aは時間が余りがちなので、時間が余った場合は科目A試験完了ボタンを押さずに、試験時間いっぱいまで席で休憩するのもアリです。

ここまでお読みいただき、ありがとうございました。
よわよわエンジニアから少しでも脱却できるよう、私も引き続き頑張っていきたいと思います！！
[memo] deploy flutter web on Cloudflare Pages by Subdomain

SSGの普及に伴い、牧歌的あるいは原始的なHTMLを我らがインターネットに公開する方法もスマートになりました。

FTP？いやせめてSFTPで！とか言っていた時代は終わったのです！万歳！

## Flutter web のホスティング
```
$ flutter build web
```
↑をするとbuild/webに、すごく懐かしい（思わずFFFTPとかNextFTPとか起動したくなる）感じの構成でHTMLが出力されます。

flutterがどうとかは置いといて、つまりはこのファイルというかディレクトリの中身をなんかで公開すればいいわけです。

いい時代になりました。

とはいえ今は２０００年代、アプリに割り振るアドレスもそれらしくしておきたいものです。

…そう、some.domain/app-name（１９００年代風）ではなく、app-name.some.domain（２０００年代風）で運用したいんです！

## Cloudflare Pages キミにきめた！
（netlifyでもいいけど）

## flutter! 

```
$ flutter create someapp
~
All done!
~
In order to run your application, type:
  $ cd someapp
  $ flutter run
```
```
someapp $ flutter build web
~
✓ Built build/web
```

## wrangler!
CloudflareのCLI、wranglerをインストールします。
globalへのインストールはいつの間にか非推奨になっている？

```
someapp $ pnpm install wrangler --save-dev
~
+ wrangler 3.74.0
```

```
someapp $ pnpm wrangler login
~
```
```
someapp $ pnpm wrangler whoami
~
👋 You are logged in with an OAuth Token, associated with the email ~
~
```

```
$ pnpm wrangler pages project create ~
~
✨ Successfully created the '~' project. It will be available at https://~.pages.dev/ once you create your first deployment.
To deploy a folder of assets, run 'wrangler pages deploy [directory]'.
```

```
$ pnpm wrangler pages deploy build/web --project-name ~
~
✨ Deployment complete! Take a peek over at https://~.~.pages.dev
```

## subdomain!
Cloudflare DashboardのWorkers & Pagesにて、作成したプロジェクトを選択しカスタム（サブ）ドメインを設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3733061/4b1e606a-9451-45d6-622f-1aa530a53a86.png)

## it works!
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3733061/134cbf77-636e-6523-0602-50b0e601d6c0.png)

٩( ''ω'' )و
CSPに関するメモ

# どう設定するか

## レスポンスヘッダーとして設定 (推奨)

CSPはサーバー側でHTTPレスポンスヘッダーとして設定するのが基本です。
この方法では、サーバーからのレスポンスに含まれるCSPヘッダーが、ブラウザに対してそのページに適用されるセキュリティポリシーを伝えます。

```
Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.cdn.com;
```


・全ページに一貫したセキュリティポリシーを適用できる。
・ヘッダーはHTMLのレンダリング前に適用されるため、より早い段階でセキュリティ対策が有効になる。
・ポリシーがサーバー側で集中管理されるため、メンテナンスが容易。
ページの初期ロード時に発生する攻撃を防ぎたい場合は、サーバーヘッダーでの設定が推奨されます。

## HTMLファイル内にタグを埋め込む形で設定
CSPはHTMLファイル内で<meta>タグを使っても設定できます。
この方法は、サーバー設定が難しい場合や、特定のページだけに異なるポリシーを適用したい場合に役立ちます。

```
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' https://trusted.cdn.com;">
```
・特定のページだけに異なるポリシーを設定する場合に便利。
・サーバー設定が難しい場合でも、CSPを導入可能。
・CSPの設定をHTML内の<meta>タグで行うと、ポリシーがHTMLの読み込み後に適用されるため、ヘッダーによる設定に比べるとセキュリティ的には若干劣ることがあります。

# 参考サイト

https://developer.mozilla.org/ja/docs/Web/HTTP/CSP
Reactでのプロパティ値のコールバック関数

## アジェンダ
Reactでのプロパティ値のコールバック関数の書き方について要点だけまとめます。

:::note warn
この後に紹介する3つ目の記法は基本的には避けるべき記法です。
:::


## コールバック関数の書き方
### 1. `<button onClick={onClick}>Click me</button>`

- **説明**: `onClick`イベントハンドラーに直接関数を渡しています。
- **動作**: `onClick`がクリックされると、`onClick`に渡された関数が実行されます。
- **特徴**:
  - 関数を直接渡すので、無駄な再レンダリングが発生しにくい。
  - 関数に引数を渡す必要がない場合に使用されます。

```jsx
function onClick() {
  alert('Button clicked');
}

// JSX
<button onClick={onClick}>Click me</button>
```

### 2. `<button onClick={() => onClick()}>Click me</button>`

- **説明**: アロー関数を使って`onClick`イベントハンドラーを定義しています。
- **動作**: クリックされると、アロー関数が実行され、その中で`onClick`関数が呼び出されます。
- **特徴**:
  - 関数に引数を渡す必要がある場合や、関数をラップしたい場合に使用されます。
  - 再レンダリング時に毎回新しい関数が作成されるため、性能に影響を与える可能性があります。

```jsx
function onClick() {
  alert('Button clicked');
}

// JSX
<button onClick={() => onClick()}>Click me</button>
```

### 3. ❌`<button onClick={onClick()}>Click me</button>`

- **説明**: `onClick`に関数の実行結果を渡しています。
- **動作**: コンポーネントがレンダリングされる際に`onClick`が即座に実行され、その戻り値が`onClick`プロパティに渡されます。
- **特徴**:
  - 関数がクリック時ではなく、レンダリング時に実行されてしまうため、ほとんどの場合意図しない動作になります。
  - イベントハンドラーとして正しく機能しないことが多いため、通常は避けるべき書き方です。

```jsx
function onClick() {
  alert('Button clicked');
}

// JSX (この書き方は通常避けるべきです)
<button onClick={onClick()}>Click me</button>
```

## 結論とまとめ

- **`onClick={onClick}`**: 最もシンプルで性能的にも適しているので、基本的にはこの書き方を使用します。
- **`onClick={() => onClick()}`**: 引数を渡したい場合や、ラップする必要がある場合に使用しますが、パフォーマンスに注意が必要です。
- **`onClick={onClick()}`**: 通常避けるべき書き方であり、イベントハンドラーとしては適していません。
マイナス×マイナスがプラスの値になるワケ

# -(-a)=a の証明
$-(-a)=a$ を示すにはいくつかの前準備が必要である．
### 逆元の一意性

任意の$a$に対して, $a$の逆元はただ一つである.
### 証明
$a$の逆元を$b,c$とする．
```math
b + a = 0, \quad c + a = 0
```
とすると，
```math
b = b + 0 = b + (a + c) = (b + a) + c = 0 + c = c
```
である．

### 系
```math
(-1)a = -a
```

### 証明
```math
(-1)a + a = (-1)a + 1a = ((-1)+1)a = 0a = 0
```
逆元の一意性より, $(-1)a = -a$である.

## 今回の目標
```math
-(-a) = a
```

### 証明
```math
-(-a) + (-a) = -(-a) + (-a) = (-1)(-a) + (-1)a = (-1)(-a + a) = (-1)0 = 0
```
逆元の一意性より, $-(-a) = a$である.