OmniAICreator/Qiita-1.07M huggingface dataset:
[Python] unittest.mock チートシート

## この記事について

Python の `unittest.mock` に関するチートシート。

※あくまで自分用のチートシートなので、テストコードはかなり簡潔に書いています。

公式のドキュメントはこちら
→ https://docs.python.org/ja/3/library/unittest.mock.html

## unittest.mock.MagicMock

特定のクラスなどをモックしたい場合に利用。

```py
# これは実装側
class Foo:
    # クラスのプロパティ
    is_foo = True

    # クラスのメソッド
    def do_something():
        # ...

# これはモック定義
import pytest
from unittest.mock import MagicMock, patch
from path.to.foo import Foo

@pytest.fixture()
def mock_foo():
    foo_mock = MagicMock(spec=Foo)

    foo_mock.do_something = MagicMock(return_value=123)

    with patch('path.to.foo.Foo', return_value=foo_mock):
        # 各テストケースはこの with の中で実行される
        yield foo_mock  # テストケースからモックしたインスタンスを参照するため、yeild に foo_mock を渡す

# これはテストファイル
class TestFoo:
    def test(self, mock_foo):
        # Fooクラスがモックされた状態でのテストとなる
        
        assert mock_foo.do_something.call_count == 1
```

## unittest.mock.patch

クラスの特定のメソッドなどをモックしたい場合に利用。

```py
from unittest.mock import patch
from path.to.foo import Foo

class TestFoo:
    # patch は何度でも指定できる
    # patch ではなく patch.object を使うことで、参照元にコードジャンプしやすくなる
    @patch.object(Foo, 'do_something')
    @patch.object(Foo, 'check_if_ok')
    def test(
        # 引数の順序は、デコレータで指定した順序の逆になる（Pythonの言語仕様）
        mock_check_if_ok,
        mock_do_something,
    ):
        # 例外を投げさせる
        mock_check_if_ok.side_effect = Exception('NG!')

        # 返り値を設定する
        mock_do_something.return_value = True

        # 1度も実行されていない
        assert mock_do_something.assert_not_called()

        mock_do_something(1,2,3)

        # 実行された
        assert mock_do_something.called

        # 少なくとも1度実行された
        assert mock_do_something.assert_called()

        # 1度だけ実行された
        assert mock_do_something.assert_called_once()

        # 1度だけ実行された（引数指定）
        assert mock_do_something.assert_called_once_with(1,2,3)

        # 最後に実行された際の引数
        args = mock_do_something.call_args.args
        assert args[0] == 1
        
        mock_do_something(key='abc', value=100)

        # N回実行された
        assert mock_do_something.call_count = 2

        # 最後に実行された際のキーワード引数
        kargs = mock_do_something.call_args.kargs
        assert kargs['key'] == 'abc'

        # 今までに以下のように実行されたことがある
        assert mock_do_something.assert_any_call(1,2,3)

        # これまでの実行された引数
        assert mock_do_something.call_args_list == ...
```

以下、個人的な所感。

- 自前で MagicMock() するとモックを元に戻す手間が発生するので、ちょっとしたモックでは patch デコレータを使うのが良さそう
- assert_called() よりは called の方がシンプルで良い
- call_args には最後に実行された引数が入っている、と覚えておく
- assert_any_call() は便利だけど、名称に any が入っているのでちょっと拒否感がある
- assert_has_calls() は使うことはあまり無さそう… 実装を変えたらすぐにテストが壊れそう any_order=True を指定しても良いけど
- call オブジェクトとか気にしたくないので、それを意識させないテストコードにするのが良さそう
脱ETLツールのすゝめ

こんにちは。

テックリードのTerukiです。
前回の記事で脱PHPを前Qで終えたと書いたのですが、その裏で実は脱ETLツールも行っていました。

https://qiita.com/omt_teruki/items/eb0d953198120a2dc7c2

脱〇〇が社内で流行っていますが、脱ETLをした結果や過程などを共有できればと思います。
今回もゆるい感じの記事です。

# 脱ETLツール
Oh my teethではETLツールを複数使っていました。
SNS等に出稿している広告媒体データや自社サービスのユーザーデータをBigQueryで分析するためにサードパーティのサービスを使うわけです。

実際に使っていたのはStitchやSupermetrics、TROCCOなどです。

https://www.stitchdata.com/

https://supermetrics.com/

https://trocco.io/

どれもGUI上でETLを設定できるので便利な反面、規模が大きくなると馬鹿にならない金額が掛かってきます。

Oh my teethでも年間にすると数百万円ほどETLツールに支払いをしていました。

マーケティングチームが消費する広告予算を考えると年間数百万円はそんなに大きくないという考え方もあるかもですが、マーケターではないエンジニアの私にとっては「<font color="orange">データコピーするだけで数百万！？</font>」という感情を捨てきれません。

実際にETLツールでETLを実行していた媒体は下記の通りです。

- Facebook広告
- Google広告
- Microsoft広告
- TikTok広告
- X広告
- Yahoo広告

彼らのデータは必ずしも商用のETLツールを経由しないと取得できないわけではありません。
実際、これらの広告媒体はすべてAPIドキュメントが公開されており、やる気さえあれば自作することができます。

# 大変な点

まず挙げられるのは申請系です。
Facebook広告とMicrosoft広告以外は開発者プラットフォームからポチポチすればすぐ使えるようになるわけではありません。
特に大変だったのはGoogle広告で、英語でのやり取りはもちろん、自作するツールのサマリーを書いてPDFにして提出する必要があります。

他の広告媒体も基本的に用途や必要な理由を英語で記載して承認されるのを待つ必要があります。
自社に広告媒体の担当者を付けてもらえている場合は彼らも力になってくれるでしょう。

この申請が億劫で心が折れる人も一定数居るかと思いますが、申請が終わったら実装です。

これは各広告媒体のAPIドキュメントやSDKを参照してゴリゴリ進めていくことになります。
開発する人にマーケティングの知識がない場合は難易度に拍車を掛けます。

私もその辺りの知識は乏しかったため、マーケティングチームの人に手助けをしてもらいながら実装を進めました。

後は黙々と実装していくだけです。

# メリット
実際に自作してみて良かったと感じている点がいくつかあります。

データ分析を行うエンジニアに広告データの知見が貯まるので、その後の分析業務の効率が上がったり精度向上に寄与します。これは会社にとっては結構大きいです。

ETLツールの場合、ETL間隔を短くすると追加課金になったりしますが、自作の場合はAPIのレートリミットを超えない限り自由です。これも結構大きいと思います。

最後にコストメリットですが、Oh my teethでは年間数百万円掛かっていたETLが自作によって年間<font color="orange">数百円</font>程度にまで落とすことができました。

もはや誤差レベルです。実行基盤としてはAWSのLambdaを使用しています。
下記の記事の仕組みをそのまま使っているので気になる方はこちらも見てみてください。

https://qiita.com/omt_teruki/items/7b2e876dddd4cb0b0461

# おわりに

ETLツールはGUIで設定できて非常に便利です。

自社にエンジニアがいない場合は有力な選択肢となると思いますが、もし自社にエンジニアがいるのなら腕試しとしてやってみてはいかがでしょうか。

APIドキュメントを正確に理解して実装していくわけですが、難解な部分も多いので実装を完遂するのに要求されるエンジニアリングスキルはそこそこ高いと思われます。

それでも自社に貯まる知見やコストメリットを考えたらやってみる価値はあるんじゃないかなと思います。

個人的にETLツール自作勢が増えると嬉しいです。楽しいですよ！

今回はちょっと短いですが、別の機会に各媒体の広告APIの使い勝手だったりをランキングにした記事を書こうかなと思っています。完全にエンタメ記事になる予定ですがそちらも良かったらお楽しみに。


# Oh my teethについて
Oh my teethでは未来の歯科体験を創るために日々活動しています。

Techチームではより良いユーザー体験を提供するべく、Webフロントエンドからバックエンド、スマホアプリに機械学習モデルなど、さまざまなプロダクトを開発しています。

一緒に未来の歯科体験を創りませんか？興味がある方は是非こちらを確認してください。

https://oh.careers/

カジュアル面談も可能なので気軽に応募してみてください！

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192685/0138b492-e02b-852e-61fa-fc065b53d285.png" width="450" />
【AWS SAP】OpsWorksとは？

# はじめに
OpsWorksはサービス終了になりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2746730/610ae351-d570-fc29-0dab-c21d6ce26dd6.png)


## 勉強前イメージ
Ops＝運用、Works＝働く？

## AWS OpsWorksとは？
- <INS>Chef</INS>、<INS>Puppet</INS>を活用し、サーバの構成管理やデプロイを自動化するサービス

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2746730/44ccf047-3975-5631-9387-f85cd7d1556c.png)

:::note info
Chef、Puppetとはサーバの設定や管理を自動化するOSS

↓Chefのイメージ図　※引用「https://thinkit.co.jp/story/2013/11/18/4679」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2746730/21100bcb-29fb-6e13-5d44-738beb1f5454.png)

↓Puppetのイメージ図　※引用「https://atmarkit.itmedia.co.jp/ait/articles/1504/06/news008.html」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2746730/435e994e-9896-d60d-67f1-4f4118edbf80.png)
:::

## 具体的には？

### OpsWorksには以下の3つの種類があります

