OmniAICreator/Qiita-1.07M huggingface dataset:
kubectlコマンドの実行をエイリアスを使用して検知する方法

#### 作った理由
卒業課題で使用するために```kubectl apply```されたYAMLファイルを取得したかったため，エイリアスを使用してkubectlコマンドの実行を検知する必要があったので作りました

### Kubernetesとkubectl
- Kubernetesとは
    - コンテナ化されたアプリケーションを管理するシステム
- kubectlとは
    - Kubernetesクラスターを制御するためのコマンドライン


### Alias(エイリアス)
- エイリアスとは
    - ファイルやコマンドに別の名前を付け実行できるようにすること


## kubectlコマンドを検知する方法
1. シェルファイルを作成する
    - このシェルファイルでは，kubectlコマンドの実行とkubectlコマンドを検知して行いたい動作を書きます
    - シェルファイル(kubectl-detect.sh)
        ```
        #!/bin/bash
        
        # 実際の kubectl コマンドを実行
        /usr/local/bin/kubectl "$@"

        # 行いたい動作
        cat /hoge.txt
        ```
        - この記事では，kubectlコマンドを検知して行いたい動作として```/hoge.txt```に記載されている内容(hoge)をターミナルに表示します


1. エイリアスを設定する
    - kubectlコマンドが実行されると先ほど作成したシェルファイルが実行されるエイリアスを設定する
    - ```/etc/profile```にエイリアスを書き込みます
        - ```sudo vim /etc/profile```でファイルを開きます
            - ```sudo```が無いと書き込み権限がありません
        - ```alias kubectl='{シェルファイルを置いた場所のパス}'```を最後に書き込んでください
            - シェルファイルを置いた場所のパスは，シェルファイルを置いた場所で```pwd```を実行するとその場所の絶対パスが表示されるので，そのパスの後ろに```/kubectl-detect.sh```と付けえ加えたものです
    - エイリアスを書き込んだら一度VMからログアウトして，ログインし直してください
        - ログインし直すことで先ほど書き込んだエイリアスが反映されます


1. 最後に確認
    - 例：```kubectl get pod``` が実行されたときのターミナル表示
      ```
      No resources found in default namespace.
      hoge
      ```
      - ```No resources found in default namespace.``` はpodが無いときに表示される
      - ```hoge``` は先ほど作成したシェルファイルが実行され，```cat /hoge.txt```が実行されたことで表示された


1. kubectlコマンドの実行の検知を辞めたい場合
    - ```/etc/profile```に書き込んだエイリアスをコメントアウトするか削除してください
    - VMをログアウトしてログインし直すと先ほどコメントアウト（削除）したエイリアスは動作しないため，kubectlコマンドの実行を検知できなくなります
chart.js v2の凡例

通常凡例はdatasetのlabelで設定された文字列が使用されます。これはグラフの中のポップアップでも使われます。

これらを別々に設定したい場合以下のような方法があります。

まずdatasetをconfigの中で定義します。

そしてoptions.legendを以下のようにします。

```javascript
          legend: {
            labels: {
              generateLabels: function(chart) {
                labels = Chart.defaults.global.legend.labels.generateLabels(chart)
;
                labels[0].text = data.label[0] + ' average: ' + String(Math.round(ave * 10) / 10);
                return labels;
              }
            }
          },
```

これで、datasetのlabelを空にすると、こんな風になります。

![chartjs_leg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/915bc42e-b35e-bf86-7561-890cc0e0db08.png)

系列が一つの時はポップアップのlabelはじゃまです。

datasetを後からpushするとうまくできませんでした。

chart.jsはバージョン間の互換がないので、他のバージョンではやり方が違うと思われます。
GitHubの個人アカウントが所有しているリポジトリを移譲する

# はじめに
リポジトリを別の組織に移す機会があったので、その際に実施した内容を整理してみました。

# 前提
以下については事前に用意済みで話は進めます。
- GitHubアカウント
- 移譲用リポジトリ
- 移譲先組織への参加

# リポジトリの移譲
1. 対象のリポジトリを選択し `[Setting]` をクリックします。
![スクリーンショット 2024-10-23 13.11.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82090/9ebccddd-15a9-9641-ccfc-bcc2ee989189.png)

2. ページ下部にある **Danger Zone** のセクションで `[Transfer]` をクリックします。
![スクリーンショット 2024-10-23 13.11.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82090/5d97abfa-a05e-fb38-9290-43232e1b8410.png)

3. Transfer 設定画面になるため **New owner** の **Select one of my organizations** を選び、リストから移譲先となる組織を選択します。
また、**Repository name** で移譲後のリポジトリ名を変更することができます。
内容に問題なければ、**Type アカウント名/リポジトリ名 to cofirm.** に `アカウント名/リポジトリ名` を入力し、`[I understand, transfer this repository.]` をクリックします。
![スクリーンショット 2024-10-23 13.13.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82090/44582a67-2548-2041-a5e4-0017f5a359f4.png)

4. 移譲先で *Team* 運用がされている場合は **Team access** という画面が表示されるので適用させたい項目にチェックを入れ `[Transfer]` をクリックします。
![スクリーンショット 2024-10-23 13.13.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82090/667889d1-d83d-3ec0-07b7-f0ab76ddcf87.png)

5. 移譲が完了すると **Moving repository to アカウント名/リポジトリ名. This may take a few minutes.** と表示されます。
![スクリーンショット 2024-10-23 13.14.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82090/5de84ed0-63e4-d764-31d9-d29d08d7bd25.png)

# 確認
- 移譲先でリポジトリを検索すると、先ほど自分のアカウントにあったリポジトリが移譲されているのが確認できます。
![スクリーンショット 2024-10-23 13.15.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82090/8c6b233a-080f-dc67-2cd1-4c269fd54e2b.png)

# 備考
組織から個人アカウントまたは他の組織アカウントへリポジトリを移譲させたい場合も同様の手順で行えます。
ただし、その際は **組織アカウントのオーナー権限** または **対象リポジトリの管理者権限** を有している必要があります。

# おわりに
リポジトリの移譲を行う際に、こんな簡単にできるとは思わなかったので知って良かったです。
あまり移譲する機会はないため知らない人も多いと思います。
ただ、移譲したいという要望が出た際に、知っているだけでその後の話がスムーズに進むのではと感じました。

### 参考
https://docs.github.com/ja/repositories/creating-and-managing-repositories/transferring-a-repository
Microsoft Storeからインストールしたアプリがスタートアップに設定できない

スタートアップ画面に、インストールされているアプリの一覧が表示されます。Microsoft Storeからインストールしたアプリもここに含まれています。　こちらは表示されませんでした。代替方法も「詳細」→「ファイルの場所を開く」は表示されませんでした。

Microsoft Storeからインストールしたアプリがスタートアップ設定画面に表示されない場合、以下の代替方法を試すことができます:
タスクスケジューラを使用する方法
Windowsキー + Rを押して「ファイル名を指定して実行」を開きます。
「taskschd.msc」と入力してEnterを押し、タスクスケジューラを起動します。
左側のペインで「タスクスケジューラライブラリ」を展開します。
「新しいタスクの作成」を右クリックして選択します。
「全般」タブで、タスクの名前を入力し、「最上位の特権で実行する」にチェックを入れます。
「トリガー」タブで「新規」をクリックし、「ログオン時」を選択します。
「操作」タブで「新規」をクリックし、「プログラムの開始」を選択します。
「プログラム/スクリプト」欄に以下のコマンドを入力します:
text
```
explorer.exe shell:AppsFolder\{パッケージファミリー名}!App
```

※{パッケージファミリー名}の部分は、実際のアプリのパッケージファミリー名に置き換えてください。
「OK」をクリックして設定を保存します。
パッケージファミリー名の確認方法
PowerShellを管理者権限で開きます。
以下のコマンドを実行して、インストールされているアプリの一覧を表示します:
powershell
```
Get-AppxPackage | Select Name, PackageFamilyName
```

目的のアプリのPackageFamilyNameを確認し、上記のタスクスケジューラの設定で使用します。
注意点
この方法は、通常のスタートアップ設定よりも高度な設定が必要です。
システムへの影響を考慮し、必要最小限のアプリのみをスタートアップに追加することをお勧めします。
タスクスケジューラの設定を誤ると、システムの動作に影響を与える可能性があるため、慎重に操作してください。
これらの手順を試してみても問題が解決しない場合は、Microsoftのサポートに問い合わせるか、Windows 11の最新のアップデートを確認することをお勧めします。
FIrebase の Google 認証で OAuth 2.0 クライアント ID を再作成方法

:::note info
この記事は、Firebase の Google 認証を使っている人で OAuth2.0 の認証情報を再作成したい人のための記事です。
( OAuth2.0 の復元ではなく、再度 OAuth2.0 の認証情報を作成したい人が対象です。)
自分のための備忘録なので、画像がありません。
予めご了承ください。
:::

# 解決法
1\. **古い OAuth2.0** の認証情報が残っていて、もう使わない場合は**削除**しておきます。

2\. **Firebase Authentication** の **Google 認証**のプロバイダを**削除**します。
(「無効」ではなく「削除」なので、間違えないように気を付けてください。)

3\. **Firebase Authentication** の **Google 認証**の**新しいプロバイダを追加**から Google 認証を追加します。

4\. **自動で OAuth2.0 の Google 認証用の クライアント ID が追加**されます。

:::note info
ここから先は、**誤ったアプローチ**の備忘録なので、興味のない方は**読む必要がありません**。
:::

# 誤ったアプローチ
1\. **手動で OAuth2.0 の認証情報を作成**する。

