OmniAICreator/Qiita-1.07M huggingface dataset:
Databricksのvector_search関数

こちらのSQL関数がパブリックプレビューになりました。

https://docs.databricks.com/en/sql/language-manual/functions/vector_search.html

`vector_search()`関数によって、SQLを用いて[Mosaic AI Vector Search](https://docs.databricks.com/ja/generative-ai/vector-search.html)のインデックスにクエリーを行えるようになります。

# 要件

- この関数はクラシックSQLウェアハウスでは利用できません。
- 詳細は、[Databricks SQLのプライシング](https://www.databricks.com/jp/product/pricing/databricks-sql)のページをご覧ください。
- この関数は、[Mosaic AI Vector Searchがサポートされているリージョン](https://docs.databricks.com/ja/resources/feature-region-support.html#ai-aws)で利用できます。

# 構文

```sql
vector_search(index, query, num_results)
```

# 引数

全ての引数は`vector_search(index => indexName, query => queryText)`のように名前で指定しなくてはなりません。

- `index`: 同じワークスペースに存在する、呼び出す既存のベクトルサーチインデックスの完全修飾名を表す`STRING`の定数。定義するユーザーはインデックスに対して"SELECT"権限が必要です。
- `query`: インデックスを検索する文字列を表現する`STRING`のエクスプレッション。
- `num_results`(オプション): 返却するレコードの最大数を示す整数値。デフォルトは10。

# 戻り値

インデックスでトップでマッチしたレコードのテーブル。インデックスの全てのカラムが含まれます。

# サンプル

Vector Searchが使えるAWS東京リージョンで試します。

```sql
SELECT
  title,
  body_sub
FROM
  VECTOR_SEARCH(
    index => "takaakiyayoi_catalog.vector_seach.taka_qiita_vs",
    query => "Databricksとは何か",
    num_results => 5
  )
```

ちゃんと動いていますね。
![Screenshot 2024-10-02 at 8.42.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/23c194e4-719a-ed01-ff33-3b311b484ef4.png)

# 制限

プレビュー中には以下の制限が適用されます:

- インデックスタイプ`DIRECT_ACCESS`へのクエリーはサポートされません。
- `embedding_vector_columns`を持つインデックスはサポートされません。
- 入力パラメーター`filters_json`や`columns`はサポートされません。
- `num_results`が100より大きいベクトル検索はサポートされません。
- ソーステーブルに対して`READ`権限を持たないユーザーは、`vector_search()`を使うことはできません。
- [プロビジョニングされたスループットの基盤モデルAPI](https://docs.databricks.com/ja/machine-learning/foundation-models/index.html#provisioned-throughput-foundation-model-apis)を用いているモデルサービングエンドポイントで`vector_search`を使うことはできません

### はじめてのDatabricks

[はじめてのDatabricks](https://qiita.com/taka_yayoi/items/8dc72d083edb879a5e5d)

### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
DCとNAの違い

## DCとNAの違い

- **DC (Don’t Care)**:
    - 特定の条件や値が重要でない場合に使用されます。無視しても問題ない状態を示します。

- **NA (Not Available/Not Applicable)**:
    - データや情報が存在しない場合や、特定の条件や項目が該当しない場合に使用されます。


## DC (Don’t Care) とは？

`DC`（Don’t Care）は、特定の条件や状況において、値や状態が重要でない場合に使用される一般的な用語です。

## NA (Not Available/Not Applicable) とは？

`NA`は「Not Available」または「Not Applicable」を意味し、以下のような場合に使用されます：

1. **Not Available（利用不可）**:
    - データや情報が存在しない場合に使用されます。例えば、データベースのフィールドに値が存在しない場合や、特定のデータが収集されていない場合に`NA`が使用されます。

2. **Not Applicable（該当なし）**:
    - 特定の条件や項目が詄当しない場合に使用されます。例えば、特定の質問が特定のユーザーに対して適用されない場合や、特定のフィールドが特定のレコードに対して関連性がない場合に`NA`が使用されます。

### 使用例

- **データベースフィールド**:
    ```plaintext
    このフィールドはNAです。（このフィールドには該当するデータがありません）
    ```

- **アンケート調査**:
    ```plaintext
    質問: あなたは車を所有していますか？
    回答: NA（該当なし） - この質問は車を所有していない人には該当しません。
    ```


## まとめ

`DC`（Don’t Care）と`NA`（Not Available/Not Applicable）は、データや情報の管理において重要な概念です。`DC`は無視しても問題ない状態を示し、`NA`はデータが存在しない場合や特定の条件が該当しない場合に使用されます。
ローカルでは動くのにApp Serviceでfailed during startup

# 動かない
おかしい、色々調べてあってるはずなのにとなってハマってしまいました。

App Serviceのデプロイセンターのログ
```
Stopping site xxx because it failed during startup
```

## 前提
Web App
コンテナデプロイ
Linux
Azure Container Registry
単一コンテナー
開発環境 Mac M1


## 確認事項
- アドレス 0.0.0.0
- ポート 8080または80
    - それ以外の場合、Appserviceの環境変数にWEBSITES_PORTとして設定している
- ビルドしたイメージが以下コマンドでアクセス可能

```bash
docker run -p 8080:8080 {イメージ名}:{タグ}
```


- DockerfileでENTRYPOINTなどの起動コマンドがない場合、以下コマンドでDockerの中に入り起動コマンドを実行してアクセスできる
    - そのコマンドをApp Serviceのスタートアップコマンドに設定している

```bash
docker ps
docker exec -it {コンテナID} /bin/bash
```

## それでも動かない
ACRへPUSHするイメージをビルドする際、 --platform linux/amd64を指定する

```
docker build --platform linux/amd64 -t {イメージ名}:latest . \
```

これで動きました
M1やM2のMacを指定していると、CPUアーキテクチャが違うらしくエラーになるとのことでした。
エラーが出ない（見つけられない、、）のですごく時間使ってしまいました。。。

## もっと詳しいのあった
この記事を書くときに調べると、エラー調査方法と、CPUアーキテクチャの調べ方まで載っている記事を見つけました
（早く知りたかった。。。）
https://zenn.dev/murakami_koki/articles/a3cf2ab6f5f261
【基本情報】独学マラソン ACID特性 Day 2

努力を努力と思わないレベルへ‥

:::note worn
この記事は自分用の備忘録です。
:::


# トランザクションとは

<br>

- 1つの作業単位として扱われるあらゆる操作のこと
- 複数の処理を1セット扱い
    - 処理の間に他のSQLが割り込んでこないようにする
- もし途中で作業が失敗したらロールバックしてなかったことにする
- 中間はなく、成功か失敗のみ
    - もし銀行で預金を引き出す処理で中間状態が残っていたら、お金を引き出しても残高が減らないとかになりそう

<br>

# ACID特性とは

トランザクション処理に備わっていなければならない4つの特性である

### Atomicity（原子性）

- 処理が成功する（COMMIT）かなかったことにする（ROLLBACK）かの2択
- 原子なのでそれ以上分割できない
- ALL or NOTHING

<br>

### Consistency（一貫性）

- データに矛盾が生じないようにする
- NOT NULLやUNIQUEなどの制約できちんと整備されていれば良い
- 要は変なデータ入らんように守っておくってこと

<br>

### Isolation（独立性）

- 複数のトランザクションが互いに干渉しないよう独立して動くこと
- ダーティーリード（終わってない処理を読み取るやつ）やファントムリード（終わってない処理に横入りするやつ）が発生しないようにする
- レベル設定ができて、厳しくしすぎるとファントムリードが発生しないがパフォーマンスは落ちるらしい

<br>

### Durability（永続性）

- 停電とかあってもデータが消えないように
- ログを残すようにするらしい
    - WALと呼ばれている
- COMMIT後、ディスクに強制書き込みしたりする
    - パフォーマンス上げるために、メモリ上のキャッシュにデータを保存しておいて後でまとめて書き込むんだとか

<br>

# 感想
ちょうど2年前ぐらいに学んだ「スッキリわかるSQL入門」の内容だったので、すぐに思い出せてよかった。あの頃はバッジ処理とかパフォーマンスのこととか全くイメージできんかったなぁ。成長していると喜んでおこう。

# 参考

https://www.geeksforgeeks.org/acid-properties-in-dbms/
【個人開発】Railsで経営・起業につかえるフレームワーク分析アプリを作成!

この度、実は前から考えていた、フレームワークアプリを作りました！
以前、↓Nolaというサービスを見かけたときに、小説→経営や起業に置き換えたエディターツールって便利なのでは？と思ったのがきっかけです。

https://nola-novel.com/

## アプリ紹介
そこで今回、経営・起業フレームワーク分析ができるアプリ、Compassbookを作成しました。
PEST分析、3C分析、STP分析、4P分析、ビジネスモデルキャンバスの記入が可能です。

サイトはこちら
URL:https://compassbook.onrender.com/

閲覧用アカウント
ID:test@test.co.jp
Pass:111111


※自由に書き込みや登録いただいて大丈夫です。その際はご自身でアカウントを作成ください。
※ポートフォリオの役割があるため、場合によっては投稿を削除する可能性がございます。予めご了承ください。

Githubはこちら
https://github.com/yusukesugahara/compassbook

## サービス概要
経営や起業のためのフレームワーク分析を行えるアプリです。
PEST、3C、STP、4P、ビジネスモデルキャンバスのフォーマットが利用可能です。
順次フレームワークは追加予定です。

## 開発背景
### 1、もともと経営や起業といった分野に興味があり、こういうアプリを作ってみたかった。
本屋さんに行ったらビジネス書コーナーまっしぐらという私です。とにかくビジネス書が好きなので、私の好きな二つを組み合わせて（IT×経営・起業）今回のアプリを作成しました。

### 2、Ruby on Railsを使用したアプリを作るため
現在転職活動中です。応募先企業様にRuby on Railsを使用されていることがあり、ポートフォリオとしてこちらのアプリを作りました。

## MERNスタックとRails違い
先週まで、MERNスタックでアプリを作り、今回はRailsでアプリを作りました。
感想としては、簡単に書けるのはRailsだと感じました。MVCの形で、記載するファイルが少ないためどこに何を書いたのかも探しやすい。
また、ドキュメントが日本語化されていることや、日本語の検索結果にRailsの情報が出やすいことが良いことだと思いました。
一方で、ChatGPTを使って開発する場合、Railsは弱いのかなと感じました。MERNスタックの時に比べて、情報が出にくいと感じました。英語圏のデータを使っているためか？？？

おそらく、作りやすさ以外の動作速度など非機能要件的なところで差がつくのかなと仮説を考えてみたり。。。
今後学習を続けながら、どんな差があるのかを確認できたらと思います。


## メイン機能
### 一覧表示・記事閲覧
[![Image from Gyazo](https://i.gyazo.com/e94070a7be8772e510fc5e07c6deffb7.gif)](https://gyazo.com/e94070a7be8772e510fc5e07c6deffb7)

### 投稿の作成、編集、削除機能
投稿・編集
[![Image from Gyazo](https://i.gyazo.com/d54b4af3fbcec501b2bf3103a7a45e69.gif)](https://gyazo.com/d54b4af3fbcec501b2bf3103a7a45e69)

## その他機能
### ユーザー登録、ユーザーログイン
[![Image from Gyazo](https://i.gyazo.com/3484d5d6b868ad3d83e962b4f9b8a24a.gif)](https://gyazo.com/3484d5d6b868ad3d83e962b4f9b8a24a)


## 工夫点
・ボタンの色や配置を工夫し、直感的に操作できるようになっています。
・セキュリティ対策**：ログインパスワードの暗号化、ユーザー認証機能の実装を行っています。

## 苦労した点
Herokuが有料化されていたため、無料で使えるサーバを自ら探しました。その結果、Renderに選定しました。
Dockerを使ってのデプロイで、初めてだったので苦労しながらなんとかデプロイできました。
Renderはエラーログの出力が充実しておらず？エラーは出ているものの詳細な情報がなく苦労しました。
こちらの記事に書いています。
https://qiita.com/sghr2020/items/822008e9987ad88a6bc6
## ER図作成
![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426016/a85bbfd8-c446-36d6-8c70-97fcde21419f.png)
## 構成図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426016/9ff25140-1bf0-1c16-bc48-f1ff4163538d.png)


## 技術スタック
| カテゴリ | 技術スタック | 
|:-----------|:------------|
| フロント・バックエンド| Rails 7.2.1 Ruby3.2.0    |
| データベース| PostgreSQL 13|
|開発環境|Docker|
| デプロイ     | Render      |

## 終わりに
最後までご覧いただきありがとうございました。
今後もアプリ制作を続けていきたいと思っております。
フィードバック等ございましたらいただけますと幸いです。
何卒、よろしくお願いいたします。
【AWS】サブネットとサブネットグループを作成する

# はじめに
この記事では、RDS 向けにサブネットとサブネットグループを作成する手順を記載します。

https://aws.amazon.com/rds/

# サブネットを2つ作成する
以下の手順でサブネット作成画面に遷移します。

1. VPC のダッシュボードを開く
1. ダッシュボードの左側のメニューから「Subnets」をクリックして、Subnets 画面を開く
1. Subnets 画面右上の「Create subnet」をクリックする

それぞれ以下の値を選択・入力して「Create subnet」をクリックします。

**1つ目の VPC**
- VPC
  - VPC ID : 任意の VPC
- Subnet settings
  - Subnet name : db-subnet-01
  - Availability Zone : ap-northeast-1a
  - IPv4 subnet CIDR block : 10.0.2.0/24

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/efb40e62-779d-d07c-8936-a652bbb35af8.png)

**2つ目の VPC**
- VPC
  - VPC ID : 1つ目と同じ VPC
- Subnet settings
  - Subnet name : db-subnet-02
  - Availability Zone : ap-northeast-1c
  - IPv4 subnet CIDR block : 10.0.4.0/24

# サブネットグループを作成する
以下の手順でサブネットグループ作成画面に遷移します。

1. RDS のダッシュボードを開く
1. ダッシュボードの左側のメニューから「Subnet groups」をクリックする
1. Subnet groups 画面右上の「Create DB subnet group」をクリックする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/53aa300d-a03b-4546-46f8-0f27c6a0abbd.png)

サブネットグループ作成画面で以下の値を入力して「Create」ボタンをクリックします。

- Subnet group details
  - Name : my-subnet-group
  - Description : my-subnet-group description
  - VPC : サブネット作成時に選択した VPC
- Add subnets
  - Availability Zones : ap-northeast-1a、ap-northeast-1c
  - Subnets : 先ほど作成した2つのサブネット

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/271d06b0-4196-21c1-2981-c5ea17e15d1b.png)

作成に成功すると、成功したメッセージが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/c922075e-f9e5-87ef-f285-5004bb4da659.png)

# 参照
- [Working with a DB instance in a VPC](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_VPC.WorkingWithRDSInstanceinaVPC.html)
【Linux】LPIC201合格の最短ルート

## 使用した書籍やサイト
・あずき本
・スピマス（通称：白本）
・ping-t

## 受験までの期間
・２週間（１日：約２～３時間勉強のペースで）

試験までの流れ
１．あずき本をとりあえず一通り読んでみる。（全部を理解する必要はない。）

２．ping-tの最強Web問題集を使用（10問形式で解く→解説を繰り返して全問行う。）
【重要！】この期間が一番しんどいけど、諦めずに毎日コツコツと短い時間でもいいから継続する。

３．スピマスの第１章～第７章までを解いて、間違えたところは解説を読んで疑問がなくなるようにする。

４．２を全問分２～３回分繰り返したら、模擬試験にチャレンジしてみる。

５．模擬試験でコンスタントに９割取れればPeasonVUEにて試験予約

６．コマ問を解いてみる。（実際にコマンド手打ちでの解答により理解が深まる。）

７．試験前日か当日の空き時間にスピマスの模擬試験を解いてみる。

８．試験

## 受験してみての感想
　LPICレベル１から助けられているping-t様様だと感じました。加えて、スピマスの問題集も試験に近い問題が多く掲載されている印象でした。
 是非、受験を考えている方は参考にしてください。
【Docker】DockerFile

## Dockerfileとは
Dockerfileは、Dockerイメージを作成するためのテキストファイル

以下の情報が記述される

- 基本となるOS
- インストールする必要があるソフトウェア
- コピーするファイル・ディレクトリ
- 実行するコマンド

```docker
#### ベースとなるイメージを指定
FROM python:3.7-alpine

#### 作業ディレクトリを指定
WORKDIR /app
# /app ディレクトリを作業ディレクトリに指定
# 存在しない場合でも自動的に作成される

#### ローカルファイルをDockerイメージにコピー
COPY ./src/ /app/
# ローカルのsrcディレクトリをコンテナの/appディレクトリにコピー
# srcディレクトリ内のすべてのファイルが/appに入る

#### 必要なパッケージをインストール
RUN apk update && apk add --no-cache python3 gcc musl-dev libc-dev
# Alpineベースのイメージでパッケージリストを更新し、Python3関連のツールと依存関係をインストール

#### Pythonの依存パッケージをインストール
COPY requirements.txt /app/
RUN pip3 install --no-cache-dir -r requirements.txt
# requirements.txtに記載されたPythonの依存パッケージをインストール

#### ENTRYPOINT命令でコンテナ起動時に実行されるコマンドを指定
ENTRYPOINT ["python3", "app.py"]
# コンテナ起動時に必ず "python3 app.py" が実行されるように指定
```

## FROM
作成するコンテナのベースとなるイメージを指定
`FROM ubuntu:18.04`と記述すると、Ubuntu 18.04をベースにしたイメージが作成

コロンの後にタグを指定
タグなしの場合、latest(最新)が選択される
```docker
FROM イメージ[:タグ]
# example
FROM python:3.7-alpine
```

## WORKDIR
コマンドを実行する作業ディレクトリを指定
`WORKDIR /app`と記述すると、その後のRUN、CMD、ENTRYPOINT、COPY、ADD命令が/appディレクトリで実行される

>※ディレクトリが存在しない場合:
指定したディレクトリがイメージ内に存在しない場合でも、自動的にそのディレクトリが作成されます。たとえば、以下のように /app/mydir がまだ存在しない場合でも、自動的に作成されます。
```docker
WORKDIR /app/mydir
```

>※Dockerfile に WORKDIR が存在しない場合、
ルートディレクトリ（/）に自動で作成されます。

## COPY
ソースコードや設定ファイルをローカルからDockerイメージにコピーする
`COPY index.html /mydir/index.html`と記述すると、ローカルの`index.html`がイメージ(コンテナ)の`/mydir/index.html`にコピーされる

```docker
COPY <コピー元ファイル名(orディレクトリ名)> <コピー先ディレクトリ名>
# example
COPY ../web/src/index.html /var/www/
COPY ../web/script/ /var/www/script/
COPY *.txt /var/www/docs/
```

よく使われる「.」について
```docker
## . は 現在のローカルディレクトリ を指します（Dockerfileが置かれているディレクトリ)
# DockerFileの置いてあるフォルダの内容を全ての内容をappディレクトリにコピー
COPY . /app

# ローカルディレクトリのすべての内容を、
# コンテナのカレントディレクトリ（WORKDIRで指定された場所）にコピー
COPY . .
```
------------------------------------
例：
```docker
COPY . /app
```
もしローカルの`project/`ディレクトリに以下のファイルがあるとします:
Dockerfileは`/home/user/project/`にある状態。
```
/home/user/project/
├── Dockerfile
├── app.py
└── requirements.txt
```
この命令により、コンテナ内に`/app`フォルダが作成され、その中に`app.py`と`requirements.txt`がコピーされます。


## RUN
イメージ作成時に実行するコマンドを指定します。例えば、`RUN apt-get update && apt-get install -y git`と記述すると、イメージ作成時にパッケージリストの更新とgitのインストールが行われます

## ENTRYPOINT
コンテナ起動時に実行するコマンドとオプションを変更できる
原則は末尾に記載する
コンテナを実行したときに”必ず”実行されるコマンド

```docker
# コンテナ起動時に必ず "ping 127.0.0.1 -c 100" コマンドが実行される
# "ping" コマンドはネットワーク接続のテストに使用
# "127.0.0.1" はlocalhostを指すIPアドレス
# "-c 100" はパケットを100回送信することを指定している
ENTRYPOINT ["ping", "127.0.0.1", "-c", "100"]

# このコンテナは、起動すると 127.0.0.1 に対して 100 回の ping を実行し、その後終了します。
```


## CMD 
起動時に実行するコマンド
1つのDockerfileで1度だけ指定できる
```docker
CMD <コマンド>
# example
CMD python -m http.server 80
```

## ENV
環境変数の定義
```docker
ENV <環境変数名>=<値>
# example
ENV TZ=Asia/Tokyo
# イコールの代わりに半角スペースでもOK
ENV DB_ENDPOINT 172.16.0.2
```
UbuntuでPCの有線LANインターフェースにIPアドレスを設定する方法

今回は有線LANインターフェースにIPアドレスを設定していきます。
今後のやりたいことのための準備です〜
# プライベートIPアドレスの範囲
ネットワークに合わせて設定してください。
- 10.0.0.0~10.255.255.255
- 172.16.0.0~172.31.255.255
- 192.168.0.0~192.168.255.255
# 必要なネットワークインターフェースの確認
ターミナルを開いて、利用可能なネットワークインターフェースを確認します。
``ip link show``
「enp0」や「eth1」を確認してください。
# 接続プロファイルの設定
既存の接続プロファイルを確認します。
``nmcli connection show``
「Wired connection 1」や「有線接続 1」を確認してください。
# IPアドレスの設定
- "プロファイル名"：確認したプロファイルを使用します。
- "インターフェース名"：確認したネットワークインターフェース名を使用します。
- "設定したいIPアドレス"：プライベートIPアドレスの範囲を使用します。
(例)192.168.1.100/24
``sudo nmcli connection modify "プロファイル名" ifname "インターフェース名" ipv4.addresses "設定したいIPアドレス" ipv4.method manual``
# 設定の適用
有線接続プロファイルを再起動して設定を適用します。
- 接続を無効化する
``sudo nmcli connection down "プロファイル名"``
- 接続を有効化する
``sudo nmcli connection up "プロファイル名"``
# 設定の確認
- 現在アクティブな接続を確認します。
``nmcli connection show --active``
- インターフェースのIPアドレスを確認
設定したIPアドレスが表示されることを確認してください。
``ip addr show "インターフェース名"``

適用されていれば、設定は以上です。
# 有線接続を無効化する方法
念の為、書いておきます。
``sudo nmcli connection down "プロファイル名"``
# 最後に
今回の手順は今後いろいろと使っていくのかな？と感じています。
コツコツとやっていこうと思います！
[Python] 辞書操作

# 辞書のキーと値を入れ替える
こんな感じです。
~~~Python:Irekae.py
dic = {"英語":90, "国語":85, "数学":82, "理科":95, "社会":84}
reversed_dic = {j:i for i, j in dic.items()}
print(reversed_dic)
# 出力結果
{90:'英語', 85:'国語', 82:'数学', 95:'理科', 84:'社会'}
~~~
# ２つの辞書をマージする　その１
辞書に対してアスタリスク２つをつけると、キーワード引数としてアンパックできるので、アスタリスクを２つつけた辞書データを{}で囲って結合します。
~~~Python:merged_dict1.py
menu1 = {"カツカレー":850, "味噌カツ定食":900, "アジフライ定食":800}
menu2 = {"鯖の塩焼き定食":950, "シェフの気まぐれ定食":1000}
merged_menu = {**menu1, **menu2}
print(merged_menu)
# 出力結果 
# {'カツカレー':850, '味噌カツ定食':900, 'アジフライ定食':800, 鯖の塩焼き定食':950, 'シェフの気まぐれ定食':1000}
~~~
# ２つの辞書をマージする　その２
Python3.9以降はマージ演算子 | が使えるのでそれを使います。便利ですね！
~~~Python:merged_dict2.py
menu1 = {"カツカレー":850, "味噌カツ定食":900, "アジフライ定食":800}
menu2 = {"鯖の塩焼き定食":950, "シェフの気まぐれ定食":1000}
merged_menu = menu1 | menu2
print(merged_menu)
# 出力結果はその１と同じです。
~~~
# ２つの辞書をマージする　その３
update()メソッドを使います。なお、辞書のキーが重複した場合は、追加する辞書の値で上書きされます。
~~~Python:merged_dict3.py
import copy

menu1 = {"カツカレー":850, "味噌カツ定食":900, "アジフライ定食":800}
menu2 = {"鯖の塩焼き定食":950, "シェフの気まぐれ定食":1000}
merged_menu = copy.copy(menu1)
merged_menu.update(menu2)
print(merged_menu)
# 出力結果はその１、その２と同じです。
~~~
日々進化しているAmazon Q

## Amazon Qとは
2023 年 11 月末よりAWSがプレビュー提供を開始した、AWS のサービスやベストプラクティスに関する知識を学習した生成 AI アシスタントです。
https://aws.amazon.com/jp/builders-flash/202402/amazon-q-console-support/

## Amazon Q for AWS Builder Use
Amazon Qには複数のサービスがあります。
その中に、Chat形式の「Amazon Q for AWS Builder Use」がAWS利用者支援に向けるサービスです。
AWS Consoleに統合され、Console画面の右上にある六角形のマークをクリックするとアクセスすることができます。 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3470230/f5ddd1c9-2b6e-1b9f-2dd9-99ba58206ca2.png)

## 進化スピードの速いを体感した１例
ただ１日の差で、同じ問題に対する回答が真逆になりました。

- Q-1: How to download multiple files from an Amazon S3 bucket?
- A-1: CLIでaws s3 syncの利用
その回答自体は問題ないですが、回答文に以下の"ただし文"があります。
 It will also delete any files in the local directory that are not present in the S3 bucket, so be careful when using this command.
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3470230/6a18e5a7-8e2c-c270-44e8-399769dd284a.png)

その"ただし文"に気になったため、再度聞いてみました。
- Q-2: Does the sync command will also delete any files in the local directory that are not present in the S3 bucket?
- A-2: YES

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3470230/9db53274-8d8c-b881-a880-2f274230da34.png)

その場でその回答が間違ったとfeedbackしました。
そして、翌日同じ問題を聞いてみた結果、正しく回答してくれました。
- Q-3: Does the sync command will also delete any files in the local directory that are not present in the S3 bucket?
- A-3: No

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3470230/5c4c7744-a187-63e9-b255-c65212d1d1b9.png)

さすがです！
ログインでのエラー



+ [特別版のDEにログインできない](https://qiita.com/Keiji_otsubo/items/3cb107492175fdc46187)

# PLCにログインできません

+ [PLCにログインできません](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000MgjyCSAR)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/835e9779-4cc8-6a61-79c9-c944632567b7.png)


:::note
ブラウザのシークレットモードでログインすると入れるようになります。

また、ブラウザの履歴とキャッシュのクリアをしてからブラウザの再起動を行い、Partner Communityに接続しているSalesforce以外に接続することなくログインすると入れるようです。
:::

+ [【未解決】Unable to login to Partner Portal or PLC](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007epjkgSAA)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/e6607fe3-98c3-b787-d5e5-18f2590eef9c.png)


# Unable to LogIn

+ [Unable to LogIn](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000Jda5r)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/6db5c6cf-1fee-bcba-713a-91312b261ee6.png)

:::note
Please follow below url:-

https://trailblazer.salesforce.com/answersHome_1%3Fid=9063A000000q0clQAA?id=9064V000000tP6WQAU
:::

# trailhead

+ [【未解決】Trailhead login](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007iftym)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/0cf65ef8-1ce6-72f8-9f8f-c601cc5bd901.png)
Azure Functions で スクレイピングするため、Praywrightを動かしたい～2つ目の関数を追加～

