OmniAICreator/Qiita-1.07M huggingface dataset:
展開したデータヒントを開いたままにする（Visual Studio）

## 参考
この記事は、以下の動画を参考にしています。
詳しくは、動画をご覧ください。

https://youtube.com/shorts/2GjjbRAw0II?si=AR-uzKUfYSkqeCPI

## 展開したデータヒントを開いたままにする
### データヒント
ブレークポイントなどでコードの実行が中断しているとき、エディターで変数などをマウスでポイントすると、データヒントが現れ、変数などの値を表示・変更できます。

メンバーを持ったデータの場合、データヒントを展開してメンバーを表示できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293884/6befcb95-83e4-47eb-ab75-2bdf39537cdb.png)

デフォルトでは、データヒントからマウスカーソルが離れると、データヒントが消えます。

### 設定
以下のように設定することで、メンバーを展開していた場合、マウスカーソルが離れても、データヒントを表示したままにできます。

- 「オプション」→「デバッグ」→「全般」の中の「クリックされるまで、展開されたデータヒントを開いたままにする」にチェックを入れる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293884/b28212f3-bb8e-192d-bd57-edaca9f20501.png)

（この設定にしても、メンバーを展開していない場合は、マウスカーソルが離れると、データヒントが閉じます）
Amazon Bedrockの新機能「Prompt Flows」Collectorノード、Iteratorノードを使ってみた

# はじめに
今回はAmazon Bedrockの新機能「Prompt Flows」のCollectorノード、Iteratorノードを使って、配列の中身を出力する、シンプルなアプリケーションを作成してみました。
作成してみて分かったことも共有します。

「Prompt Flows」は、ノードを配置して生成AIのワークフローを開発・管理できるサービスです。

https://aws.amazon.com/jp/bedrock/prompt-flows/

今回Collectorノード、Iteratorノードを使うにあたって、以下のサイトを参考にしました。

https://docs.aws.amazon.com/ja_jp/bedrock/latest/userguide/flows-nodes.html

# 導入
アプリケーションの全体像は以下の通りです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806967/25e2d6e9-3b55-865e-57ad-6e3d33ff6875.png)


●Iterator
・Input
array型のみを受け取ります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806967/203dc25c-1979-cd65-a670-aad16e70af20.png)

・Output
arrayItem、arraySize
 
この2つを出力します
どちらも出力データ型は、String,Number,Boolean,Object,Arrayの5つから選ぶことが出来ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806967/dc167c52-a3fe-17a4-2fbc-1197d058283b.png)


※arraySizeは、CollectorノードのarraySizeにしか繋ぐことが出来ませんでした。
試しにこのようなノードで繋いでみると、以下のようなエラーが出ました。

![イデレータ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806967/01de4891-c6ea-06df-50ae-b2167602764b.png)


●Collector
・Input
arrayItem、arraySize
この2つのみを受け取ります。
データ型は、String,Number,Boolean,Object,Arrayの5つから選ぶことが出来ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806967/18204a69-4952-0177-52b0-b8cf46f6aee9.png)

・Output
collectedArrayを出力します
この時の出力データ型は、Arrayのみです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806967/d88af01f-a658-ebd6-59ad-13fb96295346.png)


# 実行結果
配列を入力すると、入力された配列をそのまま返します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806967/feda4e7c-6b64-243b-2716-501cce51629a.png)

# まとめ
今回は「Prompt Flows」のCollectorノード、Iteratorノードを使って、配列の中身を出力するシンプルなアプリケーションを作成してみました。

配列の出力には成功しましたが、配列のサイズが出力出来ていない事、配列をそのまま出力しているため具体的な使い道が考えられていない事が課題です。
今後その点について考えながら、何か具体例を作成できればなと思っています。
M5Stack Core2: Hello World

## プログラム

```text:hello_world.ino
// ---------------------------------------------------------------------
/*
	hello_world.ino for M5StackCore2

						Aug/28/2024
*/
// ---------------------------------------------------------------------
#define	PROGRAM	"hellow_world.ino"
#define	VERSION	"2024-8-28 AM 09:43"

int count = 0;
void setup()
{
	Serial.begin(115200);
	delay(3000);
	Serial.println("*** start ***");
	Serial.println(PROGRAM);
	Serial.println(VERSION);
	delay(1000);
	Serial.println("*** setup end ***");
	delay(1000);
}

// ---------------------------------------------------------------------
void loop() 
{
	Serial.println(PROGRAM);
	Serial.println(VERSION);
	Serial.println("Hello World! " + String(count));
	delay(1000);
	Serial.println("Good Morning! " + String(count));
	delay(1000);
	Serial.println("こんにちは " + String(count));
	Serial.println();
	delay(3000);
	count++;
}

// ---------------------------------------------------------------------
```

## Arduino IDE
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/6171cb7a-3bcd-65ca-c5a0-21fcfd20b7bf.png)
Lambdaをコンテナイメージとしてデプロイする方法

 従来のZIPファイルによるデプロイに代わり、Dockerイメージを使ってLambdaをデプロイする方法をメモ

 ## ファイル
 ```:構成
 .
├── Dockerfile
├── app.py
└── requirements.txt
```

```docker:Dockerfile
# ベースイメージとして公式のAWS Lambda Python 3.8ランタイムを使用
FROM --platform=linux/amd64 public.ecr.aws/lambda/python:3.8

# Lambda関数コードをコンテナにコピー
COPY app.py ${LAMBDA_TASK_ROOT}

# 必要なパッケージをインストール
COPY requirements.txt ./
RUN pip install -r requirements.txt

# Lambdaハンドラーを指定
CMD ["app.lambda_handler"]

```

※M1 Mac上でビルドする場合、FROMに「--platform=linux/amd64」を指定してあげないと、AWSコンソール上でLambdaが動かない。


```py: app.py
import json

def lambda_handler(event, context):
    # クエリパラメータ "name" を取得
    name = event.get("queryStringParameters", {}).get("name", "World")

    # レスポンスを返す
    return {
        "statusCode": 200,
        "body": json.dumps({
            "message": f"Hello, {name}!"
        })
    }
```

requirements.txt は空

## デプロイ手順
### Amazon ECR リポジトリ作成
Amazon ECR（Elastic Container Registry）は、Dockerイメージをホスティングするためのサービス。
まずはECRリポジトリ作成

```bash
aws ecr create-repository --repository-name your-lambda-repo
```

### Dockerログイン
```bash
aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin your-account-id.dkr.ecr.your-region.amazonaws.com
```


### イメージのビルド
```bash
docker build -t my-lambda-image .
```

### ECRリポジトリのURIにイメージをタグ付け
```bash
docker tag your-lambda-image:latest your-account-id.dkr.ecr.your-region.amazonaws.com/your-lambda-repo:latest
```

### ECRにプッシュ
```bash
docker push your-account-id.dkr.ecr.your-region.amazonaws.com/your-lambda-repo:latest
```

これで、ECRにコンテナイメージがプッシュされる。

![スクリーンショット 2024-08-28 9.36.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440409/c1a4bcb8-410f-fe9d-3f7d-621969a0b179.png)

### Lambdaデプロイ
ECRのイメージを指定して、デプロイする。

```bash
aws lambda create-function \
  --function-name your-lambda-function \
  --package-type Image \
  --code ImageUri=your-account-id.dkr.ecr.your-region.amazonaws.com/your-lambda-repo:latest \
  --role arn:aws:iam::your-account-id:role/your-lambda-role
```

- function-name: Lambda関数名
- ImageUri: ECRにプッシュしたイメージのURI
- role: Lambdaに必要なIAMロールのARN
    - Lambda用のロールを作成していないのであれば、IAMから作成
アカウント量産したいときに便利な捨てメアドの使い方

こんにちは、りょうです。
今回はメールアドレス認証に使える捨てメアドの使い方紹介です。

## 捨てメアドとは
捨てメアドは一時的にアカウントをつくるときに使うサービスです。
すぐメールアドレスの作成ができ、送受信が可能です。
Twitter、Discordなどのサービスのアカウントを作るときにも問題なく使えます
今回はこちらの[メルアドぽいぽい](https://m.kuku.lu/ja.php)を使って説明します。

## メールアドレスの作成
1: サイトにアクセスします。
2: アドレスを指定して追加を押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818367/8423540c-aca2-cd78-5c8e-a189720401b8.png)

3: アカウント名、ドメインの設定を行います。
　日本限定と書いているものがおすすめです。

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818367/590c1309-5d45-cb27-2fd2-59ad5df44cd2.png)

4: 作成が完了すると`あなたのメールアドレス`という欄に表示されるので押します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818367/cee627ca-ab63-5aa0-2864-f69979cd5986.png)

5: これで完了です。作成数に上限はありません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818367/417a6d9b-16f2-9f33-5222-80ac7e62b709.png)

## メールアドレスの別端末間での共有
メルアドぽいぽいはアドレスの共有が可能です。
`あなたのユーザー情報 > 使用中のアカウント情報`に移動します。
IDとパスワードをコピーして保存しておきます。(悪用防止の為消してます)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818367/b27f91d8-9c9c-8d1f-f116-06ead9a1233d.png)

次に、共有したい別の端末側での処理をします。
`あなたのユーザー情報 > 他のアカウントにログイン (復元/同期)`に移動します。
ここで先ほど保存したIDとパスワードを入力すれば共有が完了します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3818367/526edb69-9773-2596-5eed-9feb004ba40f.png)

## まとめ
今回は捨てメアドの使い方解説でした。
サブ垢作りたいってときに簡単にできるので便利ですよ。

わからないことあったら書いてくれれば答えていきます。