2\. **Firebase Authentication** の **Google 認証の「ウェブ SDK 構成」を編集**する。

3\. 保存を押すと**エラー**になる。

# まとめ
編集ができそうになっているので、手動で登録ができそうだが、現在のところ登録できないようです。
Google 認証のプロバイダを削除しても、Firebase Authentication のユーザ情報は残っているようなので、現在の仕様ならばプロバイダを削除して、再度追加しても大きな問題はないと思われる。
しかし、ミスが許されない環境の場合は、GoogleCloudConsole の OAuth2.0 の認証情報を復元し設定を見直すほうがいいかもしれない。
AWS Lambdaのコンソール画面が大きく変わったので試してみた。

AWSが代表するサーバレスサービスであるAWS Lambdaの画面が大きく変わり独自のエディタからVSAWSが代表するサーバレスサービスであるAWS Lambdaの画面が大きく変わり独自のエディタから慣れ親しんだVisual Studio Code(VScode)のようなUIに変わったようなので早速試してみました。


# Lambda作成
まずはLambdaの作成です。
![スクリーンショット 2024-10-23 230714.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/616483/18422278-6e09-de4a-d13f-5785233c51d5.png)
「関数の作成」からリソースを作っていきます。
![スクリーンショット 2024-10-23 234208.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/616483/4db43cad-8d52-1e9c-6448-97f53e550386.png)
![スクリーンショット 2024-10-23 234228.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/616483/153c1f1d-1ba9-b314-b678-28e367344e5e.png)


今回はテスト用なのでサンプルコード(設計図)を使います。

言語やサンプルはなんでもいいですが、シンプルにPythonのHello World functionを選びました。
IAMロールはCloudWatch Logsへのログ出力権限用のため、ロググループ作成とログの書き込み権限があれば既存のロールでも大丈夫です。
今回は新規に作成しています。
![スクリーンショット 2024-10-23 234259.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/616483/38a758e8-9aa4-9075-6590-5214fb5d81fb.png)
上記ができた関数です。
さっそくエディタがVScodeのようになっており、違和感があるようで無いです。

![スクリーンショット 2024-10-23 234436.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/616483/c7be2f4d-79fe-7f8c-3e75-aa125543ac40.png)
ちなみに旧コンソールへの切り替え、切り戻しも可能です。




# 色々と試してみる
早速触っていきましょう。
ちなみにエディタが小さい場合はF11キー等で全画面表示にすることができます。

![スクリーンショット 2024-10-23 235337.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/616483/c4531adc-044d-e123-4a88-3a3c16bf6251.png)
こちらなんと今話題のAmazon Q Developerが搭載されているので、修正時にコードの提案をしてくれます。
タブキーを押すことで、提案されたコードを記載することができ、またコメントで指示を出すこともできます。

こちら無効化したい場合はEscキーで無効化できます。
再度有効化したい場合は左下のAmazon Qの文字列をクリックすることで再度有効化できます。


![スクリーンショット 2024-10-23 235406.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/616483/0a712929-c8fe-b34f-8110-f560dc848d47.png)
また、左ペインにもある通り、TestDeployもしやすくなっています。
Testをクリックすることで、別タブでテストを作成することができます。
また、関数の修正後、Deployボタンをクリックすることでそのままデプロイも可能です。

![スクリーンショット 2024-10-23 235444.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/616483/963d8777-f106-3783-bddb-94668af70114.png)
また、デバック機能では修正した関数をそのまま、SAM Build,SAM Deployに必要なファイル一式ローカルにダウンロードすることができます。
残念ながら拡張機能は追加できないため、そのままGitにプッシュができないですが、ローカルに更新したファイルを持ってきてGitに上げることが可能です。


![スクリーンショット 2024-10-24 001406.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/616483/33bb187a-b141-01e3-babf-072b5b7484ff.png)

また、先日公開されたCloudWatch Logs Live Tailにもしっかり対応しています。
こちらはLambdaの実行後、ログをCloudWatch Logsにわざわざ切り替えずともTailコマンドでログを見るかのようにログを確認できます。


CloudWatch Logs Live Tailについてはこちらの情報も併せて参考にしてみてください。
https://aws.amazon.com/jp/about-aws/whats-new/2024/10/aws-lambda-console-real-time-analytics-amazon-cloudwatch/

# 最後に
そのほか今回試せてない機能としてダークモードなどにエディタを切り替えるなど自分好みに色々と設定をすることができます。
以下の記事にもその方法がありますので参考にしてください。
https://aws.amazon.com/jp/blogs/compute/introducing-an-enhanced-in-console-editing-experience-for-aws-lambda/


以上、AWS Lambda のコンソールの変更についてでした。
個人的にLambdaの画面での修正がしやすくなったので、コンソールでがちゃがちゃ触るときにすごく便利なアップデートでした。
oss-licensesを使用してOSSライセンスを表記する