| 種類                          | 特徴                                                                 | 主な用途                                       |
|-------------------------------|----------------------------------------------------------------------|-----------------------------------------------|
| **OpsWorks Stacks**           | サーバやリソースをスタック単位で管理しアプリやOSやミドルウェアの設定を一括管理          | アプリ全体のライフサイクル管理や設定の統一                      |
| **OpsWorks for Chef Automate**| ChefサーバをAWS上でホストしインフラをコードで管理 設定の自動化と一貫性を提供           | サーバ構成のコード化や再現性のある環境構築や継続的な運用管理     |
| **OpsWorks for Puppet Enterprise** | PuppetをAWS上でホストし詳細なサーバ設定や管理を自動化                           | サーバ設定の細分化が必要な環境や大規模なインフラ管理            |

AWSコンソール画面はこんな感じ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2746730/2b54f674-74c6-3e3d-ff5a-34289d66eb5c.png)

## まとめ
とりあえず、OpsWorksはChef、PuppetのOSSが使えるAWSサービス！
micro:bitでファミコン/スーパーファミコンのコントローラーを使う

micro:bitでファミコン/スーパーファミコンのコントローラーを使うことに成功したのでここにまとめます。

## やりたいこと
僕らの青春とともにあったファミコン、スーパーファミコン。
micro:bitでコントローラーを使えるようにして将来的には簡単なゲームをつくりたいと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71746/905f45ec-83be-c574-a3f9-04b1e56fc914.png)


## 参考文献
[■Blog:54byteのスーファミコントローラドライバ、IchigoJam BASICとマシン語でつなぐ極上のコントローラ](https://fukuno.jig.jp/1850)

[■書籍:Raspberry Piのファミコン化/スーパーファミコン化](https://www.sayonari.com/comiket/order.html)


## 物理的な接続方法
ファミコンもスーパーファミコンも接続ケーブルの信号線数・役割は同じため、micro:bitとの接続自体は同様となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71746/df2f8106-639c-1da6-5d42-4982b20b1056.png)


ただし、ファミコンはコントローラーがファミコン基板に独自？と思われるコネクターでつながっているので別のものに付け替えるなどの方法が必要です。
(私はジャンパーピンに付け替えました)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71746/31fd11ac-8d83-8703-0ebe-c1fc86b7d09e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71746/fc314f4c-05b2-5686-86e0-bf8aedd6b74c.png)


スーパーファミコンはもともと本体とつなぐ部分がコネクターになっているのでメスのコネクターを入手すればそこから先をmicro:bitに繋げばOKです。
(私はAliexpressで購入しました。1つ300円程度。)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71746/1683d2a3-a47d-7e57-5467-bc9ea27a54eb.png)


https://ja.aliexpress.com/item/32838396935.html

## ピンアサインについて
### ファミコンの端子
色ごとに下記のように分かれています
GND(茶) / D:DATA(赤) / P/S(オレンジ) / CLK(黄) / VCC(白)

### スーパーファミコンの端子
コネクターからは色は見えませんが、本体全面からみた場合の1コン(左側)を基準とすると下記となります
 ( A B C | D E F G)
A:GND(茶) / B:未接続/ C:未接続
D:DATA(赤) / E:P/S(オレンジ) / F:CLK(黄) / G:VCC(白)

コントローラーとmicro:bitの各端子の接続は下記の通り。

|ファミコン・<BR>スーファミ<BR>コントローラー |---|micro:bit|
|---|---|---|
|VCC(白) |--- |3V |
|GND(茶) |--- |GND |
|DATA(赤) |--- |P0(デジタル入力)|
|P/S(オレンジ) |--- |P1(デジタル出力)|
|CLK(黄) |--- |P2(デジタル出力) |

※micro:bit側はプログラムの指定でポートは変わってきますが、この記事のプログラムでは上記で設定しています

## コントローラーと各ポートの通信の流れについて
コントローラーとmicro:bitとの接続はSPIで行います。
MakeCode内のブロックの中にもSPIのブロックはあるのですがややこしいのでSPIのお作法を理解し、下記の手順を再現しました。

読み取りの一単位をスタート：P1(デジタル出力)に0を出力
最初のボタン読み取りをスタンバイ：P2(デジタル出力)に0を出力
最初のボタンの読み取り：P0にボタンの状況を出力
最初のボタン読み取りを終了：P2(デジタル出力)に1を出力
次のボタン読み取りをスタンバイ：P2(デジタル出力)に0を出力
※以下必要な回数繰り返し、ファミコンは8回、スーファミは16回
読み取りの一単位を終了：P1(デジタル出力)に1を出力

※以上のサイクルを繰り返し

## プログラム
こちらのサンプルプログラムではスーパーファミコンの各ボタン押し下げと連動し、micro:bit上の各LEDが光ります。

<iframe width="560" height="315" src="https://www.youtube.com/embed/3uMwfYijMgM?si=0weWZ5bVH4EYHvoP" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

https://makecode.microbit.org/S22641-11407-84972-41823

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71746/c948c42a-875e-a3ff-ff51-0f6a69837d41.png)
ソフトウェアアーキテクチャの基礎を読んだ感想3

モジュールのとは
一般的ににモジュールとはより複雑な構造を構築するために使用できる標準化された部品、または独立した単位の各集合

本社では
関連するコードを論理的にグループ化することをモジュール

定義
モジュールをモノリシックのようにするのではなく、部品ごとにプラットフォームに
分けるほうが再構築ができ、変更や修正がスムーズに行うことが出来る。

モノリシックとは
システムなどの構造について、要素に分割されておらず、全体が一体になっていること

3-2 モジュール性の計測
凝集度
本書では
凝集度とはモジュールの要素がどの程度、そのモジュールに収まっているかの度合いを指す。言い換えれば、凝集度とはモジュール内の要素同士の関連度を表す。

自分で翻訳
一つのモジュール内のコンポーネントがお互いに関連している程度

凝集度の尺度は次のように定義している
・機能的凝集度
関連する要素だけでモジュールが構成され、モジュールが機能するために必要なものがすべて含まれている。

・逐次的凝集
一方が出力したデータをもう片方が入力する形で２つのモジュールが相互に作用している

・通信的凝集
２つのモジュールが通信の連鎖を形成し、お互いの情報を操作したり、なにかしらの出力に貢献したりする。たとえば、データベールにレコードを追加し、電子メールを生成する。

・手続き的凝集
２つのモジュールは特定の順番でコードを実行する必要がある。

・時間的凝集
モジュール間に時間的な依存関係がある。たとえば、多くのシステムには起動時に初期化しなければならない。一見、無関係な処理群が存在している。これらの異なる処理には時間的な凝集があるといえる。

・論理的凝集
モジュール内のデータは論理的に関連しているものの、機能的には全く関連していないといえる。（フォーマットやデータの型が全く違う)
例えば、テキストやシリアライズされたオブジェクト、またはストリームを情報へと変換するモジュールだと、これらの場合、操作上では関連があるものの、機能は全く違う。

・偶発的凝集
モジュール内の要素は同じソース内にある以外には関連性がない。これは最も悪い形になる

７段階も尺度があるにもかかわらず、凝集度は結合度よりも精度が低いメトリクスです。（CPU使用率、メモリ使用率、ディスク使用率、Date //o ,アクセス数、などの情報を取得して測定値をグループ化したもの）

モジュールはLOCMのスコアが低く、凝集度が高いとよいモジュール構造といえる

LOCMとは（メゾッドの凝集度の欠如）とはモジュールの構造的な凝集度を計測するメトリクスのこと。LOCMのスコアが低いとモジュール内のメゾットがお互い密接に関連していなくモジュール全体が統一感があり、再利用性が高く、テストしやすい。一般的にLOCMスコアが低いと良い。ただLOCMではクラス同士の関係性は見れない。
モジュールの凝集度が低いと責任が分かれている。つながりが複雑で目的が違う部品が同じモジュールに存在する部品同士の関係が強くなったり、再利用性が難しくテストも難しいなのでモジュール凝集度が低いと役割の分散やつながりの複雑化、再利用、テストの難しさの問題が生じる可能性があるので凝集度が高い設計を心掛けたほうがいい。
ソフトウェアアーキテクチャの第二のほうそくとはモジュール（クラス）間の結びつきをできるだけ弱くするということ。

・求心性結合
コードアーティファクト（コンポーネント、クラス、関数など）に外部から入力される接続数を計測する

・遠心性結合
他のコードアーティファクトに出力する接続数を計測する

・コナーセンス
求心性と遠心性の結合メトリクスを解消しそれをオブジェクト指向向けに再構築したもの
静的と動的、2種類のコナーセンスを定義した。

上をわかりやすくまとめると

求心性と遠心性はプログラムの設計において各部分がどれだけ依存しているか独立しているか示す尺度のこと

コナーセンスとは
システムやプログラムを作る際にお互い関連しあっていることを意識することで全体として正しく機能するシステムをお作るための考え方のこと。
Windows 11 + WSL2環境でのPythonブラウザ自動操作環境構築(browser-use)

## はじめに

この記事では、Windows 11のWSL2（Windows Subsystem for Linux 2）環境で、Pythonを用いてブラウザを自動操作するための開発環境構築手順を解説します。具体的には、Playwrightというライブラリを使用し、Webページのスクレイピングや自動テストなど、様々なブラウザ操作をPythonから行う方法を説明します。

## 環境構築

### WSL2とUbuntuのインストール

まず、WSL2とUbuntuをインストールします。以下のコマンドをPowerShellで実行してください。

```powershell
wsl --install
wsl --install -d Ubuntu-24.04
```

これにより、WSL2が有効になり、Ubuntu 24.04がインストールされます。インストール後、Ubuntuの初期設定を行ってください。

### Python 3.11の環境構築

