OmniAICreator/Qiita-1.07M huggingface dataset:
【自作キーボード】はじめての自作キーボード制作

## はじめに
みなさんは自作キーボードを作りたいと思ったことはございますか？
わたしは2025年から自作キーボードを作ろうと思い立ち、1ヶ月ほどでつくりました。

この記事では、自作キーボードを作るにあたった経緯やつくる時の失敗などを紹介しようと思います

## 自作キーボードを作ろうと思ったきっかけ

自作キーボードを作ろうと思ったきっかけは２つあります。

**1つ目はこの動画です。**

<iframe width="560" height="315" src="https://www.youtube.com/embed/Xdq6rDKU8g0?si=32DKOrDKK6vjux9w" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

この動画を見て、以下のようなことを思いました。

- これから何十年と使っていくであろうデバイスに拘らないのはダサいな
- もっと業務に最適な配列はあるんじゃないか

**2つ目は肩こりです。**
私は、普段Mac BookのJIS配列の使っていましたが、平日も休日もキーボードに手をおいてデザイン・開発をしているので、長時間巻き肩状態が続き、首・肩・背中周りの凝りが辛くなっていました。

そのため、肩こりを少しでも解消したいと感じ、自分にあったキーボードをつくってみたいと感じたことがきっかけです。

## 自作キーボードを作っていく
### 自作キーボードの方針を決める
まずは、どんな自作キーボードを作るか方針を決めました。

具体的には...

+ 電子工作初心者なので、作りやすいキーボードがいい
    + 作り方のガイドがわかやすい
+ 肩こりを解消するために、分割キーボードにしたい
+ キーボードからできるだけ手を話したくなかったため、トラックボール付きのキーボード

という方針をきめました。

この方針を満たすキーボードを探した結果こちらのキーボードが候補に上がりました。

+ keyball44, keyball61
    + https://github.com/Yowkees/keyball
+ killer whale
    + https://github.com/Taro-Hayashi/KillerWhale/blob/main

### 実際に観にいく
候補のキーボードをきめたら、実際に手に触って軽くタイピングしたいと思い、[秋葉原の遊舎工房](https://yushakobo.jp/shopinfo/)にいくことにしました。

そして、遊舎工房にキースイッチも試せるとのことでしたので、どんなスイッチにするか決めることにしました。
（実際に行ってみると、色々なキーボードあり、楽しかったです。）

候補のキーボードを触ってみて、手にしっくり馴染んだ**killer whale** を作ることにしました。
そして、キースイッチは、[Kailh Clione Limacina Switch / Linear](https://shop.yushakobo.jp/products/7924)にすることにしました

### 購入する
遊舎工房のオンラインショップから以下をキーボードを購入します。

https://shop.yushakobo.jp/products/7948

https://shop.yushakobo.jp/products/7924

https://shop.yushakobo.jp/products/oled

https://shop.yushakobo.jp/products/9531

あと、Amazonで以下をキーボードを購入します。
(ブラックフライデーで安く書いました！)

https://www.amazon.co.jp/gp/aw/d/B0D1Y7BV1T

https://www.amazon.co.jp/gp/aw/d/B0C7KQNDYR

https://www.amazon.co.jp/gp/aw/d/B08DD6GQRV

### 実際に組み立てる

実際に指示通りに組み組み立てていきます！

![IMG_2548.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/7848bf1f-6a53-4506-8ea5-8d9404f60157.jpeg)

そして、左も作っていきます！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/c8e906f1-5d59-43b5-864b-6d9a75310d7c.png)
（アドカレの完走賞でもらったきーたんのキーキャップをつけてみました）

### キー配列を調整する
https://remap-keys.app/

こちらのサイトでキー配列を調整します
そして、調整した配列はこちらになります。

|![スクリーンショット 2025-02-16 17.51.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/1b40f339-2f7e-4473-95ed-d16da48241d7.png)
|----|
|![スクリーンショット 2025-02-16 17.53.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/12e422d5-e64f-4dd3-9c3f-c62d29585831.png)|

（れ）

## まとめ
この記事は、実際につくったキーボードで入力してみましたが、まだ慣れてないと感じています。

これから記事や開発をしながら、慣れていこうと思います。


最後まで読んでくださってありがとうございます！

普段はデザインやフロントエンドを中心にQiitaに記事を投稿しているので、ぜひQiitaのフォローとX(Twitter)のフォローをお願いします。

https://twitter.com/degudegu2510
S3 メタデータが GA されたとのことなのででやってみる

# S3 メタデータ

https://aws.amazon.com/jp/about-aws/whats-new/2025/01/amazon-s3-metadata-generally-available/

https://aws.amazon.com/jp/blogs/aws/introducing-queryable-object-metadata-for-amazon-s3-buckets-preview/

- S3 に保存されたデータの詳細情報（メタデータ）を自動的に取得し、ほぼリアルタイムで更新されるため、データの管理や分析が容易に
- ファイルサイズや作成元などの基本情報（システム定義メタデータ）だけでなく、タグを使って独自の情報（カスタムメタデータ）をファイルに付加することも可能


# 対応リージョン

:::note info
2025/02 現在では東京リージョンはみ対応
:::

- 米国東部 (バージニア北部)
- 米国東部 (オハイオ)
- 米国西部 (オレゴン)

# 設定

他の方も試されていると思いますので、私の記事では余分な解説は省いてシンプルな設定方法を纏めます。

## テーブルバケットを作成

Amazon S3 > テーブルバケット > テーブルバケットを作成 より「テーブルバケット名」を入力し、テーブルバケットを作成する。

![スクリーンショット 2025-02-16 16.04.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/57ec1f27-07b6-4448-af3c-d0bdfcb4511e.png)

## 汎用バケットでメタデータを設定

Amazon S3 > バケット > <自身の S3 バケット名> より「メタデータ」 タブよりメタデータを作成していきます。

![スクリーンショット 2025-02-16 16.06.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/9c083c2c-f54b-4999-b089-debf67e53b76.png)

送信先テーブルバケットは【テーブルバケットを作成】で作成した arn を指定。
メタデータテーブル名はデフォルトのままで設定。

![スクリーンショット 2025-02-16 16.07.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/11275916-0c57-4dbf-b6a9-69591560b57e.png)

## テーブルに対する Lake Formation の権限を付与する

Amazon Athena がテーブルにアクセスできるように ドキュメントに従って、Lake Formation の権限を付与します。

https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/s3-tables-integrating-aws.html#database-link-tables

## Athena でメタデータをクエリする

汎用バケットにファイルをアップロードし、クエリを実行してみると簡単にメタデータを取得可能です。

![スクリーンショット 2025-02-16 17.35.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/419eef14-9035-425d-9495-8075d8174286.png)

参考までにカラムは次の通りとなっておりました。

```sql
SELECT column_name
FROM information_schema.columns
WHERE table_name = '<テーブル名>';
```
![スクリーンショット 2025-02-16 17.53.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/b4e1fd14-62a9-403d-9d1b-2ac020b249e0.png)
Docker Composeの基本と開発フローでよく使うコマンド

## はじめに

本記事では、Docker Compose の基本的な書き方と、よく使うコマンドを紹介します。
備忘録的に使っていただくと嬉しいです。

## Docker Compose の基本

### `docker-compose.yml` の基本構造

`docker-compose.yml` は、複数のコンテナ設定をまとめて記述できるファイルです。基本的な構成は以下の通りです。

```yaml
docker-compose.yml
version: '3.8'
services:
  app:
    image: python:3.9
    container_name: my_app
    volumes:
      - .:/app
    working_dir: /app
    command: python app.py
    ports:
      - "5000:5000"
    depends_on:
      - db

  db:
    image: postgres:15
    container_name: my_db
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
      POSTGRES_DB: mydatabase
    ports:
      - "5432:5432"
```

## 開発時によく使うDocker Composeコマンド

### 1. `docker compose up`

コンテナを起動し、必要ならばイメージをビルドする。

```sh
docker compose up -d  # バックグラウンドで起動
```

### 2. `docker compose down`

コンテナを停止し、ネットワークなどを削除する。

```sh
docker compose down
```

### 3. `docker compose build`

明示的にイメージをビルドする。

```sh
docker compose build
```

### 4. `docker compose ps`

現在実行中のコンテナの一覧を表示する。

```sh
docker compose ps
```

### 5. `docker compose logs`

コンテナのログを表示する。

```sh
docker compose logs -f  # リアルタイムで表示
```

### 6. `docker compose exec`

実行中のコンテナ内でコマンドを実行する。

```sh
docker compose exec app bash  # appコンテナ内でBashを起動
```

### 7. `docker compose stop/start/restart`

コンテナの起動・停止・再起動。

```sh
docker compose stop   # 停止

docker compose start  # 再開

docker compose restart # 再起動
```

### 8. `docker compose rm`

停止中のコンテナを削除。

```sh
docker compose rm -f  # 確認なしで削除
```

### 9. `docker compose run`

一時的なコンテナを作成して実行。

```sh
docker compose run --rm app python manage.py migrate
```

### 10. `docker compose config`

`docker-compose.yml` の構文チェック。

```sh
docker compose config
```

## 開発時のワークフロー

1. **環境構築・初回起動**
   ```sh
   docker compose up -d
   ```
2. **コードを変更したらイメージを再ビルド**
   ```sh
   docker compose build
   docker compose up -d
   ```
3. **ログを確認する**
   ```sh
   docker compose logs -f
   ```
4. **コンテナ内に入ってデバッグ**
   ```sh
   docker compose exec app bash
   ```
5. **環境をリセット**
   ```sh
   docker compose down -v
   ```
AIにおけるAWSのマネージドサービスをまとめてみた

# はじめに
AWSのAI/MLサービスには、インフラの管理が不要で簡単に利用できるマネージドサービスが多数あります。これらを活用すれば、機械学習の専門知識がなくても高度なAI機能をアプリケーションに統合できます。

本記事では、AWS認定(AIF/MLA) の学習に役立つように、代表的なマネージドAI/MLサービスを紹介します。試験勉強のインプットとして、ポイントも記載してます。

# 1. Amazon Textract
### 概要
Amazon Textract は、スキャンしたドキュメントや画像から テキストや構造化データを自動抽出 できるサービスです。OCR（光学文字認識）技術を用いて、単なる文字認識だけでなく、表やフォームの情報も識別できます。

### 主な機能
- 手書き・印刷されたテキストの自動抽出
- 表やフォームのデータを構造化して取得
- IDカード（運転免許証、パスポート）の情報抽出

### ポイント
Textract → テキスト抽出（OCR）
Rekognition → 画像認識（顔・物体検出）

### 公式URL
https://aws.amazon.com/jp/textract/

# 2. Amazon Translate
### 概要
Amazon Translate は、ニューラル機械翻訳（NMT）を利用した自動翻訳サービス です。100以上の言語間でリアルタイム翻訳が可能で、カスタム辞書機能も利用できます。

### 主な機能
- 高精度なニューラル機械翻訳
- カスタム辞書による用語の最適化
- バッチ処理とリアルタイム翻訳の両方に対応

### ポイント
多言語対応が必要な場合はAmazon Translateを意識
カスタム辞書で専門用語の翻訳精度を向上できる

### 公式URL
https://aws.amazon.com/jp/translate/

# 3. Amazon Transcribe
### 概要
Amazon Transcribe は、音声をテキストに変換する自動音声認識（ASR）サービス です。会話や音声データをリアルタイムまたはバッチ処理で文字起こしできます。

### 主な機能
- 音声ファイルの文字起こし
- 異なる話者の識別（話者分離）
- カスタム語彙を追加して認識精度を向上

### ポイント
リアルタイム音声のテキスト化 → Transcribe
話者を区別する必要がある場合は「話者分離」機能を活用

### 公式URL
https://aws.amazon.com/jp/pm/transcribe/

# 4. Amazon Polly
### 概要
Amazon Polly は、テキストを自然な音声に変換するテキスト読み上げ（TTS）サービス です。ディープラーニングを活用し、人間のような音声を生成します。

### 主な機能
- 30以上の言語、90以上の音声をサポート
- 高品質なニューラルTTS（NTTS）音声
- 音声のカスタマイズ（速度・ピッチ調整）

### ポイント
テキストを音声に変換するなら Polly（逆は Transcribe）
ニューラルTTS（NTTS）でより自然な発音

### 公式URL
https://aws.amazon.com/jp/polly/

# 5. Amazon Comprehend
### 概要
Amazon Comprehend は、自然言語処理（NLP）を活用したテキスト分析サービス です。文章の感情分析、固有表現抽出、トピックモデリングなどが可能です。

### 主な機能
- 感情分析（ポジティブ、ネガティブ、中立）
- キーフレーズ、エンティティ（人名、場所、組織）抽出
- 言語識別と文書分類

### ポイント
テキストの意味を理解したい場合は Comprehend
感情分析やエンティティ抽出が必要な場合に適用

### 公式URL
https://aws.amazon.com/jp/comprehend/

# 6. Amazon Lex
### 概要
Amazon Lex は、音声・テキストの両方で対話型AIチャットボットを作成できるサービス です。Alexaの技術を活用しており、自然な対話フローを構築できます。

### 主な機能
- 音声・テキスト両対応のボット構築
- 会話フローの設計（インテント・スロット）
- 他のAWSサービス（Lambda、DynamoDB など）との連携

### ポイント
ボットを構築するなら Lex
Lambda との連携で複雑な応答処理が可能

### 公式URL
https://aws.amazon.com/jp/lex/

# 7. Amazon Personalize
### 概要
Amazon Personalize は、機械学習を利用したパーソナライズ推薦サービス です。ECサイトや動画配信サービス向けのレコメンドシステムを簡単に構築できます。

### 主な機能
- 個別ユーザー向けのコンテンツ推薦
- 購買履歴や行動データを活用した分析
- リアルタイムのパーソナライズ対応

### ポイント
ECサイトの商品推薦には Personalize
トレーニングデータの用意が必要

### 公式URL
https://aws.amazon.com/jp/personalize/

# 8. Amazon Rekognition
### 概要
Amazon Rekognition は、画像・動画の解析ができるコンピュータビジョンサービス です。顔認識や物体検出、テキスト抽出などが可能です。

### 主な機能
- 顔認識・人物追跡
- 画像内のオブジェクトやテキストの検出
- 不適切コンテンツのフィルタリング

### ポイント
画像や動画の解析が必要なら Rekognition
顔認識、ラベル検出、テキスト抽出が可能（OCRは Textract）

### 公式URL
https://aws.amazon.com/jp/rekognition/

# 9. Amazon Kendra
### 概要
Amazon Kendra は、機械学習を活用したエンタープライズ向け検索サービス です。社内文書やFAQを横断的に検索できます。

### 主な機能
- 高精度な自然言語検索
- 様々なデータソースの統合（S3、SharePoint など）
- 関連性の高い検索結果の提供

### ポイント
FAQやドキュメント検索には Kendra
社内ナレッジベースの検索を強化できる

### 公式URL
https://aws.amazon.com/jp/kendra/

# まとめ
AWSのマネージドAI/MLサービスを活用すれば、基盤管理の負担を減らしながら高度なAI機能を導入できます。
ポイントを押さえると、試験勉強にも役立つと思います。
実際に触れたり、 Black Beltで詳細を学んでいくのがいいかと思います。
M5StampS3のGPIO3は10kΩでプルアップされているので注意

# 経緯

M5StampS3のGPIO1,3,5,7,9にセンサーを接続してADCを使っていたのですが、GPIO3だけ値がおかしくて悩んでいました。

# 発見

[公式サイト](https://docs.m5stack.com/en/core/StampS3) にある回路図をよく見ると…

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70022/8249a917-d3be-4750-85b5-71126f5db63e.png)

GPIO3だけ10kΩでプルアップされとるやんけ！

# プルアップ抵抗の位置

テスターで調べたところ、アンテナの下にある抵抗が当該の抵抗の模様。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70022/97e21492-0beb-4f9b-9694-70910915f751.png)

