OmniAICreator/Qiita-1.07M huggingface dataset:
個人的備忘録：GitHub Actions の workflow_dispatch を活用した ECR への Docker イメージのプッシュについて解説

## はじめに
GitHub Actions を活用すると、リポジトリの特定のイベントをトリガーとして CI/CD パイプラインを構築できます。

本記事では、`workflow_dispatch` を用いて、手動で GitHub Actions を実行し、Amazon ECR へ Docker イメージをプッシュする方法を解説します。

## 書こうと思ったきっかけ
実際に、受講している IT スクールのハッカソンでは、Docker イメージを ECR にプッシュする際に、適当な変更を加えてプッシュしていました。

:::note info
**しかし、同じチームメンバーの方から別の方法を教えていただいたため、今回はその手順を記事としてまとめます。**
:::

そのため、確実に動作する GitHub Actions のワークフローを構築し、手動実行の `workflow_dispatch` を活用することで、よりスムーズにデプロイを行う方法を整理しました。

## workflow_dispatch とは？
`workflow_dispatch` は、GitHub Actions のワークフローを手動で実行できるトリガーです。

通常の `push` や `pull_request` とは異なり、リポジトリのアクションタブから任意のタイミングで実行できます。

### 使いどころ
- CI/CD のテストを手動で実行したい場合
- 一部の開発者だけがデプロイ操作を実行できるようにしたい場合
- 特定のブランチに関係なく任意のタイミングでワークフローを実行したい場合

## サンプルワークフローの解説

```.github/workflows/main.yml
name: Push to ECR

on:
  push:
    branches:
      - development
  workflow_dispatch:

jobs:
  build-and-push:
    runs-on: ubuntu-latest

    steps:
      # リポジトリのクローン
      - name: Checkout code
        uses: actions/checkout@v3

      # AWS CLI のセットアップ
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v3
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ${{ secrets.AWS_REGION }}

      # Dockerログイン
      - name: Log in to Amazon ECR
        run: |
          aws ecr get-login-password --region ${{ secrets.AWS_REGION }} \
            | docker login --username AWS --password-stdin \
              $(aws sts get-caller-identity --query 'Account' --output text).dkr.ecr.${{ secrets.AWS_REGION }}.amazonaws.com

      # Dockerイメージのビルド
      - name: Build Docker image
        run: |
          docker build -t ${{ secrets.ECR_REPOSITORY }}:${{ secrets.IMAGE_TAG }} -f infra/Dockerfile.prod .

      # Dockerイメージのタグ付け
      - name: Tag Docker image
        run: |
          docker tag ${{ secrets.ECR_REPOSITORY }}:${{ secrets.IMAGE_TAG }} \
          $(aws sts get-caller-identity --query 'Account' --output text).dkr.ecr.${{ secrets.AWS_REGION }}.amazonaws.com/${{ secrets.ECR_REPOSITORY }}:${{ secrets.IMAGE_TAG }}

      # Dockerイメージのプッシュ
      - name: Push Docker image to Amazon ECR
        run: |
          docker push \
          $(aws sts get-caller-identity --query 'Account' --output text).dkr.ecr.${{ secrets.AWS_REGION }}.amazonaws.com/${{ secrets.ECR_REPOSITORY }}:${{ secrets.IMAGE_TAG }}
```

## まとめ
- `workflow_dispatch` を利用すると、GitHub Actions を手動で実行できる。
- AWS ECR に Docker イメージをプッシュするワークフローを構築できる。
- `workflow_dispatch` と `push` を組み合わせることで、柔軟なデプロイ戦略が可能になる。

本記事のワークフローを活用し、手動・自動の両面からデプロイを管理してみてください！
非同期処理 -イベントループの全体像整理

## 全体像

JavaScriptは**シングルスレッド**で動作し、コードの実行は常に「1つのコールスタック」上で順番に行われます。

非同期処理（タイマーやネットワーク呼び出し、Promiseなど）は、ブラウザ（ホスト環境）が用意する機能と、イベントループによるキューの管理によって並行的に扱われます。

おおまかには下記のような手順で、イベントループが繰り返し処理を行っています。

1. **コールスタック（Call Stack）** 上でトップレベル（同期的）コードを実行
2. 非同期処理があれば、ブラウザ側が該当処理（タイマー、通信など）を担当
3. 処理結果のコールバックはキュー（**Macro Task Queue / Microtask Queue**）へ追加
4. コールスタックが空になったタイミングで、**Microtask Queue** を優先的に処理
5. Microtask Queueが空になったら、**Macro Task Queue** からタスクを1つ取り出して実行
6. 再びマイクロタスクの有無を確認
7. 以後、キューが空になるまで1〜6を繰り返す

以降のステップ詳細でより細かく見ていきます。

---

## ステップバイステップ解説

### ステップ1: コードの読み込みとトップレベルコードの実行

1. ブラウザがHTMLを読み込み、`<script>` タグなどで指定されたJavaScriptファイルをロードします。
2. JavaScriptエンジン（例: V8）がコードをパースし、**トップレベルコード（グローバルスコープで書かれた同期的処理）**を実行します。
3. このとき実行中の処理は、**Call Stack（コールスタック）** に積まれます。

Call Stack: [ トップレベルのコード ]


- **同期的な処理**は、関数呼び出しがあるたびにスタックに積まれ、処理が完了すればスタックから取り除かれます。

---

### ステップ2: 非同期処理の委譲（ブラウザやNode.jsなどのホスト環境へ）

1. トップレベルコードや関数内部で、`setTimeout()` や `fetch()` などの**非同期API**を呼び出した場合、その「待ち時間の計測」や「ネットワーク通信」などは**ブラウザのWeb API**やサーバサイドの**Node.js内部のlibuv**などが担当します。
2. つまり「JavaScriptエンジン自身」は重いI/O処理やタイマーを直接管理しません。呼び出したタイミングでブラウザやNode.jsに「あとでこのコールバックを呼んでね」と依頼する形になります。
3. 依頼を受けたブラウザやNode.jsは、該当の処理が完了したら**コールバック関数**を「キュー」に登録する準備をします。


Call Stack: [ 実行中の関数 ]→非同期API呼び出し→(Web APIが処理継続)

- この時点では、**Call Stack** から見ると「非同期処理」はすぐに戻ってくるので、実行をブロックしません。

---

### ステップ3: Call Stackが空になるまで同期処理を実行

1. 同期的（ブロッキング）なコードがまだ残っていれば、引き続きそれらが**Call Stack**上で実行されます。
2. 全部の同期処理が終わると、**Call Stack** は空（またはグローバルコンテキストだけ）になり、いわゆる「1度目の処理サイクル（タスク）」が完了します。


Call Stack:(空になる)

---

### ステップ4: イベントループがタスクを取り出す（Microtask Queue → Macro Task Queue の順番）

### 4-1. Microtask Queueの処理

1. イベントループは、**Call Stackが空になったタイミング**でまずは**Microtask Queue** を確認します。
2. `Promise` の `.then()` や `MutationObserver`、`queueMicrotask()` などで登録されたコールバックは、この**Microtask Queue**に積まれています。
3. Microtask Queueにコールバックがあれば、**先頭のコールバックを1つずつ**Call Stackに積んで実行します。
4. 実行が終わった後、追加で新たなMicrotaskが発生した場合は、Queueが空になるまで実行を繰り返します。


Microtask Queue: [ 1st, 2nd, 3rd, ... ]→Call Stackで実行→再びMicrotask Queueを確認

- Microtaskは非常に**優先度が高い**タスクとして扱われ、**次のMacro Task**に移る前に**完全に処理される**点が重要です。

### 4-2. Macro Task Queueの処理

1. Microtask Queueが空になった後、今度は**Macro Task Queue（タスクキュー）**を確認します。
2. `setTimeout()` や `setInterval()`、`I/O` によるコールバック、ブラウザのDOMイベント（クリックなど）によるイベントハンドラ呼び出し、`requestAnimationFrame`のコールバックなどは、一般的に**Macro Task**（または単にTask）として、このキューに積まれます。
3. イベントループはこのMacro Task Queueから「もっとも先頭のタスク」を**1つ**取り出し、Call Stackに積んで実行を始めます。


Macro Task Queue: [ 1st, 2nd, 3rd, ... ]→Call Stackで実行

1. 1つのMacro Taskが完了したタイミングで、再び**Microtask Queue**を確認し、そこにあるタスクをすべて片付けたうえで、次のMacro Taskに進みます。

---

### ステップ5: 描画（リペイント・再描画）との関係

ブラウザでは、「Macro Taskを1つ実行したあとに画面の描画（リペイント）を行う」といったタイミングをはさんでいます。

要素の位置や大きさを変更するDOM操作を行った場合も、実際の画面描画は基本的に**タスクの実行が完了したタイミング**などでまとめて処理されます。

---

### ステップ6: 繰り返し（ループ）の継続

1. 上記のように「Call Stackが空になった → Microtask → Macro Task → Microtask → …」というサイクルを常に繰り返します。
2. どこかで新しい非同期処理が発生（例えば`setTimeout`やネットワーク完了など）すると、そのコールバックがMacro Task Queue（またはMicrotask Queue）に追加されます。
3. キューにタスクが存在する限り、このサイクルは止まらずに続きます。
ALBの前にNLBを置いてみた

## 概要
ALBにWAFを導入するために構成変更を行っておりました。
お名前ドットコムにてドメインを管理しており、ALBのレコードが登録できない事態になりました。

そのため、ALBの前にNLBを置きNLBのIPをレコード登録することで解決したので方法について説明していきます。

## ALBがなぜ登録できないのか
ALBのAレコードをお名前ドットコムに登録できたらよかったのですが、仕様上登録できないことが判明しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882356/70fe8c54-01f7-4496-adca-e88d7d1caa1e.png)

