OmniAICreator/Qiita-1.07M huggingface dataset:
M1 Macで Create React App の環境構築  (Homebrew, Nodebrew, Node)

M1 Macで Create React App の環境構築をしました。
M1 Macの仕様でかなり苦戦しました、、

## Homebrew をインストール
```

% cd /opt
% sudo mkdir homebrew
% sudo chown $USER homebrew
% curl -L https://github.com/Homebrew/brew/tarball/master | tar xz --strip 1 -C homebrew

```

## PATHを通す

```
# PATHを通す
% cd
% vim .zshrc

export PATH=/opt/homebrew/bin:/usr/local/bin:$PATH

% source .zshrc
% which brew
/opt/homebrew/bin/brew

```

## Xcodeのライセンス

```

% sudo xcodebuild -license accept

sudo softwareupdate --install-rosetta

```

## Homebrewとnodebrewのインストール
```

brew -v
brew install nodebrew
nodebrew -v

```

## Nodeのインストール
```

% nodebrew ls-remote
% nodebrew setup
% nodebrew install-binary stable
% nodebrew ls
% nodebrew use

```

## Nodeの環境パスを通す
```

echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.bash_profile

# または

echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.zprofile

```

完了！
作業環境によるので大変でした。
rex0220 計算式プラグインの使い方をGPTsに学習させてみる（その８）使用例の学習