次に、Python 3.11をインストールします。WSL2上のUbuntuで以下のコマンドを実行してください。

```bash
# deadsnakesリポジトリの追加
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt update
sudo apt install python3.11 python3.11-venv python3.11-dev
```

`deadsnakes`リポジトリは、新しいバージョンのPythonをインストールするのに便利なリポジトリです。

### 仮想環境の作成

Pythonの仮想環境を作成し、必要なパッケージをインストールします。以下のコマンドを実行してください。

```bash
python3.11 -m venv jupyter_env
source jupyter_env/bin/activate
```

これにより、`jupyter_env`という名前の仮想環境が作成され、アクティベートされます。

## パッケージのインストール

### 基本パッケージ

Jupyter NotebookやJupyterLabなど、基本的なパッケージをインストールします。

```bash
python -m pip install --upgrade pip setuptools wheel
pip install jupyter notebook jupyterlab
```

### browser-useとその依存パッケージ

ブラウザ操作に必要な`browser-use`パッケージ（と、その依存パッケージ）をインストールします。

```bash
pip install browser-use
```
`browser-use`は、内部で`playwright`を利用しています。

## インストール確認

### 依存パッケージの確認コード

インストールしたパッケージが正しくインポートできるか確認します。以下のPythonコードを実行してください。

```python
try:
    from maincontentextractor import MainContentExtractor
    from playwright.sync_api import sync_playwright
    import httpx
    from langchain import LangChain
    
    print("Main dependencies imported successfully!")
    
    # パッケージのバージョン確認
    import pkg_resources
    version = pkg_resources.get_distribution('browser-use').version
    print(f"browser-use version: {version}")

except ImportError as e:
    print(f"Import error: {e}")
except Exception as e:
    print(f"Error: {e}")
```

このコードがエラーなく実行されれば、必要なパッケージが正しくインストールされています。

## ブラウザ操作の基本コード

Playwrightを使ってブラウザを操作する基本的なコードです。

```python
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    # ブラウザの起動
    browser = p.chromium.launch()
    
    # 新しいページを開く
    page = browser.new_page()
    
    # Googleにアクセス
    page.goto('https://www.google.com')
    
    # スクリーンショットを保存
    page.screenshot(path='screenshot.png')
    
    # ブラウザを閉じる
    browser.close()
```

このコードを実行すると、Chromiumブラウザが起動し、Googleのページを開いてスクリーンショットを保存します。

## 注意点

- Python 3.12では一部の依存パッケージに互換性の問題があるため、Python 3.11の使用を推奨します。
- `BrowserUse`クラスは現在利用できないため、代わりにPlaywrightを直接使用します。
- テレメトリーを無効化する場合は環境変数 `ANONYMIZED_TELEMETRY=false` を設定してください。

## トラブルシューティング

- Jupyter Notebookが応答しない場合は、カーネルの再起動を実行してください。
- パッケージのインストールに問題がある場合は、`--no-cache-dir`オプションを使用してみてください。
- WSL2環境でブラウザの表示に問題がある場合は、`headless=True`オプションを使用してみてください。

## まとめ

この環境構築を行うことで、Pythonからブラウザを自動操作できるようになり、Webスクレイピングや自動テストなど、様々なタスクを効率化できます。Playwrightは強力なツールであり、様々なブラウザ操作を自動化できます。ぜひ活用してみてください。

## ハッシュタグ

ハッシュタグ: #Windows11 #WSL2 #Python #Playwright #ブラウザ自動操作 #開発環境構築
OMCB032E(843)

https://onlinemathcontest.com/contests/omcb032/tasks/10387

与式に$x=1$を代入して$3$で割った余りは
　$1!+p^4≡0$ $(mod$ $3)$
になり、
　$p^4≡2$ $(mod$ $3)$
です。
　$0^4≡0,1^4≡1,2^4≡1$ $(mod$ $3)$ $…①$
なので、$x=1$は条件を満たしません。

与式に$x=2$を代入して$2$で割った余りは
　$p^4≡q^2$ $(mod$ $2)$
になり、$p,q$の偶奇が一致します。
素数の偶数は$2$しかありませんが、与式に$x=2,p=2,q=2$を代入すると
　$2!+2^4≠9×2^2$
となり、等式が成り立たないので、$p,q$は偶数ではありません。
続いて、与式を$4$で割った余りは
　$2!+p^4≡q^2$ $(mod$ $4)$
　$2+p^4≡q^2$ $(mod$ $4)$
になります。
　$1^4≡1,3^4≡1,1^2≡1,3^2≡1$ $(mod$ $4)$
なので、どの条件でも合同式が成立せず、$p,q$は奇数でもないので、$x=2$も条件を満たしません。

$x≧3$の場合、
$x!$は常に$3$の倍数であることから、任意の整数$n$を用いて
　$3n+p^4=9q^2$
と表せます。
したがって
　$p^4≡0$ $(mod$ $3)$
となり、$①$の条件より、$p$は$3$の倍数であることがわかります。
$3$の倍数の素数は$3$しかないため、$p=3$になります。

与式に$p=3$を代入して、
　$x!+3^4=9q^2$
が得られるので、
　$x!=9(q^2-9)$ $…②$
と式変形でき、$x!$は$9$の倍数になります。
　$3!=2×3$
　$4!=2^3×3$
　$5!=2^3×3×5$
　$6!=2^4×3^2×5$
であるので、$x!$が$9$の倍数であるための条件は、$x≧6$とわかります。

$②$を式変形すると、
　$x!=9(q+3)(q-3)$ $…②'$
となります。
$q=3$を代入すると右辺が$0$になり、$x≧6$の場合、$②'$の等式は成立しません。
また、$q$は$3$以外の素数なので$q+3,q-3$はともに$3$の倍数ではないことがわかります。
このことから、$x!$の素因数分解において、$3$のべき乗は$2$になります。
　$7!=2^4×3^2×5×7$
　$8!=2^7×3^2×5×7$
　$9!=2^7×3^4×5×7$
であるので、$x!$の素因数分解において、$3$のべき乗が$2$であるための条件は、$x<9$とわかります。

与式に$x=6$を代入すると
　$6!+3^4=9×89$
となり、$q^2=89$となりますが、
　$9^2<89<10^2$なので、等式が成立しません。
与式に$x=7$を代入すると
　$7!+3^4=9×569$
となり、$q^2=569$となりますが、
　$23^2<569<54^2$なので、等式が成立しません。
与式に$x=8$を代入すると
　$8!+3^4=9×4489$
となり、$q^2=4489$となります。
　$4489<67^2$
で、$67$は素数なので、これは条件を満たします。

したがって条件を満たす$(x,p,q)$は$(8,3,67)$の$1$通りだけであり、
解は$xpq=8×3×67=1608$です。
Go言語(プログラミング)入門メモ⑧

## ポインタ
変数に値を格納するとき、コンピュータはメモリの特定の位置(アドレス)を指定してそこに値を保持する。
Go言語では、この値を格納している場所を指す「ポインタ」を操作することができる。

## ポインタでメモリ上のアドレスを参照する
まず、int型の変数nを宣言して100を代入し、変数nを出力する。
次に変数nに&をつけて実行する。すると、「0x14--------」(値は適当)と変数nのポインタ(メモリのアドレス)が表示される
~~~
var n int = 100
fmt.Println(n)
fmt.Println(&n)

//以下のように出力される
100
0x14--------
~~~
続いて変数pを「var p *int」と宣言し、&nを代入する。「*int」は、int型の値のポインタをという意味。
変数pを表示すると、先ほどと同様にメモリのアドレスが表示される。このようなポインタを持つ変数は、ポインタ変数と呼ばれる。

~~~
var n int = 100
fmt.Println(n)
fmt.Println(&n)

var p *int = &n
fmt.Println(p)

//以下のように出力される
100
0x14--------
0x14--------       (変数pのメモリのアドレスが表示される)

~~~
アドレスがさすメモリの中身を取得したい場合は、ポインタ変数に*をつける。
~~~
var n int = 100
fmt.Println(n)
fmt.Println(&n)

var p *int = &n
fmt.Println(p)
fmt.Println(*p)

//以下のように出力される
100
0x14--------
0x14--------(変数pのメモリのアドレスが表示される)
100(メモリの中身が表示される)
~~~

var n int = 100では、メモリの「0x0004」というアドレスに100という値を代入している。var p *int = &nでは、アドレス「0x0010」に「0x0004」というアドレスを代入している。したがって、fmt.Println(p)では「0x0004」が表示され、fmt.Println(*p)でポインタの中身を表示させると、100という値が表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3579705/5d060313-d188-126f-f190-28f32d540fab.png)


## 関数でポインタを受け取る
関数の引数に値もしくは値が入った変数をこれまで指定していたが、ポインタを引数に指定することもできる。
int型の引数xを受け取るone関数を作り、その中でxに1を代入する。main関数で宣言した変数nを、one関数の引数に指定して呼び出す。その後、nの値を表示すると、one関数で引数の値を1にしたのに100が表示される
~~~
func one(x int) {
    x = 1
}

func main() {
    var n int =100
    one(n)
    fmt.Println(n)
}

//以下が表示される
100

~~~
これはone関数が受け取るのは変数nそのものではなくて、変数nの値を受け取る。このため、関数の中で値に1を代入しても、main関数で宣言した変数nには影響が出ない。
変数nの値をone関数内で変更したい場合は、ポインタを渡す必要がある。まず、one関数の引数を「x *int」と*を付けて、ポインタとして受け取るようにする。
one関数の処理の中では、引数のポインタがさす実体(変数の値)を変更したいので「*x = 1」とかく。
また、引数がポインタ型になったので、main関数内のone関数を呼び出すときの引数も(&n)に変更する。

