OmniAICreator/Qiita-1.07M huggingface dataset:
VBAのソースコードを一括Exportする

## 課題
Excelのマクロで社内ツールをつくると最初は良いのだが規模が大きくなってきたときに変更管理が悪夢になってきたので、GITのようなレポジトリ管理システムを使ってソースコードの変更をきちんと管理する必要が出てきた。VBEからでは１ファイルずつしかExportできないため一括Exportするための機能が欲しい

## 実装

汎用的にするため、別のExcelツールとして実装。選択したファイルのソースコードを,選択したファイルと同じフォルダにExportする（同名ファイルの存在チェックはしない）。ワークブックやシートにマクロを書くとエクスポートはできるのだがインポートするとクラスオブジェクトとしてインポートされてしまうが、目的はあくまでソースコード管理なのでワークシートやブックのマクロもExport対象とする。Active X Designerは開発環境のOffice 2024では廃止となっているので非対称。ローカルレポジトリにExcelのツールを保存して、コードをエクスポート、まとめてセントラルレポジトリにプッシュするような運用を想定

### 事前準備
* Microsoft Visual Basic for Applications Extentibility x.x に参照設定
* Excelのオプション→トラストセンター→マクロの設定で"VBA プロジェクトオブジェクトモデルへのアクセスを信頼する"をチェック

### コード
```vb
Sub Export()

    Dim wb As Workbook
    
    With Application.FileDialog(msoFileDialogFilePicker)
        .Filters.Clear
        .AllowMultiSelect = False
        .Filters.Add "Macro-enabled", "*.xlsm"
        .Filters.Add "Macro-enabled (bin)", "*.xlsb"
        .Filters.Add "Macro-enabled (old)", "*.xls"
        .Filters.Add "Add-in", "*.xlsa"
        .Filters.Add "Add-in (old)", "*.xla"
        .Show
        If .SelectedItems.Count <= 0 Then
            MsgBox "Operation Cancelled", vbExclamation, "Operation Cancelled"
            Exit Sub
        Else
            Set wb = Workbooks.Open(.SelectedItems.Item(1), False, True)
            If wb.FullName <> ThisWorkbook.FullName Then
                ActiveWindow.Visible = False
                ThisWorkbook.Activate
            End If
        End If
    End With
    
    Dim vbc As VBComponent
    Dim strExt As String
    Dim blnExport As Boolean
    Dim strPath As String
    For Each vbc In wb.VBProject.VBComponents
        blnExport = False
        Select Case vbc.Type
        Case VBIDE.vbext_ComponentType.vbext_ct_Document:
            blnExport = True
            strExt = ".dco"
            Debug.Print "Exporting Document object: " & vbc.Name & strExt
        Case VBIDE.vbext_ComponentType.vbext_ct_ActiveXDesigner:
            Debug.Print "Skipping Active X Designer type: " & vbc.Name
        Case VBIDE.vbext_ComponentType.vbext_ct_StdModule:
            blnExport = True
            strExt = ".bas"
            Debug.Print "Exporting Standard Module: " & vbc.Name & strExt
        Case VBIDE.vbext_ComponentType.vbext_ct_MSForm:
            blnExport = True
            strExt = ".frm"
            Debug.Print "Exporting MS Form: " & vbc.Name & strExt
        Case VBIDE.vbext_ComponentType.vbext_ct_ClassModule:
            blnExport = True
            strExt = ".cls"
            Debug.Print "Exporting Class module: " & vbc.Name & strExt
        Case Else:
                Debug.Print "Skipping unsupported type: " & vbc.Name & "(" & CStr(vbc.Type) & ")"
        End Select
        
        If blnExport Then
            strPath = wb.Path & "\" & vbc.Name & strExt
            vbc.Export strPath
            Debug.Print "Saved As " & strPath
        End If
    Next
    
    If wb.FullName <> ThisWorkbook.FullName Then
        Stop
        wb.Close False
    End If
End Sub
```
【Web】脆弱性診断

# はじめに
こんにちは！アメリカで独学でソフトウェアエンジニアを目指しているものです。
現在webについて学んでいますが、Webの脆弱性診断をテーマに、脆弱性情報データベースやペネトレーションテスト（ペンテスト）などを中心とした記事の構成例をご紹介します。

# Web脆弱性診断とは
Web脆弱性診断とは、Webアプリケーションやサイトに存在する脆弱性を事前に洗い出し、攻撃を受ける前に対策を講じるためのプロセスです。
具体的には以下のような観点から行われます。

  * **アプリケーションレイヤー**: 入力値の検証不足やSQLインジェクション、XSSといった典型的な脆弱性のチェック
  * **サーバー設定・ミドルウェア**: 不適切なサーバー設定や古いライブラリの使用などによるリスクの確認
  * **ネットワーク構成**: 不要なポートの開放や不適切なファイアウォールルールなど、インフラ層での脆弱性

脆弱性が発見された場合は、修正（パッチ適用・コード修正）し、再テストを行うという流れを繰り返すことで安全性を向上させます。

# 脆弱性情報データベースとは
脆弱性情報データベース（Vulnerability Database）は、既知の脆弱性やセキュリティ問題に関する情報を集約し、公開しているプラットフォームです。
セキュリティ研究者、ベンダー、コミュニティなどが報告した脆弱性を体系的に整理・管理しています。

## 代表的な脆弱性情報データベース
以下にいくつか代表的な脆弱性情報データベースの例を載せておきます
1. **CVE (Common Vulnerabilities and Exposures)**
MITREが管理する脆弱性識別子システム。各脆弱性に「CVE-XXXX-XXXX」といったIDが付与され、世界的に認知されています。

2. **NVD (National Vulnerability Database)**
アメリカ国立標準技術研究所 (NIST) が運営するデータベース。CVE情報をベースにCVSS（Common Vulnerability Scoring System）のスコアなど追加情報を付加して提供しています。

3. **JVN (Japan Vulnerability Notes)**
IPA（独立行政法人情報処理推進機構）とJPCERT/CCが共同運営する日本の脆弱性情報ポータル。日本語での情報提供が主で、国内向け製品やサービスの脆弱性もカバーしています。

4. **OSS Security Mailing Lists / GitHub Security Advisories など**
オープンソースソフトウェアの脆弱性は、セキュリティ関連のメーリングリストやGitHubリポジトリのSecurity Advisoriesで報告されることも多いです。

# ぺネトレーションテスト（ペンテスト）とは
ペネトレーションテスト（以下、ペンテスト）とは、悪意ある攻撃者の視点でシステムに対する疑似攻撃を実施し、実際に侵入や情報漏洩が可能かどうかを検証する手法です。
単なる診断ツールによるスキャンでは検出しきれない攻撃シナリオを洗い出すうえで非常に有用です。

## ペンテストの種類
1. **ブラックボックステスト**
攻撃者視点に近く、システムの内部情報をほとんど知らない状態でテストを行う。実際の不正侵入に近い手法を取り、外部からの攻撃経路を探る場合に有効。

2. **ホワイトボックステスト**
システム内部の設計情報やソースコードを共有した状態でテストを行う。コードの脆弱性や設定ミスなどを詳細に調査できるため、より網羅的な検証が可能。

3. **グレーボックステスト**
部分的にシステム情報を共有した状態でのテスト。ブラックボックスとホワイトボックスの中間的手法として使われる。

## ペンテストの流れ
1. 要件定義と範囲設定
  どのシステムや機能を対象にするか、攻撃手法の制限や期間などを明確化する。
2. 情報収集
  DNS情報、IPアドレス範囲、サービスバナーなどを調べて攻撃の足がかりを探る。
3. 脆弱性スキャン
  ツールや手動テストで脆弱性がないかチェック。
4. 脆弱性の検証・侵入試行
  見つかった脆弱性が本当に悪用可能かを確認し、侵入に成功した場合はどの範囲まで被害が拡大するかを調べる。
5. レポート作成・対策提案
  発見された脆弱性、攻撃手順、被害範囲、必要な対策などをまとめ、報告する。

## 代表的な診断ツール・ペンテストツール
### オープンソースツール
* **OWASP ZAP (Zed Attack Proxy)**
  OWASPプロジェクトの一環で開発・提供されるオープンソースの脆弱性診断ツール。Webアプリケーションのスキャンだけでなく、プロキシ機能を使った手動検査にも役立つ。
* **Burp Suite (コミュニティ版)**
  プロキシを介してリクエストやレスポンスを解析し、脆弱性を検知する。無料のコミュニティ版でも基本的なテストが可能。
### 商用ツール
* **Acunetix / Netsparker / AppScan など**
自動スキャンの精度が高く、レポート機能やCI/CDパイプラインとの連携機能を備えている。大規模・複雑なアプリケーションの診断や継続的セキュリティテストに有用。
### APM/Observabilityツールとの併用
* **New Relic / Datadog / Sentry など**
APMやロギングを活用することで、ペンテストや脆弱性診断の結果が稼働中のアプリケーションに与える影響をリアルタイムに把握できる。ボトルネックや異常動作も素早く検知が可能。

# まとめ
この記事で一旦Webの勉強は終わりですが、これから「安全なWebアプリケーションの作り方」をしっかり見て、セキュリティ面にも当たり前に知っているエンジニアになれるよう引き続き勉強頑張りたいと思います
SPSS Modelerで複数カテゴリの複数フィールドの平均を比較

SPSS Modelerの平均値ノードで複数カテゴリの複数フィールドの平均を比較します。


Modelerの「平均値」ノードを使うと複数カテゴリで複数フィールドの平均値を比較して、特徴量を重要度順に並べ替えることができます。これはとても強力なので例をご紹介します。