![がっかり.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882356/22476c83-58dc-4ad0-b2df-160699b88d76.png)

ALBのIPをAレコードで登録したらいいじゃない？と思う人もいるでしょう
ところが、ALBのIPは固定でなくランダムで変わってしまいます。
＼(^o^)／ｵﾜﾀ

そこで思いついたのが、NLB→ALB→EC2にすることです。
NLBの場合IPが固定になるので、このIPをAレコードで登録してあげたらいいじゃないかと。

実際行ってみたところ、成功しましたので手順を記載します。

## 手順
### 前提
ALB→EC2の設定は終わっており、かつALBのHTTPSには証明書がついている前提で記載していきます。

### NLB用のセキュリティグループを作成する
- セキュリティグループ名：任意の名前
- インバウンドルール:HTTPとHTTPSを許可する

:::note
ALBのセキュリティグループでNLBのセキュリティグループからのインバウンドを許可してください。
:::

### ターゲットグループを作成する
- ターゲットタイプの選択は、Application Load Balancerを選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882356/5c875a5c-6378-4b22-b9ec-3d1b67344a69.png)
- プロトコルは443を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882356/daa9f215-a60c-4d38-b7d9-724454e64d87.png)
- ターゲット登録は以下にする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882356/1da61017-5867-4eb0-8957-c035d4c20419.png)


- ヘルスチェックプロトコルもHTTPSを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882356/d954f751-8478-4ca8-a85a-a6c16784873e.png)


### NLBを作成していく
 Network Load Balancerの作成をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882356/212769a5-c7f0-45b7-be73-f0eb36d9600f.png)


### 設定値
- スキーム：インターネット向け
- ロードバランサーのIPアドレスタイプ：IPv4
- セキュリティグループ：NLBのセキュリティグループ選択する

- リスナーとルーティング
    - プロトコル：TCP
    - ポート：443と80
    - ターゲットグループ：作成したターゲットグループ

### NLBのIPを探す
ネットワークインターフェイスの画面にて、インターフェイスのタイプが
network_load_balancerになっているものがNLBのIPになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882356/ad1213f6-7375-4ae4-8f06-805fe4587df2.png)

特定したIPをAレコードで登録すると成功します。

### まとめ
ALBの設定で、HTTPをHTTPSにリダイレクト設定していたら最初400番表示になってびっくりしました。(　ﾟдﾟ)
この記事が初心者のためになればうれしいです。
Cloudflareと外部DNSを活用して無料でウェブサイトをデプロイする方法


この記事では、Cloudflareの無料機能と外部DNSプロバイダー（お名前ドットコム）を組み合わせ、費用を抑えながらウェブサイトを展開する方法を解説します。自分の例を元に、具体的な設定手順を詳しくご紹介します。

## 1. 背景と動機

Cloudflareのドメインレジストラは初期契約が有料ですが、お名前ドットコムなどの外部DNSプロバイダーを利用することで、初期費用を無料でデプロイすることができます。
また、Cloudflareの無料プランを利用してDNS管理、CDN、SSLなどの機能を活用することで、安全かつ高速なウェブサイトを低コストで運用できます。
(なお、お名前ドットコムはドメインの更新に年間1500円程度の費用がかかるので、ドメインを維持し続ける場合はcloudflareに移管しても良いと思います)

## 2. 前提条件

- Cloudflareのアカウント
- お名前ドットコムで取得したドメイン (ここでは`example.com`を取得したとします)
- Cloudflare Pagesにデプロイするウェブサイトのプロジェクト

## 3. 手順

### ステップ 1: Cloudflareでドメインの追加

  Cloudflareのダッシュボード上で、追加→既存のドメインと遷移し、お名前ドットコム等で取得したドメインを入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3761984/3cbcd9cf-b35f-419f-b1ac-2cb573b49628.png)
  ここで無料の料金プランを選択し、CloudflareがDNSのスキャンを行います。この後アクティベーションに進むと、最後のステップとしてネームサーバーの更新としてcloudflareからネームサーバーが指定されます。
![image-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3761984/18edaba7-9ce6-485b-bc7c-e92dbe5f5ec5.png)

