OmniAICreator/Qiita-1.07M huggingface dataset:
Rustのvalidatorとthiserrorを使ってみる

## validatorとは
validatorは構造体にValidationのルールを記載することで簡単にバリデーションを実装できるクレートです。

## 簡単な使い方
validatorの簡単な使い方です
deriveにValidateを追加して、あとは各プロパティにバリデーションの条件を色々と追加していくだけです。
カスタムバリデーションを追加したい場合は、custom(function = "バリデーション名"で作ることができます。
また、必要な時は構造体のインスタンスに対して.validate()を読んであげるだけで実装が完了します。messageを指定することで、バリデーションが起きた時の文言を変更することもできます。

```
#[derive(Deserialize, Validate, Debug)]
struct AddParams {
    #[validate(
        length(min = 1, max = 5, message = "一文字以上五文字以内にしてください"),
        custom(function = "validate_unique_username")
    )]
    text: String,
}

fn validate_unique_username(username: &str) -> Result<(), ValidationError> {
    if username == "xXxShad0wxXx" {
        // the value of the username will automatically be added later
        return Err(ValidationError::new("terrible_username"));
    }

    Ok(())
}
```

## thiserrorへの登録
前回記事に書いたthiserrorへの登録も簡単です。
と書けば、OKです。
```
#[error("Validation!!")]
Validation(#[from] validator::ValidationErrors)
```

また、バリデーションメッセージをそのままエラーとして返したい場合は下記のように書き換えると、プロパティ名: メッセージが表示されます。

```
#[derive(Deserialize, Validate, Debug)]
struct AddParams {
    #[validate(
        length(min = 1, max = 5, message = "一文字以上五文字以内にしてください")
    )]
    text: String,
}

#[derive(Error, Debug)]
enum MyError {
    #[error(transparent)]
    Validation(#[from] validator::ValidationErrors),
}
// text: 一文字以上五文字以内にしてください
```
ターミナルでかっこいいコマンド!!

## ターミナルでかっこいいのを出したい
ターミナルでかっこいい描画をしましょう!!

今回は
- cmatrix
- [TTE](https://github.com/ChrisBuilds/terminaltexteffects) + screenfetch
を紹介します。

環境は
- OS: KDE neon (Linux/Debian/Ubuntu ベース)
です。

## cmatrix
マトリックスが表示できます。(実際は動きます!)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2769460/685515ff-78b6-b600-0c58-a623404582da.png)


#### インストール
```shell
$ sudo apt install cmatrix
```

#### 作動
```shell
$ cmatrix
```

:::note
色を変えることもできます。
```shell
# 赤
$ cmatrix -C red
# シアン
$ cmatrix -C cyan
```

対応している色:
- `green` (デフォルト)
- `red`
- `blue`
- `white`
- `yellow`
- `cyan`
- `magenta`
- `black`
:::

#### 終了
<kbd>Ctrl</kbd> + <kbd>C</kbd>

## TEE + screenfetch
ビームのあとに、パソコンの詳細情報が表示されます。かっこいい…

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2769460/a23ab037-de6f-0670-7d05-cd7823c7122f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2769460/eb9152c2-9220-a480-c0de-d5bb1e4c1df1.png)

#### インストール
```shell
# screenfetch のインストール
$ sudo apt install screenfetch

# tte のインストール
# pip (python) が必要です。
$ pip install terminaltexteffects
```

#### 動作
```shell
$ scrennfetch -N | tte beams
```

:::note
screenfetch 以外でも利用できます。

```shell
$ ls | tte beams
```
:::

:::note
ビーム以外の効果も利用できます。

```shell
$ scrennfetch -N | tte slice
```

詳細はこちら: https://chrisbuilds.github.io/terminaltexteffects/showroom/
:::

### 最後に
ターミナルかっこいいね
python: requirements.txt に platform や python 条件書きたいなら、requirements.in に Environment Markers を書こう

# 背景

local windows で開発時は特に問題なかったが、
Azure に deploy したら何故か動かない。

で、調べたら、pywin32 がねーよって怒られていた。
そりゃそうだよね、**win32** ですから！ :sweat: 

で、その対策の備忘録

# 環境

local Windows11 powershell
az/azd cli
Azure App Service Linux
Python 3.11

# 対応策

windows でのみ動くように requirements.in を定義する

以下のように定義してやることで、platform 条件で install させることが可能

```text: requirements.in の例
pywin32; sys.platform == 'win32'
```

依存関係処理した上で、条件追記してくれるので、非常に助かる

```text: requirements.txt 出力例
pywin32==306 ; sys.platform == 'win32'
    # via
    #   -r requirements.in
```

他にも　Python version なんかも指定できる。
詳細は以下で

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/81223328-0208-3ef7-086c-a5b6866c5e3c.png)


https://peps.python.org/pep-0345/#environment-markers

:::note warn
ネット記事だと、古い書き方？が記載されてたりするので、公式を確認しましょう

ex.) sys_platform == "win32"
これで、動かねーって少し悩みました :sweat_smile: 
:::

# あとがき

当初、これしたと気、requirements.txt にしか書けないと思って、
自動生成されると上書きで困るーとか思ったけど、in に書いても上手くいってめっちゃ助かった :laughing:
Makefile素人がtwmd(Twitter-media-downloader)のmake install失敗を解消したたった一つの方法

# 結論
簡潔に言うと、Makefileファイルの`install`と`clean`のパスを書き換えるだけ。

## 大袈裟な記事タイトル恥ずかしいね
応援していたVtuberが引退するとのことで、Twitter(新X)の画像を一括保存できるソフトを探していたら、こういうものを見つけた。

https://github.com/mmpx12/twitter-media-downloader

最近話題になりがちなAPIを使っていないらしく、2024年6月現在問題なく使えるとのことで試してみようと思ったが、インストール段階で躓いた。
以下素人による手探り解決。

:::note
なお、そもそもの前提としてgoのインストールが必要。
:::

## macOSの仕様が原因

最近のmacOSではSIPというものがあり、システムの根幹に関わるディレクトリは触れなくなっているようだ。
環境設定から『ターミナル』にフルディスクアクセスを許可するも変わらず、
リカバリーモードで再起動してSIPをオフにするのを恐る恐る試してみたが、
```
/usr/bin/twmd: Operation not permitted
```
だったのが
```
/usr/bin/twmd: Read-only file system
```
になるくらいで結局うまくいかなかった。

## そもそも`/usr/bin`でいいの？
メッセージをよく見ると`make`したtwmdファイルを`/usr/bin`に移動しようとしてエラーが出ているようだ。
強行突破しようとしてFinderから手動でファイルを移動を試みたが、カーソルが🚫になって受け付けなかった。
そもそもbinの使い分けってどないなんじゃいと思って調べてみると

https://linuc.org/study/knowledge/544/

どうやらこの類のソフトは`/usr/local/bin`に入れた方が良いらしい。
こちらにはFinderからでもファイルの移動ができるので、こちらにインストールしてみることに。

## make経験値

なんとなく敬遠していたが、意を決してMakefileを覗いてみたところ、中には`make`に続く『ターゲット』に対応したターミナルコマンドが書いてあるだけだった。なーんだ。
```makefile
#前略
install:
	mv twmd /usr/bin/twmd
#中略
clean:
	rm -f twmd /usr/bin/twmd
#後略
```
インストール時に使う`make install`と削除用の`make clean`だけ抜粋。ここのディレクトリを変更する。

```makefile
#前略
install:
	mv twmd /usr/local/bin/twmd
#中略
clean:
	rm -f twmd /usr/local/bin/twmd
#後略
```

## これだけかよー、びびって損した。
その後はgithubのドキュメント通りに問題なく動作した。
これまで自分でビルドするのは避けてきたけど、そんなに難しくないのかもしれないと思えた。これからはバイナリで配布されてないソフトにも手を出してみよう。

# 参考
https://qiita.com/kasei-san/items/ad25df63260e86c5cc71

https://qiita.com/valzer0/items/67a4c8bf2b1be0fc825a

https://qiita.com/KEINOS/items/0366f1c281b574a79cfb

https://qiita.com/whitefox_105/items/0b70f7a504dcb72788e6
【超小ネタ】EC2を再起動するとSystems Managerに少し早く認識されると公式ハンズオンで書かれていた

プライベートな環境のEC2に、セッションマネージャやフリートマネージャを用いて接続した経験がある方は多いでしょう。その中で、設定に漏れがあり修正したものの、マネージドノードに表示されるまで時間を要した、という方もいらっしゃるかもしれません。

このとき設定を正しく直した状態でEC2を再起動すると、「お、少し早いタイミングでマネージドノードになった！」ということが多々あります。これについてAWSから公式に出されているハンズオンで言及されている箇所を見つけたので共有です。対象ハンズオンはこちらです↓

https://catalog.us-east-1.prod.workshops.aws/workshops/d071f444-e854-4f3f-98c8-025fa0d1de2f/en-US/lab-one/step-three

この中のLab One、Create route tablesセッションで以下のように言及されています。

> It might take up to 15 minutes for the Systems Mananager Agent to register with AWS Systems Manager to allow for remote administration of the server. You can reboot the EC2 instance to speed up the process if needed.

日本語訳すると以下の通りです。

> Systems Mananager Agent が AWS Systems Manager に登録され、サーバーのリモート管理が可能になるまでに、最大 15 分かかる場合があります。必要に応じて、EC2 インスタンスを再起動してプロセスを高速化できます。