## はじめに
* Androidアプリ開発の際にOSSライセンス表記が必要になる場合がある
* 自動で表示をしてくれるAPIをGoogle公式が提供してくれているため試す
  * [オープンソースの通知を含める](https://developers.google.com/android/guides/opensource?hl=ja)

## 対象者
この記事の対象者

- Androidアプリ開発初学者

## 最低限で実装してみる

### gradle
``` gradle:build.gradle.kts 
buildscript {
  repositories {
    ...
    google()  // maven { url("https://maven.google.com") } for Gradle <= 3
  }
  dependencies {
    ...
    classpath("com.google.android.gms:oss-licenses-plugin:0.10.6")
  }
  plugins {
    id("com.android.application")
    id("com.google.android.gms.oss-licenses-plugin")
  }
}
```

``` gradle:app/build.gradle.kts

dependencies {
    implementation("com.google.android.gms:play-services-oss-licenses:17.0.1")
}
```
### ソース

* 最低限、下記の実装で一覧表示してくれる
``` kotlin
fun startOssLicensesMenuActivity(context: Context) {
    val intent = Intent(context, OssLicensesMenuActivity::class.java)
    context.startActivity(intent)
}
```

* リリースビルドの場合
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491949/ccd2b537-60b3-2051-850c-4107facf98ba.png" width="30%">

* デバッグビルドでは一覧は表示されなかった
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491949/e9f63d2e-4aa9-e06e-3401-284792e7cfaa.png" width="30%">

## おわりに
* カスタマイズ方法やOSS ライセンス一覧のデータをパースする方法があるようなので、調べ次第追記していく

## 参考記事
* [オープンソースの通知を含める](https://developers.google.com/android/guides/opensource?hl=ja#kotlin-dsl)
TCP/IPの基礎知識

TCP/IPについて、いろいろ忘れていることが多かったのでその復習。

# 想定する読者層

- TCP/IPとかよく分からないけど、ざっくりと知っときたい人

# 01. 4つの階層があるよ

TCP/IPプロトコルは4つの階層でできています。

- アプリケーション層
- トランスポート層
- インターネット層
- ネットワークインターフェース層

# 02. データの流れ

## 送信側

1. **アプリケーション層**のプロトコルがデータを処理して、**トランスポート層**にパスッ！
2. **トランスポート層**ではデータを分割して、「受信側の**トランスポート層**」で必要なヘッダ情報を追加して**パケット**を作成
3. **トランスポート層**から**インターネット層**へパスッ
4. (今こんな感じ)インターネット層が受け取ったデータ
    「データ + ヘッダ = パケット」 
5. 「受信側の**インターネット層**」で必要なヘッダ情報を追加して**パケット**を作成
6. ここまでの流れを**カプセル化**という
7. **インターネット層**から**ネットワークインターネット層**にパスッ
8. 同様に**ヘッダ**と**トレーラ**を追加して、データを送信

## 受信側

送信側の逆の手順！
送信側と受信側のどちらも同じ階層のプロトコルが処理する。

# 03. アプリケーション層の役割

ユーザーにサービスを提供するよ

- HTTPプロトコル...ウェブサービス
- SMTPプロトコル...メール送信
- POP3プロトコル...メール受信

# 04. トランスポート層の役割

送信側から受信側までのデータのやり取りを制御

- TCP
- UDP

## TCP

ほとんどがこれ。
送信側と受信側で「送ったよ」「来たよ」って連絡を取り合う**コネクション型**

送信側ではパケットに**シーケンス番号**を付けるので、届く順番が変わっても大丈夫

## UDP

パケットは送りっぱなし。届いたかどうかは分からない。
ただし、**速いっ**
動画配信サービスなどで使われるよ

# 05. インターネット層の役割

送信側から受信側まで、どのような道筋（プロトコル）を使うかを決める。
**IPプロトコル**が属する。

1. ネットワークにあるコンピュータや機器を特定するために**IPアドレス**がある
2. IPプロトコルの作るパケットのヘッダには「最後に受信するコンピュータや機器のIPアドレス」が入ってる
3. パケットを受け取ったコンピュータや機器はそのヘッダをみて、「自分宛てか」「どこに回したらいいのか」を判断する
4. これを**ルーティング**という

# 06. ネットワークインターフェイス層

物理的な決まり事
- ケーブルや端子の形状
- 電気信号の形式
- イーサネット
- PPP...コンピュータの1対1の通信

ネットワークインターフェイス層でも識別番号を使う。
イーサネットでは**MACアドレス**を使う。

---
参考
- 増田若菜・根本佳子,図解サーバー仕事でつかえる基本の知識,技術評論社,2018
【Google広告】 最適化案の自動適用とは

# Google広告の最適化案
こんにちは、所属企業で広告運用を担当している鈴木です。

Google広告を運用していると、管理画面上に「最適化案」が表示されると思います。

各キャンペーンで効果的だと判断された改善案が表示されるこのサポート機能ですが、
様々な案が表示されるため、確認に時間を取られてしまう・・と感じている方も多いのではないでしょうか？

そんなときに便利なのが、最適化案の「自動適用」です。

## 最適化案の自動適用

![スクリーンショット 2024-10-16 115742.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780649/02e29235-0d5b-3ac0-da75-81a93a8bb7cd.png)
「最適化案」は、Google広告管理画面にログイン後、左メニュー「キャンペーン」から表示します。

このページの右上に存在するのが「自動適用」です。

![スクリーンショット 2024-10-16 120255.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3780649/bf85117c-8669-e60c-1dcc-54997af30005.png)
「広告のパフォーマンスを維持する」ための8種類と、「ビジネスを拡大する」ための14種類の最適化案の中から、
自動で適用したいものを選び、チェックを入れ保存します。

こうすることで、各項目で利用できる最適化案がある場合、常に自動で適用されるようになります。

### まとめ
最適化案の自動適用は、成果向上と工数削減に役立つ機能です。

ただ、使い方を間違えると予期せぬ広告配信が行われる結果になったり、パフォーマンス低下の原因になったりと
悪影響を及ぼす可能性もあります。

配信の方針に沿った適切な使い方で、運用効率UPを目指してみてください。

以上、鈴木でした。
Git BASHでPythonの再インストール（Microsoft Store版をやめます）

## はじめに

Git BASHで開発環境を管理してみたい人向けです。

Microsoft StoreでインストールされるPythonは、設定パスが長く使いづらく、また最新版等が利用できません。ここでは、Pythonオフィシャルサイトのインストーラでインストールする方法を解説します。

## Pythonの（再）インストール

まず、Microosft ストアからPythonがインストールされている方はUninstallをしましょう。とても長いパスを利用しており、どこにインストールされるか不透明で利用しにくいです。このままでという人は無視しくください。

```bash 
# Windows Menu -> Settings -> Installed Apps -> Python 3.xx -> Uninstallを選ぶ
```
Pythonサイトから最新版をダウンロードし、インストールします。

https://www.python.org/downloads/windows/

Pyton.exeをPATHに設定をチェックして、ディフォルトパスにインストールします。

終了時にインストール場所を確認しておきます。おそらく以下のようなパスを表示されるはずです。

```bash
# C:\Users\UserName\AppData\Local\Programs\Python\PythonVersionNumber
```
## .bashrcの設定
以下の設定を.bashrcに書き込んください。Windowsの場合は、.bashrcは/C/Users/YourName/の下に作成できますので、bashrcが存在しない場合は、新規に作成してください。

```bash
alias python='winpty python.exe'
export PATH="$PATH:/c/Users/YourUsername/AppData/Local/Programs/Python/Python311"
export PATH="$PATH:/c/Users/YourUsername/AppData/Local/Programs/Python/Python311/Scripts"
``` 
Git BASHを立ち上げて、Pythonを実行します。
```bash
python --version
```
実行できるはずです。

ただし、Pythonのインタラクティブの実行は、-iをつけて実行してください。
```bash
python -i
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283070/5b87836a-ebcb-1c0b-be5a-b8a30b6e8aa9.png)

今回は以上になります。

Happy Hacking!!!
Railsで学ぶ依存性注入（DI）！なぜDIが開発効率を劇的に向上させるのか？

## はじめに
**依存性注入**（DI: Dependency Injection）という言葉を聞いたことはあるでしょうか？ソフトウェア開発において、オブジェクト同士の依存関係を解消し、柔軟で拡張性の高いコードを書くための手法として注目されています。特に、Ruby on Railsのようなフレームワークでも、このDIの考え方を取り入れることで、テストのしやすさやコードの保守性が格段に向上します。

この記事では、DIとは何か、そしてRailsでの実践方法についてわかりやすく解説していきます。まずは依存性注入の基本的な概念を押さえ、Railsでどのように活用できるのかを見ていきましょう。

## 依存性注入（DI）とは？
**依存性注入**（DI）は、オブジェクトが内部で依存する他のオブジェクトを外部から注入（渡す）する仕組みです。通常、クラス内で依存するオブジェクトを生成する場合、そのクラスと依存オブジェクトが強く結びついてしまうため、コードの変更がしにくく、テストもしづらくなります。

### 例: 依存性が結びついたコード
```ruby
class PaymentProcessor
  def initialize
    @gateway = StripeGateway.new
  end

  def process_payment(amount)
    @gateway.charge(amount)
  end
end
```
このコードでは、`PaymentProcessor`が`StripeGateway`に強く依存しており、他の決済サービスに変更する際にコードの修正が必要です。また、テスト時に`StripeGateway`をモックに差し替えることが難しくなります。

### 依存性注入を使った例
```ruby
class PaymentProcessor
  def initialize(gateway)
    @gateway = gateway
  end

  def process_payment(amount)
    @gateway.charge(amount)
  end
end
```
このように、`StripeGateway`のインスタンスを外部から渡すことで、`PaymentProcessor`は特定の実装に依存しなくなり、どのゲートウェイでも使えるようになります。これにより、柔軟に他の決済サービスを注入したり、テストでモックを使用することが容易になります。

## Railsにおける依存性注入
Railsでは、コントローラーやモデルが主に依存性を持ちますが、これらにDIの考え方を取り入れると、より柔軟な設計が可能になります。特に、サービスクラスを導入した設計では、DIを使うことでコードの再利用性とテスト容易性が高まります。

### 例: RailsのサービスクラスにDIを適用
たとえば、支払い処理を行うサービスクラスを作成し、その中で依存性注入を利用してみましょう。

```ruby
# app/services/payment_service.rb
class PaymentService
  def initialize(gateway = StripeGateway.new)
    @gateway = gateway
  end

  def process(amount)
    @gateway.charge(amount)
  end
end
```
上記の`PaymentService`では、デフォルトで`StripeGateway`を使用していますが、外部から異なるゲートウェイを渡すことができます。これにより、テスト時にはモックを注入したり、異なる決済サービスに簡単に切り替えたりすることができます。

### コントローラーでの利用
```ruby
# app/controllers/payments_controller.rb
class PaymentsController < ApplicationController
  def create
    payment_service = PaymentService.new
    payment_service.process(params[:amount])
    redirect_to success_path
  end
end
```
## Railsで依存性注入を活用するメリット
### 1. テストのしやすさ

- モックやスタブを注入できるので、依存する外部サービスに依存せず、ユニットテストが簡単に行えます。
### 2. コードの再利用性が向上

- 特定の実装に依存しないため、柔軟に機能の切り替えが可能です。たとえば、支払いゲートウェイをStripeからPayPalに切り替える際も、サービスクラス内での注入のみで対応できます。

### 3. 変更に強い設計

- 新しい要件や変更があった際に、依存するオブジェクトを注入するだけで簡単に対応できるため、変更に強い設計が可能です。

## まとめ
**依存性注入**（DI）は、コードの柔軟性とテスト容易性を高めるために有効な設計手法です。Railsでは、サービスクラスやコントローラーにDIの考え方を取り入れることで、変更に強い設計が実現できます。

Railsアプリの保守性や拡張性を向上させるために、ぜひ**依存性注入**を実践してみてください！
道路OSMデータの位置正確性を調べる方法（道半ば）

こんにちは
道路のOSMデータの位置正確性を調べたいと考えました。

しかし、難度が高く、方法論も不明です。したがって今回は、手っ取り早く、日本の高速道路（highway=motorway）だけについて polyline の各頂点角を全て計算し、補角が一定以上の点を抽出しました。安易ですが、線形が滑らかのはずの高速道路ですから、位置正確性が劣っていれば検出されるだろうと思います。

処理結果例として、補角14度以上の点を地図上に表示させました（関東甲信越東海地方には無いようです）。

![mini1729706757.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54617/8b7a61bf-1499-2580-fb5c-19dca7f15831.jpeg)
AWS環境下でのログ基盤の構築

初めて情報発信をするので、拙い箇所が多々あるかと思いますがご容赦ください。

AWS環境下でのログ基盤について考える機会があったので、備忘も兼ねて記事にします。

## 前提
* AWS環境
* ECS使用
* アプリケーションログの収集（アクセスログ、監査ログまでは取らない）


## 簡単な構成図（基本的なもの）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3917787/72fbb802-c5ff-a151-62cf-215a4e3f0722.png)

## 詳細
さっと作った構成図になりますが、一番手っ取り早くコストも抑えることができる選択肢の一つと考えています。
　
サイドカーコンテナとしてfluent bitを用いた構成であり、
ECSのタスク定義からログの出力先をfluent bitに指定し、fluent bitからS3へログ出力
その後S3のデータを元にGlueデータカタログを作成しAthenaから参照できるようになる

Firelensの設定値については割愛します。（そんな難しいものでもないので安心してください）

S3にはパーティション射影を用います。
これはAthenaの検索結果の高速化、ならびにコストを抑えるために用います。

※パーティション射影はS3のディレクトリを自動的にパーティション分けしてくれる便利な機能と思ってください
例）year=2024/month=10/day=23/hour=00 みたいなHive形式でS3出力するときに勝手にパーティション分けしてくれる

これでログの内容をAthenaから参照することはできる、はず

---

とは言ってもdev/staging/prodでAWSアカウントを分けていることが多いと思われますので、そういった場合に1つの案として下記提示しておきます。

※検証等していない頭の中で考えたものなので、うまく行かなかった場合の責任は取れません。

## 構成図（クロスアカウントでのログ基盤想定）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3917787/c437a865-c946-ef0b-1927-1bc7f9317134.png)

記載していませんが、Staging/prod共にECSからS3へのログ出力があると思ってください。

## 詳細

これはGlueデータカタログの共有を用いた方法を使って、DevアカウントからStag/Prodアカウントのログを見られる構成になります。

多分、S3のクロスアカウントを用いることでDevアカウントがstaging/prodのS3を元にしてデータカタログを作ることも可能だと思います。

個人的に環境による差異をできるだけ生み出したくないので、深掘りはしません…
（今回でいうとデータカタログがDevにだけあるけど、他には無いという状態）


### メリット
* 逐一アカウントを切り替える必要がない
* Staging/prodアカウントにアクセスする権限は渡したくないけど、ログは見られるようにしたい場合

### デメリット
* ログに見てほしくない内容が出力されている場合は運用を更に考える必要がある
（そんな内容ログに出すなとは思いますが）

---

以上、簡単なログ基盤を作ることがあったので気分転換として記載させていただきました。

ざっくりとしか書いてないので、ツッコミどころはあると思いますがあくまでこんなもんもあるんだなと思ってもらえると助かります。

余談ではありますが、CloudWatchLogsに一度吐き出してからDataFirehoseを用いてS3に転送する方法はコストがバカ高くなるのでオススメしません。
p5.js の WEBGLモードで深度バッファ（ depth buffer ）を無効にするための処理とその周辺情報

## はじめに
自分の場合、「ごく稀に使う内容」に関して、「使うたびにやり方を忘れて検索をしている気がする内容」がいくつかある感じがしています。
そのような事例の 1つに入るのが、今回の記事のタイトルに書いている「p5.js での深度バッファ無効化」の話です。

そろそろメモを作って参照できるようにしておくのが良さそうな感じになってきたので、記事として書きとめておこうと思います。

### 記事でメインとなる内容
メインとなる処理内容は、以下に記載している、たった 1行だけの内容です。

```javascript
  setAttributes("depth", false);
```

p5.js のキャンバスを `createCanvas(..., ..., WEBGL)` というように WEBGLモードで作成して、その後に使います。

内容としては、以下で書かれている深度値を格納するための専用のバッファです。

●wgld.org | WebGL: 深度値と座標系について理解する |
　https://wgld.org/d/webgl/w069.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/651823be-28b2-c4fc-39aa-4be0a8ffe2c6.png)

また、深度値を使って行われている内容については、以下の「深度テスト」を見てみると良いかもしれません。

●WebGL 2.0 - ANY_SAMPLES_PASSED応用編 - オクルージョンクエリで衝突判定を行う（その1） - ICS MEDIA
　https://ics.media/web3d-maniacs/webgl2_occlusion_query_collision_detection_1/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/bb9152b8-adb6-54f5-b084-373693987d8e.png)

大まかに関連する内容（や、その情報の参照先の例）を書くと上記のとおりなのですが、さらに関連する p5.js公式の情報も合わせてメモしておこうと思います。

## p5.js の「setAttributes」
上で書いた処理では「setAttributes」を使っています。
これに関する説明として、以下の p5.js公式のページに記載の内容があります。

●setAttributes
　https://p5js.org/es/reference/p5/setAttributes/
 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/45944499-5bef-3112-35a0-356ae0de2702.png)

冒頭の内容では「depth」の「true/false」を設定していました。
「depth」以外にも、setAttributes で設定可能な内容が、この公式ページに複数書かれています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/f2406a43-c936-5b18-5880-6022f6623bcc.png)

### 説明の機械翻訳版
上記の setAttributes で設定可能な内容について、機械翻訳版の日本語説明を以下に記載してみます。

- alpha - キャンバスにアルファバッファが含まれているかを示します。デフォルトはtrueです。
- depth - 描画バッファが少なくとも16ビットのデプスバッファを持っているかを示します。デフォルトはtrueです。
- stencil - 描画バッファが少なくとも8ビットのステンシルバッファを持っているかを示します。
- antialias - アンチエイリアスを行うかどうかを示します。デフォルトはfalseです（Safariではtrue）。
- premultipliedAlpha - ページの合成機能が、描画バッファにプリマルチプライドアルファを含む色があると仮定するかを示します。デフォルトはtrueです。
- preserveDrawingBuffer - trueの場合、バッファはクリアされず、クリアまたは上書きされるまでその値を保持します（p5ではdrawループ中に自動でクリアされることに注意）。デフォルトはtrueです。
- perPixelLighting - trueの場合、ライティングシェーダーでピクセル単位のライティングが使用されます。そうでない場合、頂点単位のライティングが使用されます。デフォルトはtrueです。
- version - WebGLのバージョン1または2を指定します。デフォルトではWebGL 2が要求されます。WebGL 2が利用できない場合、WebGL 1にフォールバックされます。使用されているバージョンはグローバルなwebglVersionプロパティを確認することで確認できます。

これらの内容を、setAttributes で扱えるようです。

上記のとおり、version以外は ture/false で指定する内容で、デフォルト値がどちらになるかは、上に書いてあるとおりです。

また、他の情報源で日本語で書いてあるものも掲載してみます。

●WebGL リファレンス.md
　https://gist.github.com/gyohk/afe4d0f6a0a69a329d4e178ced77eecb

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/7a9a5941-95b3-fc00-3962-bb0c0c45e677.png)

今のところ、p5.js の WEBGLモードで上記の設定を変えたい場合があるのは、この記事でメインで扱っている深度バッファ（ depth buffer ）のみで、他のものは利用するか分からない状況です。
ただ他のものも、そもそもどういった内容なのかといったあたりは、機会があれば情報を見てみられればと思いました。
【初心者】Git BashでLinuxコマンドに慣れたい

# 1. コマンドに慣れたい
・タイトルの通りです。linuxのコマンドに慣れていくにはとにかく使い倒して自然で覚えていくのが一番良いということで、そういった環境づくりを行おうと考えました。
・私は普段使いのpcがwindowsなので、普通に生活していたら意図的に触る機会がないので何か良い方法はないかなとなんとなく考えていた所、XのフォロワーさんにGit Bashを使えばlinuxのコマンドを使うことができるということを知ったので、早速試そうと触ってみました。
・Git Bash自体は元々Githubってなんだろ～みたいなことを思っていた時にインストールしていました。その時はそんなに色々できるものだとは思っていませんでした。

# 2.軽く触ってみる
・とりあえずスタートアップアプリにぶちこんで、毎回勝手に起動するように。

### ・cd
```bash
Owner@Owner-PC MINGW64 ~
$ cd desktop/

Owner@Owner-PC MINGW64 ~/desktop
```
しっかり移動できてそう。しかしこれはコマンドプロンプトでも同様ですね。
### ・touch
```
Owner@Owner-PC MINGW64 ~/desktop
$ touch test
```
![スクリーンショット 2024-10-23 234426.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3902112/5269e73b-fe90-f8ac-b71d-b83cd832ac14.png)
desktop上にtestの空ファイルが作成されていました。
ついでにviエディタも試してみます。

```
Owner@Owner-PC MINGW64 ~/desktop
$ vi test
```
![スクリーンショット 2024-10-23 235135.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3902112/14f13649-b3ab-3153-769e-8df8ee74b146.png)

viエディタが起動しました。
メモ帳でwindows側から覗いてみると、しっかり入力が反映されておりました。
![スクリーンショット 2024-10-23 235322.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3902112/3d2f2abb-b825-e312-2941-491747e4f4af.png)

### ・アプリの起動とailasの設定
・日常的によく使うアプリケーションの起動方法とaliasの設定について調べました。
・microsoft edgeやexcelなどのアプリケーションは、explorer.exeというコマンドで起動できるみたいです。explorer.exeとは、Windowsのファイルエクスプローラー（Windows Explorer）を起動するための実行ファイルで、GUI環境の操作のほとんどに使われるシステムファイルです。（ダブルクリックしたらファイルが開くとか）
　何故windowsのシステムファイルが使えるのかということですが、GitBashはwindows側の環境変数を引き継ぐようで、環境変数PATH内にexplorer.exeが含まれているから、コマンドで引っ張って来れるということみたいです。windowsのシステムファイルで試しに私がよく資産管理に使っているexcelを開いてみます。
```
Owner@Owner-PC MINGW64 ~/desktop
$ explorer.exe "C:\Users\Owner\Desktop\目標管理・資産管理.xlsx"
```
これで開けました。こういった頻繁に開く必要があるものはaliasで永続的にサクッと開けるようにしたいので、~.bashrcを編集してaliasを追加していきます。

##### ・ホームディレクトリに移動
```
$ cd ~
```
##### ・bashrcを編集
```
vi .bashrc
```
##### ・ファイル内にaliasを追加して保存
webブラウザとよく利用するexcelファイルを素早く呼び出せるように設定しました。
```
alias edge='explorer.exe "C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"'
alias sisan='explorer.exe "C:\Users\Owner\Desktop\目標管理・資産管理.xlsx"'
```
##### ・設定を保存して、sourceコマンドで反映
```
$ source ~/.bashrc
```
これで、microsoft edgeを起動してみます。
![スクリーンショット 2024-10-24 003351.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3902112/86fdd541-8223-0c3f-9486-15de90480138.png)
無事起動されました。
これでGit Bash再起動後もaliasが保持されるかなと思いきや、Git Bash上に~/.bashrcファイルは見つかったが、~/.bash_profile、~/.bash_login、または~/.profileのいずれも存在しないというような警告文がでてきました。ですので、bash_profileを作成し、bashrcを読み込むような設定を追加してみます。

##### ~/.bash_profileの編集
```
vi ~/.bash_profile
```

##### bashrcを読み込む設定の追加
・viエディタで開いたファイル内に下記の設定を追加します。
```
if [ -f ~/.bashrc ]; then
    . ~/.bashrc
fi
```
上記の操作を実施した所、先ほど表示されていた警告文が消えました。この後にGit Bashを再起動してaliasを実行した所、問題なくアプリケーションが実行されました。

# 3.まとめ
今回Git Bashを使ってpc操作を行ってきました。正直まだ触れて間もないですが、どうやら学習したLinuxコマンドの多くを使うことができるようで、非常によさげかなと感じています。ただsystemctlやmountといったLinux特有のコマンドや、パッケージマネージャ関連（apt,yumなど）などなど、使うことができないコマンドもいくつかあるので、そちらは実際にlinuxを触って覚えていく必要がありそうです。
　今回色々と触ってみて、linuxもですがwindowsに関しても全然知識が足りないな～と思うことが多かったです。PCといいいますか、OSに関する知識も業務効率化やトラブルシューティングの速さに直結しそうな感じがなんとなくしてきますね。とにかく、今後もひたすらGit Bashを使い倒してみようと思います！
【Cコード解析】関数内の未使用変数の削除

関数内の未使用変数を削除するスクリプトを考える。

## 関数のブロックと変数宣言を抜き取る
関数ブロックは下記の正規表現でマッチできる。
```regex
(?:(?:auto|register|static|extern)\s+)?(?:(?:const|volatile|restrict|signed|unsigned|short|long)\s+)*\w+\s+\w+\s*\([^()]*\)\s*(\{([^{}]|(?1))*\})
```
https://qiita.com/name_ko/items/0bb30309074e10f1791f

関数ブロックの抜き出し方はソースツリー作成のスクリプトを考えたときに似たような正規表現を作成したため、こちらの記事を参考にすること。

変数宣言のマッチは下記。単一変数宣言であることを前提とする。
```regex
[\t ]*(?:(?:auto|register|static|extern)\s+)?(?:(?:const|volatile|restrict|signed|unsigned|short|long)\s+)*\w+[\s*]+\w+\s*(?:=[^;]+)?;[^\n]*\n
```
https://qiita.com/name_ko/items/c014fd67bd6d146a73cd

こちらも前に複数変数宣言のマッチを考えたため、こちらの記事を参考にする。

## 未使用変数の宣言は行ごと削除する
下記のスクリプトで実現する。
```Python
import regex

pattern = r"(?:(?:auto|register|static|extern)\s+)?(?:(?:const|volatile|restrict|signed|unsigned|short|long)\s+)*\w+\s+\w+\s*\([^()]*\)\s*(\{([^{}]|(?1))*\})"

pattern_val = r"[\t ]*(?:(?:auto|register|static|extern)\s+)?(?:(?:const|volatile|restrict|signed|unsigned|short|long)\s+)*\w+[\s*]+\w+\s*(?:=[^;]+)?;[^\n]*\n"

with open("test.c", "r", encoding="utf-8", errors="ignore") as file_obj:
	codetext = file_obj.read()
	functions = regex.finditer(pattern, codetext, regex.DOTALL)
	for func in functions:
		functext = func.group()
		functext_edit = functext
		values = regex.finditer(pattern_val, functext, regex.DOTALL)
		for val in values:
			valtext = val.group()

			if "=" in valtext:
				# 代入演算子がある場合は=の左にある文字列が変数名.
				valname = regex.search("\w+(?=\s*=)", valtext).group()
			else:
				# 代入演算子がない場合は;の左にある文字列が変数名.
				valname = regex.search("\w+(?=\s*;)", valtext).group()


			valmatchs = regex.finditer(rf"\b{valname}\b", functext, regex.DOTALL)
			usedcount = 0
			for vallll in valmatchs:
				usedcount += 1

			if usedcount == 1:
				# 一度しか記述されていない場合は未使用変数と判断して削除.
				functext_edit = functext_edit.replace(valtext, "")
				pass
		
		codetext = codetext.replace(functext, functext_edit)
			
	print(codetext)
```
大まかな流れは下記である。
```mermaid
    graph TD;
    
    load_code[test.cの読み込みコードをテキストとして取得]
    get_funcs[regex.finditerを使用して関数ブロックのリストを取得]
    func_loop_st{ }
    func_list_pop[関数ブロックリストから1つ取得する]
    get_values[regex.finditerを使用して変数宣言のリストを取得]
    value_loop_st{ }
    get_valuename[変数名を抽出]
    count_valuename[関数内での変数使用箇所を数える]
    is_count_1{実処理に変数が}
    delete_value[replaceメソッドにより変数宣言部を削除]
    value_loop_ed{ }
    edit_functext[変数宣言部を削除した関数ブロック文字列で置換してコードを更新する]
    func_loop_ed{ }
    task_end[処理終わり]
    
    load_code -->
    get_funcs -->
    func_loop_st -->
    func_list_pop -->
    get_values -->
    value_loop_st -->
    get_valuename -->
    count_valuename -->
    is_count_1 -- 使用されていない -->
    delete_value -->
    value_loop_ed -- 変数リストをすべて処理した --> 
    edit_functext -->
    func_loop_ed;

    is_count_1 -- 使用されている --> value_loop_ed
    
    
    value_loop_ed -- 未処理の変数がある --> value_loop_st;

    func_loop_ed -- 未処理の関数ブロックがある --> func_loop_st;
    func_loop_ed -- 関数ブロックをすべて処理した --> task_end;
```

## まとめ
未使用変数の変数宣言部を""で置換することにより削除することを実現している。こういった自動化を検討して思ったことだが、ソースコードなどテキストデータをプログラムで編集する場合は置換が扱いやすい。特定の行を削除などといった処理を組むと行数管理が煩雑になる。消したいところを検索して、""で置換するのが簡単だし、バグも起きにくい。
[Markdown] 私がMarkdownを使用する理由

## はじめに
こんにちは。中野です。
私は日常的に資料を作成する際、**エクセル**や**パワーポイント**の代わりに、**マークダウン（Markdown）形式**をよく使用しています。
この記事では、Markdownで資料を作成する際によく使う拡張機能や、Markdownのメリット・デメリットについて紹介いたします。

## Markdown記法のメリット・デメリット
### メリット
- **シンプルで軽量**：テキストベースのフォーマットなので、非常に軽く、どんなエディタでも編集可能です。
- **可読性が高い**：記法が簡単なので、初めて見る人でも内容を理解しやすい。
- **Gitと連携しやすい**：前述のように、バージョン管理との相性が良いため、共同編集にも向いています。
- **多用途に利用可能**：Webページの作成、ドキュメント作成、ブログ記事など、さまざまな用途で活用可能です。

### デメリット
- **デザインには不向き**：画像や図表の複雑なレイアウトを駆使した資料には不向きです。
- **表現力が限られる**：パワーポイントのように派手なデザインやアニメーションなどを使った資料は作りづらいです。
- **一部ツールに依存**：MarkdownのプレビューやPDFへの変換など、追加のツールや拡張機能が必要になる場合があります。

## なぜMarkdownを使用するのか
### Git管理との親和性
私がMarkdownを使用し始めた一番の理由は、**Gitでソースコードや設定ファイルと同様にドキュメントを管理したかった**からです。
Markdownはテキスト形式であるため、バージョン管理システムとの相性が非常に良いです。
バージョンの追跡や差分確認が簡単に行える点で、他のドキュメント形式に比べて圧倒的に優れていると考えています。

### VSCodeとの相性
ドキュメント作成に使用しているエディタは**Visual Studio Code (VSCode)**です。
VSCodeには多くの便利な拡張機能があり、Markdown作成が非常に快適に行えます。
私の場合は以下で紹介する拡張機能を組み合わせてMarkdown形式の資料を作成しています。

## よく使うMarkdown拡張機能
VSCodeには、Markdown関連の便利な拡張機能が数多くありますが、その中でも特に頻繁に使っているものをご紹介します。

### 1. Markdown All in One
この拡張機能は、Markdownの執筆を補助してくれる万能ツールです。自動で見出し番号を振ったり、テーブルの整形を行ってくれたり、ショートカットキーでさまざまな操作が可能です。
個人的には**Markdownを使うなら必須の拡張機能**だと考えています。

### 2. Markdown PDF
Markdownで作成したドキュメントを、簡単にPDFやHTMLに変換できる拡張機能です。
プレビュー機能を利用して仕上がりを確認しながら、最終的にPDF形式で保存できるため、**Markdownで書いた資料をPDFで共有する**場合に非常に役立ちます。
Markdownをご存じない方にも連携したい場合はこの拡張機能を使用しています。

### 3. Markdown Preview Mermaid Support
この拡張機能を使うことで、Markdown内に**Mermaid記法**を使用した図やフローチャートを作成できるようになります。ビジュアル表現が必要なときに非常に便利で、Markdownの欠点である「表現力の限界」を補う手段として重宝しています。

## まとめ
Markdownはシンプルな記法でありながら、GitやVSCodeとの組み合わせで強力なドキュメント作成ツールになります。
ぜひ、皆さんもMarkdownを使ったドキュメント作成に挑戦してみてください！
has_one_attachedとは

## 初めに

疑問に思ったことや上手くいかなかったことのアウトプットをしています。
自分なりの理解でアウトプットしていきます。初学者なので誤りもあると思います。
その際はご指摘いただけると幸いです。

## 発端
モデルにhas_oneと書いてるのにattachedというモデルが存在しない。
そもそも書き方も他のリレーションメソッドと違う？

## 調査結果
has_one_attachedで一つのメソッド。
レコード一件に一個のファイルを添付できます。

例えばユーザーのモデルにこう書きます

```
class User < ApplicationRecord
  has_one_attached :example
end
```

以下のようにすると、ファイルをアップロードできます
```
<%= form.file_field :example %>
```

以下のようにすると画像をがアップされているか確認できます
```
user.example.attached?
```

## 参考文献
Railsガイド. 「Active Storage の概要」, https://railsguides.jp/active_storage_overview.html, （参照2024.10.24）
BlenderでインポートしたVRMモデルのボーンを左右対称に編集する方法

## 起きた問題  
Blenderの**ポーズモード**でボーンを左右対称に編集しようとミラー機能を使用したところ、**片側のボーンしか動かない**問題が発生しました。  
![スクリーンショット 2024-10-23 235348.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987176/1a10c6ac-2860-0b50-26ec-50ac7255cf49.png)

## 環境  
Blenderバージョン: 3.6  
VRMインポートアドオン: [VRM Add-on for Blender](https://vrm-addon-for-blender.info/en/)

## 原因  
VRMモデルをBlenderにインポートすると、**ボーン名の形式の違い**により、Blenderのミラー機能が正しく働かなくなります。

Blender: xxx.L / xxx.R の形式を左右対称と認識
VRM: J_Bip_L_Hand / J_Bip_R_Hand → Blenderではミラー対象とみなされない

この形式の違いにより、**ミラー編集が片側しか反映されない**という問題が起きます。

## 解決策：ボーン名の一括変換スクリプト
**ボーン名をBlenderで認識される形式（語尾が .L または .R になっている）に変更**する必要があります。
以下のPythonスクリプトを使用すると、現在のボーン名に応じてVRM形式またはBlender形式のいずれかに一括で変換できます。

このスクリプトは、Blender形式に変換可能なボーン名（`_L_`や`_R_`を含む）を検出した場合に`.L`や`.R`付きのBlender形式へ変換し、それ以外の場合はVRM形式に戻します。  
これにより、**ポーズ作業時にはBlenderのミラー機能を使い、作業後はVRM形式へ復元**することが可能です。

![スクリーンショット 2024-10-23 234203.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987176/4837c4de-fe06-c60f-7711-45ae42c11b6b.png)

## ボーン名を変換するPythonスクリプト
```python
import bpy

# アーマチュアオブジェクトを取得
armature = bpy.context.active_object

def to_vrm_default():
    """ボーン名をVRM形式に戻す（末尾の .L/.R を削除し、_LR_ → _L_/_R_）"""
    for bone in armature.data.bones:
        if bone.name.endswith(".L"):
            # 末尾の .L を削除し、_LR_ を _L_ に置換
            new_name = bone.name[:-2].replace("_LR_", "_L_")
            bone.name = new_name
        elif bone.name.endswith(".R"):
            # 末尾の .R を削除し、_LR_ を _R_ に置換
            new_name = bone.name[:-2].replace("_LR_", "_R_")
            bone.name = new_name

def to_blender_default():
    """ボーン名をBlender形式に変換（_L_/_R_ → _LR_ に変換して末尾に .L/.R を追加）"""
    converted = 0
    for bone in armature.data.bones:
        if "_L_" in bone.name:
            new_name = bone.name.replace("_L_", "_LR_")
            bone.name = new_name + ".L"
            converted += 1
        elif "_R_" in bone.name:
            new_name = bone.name.replace("_R_", "_LR_")
            bone.name = new_name + ".R"
            converted += 1
    return converted > 0

# 状態に応じて変換実行（すでにBlender形式ならVRM形式に戻す）
if not to_blender_default():
    to_vrm_default()
```
↓実行後
![fba0a55c-b4ad-632e-2351-60167f25343d.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987176/2b481a55-0964-4938-98b4-be0b061cf6a7.png)



この手順によって、Blender内でVRMモデルのボーンを左右対称に編集できるようになります。
# 注意
このスクリプトはボーン名を書き換えるため、他ツールとの互換性やVRM出力に影響を与える可能性があります。 
例えば、Humanoidボーンが未設定と判定されたり、エクスポート時にボーンが認識されなくなる可能性があります。
自動変換後に保存する場合は、変換前の状態を必ずバックアップしておくことを強く推奨します。
【学習記録　2024-10-24】

## 使用した教材など
Udemy：【CLF-C02版】この問題だけで合格可能！AWS 認定クラウドプラクティショナー 模擬試験問題集（6回分390問）
## 学習内容
- 模擬問題演習

## 所感
　勉強すればするほどAWSの凄さを実感します...!
【Ruby】Procとlambdaの違いまとめ

どうもこんにちは。

今回は、RubyGoldで出てきそうな`Proc`と`lambda`についてまとめました。

# `Proc`と`lambda`の比較表

もう先に比較表を載せておきます。

| 特徴 | lambda | Proc |
| --- | --- | --- |
| 引数のチェック | 厳格にチェック。引数が不足または過剰だとエラー | 引数の数に寛容。足りない場合はnilを補完する |
| returnの動作 | lambda内でのみ終了し、呼び出し元に戻る | 呼び出し元全体からreturnする |
| 作成方法の違い | lambdaまたは->で定義 | Proc.newで定義 |

# `lambda`

## `lambda`の基本構文

`lambda`を使うことで、引数を受け取る無名関数を作成できます。以下は、`lambda`の一般的な構文です。

```rb
my_lambda = lambda { |x, y| x + y }
```

または、短縮形で->（ラムダリテラル）を使うこともできます。

```rb
my_lambda = ->(x, y) { x + y }
```

## `lambda`の使い方

定義した`lambda`は、`call`メソッドを使って実行します。引数は`call`メソッドに渡します。

```rb:例
my_lambda = ->(x, y) { x + y }

result = my_lambda.call(2, 3)
puts result  #=> 5

result = my_lambda.call()
puts result  #=> エラー: wrong number of arguments (given 1, expected 2)
```

# `Proc`

## `Proc`の基本構文

`Proc`を使用した無名関数を定義する場合は、`new`メソッドを使用して`Proc`クラスのインスタンスを作って定義します。

```rb
my_proc = Proc.new { |x, y| x + y }
```

## `Proc`の使い方

`lambda`と同様で、`call`メソッドを使って実行します。

```rb
my_proc = Proc.new { |x, y| x + y }

result = my_proc.call(2, 3)
puts result   #=> 5

result = my_proc.call(2)
puts result   # => nil(yがnilとして扱われ、計算結果がnil)
```

# `Proc`と`lambda`内での`return`動作

## `Proc`の場合

`Proc`内で実行された`return`は、`Proc`の中身だけじゃなくてその`Proc`を含むメソッド全体を終了させます。今回で言うと、`return`が実行される`Proc`の含まれる`test_proc`メソッド全体の処理が終了します。

```rb
def test_proc
  my_proc = Proc.new { return "Inside proc" }
  my_proc.call
  return "Outside proc"
end

puts test_proc  # => "Inside proc"（Procが呼び出し元のメソッドも終了させる）
```

## `lambda`の場合

`lambda`の場合は、`lambda`内で実行された`return`は`lambda`内でしか効力を発揮できません。
そのため、`test_lambda`メソッドは継続して実行されます。

```rb
def test_lambda
  my_lambda = -> { return "Inside lambda" }
  my_lambda.call
  return "Outside lambda"
end

puts test_lambda  # => "Outside lambda"（lambda内でのみ処理が終了し、呼び出し元に影響しない）
```

# まとめ

Rails開発する人は、`lambda`を使うと割と簡潔にメソッドを定義できたりするので覚えておくと良いと思います。

モデルで以下のように定義しておくと...

```rb:app/models/sample.rb
class Sample < ApplicationRecord
    active = -> { where(destroy_flag: false) }
end
```

いろんなところで、メソッドを呼び出せます。

```rb
class SamplesController < ApplicationController
    def index
        @samples = Sample.active
    end
end
```
AWS Lambda + SNS でメール通知機能を実装してみた

# はじめに
本記事ではAWSのLambdaとSNSを使用して、Lambdaが実行されたときにSNSのトピックに登録されてる宛先にメール通知をする処理を実装していきます。


# ゴール
Lambdaを実行してSNSのトピックに登録してる通知先にメール通知が来ることを確認する

# 1. SNSトピックの作成

トピックを作成していきます。
メッセージの処理順序は気にしないので `スタンダード` を選択し、任意の名前でトピックを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/fbf2c540-d4c2-6fd5-15ea-126a330b9d2f.png)

トピックを作成したら通知先のEメールを登録したサブスクリプションを作成していきます。
プロトコルとエンドポイントを入力出来たら `サブスクリプション` を押下します。

- プロトコル：Eメール
- エンドポイント：任意のメールアドレス（通知先）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1247619/63d79a2b-1545-ce58-ebaf-5853b64e749d.png)

:::note info

SNSのトピックを作成すると `AWS Notification - Subscription Confirmation` で認証のメールが届くので、対象のメールを確認してください。

:::


# 2. Lambdaの作成
SNSのトピック > サブスクリプションに登録したメールアドレスに通知を出す用のLambdaを作成していきます。
`TopicArn` のところは作成したSNSのARN値で置き換えてください。

```python:lambda_function.py
import json
import boto3

# SNSクライアントの初期化
sns = boto3.client('sns')

def lambda_handler(event, context):
    # メールの本文
    message = "これはテスト通知メッセージです。"
    # メールのタイトル
    subject = "Lambda からの通知"
    
    try:
        # SNSトピックにメッセージを発行
        response = sns.publish(
            TopicArn='SNSトピックのARNをコピペ',
            Message=message,
            Subject=subject
        )
        return {
            'statusCode': 200,
            'body': json.dumps('通知が送信されました')
        }
    except Exception as e:
        return {
            'statusCode': 500,
            'body': json.dumps(str(e))
        }
```


# 3. 動作の確認

Lambdaのテストイベントを作成し、実際にテスト実行します。

:::note warn

Lambdaを動かす際にはIAMのポリシーからSNSの権限付与を行っていてください。

:::

実行すると数秒で `AWS Notifications` から、次の内容でメールが届いている事が確認できます。

```:通知メール
- メールタイトル：Lambda からの通知
- メール本文：これは通知メッセージです。
```
【Next.js】middleware.jsでサーバーアクションを除外する方法

`middleweare.js`に以下のように記述するとサーバーアクションを除外できます。

```js:middleware.js
export const config = {
  matcher: [
    {
      source:
        '/((?!api|_next/static|_next/image|media|fonts|favicon.ico|favicon.png).*)',
      missing: [
        // Server Actions を除外する
        { type: 'header', key: 'next-action' },
      ],
    },
  ],
};

```
【モチベーション】睡眠不足があたえる影響

# はじめに
こんにちは、現在アメリカの大学に行って語学を学びながらソフトウェアエンジニアになるために独学で勉強しているものです
この記事を見ている方の中にも、平日にYoutubeで動画を見て時間を過ごしてしまい時間が無くなったり、ゲームをしてしまったりして睡眠負債をためている方がいるのではないでしょうか。
私は現在アメリカのBoise State University に英語を学ぶために2か月限定でいっており宿題が出ているため、夜遅めまでに作業していしまうことがしばしばあります。
頭ではわかっていても、なかなか睡眠を積極的に取れない方もこの記事を見て改めて睡眠不足の悪影響を理解して、睡眠不足を避けるような行動をとるようにしていただければ幸いです。
睡眠不足を避けるためには、やることがあっても早く寝る以外に選択肢はないと思っているので、あくまでも今回は睡眠不足を避けるための記事ではありません。

# 仕事のパフォーマンスによる影響
まず一つ目に、皆さまが一番気になっている(?)であろう仕事による影響について説明していきます。
睡眠不足は集中力、注意力、判断力を低下させ、作業効率を悪化させます。また、クリエイティブな思考や問題解決能力が鈍り、仕事のミスや事故のリスクが増加します
どれくらいの割合が低下するかについて、2003年に実験した結果をわかりやすくまとめた図が以下のリンクに載っています
あるグループについて2日徹夜の人、2週間1日8時間の睡眠の人、2週間1日6時間睡眠している人に分けてどれくらい脳の反応速度が違うかを測定した実験が2003年に行われました。
驚くべき結果ですが、2週間1日6時間睡眠した人の脳の反応速度と、2日徹夜した人の脳の反応速度が同じという結果が出ているようです。

https://www.heart-center.or.jp/rehabnow/1686/#:~:text=6%E6%99%82%E9%96%93%E7%9D%A1%E7%9C%A0%E3%81%8C2,%E7%A4%BA%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99*1%E3%80%82

また、2017年のハーバード大学の研究においても6時間未満の場合に著しいパフォーマンス低下がされるといわれています。
上記の内容をみてかなり納得できるような記事だなと体感的に思いました。
勉強時間が増えて、今までよりも睡眠時間が減ってしまったので機能たくさん睡眠時間をとったら思考速度が速くなったように感じました。
これは意識しないとあまりわかりずらいかもしれませんが、睡眠不足の時としっかり寝た日とで技術書の理解度を比べてみるとかなり違うとおもいます。

# 健康への影響
睡眠不足は免疫系の機能低下、肥満、糖尿病、心血管疾患のリスク増加など、長期的に深刻な健康問題を引き起こす可能性があります。
特に、ホルモンバランスが乱れやすくなり、代謝障害が発生しやすくなります。
2021年のアメリカ国立衛生研究所（NIH）は、慢性的な睡眠不足が心臓病や高血圧などのリスクを増加させると報告しています。
睡眠不足が続くと、血糖値のコントロールが難しくなり、2型糖尿病のリスクも増加します。また、体重増加の原因にもなりやすいとされています 。
私たちが実感しやすいのは、睡眠不足によって免疫系機能が低下し風邪になることではないでしょうか。
睡眠不足による影響って短期的な影響のみと思っていましたが、実は中長期的な影響もあることが上記から分かると思います

# 精神面による影響
睡眠不足は精神的な不安定さを引き起こし、うつ病や不安障害のリスクを高めます。
情緒のコントロールが難しくなり、怒りやイライラが増し、対人関係に悪影響を与えることもあります。 
友人やパートナーと喧嘩した際に振り返ると睡眠不足であることも多いのではないでしょうか。
根拠として、サンフランシスコ大学の研究では、睡眠不足が感情の不安定さやストレスへの脆弱性を増大させることが示されています。
睡眠不足の人は、ネガティブな感情をコントロールする能力が低下し、うつ症状の悪化や新たな不安症状を発症しやすくなることが報告されています 。

この研究から、睡眠負債がない状態のときにネガティブな感情をコントロールをしていることがわかりますが、確かにいらいらとかは睡眠不足のほうが爆発しやすいですよね。

# 学習機能
睡眠中、脳は新しい情報を整理し、記憶として定着させるため、睡眠不足になると記憶の定着や学習能力が著しく低下します。
根拠としてカリフォルニア大学バークレー校の研究では、睡眠不足の状態が脳の情報処理機能を損ない、新しい知識の習得や長期記憶の定着に悪影響を及ぼすことが示されています。
特に学習中に睡眠が不足していると、試験や日常業務でのパフォーマンスが著しく低下することが確認されています 。

やることがある程度あっても、新しいことを学ぶためにしっかり睡眠時間をとった方がいいことがこの研究結果からもわかると思います。

# まとめ
本日はRubyのことではなく睡眠時間という日常的なテーマを取り扱いましたが、モチベーションを管理するためにも睡眠時間をしっかり確保するのはとても重要です。
独学は一人でどれだけ自分を律せることができるかなので、しっかり睡眠をとって誘惑に負けないようにこれからも勉強継続したいと思いました。
バグ発見tips　その１

バグ発見tipsを暫くの間、書き連ねてみようと思う。
バグ発見と言っても、nullチェックをしているかなどのテストではなく、なぜかよくわからない方法でバグを発見できる嗅覚を言語化してみる。

変なところでkillする。

例えばFormAがFormBを作成し、Bの戻るボタンでAに戻るような構成だとしよう。
この時AからBにページ遷移した後、タスクマネージャーなどでAを削除して、Bの「戻るボタン」を押す。

こういった動作中に途中でkillすることをチェックする
【TIPS】Play with Dockerで2048オンランゲーム構築について

まず、[https://labs.play-with-docker.com/ ](https://labs.play-with-docker.com/ ) にアクセスします。Googleアカウントを使用してログインできます。ログイン後、画面に「start」ボタンが表示され、それをクリックすることで無料のDocker環境を起動できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/742640/5544959b-2301-59ab-6c67-ee8687b0a6fc.png)


操作パネルに入ると、画面の左側に「ADD NEW INSTANCE」ボタンが表示されます。クリックすると、4時間使用できる一時的なDocker環境が作成されます。この環境は、自由に利用して任意の環境を構築することができ、インターネット経由で自由にアクセスすることも可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/742640/aa8f742c-ca4b-2ef7-1e73-e38d3ab91920.png)


画面の右下に黒いCLI画面が表示されたら、Docker環境の使用を開始できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/742640/11f521a2-7d9d-b5dd-1875-91299131039c.png)


以下のコマンドを使用して2048ゲームの画面を作成し、このDocker環境が正常に動作し、インターネット経由でアクセスできるかを確認できます。
```
$ docker run -it -p 80:80 cnrock/2048
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/742640/2518a771-2c62-f297-63b1-4f3d6697fc9a.png)

Docker runコマンドを実行後、一番上に「80」リンクがあり、クリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/742640/61943e6e-2498-0b96-faae-5101d0db6383.png)