~~~
func one(x *int) {     //ポインタの変数xを引数にする
    *x = 1　　　　　　　//変数x(ポインタ)がさす実体に1を代入する
}

func main() {
    var n int =100
    one(&n)　　　　　　//&nのアドレスをone関数に渡す
    fmt.Println(n)
}

//以下が表示される
1
~~~
## 変数のアドレスと中身を表示する
&と*を使って、変数のアドレスを表示したり、アドレスが指す実体を表示したりしてみる。
int型の値が格納された変数nについて、アドレスを見るためには「&n」と書く。
~~~
func main() {
    var n int = 100
    one(&n)
    fmt.Println(n)
    fmt.Println(&n)
}

//以下のように出力される
1
00140001120018(アドレスが出力される)
~~~

&nのアドレスの中身を見るためにはさらに「*」をつけて「*&n」と書く。
~~~
func main() {
    var n int = 100
    one(&n)
    fmt.Println(n)
    fmt.Println(*&n)
}

//以下のように出力される
1
1(アドレスの中身が出力される)
~~~
さらにアドレスの中身のアドレスを見るためには「&*&n」と書く。
~~~
func main() {
    var n int = 100
    one(&n)
    fmt.Println(n)
    fmt.Println(&*&n)
}

//以下のように出力される
1
0x14000113018(アドレスが出力される)
~~~

















## 学習に使用した教材
・『入門】Golang基礎入門 + 各種ライブラリ + 簡単なTodoWebアプリケーション開発(Go言語)』M.A EduTech
https://www.udemy.com/course/golang-webgosql/?utm_medium=udemyads&utm_source=bene-msa&utm_campaign=responsive&utm_content=top-1&utm_term=general&msclkid=81e2f24a32cc185d275d953d60760226&couponCode=NEWYEARCAREERJP

・『シリコンバレー一流プログラマーが教える Goプロフェッショナル大全』酒井 潤 (著)
https://www.amazon.co.jp/%E3%82%B7%E3%83%AA%E3%82%B3%E3%83%B3%E3%83%90%E3%83%AC%E3%83%BC%E4%B8%80%E6%B5%81%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%83%BC%E3%81%8C%E6%95%99%E3%81%88%E3%82%8B-Go%E3%83%97%E3%83%AD%E3%83%95%E3%82%A7%E3%83%83%E3%82%B7%E3%83%A7%E3%83%8A%E3%83%AB%E5%A4%A7%E5%85%A8-%E9%85%92%E4%BA%95-%E6%BD%A4/dp/4046070897
自宅にXeonサーバーを設置した。

# 経緯
普段高校生をしている身、財力にはとぼしいのであります。
なるべく安くサーバーを手に入れたい、という要望を叶えられそうな記事を発見しました。
[その記事](https://pc.watch.impress.co.jp/docs/topic/feature/1558511.html)
E5 2650 V4　ハードウェアには疎いのですが、
2016年に発売されたxeonシリーズで12コア/24スレッドとサーバーとしては申し分ないでしょう。
現在は1500円程度で購入が可能です。(当時は15万ぐらいしたそうな...)

ということで、我らが味方AliExpressを彷徨っていたところX99(xeonの何か規格？)デュアルCPU搭載のマザーボードを発見しました。

デュアルなのでパワーは2倍ですね。

今回お世話になった記事です。

https://blog.kabocy.com/homebuilt-computer/2466/


# 構成
今回は自宅サーバーです。
用途はアプリケーションの設置、つまりデプロイ場所を作りたいということです。

図が汚いのと用語・英語が弱いのは御愛嬌で...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3769595/042d3c97-92be-4170-70fa-06b7ed282261.png)
左下のApps serverの部分を今回は作っていきます。

OSは前回の記事で紹介したproxmoxを使用したいと思います。
unlock vGPUをサポートしていることが理由です。

サーバーの安全のために入口は一つに絞り、グローバルIPを公開しないcloudflareを使っています。