経験として、再起動したら早くマネージドノードに登録されるのは認識していました。これについてAWS公式ドキュメントで明記されているは初めて見かけたので、本記事で共有させていただきました。短いですが本記事は以上です。
ニューラルネットワークで生成される埋め込みベクトルのイメージ（初心者向け）

# 1. はじめに
ニューラルネットワークモデル構築に不可欠な"埋め込みベクトル"という概念。
何を埋めてんねん、と思っている私含めた初心者向けの記事となっています。
# 2. 本題
### 1. 埋め込みベクトルとは？
特徴量行列の各要素の関係をより詳細に表すために次元数を増やした行列です。

### 2. 具体例
ある物質1の特徴を下記のベクトルで表す時のことを考えます。
```
物質1の特徴量ベクトル = (原子番号1, 結合方式1, 電荷1)
```
今は次元数が3ですが、これを引き延ばして5にした時の埋め込みベクトルを考えます。
例えば下記のベクトルのようになります。
```
埋め込みベクトル = (e1, e2, e3, e4, e5)
e1: 原子の種類に強く関連
e2: 結合方式に強く関連
e3: 電荷に強く関連
e4: 原子の種類と結合方式の相互関係
e5: 結合方式と電荷の相互関係
```
このように、元のベクトルの次元を増やし、要素間の相互作用・非線形的な関係をきめ細やかに表すことができます。

ニューラルネットーワークにおける学習では、この埋め込み行列の生成時の設定値＝重みを学習しています。

# 3. おわりに
なるべく簡潔に書かせていただきましたが、分かりにくいところ、間違っているところ等あればご意見待ってます！
PowerBI：日付テーブルの重要性について

## はじめに
PowerBIでデータの可視化を行うにあたり、月ごとや年度ごとの集計、前年前月比などを正確に可視化するためには、「**日付テーブル**」が非常に重要になってきます。

今回はPower BIにおける日付テーブルの重要性について述べています。

