OmniAICreator/Qiita-1.07M huggingface dataset:
機械学習のDocker環境の中にジュピターノートブック環境を用意してみた

# これは何？

業務で機械学習のプロジェクトにふれる機会がありました
Docker環境も用意されていて、本番環境でも利用できるコンテナが構築されるようになっていました

下位フォルダにノートブック環境のファイルも用意されていたのですが、こちらはDocker環境の用意がなくて、おそらく個人PC上に環境を作って利用していたんだと思います

個人PC上に環境を作るのは、今構築することができても、ちょっと時間が経過した時に同じ環境が作れるか自信がなかったので、別途Docker環境を構築しました

その時のメモになります


# Docker環境の構築

プロジェクトのルートディレクトリには既に`Dockerfile`と`docker-compose.yml`ファイルが存在しているので、ノートブックフォルダ内に`Dockerfile`と`docker-compose.yml`ファイルを作成しました

```tree
.
├── notebooks
│    ├── Dockerfile
│    ├── docker-compose.local.yml
│    └── requirements.txt < ルートディレクトリのをコピー
├── Dockerfile
├── docker-compose.yml
└── requirements.txt
```

- Dockerfile
    ルートディレクトリのDockerfileがPython3.10を利用していたので同じバージョンのノートブックイメージを利用しました
    ※requirements.txtでパッケージをインストールしていたので同じバージョンをインストールするため
    ```dockerfile:notebooks/Dockerfile
    FROM jupyter/base-notebook:python-3.10
    
    ENV APP_HOME /home/jovyan/work
    WORKDIR $APP_HOME
    
    COPY ./requirements.txt requirements.txt
    RUN pip install -r requirements.txt
    ```

- docker-compose.local.yml
    ※もし誤ってルートディレクトリのファイルを上書き保存しないようにファイル名を修正
    ```notebooks/docker-compose.local.yml
    version: '3.4'
    services:
      notebook:
        build: .
        command:
          - start-notebook.sh
          - --NotebookApp.token='' # 認証を無効化
          - --NotebookApp.disable_check_xsrf=True # CSRFチェックを無効化
        ports:
          - 8888:8888
        volumes:
          - ./:/home/jovyan/work
        working_dir: /home/jovyan/work
    ```

## Docker compose で起動

ルートディレクトリから以下のコマンドを実行してコンテナを起動します
```console
docker compose -f notebooks/docker-compose.local.yml up
```

起動後は、コンテナに接続（アタッチ）してノートブックが実行できます


# VSCodeでノートブック環境で必要そうな拡張機能

VSCodeの拡張機能を使うことで上記で構築した環境を利用してジュピターノートブックを開くことができます

- インストールした拡張機能
  - Dev Containers
  - Jupyter
  - Python


# まとめ

機械学習のDocker環境にジュピターノートブック環境も構築することができました
開発がしやすくなってよかったです:relaxed:
(Office 365) Exchange Online にてメールが外部送信できているか確認するスクリプト

利用者より相手にメールが届いているか確認して欲しいという依頼がありましたので PowerShell のコマンドを作成しました。

## メールが外部送信できているか確認するスクリプト
◆使い方
1. **宛先の情報を入力(任意)**
※空にした場合はすべてのメールが対象になります。

2. **差出人の情報を入力(必須)**
※自ドメインのメールアドレスにしてください。

3. **検索範囲を入力(必須)**
※Get-MessageTraceDetail は過去10日までしか遡れません。それ以上の日は指定しないでください。

4. **スクリプトを実行**

```test.ps1
# 宛先の情報を入力する(任意)
$RecipientAddress = '宛先メールアドレスを記入'

# 差出人の情報を入力する(必須)
$SenderAddress = '差出人メールアドレスを記入'

# 検索範囲を入力する(必須)
$StartDate = (Get-Date).AddDays(-10)
$EndDate   = (Get-Date)

# メールアドレスをドメインパートとローカルパートに分ける
$LocalPart  = $SenderAddress.Split("@")[0]  # 出力するファイル名に利用
$DomainPart = $SenderAddress.Split("@")[1]  # 組織内の配信を除外するのに利用

# Get-MessageTrace のオプションを作成する
$MessageTraceOptions = @{
    "RecipientAddress" = $RecipientAddress
    "SenderAddress"    = $SenderAddress
    "StartDate"        = $StartDate
    "EndDate"          = $EndDate
}

# 宛先が存在しない場合はオプションから除外する
if ($RecipientAddress -notlike "*@*" -or $RecipientAddress -eq $null ) {
    $MessageTraceOptions.Remove("RecipientAddress")
}

# Get-MessageTrace の結果を変数に入れる
# ※Mmessage Trace ID の取得が目的
# ※この時、組織内の配送は除外する
$messageTrace = Get-MessageTrace @MessageTraceOptions | Where-Object {$_.RecipientAddress -notlike "*@$DomainPart"}

# 繰り返す
$messageTrace | ForEach-Object {

    # Get-MessageTrace の要素を取り出す
    $tmpSubject          = $_.Subject
    $tmpSenderAddress    = $_.SenderAddress
    $tmpRecipientAddress = $_.RecipientAddress
    $tmpReceived         = $_.Received
    
    # Get-MessageTraceDetail のオプションを作成する
    $MessageTraceDetailOptions = @{
        "MessageTraceId"   = $_.MessageTraceId
        "RecipientAddress" = $tmpRecipientAddress
        "StartDate"        = $StartDate
        "EndDate"          = $EndDate
    }

    Get-MessageTraceDetail @MessageTraceDetailOptions | 
        Select-Object @{Label="Subject";Expression={$tmpSubject}}, @{Label="SenderAddress";Expression={$tmpSenderAddress}}, @{Label="RecipientAddress";Expression={$tmpRecipientAddress}}, @{Label="Received";Expression={$tmpReceived}}, Date, Event, Action, Detail, MessageId, MessageTraceId

} | Export-Csv -Append -Path $ENV:USERPROFILE\Desktop\Get-MessageTraceDetail_$($LocalPart)_$(Get-Date -Format "yyyyMMdd").csv -Encoding Default -NoTypeInformation
```

◆結果
結果はデスクトップに **「Get-MessageTraceDetail_差出人_yyyyMMdd.csv」** というファイルが出力されます。
内容は下記となります。

| 項目 | 意味 |
|:-:|:-:|
| Subject | 件名 |
| SenderAddress | 差出人 |
| RecipientAddress | 宛先 |
| Received | メッセージが受信した日時 |
| Date | メッセージが処理された日時 |
| Event | イベント |
| Action | メッセージに対して実行されたアクション |
| Detail | メッセージトレースイベントの詳細情報 |
| MessageId | メッセージの一意の識別子 |
| MessageTraceId | メッセージトレースの一意の識別子 |

Event 列に **「外部に送信」** があれば外部送信されています。

:::note alert
注意
※外部送信≠相手に届いたですのでご注意ください。
:::
個人的によく使うコードまとめ（R ver.)

# 準備
## フォルダの作成
```
#パッケージのダウンロード
library(fs)
library(here)
# 作業ディレクトリ名やフォルダ名を示す
here::here() 
fs::dir_create(   # 作業ディレクトリ内に複数のフォルダを作成する．
  here::here(
    c("figure",   # 図
      "table",    # 表
      "script",   # スクリプト
      "qmd",   # quartoのqmdファイル
      "data",   # データ
      "document",   # 論文に必要な資料の保存
      "manuscript",   # 原稿
      "submit")    # 提出用ファイルをまとめる  
    )
  )

# 図を保存する時のパス
here::here("figure") 
```
## データの出力
```
# 作成したオブジェクトをdataフォルダに保存
save(a, b,    # 保存したいオブジェクト
     file = here::here("data", "02_objects.RData"))

# 作成した関数についてのデータを読み込む
load(file = here::here("data", "02_objects.RData"))
```


# データの読み込み

# データの確認

# 前処理
【JavaScript】トーンを貼るアルゴリズム【Canvas】

## 前書き

コードはないです。
ぼくがかんがえたさいきょうのトーンペタペタアルゴリズムを語ります。

トーンってなんだよという方は以下のサイトを見てください。

https://ja.wikipedia.org/wiki/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%83%88%E3%83%BC%E3%83%B3

## したいこと

これを

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649673/fcbc5a08-6674-f6d9-e250-d835b15b2f91.png">

こうしたい。

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649673/12a666ea-a873-d751-cbea-8805f9bb9fb5.png">

## アルゴリズム

簡単のため以下の用語を定義します。
加工用キャンバス：加工したい画像が貼られているキャンバス
トーンキャンバス：全体にトーンだけが貼られているキャンバス

### 1. まず加工したい画像を加工用キャンバスに貼ります。

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649673/fcbc5a08-6674-f6d9-e250-d835b15b2f91.png">

### 2. トーンに変換したい色に対応したトーンでトーンキャンバスを生成します。

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649673/20cbe68b-5f9f-f710-72ef-a1a0802d63db.png">