買ったもの
[ECC対応メモリ16GB](https://ja.aliexpress.com/item/1005007218012984.html?spm=a2g0o.order_list.order_list_main.5.21ef585a3pPisX&gatewayAdapt=glo2jpn)

返品や不良品の対応が良いのでアリエクと同じものをAmazonで買いました。
[X99デュアルCPU対応マザーボード](https://www.amazon.co.jp/dp/B09B38TS6Z)

2ファンの物もありますが大きさ的にキツく1ファンの方が良いと感じました。
[CPUクーラー](https://ja.aliexpress.com/item/1005005988738391.html?spm=a2g0o.order_list.order_list_main.11.21ef585auoIYXc&gatewayAdapt=glo2jpn)

物によっては不良品の可能性があるみたいで、運ゲーです。
[CPU](https://ja.aliexpress.com/item/1005007203894932.html?spm=a2g0o.order_list.order_list_main.27.21ef585auoIYXc&gatewayAdapt=glo2jpn)

店舗で世代遅れのを安く買いました。**ジャンクショップで漁ることをおすすめします。**
[**E-ATX対応**ケース](https://kakaku.com/item/K0001460795/)


電源(750W)は家に落ちていたものを使用したのですが、何故かピンの口が合わず(意味がわからない)カッターで切って無理やり接続しました。一応変換のケーブルは買ったほうが良いでしょう。

どれも問題なく動作しましたが、やはり個体差があるようなので気をつけてください。
(アリエクで2650 V4動作しないというレビューがしてあってビビりました...)

![スクリーンショット 2025-01-15 231439.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3769595/b3ed1c9f-729a-e51a-9fb6-6f8a50ee631f.png)


金額は合計で約3万円ほどになりました。
電源と工具の値段が入っていないのでおそらく4万円を見積もったほうが安牌です。

**何か間違いや勘違いなどあったらコメントお願いします。**

# 組み立て
気が向いたら書きます・・・

# 感想とか余談
初めての自作PCでしたが、少しマイナーを攻めすぎた感が否めない結果になってしまいました。
組み立てをしたらパソコンへの解像度が上がると勝手に思っていましたが、事前知識を持って自作をするからいいものなんですね。勉強になりました。
【Starship】FishのTransientPromptを設定する方法

`~/.config/fish/config.fish`に以下を追記するとTransientPromptが設定できます。

```config.fish
function starship_transient_prompt_func
  starship module character
end
starship init fish | source
enable_transience

```

上記の場合には実行後のプロンプトは`>`のみになります。

![画面収録 2025-01-14 0.04.17.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/486592c5-6d5b-cebb-47d7-1557da4c30af.gif)
React19のformタグに関する新機能についてまとめてみる

React 19では、新しいフォーム機能「Form Actions」が追加され、サーバーサイドプロセスの実装がこれまで以上に簡単になりました。

## Form Actionsとは？
Form Actionsは、Reactでフォームを送信する際のサーバーサイド処理を簡略化するための機能です。具体的には以下の特徴があります。

### 関数を直接actionプロパティに指定可能
フォームのactionプロパティに関数を渡すことで、サーバーサイド処理を簡単に統合することができるようになった。

### 同期・非同期関数のサポート
関数内で同期的な処理や非同期的な処理を自由に組み込むことが可能

### FormDataの利用
フォームのデータが引数として渡され、簡単に取得・操作できます。

## Form Actionsの主な利点

### エンドポイントの作成が不要
これまでのフォーム送信では、バックエンドAPI（例:/api/submit）を用意し、クライアントからデータを送信する必要があった。Form Actionsを使うと、この手間が省ける。

### useStateやonChangeの不要化
入力データを状態で管理する必要がなくなり、簡潔なコードを実現できます。

### 新しいuseFormStatusフックとの連携
フォームの状態（例：pending）を取得するためのフックが提供され、リアルタイムでの状態管理が可能です。

## React18以前のコード
React 18以前では、以下のようにフォームの送信処理を実装していました。
	1.	useStateを用いて入力値を管理。
	2.	onChangeイベントで状態を更新。
	3.	サーバーサイド処理を行うエンドポイントを準備。
	4.	fetch関数などでデータをPOSTリクエストとして送信。

```typescript
"use client";
import React, { useState } from "react";

export default function Home() {
  const [name, setName] = useState("");

  const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    fetch("/api/submit", {
      method: "POST",
      body: JSON.stringify({ name }),
    });
  };

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setName(e.target.value);
  };

  return (
    <form onSubmit={handleSubmit}>
      <label>
        Name:
        <input type="text" value={name} onChange={handleChange} />
      </label>
      <button type="submit">Submit</button>
    </form>
  );
}
```

## Form Actionsを用いた新しいフォーム送信方法
React 19のForm Actionsでは、上記の手間を大幅に省くことができます。
	1.	actionプロパティにサーバーサイド関数を指定。
	2.	関数内でFormDataを使ってデータを取得。
	3.	必要に応じて非同期処理を組み込む。

```typescript
export default function Home() {
  const formAction = async (formData: FormData) => {
    "use server"; // サーバーサイドで動作する関数
    console.log(formData.get("name")); // フォームデータを取得
  };

  return (
    <form action={formAction}>
      <label>
        Name:
        <input type="text" name="name" />
      </label>
      <button type="submit">Submit</button>
    </form>
  );
}
```
Bitwarden拡張機能の改悪されたUIをもとに戻す

# 突如訪れた ~~センスのない~~ UIアップデート！

今までは、ワンクリックでユーザ名やパスワード、TOTPをコピーできていました。また、自動入力候補として表示された項目のどこをクリックしても自動入力されていました。

しかし去年12月頃のアップデートで、ワンクリックコピーボタンはケバブメニュー（三点リーダー）に押し込められ、2クリック必要になってしまいました。また、自動入力機能は小さなボタンへと移行され、代わりに項目をクリックすると編集画面に入ります。~~よく使う自動入力は小さなボタンで、あまり使わない編集機能が広い面積を占める非常に非合理的なアップデートだと言えます。~~

# Bitwarden コミュニティの不満

https://community.bitwarden.com/search?q=fill%20button%20after%3A2024-12-04

このような不満を持った人が多くいたようで、Bitwardenフォーラムでは相次いてスレッドが建っています。これにより、Bitwarden 開発チームはUIをもとに戻す機能を実装したのですが、そのボタンの場所 ~~がクソ分かりにくいので~~ 紹介します。

# ~~治し方~~ UI変更オプションの場所

**~~豆粒みたいな~~ Fillボタン**

「設定 -> 自動入力 -> Click items to autofill on Valut view」をオンに

**~~手間のかかる~~ コピーボタン**

「設定 -> 外観 -> Show quick copy actions on Vault」をオンに

ちなみに同じ場所の Compact Mode (Beta) で以前のようにスマートな見た目に変更できます。
Pythonの基礎、Docker、Flaskでアプリを作る（１）　　-python

新年目標として本格的にバックエンド言語を扱い、フロントエンドとの繋がりを確実に作れることにした。最近、仕事で使っているpythonが面白し、会社の先輩からもpythonは初心者が理解し比較的に簡単な言語だと聞いた。

udemyのRestApis with Flask and Python（https://www.udemy.com/share/101sjY3@PBNEDColeMflnyBIaXXCd_dUSPz0Ew8jvSIEsmxgDQ2hjv_L8GCnC9keSptFVBm08g==/）を勉強を完了した後、Reactとのつながりを設計することに決まった。結構pythonの基礎からFlask, Docker, SQLAlquemy回りをしっかり優しく教えてくれるのでおすすめです。

最初に学んだ言語がRubyだったので、色々似ていることに気づいたが、一番慣れているJavaScriptの差があって迷いの中。

### Pythonの基礎
```python
#python types
list = ["Bob", "Rolf", "Anne"]
tuple = ("Bob", "Rolf", "Anne")  # <-何を入れたり外したりすることができない
 set = {"Bob", "Rolf", "Anne"}
```

```python
#loopの使い方
numbers = [1,3,5]
doubled =  [num * 2 for num in numbers]

#下のコードより上の整理されたコードを使うこと
for num in numbers:
	doubled.append(num*2)
```

```python
#dictionaryでkey,valueの値を取得する方法
student_attendancd = {"Rolf": 96, "Lena": 100}

for student, attendance in student_attendance.items():
		print(f"{student} : {attendance}")
		
		student_attendence.values()
```

```python
#mapの使い方
def double(x):
	return x*2
	
	
sequence = [1,2,3,4]
doubled = [double(x) for x in sequence] #listcomprehension
doubled = map(double, sequence)
```

```python
#dictionaryを使う方法
users = [(0, "bob"), (1, "lena")]

result = {user[1]: user for user in users}
print(result)

{
    "bob": (0, "bob"),
    "lena": (1, "lena")
}
```

```python
#関数で引数を渡す方法
def both(*args, *kwargs)
	print(args)
	print(kwargs)
	
both(1,3, 5, name="lena", hobby='dancing') 
```

```python
#classを使い方
class Student:
	def __init__(self, name):
		self.name = name
		self.grades = (90, 35, 62)
		
		
	def average(self):
		return sum(self.grades) / len(self.grades)

#classmethodを使う方法
class Book:
	TYPES = ("hard cover", "soft cover")
		def __init__(self, name, book_type):
				self.name = name
				self.book_type = book_type
				
		@classmethod
		def hard_cover(cls, name)
				return Book(name, Book.TYPES[0])
				
		@classmethod // better way
		def hard_cover(cls, name)
				return cls(name, cls.TYPES[0])
```


```python
#first class functions -関数は引数だ。
import functools

user = {"name": "Tom", "access_level": "admin"}


def make_secure(func):
    @functools.wraps(func)
    def secure_function(*args, **kwargs):
        if user["access_level"] == "admin":
            return func(*args, **kwargs)
        else:
            print("you dont have any access right")

    return secure_function


@make_secure
def get_password(panel):
    if panel == "admin":
        return "1234"
    elif panel == "billing":
        return "super_secure_password"


print(get_password("admin"))
print(get_password("billing"))
```

udemyで聴く時はちゃんと理解したが、もう一回振り返そうとしたが、もう記憶にあまりなくてびっくり。なんとなく何回の振り返しや実際のアプリ作りが学びの一番大事なことだと思います。
Dockerやflaskについては、まだまだ後で🍋
【一発合格】AZ-104: Microsoft Certified: Azure Administrator Associateの勉強記録

# 概要
AZ-14を無事一発合格しました。記録を残します。
点数は765/1000点。
勉強期間は約1週間。実施したログはすべて以下に記載しています。

# 教材
Microsoft公式

https://learn.microsoft.com/ja-jp/credentials/certifications/azure-administrator/?practice-assessment-type=certification

Udemy

https://www.udemy.com/course/30az-104-microsoft-azure-administrator240/?couponCode=NEWYEARCAREERJP

https://www.udemy.com/course/microsoft-azure-az104-exam/?couponCode=NEWYEARCAREERJP

https://www.udemy.com/course/azure-az104-learn/?couponCode=NEWYEARCAREERJP

https://www.udemy.com/course/az-104-microsoft-azure-administrator-jp/?couponCode=NEWYEARCAREERJP

その他

https://it-concepts-japan.com/

# 模擬試験受講ログ
## Udemy 模擬問題集4
- 回数：2回目
- 受講日：2025/1/19
- 結果：98%
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3973326/540d37ee-a332-edeb-024f-88c38903737e.png)


- 回数：1回目
- 受講日：2025/1/19
- 結果：57%
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3973326/819f05bf-4826-a951-6f8e-d33c04d028d7.png)


## Udemy 模擬問題集3
- 回数：3回目
- 受講日：2025/1/18
- 結果：98%
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3973326/38e559f5-f3ff-cc33-32a4-d29e8307df46.png)


- 回数：2回目
- 受講日：2025/1/18
- 結果：64%
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3973326/af4910e1-d8bd-c8b8-a976-19cc9c63b596.png)


- 回数：1回目
- 受講日：2025/1/13
- 結果：50%
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3973326/b96ff77b-6154-d4c3-d642-cafa9c5eae50.png)


## Udemy 模擬問題集2
- 回数：3回目
- 受講日：2025/1/18
- 結果：93%
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3973326/92d15584-3838-07b6-49b5-d5f49205ecbb.png)


- 回数：2回目
- 受講日：2025/1/18
- 結果：66%
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3973326/ccebc100-73e5-ef35-af07-4d5d42f262ce.png)


- 回数：1回目
- 受講日：2025/1/13
- 結果：58%
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3973326/6845eb13-d3de-41da-37c9-07b765cfac42.png)


## Udemy 模擬問題集1

- 回数：3回目
- 受講日：2025/1/18
- 結果：81%
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3973326/d4ba57f9-d162-c829-5456-963ee269a8a2.png)

- 回数：2回目
- 受講日：2025/1/13
- 結果：89%
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3973326/3452ca0f-4b39-2f73-c782-ba5ac33c9166.png)


- 回数：1回目
- 受講日：2025/1/13
- 結果：59%
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3973326/1d0e6f55-f97f-6dde-1918-e64882b34a2a.png)



## Microsoft 公式Practice
- 回数：4回目
- 受講日：2025/1/19
- 結果：84%
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3973326/22c86d23-0412-a7da-ee07-5f439e18603b.png)


- 回数：3回目
- 受講日：2025/1/19
- 結果：62%
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3973326/e6475819-94e6-ed03-cd6e-3af65cda7796.png)


- 回数：2回目
- 受講日：2025/1/13
- 結果：72%
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3973326/d9c93d59-1fd7-6052-6c67-946c2beb7a2c.png)


- 回数：1回目
- 受講日：2025/1/12
- 結果：44%
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3973326/b70ca1d9-9a9e-18e2-773a-9a61781fa1bc.png)
OpenAI APIのアカウントと作成とチャージについて

## GPTのAPI利用について

ChatGPTは、GPTにWebUIを付けた仕組みを指します。このWebUI部を除いたGPTそのものを利用する仕組みがOpenAI APIです。OpenAIを支援しているMicrosoftからは、課金体制でAzure OpenAI APIも使えます。

### API利用のメリット
 * WebAPIで利用でき、さまざまなツールからGPTへの問い合わせが可能
 * 問合せ内容やその結果が、GPTの学習に使われない（情報漏洩に強い）
 * 非常に安価で使うことができる

個人や業務の中で使う分であればWebUIでも問題ありません。
しかし、業務効率化や自動化の中で、GPTの恩恵を受ける場合、どうしてもシステムから実行したいケースが出てきます。その場合、このOpenAI APIを利用することで、実現ができます。

RPAやクラウドフロー等からWebUIを介することなく、API経由で問合せをすることで、エンドユーザがわざわざプロントエンジニアリングをしなくとも、知らず知らずのうちにGPTの恩恵を受けることができるようになります。

## OpenAI API KEYの作り方