## 目次
[日付テーブルとは](#日付テーブルとは)
[暗黙的な日付テーブルについて](#暗黙的な日付テーブルについて)
[日付テーブル作成することで得られるメリット](#日付テーブル作成することで得られるメリット)
[日付テーブルの作り方](#日付テーブルの作り方)
[まとめ](#まとめ)

## 日付テーブルとは
まず日付テーブルは、以下のような特徴を持っています。
- 集計対象となる期間の日付を全て含み、連続した日付の列を持つテーブル
- 「年」「四半期」「月」などの時系列の階層を持つ
- 年・月・日などの単位は日付に関連するようにそれぞれの列を持つ（年、月、日、曜日などの値が入った列）
- 日付をキーに他データと紐づけることで、時系列の様々な集計やレポート表現を実現することができる

## 暗黙的な日付テーブルについて
暗黙的な日付テーブルとは何かというと、PowerBIには、自分で日付テーブルを作成しなくとも、日付列のあるデータを用いてグラフを作成すると、PowerBI側で自動的に日付テーブルを作成する機能がある。PowerBIが裏側で作成している日付テーブルのことを暗黙的な日付テーブルと呼ぶ。

しかし、暗黙的な日付テーブルには以下のようなデメリットがある。

暗黙的に作成された日付テーブルを日付階層やクイックメジャーなどで使用した場合、自分が意図した結果を得られない可能性がある。

例えば、週の曜日の始まりを月曜単位で集計したいのに日曜始まりになってしまっていたり、曜日や月の表記を英語ではなく日本語で表示したい場合など。

そのため、明示的に日付テーブルを作成することで、自分の意図した結果をえられるようにする。


## 日付テーブル作成することで得られるメリット
例えば、ECサイトなどの購入履歴データ（購入日が1月1日から1月31日）を可視化する際に、購入履歴の無い日付がある場合、明示的な日付テーブルを作成していないと、その日付がグラフに反映されないことがある。折れ線グラフなどで履歴の無い日付の箇所で線が途切れてしまうイメージだ。
そのため、1月1日～31日までの連続した日付データを持つ日付テーブルを作成し、購入履歴データと繋げることで購入履歴の無い日付は0としてグラフに反映させることができるようになる。

日付テーブルは日付列の他に年や月、四半期などの列も追加して作成すると時系列操作に以下のような柔軟性を持たせることができる。

- 四半期＞月＞週など任意の階層で表示する
- 相対的に直近期間を常に表示する
- スライダー機能で表示期間を可変にする（○月～○月までなど期間で絞り込みできる）
- 「2024年6月26日（水）」など任意の形式で表示する

また、タイムインテリジェンス関数使い、以下の集計が可能となる。

- 相対的にずらした期間の値（昨年値・昨月値など）を出す
- 期間ごとの差分や比率（昨年対比・昨月比など）を出す
- 期間ごとの累計値（月別累計、日別累計など）を出す
- 移動平均を出す

## 日付テーブルの作り方
日付テーブルの作り方については下記の記事が非常にわかりやすいので参考にしてみてください。

https://qiita.com/y-komuro/items/de3e2cb3dea129260079


## まとめ
今回はPowerBIにおける日付テーブルの重要性についての記事でした。
日付テーブルを作成することで、集計や可視化が容易になり、効率的にダッシュボードを構築することができるようになります。
また、複数のテーブルを使用したダッシュボードにおいて、正確性を担保することもできます。

最後まで読んでいただきありがとうございました。
商品はどこに陳列されているのか(仮)

# 店員さんに商品の場所を紹介してもらう時間を削減したい
私のお店ではこんな悩みがあります。

- お客さまに商品がどこにあるか聞かれてもまったくわからない(教えるのに時間がかかる)

これを解決するために構想を練っておりました。
今回、teachablemachineを使用して解決に挑みます。

# 最終的に作りたいもの

画像を読み込む→商品が判別され店内のどこで販売されているかマップを表示
このスタンスで制作に励みます。
すべての商品の売り場を丁寧に提示するのは労力の面でも時間がかかるため、大まかな売り場の特定に絞ろうと思います。
また、在庫が確認できる機能が付けられれば良いかなと思っています。(おまけようそ)


# モデルづくり

teachablemachineを使用しモデルを作成
![Image Model - Teachable Machines - Google Chrome 2024_06_27 21_33_43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3773807/84859515-d06c-04ba-287d-8c119aadb2a5.png)

トップバリュが好きなのでこのようなものを作成

精度は上々です。

次の記事ではcodepenを利用しweb上で作動するアプリを作成しようかと考えています。
具体的にはカメラで読み取ってもらった内容に沿って店内のどこに販売されているかのマップを出力するモデルを作成したいと思っています。

ありがとうございました。
VBAで一覧追加マクロを作成する


## 完成画像

### 登録シート

![登録シート](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166924/711de82f-d805-d332-ea7a-ef4fd8fc844a.png)

### 一覧

![一覧](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/166924/f2046471-9128-609b-8248-f9503547618e.png)



## VBA

```
Sub 一覧登録()
     Dim name  As String
     Dim content As String
     Dim no
     
     name = Worksheets("登録シート").Range("C2").Text
     content = Worksheets("登録シート").Range("C4").Text
     
     If name = "" Then
        MsgBox ("項目名が入力されていません ")
     ElseIf content = "" Then
        MsgBox ("内容が入力されていません ")
     Else
        no = Worksheets("一覧").Range("B2").End(xlDown).Value
        
        If no = "No." Then
            no = 1
        Else
            no = no + 1
            
            Worksheets("一覧").Range("B2").End(xlDown).Offset(1, 0).Value = no
            Worksheets("一覧").Range("B2").End(xlDown).Offset(0, 1).Value = name
            Worksheets("一覧").Range("B2").End(xlDown).Offset(0, 2).Value = content
            Worksheets("一覧").Range("B2").End(xlDown).Offset(0, 3).Value = Now
        
            Worksheets("登録シート").Range("C2").ClearContents
            Worksheets("登録シート").Range("C4").ClearContents
        End If
    End If
End Sub
```
WindowsでのReact開発環境の構築手順について

Windows環境でReact開発環境を構築した時の手順についてまとめる。

# 手順

## nvmのインストール

以下のサイトからnvm-setup.exeをダウンロードする。

https://github.com/coreybutler/nvm-windows/releases/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152706/bd851331-96d6-ff7c-c213-caa4d7f2ca58.png)
"I accept the agreement"を選択して、以降は"Next"を選択し続ければよい。

## Node.jsのインストール

先ほどインストールしたnvmを使用してNode.jsをインストールする。
バージョンは以下サイトでLTSのものを選択する。

https://nodejs.org/en

```
nvm install v20.15.0
```

続いて使用するバージョンを指定する。

```
nvm use 20.15.0
```

インストールがされていることを確認する。併せてnpmについても-vオプションでインストールされていることを確認する。

```
node -v
npm -v
```

## プロジェクト作成

ここではviteを使用して環境を構築する。
以下コマンドでアプリケーションの作成を行う。

```
npm create vite@latest
```

対話型でプロジェクトの作成を行うことができる。
プロジェクト名を入力し、使用するフレームワークと言語を選択する。

```
> npx
> create-vite

√ Project name: ... first-react-app
√ Select a framework: » React
√ Select a variant: » TypeScript

Scaffolding project in D:\hoge\first-react-app...

Done. Now run:

  cd first-react-app
  npm install
  npm run dev
```

この時点でカレントディレクトリの直下に入力したプロジェクト名のフォルダが作成されている。
cdコマンドでディレクトリを移動し、以下のコマンドを実行する。
installコマンドを実行することで、依存関係にあるパッケージを取得することができる。
パッケージの取得が完了したら、npm run devコマンドを実行してローカル環境を立ち上げる。

```
npm install
npm run dev
```

以下の通り表示されればOK。
```
  VITE v5.3.1  ready in 471 ms

  ➜  Local:   http://localhost:5173/
  ➜  Network: use --host to expose
  ➜  press h + enter to show help
```

localhost:5173をブラウザで開くと、それっぽい画面が表示され動作していることが確認できる。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152706/3bd310dd-593d-ebd1-fea3-129d2c9d7ebc.png)


# まとめ
nvmとviteを用いたReact開発環境の構築手順についてまとめた。
想像していたよりもはるかに手軽で素早く環境構築することができた。
【Progate】HTML&CSSコース 学習内容(レスポンシブ)まとめ

## 自己紹介
29歳。文系卒。新卒入社でWebディレクターを２年半経験。
その後は番組の字幕制作の仕事に従事。
現在はエンジニア転職を目指して勉強中。

## HTML/CSSの印象
おそらく最も親しみのある言語。学習していて発見という発見はなかったが、marginやpaddingなどふわっとしていた概念が少しずつ身についてきている気がする。

## レスポンシブデザイン
基本的なことは問題ないので、レスポンシブに関する基本～Flexboxの順でまとめる。

### viewport
レスポンシブはこれをしないと始まらない。headタグ内に設定しよう。これがないと後述のmediaクエリがうまく機能しない。
~~~html:html
<!-- headerタグ内に設定 -->
<meta name=”viewport” content=”width=device-width,initial-scale=1″>
~~~

### box-sizing
これも準備のうち。paddingとborderがwidthに収まる。レイアウト崩れ防止に使用。
~~~css:css
/* 全体に適用するとレイアウトを管理しやすいらしい */
*{
    box-sizing:border-box;
}
~~~

### max-width
これも準備。全体の画面幅の上限を指定しよう。もし2000pxとかになったら、要素も広がって見づらくなるので。

ついでに全体のwidthは100%にするといい。pxで固定するとスマホで見づらくなっちまうからね。
~~~css:css：例
.container{
    max-width:1170px;
    width:100%;
}
~~~

### mediaクエリ
こいつでブレイクポイント(タブレットやスマホの幅に合わせてCSSを切り替えるポイント)を指定する。
~~~css:css
/* 〇〇px以下の場合～という意味 */
@media(max-width:1000px){...}
~~~

### テクニックやお作法

* レスポンシブ用にcssファイルを分けるといい。読み込みタグはviewportよりも下に記述しな
* コンテンツが並ぶ場合、widthを%で記述すると段組み表示されるよ。100%で１段、50%で２段って具合さ
* heightが固定されてるせいで段組み時にコンテンツがはみ出す場合。それはコンテンツがfloatで浮いちまってるからさ。コンテンツ終わり直後に空タグを作って、clear:left;でfloatを消してやれば解決だよ
~~~css:css
.clear{clear:left;}
~~~

### 要素の表示/非表示
画面幅によって要素を表示したり消したりするよ。
~~~css:css
display:none;
display:block;
~~~

## Flexbox
コンテンツの並び向きや、折り返しの有無を指定できる。mediaクエリを併せて使えば、もう立派なレスポンシブデザイン。
~~~css:css
/* 子要素を横並びにする(親要素で指定) */
display:flex;

/* 幅を親要素に合わせて伸縮させる(子要素で指定) */
flex:auto;

/* 子要素のサイズに応じて折り返す(親要素で指定) */
flex-wrap:wrap;
/* 列数に応じたwidthを指定 */

/* 子要素を上から下に並べる(親要素で指定) */
flex-direction:column;
/* 併せて、ブロック要素を中央合わせに */
margin:0 auto;
/* 必要であればwidthで%指定 */
~~~

## まとめ
個人開発の際、ここに記したことがきっと役に立つことでしょう。

今後も継続して学習を続けていきたいと思います。

[Progate](https://prog-8.com/)
TypeScriptでChatGPT(OpenAI API)

# 導入

OpenAIのChatGPT APIを使うと、さまざまなアプリケーションに自然言語処理の能力を簡単に追加できます。TypeScriptでOpenAI APIを利用してみたので、その内容を記事にしました。

# 手順
## 前提

1. **Node.jsとnpmのインストール**: Node.jsとnpmがインストールされている必要があります。
2. **プロジェクトのセットアップ**: 既にNext.jsやNuxt.jsなどのTypeScriptを利用するプロジェクトがセットアップ済みとします。
3. **OpenAI APIキー**: OpenAIのAPIキーが必要です。OpenAIのウェブサイトでログインして取得できます。

## 1. OpenAI APIのインストール

`openai`というライブラリを使用して、OpenAIのAPIにアクセスします。
以下のコマンドでこれをインストールします。

```bash
npm install openai
```

## 2. APIキーの取得

前提にも記載しましたが、APIキーを取得します。OpenAIの[APIキー](https://platform.openai.com/account/api-keys)から取得可能です。
このキーを使ってAPIにアクセスします。

## 3. 環境変数の設定

ルートディレクトリに`.env`ファイルを作成し、APIキーを設定します。

```env:.env
OPENAI_API_KEY=openai-api-key
```

`openai-api-key`は、取得したAPIキーに置き換えてください。

## 4. TypeScriptでの実装

```typescript
import { Configuration, OpenAIApi } from "openai";
import * as dotenv from "dotenv";
dotenv.config();

// 環境変数からAPIキーを取得します
const configuration = new Configuration({
  apiKey: process.env.OPENAI_API_KEY,
});
const openai = new OpenAIApi(configuration);

/** 
 * GPT-4とチャットをするための関数
 * prompt: GPTに送信するメッセージ(プロンプト)
 */
async function getChatGPTResponse(prompt: string) {
  try {
    const response = await openai.createChatCompletion({
      model: "gpt-4",
      messages: [{ role: "user", content: prompt }],
    });
    return response.data.choices[0].message?.content;
  } catch (error) {
    console.error("Error response from OpenAI: ", error);
  }
}

// 使用例
(async () => {
  const response = await getChatGPTResponse("こんにちは");
  console.log(response);
})();
```

# 終わりに

この記事では、TypeScriptでOpenAIのChatGPT APIを利用するための基本的な手順を解説しました。
これを基に、是非AIを様々なことに活用してみてください。
Git チートシート


# Overview

Gitのコマンドについて記載する。

# git

```shell
# Print logs stdout
git log

# Print logs stdout (oneline)
git log --oneline

# Print logs stdout (graph / oneline)
git log --all --graph --oneline

# initializing the repository
git init

# Print status stdout
git status

# Clone the remote repository to local repository
git clone <repository URL>

# Create new branch
git branch <branchname>

# Change to new branch
git switch <branchname>

# Create & change to new brance
git checkout -b <branchname>

# Add changed file
git add <file>

# Add all changed files
git add .

# ステージングしたファイルを削除する
git rm --cached <file>

# Commit & write message of added files
git commit -m <messages>

# Move specific commit
git checkout <numbers>
```
flet ページ切り替え (decorator)

最初は [flet-easy](https://github.com/Daxexs/flet-easy)を使おうとしたけど
`page.theme_mode` がページ上で変更できなかったり (見つけてないだけかも)
`fs.Datasy` が使いにくかったので、fletだけで作ろうと思い
flet-easyの構文が好きだったので作りました


```py: easy_app.py
import flet as ft

class EasyApp():
  def __init__(self, route_init="/"):
    self.route_init = route_init
    self.route_list = []
    self.ft_page = None
    self._custom_wrapper_befor = None
    self._custom_wrapper_after = None
  
  def custom_wrapper_befor(self, func):
    self._custom_wrapper_befor = func
  def custom_wrapper_after(self, func):
    self._custom_wrapper_after = func
  
  def route_change(self, e):
    for func, route, title in self.route_list:
      if e.route == route:
        if self.ft_page.controls: self.ft_page.controls.pop()
        self.ft_page.title = title
        if self._custom_wrapper_befor: self._custom_wrapper_befor(self.ft_page)
        func(self.ft_page)
        if self._custom_wrapper_after: self._custom_wrapper_after(self.ft_page)
        self.ft_page.update()
  
  def page(self, route="/", title=""):
    def decorator(func):
      self.route_list.append((func, route, title))
    return decorator
  
  def use(self, func=None, route="/", title=""):
    self.route_list.append((func, route, title))
  
  def main(self, page: ft.Page):
    self.ft_page = page
    page.on_route_change = self.route_change
    page.go(self.route_init)

  def run(self, *args):
    ft.app(target=self.main, *args)
```
### 使い方
```page/Test.py
def Test(page: ft.page):
  pass
```
```py: app.py
import flet as ft
from lib.easy_app import EasyApp #ここは変えてね

app = EasyApp(route_init="/home")

@app.page(route="/home", title="home")
def home_page(page: ft.page):
  page.add(ft.FilledButton("これはホームページです。", on_click=lambda e: page.go("/next")))

@app.page(route="/next", title="next")
def next_page(page: ft.page):
  page.add(ft.FilledButton("これは次のページです。", on_click=lambda e: page.go("/home")))

from pages import Test
app.use(Test, route="/test", title="test")

app.run()
```


余談
```py
def befor_anim(page: ft.page):
  # fade outアニメーション
custom_wrapper_befor(befor_anim)
```
みたいにアニメーションつけてもいいかも
Fluent-BitのINPUTセクションにおけるストレージ指定

# この記事では

前回の記事、[Fluent-Bitのストレージ設定と挙動(SERVICEセクション)](https://qiita.com/Takagi_/items/cd28dfb3a6be1556c804)に引き続き、INPUTセクション内でメモリリソース使用量を制限するための方法について記します。

ここでのINPUTはtailプラグインによるログファイルの読み取りを前提とします。

# INPUTセクションのstorage.type

例えばアプリケーションログをワイルドカード指定し、複数ファイルを読み取る設定を行います。
```
[INPUT]
    Name          tail
    Path          /application/log/*.log
    storage.type  filesystem
```
**storage.type**にfilesystemを指定してますが、何も指定をしないデフォルトだとメモリ上にバッファ領域を作成する**memory**となります。

storage.typeをfilesystemにすることで、メモリ上ではなくファイルシステム上にバッファ領域を作成して複数のログファイルを読み込んでもメモリリソースの消費を抑えることに繋がります。
メモリ使用量に厳しい制限があるコンテナ環境で動作させる場合に、ディスクI/Oが多少増えてもメモリ使用量を抑えたいといったケースに向いていると思います。

# おわりに

特にスタックトレースのように何十行も出力されたものを一つのログとしてまとめるマルチライン処理をINPUTセクションで行う場合にはリソース消費量の急騰が予想されますので特に気を付けておきたいポイントです。

以上です。
LT初登壇してみた

# はじめに

本日(2024年6月27日)に行われた、Qiita主催のLT会において初登壇してきました！😄

https://increments.connpass.com/event/317283/

テーマは「TypeScript(Next.js)でCIを構築してみる！」です。
初めてのLTという事で、色々思う事があったのでつらつらと書いていきます。

# LT初登壇の感想
率直な感想としては、オンラインでも皆さん温かかったため、**すごく楽しかったです**!😉

発表中にコメントを頂いたり、発表後に沢山の方から拍手を頂けたので頑張った甲斐がありました。
(自分の発表に対してコメント頂けるのってこんなにも嬉しいんだと思いました)

また、発表順序が最後でしたが、それまでの方々が発表してくださった内容も面白くて、意外と緊張せず楽しく聞けてました！🥹

特に、TypeScriptでのアプリ開発談が、自分の発表と似ていた部分もあり面白かったです！
TypeScriptでもWebviewを用いてアプリ開発が行えると言った内容で、個人的にも興味が湧きました😍

# 今回の反省点
今回のLTでは、以下の2つが反省だったと感じました。

1. 時間の使い方を工夫できなかった
1. 内容が細かすぎて伝わり辛くなってしまった

### 1. 時間の使い方を工夫できなかった
与えられた時間が10分だったのですが、**発表全てに10分使い切るのではなく質疑応答タイムも作った方が盛り上がったなあ**。。。と感じました。

実は、リハーサルを行うまで発表時間10分だと勘違いしてしまっていました。🫣
そのため、色々詰め込んでから、少しづつ削っていったという事が背景としてありました。

「分かりやすい」というありがたい反応も頂けましたが、発表の中で疑問点もあったとは思うので、その疑問を払拭してもらう方が実りがあったのかなという反省です。

また、LTで実際に意見を頂けた方が次に繋げやすいかもと思いましたので、そういうフリートーク時間は確保しておいた方が良かったかなあ。。。

### 2. 内容が細かすぎて伝わり辛くなってしまった
頂いたコメントの中に「申し訳ないが細すぎて分かりにくい」という感想もありました。
こちらは、**発表内容を理解してもらうための配慮が足りてなかった**のかなと思いました。

今回は実装内容をできる限り詳細に伝えてみたのですが、細かい中身は実際に調べてもらう形にし、概要として大まかな処理の流れを発表する方が良かったかも知れません。

思い返してみると、参加したLTで具体的な実装内容にまで言及しているLTがありましたが、自分の理解では難しかったので「ほえ〜😮」と言った感想しか出てきていませんでした。

また、**LTで具体的な実装まで聞きたい方は果たしてどのくらいいるのだろう**？と考えていませんでした。

今思うと、

::: note info
内容の雰囲気を感じてもらい、とりあえず概要だけ知ってもらう。
気になった方がいれば自分で調べてもらう
:::

と言った形の方が自然そうですね。。。

また、内容を簡略化することで発表時間にも余裕ができるため、その時間を質疑応答として活用出来たんじゃないかなということが反省です。

# おわりに
色々と書きましたが、やっぱり参加して良かったなと思います！(登壇申し込みをした自分を褒めてあげたい😎)

自分だけで考えることには限界があるので、LTなどで外部の方と関わりを持って自分の視野を広げたいと感じました。

後はアウトプットすることでセルフブランディングも行えるので一石二鳥だなと感じました🥳

最後までご覧いただきありがとうございました！
以上、センリツでした。🤓
ChatGPT-3.5先生へ「3次関数のグラフでは接点が異なれば接線も異なるとは 」

# ChatGPT-3.5先生へ
User
```
3次関数のグラフでは接点が異なれば接線も異なるとは
```
```
証明をお願いします。
```
```
sympyで
```
```python
from sympy import symbols, diff, Eq, solve

# x を変数として定義
x = symbols('x')

# 3次関数 f(x) = x**3 を定義
f_x = x**3

# f(x) の導関数 f'(x) を計算
f_prime_x = diff(f_x, x)

# 異なる接点 a, b を定義
a = 1
b = 2

# a での接線の傾き f'(a) を求める
slope_at_a = f_prime_x.subs(x, a)

# b での接線の傾き f'(b) を求める
slope_at_b = f_prime_x.subs(x, b)

# 傾きが異なることを確認する
assert slope_at_a != slope_at_b, "The slopes at different points are equal, which contradicts the theorem."

# 結果を出力
slope_at_a, slope_at_b
```

# いつもの? sympyの実行環境と 参考のおすすめです。
[(テンプレート)](https://qiita.com/mrrclb48z/items/00dd08b0317069be9342)

・以下ができたら、助かります。指定と全部です

https://qiita.com/mrrclb48z/items/555d85face87552c34fb

https://qiita.com/mrrclb48z/items/5f57eac92aaca30e85c0

# いつもと違うおすすめです。


https://www.google.com/search?q=3%E6%AC%A1%E9%96%A2%E6%95%B0%E3%81%AE%E3%82%B0%E3%83%A9%E3%83%95%E3%81%A7%E3%81%AF%E6%8E%A5%E7%82%B9%E3%81%8C%E7%95%B0%E3%81%AA%E3%82%8C%E3%81%B0%E6%8E%A5%E7%B7%9A%E3%82%82%E7%95%B0%E3%81%AA%E3%82%8B%E3%81%A8%E3%81%AF+...%0D%0A&sca_esv=b492b5af9f856ada&rlz=1CAUHAM_enJP1105&sxsrf=ADLYWIL-WXlwlWI6tPIaSqpV-kedIu2AxQ%3A1719489273272&ei=-VJ9ZteaENWOvr0PwJ-BgAY&ved=0ahUKEwiX-8_a3PuGAxVVh68BHcBPAGAQ4dUDCBA&uact=5&oq=3%E6%AC%A1%E9%96%A2%E6%95%B0%E3%81%AE%E3%82%B0%E3%83%A9%E3%83%95%E3%81%A7%E3%81%AF%E6%8E%A5%E7%82%B9%E3%81%8C%E7%95%B0%E3%81%AA%E3%82%8C%E3%81%B0%E6%8E%A5%E7%B7%9A%E3%82%82%E7%95%B0%E3%81%AA%E3%82%8B%E3%81%A8%E3%81%AF+...%0D%0A&gs_lp=Egxnd3Mtd2l6LXNlcnAiTjPmrKHplqLmlbDjga7jgrDjg6njg5Xjgafjga_mjqXngrnjgYznlbDjgarjgozjgbDmjqXnt5rjgoLnlbDjgarjgovjgajjga8gLi4uCjIHECMYJxjqAjIHECMYJxjqAjIHECMYJxjqAjIHECMYJxjqAjIHECMYJxjqAjIHECMYJxjqAjIHECMYJxjqAjIHECMYJxjqAjIHECMYJxjqAjIHECMYJxjqAjIUEAAYgAQY4wQYtAIY6QQY6gLYAQEyFBAAGIAEGOMEGLQCGOkEGOoC2AEBMhQQABiABBjjBBi0AhjpBBjqAtgBATIWEAAYAxi0AhjlAhjqAhiMAxiPAdgBAjIWEAAYAxi0AhjlAhjqAhiMAxiPAdgBAjIWEAAYAxi0AhjlAhjqAhiMAxiPAdgBAjIWEAAYAxi0AhjlAhjqAhiMAxiPAdgBAjIWEAAYAxi0AhjlAhjqAhiMAxiPAdgBAkigJlDLBVi-GnACeAGQAQCYAeQBoAGAEqoBBjAuMTYuMbgBA8gBAPgBAfgBApgCBKACoQOoAhLCAgoQABiwAxjWBBhHwgIIEAAYgAQYogTCAgQQIxgnwgIIEAAYgAQYsQPCAgUQABiABJgDIYgGAZAGA7oGBggBEAEYAboGBggCEAEYC5IHBTIuMS4xoAfhXg&sclient=gws-wiz-serp
C_TS422_2021 SAP Certified Application Associate SAP S/4HANA Production Planning and Manufacturing対策（19/100）

【19日目】
トピック 3：SAPS/4HANAのマスタデータ（8/22）

≪問題19≫
部品表/配合表（BOM）内では、以下のどの標準明細カテゴリを選択できますか。
（２つ選択）
□ワークアイテム
□非在庫品目
□WBSアイテム
□可変サイズ品目

≪解答≫
□ワークアイテム
■非在庫品目
□WBSアイテム
■可変サイズ品目

≪解説≫
◆BOM明細には、明細カテゴリが割り当てられている必要があります。明細カテゴリは、以下のような明細の機能を定義します。
（1）品目を入力する必要があるかどうか。
（2）明細が数量基準の在庫管理をサポートするかどうか。
（3）プラス符号とマイナス符号の両方をサポートするかどうか。
（4）副明細がサポートされるかどうか。
（5）どの画面が選択されるか、また、明細の詳細画面のレイアウトはどうなっているか。
◆BOM明細の標準明細カテゴリとしては、以下のものがあります。
（1）在庫品目
（2）非在庫品目
（3）可変サイズ品目
（4）テキスト明細
（5）文書明細
（6）クラス明細
（7）PM構造要素
（8）中間品目
AzureVMをPythonで起動したい！

# はじめに
私はゲームのサーバーをAzureVMで実行して、日々ゲーミングライフを楽しんでいます。
DiscordからAzureVMを起動するために、Python側から起動と停止を調べたので書き記します。
# 準備
この後のコードで使用するための`SUBSCRIPTION_ID`、`CLIENT_ID`、`CLIENT_SECRET`、`TENANT_ID`はそれぞればれたらまずい（`SUBSCRIPTION_ID`は問題ないかもしれない）ので、環境変数にしてあげます。
それぞれの取得方法は以下の通りです。

AzureVMは作成済みの状態で、「Microsoft Entra ID＞アプリの登録＞新規登録」に進みます。
設定は特に変えずに名前を変えて登録します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883745/20ee995b-cf6d-c681-279a-96ab288453ce.png)
こちらの画像の赤文字が対応しています。それぞれコピーしましょう。

`CLIENT_SECRET`は「証明書またはシークレットの追加」を押せばシークレットキーが作成できるページに飛ぶので、「新しいクライアントシークレット」から追加してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883745/80344c0d-ed1b-6461-d375-bbf6fe1f3ca4.png)
次に自分のAzureVMの管理ページを開き、それぞれコピーします。
# 起動
まず、AzureVM起動のプログラムを書きます。
`azure-identity`と`azure-mgmt-compute`の2つをインストールする必要があります。
```bash
pip install azure-identity azure-mgmt-compute
```
それぞれ`azure-identity`は認証用に、`azure-mgmt-compute`はAzureVMの起動などの操作に使用します。
```python
from azure.identity import ClientSecretCredential
from azure.mgmt.compute import ComputeManagementClient
import os

subscription_id = os.environ["SUBSCRIPTION_ID"]
resource_group_name = "MyVM_group"
vm_name = "MyVM"

client_id = os.environ["CLIENT_ID"]
client_secret = os.environ["CLIENT_SECRET"]
tenant_id = os.environ["TENANT_ID"]

credentials = ClientSecretCredential(tenant_id, client_id, client_secret)

compute_client = ComputeManagementClient(credentials, subscription_id)

vm = compute_client.virtual_machines.get(resource_group_name, vm_name)

operation = compute_client.virtual_machines.begin_start(resource_group_name, vm_name)
print("AzureVMを起動します。")
```
`SUBSCRIPTION_ID`、`CLIENT_ID`、`CLIENT_SECRET`、`TENANT_ID`には先ほど控えたものを入れればOKです。

# 待機
起動といっても、現在のコードでは「起動しろ」という命令を送っただけなので、実際に起動するのはもう少し先になります。
```python
operation = compute_client.virtual_machines.begin_start(resource_group_name, vm_name)
print("AzureVMを起動します。")
operation.wait()
print("AzureVMが起動しました。")
```
`operation.wait()`を使用することでAzureVMが完全に起動するまでの待機が可能です。
# 停止
停止はするときも似たような書き方で`begin_deallocate`を使用します。
```python
operation = compute_client.virtual_machines.begin_deallocate(resource_group_name, vm_name)
```
私が実際に使用するときには停止完了を検知していませんが、上の`operation.wait()`で待機できるはずです(確か)。

# おわりに
私は全部読めていませんが、こちらのサンプルコードがまとまっています。
[Azure-Samples/azure-samples-python-management](https://github.com/Azure-Samples/azure-samples-python-management)

実際にDiscordBotと連携して、AzureVMを制御できるとAzureにログインしていない鯖の人でもAzureVMの起動をすることができるので重宝させてもらっています。
C_TS4FI_2021 SAP Certified Associate - SAP S/4HANA 2021 for Financial Accounting対策（6/100）

【6日目】
トピック 1：組織割当およびプロセス統合（6/15）

≪問題6≫
会社コードに対してカスタム通貨タイプZ1を定義します。
次のどの通貨タイプをデータ入力ビューに保存する必要がありますか。
正しい答えを2つ選択してください。
□グローバル通貨
□会社コード通貨
□伝票通貨
□カスタム通貨タイプZ1

≪解答≫
□グローバル通貨
■会社コード通貨
■伝票通貨
□カスタム通貨タイプZ1

≪解説≫
◆カスタム通貨タイプ（ユーザー定義の独自の通貨タイプ）を含む定義通貨1～8は、データ入力ビューではなく、ユニバーサルジャーナル（総勘定元帳ビュー）に対して設定されます。
◆データ入力ビューに設定されるのは、伝票通貨と会社コード通貨です。
Javaプログラミングの注意点と文字の出力

# 概要
### このページでわかること

- プログラミングする際の注意点
- 文字を出力するパターンを２つ知る

### 今回に覚えておきたいこと
- プログラミングの注意点
- `println`と`print`の二つ

# Javaプログラミングの注意点
1. 全角と半角に注意する
    + プログラムの中でこれらは区別される（全部全角で書くとエラーが起きる）
    + 全角と半角は文字だけでなくスペースにも注意する→スペースを開ける時は半角を使う（””の中では全角でも大丈夫）
2. 大文字と小文字を区別する
    + javaと JAVAの意味は違う
    + プログラムを記述する際に大文字と小文字を指示通り使い分ける
3. カッコをきちんと使い分ける
    + (){}[]といったカッコがあるが、それぞれ役割が異なるため指示通り、必要な場所で必要なカッコを使う
4. 事前に予約されている言葉がある
    + do、if、importといった言葉はあらかじめプログラムの中で役割が決められている言葉である（これを予約語という）
    + 予約語を自分で命名するときに使わないようにする

# 文字を出力するコード
+ 実際に文字を出力するコードを書いてみる
```java:文字の出力１
public class Sample {
	public static void main(String[] args){
		System.out.println("こんにちは");
		System.out.println("よろしくお願いします");
	}
}
```
```:出力結果
こんにちは
よろしくお願いします
```

+ 次にもう一つのパターンで文字を書いてみる
```java:文字の出力２
public class Sample04 {
	public static void main(String[] args){
		System.out.print("こんにちは");
		System.out.print("よろしくお願いします");
	}
}
```
```:出力結果
こんにちはよろしくお願いします
```

# まとめ
```java:文字を出力するコード２つ
System.out.println()
// 文字列を１行ずつ改行したいとき

System.out.print()
// 文字列を続けて出力したいとき
```
+ この２つによって文字を出力することができる
+ 状況による使い分けが必要になる！
SAP S/4 HANA 販売管理（SD）基本知識２：組織とマスタ（販売管理関連組織・品目マスタ）

### 販売管理関連組織
![販売管理関連組織.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3432463/cda455cf-9713-4639-bfef-07b3c2c7e299.png)
ここでは、販売管理の各組織の目的と関係を説明します。
会社は独立した会計単位を表わし、企業グループ内の会社などが該当します。法律で定められている貸借対照表や損益計算書は会社レベルで作成されます。
販売組織は販売活動で責任を負う組織単位です。また、管理レポート、業務管理、及び分析を行う際に重要な単位です。テンプレートでは、国内販売と海外販売の２つの販売組織が用意されています。
流通チャネルは商品やサービスを得意先に届ける流通の形態を表します。 （例.店頭販売、インターネット取引　等）。通常は流通チャネルをダミーとして1つだけ設定するケースが多いです。テンプレートでは、複数の流通形態を持たない想定のため、流通チャネルは1つだけ用意されています。
製品部門は商品やサービスをグループ化することができます。テンプレートでは、見込生産品と受注生産品の２つの製品部門が用意されています。
営業所は取引や販売で使用する組織構造の地理的な側面を定義します。営業所は販売組織＋流通チャネル＋製品部門の組合せに対して割り当てます。テンプレートでは営業課として、物理的な営業所＋製品ラインアップごとに定義しています。営業所は、販売の各伝票においては、受注や売上の実績がどの営業組織に帰属するかを識別できます。また、得意先マスタには、管轄している営業組織を登録します。
![販売管理関連組織2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3432463/e954d317-1005-f978-ebda-34da2a4b259c.png)
会社コードは前述で説明した通りです。
プラントは、品目の在庫の金額と数量を管理する単位です。同じ品目でも複数の原価を管理したい場合には、プラントを分けることを検討します。販売管理では、どこから商品を出荷するか？という観点から、「出荷プラント」と呼びます。
出荷ポイントは出荷を管理する単位です。出荷指示（出荷伝票登録）を行う場合に指定するキーとなるため、倉庫や物流部門、出荷パース等、出荷を分けて管理したい単位にそれぞれ設定します。プラントが近接している場合は、1つの出荷ポイントを複数のプラントに割り当てることも可能です。

### 品目マスタ
![品目マスタ１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3432463/a839fdfa-d613-4a98-ff12-a5bc0ea586d3.png)
【基本データビュー】
- 名称や重量・容積等、品目に関する基本的な情報を登録・管理します。
- 品目につき１つだけ登録し、全ての組織構造で共通で使用されます。
【販売ビュー】
- 販売の数量単位や、出荷プラント等、販売管理業務に関する情報を登録・管理します。
- 販売組織＋流通チャネルの組合せごとに登録し、その組織の組合せにおいてのみ使用されます。
- 同じ品目を異なる取引条件で販売する場合は、販売組織または流通チャネルを分ける必要があります。但し、組織を分けるとマスタのメンテナンス負荷も増えるので注意が必要です。
【会計ビュー】
- 会計仕訳に関わる情報（主に原価）を登録・管理します。
- プラントごとに登録し、該当のプラントにおいてのみ使用されます。
- 同一の品目でも売上原価が異なる管理を行いたい場合は、プラントを分けることを検討します。
![品目マスタ２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3432463/e3078edb-3d57-be0b-19bf-1135e39076cf.png)
![品目マスタ3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3432463/0196bd0c-1e46-a68a-775b-85d080226b06.png)
![品目マスタ4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3432463/1bb0ec05-99e7-bb92-771e-23f9f120aaa1.png)
![品目マスタ5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3432463/d5cacbf0-2d48-fb45-329a-3306bcf48442.png)
![品目マスタ6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3432463/0d51e549-af98-4661-9cf4-19a5d8a4d27f.png)
pythonインストール時のFailed to install MSI Packageの解決策

# はじめに
これまで何回かpythonのインストールを行ってきたが、
初めてインストール時点でエラーが発生したので備忘録。


# エラー内容
【ログの一部】
MSI Packageのインストールに失敗
![image0.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3634951/eeb64619-1e13-9836-1db7-3c9e588a4238.jpeg)



# 解決
解決策をいくつか掲載してくれている中で、
自分は下記の方法でインストールできるようになりました！

>「Windowsキー+R」を押下し、「services.msc」と入力します。
「Windows Installer」をダブルクリックし、「手動」を選択して適用してください


https://linx-jp.my.site.com/kb/s/article/pylon%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB-%E3%82%A2%E3%83%B3%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%AB%E5%A4%B1%E6%95%97%E3%81%99%E3%82%8B



# 参考サイト
こちらの記事参考にカスタマイズでインストール試みるも再度エラー発生...
ただ、インストールできるようになった方もいるみたいですね:thinking:

https://1kara-hajimeru.com/2020/01/534/



# 最後に
こんなこともあるんだな。

でもやっぱりエラー解決できた時は嬉しいし、
情報があるのは本当にありがたい:sparkles:
チューリングマシン自作した話

https://github.com/KajizukaTaichi/Stem

教育用のチューリングマシン「Stem」を開発しました。これはチューリングマシンの基本概念を理解するためのシンプルなエミュレータです。特に、計算理論やチューリングマシンに興味がある方には必見のツールです。

## Stemとは？

Stemは、「Stem: Turing Educational Machine」の略で、再帰的頭字語になっています。このエミュレータは、チューリングマシンの動作をシンプルに再現することで、教育的な価値を提供します。具体的には、以下のような特徴を持っています：

- **CLI**: コマンドラインで実行できるので出力をファイルにも書き込める
- **JSON**: 分かりやすいデータ構造JSONでチューリングマシンを定義できる

## 仕様
- **tape**: シンボルとして UTF-8 文字を含める
- **start_state**: 実行開始時の初期状態
- **transitions**: 遷移のルールを定義する

### 遷移ルールの形式
分割された "_" アンダースコアを記述します。
左は状態を指定し、右は読み取られるシンボルを指定します

## 実例: ビット反転

ここでは、ビット反転を行う簡単なチューリングマシンの例を示します。

```json
{
    "tape": "11010010",
    "start_state": "q0",
    "transitions": {
        "q0_0": { "write": "1", "direction": "Right", "next_state": "q0" },
        "q0_1": { "write": "0", "direction": "Right", "next_state": "q0" }
    }
}
```

### 実行トレース

この設定を使ってチューリングマシンを実行すると以下のようになります：

```
Stem: Turing Educational Machine
-----------------------------------
Current State: q0, Read: 1
[1] 1 0 1 0 0 1 0
Write: 0, Move: Right, Next State: q0
 0[1] 0 1 0 0 1 0

Current State: q0, Read: 1
 0[1] 0 1 0 0 1 0
Write: 0, Move: Right, Next State: q0
 0 0[0] 1 0 0 1 0

Current State: q0, Read: 0
 0 0[0] 1 0 0 1 0
Write: 1, Move: Right, Next State: q0
 0 0 1[1] 0 0 1 0

Current State: q0, Read: 1
 0 0 1[1] 0 0 1 0
Write: 0, Move: Right, Next State: q0
 0 0 1 0[0] 0 1 0

Current State: q0, Read: 0
 0 0 1 0[0] 0 1 0
Write: 1, Move: Right, Next State: q0
 0 0 1 0 1[0] 1 0

Current State: q0, Read: 0
 0 0 1 0 1[0] 1 0
Write: 1, Move: Right, Next State: q0
 0 0 1 0 1 1[1] 0

Current State: q0, Read: 1
 0 0 1 0 1 1[1] 0
Write: 0, Move: Right, Next State: q0
 0 0 1 0 1 1 0[0]

Current State: q0, Read: 0
 0 0 1 0 1 1 0[0]
Write: 1, Move: Right, Next State: q0
 0 0 1 0 1 1 0 1[_]
```

このトレースでは、次のことが確認できます：

- 初期状態`q0`から開始し、テープの各シンボルを一つずつ読み取ります
- 読み取ったシンボルに応じて、反転したシンボルを書き込み、右に移動して次の状態に遷移します
- テープの最後までこのプロセスを繰り返します

## まとめ

Stemは、チューリングマシンの基本概念を理解するための強力なツールです。簡単な設定で動作し、視覚的に状態遷移を確認できるため、教育現場での利用に最適です。

ぜひ、このエミュレータを試してみて、チューリングマシンの世界に触れてみてください！
BottomNavigationViewのWindowInsetsを変える

Edge-to-Edge 対応で現状のレイアウト構成から仕方なく material-components の `BottomNavigationView` のデフォルトの WindowInsets から適用する箇所を変更したいときの方法です。

* * *

`BottomNavigationView` のデフォルトの WindowInsets は内部でのみ処理されているのでパラメータでの切り替えができません。

https://github.com/material-components/material-components-android/blob/20f92dfb513916d0df6c38bfd630dfc41aff484e/lib/java/com/google/android/material/bottomnavigation/BottomNavigationView.java#L141-L164

そのため、レイアウトの構成によっては不要な WindowInsets がついてしまう場合があります。


![Screenshot_20240627_195656.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126298/ee1a7ad6-cdd4-defa-1902-8236e9d38a84.png)

このスクショの場合だと DisplayCutout 分の WindowInsets が余分についてしまっています。

<br />

この解決には WindowInsets の消費の仕組みを利用します。
`BottomNavigationView` に対して `ViewCompat.setOnApplyWindowInsetsListener` で `WindowInsetsCompat.CONSUMED` を返して処理したことにしてしまえば、`BottomNavigationView` 内部の WindowInsets の処理が呼ばれなくなります。


```kotlin
ViewCompat.setOnApplyWindowInsetsListener(bottomNavigationView) { v, windowInsets ->
    WindowInsetsCompat.CONSUMED
}
```

もちろん `WindowInsetsCompat.CONSUMED` を返すだけだと必要な WindowInsets まで消えてしまうことになります。

![Screenshot_20240627_201135.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126298/d95f274c-8df1-aee1-ce1f-214c5ac45b95.png)


そのため、必要な WindowInsets を設定しつつ `WindowInsetsCompat.CONSUMED` を返すようにしましょう。

```kotlin
ViewCompat.setOnApplyWindowInsetsListener(bottomNavigationView) { view, windowInsets ->
    val insets = windowInsets.getInsets(WindowInsetsCompat.Type.navigationBars())
    view.updatePadding(
        bottom = insets.bottom
    )
    WindowInsetsCompat.CONSUMED
}
```

![Screenshot_20240627_195742.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126298/c16a162b-8854-fa4c-4c36-76ab07d85d12.png)

もちろん、この WindowInsets の消費による `BottomNavigationView` の WindowInsets の上書きは [Insetter](https://github.com/chrisbanes/insetter/) での実装でも可能です。
Docker 周りでエラーが発生した時の汎用コマンド

## はじめに
はじめまして！2024/04/11よりRUNTEQというプログラミングスクールに在学中のみうらと申します。
`Ruby on Rails` を学習中です。
今回は初めての投稿として`Docker`周りにエラーが発生した時のコンテナ、イメージ、ボリューム、ネットワークを削除する流れについて記していきます。
初心者ゆえ、至らないところがあると思いますがご理解のほどよろしくお願いいたします。

## 現状発生しているエラーの確認
**環境構築中に発生**
下記コマンドを実行すると、エラーが発生。
```:ターミナル
docker compose up
```
何度か`Doker`の環境構築でつまずいた時に後述する手順で解決できたので記していきます。

## 実際の流れ
```:ターミナル
docker stop $(docker ps -q)
docker ps

# yes or no と効かれるので y を入力してエンター
docker container prune
docker container ls -a

# yes or no と効かれるので y を入力してエンター
docker rmi $(docker images -q)
docker images

# yes or no と効かれるので y を入力してエンター
docker network prune
docker network ls

# yes or no と効かれるので y を入力してエンター
docker volume prune
docker volume ls
```
`docker volume ls`コマンド入力後表示されたボリュームを削除していきます。
#### 以下例
```:ターミナル
docker volume ls
DRIVER    VOLUME NAME
local     test1
local     test2
local     test3
```
```:ターミナル
# 任意のボリュームを消したい時
docker volume rm test1

# 任意のボリュームを消したい時(複数)
docker volume rm test1 test2

# 大量にある時(全て削除されてしまうので要確認)
docker volume ls -q
docker volume ls -q | xargs docker volume rm

```
上記コマンド後再度`docker volume ls`コマンドを実行し削除されていることを確認しましょう。
コマンドでコンテナ、イメージ、ボリューム、ネットワークを削除しクリーンな状態になります。この状態で`docker compose up`など実行するとうまく行くケースが多いです。(個人的意見)

## おわりに
今回初めての投稿となり至らない箇所多くあると思いますが、ご了承ください。
今後も日々のアウトプットとして記していきたいと思います。
Next.jsでリバースプロキシーのかわりになるもの

# Nextjsにおけるリバースプロキシーとは

rewritesを指しています。

https://nextjs.org/docs/app/api-reference/next-config-js/rewrites

SPAとかで、viteとか、webpack使うと、だいたいみんな記述するやつです。
nextjsにも備わっていますが、例を出すとこんなかんじです。

`http://localhost:3000/api`に来たリクエストを`http://localhost:3001`にリクエストし直す設定だと下記のようになります。



```next.config.js
/** @type {import('next').NextConfig} */

const nextConfig = {
  async rewrites() {
    return [
      {
        source: "/api/:path*",
        destination: `http://localhost:3001/:path*`,
      },
    ];
  },
};

module.exports = nextConfig;
```

# ただ、弱点もある

いろいろ機能は揃っているものの、rewriteしたパスを考えるのは面倒になってきます。
あと、 内部的にHTTP2に対応していないようなので、gRPCへの転送は残念ながらできません。

# 代替え案、キャッチオールセグメント

`/app/api/[...api]/route.ts`

のように、`[...api]`でjavascriptのスプレッド構文みたいに記述すると、パスの`/api/`配下に来たリクエストをすべて、`route.ts`が受けることができます。

これだと、rewritesでやっていたことを代替えできますし、あとはパスを見たりheadersやcookiesも[ルートハンドラ](https://nextjs.org/docs/app/building-your-application/routing/route-handlers)で、できるすべて叶えることができます。
gRPCのクライアントを使えば、gRPCのリクエストも出来るようになります。

```/app/[...api]/route.ts

export function GET(req: NextRequest) {
  try {
    const { pathname } = new URL(req.url);
    
    if (pathname === "/api/health") {
      return Response.json({ status: 200, message: "OK" });
    }

    return Response.json({ status: 404, message: MESSAGE.NOT_FOUND });
  } catch (error) {
    return Response.json({ status: 500, error, message: MESSAGE.SERVER_ERROR });
  }
}

```

### 結果
```sh
curl http://localhost:3000/api/health
{"status":200,"message":"OK"}
```

現場からは以上です。
MongoDB: Docker 上の MongoDB に mongoose で接続

## プログラム

データの挿入

```js:insert_authors.js
// ----------------------------------------------------------------
//	insert_authors.js
//
//						Jun/27/2024
// ----------------------------------------------------------------
const mongoose = require('mongoose');

// MongoDB コネクションの設定
const mongoURI = 'mongodb://localhost:27017/my_database';

// MongoDB への接続
mongoose.connect(mongoURI);

// 接続が確立された時のコールバック
const db = mongoose.connection;
db.on('connected', function() {
  console.log('MongoDBに接続しました');
});

// データのスキーマ定義
const authorSchema = new mongoose.Schema({
  name: String,
  birth: Number
});

// モデルの作成
const Author = mongoose.model('Author', authorSchema, 'my_collection');

// データの挿入
const author1 = new Author({ name: '森鴎外', birth: 1862 });
const author2 = new Author({ name: '夏目漱石', birth: 1867 });
const author3 = new Author({ name: '島崎藤村', birth: 1872 });

// データの保存
const saveAuthors = async () => {
  try {
    await author1.save();
    await author2.save();
    await author3.save();
    console.log('データを保存しました');
  } catch (error) {
    console.error('データの保存に失敗しました', error);
  } finally {
    // 接続の切断
    mongoose.connection.close();
  }
};

// ----------------------------------------------------------------
saveAuthors();

// ----------------------------------------------------------------
```

データの取得

```js:read_authors.js
// ----------------------------------------------------------------
//	read_authors.js
//
//						Jun/27/2024
// ----------------------------------------------------------------
const mongoose = require('mongoose');

// MongoDB コネクションの設定
const mongoURI = 'mongodb://localhost:27017/my_database';

// MongoDB への接続
mongoose.connect(mongoURI);

// 接続が確立された時のコールバック
const db = mongoose.connection;
db.on('connected', function() {
  console.log('MongoDBに接続しました');
});

// データのスキーマ定義
const authorSchema = new mongoose.Schema({
  name: String,
  birth: Number
});

// モデルの作成
const Author = mongoose.model('Author', authorSchema, 'my_collection');


// データの取得
const getAuthors = async () => {
  try {
    const authors = await Author.find();
    console.log(authors);
  } catch (error) {
    console.error('データの取得に失敗しました', error);
  } finally {
    // 接続の切断
    mongoose.connection.close();
  }
};
// ----------------------------------------------------------------

getAuthors();
// ----------------------------------------------------------------
```

## 実行コマンド

データの挿入

```bash
export NODE_PATH=/usr/local/lib/node_modules
node insert_authors.js
```

データの取得

```bash
export NODE_PATH=/usr/local/lib/node_modules
node read_authors.js
```
CoreMP135のbuildroot をビルドする

## 概要

CoreMP135は、M5Stackが発売するSTM32MP135Dを搭載したLinux搭載したIoT開発キットです。CoreMP135のLinuxOSには,BuildrootとDebianが用意されており、ここでは、Buildrootをビルドする手順を説明します。
ビルド手順1とビルド手順2の２つの方法があります。

M5Stack CoreMP135
https://www.switch-science.com/products/9650

### 補足

本手順でビルドせずに、M5Stackが用意するBuildrootのイメージファイルをダウンロードして書き込むことができます。
https://docs.m5stack.com/en/guide/linux/coremp135/image


## ビルド手順1

```
git clone https://github.com/m5stack/CoreMP135_buildroot.git
git clone https://github.com/m5stack/CoreMP135_buildroot-external-st.git
cd CoreMP135_buildroot
make BR2_EXTERNAL=../CoreMP135_buildroot-external-st/ m5stack_coremp135_515_defconfig
make -j4
```

現在、プロジェクトは、m5stack_coremp135_defconfig（カーネル・バージョン6.1）とm5stack_coremp135_515_defconfig（カーネル・バージョン5.15）の2つのカーネル・バージョンのコンフィギュレーションが用意されています。いくつかのドライバがLinux 6.1用のバージョンにない問題があり、M5Stackの推奨バージョンは、カーネル・バージョン5.15になっています。
コンパイルが完了すると、CoreMP135_buildroot/output/imagesディレクトリに、sdcardに書き込むイメージ・ファイルsdcard.imgが得られます。


## ビルド手順2

Buildrootのビルド手順を自動化するスクリプトが用意されています。
ビルド手順2として、この手順を試してみます。
 
```
git clone https://github.com/m5stack/CoreMP135_buildroot-external-st.git
cd CoreMP135_buildroot-external-st/tools
./creat_coremp135_buidlroot_image.sh
```
コンパイルが完了すると、tools/build_coremp135_buidlroot/CoreMP135_buildroot/output/ディレクトリに、sdcardに書き込むイメージ・ファイルsdcard.imgが得られます。

## 参照資料

CoreMP135 image burning
https://docs.m5stack.com/en/guide/linux/coremp135/image

CoreMP135_buildroot-external-st
https://github.com/m5stack/CoreMP135_buildroot-external-st
画像から文字を抽出

#### 今回はこちらの画像から文字の抽出を行う

<img width="400" alt="スクリーンショット 2024-06-22 210546.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3634951/96403802-130b-94af-e8ba-34c494f46c97.png"> 


# Pillowとは
広範な画像処理機能を提供する Python Imaging Library (PIL) フォーク。
画像ファイル形式を開いたり、操作したり、保存したりするためのライブラリ

https://python-pillow.org/

```
pip install pillow
```

# pytesseractとは
>Python 用の光学文字認識 (OCR) ツールです。つまり、画像に埋め込まれたテキストを認識して「読み取り」ます。

https://github.com/madmaze/pytesseract

```
pip install pytesseract
```

# スクリプト
```python
import pytesseract
from PIL import Image

# 画像ファイルを開く
image = Image.open('image.png')

# PyTesseractを使って文字列を抽出する
text = pytesseract.image_to_string(image)
print(text)
```



# 参考サイト
https://www.educative.io/answers/how-to-extract-text-from-an-image-in-python

また、下記のサイトでは精度を上げることもできるみたい:thinking:

https://note.com/luuluu3311/n/nade49014bdf2

# 最後に
全ての画像から文字を抽出できるわけではないみたいなので、そこ考慮して使う必要がある

今回は、業務で知ったライブラリをただ試してみたかった。
pythonは出来ることが多く、まだまだ知らないことばかりだが、
少しずつ知っていけてる今が楽しい♪
【Application Integration】削除したはずの統合と同名の統合を作れない時の対応

# はじめに
この記事は 2024年6月10日時点の仕様に基づいています
ドキュメントに一切書かれていないため、独自に検証した内容です
まだリリースされて日が浅いサービスなので今後仕様が変更になる可能性があります

# 事象
画像のように統合を新規作成しようとすると、下記のエラーで失敗します

```text
The integration name: <Integration name> already exists in the selected region.
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1217064/a6667fec-81e3-c802-e517-734762d231b8.png)

「testという名前の統合は既に存在するよ」とのこと
しかしその統合、既に削除済みなのです
実際、統合一覧に「test」という名前は見当たりません


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1217064/3d2163f1-734d-f8e7-8300-3c9428115834.png)

# 発生条件
コンソール上で統合を削除する方法は3パターンあります

1つ目は一覧画面で`︙`を選択し削除
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1217064/7cec7686-7087-86db-c645-aaf6080b2dde.png)

2つ目は統合詳細画面から`Delete all versions`で削除
![Google Chrome 2024-06-27 17.03.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1217064/07bdf6e4-35e3-0cfb-d4f5-2c20670c7a0c.png)

3つ目は統合詳細画面から`Delete the current version`で削除
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1217064/4ed1eacc-4632-5768-57e2-1d89010728ef.png)

今回のような事象を引き起こすのは、**3つ目の方法で統合を削除したとき**です

画像のように`VERSION 1`しか無い時に`Delete the current version`を実行すると、このような表示が出ます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1217064/0a753863-c5bd-3359-da47-c753d97846fd.png)