[Azure Functions (FaaS)で スクレイピングするため、Puppeteer / Praywrightを動かしたい](https://qiita.com/teraco/items/86006ef8636de694f2c5) の続きです。

### 修正点

- 前回は写経しただけなので、JST Clockの画面ショットを取得するコードをデプロイした
- 次は自分のコードをデプロイしたい
- 前回の手順を1から再実行する必要がある…と思ったが、よくよく考えればdockerのイメージはAzure上にあるので、関数だけ追加すればよい
    - 自分のコードもPlaywright以外は利用しないシンプルなものなので


### やったこと

#### 1.ローカルのプロジェクトディレクトリに2つ目のHTTP Trigger 関数を作成

```
# 2つめのHTTP Trigger の関数を作成します。
func new --name httpTrigger2 --template "HTTP trigger" --authlevel "anonymous"
```
Azure Functions のプロジェクトディレクトリは前回の手順で作成済みなので、関数だけを作成。

※プロジェクトディレクトリを作成するコマンドは参考までに以下。

```
func init --worker-runtime node --language javascript --docker
```

### 1-2.ローカルで動作確認する場合

ローカルの Azure Functions ランタイム ホストを起動して関数の動作を確認する。
http://localhost:7071/api/httpTrigger2 にアクセスして、期待する動作が行われていることを確認します。

※ 写経元の [Azure Functions on Azure Container Apps で Playwright をサーバーレスで実行する](https://zenn.dev/awell/articles/auzre-functions-on-container-apps-for-playwright) に書いてありました。
 
```
func start
```

2つの関数が正しく認識されれば、Functions:以下の2つの関数と対応するURLが表示される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147841/c3a24056-9856-0ada-0783-de5bef46b0bd.png)

```
# 2つめのHTTP Trigger の関数を作成します。
func new --name httpTrigger2 --template "HTTP trigger" --authlevel "anonymous"
```

で --name httpTrigger2を指定したことで、生成されるhttpTrigger2.jsのコードがapp.http('httpTrigger2', { ～となる。

```javascript
const { app } = require('@azure/functions');

app.http('httpTrigger2', {
    methods: ['GET', 'POST'],
    authLevel: 'anonymous',
    handler: async (request, context) => {
        context.log(`Http function processed request for url "${request.url}"`);

        const name = request.query.get('name') || await request.text() || 'world';

        return { body: `Hello, ${name}!` };
    }
});
```

#### 2.Playwrightのコードを作成

src/functions/httpTrigger2.js に適当なコードを作成

初回作業時、httpTrigger.jsのコードをコピペしたことによって

```
app.http('httpTrigger2', {
```

ではなく

```
app.http('httpTrigger', {
```

となってしまい、Functionsの構成的にエラーになってしまった。注意。

#### 3.Azure Function をデプロイする

```
az functionapp create --name $APP_NAME --resource-group $RG  --functions-version 4 --runtime node  --environment $APP_CONTAINER_ENV_NAME --workload-profile-name "Consumption"  --storage-account $STORAGE_NAME  --registry-server $LOGIN_SERVER --registry-username $REGISTRY_NAME --registry-password $ADMIN_PASSWORD --image nodescraperregistryrg20240930.azurecr.io/nodewebscraperrg20240930:WebScraperAppRG20240930
```

#### 4. 動作確認

以下のコマンドで帰ってきたURLにブラウザ経由でアクセス

```
az functionapp function show -g $RG -n $APP_NAME --function-name "httpTrigger2" --query "invokeUrlTemplate" --output tsv
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147841/cf9ecd88-30cd-750f-ff74-7c83f03e9241.png)

正常に動作が確認できました。ちなみにこのコードはNHKのサイトにアクセスし、covid19の感染者数を取得するスクリプト。
Shell、ShellScriptで空のZIPファイルを作成する方法

# 概要

さて、これを読んでいる皆さん

業務の要件でファイルが入っていないZIPファイルを作成して置いておく必要があったのでは？

そんな皆さんには非常に残念なお知らせですが、Linuxのzipコマンドは空のZIPファイルを作成する為のオプションが用意されていません！

そして、空のZIPファイルは単純な0バイトのファイルという訳ではないので、touchコマンドで空ファイルを作成するように簡単には作れないのです…

そこで空のZIPファイルを作成するやり方を試行錯誤してみます！

# やり方を考える

## 空のディレクトリでファイルだけアーカイブする

残念ながらこの方法ではZIPファイルは作成できません

```terminal
$ mkdir test
$ zip -j test.zip test

zip error: Nothing to do! (test.zip)
```

zipコマンドがエラーになってしまい、ZIPファイルは作成されませんでした

## ファイルを1つアーカイブして、作成されたZIPからファイルを削除する

この方法では空のZIPファイルは一応作成できます

```terminal
$ touch test
$ zip test.zip test
  adding: test (stored 0%)
$ zip -d test.zip test
deleting: test
        zip warning: zip file empty
```

が、警告が表示されるのと、一時的にもアーカイブするファイルを作成する必要があるので汚いコードだなーって愚痴られるかもしれません

# キレイな作り方(答え) 1

echoコマンドを使うやり方

```terminal
$ echo -ne '\x50\x4b\x05\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' > empty.zip
```

# キレイな作り方(答え) 2

printfコマンドを使うやり方

```terminal
$ printf "%b" '\x50\x4b\x05\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' > empty.zip
```

もしかしたら"#%b"は無くても動くかも…

## 結局のところ

HEX```50 4B 05 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00```のファイルが作れれば、どんなやり方でも良いんですけどね
ChatGPTでエンジニアスキルアップに挑戦

## 前置き
はじめまして、36歳にして3度目の転職活動中の`nonamini_kunikara`です。
モノづくりに携わりたいという思いで、これまで2回の転職を経験しましたが、体系的にスキルを身に付ける機会がなく、ただがむしゃらにプログラミングやプロジェクトマネジメント、組織管理に取り組んできました。
その結果、自分が何を得意としているのかはっきりしないまま、なぜかマネジメントのポジションに進んでしまっている現状です。

そんな状況から脱却したいと思いつつ、振り返ってみると、QiitaやGitHubといったアウトプットの場を全く活用してこなかったため、「エンジニアとしてこのままでいいのか？」と、自己嫌悪に陥っている今日この頃です。

そして今、「このままではダメだ！」と思い立ち、いくつかのプログラミング言語を学び直し、その学習結果をQiitaとGitHubにアウトプットしていくことを決意しました！！

ただ、めんどくさがり屋な性格ゆえに、書籍やインターネットでの独学が続くかどうか不安だったので、効率良く学べる方法としてChatGPTを活用した学習プランに取り組むことにしました。

今回はその概要をご紹介します。


## 目標
- Ruby, Go言語, Python, React, Vue.js, TypeScriptの習得を目指す[^1]
- ChatGPT[^2]をサポートとして活用し、効率的かつ自動的にフィードバックを得る
  - ChatGPTから情報を得るための呪文は`How To Get ～`という形で記載していきます

[^1]: これらの言語をピックアップしたのは求人情報でよく目についたためです
[^2]: 自由に使えるお金がないので、無料プランで頑張ってみます、、！


## ChatGPTを使うメリット[^3]
- 自由なタイミングで質問ができる
- ハンズオン学習やクイズの即時対応
- 大量のリソースを持つAIが常にサポート

[^3]: ChatGPTの受け売りです。つまり自慢！？

## 学習プランの取得
まずは、目標に挙げた言語の学習プランをChatGPTに提示してもらいました。

:::note info
【How To Get 学習プラン】
Ruby, GO言語, Python, React, Vue.js, Typescript
このあたりの言語をまとめて身に着けたい。
すべてじゃなくてもよいので、複数個まとめて網羅的に学べる学習プランを提示してほしい
:::

結果が以下です。

-----------
### 1. Web開発の基礎: Ruby on Rails
- 目的: RubyやRailsの習得により、バックエンドのWeb開発の効率化とMVCアーキテクチャを理解します。
- 学習内容:
  - Railsフレームワークの使用方法
  - データベースの操作とREST APIの設計
  - 認証、認可、テストなど
- 期間: 1.5～2ヶ月
### 2. フロントエンド開発: React or Vue.js
- 目的: UI開発において、JavaScriptフレームワークの習得を目指します。ReactかVue.jsのいずれかを選択し、実践的なUI設計を学びます。
- 学習内容:
  - コンポーネントベースの設計
  - 状態管理とAPI連携
- 期間: 1～1.5ヶ月
### 3. 静的型付け: TypeScript
- 目的: TypeScriptを使用して、JavaScript開発における型の安全性を強化し、保守性の高いコードを書くスキルを磨きます。
- 学習内容:
  - 基本的な型定義、ジェネリクス、クラス設計
  - フロントエンド（React or Vue.js）との統合
- 期間: 1ヶ月
### 4. 高性能バックエンド: Go
- 目的: Goによる高パフォーマンスなWebサーバやAPI設計、並行処理の理解を深めます。バックエンドに特化した学習が必要です。
- 学習内容:
  - goroutineを使った並行処理
  - GoによるAPI開発、テストとデプロイ
- 期間: 1.5～2ヶ月

  
**合計学習期間: 5～7ヶ月**  

このプランでは、CやC#での基礎理解を前提[^4]に、Web開発やフロントエンド技術、Goによる並行処理やAPI開発など、実務に即した技術を短期間で学べるように構成しています。
[^4]: 当初はプログラミング基礎をPythonでやることになっていたが、プログラミングの基礎知識があることを伝えたら、Pythonメニューがごっそり消えてしまった、、、orz

-----------

## 学習プラン

- **Ruby on Rails**: Web開発の基礎を学びます。
- **React/Vue.js**: フロントエンド開発のモダン技術を学びます。
- **TypeScript**: JavaScriptに型を追加することで、堅牢なコードを書く技術を習得。
- **Go言語**: 高性能かつスケーラブルなシステム開発に挑戦。

各言語について、段階的に深掘りし、座学・ハンズオンを組み合わせて学びを進めていきます。

## 注意事項と免責
生成AIを使った学習は効率的ですが、間違いも起こり得ます。
特にAIと自身のスキル不足が重なると、誤解や不正確な内容が発生する可能性があります。
そのため、常に検証と反復を大切にし、実践を通じて正確な知識を身に付けていくつもりです。
もし間違いを見つけたら、温かいご指導のコメントをいただけますと幸いです。

## まとめ
今回はChatGTPを使えば、エンジニアスキルアップのための学習プランが得られるぞということを書きましたが、今後この提示された学習プランをもとに、本気で学習していきたいと思います！！

## おまけ
こんなこともChatGPTに頼んでいます。

:::note info
【How To Get 学習プラン補足】
それでは上記学習プランに沿って授業を行ってほしい。
座学に加えて、クイズやハンズオンもしていきたい。
また、この学習をポートフォリオとして、githubとQiitaに記録していきたいので、その点のサポートもしてほしい
:::
 
:::note info
【How To Get Qiita記事作成】
一旦ここで区切って、Qiita記事を２つ書きたい。
内容としては以下の通り。
詳細は自分で書くが、これまでの内容を踏まえて、章立てと簡単に書く内容の提案をしてほしい
また、Qiita記事なので、Markdown形式でお願いしたい。

１．ChatGPTを使ってエンジニアスキルアップ
この取り組み全体の概要についてまとめたい。
学習プランについても説明
これから取り組んでいきますといった意気込み的な記事にしたい。
生成AIを使うこととエンジニアスキルが低いことでの誤りがあるかもしれないといった旨の免責も入れておきたい。

２．１の実践　Ruby学習編　第１弾 [^5]
今回の座学内容をまとめたい。
Ruby学習編の学習プランも最初に掲示する。
[^5]: この内容は次の記事にします！
:::
Office 2024はActiveXコントロールがデフォルト無効化、 ADODBはどうなる？

# はじめに
Microsoftは2024年9月6日（米国時間）、次期永続版Office製品である「Microsoft Office 2024」において、ActiveXコントロールを既定で無効にすることを発表しました。Microsoft 365 Appsサブスクリプション製品については、2025年4月から同様の変更を実施するとしています。

https://www.say-tech.co.jp/contents/blog/yamanxworld/news012

https://news.mynavi.jp/techplus/article/20240910-3021881/

## Accessは対象外
この変更の影響を受けるのは、以下のWin32アプリです。

* Word
* Excel
* PowerPoint
* Visio

Accessは対象外です。ここ重要！

# 疑問点
Excelにてデータベース操作として使用される ADODB(Microsoft ActiveX Data Objects *.* Library)も、ActiveX と呼ばれています。

さて、これはどうなるのでしょうか？

## ActiveXコントロール(UI COM Object)
今回対象となるActiveXコントロールですが、あくまでExcelなどの画面上に貼り付けて操作等ができるものという認識で筆者が考えています。
つまり、UIを持つActiveX(UI COM Object)が、ActiveXコントロールです。

例えばExcelにバーコードを作成できる「Microsoft Barcode Control 16.0」などが代表です。

https://www.a-poc.co.jp/howto/howto_excel_ocx.html

# ActiveX(COM Object)
対象とならないActiveXとして、UIを持たないもの。
例えば、ADODB(Microsoft ActiveX Data Objects *.* Library)は、UIを持っていません。

但し、これはあくまで筆者の考えであり、**Microsoftの公式見解ではありません。**
Microsoft Copilot に質問しても、「ActiceX全般が対象なので ADODBも無効化の対象です。」といった回答が返ってきます。

一応 Reddit にて、下記のようなコメントがあるくらい。
>これは ActiveX コントロールを指しており、COM オブジェクトのより広範な利用を指しているわけではないと思います。
>>そうですね、たとえば ADODB ライブラリを使用する VBA コードがこれによって壊れるとしたら最悪ですが、彼らがこれを壊そうとするとは思えません。

https://www.reddit.com/r/vba/comments/1fc3419/activex_will_be_disabled_by_default_in_microsoft/

# 最後に
設定で有効化できるとしても、ADODB が無効化されてしまったら、かなり混乱を招くことになるでしょう。いくら Microsoft でもそこまではしないでしょう。

Microsoftの方で公式な見解を提示してくれるのが一番ありがたいです。

最近、下記ツールを作成しましたが、1いいねと全く反応がありません。ちと残念です。

https://qiita.com/yaju/items/66678f9abb530f169a80
JoolでNAT64を実装する

# はじめに
最小の構成をまとめている人が見当たらなかったので備忘録も兼ねての投稿です。

# 検証環境
  - ホストOS: Windows11 Pro
  - ハイパーバイザ: VMWare Workstation 17 Pro 
  - ゲストOS: Ubuntu 24.04 LTS

# ネットワーク構成
```
+---------+          192.168.51.1/24 +--------------+           +-----------+
| IPv4 NW |--------------------------| Ubuntu 24.04 |-----------| IPv6 Host |
+---------+                          +--------------+           +-----------+
```

# インストールと設定ファイル準備
```shell
apt update
apt upgrade
apt install jool-tools
mkdir /etc/jool
```

# 設定ファイルの編集
```shell
# テンプレートとなるファイルをコピーして編集
cp /usr/share/doc/jool-tools/examples/jool.conf /etc/jool
vi /etc/jool/jool.conf
```

編集前のテンプレートファイルは以下のようになっています
```編集前
{
	"comment": {
		"description": "Sample full NAT64 configuration.",
		"notes": [
			"192.0.2/24 and 2001:db8::/32 are documentation blocks",
			"(RFC 5737 and RFC 3849), and you WILL need to change or",
			"remove them for your setup."
		],
		"last update": "2022-03-20"
	},

	"instance": "sample-nat64",
	"framework": "netfilter",

	"global": {
		"pool6": "64:ff9b::/96",
		"lowest-ipv6-mtu": 1280,
		"logging-debug": false
	},

	"pool4": [
		{
			"protocol": "TCP",
			"prefix": "192.0.2.1/32",
			"port range": "61001-65535"
		}, {
			"protocol": "UDP",
			"prefix": "192.0.2.1/32",
			"port range": "61001-65535"
		}, {
			"protocol": "ICMP",
			"prefix": "192.0.2.1/32"
		}
	],

	"bib": [
		{
			"protocol": "TCP",
			"ipv6 address": "2001:db8::1#80",
			"ipv4 address": "192.0.2.1#62000"
		}, {
			"protocol": "UDP",
			"ipv6 address": "2001:db8::2#10000",
			"ipv4 address": "192.0.2.1#62000"
		}
	]
}
```

これを以下のように編集します
```編集後
{
	"comment": {
		"description": "Sample full NAT64 configuration.",
		"notes": [
			"192.0.2/24 and 2001:db8::/32 are documentation blocks",
			"(RFC 5737 and RFC 3849), and you WILL need to change or",
			"remove them for your setup."
		],
		"last update": "2022-03-20"
	},

	"instance": "default",                            # インスタンス名をdefaultに変更
	"framework": "netfilter",

	"global": {
		"pool6": "64:ff9b::/96",
		"lowest-ipv6-mtu": 1280,
		"logging-debug": false
	},

	"pool4": [
		{
			"protocol": "TCP",
			"prefix": "192.168.51.1/32",              # 自身のIPv4アドレスに変更
			"port range": "61001-65535"               # ポート番号はお好みで
		}, {
			"protocol": "UDP",
			"prefix": "192.168.51.1/32",              # 自身のIPv4アドレスに変更
			"port range": "61001-65535"               # ポート番号はお好みで
		}, {
			"protocol": "ICMP",
			"prefix": "192.168.51.1/32"               # 自身のIPv4アドレスに変更
		}
	]
}
```
pool6で指定したIPv6プレフィックスの下32ビットをIPv4アドレスのビットで置き換えたアドレスに通信すると、pool4で指定したIPv4アドレスに変換されて通信が可能になります。

# サービスの再起動
```shell
systemctl restart jool.service
```

# 確認
IPv6ホストにて以下の通信が成功する
```shell
ping 64:ff9b::8.8.8.8
```

Ubuntuサーバにて
```shell
# インスタンス名の確認
jool instance display

# IPv4プールの確認（なぜか一番上に書いたものしか表示されない）
jool pool4 display

# セッションの確認
jool session display
```

# おわりに
ただのアドレス変換なのでNIC間転送のカーネルパラメータ変更は不要でした。
SIITやらCLATとかPLATとかいろいろあるらしいですがよくわからないのでとりあえず以上。
Release Please Action のリリースにファイルもアップロードしたい

OSS などのプロジェクトに更新を入れたはいいけれどリリースを打つのが面倒なことよくあると思います。そんな私のような面倒くさがりにも嬉しい GitHub Actions に [Release Please Action](https://github.com/googleapis/release-please-action) がありますが、この Release Please が作成したリリースにアーティファクト (ビルドしたファイルなど) をアップロードしたいことがあります。使いやすいテンプレートが見つからなかったため備忘録として書き残します。

## リリースフロー

1. 変更を `main (master)` にコミットする
2. Release Please がバージョンを上げる PR を作ってくれる (`release-please` job)
    - 続けて変更をいれるたびに PR を更新してくれる
    - コミットメッセージの詳細行に `Release-As: x.x.x` を記述するとバージョンを指定できる
        - empty commit とかでやると便利
    - `CHANGELOG` や `version.txt` があったら勝手に更新してくれる
3. PR をマージする
4. Release Please がタグとリリースを作成してくれる (`release-please` job)
5. Actions でビルドしてアップロードする (`upload-artifact` job)

:::note warn
この Action はモノレポなど複数のバージョンのパッケージを管理する場合には使用できません。`tag_name` を使用している箇所を適宜置き換えてください。 
:::

#### 設定ファイル

`release-please` job でリリース / PR を作成し、リリースが作成された場合 `upload-artifact` job でビルド・アーティファクトのアップロードを行います。

```yaml
on:
  push:
    branches:
      - main
      - master

permissions:
  contents: write
  pull-requests: write

name: release

jobs:
  release-please:
    runs-on: ubuntu-latest
    timeout-minutes: 1
    outputs:
      release_created: ${{ steps.release.outputs.release_created }}
      tag_name: ${{ steps.release.outputs.tag_name }}

    steps:
      - id: release
        uses: googleapis/release-please-action@v4
        with:
          release-type: simple


  upload-artifact:
    runs-on: ubuntu-latest
    needs: release-please
    if: ${{ needs.release-please.outputs.release_created }}
    timeout-minutes: 5

    steps:
      - uses: actions/checkout@v4

      - uses: leafo/gh-actions-lua@v10
        with:
          lua-version: 5.4

      - name: Build
        run: make build

      - name: Upload Artifact
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: gh release upload ${{ needs.release-please.outputs.tag_name }} fil1 file2 ...
```
LeetCode 1011. Capacity To Ship Packages Within D Days 再び

## はじめに
前回投稿したタイトルのこの問題。
最初に取り組んだ時は二分探索ではない方法でやろうとしました。
ずっと解けずに「Time Limit Exceeded」。
私の記事の大半を占めるTLEが出続けていました。

でも、諦めずにコード書き続けたらAcceptedになったので
嬉しなって投稿します。

https://qiita.com/yorocovich/items/3ce6ce09134d98623f1f

## 考え方
問題そのものは前回の記事見てもらうとして、考え方です。

出発点は、以下の式から考えました。

$総重量 = 1日の積載量 \times 積載日数$

この式を $1日の積載量$ について解くと

$1日の積載量 =  \frac{総重量}{積載日数} $

となり、総重量は`sum(weights)`で一定なので、
反比例の式になる。

ということは、積載日数`days`が最大のとき、$1日の積載量$が最小になる。

なので、最大積載量を積載日数で割ったものが$1日の積載量$最小なので、
そこから積載できなければ、$1日の積載量 を +1$していく。

## 解答例
```python:1011. Capacity To Ship Packages Within D Days
class Solution(object):
    def shipWithinDays(self, weights, days):
        # days以内でさばけるか
        def can_ship_within_days(capacity_a_day):
            spend_days = 1
            total_weight_a_day = 0
            for weight in weights:
                if total_weight_a_day + weight > capacity_a_day:
                    spend_days += 1
                    total_weight_a_day = weight
                else:
                    total_weight_a_day += weight

                if spend_days > days:
                    return False
            return True

        total_weight = sum(weights)
        avg_a_day = max(max(weights), total_weight // days)

        # 最小値でdays以内にさばけるか。さばけないなら1日あたりの積載量+1
        while not can_ship_within_days(avg_a_day):
            avg_a_day += 1

        return avg_a_day
```

## おわりに
問題文やヒントに`binary search`って書かれているので、基本的には二分探索を使って解く問題です。

天邪鬼な部分が出てしまい、どうしても二分探索使わずに解きたかったです。
個人的には解けて満足です。
問題によっては解けないこともあると思います。
機械学習入門

# 機械学習とは
　機械学習（Machine Learning, ML）は、システムが明示的なプログラムなしに大量のデータからパターンやルールを自動的に学習し、予測を行う技術です。このプロセスは、データを中心にしたアプローチである「データドリブン」（Data-Driven）な手法です。

## 機械学習のメリット
　機械学習のメリットは、主に以下の二つです。
- データから自動的にモデルが学習され、適切な出力が得られるようになる点です。ルールベースのような人工的な設計が不要です。
- 複雑なデータも学習することができる点です。人間が手作業でルールを定義することが困難なタスクにも対応可能です。

## モデルとパラメータ
　モデルは関数のようなもので、データを入力すると、それに対応するデータを出力します。例えば、モデルを$f$、入力データを$x$, 出力データを$y$とすると、以下のように表されます。
 $$y=f(x)$$

　また、モデルは内部に調整可能な要素として、複数のパラメータを持ちます。例えば、複数のパラメータを$\boldsymbol{\theta} = [\theta_1, \theta_2, \dots]$とすると、モデル$f$は、次のように記述されます。

$$y = f(x; \boldsymbol{\theta}) = f(x; \theta_1, \theta_2, \dots)$$

　上記式より、入力データ$x$が同じでも、複数のパラメータ$\boldsymbol{\theta}$が変わると、推論される出力データ$y$も変化することが分かります。

## 損失関数
　損失関数は、学習中にモデルがどれだけ誤った予測をしているかを測定するための関数です。損失が小さいほどモデルからの出力が適切であることを示しています。つまり、モデルは損失が小さくなるように学習を進めます。

## 学習と推論
　機械学習モデルの動作は、主に以下の二つに分けられます。

- 学習（Training）：主に開発過程で、出力データ$y$が適切になるように、モデル内部の複数のパラメータ$\boldsymbol{\theta}$が調整されます。具体的には、損失関数を使用して損失を計算し、その損失を最小化するように複数のパラメータ$\boldsymbol{\theta}$が調整されます。
- 推論（Inference）：主に運用過程で、未知の入力データ$x_{new}$に対してモデル$f$を適用し、出力データ$y_{pred}$の推論を行います。推論段階では、学習によって最適化された複数のパラメータ$\boldsymbol{\theta}$は固定されています。

## データセット
　データセットは、モデルの学習に使用されるデータの集合です。データセットは、主に以下の三つに分けられます。

- 訓練データ（Training Data）：モデルの学習するために使用するデータです。つまり、モデルのパラメータを更新するために使用するデータです。
- 検証データ（Validation Data）：モデルの学習過程で、モデルの汎化性能を評価するために使われるデータです。過学習（Over Fitting）を防ぐために使用されます。
- 推論データ（Test Data）：最終的なモデルの性能を評価するために使用するデータです。訓練にも検証にも使用されていないデータです。

## 機械学習の種類
　機械学習は主に、教師あり学習、教師なし学習、そして強化学習の3つのタイプがあります。以下でそれぞれを詳しく説明します。

# 執筆中...
MySQL の DELIMITER, ストアドプロシージャー諸々に関して

# 動機
DELIMITER、ストアドプロシージャ 使ったことなかったので、調べてみました。

# ストアドプロシージャ
ストアドプロシージャは、簡単に言えば、DBにおいて値を返さない関数のような処理の集まり。
値を返すものは、ストアドファンクションと呼ばれる。

# DELIMITER に関して
デフォルトでは、MySQL は SQL 文の終わりを示すために ; を使用します。しかし、ストアドプロシージャのようなスクリプトでは、プロシージャ本体内でセミコロンが頻繁に使用されるため（複数の SQL ステートメントなど）、混乱を避けるために一時的に区切り文字を他のものに変更する必要があります。

## 例 デリミタの変更
この例では、ストアドプロシージャを定義するためにデリミタを // に変更します：

``` SQL
DELIMITER //

DROP PROCEDURE IF EXISTS SampleProcedure;

CREATE PROCEDURE sample_procedure()
BEGIN
    DECLARE sample_variable INT DEFAULT 1;
    SELECT sample_variable;  -- セミコロンをストアドプロシージャーの中で使っています。
END //

DELIMITER ;

CALL SampleProcedure()
DROP PROCEDURE IF EXISTS sample_procedure;

```

## 説明
DELIMITER //： これは MySQL に一時的に区切り文字をデフォルトの ; から // に変更するように指示します。これで、MySQL は文の終わりを認識するために ; の代わりに // を待つようになります。
プロシージャの定義： CREATE PROCEDUREブロックの中では、複数のステートメントがセミコロン（;）で終わっています。区切り文字を変更したので、MySQLはこれらのセミコロンをプロシージャ全体の終わりとして解釈しません。
DELIMITER ;： プロシージャを定義した後、デリミタをデフォルトのセミコロン (;) に戻します。
一般的なデリミタ
//
$$
'#'

SQL ステートメントと衝突しない記号であれば何を選んでもかまいませんが、// または $$ がよく使われます。

複数の SQL ステートメントを含む複雑な MySQL オブジェクトを作成する場合、このテクニックは非常に重要です。

# ストアドプロシージャ書くにあたり便利なもの

## SET 

`SET @sample = 0;`は次のようになる：

ユーザ定義変数 (@sample) を宣言します： シンボルは MySQL のユーザ定義セッション変数を示します。これらの変数はセッションにスコープされ（つまり、接続の間アクセス可能）、ストアドプロシージャや関数に制限されません。

値 (0) を割り当てます： SET 文は、変数 @sample に値 0 を代入します。

使用例
カウンタ： これは通常、一括挿入、バッチ処理、ストアド プロシージャのループ ロジックなど、特定の回数を繰り返し実行する必要があるスクリプトやループでカウンタとして使用されます。
一時ストレージ： 中間結果を保存したり、スクリプトのフローを制御するためにも使用できます。
ループの使用例
データを一括挿入し、処理を複数回繰り返し実行するとします：


## backticks '`'
MySQL では、バックスティック ( ) はバッククォートとも呼ばれ、テーブル名、カラム名、データベース名などの識別子を囲むために使用されます。これにより、予約キーワードや特殊文字をこれらの識別子で使用することができます。

バックティックの一般的な使用法
予約キーワードを識別子として使用する： 予約キーワード（SELECT、ORDER など）をテーブル名やカラム名として使用する場合、バックティックで囲むことで MySQL がキーワードとして解釈するのを防ぐことができます。

``` sql
CREATE TABLE `select` (
    `id` INT PRIMARY KEY,
    `name` VARCHAR(100)
);
```

バックスティックがないと、select は MySQL キーワードなので構文エラーになります。

識別子での特殊文字の使用： テーブル名やカラム名にスペースや特殊文字が含まれる場合は、バックスティックが必要です。

``` sql
CREATE TABLE `user data` (
    `user-id` INT PRIMARY KEY,
    `first name` VARCHAR(50)
);
```

大文字と小文字の区別： MySQL 識別子はオペレーティングシステムによって大文字と小文字が区別されます。バックティックを使用することで、OS に関係なく一貫した動作が保証されます。

安全のためのバックティックの使用： 識別子にバックティックが必要ない場合でも（特殊文字がない、または予約語でないため）、新しい予約語が導入される可能性のある将来のバージョンの MySQL での競合を避けるために、バックティックを使用することは良い習慣です。

Example Usage:
``` sql
CREATE TABLE `order` (
    `id` INT PRIMARY KEY,
    `product_name` VARCHAR(100),
    `order_date` DATE
);
```

ここでは、orderは予約キーワードですが、バックスティックを使用することで、テーブル名として使用することができます。

バックティックが不要な場合：
特殊文字を含まない識別子や予約キーワードでない識別子には、バックティックは必要ありません：

``` sql
CREATE TABLE users (
    id INT PRIMARY KEY,
    username VARCHAR(50)
);
```

#### まとめ　
バックティックは、特殊文字や予約語などの構文上の問題が発生する識別子（カラム名やテーブル名など）を囲むために使用されます。
バックティックを使用することで、特に動的スキーマや複雑なスキーマを扱う場合に、SQLスクリプトをより柔軟で堅牢なものにすることができます。
フォルダ内の同一拡張子のファイルを結合して一つのファイルにまとめる

### 同一拡張子のファイルを一つのまとめたい

業務でDDLの差分チェックを任されたのですが、一方が一つのSQLファイルにまとまっているのに対し、もう一方は1テーブルにつき1ファイルで作成されていました。
テーブルは全部で200個以上あり、このままの状態で差分比較をするのは現実的でなかったので、後者を一つのファイルにまとめるスクリプトを作成しました。

### 実行環境
- Windows 11

### 1. スクリプトの作成
下記スクリプトを適当なファイルパスに作成します。
```concatFiles.bat
@echo off
setlocal

rem 1. 
rem 出力元フォルダ
set "SOURCE_DIR=C:\Users\dev\sql"
rem 出力先フォルダ
set "OUTPUT_DIR=C:\Users\dev\sql\concat"
rem 出力ファイル名
set "OUTPUT_FILE=combined.sql"

rem 2. 
rem 出力ファイルがすでに存在する場合は削除
if exist "%OUTPUT_DIR%\%OUTPUT_FILE%" del "%OUTPUT_DIR%\%OUTPUT_FILE%"

rem 3. 
rem 指定したディレクトリ内のすべての.sqlファイルを結合
for /f "delims=" %%f in ('dir /b /on "%SOURCE_DIR%\*.sql"') do (
    type "%%f" >> "%OUTPUT_DIR%\%OUTPUT_FILE%"
    echo. >> "%OUTPUT_DIR%\%OUTPUT_FILE%"
    echo. >> "%OUTPUT_DIR%\%OUTPUT_FILE%"
)
)

echo 結合が完了しました: %OUTPUT_DIR%\%OUTPUT_FILE%
pause
endlocal

```
#### 解説
1. 出力元フォルダ、出力先フォルダ、ファイル名を指定します。
もし実行時にそれらを指定したい場合は、以下のように引数を使う形に変更可能です。
    ```.bat
    set "SOURCE_DIR=%1"
    set "OUTPUT_DIR=%2"
    set "OUTPUT_FILE=%3"
    ```
\
2. 
`if exist` コマンドで、同名のファイルがすでに存在する場合は、そのファイルを削除します。
これにより、古い内容が残った状態で上書きされるのを防ぎます。
3. 
- `for /f "delims=" %%f in ('dir /b /on "%SOURCE_DIR%\*.sql"')` 
    指定されたディレクトリ内にあるすべての .sql ファイルを取得し、ファイル名を昇順に並べます。
- `/b` はファイル名のみを表示し、`/on` でファイル名を昇順にソートします。
- 各ファイルを type コマンドで読み込み、出力ファイル `%OUTPUT_FILE%` に追加します。
- `echo.` を2回実行して、ファイル間に2行の空行を挿入し、視覚的な区切りをつけています。
この区切りにより、結合された各テーブルの間がはっきりとわかるようになります。不要な場合は削除してください。


### 2. 実行方法
エクスプローラーからバッチファイルをダブルクリックで実行できます。

![バッチファイル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881444/e1d53807-5abc-6d42-dd21-01c2e235ccd1.png)

または、コマンドプロンプトを開き、バッチファイルのファイルパスを入力して実行します。

```cmd
C:\Users\dev> C:\Users\dev\pj\bat\concatFiles.bat
```
フォルダやファイル名を引数指定にした場合は、以下のようにして実行します。
```
C:\Users\dev> C:\Users\dev\pj\bat\concatFiles.bat "C:\Users\dev\sql" "C:\Users\dev\sql\concat" "combined.sql"

```


### 3. 実行結果
#### 結合前のファイル
![ファイル1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881444/f6cb3fc1-9712-fdb5-412e-6740912c2de7.png)
![ファイル2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881444/72e9ff24-1ab5-509e-3076-68f649b4b336.png)
![ファイル3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881444/93fe1427-28d4-0b2a-6282-1a4d7b66cd96.png)

#### 結合ファイル
![結合結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881444/6724d38a-2ab1-1b6f-2a23-e728d99802e7.png)

ひとつのファイルにまとまりました。間に空行が入っています。
psqlコマンドなど(postgreSQL/PostGIS）

# はじめに
macを用いてWindows仮想デスクトップにアクセスし、そこからさらにpostgreSQL/PostGISデータベースにアクセスをしていますが、psqlコマンドや日本語macキーボード配置との関係性など覚えることがあるので、ここにメモします。

# psqlコマンド
psql は PostgreSQL に接続するクライアントコマンドです。PostgreSQLにはpsqlが標準で付属しているので、PostgreSQLをインストールすればpsqlはすぐに利用できます。

### オプション
-h： ホスト名を指定
-U： ユーザIDを指定
-d： データベース名を指定（PostgreSQLのデフォルトのデータベース名は「postgres」なので、データベース名が分からなければ、とりあえずそのように書けばよいと思われます。）
-p：ポート番号を指定

psqlは、以下のデフォルト設定を使用しますので、場合によってはオプションを省略しても接続できます。
- データベース名: OSのユーザー名
- ユーザー名: OSのユーザー名
- ホスト名: localhost
- ポート: 5432

例
```
psql -h localhost -U postgres -d sdb_course
```

接続後の表示は以下の２つです。
=#　接続したユーザがスーパーユーザであることを示す
⇒　接続したユーザが一般ユーザであることを示す


## データベース接続後によく使うコマンド
```
\q: psqlの終了
\du: ユーザーリスト表示
\l: データベースリスト表示
\d: テーブル、インデックス、シーケンス、ビューの一覧を表示
\conninfo: 接続中のデータベースの情報を表示
```

# ビューやテーブルの中身確認

```
SELECT column_name FROM table_name
```

SQLキーワードは大文字使うのが慣例です。。
;（セミコロン）がないとコマンドが実行されないので必ずつける必要があります。

例
```
SELECT c1, c3 FROM table_name; // c1とc3のカラムだけ表示
SELECT * FROM table_name;  // 全て表示
SELECT * FROM table_name LIMIT 1;  // 1行のみ表示
SELECT count(*) FROM table_or_view; // レコード数を表示
```

# 日本語macキーボード配置の場合の挙動
macを用いてWindows仮想デスクトップにアクセスしていますが、その際の日本語macキーボード配置の表示と実際に入力される文字が異なるので、ここにメモします。左側がWindowsで打ちたい文字で、右側がmacのキーボード表示です。

\\：　「}」
_（アンダーバー）： shift + 「-」
大文字、小文字切り替え： 「英数」
:（コロン）： shift + 「;（「れ」の文字）」
* : shift + 「8」


# まとめ
postgreSQL/PostGISデータベースで使用されるコマンドをpsqlを中心にメモしました。今後作業を進めていく中で、また追記していきたいと思います。

# Reference

https://qiita.com/T-ubu/items/2a097fd7e880bfbfa10c
ghqのディレクトリにfzf使って移動する方法

たぶん一番簡単な方法だと思います。

```bash
alias ghqcd='cd $(ghq list --full-path | fzf)'
```
これを.bashrcなどに登録しておくだけです。
※ これは問題点があります。詳しくはこちら → [問題点](https://qiita.com/tontoroRR/items/561cbe15f6eac85b0227#%E5%95%8F%E9%A1%8C%E7%82%B9)

#### 失敗例1
はじめは
```
$ ghq list --full-path | fzf | cd
```
としたけど、cdが動いてくれませんでした。

#### 失敗例2
次にxargsを使ったけど
```
$ ghq list --full-path | fzf | xargs cd
$ xargs: cd: No such file or directory
```
と動きませんでした。

#### 参考情報
* [unix - using xargs to cd to a directory - Super User](https://superuser.com/questions/206789/using-xargs-to-cd-to-a-directory)
xargsはcdのようなビルトインコマンドは使えない、らしい。

#### 問題点
ghqcdをキャンセルすると"cd"が実行されるので、ホームディレクトリに戻ってしまう。
どうしたものでしょう。。。

##### 解決策
寄せていただいた[コメント](https://qiita.com/tontoroRR/items/561cbe15f6eac85b0227#comment-529b8959ee61af2e2b0c)のおかげで解決しました。ありがとうございました。
WordPressの子テーマがzipでアップロードできない


テーマの構成ファイルには何の問題も無いのに、「互換性のないアーカイブ。」や「Incompatible Archive」と出てしまった場合の対応案です。

## 環境
* WordPress 5.3.18
* Windows 11
* where zip -> D:\texlive\2024\bin\windows\zip.exe

## 試したこと
Windowsのエクスプローラーでは、右クリックからzipファイルを作成することができますが、今回はこれで作成したzipファイルは受け付けてもらえませんでした。

次に、Powershellから`zip`コマンドを使用したところ、
```
zip warning: Local Entry CRC does not match CD
```
というwarningを発見します。どうやら正しく圧縮できていないようです。

私はzipの実装を確認するなどとてもできないので、別の実装を使おうと思い、7zipで試したところ正しくアップロードすることができました。

## 教訓
* GUIでの操作はwarningが出てもスルーされているかもしれない。
[備忘録]Pythonで特定のディレクトリ内にある全ファイルパスを取得したい

# はじめに
本記事では特定のディレクトリ内に存在するすべてのファイルのパスを取得するサンプルコードを示す。

# 基本的な方法
```os```モジュールは、ディレクトリやファイル操作を行うための標準ライブラリである。

次のコードでは、```os```モジュールを用いて、指定したディレクトリ内の全ファイルパスを取得する。

```py
import os

def get_all_file_paths(directory):
    file_paths = []
    for root, dirs, files in os.walk(directory):
        for file in files:
            file_paths.append(os.path.join(root, file))
    return file_paths

directory = "任意のディレクトリ"
file_paths = get_all_file_paths(directory)
print(file_paths)
```

# 高機能な方法
```glob```モジュールを使うと、パターンマッチングでファイルを取得できる。

```py
import glob

def get_all_file_paths(directory):
    return glob.glob(f"{directory}/**", recursive=True)

directory = "任意のディレクトリ"
file_paths = get_all_file_paths(directory)
print(file_paths)
```
【IT未経験用】向け　USBケーブル　LANポート　資料

# はじめに
PCや内定者、あまり普段PCに触れない方向けの資料です。
<br>
<br>
`【プリンターとPCの接続方法　USBケーブル編　黒文字画像】`
<br>

![図解その③　黒文字.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3772884/6507c038-0fdb-766d-9929-00d3b828af38.png)


<br>
<br>
<br>


`【プリンターとPCの接続方法　USBケーブル編　白文字画像】`
※ダークモードなどに使用します。



![図解その④　白文字.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3772884/9b71850b-335f-820e-e3c6-3ef202be5c50.png)


<br>
<br>
<br>

`【PCとLANケーブルをつなぐ方法　黒文字画像】`

<br>

![図解その①  黒文字.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3772884/d235a36d-77f0-078d-7112-bab4abb615ff.png)


<br>
<br>

`【PCとLANケーブルをつなぐ方法　白文字画像】`
※ダークモードなどに使用します。

<br>

![図解その②　白文字.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3772884/d961ca98-6ebe-d264-1060-b18ba47bfb03.png)


<br>
<br>

`【インターネット接続　アイコン】`
<br>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3772884/24b0c087-3d3c-671b-ed08-76610aa98bb3.png)


<br>





#　以上です。最後まで閲覧いただきありがとうございました。
[備忘録][Ruby]each_sliceメソッドによる分割件数について

:::note
`each_slice`メソッドを使用して大量のデータを扱う時の、分割件数について学びがあったのでメモ
:::

|| メリット | デメリット |
|:-----------|:------------|:------------|
| 分割件数を増やす  | 1度に処理するデータ量が減るので、DB負荷が軽減|処理時間が遅くなる|
| 分割件数を減らす |クエリの回数が減り、効率的にデータを取得し処理時間の短縮が期待できる|あまりに件数が多いと、メモリ負荷が高まる|


https://docs.ruby-lang.org/ja/latest/method/Enumerable/i/each_slice.html
投稿 93 どうしてエンジニアになりたいか 2024/10/01

本日の勉強時間　3H

理由は1つに絞って答えた方が良い。

「エンジニアリングを通じて業務効率を改善し、人が本来集中すべきことに時間を使えるよう手助けしたい」という考え方は、エンジニアとしての価値をしっかりと示している。
特に、技術を使って他の人の仕事や生活を改善したいという意欲が伝わる点が良い。
iOSのテストをシミュレーターで自動化してみる

# 実現したいこと
あくまでiosアプリを自動的に操作して、自動的にエビデンスを取る仕組みを作りたいということ。
内部結合・外部結合といった感じで内容によっては自動化できないものもあるがそこはまた別の機会に。

# 環境構築
※Mac bookのm1 Pro
- maestroを入れる
- javaを入れる
- Facebook IDBを入れる(iOS自動化をお助け)



# 自動化してみる

以下のコマンドを実行し、シミュレーターを開く
```
open -a Simulator
```


サンプルを落とす
```
maestro download-samples
```

以下を実行して、サンプルアプリをシミュレーターにインストールする。
```
cd samples
unzip sample.zip
xcrun simctl install Booted Wikipedia.app
```

サンプルを実行したらこのように開かれる。
```
maestro test ios-flow.yaml
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179803/aa74a923-267d-42fc-e84f-fc9b3ecfd5a8.png)



うん、アプリを開いただけだ。

さっきコマンドで指定したサンプルの「ios-flow.yaml」の中身はこちら。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179803/e6f41a07-be12-78a2-8fdf-5a264c42db23.png)

appIdはxcode側にあるBundle Identifierを指定。「launchApp」がアプリ起動を表す。操作に関しては「launchApp」しか書いていないから、指定したアプリのidを開いて終わった。このファイルに自動操作のための記述をしていけばいい。そのあとはmaestroで用意されているコマンドを書いていけばいい。「- tapOn: "ユーザID"」みたいに書いたら、「ユーザID」という文字が書かれたボタンやテキストなど自動でタップしてくれる。ブラウザ操作する場合はhtmlのidなどを指定しなくてはならないケースがほとんどだが、これは便利。

Webシステムの自動テストの仕組みをガッツリ作ったこともあったが、それに比べたらちょっとアプリ操作速度は遅い。まあその自動操作をして自動画面キャプチャを撮ってもらう間に他の作業をやるのはかなりラクになると思う。


# まとめ

他のテクニック(スクロールやテキスト入力、画面キャプチャし画像保存)はググれば出てくるので私も同じように書く必要もないので省略するが、便利であることは伝えられたかもしれない。
カーソルの座標取得

備忘録として、カーソルの座標を取得する方法を書いていきたいと思います。
私は現在 Reactの勉強中で、ウェブサイトを作るときにカーソルストーカーを作ってみたかったので調べてみました。
```React:App.jsx
import './App.css';
import { useState } from 'react';
const App = () => { 
    const [mousePosition,setMousePosition] = useState( { x : 0 , y : 0 } ); 
    const moveMouse = (e) => { 
        setMousePosition( { x : e.clientX, y : e.clientY}); 
    } 
    return ( 
    <div className='main' onMouseMove={moveMouse}> 
        <h1>座標</h1> 
        <p>x : { mousePosition.x } , y : {mousePosition.y} </p> 
    </div> 
    ); 
}

export default App;
```

```App.css
*{
margin:0; 
padding:0; 
} 
.main{ 
height:100vh; 
width:100vw; 
}
```

このコードはおそらく座標を取得するための最低限のコードですが、少しわからなかったことがあったので、それについての詳細を記述していきます。

まず、何を考えるかというと、カーソルが動いたらカーソルの座標を更新するので、その座標の状態を把握する必要がある。ということを考え、useStateを利用します。

その次に、どのようにpositionを把握するのかというと、マウスイベント限定で使える
clientX/Yというものを使います。これを使えば座標を定義できます。

そのあとに、mouseが動いたときに、座標を取得するために、onMouseMoveで実行する関数として、座標を再セットするようにすれば、座標を得られます。