OmniAICreator/Qiita-1.07M huggingface dataset:
Emacsでパッケージマネージャーって使ったほうがいいの？

## 短い答え

- 使ったほうがいい

## 長い答え

1. 最終的にはEmacsの設定を書くのにパッケージマネージャーを使ったほうがよい
1. とはいえ、パッケージマネージャーを使う難しさもあり、最初は使わず初めてみるのもよいと思う

## Emacsの設定はどんなものか

Emacsの設定はEmacs Lispというプログラミング言語で行います。
例えば、`~/.config/emacs/init.el`など[^init.el]に以下のように書きます。

[^init.el]: `~/.emacs.d/init.el`でもよい。`~/.emacs.el`や`~/.emacs`でもよいが、Emacsが自動生成するファイルも設置されるため、`~/.config/emacs/`や`~/.emacs.d/`でディレクトリを切るほうがよい。 https://www.gnu.org/software/emacs/manual/html_node/emacs/Find-Init.html

```elisp
;; 設定変数をセット
(setq hoge-enabled t)

;; プログラミング言語なので、関数や計算もできる
(defun hoge-levelup (x)
  (+ x 1))
(setq hoge-level (hoge-levelup (5))
```

## 各種パッケージのREADMEにおける設定の現状

パッケージによってREADMEの設定の書き方はバラバラです。
例えば、以下ような種類が考えられます。
パッケージマネージャーを使う・使わないで全然違う書き方になります。

```elisp:生書きの例
;; M-x package-install RET hoge RET
(setq hoge-fuga t)
(require 'hoge)
```

```elisp:use-packageを使った例
(use-package hoge
  :ensure t
  :config
  (setq hoge-fuga t))
```

```elisp:leafを使った例
(leaf hoge
  :ensure t
  :require t
  :config
  (setq hoge-fuga t))
```

## 現状におけるパッケージマネージャを使う難しさ

自分の手元設定とそろった書き方で設定がREADMEに記載されていれば簡単です。
そうでない場合は、自分で翻訳する必要があります。

具体的には、`macrostep-expand`[^macrostep]や`leaf-expand`などを使い、READMEに従った設定を書けているか確認する必要があります。

[^macrostep]: Emacs Lipsのマクロを展開プレビューしてくれるパッケージ。 https://github.com/joddie/macrostep

例えば、leafが用意している`leaf-expand`を使うと[^leaf-expand]、というコマンドを用意しています。
これを使うと、自分が書いたleaf節がどのように展開されるのかを確認できます。

[^leaf-expand]: 展開したいマクロの上にカーソルを置き`M-x leaf-expand`を実行すると、`*Leaf Expand*`という新しいバッファにマクロ展開結果を表示してくれる。

インストール処理など多少の差異はありますが、ほぼ生書きと同じ設定なのが確認できます。

```elisp:leafの例をleaf-expandした様子
(leaf hoge
  :ensure t
  :require t
  :config
  (setq hoge-fuga t))

;; --------------------------------------------------------------------------------

(prog1 'hoge
  (leaf-handler-package hoge hoge nil)
  (require 'hoge)
  (setq hoge-fuga t))
```

## パッケージマネージャーを使う利点

最初に利用を推奨したように、パッケージマネージャーには多くの利点があります。
多少の難しさはありますが、楽しいEmacs Lispプログラミングが可能です。

- 繰り返しでてくる定番フレーズを短く書ける
  - `(custom-set-variables hoge-fuga t)`→`:custom (hoge-fuga . t)`
  - 他にもhookやbindなど便利な設定マクロがある
- 構造化され読みやすい
- デバッグが容易になる
  - 例えば、特定の設定ブロックをまとめてdisabledしたりできる

## まとめ

パッケージマネージャーは確かに使ったほうがいいです。
とはいえ最初から100点満点を目指すのも大変です。
なので、初心者の皆さんが少しずつEmacsに慣れてもらえればと思います。

わからないことはemacs-jpのSlackなんかで聞くと答えてもらえると思います！

https://emacs-jp.github.io/
Flutterにコントリビュートしてみた ~OSSコントリビュートのすすめ~

# はじめに
こんにちは。
Flutterにコントリビュートしてみたので、その流れや感想などを書きます！
(ドキュメントの修正しかしていないけど、これも立派なコントリビュート！)

# コントリビュートしようとおもった理由

- そのOSSを深く知ることができると思ったから
    - 何かひとつ深く知れば他の技術にも活かせるはず！という考え
- 外部の人に自分のコードをレビューしてもらえるから（今回コード書いてないけど😽
- なんかカッコ良いから

# コントリビュートまでの流れ

ざっくりこんな流れだと思います。

1. コントリビュートしたいOSSを見つける
2. コントリビュートのルールを確認する
3. 挙がっているIssueからできそうなものを見つける
4. コード/テスト書く
5. PR(プルリクエスト)を作成する
6. レビュー/マージ


## 1. コントリビュートしたいOSSを見つける

まずはOSS見つけましょう！自分が好きなOSSで良いと思います。
普段からお世話になっているOSSでも良いし、コントリビュートが活発に行われているOSSに挑戦するのも良いと思います。

僕はFlutterにしました。

## 2. コントリビュートのルールを確認する

OSSによってコントリビュート時のルールが違うと思います。
コントリビュートが活発なOSSであれば資料があると思うので読みましょう。
不明点があればすぐに資料を確認するのが大事だと思います。

flutterもコントリビュート用の資料がありました。その中に環境構築のやり方やスタイルガイド(コーディングルール)なども詳細にまとまっており、わかりやすかったです。
また、何かわからなければdiscordで質問できるような環境でした。


## 3. 挙がっているIssueからできそうなものを見つける
これが結構難しいです。特にあまり使ったことないOSSだと、どのIssueなら直せそうか判断しづらい気がします。
Flutterではissueのラベルがとても参考になりました。

### できそうなIssueを見つける戦略

ここで僕がコントリビュートする時のIssue発見戦略をご紹介します。
Flutterでの話をしますが、他のOSSでも大体通用するはずです。

### ①「good first issue」ラベルの付いたIssueから見つける

最初のコントリビュートとして取り組みやすいIssueにこのラベルが貼ってありました。

### ②「regression」ラベルの付いたIssueから見つける

デグレが起きているバグにはこのラベルが貼られていました。
コミットを遡れば直す場所がわかりやすいのでは？

### ③ドキュメント関連のIssueを見つける

typoしてるとか、リンク切れしているとか色々ありますが、これが一番簡単かも。


たまに公式ドキュメントのリンク切れを見つける時があると思います。
そんな時はコントリビュートのチャンス！！

:::note info
着手するIssueが決まったら、「これ僕がやります！」みたいにコメントで宣言するか仮のPRを作っておくのが良さそうです。簡単なIssueほど他の人もすぐに着手すると思うので。
このへんもOSSによってルールがあるかも知れません。
:::

## 4. コード/テスト書く
Issueが見つかったらコード・テストを書いていきます。

## 5. PR(プルリクエスト)を作成する
完成したら、いよいよPRを作成します。
PRのテンプレートがある場合はそれに従ったり、コントリビュートガイド見たり、他のPRの真似したりして概要を埋めます。

## 6. レビュー/マージ
PRを作成したらレビューしてもらいます。

レビュー依頼方法もOSSによって違うと思いますが、
Flutterの場合は依頼しなくてもレビューしてくれました。
googleの人にレビューしてもらうときは少し緊張しました😆

また、レビューが済んだら自動的にmasterへマージされました🎉🎉

レビュー/マージ関連もコントリビュートの資料に書いてありました。

# 最後に
大雑把な流れを書きましたが、いかがでしたでしょうか？

コントリビュート用の資料がとても参考になったので、皆さんも迷ったらすぐにそのOSSの資料を見ることをおすすめします。もしくは管理者に質問するなど。

次はコードの修正に挑戦します！！
Let's try!
Windows11 PowerShell のみで GeminiをAPI実行

# はじめに

API利用未経験でつまづいたので、これから始める方のためにも情報共有します。

(24年8月 現在) GemeiniのAPI実行は一定の回数まで無料で利用することができます。
簡単な個人アプリなどの利用では十分だと感じ個人開発に組み込みました。

次回の記事でアプリでの実行について紹介し、
今回は**PythonやNodeJSを利用せずに、コマンドのみを使って実行テストをする**チュートリアルとします。

以下の３ステップをコピー、修正して実行を確認しましょう。

## 0.APIキーの取得