一覧ページに戻ると先ほどの統合は表示されない、にもかかわらず同名の統合を作成しようとするとエラーになってしまうのは前述のとおりです
おそらく**3つ目の方法では統合が完全には削除されない**のでしょう

# 解決方法
コンソールではもうどうすることもできません
こちらのAPIで統合を完全削除してやります


https://cloud.google.com/application-integration/docs/reference/rest/v1/projects.locations.integrations/delete

プロジェクトID、リージョン、削除したい統合名に認証情報を加えてリクエストします
これで同じ名前の統合が作れるようになるはずです

```shell
curl --request DELETE \
  'https://integrations.googleapis.com/v1/projects/[PROJECT_ID]/locations/[REGION]/integrations/[INTEGRATION_NAME]?key=[YOUR_API_KEY]' \
  --header 'Authorization: Bearer [YOUR_ACCESS_TOKEN]' \
  --header 'Accept: application/json' \
  --compressed
```

ちなみに削除が成功すれば200、指定した統合が存在しなければ404が返ってきます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1217064/5fb89cf6-1f04-6622-95db-ef7a4632a662.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1217064/d8b00c4b-0b34-efa9-3689-a1d44510deae.png)

# FAQ
### gcloud コマンドでできないの？
できません。少なくともこの記事作成時点（2024年6月）では Application Integration に関わる gcloud コマンドは確認できませんでした