2048ゲームの画面が表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/742640/645c6589-3d1d-f888-faef-98908ba246ae.png)


最後
この無料環境は4時間しか使用できず、時間を超えると再構築が必要です。学習用のPOC環境としては十分だと思います。気に入っていただければ幸いです。
東大の「コードで学ぶAWS入門」を読んで理解したことのまとめ＃１


## きっかけ
先日AWSクラウドプラクティショナーの取得したが、正直全く理解せず、用語を覚えるだけで資格がとれてしまったので、復習＋実用的な知識を獲得するために、学習した内容をまとめます。

## 第２章の「クラウド概論」を理解する＃１
#### 「クラウド」とは？
「クラウド」ってよく耳にするし、ストレージとか、Google Driveとかで身近に使っているものの正直その正体を正確には理解していかったので、まずはそこから理解を深めていく。

クラウドの定義として引用されるのが The NIST  Definition of Cloud Computing というもがあるらしい。そこには５つの要件が定義されているが、ざっくりいうと<font color ="Red">利用者の要望に応じて好きな時に好きな分だけクラウド提供会社のサービスをインターネット経由で利用できる。　</font> といったもの。

一番みじかでわかりやすいのはiCloudサービスだろう。写真や動画などのデータを「クラウド」に保存して、インターネットさえ繋がっていれば、ケータイ本体の写真フォルダと同じように使用できる。まるでケータイ内部に容量無限の「クラウド」という名前のフォルダが存在しているように感じる。