### 3. 加工用キャンバスでトーンに変換したい色を透明にします。

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649673/b013fe46-d047-e643-149a-a48494ddbf08.png">

### 4. トーンキャンバスに加工用キャンバスを貼り付けます。

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649673/75b7a8a1-5a5b-2ebd-4117-c8194ece818c.png">

### 5. 加工用キャンバスにトーンキャンバスを貼り付けます。

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649673/75b7a8a1-5a5b-2ebd-4117-c8194ece818c.png">

### 6. トーンに変換したい箇所がなくなるまで2.～5.を繰り返します。

### 7. 加工用キャンバスにあなたが求めるものが出来ています。

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649673/12a666ea-a873-d751-cbea-8805f9bb9fb5.png">

## チラ裏

http://honttoni.blog74.fc2.com/blog-entry-193.html

↑を参考にすれば処理を減らせそうな気がする。
Tips: IssueにはWhyを書こう

## この記事は何
僕はプロダクトマネジメントもやっている都合上、Issueを作成することが多いです。
Issueを作成する上で僕が普段気をつけている「Why」を書くことについて紹介します。

## Issueとはそもそも何か
Issueとは、ソフトウェア開発における問題点や改善すべき箇所を指し示すための報告書です。
これは、開発者が問題を理解し、適切な対策を立てるための重要な情報源となります。

Issueには僕はいつも以下のような情報を含めるようにしています。

- Why（今回の主題）
    - なぜこれに取り組むのか
- What
    - 具体的な仕様
- TODO
    - 実装すべき機能や修正点

## Whyをなぜ書くのか
前項のように、僕はIssueにはまずWhyを書きます。特にWhyは丁寧に書くことが多いです。
Whyを丁寧に書く理由は、「Issueに取り組む理由は不変なため」です。
開発現場ではよく起こることだと思いますが、ユーザーに提供したい機能や実装方針などは、進めていく中で変わることが多いです。
これは実際にかかる工数や外部要因などで状況が変わったなど、さまざま理由があると思います。
しかし、そのIssueに取り組む根本的な理由、つまり「Why」は基本的には変わりません。
開発とは基本的に「何かしらの目的を達成するため」に行われるものです。
その目的自体は、少なくとも取り組んでいる間は変化しないはずです。
逆にいうと、目的さえしっかりと定まっていれば、状況が変わったとしても、手段や開発方針を変えたとしても、結果的に得られる成果などは変わりません。

これはシステム開発における「不変なものに依存させていく」アプローチに通じるものだと考えています。
【SwiftUI】@Stateの動きと使い方

## まず変数(Variables)とは
変数（Variables）は、プログラムでデータや値を格納するための「箱」のようなものです。Swiftでは、`var`キーワードを使って変数を宣言します。変数には様々な種類のデータを格納することができます。

これらの変数には、それぞれの状態や遷移の情報が格納されています。

SwiftUIでの状態管理に用いる`@State`と`@Binding`を説明します。

### `@State`とは
`@State`は、SwiftUIで状態を管理するためのプロパティラッパーです。`@State`を付けた変数は、SwiftUIのビュー内でその状態を管理します。この状態が変更されると、SwiftUIは自動的にビューを再描画します。

これらのプロパティラッパーを使うことで、SwiftUIでは簡単に状態を管理し、ビュー間でデータの受け渡しや同期が行えます。

## `@State`使用例
例えば、「ボタンを押したらTextの文字を変える」というプログラムを考えてみましょう。この動作を実現するには、ボタンが押されたことを検知して、Textの内容を変更するための変数が必要です。


```swift:swift
import SwiftUI

struct ContentView: View {
    @State var str = "Hello, world!"
    
    var body: some View {
        VStack {
            Text(str)
                .padding()
            Button {
                str = "ハローワールド"
            } label: {
                Text("ボタン")
            }
        }
    }
}
```

この画面は、テキストとボタンのみが表示されるシンプルな構成です。

テキストでは、変数`str`の内容を表示しています。`str`は初めに "Hello, world!" という文字列で初期化されているため、画面には "Hello, world!" と表示されます。

ボタンをタップすると、`str`変数に "ハローワールド" という新しい文字列が代入され、これによりテキストの表示が "Hello, world!" ⇒ "ハローワールド" に変わります。

このように、テキストの内容を`str`という変数に紐づけることで、ボタンを押すことでテキストの表示を変更することが可能になります。変数`str`がなければ、このプログラムは実装できません。

## 動きを見てみよう
ボタンをタップしたことで、`str`変数に "ハローワールド" という新しい文字列が代入されてテキストの表示が "Hello, world!" ⇒ "ハローワールド" に変わります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2958142/2ff00763-d86c-9c74-224b-0a717482e12c.png)

## 変数に`@State`をつけると変わること
通常の変数とは異なる2つの主な点があります。

1. **値が変わったらViewがリロードされる:**
   `@State`が付いた変数を変更すると、それが反映される部分のViewが再描画されます。ボタンなどで`@State`変数を変更すると、Viewが再読み込みされます。もし`@State`が付いていない変数を変更しても、Viewの再描画は行われず、表示は更新されません。

2. **Structの中で値を変更できる:**
   Swift言語のルール上、通常のstruct内では変数の変更ができません。しかし、`@State`を付けることでstruct内でも変数の変更が可能になります。これにより、Viewの状態を変更するたびに再描画がトリガーされます。

まとめると、`@State`はstruct内で値を変更できるようにし、変更されるたびに再描画される修飾子であると言えます。

***
### 補足

#### var, let の違い
`var`と`let`は、Swift言語における変数宣言のためのキーワードであり、それぞれ異なる振る舞い方をします。

1. **var**
   `var`は「variable（変数）」の略であり、<font color="red">変更可能な（mutable）変数</font>を宣言する際に使用します。変数が`var`で宣言されると、その値は後で変更することができます。

   ```swift
   var myVariable = 10
   myVariable = 20  // 値の変更が可能
   ```

2. **let**
   `let`は「constant（定数）」の略であり、<font color="red">変更不可能な（immutable）定数</font>を宣言する際に使用します。定数が`let`で宣言されると、一度値を割り当てた後はその値を変更することはできません。

   ```swift
   let myConstant = 30
   myConstant = 40  // これはエラーになる（定数の再代入は不可）
   ```

主な違いは、`var`で宣言した変数は後で値を変更できる（mutable）のに対し、`let`で宣言した定数は値を変更できない（immutable）点です。一般的には、変更される可能性がある変数は`var`、一度値が設定されたら変更されない値は`let`を使うと良いです。また、Swiftでは、できるだけ定数を使って変更不要の変数を使用することが推奨されています。
いつもの? sympyの実行環境と 参考のおすすめです。

(テンプレートとして使っています。)

# web上の実行方法(SymPy Live Shellで)　
(2025/03/08追加)
・今の時代は?次のセクションの AI上のマルチモーダルかも。
　(2025/04/14編集)
　**インストール不要です。**
・ソースコードの右上に、マウスを移動するとコピーマークが発生します。
・クリックしたら、Copiedとでます。
・以下に移動します。
　https://live.sympy.org/
・下の入力欄に貼り付けて、Enterです。(実行時間約1分)
・clearコマンドがあります。
・グラフの出力は、テキストです。
・開発環境は、本ページ後半のリンクです。 
(2025/03/24追加)
・sympyのBeamは、エラーがでます。開発環境で実行しました。
・FreeCADのマクロは実行できません。

# sympyの実行環境(AI上で) 2025/01/05追加

マルチモーダル対応? Python 実行を内蔵
??? pythonだけ実行可能なようです。

https://qiita.com/daigo1130/items/37706c2a631c477c484c

https://qiita.com/aoinakanishi/items/1c4b8dfd0ed9e7e8155b

https://qiita.com/aoinakanishi/items/9b3f04bbeec24c02cf9d
　(2025/03/08追加)
# 以下旧いです。\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
・FreeCAD最新は,ver1.＊＊です。
# sympyの実行環境(SymPy Live Shellで)
1. 私の環境は,~~pycharmです。~~ vscode,chromebook です。(2024/01/18)
1. よく聞くのは、Jupyterです。
1. web上で、上記のソースを「SymPy Live shell」に、コピー貼り付けでもできました。
1. 黒背景の右上に、マウスを移動すると、コピーマークが発生します。
???　タブレット環境で、コピー貼り付けが実行できませんでした。???

https://live.sympy.org/

# sympyとFreeCAD のインストール
(2024/03/29追加) 世の中色々変わってきてます。

~~https://nochitamama.hatenablog.com/entry/installpip~~

~~https://uepon.hatenadiary.com/entry/2024/03/07/011738~~

~~https://monaledge.com/article/588~~

https://blog.jp.square-enix.com/iteng-blog/posts/00043-play-with-the-pep668/

~~$ apt install python3-pip~~
＞$ sudo apt install python3-pip

https://smootech.hatenablog.com/entry/2016/12/14/190155

＞$ pip3 install --break-system-packages --user sympy 

https://qiita.com/takiyama/items/8af11f91056a5db888b7