### バージョンを消すことで統合を消すなんて謎な行動とる人いる？
はい。ここにいます...
というのも、今回紹介した3つの削除方法の中で1、2番の方法を実行するには強い権限が必要なのです
私の場合、権限が足りず仕方なく3番の方法を実行したところ、今回の問題に遭遇したわけです
結局、今回の解決方法を取るには強い権限が必要になってしまったのですが...

### 時間が経ったら勝手に統合が消えるのでは？
その可能性はあります。ただ確認した限り、30日経っても消えませんでした

# おわりに
こんなピンポイントすぎる記事が誰かの役に立つかわかりませんが、同じ問題を抱える人の助けになれば幸いです
円錐（えんすい、英: cone）について調査中

# wikipedia 

https://en.wikipedia.org/wiki/Cone

https://ja.wikipedia.org/wiki/円錐




# 文献

#### 3.4 直円錐の切断　P43
＞いろいろな曲線 (新しい数学へのアプロ-チ) : 栗田稔: 本
01 直線と円
02 関数のグラフ
03 2次曲線
04 曲線 f(x,y) = 0
05 運動と曲線
06 極座標と曲線
07 曲線の微分方程式
08 曲線と極大極小
09 空間曲線
10 曲線の基礎
https://www.amazon.co.jp/%E3%81%84%E3%82%8D%E3%81%84%E3%82%8D%E3%81%AA%E6%9B%B2%E7%B7%9A-%E6%96%B0%E3%81%97%E3%81%84%E6%95%B0%E5%AD%A6%E3%81%B8%E3%81%AE%E3%82%A2%E3%83%97%E3%83%AD%E3%83%BC%E3%83%81-%E6%A0%97%E7%94%B0%E7%A8%94/dp/4320010590




