OmniAICreator/Qiita-1.07M huggingface dataset:
early return【良いコードの書き方】

## 概要
- early returnとは、関数内のif文の分岐先などにおいて、できるだけ早くreturnすること
- ネストが浅くなるので見た目が美しくなるよ
- 分岐先のロジックを追うとき、return以下は読まなくてよくなるよ

## コード例
### early returnしない場合
```UserForm.cs
class UserForm
{   
    bool VerifyUser(User user)
    {
        bool isVerified;
        if (user.HasBadStatus)
        {
            isVerified = false;
        }
        else
        {
            // 0以下のIDは存在しない
            if (user.ID <= 0)
            {
                isVerified = false;
            }
            else
            {
                isVerified = user.VerificationStatus;
            }
        }
        return isVerified;
    }
}
```
- ネストが比較的深く、可読性が低い。
- 変数isVerifiedがどこで変更されているのかわかりにくい。

### early returnした場合
```UserForm.cs
class UserForm
{
    bool VerifyUser(User user)
    {
        if (user.HasBadStatus)
        {
            return false;
        }

        // 0以下のIDは存在しない
        if (user.ID <= 0)
        {
            return false;
        }

        return user.VerificationStatus;
    }
}
```
- ネストが比較的浅く、可読性が高い。
- どのケースでfalseが返されるのかが明確である。また、そのようなケースにおいてreturn以下を追わなくてよい。

上記のサンプルコードではあまり恩恵が無いかも知れませんが、関数が長いほど・ロジックが複雑であるほど、early returnによる恩恵は大きいと思います。
（そもそも、そういう場合は関数を分割すべきという話はある）

## どんな時に使う？
- if文の分岐が原因でネストが深いとき
- ロジックが複雑すぎて、どのようなケースが存在するのか分かりにくいとき
- 異常系の処理をして関数を終了したいとき
- ただし、**early returnすることにより実行されなくなる処理がある場合は注意**
    - 意図しない状態に陥る可能性あり
    - early return時の状態に気を配ろう

## 記事について
本記事は新卒1年目の新米エンジニアが、良いコードの書き方について学んだことを記録したものです。
もし内容に不備などがあれば、ご指摘いただけるとありがたいです。
GitHub Actions で npm audit を定期的に実行する

# 概要
GitHub Actions で `npm audit` の定期実行を行い，パッケージの脆弱性を確認する．

# 詳細