#### FreeCAD manual

https://www.freecad.org/manual/a-freecad-manual.pdf

https://data.engrie.be/FreeCAD/FreeCAD_for_beginners.pdf

http://ftp.labdoo.org/download/Public/manuals/manuals-ubuntu/EN/en_FreeCAD_documentation.pdf




# 参考

以下、いつもの?おすすめです。
(2023/10/08追加)

https://qiita.com/mrrclb48z/items/ce23cf0a2a32593b6091#:~:text=bbs.fc2.com/-,%E3%80%8C,-%E6%95%B0%E5%AD%A6%E8%8B%A6%E6%89%8B%E3%81%AA

https://qiita.com/mrrclb48z/items/75904cdc6e84ecef4d03#%E5%8F%82%E8%80%83wolframalpha-%E9%96%8B%E7%99%BA%E7%89%A9%E8%AA%9E


# 表示の重複かも

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

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

https://qiita.com/mrrclb48z/items/5f57eac92aaca30e85c0
イナバくんの禁煙完全マニュアル🚬

# 自己紹介

著者はイナバくん。30歳(2023年現在)。
禁煙家。(1ヶ月経ちました)
フロントエンドエンジニア。🚬

# 禁煙を始めたきっかけ

僕は10年前ぐらいからタバコを吸ってました。🚬
登山に行った時に心肺がゴミすぎてバテてしまったのが悔しくて禁煙を始めました。🚬

あと、リモートワークになってから1日2箱ぐらい吸ってたので固定費として勿体なかったんです。
月3~4万かかってました。
3~4万あったら、もっと良い家住めるし、ボクシングジムにも通えるぞ、ってことで急に金が惜しく感じました。🚬

# イナバくんの禁煙方法

## 1. IQOSだったので本体を友だちに預けました🚬

本体が無いので、物理的に吸えない、禁煙成功。

## 2. 忙しい日に禁煙を始める

暇だと吸いたくなる🚬

とりあえず2日吸わなければ中毒症状のピーク超える(たぶん)

## 3. ニコチンパッチを貼る + Dr.vapeを吸う🚬

とりあえず口からニコチンを接種することから辞めるアプローチ。🚬

ニコチンパッチを体に貼ると、貼った箇所から少量のニコチンが入るため、ヤニ切れしにくい。🚬

さらに、ニコチンレスのDr.vapeでメンソールの水蒸気を吸うことで、煙を吸う習慣はそのままでニコチンだけ減らすことができる。🚬

酒を飲んでる時や、ラーメンを食べた後や、仕事が一段落した時はどうしてもタバコが吸いたくなります。

Dr.vapeで水蒸気を吸って煙を出せば、自分の脳を騙すことができます。🚬

(心理学で「習慣の置換」、というらしいです)

僕の場合はニコチンパッチは1週間程度で外しました。

## 4. SNSで大々的に禁煙宣言をする

僕は会社のslackとプライベートのinstagramで禁煙宣言しました。🚬

仲のいい友達にはLINEで報告しました。

禁煙宣言したあげく失敗したらダサいので、失敗しにくくなる。

(3日目、1週間 など節目でもSNSで宣言すると効果あり)

## 5. 喫煙者の友達と一緒の時はDr.vapeを吸う🚬

疑似タバコミュニケーションをする。🚬

ニコチンを体から排除するだけで、煙を吸う楽しみはそのまま趣味として継続してます。(シーシャみたいな感覚)🚬

## 6. 禁煙するメリットを心に刻む

月々3万ぐらい浮く。

寿命もすごい伸びる、多分。

体力も戻る、多分。

# まとめ

結局気合です。がんばろう。
坂本金八が考える「QAエンジニアの10カ条」

### あらすじ
**坂本金八**は、とある中学校・3年B組の教師だったが今は退職し、異業種へのチャレンジとして某家電メーカーのQAチームの一員として勤め始めた。  
彼の旧友である**大森**も警察官を退職した後、大手家電量販店の営業として地域一番の成績を残した後、金八と同じメーカーに転職している。
金八は中学校の教師時代に培ってきた成功・失敗体験をQAチームの若いメンバーに共有しながら、  
未来のQAエンジニアの在り方を模索していく。  
また妻の**里美**も金八の活躍を見守りつつ、時に適切なアドバイスを送っているようだ。

以下は坂本金八の性格と、QAエンジニアへの強い思いを踏まえ、  
彼が考えた「QAエンジニアの在り方10カ条」である。

### QAエンジニアの10カ条 (坂本金八＆Bing AI考案)

1. 品質保証はプロダクト開発の最優先事項であることを忘れないこと。
2. ユーザーが求める価値を提供することが使命であることを忘れないこと。
3. 失敗から学ぶことが大切であることを忘れないこと。
4. ユーザーからのフィードバックを積極的に取り入れること。
5. テストケースをつくらず、チケット単位（プルリクエスト単位）で小さくテストすることを理想とすること。
6. 自動テストを実装していく基盤があり、QAグループメンバー同士でのフォローもしていくこと。
7. プロダクト開発チーム全員で品質に取り組むこと。
8. 他人から教えられた知識を詰め込む「お勉強」ではなく、自分で考えて学ぶことが重要であること。
9. 常に広い知識を持ち、柔軟な発想力を持つこと。
10. チームワークを大切にし、協力してプロダクト開発に取り組むこと。

### 「QAエンジニアの10カ条」をQAメンバーと話し合う

> 金八は『ユーザーへ届けたい価値になっているかどうかを検証すること』を軸としたアプローチを提案するが、QAチームリーダーは一定の理解を示しつつも冷たい反応を取る。  
> QAメンバー(A,B,C氏)も混じり、QAの在り方を真剣に議論し始める。

金八：「QAエンジニアの10か条について、皆さんの意見を聞かせてください。」
QAチームリーダー：「品質保証が最優先事項であることは間違いありません。しかし、金八さんの提案も興味深いですね。」
大森：「金八、お前も変わったな。」
金八：「失敗から学ぶことも大切です。」
A：「私たちは、ユーザーに価値を届けることが使命だと思います。」
B：「でも、ユーザーの意見に流されすぎるのも問題だと思います。」
C：「そうですね。私たちは、ユーザーが本当に必要としているものを提供することが大切だと思います。」
里美：「金八さん、あなたはいつも生徒たちに勇気を与えてきましたね。私たちのチームでも、その精神を忘れずに頑張りましょう。」
金八：「ありがとうございます。私たちは、品質保証だけでなく、ユーザーが求める価値を提供することが重要だと考えています。」
QAチームリーダー：「確かに、ユーザーが求める価値を提供することは重要ですね。しかし、品質保証も欠かせません。」
大森：「そうだな。でも、金八の提案は面白いな。」
A：「私たちは、品質保証だけでなく、ユーザーが求める価値を提供することに注力していきましょう。」
B：「でも、どうやってユーザーが求める価値を把握するかが問題ですよね？」
C：「そうですね。私たちは、ユーザーからのフィードバックを積極的に取り入れることが必要だと思います。」
里美：「それでは、私たちはどうやってフィードバックを取り入れることができますか？」
金八：「例えば、ユーザーからの問い合わせやレビューを集めて分析することが考えられますね。」
QAチームリーダー：「それは良いアイデアですね。私たちは、今後そのような取り組みを進めていくことにしましょう。」
A：「私たちは、ユーザーからのフィードバックを積極的に取り入れることで、より良いプロダクトを開発していくことができますね！」
B：「でも、フィードバックを取り入れるだけでは不十分ですよね？」
C：「そうですね。私たちは、自分たちで考えて改善策を提案することも大切だと思います！」
里美：「それでは、QAエンジニアの10か条に沿ってプロダクト開発に取り組んでいきましょう！」

#### 感想
・なぜか妻の里美もQAチームの議論に参加している、
・会話が堂々巡りだったり表面的で面白くない
このあたりはプロンプトに問題あると思うのでそのうちアップデートします。
Salesforce B2B/D2C Commerce サイトのマルチ言語対応 - 事前準備編

※ これから記載する事項は、私が所属する会社とは一切関係のない事柄です。