#### 円錐曲線もコマンドImplicitPlotでグラフ化できる...
＞Mathematica演習 | マーサ L.アベル, ジェームス P.ブレイ ...
https://www.amazon.co.jp/Mathematica-%E3%83%9E%E3%82%BB%E3%83%9E%E3%83%86%E3%82%A3%E3%82%AB-%E6%BC%94%E7%BF%92-%E3%83%9E%E3%83%BC%E3%82%B5%E3%83%BBL-%E3%82%A2%E3%83%99%E3%83%AB/dp/4938455358
HSP3.6でメキシカンハット

# 概要

巷でメキシカンハットチャレンジが流行っていると聞いてHSP3.6に移植してみました。BASICが源流のHot Soup Processorだけあって元コードの雰囲気で書けている気がします。

```hs
screen 0, 640, 480, 0 : cls 4
dim d, 160 : repeat 159, 1 : d(cnt) = 100 : loop : dr = M_PI / 180.0
y = -180
repeat
	x = -180
	repeat
		r = dr * sqrt(double(x*x + y*y))
		z = 100.0 * cos(r) - 30.0 * cos(3.0 * r)
		sx = int(80.0 + double(x) / 3.0 - double(y) / 6.0)
		sy = int(40.0 - double(y) / 6.0 - double(z) / 4.0)
		if (sx < 0) + (sx >= 160) : goto *skip
		if d(sx) <= sy : goto *skip
		zz = int((z + 100.0) * 0.035) + 1
		rc = 0 : gc = 0 : bc = 0
		if (zz==1) + (zz==3) + (zz==5) + (zz==7) : bc = 255
		if (zz==2) + (zz==3) + (zz>=6) : rc = 255
		if zz >= 4 : gc = 255
		if (rc != 0) + (gc != 0) + (bc != 0) {
			color rc, gc, bc : boxf sx*4, sy*4, sx*4+2, sy*4+2
		}
		d(sx) = sy
*skip
		x += 4
		if x > 180 : break
	loop
	y += 6
	if y > 180 : break
loop
```