[rex0220 計算式プラグインの使い方をGPTsに学習させてみる（その７）誤った計算式の訂正学習](https://qiita.com/rex0220/items/b68659ae87d6c49b1898)の続きです。
計算式の使用例を学習させてみます。

# 概要

「文字列項目に"ABC"があるか判定するには？」を実現する計算式はいくつかあります。
学習前は、計算式プラグインで利用できない INSTR 関数の使用例を応答するなどの誤りがありましたが、学習後は、TEST 関数などの計算式プラグインで利用できる計算式になります。

# 学習前の応答

計算式プラグインで利用できない INSTR 関数の使用例を応答
![2023-11-17_11h19_55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/21b53aa5-e3e0-2fcd-1877-021c1656bd2e.png)

# 計算式の使用例を学習

計算式プラグインで利用できるTEST 関数などの使用例だけでは、INSTR 関数を応答したので、INSTR 関数等は利用できないことを記述した。

```計算式の使用例.txt
example　計算式の使用例

・文字列項目に"ABC"があるか判定するには？
TEST("ABCD1234","ABC") -> true ※ "ABC"が含まれている
TESTRE("ABCD1234","ABC") -> true ※ "ABC"が含まれている
FIND("ABCD","ABC") -> 0 ※ "ABC"が含まれている場合に、位置を返す。無い場合は -1 


計算式プラグインでは、下記の関数・演算子は利用できない
関数 INSTR は、利用できない
演算子 CONTAINS は、利用できない
```

# 学習後の応答（Preview）

![2023-11-17_11h22_47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/ebf1b161-51d7-94dd-3e07-20b1354331ff.png)

# 学習後の応答
Preview とは、少し応答が異なる。応答内容は、使うほど整理されていくのか？

![2023-11-17_11h52_15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/c04e7c85-e93b-09c4-7870-5ddbbf83551a.png)

# 学習後の応答（別の文字列"あいう"で検証）
使用例の文字列も"あいう"に合わせた内容で、応答してくれる。

![2023-11-17_11h54_09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/4bec9727-3851-542e-5c83-11ce14d9ec99.png)

# 学習後の応答（"A"と"C"に囲まれた文字列で検証）
こちらは、ちゃんと正規表現で検索する TESTRE 関数の使用例となった。

![2023-11-17_11h56_23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/bf6b1073-aeb7-d128-ca57-9f43b236864f.png)

# まとめ

INSTR 関数は、VBA の関数だと思うが、計算式プラグインでは使えないものでも、どこからか引っ張ってきて応答してしまう。
よくある使用例を学習させることと、使えない関数等を学習させることを、モグラたたきのように続けていくしかない。
学習したものについては、応用も効くし分かりやすく解説してくれるのは、便利。
【ChatGPT有料版 - My GPTs】で、自分のGPTsをリンク以外で、ほかの人と共有したい。


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

　今回は、My GPTsの作品を、リンク以外で、人と共有するやり方を書きます。

:::note info
本記事は、ChatGPT（有料版）で
行なっております。ChatGPT（無
料版）ではご利用いただけません。
あしからず。
:::

　なぜ？と
　　思われた方は
　　　いらっしゃらない？

　リンクアドレスを
　　渡せば、それでいいじゃん、と。

　うん、確かに、そのとおり。

　でもね、
　　そのGPTsを
　　　ほかの用途にも
　　　　使いたい、とは思いません？

　ChatGPTの
　　プロンプトが
　　　配布されたら、
　　　　それを改造して
　　　　　使ってきた
　　　　　　じゃないですか。

　それと同じように
　　自分のプロンプトを
　　　用途によって、
　　　　修正・改造できるならば、
　　　　　と思ったわけです。

　ところが、
　　GPT BuilderのCreateだと、
　　　指示プロンプトは無理。
　　　　（やってみた）

　それに、内容も
　　ChatGPTの性質上、
　　　一定ではありません。

　向こうは、
　　聞きたいことだけ
　　　聞いてくるだけだし。

　うっ、愚痴になってきた(汗)
***
　さて、理由はともかく、
　　そのやり方のひとつを
　　　書いてみます。

```Text:GPTs配布用フォーマット
Configure
Name:「」
Description:「」
Instructions:「」
Conversation starters:「」「」
```
　もちろん、
　　Knowledge
　　　/ Capabilities
　　　　/ Actions
　もありますが、
　　各自の判断でお願いしたいです。

　だって、
　　用途によって、
　　　必要な機能も違いますし。

　何より、
　　Knowledgeは、必要なファイルを
　　Actionsは、API使用を
　　　想定しているわけですからね。

　【注意点】
　　プロフィール写真は、
　　　自分で作成するか、
　　　　そのままにしておくか
　　　　　各自にお任せします。
***
　実は、
　　理由が
　　　もうひとつ、あります。

　有名どころの言葉
　　（例えば、MicrosoftやGPT）を
　　　使うと、
　　　　Save時に
　“Your changes couldn't be published”
　“変更を公開できませんでした”
　　　　　と言われてしまいます。

　それを避けるのも
　　理由のひとつです。
***
　それでは、
　　先日、アップした拙作の
　　　「Kabumira AI QA アシスト」
　　　　から抜き出して、
　　　　　ほかのサイトでも
　　　　　　使えるフォーマットを
　　　　　　　公開します。

　下記をコピーして、
　　QQQQQの部分を
　　　WEBサイトの名前に
　　　　置換してから、
　　　　　Configureの各項目に
　　　　　　設定してください。

　　Conversation startersについては
　　　各自で変更してください。

　　QQQQQの例としては、
　　　OpenAIやMicrosoftですね。
　　　　Wikipediaもイケます。
　　　　　ちょっと
　　　　　　遊んでしまいましたw

```Text:FAQ アシストGPTs
Name:「QQQQQ FAQ アシスト」
Description:「QQQQQ FAQ のアシストを目的としています。」
Instructions:「QQQQQ FAQ アシストは、QQQQQのウェブサイトから情報を取得して、ユーザーの質問に応答するために設計されています。ユーザーがQQQQQに関連する質問を指導すると、日本語で情報検索、抽出、正確な回答を提供します。情報の信頼性を確かめるために、出典を直接引用したり、日本語での訳を提供します。ユーザーの質問にあいまいな点があれば、質問を明確にするために読み解き能力を発揮します。QQQQQの技術、更新、一般情報に関連する広範囲の質問に対応します。すべて日本語で対応します。」
Conversation starters:「自己紹介をお願いします。」「Please introduce yourself.」
```
　Wikipediaは、
　　調べたい項目のページに
　　　移動して、知りたいことを
　　　　探さねばなりません。

　その点、
　　これは、
　　　項目と知りたいことを
　　　　最初に入力すれば、
　　　　　回答してくれます。
　　　　　　便利！　　　

　みなさんも
　　使ってみて！

　コピペは、
　　手間ですけどねw

　今回は、ここまで。
epel-nextリポジトリって何？

# 結論

epel-nextは、CentOS Stream専用の追加リポジトリ。
epelに依存して使うリポジトリ。

# 情報源

Extra Packages for Enterprise Linux (EPEL) :: Fedora Docs
https://docs.fedoraproject.org/en-US/epel/#what_is_epel_next
知らないと現場でヤバイ!Reactの開発でよく使われるOpenAPIを使ったスキーマ駆動開発とは何だ？

# 最近の開発環境
最近の***モダンな開発現場***では```OpenAPI```を使っているみたいです。
***参考書とかに載っていない技術で現場に出ないと知らないことが多い***みたいです。

スキーマ駆動開発ができたら「お！この人現場のことを勉強している!」と評価されるみたいです。


# スキーマ駆動開発とは
***APIのスキーマを最初に定義して、定義をもとにバックエンドやフロントエンドの開発を進める***やり方です。
このやり方のおかげで***フロントエンドとバックエンドのAPIの認識違いが発生しづらく***なります。

# これはなぜ必要か
フロントエンドとバックエンドは別れて開発することが多いですが、この開発手法にも問題があるみたいです。

1. ***フロントエンジニアがバックエンドのコードを見ないとAPIの仕様がわからない***

2. ***バックエンドの開発が終わらないとフロントエンドの開発が進まなくなる***

3. ***フロントエンド側のAPIに関わるコードを手動でやらなければいけない***

これらによって***工数が多くなってしまい、非効率な稼働になってしまっている***プロジェクトがあるみたいです。特に3番ではAPIの数が増えるほど毎回毎回APIを手動で開発し、人がやるのでエラーが発生してしまうリスクがあります。これらを解決するために```OpenAPIを使ったスキーマ駆動開発```です。

# OpenAPIとは何か
```スキーマ駆動開発をやりやすくするためのツール```です。以前は```Swagger```と呼ばれていました。
言い方間違っていたらすみません。
実際に***自分も現場でAPIの仕様が迷った時に非常に役に立ちました***。こんな感じです。

![スクリーンショット 2023-10-12 12.53.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/8cb0dc01-6fe0-1d69-f6b4-c41b1327cbec.png)

> 引用　　https://blog.techscore.com/entry/2023/06/16/080000

```上のようにAPIの仕様を視覚的にわかるようになります```。postmanで叩くと実際にAPIが取得できたりします。

![スクリーンショット 2023-10-12 13.02.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/da0e9ca3-c29e-d7ad-eb5a-703a33078676.png)

> 引用　https://qiita.com/KNR109/items/7e094dba6bcf37ed73cf

そしてOpenAPIのおかげで、```ダミーのAPIを作ることができて```、
***フロントエンドのAPIに関係するコードを自動で作る***ことができます。


# スキーマ駆動開発の種類
スキーマ駆動開発には以下の２種類があるみたいです。

### スキーマファースト
```スキーマファイル（OpenAPIでいうとAPIが定義されたYamlもしくはJSON）```から
コードジェネレータを使ってコードを生成しAPIを開発していきます。

***APIの使用をベースに、フロントエンド、バックエンドの開発***をしていきます。

現場はこっちが多いみたいです。

### コードファースト
コードからスキーマファイルを作ってAPIを開発していきます。
***バックエンドのAPIをベースにAPIの仕様書を作成***していきます。

# SwaggerUI
以下の記事を見ればどんな感じかわかると思います。***APIの仕様書を可視化***してくれます。

https://petstore.swagger.io/?_gl=1*1ozbne2*_gcl_au*MTAzMTY3NDQ2Mi4xNzIxNjQwMjQ5&_ga=2.256696139.1590731265.1721640244-2106335002.1721640244



# 有益な教材
こちらの教材もReactエンジニアになる上で有益なのでよかったら
使ってみてください。この教材も参考にさせてもらいました。

https://read-engineer.com/2022/11/06/brain-react/


# 資料


https://qiita.com/80andco_tech_pr/items/10af32308f7b22c8b052

https://www.aeyescan.jp/media/openapi

https://qiita.com/KNR109/items/7e094dba6bcf37ed73cf#openapi

https://techblog.raccoon.ne.jp/archives/1630923574.html
Distribution Map（StepFunctions）の限界を知った話

## はじめに
昨年のre:Inventで発表されたStepFunctionsの新機能である、Distribution Mapは我々開発者にとってかなり強力な機能だと思います。
（Distribution Mapがどんな機能かは、[リンク](https://qiita.com/saba_miso/items/3309348bb46d50dea158)を確認してみてください。）

今回はDistribution Map(Step Functions)を利用して分かった「限界」に関して記録したいと思います。

## 目次
1. 何をしたかったか。
2. やったこと・起こったこと
3. どのように乗り越えたか
4. まとめ

### 1. 何をしたかったか。
我々は開発フローの中でCICDでデプロイされるWeb資材をS3にビルドを実施しています。
さらにそのWeb資材をユーザー毎に展開していくために、これまではVBAツールを利用して1ユーザーずつコピーを行っていました。
（1つずつ行うのは、ユーザー毎にWeb資材のカスタマイズがあるため、一括コピーができないため）

ただこのツールはお察しの通り、ユーザーが増えるのに比例して処理時間も増え、すでに5時間を超すまでになっていました。

迅速なリリースを実現し、運用保守稼働を低減させることを目的として、LambdaとStep FunctionsのDistribution Mapを利用して超高速な並列処理を実装していくことに至ったわけです。

### 2.やったこと・起こったこと

  #### やったこと
- Lambda×PythonでVBAツールをLambda化（ソースは割愛）
    - 以下2つのLambdaを実装
        1. Web資材の更新対象の顧客リストをDBから取得し、JSON形式でリストをreturnする関数
        2. StepFunctionsでリストから1件ずつ抽出された顧客データを元にS3からコピーを実行する関数
- StepFunctionsのステートマシン作成
    - 以下の構成でDistributionMapを利用して、リストのアイテム数だけLambdaを並列実行させるステートマシンの作成
    ![stepfunctions_graph.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2956558/0016914a-e5a5-5ddd-9dd8-eccfc5924f6e.png)


 ### 起こったこと

開発環境での動作確認は以下のように成功し、実行時間の短さに驚嘆していました。
やっぱDistribution Mapすごいですわ。
![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2956558/fcf5d439-7fe0-1730-a4a7-5f989cec5fc9.png)

しかし負荷試験用の環境で、このステートマシンを実行させると、以下のエラーになり、ステート遷移に失敗してします。
> The state/task 'lambda' returned a result with a size exceeding the maximum number of bytes service limit.

[参考記事](https://qiita.com/Macaron_Suke/items/faba4616a5378b5d571d)

上記の参考記事にもAWS公式ドキュメントにも、S3にデータを一時保存して後続処理に渡す的なことが書いてありましたが、今回扱っているデータはシーケンスレスで後続処理がどのデータを処理しているか判断することが難しそうだったので、ここでStep Functionsを利用することを諦めました。（先に調べておけよという感じですね）

### 3.どのように乗り越えたか
Step Functionsが使えなくなったので、その他のAWSサービスを利用して並列処理を実現する方法を考えたところ、
1のLambdaからSQSにユーザー毎のデータでSQSキューに渡して、そのキューを2のLamabdaにサブスクライブさせる方法を思いつきました。

Step FunctionsならJSON定義で記載できるし、実行結果がビジュアライズされているので分かりやすいので好きだったんですが、今回の場合は、Lambda×SQSで大規模並列処理を実現させました。

Lambdaの処理自体もあまり変わらないので、変更は容易でした。

構成としては以下のようになります。
![SQS_Lambda.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2956558/404394cc-f61a-954f-31d0-f0085bd3eedc.png)

Step Functionsを利用したかったのは、実行結果がかなり見やすく成功失敗の判断が容易なこともあり、その点を補うためにLambdaログをCloudWatch Logs Insightのクエリで、成功ログがSQSにキューイングされた数と一致していることを確認することにしています。

少し手運用が入ってしまうことは残念ですが、上記構成でも処理時間は15分以内で実行できるので、稼働削減効果としては、莫大です。

### 4.まとめ
今回はStep Functionsのデータサイズリミットに苦しみましたが、まとめると

- Step FunctionsのDistribution Mapは優秀。だが扱うデータはシーケンスのある、細分化されたデータが好ましい。
- それでもStep Functionsのデータサイズ上限、256KBは小さすぎる、、AWSさんなんとかしてください。。
- Distribution Mapを使わなくてもSQSで同じように大規模並列処理を実行することは可能

といった具合です。データサイズの大きい並列処理を検討している方はご参照ください！
Kubectlのconfig設定について

# Kubectlの話
Kubernetes ClusterはMaster Node と Worker Nodeで構成されています．

![Kubernetes-Architecture.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2747713/0ca1197b-f8ed-4e8b-5413-6379ec7c39d9.png)

引用元
https://lutaverse.com/blog-details/the-evolution-of-containerization-revolutionizing-software-development-and-deployment

**ここで注意が必要です**
Master Nodeで作業もできるのですが，セキュリティやNode内にファイルが散乱するなど，おすすめできません．
この図の左下のようにCLI(Kubectl)を外部の環境に用意することが必要です．
なので，今回はkubectlのインストールからkubectlのkubernetesクラスタへの接続方法について記述します．

## kubectlのインストール
ここではUbuntu OSを前提とした内容となっています．
curlコマンドを使用してkubectlをインストールします．この方法は公式ドキュメントにも記されています．
https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/
実施コマンド
```
curl -LO "https://dl.k8s.io/release/$(curl -LS https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
```
実行結果
```
 % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   138  100   138    0     0    666      0 --:--:-- --:--:-- --:--:--   666
100     7  100     7    0     0     16      0 --:--:-- --:--:-- --:--:--    16
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
"config" 0L, 0B                                                                                   0,0-1         All
apiVersion: v1
100   138  100   138    0     0    719      0 --:--:-- --:--:-- --:--:--   718
100 47.5M  100 47.5M    0     0  43.3M      0  0:00:01  0:00:01 --:--:-- 44.2M
```
これで無事kubectlのインストールが完了しました．
次に実行権限の付与(chmod)とkubectlをバイナリーPATHに移動させます

## kubectlへの実行権限
このままだとkubectlコマンドが使えません．
まず実行権限を与えます．
```
chmod +x ./kubectl
```

そして次にバイナリーPATHに移動させます．
```
sudo mv ./kubectl /usr/local/bin/kubectl
```

## configファイルの設定
今回はすでにconfigファイルがあることを前提とした内容となっています．
ホームディレクトリ直下に「./kube」ディレクトリを作成します

```
mkdir ~/.kube
```

「./kube」ディレクトリ直下に「config」を作成します．

```
touch ~/.kube/config
```

この作成したconfigに事前に用意したconfigの内容を記述します(コピペでOK)

```
vim ~/.kube/config
```

以下がconfigの例(一部消しています)
```
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: 
    server: https://
  name: default
contexts:
- context:
    cluster: default
    user: default
  name: default
current-context: default
kind: Config
preferences: {}
users:
- name: default
  user:
    client-certificate-data: LS0tLS1CRUdJTiBDRV
    client-key-data: 
```

これでconfigの作成は終了です．
次はkubectlの実行パスを通す作業に移ります．

## kubectlのパス設定
先程設定したconfigを使用するためにkubectlのパスを設定します．
~~と思ったのですが，kubectlは初期設定で「.kube/config」を参照しに行くので，設定が必要ありません．~~
**というのは誤りでした** 11月3日早朝に気づく
インストールした後に実行権限を与えバイナリパスに移動させる必要が有りました！！
すでにインストール後の作業に追記済み
## ログインの度にkubectlが使えない人へ
ログイン時に自動的にkubectlのconfig参照先を設定します．

configの所有者を変更し，参照先を固定することで解決できます．

所有者の変更
```
sudo chown $(id -u):$(id -g) ~/.kube/config
```

参照先の固定
```
echo 'export KUBECONFIG=~/.kube/config' >> ~/.bashrc
```

```
source ~/.bashrc
```

これで無事解決！！！！！！
Scala - Call by Name & Call by Value (関数パラメータの評価戦略)

# Call by Name & Call by Value

`Call by Name` & `Call by Value` は関数パラメータの評価戦略を指しています。
相違点としては、評価のタイミングにあります。

## Call by Value
| item | description |
| --- | ---- |
| 評価タイミング | パラメータ(引数)は関数を渡す前に評価される |
| 動作 | パラメータの実際の値が計算され、その結果が関数内で使用される |
| 特徴 |  パラメータは一度だけ評価され、その評価された値が関数の中で複数回使われても、再評価は行われない |


## Call by Name
| item | description |
| --- | ---- |
| 評価タイミング | パラメータは関数の中で実際に使用されるまで評価されない |
| 動作 | パラメータは関数内で参照されるたびに評価される |
| 特徴 | パラメータが関数内で一度も使われなければ、そのパラメータの評価も行われない。<br>関数内で複数回参照される場合は、その都度評価される。 |



## Sample code 

```scala
def methodCallByValue(x: Long): Unit = {
  println("Call by value: " + x)
  println("Call by value: " + x)
}

def methodCallByName(x: => Long): Unit = {
  println("Call by name: " + x)
  println("Call by name: " + x)
}

methodCallByValue(System.nanoTime())
methodCallByName(System.nanoTime())


/* output
Call by value: 3529902534708
Call by value: 3529902534708
Call by name: 3529925374833
Call by name: 3529925707125
*/
```
> methodCallByValue -> 一度だけ評価されている
> methodCallByName -> xが呼び出されるたびに評価されている

## Which Choose?
- Call by Value
> 他言語でも一般的に利用されていて馴染み深い
> パラメータの評価に副作用がないか、パラメータの評価結果を複数回使用する場合に適している

- Call By Name
> 遅延評価が必要な場合や、条件によってパラメータを評価しない場合に有効
> 例: 短絡評価(short-circuiting)を行う論理演算など

## 補足事項
- 短絡評価(short-circuiting)

> ブール演算(論理演算)において、結果が最初のオペランドの評価だけで決定できる場合、残りのオペランドを評価しないというテクニック<br> 主にパフォーマンスの最適化や不必要な副作用を避けるために使用されます

```scala
def and(a: Boolean, b: => Boolean): Boolean = {
  if (a) b else false
}

def testA(): Boolean = {
  println("testA called")
  false
}

def testB(): Boolean = {
  println("testB called")
  true
}
println(and(testA(), testB())) // testBは呼ばれない
```

> ※　正格評価の場合、論理演算においえて結果を決定するために必要かどうかかからず、全てのオペランドが評価される 

### 参考文献
> [Scala & Functional Programming Essentials | Rock the JVM](https://www.udemy.com/course/rock-the-jvm-scala-for-beginners/)
> [Programming Scala, 3rd Edition](https://www.oreilly.com/library/view/programming-scala-3rd/9781492077886/)
Scala - Tail Recursion 末尾再帰関数

# Tail recursion

tail recursion(末尾再帰)とは、関数の最後のアクションが再帰呼び出しであるときに使われる用語です。  
最大の特徴として、コンパイラが該当の再帰を最適化して、スタックオーバーフローのリスクを軽減することが挙げられています。

## 通常の再帰処理

```scala
def factorial(n: Int): Int = {
  if (n <= 1) 1
  else n * factorial(n - 1)
}
```

> 関数が自身を呼び出す際に、それまでの計算の状態(local変数やパラメータ)をスタック領域に保存します。
> 再起が深くなり、スタックが限界を超えるとスタックオーバーフローが発生し、プログラムがクラッシュしてしまいます。

| item | descritpion |
| ---- | ---- |
| 使い所 | シンプルなアルゴリズムや浅い再帰呼び出しで適している |
| リスク | 深い再帰ではスタックオーバーフローのリスクがある |
| 適応例 | 短いリストの操作、単純な計算問題 |


## 末尾再帰処理

```scala
import scala.annotation.tailrec

def factorial(n: Int): Int = {
  @tailrec // scalaでは、`@tailrec`を付与することでコンパイラに末尾再帰を確認させることができます。
  def factorialTailrec(x: Int, accumulator: Int): Int = {
    if (x <= 1) accumulator
    else factorialTailrec(x - 1, x * accumulator)
  }

  factorialTailrec(n, 1)
}
```

> 関数の最後のアクションが自身の再帰呼び出しであり、その呼び出しの結果が直接返されます。
> 末尾再帰最適化をサポートする言語では、これをループに変換して、`新しいスタックフレームの生成を防ぎます。`
> 結果として、メモリ使用量が大幅に減少し、スタックオーバーフローのリスクが軽減されます。

| item | descritpion |
| ---- | ---- |
| 使い所 | 深い再帰やパフォーマンスが重要な場合に適している |
| 利点 | スタックオーバーフローのリスクが軽減され、効率的なループに最適化される |
| 適応例 | 大規模なデータセット、複雑な計算問題 |


## Sample code

商品の在庫管理を想定しているものです。  
各種品には、在庫数がる、特定の物量が要求された場合にその要求を満たすことができるかシュミレートしています。

```scala
import scala.annotation.tailrec

case class Product(name: String, quantityInStock: Int)

def canFulfillOrder(products: List[Product], quantityRequired: Int): Boolean = {
  @tailrec
  def checkProducts(products: List[Product], quantityRemaining: Int): Boolean = products match {
    case Nil => quantityRemaining <= 0
    case Product(_, quantityInStock) :: tail =>
      if (quantityInStock >= quantityRemaining) true
      else checkProducts(tail, quantityRemaining - quantityInStock)
  }

  checkProducts(products, quantityRequired)
}

val products = List(Product("Widget", 10), Product("Gadget", 5), Product("Thing", 3))
println(canFulfillOrder(products, 15)) // true
println(canFulfillOrder(products, 20)) // false
```

### 参考文献
> [Scala & Functional Programming Essentials | Rock the JVM](https://www.udemy.com/course/rock-the-jvm-scala-for-beginners/)
> [Programming Scala, 3rd Edition](https://www.oreilly.com/library/view/programming-scala-3rd/9781492077886/)
QAに携わっていて日常に役立ったこと５選


QAに携わっていて日常に役立ったかなーと思うことを５つ挙げて記事を記載します。

# 自己紹介
もともと業務システムやWebシステムのエンジニア。20年ほど前からQAに携わっている。
QAでは様々なハードウェア、ネットワーク、ミドルウェア、ゲーム、Webサービスに携わってきた。
スタンバイに入社してもうすぐ2年。
***

## １．原因の深堀

もうだいぶ過去になるが、大規模インフラのQAに携わっていた時などは日常的にポストモーテムが実施され、ポストモーテムファシリテートとして活動していた。
「毎日が日曜日」ならぬ「毎日がポストモーテム」という感じ。

再発防止のために原因を深堀し続ける毎日の中でこのポストモーテムの考え方は日常生活でも役に立ち、何か問題が発生したときに原因はなんだろう、真因はなんだろうと深堀することで表層的な対症療法ではなく根治療法まで結びつける役立ちがある。

### 電気代
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56839/01a611dc-04b6-744f-5c47-cf7cea79a812.png)

### 階段
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56839/a47576e5-b0c2-cf95-6968-30ab84e74e47.png)


## ２．裏を考えるようになった
QAでは仕様どおりに動作することを検証することはもちろん、仕様に記載されていない部分の確認も行う。

「この機能は営業時間中はＡの動作を行い、それ以外の時間はBの動作を行う。」

みたいな仕様があった場合、記載どおりの挙動を確認することはもちろんだが、境目となる時間のちょうどぴったりの時はどうなるのか、Ａの動作中に営業時間が終了した場合は？年末年始やGWなど長期休暇中は？など仕様に記載されていない裏の部分を考慮して検証することがある。

日常では
__「主婦の95%が支持している。」__
みたいな広告があった時に残りの5%どういう層が支持しなかったのか、どんな理由で支持しないのかなど裏を返して考えるようになった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56839/049d0453-eeb4-3ecb-3d10-4c64799c5ef8.png)



表立ったメリットはない。

## ３．ブラウザに詳しくなった

日常的に使っていたのは過去を含めてNetScape(IEがなかった頃）→IE(20年くらい前まで）→Firefox(IEとChromeの間の2年くらい）→Chrome(2005年くらいから？）を使用していた。
業務では複数種類のブラウザの通常操作からUserAgentを偽装したりネットワーク通信を偽装したりブラウザの操作を自動化が必要になります。

日常使いではQAの時に使用していて便利だったアドオンを自宅でも使ってみたりなどしている他、遊んでいるブラウザゲームを自動操作させてみたりなど・・・一応、日常でも役に立ってはいるかな。

## ４．スマホに詳しくなった

これはドメイン、検証対象の動作機器によって大きく変わるところだが、自分の場合、スマホ端末を使ったプロダクトに長く携わっていたため、プライベートではiOSユーザではないのだけど、iOSのこともある程度詳しくなっている。

今まで一緒に仕事をしたQAメンバーの中には端末名を言えば、メモリ、ストレージ、さらにはチップセットまで記憶していて即座に答えられる人もいた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56839/e8086699-ec82-747a-b79c-c2e260211934.png)

職業病という範囲では収まらない気がした。（笑）

QA業務では多くの種類の端末に触れる機会も多く、自分が購入するときの参考情報が得られたりもします。

## ５．５つもなかった
５つなんとしても揚げないとと思うと大抵中途半端な内容があがっていくことになるのでさくっとあきらめることも大事。
できる範囲は限られていて全てを完璧に仕上げることはできないので、「線」は意識しつつも許容する考えも必要。
最後となる５つ目がこんな内容で良いのかは思案が必要。


***
おしまい。
ホールケーキ，ナイフ2回で3等分

問: 半径1のホールケーキを，ナイフを2回入れて3等分する。

答: 中心から上下（または左右）へ，約$\pm 0.265$離れた点を通り$x$軸（$y$軸）に平行にカットする。

この解が適切かどうか，3分割された半月状の部分の面積をシミュレーションにより求めて，真値と比較検証する。

第1象限の一辺の長さ1の正方形内に二次元一様乱数$(x, y)$を$n$組発生させ，$(x, y)$が四分円内にあり，かつ，$y \gt y_{0}$ の点の割合が$\pi/3=1.0471975511965976$になることを確認する。

```Python
import numpy as np
n = 100000000
x = np.random.rand(n)
y = np.random.rand(n)
print(2*np.mean((x**2 + y**2 < 1)*(y > 0.26493208460277684)))
```

    1.04728812

![fig1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611739/58338a7f-9a39-96db-f136-793ecdd6c7d7.png)

追記：上（下）の平行線はそのままで，下（上）の線はx軸に平行でなくてもよいね。そのとき，何らかの制約をつけないと解は無数にあることになるが。
もっとも，上だって平行線でなくてもよいけど，まあ，それは回転すればよいだけのこと。
更には，上の線は平行線として決めて，二本目は下半分をy軸で左右半々に切るとかその他の二等分法。
PostmanからOpenAIのTextToSpeech実行してミルクボーイのネタをしゃべってもらった

ついにChatGPT plusの音声会話機能で利用できていた、テキストの読み上げ機能がAPIでも使えるようになりましたね✨

今回は、Postmanを使って実際にこのAPIを使って音声ファイルを作ってみたいと思います。



## APIドキュメント確認

OpenAIのテキスト読み上げ機能のAPIドキュメントは以下にあります
https://platform.openai.com/docs/guides/text-to-speech


## Postmanでリクエストを出してみる
ここから、APIの仕様に沿って、Postmanを使ってリクエストを作っていきたいと思います。

### Collectionの作成
まずは、Collectionの作成を行います。Collectionとは、Requestをまとめる単位です。フォルダのようなものだと考えるとわかりやすいかもしれません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77722/c4b3ad1a-ca12-55c4-0998-a87a0d60e9aa.png)


### Requestの作成
次に、作成したCollectionを右クリックして > Add Collectionを選択することにより、Requestを作成します。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77722/415c59cf-7e23-4e1a-1d36-414154c20705.png)


### Authrizationの設定
Requestが作成できたら、Authorizationタブをクリックし、TypeにBearerTokenを選択し、Tokenの値にOpenAIから取得したAPI Keyを設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77722/c1f51e7d-bafb-0cf8-0196-db58071d949c.png)


### Bodyの設定

最後に、Bodyの設定を行います。
Bodyタブを開き、rawを選択し、右側のプルダウンでJSONを選択し、下の入力エリアに以下の通りに値を設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77722/b4d2fb8c-fa3a-da1f-2fb1-eb9d0c6af190.png)

```:bodyに設定する値（コピペ用）
{
    "model": "tts-1",
    "input": "いきなりですけどね　うちのオカンがね　好きな朝ごはんがあるらしいんやけど」「あっ　そーなんや」「その名前をちょっと忘れたらしくてね」「朝ごはんの名前忘れてもうて　どうなってんねそれ」「でまあ色々聞くんやけどな　全然分からへんねんな」「分からへんの？　いや　ほな俺がね　おかんの好きな朝ごはん　ちょっと一緒に考えてあげるから　どんな特徴ゆうてたかってのを教えてみてよ」「あのー甘くてカリカリしてて　で　牛乳とかかけて食べるやつやって言うねんな」「おー　コーンフレークやないかい　その特徴はもう完全にコーンフレークやがな」「コーンフレークなぁ」",
    //alloy, echo, fable, onyx, nova, and shimmer.
    "voice": "alloy",
    "speed": 1
}
```


### 結果確認
実行が完了すると、以下の様に再生ボタンが表示されます。クリックするとその音声を聞くことができます。
実際には音声データが返ってきているのですが、それをPostmanが検知して簡単に確認できるようにしてくれています。すごいですね👩‍🚀
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77722/fbc3fbae-9a2b-75ca-7638-6aee22c4836f.png)



## 実際に出力された音声ファイル
上記の手順で実際に出力された音声ファイルはこちらから確認できます。
日本語だとなぜか外国人訛りがありますが、とてもリアルで聞きやすい音声となっています。


https://drive.google.com/file/d/1cXLTEPv-UWZGywivQrsKsI1kBsp0EflJ/view?usp=sharing



英語の場合は、実際に人がしゃべっているのとほぼ区別がつかないレベルです。

https://drive.google.com/file/d/1IzXumMyfe5Q-tu6pbxP3MYxQg5yP6guJ/view?usp=sharing


## まとめ

今回は、OpenAIのText to speechを使って、テキストの読み上げをしてもらいました。
これまでも文章の読み上げ機能は多くありますが、ここまで自然な音声を作ってくれるサービスはこれまでなかった気がします。

ここまで聞き取りやすい音声が出力できるとなると、Youtubeでのナレーション、Podcastの作成・・英語の勉強など、いろんな用途で利用ができそうですので、どんどん使っていきたいですね！
続React-Leafletを使って座席管理システムを作る

# 機能追加
https://qiita.com/y_nomura_kawaii_komugi/items/0c8e35e07f1badbe9884
前記事から少し機能を追加しました。

# 管理モードを追加
管理モードを追加しました。
?admin=trueをつけてアクセスすることで、座席の移動、追加、削除ができるようにしました。
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546752/e66b8d17-b6ff-586c-a2d0-72d16803d912.png)
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546752/49d8fbc2-f726-c586-0645-be19814edc30.png)