### ステップ 2: お名前ドットコムでの名前サーバー変更
![image-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3761984/2f8af08f-f4e8-4e52-ab37-7184e0812704.png)
  今度はお名前ドットコムのサイト側でネームサーバーの設定を行います。前のステップで割り当てられたcloudflareのネームサーバーを取得したドメインに変更します。
  変更が全世界に反映されるまで、最大72時間程を要すると書かれていたりしますが、だいたい30分程度で反映された気がします。([DNS lookup](https://mxtoolbox.com/DNSLookup.aspx)等のツールで反映されたか確認しても良いかもしれません)
  反映が完了すると、Cloudflareのネームサーバーがアクティブになります。
  

### ステップ 3: Cloudflare Pagesでのプロジェクトデプロイとカスタムドメイン設定

1. **プロジェクトのデプロイ**  
   Cloudflare Pagesから無料プランを利用してウェブサイトのプロジェクトをアップロードします。詳細は割愛しますが、最終的には `example.pages.dev`等のurlからデプロイされたサイトが見れる形になるかと思います。

2. **カスタムドメインの設定（wwwサブドメイン）**  
   Cloudflare Pagesの管理画面で、カスタムドメインの設定から`www.example.com`を設定します。  
   ※ルートドメイン（`example.com`）では、ドメイン所有権移管が必要なため、今回は`www`サブドメインを利用します。これにより、SSL証明書が自動的に発行され、HTTPS通信が可能になります。

### ステップ 4: CNAMEリダイレクトとルートドメインのリダイレクト設定

1. **CNAMEリダイレクトの設定**  
   CloudflareのDNS管理画面で、`www`サブドメインに対して`CNAME`レコードを追加し、Cloudflare Pages上のサイトに紐付けます。（名前の部分に`www`、ターゲットの部分に`example.pages.dev`と入力）
   この段階で設定が正しければ、`www.example.com` がアクセスできるようになっているはずです。

2. **ルートドメインからwwwへのリダイレクト**  
   ルートドメイン（`example.com`）にアクセスされた場合、HTTPおよびHTTPSリクエストが自動的に`www`サブドメインに転送されるよう、Cloudflareのリダイレクトルールを設定します。  
   このリダイレクト設定により、ユーザーはルートurlをアクセスした際も常にSSLが有効な`www`サブドメインにリダイレクトされます。
![image-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3761984/b95c064f-1a3a-4bea-80cd-2b03d28dac65.png)

## 5. まとめ

反映まで数時間かかってしまう場合がありますが、設定が完了したかどうかはDNS lookupのツールなどを使用して全世界からアクセスできるか確認できます。（ちなみにこれをするとcloudflare側でのトラフィックのリクエストがいろいろな国から来ていることが確認できます）
参考になれば幸いです。
2025/2/25主にITとかセキュリティの記事

Appleが英国でデータ暗号化機能を削除し、ユーザーはプライバシーを失う危険にさらされています(2/22)
https://voi.id/ja/teknologi/462587

欧州 ENISA 脅威状況 (2023.01-2024.06)：金融セクター(2/23)
http://maruyama-mitsuhiko.cocolog-nifty.com/security/2025/02/post-ffa151.html

iPhoneを“自由なスマホ”に変える「脱獄」をすると何がうれしい？(2/23)
https://techtarget.itmedia.co.jp/tt/news/2502/23/news02.html

ハッキングされたBybitプラットフォーム、失われたイーサリアムの形で24.4兆ルピア(2/23)
https://voi.id/ja/teknologi/462686

Bybitハッキング、ハッカーがビットコイン換金で資金洗浄を試みる(2/23)
https://crypto-times.jp/news-hackers-attempt-to-launder-money-using-chainflip/

仮想通貨ニュース週間まとめ「アルトコイン・金融庁・ADA・トランプ氏」などの注目記事(2/23)
https://bittimes.net/news/197871.html

Bybit事件：15億ドル盗難後のETH買い戻しで市場に動き | 北朝鮮ハッカー集団の資金はブラックリストへ(2/23)
https://innovatopia.jp/blockchain/blockchain-news/48295/

Bybit、ハッキング被害の資金回収協力者に最大1.4億ドルの報奨金を発表(2/23)
https://crypto-times.jp/news-bybit-announces-bounty-of-up-to-140-million/

Bybitがハッキング被害！約1.4億ドルの流出と今後の影響(2/22)
https://www.coindeskjapan.com/learn/bybit-hacking/

週刊仮想通貨ニュース｜Bybitへの過去最大規模のハッキングやグーグルのビットコイン参入本格化に高い関心(2/23)
https://coinpost.jp/?p=596824

2024年の10大ランサムウェア攻撃を振り返る(2/23)
https://techtarget.itmedia.co.jp/tt/news/2502/23/news01.html

トラブル拡大を未然に防ぐ、インシデント管理の重要性とその進め方(2/22)
https://topics.smt.docomo.ne.jp/article/manegy/business/manegy-11063?fm=latestnews&redirect=1

NTT DATAレポート:規制と人的資源がAI実装の障壁になる(2/23)
https://voi.id/ja/teknologi/462680

暗号資産１４億６０００万ドル「過去最大規模」で奪われた…北朝鮮のハッキング組織の仕業の可能性提起(2/23)
https://news.livedoor.com/article/detail/28209654/

「AIで言語の壁なくなり、日本へのサイバー攻撃容易に」　米セキュリティー大手の担当者(2/22)
https://www.sankei.com/article/20250222-H76J32DLRRLPRMM53HGVO3NBLM/

アングル：ＡＩチャットボット、子ども保護へ規制導入求める声(2/23)
https://jp.reuters.com/economy/industry/GE7GK7GTK5MG7L4ZWBKMCPXAJ4-2025-02-22/
SharePoint サイトのニュースが投稿または更新を Power Automate でフェッチする。下書きはフェッチしない。

## トリガーの設定

![スクリーンショット 2025-02-25 024856.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629955/c0590656-3e61-4d5c-a5b0-9f9baa565da9.png)

### トリガー条件
![スクリーンショット 2025-02-25 025028.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629955/9e927833-4db4-4164-8661-32cf486fb0cd.png)

```
// ニュースを判別
@equals(triggerBody()?['PromotedState'],2.0)

// メジャーバージョン＝投稿済みニュースと判別
@equals(mod(float(triggerBody()?['{VersionNumber}']),1.0),0)
```


## 検証メモ

SharePoint サイトの所有者のユーザーアカウントでコネクタを接続した場合、SharePoint サイトのメンバーがニュースを下書き保存すると、直前にメジャーバージョンのニュースがフェッチされてしまう。

色々調べたところ、メンバーがニュースを下書きすると、直前のメジャーバージョンに対して CheckoutUser の情報が加筆されていた。これによってファイルが変更されたと判断されて、直前のメジャーバージョンのニュースがフェッチされてしまうっぽい。

取り急ぎはトリガー条件に下記を加えて、CheckoutUser が書かれたメジャーバージョンをフェッチの対象から除外すると良さそう。

```
// メンバーによる下書きを除外
@empty(triggerBody()?['CheckoutUser'])
```

SharePoint、所有者とメンバーで下書きの扱いが違うのが謎。引き続き、SharePoint の仕様を調査。

## 検証メモ on 2025.03.25
```
// メンバーによる下書きを除外
@empty(triggerBody()?['CheckoutUser'])
```
トリガーから上記の条件を抜いたうえで、トリガーの接続を SharePoint サイトのメンバーのアカウントに切り替えて実験。結果として、メンバーがニュースを下書き保存を行っても、直前にメジャーバージョンのニュースがフェッチされない。

下書き保存者とトリガーの接続のアカウントをイコールにしないと、下書き情報を適切に取得できない感あり。故に直近の取得可能なデータである、現在公開されているニュースをフェッチしてしまったと推察。

## 結論
SharePoint の権限でどうにかするより、Power Automate のトリガー条件を工夫したほうが良さそう。`@empty(triggerBody()?['CheckoutUser'])` を条件に引っ掛けるのが今のところ無難。そして特権前提の記事は要注意。
ハッカソンに初めて参加してみた

## 参加しようとしたきっかけ
自分はITを勉強している専門学生で技術的にもまだまだなのですが、できる人たちと一緒に開発とか人脈を広げたくて参加してみました。

## 参加してみて
今回参加したものは割と初心者でも参加しやすいものだったので気楽にいけました。
参加者のレベルも様々で、学生から駆け出しのエンジニアやベテランまでいろんな人がいました。

今回はその場でチームを作っていく形式でした。
テーマに沿って最初のアイデア出しから実装まで一日半でやっていくのでかなり大変でしたが、やりがいと充実感はすごくありました。
自分は技術が本当に浅いのでchat gptをフル活用して進めていきました

人脈も作れるし短期間で完成させる経験が自信にもつながったので、技術力が心配だとか難しそうだとか感じている方々も、重くとらえずに気楽に参加してみると世界が広がると思います。

かなりこのハッカソンの雰囲気にはまってしまったのでまた近くで開催されることがあればジャンジャン参加したいと思います。
Dear 作りたいものがない！というバックエンドエンジニアへ

## はじめに
仕事や学校の授業だけじゃ、なんか物足りない！もっとスキルアップしたい！
そう思って、個人開発に挑戦しようとしたことはありませんか？
でも、いざ始めようとすると...
* 「作りたいものが全然思い浮かばない...」
* 「競プロみたいなアルゴリズムより、実務で役立つスキルを身につけたい」
* 「毎回、環境構築で挫折するんだよなぁ...」

かつての私も、まさにこんな状態でした。
「個人開発ってハードル高すぎ...」
そう思っていた私が、今では気になる技術をどんどん試せるようになりました！

この記事では、そんな私が個人開発をスムーズに始められるようになるまでのプロセスを、経験談を交えながら紹介します。

## 対象
- 学生さん
- 駆け出しエンジニア
- 新卒エンジニア
- ジュニアエンジニア
- めんどくさがりさん

## 1. 作りたいもの、本当にない？？
個人開発になかなか手が出せない人にとってまず出てくる問題。それが

    何を作ればいいのかわからない問題

学びは得たいが、どんなプロダクトをつくればいいのかなかなか思い浮かばない人は多いと思います。

### 個人開発 ≠ 1つのプロダクトを作り上げること
作りたいプロダクトが思い浮かばないのにプロダクトを作ろうとする必要はありません。確かに1つのプロダクトを最初から最後まで作りあげることも大きな学びですが、それにはかなりの時間を必要とします。
（そもそも最初から完全なプロダクトを作りたい！という人はこの記事見ていないと思いますし...）
ほとんどの人にとって個人開発をしたいと思う理由は**学び**を得たいからではないでしょうか。自身の技術力を上げるために実際に手を動かして学びたい。その手段の1つとして個人開発にチャレンジしたいのではないでしょうか。つまり、何を開発するかは自身のスキルアップのために何を開発するか。そこにフォーカスを当てることが重要だと思います。

### スキルアップとしての開発
スキルアップのために何を開発するか。それを見つけるためにまずは自身の現状のスキルを明確にする必要があると思います。
何を理解していて、どんなことが実装できるのか。また、フロントエンジニアもしくはバックエンドエンジニアとしてどんなスキルが足りないのか。これらを明確にすればおのずと実装すべきことが明確になるはずです。

例として、新卒のバックエンドエンジニアを挙げます。新卒エンジニアはまずはジュニアレベルのエンジニアを目指すと思います。個人の方のQiita記事ですか載せておきます。

https://qiita.com/mamimami0709/items/fd6556707e4b924c65ab

この記事にはジュニアレベルのエンジニアとして必要な知識が書かれています。特に認証周りなんかは、仕事でも新卒エンジニアではなかなか実装する機会がないのではないでしょうか。しかし、バックエンジニアにとっては理解しておきたい分野です。このような分野を仕事で経験できない分、個人開発で実装してみて学べばいいのです！

むしろ逆説的ですが、このように自分に足りない分野がないのであれば、もうシニアレベル以上のエンジニアなのではないでしょうか？

## 2. 環境構築なんて慣れているひとに任せてしまえ
### 環境構築めんどくさい
作りたいものが決まった後に出てくる新たな問題。それが

    環境構築めんどくさい問題

おそらく、環境構築であきらめてしまう人の心情は、「新しく実装するならローカルの環境に影響を与えないようにDocker環境を構築したい」と思ってDocker環境の構築をしてみるが、いざやってみるとめんどくさくてやめてしまう。という人が多いと思います。
私も「これ実装してみたい！」と何度か思ったことがありますが、いつもこの環境構築がめんどくさくなってやめてしまいました。

### GitHubのPublic リポジトリ
だがしかし、あきらめるのは早いです！！
今の時代GitHubでDocker環境を共有してくださっている方が大勢います！そういったリポジトリを活用して開発を進めるのが一番効率的です。学びたいことがインフラ周りでないのであれば、環境構築は楽をしてしまうのが一番です。むしろ、環境構築のせいで本来学びたいことが学べなかったり、そこまでの道のりが長くなることの方が大問題だと思います。

（話を戻します）公開されているDocker環境のリポジトリをforkして自分のリポジトリにもってくるのもいいのですが、もし**Template Repository**があれば、そちらを活用するのがおすすめです！
Template Repositoryを活用することよって、自分のリポジトリに同じ環境をいくつも作成できるので、慣れている環境でリポジトリごとに様々な実装ができます。

Template Repositorとは↓

https://qiita.com/ryo2132/items/08f0561804c798012146

Templateとして公開されている環境例
- Laravel
    - Qiita記事：https://qiita.com/ucan-lab/items/5fc1281cd8076c8ac9f4
    - GitHub　：https://github.com/ucan-lab/docker-laravel
- Ruby on Rails
    - Qiita記事：https://qiita.com/malvageee/items/db6f00271d78552b53ca
    - GitHub　：https://github.com/salvage0707/rails-new-template

（思たよりTemplateとして公開している人が少なかったので、自分でTemplate作って公開しようかな）

## 3. 最後に一番大事なこと
本当はこれを一番初めにお伝えしたかったのですが、エンジニアにとって技術以外の部分ってそんなに興味ないと思ったので最後にしれっと書いておきます。

一番大事なこと：**とにかくやってみる！**

### なぜ個人開発を始められないか
個人開発をしたいけどなかなか手を出せない人って、始める前に全体像を明確にしたり、実装可能かどうかを調べてみたりという人が多いと思います。それでなかなか実装自体が始まらない・・・という負の連鎖になってしまっているのではないでしょうか？
何を隠そうか！私がそうでした！

### チャレンジするのに完璧主義は邪魔でしかない
確かに、仕事では全体像の把握や影響範囲、工数などが明確であることが求められます。しかし、やりたいことは**個人開発**です。実務のように完璧なプランニングなんていらないのです。
なにかを実装したいと思ったら、プロダクトの入り口から出口まで設計せずに、**実装したい部分**だけ実装してもいいんです！なんなら実装できなかったで終わってもいいんです！なぜなら個人開発だから。

### おわり
以上が私の思う個人開発の始め方になります。
エンジニアにとって自己研鑽はとても大事なことだと思います。学びにさえなれば別に個人開発がうまくいってもいかなくてもどちらでも良いと思います。そのくらいのマインドでやっていくのが大事なんじゃないかな～と私は思います。
英語の単語の読み方（発音）

こんにちは。
英語の単語の読み方（言い方、発音）は、古代からの発音記号とみなして規則的に読むことが原則です[^1]。これはアルファベットシステム自体の原則です（ラテン語も同様）。

ただし、現代英語は、各種の発音（長母音など）が独特となっている場合があり注意も必要です（他言語話者から見て）。

[^1]: これら基礎を学校教育で教えるべきでしょう。

### 発音例
現代の発音記号を用いると、

##### 短母音
* a は /æ/ です。例：cat は /kæt/
* o は /ɑ/ です。例：cot は /kɑt/
* u は /ʌ/ です。例：cut は /kʌt/、curl は /kʌrl/
* i は /ɪ/ です。例：bit は /bɪt/
* e は /e/ です。例：bet は /bet/
* oo は /ʊ/ です。例：hood は /hʊd/
##### 長母音
* a は /eɪ/ です。例：cate は /keɪt/
* o は /oʊ/ です。例：cote は /koʊt/
* u は /juː/ です。例：cute は /kjuːt/
* i は /aɪ/ です。例：bite は /baɪt/
* e は /iː/ です。例：betel は /biːtl/
* oo は /uː/ です。例：shoot は /ʃuːt/
##### 第二長母音
* a は /ɑː/ です。例：father
* au は /ɔː/ です。例：auto
* ou は /aʊ/ です。例：pouch
* oi は /ɔɪ/ です。例：point

##### 子音
* c は /k/ です[^2]。
* q は /k/ です（qu /kw/ で使われます）。
* x は /ks/ です。
[^2]: これはギリシャ語の 𐌂 /g/ の異形字ですが（= Γ：Gamma）、ラテン語では /k/ の発音です。

###### 軟音化（現代英語）
c に i もしくは e が続く場合は、/s/ の発音へ変化しました。
* 例：civil /sɪvl/、cell /sel/、cite /saɪt/、cee /siː/

j は /dʒ/ へ変化しました。
GitHub Copilot のコード補完で GPT-4o が使えるらしいので試す

GitHub Copilot のコード補完で GPT-4o が使えるらしいので試してみます。

https://github.blog/changelog/2025-02-18-new-gpt-4o-copilot-code-completion-model-now-available-in-public-preview-for-copilot-in-vs-code/

お題はいつものこちら

https://rksoftware.hatenablog.com/entry/2025/02/02/150000


https://rksoftware.hatenablog.com/entry/2025/01/20/010000

この記事にも書いておくと

# ■ 検証コード
こんなコードを改善してもらいます。
```cs
int[] array = new int[] { 1,2,3};
List<int> list = new List<int>();
for(int i = 0; i < array.Length; i++)
{
    list.Add(array[i]);
}
```

Visual Studio のクイック アクションで改善してもらうとこんな感じになります。
```cs
using System.Linq;

var list = (new int[] { 1,2,3}).ToList();
```
この改善コードを基準に見ていきましょう。

# ■ GPT-3.5 Turbo
まずはモデルを変更せず、GPT-3.5 Turbo で。

結果としてこんなコードになりました。結構違和感はありますね。
```cs
var array = new int[] { 1, 2, 3 };
var list = new List<int>(array);
```
![image](https://cdn-ak.f.st-hatena.com/images/fotolife/r/rksoftware/20250224/20250224144316.png)  
![image](https://cdn-ak.f.st-hatena.com/images/fotolife/r/rksoftware/20250224/20250224144321.png) 
# ■ GPT-4o Copilot (Preview)
こんなコードになりました。違いが判らない...... (違いはありません)  
```cs
var array = new[] { 1, 2, 3 };
var list = new List<int>(array);
```
 
![image](https://cdn-ak.f.st-hatena.com/images/fotolife/r/rksoftware/20250224/20250224144324.png)  
![image](https://cdn-ak.f.st-hatena.com/images/fotolife/r/rksoftware/20250224/20250224144327.png)
![image](https://cdn-ak.f.st-hatena.com/images/fotolife/r/rksoftware/20250224/20250224144255.png)  

とはいえよく考えたら、Copilot Chat でも依然試したとき、この回答でしたね。  
[https://rksoftware.hatenablog.com/entry/2025/02/02/150000:embed:cite]  

# ■ もっとコードかかないと
もっとコード書かないと違いを体験できないですね。コード書いてきましょう！

# ■ モデルの変更方法

コマンドパレットの右の Copilot メニューから。  
```
Configure Code Completions...
```
![image](https://cdn-ak.f.st-hatena.com/images/fotolife/r/rksoftware/20250224/20250224144300.png)  
```
Change Completions Model...
```
![image](https://cdn-ak.f.st-hatena.com/images/fotolife/r/rksoftware/20250224/20250224144307.png)  
モデルを選択します。  
![image](https://cdn-ak.f.st-hatena.com/images/fotolife/r/rksoftware/20250224/20250224144312.png)  

簡単ですね。
Chromebook でVScodeをセットアップする

## はじめに
Chromebook (Chromebook Plus)を購入したので、Visual Sutido Code (以下VScode)をインストールして利用可能にするまでの作業の流れをメモとして、記載していきます。

ChromebookにVScodeをインストールする記事はWeb上に多々ありますが、月日の経過で機能Updateされたのか、少しだけ手順が違う部分もありましたので、2025年2月時点のセットアップメモとして記載しています。
同様にセットアップする方の参考になればと思います。

## 環境
今回セットアップした環境です。
- 機種: ASUS Chromebook Plus CX34 (CX3402)
- バージョン: 132.0.6834.208（Official Build） （64 ビット）

## Linux環境を有効にする
ChromebookにVScodeをインストールする前に、Linux開発環境を有効にする必要があります。
  1. 設定を開く
  1. サイドバーの「ChromeOSについて」から、「デベロッパー」-「Linux開発環境」を選択する
  1. Linux開発環境をオンにする
  1. 仮面の指示に従って、Linux環境を設定する
    - デフォルトの設定のまま
    - ユーザー名やディスクサイズは適宜
  1. 終わると、ターミナルが表示される
    - ターミナルはChromebookのメニューから、いつでも開けます

:::note info
Web上の記事でいくつかベータ版である旨が補記されている記事もありますが、ベータ表記がありませんでした。正式になったようですね。
:::

## Linux環境をアップデートする
ターミナル上にて、以下のコマンドで、最新の状態アップデートします。
```bash
$ sudo apt update && sudo apt upgrade -y
```

出来上がったLinux環境は以下の通りです。
```bash
$ cat /etc/os-release 
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
NAME="Debian GNU/Linux"
VERSION_ID="12"
VERSION="12 (bookworm)"
VERSION_CODENAME=bookworm
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
$ 
```

## VScodeをインストールする
VScodeは、公式サイトから、パッケージをダウンロードして、インストールします。
VScodeをインストールするために、ブラウザで[VScode](https://code.visualstudio.com/)の[ダウンロードページ](https://code.visualstudio.com/download)へ行きます。

https://code.visualstudio.com/download

ダウンロードするパッケージを選択するため、自分のChromeboookのアーキテクチャを確認します。ターミナル上で以下のコマンドを実行します。

```bash
$ dpkg --print-architecture
amd64
$
```
今回、`amd64`でしたので .debパッケージ(debian)のx64をダウンロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125593/cad7ee0d-352b-400d-b405-86ebcc57a4be.png)

ダウンロードしたファイルを、ファイルエクスプローラー上で、ダブルクリックすると、インストールが始まります。

インストールが完了すると、Chromeのメニューに「Visual Studio Code」が追加されています。
以後、ChromeメニューからVScodeを利用できます。
VScodeのアイコンを「シェルフに固定」しておくと便利ですね。

## VScodeインストール後の設定
もろもろ、好みに合わせて、VScodeをセットアップしましょう。

デフォルトではメニューは英語表示になっています。

日本語は何も設定しなくても変換、入力できました！
ただ、フォントがちょっとおかしいです（Linuxでありがちな中華フォントっぽい）ので、好みで。

### VScodeの日本語フォント変更
フォントまわり、あまり詳しくないですが、今回は[Notoフォント](https://ja.wikipedia.org/wiki/Noto)を以下のようにインストール＆設定。

1. ターミナルでfontをインストール
    ```bash
    $ sudo apt install fonts-noto-cjk fonts-noto-cjk-extra
   ```

1. VSCodeの設定(Settings)で、`Editor: Font Family`を変更
    - 変更前：`'Droid Sans Mono', 'monospace', monospace`
    - 変更後：`'Noto Sans Mono CJK JP', 'Noto Sans CJK JP', 'Noto Serif CJK JP', 'Droid Sans Mono', 'monospace', monospace`

1. VSCodeの設定(Settings)で、`Markdown › Preview: Font Family`を変更
    - 変更前：`-apple-system, BlinkMacSystemFont, 'Segoe WPC', 'Segoe UI', system-ui, 'Ubuntu', 'Droid Sans', sans-serif`
    - 変更後：`'Noto Sans CJK JP', 'Noto Serif CJK JP', 'Noto Sans Mono CJK JP', -apple-system, BlinkMacSystemFont, 'Segoe WPC', 'Segoe UI', system-ui, 'Ubuntu', 'Droid Sans', sans-serif`

:::note info
インストールされているフォントは、ターミナル上で以下のコマンドで確認できます。
```bash
$ fc-list
```
日本語フォントだけであれば、以下で確認できます。
```bash
$ fc-list :lang=ja
```
:::

### Extensionsのインストール
お好みのものを。
自分は、Markdown All in One、markdownlint、Drawio. Integration、indent-rainbow、Rainbow CSVなどを入れています。

## おわりに
Chromebookで、VScodeをインストールするときの手番をメモしました。
自分のほかにも、どなたかのお役ｎ立てたら幸いです。
最適化手法の整理（AHC用）

:::note info
AHC用にまとめた自分用の備忘録です。誤っている箇所があればご指摘ください
:::

- 組合せ最適化の解法
    - 厳密解法
        - 分枝限定法
        - 動的計画法
        - 整数計画法
    - 近似解法
        - ヒューリスティック：経験則や直感に基づいてある程度の正解に近い解を見つけ出す発見的手法（特定の問題に特化した手法のこと）
            - 貪欲法：局所的に最適な選択を積み重ねる手法
            - ビームサーチ：貪欲法において、各段階で評価値の高い上位n件を保持しておく（幅優先探索の一種）
            - 局所探索
                - 山登り法
                    - ある解を少しずつ変更しながらより良い解を探索。
        - メタヒューリスティック：特定の問題に依存しないヒューリスティック解法
            - 焼きなまし法（Simulated Annealing, SA）
                - 山登り法の発展で、局所最適解に陥るのを防ぐため、確率的に悪化を許容しながら最適解を探索。温度パラメーターにより探索範囲を狭めて局所最適化に移行する
            - 遺伝的アルゴリズム：個体の集合（集団）を進化させながら最適解を探索。交叉や突然変異により多様性を確保する。焼きなましよりも局所最適解に陥りにくい
    - 乱択アルゴリズム：シミュレーションや数値計算を乱数を用いて行う手法
        - モンテカルロ法
    - その他（学習・統計的手法）
        - 強化学習
        - ベイズ最適化
blastengineのGo SDKを使ってList-Unsubscribeヘッダーを利用する


[blastengine（ブラストエンジン）](https://blastengine.jp/)はシンプルに使える開発者向けメールサービスを提供しています。何かと面倒なメール配信をシンプルに、かつ確実に送信先へメールを届けられます。

現在、Go言語向けに、blastengine SDKを開発しています。今回は、バルクメール（一括配信メール）のテンプレート登録や大量のアドレス宛に送信する方法について解説します。

## ユーザ登録する

[blastengine](https://blastengine.jp/)にユーザ登録します。管理画面に入るためのユーザID、パスワードが手に入るので、ログインします（ユーザIDは後で使います）。

## 送信元ドメインのSPFを設定する

送信元として利用するドメイン（自分で持っているもの）の設定をします。これは任意のドメイン管理サービスで設定できますが、TXTレコードに以下のSPFを追加します。

```
txt @ v=spf1 include:spf.besender.jp ~all
```

## APIキーを取得する

ログイン後、管理画面の右上にある設定メニューに移動します。

![getting-started-6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/47b2b2ac-2e41-77fe-d84f-0ae0b7541f36.jpeg)

そして設定の中で、APIキーを取得します。

![getting-started-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/2b5ca124-3020-1d39-84e4-911cd4db27e2.png)

## 必要な情報について

SDKを使う上で必要なのは、先ほどのAPIキーとユーザIDになります。

## SDKのインストール

SDKは[blastengineMania/blastengine\-go: Blastengine Golang SDK](https://github.com/blastengineMania/blastengine-go)にて公開しています。インストールは `go get` で行います。

```bash
go get github.com/blastengineMania/blastengine-go
```

## 初期化

先ほどのAPIキーとユーザIDを使って初期化します。

```go
package main

import (
	"fmt"
	"github.com/blastengineMania/blastengine-go"
)

func main() {
	apiKey := "yourApiKey"
	userId := "yourUserId"
	client := blastengine.Initialize(apiKey, userId)
}
```

## メールの送信

### メール送信時のクラス

blastengine Go SDKでメール送信を行う際には、2つのクラスが利用できます。

- **Transaction:**  
都度配信用クラス
- **Bulk:**  
一括配信用クラス

以下のメソッド名は共通です。

## List-Unsubscribe用の情報設定

List-Unsubscribeヘッダーを使う際には、 `SetListUnsubscribe` メソッドを使います。

```go
transaction := client.NewTransaction()
transaction.SetListUnsubscribe(&ListUnsubscribeParams{
  Email: "unsubscribe+__code__@example.com",
})

bulk := client.NewBulk()
bulk.SetListUnsubscribe(&ListUnsubscribeParams{
  Url: "https://example.com/unsubscribe/__code__",
})
```

`SetListUnsubscribe` は `Url` と `Email` をオプションに取ります。どちらもオプションです。`__code__` は置換文字列になります。

## メールの送信

メールの送信は `Send` メソッドを使います。

```go
err = bulk.Send(nil) // または transaction.Send()
if err != nil {
  t.Errorf("Expected error to be nil, but got %v", err)
}
```

## まとめ

List-Unsubscribeヘッダーは、Gmailのガイドライン変更に伴って、対応が必須になっている機能になります。blastengineの場合は、APIとSMTP両方でList-Unsubscribeヘッダーに対応しています。

現在はGmailのみですが、他のメールプロバイダーについても対応が進んでいくことでしょう。blastengineを使って、配信したメールを確実に受信者に届けるためにも、List-Unsubscribeヘッダーの対応を行ってください。

[blastengine API](https://blastengine.jp/documents/)
🚀【無料で爆速検索】Webエンジニアの作業効率を向上させるListary活用術！

# :fire:はじめに
**あの機能の仕様書どこ置いたっけ？...ミーティングの資料どこやったっけ？...**
エンジニアとして日々の作業を効率化するために、ファイルやフォルダを素早く開きたいと思ったことはありませんか？
そんなあなた！！Listaryをぜひぜひお勧めします！
Listaryは、Windowsのファイル検索やアプリケーションの起動を劇的にスピードアップしてくれるツールです。
特に、無料で利用できる範囲でも十分便利なので初心者でも簡単に無料で利用できます。

**一度使えば手放せなくなる、まさに「Windowsの必須ツール」です。**

# :mag:Listaryとは
ListaryはWindows向けの検索ツールで、以下の特徴があります。
- 超高速検索：ファイルやフォルダを一瞬で検索
- どこでも起動：エクスプローラー、デスクトップ、開いているフォルダ内で直接検索可能
- アプリランチャー機能：アプリやスクリプトを瞬時実行
- 無料で使える：基本機能は無料で十分活用できる

特に、デフォルトのWindows検索が遅くて使いにくいと感じている方には、Listaryの快適さをぜひ体感いただきたいです。
（ListaryはWindows専用のツールのため、macは2025/02/24現在対応しておりませんがspotlight検索が優秀なので、macを使用する場合はそちらを使うのがいいかもしれません。）

# :wrench:基本機能の紹介
**1.  どこでも検索**
Listaryをインストールすると、どのウィンドウでも`Ctrl`キーを2回押すだけで検索バーが開きます。
![record1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3907998/e3828591-e361-4d18-bfc8-7684f0b841b4.gif)
例えば、
    - `〇〇仕様書`と入力すれば、瞬時に表示され`Enter`を押すとそのファイルがヒットします！
    
Windowsの標準検索と比べて、爆速＆精度が高いので、エクスプローラを開く必要はなくなります。


**2.  アプリケーションの瞬時起動**
Listaryがあれば、フォルダ階層を一々辿る必要なしです！
例えば検索バーに、
- `chrome`と入力すれば、google chromeを開けます。
- `cmd`と入力すれば、コマンドプロンプトを即座に開けます。
- ファイルエクスプローラなどを、マウスを使わずに一瞬で起動できます。

**3. gスペースでgoogle検索が可能**
検索バー内で`g`と入力し、スペースを入力するとgoogle検索が可能です。
![スクリーンショット 2025-02-25 0.26.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3907998/65d67525-3554-42f6-ad28-cf077726c594.png)

他にもwiki、gmail、youtubeなどがあります。詳しくは下記を参照してください。

https://help.listary.com/web-search#:~:text=Listary%20%E3%81%AB%E3%81%AF%20Web%20%E6%A4%9C%E7%B4%A2%E6%A9%9F%E8%83%BD%E3%81%8C%E7%B5%84%E3%81%BF%E8%BE%BC%E3%81%BE%E3%82%8C%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99%E3%80%82

# :writing_hand:Webエンジニア向けの応用テクニック

**1. VS Codeやターミナルとの連携**

Listaryを使えば、特定のプロジェクトフォルダを 一瞬でVS Codeで開くことができます。
例えば、`my-project` フォルダを `code my-project` で開くように設定すれば、
Listaryの検索バーで `my-project` と入力 → `Enter` だけでVS Codeが開きます。

同様に、ターミナル(Windows Terminal や Git Bash)との連携も可能です。

**2. カスタムコマンドの活用**
Listaryでは、独自のコマンドを登録することができます。
例えば、

`serve` → `npm run dev` を実行

`deploy` → `git push origin main` を実行

これらをListaryのカスタムショートカットに登録すれば、CLI操作を最小限にして作業効率を向上できます。


# :desktop:インストール方法
:link:ダウンロードページ
https://www.listary.com/download

1. 上記のURLからダウンロード
2. インストーラを実行し、指示に従ってインストール
3. `Ctrl`を2回押すと、Listaryが起動される

# :point_up:まとめ
Listaryを活用すれば、
✅ **ファイル・フォルダ検索が爆速化**
✅ **アプリ・ターミナルを瞬時に起動可能**
✅ **Webエンジニアの作業効率を向上**
特に、**無料で使える範囲でも十分便利**なので、まだ導入していない方はぜひ試してみてください！
あなたの作業効率が劇的に向上すること間違いなしです！
RANDOM 変数の第一文字に 0|9 が現れにくい（bash）？

こんにちは。
bash の RANDOM 変数の第一文字に 0|9 が現れにくい？ことに気がつきました。完全な乱数と思っていたのですが。

```console
$ for i in $(seq 9); do echo $RANDOM; done
30271
7897
655
27235
17049
21495
22793
30518
21757
```
Pythonのset（集合）メソッドの図解

Pythonのset（集合）は、ものの集まりを扱うのに便利な機能です。
この記事では、setの基本的なメソッドを図を使って説明します。

## set（集合）って何？

setは、ものの集まりを表すことができます。例えば、

* 好きな果物の集まり（りんご、みかん、ぶどう）

みたいな感じです。setでは、同じものが2つ以上入ることはありません。

## setの主なメソッド

setには、いくつかの便利な機能（メソッド）があります。その中でも、特によく使うものを紹介します。

### 1. 和集合（union）

2つのsetを合わせて、全部の要素を集めたものです。

```python
set1 = {"りんご", "みかん"}
set2 = {"みかん", "ぶどう"}
set1.union(set2) # 結果：{"りんご", "みかん", "ぶどう"}
```

図で表すと、以下のようになります。

```
       set1         set2
    +--------+    +--------+
    | りんご |    | みかん |
    | みかん |    | ぶどう |
    +--------+    +--------+
          \       /
           \     /
            \   /
         +-----------------+
         | りんご, みかん, ぶどう |
         +-----------------+
```

### 2. 積集合（intersection）

2つのsetに共通して含まれる要素を集めたものです。

```python
set1 = {"りんご", "みかん"}
set2 = {"みかん", "ぶどう"}
set1.intersection(set2) # 結果：{"みかん"}
```

図で表すと、以下のようになります。

```
       set1         set2
    +--------+    +--------+
    | りんご |    | みかん |
    | みかん |    | ぶどう |
    +--------+    +--------+
          \       /
           \     /
            \   /
         +--------+
         | みかん |
         +--------+
```

### 3. 差集合（difference）

最初のsetにあって、2番目のsetにない要素を集めたものです。

```python
set1 = {"りんご", "みかん"}
set2 = {"みかん", "ぶどう"}
set1.difference(set2) # 結果：{"りんご"}
```

図で表すと、以下のようになります。

```
       set1         set2
    +--------+    +--------+
    | りんご |    | みかん |
    | みかん |    | ぶどう |
    +--------+    +--------+
          \       /
           \     /
            \   /
         +--------+
         | りんご |
         +--------+
```

### 4. 対称差（symmetric\_difference）

2つのsetのどちらか片方だけに存在する要素を集めたものです。

```python
set1 = {"りんご", "みかん"}
set2 = {"みかん", "ぶどう"}
set1.symmetric_difference(set2) # 結果：{"りんご", "ぶどう"}
```

図で表すと、以下のようになります。

```
       set1         set2
    +--------+    +--------+
    | りんご |    | みかん |
    | みかん |    | ぶどう |
    +--------+    +--------+
          \       /
           \     /
            \   /
         +---------------+
         | りんご, ぶどう |
         +---------------+
```

これらのメソッドを使うと、setに入っている要素を色々と操作することができます。

## まとめ

* 和集合：2つのsetの要素を全部集める
* 積集合：2つのsetに共通する要素を集める
* 差集合：最初のsetにあって、2番目のsetにない要素を集める
* 対称差：2つのsetのどちらか片方だけに存在する要素を集める
reactでwebサイトを作る


#### HTMLとCSSでいい感じのサイトが作りたい！！

今月はwebサイトを作成するにあたり勉強になったところをまとめていきます。
諸事情で「webサイトいい感じに作って」というリクエストがありまして……

いくつかソースを見ていると、画像をペタペタ貼っているサイトが多かったため、当初canvaで画像を作成してべた張りするという暴挙に出たのですが、スマホ対応諸々を考えて断念しました。

## 1. サイトを作る
reactでサイトを作る際には下記を参考にすると非常に分かりやすいのでぜひご覧ください。
他のやり方が好みという方はご随意に。
- [TypeScript でWebアプリ開発](https://qiita.com/Yasushi-Mo/items/3f6af80b871e2ff22568)

## 2. 素材を作る
つづいて[canva](https://www.canva.com/)でベースの画像を作成。
「webページ」で検索するといい感じのテンプレートが出てくるので、それをベースに作ると多少センスがなくとも大事故は避けられる気がします。
特にこだわりがないのであれば、そこからwebページをビルドしたリンクを取得して公開もできるようなのですが、画像だけ取得してこっちでいいようにした方がメンテナンスや自由度的に良い気がします。


## 3. そのほかいい感じにする
雑多に参考になったものを、また必要になったら再度検索するであろう自分のために載せておきます。
#### 手書き風のマーカーを引く
- html
```
<p>私の夢は<mark>非課税の</mark>大金を得ることだ</p>
```
- css
    - tansparent部分で線の太さ、色の後ろの%で色の濃さを調整できます
    - reactの場合、`index.css`に書いて、該当のtsxファイルでimpotしてやると使えます
```
mark {
  background: linear-gradient(transparent 30%, #00ffff 60%);
}
```


反映するとこんな感じになります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3811577/2b2a5eef-29ea-48e3-84f4-91aaa53c27c6.png)



#### フォントを変える

- html
    - google fontの場合は`<head>`タグに下記のような参照を加える
    ```
    <head>
        <link href="https://fonts.googleapis.com/css2?family=Zen+Kaku+Gothic+New&display=swap" rel="stylesheet">
    </head>
    ```
    - reactの場合は`index.html`に`<head>`があるのでそちらに書き足しましょう
- css
```
body {
  font-family: "Zen Kaku Gothic New", sans-serif;
}
```

あまりfontを変更してこなかった人生なので、headはどこだ……としばし彷徨いました


#### スマホ対応する
PCに合わせて描画を調整するとスマホで「なんだこの奇怪なサイトは？？」と思われかねないためです。
やりようはいくつかあるようですが、今回はtailwindを用いました。
- npmで追加して（バージョンによってはエラーが出たので環境に合わせてください。私の環境の`package.json`を参考に晒すと該当箇所は下記のとおりです）
- prefixを指定するだけでいい感じにスマホ対応できます
    - 詳細は参考に貼ってあるサイトを見てください
```
  "devDependencies": {
    "autoprefixer": "^10.4.20",
    "postcss": "^8.5.3",
    "tailwindcss": "^3.3.5",
  }
```
- スマホでの確認方法
    - localhostで立ち上げていると、スマホでは見られないと思うので、ngrokをお勧めします
    - reactの場合は`vite.config.ts`にallowedHostsを追加しないとエラーになるので注意
```
export default defineConfig({
  plugins: [react()],
  server: {
    allowedHosts: ["9d46-49-250-139-233.ngrok-free.app"],
  },
});
```

## 参考
- [TypeScript でWebアプリ開発](https://qiita.com/Yasushi-Mo/items/3f6af80b871e2ff22568)
- [HTMLのmark要素とCSSで蛍光ペン風マーカーを引く方法](https://web-camp.io/magazine/archives/82496/)
- [ページにWebフォント（Google Fonts）を使用する方法](https://knowledge.spirers.jp/article/development/detail/3636)
- [TailwindCSSのレスポンシブデザイン](https://qiita.com/senju797/items/ad85794ec927f6ebd7bc)
Nordic nRF9160 DKをはじめよう6～1nceOS編2～　

__Nordic nRF9160 DKをはじめよう5～1nceOS編1～__ の続きです。

https://qiita.com/usashirou/items/4d666825961d5ab807ed

今回は、__1nceOS__ を動作させます。

https://portal.1nce.com/portal/customer/dashboard
# ICCID
最初にMySIMをクリックしICCIDを記録しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/08b1cc62-8a30-43fd-a239-fb59b7ef219e.png)
# 1nce OS
1nceOSに入り接続してみましょう。
__1nceOS__ を __クリック__ します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/de9f347a-6bb0-3604-ccad-7a529e5cb011.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/ee992ecb-6293-956e-24f6-19f1816463d2.png)
__Device Integrator__ を __クリック__ し今回テストする __LwM2M⇒Test Integration__ を __クリック__ します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/b6eb29ab-36f0-a072-6e75-89f705f7c63a.png)
__DeviceID__ にSIMカードの __ICCID__ を入力します。
__Pre-shared Key__ は __None__ にし、__Test Integration__ を __クリック__ します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/7bfc8f1e-0d41-a5d4-0dc9-b52afcc4117f.png)
接続できた場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/cef73368-5284-cfaa-c319-593e6ce241db.png)
__View Device Details__ を __クリック__ して内容を見てみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/6f40d9ef-9b5b-289f-b561-32adc817a593.png)
LEDやGPIOのデータを見ることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/65c34d31-c410-0690-117d-b2f515c4513f.png)
__Device Controller__ を __クリック__ し、接続する __Device__ を __クリック__ します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/7fabb7da-f0a9-05df-1821-9f049e1ddf43.png)
__LwM2M__ を __クリック__ します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/5b2fb042-d6a9-2eeb-d25b-d27c75a440c9.png)


|Action|Write |
|:-:|:-:|
|Resource Address|/3311/0/5850 |
|Data|true|

とし、__Send Data__ を __クリック__ します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/02c809c2-6aee-778b-2e61-e3d6a97d4247.png)
nRF9160 DKのLEDが点灯すれば通信成功です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/02bf63b3-067b-0e1d-4bb8-7350dd127d12.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/012da803-babf-9c3b-e8ef-5d43558a44f2.png)
nRF9160で1nceOSを使う事が出来ました。
Excelで"①","②",...を連番として使用する方法

「1.」「(1)」「1月」などは数字を含む列として、セルの右下を引っ張ると連番が表示される。

が、「①」を入力してセルの右下を引っ張ると連番が表示されず、イライラしたことはないだろうか？
（筆者は、箇条書きでは①②③…を項番としたいタイプなので、毎回入力するのがメンドウだった、、、）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3884030/1954b954-8cef-4e2d-9ea6-b4dc4efb93ec.png)


以下、「①②③…」を連番としてExcelに認識させ、セルの右下を引っ張ると続く数字が自動入力できる設定を紹介する。


## 設定手順（ユーザ設定リスト）
3. 「ファイル」タブからオプションを開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3884030/e4951d22-ffcd-4e94-81a3-e1008a0a3bb8.png)


3. 「詳細設定」 > 「ユーザー設定リストの編集」 を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3884030/8f5ac62d-57d3-4334-a42e-90f89a939f4a.png)


3. 「新しいリスト」を選択し、「リストの項目」に連番表示させたい文字列リストを入力し、「追加」→「OK」を押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3884030/1b19997a-c06f-4001-8a83-0d9460b537f6.png)

※例と同じリストを追加したい場合は、下記をコピー
①,②,③,④,⑤,⑥,⑦,⑧,⑨,⑩,⑪,⑫,⑬,⑭,⑮,⑯,⑰,⑱,⑲,⑳,㉑,㉒,㉓,㉔,㉕,㉖,㉗,㉘,㉙,㉚,㉛,㉜,㉝,㉞,㉟,㊱,㊲,㊳,㊴,㊵,㊶,㊷,㊸,㊹,㊺,㊻,㊼,㊽,㊾,㊿




4\. すると、「①」も連番表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3884030/b0edb375-1c35-483c-a0a1-c61158723437.png)





他にも、、、、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3884030/707bde45-75d5-45c0-aae9-2328604b8590.png)
【Python】C・Dランク相当のコード問題を4問解説【電脳少女プログラミング2088 ─壊レタ君を再構築─】

## はじめに

こんにちは！Qiita初投稿です
この記事では，paizaの新作ゲーム [電脳少女プログラミング2088 ─壊レタ君を再構築─](https://ppg.paiza.jp/denno2088) にて出題されている問題のうち，C・Dランク相当の問題を4問解説します．

以下が今回解説する問題です．
- Dランク：カジノ，郊外のスラム街，ネオン街の裏路地
- Cランク：自然の残る公園

より簡単なDランク問題から，早速解説していきます

## Dランク問題：カジノ

問題文
> あなたはカジノにやってきました。
> カジノで使われるチップは 1ドルのもの, 5ドルのもの, 10ドルのものがあるようです。
> 各チップの枚数が 1ドル, 5ドル, 10ドルの順で改行区切りで与えられるので合計で何ドルかを出力してください。
```python:入力形式
a #1ドルの枚数
b #5ドルの枚数
c #10ドルの枚数
```
金額ごとの枚数を受け取り，合計金額を計算すればよいです

```python:コード例
a=int(input())
b=int(input())
c=int(input())
print(a+5*b+10*c)
```

## Dランク問題：郊外のスラム街

問題文
> 郊外のスラム街にジャンク品を扱うお店があります。
> あなたはある商品を買おうとしましたがジャンク品なので値切ろうとしています。
> 値切りの戦略はまず半額を希望しそれが駄目な場合に半額から 100 増やした値段を伝えることにしました。
> ある商品の値段 n が与えられるので上記の戦略で半額の希望が駄目だった場合の額を出力してください。

条件
> nは10の倍数

```python:入力形式
n #値段

```
nを2で割った値に100を足して出力しろ という問題です．

条件によるとnは10の倍数なので，2で割り切れます．
/ ではなく // を使うことで，小数点以下の .0 の登場が回避でき，少し楽ができます．
```python:コード例
n=int(input())
print(100+(n//2))
```

## Dランク問題：ネオン街の裏路地

問題文
> あなたは裏路地にある扉を開けようとしています。
> 扉は n 個あり各扉は順不同に数字が書かれています。
> 最も大きな扉の数字を出力してください。

```python:入力形式
n
m_1
m_2
.
.
.
m_n
```
縦n行にわたる入力の受け取りと，配列内の最大値の求め方が重要です．
配列内の最大値は max() 関数で取得できます．

ついでに，縦または横に多くのデータが入力されるときの受け取り方法をまとめておきます
```python:縦n行
n=int(input())
a=[int(input()) for i in range(n)] #整数ではなく文字列の場合はintをstrに変える
```
```python:横1列
a=[int(i) for i in input().split()] #整数ではなく文字列の場合はintをstrに変える
```
以下がこの問題の回答例です
```python:コード例
n=int(input())
m=[int(input()) for i in range(n)]
print(max(m))
```
## Cランク問題：自然の残る公園
問題文
> 自然の残る公園にいくつかのビーコン反応があります。
> 現在地の座標 (y, x) から最も近いビーコンの反応の地点を目指すことにしました。
> N 個のビーコンが発信されている座標と現在の座標が与えられるので最も近いビーコンの番号を出力してください。

条件
>5 ≦ N ≦ 100
-1000 ≦ y_i, x_i, a, b ≦ 1000 (1 ≦ i ≦ N)
最も近いビーコンはただひとつ存在する

```python:入力形式
N a b
y_1 x_1
y_2 x_2
.
.
.
y_N x_N
```
初期値 t をある程度大きい値で設定して，N個の点それぞれとの距離を比較し，小さければ t を更新するという方法を取ることにします．

出力するのは最も近い点の番号なので，現在最も近い点の番号を k として保存します．
t が更新されるたびに，k の値も更新します．

距離の比較は三平方の定理を用いることで簡単にできますね．
ルートをしてもしなくても距離の大小関係は変わらないので，ルートはせずに比較します．

条件から，点同士の距離の2乗は最大でも$2000^2+2000^2=8000000$なので，
t = 8000001としておきます．

```python:コード例
n,a,b=map(int,input().split())
c=[list(map(int,input().split())) for _ in range(n)]
t=8000001
k=0
for i in range(n):
    if t> (c[i][0]-a)**2+(c[i][1]-b)**2:
        t= (c[i][0]-a)**2+(c[i][1]-b)**2
        k=i+1
print(k)
```
## 最後に
記事は以上です！
ありがとうございました
【Markdown】リンク付きの画像

リンク付きの画像を表示するには以下のように記述します。

```markdown
[![代替テキスト](画像URL)](リンク先URL)
```

[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/9299dac6-d5ac-4770-9670-54edda369758.png)リンク付きの画像](https://qiita.com)
Elixirに知識ゼロの状態から入門した感想【電脳少女プログラミング2088 ─壊レタ君を再構築─】

## はじめに
paizaとqiitaのコラボキャンペーンがあることをたまたま目にし、せっかくなので全く触ったことのない言語で問題を解いてみることにしました。選んだのはElixirです。理由は響きがなんかカッコよかったので。

## 問題
![スクリーンショット 2025-02-24 23.08.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4020140/5399c900-304a-43f1-9b68-0b1f02c41227.png)

## コード

```elixir
n = IO.gets("") |> String.trim() |> String.to_integer()
numbers = Stream.repeatedly(fn -> IO.gets("") end) |> Stream.take(n) |> Enum.map(fn line -> String.trim(line) |> String.to_integer() end)

max_number = Enum.max(numbers)
IO.puts(max_number)
```

## ポイント

### 入力の受け取り
```elixir
n = IO.gets("") |> String.trim() |> String.to_integer()
```
`IO.gets("")`で標準入力を受け取ることができます。これだけだと改行文字も含まれてしまうので、`String.trim()`で改行文字を取り除き、`String.to_integer()`で整数変換します。こうやって、左から右に順番に処理を進めていくのを、`|>`という記号で表しているわけですが、これを「パイプライン演算子」と呼ぶらしいです。

```elixir
numbers = Stream.repeatedly(fn -> IO.gets("") end) |> Stream.take(n) |> Enum.map(fn line -> String.trim(line) |> String.to_integer() end)
```

`Stream.repeatedly(fn -> IO.gets("") end)`で1行ずつ読み込んでいきます。ストリームで受け取るのでこれだけだと無限に取ってきてしまいます。
そこで、`Stream.take(n)`でn個だけ要素を取り出すように指定してあげます。これによりnumbersという名のn個の配列ができます。

`Enum.map(fn line -> String.trim(line) |> String.to_integer() end)`では、n個の要素に対して改行記号の除去と、整数変換をします。

### 最大値を計算する
```elixir
max_number = Enum.max(numbers)
```

`Enum.max(numbers)`で、`numbers`配列の中で最も数が大きいものを出力してくれるみたいです。

### 出力
```elixir
IO.puts(max_number)
```
`IO.puts(max_number)`で標準出力です。

## おわりに
普段Pythonを使っている身としては、雰囲気がPythonに似ているので簡単な言語だと感じました。パイプライン演算子はPythonにないですが、機械学習でパイプライン処理は学んだことがあったので、理論的なところはすぐに理解できました。なのでElixirとは仲良くやっていけそうです。

一方で、記事を書くことも初めてだった訳ですが、そちらの方がずっと難しいと思いました。読みにくい部分が多々あるかと思いますが、プログラミングの技術共々上達させていきたい所存です。
JSとCSSで中央寄せがなぜかズレる

#はじめに
JSを使用して要素の中央揃えを作成した時、なぜかCSSのフレックスボックスと中心がずれる場合があるので調べてみました

# 検証用コード
要素を3つ用意し
1.CSSのフレックスボックスを使用して中央揃えしたもの
2.JSの window.outerWidth を使用し計算を行い中央揃えしたもの
3.JSの window.innerWidth を使用し計算を行い中央揃えしたもの

を作成しどういった場合に中央揃えがずれるのかを検証してみます

```html
<style>

  .frame{
    /* height: 10000px; */
  }

  .flex{
    display: flex;
    justify-content: center;
    align-items: center;
  }

  .box{
    width: 100px;
    height: 100px;
    color: white;
  }

  #box1{
    background-color: rgb(255, 116, 116);
  }

  #box2{
    background-color: rgb(126, 160, 253);
    position: absolute;
    top: 100px;
  }

  #box3{
    background-color: rgb(123, 255, 128);
    position: absolute;
    top: 200px;
  }

</style>

<div class="frame">
  <div class="flex">
    <div id="box1" class="box">
      フレックスボックスによる中央寄せ
    </div>
  </div>

  <div class = "inner_frame">
    <div id="box2" class="box">
      outerWidthによる中央寄せ
    </div>
  </div>

  <div class = "inner_frame">
    <div id="box3" class="box">
      inner_widthによる中央寄せ
    </div>
  </div>
</div>

<script>
  const outer_width = window.outerWidth
  const box2 = document.getElementById('box2')
  box2.style.left =  `${(outer_width - box2.clientWidth) / 2}px`;

  const inner_width = window.innerWidth
  const box3 = document.getElementById('box3')
  box3.style.left =  `${(inner_width - box3.clientWidth) / 2}px`;

</script>
```
# 実際の動作
下記は赤い要素がフレックスボックス、青と緑がそれぞれJSで画面幅と要素幅から、leftの値を計算して中央に移動させています。
現時点では特に問題なくすべて中央にそろっています


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727407/33672798-633d-4b46-93d5-9fa7d73cf002.png)

ではここで親要素の縦幅を伸ばしてスクロールバーが表示されるように修正すると

CSSのフレックスボックスで中央揃えした要素が左にずれてしまいました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727407/02c5f718-ab4d-4ca9-a816-79290df71b98.png)

さらにウィンドウ幅を調整すると

window.outerWidth を使用し計算を行い中央揃えしたものが左にずれてしまいました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2727407/60735b6f-de20-4d0f-931b-e6af0ff785fd.png)


#原因

それぞれの計算元となる画面幅の違いが原因でした

①1枚目の画像では、全ての要素が左端から右端の画面幅をもとに中央位置の計算をしているためすべて同じ中央の位置に配置されます

②スクロールバーが表示されたことにより
　赤要素は左端からスクロールバーの左側まで
　window.outerWidthとwindow.innerWidthを使用している青と緑要素は左端からスクロールバー右端までを画面幅とすることにより中央揃えの計算に差が発生しています

 となることでズレが発生しています

③window.outerWidth（青要素）は左端からウィンドウの一番右端、window.innerWidthは左端からスクロースバーの左側までを取得しているため画面サイズを知事メルことによってこれまたズレが発生しています



# 解決方法
赤要素のフレックスボックスはあくまで親要素の幅を参照しているため、ＪＳで計算を行う場合も対象の親要素の幅を取得し計算することによってずれがなくなります
【Supabase】「42501 permission denied for view (View名)」エラーの解消方法

以前ハマったところで、もう一回ハマったので、備忘録として残しておきます

## 事象
View を作り直したところ、`Supabase-js`での`select`結果として、以下のエラーが帰ってくるようになった
```
42501 permission denied for view (View名)
```

## エラーの解消方法
以下の`SQL`を実行して、権限を付与する
`View`に対しての実行だが、`~ ON table ~`で実行する
（`table`の記載を`view`に置き換えて実行すると構文エラーになる）
```
GRANT ALL ON table スキーマ名.View名 TO postgres;
GRANT ALL ON table スキーマ名.View名 TO anon;
GRANT ALL ON table スキーマ名.View名 TO authenticated;
GRANT ALL ON table スキーマ名.View名 TO service_role;
```
※`スキーマ名.View名`は実行する`View`の名称に置き換え

開発様に全権限を与えているので、必要に応じて設定は変更すること

テーブルに`select`して、`42501`エラーが返ってくることがあるが、その場合の対処方法も同じ
JavaScriptのイベントループと非同期処理 - 基本概念


## JavaScript の実行モデル

### シングルスレッドの特性（なぜ非同期処理が必要なのか）

JavaScript は **シングルスレッド** で動作するため、一度に一つの処理しか実行できません。

このため、長時間かかる処理（I/O、ネットワーク通信など）を同期処理で行うと、メインスレッドがブロックされ、他の処理が止まってしまいます。

そこで、**非同期処理** を活用することで、他の処理を止めることなく並行して処理を進めることができます。

### 同期処理 vs 非同期処理（実行の仕組みと違い）

- **同期処理**: 順番に処理が実行され、1つの処理が終わるまで次の処理は実行されない。
- **非同期処理**: 時間がかかる処理を別の仕組みに委ね、結果が得られたら後で処理を再開する。

---

## 学習内容

### 実行モデルとは？

JavaScript のコードがどのように解釈・処理されるのかを決める仕組み。

### メインスレッドとは？

JavaScript のコードを実行する中心的なスレッド。

ブラウザ環境では、以下のような処理をメインスレッドが管理します。

- ユーザー操作（クリック、キー入力など）
- 画面の描画
- 関数の呼び出し など

**ポイント**

- JavaScript は **シングルスレッド** で動作し、同期的な処理はメインスレッド上で実行される。
- ただし、メインスレッドが直接処理の流れを管理しているわけではない。
- 実際のタスクの順序やタイミングは **イベントループ** や **タスクキュー** によって制御される。
- **イベントループ** を通じて **「どの関数をいつ実行するか」** が決まり、メインスレッドが CPU に処理を依頼するイメージ。

---

## イベントループとは？

タスクキューからルールに従ってコールスタックへ関数を追加する流れ

### イベントループの流れ

1. **マクロタスクキュー** からタスクを取り出し、**コールスタック** で実行
2. **マクロタスクが終了後**、**マイクロタスクキュー** のすべてのタスクを実行
3. 必要に応じて **描画更新**
4. 再度 **マクロタスクを取り出し実行**→ これを **繰り返す**

> イベントループ = 全体の処理の順番を取り仕切る現場監督
> 

---

## コールスタックとは？

同期処理の **実行順序を制御** するための **スタック（LIFO）** 構造。

### コールスタックの仕組み

- 関数が **呼び出されると** スタックに **積まれる**。
- 関数の実行が **終わると** スタックから **取り除かれる**。
- **常にコールスタックのトップにある関数が実行される。**

> コールスタックの一番上 = メインスレッド
> 

**重要な特徴**

- **コールスタックが空になるまで他の処理は実行されない**。
- **「作業員①」：同期処理を担当する作業員のような役割**。

---

## Web API とは？

**ブラウザ**（または Node.js などの実行環境）が提供する **JavaScript 以外の機能** の総称。

### 例：

- `setTimeout`
- `fetch`
- `addEventListener`など

**仕組み**

1. これらの API は **ブラウザの内部で実装** されている。
2. `setTimeout` や `fetch` を呼び出すと、**非同期処理としてブラウザに委ねられる**。
3. 処理が完了すると、**タスクキューにコールバックを登録**。
4. **イベントループがコールスタックに取り込み実行** → **非同期処理が可能に！**

> 注意： Promise は Web API ではなく、JavaScript の機能。
> 

---

## タスクキュー（Task Queue） / コールバックキューとは？

非同期 API によって実行タイミングが予約された **コールバック関数を蓄えておくキュー**。

- `setTimeout`、`setInterval`、`DOM イベント`、`XHR/Fetch` などによる非同期処理が完了すると、コールバック関数が **マクロタスクキュー（タスクキュー）** に登録される。
- イベントループは **コールスタックが空になったタイミング** で **タスクキューの先頭のコールバックを実行**。

> 「作業員②」：非同期処理のコールバックを管理する作業員
> 

---

## 非同期処理とは？

JavaScript のメインスレッドが **ブロックされるのを防ぐための処理方式**。

### 仕組み

- 時間のかかる処理（I/O、ネットワーク通信など）を **ブラウザや Node.js に委ねる**。
- 処理が完了したタイミングで **タスクキューに登録** し、**イベントループを介して処理**。

---

## 非同期な関数とは？

呼び出しと結果の取得が **同時ではなく**、処理完了のタイミングで結果を返す関数。

### 例：

- `fetch`
- `setTimeout`
- DOM イベントハンドラ
- Node.js の I/O 関数 など

**特徴**

- **メインスレッドがブロックされない**。
- **非同期処理はブラウザや Node.js が担当**し、処理完了後にコールバックをタスクキューへ。

---

## ブラウザ環境でのイベントループの詳細な動作

1. **マクロタスクの取り出し**
    - タスクキュー（マクロタスクキュー）の先頭のタスクを取り出し、**コールスタックで実行**。
    - `setTimeout` や **ユーザーイベント（クリックなど）** のコールバックがここに入る。
2. **コールスタックでの実行**
    - `fetch` や `setTimeout` の**実際の処理はブラウザの内部へ**（バックグラウンド処理）。
    - 完了後に **マクロタスクキュー or マイクロタスクキューに登録**。
3. **マイクロタスクの処理**
    - **マクロタスクが終了後**、マイクロタスクキューのタスクをすべて処理。
    - 例: `Promise.then()` / `catch()` / `finally()` / `await` の後処理。
    - **優先度が高いため、すべて処理されるまで実行が続く。**
4. **ブラウザの描画更新**
    - 必要に応じて **レンダリング（画面描画の更新）** を実施。
5. **次のマクロタスクへ**
    - **マクロタスクキューの次のタスクを実行**。
    - **タスクがない場合は待機**。

---

## マイクロタスクとマクロタスクの優先度

- **マイクロタスク（Promise.then() など）** → マクロタスクが終わった直後に**すべて実行**。
- **マクロタスク（setTimeout など）** → マイクロタスクが終わった後に**次のループで実行**。