[Google AI Studio](https://aistudio.google.com/app/prompts/new_chat)
にて画面左上の Get API Key をクリックしAPIキーをコピーする。

![GetAPIKey.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3734047/562568f5-63d9-867a-d89b-a80cea07453d.png)

## 1. 初期処理をします。
    
:::note info
コマンドの改行コードについて
Windowsのメモ帳で改行を打つと 「CRLF (\r\n)」になります。
そうすると1行ごとに実行してしまい正しく処理が書けません。
改行コードは「LF (\n)」になるように Sakuraエディタなどを
活用して変換しましょう。
:::

```powershell:Init
    ## ここにAPIキーを入力してください。(毎回コピーしなくていいように)
    $API_KEY = "YOUR_API_KEY"
    
    ## headersの設定をします。
    $headers = @{
        "Content-Type" = "application/json"
        "x-goog-api-key" = $API_KEY
    }
```
    
## 2. プロンプトを入力します。
    
:::note warn
警告
ここでのAPI実行は日本語でのプロンプト実行ができません。
英語でプロンプトを書いてください！

(以下、日本語使用時のエラーメッセージ)
It seems you've provided a string of question marks. 
Could you please tell me what you'd like to kn...
:::

```powershell:Prompt
    $body = @{
        contents = @(
            @{
                role = "user"
                parts = @(
                    @{
    		            ## 英語でプロンプトを入力
                        ##text = "豚肉を使った晩ごはんの献立を考えてください。"
                        text = "Think about a dinner menu that uses pork."
                    }
                )
            }
        )
    } | ConvertTo-Json -Depth 10
```
    
## 3. Gemini1.5ProをAPI実行する。
    
```powershell:Execute
    Invoke-WebRequest `
        -Uri "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-pro:generateContent" `
        -Method Post `
        -Headers $headers `
        -Body $body `
        -ContentType "application/json"
```

### 3.1 実行結果を確認する。
**StatusCode: 200** と 帰ってきたら通信成功で、
Content内の "text"に回答が来ています。

PowerShell実行での回答は先頭の一部のみ表示され、
英語で表示されています。

```powershell:Execute_Err
	StatusCode        : 200
	StatusDescription : OK
	Content           : {
	                      "candidates": [
	                        {
	                          "content": {
	                            "parts": [
	                              {
	                                "text": "## A Pork-Centric Feast \n\n**Appetizer:**\n\n* **Crispy Pork Belly Bites with
	                     Spicy Apricot Glaze:** T...
	RawContent        : HTTP/1.1 200 OK
```

# おわりに
はじめての記事投稿になりますがいかがでしょうか。

**先頭の一部のみ表示され英語で表示されるなど調査が甘いところはあります。**
しかし、目的のAPI実行できるかの確認には十分かと思い投稿しました。

次回はプログラムに実装する方法を投稿します。
(回答は途切れず質問文の言語で返ってきます。)

お楽しみに！
コーディング環境を整えよう（可愛い編）

# はじめに
今回は技術的な記事ではありません。
vscodeでコーディングの際に、ちょっと幸せになれる拡張機能を見つけたのでおすそ分けします。
既に知っている方、使っている方がいたら(｡-人-｡) ｺﾞﾒﾝﾈ

# その名も「bongo cat」
まずはvscodeの拡張機能の検索欄で**bongo cat**と検索してみてください。

![スクリーンショット 2024-08-05 22.44.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524375/d499fe7a-fe07-76b4-8bd6-2c0002fc850c.png)

はい。猫ちゃんが出てきますね。
どちらでもいいんですが、**bongo cat buddy**の方がおすすめです。
どういう拡張機能かというと実際に見ていただいた方が早いです。

![bongocat.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524375/a234186b-a263-9077-c29b-71396bc8059f.gif)

いかがでしょうか。
タイピングする度に猫ちゃんがペシペシ！と叩いてくれます！！！！！！
コマンドパレットを開いて、`bongo cat`と入力すると猫ちゃんが現れます。
これで、あなたのコーディング環境に可愛いがやってきましたね。めでたしめでたし。

# まとめ
少しでも皆様のコーディング環境が良くなれば幸いです。
他にも可愛いものがあれば紹介してください！
それでは！！！
PythonでWebスクレイピングを行うアプリの作り方

## はじめに
Webスクレイピングは、ウェブサイトからデータを自動的に取得するための技術です。

Pythonはこのタスクに非常に適しており、強力なライブラリが揃っています。

本記事では、Pythonを使用してWebスクレイピングアプリを作成する方法を紹介します。

## 1. 必要なライブラリのインストール

まず、Webスクレイピングに必要なライブラリをインストールします。主に使用するライブラリは以下の通りです：

- `requests`: HTTPリクエストを送信するためのライブラリ
- `BeautifulSoup`: HTMLやXMLのパースに使用するライブラリ
- `pandas` (オプション): データを整形し、保存するためのライブラリ

以下のコマンドでこれらのライブラリをインストールします。

```bash
pip install requests beautifulsoup4 pandas
```

## 2. スクレイピング対象のウェブサイトを決定する
スクレイピングを行うためには、対象のウェブサイトと取得したいデータを決定します。本記事では、例として「架空のニュースサイト」を使用します。

## 3. HTMLコンテンツを取得する
requestsライブラリを使用してウェブサイトからHTMLコンテンツを取得します。

```python
import requests

url = 'https://example.com/news'
response = requests.get(url)

if response.status_code == 200:
    html_content = response.text
else:
    print('Failed to retrieve the webpage.')
```

## 4. HTMLコンテンツをパースする
取得したHTMLコンテンツをBeautifulSoupでパースし、必要なデータを抽出します。

```python
from bs4 import BeautifulSoup

soup = BeautifulSoup(html_content, 'html.parser')

# ニュースタイトルを取得する例
titles = soup.find_all('h2', class_='news-title')
for title in titles:
    print(title.text)
```

## 5. データの保存（オプション）
データをCSVファイルに保存するために、pandasを使用することができます。

```python
import pandas as pd

data = {'Title': [title.text for title in titles]}
df = pd.DataFrame(data)

df.to_csv('news_titles.csv', index=False)
```

## 6. 完全なコード例
以下に、全てのステップを含む完全なコード例を示します。

```python
import requests
from bs4 import BeautifulSoup
import pandas as pd

# スクレイピング対象のURL
url = 'https://example.com/news'

# HTMLコンテンツを取得
response = requests.get(url)
if response.status_code == 200:
    html_content = response.text
else:
    print('Failed to retrieve the webpage.')
    exit()

# HTMLコンテンツをパース
soup = BeautifulSoup(html_content, 'html.parser')

# ニュースタイトルを取得
titles = soup.find_all('h2', class_='news-title')

# データを保存
data = {'Title': [title.text for title in titles]}
df = pd.DataFrame(data)
df.to_csv('news_titles.csv', index=False)

print('Data has been saved to news_titles.csv')
```

## まとめ
Pythonを使用したWebスクレイピングは、非常に強力で柔軟なツールです。

requestsとBeautifulSoupを組み合わせることで、簡単にウェブサイトからデータを抽出し、pandasを使ってデータを整形・保存することができます。

スクレイピングを行う際には、サイトの利用規約を守り、適切なエラーハンドリングを実装することを忘れないようにしましょう。
【React】propsで関数を受け渡す時はアロー関数でラップする

やらかしたので記録します。
アロー関数でラップしないと、描画時に該当の関数が実行されてしまうようです。

# 問題

任意のユニークキーを引数に受け取り、データベースから一致する行を削除するReactアプリを作成中でした。

```table.jsx
export const DataRow = ({ record, onClickDelete }) => {
    // 実際は他に各カラムのデータがある
    return(
            <button onClick={onClickDelete(record.id)}>削除</button>
    );
};
```

```App.jsx
const onClickDeleteRecord = (uniqueKey) => {
    const deleteRecord = async(key) => {
        // keyをデータベースから削除するコード
    };
    deleteRecord(uniqueKey);
    
    const newRecords = records.filter((rec) => rec === uniqueKey);
    setRecords(newRecords);
    setError("");
}
```

このコードを描画した所、一覧に何も表示されなくなってしまいました。
該当のコードを編集前に戻しても何も表示されず。
もしやと思ってDBを見てみたら、**データがすべて消えていました。** 

![スクリーンショット 2024-08-05 223759.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3815580/40d96c6d-393e-696e-1af4-52bfc215a766.png)

# 原因

propsの渡し方が間違っていました。
`onClick={onClickDelete(record.id)}`という渡し方をすると、描画時に実行されてしまうようです。

https://stackblitz.com/edit/vitejs-vite-cvbvp9?file=src%2Fcompornents%2FOnClickChildren.jsx

# 解決

アロー関数でラップすると、クリック時に呼び出されます。

```table.jsx
export const DataRow = ({ record, onClickDelete }) => {
    return(
            <button onClick={() => onClickDelete(record.id) }>削除</button>
    );
};
```

https://stackblitz.com/edit/vitejs-vite-jema29?file=src%2Fcompornents%2FOnClickChildren.jsx

# 最後に

DBデータが飛んだのは焦りました、気を付けようと思います。
ほぼ作りたての環境で良かったです。
Visual Studio Codeのソース管理で表示されるGitの履歴を非表示にする方法

# いきなり結論

設定画面で`scm.showHistoryGraph`のチェックを外す、以上。

## 詳しく

Ver.1.92からの機能らしい。

下図のように表示されて履歴が視覚的にわかるらしいが、Git Graphが手に馴染んでいるので私は使わない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310702/677bb4e0-12ab-79ab-f4de-c249709a3366.png)

> 画像は[localstack](https://github.com/localstack/localstack)のコミットログ

`scm.showHistoryGraph`でオフにできるらしいのでオフにした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310702/14202d9a-6e25-d5a1-8715-337207c47246.png)

これでスッキリ
Java関連概念まとめ集 (Hibernate, Thread, Lock)

### Javaのオブジェクトレベルロックとクラスレベルロック

**Object Level Locking**（オブジェクトレベルロック）と**Class Level Locking**（クラスレベルロック）は、マルチスレッド環境でデータの一貫性を維持するために使用されるJavaの2つの同期メカニズムです。

#### オブジェクトレベルロック：
- **範囲**: クラスの特定のインスタンス。
- **メカニズム**: 特定のオブジェクトをロックし、そのオブジェクトの同期メソッドやブロックに一度に1つのスレッドのみがアクセスできるようにします。
- **例**:
    ```java
    public class MyClass {
        public synchronized void instanceMethod() {
            // 同期インスタンスメソッド
        }

        public void someMethod() {
            synchronized(this) {
                // 同期ブロック
            }
        }
    }
    ```
- **使用方法**: 特定のクラスインスタンスに関連するデータを保護します。

#### クラスレベルロック：
- **範囲**: クラス全体。
- **メカニズム**: クラス自体をロックし、そのクラスの同期静的メソッドやブロックに一度に1つのスレッドのみがアクセスできるようにします。
- **例**:
    ```java
    public class MyClass {
        public static synchronized void staticMethod() {
            // 同期静的メソッド
        }

        public void someMethod() {
            synchronized(MyClass.class) {
                // 同期ブロック
            }
        }
    }
    ```
- **使用方法**: クラスのすべてのインスタンスに共有されるデータを保護します。

### CallableとRunnableの違い

**Callable**と**Runnable**は、複数のスレッドによって実行されるタスクを表すために使用されるJavaの2つのインターフェースです。

#### Callable：
- **戻り値の型**: タイプVの結果を返すことができます。
- **メソッド**: 例外をスローできる`call()`。
- **使用方法**:
    ```java
    import java.util.concurrent.Callable;

    public class MyCallable implements Callable<Integer> {
        @Override
        public Integer call() throws Exception {
            // タスクを実行
            return 123;
        }
    }
    ```

#### Runnable：
- **戻り値の型**: Void。
- **メソッド**: 例外をスローできない`run()`。
- **使用方法**:
    ```java
    public class MyRunnable implements Runnable {
        @Override
        public void run() {
            // タスクを実行
        }
    }
    ```

### HibernateのGetとLoadの違い

**Get**と**Load**は、Hibernateでエンティティを取得するために使用されるメソッドです。

#### Get：
- **ローディング**: 即時。
- **戻り値**: エンティティオブジェクトまたはnull。
- **例外**: エンティティが存在しない場合、例外をスローしません。
- **使用方法**: エンティティが存在しない可能性がある場合。
    ```java
    Session session = sessionFactory.openSession();
    MyEntity entity = session.get(MyEntity.class, 1);
    session.close();
    ```

#### Load：
- **ローディング**: 遅延（プロキシを返します）。
- **戻り値**: プロキシオブジェクトまたはエンティティオブジェクト。
- **例外**: エンティティが存在しない場合、`ObjectNotFoundException`をスローします。
- **使用方法**: エンティティが存在すると仮定する場合。
    ```java
    Session session = sessionFactory.openSession();
    try {
        MyEntity entity = session.load(MyEntity.class, 1);
    } catch (ObjectNotFoundException e) {
        // 例外を処理
    }
    session.close();
    ```

このドキュメントは、オブジェクトレベルロックとクラスレベルロックの概要、CallableとRunnableの違い、HibernateのGetとLoadメソッドの違いについての包括的な説明を提供します。
JavaのDIの種類とその違いについて

# はじめに
Javaによるオブジェクト指向開発を行うときに必ず出てくるのがDI(Dependency Injection）です。
DIは依存性の注入と訳され、オブジェクトの依存関係を外部から注入することで、コードの結合度を下げ、テストしやすく、保守性の高い設計を可能にします。

DIにはいくつか種類があってそれぞれ特徴があります。
今回はDIについて説明します。

# 1. コンストラクタインジェクション
コンストラクタを通じて依存性を注入します。


依存するオブジェクトはコンストラクタの引数として渡されるため、オブジェクトが生成されるときに必要な依存性が全て設定されます。

### 特徴:

* 依存性が不変であるため、オブジェクトが一度作成されるとその依存性は変更されません。
* コンストラクタが複雑になる可能性がありますが、依存性が全て揃っていることが保証されます。

```java
public class Service {
    private final Repository repository;

    public Service(Repository repository) {
        this.repository = repository;
    }

    // ビジネスロジック
}
```

# 2. セッターインジェクション

セッターメソッドを使用して依存性を注入します。
オブジェクトが生成された後、セッターメソッドを呼び出すことで依存性を設定します。

### 特徴

* 依存性がオプションであり、オブジェクトが作成された後に依存性を設定できるため、柔軟性があります。
* 必要な依存性が設定されていない可能性があるため、セッターメソッドを使う際には注意が必要です。

```java
public class Service {
    private Repository repository;

    public void setRepository(Repository repository) {
        this.repository = repository;
    }

    // ビジネスロジック
}
```

# 3. フィールドインジェクション
フィールドに直接依存性を注入します。
通常、Javaの依存性注入フレームワーク（例えば、Spring）ではアノテーションを使用して依存性を注入します。

### 特徴

* コードが簡潔になりますが、依存性がクラスの状態として直接注入されるため、テストが難しくなる可能性があります。
* 依存性が非公開フィールドとして扱われるため、カプセル化の原則が破られることがあります。

```java
public class Service {
    @Autowired
    private Repository repository;

    // ビジネスロジック
}
```


# 4. インターフェースインジェクション
インターフェースを通じて依存性を注入します。
依存するクラスはインターフェースを実装し、そのインターフェースを通じて依存性を注入されます。

### 特徴

* より明示的な依存性注入が可能になりますが、インターフェースの設計が必要です。
* 他のDIの種類に比べて少し複雑な実装になります。

```java
public interface RepositoryAware {
    void setRepository(Repository repository);
}

public class Service implements RepositoryAware {
    private Repository repository;

    @Override
    public void setRepository(Repository repository) {
        this.repository = repository;
    }

    // ビジネスロジック
}
```


# まとめ
* コンストラクタインジェクションは依存性が必須である場合に推奨されます。
* セッターインジェクションは依存性がオプションである場合に適しています。
* フィールドインジェクションはコードの簡潔さを重視しますが、テスト性の問題がある可能性があります。
* インターフェースインジェクションは依存性の明示的な管理が必要な場合に使用されます。


それぞれのDIの種類には利点と欠点があり、具体的な要件やプロジェクトの状況に応じて適切な方法を選ぶことが重要です。
Mackerelのログ監視で"を含めたパターンで監視する方法

## 概要
Mackerelのログ監視で下記のように`"`で囲まれた文字を対象にする方法をご紹介します。

```
{"level":"error" XXXX}
```

## 解決策

下記のように`”`を`.`に置き換えることでログ監視ができるようになります。

```
command = ["check-log", "--file", "/var/log/access.log", "--pattern", ".level.:.error."]
```


## 背景
監視対象のログファイルで、ログレベルが `info` であるにもかかわらず、`error` が書き込まれることがあるため、ログレベルが`error`のログのみを監視する必要がありました。

Mackerelのログ監視設定では、`"`をエスケープした場合でWarningが発生し、ログ監視を行うことができませんでした。

そこで、`.`を使用し、`"`を使用しない設定に変更しました。
```
command = ["check-log", "--file", "/var/log/access.log", "--pattern", "\"level\":\"error\""]
```
光のための数学



```
import numpy as np
import matplotlib.pyplot as plt

# 光束 (ルーメン)
luminous_flux = 1000  # 例: 1000ルーメンの光束

# 距離 (メートル)
distance = np.linspace(0.1, 10, 500)  # 0.1mから10mまでの500点

# 照度 (ルクス)の計算
# 照度 = 光束 / (4 * π * 距離^2)
illuminance = luminous_flux / (4 * np.pi * distance**2)

# プロット
plt.figure(figsize=(10, 6))
plt.plot(distance, illuminance, label='Illuminance (lux)', color='blue')
plt.xlabel('Distance (meters)')
plt.ylabel('Illuminance (lux)')
plt.title('Illuminance vs. Distance from Light Source')
plt.grid(True)
plt.legend()
plt.show()
```


```
import numpy as np
import matplotlib.pyplot as plt

# 実際の測定データ (例: 照度計で取得したデータ)
# 距離 (メートル)
distance_measured = np.array([0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5])
# 照度 (ルクス)
illuminance_measured = np.array([4000, 1000, 444, 250, 160, 111, 81, 63, 50, 40])

# 照度データのプロット
plt.figure(figsize=(10, 6))
plt.plot(distance_measured, illuminance_measured, 'o-', label='Measured Illuminance (lux)', color='red')
plt.xlabel('Distance from Light Source (meters)')
plt.ylabel('Illuminance (lux)')
plt.title('Measured Illuminance vs. Distance')
plt.grid(True)
plt.legend()
plt.show()


```



```
import numpy as np
import matplotlib.pyplot as plt

# 照明器具の位置 (x, y)
light_positions = [(2, 2), (6, 2), (4, 6)]

# 照度の計算
def illuminance_at_point(x, y, light_positions, intensity=1000):
    illuminance = np.zeros_like(x)
    for (lx, ly) in light_positions:
        distance = np.sqrt((x - lx)**2 + (y - ly)**2)
        illuminance += intensity / (distance**2 + 1e-10)  # Avoid division by zero
    return illuminance

# グリッドの設定
x = np.linspace(0, 8, 200)
y = np.linspace(0, 8, 200)
X, Y = np.meshgrid(x, y)
Z = illuminance_at_point(X, Y, light_positions)

# 照明の分布プロット
plt.figure(figsize=(10, 8))
plt.contourf(X, Y, Z, levels=100, cmap='hot')
plt.colorbar(label='Illuminance (lux)')
plt.scatter(*zip(*light_positions), color='blue', marker='x', label='Light Positions')
plt.xlabel('X (meters)')
plt.ylabel('Y (meters)')
plt.title('Illuminance Distribution from Multiple Light Fixtures')
plt.legend()
plt.show()



```
```
import numpy as np

# 行列の定義
def propagation_matrix(d):
    return np.array([[1, d], [0, 1]])

def lens_matrix(f):
    return np.array([[1, 0], [-1/f, 1]])

# パラメータ設定
f1 = 100  # 焦点距離1 (mm)
f2 = 150  # 焦点距離2 (mm)
d = 200   # レンズ間の距離 (mm)

# 行列の計算
M1 = lens_matrix(f1)
M2 = propagation_matrix(d)
M3 = lens_matrix(f2)

# 合成行列の計算
M_total = M3 @ M2 @ M1

# 結果の表示
print("合成行列 M_total:")
print(M_total)
```


```


```

```


```
Android データセーフティの対応　2024年6月実施



# はじめに

こんにちは、エンジニアのkeitaMaxです。

Androidアプリを公開しているのですが、データセーフティを設定し直して欲しいと警告があったので対応方法について備忘録として書いておきます。

以下の記事を参考に行いました。

https://minpro.net/how-to-set-up-google-play-console-data-safety-when-using-admob-ads

このアプリは広告にAdmodを入れているのでその設定をしていきます。(広告以外特に個人情報などは取っていません。)



# データ収集とセキュリティ

まずデータ収集とセキュリティは以下のように設定します。

![スクリーンショット 2024-06-13 15.02.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715123/2cc6001b-6d81-3e7c-27f2-d74b84a01871.png)

設定すると次へボタンが押せるようになるので押して次画面を押します。

# データの種類

データの種類は以下４つを選択します。

![スクリーンショット 2024-06-13 15.04.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715123/ddd22cb8-1b06-3634-4b4c-4f980c1d1143.png)

![スクリーンショット 2024-06-13 15.05.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715123/081b93ed-de77-4916-56c5-d5fca15eac2c.png)

![スクリーンショット 2024-06-13 15.05.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715123/93df2877-1a72-d553-2bfa-daa88c3ff943.png)

![スクリーンショット 2024-06-13 15.05.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715123/65970601-82b2-7024-11de-b667bef8a92d.png)

選択が終わると次へを押せるようになるので押して次画面へいきます。

#　データの使用と処理

![スクリーンショット 2024-06-13 15.07.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715123/9c8abf3e-2d6f-3f04-7841-a66dbe68dd42.png)

開始を押して以下のように設定します。

![スクリーンショット 2024-06-13 15.07.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715123/f5c35377-47ed-1127-d503-355d380263c5.png)

これを前画面から選択したものすべてで行ってください。

全部終わると次へボタンが押せるようになるので指示に従ってください。


# 審査に出す

全部終わったら、審査に出せば大丈夫です。


# おわりに

この記事での質問や、間違っている、もっといい方法があるといったご意見などありましたらご指摘していただけると幸いです。

最後まで読んでいただきありがとうございました！

# 参考

https://minpro.net/how-to-set-up-google-play-console-data-safety-when-using-admob-ads
メモリの規格のPCx-yyyy-z-a-b-cについて

# メモリの規格のPCx-yyyy-z-a-b-cについて

## 概要

メモリの規格には、多くの種類が存在します。それぞれの規格には、ピン数や動作周波数、転送速度、エラー修正機能などが異なります。本記事では、PCx-yyyy-z-a-b-c形式のメモリ規格について説明します。

## ピンの数

メモリの規格によって、ピンの数が異なります。

- **DDR3**: 240ピン
- **DDR4**: 288ピン

## そもそもDDRとは？

DDRとは、規格の一つで、`DDR-SDRAM(ダブルデータレート同期動的ランダムアクセスメモリ)`を略したものです。DDRは`Double Data Rate(ダブルデータレート)`の略で、SDRAMは`Synchronous Dynamic Random Access Memory(同期動的ランダムアクセスメモリ)`を指します。

## チップ規格名とモジュール規格名

メモリには、チップ規格名とモジュール規格名があります。

- **DDR3-〇〇**や**DDR4-〇〇**: これはチップ規格名を表しています。
- **PC3-〇〇**や**PC4-〇〇**: これはモジュール規格名を表しています。

チップ規格名の〇〇部分は、チップの動作周波数を表しています。一方、モジュール規格名の〇〇部分は、転送速度（帯域幅）を表しています。

## PC3-10600△のように△が付いていた場合

メモリ規格名の後に付く△は、特定の機能や特性を示します。

- **E** -> ECC (Error-Correcting Code)
- **L** -> Low Voltage（低電圧）: 通常よりも低い電圧で動作し、省電力
- **P** -> Parity: パリティビットを使ってエラー検出
- **F** -> Fully Buffered DIMM (FB-DIMM): メモリモジュールにバッファチップを搭載
- **T** -> Thermal sensor（温度センサー）
- **M** -> Miller: ミラーリングされたメモリ

https://qiita.com/YukiTetsuka/items/91681f89d7e8c9c3ce29

## PC3-10600E-△のように△が付いていた場合

この形式では、CAS Latency（CL）を示します。CL値は、メモリがデータをリクエストしてから最初のデータが転送されるまでのクロックサイクル数を表します。CL値はクロックサイクルの合計数を表すに過ぎず、各クロックサイクル時間とは無関係です。

## PC3-10600E-9-△のように△が付いていた場合

この形式では、RAS to CAS Delay（tRCD）を示します。tRCDは、メモリの準備ができた後、メモリの読み取りに要するクロックサイクル数を表します。

## PC3-10600E-9-13-△のように△が付いていた場合

この形式では、JEDEC標準に準拠した特定のプロファイルや製品コードを示すメーカー固有の識別子を表します。

## まとめ

メモリの規格名は、さまざまな要素を表しています。これらの要素を理解することで、メモリの性能や特性をよりよく理解できるようになります。

## 参考文献
https://www.dospara.co.jp/5info/cts_str_parts_ddr4.html
https://contents.zaikostore.com/semiconductor/3923/
https://qiita.com/yamasaki1ma/items/9ad197da386ffd66275b
https://www.fmworld.net/cs/azbyclub/qanavi/jsp/qacontents.jsp?PID=1911-3491
https://akiba-pc.watch.impress.co.jp/docs/sp/1231939.html
[2024年]FlutterをiOS Simulatorでデバックがうまくいかなかった時の解決方法

Fluttterをやり始めて、最初のころはchromeでデバックしていたのですが
iOS Simulatorでデバックしようとしたところうまくいかず苦労したので、
解決方法をメモしておきます。

【環境】
・PC:Mac(OS: Sonoma ver14.6)
・Flutter: ver. 3.22.3
・エディタ: cursor

## 症状
本来は、Simulatorを起動させておいてcursorのデバイス選択からSimulatorを選択し、
![sdヴィっxっcえ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332453/aeccfdaf-cf45-5ab1-58aa-c767b37c219e.png)

"Flutter"を選択状態で三角ボタンを押してデバックを実行するだけでいけます。
![流ううn.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332453/392363a8-6c0e-642d-f9be-c09e914aa756.png)

ですが、自分の場合はそもそもデバイス選択にSimulatorが表示されていませんでした。

## 問題特定と対応

そこで、まず何が問題なのか調べるために下記のコマンドで確認します
```
flutter doctor
```
すると、このような結果になりました
![fidoctro.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332453/9f281d10-0e9a-0be1-2bf0-1909810d9f8f.png)
エラー(赤い×マーク)が2つ出ていますね。
①Xcode installation is incomplete; a full installation is necessary for iOS and macOS development.
②CocoaPods not installed.

①はXcodeが最新でないとダメなようです。App Storeでバージョンアップしました。
その後、次の2つのコマンドをhomeディレクトリで実行します。
```
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
```
```
sudo xcodebuild -runFirstLaunch
```

②は、"CocoaPods"がインストールされてないとのことでした。
下記でインストールします。
```
sudo gem install cocoapods
```
これで、デバイス選択からSimulatorを選択できるようになりました。

ところがデバック開始しても途中で処理がうまくいかず・・・・。

調べてみると、FlutterプロジェクトのiosのPodfileの中の下記を編集する必要がありました。
```
platform :ios, '13.0' 
```
数字の部分を13.0に描き抱えました。
そもそも、自分の場合はデフォでコメントになっていたのでコメントアウトしました。

これでデバックできるようになります。
(初回はSimulatorの中にFlutterアプリを追加するような処理が走るため時間がかかります。)

![素ccertbots定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332453/39b96ab7-5030-213a-6b0c-fcdba1e4b8bb.png)



参考になれば幸いです。
Python `typing.Generic`を使って汎用的なクラスを定義する

## はじめに

Pythonでは、`typing`モジュールを使用して型ヒントを提供することができます。その中でも`typing.Generic`は、汎用的なクラスを定義する際に非常に強力なツールです。この記事では、`typing.Generic`の使い方と、それを使って汎用的なクラスを定義する方法について説明します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/1205cd94-d19c-8a8a-375a-cbac284fdcec.png)

## `typing.Generic`とは

`typing.Generic`は、型パラメータを持つクラスを定義するために使用されます。これにより、クラスの中で使用される型を柔軟に指定することができ、コードの再利用性と型安全性を高めることができます。

## 基本的な使い方

まず、簡単な例から見てみましょう。

```python
from typing import Generic, TypeVar

T = TypeVar('T')

class Box(Generic[T]):
    def __init__(self, content: T):
        self.content = content

    def get_content(self) -> T:
        return self.content
```

この例では、`Box`クラスが任意の型`T`の内容を持つことができます。

## 実践的な例

次に、より実践的な例として、汎用的なデータベース接続クラスを定義してみましょう。

```python
from typing import Generic, TypeVar, List, Dict

T = TypeVar('T')

class DatabaseConnection(Generic[T]):
    def __init__(self, connection_string: str):
        self.connection_string = connection_string

    def insert(self, item: T) -> None:
        # 実際のデータベース挿入ロジックをここに実装
        print(f"Inserting {item} into the database")

    def select(self, criteria: Dict[str, any]) -> List[T]:
        # 実際のデータベース選択ロジックをここに実装
        print(f"Selecting items with criteria: {criteria}")
        return []  # ダミーの空リストを返す

# 使用例
class User:
    def __init__(self, name: str, age: int):
        self.name = name
        self.age = age

user_db = DatabaseConnection[User]("user_db_connection_string")
user = User("Alice", 30)
user_db.insert(user)
users = user_db.select({"age": 30})
```

この例では、`DatabaseConnection`クラスが任意の型`T`のアイテムを扱えるようになっています。

## `typing.Generic`の利点

1. **型安全性**: コンパイル時やIDEでの型チェックが可能になり、多くのバグを事前に防ぐことができます。

2. **コードの再利用性**: 同じクラス構造を異なる型で再利用できます。

3. **明確なインターフェース**: クラスが扱うデータの型が明確になり、コードの理解が容易になります。

4. **ドキュメンテーション**: コードそのものが型情報を含むドキュメントとなり、APIの使い方が分かりやすくなります。

## 注意点

- Python 3.5以降でのみ使用可能です。
- 実行時には型チェックは行われないため、動的型付け言語としてのPythonの特性は維持されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/6b67eae5-f0f0-23e1-3dcb-51ab3103807e.png)

## まとめ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2648069/ae871721-5417-91b2-0b63-939fb2b1dfbb.png)

`typing.Generic`を使用することで、汎用的で型安全なクラスを定義することができます。これにより、コードの品質と再利用性が向上し、大規模なプロジェクトでも保守性の高いコードを書くことができます。Pythonの型ヒントを積極的に活用し、より堅牢なソフトウェアを開発しましょう。

## 参考情報

より詳細な情報や高度な使用方法については、以下の公式ドキュメントを参照してください：

1. [Python公式ドキュメント - typing — Support for type hints](https://docs.python.org/3/library/typing.html)
   - `typing`モジュール全般に関する詳細な情報が得られます。

2. [Python公式ドキュメント - Generic Types](https://docs.python.org/3/library/typing.html#generics)
   - `Generic`クラスの詳細な使用方法や、より複雑な型パラメータの使い方が説明されています。

3. [PEP 484 -- Type Hints](https://www.python.org/dev/peps/pep-0484/)
   - Pythonの型ヒントに関する提案書です。型ヒントの背景や設計思想について理解を深めることができます。

4. [mypy documentation - Generics](https://mypy.readthedocs.io/en/stable/generics.html)
   - 静的型チェッカーmypyのドキュメントです。`Generic`の実践的な使用方法や型チェックの詳細について学べます。

これらの資料を参照することで、`typing.Generic`やPythonの型ヒントについてより深い理解を得ることができます。
eSIMのしくみについてまとめてみた

はじめに
--
従来の物理SIMカードとeSIMの違いに関する情報が少ないと思いましたので、記事としてまとめました。
また、次世代規格であるeSIMの仕組みについても超訳してまとめることにしました。
理解の不十分により、内容が間違っていたりなど至らない点があるかと思います。

---

概要
---
SIMとは「契約したキャリア」「電話番号」といった契約者情報などの様々なデータが書き込まれた小さなチップのことです。スマホなどの携帯端末にSIMを装着することによって「電話回線での音声通話」や「データ回線を使ったインターネット通信」といった機能を使用することができます。

従来では、物理SIM(pSIM)が使用されており、カード型のSIMを携帯端末に挿すことによって、上述の機能を実現していました。

近年では、カード型の物理SIMを挿すのではなく、あらかじめ、端末の内部にチップが埋め込まれていて、そこに必要な情報をあとから追加（書き込み）し、音声通話やインターネット通信を実現するeSIMが登場しています。

---

物理SIMとeSIMの違いについて
---
物理SIMはキャリア(通信事業者)を変更するたびにSIMカードを差し替える必要があり、作業コストが発生します。
一方、eSIMはオンラインでプロファイルを携帯端末にダウンロードすることで使用することができ、作業コストは比較的少ないです。

eSIM全体像
---
![0704-mvn5-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96644/797ed2d7-9d42-9192-b2cb-0eb7215d3011.png)
図-1 eSIM内部の構造 出典元:GSMA SGP.22


![0704-mvn5-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96644/34aa4e84-8877-1d21-7a38-8a2883b1d81a.png)
図-2 コンシューマモデルのインタフェース 出典元:GSMA SGP.22

【用語】
SM-DP+:eSIMにおいてプロファイルを保管・管理するサーバー。
SM-DS:eSIMに提供されたプロファイルの検索を行うサーバー
eUICC:キャリアが提供するプロファイルをOTA（無線経由）技術を使ってサーバーからダウンロードする。
LPA(ローカル プロファイル アシスタント):スマホなどの端末で動作するアプリ。
ユーザーは本アプリを操作することでプロファイルのダウンロードやプロファイルの有効/無効の切り替えができる。



参考文献
---
https://ent.iij.ad.jp/articles/31/

https://www.iijmio.jp/simguide/esim/kihon.html

SGP.21-v2.4.pdf

SGP.22-v3.0-1.pdf
【Netlify / React】知識ゼロからデプロイ成功まで

# はじめに
今年の初めごろ、Youtube のハンズオン教材で React の勉強をしていた。真似をしてコードをいくつか書いたので [Netlify](https://www.netlify.com/) にデプロイしてみる。

# Netlify とは
Netlify とは（Netflixじゃないよ）、フロントエンド Web アプリケーションのデプロイを簡単かつ**無料で**行えるクラウドサービスである。また GitHub リポジトリに変更を加えると自動デプロイされるので管理の手間が少ない。

# デプロイした URL
> - [タイピングゲーム](https://github-typing.netlify.app/) / [GitHubリポジトリ](https://github.com/TanakaLatias/github-typing)
> - [メモリーゲーム](https://qiita.com/shozzy/items/dadea4181d6219d2d326) / [GitHubリポジトリ](https://github.com/TanakaLatias/netlify-memorygame)
> - [キャンディクラッシュ](https://netlify-candycrush.netlify.app/) / [GitHubリポジトリ](https://github.com/TanakaLatias/netlify-candycrush)

# 使わせていただいたハンズオン教材
> - [寿司打クローンをJavascriptで作ってみた - タイピングゲームチュートリアル](https://www.youtube.com/watch?v=o4a_xL9w3f0)
> - [Build a Memory Game with React](https://www.youtube.com/watch?v=ZCKohZwGZMw&list=PL4cUxeGkcC9iQ7g2eoNXHCJBBBz40S_Lm)
> - [Candy Crush in React](https://www.youtube.com/watch?v=PBrEq9Wd6_U)

React の Hooks を網羅的に学べて勉強になりました。また JavaScript の書き方にも慣れることができたと思います。

# デプロイで参考にさせていただいた記事
> - [NetlifyでWebサイトを公開する方法](https://qiita.com/shozzy/items/dadea4181d6219d2d326)

こちらの記事一本だけで知識ゼロからデプロイできました(人'▽｀)

# デプロイで少し詰まったところ
#### １．Site Configuration の設定は以下のようにする
![Screenshot (241).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3047950/5ca9d97a-9425-e647-2ca9-908d9241d411.png)
自分の React サービスの場合はこの設定でうまくいった。この２点以外に Netlify で手動設定する部分はあまりなく、基本的に GitHub のリポジトリを選択するだけでデプロイできた。

#### ２．デプロイする前にローカルで npm run build してテストしておく
普段 npm run **dev** ぐらいしか使うことがなく、今回初めて npm run **build** を使った。ローカルでビルドエラーが出るときは必ず Netlify でも出るので、エラーがなくなるよう修正しておく。
このとき自分の場合は以下の点でビルドエラーが出た。
- 画像に alt 設定がない
- useEffect の第二引数には、useEffect 内で使っている関数を全て入れないといけない（依存関係の問題らしい）
- useEffect 内で使っている関数はuseCallBackで包まなければならない

# おわりに
Netlify を使ってのデプロイは GitHub と連携して行うので初心者にも簡単にできた。一方で一般的なサーバにおける React の本番環境構築の知識は得られなかったと思うので、また機会があれば学習したい。
Oracle Java Silver 学習メモ


## 👋初めまして

プログラミングと日本語の両方を勉強しているSUUSHIと申します。

🎨22年に武蔵野美術大学の大学院を卒業後、留学生支援の学習塾に入社しました。教務管理が大変なところ、プログラミングで何か解決できないかと思い、今年の6月からJavaの勉強を始めました！

🤔Oracle Java Silver資格を一つの目標とすれば、より明確に勉強のスケジュールが組みやすいと感じたので、受験の準備をしています。現在は、Notionというツールで学習についてのタスク管理やメモ整理を行っていますが、今後はその内容をQiitaにもコツコツとアップロードしていきたいと思います。

よろしくお願いします！




## 👇私のNotion風景👇

![截屏2024-08-05 21.07.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3854122/9b635afd-1125-9647-c7a0-f7136bb6b933.png)

![截屏2024-08-05 21.08.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3854122/861384f2-5cc1-784e-813a-1bb1b1845ee7.png)

![截屏2024-08-05 21.07.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3854122/eb5a7e6b-32d4-cd49-0fa0-304d7d8498e0.png)
[全体構造]図解 Gitコマンド 

:::note info
以下は私の現状の理解を整理したもので、内容の正しさを保証するものではありません。
:::
# Gitコマンドの全体構造
・Gitの入門書を2冊読んだがGitの静的な側面と動的な側面が十分に区別されておらず、当初理解に苦労した。
・静的な関係、ファイルのある状態が取りうる位置と、ある場所がその状態を取るためのコマンドを以下に示す
![visual_git_cmd.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569906/66b46217-0dee-1fa6-0f10-b989954bda73.png)
・動的な関係はgit log --graphで示される状態遷移図、ただしGitは動的な要素を持たない

以下覚書
・Gitが保存しているのはファイルではなくファイルの状態である※
・ということはGitはファイルを多様な状態を取りうるオブジェクトと理解している（書き込まれたものと書きこまれた内容は分離して管理されている）
・またgit log --graphで示される図は時系列での状態の変化を図にしたものということになる（主語がファイル）。
・git log --graphで示される図のエッジは時間的な前後関係をもとにしたものでユーザに規律を提供しない（例：cherry pickコマンド）だから、状態遷移図ではない。

---
※手当たり次第にテキストのコマンドを試していくうちにgitで保存されているものが状態だということは察しがついたものの、以下の記事を通じて公式で確認するまではそれらしい記事が検索に引っかからず確信が持てなかった。GITを習う人/教える人はこういったことに関心がないのだろうか
SVN脳患者から見たGit：https://qiita.com/kaityo256/items/81e7951a1ca2706955a4
で、Gitがコミットオブジェクトとして実際何を管理しているかというと、とりあえずこういうものなんだけれど、これをたとえばgit cherry-pickする際に「チェンジセット」としてとらえてよいと思ってたら、コメントで「Gitは状態を保存するのであって変更を保存するのではないからチェンジセットという言葉はGitで使うな」と公式に書いてあることを教えていただいた。もともとJoelが「チェンジセット」という言葉を使っていたのはMercurialを使っていたからで、そっちやBitkeeperは「チェンジセット」を保存するという気持ちになっているはず。そんなわけで、MercurialとGitをごっちゃにしてました。すみません。

Git 公式：https://git-scm.com/docs/gitglossary#gitglossary-aiddefchangesetachangeset
changeset
BitKeeper/cvsps speak for "commit". Since Git does not store changes, but states, it really does not make sense to use the term "changesets" with Git.
【備忘録】shadcn/uiの初期設定を解説

# はじめに

shadcn/uiのインストール時に聞かれる内容を噛み砕いてまとめておく。

# インストール

使用するFWに合わせて。

https://ui.shadcn.com/docs/installation

```
npx shadcn-ui@latest init
```

# 初期設定

## テーマの選択

```
? Which style would you like to use? › - Use arrow-keys. Return to submit.
❯   Default
    New York
```

下記を比較してみてください。

- [Defaultテーマのサンプル](https://ui.shadcn.com/sink)
- [New Yorkテーマのサンプル](https://ui.shadcn.com/sink/new-york)

## ベースカラーの選択
```
? Which color would you like to use as base color? › - Use arrow-keys. Return to submit.
❯   Slate
    Gray
    Zinc
    Neutral
    Stone
```

## 色の設定としてCSS変数を使うかどうか
```
? Would you like to use CSS variables for colors? › no / yes
```

# 設定の変更方法

インストールすると、components.jsonファイルが生成されます。
書き換えることで設定を変更することもできます。

```components.json
{
  "$schema": "https://ui.shadcn.com/schema.json",
  "style": "default",
  "rsc": true,
  "tsx": true,
  "tailwind": {
    "config": "tailwind.config.ts",
    "css": "app/globals.css",
    "baseColor": "slate",
    "cssVariables": true,
    "prefix": ""
  },
  "aliases": {
    "components": "@/components",
    "utils": "@/lib/utils"
  }
}
```

# 参考
https://ui.shadcn.com/
【Chakra UI】import文が長くなりすぎる問題を何とかする方法

# はじめに
Chakra UIに初めて触れてみましたが、様々な部品が用意されて感動する反面、タイトルのような問題（？）が出てきたので対応する方法です。

# 問題
Chakura UIで用意されている、様々なコンポーネントを1つのファイル内で沢山importしているせいで、import文がやたら長くなるのがちょっとダサいなと思ったので、それを解決する方法です。

# 解決方法
ES Modulesのimport文にはアスタリスク（*）が使える。

例（対応前）：
```jsx
import {
  Box,
  Button,
  Input,
  Center,
  Flex,
  Img,
  Alert,
  Drawer,
  Stack,
  Divider,
  Card,
} from "@chakra-ui/react";
```

例（対応後）：
```jsx
import * as UI from "@chakra-ui/react";
```

使い方：
```jsx:使用例
<UI.Button type="submit">登録</UI.Button>
```

# おわりに
ググってもChakra UIを上記のように使う人は居なかったっぽいのでこういう使い方は普通しないのかもしれません…

## JISOUのメンバー募集中🔥
プログラミングコーチングJISOUではメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか？
気になる方はぜひHPからライン登録お願いします！👇

https://projisou.jp/
Javaのプリミティブ型とオブジェクト型の違い

# はじめに
Javaの内容で知らなくてもコードが書けてしまうことがあります。
ただし、知らないことで予期せぬ事態に繋がることはよくあることです。

Javaで知らずに使っていたけど、そういうことだったんだ！とかそうやって使い分けるんだ！というような内容をまとめていきます。

今回は値（プリミティブ）型と参照（オブジェクト）型の違いについて説明します。

# 値（プリミティブ）型
値型（またはプリミティブ型）は、基本的なデータ型であり、Javaでは以下の8つのプリミティブ型が提供されています。

| 型       | 説明                  |
|----------|---------------------------|
| byte     | 8ビット整数               |
| short    | 16ビット整数              |
| int      | 32ビット整数              |
| long     | 64ビット整数              |
| float    | 単精度32ビット浮動小数点数|
| double   | 倍精度64ビット浮動小数点数|
| char     | 16ビットUnicode文字       |
| boolean  | 真偽値（trueまたはfalse）| 


プリミティブ型は、メモリ上に直接値を保持し、オーバーヘッドが少なく、効率的に動作します。

しかし、プリミティブ型にはメソッドが存在しません。

# 参照（オブジェクト）型
参照型は、オブジェクトを参照するための型です。


Javaでは、クラス、インターフェース、配列が参照型に該当します。
参照型の変数は、実際のオブジェクトを指す参照（ポインタ）を保持します。

例として、以下のクラス型があります。

| データ型  | 説明                          |
|-----------|-------------------------------|
| Integer   | `int`のラッパークラス           |
| Double    | `double`のラッパークラス        |
| String    | 文字列を扱うクラス              |


参照型は、メソッドを持つことができ、オブジェクトに対する操作を行うための豊富な機能を提供します。

# 値型と参照型の具体例
### intとInteger
intはプリミティブ型であり、Integerはそのラッパークラスです。以下に例を示します。

```java
int num = 10;  // プリミティブ型
Integer obj = Integer.valueOf(num);  // オブジェクト型
```

Integerクラスを使用することで、さまざまなメソッドを利用できます。

```java
int num = 10;
Integer obj = Integer.valueOf(num);

// メソッドの使用例
String str = obj.toString();  // numを文字列に変換
int hash = obj.hashCode();    // ハッシュコードを取得
```

### charとString
charは単一の文字を表すプリミティブ型であり、Stringは文字列を扱うクラスです。

```java
char c = 'A';  // プリミティブ型
String str = "Hello";  // オブジェクト型
```

Stringクラスを使用すると、文字列操作に関する多くのメソッドを利用できます。

```java
String str = "Hello";

// メソッドの使用例
int length = str.length();  // 文字列の長さを取得
char ch = str.charAt(0);    // 文字列の特定の位置にある文字を取得
String upper = str.toUpperCase();  // 文字列を大文字に変換
```


# まとめ
Javaでは、値（プリミティブ）型と参照（オブジェクト）型の違いを理解することが重要です。

プリミティブ型は軽量で効率的ですが、メソッドを持ちません。
一方、参照型はオブジェクト指向の特性を活かして、多くのメソッドと機能を提供します。

これらの違いを理解し、適切に使い分けることで、より効果的でメンテナブルなコードを書くことができます。

特に、ラッパークラスを使ってプリミティブ型の利便性を向上させる方法や、文字列操作におけるStringクラスの活用法は、Javaプログラマーにとって知っておくべき重要な知識です。
ECCメモリと非ECCメモリについて

# ECCメモリと非ECCメモリについて

## 概要

メモリ（RAM）は、コンピューターの性能と信頼性に大きな影響を与える重要なコンポーネントです。特にECCメモリ（Error-Correcting Codeメモリ）と非ECCメモリの違いは、データの整合性とシステムの安定性に直結します。本記事では、ECCメモリと非ECCメモリの見分け方、特徴、エラー検出方法の違いについて解説します。

## 見分け方

メモリモジュールを見て、黒四角のメモリチップの数でECCメモリか非ECCメモリかを見分けることができます。

- **ECCメモリ**: メモリチップが9つあります。
- **非ECCメモリ**: メモリチップが8つあります。

![IMG_1527 2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3847927/56529bb3-ebcc-8e3d-4852-6d7e55809457.jpeg)

## ECCメモリとは？

ECCメモリ（Error-Correcting Codeメモリ）は、コンピューターのメインメモリ（RAM）に使用されるメモリの一種です。主にサーバーやミッションクリティカルなシステムで使用されます。ECCメモリは、9番目のメモリチップを追加することで、データの誤りを検知し訂正する機能を持っています。

### 特徴
- 潜在的な脅威からシステムを保護します。
- データの誤りを検知し訂正する機能があります。
- 主にサーバーで使用されます。

## エラー検出方法の違い

### 非ECCメモリ

非ECCメモリは、パリティビットを使用してエラーを検出します。

- 8ビットのデータにつき1ビットのパリティを加えて、合計が偶数になるようにします。
- 合計が奇数となることで、エラーが発生したことが分かります。

| | |  | | | | | | | パリティ | 判定 |
|:-----:|:-----:|:-----:|:-----:|:-----:|:-----:|:-----:|:-----:|:-----:|:-----:|:-----:|
| ビット | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | 偶数 |

1bitエラーが発生すると...

| | |  | | | | | | | パリティ | 判定 |
|:-----:|:-----:|:-----:|:-----:|:-----:|:-----:|:-----:|:-----:|:-----:|:-----:|:-----:|
| ビット | 0 | 1 | 1 | 0 | **0** | 0 | 1 | 0 | 0 | **奇数** |

しかし、これだとどのビットがエラーなのかわからず修正できません。

また、偶数箇所エラーが発生した際に、エラーを検知できない点も挙げられます。

### ECCメモリ

ECCメモリは、パリティの欠点を補うために、垂直パリティと水平パリティを組み合わせてエラーを検出し訂正します。

- 1つのエラーが発生した場合、修復が可能です。
- 2つ以上のエラーが偶数で発生した場合でも、高い確率で発見することができます。

| | | | | | | | | | パリティ | 判定 |
|:-----:|:-----:|:-----:|:-----:|:-----:|:-----:|:-----:|:-----:|:-----:|:-----:|:-----:|
| | 0 | 1 | 1 | 1 | 0 | 0 | 1 | 1 | **1** | 偶数 |
| | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | **1** | 偶数 |
| | 0 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | **1** | 偶数 |
| | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | **0** | 偶数 |
| | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 0 | **1** | 偶数 |
| | 1 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | **1** | 偶数 |
| | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | **1** | 偶数 |
| | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 1 | **1** | 偶数 |
| パリティ | **0** | **1** | **0** | **0** | **0** | **1** | **1** | **0** | **1** | 偶数 |
| 判定 | 偶数 | 偶数 | 偶数 | 偶数 | 偶数 | 偶数 | 偶数 | 偶数 | 偶数 | 偶数 |

1bitエラーが発生すると...

| | | | | | | | | | パリティ | 判定 |
|:-----:|:-----:|:-----:|:-----:|:-----:|:-----:|:-----:|:-----:|:-----:|:-----:|:-----:|
| | 0 | 1 | 1 | 1 | 0 | 0 | 1 | 1 | **1** | 偶数 |
| | 1 | 0 | 0 | **0** | 0 | 0 | 0 | 1 | **1** | **奇数** |
| | 0 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | **1** | 偶数 |
| | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | **0** | 偶数 |
| | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 0 | **1** | 偶数 |
| | 1 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | **1** | 偶数 |
| | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | **1** | 偶数 |
| | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 1 | **1** | 偶数 |
| **パリティ** | **0** | **1** | **0** | **0** | **0** | **1** | **1** | **0** | **1** | 偶数 |
| **判定** | 偶数 | 偶数 | 偶数 | **奇数** | 偶数 | 偶数 | 偶数 | 偶数 | 偶数 | **奇数** |

これにより、どこのビットでエラーが発生したかを検知でき、修正することができます。

## まとめ

ECCメモリは、データの誤りを検知し訂正する機能を持つため、サーバーやミッションクリティカルなシステムで重要です。非ECCメモリは、パリティビットを使用してエラーを検出するため、一般的なデスクトップPCやラップトップに使用されます。それぞれの用途に応じたメモリを選ぶことが、システムの信頼性と安定性を確保するために重要です。


## 参考文献
https://community.fs.com/jp/article/ecc-vs-non-ecc-memory-which-one-is-better.html
Windows版GPUStack完全トラブルシューティングガイド：500エラーとllama-box問題の解決法

GPUStackをWindowsで使用する際に遭遇する可能性のある主要な問題とその解決策を紹介します。

基本的な起動方法はこちら

https://hamaruki.com/gpustack-open-source-gpu-cluster-manager-guide/

## ダッシュボードの500エラー

https://github.com/gpustack/gpustack/issues/93

### 問題
以前のバージョンのGPUStackでは、ダッシュボードUIにアクセスすると500エラーが発生する場合がありました。

### 原因
この問題は、ワーカーが設定されていない状態でダッシュボードにアクセスしようとした際に発生していました。

### 解決策
この問題は既に修正されており、最新バージョンのGPUStackを使用することで解決できます。以下の手順に従ってGPUStackを再インストールしてください：

1. アンインストール：
   PowerShellを管理者権限で開き、以下のコマンドを実行してGPUStackをアンインストールします：
   ```powershell
   Set-ExecutionPolicy Bypass -Scope Process -Force; & "$env:APPDATA\gpustack\uninstall.ps1"
   ```

2. 再インストール：
   アンインストールが完了したら、以下のコマンドを実行してGPUStackを再インストールします：
   ```powershell
   Invoke-Expression (Invoke-WebRequest -Uri "https://get.gpustack.ai" -UseBasicParsing).Content
   ```

3. インストールが完了したら、GPUStackを起動し、ダッシュボードにアクセスして問題が解決したか確認します。

## llama-boxの起動エラー

https://github.com/gpustack/gpustack/issues/109

### 問題

llama-boxの起動時に以下のようなエラーが発生する場合があります：

```bash
障害が発生しているアプリケーション名: llama-box-windows-amd64-cuda-12.5.exe、バージョン: 0.0.0.0、タイム スタンプ: 0x6698d6eb
障害が発生しているモジュール名: MSVCP140.dll、バージョン: 14.34.31938.0、タイム スタンプ: 0xe7a4b09e
例外コード: 0xc0000005
```

### 原因

このエラーは、Microsoft Visual C++ ランタイムライブラリの問題や、GPUStackのインストールに問題がある場合に発生することがあります。

### 解決策

以下の手順を順番に試してください：

#### Microsoft Visual C++ 再頒布可能パッケージの更新：

a. [Microsoft公式サイト](https://docs.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist)から最新のMicrosoft Visual C++ 再頒布可能パッケージをダウンロードします。
b. ダウンロードしたインストーラーを実行し、画面の指示に従ってインストールします。
c. インストールが完了したら、コンピューターを再起動します。

### GPUStackの再インストール：

上記の方法で問題が解決しない場合は、GPUStackを再インストールしてみてください。

a. アンインストール：
    ```powershell
    Set-ExecutionPolicy Bypass -Scope Process -Force; & "$env:APPDATA\gpustack\uninstall.ps1"
    ```

b. 再インストール：
    ```powershell
    Invoke-Expression (Invoke-WebRequest -Uri "https://get.gpustack.ai" -UseBasicParsing).Content
    ```

### 再起動：

再起動後、GPUStackを起動し、llama-boxが正常に動作するか確認します。

## 確認方法

llama-boxが正常に起動しているかを確認するには、以下のいずれかの方法を使用できます：

1. タスクマネージャーを開き、"詳細" タブで "llama-box-windows-amd64-cuda-12.5.exe" プロセスを探します。

2. コマンドプロンプトで以下のコマンドを実行します：
   ```
   tasklist | findstr llama-box
   ```

3. PowerShellで以下のコマンドを実行します：
   ```powershell
   Get-Process | Where-Object {$_.Name -like "*llama-box*"}
   ```

これらの方法でllama-boxプロセスが表示されれば、正常に起動していることが確認できます。

<blockquote class="twitter-tweet" data-media-max-width="800"><p lang="ja" dir="ltr">やっとGPUStack動かせました！！！<br>だいぶ苦労したので後で記事にします！！！ <a href="https://t.co/gvmg7wku41">https://t.co/gvmg7wku41</a> <a href="https://t.co/k8MTnZFbxs">pic.twitter.com/k8MTnZFbxs</a></p>&mdash; Maki@Sunwood AI Labs. (@hAru_mAki_ch) <a href="https://twitter.com/hAru_mAki_ch/status/1820424920461082918?ref_src=twsrc%5Etfw">August 5, 2024</a></blockquote> 

## まとめ

GPUStackをWindowsで使用する際に遭遇する可能性のある主要な問題を紹介しました。ダッシュボードの500エラーとllama-boxの起動エラーは、GPUStackの再インストールとMicrosoft Visual C++ 再頒布可能パッケージの更新で解決できる場合が多いです。これらの手順に従うことで、GPUStackをWindowsで正しく起動させることができるはずです。

問題が解決しない場合や、他の問題が発生した場合は、GPUStackの公式サポートチャンネルやGitHubのイシューページで支援を求めることをお勧めします。

<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
画像変換エンジンを構築して画像配信システムを運用にのせた話

# 概略

簡潔に説明すると、以下のメルカリの事例のような画像配信の仕組みを運用に載せました。

https://imageflux.sakura.ad.jp/case-study/mercari/

画像変換基盤は自前で構築しました。

サービスインを社内でアナウンスしてもあまりにも反応が少なかったので、供養のためにQiitaにのせときます。

どこかのサービスの運用コストが下がる、もしくは技術的課題の解決につながればよいです。

# どんなプロダクト？

サービス自身には 中央値が 2.5k rpsくらい。直近５日くらいの最大が 5k rps くらい、
画像のCDNに対しては中央値が 4k rps くらい。直近５日くらいの最大が 8k rps　くらい
の規模感のサービスです。 

クローラからもそれなりにリクエストくるのでそれなりのサービスです。
日系のサービスだったらそこそこのサービスだと思っています。

# 基盤を構築する背景

当該のサービスは１０年以上運用されているのでストレージにためられた画像のデータ量がペタ（単位）を超えてます。
同じ画像で画像サイズだけが異なっているものが数種類あって、それを管理しているだけで毎年相当なコストがかかっていました。
FinOpsの一環でストレージのコスト削減の施策を行うことになりました。
施策の内容は、

1. ストレージに保存されている数種類ある画像を１枚にする
1. それぞれのサイズはユーザからリクエストされたときに元画像からリサイズを行い、配信する
1. 配信した画像はCDNにキャッシュする

つまり、A社やS社が提供している画像変換配信エンジンをかます

というものでした。

それぞれの会社さんに当該サービスの導入コストをヒアリングしたのですが、
試験段階の自作アプリの運用試算のが運用コストを落とせそうだったので、一旦自前で構築・運用してみよう
という流れで、画像変換配信のシステムを自前で構築しました。

# 結果

本番運用できるものを構築できました。
運用にのせることができました。

コストは画像配信全体で　20 ~ 30 core CPU くらいのサーバリソースで画像配信ができることがわかりました。
アプリケーションはコンテナ化されているので、アプリケーションに割り当てているCPUとコンテナの台数をもとに算出しています。

AWSのEC2とかをもとに計算してみると　8xlarge 2台分くらいでしょうか？
１時間で　２〜３USD　くらい？
システムの運用コストは月額 30万円 くらいです

年間で 360　万円
そこそこかかるように思えてしまいますが、当該のシステムのストレージの運用コストはそれを遥かに上回っています。（年間で数千万かかっているみたいでした。）

詳しい話が聞きたい方はコメントかDMください。
会社にバレてなにか言われたらこの記事は削除します。
Git中級者のためのドヤれるガイド

## Gitのいろんなことを知っておこう

Gitはソフトウェア開発におけるバージョン管理システムとして広く利用されています。基本的な操作に慣れたら、次のステップとして高度な機能を学ぶことが重要です。このガイドでは、Gitの高度なトピックについて詳しく説明します。

### 1. リベース（Rebase）の使い方

リベースは、ブランチの履歴を再構成するための強力なツールです。特に、履歴をクリーンに保つために役立ちます。

```bash
# featureブランチをmainブランチの最新のコミットにリベースする
git checkout feature
git rebase main
```

リベースを行うことで、ブランチの履歴が一連の直線的なコミットとして整理されます。これにより、履歴が見やすくなり、コードレビューが容易になります。

### 2. インタラクティブリベース（Interactive Rebase）

インタラクティブリベースは、コミットの履歴を詳細に編集するための方法です。コミットの順序を変更したり、複数のコミットを一つにまとめたりすることができます。

```bash
# 過去の5つのコミットをインタラクティブにリベースする
git rebase -i HEAD~5
```

エディタが開き、各コミットに対して操作を指定できます。例えば、`pick`を`reword`に変更すると、コミットメッセージを編集できます。

### 3. スタッシュ（Stash）の活用

作業中の変更を一時的に保存して、他の作業に切り替える際に便利なのがスタッシュです。

```bash
# 現在の作業をスタッシュに保存
git stash

# スタッシュした変更を適用
git stash apply
```

スタッシュを使うことで、未完成の作業を一時的に保存し、他の重要なタスクに迅速に対応できます。

### 4. サブモジュール（Submodule）の管理

サブモジュールを使うことで、他のGitリポジトリを自身のリポジトリに含めることができます。これは、大規模なプロジェクトで外部ライブラリを管理する際に非常に有用です。

```bash
# サブモジュールの追加
git submodule add https://github.com/example/repo.git path/to/submodule

# サブモジュールの初期化と更新
git submodule update --init --recursive
```

サブモジュールを適切に管理することで、依存関係を明確にし、プロジェクトの一貫性を保つことができます。

### 5. Gitフック（Hooks）の設定

Gitフックは、特定のGitイベントに対してスクリプトを実行するための仕組みです。例えば、コミット前にコードスタイルをチェックするスクリプトを実行できます。

```bash
# pre-commitフックの例
echo '#!/bin/sh' > .git/hooks/pre-commit
echo 'npm run lint' >> .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit
```

Gitフックを活用することで、チーム全体でのコード品質を自動的に維持することができます。

### まとめ

高度なGitの機能を活用することで、プロジェクトの管理がさらに効率的になります。リベースやスタッシュ、サブモジュール、Gitフックなどのツールを使いこなすことで、開発プロセスを最適化し、チーム全体の生産性を向上させることができます。ぜひ、これらの高度な機能を日常の開発に取り入れてみてください。
【PHP8.4】DateTimeの秒だけ0にしたいんじゃが

# なにがしたい？

[DateTime](https://www.php.net/manual/ja/class.datetimeimmutable.php)のインスタンスに'2024-01-01 01:23:45'が入っていたとして、ここから秒だけ削除して'2024-01-01 01:23:00'にしたい。


# どれがいいだろう？

```php
    $dt = new \DateTimeImmutable('2024-01-01 01:23:45');

    // その1
    $dt2 = new \DateTimeImmutable($dt->format('Y-m-d H:i:00'));

    // その2
    $dt2 = $dt->setTime($dt->format('H'), $dt->format('i'), 0);

    // その3
    $dt2 = $dt->setTimestamp(intdiv($dt->getTimestamp(), 60) * 60);

    // その4
    $dt2 = $dt->sub(new DateInterval(sprintf('PT%dS', $dt->format('s'))));
```

どれも不毛感がすごい。

[DateTimeImmutable::setTime](https://www.php.net/manual/ja/datetimeimmutable.settime.php)で秒だけ指定できないかと思ったのですが、何故か引数`$hour`・`$minute`が必須となっているため駄目でした。

```php
$dt = $dt->setTime(second: 0);
// PHP Fatal error: DateTimeImmutable::setTime(): Argument #1 ($hour) not passed

$dt = $dt->setTime(null, null, 0);
// Deprecated: DateTimeImmutable::setTime(): Passing null to parameter #1 ($hour) of type int is deprecated
// 00:00:00になる
```

どうして。

一番有望そうだった[modify](https://www.php.net/manual/ja/datetimeimmutable.modify.php)にも、相対指定の方法は数あるものの、任意の値に設定するような方法は見当たらないようでした。

汎用性を考えると、やはりその1の一度`format`で出力して再度newするのが最も手っ取り早いですかね。
しかし、せっかくできているインスタンスを捨てて一度文字列に戻すのって微妙過ぎる。


# 結局どうすればいい？

いちいち消さずにそのまま持っておいて、出力時にformat指定すればいいんじゃないかな。
テスト109

```vb

Sub reg_test2()

'正規表現練習
Dim reg As Object
Dim str1 As String
Dim aaa As Variant
Dim aa As Variant

str1 = "今日は令和11年2月11日です"
Set reg = CreateObject("VBScript.RegExp")

'和暦だけ取得
With reg
    .Pattern = "(昭和|平成|令和)(\d{1,2})年(\d{1,2})月(\d{1,2})日"   'パターンを指定
    .IgnoreCase = True       '大文字と小文字を区別する(False)、しない(True)
    .Global = True           '文字列全体を検索する(True)、しない(False)
End With

Set aaa = reg.Execute(str1)

Debug.Print aaa.Item(0)

'-------------------------------------------
str1 = "今日は2024/11/21です"

'YYYY/M/D(YYYY/MM/DD)だけ取得
With reg
    .Pattern = "(\d{4})/(\d{1,2})/(\d{1,2})"   'パターンを指定
    .IgnoreCase = True       '大文字と小文字を区別する(False)、しない(True)
    .Global = True           '文字列全体を検索する(True)、しない(False)
End With

Set aaa = reg.Execute(str1)

Debug.Print aaa.Item(0)

'-------------------------------------------
str1 = "今日は2024年11月21日です"

'YYYY年M月D日(YYYY年MM月DD日)だけ取得
With reg
    .Pattern = "(\d{4})年(\d{1,2})月(\d{1,2})日"   'パターンを指定
    .IgnoreCase = True       '大文字と小文字を区別する(False)、しない(True)
    .Global = True           '文字列全体を検索する(True)、しない(False)
End With

Set aaa = reg.Execute(str1)

Debug.Print aaa.Item(0)
Set reg = Nothing


End Sub