これを外してしまえば良いわけですが、本体に手を入れると技適がNGになってしまうかもしれない（※ふめい）のでやめました。
仕方なくセンサーのピンを変更しました。

# 補足

今回センサーがオープンドレインだったのでプルダウン抵抗が必要でプルアップだと都合が悪かったのですが、プッシュプルのセンサーの場合や、オープンコレクタのセンサーの場合は10kΩを考慮すればGPIO3を問題なく使えるかもしれません。
GPIO3をLEDなどの出力に使う場合も注意が必要そうです。

それしてもどうしてGPIO3だけ…
【AWS】Amazon Linux 2023 で mod_php を使ってPHPを実行する


## **📖 概要**
Amazon Linux 2023 のコンテナイメージに **PHP 8.3 と Apache2** をインストールし、  
**php-fpm を使わずに、モジュール版（mod_php）で動作させる** 方法を検証しました。

---

## **🛠️ やったこと**
- `php-fpm` の自動起動を無効化  
- `mod_php`（Apache のモジュール）で PHP を動作させるように設定  
- **Dockerfile を作成し、コンテナで環境を構築**

---

## **📃 Dockerfile**

```dockerfile
FROM amazonlinux:2023.6.20250107.0

# 必要なパッケージをインストール
RUN dnf install -y php httpd mod_php && \
    dnf clean all

# FastCGI 設定を削除
RUN test -f /usr/lib/systemd/system/httpd.service.d/php-fpm.conf && rm /usr/lib/systemd/system/httpd.service.d/php-fpm.conf || true

# Prefork MPM を有効化し、他のMPMを無効化
RUN sed -i 's/^LoadModule mpm_event_module/#LoadModule mpm_event_module/' /etc/httpd/conf.modules.d/00-mpm.conf && \
    sed -i 's/^LoadModule mpm_worker_module/#LoadModule mpm_worker_module/' /etc/httpd/conf.modules.d/00-mpm.conf && \
    sed -i 's/^#LoadModule mpm_prefork_module/LoadModule mpm_prefork_module/' /etc/httpd/conf.modules.d/00-mpm.conf

# ServerNameの警告を抑制
RUN echo "ServerName localhost" >> /etc/httpd/conf/httpd.conf

# PHPモジュールをロード
RUN echo "LoadModule php_module modules/libphp.so" >> /etc/httpd/conf/httpd.conf && \
    echo "<FilesMatch \.php$>" >> /etc/httpd/conf/httpd.conf && \
    echo "SetHandler application/x-httpd-php" >> /etc/httpd/conf/httpd.conf && \
    echo "</FilesMatch>" >> /etc/httpd/conf/httpd.conf

# 作業ディレクトリを設定
WORKDIR /tmp

# 必要なファイルをコンテナにコピー
COPY . /tmp

# phpファイルを配置
COPY info.php /var/www/html/info.php

# ポート 80 を開放
EXPOSE 80

# Apache を起動
ENTRYPOINT ["/usr/sbin/httpd", "-D", "FOREGROUND"]
```
----
### **🌐 ブラウザで表示確認**
 コンテナ起動後に`http://localhost/info.php` を開くと、表示することができました。