でも実際は世界のどこかにある「データセンター」とよばれる、みんなのデータを全て集約して保管している、まるで超巨大なIKEAの倉庫みたいなところが各国に散らばっており、そこに僕らの高校の思い出写真なんかを預けているわけだ。「データセンター」は世界のどこかに、「物理的なハードウェア」として存在している。しかし、IT関連で仕事をしていない人からすると、そんなものの存在すら知らないと思うし、ましてやどこにあるのかもわからない。そのため、<font color ="Red">僕たちユーザの目線からするとまるで物体のない「雲」のようなところにデータが存在している</font>ように見えるわけだ。

正直、僕は「クラウド」という名前がいまいちピンとこなくて、高校のとき電気屋のおっちゃんに「雲みたいなところにデータを保存するサービスです」と説明されて、「へぇ〜データって空気中にあるんだ」って本気で思ってた。たぶんあののおっちゃんも全然理解せずに営業してたんだなと、今になって思う。

結論、僕の思うクラウドの本質は、<font  color ="Red">ケータイに入っているアプリのようなソフトウェアからインターネットを通じて、世界のどこかの物理的なデータセンター（ハードウェア）を利用できる</font>というものな気がする。
AIを使うルール

１，理解していないコードはそのままコピペしない。最初から最後まで理解していることが条件。
２，例えばActiveHash::Baseのモデルファイルで都道府県や年月日やジャンル等々、あまりに単調で長すぎて手入力が理不尽な場合はAIを使うのが有効。