**Discordにいる荒らしの情報や対策方法の共有をしている自鯖です**
ぜひ参加お願いします↓↓↓↓

https://discord.com/invite/ESRGwGQhxc
VirtualBoxでCentOS7を使用したため、次のOSをまとめ

# はじめに

VirtualBoxのCentOS7を使用しようして学習していましたが、CentOS7のEOLに伴い
次に個人的に学習できるOSについてまとめてみました。

知見のある方にご教示いただきました

## AlmaLinux9
AlmaLinux9とは
https://www.designet.co.jp/faq/term/?id=QWxtYUxpbnV4

以下のサイトで学習出来ます
https://infracollege.vamdemicsystem.black/almalinux9/

## RockeyLinux9
VirtualBoxで使用できそうです
以下のサイトにインストールの仕方が記載されています。
https://qiita.com/Chiramium/items/d4fcae7872bc00928894

## OracleLinux9

以下のサイトにインストールの仕方が記載されています。
https://qiita.com/shimatter/items/c400a01f0ce23956ef73

## CentOS9 Stream

以下のサイトにインストールの仕方が記載されています。
https://tech.willserver.asia/2021/12/15/centos-stream9-%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E6%89%8B%E9%A0%86/
高還元SESの闇を暴く！高年収を望むならフリーランスエンジニアすべき理由

エンジニアの皆さん、高還元SESに魅力を感じていませんか？確かに、安定した仕事量で報酬が得られる点が魅力的です。多くのエンジニアが「これぞ理想の働き方！」と飛びついているのも無理はありません。

でも、ちょっと待ってください。その輝かしい外見の裏に隠された真実をご存知ですか？実は、<b>高還元SESには知られざる「闇」が存在</b>するのです。

本記事では元SES企業エンジニアの私が、高還元SESの実態を徹底解剖します。そしてフリーランスエンジニアと比較して、どちらが有利なのかを明らかにしていきます。

この記事を読み進めれば、あなたのキャリアを左右する重要な情報が手に入ります。エンジニアとしての未来を見据えた選択をするために、ぜひ最後までお付き合いください。