OpenAI APIを使うには、アカウントとAPI Keyが必要になります。
アカウントは、誰が使うのか（誰がAPI利用料の支払いをするのか）に紐づきます。
API Keyは、複数作ることができます。作るだけであれば無料ですので、個人的にはシステム毎であったり、プロジェクト毎に作成することオススメします。
API Keyが漏れてしまうと、他人がGPTを使いたい放題になってしまいます（無断使用料が請求されてしまいます）。よって、API Keyが漏れたことを想定したリスク対策が必要で、システム毎やプロジェクト毎にAPI Keyを使うことでリスク対策になります。

実際のアカウントの作成とAPI Keyの作成は、こちらの記事を参考にしてください。

https://note.com/kerdy/n/n993eadf242b5

## チャージの仕方

アカウントを新規に作成すると、US5$分程度が自動でチャージされます（この分は課金対象外です）。
ですので、まずはこの自動付与されたチャージでOpen AI APIを試すことができます。

そして、APIを使用する毎にこのチャージが減っていき、チャージ分が無くなってしまうと、APIが利用できなくなってしまいます。
そのため、事前にチャージをする必要があり、そのための手順がメモしてあります。

https://note.com/kerdy/n/n9bd1b93a21df

## OpenAI APIは便利なツール

OpenAI APIは、非常の性能の良いGPT-4やGPT-4o、GPT-o1などが安価に使えるサービスです。特に、GPT-4o-miniは、トップクラスの性能ながら、GPT-3.5よりも安価な価格設定となっております。
ソフトウェアアーキテクチャの基礎本を読んだ感想2

アーキテクチャの思考
2-1 アーキテクチャと設計
アーキテクチャ
・アーキテクチャ特性
・スタイル
・コンポーネント構造

開発者
・クラス設計
・ユーザインターフェイス
・ソースコード

従来、アーキテクトがアーキテクチャを開発者に伝える。しかしうまく伝わらない場合、開発者はアーキテクトが伝えたアーキテクチャを守らないこと、よく理解していなことがある。そーなっても開発者はアーキテクトにそのことを伝えない。それでは良くないのでしっかり、双方でコミュニケーションを取って連携をしたほうがいいということ

2-2アーキテクトの技術的な幅
アーキテクトは技術の幅を広くしてわかっていないことを減らしていくが大事
よーするに浅く広くを意識する。

トレードオフを分析する

2-3トレードオフとは利点と欠点のバランスのこと
アーキテクチャには正解がなく、必ずしも正しいというわけではない。なぜなら、それぞれの形や仕組みにメリットデメリットがあるから。
だからアーキテクチャの選択は常にトレードオフを考える必要がある。どのメリットを
重視するか。どのデメリットを受けいれるか。

2-4ビジネスドライバーを理解する
ビジネスドライバーとは仕事や事業を成功させるために必要な要素

アーキテクトに必要なことは美辞ネルドライバーを理解してそれをアーキテクチャの特性に変換して関係者と協力してシステム設計すること。

2-5 アーキテクティングとコーディングのバランスをとる
一番注意しなければいけないことはチームのボトルネックになってしまうこと
結論
実現できそうな機能（サービスや画面）の開発に集中する
メリット
・開発の実務経験がつめる。
・チームの開発者にアーキテクチャの難しい部分を理解してもらえる。
・開発の問題や難しい部分を知ることができる
SAP环境配置

1.选择「可変ログイン」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795764/14cc148f-0046-875a-306b-a74744998afb.png)

2.点击「次画面」，输入必要的信息。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795764/bf867aa4-7507-627d-6f6c-b8bf89f70dd7.png)
ラズパイ５　初期設定

勉強の一環でWebサイトの作成を始める事にしました。
そのためにラズパイを購入して組み立て、初期設定まで終了したのでその時にやったことを復習用で残したいと思います。

まず最初に、始めるにあたって必要になったものが
・MacBook Air
・Raspberry Pi 5 スターターキット
・microSDカード変換アダプター
・HDMI変換アダプター

MacBookだと変換ケーブル多くて面倒でした。元々パソコンにさせるならアダプターは必要ありません。
あと、ラズパイは基盤だけかって周辺パーツを別で揃えることもできますが、機器にあまり詳しくないのでスターターキットを購入しました。

というわけで、早速設定に入ります。
まず私が参考にしたサイトが

[組み立て]
https://www.switch-science.com/pages/pi5assy?srsltid=AfmBOorLwr-IKQqNwrJIrQk3e8q8rq_5QigjGVbsoAp0RWuWUe29ZpVW

[設定]
https://sukiburo.jp/setup-raspberry-pi/#2-1

この二つです。
組み立てはスターターキット買っているならまずつまづかないと思うので割愛。
設定のほうに行きます。

まずは
https://www.raspberrypi.org/downloads/
こちらから「Raspberry Pi Imager」をインストールします。
「Raspberry Pi Imager」はmicroSDカードの初期化から、ラズパイOSのインストールまでを自動で行ってくれます。OSは「Raspberry Pi OS (64-bit)」、ストレージは挿しているmicroSDを選びます。
この後ユーザー名とパスワードを設定しますが、忘れないようメモしといて下さい。ちなみにメモしておくべきことはこの2つとラズパイのipアドレスです。この先必要になるものがあるかもなのでちゃんと調べてほうがいいかもですが...

で、この後はしばらくターミナルを触ります。あまり詳しくないので説明できないですができる限りで。
ラズパイのipアドレスを特定してSSH接続という方法でラズパイにアクセスします。これだとアクセスするだけなので、画面表示するためにVNC接続を行います。VNC接続行ってからはターミナルでの操作はVNSサーバー上になります。このサーバーからラズパイの初期設定を行います。
私が行った初期設定は上記サイトのもののみです。
書いてるままやれば問題ないので難しくないですが、強いていうならファイヤウォールの設定がVNCをローカルで使用するもので設定することですかね。何通りかあってちょっとだけ迷いました。

全体を通して、Webの解説がしっかりしているのであまり躓かず済みました。
私の解説ほぼありませんが、参考になれば嬉しいです。
[PowerApps]カスタムコンポーネント

# 背景
PowerAppsのキャンバスアプリで同じ部品をいくつか並べる必要があり、**共通化できない**か調査してみたところ、カスタムコンポーネントを活用できるみたいです。
**カスタムコンポーネント**に様々な種類のカスタムプロパティがあったのでまとめておきます。

# カスタムコンポーネント作成
1. ツリービューを選択
1. コンポーネントを選択
1. アクセスアプリスコープをオン
※上記3については、カスタムコンポーネントで**コンポーネントを実装する画面のグローバル変数を参照するか**。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987347/34a8a5db-a2ac-9742-27e7-2048b4966142.png)

# カスタムコンポーネントのプロパティの種類
|種類  |概要  |使用するケース  |
|---|---|---|
|入力  |コンポーネント実装画面から**入力**するカスタムコンポーネントプロパティを定義できます  |**コンポーネント実装画面から値を入れたい**カスタムコンポーネントプロパティがある  |
|出力  |コンポーネント実装画面に**出力**するカスタムコンポーネントプロパティを定義できます  |**コンポーネント実装画面へ渡したい**カスタムコンポーネントプロパティがある  |
|イベント  |カスタムコンポーネントの処理をトリガーにした**イベント関数**をコンポーネント実装画面側にコンポーネントに定義できます  |**コンポーネント実装画面にカスタムコンポーネントの処理をトリガーとして**、定義したい関数がある  |
|関数  |コンポーネント実装画面側から呼び出すカスタムコンポーネントの**関数**を定義できます  |**コンポーネント実装画面から呼び出したい**カスタムコンポーネントの関数がある  |

### 入力プロパティ画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987347/6a89d9f3-d15a-fae9-ac6e-9aac8ca14bd5.png)

#### コンポーネント実装画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987347/9d77ae2f-1208-c11a-1288-6e4589fc4f76.png)
※turnはオセロゲームが誰の番かを表す変数です。

#### カスタムコンポーネント画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987347/b2604d87-4292-9f7b-41cd-2d0c463eb0c0.png)

### 出力プロパティ画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987347/187075c4-cb96-65d6-8a37-08e61da527a9.png)

#### コンポーネント実装画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987347/9ede3d6f-46aa-55aa-8141-e435c07965f2.png)
※OutTurnはカスタムコンポーネントで更新したオセロゲームの誰の番かを表したプロパティ値になります。

#### カスタムコンポーネント画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987347/8e1f0dce-010b-d280-8044-2dfe5e57e66a.png)

### イベントプロパティ画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987347/fce856b9-9b50-bc73-0756-267cbc1e1557.png)

#### コンポーネント実装画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987347/da77cc09-edca-5263-d431-e62def85d995.png)
※オセロゲームの碁石が置かれたことをトリガーにした関数です。

#### カスタムコンポーネント画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987347/3b0991e2-30f0-836e-c020-34218ba662f3.png)

### 関数プロパティ画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987347/30045201-40f7-3208-3836-1fc6c5a1f3e1.png)

#### コンポーネント実装画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987347/105dbf06-163d-a59d-c557-d1e5c26c20de.png)
※オセロゲームで他の石が置かれたとき、それぞれの碁石をひっくり返す関数を呼び出しております。
※ひっくり返す関数を碁石を置いた位置から縦、横、斜めの八方向に碁石が置けるまで呼び出せば、完成ですが、未実装です。

#### カスタムコンポーネント画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2987347/f1acf635-e934-9510-c890-c1f09c08aeed.png)