# アイコン機能を追加
アイコン機能を追加しました。
![座席Ver2_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546752/1c2b4414-0d18-df43-fb61-1921959d2d1a.png)
![座席Ver2_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546752/06571dbf-6131-373e-b8b9-f09e3250f3bc.png)

# 席予定確認機能を追加
席予定確認機能を追加しました。
カレンダボタンを押下すると、その席の予約状況が確認できます。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546752/cb4ac71e-8728-c264-fbe3-ab818e9750a0.png)
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546752/ae4397d5-14a6-c684-073a-e186cc384e6d.png)
Adobe Marketo Engage 



+ [Salesforce 診断:エラーコード集](https://experienceleague.adobe.com/docs/marketo/using/product-docs/marketo-sales-connect/crm/salesforce-integration/salesforce-diagnostics.html?lang=ja)

Salesforce 統合の一部には、Web アプリケーション内に Salesforce の診断ページが含まれています。このページでは、失敗したデータログから Salesforce にエラーを取り込みます。エラーは役に立ちますが、常に読みやすいわけでは限りません。そのため、エラーメッセージを説明するのに役立つカンニングペーパーを作成しました。
Gitでパターンマッチングを使って特定のファイルを見つける方法

## **はじめに**

Gitは、ソースコードのバージョン管理システムとして広く使用されていますが、その強力な検索機能をフルに活用している開発者は意外と少ないかもしれません。今回は、Gitのコマンドを使って、特定のパターンにマッチするファイル名を効率的に見つける方法をご紹介します。

### `git ls-tree` **を使用する方法**

`git ls-tree` コマンドは、Gitリポジトリの特定のブランチやコミットに含まれるファイルのリストを表示するのに使います。このコマンドを使って、特定のパターンにマッチするファイル名を検索することができます。

例えば、`develop` ブランチ内で `sample*.schema` というパターンにマッチするファイル名を見つけたい場合、以下のコマンドを使用します。

```bash
git ls-tree -r develop --name-only | grep 'sample.*\.schema'
```

このコマンドは `develop` ブランチのすべてのファイル名をリストアップし、その結果を `grep` でフィルタリングして目的のパターンにマッチするファイル名を探します。

### `git ls-files` を使用する方法

もう一つの方法は、`git ls-files` コマンドを使用することです。このコマンドは、作業ディレクトリとインデックスにあるファイルを表示します。

まず、対象のブランチにチェックアウトします。

```bash
git checkout develop
```

次に、以下のコマンドを実行します。

```bash
git ls-files | grep 'sample.*\.schema'
```

この方法では、現在チェックアウトしているブランチのファイルに対して検索を行います。

## **まとめ**

Gitの**`ls-tree`**や**`ls-files`**コマンドを使用することで、特定のパターンにマッチするファイル名を簡単に見つけることができます。これらのコマンドは、大規模なプロジェクトで特定のファイルを探す際に特に便利です。
Webアプリ開発環境作ってみた(0) - 事前検討

### はじめに
新たに仕事でWebアプリケーションの開発方法について、調査検討することになりました。
Webアプリケーションの実装経験は少なく、10年ほど前にSpring3.0-J2EEでの開発を2年くらいやったことがあるだけ。
当時とはだいぶ手法も変わっているだろうし、いまはPCだけではなくスマホ向けの実装も必要？いろいろわからないことだらけ。
Webで検索してみるとたくさんの情報があるけど、ほんとの初心者がつまづきそうなところの対策がないことも多く。
なので、そんな人の参考になれば、と試行錯誤の過程も含めて記録してみようと思いました。

### 候補を探す
まずは、現在の開発手法としてどんなものがあるのかから調べることに。
どうせならスマホ向けアプリを作るのと兼用できないかなと、そちらから調べてみた。
ネイティブアプリはさすがに荷が重いので、クロスプラットフォームアプリの開発手法はとWebで調べたところ、以下のような候補が。

- React Native
- Flutter
- Xamarin

実際にどのくらいそれらが使用されているのか、それが気になって以下の感じでググる。
[React Native Flutter Xamarin 比率](https://www.google.com/search?client=firefox-b-d&q=React+Native+Flutter+Xamarin+%E6%AF%94%E7%8E%87)

そうすると、検索結果で以下の表示が。ふむふむ。

||　　割合|開発者割合|
|:--|----:|--:|
|Flutter|3.2|12.56
|React Native|10.8|13.62
|Xamarin|6.5|5.54
|Cordova|7.4|4.72

また、Xamarinは今後.NET MAUIという形で継承されていくことも、このあたりでわかった。

### 書籍・セミナーを調査
ほんとかどうかはよくわからないので、次は書店でどのくらい書籍が出ているかを見てみることに。
感覚的には以下の順で本が置いてあった。
1. React関連
1. Flutter
1. .NET MAUI

それとセミナーですね。大手IT関連のセミナーコースも見てみますが、さすがに多くは見当たらない。
結局のところ、以下のあたりで受講可能な感じ。

[カサレアル](https://www.casareal.co.jp/ls/service/openseminar/top/)
[Udemy(e-Learning)](https://www.udemy.com/)

React関連やFlutterは見かけるものの、.NET MAUIはあまり多くない印象。
ということで、当面の検討対象をReactとFlutterに絞ることに。

### 書籍を購入
e-Learningは別ですが、セミナー受講は時期などの即効性がむずかしいので、差し当たって書籍をベースに学習する方針。再度書店で眺めたり、Amazonで検索したり。買う買わないにかかわらず、Amazonは重宝しますね。
結果、以下のものを購入。

[現場で使える Flutter開発入門:澤 良弘ほか:2021/08/24/:マイナビ出版](https://www.amazon.co.jp/%E7%8F%BE%E5%A0%B4%E3%81%A7%E4%BD%BF%E3%81%88%E3%82%8B-Flutter%E9%96%8B%E7%99%BA%E5%85%A5%E9%96%80-Compass-Books%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E8%89%AF%E5%BC%98%E3%80%81%E4%B8%8A%E6%9D%91/dp/483997375X/)
[これからはじめるReact実践入門:山田 祥寛:2023/09/28:SBクリエイティブ](https://www.amazon.co.jp/%E3%81%93%E3%82%8C%E3%81%8B%E3%82%89%E3%81%AF%E3%81%98%E3%82%81%E3%82%8BReact%E5%AE%9F%E8%B7%B5%E5%85%A5%E9%96%80-%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88%E3%81%AE%E5%9F%BA%E6%9C%AC%E3%81%8B%E3%82%89Next-js%E3%81%AB%E3%82%88%E3%82%8B%E3%82%A2%E3%83%97%E3%83%AA%E9%96%8B%E7%99%BA%E3%81%BE%E3%81%A7-%E5%B1%B1%E7%94%B0-%E7%A5%A5%E5%AF%9B/dp/4815619484/)
[モダンJavaScriptの基本から始める React実践の教科書:じゃけぇ(岡田 拓巳):2021/09/17:SBクリエイティブ](https://www.amazon.co.jp/%E3%83%A2%E3%83%80%E3%83%B3JavaScript%E3%81%AE%E5%9F%BA%E6%9C%AC%E3%81%8B%E3%82%89%E5%A7%8B%E3%82%81%E3%82%8B-React%E5%AE%9F%E8%B7%B5%E3%81%AE%E6%95%99%E7%A7%91%E6%9B%B8-%E6%9C%80%E6%96%B0ReactHooks%E5%AF%BE%E5%BF%9C-Informatics-IDEA/dp/481561072X/)
[React Native ~JavaScriptによるiOS/Androidアプリ開発の実践:髙木 健介:2020/05/30:技術評論社](https://www.amazon.co.jp/React-Native-JavaScript%E3%81%AB%E3%82%88%E3%82%8BiOS-Android%E3%82%A2%E3%83%97%E3%83%AA%E9%96%8B%E7%99%BA%E3%81%AE%E5%AE%9F%E8%B7%B5-%E9%AB%99%E6%9C%A8/dp/4297113910/)
[Node.jsフレームワーク超入門:掌田 津耶乃:2022/05/28:秀和システム](https://www.amazon.co.jp/Node-js%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AF%E3%83%BC%E3%82%AF%E8%B6%85%E5%85%A5%E9%96%80-%E6%8E%8C%E7%94%B0-%E6%B4%A5%E8%80%B6%E4%B9%83/dp/4798066915/)

選定はわたしの独断と偏見。さてこれからどうなることやら。。。
ホールケーキ，ナイフ2回で3等分

問: 半径1のホールケーキを，ナイフを2回入れて3等分する。

答: 中心から上下（または左右）へ，約$\pm 0.265$離れた点を通り$x$軸（$y$軸）に平行にカットする。

この解が適切かどうか，3分割された半月状の部分の面積をシミュレーションにより求めて，真値と比較検証する。

第1象限の一辺の長さ1の正方形内に二次元一様乱数$(X, Y)$を$n$組発生させ，$(X, Y)$が四分円内にあり，かつ，$Y \gt y$ の点の割合が$\pi/3=1.0471975511965976$になることを確認する。

```R
n = 100000000
X = runif(n)
Y = runif(n)
print(2*mean(X^2 + Y^2 < 1 & Y > 0.26493208460277684))
```
    [1] 1.047193

![output_1_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611739/299d8ae8-e329-337f-6d79-4281c720250f.png)

追記：上（下）の平行線はそのままで，下（上）の線はx軸に平行でなくてもよいね。そのとき，何らかの制約をつけないと解は無数にあることになるが。
もっとも，上だって平行線でなくてもよいけど，まあ，それは回転すればよいだけのこと。
更には，上の線は平行線として決めて，二本目は下半分をy軸で左右半々に切るとかその他の二等分法。
Apatch備忘録

## はじめに
ミドルウェアの学習進める中でApatchについて調べたことを備忘録的にまとめます。
## Apachとは

[公式ドキュメント](https://httpd.apache.org/ABOUT_APACHE.html)より引用
>The Apache HTTP Server Project is a collaborative software development effort aimed at creating a robust, commercial-grade, featureful, and freely-available source code implementation of an HTTP (Web) server. The project is jointly managed by a group of volunteers located around the world, using the Internet and the Web to communicate, plan, and develop the server and its related documentation. This project is part of the Apache Software Foundation. In addition, hundreds of users have contributed ideas, code, and documentation to the project. This file is intended to briefly describe the history of the Apache HTTP Server and recognize the many contributors.

ざっくりまとめるとApatchとは

堅牢なHTTPサーバーの実装：Apatchは、信頼性の高い、商用レベルで使用できる品質を持っています。
多機能性：様々な機能を備え、幅広い用途に対応できる設計。
自由に利用可能なソースコード：オープンソースであり、誰でも無料でソースコードにアクセスし、利用することが可能です。


### 特徴

- **オープンソース**：Apacheは自由に使用、改変、配布が可能です。
- **モジュラー設計**：様々な機能をモジュールとして追加・削除できます。
- **クロスプラットフォーム**：Linux, Windows, macOSなど多くのOSで動作します。

### モジュラー設計


#### 概念

モジュラー設計とは、Apacheウェブサーバーが特定の機能を独立したモジュールとして提供し、それらを組み合わせて使用できる設計のことを指します。このアプローチにより、サーバーのパフォーマンスを最適化し、必要な機能のみをロードすることができます。

#### 主要なモジュール

- **mod_ssl**：SSL/TLSサポートを提供し、セキュアな通信を実現します。
- **mod_rewrite**：URLの書き換えやリダイレクトを行うための強力なツールです。
- **mod_security**：Webアプリケーションファイアウォールとして機能し、セキュリティを強化します。
- **mod_proxy**：プロキシサーバーとしての機能を提供し、リバースプロキシやロードバランシングの設定が可能です。

### Apacheの内部構造

- コアアーキテクチャ
マルチプロセス/マルチスレッドモデル：Apacheはマルチプロセスとマルチスレッドのモデルを採用しており、これにより同時に多数のリクエストを効率的に処理することができます。このモデルには、プリフォーク、ワーカー、イベントなど、異なるマルチプロセス/スレッド方式があります。

- リクエスト処理の流れ：クライアントからのリクエストは、Apacheによって受信され、適切なモジュールによって処理されます。この処理は、認証、URL書き換え、コンテンツ提供など、

- 主要コンポーネント
   - コアサーバー：基本的なリクエスト処理とレスポンス送信を担当します。コアサーバーは、リクエストを解析し、適切なモジュールに転送する役割を果たします。
   - モジュール：Apacheの機能は、多くのモジュールによって拡張されます。これらのモジュールは、セキュリティ、ルーティング、コンテンツの変換など、特定の機能を提供します。
   - 設定ファイル：httpd.conf と .htaccess などの設定ファイルを通じて、Apacheの挙動をカスタマイズできます。これらのファイルは、サーバーの全体設定や個別のディレクトリの挙動を制御するために使われます。

## インストールと設定


```bash
sudo apt-get update
sudo apt-get install apache2
```
基本設定
/etc/apache2/apache2.conf ファイルを編集して、基本的なサーバー設定を行います。

テスト
ブラウザで http://your_server_ip にアクセスし、Apacheのデフォルトページが表示されることを確認します。

## なにやってるの？

ウェブページのホスティング
Apacheは静的（HTML、CSS、JavaScriptファイルなど）や動的（PHP、Perl、Pythonを使用したアプリケーション）なコンテンツをインターネット上で提供します。ユーザーがブラウザで特定のURLにアクセスすると、Apacheは適切なウェブページを返します。

HTTPリクエストの処理
ユーザーのブラウザからのHTTPリクエスト（ウェブページの要求など）を受け取り、適切なレスポンス（ウェブページやエラーメッセージなど）を送り返します。

セキュリティの提供
SSL/TLSを使用した安全な通信をサポートし、ウェブサイトへの安全なアクセスを保証します。また、アクセス制御や認証機構を提供して、ウェブコンテンツのセキュリティを強化します。

モジュールによる機能の拡張
様々な追加モジュールを導入することで、URLの書き換え、コンテンツ圧縮、キャッシュなどの追加機能を提供できます。

バーチャルホスティング
単一のApacheサーバー上で複数のウェブサイトをホストし、それぞれに異なるドメイン名や設定を割り当てることが可能です。

ロギングと監視
アクセスログやエラーログを生成し、ウェブサイトの訪問者情報や発生した問題を記録します。
【Flutter】in_app_reviewを利用したアプリ内レビュー機能の組み込み

# 実装の目的

ユーザーがアプリ内から直接レビューを投稿できるようにすることで、アプリのフィードバックを容易に受け取れるようにする。

---
:bulb: 2023/11/25 追記
rete in app を用いた実装方法についての記事も公開しました。現在はこちらを採用しています

https://qiita.com/kotap15/items/2da199140f5d45355d12

## 実装のイメージ

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262578/c5512f9f-c1a5-166d-7af3-c5814af5bbce.png" width="540">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262578/6e64053b-d98b-554d-0e12-2d0c4f35227b.png" width="180">


[pub.dev/packages/in_app_review](https://pub.dev/packages/in_app_review) より引用


# 概要

この記事では、in_app_review パッケージを使用して、Flutter アプリ内でレビュー機能を実装する方法について紹介します。

また、アプリが特定のバージョンに対応していない場合に備え、ユーザーをApp StoreやGoogle Play Storeのページに誘導するフォールバック処理を実装する方法についても説明します。

# 使用するパッケージとバージョン
- Flutter: 3.0.6
- [url_launcher](https://pub.dev/packages/url_launcher): 6.1.14
- [in_app_review](https://pub.dev/packages/in_app_review): 2.0.8

# 実装方法

## コア機能の実装

以下のコードは、アプリ内レビュー機能を実装するためのコアとなる部分です。InAppReview インスタンスを使用して、ユーザーがApp StoreやGoogle Play Storeで直接レビューを行えるようにします。また、この機能が利用できない場合は、ユーザーを適切なストアのページに誘導します。

``` dart
class DrawerHelper {
  static final InAppReview _inAppReview = InAppReview.instance;

  // URLを定数化
  static const String _urlAppStore =
      'AppStoreURL';
  static const String _urlPlayStore =
      'PlayStoreURL';

  static void launchStoreReview(BuildContext context) async {
    try {
      if (await _inAppReview.isAvailable()) {
        _inAppReview.requestReview();
      } else {
        // ストアのURLにフォールバック
        final url = Platform.isIOS ? _urlAppStore : _urlPlayStore;

        if (!await launchUrl(Uri.parse(url))) {
          throw 'Cannot launch the store URL';
        }
        AnalyticsService.instance.analytics.logEvent(
          name: 'navigate_to_store_url',
        );
      }
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('ストアページを開けませんでした')),
      );
    }
  }
}
  ```

### 呼び出し元の例
``` dart
ListTile(
    leading: const Icon(Icons.star),
    title: const Text('レビューをする'),
    onTap: () => DrawerHelper.launchStoreReview(context),
),
```

  # デモ

 実際にこのコードを使用してListTileビューを実装し、以下のようなインターフェースを作成しました。
 シミュレーターなので送信はできませんが、実際には送信後文章を書けたりします。

![Simulator Screen Recording - iPhone SE (3rd generation) - 2023-11-17 at 10.31.14.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262578/e68a8bd9-4215-c9bc-ec5b-62c44689377b.gif)
[iOS さわやか待ち時間](https://apps.apple.com/jp/app/%E3%81%95%E3%82%8F%E3%82%84%E3%81%8B%E5%BE%85%E3%81%A1%E6%99%82%E9%96%93/id6459793328)で利用できます
Linuxについて学習

[【初心者向け】Linuxカーネルって一体なんだ？](https://qiita.com/uguis410/items/17ec1e447e9716bfdca7)

##### カーネルとはソフトウェアと（アプリ）ハードウェア（PC）を橋渡しするような存在。
〇〇がアクセスしようとしていますと制御が入るのもカーネルのシステムコールが依頼を受けて聞いてきてるかんじ

##### macにUTMという仮想環境を作るアプリを用いてLinux環境にすることもできるらしい
[【Linux】UTMを用いてM1 MacBookにUbuntuの仮想化環境を構築する](https://envader.plus/article/66)

##### wslを用いたwindowsでのLinux環境構築
[WSLでWindows 10にLinux仮想環境を構築](https://www.pc-koubou.jp/magazine/21475)
なぜ初めからLinuxを使わないのか、windowsでLinuxを使う理由、メリットなどわかりやすい。
世の中にはword,excelで作られたデータやファイルが多く存在しており、それらはwindowsで開けるし、開発はLinuxで進めれるというようは２つのOSのおいしいところをとれる

### wslにhomebrewをいれる

https://tech-blog.cloud-config.jp/2019-07-19-homebrew-on-wsl/

Linux環境でもhomebrewでパッケージ管理する方がやはり楽
いちいちアプリがバージョンアップされるたびに削除とダウンロードはめんどくさい


### WSLインストール
https://xtech.nikkei.com/atcl/nxt/column/18/01863/112600005/

### WSL エクスポートインポート
https://forest.watch.impress.co.jp/docs/serial/yajiuma/1220926.html
現場ではtarファイルをインポートした
MUIを使う際に、ViteのSSRの場合で発生したエラーに対処した設定

MUIを使って構築しViteでビルドした際に、ブラウザレンダリングではなんともなかったが、SSRのbuildをして、いざ動かすとエラーが出ることが多々あった。
それの対応について。

## materialとかの読み込みエラー

多くの場合は下記のようにMUIのパーツを読み込む場合

```javascript
import MenuItem from "@mui/material/MenuItem";
```

ブラウザでレンダリングしているときはエラーではなかったが、SSRにするとなぜかエラーになった

```shell
(node:66490) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
/*****/node_modules/@mui/material/MenuItem/index.js:3
export { default } from './MenuItem';
^^^^^^

SyntaxError: Unexpected token 'export'
    at internalCompileFunction (node:internal/vm:74:18)
    at wrapSafe (node:internal/modules/cjs/loader:1141:20)
    at Module._compile (node:internal/modules/cjs/loader:1182:27)
    at Module._extensions..js (node:internal/modules/cjs/loader:1272:10)
    at Module.load (node:internal/modules/cjs/loader:1081:32)
    at Module._load (node:internal/modules/cjs/loader:922:12)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:169:29)
    at ModuleJob.run (node:internal/modules/esm/module_job:194:25)
```

色々探って、下記みたいな回避策を取っていた。しかし開発中は気づけなくて割と困っていた。

```javascript
import { MenuItem } from "@mui/material";
```

しかし実は下記のような記載をvite.config.jsに記載すれば回避できるようである

https://github.com/brillout/vite-plugin-ssr/discussions/901

```vite.config.js
export default defineConfig({

  plugins: [
  (省略)
  ],
  ssr: {
    noExternal: [
      // MUI needs to be pre-processed by Vite in production: https://github.com/brillout/vite-plugin-ssr/discussions/901
      "@mui/base",
      "@mui/icons-material",
      "@mui/material",
      "@mui/utils"
    ],
  }
```

## MUI DatePickerまわりでのエラー

正確には自分の場合は先に読み込んだ `AdapterDayjs` で同じ内容のエラーがまず出たのだが、

```sh
import { DatePicker } from "@mui/x-date-pickers/DatePicker/index.js";
         ^^^^^^^^^^
SyntaxError: Named export 'DatePicker' not found. The requested module '@mui/x-date-pickers/DatePicker/index.js' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from '@mui/x-date-pickers/DatePicker/index.js';
const { DatePicker } = pkg;

    at ModuleJob._instantiate (node:internal/modules/esm/module_job:124:21)
    at async ModuleJob.run (node:internal/modules/esm/module_job:190:5)

Node.js v18.18.2
```

これも同様で、vite.config.jsに記載すれば回避できるようである

```vite.config.js
  ssr: {
    noExternal: [
      // MUI needs to be pre-processed by Vite in production: https://github.com/brillout/vite-plugin-ssr/discussions/901
      "@mui/base",
      "@mui/icons-material",
      "@mui/material",
      "@mui/utils",
      "@mui/x-date-pickers" // これを追加
    ],
  }
```

エラー周りは、MUIが原因か、Viteが原因か、自分はInertiaでPHPからReactを使っているのでそこが原因かわかりにくいのがしんどいです。まあコピペは間違っていないのでMUIが直接原因という可能性は低そうですが。
これにより私の睡眠時間が2時間削られた……。
ホールケーキ，ナイフ2回で3等分

問: 半径1のホールケーキを，ナイフを2回入れて3等分する。

答: 中心から上下（または左右）へ，約$\pm 0.265$離れた点を通り$x$軸（$y$軸）に平行にカットする。

この解が適切かどうか，3分割された半月状の部分の面積をシミュレーションにより求めて，真値と比較検証する。

第1象限の一辺の長さ1の正方形内に二次元一様乱数$(x, y)$を$n$組発生させ，$(x, y)$が四分円内にあり，かつ，$y \gt y_{0}$ の点の割合が$\pi/3=1.0471975511965976$になることを確認する。

```Julia
n = 100000000
x = rand(n)
y = rand(n)
print(2sum(@. x^2 + y^2 < 1 && y > 0.26493208460277684)/n)
```
```
   1.047205
```

![output_1_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2611739/d4d440aa-e708-dbf9-607c-9fa498a9c899.png)

追記：上（下）の平行線はそのままで，下（上）の線はx軸に平行でなくてもよいね。そのとき，何らかの制約をつけないと解は無数にあることになるが。
もっとも，上だって平行線でなくてもよいけど，まあ，それは回転すればよいだけのこと。
更には，上の線は平行線として決めて，二本目は下半分をy軸で左右半々に切るとかその他の二等分法。
Markdown PDF（VSCode拡張機能）を使ってみた。

## 本記事の内容
- VSCodeの拡張機能「Markdown PDF」を導入する。
- マークダウン形式のファイル（.md）をPDFファイル（.pdf）に変換する。

## 手順
1. VSCodeを開く。
2. VSCodeの拡張機能から「Markdown PDF」を検索し、インストールする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3575620/4d112726-bc21-e731-2a42-b9203faea87e.png)
3. PDF化したいファイルを開き、ファイル画面のどこかで右クリックをする。
4. 「Markdown PDF Export (pdf)」を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3575620/6736166d-fe2c-f6bf-37e4-6ba6fb672057.png)
5. できた！
自動採番項目のまとめ



+ [「カスタムの「自動採番」フィールドを生成するフローを「バルク化」するにはどうすればよいですか」](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000LIMhG)
+ [自動採番項目のリセット方法について](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007Pz1kK)
F-Secure Linux Security 64 対応OS

有償のサーバで使えるウィルス対策ソフト `F-Secure Linux Security 64` をネット検索してみましたのが、パッと出てこなかったのでリンクを記載。

System requirements | Linux Security 64 | Latest | WithSecure User Guides
https://www.withsecure.com/userguides/product.html#business/linux-security-64/latest/en/concept_94205F0A21A241C2A1741A9965BC0C49-latest-en
AI-102試験対策のまとめ「Speech SDKでMicrosoft Entra認証を使用する方法」

## はじめに
Azure AI Engineer Associate(AI-102)取得に向けた勉強でまとめた内容を本記事では投稿しています。
試験範囲の内容を私が勉強していく中で、
・忘れてしまっていた内容
・他の知識と絡めて理解した方が良い内容
・Microsoft Learnの読解に苦戦した内容
などをできるだけ分かりやすく簡潔にまとめることを意識しています。
Azureの勉強を一から始め、AI-102取得を目指している方の参考になれば幸いです。
※本記事の内容が必ず試験に出るわけではないこと、ご注意ください
※勉強しながら投稿しているため、追加で学んだことがあれば随時投稿内容を更新します。

## 試験対策のまとめ
### Speech SDKでMicrosoft Entra認証を使用する方法
1. Speechリソースの作成

#### **Microsoft Entra認証のSpeechリソースを構成**
1. カスタムサブドメイン名を作成
1. 下記のいずれかのロールをユーザーまたはアプリケーションに割り当てる
    * Cognitive Services Speech 共同作成者
    * Cognitive Services Speech ユーザー

#### **Microsoft Entraトークンを取得**
※C#やJavaの場合
1. Azure IDクライアントライブラリを使い、Microsoft Entraアクセストークンを取得
1. Azure PortalかPowerShellを使い、SpeechリソースIDを取得

#### **Speech SDK構成オブジェクトを作成**
※使用するオブジェクトによって下記が変わる
* トークンの提供方法
* 対応するSpeech SDKの`Config`オブジェクトの構築方法
1. リソースIDとMicrosoft Entraアクセストークンから認可トークンを作成
1. 認可トークンを使用して`SpeechConfig`オブジェクトを作成

* 参考
    - https://learn.microsoft.com/ja-jp/azure/ai-services/speech-service/how-to-configure-azure-ad-auth?tabs=portal&pivots=programming-language-csharp

## 次の試験対策のまとめ
* **AI-102試験対策のまとめ「スマートトリミングされたサムネイルの作成」**

https://qiita.com/fsd-jume/items/2a7abb88b845fd4bfb3e

## 学習内容をまとめたページの一覧

https://qiita.com/fsd-jume/items/65aba5d5514e023fd66d
.Net8でMudBlazorを使うには

[前回.Net8 BlazorでMudBlazorを動かすために](https://qiita.com/k-yamamoto/items/8617ec3cda5f6d272ec3)という記事で投稿しました。
.Net8(8.0.100-rc.2.23502.2)でのBlazorでMudBlazorを使うための記事です。

本記事(.Net8 8.0.100)は前回の暫定対処をアップデートするものです。
Routes.razorに
```
@rendermode InteractiveServer
```
を追加します。
終わりです。

:::note warn
残念ながらWASM側はVisualStudioのIntelliSenseが正しく働いていないため警告が出ますが、ビルド＆実行できました
:::
Control

```java:Control.java

    @RequestMapping(value = "/user/create", method = RequestMethod.POST)
    public String create(@Validated @ModelAttribute UserRequest userRequest, BindingResult result, Model model) {
        if (result.hasErrors()) {
            List<String> errorList = new ArrayList<>();
            for (ObjectError error : result.getAllErrors()) {
                String defaultMessage = Objects.requireNonNull(error.getDefaultMessage());
                String errorMessage = messageSource.getMessage(defaultMessage, null, defaultMessage, LocaleContextHolder.getLocale());
                errorList.add(errorMessage);

                // 添加以下日志输出
                System.out.println("Error Message: " + errorMessage);
            }
            model.addAttribute("validationError", errorList);

            return "user/add";
        }

        userService.create(userRequest);
        return "redirect:/user/list";
    }

```

        <!-- 在合适的位置添加，例如表单上方或下方 -->
        <div th:if="${validationError}">
          <div th:each="error : ${validationError}">
            <label class="text-danger" th:text="${error}"></label>
          </div>
        </div>
プログラミング初心者の日記 第0回

# 前置き
初めまして。syamaと申します。
私は今年新卒でIT業界に入りまして、しかしプログラミングは未経験なので毎日新鮮な気持ちで新しいことを学んでいます。
本日より、学んだことをアウトプットとして記事にしていくことにしました。
本日は、第0回としてQiitaの書き方について調べた内容をつらつらと書きつらねていきます。

# Qiitaいろいろ
## Markdown記法について
私Markdownで文章を書くのが初めてなんですが、便利なものですね。今まではQiitaは見る専だったのですが、`こうやって`コマンド部分を表示したりしていたのか、などと世界の解像度が上がったような感覚です。

    `こうやって`

[Markdown記法について詳しい内容は識者の方々が既に書いてくださっているので](https://qiita.com/tbpgr/items/989c6badefff69377da7)ここで羅列はしないことにます。

## タグ
これも記事を書くまで意識していなかったのですが、記事にタグを紐付けることで興味分野で記事を調べる方の目に留まるようになっています。(この記事を読んでいる方々からすれば「そんなこと常識だろ」と思われるでしょうが……。)
私のこの記事も、「初心者の初々しい記事を読みたいなぁ」と思われた諸先輩方の目にとまっているのかもしれません。
![Screenshot_20231117-073251.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622599/75342e70-52a8-70e4-845c-02fb8ad776f2.png)
タグはフォローすることで、興味ある分野の記事や質問の情報を的確に取得することが出来るようになっていて、右上の`···`からミュートすることも出来るようです。
「有識者の確度の高い内容だけが目に入るようにしたい」という場合には初心者タグをミュートにすることで、この記事のように付け焼き刃で二番煎じの記事が表示されなくなるわけですね。(冗談です)

## 文章の書き方について
実はこれが一番気になっていた内容で、例えばこういった雑記でも様々な書き方があると思います。
私が調べた中で「こういう書き方があるんだな」と思った書き方を3つ紹介します。

### スタンダード
[【Python】Python入門①【Pythonって何？】](https://qiita.com/dmm7txk2/items/03e2ebb089ce93d35bab)
元にした書籍や記事等ソースを用意した上で、調べたことを上から下に書いていくスタイル。こういうタイプの記事は内容が多くなりがちでナンバリングで複数記事に渡っている感覚がある一方で、端折らずに情報を書き連ねているため、正確性は確保されやすい。
どちらかと言うと自分のアウトプットとして出すというよりは、備忘録や他人が情報ソースとして使うことを意識した記事に向いている書き方かもしれない。

### 読者に語りかけるように書くタイプ
[非エンジニアの友人にPythonを教えた。彼はPythonistaとなった。](https://qiita.com/1021ky@github/items/3d9230f35be5c7d61e4d)
日記(この記事の方はポエムと仰っていますが)のように事実や起きたことを書き連ねていく書き方。ただ事実を書くだけでなく、筆者が思ったことや考え方までアウトプットしていることで読者が没入・理解しやすくなっていると感じます。
上記の記事では最初にサマリ、対象者、経緯、環境と必要な情報を最初に書いており、読者としても助かりますし、読みやすい形だと思います。
私の記事(日記)もこのような形で書いていくことになると思います。

### 変わった書き方
[4歳娘「パパ、懐かしいJavaScript書いてるね！」](https://qiita.com/Yametaro/items/70e7878c5ea51788b643)
筆者が実在しない娘さん(実在はするかもしれませんが、こんなことは喋らないでしょう)と対話しながら知識のアウトプットを行ってくれるという形式の記事です。
「物語」のエッセンスも含む書き方で、読者が引き込まれる書き方である一方で、堅い内容には向かないこと、センスが必要なことが難しい要素となっており、手は出しづらいと感じます(だからこそ、こういった文章を書ける方が人気を得るのだと思います)

## 公開について
さて、記事の内容を書いたらいよいよ公開です。公開方法には「全体に公開」と「限定公開」の2種類があります。
![Screenshot_20231117-060411~2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3622599/28d4e4e2-9230-d4f5-70ce-421425d1b061.png)
限定公開を指定すると、記事を書いた本人とリンクを知っている人しか記事を読むことができず、公開前に特定の人に見せたいだとか、そもそも全世界に公開はしたくない！といった場合に役立ちます。
限定公開後、全体に公開に設定を変更することは出来ますが、一度全体に公開した記事を限定公開に戻すことは出来ないため注意が必要です。

# 終わりに
ここまで読んでいただきありがとうございました。今後は定期的に学んだ知識を皆さんにも為になる形でアウトプットしていければと思うので、よろしくお願いいたします。( * . .)"ぺこり
Flutter初期アプリをproviderの状態管理に変えてみる

こんにちは、アウトプット太郎です。

今回はタイトルの通り、初期アプリ(カウンターアプリ)
の内容をproviderを使った状態管理に変更し、setStateとはどんな点が違うのか、
学んでみました。

[初期アプリ解説記事はこちら](https://qiita.com/output_tarou/items/a0257ba0699a05f0425a)

以降手順としては下記になります。

1.providerパッケージの追加

ターミナルで下記を実行
``
 $ flutter pub add provider
``

上記によって、pubspec.yamlにproviderパッケージが入ります。
こうすることでローカルキャッシュにソースコードが保存され、build時に使用されるようになります。

2.counter_modelの作成
別ファイルとしてcounter_model.dartを作成します。

```
import 'package:flutter/material.dart';

class CounterModel extends ChangeNotifier {
  int _counter = 0;

  int get counter => _counter;

  void incrementCounter() {
    _counter++;
    notifyListeners();
  }
}
```

ChangeNotifierクラスを継承したCounterModelを定義しています。

ChangeNotifierクラスとは
状態変更を通知する機能を持ったクラスです。

FlutterではしばしばProviderと一緒に使われ、
アプリケーションのトップレベルで状態モデルを宣言した後、
各widgetでその状態モデルを使用すると、そのwidgetはリスナーとして
ChangeNotifierに保持されます。

そして、ChangeNotifierクラスが持つメソッド内でnotifyListeners();が実行されると、状態の変更としてリスナーへ通知が行われ、リスナーの再描画が行われます。

要するに、ChangeNotifireは事前にリスナーとして登録しておいたら、変更があった時に通知がきて、リロードがかかる仕組みを提供しています。

それではステップ3としてproviderの宣言を行います。

```
void main() {
  runApp(
    ChangeNotifierProvider(
      create: (context) => CounterModel(),
      child: const MyApp(),
    ),
  );
}
```

そして利用したいwidget内で状態モデルを定義し、
ボタン内でクリックイベントが起きた時にcounterModelの持つ、incrementCounterを呼び出しています。

```
class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    final counterModel = Provider.of<CounterModel>(context, listen: false);

    return Scaffold(
      // ...
      floatingActionButton: FloatingActionButton(
        onPressed: () => counterModel.incrementCounter(),
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}
```

``
final counterModel = Provider.of<CounterModel>(context, listen: false);
``
この書き方について解説すると、
Providerパッケージのofメソッドで、CounterModelの状態モデルを指定しています。
また、listenパラメータにfalseを渡すことでこちらはリスナー登録していないことが分かります。

逆に実際にカウンターの数字を示している下記では
```
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '${Provider.of<CounterModel>(context).counter}',
              style: Theme.of(context).textTheme.headlineMedium,
            ),
          ],
        ),
      ),
```

``
'${Provider.of<CounterModel>(context).counter}',
``
listenは定義されず、defaultでtrueになっています。

以上、一連の流れでsetStateからproviderを使った状態管理に移行することが出来ました。

setStateの時はStatefulWidgetとStateが1対1でしたが、
providerにすると、一度宣言すれば色々な画面でCounterModelを使えるのは便利だなと思いました。

ただ、トップレベルで宣言するとなると、数が増えてきたときにmain関数が長くなる恐れがあり、その場合は別ファイルに書いて、その関数を呼び出すといいのではと思いました。