![スクリーンショット.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4007885/c7280206-248d-403c-a7e8-78fae92228b7.png)
gitコマンドのまとめ

# gitコマンド

### 1.変更内容をリモートリポジトリにあげるコマンド

変更したファイルをステージングエリアに追加するコマンド
変更したファイルすべてをリモートリポジトリにあげるときは`.`でいける.
```
git add リモートリポジトリにあげるファイル
```
その変更をローカルリポジトリにコミットするコマンド
```
git commit -m "変更内容のコメント"
```
リモートリポジトリ（GitHubなど）にプッシュするコマンド
```
git push ブランチ名
```
ローカルブランチとリモートブランチを関連させるには
```
git push --set-upstream origin ブランチ名
```
例
```
git add .
git commit -m "indexの修正"
git push origin main
```
### 2.ローカルブランチの一覧と現在のブランチを確認するコマンド
```
git branch
```
で*のマークがついているのが現在のブランチである.
例
```
$ git branch
  main
  top_about
* url_new
```
現在のブランチはurl_newであることがわかる.

### 3.新しいブランチを作成して切り替えるコマンド
```
git checkout -b  新しいブランチ名
```
新しいブランチを作成
```
git push origin 新しいブランチ名
```
新しいブランチをリモートにプッシュ

例
```
git checkout -b login

git push origin login
```

### 4.既存のブランチにもどるコマンド
```
git checkout ブランチ名
```
例
```
git checkout main
```
これにより`main`ブランチにもどることができた.

### 5.リモートのブランチをローカルのブランチにプルするコマンド
```
git pull origin リモートブランチ名
```
例
```
git pull origin main
```
これにより,リモートのmainブランチをローカルのmainブランチにプルできた.
### 6.作成したブランチをmainブランチにマージするコマンド
マージするブランチの最新の状態を取得.
```
git fetch origin
```
マージ先のmainブランチにいく.
```
git checkout main
```
リモートのmainブランチをローカルのmainブランチにプルする
```
git pull origin main
```
作成したブランチをmainブランチにマージする
```
git merge 作成したブランチ名
```
マージした内容をリモートの main ブランチにプッシュする
```
git push origin main
```
これにより,作成したブランチをmainブランチにマージすることができる.

### 7.変更したファイルが分かるコマンド
addで追加したファイルは緑で表示されて,まだaddされていないファイルは赤で表示される.
```
git status
```
### 8.変更したファイルの場所が分かるコマンド
```
git diff
```
### 9.gitの履歴が見れるコマンド
コミットメッセージを見ることができる
```
git log
```
このコマンドに`-p`を付けるとどのファイルのどこを編集したのかがわかる
```
git log -p
```
### 10.ブランチの削除コマンド
ローカルブランチを削除するコマンド
```
git branch -d 削除するブランチ名
```
リモートブランチを削除するコマンド
```
git push origin --delete 削除するブランチ名
```
Python3エンジニア認定基礎試験に合格したい人間が勉強する話①

Pythonができるようになりたい、そしてPython3ができるよということを少しでも示せるようになるにはPython3エンジニア認定基礎試験に合格するのが手っ取り早いかなということで勉強し始めました。

https://www.pythonic-exam.com/exam/basic