以下のようなデータを用意しました。
各顧客に対して、アクセサリの購入金額合計などのさまざまな集計がなされています。
「マネタリー５」というフラグ列があり、これは購入金額が全体の上位20%の優良顧客であるということを示しています。
この優良顧客とそうでない顧客でどんな差があるかどうかを「平均値」ノードを使って調べてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/3c68d8f3-ad0f-85ba-47bf-68d140a75208.png)

「フィールド内のグループ間で比較」を選び「グループ化フィールド」に比較したいカテゴリ列を指定します。この例では「マネタリー5」です。
「テストフィールド」に比較したい値を設定します。ここではすべての数値列を選びました。この中から特に平均値の差を注目すべき特徴量を探します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/56500bcf-02a0-eb25-ed38-aff3b8e0b397.png)

表示を「詳細」にして、「F検定」の降順で並べ替えます。
そうするとF値が大きい順に並びますので、優良顧客とそれ以外で平均値の違いが顕著な順に特徴量が並べ替えられます。（「重要度」で並べ替えても本来は同じ順序になるべきなのですが、p値がとても小さいと丸められてしまって順位がつかなくなるのでF値で並べ替えるのがコツです）


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/12366b45-213b-c845-c388-fa2a9d6ae852.png)

中身をみてみると、「Monetary」や「マネタリースコア」が最上位に来ています。これは「購入金額が全体の上位20%の優良顧客」が「マネタリー5」＝Trueなのでチートになり、当たり前の結果です。
次点の「Frequency」は優良顧客は77.9回、そうでない顧客は21回なので大きな差があることがわかります。
このようにチートも含まれますが、たくさんの特徴量候補があるときに、とりあえず、すべての特徴量から重要そうな特徴量を知りたいときにとても便利です。

ちなみに「特徴量選択」ノードでも、目的変数がカテゴリ型で説明変数が数値型の場合は、同様のロジックを使っています。ただ「平均値」ノードの場合は各カテゴリの平均値も表示されるので、具体的な値で各カテゴリでどちらがどれだけ大きいのか小さいのかも比べることができるのがメリットです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/41105bb1-4180-fb3e-5ea4-72b206859348.png)






# サンプル
サンプルは以下に置きました。

#### サンプルストリーム

https://github.com/hkwd/200611Modeler2Python/raw/master/mean/mean.str



#### 利用データ
https://raw.githubusercontent.com/hkwd/200611Modeler2Python/master/mean/goodcustomer.csv

■テスト環境
Modeler 18.4
Windows 10 64bit
Python 3.8.10
pandas 1.4.1
scipy 1.8.0
statsmodels 0.13.2



# 参考
##### SPSS Modeler ノードリファレンス 6-9 平均値 - Qiita 

https://qiita.com/416nishimaki/items/f5b957a24430b9a3aa9e


##### SPSS Modelerの平均値ノードをpythonに書き換える  - Qiita 

https://qiita.com/spssfun2017/items/71b3d6edd3d56d23cb0c

上の記事の3mを抜粋しました。
Fivetran が提供している Connectors の Interactive ERD のページを表示する方法

## 概要

Fivetranのウェブサイトでは、一部のコネクターのデータ構造を確認できる **Interactive ERD（Entity-Relationship Diagram）** ページが提供されています。以下はその表示方法についてのガイドです。

![Interactive ERD イメージ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/7be7dacf-1b66-579c-916b-0a4816f03ffb.png)

![ERD 詳細イメージ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/f79da52d-58af-87e9-536e-4027bd9b33a2.png)