サイトをマルチ言語にする方法を２部（事前準備編・[翻訳編](https://qiita.com/syunyama/items/02294f2b3730578dca3c)）に分けて紹介します。
今回はまず事前準備の方法について紹介したいと思います。


## 設定内容

サイトの表示とカテゴリと商品の名称や説明文を日本語と英語で切り替えられるようにしたいと思います。方法の詳細はヘルプの「[グローバルな販売](https://help.salesforce.com/s/articleView?id=sf.comm_language_currency.htm&type=5)」をご確認ください。

:::note warn
※ 今回は通貨や納入先をマルチロケールにする設定は省きますので、ご了承ください。
:::



## 事前設定

### 1. ストアページレイアウトへの言語サポートの追加

**_設定 > オブジェクトマネジャー_**  からストアオブジェクトのページレイアウトに「使用言語」「言語のデフォルト値」項目を追加します。必要であれば「デフォルトの国(納入先)」「サポートされる国(納入先)」「サポートされる通貨」「デフォルトの通貨」も追加しましょう。


### 2.  データ翻訳の有効化

**_設定 > 会社の設定 > 組織情報_**  から **[編集]** をクリックし、**[データ翻訳を有効化]** にチェックを入れ保存します。すると **_設定 > トランスレーションワークベンチ >データ翻訳設定_** に翻訳できるオブジェクトの一覧が表示されます。


### 3. トランスレーションワークベンチを有効にする

**_設定 > トランスレーションワークベンチ > 翻訳言語設定_** に遷移し **[有功化]** ボタンをクリックします。すると使用言語リストが表示されるので **[追加]** ボタンで日本語と英語を設定します。その際翻訳するユーザも同時に設定しましょう。


### 4. バイヤーグループページレイアウトへの言語サポートの追加

**_設定 > オブジェクトマネジャー_**  からバイヤーグループオブジェクトのページレイアウトに **「ロケール」** を関連リストに追加しましょう。


### 5. ストアの設定

ストアのホームページから、 **[管理]** タイルをクリックします。 **[一般設定]** をクリックします。
使用言語の鉛筆マークから修正し、英語と日本語を選択し、さらに言語のデフォルトも設定します。
![スクリーンショット 2023-10-04 18.07.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/a64a34f8-3fb7-a925-9cac-3c195380e19d.png)



### 6. マーケットの設定

ストアのホームページから、 **[管理]** タイルをクリックします。 **[マーケット]** をクリックします。 **「マーケットを作成」** をクリックして任意の名前を設定します。設定が完了するとリストに設定した名前が表示されるのでクリックします。
設定したマーケットはバイヤーグループとして表示されます。関連リストのロケールから利用する言語（ロケール）を割り当てましょう。
![スクリーンショット 2023-10-04 18.12.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/47d45faa-aa8d-d587-5ff3-9a954bd6ae72.png)



### 7. Experience Builder の設定

ストアのホームページから、 **[エクスペリエンスビルダー]** タイルをクリックし、エクスペリエンスビルダーを表示します。さらに左ナビより設定マークをクリックし、 **[言語]** を選択します。 **[言語を編集]** ボタンから利用する言語を選択し、保存します。
![スクリーンショット 2023-10-04 18.36.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/a3ec744d-f6f3-3228-5cbb-49b5c9672457.png)


すると、エクスペリエンスビルダーの右上に地球マークが表示され設定する言語を切り替えられるようになっていることを確認できます。
![スクリーンショット 2023-10-04 18.37.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2110894/9280bb0e-6ad2-bfff-2352-417914d46d74.png)
メールアドレスとXSS

---
# はじめに

ずっと前に見つけたメールアドレスのXSSの話。
少し珍しいので今更ながら記録に残しておくけど、結論としては、ちゃんと念のためにHTMLエンコードしていれば脆弱性診断で指摘されることはなかった。という内容です。

---
# Webアプリケーションの仕組み

ユーザ登録機能の最初のメールアドレス仮登録画面だったかな...(記憶が曖昧だけど...)

1. 入力データとして、メールアドレスを取得
2. メールアドレスを元にAddressクラスのインスタンスを生成
3. XSSを発動するようなメールアドレスとして不適切な書式の場合は、Addressクラス生成に失敗して、Exceptionが発生する
4. エラーが発生した場合は、単純な「エラーです」のみ表示(入力データは使われない)
5. 正常な場合は、そのままメールアドレス宛にメールを送信して、終了。
6. 最後に入力データ(メールアドレス)を画面上に(HTMLエンコードせずに)表示して終了

<B>最後にHTMLエンコードしていない</b>のは、XSSを発動するようなメールアドレスなら、<b>途中の例外発生で処理が中断されるので、必要ない</b>ということ。

![eMailXSS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182822/9b467968-426d-1ee4-3828-1374ceda0401.png)

---
# 突破方法

ということで

```
"コメント" <メールアドレス>
```

というメールアドレスの適切な書式を使って突破できました。

具体的には

```
"
XSS
" <メールアドレス>
```

な感じ

---
# 結論

文頭でも記述したけど、<b>念のためにHTMLエンコードすることはとても重要</b>ということ。

---
# 以上
.vueのインポートでCannot find module or its corresponding type declarations.

# 目的
.vueのインポートでCannot find module or its corresponding type declarations.
になるので回避したいです。

# @エイリアスを疑う

@エイリアスの問題ではないです。
tsconfigでは正しく設定されていました。
```json:tsconfig
{
"baseUrl": ".",
"paths": {
      "~/*": [
        "./*"
      ],
      "@/*": [
        "./*"
      ]
    },}
```

# shims-vue.d.tsを宣言
[shimsとは](https://qiita.com/ironsand/items/4f0342f5914a9ae99b0e)
特定の非標準のコンテンツやモジュールに対して型情報を"埋める"役割を果たします。

こちらより、以下の型定義ファイルを宣言することで解決しました。
[Cannot import from a typescript Vue component into another typescript Vue component](https://github.com/vuejs/vue/issues/5298#issuecomment-453036640)
```shims-vue.d.ts
declare module "*.vue" {
  import Vue from "vue";
  export default Vue;
}
```

# 参考
- [VSCode showing "cannot find module" TS error for .vue import while compiling doesn't](https://stackoverflow.com/questions/54839057/vscode-showing-cannot-find-module-ts-error-for-vue-import-while-compiling-doe)
- [VSCode + TypeScript の環境構築で "モジュール 〜.vue が見つかりません" とエラーが出る時の対処法](https://qiita.com/sygnas/items/40b3a7cf79d47eab7616)
Keycloakをdockerで動かしてレルムをエキスポートする


Dockerで開発用にレルム/ユーザー/クライアントを登録して、それをエキスポートする方法を備忘録的に書いておきます。

## データ登録

開発用にレルム/ユーザー/クライアントを登録します。

空のフォルダに移動して Docker で Keycloak をstart-devで起動します。
このときカレントディレクトリを /opt/keycloak/data にマウントしておきます。
このなかに既定のデータベースであるh2のデータフォルダができます。

あとは普通に <http://localhost:8080> にアクセスして、adminコンソールから、レルムの作成、クライアントやユーザーを登録してください。
今回はレルムはmainという名前にします。

```sh
docker run --rm -v .:/opt/keycloak/data -p 8080:8080 \
  -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=P@ssw0rd \
  quay.io/keycloak/keycloak:latest start-dev
```

終わったら、<kbd><kbd>C</kbd>-<kbd>c</kbd></kbd>で終了します。

## エキスポート

エキスポートは以下のコマンドで実行します。

```sh
docker run --rm -v .:/opt/keycloak/data quay.io/keycloak/keycloak:latest \
  export --dir /opt/keycloak/data/export --users realm_file --realm main
```

これで `export` ディレクトリに `main-realm.json` が出来上がります。

## インポート

起動時にインポートするには、/opt/keycloak/data/import に、この`main-realm.json`を置いておいて、起動時の引数に--import-realmをつけて起動することで自動的にインポートされます。

ボリュームのマウント位置が変わっているので気を付けてください。

```
docker run --rm -v export:/opt/keycloak/data/import -p 8080:8080 \
  -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=P@ssw0rd \
  quay.io/keycloak/keycloak:latest start-dev --import-realm
```

これで起動時に読み込めます。簡単ですね。

注意点としては

1. master-realm.jsonは読み込めない。既にレルムが存在する場合にはスキップ。
2. ユーザーが多いときは --usersのオプションを変更する 

詳しくは[Importing and Exporting Realms](https://www.keycloak.org/server/importExport)を参照してください。
【Gatby x TypeScript】pageコンポーネントで受け取るgraphqlからのデータの型定義


## 結論
**PagePropsと型ジェネリクスを使う。**

参照：https://www.gatsbyjs.com/blog/gatsby-5-typescript-and-generated-graphql-types-a-walkthrough/

### サンプルコード
```typescript
import * as React from "react"
import ComponentX from "./component-x.tsx"
import type { HeadFC, PageProps } from "gatsby"

const IndexPage: React.FC<PageProps> = ({data}) => {
  return (
    <main>
        <h1>{data.siteMetadata.title}</h1>
        <ComponentX data={data} />
    </main>
  )
}
こんな感じで、

export default IndexPage

export const Head: HeadFC = () => <title>Home Page</title>

export const query = graphql`
    query {
      site {
        siteMetadata {
          title
          siteUrl
          description
        }
      }
    }
`
```
こんな感じで、ページコンポーネントでdataを受け取り、なんやかんやしたり、他のコンポーネントに渡したりできます。

### graphqlの型も定義する場合
型ジェネリクスを使ってできます。（[参照](https://www.gatsbyjs.com/blog/how-to-use-gatsby-graphql-type-generation/)）
```typescript
import * as React from "react"
import { graphql, PageProps } from "gatsby"
 
const IndexPage = ({ data }: PageProps<Queries.IndexPageQuery>) => {
 return (
   <main>
     <p>Site title: {data.site?.siteMetadata.title}</p>
   </main>
 )
}
 
export default IndexPage
 
export const query = graphql`
 query IndexPage {
   site {
     siteMetadata {
       title
     }
   }
 }
```
上記の参照ページに記載されているセットアップ（tsconfig.jsonやgatsby-config.jsなどの記述）を行えば、Queriesというグローバル名前空間が使えるようになります。

そこから```${クエリ名}Query```という型が取得できるので、それを使えばあら不思議。graphql内で指定したものの型が生成されます。（```${クエリ名}```には、graphql内で指定したクエリ名、上記だとIndexPageが入ります）

上記のサンプルコードで言うと
```{ readonly site: { readonly siteMetadata: { readonly title: string } } | null };```
こんな型がdata引数に適用されています。

## まとめ
自分で型定義せずに、めちゃくちゃ簡単に型が使える。

gatsbyありがたやです。
Laravelのテストで .env.testing に設定した環境変数の値が反映されない

# 1行結論

PHPUnit の TestCase ではなく、Laravel が用意している TestCase を使う

```php
<?php

namespace Tests\Unit\Models;

// 変更
// use PHPUnit\Framework\TestCase;
use Tests\TestCase;

class AirportTest extends TestCase
{
```

Tests/TestCase 側に APP_ENV の値を元に .env を切り替える処理が記述されているようです
分かってみれば当然の話でしたね…通常 PHPUnit の環境変数は phpunit.xml で設定するようになっているんですから

## もう1点

Tests\TestCase の setUp() が動いてないと、同様の現状が発生します。
setUp() メソッドを記述する際は、忘れずに記述しましょう。

```php
public function setUp(): void
{
    // これが必要
    parent::setUp();
}
```


# まとめ

ただ Tests\TestCase を継承しているテストは PHPUnit\Framework\TestCase を継承しているテストと比べて動作がちょっと重くなるので、ENV を使うテストは Tests\TestCase、使うことのないテストは PHPUnit\Framework\TestCase と切り替えた方が良いですね
Blazor WebAssemblyでAPIから取得した値を設定しても画面に反映されない場合

# 実装
StateHasChanged() 関数を呼び出してUIを更新してやることで表示されます。

```html
<p class="place_p">@officeName</p>
```

```C#
private string? bookName = "";
private async void GetBookName(string Code)
{
    // API経由でデータ取得
    var list = await Http.GetFromJsonAsync<List<Book>>($"api/books/all/first?id={Code}");
    
    if(list != null && list.Count > 0)
    {
        // ↓ここでは「手を伸ばせ、そしてコマンドを入力しろ」が取得できるとする
        bookName = list[0].officeName == null ? "" : list[0].officeName ;
        // ↓UIの手動更新をトリガーすることで画面に表示される
        StateHasChanged();
    }
}
```
VS-Code で Source control に Repositoryが表示されなくなった



# Source ControlにGitリポジトリが表示されない

Source Controlで間違えて `Close repository` を押してしまい、Source Controlに表示されなくなってしまった！

超大したこと無い内容ですが、地味にハマったので備忘録として。


## 結論　

`Ctrl+Shift+P` で コマンドパレットを開き、 ` Reopen Closed Repositories` を入力したら、Closeしてしまったリポジトリを選択でき、追加できる。



### 詳細

間違って押すと、ソースコントロール画面からリポジトリパネルが消えてしまう。

１つのリポジトリしかないフォルダを開いている場合は上記の `Reopen Closed Repositories` がパネル上に表示されてUI上から追加できる。

ただ、複数リポジトリを開いているような環境だと、1つ消してもUI上には表示されずメニューバー等にも無いため、戻せずに焦ってしまった。

なお、VS-Codeを開き直してもClose状態はキープされて復活しない模様。
【Mac版】fish + anyenv のセットアップ

# はじめに
macOSにおける「fish + anyenv」のセットアップ手順をまとめます。

プロセッサ：Apple M2
OS: macOS Sonoma 14.0

# 概要
- セットアップ
    - Homebrew
    - fish
    - anyenv

# セットアップ

## Homebrew

未インストールの方は下記手順でHomebrewをインストールします。

- [Homebrew 公式](https://brew.sh/)
- 下記スクリプトをターミナルで実行

```sh
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```

https://qiita.com/zaburo/items/29fe23c1ceb6056109fd

https://qiita.com/___fff_/items/17655df4e80ebadd8fc3

## fish

### インストール

Homebrewがインストールできたら、fishをインストールします。

```sh
$ brew install fish
```

### デフォルトシェルに設定

パスの確認

```sh
$ which fish
/opt/homebrew/bin/fish
```

:::note warn
M1/M2チップMac と IntelチップMac でパスが異なるため注意してください。
M1/M2：/opt/homebrew/bin/fish
Intel：/usr/local/bin/fish
:::

/etc/shellsに確認したfishのパスを追加

```sh
$ sudo vi /etc/shells
```

```sh
# List of acceptable shells for chpass(1).
# Ftpd will not allow users to connect who are not using
# one of these shells.

/bin/bash
/bin/csh
~~~~~~~~~~~~
/opt/homebrew/bin/fish
```

デフォルトシェルの変更

```sh
$ chsh -s /opt/homebrew/bin/fish
```

※brew経由で fish をインストールした場合に不具合が起こる可能性があるため、その場合は fish の公式サイトから直接ダウンロード＋インストールします。

https://zenn.dev/datchlive/articles/081a8529aa0395

## anyenv

### インストール

```sh
brew install anyenv
```

### 初期化

```sh
anyenv init
```

### config 修正

```sh
echo 'status --is-interactive; and source (anyenv init -|psub)' >> ~/.config/fish/config.fish
```

### fish リロード

```sh
exec $SHELL -l
```

### install manifestsの初期化

```sh
anyenv install --init
```

ここまでできたら、好きなツールをインストールできます。

```sh
// nodenvのインストール
anyenv install nodenv
```

# 最後に
バージョン管理ツールはそのうち asdf に乗り換えたいと思ってます。
最後まで読んでいただきありがとうございました。

参考記事

https://www.janx2.info/anyenv-fish/
ASP.NETにおけるレシートOCR開発-折れ曲がりによって二分されたレシートの補正-

# レシート上の要素に対する領域ごとの角度補正

## 前回までの概要
レシートの要素の行の判別を行うために、座標を利用して同じ行のグループ化をおこないました。
その際にレシートが斜めになっている場合を考慮して、要素の傾きによって全体を回転させることで、
より多くの要素を水平にし、行の判別をより正確にできました。
前回ページはこちらから確認ください！

https://qiita.com/y-okada1412/items/af6070f21e338d65588a

## 今回の背景
現実問題として、レシートは保管が難しく撮影し、OCRに読み込ませる際には、
折れ曲がっている場合があります。これを正確に読み取り,行の判別を行うのはかなり難しいです。
今回はその折れ線によって分割された領域ごとに、別の回転や移動を適応することで、
より精度の高い行のグループ化が実現できるかどうかを検討します。

## 今回与えられたタスクと課題
レシートの要素の中に、レシートの左端から右端までまたがるような、大きい要素に注目しました。
レシートが縦に折れ曲がっているとき、この要素も折れ曲がっている可能性が高いと考えられます。
レシートの折れ曲がりによって生まれる、y座標の変化をある程度検出するために、
この大きい要素を利用します。今回はレシートに折れ曲がりが、
一つあることを前提として検証しました。一つの大きい要素を、
折れ曲がりの右側と左側で別に回転させ、回転後の差を得ることで、
全体の折れ曲がりによる差分を取得したいと考えました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3566779/7fac9d68-f491-defd-dbfb-4d5860dde5f3.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3566779/3dc61e04-b72f-84ec-7089-988a65172c0c.png "図1")

## 大きな要素を左右別々に回転させる

前回要素全体の平均傾きを利用して、傾きを0に近づけるというアプローチで回転させましたが、
それでは左右を別々で回転することはできません。また、全体を同時に回転させていました。
今回はレシート内で幅が一番大きい要素に対し、縦の辺を垂直にするという
アプローチで回転させることで、左右を別々に回転させることを考えました。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3566779/6e5cd5f1-4296-f1be-e2b9-890a9c215502.png)

要素の四頂点の座標を$ (𝑥_1, 𝑦_1)～(𝑥_4, 𝑦_4) $として回転角を求めていきます。まず、右の要素の傾き`rightAngle`を求めます。
$$ rightAngle = \frac{y_3-y_2}{x_3-x_2} $$

次に回転角を求めます。回転角を𝜃、要素の中心座標を$ (𝐶_𝑥, 𝐶_𝑦) $とし、回転させたい座標を
$ (𝑥, 𝑦) $とすると、三角関数を用いた計算方法は次のようになります。

$$
\theta = 90-tan^{-1}(angle) 
$$
$$ 
\hat{y} = C_x + (x-C_x) * \cos{\theta} - (y-C_y) * \sin{\theta} 
$$
$$
\hat{y} = C_y + (x-C_x) * \sin{\theta} + (y-C_y) * \cos{\theta} 
$$

左の要素の傾き`leftAngle`は`rightAngle`を次のようにして三角関数を適応すればよいだけです。

$$
leftAngle = \frac{y_4-y_1}{x_4-x_1}
$$

ここまでが、傾きを垂直、つまり 90 度に近づけるための要素の回転方法です。

次に左右の要素の y 座標の差を取得します。右の縦の辺を基準に要素を回転したものを
`leftBoundingbox`、左を基準に回転したものを`rightBoundingbox`とし、中間座標を求めます。
左の中間座標は`leftBoundingbox`の$ ((𝑥_1 + 𝑥_4)/2, (𝑦_1 + 𝑦_4)/2) $、
右の中間座標は`rightBoundingbox`の$ ((𝑥_2 + 𝑥_3)/2, (𝑦_2 + 𝑦_3)/2) $で求められるので、
これより`y`座標の差`diff`は$ (𝑦_1 + 𝑦_4)/2 − (𝑦_2 + 𝑦_3)/2 $となります。

## 全体の補正
先ほど求めた回転角とy座標の差を、右寄りの要素と左寄りの要素に対して、
それぞれ適応していきたいと思います。初めに、その右寄りの要素とするか、
左寄りとするかの条件付けを行っていきます。

まず、すべての要素の横幅を取得し、横幅が一番大きい要素の`60%`以下かつ、
左端のx座標が一番大きい要素の横幅の`+-20%`以内であれば左寄りの要素とします。
右寄りの要素も同様の条件で右端の座標で比較します。
ただし、ここでの閾値の%の値は必要に応じて変更し、最適な値を模索していきます。

これにより振り分けられた右寄りの要素と、左寄りの要素をそれぞれ
`rightAngle`と`leftAngle`で回転し、右寄りの要素のy座標に`diff`を足します。
そうすることで回転によって生じたy座標のずれが軽減されることを期待しています。

## 最後に
今回まとめた方法の具体的な実装は、次回以降にまとめていく予定です。
また、これらを利用したOCRは、LINEからどなたでも無料でご利用いただけますので、
ぜひ試してください！

https://receiptroller.com/ja


また、OCRのでも体験がこちらのページからできます！

https://ocr.receiptroller.com/read-receipt
【ChatGPT無】「水平思考で考えて」を使ってみた。


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

　今回は、X-Twitterでの記事から「水平思考で考えて」を使ってみます。

:::note info
本記事は、ChatGPT（無料版）で
行なっております。GPT4での確認
はできておりません。あしからず。
:::

　今回の記事は、
　　X-Twitter上にて
　　　アップされたツイート
[ChatGPTに「水平思考で考えて」と付け加えると、より創造的で独自性の高いアイデアになるよ。](https://twitter.com/promptia_jp/status/1684044516175773699?t=wBeONU2OSD5SVqWZcgVEsA&s=19)
　　　　を読んでのものです。
***
　「水平思考」とは？

　ウィキペディアから
　　引用します。
>水平思考（すいへいしこう、英：Lateral thinking）は、問題解決のために既成の理論や概念にとらわれずアイデアを生み出す方法である。エドワード・デボノが1967年頃に提唱した。

　いいですねぇ。

　さっそく、
　　Promptに
　　　組み込んでみましょう。

　なんですけどね、
　　どんなPromptに
　　　組み込みましょうか……

　すごく考えましたw
　　これにします。

```Text:人間についてPrompt
人間について教えてください。
箇条書き（説明不要）でお願いします。
```
　このPromptの
　　先頭に
　　　「水平思考で考えてください」
　　　　を追加したものとの
　　　　　比較を続けて出します。

　まずは、そのまま。
***
***ChatGPT***
もちろん、人間についての箇条書きです。

- 哺乳類
- 脊椎動物
- 有意識
- 社会的
- 文化を持つ
- 言語能力
- 抽象思考
- 道徳規範
- 感情と感情表現
- 学習能力
- 環境への適応能力
- 技術の発展
- 自己意識
***
　次に、水平思考を入れたもの。
***
***ChatGPT***

もちろん、水平思考で人間についての情報を以下に示します：

- 有限の生命体
- 意識と知覚
- 社会的生物
- 文化の創造者
- 抽象的思考能力
- 感情と情緒
- 学習と進化
- 自己認識
- 道徳と倫理
- 技術の発展
- 生態系への影響
- 哲学的な考察
***
　どうでしょうか？

　箇条書きを
　　指定したためか、
　　　これといって、
　　　　目立った違いが
　　　　　見られません。
***
　ほかにも、
　　確かめましたが、
　　　ちょっと長くなるので、
　　　　控えますね。

　結論としては、
　　使わないよりは、
　　　いいのかな、という程度に
　　　　感じました。

　ただ、
　　これは無料版では
　　　変化が少なく、
　　　　ほかの有料版モデルならば
　　　　　変化が大きい可能性も
　　　　　　あります。

　有料版を
　　お使いのみなさんで、
　　　試してみてください。

　今回は、ここまで。
Pythonのプログラム分割について【覚書】

Pythonのソースコードを分割する一般的な方法
## モジュールとして分割する！
Pythonでは、関数やクラスを含むコードをモジュールとして分割することができます。モジュールは.pyファイルとして保存され、他のPythonファイルからインポートして使用できます。

**例**：
モジュールを作成して、それを他のPythonファイルからインポートすることができます。

**my_module.py**

```Python
def hello():
    print("Hello, World!")
```
別のPythonファイルから「import」で呼び出す。

**main.py**
```Python
import my_module

my_module.hello()
```

## 関数に分割する！
コードを関数に分割することで、コードを論理的なブロックに分けて再利用性を高めることができます。

**例**：
```Python
def calculate_square_area(side_length):
    return side_length * side_length

def calculate_circle_area(radius):
    return 3.14159 * radius * radius

side_length = 5
radius = 2

square_area = calculate_square_area(side_length)
circle_area = calculate_circle_area(radius)
```
## クラスに分割する
クラスを使用してコードをオブジェクト指向的に分割することができます。クラスはデータとメソッドを組み合わせてカプセル化するのに役立ちます。

**例**：
```Python
class Rectangle:
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def calculate_area(self):
        return self.width * self.height

class Circle:
    def __init__(self, radius):
        self.radius = radius

    def calculate_area(self):
        return 3.14159 * self.radius * self.radius

rectangle = Rectangle(5, 4)
circle = Circle(2)

rectangle_area = rectangle.calculate_area()
circle_area = circle.calculate_area()
```
Pythonのコードを論理的なブロックに分割し、保守性を高め、再利用性を向上させることができます。どの方法が最適かは、プロジェクトの要件とコードの性質によります。
Mac の日付設定が遅れた時の対処

日付がずれていると TLS のコネクション確立に失敗するらしく、デスクトップアプリ含めてなんもできなくなる。  
再起動も意味をなさなかった。

以下のコマンドで NTP サーバに接続させシステムの時計を設定する。

```
sudo sntp -sS time.asia.apple.com
```

時計がズレた原因はしばらく当該 Mac 端末がバッテリー切れしていたことだと思われる。  
が、修正されなかった理由は不明。
サーバーサイドのデザインパターン[Decorator Patternの章]

# はじめに
Decorator Patternは、既存のオブジェクトに新しい機能を動的に追加するデザインパターンです。Pythonでは特に、関数やクラスのデコレータとしての用途で頻繁に使用されています。
# Decorator Patternの基本
1. 定義と概要
Decorator Patternは、コアとなるオブジェクトに追加の機能や責務を動的に付加するためのデザインパターンです。このパターンを使用することで、既存のコードを変更せずに、新しい機能を追加できます。

2. メリットとデメリット
メリット
既存のコードを変更しないで拡張が可能。
一般的な継承より柔軟性がある。
機能を組み合わせることが容易。
デメリット
多くの小さなオブジェクトを使うことで、全体のシステムが複雑になる可能性がある。
# 実装例
以下は、コーヒーの注文を想定したシンプルなDecorator Patternの実装例です。

```python
# コアとなるコンポーネント
class Coffee:
    def cost(self):
        return 5

# Decorator
class MilkDecorator:
    def __init__(self, coffee):
        self._coffee = coffee

    def cost(self):
        return self._coffee.cost() + 2

class SugarDecorator:
    def __init__(self, coffee):
        self._coffee = coffee

    def cost(self):
        return self._coffee.cost() + 1

# 使用例
coffee = Coffee()
print(coffee.cost())  # 5

milk_coffee = MilkDecorator(coffee)
print(milk_coffee.cost())  # 7

sugar_milk_coffee = SugarDecorator(milk_coffee)
print(sugar_milk_coffee.cost())  # 8
```
### PythonにおけるDecorator Pattern
 PythonのDecoratorについて
Pythonのデコレータは、関数やメソッド、クラスに動的に機能を追加する仕組みです。@シンボルを使って、関数の上に記述します。

#### PythonでのDecorator Patternの実装例
```python
def my_decorator(func):
    def wrapper():
        print("Something is happening before the function is called.")
        func()
        print("Something is happening after the function is called.")
    return wrapper

@my_decorator
def say_hello():
    print("Hello!")

say_hello()
# Something is happening before the function is called.
# Hello!
# Something is happening after the function is called.
```
# ユースケース
GUIコンポーネント: 既存のウィジェットに新しい振る舞いやスタイルを追加する。
Webミドルウェア: HTTPリクエストやレスポンスに対する前処理や後処理を実装する。
プラグインアーキテクチャ: コアシステムに新しい機能や特性を動的に追加する。

# アンチパターン
1. 過度な装飾（Over-Decoration）
問題: 一つのオブジェクトに対して多数のデコレータを組み合わせて使用することで、コードが複雑になり、デバッグやメンテナンスが困難になる。
解決策: 必要最低限のデコレータのみを適用し、冗長な装飾を避ける。

2. 不明瞭なデコレータの順序
問題: デコレータの適用順序が文書化されていない、または直感的でないため、不意の挙動やバグを引き起こす。
解決策: デコレータの適用順序を明確に文書化し、また直感的な命名や構造を持たせる。

3. デコレータの過度な汎用性
問題: あらゆるシチュエーションに対応するようにデコレータを設計することで、実際の使用ケースでは不要な複雑さやオーバーヘッドが増加する。
解決策: デコレータを特定のタスクや問題に特化させ、不要な機能を省略する。

4. 再利用せずに新たなデコレータの作成
問題: 既存のデコレータを再利用または拡張するのではなく、似たような機能のために新しいデコレータを繰り返し作成する。
解決策: 既存のデコレータの再利用や、必要に応じて既存のデコレータを拡張する。
【Oracle Cloud Infrastructure, OCI】インスタンス作成時にIPv6アドレスを割り当てる

# 要旨
2021年4月、OCIの全リージョンでIPv6が利用可能になった当時 [[1]](https://docs.oracle.com/en-us/iaas/releasenotes/changes/5b5cc0a0-cc06-4d25-bde8-5bcb8cbe94b6/)、インスタンス作成後、VNICにIPv6アドレスを割り当てる設定を別途行う必要があった [[2]](https://qiita.com/500InternalServerError/items/be14d19a8a51601346cb)。2023年9月のアップデートでは、インスタンス作成時にIPv6アドレスを与えることが可能になった。

# 手順
1. IPv6に対応したVCN (Virtual Cloud Network)、およびサブネットを作成した [[2]](https://qiita.com/500InternalServerError/items/be14d19a8a51601346cb)
    
1. インスタンス作成ウィザードのプライマリVNICの設定画面で「サブネット接頭辞からIPv6アドレスを割り当てます」にチェックを付けて（下図1枚目）、Oracle Linux 8イメージでインスタンスを作成した（下図2枚目; コンソール画面でIPv6アドレスが割り当たっていることが確認できる）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844955/bba07fb8-0197-2d7b-e7e4-7bc2199b85c3.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844955/6c0c71dc-f154-8e0f-ff5d-d7feec7dd673.png)
 
1. ipコマンドでOS側からインターフェースの設定を確認した（コードブロック内の★）。OSのインターフェースはDHCPv6で自動設定されるが、dhclientコマンドを実行し即時割り当ても可能 [[3]](https://docs.oracle.com/ja-jp/iaas/Content/Network/Concepts/ipv6.htm)
```bash: bash
[opc@vm-wait4ipv6 ~]$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000

（中略）

2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 qdisc pfifo_fast state UP group default qlen 1000
    link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
    altname enp0s3
    inet 10.0.0.xx/24 brd 10.0.0.255 scope global dynamic ens3
       valid_lft 86391sec preferred_lft 86391sec
    ★inet6 xxxx:xxxx:xxxx::xxxx:xxxx:f56e/128 scope global dynamic noprefixroute
       valid_lft 89992sec preferred_lft 86392sec
    inet6 fe80:xxxx::xxxx:xxxx/64 scope link
       valid_lft forever preferred_lft forever

```
【Power Automate】疑問点を自動でまとめよう！

# はじめに
今回は、プロジェクトで実際に役立つフローについて紹介します。
業務をする上で必ずと言ってよいほど発生する疑問点に対するフローとなります。
それらの疑問点を1か所にまとめておくことにより、疑問点やその解決方法を共有しやすく、
同じ課題の発生を防ぐ目的があります。
（実際にPJで運用中です！）

# 取り扱うフロー
「Formsで自分の疑問点やその解決策を入力し送信するだけで、Excelのテーブルに随時追加できる」というフローです。
しかし、Excelに内容が追加された際、誰も確認しなければあまり実用的ではありません。
そこで、最後のアクションとして「Teamsのチャネルに疑問点が追加された旨のメッセージを送信する」というものを追加することで、より可視化でき、効率の良い運用を図ることができます。

# フローの全体像
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3561523/212afd57-5dde-46cf-dbc6-240a93346cb6.png)

# 事前に用意しておくもの
・疑問点等を記入するForms
・Formsの回答を転記するためのExcel

※PJで共有するのであれば、Teamsのファイル配下においておくと運用しやすい。

# フローの詳細
## 1.新しい応答が送信されるとき（Forms）
このフローのトリガーとなります。
事前に作成しておいたFormsを指定します。
この時、Formsが一覧にない場合は、FormsのIDをコピペすることも可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3561523/658a250f-64cd-1d0f-0f7c-5106e9b8962e.png)

## 2.応答の詳細を取得する（Forms）
1で設定したFormsの回答の内容を全て取得します。
（応答IDの枠にカーソルを合わせると選択肢が右側に表示されるので、そこから「応答ID」を選ぶだけで設定できます！）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3561523/0807f059-7a2b-6129-b4d4-8426b457133b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3561523/a9ddf101-d4e9-c9b6-1a12-ef6c3d34961b.png)

## 3.表に行を追加（Excel）
Formsで入力した内容をExcelに転記します。
自分で格納したExcelの場所を上から順番に入力し、事前に作成したExcelのテーブルとFormsの項目を紐づけます。
この時、テーブルの項目をFormsの項目と同様にしておくと、
項目同士の紐づけの際に混乱が減るのでおすすめです。
![PLキャプチャ_Excel.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3561523/74541f38-09d9-f6b6-bbff-32ff7be62be9.png)

## 4.チャネル内のメッセージで応答します（Teams）
Excelに疑問点とその解決策が追加されたことをTeamsに通知します。
このフローを運用したいチームのチャット、またはチャネル内のスレッドを選択すると、
設定したメッセージとともに通知を送ることができます。
今回私が設定した通知方法は、チームのチャネル内にあらかじめ用意しておいたスレッドに対し、
返信の形で通知を送るというものになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3561523/fab21df9-6135-708c-966b-a80f4d72ba6c.png)

# おわりに
チーム内では発生する疑問点をわかりやすく共有することができ、業務の効率化を図ることができるフローとなっております。
作成も簡単なフローなので是非活用してみてください。
お手軽Redoc入門

# 結論
下記のようにHTMLとAPI仕様yamlを用意し、ローカルサーバーを立ち上げればよい。
ローカルサーバーを立ち上げるのがポイントで、そうしないと、エラーになる。
理由はわからない。（ご存じの方教えてください...）

``` index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Redoc Sample</title>
</head>
<body>
    <redoc spec-url='./swagger.yaml'></redoc>
    <script src="https://cdn.redoc.ly/redoc/latest/bundles/redoc.standalone.js"> </script>
</body>
</html>
```

``` swagger.yaml
この中身は下記取得し、書き換えてください。
https://petstore.swagger.io/v2/swagger.yaml

```

``` shell:server立ち上げ
>python -m http.server -8000
## ブラウザでlocalhost:8000 にアクセスできるようになる
```

## 経緯とか
API仕様書をエクセルで管理すると更新情報の記載だったり、差分の確認がそもそも困難だったりといろんなデメリットがあります。
UIがそこそこなのはメリットですが。

とりあえずお試しで使ってみてます。

## 参考記事
https://hirabay.net/?p=108
https://techblog.asia-quest.jp/202207/api-documentation-has-been-redesigned-with-redoc
https://qiita.com/tuken24/items/fc002cd373bbcc9b726c

pythonでローカルサーバー
https://qiita.com/okhrn/items/4d3c74563154f191ba16

ローカルのyamlが表示できない問題の話題（ローカルサーバーで解決）
https://github.com/Redocly/redoc/issues/1222
https://stackoverflow.com/questions/75300068/redoc-cannot-display-a-local-openapi-definition-file

公式の説明 ローカルサーバーが必要な記述、、、ある？
https://redocly.com/docs/redoc/deployment/html/
Laravelでページネーション時に起きる変なところ対策

Laravel使ってページネーションした時、< や > の文字が大きすぎる件と、検索条件が引き継がれない場合、下記で置き換えると直る。$valiablesは環境に合わせて変更してね。

```
{{$valiables->appends(request()->query())->links('pagination::bootstrap-4')}}
```
VSCodeでPHPをローカル実行してみた

ひょんなことからphpコードをいただいたのだが、手元でパッと確認するにはどうしたら良いのかな、と思って調べた。（いつもはDocker使っちゃってる）
なんやアプリダウンロードせぇだの出てきたんだが…なんと、VSCodeの拡張機能で簡単にローカルサーバーを立ち上げられるらしい！
それが一番簡単じゃん！やってみよう！

## 必要なもの
- VSCode
- 動かしたいphpのソース

## 手順
1. VSCodeで`PHP Server`という拡張機能を探してインストールする
2. `index.php`など実行したいファイルを開き、ウィンドウ右上にある青いボタンを押す
3. ブラウザで実行されたphpファイルが開かれる！ 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490854/b6d344ae-716e-4ea1-e423-f38bed76b595.png)

## 注意
上記手順で実行ボタン押したら`php not found`って怒られた。
その場合、設定で`Phpserver: PHP Path`を検索し、パスを指定してあげる。
phpがある場合、ターミナルで`which php`と打てばパスがわかる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490854/3d52d60c-3502-f2de-3550-9d6707a5397f.png)

## その他のコマンド
`Command + Shift + p`で`phpserver`って打つと、コマンドリストが表示される。
停止とか、リロードとかはここから。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3490854/529ed792-e66b-6fd6-e3e1-55bee83b0327.png)


## あとがき
AtomからVSCodeに乗り換えてしばらく経ちますが、結構気に入ってます。
tikzで辺の長さを書き込む時の微調整

tikzで三角形の辺の長さを書き込みたいとき

midwayで書き込むことはいろんなページで説明されているが、書き込む長さが5cmとかだと、少し位置を調整したい時がある。
位置を調整するのが

anchor=east
とかなので、midwayの代わりにanchor=eastを書いたりしてうまくいかない感じになっていたが、どちらも書くことで求める図が記述できた。

midwayのみの時の図（5cmが重なってしまっている、これを少し右に移動させたい。![test.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197731/d89e4e09-6efb-df5c-ec5f-20c533e04ff7.jpeg)
)




完成図形



![三角関数説明の図[30do比がついている].jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197731/3d5435b5-84f1-4d7d-8ded-8967b490c7d0.jpeg)
```
\begin{tikzpicture}

\path(0,0) node[name=o]{};
\path(0:{sqrt(3)*4}) node[name=a]{};%{sqrt(3)}*4とするとエラーが出るので注意
\path(30:2*4) node[name=b]{};

\huge

\path pic[draw,"$\SI{30}{\degree}$",angle eccentricity=2,angle radius=25pt]{angle=a--o--b};
\path pic[draw,"",angle eccentricity=2]{right angle=b--a--o};


\path [draw,dashed] (o) to[out=60,in=180,edge node={node [midway,fill=white]{ここの長さは？}}](b);
\path [draw,dashed] (a) to[out=60,in=300,edge node={node [midway,anchor=mid west,fill=white]{$\SI{5}{\centi\meter}$}}](b);


%\path[draw,arrows=-stealth,color=red,line width=3pt] (0,0) --(0:4) node[anchor=north east] {$\overrightarrow{a}$};
%\path[draw,arrows=-stealth,color=blue,line width=3pt] (0,0) --(180:5) node[anchor=east] {$\overrightarrow{b}$};

\path[draw,line width=2pt] (0,0) --(30:2*4) --(0:{sqrt(3)*4}) --(0,0);

\end{tikzpicture}
```
rex0220 関連レコード集計・アプリ集計プラグイン レコード・テーブル間の相互反映

rex0220 関連レコード集計・アプリ集計プラグインで、レコード・テーブル間の相互反映を行ってみます。

# 概要

- 関連レコード集計プラグインで、集計区分が同じレコードを他アプリのテーブルに集計
    - レコード保存時に自動集計
    - 集計先レコードが無い場合は、自動でレコード作成
- アプリ集計プラグインで、他アプリのテーブルの最新データをレコードに反映
    - 編集画面表示時に、テーブルの値を反映
    - 一覧画面の一括集計でテーブルの値を反映

![2023-10-04_18h54_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/130d37e3-a60f-6b03-cce1-730f4eee87c2.png)


# 操作例

- レコード編集画面表示時に、テーブルの値を反映
![2023-10-05_10h09_22.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/ba99a93f-f08f-2cfe-d053-7e6968b147ca.gif)

- 一覧画面で、テーブルの値を一括集計
![2023-10-05_10h28_09.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/37046288-932b-c13f-bab2-41a266a84640.gif)


# 集計元アプリのプラグイン設定

- 関連レコード集計プラグイン
- アプリ集計プラグイン

# 関連レコード集計プラグイン

同じ集計区分のレコードを集計先アプリのテーブルにまとめる。

![2023-10-05_10h21_19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/c05ffebe-6e17-3fcf-b206-f251420c4720.png)

- 集計項目　※レコード追加時の項目設定
![2023-10-05_10h22_35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/fda3f967-d308-b1c0-68b1-b07e4e5f8b32.png)

- テーブル項目
    - レコードを識別するために、レコード番号「$id」を設定
![2023-10-05_10h23_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/0cad62fd-e518-edcf-ddb9-d01b98c35a32.png)


# アプリ集計プラグイン

他アプリのテーブルから、レコードに対応する行の値を反映

![2023-10-05_10h19_16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/ab770eb6-be66-99a2-4e0b-d402a4548c2c.png)

- 集計項目
    - テーブル行の元レコード番号が同じものから集計

![2023-10-06_11h40_40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/86bb7530-9ff9-f797-6ada-2038ff0efdd7.png)
【HTML】Google Mapの縮尺を変更してみよう！

🌻埋め込んだGoogle Mapの縮尺変更方法

💡埋め込みコードの中にある
「!4f13.1」の「13.1」を変更すればOK！

・「1～180」まで指定可能
・1：狭い範囲を表示
・180：広い範囲を表示（世界地図）

試してみてくださーい✨！

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="qBLMVEG" data-user="tomok7" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/tomok7/pen/qBLMVEG">
  Google mapで縮尺変更</a> by tomok7 (<a href="https://codepen.io/tomok7">@tomok7</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525847/da271c8a-a90d-bb8d-3dd7-6738ecbf2120.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525847/085adcd2-36a9-3240-7b92-2511d05ca9d8.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525847/beff6f26-552f-cd99-74a5-9a6016974039.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525847/b62a3ee1-e253-ae03-3f78-be5a5b37cb4d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525847/304ce2a6-67bb-da0e-1fc5-21cc1ee1bf35.png)
Cultureで指定した言語を、アプリケーション全体のXAMLでの表記(StringFormat)に反映

Cultureで指定した言語を、アプリケーション全体のXAMLでの表記(`StringFormat`)に反映させる方法です。
.NET 6で確認。

## ConverterCultureによる指定（ただし個別）
```XML
Text="{Binding Num1, StringFormat='{}{0:C2}', ConverterCulture='ja-JP'}"
```


```C#
public double Num1 { get; set; } = 123456.456;
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132059/7214790a-80f6-c25d-ac9d-9671db8ea655.png)

ConverterCultureをその都度指定すれば、日本語での通貨表記になります。
ただし、これでは都度設定しないといけません。


## アプリケーション全体に設定

Aの部分のコード（下記参照）で、アプリケーション全体のCultureを変更しても、XAMLのBindingで指定するStringFormatは、デフォルトでは次のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132059/d5dc3218-e90f-55ee-c5c3-0e2e1575755c.png)


```XML
   <TextBox
       Width="200"
       Height="30"
       Text="{Binding Num1, StringFormat='{}{0:C2}'}" />
```
次の様に、アプリケーション全体で、XAML上で日本語の表記にするには、Bのコードが必要です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132059/7214790a-80f6-c25d-ac9d-9671db8ea655.png)





```c#
public App()
{
    //A
    CultureInfo culture = CultureInfo.CreateSpecificCulture("ja-JP");
    CultureInfo.DefaultThreadCurrentCulture = culture;
    CultureInfo.DefaultThreadCurrentUICulture = culture;
    Thread.CurrentThread.CurrentCulture = culture;
    Thread.CurrentThread.CurrentUICulture = culture;
    //B XAMLでの表示を変更
    XmlLanguage language = XmlLanguage.GetLanguage(culture.IetfLanguageTag);
    FrameworkElement.LanguageProperty.OverrideMetadata(typeof(FrameworkElement), new FrameworkPropertyMetadata(language));
}
```

### 参照
- [CultureInfo.DefaultThreadCurrentCulture プロパティ](https://learn.microsoft.com/ja-jp/dotnet/api/system.globalization.cultureinfo.defaultthreadcurrentculture?view=net-6.0)
- [StringFormat Localization issues in wpf](https://stackoverflow.com/questions/520115/stringformat-localization-issues-in-wpf/520334)
- [How to set and change the culture in WPF](https://stackoverflow.com/questions/4041197/how-to-set-and-change-the-culture-in-wpf)