# 教材・参考資料
勉強用に本はこちらを買いました。認定教材。
[徹底攻略Python 3 エンジニア認定［基礎試験］問題集](https://www.amazon.co.jp/dp/4295016055/)
しかしそもそもオライリー・ジャパン「Pythonチュートリアル(第4版)」の掲載内容を出題範囲とする、とあるので絶対そっちも見た方がいい……でもオライリーの本って今まで見てきても「ある程度分かってる人が分かってる人のために書いている」感が強いという超偏見があってですね……。
まずは問題集を解きながら分からないところを解説や公式が公開してるチュートリアルで確認して、最後にKindleで「Pythonチュートリアル(第4版)」を買って見直し、試験という形で臨もうかなと思っています。


公式が公開しているPythonチュートリアルはこちら

https://docs.python.org/ja/3/tutorial/

私のインストールしているPythonは3.13.1なんですけども、バージョン選択のドロップダウンに無かった……とりあえず3.13.2を見ます。

それと問題集を見ていたらコーディング規約に関する問題もあったのでこちらも確認。
Authorを見る限り、Pythonの生みの親であらせられるGuido van Rossum氏自身が書かれたものだそうです。

https://pep8-ja.readthedocs.io/ja/latest/

> 一貫性にこだわりすぎるのは、狭い心の現れである

いきなり強い言葉が出た。
色々ありますが要点を抑えながら読んでおこうと思います。
個人的にタブでのインデントが多いので気を付けないとな……。
TypeScriptでユニオン型の重複チェックを行う方法

TypeScriptで複数のユニオン型を定義し、それらのユニオン型に重複がないかをチェックしたい場合があります。例えば、以下のように複数のユニオン型を定義したとします。

``` typescript
type SubUnion1 = "one" | "two";
type SubUnion2 = "two" | "three";
type SubUnion3 = "nine" | "ten";
```

これらのユニオン型を1つのユニオン型にまとめたいとき
次のように書くとts的にはエラーが出ないので重複に気づくことができません。

```typescript
/// Initial type:"one" | "two" | "two" | "three" | "nine" | "ten" となり特にエラーは出ない
type Union = SubUnion1 | SubUnion2 | SubUnion3 

```

# ユニオン型の重複チェック方法

まず、各ユニオン型をタプルにまとめます。

```typescript
type UnionList = [SubUnion1,SubUnion2,SubUnion3]
```

次に、重複があるかどうかをチェックする型を定義します。この型は、重複がなければneverを返し、重複があれば重複情報を含むタプルのユニオン型を返します。

```typescript
type Overlaps<T extends string[]> = {
    [K in keyof T]: {
        [L in keyof T]: L extends K
            ? never
            : T[K] & T[L] extends never
              ? never
              : ['次のインデックスに', K | L, '次の重複があります', T[K] & T[L]];
    }[number];
}[number];
```

 この型は複雑なので`Overlaps<UnionList>`と定義したものとして
一つずつ説明します。

 
1. 外側のマッピング `[K in keyof T]`
これは、タプル `T` の各要素に対してインデックス K を使ってマッピングを行います。
`K` はタプルのインデックスを表します。
(`K`は`UnionList`のインデックスである0,1,2)
2. 内側のマッピング `[L in keyof T]`
内側のマッピングでは、同じタプル `T` の各要素に対してインデックス `L` を使ってマッピングを行います。
(同様にTは`UnionList`のインデックスである0,1,2)
これにより、二重ループのような構造が作られ、各要素の組み合わせ (`K` と `L`) をチェックすることができます。
3. インデックスが同じ場合の処理 `L extends K ? never`:
インデックス `L` が `K` と同じ場合（つまり、同じ要素同士の場合）は処理をスキップするために `never` を返します。
4. 重複がない場合の処理 `T[K] & T[L] extends never ? never`
`T[K]` と `T[L]` の交差型が `never` である場合、つまり重複がない場合は `never` を返します。
(`SubUnion2`と`SubUnion3`の比較の時、交差型が`never`なので`never`を返す)
5. 重複がある場合の処理`['次のインデックスに', K | L, '次の重複があります', T[K] & T[L]]`
`T[K]` と `T[L]` の交差型が `never` でない場合、重複があるとみなします。
重複がある場合、重複の詳細情報を含むタプルを生成します。ここでは、インデックス `K` と `L`、および重複している値 `T[K]` & `T[L]` を含むタプルを作成します。
(`SubUnion1`と`SubUnion2`の比較の時、交差型が`two`なので`['次のインデックスに', 0|1, '次の重複があります',two`を返す)
6. 内側のマッピングの結果をユニオン型に変換 `[number]`
内側のマッピングの結果をユニオン型に変換します。これにより、全てのインデックスの結果が1つのユニオン型にまとめられます。
7. 外側のマッピングの結果をユニオン型に変換 `[number]`
同じく、外側のマッピングの結果もユニオン型に変換します。

次に、重複がある場合にコンパイルエラーを発生させるための型関数を定義します。

```typescript
type ExpectNever<T extends never> = void;
```
これらを組み合わせて、重複チェックを行います。
```typescript
// エラーが発生する TS2344: Type ["次のインデックスに", "0" | "1", "次の重複があります", "two"] does not satisfy the constraint never
type EnsureNoOverlapsOfSubUnions = ExpectNever<Overlaps<SubUnions>>;
```

最後に、タプルの要素をユニオン型にまとめることで、元のユニオン型を取得できます。

``` typescript
type Union = UnionList[number];
```

# まとめ
以上をまとめると次のようになります。

``` typescript
type UnionList = [SubUnion1,SubUnion2,SubUnion3]
type Union = UnionList[number]


type Overlaps<T extends string[]> = {
    [K in keyof T]: {
        [L in keyof T]: L extends K
            ? never
            : T[K] & T[L] extends never
              ? never
              : ['次のインデックスに', K | L, '次の重複があります', T[K] & T[L]];
    }[number];
}[number];

type ExpectNever<_ extends never> = void;
// 重複を確認するための型重複があった場合下記がエラーになり気づける
type EnsureNoOverlapsOfSubUnions = ExpectNever<Overlaps<UnionList>>;


```
Firebaseの秘密鍵がGitHubのPush Protectionに引っかかった

## 発生した問題

Firebaseの設定後にGitHubへ`git push origin main`を実行したところ、以下のエラーが発生。

```
! [remote rejected] main -> main (push declined due to repository rule violations)
error: failed to push some refs to 'https://github.com/username/repository.git'
```
一時的にpushができなくなりました。

## 原因

GitHubの **Push Protection（プッシュ保護）** により、Firebaseの秘密鍵（Service Account JSON）がリポジトリに含まれていることが検出され、Pushがブロックされた。

- GitHubのPush Protectionは手動で設定していなかったのにブロックされた
- `.gitignore` に追加しても 過去の履歴に秘密鍵が含まれているためブロックが続く
- Firebaseの設定変更がPush Protectionに影響した可能性がある

### 発生の流れ
1. Firebaseの設定時に、秘密鍵 `study-app-a701b-firebase-adminsdk-xxx.json` をダウンロード。
2. `.gitignore` に追加し忘れたまま `git add .` → `git commit -m "Update"` を実行し、秘密鍵を誤ってコミット。
3. GitHubの **Secret Scanning（シークレットスキャン）** が秘密鍵を検出し、Pushを拒否。
4. Firebaseの設定変更が影響し、リポジトリのPush Protectionの動作が変わった可能性。

## 🛠 解決方法

Gitの履歴から完全に削除する必要があるため、以下の手順を実行。

#### 1️⃣ `git filter-repo` を使用して秘密鍵を履歴から削除

このコマンドは、指定したファイルを**過去のすべてのコミット履歴から削除**する。

```sh
git filter-repo --path study-app-a701b-firebase-adminsdk-xxx.json --invert-paths --force
```

実行後、GitHubのリモートリポジトリの情報が削除されるため、再設定が必要。

#### 2️⃣ GitHubのリモートリポジトリを再設定

```sh
git remote add origin https://github.com/username/repository.git
```

#### 3️⃣ 強制Push（履歴を書き換えるため `--force` を使用）

```sh
git push origin main --force
```

## 🚀 今後の防止策

### `.gitignore` にFirebaseの秘密鍵を追加

```sh
echo "study-app-a701b-firebase-adminsdk-*.json" >> .gitignore
```

### 環境変数を使用して秘密鍵を管理

1. Firebaseの秘密鍵をBase64エンコードして環境変数に設定
   ```sh
   cat study-app-a701b-firebase-adminsdk-xxx.json | base64
   ```
2. GitHub Actionsの `secrets` に `FIREBASE_KEY` として登録
3. `main.yml` にデコード処理を追加
   ```yaml
   - name: Decode Firebase service account key
     run: echo "${{ secrets.FIREBASE_KEY }}" | base64 --decode > ./firebase-key.json
   ```
4. Firebaseのデプロイ時に環境変数を利用
   ```yaml
   env:
     GOOGLE_APPLICATION_CREDENTIALS: "./firebase-key.json"
   ```

### GitHubのPush Protectionを事前に確認

GitHubの **Push Protection** が有効になっているか確認し、シークレットスキャンに引っかからないか意識する。

## ✅ まとめ

- Firebaseの秘密鍵がGitの履歴に残っていると、Pushが拒否される
- `.gitignore` だけでは解決せず、`git filter-repo` を使って履歴から削除する必要がある。
- 環境変数を活用し、秘密鍵をGitに含めない運用を徹底することが重要！
- Firebaseの設定変更がPush Protectionに影響する可能性があるため、事前に認識しておくべき

Firebaseの秘密鍵は生の状態で絶対にGitにコミットしない🔥
M5StampS3をplatform.ioで開発する際にハマったこと

簡単なメモですが記しておきます。

## 普通にプロジェクト作成してもビルドできない

### 症状

PIO Homeからボード「M5StampS3」を選んでプロジェクトを作成し、簡単なプログラムをビルドすると以下のようなエラーが出ることがありました。

```
error: 'SCK' was not declared in this scope
error: 'MISO' was not declared in this scope
error: 'MOSI' was not declared in this scope
error: 'SS' was not declared in this scope
```

### 対処方法その1

[この記事](https://community.platformio.org/t/unable-to-compile-m5stack-factory-arduino-examples/36936/5) に対処方法がありました。
platformio.iniファイルに以下を追記します。

```platformio.ini
platform_packages =
    framework-arduinoespressif32@https://github.com/espressif/arduino-esp32/archive/refs/tags/2.0.14.zip
```

### 対処方法その2

[こちらの記事](https://community.m5stack.com/topic/7046/m5dail-platformio-setup-problems) に別の対処方法がありました。
platformio.iniファイルに以下を追記します。

```platformio.ini
platform = espressif32@6.9.0
```

GitHubに依存しない分、こちらの方法の方が良い気がします。

### おまけ: 2025/2/16 再現しなくなった

メモしておいたのを記事に書こうと、platformio.iniをデフォルトに戻したのですが、なぜか問題なくビルドできるようになってしまいました。環境が残ってしまっているような気がします。また再現したときのために記事は書いておくことにします。

```デフォルトのplatformio.ini
[env:m5stack-stamps3]
platform = espressif32
board = m5stack-stamps3
framework = arduino
```

## USBシリアルに出力されない

### 症状

`Serial.println("Hello");` としても、USBシリアルに出力されていませんでした。

### 対処方法

[こちらの記事](https://qiita.com/ta-oot/items/c60e67ba80d55296b823) に対策がありました。
platformio.iniに下記を追加します。

```platformio.ini
build_flags =
    -DARDUINO_USB_CDC_ON_BOOT=1
```

こうすると無事USBシリアルに出力されるようになりました。
SelectionContainerのweightが上手く動作しない時の対処法


# 初めに
:::note warn
この記事では対処法は記載していますが、根本的な原因については言及していません。
ご存知の方がいらっしゃいましたら、教えていただけると助かります。
:::
JetPack ComposeでSelectionContainerを使う時に、
weightの動作がBoxなどと違う場合があります。(weightが適切に分配されないなど)

この記事では、そのような問題が発生した際の対処法を記載しています。

# 関連する問題
この問題がGoogle Issue Trackerでも挙げられていました。
このIssueの結論としては、「回避策が存在するため、現状のレイアウトの崩壊を防ぐために、緊急修正(hotfix)する予定はなし。」というような感じでした。

https://issuetracker.google.com/issues/378738911

https://issuetracker.google.com/issues/372053402

# 対処法
Google Issue Trackerの情報によると、`SelectionContainer`から`Modifier.weight`を外し、
`Box(modifier = Modifier.weight(1f), propagateMinConstraints = true)`で
囲うと適切に動作するようになるそうです。


```kotlin
// 問題が発生する可能性のあるコンポーネント
@Composable
private fun Sample(
    text: String,
    modifier: Modifier = Modifier,
) {
    Scaffold(
    ) { innerPadding ->
        Box(Modifier.padding(innerPadding)) {
            Column(
                modifier = modifier,
            ) {
                SelectionContainer(modifier = Modifier.weight(1f)) {
                    Text(text = text)
                }
                Box(
                    modifier = Modifier
                        .fillMaxWidth()
                        .height(40.dp)
                        .background(color = Color.Red),
                )
            }
        }
    }
}
```

```kotlin
// weightが適切に動作するように修正したコンポーネント
@Composable
private fun Sample(
    text: String,
    modifier: Modifier = Modifier,
) {
    Scaffold(
    ) { innerPadding ->
        Box(Modifier.padding(innerPadding)) {
            Column(
                modifier = modifier,
            ) {
                // Box を新たに追加
                Box(modifier = Modifier.weight(1f), propagateMinConstraints = true) {
                    SelectionContainer { // Modifier.weightを削除
                        Text(text = text)
                    }
                }
                Box(
                    modifier = Modifier
                        .fillMaxWidth()
                        .height(40.dp)
                        .background(color = Color.Red),
                )
            }
        }
    }
}
```
サーバーレス環境とWebサーバー（NGINX・Apache）について軽くまとめた

## **はじめに**

自分は普段、GCPの **Cloud Run にDockerコンテナをデプロイ** する形でサイトを運用しており、**いわゆるサーバーレス環境** に慣れすぎていました。そのため、Webサーバーを意識することがほぼありませんでした。

しかし、ある案件で **NGINX を使った環境** に触れる機会があり、**Basic認証を設定する** 必要が出てきました。そこで初めて **「Webサーバーってどうやって動いてるんだっけ？」** という疑問にぶつかり、試行錯誤することに。

これを機に、**サーバーレス環境とWebサーバー（NGINX・Apache）の違い** を整理し、記事にまとめました。


## **1. サーバーレス環境とは？**

### **そもそも「サーバーレス」って？**

「サーバーレス」とは、**物理サーバーや仮想サーバーを意識せずにアプリを動かせる環境** のことです。ですが、「サーバーがない」わけではなく、GCPでは**クラウドの裏側でGoogleがサーバーを管理してくれている** だけです。

### **GCPにおけるサーバーレスの例**

| **GCPのサービス** | **サーバーの管理** | **使い方のイメージ** |
|----------------|----------------|----------------|
| **Cloud Run** | サーバー管理不要 | Dockerコンテナをデプロイするだけ |
| **App Engine** | サーバー管理不要 | コードをアップロードするだけ |
| **Cloud Functions** | サーバー管理不要 | 特定のイベントで関数を実行 |

**Cloud Run は Dockerコンテナをデプロイするだけで動くため、Nginx や Apache を意識しなくてもサイトを運用できる** のが大きな特徴です。

## **2. Webサーバー（NGINX・Apache）を使う環境とは？**

### **Webサーバーの役割**

サーバーレスとは異なり、従来の環境では **「Webサーバー」** を使ってWebサイトを公開します。Webサーバーは、**ブラウザからのリクエストを受け取り、適切なデータを返す役割** を持ちます。

代表的なWebサーバーとして、
- **NGINX（エンジンエックス）**
- **Apache（アパッチ）**

の2つがあります。

### **NGINXとApacheの違い**

|  | **NGINX** | **Apache** |
|---|---|---|
| **処理方式** | イベント駆動（軽量・高速） | スレッド駆動（1つ1つ処理） |
| **向いている環境** | 大規模サイト、負荷が高いAPIサーバー | 小規模なサイト、レンタルサーバー |
| **設定のしやすさ** | 設定ファイルがシンプル | `.htaccess` で柔軟な設定が可能 |
| **リバースプロキシ** | ◎ 優秀（よく使われる） | △ そこまで得意ではない |

今はNGINXが主流で

Apatchを使うのは下記の時です
- .htaccessを使うとき
- WordPressを使用するとき（プラグインや設定がApache向けのものが多い）
- 古いシステムのサポートが必要


## **3. サーバーレス環境とWebサーバー環境の使い分け**

|  | **サーバーレス（Cloud Run）** | **仮想マシン + NGINX** |
|---|---|---|
| **運用の手間** | ✅ サーバー管理不要 | ❌ 自分で管理が必要 |
| **スケール** | ✅ 自動で増減 | ❌ 自分で設定が必要 |
| **細かい設定** | ❌ NGINXの細かい設定不可 | ✅ 設定自由 |
| **コスト** | ✅ 使った分だけ課金 | ❌ ずっと起動していると高い |

例えば、
- **「サーバー管理をしたくない！」 → Cloud Run**
- **「細かく設定したい、負荷分散したい！」 → Compute Engine + NGINX**

というように使い分けることができます。



## **4. まとめ**

✅ **GCPのCloud Runを使うと、NGINXやApacheを意識しなくてもサイトをデプロイできる**  
✅ **しかし、従来の環境（Compute Engineなど）ではNGINXやApacheを使うことが一般的**  

NGINXを使わずにデプロイすることが多かったので最初は戸惑いましたが、こういうものだと知っておけば対処しやすいかと思いました
iptablesを使った簡単なファイアウォール設定方法

こんにちは。
株式会社クラスアクト インフラストラクチャ事業部の大塚です。

この記事では、Linuxのファイアウォールツールである**iptables**を使って、簡単なファイアウォール設定を行う方法を解説します。特に、HTTP通信を拒否する設定を例に取り上げ、設定の保存や永続化の方法についても触れます。
OSはubuntuの22.04を使っています。
iptablesは色々コマンドが複雑かなぁと思うので、簡単な例でもいいので、設定をしてみるとイメージしやすくなるような気がします。

### **1. iptablesの基本操作**

まず、現在のiptablesの設定状況を確認します。以下のコマンドを実行すると、現在のルールセットが表示されます。

```bash
iptables -L -v
```

出力例：

```
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
```

この例では、特にルールが設定されていないことが分かります。

### **2. HTTP通信を拒否するルールを追加**

次に、HTTP通信（ポート80）を拒否するルールを追加します。以下のコマンドを実行してください。

```bash
iptables -A INPUT -p tcp --dport 80 -j REJECT
```

再度ルールを確認すると、追加されたことが分かります。

```bash
iptables -L INPUT
```

出力例：

```
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
REJECT     tcp  --  anywhere             anywhere             tcp dpt:http reject-with icmp-port-unreachable
```

この状態でWebブラウジングを試みると、HTTP通信が拒否されていることを確認できます。

### **3. 設定の永続化**

iptablesの設定は、デフォルトでは再起動後に消えてしまいます。そのため、設定を保存して永続化する必要があります。

#### **3.1 iptables-saveを使用**

以下のコマンドで現在の設定を保存します。

```bash
iptables-save -c > /etc/iptables.rules
```

保存した設定を復元するには、以下のコマンドを使用します。

```bash
iptables-restore < /etc/iptables.rules
```

#### **3.2 iptables-persistentを使用**

`iptables-persistent`をインストールすることで、再起動後も設定を自動的に復元できます。

```bash
apt install -y iptables-persistent
netfilter-persistent save
```

再起動後に設定が残っているか確認します。

```bash
iptables -L INPUT
```

### **4. ルールの削除**

ルールを削除する場合、以下の手順を実行します。

#### **4.1 全ルールを削除**

すべてのルールを削除するには、以下のコマンドを使用します。

```bash
iptables -F INPUT
```

#### **4.2 特定のルールを削除**

特定のルールだけを削除する場合、まずルール番号を確認します。

```bash
iptables -L INPUT -n --line-numbers
```

出力例：

```
Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination
1    REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:80 reject-with icmp-port-unreachable
```

ルール番号を指定して削除します。

```bash
iptables -D INPUT 1
```

### **まとめ**

iptablesを使えば、簡単にファイアウォールの設定が可能です。本記事では、HTTP通信を拒否する設定を例に、基本的な操作から設定の永続化、ルールの削除方法までを解説しました。セキュリティを強化するために、iptablesを活用してみてください！
平板コンデンサの直列・並列接続における容量計算

# はじめに
2つのコンデンサを直列に接続する場合と並列に接続する場合では、合成容量が異なる。このことは、一般的に電荷保存の法則から導出されるが、今回は誘電率が同じ値のコンデンサ2つの合成容量を考える。具体的には、並列の場合は極板が広がったものとして考えて直列の場合は、板間距離が増加したものとして考察する。

![Sample3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686019/65ef6488-e38d-4d30-8503-48ae3dd3e294.gif)


# 公式の導入
以下のような平板コンデンサを考える。
ただし、この図には電場と電位の情報が入っている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686019/b892455d-ed8e-450e-9364-2e853ca103b0.png)

まず、上記コンデンサーの中心板内の平均電場について求めよう。
今回の場合は、単純にコンデンサの板内電場は一様であるとする。
（実際は端の効果により厳密には一様ではないが、それらの影響は無視できるものとする。）

電場の定義式とガウスの法則により厚さ$d$広さ$S$のコンデンサ内の電場は以下の式で与えられる。

```math
E=\frac{V}{d}=\frac{Q}{\epsilon S}
```
ゆえに、

```math
C=\frac{Q}{V}=\epsilon \frac{S}{d}
```

が成立する。

以上が、平板コンデンサの静電容量の式であるが、この式を用いて直列・並列接続時の合成容量の変化について調査する。

# 前提条件

前提条件として、2つのコンデンサを考えるのだが、まずは単純のためコンデンサに使用される絶縁体の誘電率は両者とも同じ値のものを使用する。

次に、並列接続の場合は板間距離$d$を共通の値として、広さである$S$が大きくなるというイメージで考える。一方で、直列接続の場合は、広さである$S$は共通だが板間距離$d$が大きくなるイメージで考える。


# 計算準備

以下のような2つのコンデンサの容量を考える。

```math
C_1=\epsilon \frac{S_1}{d_1}
```

```math
C_2=\epsilon \frac{S_2}{d_2}
```



# 並列接続の場合

2つのコンデンサの容量を$C_1,C_2$とし、共通板間距離$d$とすると、それぞれのコンデンサの容量は以下の式で表すことができる。

```math
C_1=\epsilon \frac{S_1}{d}
```

```math
C_2=\epsilon \frac{S_2}{d}
```

ただし、$d=d_1=d_2$

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686019/92729726-655f-49c1-aa9d-cda6955f3594.png)

並列接続は、2つのコンデンサの板を合体させることと等価である。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686019/b02e5af2-4678-4b31-b48b-0e8c979fa71f.png)

したがって、合成後（合体後）のコンデンサの板の広さは$S=S_1+S_2$であると考えることができる。

```math
C=\epsilon \frac{S}{d}=\epsilon \frac{S_1+S_2}{d}=C_1+C_2
```

となり、並列接続の場合は2つのコンデンサの容量の和が合成容量になる。


# 直列接続の場合
以下のような直列接続の場合を考える。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686019/53c5647f-61e9-4b0f-80a1-c8cf79372abb.png)