## 用語の確認
GitHub Actions で登場する用語を簡単に整理する．詳細は[公式ドキュメント](https://docs.github.com/ja/actions/about-github-actions/understanding-github-actions#github-actions-%E3%81%AE%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88)などを参照されたい．

### ワークフロー
GitHub Actions で何かをしたいときに作成するもの．
- 以下の内容を YAML 形式で記述する．
  - いつ (イベント)
  - 何を (ジョブ，アクション)
  - どこで (ランナー)

### イベント
ワークフローを実行するきっかけ (トリガー) となるもの．
- 例えば，リポジトリにコミットがプッシュされたらワークフローを実行する，ということができる．
- もちろん，手動実行もイベントに含まれる．

### ジョブ
ワークフローで実行する具体的な処理．
- 実行できるのはシェルスクリプトまたはアクションである．

### アクション
ジョブで実行できる便利ツール．
- 例えば，GitHub からの Git リポジトリのプルをやってくれるアクションが用意されている．

### ランナー
ジョブの実行が行われるサーバー．
- OS として Ubuntu Linux，Microsoft Windows，macOS を選択できる．

## ワークフローの作成
リポジトリ内の `.github/workflows` ディレクトリに以下の YAML ファイルを作成する．

```yml:daily-npm-audit.yml
# npm auditを毎日18時(JST)に実行する
name: Daily npm audit

on:
  schedule:
    # Runs at every 9:00(UTC) of every day
    - cron: '0 9 * * *'

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

# Sets permissions of the GITHUB_TOKEN
permissions: {}

jobs:
  # Check job
  check:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Setup Node
        uses: actions/setup-node@v4
      - name: Check dependencies
        run: npm audit
```

:::note info
**ポイント**
- 決められた時刻にワークフローを実行するには `schedule` イベントを用いる．
- 実行時刻の設定は cron 構文で記述する．
- cron 構文で指定する時刻は協定世界時 (UTC) であることに注意．
:::

イベントトリガーに `workflow_dispatch` も設定しているため，作成したワークフローを GitHub 上で手動実行できる．

![ワークフローの手動実行](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478774/4c066ca2-6c56-cca5-c50d-2ab26464e6ac.png)

## ワークフロー実行の通知
ワークフロー実行の通知は https://github.com/settings/notifications で設定できる．基本的にはワークフローが失敗したときだけ通知させればよいだろう．

![ワークフロー実行の通知設定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478774/9189cf0a-7c62-a938-568c-299ba443a355.png)

本記事で作成したワークフローが失敗することは，`npm audit` で脆弱性が報告されたことを意味するので，通知が来たら `npm audit fix` などの対応を行うことになる．

# 参考文献
- [GitHub Actions を理解する - GitHub Docs](https://docs.github.com/ja/actions/about-github-actions/understanding-github-actions#github-actions-%E3%81%AE%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88)
- [ワークフローをトリガーするイベント - GitHub Docs](https://docs.github.com/ja/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#schedule)
- [GITHUB_TOKEN のアクセス許可の制御 - GitHub Docs](https://docs.github.com/ja/actions/writing-workflows/choosing-what-your-workflow-does/controlling-permissions-for-github_token)
- [ワークフロー実行の通知 - GitHub Docs](https://docs.github.com/ja/actions/monitoring-and-troubleshooting-workflows/monitoring-workflows/notifications-for-workflow-runs)
- [npm-audit | npm Docs](https://docs.npmjs.com/cli/v10/commands/npm-audit)
冬のお出かけのためのバッグやアクセサリーにおすすめ

<h2>バッグとアクセサリーのご紹介</h2>

冬が来ると、ワードローブの中で一番隅に詰まっていた厚い服がついに光を見ます。しかし、外出するときに暖かい服だけでは何か不足しているという感じがしませんか？ファッショナブルな冬のファッションの完成は、バッグやアクセサリーに依存します。果たして今回の冬、どんなアイテムを選ばなければ冬の天候の中でもスタイルを生かしておしゃれになれるのでしょうか？

<strong>冬のファッションの基本原則</strong>

冬のファッションの基本原則は1つだけです：暖かさとスタイルのバランス。どんなに素敵な服でも寒くて少し震えてしまったら、それは失敗したファッションでしょう？そして、あまりにも厚くて起きることもできないような服なら、外に出ることも嫌がるでしょう。このバランスをとる上で重要な役割を果たすのが、バッグやアクセサリーです。

![画像.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3925960/0f884523-d189-a208-0df3-fb5e669c1c5b.jpeg)

寒い天候には、バッグが単に持ち物を保管する役割だけではありません。バッグはファッションの仕上がりで、冬特有の濃い色と厚い素材が際立つようにしてくれる装飾でもあります。冬のバッグを選ぶときは、耐久性、保温性、スタイルを考慮する必要があります。

<strong>クラシックな冬袋おすすめ</strong>

冬にはトレンディに乗らないクラシックなバッグが大きな人気を集めています。特にレザー素材のトートバッグやウール素材のクロスバッグは、冬の衣装と相性があります。どこにもよく似合い、長く使っても飽きない利点があります。

![冬に最適なバッグ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3925960/f62378db-c1f8-25b9-bae6-85845a75f220.jpeg)

冬にはどうしても厚い服を着るので持ち物を軽く手に入れられるミニマルなバックパックや小さなショルダーバッグが便利です。また、雪や雨に濡れても水に強い素材を選ぶことが重要です。

1つのバッグでは、冬のファッションを完成させるのは難しいです。冬に必須のアクセサリーは保温性とスタイルを同時に生かす魔法のような役割をします。

暖かさを加えるショール

ショールは首を暖かく包み込むと同時にファッションポイントとしても使える万能アイテムです。適度にカラフルなショール一つで顔に生気を吹き込んでくれます。

手がシリミョン一日中不快感を感じやすいですが、革手袋やウール手袋は素敵でありながらも暖かく手を包みます。指先まで気にしてこそ真の冬ファッションマスターと言えるでしょうか？

![冬用のショール.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3925960/0b977fd8-320a-357d-8399-fa7baacca765.jpeg)


冬の寒い風を防いでくれる帽子は暖かさを保つだけでなく、スタイリッシュなポイントになります。特にベレモナニットビーニーは流行に乗らずにスタイリッシュなイメージを与えることができます。

冬の靴の選択ポイント

冬には、バッグやアクセサリーだけでなく、靴も重要です。寒い天候に滑らず暖かく足を保護できる靴が必須です。

![美しい冬.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3925960/2cf8a82e-5657-6929-b763-7f30c5ed980a.jpeg)


冬には特に滑りやすくなるため、アウトソールが厚いブーツが必要です。雪が積もった距離で安定して歩くために、ゴム製ソールを持つブーツを選ぶことをお勧めします。

冬のファッションを完成させるには、バッグとアクセサリーの調和が重要です。カラーと素材を調和に合わせて、落ち着きながらも高級感を与えます。

冬の野外活動に適したアイテム

雪の景色、スキー旅行など冬の野外活動を計画している場合は、耐久性の高いバックパックと防水機能を備えたアクセサリーを用意してください。重くなくても必要な持ち物をすべて手に入れることができなければなりませんから。

目を引く冬ポイントアイテム

冬季のファッションがやや単調になりやすいですが、小さなポイントアイテム一つでスタイルに大きな変化を与えることができます。例えば、赤い手袋やファーマフラーは人々の目を引くのに十分です。

ページサイト: [https://transform30.com/](https://transform30.com/)

結論：冬のファッションへの完璧な変身

冬といってファッションをあきらめる必要はありません。むしろ暖かい服やアクセサリーで自分だけの個性を表現できる季節ですね。バッグとアクセサリーの選択により、保温性とスタイルの両方を備えた冬のファッションを完成させてください。少し気にすると、誰よりも素敵な冬を過ごすことができます。
【初心者向け】APIを学ぶ前に知っておきたい！Web技術の専門用語を分かりやすく解説

# Webの世界を深く知るためのキーワード
前回は、Web技術がURLを通じて情報をやり取りする仕組みについて説明しました。今回は、その仕組みをより深く理解するために、知っておくと便利な専門用語について解説していきます。

### クライアントとホスト：Web通信の主役たち
**・クライアント:**

　・Webサイトを閲覧している**あなた**のことです。

　・パソコンやスマートフォンなど、Webサービスを利用する側のことを指します。

　・クライアントは、サーバーに対して情報を要求します。

**・ホスト:**

　・**Webサイトを提供しているサーバー**のことです。

　・クライアントからの要求に対して、情報を提供します。

　・ホストは、クライアントからのリクエストを待ち受け、適切なレスポンスを返します。



![セクション２－３　Web技術の専門用語　スライド2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3923801/6e8f73e8-b747-c65f-9912-48a6762128dd.png)

**PC（クライアント）とサーバー（ホスト）との関係図**


### **リクエストとレスポンス：情報がやり取りされる仕組み**
**・リクエスト:**

　・クライアントがサーバーに対して、特定の情報を要求することです。

　・例えば、あなたが「https://www.example.com」というURLを入力すると、そのWebページの情報を要求するリクエストがサーバーに送られます。

**・レスポンス:**

　・サーバーがクライアントのリクエストに対して、応答として返す情報（レスポンス）のことです。

　・リクエストされた内容に応じて、WebページのHTMLデータ、画像データ、またはエラーメッセージなどが返されます。


![セクション２－３　Web技術の専門用語　スライド１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3923801/6bc11411-dc1f-aa4a-d93c-5406b121b4d5.png)

### **必ず返ってくるレスポンス**
重要なポイントとして、**リクエストを送ると、必ずレスポンスが返ってくる**ということを覚えておきましょう。

　**・正常なレスポンス**: 要求した情報が正しく見つかり、Webページが表示されます。

　**・エラーレスポンス**: 要求した情報が見つからない場合や、サーバーに問題がある場合など、エラーを示す情報が返されます。例えば、「404 Not Found」は、要求されたページが見つからなかったことを意味します。

例えば、japan.jp/tokyo**u**を表示して！というリクエストをサーバーに送ると、ホスト側でjapan.jp/tokyo**u**の**u**という誤りがあるため、そのページは存在しないという「404 Not Found」をクライアントにレスポンスが返ってくることとなります。
なので、レスポンスは必ず返ってきますが、ページがきちんと表示されるかどうかは、正しいリクエストができているかによります。


![(セクション２－３　Web技術の専門用語　スライド3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3923801/5d9627b3-94a3-a381-c449-af734e8916e4.png)

**リクエストの内容が誤りのため、エラーレスポンスが返ってくる例**
まとめ
今回は、Web技術における基本的な専門用語である「クライアント」「ホスト」「リクエスト」「レスポンス」について解説しました。これらの用語を理解することで、Webの仕組みをより深く理解することができます。

**・クライアント:** Webサービスを利用する側

**・ホスト:** Webサービスを提供する側

**・リクエスト:** クライアントがサーバーに送る要求

**・レスポンス:** サーバーがクライアントに返す応答

これらの用語は、今後Web技術を学ぶ上で頻繁に出てくるので、しっかりと覚えておきましょう。



### **ここでお知らせ！**
APIに興味がある初心者の方へ、基礎から実際のビジネス活用事例まで分かりやすく解説した講座です！今なら、このページから1か月限定で94％オフクーポンを利用できます。今すぐAPIの知識を深め、ビジネスの幅を広げる一歩を踏み出しましょう。クーポンがなくなる前にお見逃しなく！


クーポンコードはこちら：NOTEAPI202410

https://www.udemy.com/course/oshiro_002/?couponCode=NOTEAPI202410

Udemyは購入後30日以内であれば返金可能
上記講座はUdemyで受講することができ、Udemyでは受講コースに納得がいかない場合、購入後30日以内であれば返金可能となっています。

購入後に「思っていたものと違う」、「学びにならなかった」と感じた場合は、返金申請を出すことができます。

返金の詳細はUdemy公式ページのコースの返金方法をご参照ください。
【初心者向け】APIを学ぶ前に知っておきたい！Web技術の基礎知識を解説

# はじめに
皆さんは普段、インターネットで情報を探す際にURLを入力してWebサイトにアクセスしますよね。このシンプルな動作の裏側には、実はとても複雑な仕組みが隠されています。

APIを理解するために、WEB技術の基礎知識が必要になるため、まずはWeb技術とはなにかという説明から始めます。


### Webの世界への入り口：URLとサーバーセレクタ
**Web技術とは、URLを通じて情報をやり取りする技術の総称**です。

例えば、あなたが「猫の画像」と検索して可愛い猫の写真を見つける時、あなたのデバイス（パソコンやスマートフォン）から検索エンジン（GoogleやYahoo!など）に「猫の画像」というリクエストが送られます。検索エンジンは、そのリクエストに基づいて、膨大なデータの中から猫の画像を探し出し、あなたのデバイスに表示するための情報を返してくれます。



![「猫の画像」と検索する.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3923801/72e67f1f-465c-b6f0-46b8-1733d49dddc8.png)
**「猫の画像」と検索したときのやり取り**

この情報を送受信する役割を担っているのがサーバーです。サーバーには、検索エンジンだけでなく、ブログサイトやオンラインショップなど、様々な種類のWebサービスを提供するものが存在します。



### サーバーの種類：Webサーバー、ファイルサーバー、そしてAPIサーバー
・サーバーには、大きく分けて以下の3つの種類があります。

**１　Webサーバー:**

・Webページを表示するためのサーバーです。


・私たちが普段利用するほとんどのウェブサイトは、このWebサーバーによって提供されています。

**２　ファイルサーバー:**

・ファイルの保存や共有を行うためのサーバーです。

・音楽や動画などの大きなファイルをダウンロードする際に利用されます。

**３　APIサーバー:**
・APIと呼ばれるプログラムのインターフェースを提供するサーバーです。

・APIを利用することで、他のWebサービスやアプリケーションと連携し、より高度な機能を実現することができます。

これらのサーバーは状況に応じてサーバーが変化するというところを覚えておきましょう。

### **APIとは？APIサーバーの役割**

**APIとは、Application Programming Interfaceの略**で、アプリケーション同士が相互に通信するための仕組みです。

例えば、天気予報アプリで現在の天気を表示する場合、アプリは独自に天気データを収集するのではなく、気象庁などの外部の天気情報提供サービスのAPIを利用して、リアルタイムの天気データを取得します。

APIサーバーは、このAPIを提供する役割を担っています。企業や団体は、自社のサービスの機能を外部に公開するため、APIサーバーを構築し、APIを提供することがあります。


# **まとめ：Web技術の基礎知識**
今回は、Web技術の基礎となるURL、サーバー、APIについて解説しました。

**・URL: インターネット上のリソース（Webページなど）を一意に識別するためのアドレス**

**・サーバー: 情報を保存し、クライアント（パソコンなど）からのリクエストに応答するコンピュータ**

**・API: アプリケーション同士が相互に通信するための仕組み**

**・APIサーバー: APIを提供するサーバー**

これらの知識は、Webサイトの制作やWebアプリケーションの開発、さらにはIT業界で働く上で、非常に重要な基礎知識となりますので覚えておくと役に立つと思います。

### **ここでお知らせ！**
APIに興味がある初心者の方へ、**基礎から実際のビジネス活用事例まで分かりやすく解説した講座**です！今なら、このページから1か月限定で94％オフクーポンを利用できます。今すぐAPIの知識を深め、ビジネスの幅を広げる一歩を踏み出しましょう。クーポンがなくなる前にお見逃しなく！


**クーポンコードはこちら：NOTEAPI202410**

https://www.udemy.com/course/oshiro_002/?couponCode=NOTEAPI202410

**Udemyは購入後30日以内であれば返金可能**
上記講座はUdemyで受講することができ、Udemyでは受講コースに納得がいかない場合、購入後30日以内であれば返金可能となっています。

購入後に「思っていたものと違う」、「学びにならなかった」と感じた場合は、返金申請を出すことができます。

返金の詳細はUdemy公式ページのコースの返金方法をご参照ください。
【Python】数値が混在した文字列のリストを自然な順序でソートする

# はじめに

Pythonでファイル名のリストなどを通常のソートを使って整列すると以下のようになってしまいます。

```python:サンプルコード
file_list = ["file_9","file_12","file_40","file_29","file_3"]

print("ソート前：", file_list)
file_list = sorted(file_list)
print("ソート後：", file_list)

```
```:実行結果
ソート前： ['file_9', 'file_12', 'file_40', 'file_29', 'file_3']
ソート後： ['file_12', 'file_29', 'file_3', 'file_40', 'file_9']  <-- 意図しない整列

```


それを解消するための関数を作ります。

# 実装

reモジュールを使って実装します。

```python:
import re

def natural_sort(text):
    return [int(c) if c.isdigit() else c for c in re.split(r'(\d+)', text)]
    
```


# 実行例

```python:サンプルコード

import re

def natural_sort(text):
    return [int(c) if c.isdigit() else c for c in re.split(r'(\d+)', text)]
    
file_list = ["file_9","file_12","file_40","file_29","file_3"]

print("ソート前：", file_list)
file_list = sorted(file_list)
print("改良前：", file_list)
file_list = sorted(file_list, key=natural_sort)
print("改良後：", file_list)

```
```:実行結果
ソート前： ['file_9', 'file_12', 'file_40', 'file_29', 'file_3']
改良前： ['file_12', 'file_29', 'file_3', 'file_40', 'file_9']
改良後： ['file_3', 'file_9', 'file_12', 'file_29', 'file_40']

```

# おわりに
これでPythonを使ったファイル整理が捗りそうですね。
Flutter TextField以外の場所をタップしたときに自動的にキーボードを閉じる

# はじめに
TextField以外の場所をタップしたときに自動的にキーボードを閉じる動きはあらゆる場面で必要ですよね。
そのために汎用的に使えるクラスを作ってみました！

<blockquote class="twitter-tweet" data-media-max-width="560"><p lang="ja" dir="ltr">汎用的に使えるUnFocusクラスを作った <a href="https://t.co/mBRIQpDG9s">pic.twitter.com/mBRIQpDG9s</a></p>&mdash; kokogento (@gento34165638) <a href="https://twitter.com/gento34165638/status/1853383265606160464?ref_src=twsrc%5Etfw">November 4, 2024</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# `FocusScope`を使ってUnFocusクラスを作る

もう早速コピペを貼ります

```dart:lib/views/pages/widgets/un_focus.dart
import 'package:flutter/material.dart';


class UnFocus extends StatelessWidget {
  const UnFocus({
    super.key,
    required this.child,
  });

  final Widget child;
  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        // 現在のフォーカス情報を取得
        final currentScope = FocusScope.of(context);
        // hasPrimaryFocusがfalseで、かつhasFocusがtrueであれば、現在何らかのウィジェットがフォーカスを持っていると判定
        if (!currentScope.hasPrimaryFocus && currentScope.hasFocus) {
          // TextFieldなどに設定されているフォーカスが解除され、キーボードが閉じる
          currentScope.unfocus();
        }
      },
      child: child,
    );
  }
}
```

あとはフォームなのが存在するウィジェットを`UnFocus`でラップするとOK
最初に見せた動画の場合は`Scaffold`ごとラップしてます！

```dart
import 'package:h_calender/views/pages/widgets/un_focus.dart';

class DayPage extends ConsumerWidget {
  const DayPage({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return UnFocus(
      child: Scaffold(
          appBar: AppBar(
            title: const Text('記録しよう'),
          ),
          body: ListView(
            padding: const EdgeInsets.symmetric(horizontal: 16),
            children: const [
              _TitleField(),
              SizedBox(height: 24),
              _MemoField(),
              SizedBox(height: 24),
              _SubmitButton(),
            ],
          )),
    );
  }
}
```
Qiitaはじめました

## 自己紹介
はじめまして。
地方の国公立の理系大学生4年の yamaya です。主に、web アプリケーションを開発しています。また、地方のベンチャー企業で開発をしています。最近は、Go でバックエンド開発を行っています。

## 目的
主にアウトプットによる知識の定着や共有を目的に始めました。web 系の就活の経験談や後輩の学生エンジニアなど少しでも経験を伝えられたなと思っています。それ以外にも興味を持ったことについて書こうと思っています。

## スキル
- JavaScript
- TypeScript
- PHP
- Go
で主に開発をしています。

## さいごに
更新頑張ります。よろしくお願いします！
非同期ランタイムのメリット


最近の言語の多くにはasync/awaitを実現する非同期ランタイムが実装されているが、
非同期ランタイムには非同期それ自体以外のメリットがあるという話。

## 非同期ランタイム未使用時にありがちなこと

1. Windowライブラリを用いたプログラミングをおこなう際イベントループとしてそのライブラリが持つイベントループ関数を用いる必要が有る。
2. イベントループでWindowイベント（redraw, resize, close, マウス・キーボードイベント等）を受取りそれに応じた処理を記述する。
3. アプリの仕様上他のイベント（ファイル、ネットワークイベント等）を受けたくなるがWindowライブラリのイベントループでは他のイベント受け取ることがなかなか困難。

## イベントソース統合FWとしての非同期ランタイム

非同期ランタイムは通常「非同期処理を実現する仕組み」として認識されているが、アプリケーションを作成する上では「イベントソースを統合するFW」という側面が非常に有用となる。

例えば上記の事例であれば、Windowライブラリが非同期ランタイムに対応していればファイルやネットワークイベントについてはもともと非同期ライブラリが対応しておりウインドウイベントとその他イベントを統合的に扱うことが可能となる。

## 余談：Qtの話

Qtはそれ自体が「イベントソース統合FW」とみなすことができsignal/slotを用いて各種イベントを統合的に扱うことができる。
Stable Diffusion(SDXL)で階層マージ

## 1. はじめに

Animagine XL 3.1で「satin」(サテン)が効かず、satinyやsateenもだめで、いろいろな2次元系モデルを試したところ、blue_pencil-XL v6.0.0では出力できました。しかし、blue_pencil-XL v6.0.0で普段のプロンプトだと慣れた絵柄と異なるため、初めてマージモデルに挑戦しました。
Stable Diffusion webUI(Automatic1111)で通常マージを行ったところ、出力結果がいまいちだったので、10分で諦めて、沼と言われている階層マージを行いました。

## 2. 階層マージ操作方法(説明超はしょり)

## 2.1. 拡張機能SuperMergerインストール

1. 拡張機能SuperMergerをwebUIにインストール
2. UIリロードしてSuperMergerタブに移動

参考：
Stable Diffusionの拡張機能『SuperMerger』の使い方！階層マージを効率化させる方法！
https://romptn.com/article/19894
Stable Diffusionの「階層マージ」とは？やり方や影響について詳しく解説
https://romptn.com/article/28071

## 2.2. 階層マージ

1. Model Aを選択(今回はAnimagine XL 3.1)
2. Model Bを選択(今回はblue_pencil-XL v6.0.0)
3. Weight sumを選択したまま
4. normalを選択したまま
5. use MBWをチェック(これに気づかず時間をだいぶ無駄にしたその1)
6. safetensorsをチェックしたまま
7. option(gamma) 0.3のまま
8. Block TypeのXLを選択
9. Select presetでALL_Aを選択(全ての階層がModel Aの状態)
10. 20階層(SDXLの場合)のパタメータを0～1の範囲で設定する(Base、IN00～IN08、M00、OUT00～08。U-NETの各階層)
11. ↑Set alphaをクリック(これに気づかず時間をだいぶ無駄にしたその2)
12. Merge&Genをクリック。マージモデルを作成して、txt2imgタブの設定が使われて生成される。(一部使われない)
13. そのままのマージモデルでまた生成する場合にはGenをクリック
14. パラメータを変更する場合は10.に戻る
15. 保存する場合はSave current merge(fp16 only)をクリック

## 3. 階層マージモデル設定その1

![01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534247/68b48325-4842-44b6-b8f6-307da0b86e1d.jpeg)


## 4. 階層マージモデル設定その2(ちちぷいに今日投稿した画像で使用したモデル)

![02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534247/c9c3f511-a77c-b7c1-fc5b-7c027b27c156.jpeg)

他の情報は[投稿画像](https://www.chichi-pui.com/posts/9f4d6c9c-6138-4e02-9f03-ca40f6fe8ba4/)のメタデータにあります。

ナースキャップのマークをなくしたかったけど、何も設定しないと赤十字が出て、国際的によろしくなく、それを抑制したら白十字、十字を抑制したらハートマーク、ハートマークも抑制したらわけのわからないマークが出て、今回はマークを出さないようにできなかったので、諦めてハートマークを指定しています。目立たないように銀色で。

## 5. パラメータの決定方法

手探り。値をちょっと変えて生成しての繰り返し。
今回は、Animagine XL 3.1の顔で、サテン生地を出せるようにしたかったので、顔に影響があったところはModel A側(0近く)にして、サテンの光沢とドレープが出るようにModel B側(1近く)にして、値を変えても絵柄にあまり影響がなかった値はできるだけ0方面に近づけました。

## 6. 参考画像

同一Seed、同一プロンプト。
顔や光沢の比較用。細部は失敗している。

(1) Animagine XL 3.1
　　サテンは出ない。

![00004-3144629972.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534247/269e9a84-8521-60c1-033b-2b2a2ffa33e4.png)

(2) blue_pencil-XL v6.0.0
　　サテンっぽいのが出る。

![00005-3144629972.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534247/0a353d34-1fd9-a4dd-e4c6-24cf8a442659.png)

(3) 上記の階層マージモデルその1
　　サテンに少し近づいた。顔はAnimagine風。

![00006-3144629972.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534247/42214183-6db6-ac07-65b5-ef98a2c59315.png)

(4) 上記の階層マージモデルその2
　　サテンっぽくなった。

![00007-3144629972.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534247/3de0e0df-f292-a550-55e1-9c78b6373ab8.png)
icaclsコマンドって何?

今の現場でicaclsコマンドを使う機会がありましたが、よく知らなかったので調べてみました。


## `icacls`コマンドとは？
icaclsコマンドとは、Windowsでファイルやフォルダーのアクセス制御リスト（ACL）を管理するためのコマンドです。

アクセス制御リスト(Access Control List、ACL)は、ユーザーやグループに対するファイルやフォルダーへのアクセス権限を指定するリストです。具体的には、「読み取り」「書き込み」「実行」などの権限をユーザーごとに設定することが可能です。

つまり、ファイルやフォルダのアクセス権を変更したりする際に使用するコマンドのようです。


## `icacls`コマンドの基本構文
### アクセス権の表示
ファイルやフォルダーに設定されているアクセス権を確認できます
```
icacls <ファイル名またはフォルダ名>
```

表示されるアクセス権には様々な種類がありますが、主に使われるものを紹介します。

+ **F**：フルアクセス権限
+ **RX**：読み取りと実行権限
+ **R**：読み取り権限
+ **W**：書き込み権限


### アクセス権の設定
特定のユーザーにアクセス権を付与できます
```
icacls <ファイル名またはフォルダ名> /grant <ユーザー>:<アクセス権>
```
  + 例：ユーザ名`user1`に`test.txt`へのフルアクセスコントロール権限(F)を付与する場合
```
icacls test.txt /grant user1:F
```

### アクセス権の削除
特定のユーザーのアクセス権を削除できます
```
icacls <ファイル名またはフォルダ名> /remove <ユーザー>
```
  + 例：ユーザ名`user1`の`test.txt`へのアクセス権限を削除する場合
```
icacls test.txt /remove user1
```

::: note info
`/remove`オプションは対象のアクセス権をすべて削除してしまいます。
仮に読み取り権限(R)だけを拒否したい場合は`/deny`オプションを利用し、次のように使用します。
```
icacls test.txt /deny user1:R
```
:::

## 継承権限
Windowsのファイルシステムには、ACLの権限設定を親フォルダから子フォルダに自動的に適用し、管理を効率化する「継承権限」という仕組みがあります。
`icacls`コマンドと`/inheritance`オプションを使って継承権限の設定を行うことができます。

### 継承の有効化
親フォルダからの継承を有効にし、子フォルダやファイルは親フォルダの権限を継承します。
```
icacls <フォルダ名> /inheritance:e
```
  + 例：`Projects`フォルダ(`C:\Projects`)に`User1`のアクセス権を設定し、権限をそのフォルダ内の子フォルダやファイルに継承させたい場合
```
icacls "C:\Projects" /grant User1:F
icacls "C:\Projects" /inheritance:e
```

### 継承の無効化
親フォルダからの継承を無効にし、子フォルダやファイルは親フォルダの権限を継承しなくなります。継承されていた権限は削除されます。
```
icacls <フォルダ名> /inheritance:r
```
  + 例：`Projects`フォルダの子フォルダ`Subfolder`(`C:\Projects\Subfolder`)の権限を無効化し、`User1`にのみ独自の読み取り権限を与える場合
```
icacls "C:\Projects\Subfolder" /inheritance:r
icacls "C:\Projects\Subfolder" /grant User1:R
```

### 継承の範囲
`icacls`コマンドを使ってアクセス権を表示させると、「継承の範囲」を示すコードが表示されます。
それらはそれぞれ以下のような意味を持ちます。

+ **(I)**:親フォルダから継承されたアクセス権であることを示します
+ **(OI)**：このフォルダ内のファイルにのみ継承された権限が適用され、フォルダや子フォルダには適用されません
+ **(CI)**：このフォルダ内の子ファイルにのみ継承された権限が適用され、フォルダ内のファイルには適用されません
+ **(IO)**：継承のみの設定で、このフォルダ自体には権限が適用されず、子フォルダやフォルダ内のファイルにのみ適用されます

## まとめ
`icacls`コマンドを使うことでファイルやフォルダの権限を効率的に管理できるようです。

## 参考資料

https://learn.microsoft.com/ja-jp/windows-server/administration/windows-commands/icacls

https://wa3.i-3-i.info/word11206.html
【python3】辞書のkeyをソートして辞書のkeyを昇順に表示する

# はじめに
辞書のkeyを昇順で並び替える問題に取り込みました

## 問題
>n人の野球選手の名前が背番号と一緒に入力されます。
>各選手の背番号と名前を、背番号の数字の小さい順に並び替えて出力してください。
>ただし、同じ背番号の選手は存在しないものとします。

という問題です。

## 実装したコード
実装したコードは下記の通りです

```python3
# 数値入力
n = int(input())
# Dictionaryの定義
dict1 = {}
# listの定義
list1 = []
# 標準入力からdict1にkeyとvalueを入れる
for i in range(n):
    key,value = input().split(' ')
    dict1[key] = value
# dict1のkeyをlist1に入れる
for number in dict1.keys():
    list1.append(int(number))
# list1を昇順に並び替える
list1.sort()

print("----結果----")
# listの要素を取り出し、dict1のkeyと合わせて出力
for num in list1:
    print(str(num) + " " + dict1[str(num)] )

```

## 実行結果
実行結果は下記の通りです

![gazou1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1055346/67f85df9-3e7e-69be-4141-1621b5a3d345.jpeg)

## 追記
辞書を使わない方法は下記です

```python3
n = int(input())
b = [list(map(str, input().split())) for l in range(n)]

b.sort(key = lambda pair : int(pair[0]))
print("----結果----")
for i in range(n):
    print(b[i][0], b[i][1])
```

# 最後に
プログラミングコンテスト課題の問題に挑戦しました。
ローカル動作確認でなぜかcookie保存されないな。。というときに疑うこと

```
Cookies marked with SameSite=None must also be marked with Secure to allow setting them in a cross-site context. This behavior protects user data from being sent over an insecure connection.
```

SameSite=Noneのset-cookieはsecureをtrueにしないとダメ。

![スクリーンショット 2024-11-04 18.40.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441085/a9c38948-e5b3-f028-b5ce-f95376f739d6.png)

対処法として、httpsにするなり、SameSite=Lax or SameSite=Strict にする。
teeコマンドの応用 exit codeを標準出力に伝播させる

## はじめに

スクリプトやコマンドの実行結果をログファイルに残しつつ､標準出力でリアルタイムで確認したい場合があります｡そんな時に便利なのが`tee`コマンドです｡  
今回は`tee`コマンドの応用として､エラーハンドリングを考慮した応用的な使い方を紹介します｡

結論を読みたい方は[👇🏼こちら](#exit-codeの伝播)

## teeコマンドの基本的な使い方

```bash
command | tee result.log
```

`command`の実行結果が標準出力に表示されると同時に､`result.log`にも保存されます｡

### エラー出力もログに含める

基本的な使い方では標準出力のみがログに記録されますが､エラー出力も含めたい場合は､`2>&1`を使用します｡

```bash
command 2>&1 | tee result.log
```

## exit codeの伝播

パイプライン処理では､デフォルトで**最後のコマンドの終了コードのみが返されます｡**  
つまり､`command`が失敗しても`tee`が成功すれば､パイプライン全体は成功として扱われてしまうのです｡

これを防ぐには`set -o pipefail`を使用します:

```bash
set -o pipefail; command 2>&1 | tee result.log
```

`pipefail`を設定することで､パイプラインの中で**最後に失敗したコマンドの終了コード**が返されるようになります｡

### 検証してみる

```bash
# パイプラインで終了コードをセットする
$ ( set -o pipefail; exit 1 | exit 2 | exit 3 | cat )
# 直前の終了コードを出力
$ echo $?
# 最後に失敗したコマンドの終了コードが返される
3
```

> コメントでわかりやすい検証コードを頂きました｡ありがとうございます!

## あとがき

最近ではリッチなターミナルアプリも流行ってきており､exit codeを検出してくれる物もありますよね｡この方法はそういったターミナルにもよくマッチすると思います｡  
と言うのも､私はWarpと言うターミナルアプリを最近使い始めたり､シェルスクリプトをちゃんと学び始めたりして､この方法に辿り着きました｡

シェルスクリプトでは直接ログを書くことが多いので標準出力に出す機会は少ないとは思いますが､一応この方法はシェルスクリプト内でも動きます｡
シェルスクリプトの場合はワンライナーにしなくて良いので､最初の方の行に`set -o pipefail`を書くと良いですね｡
Kajabiで作成した商品画面のカラムをjsで共通化する

# 前提
- CMSとしてKajabiを利用している（Kajabiアカウント及び編集権限がある）
- jsの置き場所としてのサーバ環境がある

# 要件
Kajabiにおける多くのテーマで、商品のトップページ（Product）と下層ページ（Post）はそれぞれ個別に画面レイアウトを作る必要がある

が、右カラムのサイドメニュー等、**同じ商品で共通化したい要素が存在する場合**に個別に編集しなければならないのは手間なので、JavaScriptを使い共通化したい要素をトップページから取得し、下層ページにも同じ要素を捩じ込む

# 手順
テーマは各画面htmlにjsで適応されている為、scriptタグをチェックし、該当する場合のみ同商品のProduct画面をfetchし取得したカラム要素をPostページに表示する

## 1. JavaScript

```javascript:JavaScript
// 画面ロード時
window.addEventListener('DOMContentLoaded', function() {

	// ページのすべての<script>タグを取得
	const scripts = Array.from(document.scripts);

	// 右カラムを共通化したいテーマ（ターゲット）
	const targetThemes = [
		"Premier Product",
		"Prosper",
		"Creative",
		"Premier 1654788471",
		"Prosper 1654788768"
	];

	// ターゲットとなるテーマが含まれるかどうかを確認
	const isTargetTheme = scripts.some(script => 
		script.textContent.includes("Kajabi.theme = {") && 
		targetThemes.some(theme => script.textContent.includes(`activeThemeName: "${theme}"`))
	);

	// 該当テーマのPostページ
	if (isTargetTheme && window.location.pathname.includes('/posts/')) {

		// 現在のURL
		const currentUrl = location.href;

		// "/posts/"の直前までの部分
		const productUrl = currentUrl.split('/posts/')[0];

		fetch(productUrl)
		.then(response => {
			if (!response.ok) {
				throw new Error('Network response was not ok');
			}
			return response.text();
		})
		.then(html => {

			// HTMLをDOMに変換
			const parser = new DOMParser();
			const doc = parser.parseFromString(html, 'text/html');

			// 右カラムに必要な要素
			const banners = doc.querySelectorAll('.section__sidebar .panel');
			const container = document.querySelector('.section__sidebar.col-lg-4');
			banners.forEach((banner, index) => {
				if (index === 0) return; //最初の要素「hoge of hoge本を視聴済み」インジケーターをスキップ
				container.insertAdjacentHTML('beforeend', banner.outerHTML);
			});
		})
		.catch(error => {
			console.error('Error fetching the URL:', error);
		});
	}
});
```
## 2. 該当テーマを使用したProduct、Post画面の設定

Product Sidebarの内容を作り、`Show Sidebar`を有効 ✅ にしておく

![スクリーンショット 2024-11-04 17.56.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3472245/041c73db-4ab1-bbd7-41aa-7a87865e9638.png)

Post Sidebarでは、**Product Sidebarと共通化したい部分を作らず`Show Sidebar`を有効 ✅ にしておく**

![スクリーンショット 2024-11-04 17.54.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3472245/cbe06bcd-ccff-0cba-f348-7178ddf2e810.png)

## 3. Kajabiに外部.jsファイル読み込み設定

先述.jsファイルをKajabiの設定（Settings > Site Details）画面のPage scriptsに設定し読み込む

![スクリーンショット 2024-11-04 17.41.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3472245/d7af9e80-77f2-ef71-d004-878d8fceda0f.png)

以上でPreviewすると、Product Sidebarの内容がPost画面にも反映されている事が確認出来る
【MySQL】create_date BETWEEN と DATE(create_date) BETWEENの違いは？

# 概要
SQL文で日付指定する時、以下にはどのような違いがあるでしょうか？

```sql
DATE(create_date) BETWEEN '2024-10-01' AND '2024-10-31'
```

```sql
create_date BETWEEN '2024-10-01' AND '2024-10-31'
```

# `DATE`関数を使用して正しく指定する

`DATE`関数を使用していない前者の場合、実は「10月31日」は取得されません。
`DATE`関数を使用すると「10月31日」の分まで取得されます。

なぜかというと、`DATE(create_date)`は、`create_date`の日時部分を切り捨てて日付部分だけを取得するためです。

MySQLドキュメントにも以下のように記載されていますね。

https://dev.mysql.com/doc/refman/8.0/ja/date-and-time-functions.html#function_date

```sql
mysql> SELECT DATE('2003-12-31 01:02:03');
        -> '2003-12-31'
```

対して、`DATE`関数を使用しない場合は、時間部分も含めて比較されます。
`BETWEEN '2024-10-01' AND '2024-10-31'`は、`2024-10-01 00:00:00`から`2024-10-31 00:00:00`までの範囲を意味します。したがって、10月31日の分は取得されない、というわけです。

ちょっとしたところで大きなミスになりかねないので要注意ですね。

## 参考

https://zenn.dev/shuhei_takada/articles/d1444e409330ad
Swiftで作成したゲームに広告を入れる

## 事前準備

[Google AdMob](https://admob.google.com/intl/ja/home/)に登録


## 広告ユニットの作成
種類はバナー広告にしました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3760274/adb56e74-08a5-9717-0fa2-154f1188f583.png)


## 実装
Swift Package Manager (SPM) でGoogleMobileAdsライブラリを使うための準備
　
Xcode→File→Add Packages...を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3760274/561806f9-a054-9ce7-1f0c-e943519bfa93.png)
　
下記を検索して、Add Package
```
https://github.com/googleads/swift-package-manager-google-mobile-ads
```
　
プロジェクトのTARGETS→Build PhasesからGoogleMobileAdsを追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3760274/6b931386-4269-9844-4700-35c1b2a89d98.png)

AppDelegateに下記の２箇所を追加
``` Swift
import GoogleMobileAds
```
``` Swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    
    // Google Mobile Ads SDKの初期化
    GADMobileAds.sharedInstance().start(completionHandler: nil)
    
    return true
}
```

infoタブでGADApplicationIdentifier：ca-app-pub-XXXX...を追加
**AdMobのアプリIDを設定する。**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3760274/d71d3cc7-c475-daa1-9e0c-c43648971d6b.png)
　
次に、ViewControllerに広告表示をするコードを追加
GADBannerViewを作成する→[参考](https://developers.google.com/admob/ios/banner?hl=ja)
下記コードから必要な部分を入れてください。参考ページとは少し違います。
**指定するIDはデモ用IDにします。**　※リリース時には実際の広告ユニットIDに置き換える。
``` Swift
import GoogleMobileAds
import UIKit

class ViewController: UIViewController {

  var bannerView: GADBannerView!

  override func viewDidLoad() {
    super.viewDidLoad()
    
    let viewWidth = view.frame.inset(by: view.safeAreaInsets).width

    let adaptiveSize = GADCurrentOrientationAnchoredAdaptiveBannerAdSizeWithWidth(viewWidth)
    bannerView = GADBannerView(adSize: adaptiveSize)

    addBannerViewToView(bannerView)
  }

    func addBannerViewToView(_ bannerView: GADBannerView) {
        bannerView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(bannerView)
        // バナーを画面の下部に配置
        NSLayoutConstraint.activate([
            bannerView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
            bannerView.centerXAnchor.constraint(equalTo: view.centerXAnchor)
        ])
    }
   
}
```
下記だとスワイプの場所に隙間ができるのですが、
最下部に広告を配置すると、操作感が悪くなり審査に通りにくいらしいのでそのままにしました。
``` Swift
equalTo: view.safeAreaLayoutGuide.bottomAnchor
```
　
## 広告表示の確認
画面下部にバナー広告が表示されている。OK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3760274/7d5c8ca1-0d96-22a2-633a-de2e9b9c5152.png)
LaravelでIBM iに接続（２）【データ取得】

## はじめに

Laravelは、データベース処理を自動化する仕組みが含まれているPHPフレームワークのひとつです。

前回は、Laravelの拡張パッケージである[DB2 for IBM iSeries Laravel Driver](https://github.com/BWICompanies/db2-driver)のインストール方法など、環境構築に関する手順をご紹介しました。

今回は、データを取得する方法について紹介します。

## ルートの定義

まず、必要なルートを定義します。

ルートはLaravelアプリケーションで特定のURLリクエストをハンドリングするポイントです。「/routes/web.php」に定義します。

以下の例では、「/db2-page」というURLへのGETリクエストをハンドリングします。

```php:web.php

use App\Http\Controllers\Db2Controller;

Route::get('/db2-page', [Db2Controller::class, 'index']);

```

## コントローラの作成

次に、必要なコントローラを作成します。

コントローラは、特定のリクエストを処理し、対応するビューを生成するためのロジックを含むファイルです。

ここに、IBM i（DB2）に接続してクエリを実行する処理を記述します。

以下のコマンドを使用してコントローラを生成します。

`php artisan make:controller Db2Controller`

生成された「/app/Http/Controllers/Db2Controller.php」を編集し、先ほど定義したルートのためのメソッドを追加します。

```php:Db2Controller.php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\DB;

class Db2Controller extends Controller
{
    public function index()
    {
        // IBM i（DB2）に接続してクエリを実行する
        $customers = DB::select('select * from QIWS.QCUSTCDT');

        // クエリ結果をビューに渡す
        return view('db2test', ['customers' => $customers]);
    }
}

```

## ビューの作成

次に、ビューを作成します。

ビューは実際にブラウザ上に表示されるHTMLコンテンツです。Bladeテンプレートエンジンを使用します。
デフォルトでは、ビューは「/resources/views」ディレクトリに保存されています。

新しいビューのファイル「/resources/views/db2_page.blade.php」を作成します。

```php:db2_page.blade.php

<!DOCTYPE html>
<html>
<head>
    <title>DB2 Page</title>
</head>
<body>
    <h1>QIWS/QCUSTCDT CITY List</h1>

    @foreach ($customers as $customer)
        <p>{{ $customer->CITY }}</p>
    @endforeach
</body>
</html>

```

## 動作確認

ローカル開発サーバを起動して、正しく処理が実行されるかを確認します。

`php artisan serve`

「http://[IPアドレス]:[ポート]/db2-page」にアクセスし、正しく処理が実行されていれば、以下のようにIBM iからデータを取得できます。
![connectIBMiLaravel2_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2962887/a98fec41-f2cf-70b5-3b22-40e550ffc78e.png)

ご参考になれば幸いです。最後までお読み頂きありがとうございます。
教師あり学習と教師なし学習についてまとめてみました

**教師あり学習（Supervised Learning）**と**教師なし学習（Unsupervised Learning）**は、機械学習の主要な学習方法で、データに対する異なるアプローチを提供します。これらは、データにどのような情報が含まれているか、またその情報をどのように活用するかに応じて使い分けられます。以下、それぞれの特徴や適用例、メリット・デメリットについてまとめます。

---

## 1. 教師あり学習（Supervised Learning）

教師あり学習は、**ラベル付きデータ**を用いてモデルをトレーニングする方法です。トレーニングデータには、入力データとそれに対応する**正解ラベル（出力）**が含まれており、モデルはその対応関係を学習します。こうして学習したモデルは、新しいデータに対しても正確な予測を行うことを目的とします。

### 特徴
- **ラベル付きデータ**を使用して、入力と出力の関係を学習します。
- 主に分類（classification）や回帰（regression）の問題に利用されます。
- モデルの予測精度を確認しやすく、評価が行いやすい。

### 主なアルゴリズム
- **線形回帰**: 入力データと出力の間の線形関係を学習し、予測を行います。
- **ロジスティック回帰**: データを特定のカテゴリに分類するためのアルゴリズムです。
- **サポートベクターマシン（SVM）**: データの分離境界を見つけて、分類を行います。
- **決定木とランダムフォレスト**: 入力データを木構造に基づいて分類・予測します。
- **ニューラルネットワーク**: 多層のネットワーク構造を持ち、複雑なデータを学習します。

### 適用例
- **スパムメール検出**: メールの内容を学習し、「スパムメール」か「通常メール」かを分類。
- **画像認識**: ラベル付きの画像データを用いて、犬や猫といったオブジェクトの分類を行う。
- **住宅価格予測**: 家の広さや立地条件などのデータをもとに、価格を予測する。

### メリット
- 正確なラベルがあるため、モデルの精度が高く、結果が明確で信頼性があります。
- モデルのパフォーマンスが評価しやすく、最適化がしやすい。

### デメリット
- ラベル付きデータの準備が大変で、データ収集やラベル付けにコストがかかることがあります。
- ラベルが存在しない場合や、不適切なラベル付けの場合には、正確なモデルを構築するのが難しくなります。

---

## 2. 教師なし学習（Unsupervised Learning）

教師なし学習は、**ラベルのないデータ**を使用してパターンや構造を学習する方法です。データに対する明確なラベルが存在しないため、モデルはデータの分布や特徴からグループや構造を見つけ出します。教師なし学習は、データの構造を理解するためのツールとして用いられることが多いです。

### 特徴
- **ラベルなしデータ**を使用して、データ内のパターンや構造を発見します。
- 主にクラスタリング（clustering）や次元削減（dimensionality reduction）に利用されます。
- データをグループ化したり、データ間の関係を可視化することが目的です。

### 主なアルゴリズム
- **k-meansクラスタリング**: データを指定された数のクラスタ（グループ）に分けます。
- **主成分分析（PCA）**: データの次元を削減し、データのばらつきを最もよく表す軸を見つけます。
- **t-SNE**: 高次元データを低次元に変換し、データの構造を可視化するアルゴリズム。
- **階層型クラスタリング**: 階層構造でデータをクラスタリングし、データ間の類似度を反映します。
- **アソシエーション分析**: データ内のルールや関係性を見つけるために使用され、マーケットバスケット分析でよく利用されます。

### 適用例
- **顧客セグメンテーション**: 顧客を購入傾向や行動パターンに基づいてグループ化。
- **異常検知**: 取引データから正常なパターンを学習し、異常な取引を検出する。
- **画像の圧縮や分類**: 画像データの次元を削減し、パターンを見つけてグループ化。

### メリット
- ラベル付けが不要なため、データ収集のコストが低い。
- 未知のパターンや関係性を発見するのに適しており、データの理解が深まる。

### デメリット
- 正確なラベルがないため、モデルの評価や結果の解釈が難しい。
- 明確な目的がない場合や、誤った解釈を導く可能性がある。

---

## 3. 教師あり学習と教師なし学習の違い

| 特徴                 | 教師あり学習                                 | 教師なし学習                                 |
|----------------------|---------------------------------------------|---------------------------------------------|
| **データ**           | ラベル付きデータを使用                      | ラベルなしデータを使用                      |
| **目的**             | 予測や分類                                  | パターンの発見やデータ構造の把握            |
| **主なタスク**       | 分類・回帰                                  | クラスタリング・次元削減                    |
| **メリット**         | 精度が高く、評価が容易                      | ラベル付け不要、データ探索に適している      |
| **デメリット**       | ラベル付けのコストが高い                    | 結果の評価が難しく、解釈が複雑              |

---

## 4. まとめ

- **教師あり学習**は、正解ラベル付きデータでモデルを訓練し、未知のデータに対する予測や分類が可能です。メールのスパム検出や画像認識など、明確な目標があるタスクに向いています。
- **教師なし学習**は、ラベルなしのデータからパターンや構造を学習し、データのグループ化や特徴の発見を行います。顧客セグメンテーションや異常検知のような、データの理解が必要なケースに向いています。

機械学習の目的やデータの種類に応じて、教師あり学習と教師なし学習を使い分けることで、効果的な分析やモデル構築が可能になります。
なぜOAuthを利用したSSOって広範な権限が求められた？

# なぜ「サインイン」だけでなく、広範な権限が求められるのか？
OAuthを利用した認可の際に求められる権限は「最小限の情報」だけに限らず、場合によってはかなり広範な権限が求められることがあります。

たとえば、Twitterアカウントを使ってサインインする際に「ポストする権限」や「フォローする権限」などが含まれている場合があります。（いつもいやだけど。。。）

その理由は？

### アプリケーションの目的による要求
アプリケーションが提供したい機能によって、どのような権限が必要になるかが変わります。

例えば、Twitterの認証を利用しているアプリが、ユーザーに投稿を代行したり、ユーザーのタイムラインに特定のツイートを表示したりする場合は、「ツイートの投稿」「フォロー管理」などの権限が求められます。

### 利便性の向上
アプリケーションは、ユーザー体験を向上させるために追加の権限を要求することがあります。

例えば、ユーザーがTwitter上で頻繁にポストするアプリでは、アプリから直接ポストできる権限を与えることで、ユーザーがアプリ内で行う操作が便利になります。

### ビジネス上の理由
一部のアプリケーションはビジネスモデル上、ユーザーの広範なデータやアクション権限が必要になることがあります。

特定のアプリは、Twitterでユーザーの関心やエンゲージメントを測定し、サービスを提供しているケースもあります。

広範な権限があれば、それだけ多くのデータやアクションをアプリ側が管理できるため、ユーザーにサービスを提供しやすくなります。

# セキュリティリスクやプライバシーの侵害につながる可能性はないか？
特に、ユーザーとして「見たいだけ」の目的に対して過剰な権限が要求されると、悪質なサイトやアプリを見極めるのが難しく感じるかもしれません。

これについて、ユーザーができる対策と注意すべきポイントは？

### 必要な権限がどれかを見極める
信頼できるサイトやアプリであれば、サインインに必要な最小限の権限を要求します。

例えば、GoogleやTwitterを使ったサインインの場合、基本的に「メールアドレス」「名前」「プロフィール写真」など、ユーザーの識別に必要な情報のみが要求されます。

しかし、過剰な権限（例えば「投稿権限」や「フォロー管理権限」など）が含まれている場合は注意が必要です。

・必須権限の確認：多くの認可画面では、「必須」と「オプション」の区別が表示されることがあります。この違いを確認して、過剰に感じる権限には注意しましょう。

・「読み取り専用」の権限が基本：サインインに必要な権限は通常「読み取り専用」であることが多く、「書き込み権限」などが含まれていないか確認します。

### サイトやアプリが信頼できるかどうかを判断するポイント
悪質なサイトやアプリを見分けることは簡単ではありませんが、以下のポイントが参考になります。
（ここはユーザーにとって一番ムズいと思う。。。）

・アプリやサイトの提供者を確認：有名なサービスや企業が提供しているかどうかを確認しましょう。例えば、「Googleでログイン」「Twitterでサインイン」などのボタンは見た目が似たデザインで表示されますが、必ず公式の認可画面であることを確認します。OAuthの認可画面では、必ずそのサービスのドメイン（例：accounts.google.comなど）を確認してください。

・口コミやレビューを確認：アプリが提供されている場所（Google PlayやApp Store、公式ウェブサイトなど）で、他のユーザーの口コミや評価が参考になります。特にレビューに「過剰な権限を求められる」などのコメントがあれば、避ける方が安全です。

### サインイン後の権限を見直す方法
OAuthでアクセスを許可した後でも、サービスの設定から不要な権限を見直すことが可能です。

・各アカウントの「接続済みアプリ」ページ：GoogleやTwitterなどでは、アカウント設定内に「接続済みアプリ」や「アプリとセキュリティ」などのページがあります。ここで不要なアプリや過剰な権限を削除できます。

・許可を確認して都度更新：一度付与した権限も定期的に見直し、必要なくなったものは削除することをおすすめします。これにより、アカウントにアクセスできる範囲を常に最小限に抑えることができます。

### OAuthでのセキュリティリスクの低減策
・OpenID Connect（OIDC）の利用：多くのサインイン機能は、純粋に認証のみを行うプロトコル拡張であるOIDCを利用するケースが増えています。OIDCはユーザーの認証に特化しており、認証情報だけがやり取りされるため、余計な情報取得が発生しにくくなっています。

・サインイン専用のOAuthアカウントの利用：重要なSNSやメールアカウントとは別に、サインイン専用のGoogleアカウントなどを作成し、それを利用することで、不要なアクセスリスクを抑えることも一つの方法です。

# 参考サイト
https://www.proofpoint.com/jp/threat-reference/oauth

https://logmi.jp/tech/articles/325889
CodeWars オススメ問題 #10

# はじめに

個人的に好きなアルゴリズム学習サイト「CodeWars」の問題をシェア。

週1くらいのペースで、全10回を目指す予定。今回が第10回です！

:::note
CodeWarsはいいぞ！の紹介は[こちら](https://qiita.com/kohki_takatama/items/2ae2808b931e943262b8)

CodeWarsの始め方は[こちら](https://qiita.com/javacommons/items/7c473cda7825ab99e08c
)
:::

今回は（主観ですが）Rubyの特徴を活かせる問題です。

# オススメ問題

https://www.codewars.com/kata/576757b1df89ecf5bd00073b/typescript

### 問題

与えられた数値の「タワー」を作ります。

```
3 => [
  "  *  ",
  " *** ", 
  "*****"
]

6 => [
  "     *     ", 
  "    ***    ", 
  "   *****   ", 
  "  *******  ", 
  " ********* ", 
  "***********"
]
```

### 難易度
分類は 6kyu です。

アルゴリズム問題として手応えがあるレベル。

# オススメの回答
「評価が高い回答」の中から、学びの多い回答をピックアップしてご紹介。

:::note
<details><summary>丁寧な回答</summary>

```rb
export const towerBuilder = (nFloors: number): string[] => {
  let result = [];
  for (let i = 1; i <= nFloors; i++) {
    result.push(buildFloor(i, nFloors));
  }
  return result;
};

// build i'th floor for a tower of size n floors
function buildFloor(i: number, n: number): string {
  let middleSection = "*".repeat(2 * i - 1);
  let sideSection = " ".repeat(n - i);
  let floor = sideSection + middleSection + sideSection;
  return floor;
}
```

`buildFloor`関数が「それぞれの列」を作ります。

`2 * i - 1` / `n - 1`はそれぞれ、その列の`*`と` `の数を計算するアルゴリズムです。

この`buildFloor`関数を各列分ごとに呼び出し、arrayに追加して完成です。

丁寧な手続き型の回答です。

</details>
:::





:::note
<details><summary>テクい回答</summary>

```rb
export const towerBuilder = (nFloors: number): string[] => {
  return Array.from({ length: nFloors }, (_, index) => {
    const spaces = " ".repeat(nFloors - 1 - index);
    return `${spaces}${"*".repeat(index * 2 + 1)}${spaces}`;
  });
};
```

`Array.from`を使用し、ひとまとまりで書かれたコードです。
引数の`_`は、「その部分を使用しない」ことを明示しています。

`length: nFloor`が肝です。
擬似的に「lengthは5」と設定することで、lengthが5の配列であるとある種**騙して**、コードを成り立たせています。
ダックタイピングの一例と言えるでしょう。

</details>
:::

# おわりに
以上、CodeWarsオススメ問題でした。


オススメ問題・解法など、ぜひコメントお待ちしております！
【Ruby】Rubyのproductメソッドの処理について理解したい

### 本記事の内容
Rubyのメソッド`Array#product`について

Ruby リファレンスマニュアル
https://docs.ruby-lang.org/ja/latest/method/Array/i/product.html

### 俺にはわからない...ずっとそうだ...
Ruby Silverを受けようと思っているのですが、早速下記となるのがわからなかったので自分の理解を進めるのを含めて投稿します。

```
arr = [1,2].product([3,4])
p arr
=> [[1, 3], [1, 4], [2, 3], [2, 4]]
```
[Rex](https://rex.libertyfish.co.jp/)で対策少しずつがんばろうと思ってます💪

### productメソッドについて
[Ruby リファレンスマニュアル](https://docs.ruby-lang.org/ja/latest/method/Array/i/product.html)に記載の`product`メソッドについての説明は次のとおり。
> レシーバの配列と引数で与えられた配列（複数可）のそれぞれから要素を1 個ずつとって配列とし，それらのすべての配列を要素とする配列を返します。
> 
> 返される配列の長さは，レシーバと引数で与えられた配列の長さのすべての積になります。

...なんのことやら？

#### 要素の取り出し方を図解してみる
下記のページで要素を取り出す様子を図解されてました。

https://techracho.bpsinc.jp/hachi8833/2023_06_16/130313


#### 直積だ
個人的にさらにわかりやすかったのは
`product`メソッドは集合の直積（デカルト積）を作るものと見るものです。
（だから積の「product」なのかな？と思います）

wikipediaの直積の説明図と同様に考えてみます

https://ja.wikipedia.org/wiki/%E7%9B%B4%E7%A9%8D%E9%9B%86%E5%90%88

 - 配列`[1,2]`と`[3,4]`を行列の行、列に見立てる
 - Wikipediaに載っている説明図のように`[1,2]`の要素、`[3,4]`の要素を行ごと、列ごとにマスの中の要素に当てはめる
 - マスの中の配列を要素とする配列が
`[1,2].product[3,4]`の出力の正体として見ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606327/d0b9664e-3ac9-421c-ded1-32e619795ffa.png)

### 終わりに
もし出題されたときにこの記事を思い出そうと思います😅
【PostgreSQL】ｎ個の引数を受け取るFunctionを作りたい

# 作りたいもの
任意の数の引数を受け取る事ができるFunction
いわゆる「可変長引数」というやつ


```sql:例
-- 引数すべてを足した値を返却する 
SELECT custom_sum(10, 20, 30, 40, 50);
  --> 300
```

# 作り方
引数に「**VARIADIC**」をつけることで実現できる。
```sql
CREATE OR REPLACE FUNCTION custom_sum(VARIADIC nums bigint[])
RETURNS bigint AS $$
DECLARE
	l_num bigint;
	l_ret bigint = 0;
BEGIN
    FOREACH l_num IN ARRAY nums LOOP
        l_ret := l_ret + l_num;
    END LOOP
	;

    RETURN l_ret;
END;
$$ LANGUAGE plpgsql
;
```
これで何個でも*引数を受け取れる。
```sql
SELECT custom_sum(1,2,3,4,5);
--> 15

SELECT custom_sum(1,2,3,4,5,6,7,8,9,10);
--> 55
```

:::note warn
「何個でも」と言いつつも、引数数の上限（FUNC_MAX_ARGS）まで。
:::

以上
【Rails】無駄なスペースや全角文字を半角に変更して保存する方法

ユーザーにデータを入力してもらう際に、保存する内容（形式）を統一したいなと思った時に下記の設定が役に立ちました。

```rb:app>models>application_record.rb
class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true

  before_validation :normalize_attributes

  private

  def normalize_attributes
    attributes.each do |key, value|
      if value.is_a?(String) 
        self[key] = value.tr("０-９", "0-9").gsub(/[\s　]+/, "")
      end
    end
  end
  
end
```
処理の内容
```rb
attributes.each do |key, value|
```
attributes.each は、モデルのすべての属性（カラム）とその値をハッシュの形で取得するためのものです。attributes は ActiveRecord モデルに含まれているメソッドで、モデルに対応するデータベーステーブルの各カラム名と、そのレコードの値をキーと値のペアとして返します。

具体的に言うと、Employee や Company などのモデルに attributes.each を使うと、そのインスタンスのすべてのカラムと現在の値を取得できるため、各カラムごとに変換や処理が可能になります。

例えば、Employee モデルで以下のようなカラムがあった場合

Employeeモデル
```rb
class Employee < ApplicationRecord
  # カラム: name, phone_number, address, company_id
end
```
あるレコードが以下のようなデータを持っているとします：
```
employee = Employee.find(1)
employee.attributes #=> { "id" => 1, "name" => "田中 太郎", "phone_number" => "０００ １１１２２２３３３", "address" => "東京" }
```
この場合、attributes.each を使うと id, name, phone_number, address, company_id とその値を順に取り出して処理できます。

```rb
if value.is_a?(String) 
```
このコードは、Ruby の if 文を使用して、変数 value が String クラスのインスタンスであるかどうかを確認しています。具体的には、`is_a?` メソッドを使用して、value が String クラスのオブジェクトである場合に true を返し、そうでない場合に false を返します。
`is_a?` メソッドは、オブジェクトが特定のクラスまたはそのサブクラスのインスタンスであるかどうかを確認するために使用されます。この場合、value が String クラスのインスタンスである場合に true を返します。

```rb
self[key] = value.tr("０-９", "0-9").gsub(/[\s　]+/, "")
```
Ruby の application_record.rb ファイル内で特定のキーに対応する値を変換して設定するために使用されています。具体的には、全角数字を半角数字に変換し、文字列内のすべての空白（半角スペースおよび全角スペース）を削除しています。

・value の中の全角数字（"０" から "９"）を対応する半角数字（"0" から "9"）に変換します。`tr` メソッドは、文字列内の特定の文字を他の文字に置換するために使用されます。この場合、全角数字を半角数字に置換しています。
・`gsub` メソッドは、文字列内の特定のパターンに一致する部分を置換するために使用されます。`/[\s　]+/` は正規表現で、1つ以上の空白文字（半角スペース \s および全角スペース 　）に一致します。
"" は、置換後の文字列として空文字列を指定しています。これにより、すべての空白文字が削除されます。
※ちなみに、`tr`と`gsub`は同じような機能に見えるかもしれませんがここでは説明は省きます。それぞれが文字置換と削除に適しているということだけ、認識してもらえれば大丈夫です。

```rb
before_validation :normalize_attributes
```

最後にバリデーションの前に、このメソッドを実行すれば自動修正が完了です。
(例)
```rb
 birthday = "１９９０年　　３月　　１　２日"#ユーザーが左のように入力した場合
 p birthday #出力　1990年3月12日
```

以上、自作アプリ作成の際に役に立ったので記事にしました。
単相3線交流の話

# はじめに
単相3線交流回路の中性線を何故インダクタの真ん中から取らないといけないのかということについてまとめた。

# どこの話？
このバケツっぽいやつの中身の話。
![PIXNIO-1043600-725x544.jfif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30037/cb5f4ce7-9249-cbf6-c04a-66a698f9b7ae.jpeg)

※出展

https://pixnio.com/ja/%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88/%E3%82%A8%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AD%E3%83%8B%E3%82%AF%E3%82%B9-%E3%83%BB-%E3%83%87%E3%83%90%E3%82%A4%E3%82%B9/%E9%9B%BB%E5%8A%9B%E5%A4%89%E5%9C%A7%E5%99%A8%E3%80%81%E3%82%B1%E3%83%BC%E3%83%96%E3%83%AB%E3%80%81%E9%9B%BB%E6%9F%B1#

電力会社から6600Vで送電される電気を100Vもしくは200Vに変換する役割がこいつ。
んで、この中身がどうなってるかの話。

# 結論
変圧トランスの真ん中から取らないといけない理由は対地電圧を150V以内に収めるため。

**電気設備の技術基準の解釈**から引用
> 【電路の対地電圧の制限】（省令第15条、第56条第1項、第59条、第63条第1項、第64条）
第143条 住宅の屋内電路（電気機械器具内の電路を除く。以下この項において同じ。）の対地電圧は、150V以下であること。

## 検証1
LTSpiceで雑に変圧トランスを作ってみた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30037/1932c911-4e7e-f9f7-4b66-7f396e81d26a.png)

真ん中を中性線=アースにすると、アースからL1とL2を見たときは位相が180度異なる電圧が端子にかかっている。(実際には、L1からL2に流れている。でも、アース視点で電圧のかかり方を見ると、180度逆位相に電圧が印加されているように**見えている**だけ)
L1と中性線間、もしくはL2と中性線間で100Vが取れる。

中性線を一旦無視してシンプルに回路全体のコイルの巻数だけで見ると、以下のような回路になる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30037/a7214dfc-5b69-210a-8dac-37520eb72f37.png)

回路全体のコイルの巻数はL1とL2の巻数を合計したものと等しくなる(巻数は2倍になる)からL1とL2間の電圧も倍の単相200Vになる。（コイルのど真ん中=1/2の位置から取る理由は言わなくてもいい気はするけど、中性線から見たときにL1とL2を同じ電圧にしたいから）

なので、線間電圧と対地電圧をまとめると以下のようになる。

### 線間電圧
|線1|線2|電圧|理由
|---|---|---|---
|L1|L2|200V|回路全体の電圧がそのままかかるため200Vが電位差として出てくる。
|L1|N（中性線）|100V|コイルの巻数が1/2になる位置を中性線（N）としている。<br>従って回路全体の電圧は200Vなのでその半分の100Vがここで示す線間電位差になる。
|L2|N（中性線）|100V|上記同様

### 対地電圧
|線|電圧|理由
|---|---|---
|中性線|0V|中性線がB種接地されているため、対地電圧=中性線になる。
|L1|100V|中性線がB種接地されているため、中性線に対する電圧と対地電圧は同じになる。
|L2|100V|上記同様

## 検証2
では、中性線側でなく仮に**先程の図のL2**が中性線だったらどうなるか。（以下の図ではNとしている）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30037/6cc2adc4-078b-bf44-d093-5f83125305c6.png)

L1とNの線間電圧はもちろん200V取れている。（緑色のサイン波）
L1とL2（本来中性線であるべき線（青色のサイン波））からも100V取れていることが分かる。
まとめると以下のようになる。

### 線間電圧
|線1|線2|電圧|理由
|---|---|---|---
|L1|L2|100V|コイルの巻数が1/2になる位置をL2としている。従って回路全体の電圧は200Vなのでその半分の100Vがここで示す線間電位差になる。
|L1|N（中性線）|200V|回路全体の電圧がそのままかかるため200Vが電位差として出てくる。
|L2|N（中性線）|100V|コイルの巻数が1/2になる位置をL2としている。従って回路全体の電圧は200Vなのでその半分の100Vが<br>ここで示す線間電位差になる。

### 対地電圧
|線|電圧|理由
|---|---|---
|N|0V|B種接地されているから地面と電圧が等しくなるため、対地電圧は0Vとなる。
|L1|**200V**|本来L2とすべき線を接地しているため**200V**が対地電圧となる。
|L2|100V|コイルの巻数が1/2になる位置をL2としているので、対地電圧は100Vとなる。

# まとめ
- 中性線からみたL1とL2の電圧は100Vになる
- L2から見たL1への電圧、L1からみたL2への電圧は検証2の結果から200Vになる
- 合わせて、中性線への電圧は変わらず100Vになる（中性線はインダクタの巻数が1/2であるため）
- 中性線を変圧トランスの中央で取る理由は、対地電圧を150Vに収めつつ線間電圧で200V得るために真ん中で取っている
- どの線の視点から電圧を見るかによって電圧が変わる事がわかる
- アースをどの視点にすべきかという観点と対地電圧を150V以下にするという観点だと、真ん中の線をアースした方が良い事がわかる
【Kotlin】インスタンス生成時に非同期で StateFlow の初期化を開始する

次のようなクラスと suspend 関数があるとする。

```Kotlin
class MyData

/**
 * [MyData] オブジェクトを非同期でロードする。
 */
suspend fun loadMyData(): MyData {
    // 省略
}
```

ここで新たに `MyClass` クラスを実装したい。
`MyClass` クラスには `MyData` を値とする `StateFlow` をプロパティとして持たせ、
`MyClass` インスタンス生成時に `loadMyData` 関数を呼んで
その返値でこのプロパティを初期化したい。

単純に実装するとこうなる。

```Kotlin: ⚠️改善の余地あり
class MyClass(scope: CoroutineScope) {
    val myData: StateFlow<MyData?>
        get() = _myData
    private val _myData = MutableStateFlow<MyData?>(null)

    init {
        scope.launch {
            loadMyData()
        }
    }
}
```

しかしこれだと `_myData` が `MutableStateFlow` なので
「`myData` が一度だけ初期化される」ことを保証するためには
`MyClass` クラス全体をみる必要がある。

そこで次のようにする。

```Kotlin
class MyClass(scope: CoroutineScope) {
    val myData: StateFlow<MyData?> =
        flow {
            emit(
                loadMyData()
            )
        }
            .stateIn(
                scope,
                // stateIn 実行に flow の購読が開始されるようにする。
                SharingStarted.Eagerly,
                initialValue = null,
            )
}
```

これであれば `myData` プロパティが一度だけ初期化されることが、プロパティの定義だけで保証される。

なお `loadMyData` が例外をスローすることがある場合（`MyClass` だけでは復帰処理などができない場合）は
`StateFlow` の値を [`Result` 型](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-result/)にするとよいだろう。

```Kotlin
class MyClass(scope: CoroutineScope) {
    val myData: StateFlow<Result<MyData>?> =
        flow {
            emit(
                runCatching {
                    loadMyData()
                }
            )
        }
            .stateIn(
                scope,
                // stateIn 実行に flow の購読が開始されるようにする。
                SharingStarted.Eagerly,
                initialValue = null,
            )
}
```

`Result` 型および `runCatching` 関数についてはこちらも参考にされたい。

https://qiita.com/sdkei/items/030875adad33f76d1f09

／以上