参照：[Dashboard | Fivetran](https://fivetran.com/connector-erd/microsoft_power_bi)

## Interactive ERD ページを単独で表示する方法

### 方法 1: Connectors ページからのアクセス

1. **Connectors ページでコネクターを検索**  
   [Data Sources | Connector Directory](https://www.fivetran.com/connectors?q=dbt) ページにアクセスし、Interactive ERDを表示したいコネクターを検索して選択します。

   ![コネクター検索イメージ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/b36220f9-1d03-97dc-59a9-bfb601c19a82.png)

2. **`click here`を選択**  
   コネクターページで`click here`リンクをクリックします。

   ![クリックリンクイメージ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/dcba61a7-2432-c699-5f06-e3accc49460f.png)

3. **Interactive ERD ページを確認**  
   表示されたページでERDが確認できます。

   ![ERD表示結果](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/95771ec7-3984-1bad-9159-d26efb6c3505.png)  

   参照：[Dashboard | Fivetran](https://fivetran.com/connector-erd/dbt_cloud)


### 方法 2: URL 直接入力

1. **コネクターのURLを取得**  
   Connectorsページで対象コネクターのURL末尾（例: `microsoft-power-bi`）を確認します。

   ![URL末尾の取得例](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/38b07d9f-432b-887b-7360-835c1e33a718.png)

2. **URL末尾を変換**  
   - ハイフン（`-`）をアンダーバー（`_`）に置き換えます（例: `microsoft_power_bi`）。

3. **Interactive ERD ページにアクセス**  
   以下のURLをブラウザで開き、コネクターに対応したERDを表示します：  
   `https://fivetran.com/connector-erd/コネクター名`

   - 例: `https://fivetran.com/connector-erd/microsoft_power_bi`

   ![結果の表示例](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/503051d1-4c8c-9b71-f643-cfbd08a2e8e0.png)

## Interactive ERD ページをドキュメント上で表示する方法

### Document ページからのアクセス

1. **ドキュメントページで`Explore the interactive ERD`を選択**  
   ドキュメント内のリンクをクリックして、Interactive ERDを表示します。

   ![ドキュメントリンク例](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/b318944f-d0df-a7b7-7945-c666e3640e0b.png)

2. **上部にERDが表示されることを確認**  
   ページ上部に表示されるERDを確認します。ただし、この方法では単独のERDページを開くことはできません。

   ![ERDのドキュメント表示例](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/845cd618-8f6e-8f21-9798-003e70920028.png)

   参照：[15Five data connector by Fivetran](https://fivetran.com/docs/connectors/applications/15five#schemainformation)

---

このガイドを参考に、FivetranのInteractive ERDを効率よく活用してください。
Terraform講座：Infrastructure as Codeって何編

## はじめに
初投稿です。
簡単な自己紹介をすると、2024年4月に入社し、現在、AWSで開発しているシステムに関して必要なAWSリソースを構築するインフラ屋さんをやっています。
ということで、インフラ屋さんになってから学んだことを備忘録として記事に書けていけたらなと思っています！！

## 今回の記事について
### 内容
Terraform備忘録シリーズの第一弾として
前提知識である「Infrastructure as Code (IaC) 」を解説出来たらなと思います！
### 対象
- クラウドサービス (特にAWS) を使ってアプリケーションを構築しようと思っている人
- IaCって聞いたことあるけど、何かよく分かっていない人



## IaCとは？
**「開発するアプリケーションの部品 (リソース) の作成や変更をコードを使って管理・自動化しよう！」** というものです。

これのモチベーションを分かってもらうためにも
- リソースにはどんなものがあるのか？
- リソースは一般的にはどうやって作られるのか？
- アプリを開発する上で、リソースについてはどんなニーズが生まれるのか？
- 一般的な作り方だとニーズに応えられるのか？

について説明したいと思います。

### リソースの例
クラウドサービスを使って開発するアプリケーションのリソースは、例えばAWSで言うと
- [EC2](https://aws.amazon.com/jp/ec2/?gclid=EAIaIQobChMI8bSEuNDnigMV58NMAh3w5wj1EAAYASAAEgIzFPD_BwE&trk=c95527aa-2c0b-4c61-a33f-4ca98bab4822&sc_channel=ps&ef_id=EAIaIQobChMI8bSEuNDnigMV58NMAh3w5wj1EAAYASAAEgIzFPD_BwE:G:s&s_kwcid=AL!4422!3!696313349036!e!!g!!ec2!16402422398!142328429268): アプリを動かすためなどに用いる仮想サーバ
- [RDS](https://aws.amazon.com/jp/rds/): データベース

があります。

### リソースの一般的な作り方
これらのリソースは、下の画像のようにAWSのマネージメントコンソールから手動で作成することが出来ます。直感的に操作ができて、複雑なリソースでも簡単に作ることが出来ちゃいます！

![スクリーンショット 2025-01-09 11.33.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3942158/aabdbfa5-cf8e-eddb-8278-295cf903997b.png)

### アプリを開発する上で出てくるニーズ
アプリ開発は、下の画像のようなイメージです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3942158/d0b5d08a-f30e-08ed-2b13-e40435806542.png)


文字に起こすと、作成したリソースを1つに組み合わせていくことで作ることが出来ます。
車に例えると、ボディ・エンジン・タイヤなどの部品 (リソース) を作成して、車 (アプリ) を形成すると言う感じで想像してください。

こう考えると、製品に使う部品が1つで済むものはそう多くないですよね？
つまり、**同じリソースを簡単に量産したい**というニーズが生まれてきます。
また、別の製品を作るとなった際に、あの時作った部品をこっちでも活かせるじゃん！というのがありますよね？
つまり、**同じリソースをいつでも使いまわせるようにしておきたい**というニーズも生まれてきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3942158/17e77bdb-4b10-4693-f0af-872fb03b3ce2.png)

### 一般的な作り方はニーズを満たす？
手動で同じリソースを大量に作成することを考えると、必要なリソースの数だけ作業を繰り返さないといけないので、簡単に作成したり、いつでも使いまわせるようにしておくことが全く出来ません。

また、マネージメントコンソールの操作性と柔軟性により、設定が少し異なってもエラーなく作れてしまうリスクがあったり、さらには、アプリ開発はリリースするだけでは終わらず、アップデートが必須になってきます。当然リソース自体のアップデートもあります。リソースを手動で作成した場合、これら1つ1つにその変更を反映する必要があるなど、

**ミスですか？どうぞ起きてください！**

という大リスク環境が完成してしまいます。。。そんなの嫌ですよね？これらを解決してくれるのが、IaCなのです！！

### IaCがアプリ開発におけるニーズを解決！
コードの内容は、
```
    EC2の設定項目:
        1: Amazon Machine Image (AMI) はxxxを使用する
        2: セキュリティグループはxxxを使用する 
        3: サブネットxxxに立ててください
        ...
```
というようにリソースを作成するための設定項目を記述し、設計書のようなイメージを持ってもらえればと思います。
そして、そのファイルをコマンドラインインタフェース (CLI) で実行すると、設定項目をもとに自動でリソースを構築してくれます。

以上により、
- **同じリソースを簡単に量産したい！** ▶︎ ファイルの実行だけで完結する
- **同じリソースをいつでも使いまわせるようにしておきたい** ▶︎ ファイルを使いまわす！

というニーズを満たすことができるだけでなく

- **設定ミスが起きそう...** ▶︎ 決めた設計通りに記述して、実行するだけなので起きない！
- **リソースの変更...** ▶︎ コードの一部を変更してあとはCLIで実行するだけ！

と、手動作成で発生しうるリスクを全て解決してくれます！

## まとめ
IaCの ちからって すげー！

[次回](https://qiita.com/aaaaa_326/items/b32621f4cbaa1434d925)は、IaCのツールの1つであるTerraformについて解説出来たらと思います！
【2025年01月版】Ubuntu24.04 で SoftEther VPN Bridgeのインストール

# はじめに

いままでつかっていた

Raspberry Pi 4B上のUbuntu20.04のSoftEther VPN Bridgeを、
Proxmox上のVMのUbuntu24.04に

変更してみたメモ

# 前提

新規でVPN Bridgeの設定をGUIから行うか、
既存の接続できるSoftEther VPN Bridgeの設定ファイル(`/usr/vpnbridge/vpn_bridge.conf`)は存在する前提

```terminal
$ uname -a
Linux vpnbridge 6.8.0-51-generic #52-Ubuntu SMP PREEMPT_DYNAMIC Thu Dec  5 13:09:44 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
```

# VPN Bridgeのインストール

## 必要なソフトウェアのインストール

```terminal
$ sudo apt install gcc make unzip -y 
$ sudo apt install build-essential -y
$ sudo apt install libreadline-dev libssl-dev libncurses-dev libz-dev -y
```

## 作業ディレクトリの作成

```terminal
mkdir work
cd $_
```

## gitからソースの取得

```terminal
git clone https://github.com/SoftEtherVPN/SoftEtherVPN_Stable.git
```

## プログラムの修正

```
$ cd SoftEtherVPN_Stable/
$ vim src/Cedar/Server.c
```

`src/Cedar/Server.c` 内の、
`bool SiIsEnterpriseFunctionsRestrictedOnOpenSource(CEDAR *c)` のreturn を false にする

```
$ diff src/Cedar/Server.c src/Cedar/Server.c.back
10924,10925c10924
< 	//return ret;
< 	return false;
---
> 	return ret;
```

## ビルドとインストール

```terminal
$ chmod +x ./configure
$ ./configure 
$ make
$ sudo make install
```

## 設定ファイルの作成

```terminal
sudo vim /usr/vpnbridge/vpn_bridge.config
```

## サービス化

```terminal
$ sudo vim /etc/systemd/system/vpnbridge.service
$ cat /etc/systemd/system/vpnbridge.service 
[Unit]
Description=SoftEther VPN Bridge
After=network.target network-online.target

[Service]
ExecStart=/usr/bin/vpnbridge start
ExecStop=/usr/bin/vpnbridge stop
Type=forking
RestartSec=4s

[Install]
WantedBy=multi-user.target
$
$ sudo systemctl enable --now vpnbridge.service 
$ sudo systemctl status vpnbridge.service
```

## Bridgeの設定

Bridgeするインターフェイスなどは、SoftEtherのGUIツールを使って行うと楽
マシンを移動した後は、ローカルブリッジ設定のインターフェイスを修正する必要がある

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143127/f71efd09-c3b4-4dc9-5000-36b4d0b9c10d.png)


# さいごに

かんたんでしたね

# リンク

- [SoftEther VPN を UNIX 上でビルドする方法](https://ja.softether.org/5-download/src/2.unix)
- [【2021年版】RaspberryPi4 + Ubuntu20.4 + SoftEther VPN Bridge 環境構築](https://qiita.com/nouernet/items/8308d1dcdd5dd030a7e3)
Makefile暗黙のルール入門

# Make入門

まず、makeについて。

- [Makefileの基本](https://zenn.dev/keitean/articles/aaef913b433677)

例えばprogram.cppがカレントディレクトリに有った場合、makeは十分に賢いので次の様にコマンド実行すればMakefileが無くてもコンパイル・リンクして実行ファイルを吐いてくれます。

```
$ make program
g++     program.cpp   -o program
$ ls
program program.c
```

でもこれだとオプションが指定できないしmake cleanもできません。

「Makefile作るの面倒だけどmakeとmake clean一発で済ませたい」という時のためにmake暗黙のルールを使って、柔軟かつ最低限の記述で済むMakefileを以下に。ライブラリもインクルードパスも不要ならBINARY変数書き換えるだけで一発。

```
BINARY := program
OBJECT := $(BINARY).o
SOURCE := $(BINARY).cpp
CXXFLAGS := -Wall
LDLIBS :=
.PHONY: clean
$(BYNARY): $(SOURCE)
clean:
	$(RM) $(BYNARY) $(OBJCTS)
```

以下詳細

"make -p"を実行すると以下が表示されます。

```
CXX = g++
:
LINK.cc = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)
:
LINK.cpp = $(LINK.cc)
:
%: %.cpp
     $(LINK.cpp) $^ $(LOADLIBES) $(LDLIBS) -o $@
```

ここでサフィックスルールを軸に変数を展開していくと、

```
%: %.cpp
     g++ $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) $^ $(LOADLIBES) $(LDLIBS) -o $@
```

となるので、先程のMakefileは最終的に以下の様に展開されます。

```
program: program.cpp
     g++ $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) program.cpp $(LOADLIBES) $(LDLIBS) -o program
```

残りの変数についてはユーザーがMakefileで設定出来る様に定義だけされていて、以下の様な役割になってます。

- CXXFLAGS: C++のコンパイルオプションを指定する。-Wとか-Oとか-stdとか。
- CPPFLAGS: Cプリプロセッサのオプションを指定する。C言語で書いたプログラムにも適用されるため注意。
  [CXXFLAGSとCPPFLAGSの違い – かひわし4v1.memo](https://blog.ef67daisuki.club/2017/05/cxxflags%E3%81%A8cppflags%E3%81%AE%E9%81%95%E3%81%84/)
- LDFLAGS: リンクオプション、-Lとか。
- TARGET_ARCH: マシン依存なオプションを指定する、-marchとか、クロスコンパイルかCPU最適化するなら必要。
- LDLIBS: リンクするライブラリを指定する、-lboost_regexとか。
- LOADLIBS: LDLIBSと一緒だが互換性のために残ってる。
  [Re: "LOADLIBES" versus "LDLIBS"?](https://lists.gnu.org/archive/html/help-make/2005-01/msg00063.html)

これを活用すればわざわざ各ルールにレシピを書かなくてもmakeがよしなにやってくれます。

```
$ make
g++ -Wall    text.cpp   -o text
```

全部のルールにレシピを書くとMakefileが膨れ上がるので共通のレシピで済む場合は暗黙のルールを活用しましょう。
またLDLIBS等の暗黙のルールを避けて独自変数を設定するとレシピがこんがらがるのでなるべく避けましょう。
よく見るのはCPPFLAGSをC++のコンパイルオプションと勘違いしてC言語にまで波及させるパターンです。気をつけて。

困ったらmake -pを実行して暗黙のルールを確認しましょう。makeは多くのルールを予め定義してくれています。
AWS Lambdaをローカルで爆速開発！面倒なデプロイともおさらばです

# AWS Lambdaをローカルで爆速開発！面倒なデプロイともおさらばです

## こんな悩みありませんか？

「Lambda関数を書いた！よし、デプロイして動作確認...あれ？バグった...修正してまたデプロイ...」

このデプロイ地獄、私も経験しました（遠い目）。でも大丈夫！AWSの公式Dockerイメージを使えば、あなたのPCでサクッとLambdaを動かせちゃうんです。

## 今回の主役：AWS Lambda用Dockerイメージ

まずはAmazonが太っ腹に公開している [Docker イメージたち](https://gallery.ecr.aws/lambda?page=1) から好きな言語のイメージを選びましょう。Node.js、Python、Java...選り取り見取りです！

今回は例としてNode.jsを使いますが、他の言語でもほぼ同じ手順でイケます👍

## セットアップ：Docker Composeでお手軽構築

まずは`compose.yaml`を作りましょう。コピペでOKです！

```yaml
services:
  lambda-local:  # 好きな名前をどうぞ！
    image: public.ecr.aws/lambda/nodejs:20.2024.11.22.14
    command: [ "index.handler" ]
    restart: always
    volumes:
      - ./project_dir:/var/task
    ports:
      - "9000:8080"
    logging:
      options:
        max-size: "5m"
        max-file: "10"
```

### ここでのポイント（要チェック！）

- `command`の`index.handler`は「`index.js`の中の`exports.handler`関数を実行してね」という意味です
- `volumes`でプロジェクトのフォルダをコンテナにマウント。これで開発中のコードが見えるようになります
- ポートは`9000:8080`にしてますが、もちろん変更OK！（ただし右側の8080は固定です🙇‍♂️）

## 実行してみよう！

お待ちかね、実行コマンドです：

```bash
curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"payload":"hello world!"}'
```

URLが「なんじゃこりゃ」という感じですが、気にしない気にしない！これで動きます😅

## 開発中の注意点（これ大事！）

1. **コードの変更を反映したいとき**
   - コンテナの再起動が必要です
   - `docker compose restart lambda-local`でOK！
   - ホットリロード欲しい...（切実）

2. **デバッグが超ラク**
   - ログも即確認：`docker compose logs -f lambda-local`
   - エラーもすぐわかる！（AWS コンソールとにらめっこよりずっといい）

3. **本番環境との違い**
   - IAMロールとかは別途設定が必要です
   - でも基本的な動作確認には困りません！

## これがローカル開発のいいところ！

1. **爆速開発🚀**
   - デプロイ待ち？そんなの知らない！
   - 修正→実行→確認のサイクルが速すぎて笑えます

2. **お財布に優しい💰**
   - AWS料金とはおさらば
   - 特に「えいや！」で試したいときに最高です

3. **オフラインでも開発OK！**
   - 新幹線の中でも開発できちゃう
   - カフェのWi-Fiが死んでても平気！

## さいごに

Lambda開発、実はローカルでもできるんです。しかも公式イメージなので、変な罠もありません。

この方法を使えば、開発効率が段違い。同僚に教えたら「え！そんなことできるの！？」と驚かれました（ニヤリ）。

みなさんもぜひ試してみてください！きっと開発生活が変わるはず...✨

## 参考リンク

- [AWS公式ドキュメント - Node.js Lambda関数をコンテナイメージとともにデプロイする](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/nodejs-image.html)
- [Amazon ECR Public Gallery - Lambdaイメージ集](https://gallery.ecr.aws/lambda?page=1)

## おまけ
この記事を最後まで読んでくれた方、ありがとうございます！もし「いいね」していただけたら、次の記事のモチベーションになります😊
# [UIKit] UIStackView内のSubview間のスペースをカスタマイズする

完全自分用の学習備忘録。

`UIStackView` を使用している際、ビュー間の間隔を柔軟に調整したいことがあります。`setCustomSpacing(_:after:)` メソッドを使用することで、特定のビューの直後にカスタム間隔を設定できます。

お恥ずかしながら、私はこれまで、こんなメソッドがあることを知りませんでした…　「SpacerView」という名の`UIView`をわざわざ生成して、特定のビュー間の間隔を調整していました…

### やりたいこと↓
![Simulator Screenshot - iPhone 11 Pro Max - 2025-01-09 at 13.03.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3879232/2d9bdd6d-8502-80ef-433f-cb08db40f828.png)

## **`setCustomSpacing(_:after:)` の基本構文**

```
func setCustomSpacing(
    _ spacing: CGFloat,
    after arrangedSubview: UIView
)
```

- **`spacing`**: 指定する間隔（ポイント単位）。
- **`arrangedSubview`**: このビューの直後に間隔を設定します。

---

## **基本的な使い方**

以下の例では、`UIStackView` に 3 つのラベルを配置し、2 番目のラベルの直後にカスタム間隔を設定します。

### **コード**

```swift
import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        
        // UIStackView の作成
        let stackView = UIStackView()
        stackView.axis = .vertical
        stackView.spacing = 10 // デフォルトの間隔
        stackView.layer.borderColor = UIColor.black.cgColor
        stackView.layer.borderWidth = 3.0
        stackView.translatesAutoresizingMaskIntoConstraints = false

        // UIView の作成
        let view1 = UIView()
        view1.backgroundColor = .systemBlue

        let view2 = UIView()
        view2.backgroundColor = .systemGreen

        let view3 = UIView()
        view3.backgroundColor = .systemRed
        
        let view4 = UIView()
        view4.backgroundColor = .systemPink

        // サイズを設定
        [view1, view2, view3, view4].forEach { view in
            view.translatesAutoresizingMaskIntoConstraints = false
            NSLayoutConstraint.activate([
                view.heightAnchor.constraint(equalToConstant: 100),
                view.widthAnchor.constraint(equalToConstant: 100)
            ])
        }

        // スタックビューに UIView を追加
        stackView.addArrangedSubview(view1)
        stackView.addArrangedSubview(view2)
        stackView.addArrangedSubview(view3)
        stackView.addArrangedSubview(view4)

        // カスタム間隔を設定
        stackView.setCustomSpacing(50, after: view2)
        stackView.setCustomSpacing(100, after: view3)

        // スタックビューをビューに追加
        view.addSubview(stackView)

        // レイアウトの設定
        NSLayoutConstraint.activate([
            stackView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            stackView.centerYAnchor.constraint(equalTo: view.centerYAnchor)
        ])
    }
}
人対人のリバーシ対戦ゲームを、Unityで作成した（ChatGPTの助けをかりて）

　現在、Unityで9ｘ9路盤で、人とコンピューターが対戦する囲碁ゲームをつ
くりスマホで配布する、という最終目標をもっている。
　今回は、その手始めとして、人対人のリバーシゲームをUnityでつくった。Unityに詳しくないぼくは、以前の経験
（https://qiita.com/tkoji3744/items/08b71054dfba4f93f2c4 )
にならい、ChatGPTに全面的に助けてもらった。

　できあがったのは、
 
![リバーシUnity.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3676736/a73cb32a-0a4f-b642-4978-15aa0f4a01fc.jpeg)

 

このUnityのHierarchyは下記のよう。
*そのComponentと、その後の[ ]はいわゆる「アウトレット接続」）

Main Camera
Line Prefab
　（そのComponent:　Transforn,　Line Rendere[LineMaterial]）
GoBoard
　（そのComponent:　Transform,　
#スクリプトGo Board Generator[LinePrefab]
#スクリプトReversi game 
[BlackStonePrefab, WhiteStonePrefab, ResultText]）
Canvas----Result Test
そして、ゲーム上でクリックするたびに、EventSystem下に刻々とあらわれる、WhiteStone(clone), BlackStone(clone)

けっこう、いろいろなところでつまずいて、総制作時間は６時間近くを要した。

特に躓いたのは：

１．	リバーシの盤面作成
　提案されたのは、①外部あるいはChatGPTでつくったPNP画像を用意し、それとUnityの座標を一致させる②座標から盤面をつくる、のいずれか。最初、ChatGPTに碁盤のPNP画像をつくってもらったが、何度くりかえしても、下記のようなおかしな画像しか彼はつくれない。プログラムを書く卓越した能力にくらべるとChatGPTが絵を描く力はいまひとつのよう。

 ![リバーシUnity（２）.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3676736/0ab739dd-3e32-cfd9-b241-9608dd968615.jpeg)

 
　結局、ネット上の素材集から画像をとってきたが、次の「画像の線と座標を一致させる」ことが至難の技で、結局②のやり方をすることでうまく行った（GoBoardオブジェクトにアタッチされたC＃スクリプトコンポーネントGo Board Generator）。
　とはいえ、盤面の枠内に石をおくのか？、盤面の交点に石をおくのか？に関してGoBoardオブジェクトのC＃スクリプトコンポーネントReversi game内ののvoid InitializeBoard()メソッドの数回の書き換えが必要だった。とりあえず、このスクリプトの書き換えで、石を枠内にも交点にも選んでおけるようになり、今回のリバーシ（枠内に石を置く）作成だけでなく、将来の囲碁ゲーム（交点に石を置く）作成のステップにもなった。

２．	リバーシの石がひっくりかえらない。
　GoBoardオブジェクトのC＃スクリプトコンポーネントReversi gameは220行におよぶ。
　最初、実際のゲームをすると、黒ではさむと白はひっくりかえるが、白ではさむと黒はひっくりかえらなかった。
　今までの経験では、ChatGPTにこのような不具合を伝えると、あらたなスクリプト（今回の場合C＃スクリプトコンポーネントReversi game）を作ってくれてその差し替えで問題はあっさり解消されるのだった。しかし、今回、何度も何度も、伝えても改善はしなかった。すると、ChatGPTから、Debug.Logの作成を提案してきて、それにそってDebug.Logの作成→その状態をChatGPTに伝達、を何回くりかえすことでようやく不具合が解消された。この、ChatGPTから、Debug.Logの作成を提案されたのははじめてだった（彼も、万能でない？）

C＃スクリプト　Reversi gameの全文はここで表示しないが、大枠を記すと、

using UnityEngine;
using TMPro; // TextMeshProを使用

public class ReversiGame : MonoBehaviour
{
    public int gridSize = 8;  // グリッドサイズ
    public float cellSize = 1.0f;  // 1マスのサイズ
    public GameObject blackStonePrefab;  // 黒石のPrefab
    public GameObject whiteStonePrefab;  // 白石のPrefab
    public TextMeshProUGUI resultText;  // 勝敗表示用のUI
    private int[,] board;  // 盤面の状態 (0: 空, 1: 黒, 2: 白)
    private GameObject[,] stoneObjects;  // 盤面上の石のオブジェクト
    private bool isBlackTurn = true;  // 黒石のターン

　　使用されているメソッドは、
    void Start()
    void InitializeBoard()
    void Update()
    void PlaceStone()
    　// 無効な手の場合、ターンを切り替えない
      // 石を配置
      // 石をひっくり返す
      // ターン切り替え
      // ゲーム終了判定
     void PlaceStoneVisual(int x, int y, int stoneType)
   　 // 既存の石を削除
      // 新しい石を配置
    bool CanPlaceStone(int x, int y)
    bool CheckDirection(int x, int y, int dx, int dy, int opponent)
    void FlipStones(int x, int y)
    void FlipDirection(int x, int y, int dx, int dy)
    bool IsGameOver()
    void ShowGameResult()
 ｝　


　なお、最後に、ゲーム終了後に石の数を計算して、勝敗をUI（UserInterface）で表示する機能を追加したのだが、この工程は、思ったよりスムーズにいった。
　前回Qiita記事のように
（ https://qiita.com/tkoji3744/items/9cde4909de312596aecb )
　このUnity2022.3Versionには最初からTextMeshProがインポートされているのも、幸いしたかもしれない。
Pythonを用いて自作した人対人のリバーシ対戦ゲームを、python用のWEBフレームワークBottleを用いてlocalhostに表示した（ChatGPTの助けをかりて）

　前回、Pythonを用いて、人対人のリバーシ対戦ゲームをつくった（ https://qiita.com/tkoji3744/items/08b71054dfba4f93f2c4 )。
　さらに、python用のWEBフレームワークFlaskをつかって、Pythonファイル（俳句SNS）をPythonanywhereにデプロイした（Flaskのファイルも既存でつくられていた）
（ https://qiita.com/tkoji3744/items/2f605cef3348d650f7dd )

　今回、自作した人対人のリバーシ対戦ゲームを、自作のpython用のWEBフレームワークBottleを用いてlocalhostに表示した。

 ![リバーシbottle.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3676736/97d5f091-8e22-97d6-ab76-bf0fc142dce5.png)


「いちばんやさしいpython教本」（鈴木たかのり、インプレス）を参考にbottleでWEB表示してみた。

ディレクトリ構造例
プロジェクトフォルダは以下：

(Project)　reversimmweb/
├── reversimm.py
├── reversimmweb.py
├── views/
│   └── index.tpl
├── static/
│   ├── app.js
│   └── style.css

　　

　プロンプト(またはVSC)でpython reversimmweb.py　→　http://localhost:8080 (httpSでない)でうまく表示できたのが上記である。

　Bottleは、ルーチング、テンプレートができるが、データベータアクセス、セキュリティ機能（ユーザー管理など）ができない。その分、シンプルな構造で（ぼくのような）初心者でもわかりやすい。
　既にリバーシ（人対人）のpythonスクリプトがあるので、それをChatGPTに提示し、いろいろ対話しながら作っていった。
　途中、__pycache__ フォルダはPythonの仕様上作成されるもので、そのままにしておいても問題ないという、（ぼくとしては）新しい知識が得られた。
　ただ、今回、図形描写には、PythonのTkinkerはつかわずapp.js（JavaScript）やstyle.css(スタイルシート)がつかわれたので、できあがったものには、最初のリバーシ（人対人）のpythonスクリプトの痕跡はほとんどなくなってしまった。
　作業そのもは、大きな問題もなく、２時間くらいで上記のものが完成したが、まさに独力ではありえない達成だった。

　とはいえ、localhostに表示した（多くの書籍はここまでで説明はおわりである）後、このpython WEB アプリケーションをデプロイするのは、（あまりそう書かれてないが）かなり困難である（pythonの動くレンタルサーバーは多くないしその使い方はまた勉強いる、pythonanywhereでさえ、実はデプロイが実現しているのものが多くない）。
　多くのpythonコードがJavaScriptで書き換えられているところからすると、最初からJavaScriptでつくったほうが今回のような単純なプロジェクトのデプロイにはあっていると思える。
　ただ、もっと大がかりなプロジェクトについてはまた別の話ではあろうが。
AWSbackupの基本機能についてわかりやすく整理

## AWSbackupの基本用語
年末年始ではAWSbackupのルール変更と現時点でのバックアップを取得しました。以前からバックアップ関連については勉強したかったのでAWSbackupの基本知識の整理します。

### ●ボールト (Vault) 
バックアップデータを安全に保管するためのコンテナです。バックアッププランに従って作成されたバックアップデータは、指定されたバックアップボールトに格納されます。
バックアップしたスナップショットを保管している箱みたいなものです。

### ●復旧ポイント
ボールトでは復旧ポイント（Recovery point）で管理されます。
コンソールでは復旧ポイントIDと表示されてリソースIDと紐づいています。（これがEC2やRDS。）
　逆にEC2の対象のAMIからも確認ができます。イメージタイプの下にある「説明」に書いています。
復旧ポイントからリストアすることも可能ですが通常のスナップショットのリストアとはしているパラメータが異なる場合があるので要注意です。

シンプルにバックアップしたものをそれぞれのリソースと紐づけているだけのもの。

### ●アクセスポリシー
特定のユーザーに対してのみリストアを許可するなどのアクセス制限をしたい場合はアクセスポリシーで設定を行うことができます。（ボールトの復旧タブから設定できる。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1828177/794cc2c7-25ea-e582-5006-abfb0a86dbaf.png)

### ●バックアッププランの構造
backupプランの中に複数のバックアップルールを作成することができます。
バックアップルールの中でスケジュールや保存するボールトの指定、どのリソースをバックアップするかを選ぶことができます。
※バックアップ頻度をカスタムcron式を選択するとカスタマイズされたスケジュール制御を設定できる。

AWSの全体の構造をわかりやすく整理されている記事があるのでこちらも是非参考にしてみてください！

https://dev.classmethod.jp/articles/aws-backup-perfect-understand/


### ●バックアップ期間
バックアップジョブを開始する時間や完了させる時間を設定できます。

一つの例として下記に記します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1828177/9844d863-1d70-a7b2-9a97-6fc0a046564c.png)

・開始時間: 午前2時
・次の時間以内に開始: 2時間
・次の時間以内に完了: 6時間

この設定では、バックアップジョブは午前2時に開始され、
午前4時までに開始されます。
バックアップジョブは開始から6時間以内、つまり午前8時までに完了する設定になっています。

※バックアップ頻度をカスタムcron式を選択するとカスタマイズされたスケジュール制御を設定できる。


### ポイントインタイムリカバリ (PITR) のために継続的なバックアップを有効化

一言でいうとバックアップの巻き戻しを可能にするタイムマシンのような設定でしょうか。

リアルタイムでの稼働を求められ、かつ重要なシステム、もしくはDBを構築する際は設定しておいたが良さそうです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1828177/97ebf7b0-0236-fb06-1a4a-6539fc833f88.png)

例えば、以下のようなシナリオでバックアップを計画します。

・開始時間: 毎日午前2時
・次の時間以内に開始: 2時間
・次の時間以内に完了: 6時間

もしも午前10時にデータが誤って削除された場合、PITRを利用して午前9時の状態にデータベースを復元することができます。

一度リストアしその後、RDSのコンソールから
[アクション］-[特定時点への復元]で戻すことができます。

### ●ライフサイクル
バックアップを保存する期間を指定します。
この保持期間を経過すると自動で削除されます。

### バックアップインデックス - オプション
S3やEBSのインデックスをつけてそれぞれのファイルパスを検索ができます。
一言でいうとバックアップに対してファイルサーバーの検索機能を付けられるイメージ。
普段使っているファイルサーバーでファイルパスを検索できるのと同じですね。

## 参考にした技術ブログ
https://qiita.com/hamingcode/items/9674cc35b5e5b72781c3

https://dev.classmethod.jp/articles/aws-backup-perfect-understand/

https://docs.aws.amazon.com/ja_jp/aws-backup/latest/devguide/point-in-time-recovery.html

https://blog.serverworks.co.jp/30min-handson-pitr
100 マス計算アプリの VoiceOver 対応

## はじめに
年末に 100 マス計算アプリをつくりました！

https://apps.apple.com/jp/app/fast100math/id6739807220

100 マス計算アプリはいくつかあるのですが VoiceOver 対応がされているものは少ないんじゃないかなと思い対応してみました。
こんな感じです。

<iframe width="336" height="598" src="https://www.youtube.com/embed/t8gFnfEE6co" title="100マス計算アプリのVoiceOver対応" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

## VoiceOver 対応
やりたいことは下記です。

* 各ボタンを読み上げてほしい
* 「1 + 1 は？」のように問題を読み上げてほしい

![100math.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225999/30a1bad1-6399-4bbb-5217-c3953ff724f7.png)

上記画面は SwiftUI で作っており Text と Label だけ設定した Button だけなので基本的には何も設定しなくてもいい感じに読み上げてくれました。
マイナスボタンだけ対応が必要だったので以下のように対応しました。

```swift
Button("-") {
}.accessibilityLabel("マイナス")
```

このままだと縦横の「0 ~ 9」の Text も読み上げられるので読み上げられないように以下のように accessibilityHidden を設定しました。

```swift
Text("1").accessibilityHidden(true)
```

あとは問題文を読み上げてもらうだけです。全くやり方がわからなかったので ChatGPT に聞いてみたところ下記が使えそうでした。

https://developer.apple.com/documentation/uikit/uiaccessibility/post(notification:argument:)

問題回答時に正誤問わず下記を実装しました。「1 + 1 は？」とすると「は」と読み上げられたので「わ」にしています。

```swift
UIAccessibility.post(notification: .announcement, argument: String(format: "%1$lldたす%2$lldわ？", row, column))
```

### 課題
なぜかうまく読み上げてくれないときがあったのでよくわかりませんが遅延をいれると読み上げてくれるようになりました（0.01 とかにするとうまく機能しないときがあったので 0.1 にしています）。

```swift
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
    UIAccessibility.post(notification: .announcement, argument: String(format: "%1$lldたす%2$lldわ？", row, column))
}
```

画面表示時に最初の問題を読み上げてほしかったので onAppear にも同じ処理を入れているのですがうまく読み上げてくれません。。。なので今のところ一問目は一度何か解答しないと読み上げてくれません。

とりあえずはこれでそれっぽい読み上げをしてくれるようになりました:raised_hands:

## 動作確認（シミュレータ）
シミュレータで動作確認する場合は Accessibility Inspector を使うといいです。

シミュレータ起動後に Xcode > Open Developer Tool > Accessibility Inspector から起動できます。

![inspector.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225999/5192b261-dcd6-9e8b-7a37-5c1c70d76e7a.png)

下記のようにすると各パーツを読み上げてくれます。

1. シミュレータを選択
2. 対象のアプリを選択
3. 右上の吹き出しボタン選択

![inspector_voice_over.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/225999/dcf5f293-4733-569f-b642-97e04e481136.png)

## 動作確認（実機）
実機で動作確認する場合はまず下記を設定します。

設定アプリ > アクセシビリティ > ショートカットで VoiceOver をチェック。

![accessibility](https://github.com/user-attachments/assets/063a3e85-d7fd-4410-9d46-fddeeb706eb6)

これで iPhone のサイドボタンを 3 回押すと VoiceOver のオン・オフが切り替えられるようになります。
（ショートカットではなく一番上の VoiceOver をオンにすると戻し方がわからなくなるのでこっちの方が安心です）

iPhone のサイドボタンを 3 回押して動作を確認します。終わったらもう一度サイドボタンを 3 回押して完了です。

## おわりに
今まであまり VoiceOver 対応をしたことがないのでわからないことも多いのですがこれで最低限必要な部分は読み上げてくれるようになったはずです:grin:

ちょこちょこ更新つもりなのでよかったらアプリダウンロードしてください:bow:
JavaScriptによる関数の合成

## 関数定義
```js
function compose_funcs(f1, f2){
    return function(v){
        return f2(f1(v));
    };
}
```

## 呼び出し
```js
const result = compose_funcs(e => e + 2, e => e + 5)(100);
console.log(result);
```

## 表示結果
```text
107
```
生成AIも技術的負債をため込む

生成AIが生み出すコードは、その速度や利便性ゆえに技術的負債を蓄積しやすいです。

生成AIが **「指示を満たす」ことを優先** して目指すため、結果的に **継ぎはぎだらけのコード** が生まれ、運用や拡張が難しくなります。

人間のコーディングでも短期的な目標に偏ると技術的負債が発生しますが、生成AIのコーディングの速さは技術的負債の蓄積も速くしています。

生成AIを用いた技術的負債の効率的な解消方法を模索していきたいです。

# 生成AIがもたらすコードの現実

生成AIを使ってコードを生成していると、対話が進むほどに出力されるコードが次第に継ぎはぎだらけになります。

例えば、画面作成を依頼した際には便利に感じますが、バックエンドの実装や画面内のロジックが複雑化すると一気に管理が難しくなります。技術的負債が積み重なります。

生成AIは、与えられた指示に対して最速で実装を行います。人間に対して強いプレーシャーをかけて開発指示すれば同じことになります。生成AIも人間と同じです。コードの品質や長期的なメンテナンス性よりも、目先の要件を満たすことが優先されます。その結果、生成AIが生み出すコードは、構造が乱れたり、非効率的なパターンが繰り返されたりします。

# 技術的負債と生成AI

技術的負債はソフトウェア開発において避けられない側面のひとつです。生成AIが加速させているのは、この負債が蓄積されるスピードです。生成AIを使えば短時間で複雑なコードを生成できますが、その分だけコードの品質を管理する時間が圧縮され、結果的に運用や拡張が困難になるリスクが増します。

気になる点：

- 継ぎはぎコード: 段階的な指示に基づいて追加された部分が互いに矛盾する
- ロジックの分散: 各所に散らばった不統一なロジックや凝縮性のないコンポーネント
- 長期的視点の欠如: 短期的に動くコードが生み出されるが、将来的な変更に弱い

これらは生成AIだけの問題ではなく、人間のプログラマーでも、短期的な目標や納期を重視した場合には同様の負債が発生します。

生成AIに対して追加指示したら以前の指示を忘れられてしまう、という問題がよく起きるのは、生成AIのトークン数の問題だけではありません。継ぎはぎコードに対して修正をすると以前の要件とつじつまが合わなくなってしまい、人間でも犯すような不具合混入をさせてしまうのです。

プログラミング言語は人間が読み書きしやすいように進化してきました。生成AIは人間の生成物を学習しています。そのため、人間が犯しやすい間違いは生成AIでも同様です。

# 期待と現実のギャップ

生成AIは、その便利さから多くの期待を背負っています。実際、単純な画面作成やテンプレートコードの生成では非常に効果的です。しかし、開発が進むにつれて、その期待は現実の複雑さに直面します。技術的負債のリスクを高めます。

この問題を軽減するためには、生成AIを用いたリファクタリングや品質管理の手法を取り入れることが必要かもしれません。

生成AIが引き起こす期待からの揺り戻しを冷静に受け止め、長期的な視点を持ってその活用方法を模索していきたいと思います。

# 仲間募集！

生成AIを使った開発をしたいという仲間がいたら是非こちらをご覧ください！

https://note.com/ari_hr/n/n4aed9ba75421
Hyper-VのVMにワンライナーでログインする

# Hyper-VのVMにワンライナーでログインする

## はじめに

筆者はFreeBSDを日常的に使っていますが、デスクトップ環境はWindowsやmacOSを使っています。なのでFreeBSDを使う場合は、デスクトップ環境からssh等を使ってサーバーにログインするわけです。また筆者のWindowsノートPCには、手軽にFreeBSDを利用できるようにHyper-Vを使ったVM環境にFreeBSDを用意してあります。もちろんFreeBSDだけでなくLinux環境としてDebian/GNU Linuxも用意してあります。

## Hyper-VのVMを利用する

Hyper-VのVMを使う一つの方法は、Hyper-VマネージャーからVMに接続してコンソールからログインすることです。しかしこの方法ではクリップボードの利用に制限があって[^clip]扱いにくく、日本語の入力や表示もできません。そこでTera Term等のターミナルエミュレータのアプリケーションやssh.exe等で直接VMにログインすることになります。

[^clip]:コンソール表示のコピーは画像イメージになり、テキストだけのコピーできません。

## PowerShellからVMのIPアドレスを調べる方法

当たり前のことですがVMに直接ログインするには、VMのIPアドレスが必要です。しかしVMのネットワーク設定が「Default Switch」(通常はDefault Switchで、WindowsのIPアドレスを利用して外部への接続はNAT経由になる)の場合、Windowsの起動毎にVMのIPアドレスが変わるため、現在のIPアドレスを都度確認する必要があります。

VMのIPアドレスを知る方法としてはHyper-Vマネージャーを使う方法がありますが、アプリを起動してVMを選びネットワークを表示する手順が必要で少々煩雑です。

実はPowerShellには、VMのIPアドレスを調べるコマンドが用意されています。`Get-VMNetworkAdapter`でVM名を指定すればIPアドレスを表示できます。ただし`Get-VMNetworkAdapter`を実行するには管理者権限が必要なので、管理者権限でWindows Terminalを実行する必要があります[^admin]。

[^admin]:管理者権限のWindows Terminalを起動するキーボード操作は、[Win]+[X] を入力し[A]で選択するのが手っ取り早い。

```PowerShell
PowerShell 7.4.6
PS C:\Users\minmin> GET-VMnetworkAdapter -VMName minfreebsd

Name                    IsManagementOs VMName     SwitchName     MacAddress   Status IPAddresses
----                    -------------- ------     ----------     ----------   ------ -----------
ネットワーク アダプター False          minfreebsd Default Switch 00155D207102 {Ok}   {172.28.245.161, fe80::215:5dff:fe20:7102}

PS C:\Users\minmin>
```

見て明らかなように、IPAddressesでIPv4とIPv6の両方のアドレスを確認できます。

## PowerShellからワンライナーでVMにログインする

これをもう一歩進めて、ワンライナーでVMにログインしてみましょう。Select-Object を使えばIPAddressesだけを選択できます。

```PowerShell
PowerShell 7.4.6
PS C:\Users\minmin> Get-VMNetworkAdapter -VMName minfreebsd | Select-Object -ExpandProperty IPAddresses
172.28.245.161
fe80::215:5dff:fe20:7102
PS C:\Users\minmin>
```

さらにIPv4アドレスを抽出するためにWhere-Objectを使います[^string]。

[^string]:Where-Objectの代わりにSelect-Stringを使う方法もあります

```PowerShell
PowerShell 7.4.6
PS C:\Users\minmin> Get-VMNetworkAdapter -VMName minfreebsd | Select-Object -ExpandProperty IPAddresses | Where-Object { $_ -match "^\d{1,3}(\.\d{1,3}){3}$" }
172.28.245.161
PS C:\Users\minmin>
```

> なおIPv6アドレスであれば、Where-Objectのパラメータを`{ $_ -match ":" }`と変更して「:」(コロン)にマッチさせます。

IPv4アドレスを抽出できたので、あとはこれを () で囲んでssh.exeの引数にすれば、目的のVMにログインできます。

```PowerShell
PowerShell 7.4.6
PS C:\Users\minmin> ssh (Get-VMNetworkAdapter -VMName minfreebsd | Select-Object -ExpandProperty IPAddresses | Where-Object { $_ -match "^\d{1,3}(\.\d{1,3}){3}$" })
Last login: Thu Jan  9 07:19:52 2025 from mintest-cf-sx2.mshome.net
FreeBSD 14.2-RELEASE (GENERIC) releng/14.2-n269506-c8918d6c7412

Welcome to FreeBSD!

Release Notes, Errata: https://www.FreeBSD.org/releases/
<以下略>
```

PowerShellはコマンドラインヒストリーの編集が充実しているので、次からは [Ctrl]+[R] のリバースインクリメンタルサーチでVM名等を検索すれば再利用でき長いコマンドを入力する必要はありません。またsshまで入力すると直近のsshのコマンド行が補完できるので、同じVM名であればそのまま再利用できます。

(2025-03-14追記)
> このようにIPアドレスを調べて使わなくても、Hyper-Vで設定したVM名を使って`vmname.mshome.net`でアクセスできます。
【ChatGPT】夢を現実化するための行動を計画するPromptです。


　どうも、カーブミラーです。

　今回は、夢を現実化するための行動を計画するPromptです。

:::note info
本記事は、ChatGPT（Plus版）
で行なっております。
画像はありません。あしからず。
:::
　ChatGPT等の動作状況を知らせる
　　OpenAIのステータスページ。
　　　[OpenAIステータス](https://status.openai.com/)
***
　まずは、ニュースです。

　CES2025が
　　アメリカ・ラスベガスで
　　　開催されています。

　Consumer Electronics Show 2025は、
　　アメリカ時間2025年1月7日から
　　　10日まで開催される
　　　　世界最大級の
　　　　　テクノロジー展示会です。

　最新技術の発表の場で
　　多くの企業が参加・出展しています｡

　まだはじまったばかりですが、
　　その中心に
　　　AI技術があるのは
　　　　間違いありません。

　Copilot PCをはじめとする
　　AIを使う前提のハードウェア、
　　　専用CPUなど。

　自動運転やスマートホームや医療にも
　　AIが組み込まれています。
　　　もちろん、ロボットにも。

　どんなものが
　　出てくるのか
　　　楽しみですね。
***
　では、【本題】です。

　今回は、
　　夢を現実化するための行動を
　　　計画するPromptです。

　“夢”と書きましたが、
　　仕事でのプレゼンなども
　　　対象になります。

　夢を実現したい、と思っても
　　そのステップはぼんやりしていて
　　　具体性がありません。

　実現するために
　　何が必要なのか
　　　わからないことも多いはず。

　そこで
　　今回のPromptを使って、
　　　最低限必要なことを
　　　　得るようにしましょう。

　今回のPromptは
　　あくまでもそのレベルです。

　しかし、
　　その回答には、
　　　思わぬ示唆も
　　　　含まれています。

　あとは
　　そこから
　　　深掘っていけば、
　　　　夢を現実化させる力に
　　　　　なるのではないでしょうか。

　もちろん、
　　実行しなければ、
　　　絵に描いた餅にしかなりません。
　　　　頑張りましょう👍
***
　さて、Promptです。

　＊＊＊に夢を入れて、
　　送信してください。
```Text:夢を現実化するための行動計画Prompt
夢は「＊＊＊」です。この夢を現実化するために、以下のステップに従って行動を計画してください：

1. **ビジョンを明確化する**  
   - あなたの夢「{夢}」を具体的な言葉やイメージに変換してください。  
   - ゴールが何であるか、どのような状態になっているかを具体的に記述してください。

2. **逆算して計画を立てる**  
   - 最終的なゴール「{夢}」を達成するために必要な中間目標を設定してください。  
   - 中間目標をさらに小さなステップに分解してください。

3. **小さな行動を開始する**  
   - 今日からできる具体的な行動を1つ決めてください。  
   - 小さくても確実に進められる行動を習慣化してください。

4. **仮説を立てて試行錯誤する**  
   - 「この行動で夢に近づけるのか？」と仮説を立てて、実際に試してください。  
   - 仮説が正しいかどうか検証し、必要に応じて修正してください。

5. **継続しながら進捗を評価する**  
   - 定期的に進捗を確認し、達成度を測定してください。  
   - 修正が必要な部分を調整し、新しい行動を追加してください。

6. **現在に集中する**  
   - ゴールが遠く感じる場合でも、焦らずに「今できること」に集中してください。  
   - 毎日の行動がゴールへの積み重ねとなることを意識してください。

これらのステップを繰り返し、夢「{夢}」の実現に向けて行動してください。
```

　みなさんの
　　作品制作の糧に
　　　なれば、幸いです。

　今回は、ここまで。
SAMを用いた画像セグメンテーションの試み

今回はFacebook AI Researchが開発した「Segment Anything Model (SAM)」を用いて、画像から自動的にセグメントを生成する方法を共有します。

SAMは、任意の画像内のオブジェクトを検出しその領域をマスクとして抽出する高性能なモデルです。
https://segment-anything.com/

### 使用したコードの概要
以下では、画像セグメンテーションを行うためのコードを簡単に解説します。

必要なライブラリ
まず、以下のライブラリをインストールして準備します：
```ruby:qiita.rb
pip install torch matplotlib opencv-python pillow segment-anything
```

### モデルと設定の準備
SAMのモデルを読み込み、自動的にマスクを生成する設定を行います。
```ruby:qiita.rb
from segment_anything import sam_model_registry, SamAutomaticMaskGenerator

sam_checkpoint = "/path/to/sam_vit_h_4b8939.pth"  # モデルのチェックポイント
model_type = "vit_h"  # モデルのタイプ

# モデルをCPUにロード
sam = sam_model_registry[model_type](checkpoint=sam_checkpoint)
sam.to(device="cpu")

# マスク生成器の設定
mask_generator = SamAutomaticMaskGenerator(
    model=sam,
    points_per_side=32,
    pred_iou_thresh=0.98,
    stability_score_thresh=0.96,
    crop_n_layers=1,
    crop_n_points_downscale_factor=2,
    min_mask_region_area=500,
)
```
### 画像の読み込みとマスク生成
対象の画像を読み込み、マスクを生成します。
```ruby:qiita.rb
import cv2
import matplotlib.pyplot as plt

image_path = "/path/to/image.jpg"
image = cv2.imread(image_path)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

masks = mask_generator.generate(image)
print(f"Generated {len(masks)} masks.")

```
マスクの数や各マスクの詳細な情報を出力することができます。
```ruby:qiita.rb
for idx, mask in enumerate(masks):
    print(f"**** Mask Index: {idx} ****")
    print(f"- Area            : {mask['area']} pixels")
    print(f"- Bounding Box    : {mask['bbox']} [x, y, width, height]")
    print(f"- Predicted IoU   : {mask['predicted_iou']:.3f}")
    print(f"- Stability Score : {mask['stability_score']:.3f}")
```

### マスクの可視化
生成されたマスクを可視化して、画像上で確認します。
```ruby:qiita.rb
def visualize_masks(image, masks, num_masks=5):
    import numpy as np
    sorted_masks = sorted(masks, key=lambda x: x['area'], reverse=True)
    num_masks = min(num_masks, len(sorted_masks))

    plt.figure(figsize=(18, 12))
    for i in range(num_masks):
        plt.subplot(1, num_masks, i + 1)
        plt.imshow(image)
        mask = sorted_masks[i]['segmentation']
        plt.imshow(mask, alpha=0.5, cmap='jet')
        plt.title(f'Mask {i+1}\nArea: {sorted_masks[i]["area"]}')
        plt.axis('off')
    plt.show()

visualize_masks(image, masks, num_masks=5)
```

### 実行結果
画像のオリジナルとマスクされた領域を比較し、どのようにセグメントが生成されたか確認できます。

### 調整可能なパラメータ
1\. points_per_side: 探索点の密度を変更します。値を増やすと精度が向上しますが、計算時間も長くなります。
2\. pred_iou_thresh: マスク選択の精度を設定します。値を高くすると高品質なマスクのみを選択します。
3\. stability_score_thresh: マスクの安定性を調整します。値を低くすると検出領域が広がります。
4\. min_mask_region_area: 最小マスクサイズを設定します。小さい値にすると小さなオブジェクトも検出可能です。

SAMを使用することで簡単に画像からオブジェクトを検出しセグメント化することが可能です！みなさんもぜひ異なる画像やパラメータで試してみてください！
【TypeScript・JavaScript】型推論と動的型付けについて

:::note warn
TypeScript を学習し始めたばかりで至らない点があるかもしれませんがご容赦ください
:::

# はじめに
* TypeScript は JavaScript を包括した高級言語であることを知ったうえで「それなら JavaScript にもデータ型があるのに **なぜ型推論されないのだろうか**」と思いました
    * エディタツール上で JavaScript は型推論されないことに違和感

# 結論
:::note info
* TypeScript は静的型システムによって型チェックが行われている <br>また TSC、BABEL によって実行以前のコンパイル時にも精査される
    * **型推論** (静的型付け)
* JavaScript は JS エンジンがコード実行時に解釈している
    * **動的型付け**
:::
---
# JavaScript にも型はある
* 前提として TypeScript みたく明示的にデータ型を記述していないだけで JavaScript にもデータ型がある
    * 以下のコードでは一切「String 型である」という事を明示していないが、実行時に「str は String 型である」と決定されている

```javascript:sample1.js
const str = "string";
console.log(typeof str); //=> string
```

# 型推論と動的型付け
* 以下の引用先ドキュメントに大変分かりやすく説明されています

>　型推論はコンパイルのタイミングで型が決定され、その型が変更されることはありません。
　型をプログラマが書くかコンパイラが自動で決めるという点で違いがあり、あくまで静的型付けの世界に閉じた話になります。
>　一方、動的型付けでは実行時に型が決まるので、実行タイミングにより型が変化します。
【中略】
　このように実行タイミングで型が変化するので、型推論ではエラーになる処理も動的型付け言語では正常に動作します。

https://typescriptbook.jp/reference/values-types-variables/difference-between-type-inference-and-dynamic-typing

:::note info
### まとめ
* そもそも JS と TS の言語の違いとして「コンパイルをするか否か (静的型付け言語か否か)」という大きな違いがある
    * 言い換えれば「tsc、BABEL が解釈するか」「JS エンジン (ブラウザ) が解釈するか」の違い
* TS は 『コンパイラがコンパイル時にデータ型を決定する』ため、動的に型が変化するような挙動は許さない
    * その前提から「string 型のリテラルなのだから、この変数は string 型だろう」と推論してくれる
* JS は 『データ型はあるが実行時に決定する』ため、実装段階からデータ型の一貫性がなくとも問題ない
    * そもそもルールや前提としてデータ型に関する制約はない。よって不規則なので型推論ができない

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518714/5b064842-7775-c79c-961f-562765c29638.png)
:::


---
### 参考資料
https://devblogs.microsoft.com/typescript/a-proposal-for-type-syntax-in-javascript/

https://typescriptbook.jp/reference/values-types-variables/difference-between-type-inference-and-dynamic-typing
EXCELのスピル関数群を使って、縦に長いデータを段組みして表示させる

# やりたいこと
縦に長いデータを1段当たりの行数を指定して段組みする

#  サンプル
```A1:C12```のデータに対して```E1セル```に関数を入力して5行ごとのデータに段組みする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411106/8f7fff11-90f5-96b6-e80d-5d1d6d2fd710.png)
									
# セル関数
```
= LET(
行数, 5,
範囲, A1:C12,
列数, COLUMNS(範囲),
段数, ROUNDUP(ROWS(範囲)/行数,0),
拡張範囲, EXPAND(範囲,行数*段数,列数,""),
新範囲, WRAPCOLS(TOCOL(拡張範囲,,TRUE),行数),
列順, TOROW(SEQUENCE(列数,段数),,TRUE),
CHOOSECOLS(新範囲,列順)
)
```

# 数式の解説
| 項目 | 数式 | 説明 |
|------|-----|-----|
| 行数    | 5 | 1段当たりの行数を<FONT COLOR="RED">指定</FONT>
| 範囲    | A1:C12 | 段組み対象の元の範囲を<FONT COLOR="RED">指定</FONT>
| 列数    | COLUMNS(範囲)    | 1段あたりの列数を計算
| 段数    | ROUNDUP(ROWS(範囲)/行数,0)   | 指定行数から段数を計算
| 拡張範囲 | EXPAND(範囲,行数*段数,列数,"") | 全体の行数が指定行数の倍数になるように空白行を追加
| 新範囲  | WRAPCOLS(TOCOL(拡張範囲,,TRUE),行数) | 全体を1列に変換した後、指定行数ごとの範囲に再変換
| 列順  | TOROW(SEQUENCE(列数,段数),,TRUE) | CHOOSECOLSに与える列の並び順の配列を作成
| 完成    | CHOOSECOLS(新範囲,列順) | 並び替えた列順で最終的な並びを完成

# 数式の補足説明
## 行数・範囲
こちらの値を、データに合わせてその都度変更してください
例では元の列は３列ですが、汎用的になっているので、<FONT COLOR="RED">何列</FONT>でもその列数にあわせて段組みするようになっています
 

## 新範囲
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411106/2a444f2c-c608-e5b7-7f44-fc4f697b6a1e.png)

## 列順
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411106/3fc5bf3a-df3e-63db-fa35-ea5b3423127a.png)
自分で言うのもなんですが、この発想はかなりイケてると思いませんか？
そう思ってくださる人がもしおられましたら、コメントやいいねお願いします
CosmosDBのPythonSDKを使って、データを読み取る方法2種類

お疲れ様です。  
まだ、PythonのCosmosDBの記事って全然ないですね。

部分更新の記事も書きました。

https://qiita.com/taisyu6789/items/e21f40dcea83b1e5254a

## まずは、CosmosDBと接続
サンプルです。
```python
from azure.cosmos import CosmosClient, exceptions

# Cosmos DB の接続情報
ENDPOINT = "https://<your-account-name>.documents.azure.com:443/"
KEY = "<your-primary-or-secondary-key>"
DATABASE_NAME = "<your-database-name>"
CONTAINER_NAME = "<your-container-name>"

# クライアント作成
client = CosmosClient(ENDPOINT, KEY)

# データベースとコンテナ取得
database = client.get_database_client(DATABASE_NAME)
container = database.get_container_client(CONTAINER_NAME)

```
## CosmosDBで検索する方法  
CosmosDBでデータを検索する方法は主に以下の2種類があります。

1. **`query_items` メソッド**  
   - SQLライクなクエリを使用して、複数条件でデータを取得する。
2. **`read_item` メソッド**  
   - IDとパーティションキーが指定して、1件のドキュメントを効率的に取得する。

---
### `query_items` メソッド

#### 特徴
- **SQLライクなクエリで検索**:  
  WHERE句を使用して条件に一致するドキュメントを取得できます。
- **複数条件の検索が可能**:  
  パーティションキーが分からない場合でも全パーティションを検索できます。

#### デメリット
- 全パーティションをスキャンするため、`read_item` よりも効率が低い。
- RUの消費量が増加する可能性がある（データ量やパーティション数に依存）。

#### 使い方
以下は `query_items` を使用したサンプルコードです。
cは何でもいいですが、なにかテーブル名の代わりになるものが必要っぽいです。

```python
query = "SELECT * FROM c WHERE c.id = @id"
parameters = [{"name": "@id", "value": "my-document-id"}]

items = container.query_items(
    query=query,
    parameters=parameters,
    enable_cross_partition_query=True  # パーティションキーが不明な場合に有効化
)

for item in items:
    print("取得したドキュメント:", item)
```

### `read_item` メソッド

#### 特徴
- **単一ドキュメントを直接取得**:  
  ドキュメントのIDとパーティションキーを指定することで、インデックスを活用した高速な検索が可能です。
- **効率が高い**:  
  RU（Request Units）の消費が少なく、1回のリクエストで通常1RU未満です。

#### メリット
- パフォーマンスが非常に高い
- コストが低い（RU消費が最小限）
- 単一ドキュメントを特定する場合に最適

#### 使い方
以下は `read_item` を使用したサンプルコードです。

```python

# ドキュメントのIDとパーティションキー
DOCUMENT_ID = "my-document-id"
PARTITION_KEY = "my-partition-key"

try:
    # ドキュメントを取得
    document = container.read_item(item=DOCUMENT_ID, partition_key=PARTITION_KEY)
    print("取得したドキュメント:", document)
except exceptions.CosmosHttpResponseError as e:
    if e.status_code == 404:
        print("ドキュメントが見つかりませんでした。")
    else:
        print("エラーが発生しました:", e)
```

以上です。
特定1件のデータを取得したい場合は、read_itemを使った方がいいですね。
フロントエンドエンジニアのワイ、最近業務で使ったReact Hooksについてまとめてみた

## はじめに
普段の業務でなんとなく使用していたReact hookに関して、おさらいの意味も込めてざっくりとまとめてみることにした（遅い）

## useState
useState は状態（state）を管理するためのフック。コンポーネント内で状態を定義し、その値を更新する方法を提供している。

**できること**
 - 値の状態管理（数値、文字列、配列、オブジェクトなど）
 - 状態の変更による再レンダリング

**サンプルコード**
```typescript:index.tsx
import React, { useState } from 'react';

const Counter = () => {
  const [count, setCount] = useState(0); // 状態の初期値を 0 に設定

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
};

export default Counter;
```


## useEffect
useEffect は副作用（side effect）を処理するためのフック。副作用とは、データの取得、サブスクリプション、DOM の操作など、レンダリングの外で何かを実行する必要がある操作を指す。

**できること**
 - データのフェッチ（API呼び出しなど） 
 - DOM操作
 - タイマーの設定、クリーンアップ

**サンプルコード**
```typescript:index.tsx
import React, { useState, useEffect } from 'react';

const Timer = () => {
  const [seconds, setSeconds] = useState(0);

  useEffect(() => {
    const interval = setInterval(() => {
      setSeconds((prev) => prev + 1);
    }, 1000);

    // クリーンアップ処理
    return () => clearInterval(interval);
  }, []); // 空配列を渡すと、コンポーネントのマウント時のみ実行

  return <div>Seconds: {seconds}</div>;
};

export default Timer;
```


## useRef
useRef は、DOM 要素や値を参照するためのフック。React の再レンダリングに影響を与えない値を管理できる。


**できること**
 - DOM要素への直接アクセス
 - 値の永続的な保存（再レンダリングしても値がリセットされない）
 - フォーカス制御やスクロール制御

**サンプルコード**
```typescript:index.tsx
import React, { useRef } from 'react';

const FocusInput = () => {
  const inputRef = useRef<HTMLInputElement>(null);

  const handleFocus = () => {
    inputRef.current?.focus(); // input 要素にフォーカスを当てる
  };

  return (
    <div>
      <input ref={inputRef} type="text" placeholder="Type here..." />
      <button onClick={handleFocus}>Focus Input</button>
    </div>
  );
};

export default FocusInput;
```


## まとめ
これまで書いて機能たちをテーブルにしてまとめてみた。
| フック   | 主な用途 | 再レンダリングへの影響 |
|:--------------|:-----------|:-----------|
| useState　 | 状態管理（値が変わると再レンダリング）  | あり         |
| useEffect  | 副作用の処理（データ取得やクリーンアップ）| 状況によりけり |
| useRef 　| DOM要素や値の参照、再レンダリングの影響を受けない値の管理   | なし   |