# まとめ
**共通のコンポーネントを使いまわす機会はある**かと思うので、ぜひカスタムコンポーネントを使って、実装をシンプルにしてみてください。
今回**カスタムプロパティの引数、戻り値**には、触れておりませんが使用する機会があったら、触れてみようと考えております。

この記事が皆さんの役に立てば幸いです。何か質問があれば、コメント欄で教えていただけると幸いです！
FAT32 volume を macOS でマウント（コマンド利用）

こんにちは
FAT32 volume を macOS (15.2 Sequoia) にてコマンド利用でマウントしました。

#### 状況
USB 接続したところ、警告メッセージ：```接続したディスクは、このコンピュータで読み取れないディスクでした```が現れましたので、「無視」を選択しました。


#### コマンドを利用しマウント
接続したままで、Terminal 上にて diskutil コマンドを利用しマウントできました。disk identifier は```/dev/disk4```です。

```console
$ diskutil mountDisk readOnly /dev/disk4
Volume(s) mounted successfully
$ sw_vers | grep Product
ProductName:		macOS
ProductVersion:		15.2
```

disk identifier を調べるには、

```console
$ diskutil list | grep disk[0-9]s1$
   1:             Apple_APFS_ISC Container disk1         524.3 MB   disk0s1
   1:                APFS Volume Macintosh HD            11.2 GB    disk3s1
   1:                 DOS_FAT_32                         7.9 GB     disk4s1
```

参考：https://github.com/chris1111/Mount-MS-DOS-Partition
【AWS SAP】Amazon FSx for Lustreとは

# Amazon FSx for Lustreとは
高速データ処理用の分散ファイルシステム

:::note info
- Lustreの読み方は「ラスター」
- 名前は「Linux」と「Cluster」から
:::

## 他のファイルシステムとの違い

| サービス名                  | 主な用途・特徴                                                                                   | 適したユースケース                                   |
|-----------------------------|--------------------------------------------------------------------------------------------|---------------------------------------------------|
| **Amazon S3**              | オブジェクトストレージ。高い耐久性とスケーラビリティを提供。                                    | バックアップ、アーカイブ、静的ウェブホスティング、データレイク |
| **Amazon EFS**             | ネットワークファイルシステム（NFS準拠）。複数のEC2インスタンスから同時アクセス可能。              | Webサーバーの共有ストレージ、アプリケーションデータ共有 |
| <font color="red">**Amazon FSx for Lustre**</font>  | <font color="red">**高スループット・低レイテンシの分散ファイルシステム。**</font>                                           | <font color="red">**ビッグデータ処理、機械学習、メディアレンダリング**</font>     |
| **Amazon FSx for Windows File Server** | Windowsネイティブのファイルシステム。Active Directory統合やSMBプロトコルをサポート。       | Windowsアプリケーションのファイル共有、データベース |
| **Amazon FSx for OpenZFS** | オープンソースのZFSファイルシステム。スナップショットや圧縮機能を提供。                            | 開発・テスト環境、スナップショット管理               |

## Amazon FSx for Lustre が連携できるAWSサービス
- **Amazon S3**
  - 主な用途: データのインポート/エクスポート。Lustreファイルシステム上で高速処理。
  - シナリオ例: データレイク分析、機械学習トレーニングデータの準備。
　
- **Amazon EC2**
  - 主な用途: 高性能コンピューティング（HPC）環境でのファイルシステムアクセス。
  - シナリオ例: 科学シミュレーション、動画レンダリング、ビッグデータ解析。
　
- **Amazon SageMaker**
  - 主な用途: 機械学習モデルのトレーニングに高速なデータアクセスを提供。
  - シナリオ例: モデルのトレーニングや検証パフォーマンスの向上。
　
- **AWS Batch**
  - 主な用途: 大規模バッチ処理ワークロードのストレージとして利用。
  - シナリオ例: 大量データを処理するバッチタスク。
　
- **AWS Lambda**
  - 主な用途: サーバーレス環境でFSx for Lustreと連携したデータ処理やワークフローの自動化。
  - シナリオ例: イベント駆動型のデータ処理。
　
- **AWS CloudFormation**
  - 主な用途: FSx for Lustreを含むインフラのコード管理と自動化。
  - シナリオ例: 一貫性のある環境構築、デプロイの効率化。
　
- **Amazon CloudWatch**
  - 主な用途: ファイルシステムのメトリクスとログのモニタリング。
  - シナリオ例: パフォーマンス監視、問題検出とアラート。


## 補足
:::note info
高性能コンピューティング（HPC）が求められるEC2にはアタッチされたENIから「Elastic Fabric Adapter」を有効化しよう。10～40％程度の処理時間が短縮される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2746730/89204ad9-7d7d-6bf9-3d32-af415d1a8f26.png)
:::
Docker環境でGitの日本語コミットメッセージが文字化けする問題の解決まで

Dockerコンテナ内でGitを使っている際に、日本語コミットメッセージが文字化けする問題に相対した際の解決方法をまとめました。以下の手順を実行することで解決できます。

## 問題の現象

- Gitで日本語コミットメッセージを使用すると文字化けする。
- `git log` の出力が、UTF-8の文字化け表示になる。
- Nanoを使ったコミットメッセージで文字化けが起こる。

## 解決手順

### 正しいロケールを設定

まず、Dockerコンテナ内のロケールを確認します。

```bash
echo $LANG
```

正常な状態では、次のように `en_US.UTF-8` や `ja_JP.UTF-8` が返されます。

その他の値が返された場合は、以下のようにロケールをUTF-8に設定しましょう。

```bash
export LANG=C.UTF-8
```

これで一時的にロケールがUTF-8に設定されます。

この状態で、日本語コミットメッセージを再度試してください。

```bash
git commit --allow-empty -m "テスト用の日本語メッセージ"
git log
```

これで文字化けが解決されていることを確認しましょう。

### 永久的な設定

Dockerコンテナを再起動しても設定が保存されるようにするため、次の手順で `.bashrc` に追記します。

1. **`.bashrc` に追記**

   ```bash
   echo 'export LANG=C.UTF-8' >> ~/.bashrc
   ```

2. **設定を反映**

   ```bash
   source ~/.bashrc
   ```

これで、次回コンテナを再起動しても文字化けが発生しなくなります。

## Nanoでの文字化け問題の解決

Gitコミット時にNanoが開いた際、日本語が文字化けする場合は、Nano自身でUTF-8を正しく扱えていないことが原因です。下記手順で解決できます。

### Nanoのアップデート

Nanoが古いバージョンの場合、UTF-8のサポートが不完全なため、アップデートが必要です。

```bash
apt update && apt install -y nano
```

### Gitのデフォルトエディタを変更

Nanoでの問題が解決しない場合、Gitのデフォルトエディタを `vim` や `code` に変更することで解決できます。

#### Vimを使う場合

1. **Vimのインストール**

   ```bash
   apt update && apt install -y vim
   ```

2. **GitのエディタをVimに設定**

   ```bash
   git config --global core.editor "vim"
   ```

#### VSCodeを使う場合

```bash
git config --global core.editor "code --wait"
```

## おわりに

Dockerコンテナ内で日本語コミットメッセージが文字化けする問題は、ロケールの設定やエディタの変更で解決できます。同様の問題に相対している方の参考になれば幸いです。
【初心者学習記録】resourcesについての備忘録

## Railsにおけるresourcesとは 　
よく使われる7つの基本的なルーティング（ルート）を自動的に設定するための便利な方法。これにより、手動でルートを定義する手間を省くことができる。

よく使われるアクションは以下の７つ
| No. | アクション         | 説明                                   |
|-----|--------------------|----------------------------------------|
| 1   | `index`            | 一覧表示する                   |
| 2   | `new`              | 投稿フォームを表示する 　|
| 3   | `create`           | 追加する                   |
| 4   | `show`             | 詳細表示する                   |
| 5   | `edit`             | 編集フォームを表示する |
| 6   | `update`           | 更新する                   |
| 7   | `destroy`          | 削除する                   |

## 使い方
 `resources :posts` と書くと、上記の7つのルートが自動的に作成される。
 ７つ全部必要ないときは「only」や「except」で機能を制限できる。

 ```ruby
resources :posts, only: [:index, :show]
resources :posts, except: [:destroy]
AOSのアトリビュートをざっくり調べる

お疲れさまです。みやもとです。

昨年の[技術書典](https://techbookfest.org/market)にて、「ファンサイト作りで学ぶWeb開発の基本～推し活を楽しみながらスキルアップ～」という本を購入しました。

https://techbookfest.org/product/1FQZ7xU7BKXHKgX8QF895X?productVariantID=3iPG5dZTBM9KcbQN6df597

読みながら実際にファンサイトを作ってみるのがめちゃくちゃ楽しかったのでそれはまた別途記事にしたいのですが、残念ながら技術寄りのところとはまた違う話になりそうなので別のところで書く予定です。
ここでは本に出てきたツールとか技術とか、私が本で初めて見たり使ったりしたものについてちょっとだけ調べて書きたいと思います。
ということで、今回はAOSのアトリビュートについて。

## AOSとは
Animate On Scrollという、要素のスクロールをトリガにしてアニメーションを適用するためのJavaScriptライブラリです。

### アトリビュート
ひとまず[公式GitHub](https://github.com/michalsnik/aos)のREADMEに記載されている例について調べてみました。

READMEの「How to use it? 2.Set animation using data-aos attribute:」部分から

```html
  <div
    data-aos="fade-up"
    data-aos-offset="200"
    data-aos-delay="50"
    data-aos-duration="1000"
    data-aos-easing="ease-in-out"
    data-aos-mirror="true"
    data-aos-once="false"
    data-aos-anchor-placement="top-center"
  >
  </div>