上記は今のところのマイルールだが以後加筆修正予定。

先生の一人は、そもそもコードを書かせたらダメという。
自分の経験でも、1つのエラーで1日中悩んでカリキュラム繰り返し読んでたほうが今AIに頼り切り状態より勉強になっていた。
OpenID Connect（OIDC）の認証フローをサクッと理解する

OpenID Connect（OIDC）は、OAuth 2.0の上に構築された認証プロトコルで、ユーザーが認証されたことを信頼できる方法で確認するための標準的なフローを提供します。OIDCの処理フローは、ユーザーがIDプロバイダー（IdP）に認証され、クライアント（アプリケーション）がそのユーザーのID情報を取得するための手順に従います。以下がその一般的なフローです。

### 1. 認可リクエスト

クライアント（アプリケーション）は、認可エンドポイントにリクエストを送信します。リクエストには、OIDCで必要な情報が含まれています。

- **レスポンスタイプ**：たとえば「code」など（認可コードフローの場合）。
- **クライアントID**：クライアントの識別子。
- **リダイレクトURI**：認可が完了した後に、認可コードを送信するURI。
- **スコープ**：リクエストされた情報の範囲。OIDCの場合、通常「openid」が含まれます。
- **状態（state）**：CSRF（クロスサイトリクエストフォージェリ）攻撃を防ぐために使用されます。