この場合は、並列接続とは逆で、板の広さを共通として板間距離を増加させると考える。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686019/32338d44-ff35-4fcc-9b58-8bb26b2fe958.png)

そうすると、合成後の板間距離$d=d_1+d_2$となることが分かる。したがって、


```math
C_1=\epsilon \frac{S}{d_1}
```

```math
C_2=\epsilon \frac{S}{d_2}
```

とおくと、


```math
C=\epsilon \frac{S}{d}=\epsilon \frac{S}{d_1+d_2}
```

となるので、逆数をとると以下のようになる。

```math
\frac{1}{C}= \frac{d_1+d_2}{\epsilon S}=\frac{d_1}{\epsilon S}+\frac{d_2}{\epsilon S}=\frac{1}{C_1}+\frac{1}{C_2}
```

以上のことから、並列接続の場合の合成容量は逆数の和の公式になるということが分かった。

# まとめ
直列接続のコンデンサの合成容量の公式を理解するのは、並列接続の場合を理解するよりも難しい。だが、直列接続の場合は、板の広さは共通で厚さが広くなるということをイメージとして持っていれば、上手く計算することが可能になる。ただし、上の議論では誘電率が異なる場合を上手く説明できないので証明としては物足りない。したがって、証明には、有名な電荷保存の法則を用いる。しかし、今回のような公式のイメージを掴むためには、自分なりに具体的なものに落とし込むことが上達のカギである。
ER Master