[>> SESは実務経験を積むという面ではオススメの働き方です！詳しくはコチラ](https://taishi-official.com/2020/03/22/75/)

## 高還元SESとは？特徴を紹介

高還元SESは、IT業界で注目を集めている新しい就業形態です。従来のSESモデルを進化させ、エンジニアにより高い報酬還元率を提供することが特徴です。高還元SESの主な特徴は以下の通りです。

- エンジニアへの還元率が70%以上と高い
- 通常のSESの還元率(50~60%)よりも大幅に高い
- 固定費削減により高還元率を実現
- エンジニアのスキルや経験が報酬に直結しやすい

このように、高還元SESは一見するとエンジニアにとって理想的な働き方に見えます。多くのエンジニアが注目し、転職先として検討しているのも納得です。

しかし、これらの魅力的な特徴の裏には、意外な「闇」が潜んでいます。次のセクションでは、高還元SESの隠された側面について詳しく解説します。

## 高還元SESの闇：表面上の魅力の裏に潜む実態

高還元SESには、表面上の高い還元率とは裏腹に、労働者にとって不利な側面が存在します。以下に高還元SESの「闇」と呼ばれる問題点を説明します。高還元SESの問題点は、以下のようなものがあります。

- 実質的な手取りの減少
- みなし残業制度の落とし穴
- 不透明な労働条件

[>> 高還元SESの問題点詳細はコチラ！](https://taishi-official.com/2024/08/27/2826/#toc3)

## 【フリーランスがオススメ】高還元SESとフリーランスエンジニアを徹底比較

エンジニアにとってより有利な選択肢は何でしょうか？ここでは似たような働き方である、高還元SESとフリーランスエンジニアのメリット・デメリットで徹底比較していきます。

[>> 高還元SESとフリーランスエンジニア比較表](https://taishi-official.com/2024/08/27/2826/#toc6)

高還元SESとフリーランスエンジニアのメリット・デメリットを比較して、私はフリーランスエンジニアの方がおすすめだと考えます。

[>> 高還元SESよりもフリーランスエンジニアの方がオススメな理由](https://taishi-official.com/2024/08/27/2826/#toc7)

## フリーランスエンジニアを始める3STEP

フリーランスエンジニアを始めるのって、難しいイメージがありますよね。ただフリーランスエンジニアは、思っているよりも簡単に始めることができます。具体的にご紹介すると、以下の3STEPです。

- STEP1：実務経験を積んで退職する
- STEP2：開業届を提出する
- STEP3：フリーランスエージェントを使って案件獲得する

[>> 各STEPの詳細説明はコチラ！](https://taishi-official.com/2024/08/27/2826/#toc9)

## まとめ

本記事では、高還元SESの闇とフリーランスエンジニアの可能性について紹介しました。高還元SESは一見魅力的に見えますが、実際の手取りは予想を下回る可能性があります。しかし「SES＝悪」ではありません。実務経験を積むことが主な目的であれば、特にキャリア初期の方にとっては有効な選択肢と言えます。

[>> SESは実務経験を積むという面ではオススメの働き方です！詳しくはコチラ](https://taishi-official.com/2020/03/22/75/)

一方でフリーランスエンジニアの道を選べば、より高い収入を得られる可能性が高まります。ただし、この道にもリスクは存在します。収入の安定性や福利厚生の自己負担など、考慮すべき点は多々あります。この記事が、あなたのキャリア選択の一助となれば幸いです。

### おまけ

https://qiita.com/taishi_will_be/items/70a8ce8938944286b487

https://taishi-official.com/it-freelance/

<strong>＼Follow me／</strong>

- X（旧Twitter）：https://x.com/taishi_it_blog
- Instagram：https://www.instagram.com/taishi_will_be/
- YouTube：https://www.youtube.com/@Engineer_ILLBE
- TikTok：https://www.tiktok.com/@taishi_will_be
- note：https://note.com/taishi_wii_be/

<br>

最後にいいねお願いします:thumbsup:
【AWS-SAA勉強記】第6回_Amazon RDS編

この記事は作者本人がAWS-SAAの学習を通じて、曖昧や覚えづらい部分をサービス単位でまとめたものです。
特に、概要だけではイメージがわきづらいので、できるだけユースケースを活用して理解しやすいようにしています。
教材はSHOEISHAの[AWS教科書 AWS認定ソリューションアーキテクトアソシエイト テキスト＆問題集](https://www.amazon.co.jp/AWS%E6%95%99%E7%A7%91%E6%9B%B8-AWS%E8%AA%8D%E5%AE%9A%E3%82%BD%E3%83%AA%E3%83%A5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%88%E3%82%A2%E3%82%BD%E3%82%B7%E3%82%A8%E3%82%A4%E3%83%88-%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%EF%BC%86%E5%95%8F%E9%A1%8C%E9%9B%86-%E7%85%A4%E7%94%B0-%E5%BC%98%E6%B3%95/dp/4798183261/ref=sr_1_5?crid=3FF4OG65DFJ67&dib=eyJ2IjoiMSJ9.T249byXp1rsbDxkYXfxXb6fI4BUDNVOMSaquZL-1mVpPGu6oOTJAj19zZAYJR86Jon6ca0-q7sg_Ial5s1cea15f4gmNEJG8LyNQfNCbzfRWbdc3QShULjB2kryq34xDUkL-inBJMmFaiNYCb3lq0OcIRowzNObcgxFyIO96gEzEfcAYd2dxcSG6AHyl5e2DAQpdDy0xOEQZb_sRAX47vahzwyOMS8huPEScwArE3A0.zBHSxW-BjHBATnQ5vd4s6NikPxikuDNRnvEEGpF7d6A&dib_tag=se&keywords=aws+%E3%82%BD%E3%83%AA%E3%83%A5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%88+%E3%82%A2%E3%82%BD%E3%82%B7%E3%82%A8%E3%82%A4%E3%83%88&qid=1724027719&s=books&sprefix=AWS%2Cstripbooks%2C195&sr=1-5)を参考にしています。

## Amazon RDSに関する曖昧な部分
Amazon RDSはリレーショナルデータベースのサービスです。
Amazon RDSで曖昧になりがちな部分は以下の通りです。（あくまでも私個人が曖昧であると感じた部分です）
* Amazon RDS Proxy
* 認証情報の格納場所
* Amazon RDSの暗号化

## Amazon RDS Proxy
Amazon RDS Proxyは、Amazon RDS向けの高可用性フルマネージド型データベースプロキシです。
RDS Proxyは、関連付けられたAmazon RDSのDBインスタンスに対して、**接続プール**を形成します。
また、元のDBインスタンスに障害が発生した時には、別のDBインスタンスに自動的に接続する**フェイルオーバー機能**も備えています。

### 接続プールにより得られるメリット
接続プールとは、**RDS ProxyとDBインスタンス間の多数の接続を同時に開いたままにしておく機能**のことです。
これにより、**アプリケーションからDBインスタンスに対する接続・切断時のCPUオーバーヘッドなどを削減**することができます。

### フェイルオーバー機能により得られるメリット
**接続タイムアウトの回避や、接続の不足の解消などのデータベースへの接続・切断に起因するエラーの削減**が可能です。


## 認証情報の格納場所
アプリケーションかAmazon RDSに接続するときの認証情報（アクセスキーID・シークレットアクセスキー）については、アプリケーションコードに埋め込んだ場合、情報漏洩につながる可能性があります。
認証情報は、**パラメータストア**もしくは**AWS Secrets Manager**で管理することが望ましいです。

- **パラメータストア**
    - パラメータストアは、**AWS Systems Managerの一機能**として提供されており、各種設定情報などを一元管理することができます。
- **AWS Secrets Manager**
    - ID/パスワードなどのシークレットを管理するためのサービスとして提供されています。

### パラメータストアとAWS Secrets Managerの使い分け
- **AWS Secrets Manager**
    - 自動ローテーション: Secrets Managerは、データベースの認証情報を自動的にローテーションする機能を提供します。これにより、セキュリティが強化されます。
    - 統合: Secrets Managerは、AWS Lambdaや他のAWSサービスと簡単に統合でき、シームレスな運用が可能です。
    - アクセス制御: IAMポリシーを使用して、誰がどのシークレットにアクセスできるかを細かく制御できます。
- **AWS Systems Manager Parameter Store**
    - コスト: Parameter Storeは、基本的な使用において無料で利用できるため、コストを抑えたい場合に適しています。
    - シンプルな管理: パラメータの管理がシンプルで、設定や取得が容易です。
    - セキュリティ: パラメータは暗号化されて保存され、IAMポリシーでアクセス制御が可能です。

つまり、**自動ローテーションが必要な場合はAWS Secrets Manager**を、**シークレットやシークレット以外のアプリケーションの設定情報などを無料で一元管理したい場合はパラメータストア**を選択することが推奨されます。


## Amazon RDSの暗号化
**AWS KMSを使用することにより、Amazon RDSのDBインスタンスの暗号化が可能**です。

また、暗号化されていないDBインスタンスのスナップショットから、暗号化されたスナップショット及びDBインスタンスを作成する方法については以下の手順を実施します。
1. スナップショットをコピーし、コピーするときに暗号を有効か、AWS KMSを指定
1. 暗号化されたスナップショットから暗号化されたDBインスタンスを復元


## まとめ
本記事では、以下についてまとめました。
* Amazon RDS Proxy
* 認証情報の格納場所
* Amazon RDSの暗号化

次回は、[【AWS-SAA勉強記】第7回_Amazon DynamoDB編](https://qiita.com/sknp/items/542feff2b590a6d07c73)です。
【Rails】update_attributesが使用できない

## はじめに
Railsのアップデート中にupdate_attributesを使用している箇所でエラーが出たので、その対応をまとめます。

## 問題
以下のように、update_attributesを使用するとエラーが出ます。
```ruby
@user.update_attributes(attributes)
```

## 解決方法
Rails6.1からupdate_attributesは使用できなくなりました。
代わりにupdateを使います。
```ruby
@user.update(attributes)
```

## 参考
https://mrradiology.hatenablog.jp/entry/2023/09/29/213221
OpenCV videowriter fourccと拡張子で簡易ベンチマーク

## OpenCV videowriter で作成する動画の中間ファイルがデカすぎる
下記のアプリを作成したのですが、OpenCV videowriterで作成している中間ファイルの動画ファイルが大きく、その後の音声データをつける処理に影響が出ている、と感じていました。

https://qiita.com/calcMCalcm/items/178901c752f6cef481f1

当初は、fourcc mp4vを使っていたのですが、ciscoのopen-h264.dllを利用したmp4の方が（正規っぽくて）ファイルサイズが小さいのでは？？と考えたのですが、実際にやってみると違和感を感じました。
実際にどれがファイルサイズが小さく、また中間動画ファイル作成時の負荷が小さそうか、確認した方がいいと思い、簡単ですが調査しました。

## fourcc（拡張子）ごとの簡易ベンチマーク
### 環境
Windows11 64bit
python 3.11
opencv-python 4.10.0.84
intel 11400F
geforce 4700tiSUPER 16GB
MEM 32GB

### ベンチマークに用いた動画
大きい動画でも試したのですが、傾向は同じだったので、小さいファイルで確認しています。
| 拡張子 | ファイルサイズ | フレームレート（FPS） | ビットレート（kbps） | 時間（秒） | 縦 | 横 |
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
| mp4  | 47.5MB  |  60 |  19756 | 20  | 2560  | 1080  |

動画はhandbrakeで作成したもので、H.265 NVencで作成したものです。

### エントリーしたfourccと拡張子
上記のmp4v、cisco open-h264以外にも、使えるかもしれないかな？と思ったものをエントリーしました。
OpenCVでfourccと拡張子を設定すると、 **"そんな組み合わせないから俺(opencv内ffmpeg)が拡張子に合わせてコレに変えといたぜ"** と言われることが結構あり、その辺も出ないように言われるがままの組み合わせに変更して設定しています。
```cmd:例
OpenCV: FFMPEG: tag 0x5634504d/'MP4V' is not supported with codec id 12 and format 'mp4 / MP4 (MPEG-4 Part 14)'
OpenCV: FFMPEG: fallback to use tag 0x7634706d/'mp4v'
```
| fourcc | 拡張子 | テスト前の俺下馬評 |
|:-:|:-:|:-:|
| mp4v  | .mp4  | 最初はファイルサイズが大きいと感じたが、実際はどうなんだ？？  |
| avc1  | .mp4  | CISCO openh264-1.8.0-win64.dll　本当にこれがいいのかな？  |
| vp09  | .mp4  | VP9が選べた。ファイルサイズは強そうだが、果たして？  |
| FMP4  | .avi  | xvidだと思ったけど違う？FMP4？まぁイマドキAVIはないだろうな  |
| XVID  | .wmv  | WMVも試してみたかった。XVIDが通った（え？）。果たして？  |
| mp4v  | .wmv  | WMVはmp4vでも通った。果たして？  |
| FMP4  | .wmv  | WMVはFMP4でも通った。果たして？  |

### 結果
ファイルサイズが小さく、動画処理のフレームレートが速い（数値が大きい）ものが望ましい。
FPSはGPUによる推論を含むなので多少振れは発生するとは思われるが、動画圧縮の負荷
| fourcc | 拡張子 | ファイルサイズ(KB） | 動画作成時FPS | 備考 | 
|:-:|:-:|:-:|:-:|:-:|
| mp4v | .mp4 | 100842 | 17.78 |  | 
| avc1 | .mp4 | 170402 | 16.45 | CISCO openh264-1.8.0-win64.dll利用 | 
| vp09 | .mp4 | 中止 | 1.0程度 | あまりに遅かったので中止 | 
| FMP4 | .avi | 100894 | 17.63 |  | 
| XVID | .wmv | 101686 | 17.68 |  | 
| mp4v | .wmv | 101686 | 17.83 |  | 
| FMP4 | .wmv | 101686 | 18.07 |  | 

## 考察
CISCO openh264-1.8.0-win64.dllを利用するのが良いだろうと思い込んでいたが、mp4vと比べるとこちらの方がファイルサイズが大きかった。
vp09は圧縮処理の負荷が大きいのかあまりに遅かったので途中で中止。（その割にはシステムモニターでCPU負荷がMAXではないのだが）
FMP4＋.aviは、当初の期待を裏切り好成績。mp4v＋.mp4と大きな差はなかった。
wmvは最近見かけないが、もしかしたらダークホース的な位置づけになるか？と期待していた。大きな遜色はないが、積極的に採用するほどではないかな？という印象。ファイルサイズはfourccに何を選んでも同じなのはちょっと不思議（そういうもの？）。
OpenCV内のffmpegがかなり有能で拡張子に適したfourccを選んでくれるので、それに乗っかっておくスタイルが良さそう。
fourcc FMP4は知らなかったが、ラッパー的な振る舞いをするものなのかな？

https://fourcc.org/fmp4/

## 結論
アプリでの一時の動画書き出しには、mp4v＋.mp4か、FMP4＋.aviにする予定。aviの方が次の音声付加で有利か？
CISCO openh264-1.8.0-win64.dllの採用はやめておく。
OpenCV videowriterでは、mp4v＋.mp4 が王道で間違いない選択だったことを再確認できた。
顧客の初回購入金額を列として追加する(SPSS Modeler データ加工逆引き4-25)

# 顧客の初回購入金額をフィールド（列）として追加する

![スクリーンショット 2024-08-20 14.10.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/e9c0a21a-e2bc-de3f-29a5-b109f0fc5078.png)

## 1.想定される利用目的

・顧客の行動安定性を示す特徴量の作成
・行動予測モデルのための特徴量の作成

## 2.サンプルストリームのダウンロード

https://github.com/yoichiro0903n/blue/raw/main/first_value.str

## 3.サンプルストリームの説明

![スクリーンショット 2024-08-20 14.10.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/ea4810e6-2abb-ae31-5912-e0ad0515a12f.png)

a.入力するデータは以下の通りです。

![スクリーンショット 2024-08-20 14.12.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/e5f1f837-c79e-0a9a-6c6c-a7fcb54d13a4.png)


b.[重複レコード]ノードを編集します。

![スクリーンショット 2024-08-20 14.13.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/613fc605-dc05-4999-7b1b-0488d23e752e.png)

[プレビュー]します。

![スクリーンショット 2024-08-20 14.14.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/924a74cc-298b-a554-ee32-3a31c7fd500c.png)

c.[フィルター]ノードを編集します。

![スクリーンショット 2024-08-20 14.14.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/38176d5d-0f63-07b6-d342-cb74a548fdca.png)

d.[レコード結合]ノードを編集します。
![スクリーンショット 2024-08-20 14.14.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/3a6d1fe2-a933-0acd-1065-030f7e070d3a.png)

e.[ソート]ノードを編集します。

![スクリーンショット 2024-08-20 14.14.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/7e79ba1a-9678-8d77-f8a0-92c009e78b1d.png)

[プレビュー]します。

![スクリーンショット 2024-08-20 14.15.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/4ced309b-2e4e-bcc6-d3a8-df8962cc2e5a.png)

f.[フィールド作成]ノードを編集します。

![スクリーンショット 2024-08-20 14.15.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/821823df-1a63-f459-bf4e-29a8c7816185.png)

[テーブル]を実行します。

![スクリーンショット 2024-08-20 14.15.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/6062882b-dbca-491e-166c-267d326e3d81.png)

#### 注意事項

テーブル結合時に予期せぬ並びになるので、ソートノードを用いて修正します。

## 4.参考情報

#### ID毎に初回から3回目までのイベントを列に展開する

https://qiita.com/416nishimaki/items/63e47df549fa8ac8582b

#### SPSS Modeler ノードリファレンス目次

https://qiita.com/416nishimaki/private/503037195081d3323eee

#### SPSS Modeler 逆引きストリーム集（データ加工）

https://qiita.com/416nishimaki/private/4bf813e6cba84b2a1008
【Suno AIでつくった楽曲】しろぶりゅーの歌 ver.13 (3拍子、口笛、スキャット、ピアノ、陽気なアレンジ)【動画 2分03秒】【YouTubeチャンネルからの転記です】

この記事は、わたしの[YouTubeチャンネル](https://bit.ly/Yamanaka-YouTube "Living without things. 持たない生き方 手放す生き方")にある公開動画を転記しております。
( どこかのタイミングで、プログラミング-Google Apps Script or iPaaS-Zapier をつかって自動転記させる予定です )

転記のための時間コストを少なくしたいので、文字装飾( Markdown記法 )を極力つかわずに書いております。

こちらが動画内容です👇

***

![01 YouTube再生中の画像 Suno AI _ しろぶりゅーの歌 ver.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/386308/111bdf2e-799c-bce2-eb93-3574e373bcb4.png)




* # 動画URL
    * https://youtu.be/KUdEJNI28Zw

<br>

* # 動画タイトル
    * 【Suno AIでつくった楽曲】しろぶりゅーの歌 ver.13 (3拍子、口笛、スキャット、ピアノ、陽気なアレンジ)【動画 2分03秒】

<br>

* # 動画の説明欄(一部を抜粋)

📅撮影日 = 2024-08-23(金)

Suno AIとは、文章から音楽を生成することができるAI( Text-to-Music-AI )です。
わたしは、2024-04-02(火)に初めてSuno AIで有償プランを契約してから、時々楽曲をつくって遊んでいます。

🎦【Suno AI】文章から音楽を生成するAI( Text-to-Music-AI )で、3分間で2曲、6分間で4曲作りました【試聴可能】1)伴侶の曲 2)税理士の曲【動画 16分11秒】
https://youtu.be/QKfhk4HgQ_g

🎦“Suno AIでつくった楽曲”シリーズ
https://www.youtube.com/playlist?list=PLpQhBHT4oghMLdiSVqwvSs_Z5y0H4VGOe

🎦“効果的にSuno AIを活用するヒント”シリーズ
https://www.youtube.com/playlist?list=PLpQhBHT4oghPuaNOVZn-N53wVvsBkeHdI


今回は、Suno AIでつくった曲を WAV で出力してから、動画編集いたしました。

スロージョギングの途中に、早朝の中目黒で偶然出会った「しろぶりゅー」-ShiroBrew-のテーマソング( イメージソングは和製英語です )を、1人のファンとして自主的につくりました。
つまり「しろぶりゅー」のファンメイドテーマソングです。

ぜひ聴いてみてください。
そして、ぜひみなさんも、あなたが大好きなお店やブランドや企業のために楽曲をつくってみてください！

作曲日:
2024-07-20(土)

Suno AI 契約の種類:
Pro Plan

楽曲の正式名称:
しろぶりゅーの歌 #13

Suno AI Library URL:
https://bit.ly/ShiroBrew-13

Custom Mode: On

Audio Inputs: Not Used

With Vocals:


---


Lyrics(without Meta tags):

真っ白な心

そよ風感じる

コーヒーの香りと
真っ白な心


---


Lyrics & Meta tags:

[Break]

[Intro]

[Whistling]

[Verse]
真っ白な心

[Verse 2]
そよ風感じる

[Chorus]
コーヒーの香りと
真っ白な心

[Whistling]

[Outro]


---


Suno AIへの指示文章( プロンプト/Prompt ): Custom Modeの場合は”Style of Music”を指定します。


🇬🇧English

[Waltz][Female voice][Romantic]


🇯🇵日本語訳

[ワルツ][女性ボイス][ロマンチック]


---


Suno AI 公式URL
https://accounts.suno.ai


SHIROノMONO 公式URL - Instagram
https://www.instagram.com/shiro_nomono


---


✓ 🎥この動画と関連が強いわたしの動画 ↙
　・“Suno AIでつくった楽曲”シリーズ
　https://www.youtube.com/playlist?list=PLpQhBHT4oghMLdiSVqwvSs_Z5y0H4VGOe


　・“効果的にSuno AIを活用するヒント”シリーズ
　https://www.youtube.com/playlist?list=PLpQhBHT4oghPuaNOVZn-N53wVvsBkeHdI


　・“Suno AIで3拍子”シリーズ
　https://www.youtube.com/playlist?list=PLpQhBHT4oghNy-xIeeMZV6D2YAnax9Nzw


　・“しろぶりゅー ファンメイドソング”シリーズ
　https://www.youtube.com/playlist?list=PLpQhBHT4oghPk5-_YwWl499DNAOVKlcvZ


✓ 🎥Shortened URL for this video | この動画の短縮URL ↙
　https://bit.ly/4dY2cSd
自動運転における人工AIの概念

## ニューラルネットワーク
人口ニューラルネットワークデータから複雑な情報を解析する。
画像が認識した特徴をもとに重みづけを行い、インプット情報が何かを判断する。
どのように認識しているかは必ずしもわからない。
車を認識した際に、
車輪、窓、色などを検知する。
その際に、
0.8*車輪+0.2*窓+0*色など。
また、コンピュータ側で認識した特徴から重みづけを調整していく。

## バックプロパゲーション
学習はトレーニングと言われ3つのステップがある。

フィードフォワード、エラー測定、バックプロパゲーション
フィードフォワード
人口ニューロンの値である初期重みをランダム化する。ニューラルネットワークを通じて各画像をフィードして、出力地を生成する。
エラー測定
グラウンドトゥルースラベルとフィードフォワードプロセスによって生成された出力との差のこと。

バックプロパゲーション
フィードフォワードプロセスと同様に、ニューラルネットワークを介してエラーを逆方向に送信する。

3つのステップを繰り返すことで、正確なニューラルネットワークが形成される。

## 畳み込みニューラルネットワーク(CNN)は知覚の問題に適した人口ニューラルネットワークの一種である。
画像行列を1つのきょどあいな業に接続するベクトルに再形成することにより、画像を1次元ピクセル配列に展開できる。しかし、画像のピクセルがピクセル配列に分散し検出が困難になる。
そのため、CNNは入力ピクセル間の空間関係を維持することで解決する。
入力画像上を継続的にスライドさせて情報を収集するフィルターがあり、情報を収集すされるたびに全体画画像の小さな領域のみが分析される。
入力画像全体に畳み込みフィルターを使用することで、エッジと色の情報を使用して車輪、ドア、フロントガラスなどのより複雑な構造を検出する可能性がある。


## Detection and classfication
障害物には動的と静的がある。
静的障害物は壁、木、電柱、建物
動的障害物は歩行者、車両、自転車など
障害物のクラスによって自動運転車両の挙動を変化させる必要があある。
前方の障害物が自転車の場合は速度を落とし、回避。
先行者の場合は追従する形になる。

また、信号機の場合色によって信号機を分類する。
R-CNN, Fast R-CNN, Faster-RCNN, YOLO, SSD
メール署名に画像を挿入する方法




+ [【ヘルプ】Salesforce でメール署名に画像を挿入する方法](https://help.salesforce.com/s/articleView?id=000385763&type=1)

+ [アセット ライブラリからリッチ テキスト領域のカスタム電子メール署名フィールドにロゴ画像を挿入する必要があります。](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007ifhkfSAA)

:::note
 画像をアップロードした後、画像を開いて公開リンクをコピーします。このリンクは通常、ファイルの詳細ページからアクセスできます。

- コピーした URL は次のようになります: https://your-instance.salesforce.com/sfc/servlet.shepherd/version/download/068XXXXXXXXXXXX?operationContext=S1

テキストテンプレート内の画像を参照するには、次のHTML形式を使用します。

```
<img src=" https://your-instance.salesforce.com/sfc/servlet.shepherd/version/download/068XXXXXXXXXXXX?operationContext=S1 " alt="あなたのロゴ" width="150px">
```


:::


# 関連

+ [Formatting email signature fields - Getting the correct Font](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000Em0jSSAR)
paizaキャンペーン問題 Bランク 長テーブルのうなぎ屋【JavaScript】

[paiza×Qiita記事投稿キャンペーン](https://qiita.com/official-events/9ab96aa95d62fe3cbdd7) の [長テーブルのうなぎ屋](https://paiza.jp/works/mondai/b_rank_skillcheck_sample/long-table) をJavaScriptで。

大まかな処理は以下の通り。

* ①全座席の空席状況 及び ②座りたい客の並び を2進数で扱う
* ①に対して②をビットANDで確認、入り込む余地があれば①に②をビットORして更新
* 立っているビット数を返して終了

ビット演算を使うことで、1グループ内のメンバー全員の着席可否チェックをループを使わず1回で判定することができます。

例として座席数6とした場合、**席の状態**を`0b000000`とします。
(ビット配置が分かりやすいよう6桁で示しましたが、実際には単に0で初期化するだけです)

まず4人のグループが入店、2番目の席から座ろうとしているとします。
`1`を`4`ビット左シフトして`0b10000`、そこから`-1`することで`0b1111`と、2進数で1が4つ並んだ値になります。
2番目の席から確保したいので`2-1`ビット左シフトして`((1 << 4) - 1) << (2 - 1)` で `0b11110`を**確保したい席**とします。
**席の状態**と**確保したい席**をビットANDすると `0b000000 & 0b11110`は`0`で空席であることが分かります。
空席なので、**席の状態**に**確保したい席**をビットORして更新すると、**席の状態**は `0b000000 | 0b11110` で `0b011110` になります。

次に2人のグループが5番目からの席を確保しようと入店したとします。
**確保したい席**は `((1 << 2) - 1) << (5 - 1)` で `0b110000`。
`0b011110 & 0b110000`は`0b10000`で0ではない(立っているビット=確保したい席のうち既に埋まっている席 が含まれている)ので更新はしません。

これをグループ数分繰り返し、最後に `c.toString(2).match(/1/g).length` で人数を出します。

実際のコードでは`Number`ではビット数が足りないので`BigInt`を使用し、最後と1番目の座席に跨る部分の処理を簡略化するために、席の状態、確保したい席ともに重複して2周分持たせています。
（入力データによっては3周分に近くなるケースもあります）

```js:
let c = 0n, n = BigInt, h, d, x, y;
process.stdin.some(l => {
  (0 + l).split('\n').map((s, i) => {
    const [a, b] = s.split(' ');
    if (s && i)
      c & (d = (x = (1n << n(a)) - 1n) << (y = n(b - 1)) | x << h + y) || (c |= d);
    else
      h = n(a);
  });
  console.log(c.toString(2).match(/1/g).length / 2);
});
```

```js:可読性優先
let seatStatus = 0n; // 座席の状態
let seatsCount;      // 座席数
process.stdin.some(l => {
  (0 + l).split('\n').forEach((s, i) => {
    const [a, b] = s.split(' ');
    if (s && i) {
      let desiredSeats =         // 確保したい席
        ((1n << BigInt(a)) - 1n) // 人数 (3人なら0b111のように立ったビットの並びで表現)
        << (BigInt(b - 1));      // 確保したい位置の先頭

      // 確保したい席を2周分重複させる
      desiredSeats |= desiredSeats << seatsCount;

      // ビットANDで空席確認して空席ならビットORで更新
      if (!(seatStatus & desiredSeats)) seatStatus |= desiredSeats;
    }
    else
      seatsCount = BigInt(a); // 座席数
  });
  console.log(seatStatus.toString(2).match(/1/g).length / 2);
});
```

```js:短縮版
c=0n;process.stdin.some(l=>{(0+l).split`\n`.map((s,i)=>([a,b]=s.split` `,s&&i)?c&(d=(x=(1n<<n(a))-1n)<<(y=n(b-1))|x<<h+y)||(c|=d):h=(n=BigInt)(a));console.log(c.toString(2).match(/1/g).length/2)})
```
GradleとMavenの違い

## GradleとMavenの違い

### 1. 設定ファイルの形式
- **Maven**: XML形式の`pom.xml`ファイルを使用します。設定が厳密に定義されており、階層的な依存関係やプラグイン設定がXMLタグで指定されます。
- **Gradle**: GroovyまたはKotlin DSLを使用したスクリプトベースの`build.gradle`または`build.gradle.kts`ファイルを使用します。コードとして設定を書くので、柔軟性が高く、より直感的に記述できます。

### 2. パフォーマンス
- **Maven**: 依存関係やビルドタスクをシーケンシャルに処理するため、ビルド速度が比較的遅いことがあります。
- **Gradle**: インクリメンタルビルドや並列処理が可能で、キャッシュ機能も備えているため、同じビルドを繰り返す場合に高速です。

### 3. 柔軟性と拡張性
- **Maven**: 設定が厳格な分、標準的なプロジェクトでは簡単に使えますが、カスタマイズが難しい場合があります。
- **Gradle**: スクリプトベースのため、複雑なビルド処理を簡単にカスタマイズできます。また、プラグインの開発や導入も容易です。

### 4. 学習曲線
- **Maven**: XMLベースなので直感的で学習しやすい一方、カスタマイズの際に複雑さが増すことがあります。
- **Gradle**: スクリプト言語（GroovyやKotlin）を学ぶ必要があり、柔軟な分、初心者には少し難しいと感じるかもしれません。

### 5. コミュニティとエコシステム
- **Maven**: 歴史が長く、多くのライブラリやフレームワークがMavenを公式サポートしています。
- **Gradle**: 最近のプロジェクトではGradleの採用が増えており、Android開発の標準ビルドツールとしても採用されています。

### まとめ
- **簡便さと安定性を重視するならMaven**、**柔軟性とパフォーマンスを重視するならGradle**が適しています。プロジェクトの規模や特性に応じて使い分けると良いでしょう。
重複しているデータがあればINSERTをさせないようにする[MySQL, Go]

データベースのレコードの挿入を自動で行うプログラムを作っていた際に、同じデータがあったら挿入させないようにするにはどうしたらいいのかわからなかったので調べて実装してみました。

# コード
実際に実行するSQLクエリは下のようになっています。
```sql
INSERT INTO musics (music_name, composer,createdAt,updatedAt) 
SELECT ?,?,?,? WHERE NOT EXISTS (SELECT 1 FROM musics WHERE music_name = ?, AND composer = ?)
```
これはサブクエリで同じデータがないか確認し、存在しなければ実行するように条件分岐させています。

:::note
#### サブクエリ
サブクエリとは,sqlクエリの中にsqlクエリを書くことを言います。
上のクエリでは、`WHERE`文以降にある()で囲まれている部分がそれに該当します。
:::

上のクエリにおけるサブクエリ内では、`SELECT 1`と書かれている部分があると思います。

これは、実際には以下のように動作します。
```
mysql> SELECT 1 FROM musics;
+---+
| 1 |
+---+
| 1 |
| 1 |
| 1 |
| 1 |
| 1 |
| 1 |
| 1 |
| 1 |
| 1 |
| 1 |
| 1 |
| 1 |
| 1 |
| 1 |
+---+
14 rows in set (0.00 sec)
```
このようにカラムに1を指定すると、レコードの件数分１が返されることになります。
>SELECT * よりも早いという話がありますが、結果はわからないです

それを`WHERE`文で指定して件数分、1を表示させています。

加えて、`WHERE NOT EXIST`文で件数が０かどうかを調べています。
件数が0であると<font color="red">存在するものがない</font>ということでTrueとなり、`INSERT`が実行できます。件数が０より上であると<font color="yellow">存在するものがある</font>ということでFalseとなり挿入することができません。

また、挿入の際に`VALUES`ではなく、`SELECT`するのは<INS>条件付き挿入</INS>を行っているためです。

今回、このクエリをGoで行ったのですが、実際に使ったコードは下のようになっています。

```Go
import (
	"context"
	"database/sql"
	_ "github.com/go-sql-driver/mysql"
 )
 
func (m *MusicRepository) Register(ctx context.Context, music model.Music) error {
	query := `INSERT INTO musics (music_name, composer,createdAt,updatedAt) 
SELECT ?,?,?,? WHERE NOT EXISTS (SELECT 1 FROM musics WHERE music_name = ?, AND composer = ?)`

	_, err := m.db.ExecContext(ctx, query, music.MusicName, music.Composer, time.Now(), time.Now(), music.MusicName, music.Composer)

	if err != nil {
		//log.Fatal("database can't insert music", err)
		return fmt.Errorf("Error register music :%s", err)
	}

	return nil
}
```

`?`ってなんだと思われる方がいるかもしれませんが、?の部分はプレースホルダーで、後から数値を代入できるようにしています。
そのクエリを`ExecContext`メソッドで実行しています。

ぜひお役に立てば嬉しいです。
[Excel 関数] "第◯ ✕曜日"を求める

### はじめに
今日、仕事で使おうとしたときに
時間がないのでMicrosoftのGPT-4に式を聞いたんですけど嘘つかれました。
結局自分で考えました。たまに詰めが甘いコード出すよねあの子…:frowning2:

様々な方法が別サイトに載っているなか記事を書いた理由ですが、
MOD関数を用いた求め方が全然見当たらないためです。

### ざっくり説明
ちょっとタイトルが分かりづらいけど
「第２月曜日」とか「第４木曜日」とかそういう類のものです。

### 予備知識
エクセルのWEEKDAY関数は日付からそれに対応する数字を返す関数です。

第一引数は日付を、第二引数は数字を渡します。
第二引数の数字によって何曜日をどの数字に対応させるかを指示します

|第二引数|日曜|月曜|火曜|水曜|木曜|金曜|土曜|
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|1 (省略時)|1|2|3|4|5|6|7|
|2|7|1|2|3|4|5|6|
|3|6|0|1|2|3|4|5|
|11|7|1|2|3|4|5|6|
|12|6|7|1|2|3|4|5|
|13|5|6|7|1|2|3|4|
|14|4|5|6|7|1|2|3|
|15|3|4|5|6|7|1|2|
|16|2|3|4|5|6|7|1|
|17|1|2|3|4|5|6|7|

今回は一番オーソドックスな**第二引数を 1 として式を書いています**。

### 使用方法／関数(1)
A1セル：**求めたい月の初日**のシリアル値（「2024/8/1」など)
A2セル：第◯週（第２週 → 「2」）
A3セル：✕曜日（水曜日 → 「4」）

```vb
=A1+(A2-1)*7+MOD(A3-WEEKDAY(A1,1),7)
```

### 使用方法／関数(2)
A1セル：**求めたい月のいずれかの日**のシリアル値（「2024/8/24」など)
A2セル：第◯週（第２週 → 「2」）
A3セル：✕曜日（水曜日 → 「4」）

`A1`を`DATE(YEAR(A1),MONTH(A1),1)`に置き換えました。
```vb
=DATE(YEAR(A1),MONTH(A1),1)+(B1-1)*7+MOD(C1-WEEKDAY(DATE(YEAR(A1),MONTH(A1),1)),7)
```

### 使用方法／関数(3)
B1セル：**求めたい年**（「2024 (文字列可)」など)
B2セル：**求めたい月**（「8 (文字列可)」など)
A2セル：第◯週（第２週 → 「2」）
A3セル：✕曜日（水曜日 → 「4」）

`DATE(YEAR(A1),MONTH(A1),1)`の"年"と"月"を個別に指定したい場合こちらです。
etc `DATE("2024","8",1)`
```vb
=DATE(B1,B2,1)+(A2-1)*7+MOD(A3-WEEKDAY(DATE(B1,B2,1)),7)
```

### 仕様等
特になし

### 注意点
- (1)の式に月初日以外の日付を渡すと異常な値が返ってきます

### その他
オマケなんですけど、日付から第◯ ✕曜日を求めるには
`=CEILING(DAY(A1)/7, 1)` (第◯週)
`=TEXT(A1, "aaa")` (✕曜日)
の組み合わせで実現できます。

A1セル：求めたい月のシリアル値（「2024/8/20」など)
```vb
="第" & CEILING(DAY(A1)/7, 1) & TEXT(A1, "aaa") & "曜日"
'もしくは
="第" & CEILING(DAY(A1)/7, 1) & TEXT(A1, "aaaa")
```
→ 「第2木曜日」「第3火曜日」のような出力がされます
このフォントは、固定ピッチフォントなのか？

# 固定ピッチフォントか？

あやしぃ…。
実際のサイズを調べることにした。

## 描画サイズから固定ピッチかどうか判定してみる
```is_monospace_font.py
import sys
from PIL import ImageFont, ImageDraw, Image

def is_monospace_font(font_path, test_string="iW"):
    try:
        # フォントサイズを指定してフォントオブジェクトを作成
        font = ImageFont.truetype(font_path, 40)

        # 描画用の領域を準備
        image = Image.new("RGB", (512, 512))
        draw = ImageDraw.Draw(image)

        # テストする文字列の各文字の幅を取得
        widths = [draw.textbbox((0, 0), char, font=font)[2] for char in test_string]

        # すべての文字の幅が同じかどうかを判定
        if len(set(widths)) == 1:
            return True
        else:
            print(widths)
            return False
    except Exception as e:
        print(f"エラーが発生しました: {e}")
        return False

if __name__ == "__main__":
    if len(sys.argv) < 2 or len(sys.argv) > 3:
        print("使用方法: python script_name.py <フォントのパス> [テスト文字列]")
        sys.exit(1)

    font_path = sys.argv[1]
    test_string = sys.argv[2] if len(sys.argv) == 3 else "iW"

    if is_monospace_font(font_path, test_string):
        print(f"このフォントは固定ピッチフォントです（テスト文字列: '{test_string}'）。")
    else:
        print(f"このフォントはプロポーショナルフォントです（テスト文字列: '{test_string}'）。")
```

## 使い方

調べたいフォントのファイルパスと文字幅を調べたい文字で判定します。

```shell
python is_monospace_font.py path/to/font_name.ttf " .1234567890"
```
SQLインジェクションとその対策について

なんだかんだしている間にqiitaで投稿する機会を失っていたので、細々と表題についてまとめていきたいと思います。

きっかけ
-----------
身近なところでSQLインジェクションが起こってしまったため、これを機会に興味を持ったというのが理由になります。

SQLインジェクションとはなにか
-------

IPAにはこう記されています

>データベースと連携したウェブアプリケーションの多くは、利用者からの入力情報を基にSQL文（データベースへの命令文）を組み立てています。ここで、SQL文の組み立て方法に問題がある場合、攻撃によってデータベースの不正利用をまねく可能性があります。このような問題を「SQLインジェクションの脆弱性」と呼び、問題を悪用した攻撃を、「SQLインジェクション攻撃」と呼びます。


SQLインジェクションの割合について調べていたところ、ある記事によれば11％、12％ほどの割合である
1700万件というところで昨年度から攻撃件数が3倍までに増えたという記事を見たので、安易にサーバー攻撃ができることで脆弱性のあるシステムが放置されたままの現状が多い今、件数が増えてきている要因の一つではないのでしょうか。

どのようにSQLインジェクションが起こってしまうのか
=======

まず攻撃者は脆弱性のあるwebアプリケーションを探すところから始めます。

脆弱性のある可能性があるwebアプリケーションというのはダークウェブマーケット等で安易に入手することもできるっぽいので、どこでデータが漏れているかが分からない大規模開発やセキュリティルールがルーズだったりすると結構危ないということが分かりますね


脆弱性のあるwebアプリケーションを見つけた場合、SQLインジェクション攻撃が起こる場合、情報をサーバーに送信されることが多い【入力フォーム】などから**不正なSQL文**を入力されて事態が起こってしまいます。

不正なSQL文とは
======
では一体どのようなSQL文を入力されると不正なSQL文が成立してしまうのか


`SELECT * FROM hoge_users WHERE id = 'hogehoge';`

例えば上記はidがhogehoge　だった場合に  `hoge_users`のレコードをとってこれる処理が上記の処理になります。

しかしこれでは　**不正なSQL文**が起こってしまいます。

以下が不正なSQL文に書き換えられた処理となります。

`SELECT * FROM hoge_users WHERE id = 'MOKE' OR 'MOKE' = 'MOKE';`

以下の記述では条件が常にtrueとなってしまうので命令が実行されるとデータベースから全てのユーザー情報が抽出されてしまいます。

`'MOKE' OR 'MOKE' = 'MOKE';`



どのように対策していくか
===
プレースホルダ－の利用
-------
インジェクション対策として開発者ができる初めのアクションとしてはプレースホルダ－を利用することです。

プレースホルダ－はSQL文で**値に変化がある部分に用いる**場面で使用します。

プレースホルダ－をインジェクション対策として採用することで、入力された値は文字列として入力されているので不正なSQL文が入力されたとしてもエスケープされるのです。



エスケープ処理
----
データベースが持っている特殊記号を無効化する処理のことをエスケープ処理と呼びます。
具体的に言うと[']["][;]→["][""][\\]として記号の意味を無効化することができます。

しかし使用しているDBによって扱い方が変わってくる場合もあるとのこと


WAFの導入
==
WAFとはWeb Application Firewall　の略称で　サイバー攻撃を防御するための対策ツールの一つとなりまし。

アプリケーション通信の内容を1つずつ監視を行い、不正なアクセスがあった場合、遮断する効果を持っています。

SQLインジェクション攻撃の為の不正なSQL文が検出された場合でもWAFが検知する機能を持っています。

以上が今回のSQLインジェクションにおける自分が学んだ対策法になります。

投稿の頻度が下がらないように継続を頑張ります
突然の死 ずれる問題


「突然の死」というAAネタがあります。
で、これをサイトやSNSのコメントで書くとずれます。

＿人人人人人人＿
＞　ああああ　＜
￣Y^Y^Y^Y^Y^Y^￣

何故こうなるのかというと昔の2chのフォント設定と他のプラットフォームのフォント設定が異なるからです。

今はみんなそんなことを考えずにこの吹き出しを使っています。
そして、ずれます。
ずれるのは嫌ですね。

じゃあどうすんのって話ですが、`^`を消して`Y`を`Ｙ`に変えれば多少はマシになります。
ただ、それでも環境によってはずれるかもしれません。

＿人人人人人人＿
＞　ああああ　＜
￣ＹＹＹＹＹＹ￣

終わり。

## おまけ

https://mogamoga1024.github.io/ZurenaiTotuzenNoSiGenerator/
Laravel側でのIPアドレスによるアクセス制御

# IPアドレスによるアクセス制限とは
業務系Webアプリケーション構築時には、「特定のIPアドレスからのアクセスのみ許容したい」といった要件はありがちかと思います。
通常、インフラ側で制御すれば良い話ではあり、AWSであれば下記の方法で設定可能です。
- ALBのリスナールール
- ネットワークACL
- セキュリティグループ

# Webアプリケーション側で実装する必要性
前項の通り、AWSで設定することにより、簡単に実施できます。
しかし、下記のケースではどうでしょうか。
- ユーザーが二種類ある(user, admin)
- adminの中でも権限が分かれている
- adminの特定の権限のみIPアドレスによるアクセス制限を実施したい

「adminのみIPアドレスを制限したい」ということであれば、ALBのリスナールールでパス指定することにより、なんとかなりそうです。
厄介なのが、「adminの特定の権限のみ」という部分です。ログイン認証後しか判定できないため、Webアプリケーション側で実施する必要があります。

# 実装方法
MiddleWareを使って実装していきます。

### MiddleWare作成
`App\Http\Middleware\IpRestrictionMiddleware.php`を作成します。

```php:IpRestrictionMiddleware.php
class IpRestrictionMiddleware
{
    public function handle($request, Closure $next){

        //開発環境以外 && 権限チェック
        if(config('app.env') !== 'local' && Auth::guard('admin')->check() && Auth::user()->role === Admin::ROLE_RESTRICTION){
            
            //IPアドレストを比較
            if(in_array($request->ip(), Admin::IP_ADDRESS_LIST) === false){
                Auth::guard('admin')->logout();
                abort(404);
            }
        }

        return $next($request);
    }
   
}
```
`config('app.env') !== 'local`の判定を入れることで、開発環境ではアクセス制限を無効化できます。
今回は、`Admin::ROLE_RESTRICTION`にアクセス制限をする権限を記載している体ですが、フラグ的なカラムの追加や、判定式にハードコーディングでもOKです。
同じく、`Admin::IP_ADDRESS_LIST`にアクセス可能なIPアドレスを記載している体ですが、`IpRestrictionMiddleware`に記載、IPアドレス自体をテーブルに保持してもOKです。
ただし、テーブルに保持した場合は、MiddleWareを通過する毎にDBへのアクセスが発生するため注意してください。

アクセス制限をする権限で、IPアドレスが異なる場合には、ログアウト実施後に404が表示されます。
404ではなく、別画面に誘導したい場合には、`return to_route(xxx)`を記載してください。(Laravelのバージョンにより記載の差異あり)

### Kernel.phpへ記載
`App\Http\Kernel.php`に先ほど作成したMiddleWareを追記します。
```php:Kernel.php
protected $routeMiddleware = [
    'auth' => \App\Http\Middleware\Authenticate::class,
    #...
    'ip.restriction' => \App\Http\Middleware\IpRestrictionMiddleware::class, #追記
];
```
上記を追記することで、`web.php`に記載する準備が整います。

### web.php
`web.php`のMiddleWareを実行させたい箇所に記述をしていきます。
```php:web.php
# 配下に一括で適用
Route::group(['prefix' => 'admin', 'middleware' => ['ip.restriction']], function () {
    #...
});

# 個別で適用
Route::get('/hoge',[App\Http\Controllers\Admin\HogeController::class, 'index'])->name('admin.hoge')->middleware('ip.restriction');
```
実装は以上になります。

# まとめ
MiddleWareを使うことで既存のWebアプリケーションにも簡単にアクセス制限を追加できます。
記述の仕方や実現方法は様々あるかと思いますので、参考程度に見て頂けると幸いです。
最後までお付き合いいただき、ありがとうございました。
【ProxmoxVE】偶数ノードクラスタに関する検討

[【ProxmoxVE】偶数ノードクラスタでのauto_tie_breaker検証](https://qiita.com/i_bushclover/items/b84ca13e8727ad73f53b)
[【ProxmoxVE】偶数ノードクラスタでのlast_man_standing検証](https://qiita.com/i_bushclover/items/e74e0ae3b53d87f6b275)
の2つの検証結果を踏まえて、偶数ノードに関する考えをまとめてみます。
本番環境を想定した内容になります。

開発環境や検証環境であれば、障害発生時も可能な限り稼働継続させる目的で、ノード数に限らずlast_man_standingを設定するのが良いかなと思います。
いっそクラスタを組まないという選択肢もありますが、ノード数が増えてくると管理が面倒になりそうです。

### ノード数の決め方
まず、仮想基盤のノード数の決め方についてです。
観点は様々あると思いますが、必要なリソース量を満たすノード数＋障害を許容するノード数＋メンテナンス時に停止を許容するノード数、という感じで決めることになると思います。
例えば、必要なリソースが2ノード分・1ノードの障害を許容・メンテナンス時に1ノード停止を想定する場合は合計4ノード、必要なリソースが4ノード・2ノード障害を許容・メンテナンス1ノードであれば合計7ノードというように決めるのがよいでしょう。

ProxmoxVEの場合、バージョンアップが速いためメジャーなHWベンダーのサーバを利用する場合はHWの保守期間中に1回はバージョンアップを検討することになると思いますので、それに備えてメンテナンス用に1ノード追加しておく、というのは悪くない考え方かなと思います。

### 4ノード構成について
最低限必要なリソースが2ノードで足りる場合、1ノードの故障を許容し、メンテナンス用に1ノード追加すると4ノードとなるため、あり得る構成だと思います。
4ノードクラスタのデフォルト状態ではQuoram 3となってしまうため、本記事冒頭のリンクを貼った記事の検証結果を踏まえてlast_man_standingを採用するのが良いと思います。
スプリットブレイン対策にはなりませんが、NW冗長化等でスプリットブレインが起きにくい構成とすることは可能だと思います。
また、どうしてもlast_man_standingを使いたくない場合やスプリットブレイン対策を取りたい場合は
* 1ノード追加して5ノード構成にする（予算が許せば）
* 4台のProxmoxVEとは別に投票権を持つノードを用意する（RaspberryPiなどでも可能なようですが、対障害性の考慮が必要でしょうか）
* Quoram Diskを設定する（特にHCI構成にしようとしている場合、このためにストレージを用意する？）
あたりが対策になると思いますが、それぞれ一長一短ありますね。

### 6ノード以上の偶数ノード構成について
6ノード以上の偶数台構成で50%の障害を許容したい場合は、1ノード減らして奇数台構成にするのが良いと思います。
例えば、6ノード構成で3ノードまで障害を許容させたいと考えているようであれば、5ノードに減らしても耐障害性・運用性とも大きく落ちることはないでしょう。
そのうえでどうしてもという場合は、auto_tie_breakerよりは4ノード構成と同じくlast_man_standingを採用して、最小ノード数を割らないよう運用でカバーするのが良いと思います。
そもそも同時に3ノードが停止する可能性は高くないですし、本番環境で半数が停止するまで対処しないということもないと思いますので、「運用でカバー」と大げさに書くようなことではないかもしれません。

### 多ノードでのクラスタ構成について
観点は少し変わりますが、構成ノード数が多いクラスタ、例えば20ノード構成の場合にQuoramが11だからといって11ノードまで減っても問題ないかというとそんなことはないと思います。感覚的にですが、許容できる障害は4～5ノードくらいで設計するのではないでしょうか。
そう考えると、auto_tie_breakerやlast_man_standingといった設定は少ノード構成だからこそ必要になる設定なのかもしれません。
GitHub基礎まとめ

## はじめに
現場でGitHubを使っていて、ある程度使い方を知ってるつもりでしたが、理解できていない部分もあることに最近気づいたので、改めてgithubについてまとめてみました。

## GitHubとは
GitHubとは、オンラインでソースコードを共有できるものです。
元々はソースコードのバージョン管理ができる「Git」というシステムを使っていたのですが、Gitを用いてオンラインで管理できるようにしたり、Gitにはない便利な機能を追加したりしたWebサービスがGitHubです。
Gitを利用したWebサービスはGithub以外にもありますが、世界中で広く使われてるのはGitHubです。

## GitHubで知っておきたい知識
### リポジトリ
リポジトリとはファイルやディレクトリの状態や変更履歴などを保管しておくものです。
リポジトリにはリモートリポジトリとローカルリポジトリがあります。
リモートリポジトリとはネットワーク上にあるリポジトリで、ローカルリポジトリとは自分のPCにあるリポジトリです。
自分のPCで作成や変更したファイルをローカルリポジトリに保存して、それをリモートリポジトリに上げて公開することで他の開発者と共有できます。

### add,commit,push
自分のPCでファイルを変更したら　まず、`git add`でステージングエリアという控室のようなところにファイルを追加します。
その次に`git commit`でローカルリポジトリに情報を保存します。
この時に、どういうファイルの作成や追加をしたかがわかるようにコミットメッセージを書きます。
コミットメッセージは他の開発者に伝わりやすいように、ルールが設けられたりすることがあります。
以下の記事はわかりやすいコミットメッセージを書くための参考になると思うので、ぜひ見てみてください。
[僕が考える最強のコミットメッセージの書き方](https://qiita.com/konatsu_p/items/dfe199ebe3a7d2010b3e)
最後に、`git push`でリモートリポジトリに情報を保存します。

### ブランチ
ブランチとは、同じプログラムの中で変更履歴を分岐して保管していくものです。
メインのブランチから分岐したブランチは他のブランチの影響を受けないため、同じプログラム内で2人が違う変更をしたい場合、普通なら1人の作業が終わるまでもう1人は作業をすることができませんが、ブランチをそれぞれ分けることで2人同時に作業することができます。
そして作業が終わった後にはメインのブランチにそれぞれの変更内容を反映させることができます。

### プルリクエスト
プルリクエストとは、ローカルリポジトリでのファイルの変更を他の開発者に通知するものです。
変更内容をメインのブランチに反映させたい時やコードレビューをもらう時に利用します。
プルリクエストでは
- ファイルの変更内容の通知
- ファイルの変更箇所の表示
- ファイルに関してコミュニケーションを取り合う
ことができます。

### マージ
マージとは、ローカルリポジトリでのファイルの変更をメインのブランチに反映させることです。
プルリクエストでコードレビューなどを他の開発者に依頼し、問題がなければマージしてファイルの変更をメインのブランチに反映します。

## GitHubのメリット
### 作業効率が上がる
「ブランチ」のところでもありましたが、GitHubのブランチを利用することで、複数人で同時に作業することが可能です。
また、誰がどうしてファイルを変更したのか、変更履歴も遡って確認することができるため、バグが起きた時にも対処しやすくなります。

### 品質を高めることができる
GitHubではコードを共有して誰でも見ることができ、その場でコミュニケーションを取ることもできるので、レビューの機会が増えて、品質を高めることができます。
無料でプライベートリポジトリも利用できるため、公開したくないファイルを非公開で共有することができて安心です。

## GitHubのデメリット
GitHubは無料でプライベートリポジトリを利用することができますが、間違えて公開してはいけないファイルを公開してしまうこともあります。
特に公開してはいけないファイルをGitHubで取り扱う際には注意が必要です。

## まとめ
GitHubは使い方に注意な部分もありますが、使いこなすことができれば複数人での作業やバージョン管理など、とても便利なサービスです。
これからも利用して、より良い使い方を探していきたいと思います。
もし内容に間違いなどあればコメントなどで教えてください。

## 参考記事
[【入門】GitHubとは？基本的な知識やメリット、活用事例をわかりやすく解説](https://www.kagoya.jp/howto/it-glossary/develop/github/)
[【Git】と【github】の違いとは？](https://qiita.com/True-one/items/d698ebc2346ad184fd3f)
[【徹底解説】GitHubリポジトリとは？作成や削除・運用方法まとめ！](https://pengi-n.co.jp/column/design/github-repository/)
(https://qiita.com/renesisu727/items/248cb9468a402c622003)
[プルリクエストとは？](https://backlog.com/ja/git-tutorial/pull-request/01/)
【js】throwについて考える

# 例えばこんなコード
```javascript
throw new Error();
```
実行すると例外が出る。
使い道としては、エラーを返す代わりに例外を投げたい時に使う。

```javascript
function hoge(arg) {
    if(arg <= 10) {
        console.log(arg);
    } else {
        throw new Error('１０を超えてますよ');
    }
}
hoge(11)
```
```console:出力
Uncaught Error: １０を超えてますよ
```

# エラーを拾う
例外の内容が「１０を超えてますよ」エラーの場合のみ実行したい処理があったとする。
その場合は多分こうなる。
```javascript
try{
    hoge(11);
} catch(e) {
    if(e.message === '１０を超えてますよ'){
        console.log('１０オーバーエラーを取得しました。')
    }
}
```
```console:出力
１０オーバーエラーを取得しました。
```
ただこの実装はできるだけ避けたい。
※実は職場で見た実装

# どうしよう
この辺を参考にしてみた

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Error

```javascript
// オリジナルErrorを定義
class MyError extends Error{
  constructor(message) {
    super(message)
  }
}
```
```javascript
try{
    hoge(11);
}catch(e){
    // 判定に「instanceof」を使う
    if(e instanceof MyError){
        console.log('１０オーバーエラーを取得しました。')
    }
}
```
```console:出力
１０オーバーエラーを取得しました。
```

# ちなみに
実はErrorクラス以外もthrowできる。
※ややこしくなるので絶対やらないほうがいいと思う

```javascript
class MyClass {
  constructor() {}
}
```
```javascript
try{
    hoge(11);
} catch(e) {
    if(e instanceof MyClass){
        console.log('１０オーバーエラーを取得しました。')
    }
}
```
```console:出力
１０オーバーエラーを取得しました。
```

:::note info
思いつたことがあったら追記します。
:::
Swiftでキュー管理を行う(サンプル紹介)

### Operationクラスを使うとキュー管理が簡単に
アプリの開発をしているとキュー管理に迫られることは多々ありますが、再帰関数を使って書くなどいくつかやり方はあると思います。ただ自前で書こうとするとプログラムが複雑になり実装コストがかかったりするので、できればappleが既に用意している仕組みに乗っかりたいところです。そこで紹介したいのがOperationクラスを使ったキュー管理です。

### Operationクラスとは
コアライブラリであるFoundationに含まれている非同期処理実行用のクラスになります。タスクを実行するキューとなるOperationQueueクラスと組み合わせることで、非同期的にキュー管理を行ったプログラムが組めるようになります。

### サンプル
説明だけではイメージしにくいと思うので、サンプルコードを基に説明していきます。このサンプルでは、URLからデータをダウンロードする処理を、キュー管理を用いて実装しています。CacheDownloadManagerは全体のダウンロード管理を行う役割を持たせていて、downloadCacheが呼び出される度にOperationQueueに対してOperationクラスを継承したCacheDownloadOperationを追加しています。このように書くことでCacheDownloadOperationに定義したプログラムがキュー管理式に実行されます。maxConcurrentOperationCountは最大何個まで並列実行を行うか指定するためのオプションでここでは2に指定しています。

```swift
// キュー管理を行うクラス
struct CacheDownloadManager {
  static let shared = CacheDownloadManager()
  private var downloadQueue = OperationQueue()

  init() {
    self.downloadQueue.maxConcurrentOperationCount = 2
  }

  func downloadCache(from url: URL, completion: ((Data?) -> Void)? = nil) {
    let operation = CacheDownloadOperation(url: url) { data in
      Task {
        completion?(data)
      }
    }
    self.downloadQueue.addOperation(operation)
  }
}
```

Operationクラス側の実装を見ていきます。main()はOperationQueueに追加されキューの順番が来たタイミングで自動的に実行されます。処理にあるDispatchSemaphoreは非同期処理を同期的に待つようにする為の機能で、Operationクラスはデフォルトで同期的にタスクを実行することを前提としています。今回のケースだと動画ダウンロード(非同期)の完了を待ち、完了次第ダウンロードしたデータをクロージャーで返却して次のキュー処理に移るということを行いたいので採用しています。DispatchSemaphoreは、初期値としてカウンタを持ちます。このカウンタが0である限りはwait()を呼び出しているところまでで処理が止まります。defer { }でコードブロックの終了時にsemaphore.signal()を呼び出しています。signal()が実行されるとカウンタがインクリメントされ、wait()が解除され次の処理に移るといった動きになります。
```swift
class CacheDownloadOperation: Operation {
  private let url: URL
  private let completion: ((Data?) -> Void)?

  init(url: URL, completion: ((Data?) -> Void)? = nil) {
    self.url = url
    self.completion = completion
  }

  override func main() {
    if isCancelled { return }

    let semaphore = DispatchSemaphore(value: 0)
    var downloadedData: Data?

    let task = URLSession.shared.dataTask(with: url) { data, response, error in
      defer { semaphore.signal() }
      if let error {
        print("[CacheDownload] Network error occurred: \(error)")
      }
      if let httpResponse = response as? HTTPURLResponse {
        print("[CacheDownload] HTTP Status Code: \(httpResponse.statusCode)")
      }
      guard error == nil,
            let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200
      else {
        return
      }
      downloadedData = data
    }
    task.resume()

    semaphore.wait()

    if isCancelled { return }

    completion?(downloadedData)
  }
}
```



## 終わりに
以上がOperationクラスを使用したキュー管理の実装例になります。1度理解すると次からキュー管理が簡単にできるようになりますので非常におすすめです。上記以外に良いやり方がありましたら、ぜひシェアをして頂けるとありがたいです。
【Shell】コマンドで[y/n]に回答する

## はじめに

コマンドを実行した際に途中で`[y/n]`などが出力され回答を求められる場合があります。  
これに自動的に回答する方法について記載します。  

## 自動で回答する方法

`yes`コマンドを使用することで自動的に回答できます。

試しに`yes`コマンド単体で実行します。

```zsh
$ yes
y
y
y
y
^C
```

中断するまで`y`が出力され続けます。  

これを標準入力として次のコマンドに渡します。  

```zsh
$ yes | rm -i *.txt
remove example.txt? remove sample.txt? remove test.txt?
```

自動的に`y`と回答されてすべて削除されます。  

`y`以外の回答をするには以下のように`yes`コマンドの後に記述します。  

```zsh
$ yes 'n' | rm -i *.txt
remove example.txt? remove sample.txt? remove test.txt?
```

自動的に`n`と回答されます。  

`yes 'n'`のみで実行すると以下のように中断するまで`n`が出力され続けます。

```zsh
$ yes 'n'
n
n
n
n
n
^C
```

`n`以外の文字列も同様に出力されます。  

```zsh
$ yes 'foo'
foo
foo
foo
foo
foo
^C
```

なお一度だけ自動で回答できれば良い場合には以下のようにもできます。

```zsh
$ echo 'y' | rm -i sample.txt
remove sample.txt?
```
【2024年08月版】VyOS で ネットワークインターフェイスの速度確認メモ

# はじめに

なんか、ネットの速度遅いなぁ。。。

あれ、このマシンのネットワークインターフェイスの速度って10Gだっけ？

というときに、確認方法を忘れるのでメモ

# 確認方法

## 名前と状態の確認

`show interfaces` や `ip a` などで確認

```
$ show interfaces
Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down
Interface        IP Address                        S/L  Description
---------        ----------                        ---  -----------
eth0             192.168.100.235/24                u/u  
eth1             172.16.0.254/24                   u/u  
lo               127.0.0.1/8                       u/u  
```

## リンク状態と設定の確認

```
$ sudo ethtool eth0
Settings for eth0:
	Supported ports: [ TP ]
	Supported link modes:   1000baseT/Full 
	                        10000baseT/Full 
	Supported pause frame use: No
	Supports auto-negotiation: No
	Supported FEC modes: Not reported
	Advertised link modes:  Not reported
	Advertised pause frame use: No
	Advertised auto-negotiation: No
	Advertised FEC modes: Not reported
	Speed: 10000Mb/s
	Duplex: Full
	Port: Twisted Pair
	PHYAD: 0
	Transceiver: internal
	Auto-negotiation: off
	MDI-X: Unknown
	Supports Wake-on: uag
	Wake-on: d
	Link detected: yes
```

## ドライバの確認

```
$ sudo ethtool -i eth0
driver: vmxnet3
version: 1.4.17.0-k-NAPI
firmware-version: 
expansion-rom-version: 
bus-info: 0000:02:01.0
supports-statistics: yes
supports-test: no
supports-eeprom-access: no
supports-register-dump: yes
supports-priv-flags: no
```

# さいごに

かんたんでしたね

# 関連リンク

[VyOS / equuleus/ Configuration Guide / Interfaces / Ethernet](https://docs.vyos.io/en/equuleus/configuration/interfaces/ethernet.html)