|実行結果|
|:-:|
|![mexi1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213145/f426c67a-dd3b-38a4-79c1-7bfeaa65b305.png)|
|psetだと光量が足りない感じだったのでboxfで大きくしました|

# 参照

https://x.com/yone/status/1804801190448054746
【SwiftUI + SwiftData】ScrollView + LazyVStack vs Large amounts of data

どれぐらいの数の子アイテムの表示をこなせるか。

どのように処理するか。

そんな話題になります。

https://www.youtube.com/watch?v=ju8OXC9EH2w

# 🧑🏻‍💻 ```@Query``` や ```fetch()``` で 一括 1000個 以上 は重い

大量のモデルデータに対して、

View 側が重いのかと思ったら、一括抽出が重いんですよね。

https://x.com/maochanz/status/1808084351974101019

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588914/94408ee0-225c-d714-e28d-ada4d6924008.gif" width="300">



なので、1000個ずつ抽出して追加していく形で。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588914/b5b6cf5d-190d-9af2-103f-1a6d2f6f90ed.gif" width="320">


# 🧑🏻‍💻 ```@Observable``` を使う

![sc 2024-07-02 at 14.06.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588914/bbb0603f-3109-d298-c00b-e4eaa51429dd.png)


# 🧑🏻‍💻 ```@MainActor``` と ```Thread``` の関係

これは正直良く分からん。

明示的と暗黙的が混合しすぎて方向性が掴めず。

https://x.com/maochanz/status/1808749114198536296

そのうち、Swift 界著名人たちの記事を参考に咀嚼したい。


# 🧑🏻‍💻 引用

https://android.benigumo.com/20240627/scrollview-lazyvstack-vs-large-amounts-of-data/