https://ermaster.sourceforge.net/index_ja.html

https://willbrains.jp/index.html#/pleiades_distros2021.html

![スクリーンショット 2025-02-16 162931.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4009683/2b0c5104-82e6-4412-a521-61181d0d11a3.png)

http://ermaster.sourceforge.net/update-site/
AtCoder Beginner Contest 393 振り返り

ABC393の振り返りです。

## 結果

ABCの3完でした。今回も簡単目だった印象です。

![スクリーンショット 2025-02-16 16.14.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167729/1a7e8f48-9517-4c0e-8952-77188208a508.png)

![スクリーンショット 2025-02-16 16.15.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167729/28f43b59-85be-4c9c-ad30-af0b262eb11e.png)


## ふりかえり

### A問題

- 問題
  - https://atcoder.jp/contests/abc393/tasks/abc393_a
- 回答
  - https://atcoder.jp/contests/abc393/submissions/62768967

全パターンをベタ書きしました

```haskell
main :: IO ()
main = do
  ss <- getLine

  print $ f $ words ss

f ["sick", "sick"] = 1
f ["sick", "fine"] = 2
f ["fine", "sick"] = 3
f ["fine", "fine"] = 4
```

### B問題

- 問題
  - https://atcoder.jp/contests/abc393/tasks/abc393_b
- 回答
  - https://atcoder.jp/contests/abc393/submissions/62786858

文字列の間の間隔を1から刻み、始まりの文字列を1からずらしていって`A`, `B`, `C`になっているか判定します。

文字列の間隔の最大値をミスってしまって1ペナになりました

```haskell
main :: IO ()
main = do
  s <- VU.fromList <$> getLine

  let len = VU.length s
      idxs =
        [ (i, j, k)
          | stp <- [1 .. 50],
            i <- [0 .. len - (stp * 2) - 1],
            let j = i + stp,
            let k = j + stp,
            s VU.! i == 'A' && s VU.! j == 'B' && s VU.! k == 'C'
        ]

  print $ length idxs
```

### C問題

- 問題
  - https://atcoder.jp/contests/abc393/tasks/abc393_c
- 回答
  - https://atcoder.jp/contests/abc393/submissions/62792570

辺の始点を揃えてSetで管理します。
始点と終点が一緒、もしくはSetにすでに辺が存在するのであればカウントを1増やします。

```haskell
main :: IO ()
main = do
  [n, m] <- getInts
  uvs <- replicateM m do
    [u, v] <- getInts
    return (min u v, max u v)

  let ans =
        foldl'
          ( \(set, cnt) (u, v) ->
              if u == v || S.member (u, v) set
                then (set, cnt + 1)
                else (S.insert (u, v) set, cnt)
          )
          (S.empty, 0)
          uvs
  print $ snd ans
```

ちなみにこの解法で解くと、1786 msもかかってしまいます。

代わりにHashSetを使うと、686 msで解くことができます。
SetをHashSetに置き換えるだけです。

- https://atcoder.jp/contests/abc393/submissions/62820719

```haskell
main :: IO ()
main = do
  [n, m] <- getInts
  uvs <- replicateM m do
    [u, v] <- getInts
    return (min u v, max u v)

  let ans =
        foldl'
          ( \(set, cnt) (u, v) ->
              if u == v || HS.member (u, v) set
                then (set, cnt + 1)
                else (HS.insert (u, v) set, cnt)
          )
          (HS.empty, 0)
          uvs
  print $ snd ans
```

## 全体を振り返って

B問題のミスがなければもっとratingあがったのかなと思うので反省です。

最近安定して3完してますが、問題が簡単なだけに思えます。
もっと難しい問題でも安定して解けるようにしたいと思います。
PowerShell(Posh-SSH)でFortigateをシャットダウンする

# はじめに
xxDの頃に、急に落ちちゃってDisk故障して泣いて。
xxE,Fになれば、そんなこともまぁなくなって。でも不安で。
だから、UPS連動の際に安全にFortigateも停止させようって言う話。でもWindowsしかないんだ！

# 前準備
PowerShellのModuleで以下を追加しておく。
```powershell:PowerShell
Install-Module -Name Posh-SSH -Verbose
```

# 本題のスクリプト
私はせっかちなんだ。
```powershell:PowerShell
#run 1st : Install-Module -Name Posh-SSH -Verbose
Import-Module -Name Posh-SSH -Verbose
$connect  = "192.168.11.21"
$username = "admin"
$password = ConvertTo-SecureString -String "sugoipassword" -AsPlainText -Force -Verbose

$credential = New-Object System.Management.Automation.PSCredential($username, $password) -Verbose

$sshSession = New-SSHSession -ComputerName $connect -Credential $credential -AcceptKey -Verbose
$stream = New-SSHShellStream -Session $sshSession -Verbose

# This Command Shutdown !!
#Invoke-SSHStreamExpectAction -ShellStream $stream -Command "execute shutdown comment volt_stop_autoshut" -ExpectString 'Do you want to continue? (y/n)' -Action "y" -Timeout 3 -Verbose
# 動作させるときは上の行のコメントアウトを削除すること。

# #not running!!!…対話型の場合、上手く動かない。y/nがある奴。
#$session = Get-SSHSession -SessionId 0
#Invoke-SSHCommand -Command "execute shutdown comment volt_stop_autoshut" -SessionId 0
#timeout 3
#Invoke-SSHCommand -Command "y" -SessionId 0
# #not running!!!
```

* `-AcceptKey`は、フィンガープリントがいちいち出てこない。

# あとがき
こういうのもあるらしい。
```powershell:PowerShell
Install-Module -Name PowerFGT
Import-Module -Name PowerFGT
$fgtIP    = "192.168.11.21"
$username = "admin"
$password = ConvertTo-SecureString "totemosugoipassword" -AsPlainText -Force
Connect-FGT -Server $fgtIP -Username $username -Password $password -SkipCertificateCheck
#Get-FGTFirewallAddress
#Get-Command -Module PowerFGT
```
WSL上でMatplotlibを使うと時に出るフォントエラーを解消する

　テスト勉強中に限って部屋の掃除をしたくなるように、研究が上手くいっていない時は何かを作りたくなる。なのでQittaで記事を書くことにする。今回はWSLでMatplotlibを使用してグラフを描こうとしたときに指定したフォントが見つからないエラーを解消する方法を記した。結論を先に書くとMatplotlibのキャッシュを削除すると直った。

 # 生じたエラーについて