```

| Attribute | 内容 |
|:-:|:-:|
| data-aos | アニメーションの種類 |
| data-aos-offset | アニメーションを開始するスクロール量 |
| data-aos-delay | アニメーションを開始するまでの時間 |
| data-aos-duration | アニメーションの再生にかける時間 |
| data-aos-easing | アニメーションの再生速度の変化 |
| data-aos-mirror | 対象がスクロールで画面から<br>外れた後再び表示された時、<br>アニメーションを再生するかどうか |
| data-aos-once | 対象が画面に入った最初の１回だけ<br>アニメーションを表示するかどうか |
| data-aos-anchor-placement | 対象が画面のどの位置に来た時に<br>アニメーションを開始するか |

記事を書くにあたりある程度はテストページを使って確認したのですが、mirrorだけ上手く確認できませんでした。
「対象の要素を一度スクロールで通り過ぎて戻った時にアニメーションを再度再生するかどうか」ということかと思ったのですが、mirrorとonceでどう違うのかと比べてみたところ先述の指定に関連するのはonceの方だけでmirrorは特に影響しませんでした。

### アニメーション種類
| 名前 | 内容 |
|:-:|:-:|
| fade | 表示が薄い→濃いに変化する<br>上下左右斜め方向の指定が可能 |
| flip | 平面から回転動作を経て表示する<br>上下左右方向の指定が必要 |
| slide | 指定の方向にスライドで表示される<br>上下左右の指定が必要 |
| zoom | ズーム動作を経て表示する<br>ズームイン・ズームアウトと<br>上下左右の指定が可能 |

### アンカー指定
指定方法は「top-center」のように縦位置を2つ指定する形で、どちらかに対象が到達した時点でアニメーションが開始します。
「top-top」等、同じ位置を2回指定しているものはその位置以外からアニメーションを開始しないようです。

### イージング制御
基本の指定は以下5種類です。

| 名前 | 内容 |
|:-:|:-:|
| liner | 一定の速度で動作する |
| ease | 開始と終了がゆっくりになる |
| ease-in | 開始がゆっくりになる |
| ease-out | 終了がゆっくりになる |
| ease-in-out | 開始と終了がゆっくりになる |

easeとease-in-outの違いは後者の方がより緩やからしいです。
目視だといまいちわかりませんでしたが言われてみれば気持ち違うかも？ぐらいの感じでした。

上記のうち「ease-in」「ease-out」「ease-in-out」にはさらに種類があります。
以下の指定はいずれかひとつをハイフン付きで末尾につける形で指定可能です。

| 名前 | 内容 |
|:-:|:-:|
| back | 開始時に少し後退する |
| sine | サイン波に基づいて滑らかに加速する |
| quad | 二次関数に基づいて加速を少し強調する |
| cubic | 三次関数に基づいて加速をquadより強調する |
| quart | 四次関数に基づいて加速を最も強調する |

正直なところback以外は目視でさっぱり動きの違いがわかりませんでした。
以前にスライドで使ったイラストをslide-upで表示するように書いたのですが、カスタムでもっと複雑な制御をするとか、別の指定でないと効果の違いを実感しにくいのかもしれません。
Thunderbolt5とローカルLLMについて調べた

# はじめに

この調査の動機の一つとしては、Macの内蔵SSDの価格が非常に高いため、SSD容量が最小のモデルを購入して、外付けSSDでの運用ができるというのです。

Thunderbolt5は4の半分の時間で読み書きできている。
内蔵SSDとも遜色ない模様。
>https://www.youtube.com/watch?v=xDE_WUQTxb4&t=437s
>https://www.youtube.com/watch?v=xDE_WUQTxb4&t=396s
>https://www.youtube.com/watch?v=hUWGwslm9W8

またもう一つの動機としてローカルLLMを試すためには大量のVRAMが必要となるところ、複数のMacをThunderbolt5で接続することで、高速な通信を行い、クラスタ化してLLMを実行する事ができるというのです。
>https://www.youtube.com/watch?v=GBR6pHZ68Ho

macOSにはシステム設定ーネットワークーThundeboltブリッジがあり、イーサネットよりも高速な接続が可能なようです。私のMacBookAirでも設定が表示されました。
（OSはSonomaとSequoiaで確認済み）
![スクリーンショット 2025-01-13 21.12.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1032713/01ee48b7-d86b-320c-b01c-869aef2927ae.png)


# Thunderbolt5の仕様

Thunderbolt3,4の40Gbpsに対し、Thunderbolt5は80Gbpsであり、冒頭に引用したビデオにあるようにSSDの例でも概ね２倍の速度が出ていました。
ネットワークブリッジではそこまでの速度が出ていませんでしたがそれでもThunderbolt4より1.5倍は高速な様子。

https://pc.watch.impress.co.jp/docs/topic/feature/1635514.html

https://pc.watch.impress.co.jp/docs/news/1530628.html


# MacのThunderbolt対応状況（2025/1/13現在）


- CPU別
Thunderbolt3 M1,M2無印,M3無印
Thunderbolt4 M2Pro,Max,Ultra, M3Pro,Max, M4無印
Thunderbolt5 M4Pro、M4Max

- 価格別　いずれもThunderbolt 5ポートx3, SSD512GB, RAM24GB
MacBookPro 328,800円（税込）〜 Thunderbolt 5ポート x 3
Macmini 218,800円（税込）〜　Thunderbolt 5ポート x 3

70BパラメータはRTX5090の32GBをもってしても、VRAM不足で動かす事ができない状況。

https://github.com/XiongjieDai/GPU-Benchmarks-on-LLM-Inference

https://gigazine.net/news/20231227-vram-estimator/

https://zenn.dev/robustonian/articles/selection_of_gpus_for_local_llm


ローカルLLMをやるためには正攻法としてはNvidiaの大容量のVRAMを積んだシステムを使うのが一般的ですが、あくまで業務用で数百万円。

M2Ultra 192GBで動くも150万円！
https://www.apple.com/jp/shop/product/G171PJ/A

Macminiを64GBの14コアCPU、20コアGPU、16コアNeural Engine搭載Apple M4 Proチップとすると、338,800円（税込）。
これを３台購入してThunderbolt5の80Gbps接続すれば70BパラメータのローカルLLMができる可能性が・・。

しかも
![スクリーンショット 2025-01-13 21.41.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1032713/aa3110a9-8583-f633-ed61-48ebde5ed522.png)

会社なら空いてるMacを借りて試せるかも？

新しいAMDのRyzenAI搭載のPC（VRAM96GBまで割当可能）の発売にも期待したいが、こちらはUSB4っぽいのでクラスターすると帯域が問題となるか？。

https://pc.watch.impress.co.jp/docs/news/1651986.html

最後までご覧いただきましてありがとうございました。
AWS IoTルールを使ってUnix時刻タイムスタンプをISO 8601形式（JST）に変換してDynamoDB に保存する方法

# はじめに
　AWS IoTルールを使って、Unix時刻のタイムスタンプがついているMQTTトピックを、ISO 8601形式（JST）のタイムスタンプに変換して、DynamoDBのソートキーに保存する方法を紹介する。基本的な方法は、[公式チュートリアル](https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/iot-ddb-rule.html)を参照。ここでは、Unix時刻のタイムスタンプをISO形式に変換する方法を中心に説明する。

# 動作確認環境
* AWS
  * IoT Core
  * IoT Rules
  * DynamoDB

# 前提
 
　JSONオブジェクトに以下のようにUNIX時刻のタイムスタンプが含まれているMQTTトピックがデバイスから、AWS IoT CoreのBrokerに送られているとする。

```json:JSONオブジェクト例
{
   "device_id": "000001"
   "timestamp": "1736413662"
   "temperature": "25"
}
```

# 方法

## DynamoDBの設定
　事前にデータを保存するためのDynamoDBテーブルを作成する。時刻でソートしたいので、DynamoDBのソートキーに、```timestamp```を設定しておく。キー名は、MQTTトピックのタイムスタンプ(```timestamp```)と同じにする。パーティションキーは、別途デバイスIDなど指定しておく。

## IoTルールの設定

　ルールアクションのソートキー、レンジキーのタイプ、レンジキーの値を以下のように設定する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638977/a70d68f3-fe69-20b0-14b1-d64177d8d19d.png)

:::note
ポイント

レンジキーの値に、```parse_time```関数を使って、MQTTトピックのUNIX時間の```timestamp```を、ISO 8601形式（JST）に変換する。変換式は以下のようになる。

```sql
${parse_time("yyyy-MM-dd'T'HH:mm:ssZZ", timestamp, 'Asia/Tokyo')}
```
:::

DynamoDBに以下のように、```timestamp```が保存されていれば成功。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638977/10d9cf95-6125-1c6d-f6cd-adbd94babe62.png)

# まとめ

　AWS IoTルールを使って、Unix時刻のタイムスタンプがついているMQTTトピックを、ISO 8601形式（JST）のタイムスタンプに変換して、DynamoDBのソートキーに保存する方法を紹介した。デバイスで良く利用されるUNIX時間は、直感的にわかりにくいので、DynamoDBへ保存する際に変換しておくと視認性が上がるので本方法が役立つ。

# 参考

https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/iot-ddb-rule.html

https://docs.aws.amazon.com/iot/latest/developerguide/iot-sql-functions.html#iot-sql-function-parse-time

https://repost.aws/questions/QUllBKJfxgSO-o8CjHasWygg/aws-iot-core-parser-time-with-time-zone