### 2. ユーザー認証

ユーザーは、認可サーバー（IDプロバイダー）でログインを行います。ログイン方法は、ユーザー名/パスワード、2要素認証など、プロバイダーの設定に依存します。

### 3. 認可コードの発行（認可コードフローの場合）

ユーザーが正常に認証されると、IDプロバイダーは指定されたリダイレクトURIにユーザーをリダイレクトし、その際にクエリパラメータとして認可コードを送信します。クライアントはこの認可コードを使ってトークンを取得します。

### 4. トークンリクエスト

クライアントは認可コードを用いてトークンエンドポイントにリクエストを送信します。このリクエストには以下が含まれます。

- **認可コード**：IDプロバイダーから受け取ったコード。
- **リダイレクトURI**：認可リクエストで指定したものと同じ。
- **クライアントIDおよびクライアントシークレット**：クライアントの認証情報。

### 5. トークンレスポンス

IDプロバイダーは、以下を含むトークンレスポンスを返します。

- **IDトークン**：JWT形式のトークンで、ユーザーの認証情報（サブジェクト、発行者、発行時間、期限など）が含まれます。
- **アクセストークン**：保護されたリソースにアクセスするためのトークン。
- **リフレッシュトークン**（オプション）：アクセストークンの有効期限が切れたときに新しいアクセストークンを取得するためのトークン。