　Windows11でWSLを使用してWSL上でPythonを動かしている。筆者はMatplotlib.pyplotを使用してグラフを描くのだが、Macから移行を進めているのでMac上で走っていたスクリプトはたまにエラーを吐く。今回、説明するのはフォントエラーの解消である。以下が問題の１行である。
 ```
 plt.rcParams["font.family"] = "Arial"
 ```
 と指定するとフォントが見つからないよと返ってくる。
 ```
 findfont: Font family 'Arial' not found.
 ```
 なのでこれを解消していく。

 # 1. WSLにあるフォントのチェック
 　```fc-list```で入っているフォントをチェックする。Windowsに入っているフォントを使用したい場合は[こちら](https://qiita.com/query1000/items/6ea7665529b022eb5f45)の記事を参考に設定する(コマンドが使用できない場合は```sudo apt install fontconfig```で入れる)。Arial入っているのでWSL上では少なくとも使用できる。WSLインストール時にはArialは入っていない。

# 2. Matplotlibに認識されているフォントのチェック
　以下のスクリプトでMatplotlibが認識しているフォントの一覧を表示させることができる。Arialはしっかり認識されていたけどエラーが出ている状況は変わらななかった。
 
```
from matplotlib import font_manager
fonts = font_manager.findSystemFonts(fontpaths=None, fontext='ttf')
print(fonts)
```

# 3. キャッシュの削除
ターミナルを叩いてMatplotlibが参照しているキャッシュを削除する。このキャッシュファイルを削除するとmatplotlibを起動したときに勝手にフォントのリストを再び検索して作る仕様と考えられる。初期にWSL上にArialがそもそも入ってないのでフォントを更新した後には毎回、Matplotlib上のキャッシュを消さないといけない。
```
rm ~/.cache/matplotlib -fr
```
これだけで直った。2か月くらいこの問題を放置していた。
pythonの環境変数ではまった話

# 状況
1. where pythonを実行したところ、何も表示されなかった

2. 環境変数には以下の通り登録されていた
ユーザー環境変数
```
Path=C:\Users\user-name\AppData\Local\Programs\Python\Python313\Scripts\;
C:\Users\user-name\AppData\Local\Programs\Python\Python313\;
C:\Users\user-name\AppData\Local\Programs\Python\Python310\Scripts\;
C:\Users\user-name\AppData\Local\Programs\Python\Python310\;
```
システム環境変数
```
Path=C:\Users\user-name\AppData\Local\Microsoft\WindowsApps\;
C:\Users\user-name\AppData\Local\Programs\Python\Python310\Scripts\;
C:\Users\user-name\AppData\Local\Programs\Python\Python310\;
```


# 原因
環境変数は基本的にシステム環境変数よりユーザー環境変数が優先されるが、Pathは異なる
Pathはシステム環境変数の後ろにユーザー環境変数を付け足す（上書きではない）ため、システム環境変数に通したPathが優先される。

そのため、システム環境変数に登録された以下のディレクトリに存在するpythonが最優先されていた。
```
# Path
C:\Users\user-name\AppData\Local\Microsoft\WindowsApps

# Pathに以下のpythonが存在
C:\Users\user-name\AppData\Local\Microsoft\WindowsApps\python.exe
```

これはMicrosoft Store経由でインストールされるPythonだが、キャッシュが残っているだけであり実際にはインストールされていなかった。
そのため、where pythonを実行しても何も反応がなかった。

# 対応
システム環境変数から以下のPathを削除
```
Path=C:\Users\user-name\AppData\Local\Microsoft\WindowsApps\;
C:\Users\user-name\AppData\Local\Programs\Python\Python310\Scripts\;
C:\Users\user-name\AppData\Local\Programs\Python\Python310\;
```

# 結果
where pythonを実行したところ、以下の結果が得られた
```
C:\Users\user-name\AppData\Local\Programs\Python\Python313\python.exe
C:\Users\user-name\AppData\Local\Programs\Python\Python310\python.exe
```
poetryでグローバルにインストールする方法

とある理由でpoetryを使わないといけなくなり、互換性維持のためライブラリをグローバルにインストールしなければならなかったのでやり方を調べました。

```Dockerfile
# グローバル pipx と poetry をインストール
# virtualenvs.create false poetryが仮想環境を作らないようにする (グローバルにライブラリをインストールするよう設定)
RUN pip install pipx && \
    pipx install --global poetry~=2.0.1 && \
    poetry config virtualenvs.create false

COPY pyproject.toml .
COPY poetry.lock .

# --no-root: プロジェクトのルートディレクトリにいなくても、pyproject.toml, poetry.lockがあればインストールできるオプション
RUN poetry install --no-root
```
【初心者】AWSのvCPUとインスタンス選択の肌感覚

### そもそもCPUって方？
こちらのサイトをご覧ください。（非常に親切でわかりやすいです。）

https://8vivid.net/whats-cpu/#google_vignette

### 本題のvCPUについて

一言でいうとvCPU(仮想のCPU)。バーチャルCPU。
仮想化技術のもとで成り立っている。
ゲストOSから見える仮想的なCPUコアのこと。

当然の話ではあるが、スレッド数やメモリーの量は物理的なリソースに依存。

よくPCに搭載される情報でCPUのコア数やスレッド数が表示されてると思う。
もちろん、AWSにもIntel製のCPUが存在していてコア数やスレッド数が決まっている。また、Intel製のCPUはハイパースレッディングを利用していてコア数の2倍のスレッドを処理可能。

### 100超えのvCPUも可能
クラウドならではですよね。
16コア32スレッドのかなり高性能なパソコンもawsで購入できる！

<details><summary>CPUの一般的なコア数と用途の肌感覚（トグルになってます。）</summary>

・1～2コア/1～2スレッド
最近は全く見ない、メール、ブラウジング程度にしか使えない。

・4コア/4～8スレッド
普通に事務作業する文には全然問題ない。オフィスソフトやWeb会議など

・6～8コア/12～16スレッド
モデラーとかゲーム好きが買う高性能PC。

・10コア以上/20スレッド以上
個人で持ってる人はほとんどいないと思う。
大規模なデータ解析とかわりと大規模なマイクラサーバー運営してますみたいな人（？）
</details>

### 人気なのはやはりIntel製！
実際、EC2インスタンスでも汎用性が高いのはIntel製のXeonシリーズ。
多くのデータセンターでも採用されている。

:::note info
ハイパースレッディングの関係上、表記されているvCPUのコア数の2倍のスレッド数=vCPUの数。
→性能過剰の恐れ、性能低下（仮想リソース > 物理リソース）
<details><summary>chatGPTに噛み砕いた説明を求めてみた。(トグルになってます。)</summary>


ハイパースレッディングとvCPUの関係

ハイパースレッディング（Hyper-Threading）は、Intel社の技術で、1つの物理コアが同時に2つのスレッドを処理できるようにするものです。これにより、OSや仮想環境からは、物理コア数の2倍の論理コア（vCPU）として認識されます。例えば、4つの物理コアを持つCPUでは、ハイパースレッディングにより8つのvCPUが提供されます。

性能過剰の意味

「性能過剰になってしまう」という表現は、vCPUの数が物理コア数の2倍になることで、実際の物理リソース以上に仮想リソースが割り当てられ、期待した性能が得られない可能性を指していると考えられます。ハイパースレッディングにより、各物理コアは2つのスレッドを処理できますが、物理コアのリソース（演算ユニットやキャッシュなど）は共有されます。そのため、全てのvCPUが同時に高負荷の処理を行うと、物理コアのリソースが競合し、性能が低下する可能性があります。

適切なvCPUの割り当て

仮想環境でのvCPUの割り当ては、物理コアの数やワークロードの特性を考慮して行う必要があります。ハイパースレッディングにより、物理コア数の2倍のvCPUを割り当てることは可能ですが、常に性能が2倍になるわけではありません。むしろ、適切なバランスを取らないと、リソースの競合により性能が低下するリスクがあります。そのため、システムの負荷やアプリケーションの特性を考慮し、必要以上にvCPUを割り当てないことが重要です。

まとめ

ハイパースレッディング：1つの物理コアで2つのスレッドを同時に処理する技術。
vCPUの数：ハイパースレッディングにより、物理コア数の2倍として認識される。
性能過剰のリスク：vCPUを過剰に割り当てると、物理リソースの競合により性能が低下する可能性がある。
適切な割り当て：システムの負荷やアプリケーションの特性を考慮し、適切なvCPU数を設定することが重要。
このように、ハイパースレッディングとvCPUの関係を正しく理解し、適切なリソース割り当てを行うことで、システムの性能を最適化できます。
</details>

:::

### vCPU数の拡張もできる。
必要に応じてvCPUの数を後付けできる。
スケールアップのしやすさがクラウドのメリットでもありますね。

### vCPUやインスタンス選択の肌感覚について

### 1～2 vCPU：

用途: 低トラフィックのウェブサイト、まずはこれで試してみてってやつ。（個人開発）
インスタンスタイプ例: t2.micro、t3.micro、t3a.microなど。
特徴: コストを抑えつつ、基本的な処理能力を提供。バースト可能なパフォーマンスを持つインスタンスが多く、継続的な高負荷には不向き。
### 4～8 vCPU：

用途: 中程度のトラフィックを持つウェブアプリケーション、ミドルサイズのデータベースサーバー、コンテナオーケストレーション。（企業向け）
インスタンスタイプ例: m5.xlarge、m5.2xlarge、c5.xlarge、c5.2xlargeなど。
特徴: コンピューティングリソースとメモリのバランスが良く、一般的なビジネスアプリケーションに適している。

### 16～32 vCPU：

用途: 高トラフィックのウェブアプリケーション、大規模なデータベース、ビッグデータ処理、機械学習モデルのトレーニング。（ここからコストもかなり上がってくる。）
インスタンスタイプ例: m5.4xlarge、m5.8xlarge、r5.4xlarge、r5.8xlargeなど。
特徴: 高い計算能力とメモリ容量を持ち、リソース集約型のアプリケーションやデータ処理に適している。

### 48 vCPU以上：

用途: ハイパフォーマンスコンピューティング（HPC）、大規模なデータ解析、リアルタイム処理、ディープラーニングのトレーニング。（研究用？）
インスタンスタイプ例: c5.12xlarge、c5.24xlarge、p3.16xlargeなど。
特徴: 非常に高い計算能力を提供し、専門的かつ高負荷なワークロードに対応可能。ただし、コストも高くなるため、必要性を十分に検討することが重要。



### 参考文献（参照日2025年2月16日）

https://aws.taf-jp.com/blog/25991

https://www.openupitengineer.co.jp/column/it-technology/1666
Ultralytics YOLO のライセンス

# 概要
  Ultralytics を使用する前にライセンスをしっかり確認しよう。

# Ultralytics の YOLO について
Ultralytics 社が提供するライブラリ Ultralytics で YOLO の v3 から v11 まで使用可能である。物体検出タスクにおいてとても便利なライブラリであるが、使用時にはライセンスに注意が必要である。

## 各サイト
- 公式サイト: https://www.ultralytics.com/ja
- GitHub: https://github.com/ultralytics/ultralytics
- ライセンス： https://www.ultralytics.com/ja/license


## ライセンスの注意点
- AGPL-3.0 ライセンスをベースとした独自ライセンスとなっている。
- 無料で使用する際には次のことが適用される。
  - プロジェクト全体を同じライセンス（AGPL-3.0）でオープンソース化する必要がある。
  - 修正可能である。
  - 再配布可能である。
  - 学術用メインである（※）。 
  - 学習済みモデルにも、AGPL-3.0 ライセンスが適用される。
- エンタープライズ・ライセンスに加入すれば、次の利点がある。
  - オープンソース化せずに、特許使用と商用利用が可能である。
  
（※） AGPL-3.0 に従えば、オープンソース化すれば商用でも使用可能と思われるが、Ultralytics のライセンス文からでは詳細は不明である。

# ライセンスに関する考察

## 学習済みモデルに AGPL-3.0 ライセンスが適用されることについて
Ultralytics の CEO Glenn Jocher は GitHub の Issue において、上記の通り学習済みモデルにもライセンスが適用されると述べている。一般に、学習済みモデルというパラメータをどう扱うか長年議論されてきているが、Ultralytics では学習済みモデルは AGPL-3.0 ライセンスが適用されるのに十分注意する必要がある。商用ソフトウェアで学習済みモデルを組み込んでオープンソース化せず使用したい場合は、エンタープライズへの加入が必要である。

該当の Issue: https://github.com/ultralytics/ultralytics/issues/2129

- コメント1: https://github.com/ultralytics/ultralytics/issues/2129#issuecomment-1516026065
    ```
    I checked with our legal team! This is how it works: both the training code and models are under AGPL, so any downstream solution that includes YOLOv8 training code or a trained model (both pretrained or custom trained) inside it should be open-sourced to comply with the AGPL conditions.

    If you'd prefer not to open-source your work we have enterprise licenses available at https://ultralytics.com/license

    Let me know if this answers your question!
    ```

- コメント2: https://github.com/ultralytics/ultralytics/issues/2129#issuecomment-1656062630
    ```
    The interpretation of GPL depends highly on the jurisdiction and the context. We acknowledge that our interpretation may differ from others. It touched on the transformative nature of machine learning and how a model trained using a base framework should be classified. We see the characteristics of the model weights more as a derivative of the software, while others see them as data.

    We understand that there are multiple interpretations of this issue. That's why we strongly recommend every user consult their own legal counsel to ensure compliance with open-source licensing in their specific use case. We always strive to encourage an open, collaborative environment under fair licensing terms.

    We appreciate your understanding and your contributions to this important discussion.
    ```

## ライセンスに関する議論
reddit においても Ultralytics のライセンスに関する議論が行われている。確かに Ultralitcs 社が開発したのは、YOLO v5, v8, v11 だが、それ以外のバージョンの YOLO にも同ライセンスを適用しているのは疑問である（Ultralytics ライブラリに組み込まれているからと言えばそれはそうであるが…）。
https://www.reddit.com/r/computervision/comments/1e3uxro/ultralytics_new_agpl30_license_exploiting/

# 参考
- [YOLOの各バージョンについてまとめ](https://qiita.com/tfukumori/items/519d84bf3feb8d246924)
情報学部生がメガベンチャーエンジニアになるために！　３年春休み編

# Spring Bootを活用した実践的なAPI開発ロードマップ
### 目標
・学生ハッカソンに参加する！
・Spring Bootで実践的なAPIを作れるようになる
・MySQLと連携し、認証・認可を実装できるようになる
・フロントエンドとスムーズに連携できる

## 学習ロードマップ
基本的に動画講義ハンズオン形式で体系的に学ぶ。

### 1,Todolist作成の講義(CRUD + MySQL)
・目標：基本のCRUDをしっかり固める
・ゴール：Spring Bootでデータの保存・取得・更新・削除を実装
・アウトプット：GItHubにアップ

### 2,フォーム認証と権限管理の講義
・目標：APIの認証・認可の仕組みを学ぶ
・ゴール：ユーザーごとのデータ管理、ログイン必須のAPIを作る
・応用：Todolist APIに認証を追加

### 3,スキーマ駆動開発の講義(API設計 ＆ フロント連携)
・目的：API設計を聖書に決めて、効率的に発見する方法を学ぶ
・ゴール：OpenAPI(Swagger)を使い、フロントと連携しやすいAPIを設計
・応用：これまで作ったTodolist APIをスキーマ駆動開発の考え方で整理

## アウトプット方法
・Todolistに学んだことを追加（進捗管理）
・Qiitaに記事を書く（学んだことの整理）
・GitHubのREADMEを充実させる（簡単なメモでもOK）
個人的備忘録：自分なりに Linux で計画的にシャットダウンできる shutdown コマンドを簡単にまとめてみた

## はじめに  
Linux を使用していると、システムを安全にシャットダウンしたり、スケジュールを管理したりする場面に遭遇します。

:::note info
**その中でも `shutdown` コマンドは、システムの停止や再起動を制御する重要なコマンドの一つです。**
:::

本記事では、`shutdown -h now` の基本的な使い方や、シャットダウンの予約・キャンセル方法について解説します。  

## 書こうと思ったきっかけ  
システム管理を行っていると、突然のシャットダウンや計画的な再起動が必要になることがあります。

:::note warn
***しかし、`shutdown` コマンドの正しい使い方を知らないと、予期せぬトラブルを引き起こす可能性もあります。***
:::

そこで、基本的な使い方や注意点を整理し、安全にシャットダウンを管理できるようにするために、この内容をまとめました。

## 1. `shutdown -h now` とは？
`shutdown -h now` は、Linuxシステムを即座にシャットダウン（停止）させるコマンドです。

### 1.1 コマンドの構成
- `shutdown`：システムのシャットダウンや再起動を制御するコマンド。
- `-h`：システムを停止（halt）するオプション。
- `now`：すぐに実行する指定。

このコマンドを実行すると、すぐにマシンがシャットダウンするため、リモート環境や重要な作業中の環境で不用意に実行しないように注意してください。

## 2. シャットダウンの予約方法
シャットダウンを特定の時間にスケジュールすることもできます。

### 2.1 指定時間後にシャットダウン
```bash
shutdown -h +10  # 10分後にシャットダウン
```

### 2.2 指定時刻にシャットダウン
```bash
shutdown -h 22:00  # 22:00にシャットダウン
```

## 3. シャットダウンのキャンセル
予約したシャットダウンをキャンセルする場合は、以下のコマンドを実行します。
```bash
shutdown -c
```
このコマンドを実行すると、スケジュールされたシャットダウンが取り消されます。

## 4. その他のオプション
`shutdown` コマンドには、他にもさまざまなオプションがあります。

| オプション | 説明 |
|------------|------|
| `-r` | システムを再起動（reboot）する |
| `-P` | 電源をオフにする（通常 `-h` と同じ動作） |
| `-c` | スケジュールされたシャットダウンをキャンセルする |
| `-k` | 実際にはシャットダウンせず、警告メッセージのみ送信する |

## 5. まとめ
`shutdown -h now` は、Linuxシステムを即時に停止する強力なコマンドです。誤って実行すると、作業中のデータが失われる可能性があるため、慎重に使用してください。

:::note info
***また、シャットダウンを予約することで、計画的にシステムを停止することもできます。必要に応じてキャンセルする方法も覚えておくと便利です。***
:::

以上の情報を活用して、安全にLinuxシステムを管理しましょう！
Excel VBA [備忘録]FreeFile関数について

### はじめに
FreeFile関数についての備忘録です。

### プロシジャーの説明



#### サンプル１　ExcelファイルやCSVファイルを開く
ExcelファイルやCSVファイルを操作する際には、Workbooks.OpenメソッドやOpenステートメントを使用。ファイル番号は必要ありません。
``` VB
' Excelファイルを開く例
Dim wb As Workbook
Set wb = Workbooks.Open("C:\path\to\your\file.xlsx")

' CSVファイルを開く例
Dim csvWs As Worksheet
Set csvWs = Workbooks.Open("C:\path\to\your\file.csv").Sheets(1)
```

#### サンプル２　テキストファイルを操作する
VBAでは、FreeFile関数はテキストファイルやバイナリファイルを操作する際に使用
``` VB
Dim fileNum As Integer
fileNum = FreeFile
Open "C:\path\to\your\file.txt" For Output As #fileNum
Print #fileNum, "Hello, World!"
Close #fileNum
```
##### #fileNumについて
#fileNumと書くことで、VBAに対して「このファイル番号のファイルを操作する」ということを明示しています。「#」はファイル番号であることを明示するためのプレフィックスであり、他の変数や数値と区別するために使われます。Print #fileNum, "Hello, World!"というステートメントは、指定されたファイル番号を持つファイルに対して文字列を書き込むことを意味します。