### 6. IDトークンの検証

クライアントは、IDトークンの署名と内容を検証します。検証プロセスには以下が含まれます。

- **署名の検証**：IDトークンがIDプロバイダーによって署名されたことを確認します。
- **クレームの検証**：例えば「aud」（受信者）がクライアントIDと一致しているか、「exp」（有効期限）が現在の時間を過ぎていないかなどを確認します。

### 7. ユーザー情報の取得（オプション）

アクセストークンを使ってユーザー情報エンドポイントにリクエストを送信し、追加のユーザー情報（名前、メールアドレスなど）を取得することができます。

### OIDCの主なフロー

OIDCにはいくつかの異なるフローが存在し、利用するシナリオに応じて使い分けられます。

- **認可コードフロー**：サーバー側アプリケーションが認証情報を取得する標準的なフローです。
- **インプリシットフロー**：クライアントがトークンを直接受け取るフローで、主にクライアント側（ブラウザ）で処理が行われる場合に使用されます。
- **ハイブリッドフロー**：認可コードフローとインプリシットフローの組み合わせで、途中でアクセストークンを受け取ることができます。

### まとめ

OpenID Connectのフローは、クライアントがユーザーの認証情報を取得し、IDプロバイダーがそれを信頼できる方法でクライアントに提供する仕組みです。主に認可コードフローが使われ、セキュリティと柔軟性が高く、多くのWebアプリケーションやモバイルアプリケーションで利用されています。
【Cコード解析】複数変数宣言の解消

本日は複数変数宣言を単一変数宣言に分解するスクリプトを考える。

## 複数変数宣言を見つける
下記の正規表現で複数変数宣言をしている個所をみつける。
``` regex
(?<=[\n;])[\t ]*(?:(?:auto|register|static|extern)\s+)?(?:(?:const|volatile|restrict|signed|unsigned|short|long)\s+)*\w+[\s*]+\w+(?:\s*=[^,;]+)?\s*(,[\s*]*\w+(?:\s*=[^,;]+)?)+;
```
長い正規表現だが、大まかに解説する。
- `(?<=[\n;])[\t ]*`：行頭から変数宣言の記述までの空白にマッチ
- `(?:(?:auto|register|static|extern)\s+)?`：記憶クラス指定子にマッチ
- `(?:(?:const|volatile|restrict|signed|unsigned|short|long)\s+)*`：修飾子にマッチ
- `\w+[\s*]+\w+`：データ型と変数名、その間の空白またはポインタ変数宣言時の`*`にマッチ
- `(?:\s*=[^,;]+)?\s*`：1つ目の変数の初期化式にマッチ
- `(,[\s*]*\w+(?:\s*=[^,;]+)?)+`：複数変数宣言時の`,`とそれ以降の文字にマッチ
- `;`：複数変数宣言の命令の終端であるセミコロンにマッチ

## 複数変数宣言を単一変数宣言に分解する
下記の処理で実現する。
``` python
import regex

def repldef(match:regex.Match)->str:
	matchtext:str = match.group()
	
	pattern = r"[\t ]*(?:(?:auto|register|static|extern)\s+)?(?:(?:const|volatile|restrict|signed|unsigned|short|long)\s+)*\w+\*?"
	datatype = regex.search(pattern, matchtext, regex.DOTALL).group()

	ret = matchtext.replace(",", f";\n{datatype}")
	return ret

pattern = r"(?<=[\n;])[\t ]*(?:(?:auto|register|static|extern)\s+)?(?:(?:const|volatile|restrict|signed|unsigned|short|long)\s+)*\w+[\s*]+\w+(?:\s*=[^,;]+)?\s*(,[\s*]*\w+(?:\s*=[^,;]+)?)+;"

with open("test.c", "r", encoding="utf-8", errors="ignore") as file_obj:
	codetext = file_obj.read()
	ret = regex.sub(pattern, repldef, codetext, flags=regex.DOTALL)

	print(ret)
 ```
 先の正規表現を使って複数変数宣言の記述にマッチする。`regex.sub`で単一変数宣言になるよう置換するが単純な置換ではないため、関数を渡して置換後の文字列を動的に作成する。

 `repldef`関数では複数変数宣言の文字列に対して、変数名の前の記憶クラス指定子、修飾子、データ型を抜き出す。それから、`,`を抜き出した文字を置換後文字とすることで、単一変数宣言の記述に変換する。

 ## まとめ
 正直、複数変数宣言はほとんど見たことがないが、単一変数宣言になっていないと他のC言語解析処理の弊害になってしまう。例えば、未使用変数の削除スクリプトを考える場合も単一変数宣言になっていてくれたほうが楽。
LeetCodeを1日1題解いてみる (day7)

7日目に取り組んだ問題はこちら！

# 35. Search Insert Position

https://leetcode.com/problems/search-insert-position/description/

## 問題文
Given a sorted array of distinct integers and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order.

You must write an algorithm with O(log n) runtime complexity.


## 僕の回答(GPT使用)

```py
class Solution:
    def searchInsert(self, nums: List[int], target: int) -> int:
        left, right = 0, len(nums)-1
        while left <= right:
            mid = left + (right - left) // 2
            if nums[mid] == target:
                return mid
            elif nums[mid] < target:
                left = mid + 1
            else:
                right = mid -1
        return left
```


## より効率の良い回答例
今回は特にありませんでした。

### コメント
2分探索を自力で実装できませんでしたが、2分探索を使えばいいことには気づけてよかったです。

### 次回はこちら!
https://qiita.com/h_y_s_d/items/a8c1b354db60f6553681